MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / FinalizeExpression

Method FinalizeExpression

source/script.cpp:9354–9507  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

9352
9353
9354ResultType Line::FinalizeExpression(ArgStruct &aArg)
9355{
9356 auto stack = (ExprTokenType **)_alloca(aArg.max_stack * sizeof(ExprTokenType **));
9357 int stack_count = 0;
9358 // stack_count checks: Since missing operands are caught at an earlier stage, it doesn't
9359 // seem possible to produce any situation where the stack is unbalanced, but due to the
9360 // overall complexity it seems best to assume that it could happen. Having these checks
9361 // here might help catch future (or present) bugs.
9362
9363 for (auto this_postfix = aArg.postfix; this_postfix->symbol != SYM_INVALID; ++this_postfix)
9364 {
9365 auto postfix_symbol = this_postfix->symbol;
9366 ASSERT((UINT)postfix_symbol < SYM_COUNT);
9367 if (IS_OPERAND(postfix_symbol))
9368 {
9369 if (postfix_symbol == SYM_DYNAMIC)
9370 {
9371 if (stack_count < 1)
9372 return LineError(ERR_EXPR_SYNTAX);
9373 --stack_count;
9374 }
9375 stack[stack_count++] = this_postfix;
9376 }
9377 else if (IS_POSTFIX_OPERATOR(postfix_symbol) || IS_PREFIX_OPERATOR(postfix_symbol))
9378 {
9379 if (stack_count < 1)
9380 return LineError(ERR_EXPR_SYNTAX);
9381 stack[stack_count - 1] = this_postfix;
9382 }
9383 else if (SYM_USES_CIRCUIT_TOKEN(postfix_symbol))
9384 {
9385 if (stack_count < 1)
9386 return LineError(ERR_EXPR_SYNTAX);
9387 // Pop the result of the left branch of this short-circuit operator, then just allow the right branch
9388 // to be evaluated and its value/token used as the result. A consequence of this simple approach is
9389 // that when a short-circuit expression is passed as a parameter, only the right branch...
9390 // 1) is permitted to be something like &A_Index, being passed to a built-in output var param.
9391 // 2) is resolved to a function address in something like DllCall(a || "B") or DllCall(a?"B":"C").
9392 // If this is changed, be sure that both branches are "finalized"; i.e. don't just skip over the right
9393 // branch, since it might contain invalid function calls. This seems difficult to do in one pass since
9394 // the end of the right branch isn't marked in any way, but it can be done by having a recursive call
9395 // finalize from [this_postfix] to [this_postfix->circuit_token], then having this layer skip it.
9396 --stack_count;
9397 }
9398 else if (postfix_symbol == SYM_COMMA)
9399 {
9400 if (stack_count < 1)
9401 return LineError(ERR_EXPR_SYNTAX);
9402 --stack_count;
9403 }
9404 else if (postfix_symbol != SYM_FUNC)
9405 {
9406 if (stack_count < 2)
9407 return LineError(ERR_EXPR_SYNTAX);
9408 --stack_count; // Pop RHS
9409 stack[stack_count - 1] = this_postfix; // Replace LHS
9410 }
9411 else // SYM_FUNC

Callers 1

PreparseCommandsMethod · 0.80

Calls 9

GetDllProcAddressFunction · 0.85
HasObjectMethod · 0.80
is_variadicMethod · 0.80
SetValueMethod · 0.80
IsAssignedSomewhereMethod · 0.80
WarnUnassignedVarMethod · 0.80
ObjectMethod · 0.45
IsBuiltInMethod · 0.45
ArgIsOutputVarMethod · 0.45

Tested by

no test coverage detected