]> git.bts.cx Git - sun.git/blob - runtime/src/sun/tree/tree.c
118f9c633ff032155a2c5f5987fa9e195f74ce88
[sun.git] / runtime / src / sun / tree / tree.c
1 #include "tree.h"
2
3 #include "node_internal.h"
4 #include "node_type.h"
5
6 #include <stdlib.h>
7
8 typedef struct {
9 SLTTreeIteratorCallback callback;
10 SLTTreeIteratorCallback postCallback;
11 void *userParameter;
12 } TreeIteratorCallbackDetails;
13
14 static SLTNode *treeIterateCallback(SLTNode *node, void *extra);
15 static SLTNode *treeIteratePostCallback(SLTNode *node, void *extra);
16
17 void sltTreeIterate(SLTNode *root, SLTTreeIteratorCallback callback, SLTTreeIteratorCallback postCallback, void *userParameter) {
18 TreeIteratorCallbackDetails details = {
19 .callback = callback,
20 .postCallback = postCallback,
21 .userParameter = userParameter,
22 };
23 sltTreeMap(root, (callback != NULL) ? treeIterateCallback : NULL, (postCallback != NULL) ? treeIteratePostCallback : NULL, &details);
24 }
25
26 SLTNode *sltTreeMap(SLTNode *root, SLTTreeMapCallback callback, SLTTreeMapCallback postCallback, void *userParameter){
27 SLTNode *n = root;
28
29 if (callback != NULL && n != NULL && n->type != SLTNodeTypeSequence) {
30 n = callback(n, userParameter);
31 }
32
33 if (n != NULL) {
34 switch (n->type) {
35 default:
36 case SLTNodeTypeUnknown:
37 /* Produce error? */
38 break;
39
40 /* These have no child nodes */
41 case SLTNodeTypeIdentifier:
42 case SLTNodeTypeInteger:
43 case SLTNodeTypeFloat:
44 case SLTNodeTypeString:
45 case SLTNodeTypeOperator:
46 break;
47
48 case SLTNodeTypeCompound:
49 n->compoundSubexpression = sltTreeMap(n->compoundSubexpression, callback, postCallback, userParameter);
50 break;
51
52 case SLTNodeTypeArgument:
53 n->argumentExpression = sltTreeMap(n->argumentExpression, callback, postCallback, userParameter);
54 break;
55
56 case SLTNodeTypeArrayAccess:
57 n->arrayAccessArray = sltTreeMap(n->arrayAccessArray, callback, postCallback, userParameter);
58 n->arrayAccessAccess = sltTreeMap(n->arrayAccessAccess, callback, postCallback, userParameter);
59 break;
60
61 case SLTNodeTypeTypeAccess:
62 n->typeAccessType = sltTreeMap(n->typeAccessType, callback, postCallback, userParameter);
63 n->typeAccessAccess = sltTreeMap(n->typeAccessAccess, callback, postCallback, userParameter);
64 break;
65
66 case SLTNodeTypeFunctionCall:
67 n->functionCallFunction = sltTreeMap(n->functionCallFunction, callback, postCallback, userParameter);
68 n->functionCallArguments = sltTreeMap(n->functionCallArguments, callback, postCallback, userParameter);
69 break;
70
71 case SLTNodeTypeUnaryOperation:
72 n->unaryOperationOperator = sltTreeMap(n->unaryOperationOperator, callback, postCallback, userParameter);
73 n->unaryOperationOperand = sltTreeMap(n->unaryOperationOperand, callback, postCallback, userParameter);
74 break;
75
76 case SLTNodeTypeBinaryOperation:
77 n->binaryOperationOperator = sltTreeMap(n->binaryOperationOperator, callback, postCallback, userParameter);
78 n->binaryOperationLHS = sltTreeMap(n->binaryOperationLHS, callback, postCallback, userParameter);
79 n->binaryOperationRHS = sltTreeMap(n->binaryOperationRHS, callback, postCallback, userParameter);
80 break;
81
82 case SLTNodeTypeAssignment:
83 n->assignmentTarget = sltTreeMap(n->assignmentTarget, callback, postCallback, userParameter);
84 n->assignmentSource = sltTreeMap(n->assignmentSource, callback, postCallback, userParameter);
85 break;
86
87 case SLTNodeTypeReturn:
88 n->returnExpression = sltTreeMap(n->returnExpression, callback, postCallback, userParameter);
89 break;
90
91 //case SLTNodeTypeIteration:
92 case SLTNodeTypeForIteration:
93 case SLTNodeTypeDoIteration:
94 case SLTNodeTypeWhileIteration:
95 n->iterationInitialExpression = sltTreeMap(n->iterationInitialExpression, callback, postCallback, userParameter);
96 n->iterationPreValidExpression = sltTreeMap(n->iterationPreValidExpression, callback, postCallback, userParameter);
97 n->iterationPostValidExpression = sltTreeMap(n->iterationPostValidExpression, callback, postCallback, userParameter);
98 n->iterationLoopExpression = sltTreeMap(n->iterationLoopExpression, callback, postCallback, userParameter);
99 n->iterationStatement = sltTreeMap(n->iterationStatement, callback, postCallback, userParameter);
100 break;
101
102 case SLTNodeTypeSelection:
103 n->selectionValidExpression = sltTreeMap(n->selectionValidExpression, callback, postCallback, userParameter);
104 n->selectionValidStatement = sltTreeMap(n->selectionValidStatement, callback, postCallback, userParameter);
105 n->selectionInvalidStatement = sltTreeMap(n->selectionInvalidStatement, callback, postCallback, userParameter);
106 break;
107
108 case SLTNodeTypeStatementBlock:
109 n->statementBlockContents = sltTreeMap(n->statementBlockContents, callback, postCallback, userParameter);
110 break;
111
112 case SLTNodeTypeVariableDefinition:
113 n->variableDefinitionType = sltTreeMap(n->variableDefinitionType, callback, postCallback, userParameter);
114 n->variableDefinitionIdentifier = sltTreeMap(n->variableDefinitionIdentifier, callback, postCallback, userParameter);
115 n->variableDefinitionDefaultExpression = sltTreeMap(n->variableDefinitionDefaultExpression, callback, postCallback, userParameter);
116 break;
117
118 case SLTNodeTypeTypeDefinition:
119 n->typeDefinitionIdentifier = sltTreeMap(n->typeDefinitionIdentifier, callback, postCallback, userParameter);
120 n->typeDefinitionMembers = sltTreeMap(n->typeDefinitionMembers, callback, postCallback, userParameter);
121 break;
122
123 case SLTNodeTypeTypeMemberDefinition:
124 n->typeMemberDefinitionType = sltTreeMap(n->typeMemberDefinitionType, callback, postCallback, userParameter);
125 n->typeMemberDefinitionIdentifier = sltTreeMap(n->typeMemberDefinitionIdentifier, callback, postCallback, userParameter);
126 break;
127
128 case SLTNodeTypeFunctionDefinition:
129 n->functionDefinitionType = sltTreeMap(n->functionDefinitionType, callback, postCallback, userParameter);
130 n->functionDefinitionIdentifier = sltTreeMap(n->functionDefinitionIdentifier, callback, postCallback, userParameter);
131 n->functionDefinitionParameters = sltTreeMap(n->functionDefinitionParameters, callback, postCallback, userParameter);
132 n->functionDefinitionBody = sltTreeMap(n->functionDefinitionBody, callback, postCallback, userParameter);
133 break;
134
135 case SLTNodeTypeFunctionParameterDefinition:
136 n->functionParameterDefinitionType = sltTreeMap(n->functionParameterDefinitionType, callback, postCallback, userParameter);
137 n->functionParameterDefinitionIdentifier = sltTreeMap(n->functionParameterDefinitionIdentifier, callback, postCallback, userParameter);
138 break;
139
140 case SLTNodeTypeModule:
141 n->moduleStatementsAndDefinitions = sltTreeMap(n->moduleStatementsAndDefinitions, callback, postCallback, userParameter);
142 break;
143
144 case SLTNodeTypeSequence: {
145 SLTNode *readHead = n;
146 SLTNode *writeHead = n;
147 SLTNode **writeLast = &n;
148
149 *writeLast = NULL;
150
151 while (readHead != NULL) {
152 writeHead->sequenceNode = sltTreeMap(readHead->sequenceNode, callback, postCallback, userParameter);
153 readHead = readHead->sequenceNext;
154
155 if (writeHead->sequenceNode != NULL) {
156 *writeLast = writeHead;
157 writeLast = &writeHead->sequenceNext;
158 writeHead = writeHead->sequenceNext;
159 *writeLast = NULL;
160 }
161 }
162
163 break;
164 }
165 }
166 }
167
168 if (postCallback != NULL && n != NULL && n->type != SLTNodeTypeSequence) {
169 n = postCallback(n, userParameter);
170 }
171
172 return n;
173 }
174
175 SLTNode *treeIterateCallback(SLTNode *node, void *extra) {
176 TreeIteratorCallbackDetails *details = (TreeIteratorCallbackDetails *)extra;
177 details->callback(node, details->userParameter);
178 return node;
179 }
180
181 SLTNode *treeIteratePostCallback(SLTNode *node, void *extra) {
182 TreeIteratorCallbackDetails *details = (TreeIteratorCallbackDetails *)extra;
183 details->postCallback(node, details->userParameter);
184 return node;
185 }