MCPcopy Create free account
hub / github.com/emscripten-core/emscripten / buildExprTree

Function buildExprTree

src/lib/libc_preprocessor.js:177–238  ·  view source on GitHub ↗
(tokens)

Source from the content-addressed store, hash-verified

175
176 // Given a token list e.g. ['2', '>', '1'], returns a function that evaluates that token list.
177 function buildExprTree(tokens) {
178 // Consume tokens array into a function tree until the tokens array is exhausted
179 // to a single root node that evaluates it.
180 while (tokens.length > 1 || typeof tokens[0] != 'function') {
181 tokens = ((tokens) => {
182 // Find the index 'i' of the operator we should evaluate next:
183 var i, j, p, operatorAndPriority = -2;
184 for (j = 0; j < tokens.length; ++j) {
185 if ((p = ['*', '/', '+', '-', '!', '<', '<=', '>', '>=', '==', '!=', '&&', '||', '('].indexOf(tokens[j])) > operatorAndPriority) {
186 i = j;
187 operatorAndPriority = p;
188 }
189 }
190
191 if (operatorAndPriority == 13 /* parens '(' */) {
192 // Find the closing parens position
193 j = find_closing_parens_index(tokens, i);
194 if (j) {
195 tokens.splice(i, j+1-i, buildExprTree(tokens.slice(i+1, j)));
196 return tokens;
197 }
198 }
199
200 if (operatorAndPriority == 4 /* unary ! */) {
201 // Special case: the unary operator ! needs to evaluate right-to-left.
202 i = tokens.lastIndexOf('!');
203 var innerExpr = buildExprTree(tokens.slice(i+1, i+2));
204 tokens.splice(i, 2, function() { return !innerExpr(); })
205 return tokens;
206 }
207
208 // A binary operator:
209 if (operatorAndPriority >= 0) {
210 var left = buildExprTree(tokens.slice(0, i));
211 var right = buildExprTree(tokens.slice(i+1));
212 var opers = {
213 '&&': () => left() && right(),
214 '||': () => left() || right(),
215 '==': () => left() == right(),
216 '!=': () => left() != right(),
217 '<' : () => left() < right(),
218 '<=': () => left() <= right(),
219 '>' : () => left() > right(),
220 '>=': () => left() >= right(),
221 '+': () => left() + right(),
222 '-': () => left() - right(),
223 '*': () => left() * right(),
224 '/': () => Math.floor(left() / right())
225 };
226 return [opers[tokens[i]]];
227 }
228 // else a number:
229#if ASSERTIONS
230 assert(tokens[i] !== ')', 'parse failure, mismatched parentheses in parsing' + tokens.toString());
231 assert(operatorAndPriority == -1);
232#endif
233 var num = Number(tokens[i]);
234 return [function() { return num; }]

Callers 1

expandMacrosFunction · 0.85

Calls 2

sliceMethod · 0.80
assertFunction · 0.50

Tested by

no test coverage detected