SymbolListPtr CodeBlock::convert_postfix(SymbolListPtr p) { // data structs unique_ptr<stack<SymbolPtr>> op_stack = unique_ptr<stack<SymbolPtr>>(new stack<SymbolPtr>); SymbolListPtr unpostfix_symbols = SymbolListPtr(new SymbolList()); // shunting yard (modified for unary operators!) for (auto i = p->begin(); i != p->end(); i++) { if (is_operand(*i)) { unpostfix_symbols->push_back(*i); if (!op_stack->empty()) { if (is_unary(op_stack->top())) { unpostfix_symbols->push_back(op_stack->top()); op_stack->pop(); } } } else if (is_operator(*i)) { if (is_unary((*i))) { op_stack->push(*i); } else { while (!op_stack->empty() && !is_lparen(op_stack->top()) && compare_ops(*i, op_stack->top()) <= 0) { unpostfix_symbols->push_back(op_stack->top()); op_stack->pop(); } op_stack->push(*i); } } else if (is_lparen(*i)) { op_stack->push(*i); } else if (is_rparen(*i)) { while (!op_stack->empty()) { if (is_lparen(op_stack->top())) { op_stack->pop(); if (!op_stack->empty()) { if (is_unary(op_stack->top())) { unpostfix_symbols->push_back(op_stack->top()); op_stack->pop(); } } break; } unpostfix_symbols->push_back(op_stack->top()); op_stack->pop(); } } } while(!op_stack->empty()) { unpostfix_symbols->push_back(op_stack->top()); op_stack->pop(); } // set the temp symbols as the postfix stuff return unpostfix_symbols; }
int compare_ops(char *o1, char *o2) { int o1p, o2p; Operator* o1o; Operator* o2o; if (is_lparen(o2)) return 0; o1o = get_operator(o1); o2o = get_operator(o2); o1p = o1o->precedence; o2p = o2o->precedence; if ((is_lassoc(*o1o) && o1p <= o2p) || (is_rassoc(*o1o) != -1 && o1p < o2p)) { return 1; } return 0; }
void infix2rpn(char *expr, RPNEntry ***rpne, int *nrpne) { Array *rpn = array_new(32, 16); Stack *stack_ops = stack_new(16); //static char token[64]; char *token; int tokenlen; int i; int uminus = 1; int inoperand = 0; //printf("%s:-> ", expr); char lookahead; for(token = gettoken(expr, &tokenlen, &lookahead);token != NULL; token = gettoken(NULL, &tokenlen, &lookahead)) { if (uminus) { if (*token == T_MINUS) { *token = T_UMINUS; } uminus = 0; } if (is_function(token, tokenlen)) { stack_push(stack_ops, token); } else if (is_operand(token)) { array_add(rpn, token); } else if (is_arg_separator(token)) { while(!stack_empty(stack_ops) && !is_lparen(stack_peek(stack_ops))) { array_add(rpn, stack_pop(stack_ops)); } } else if (is_operator(token)) { uminus = 1; if (stack_empty(stack_ops)) { stack_push(stack_ops, token); } else { if (compare_ops(token, stack_peek(stack_ops))) { array_add(rpn, stack_pop(stack_ops)); } stack_push(stack_ops, token); } } else if (is_lparen(token)) { uminus = 1; stack_push(stack_ops, token); } else if (is_rparen(token)) { while(!stack_empty(stack_ops) && !is_lparen(stack_peek(stack_ops))) { array_add(rpn, stack_pop(stack_ops)); } stack_pop(stack_ops); } else { // errorski } } while (!stack_empty(stack_ops)) { array_add(rpn, stack_pop(stack_ops)); } stack_free(&stack_ops); *rpne = (RPNEntry **)malloc(rpn->count * sizeof(RPNEntry*)); for (i = 0; i < rpn->count; i++) { token = array_get(rpn, i); (*rpne)[i] = new_rpnentry(token, strlen(token)); } *nrpne = rpn->count; array_free(&rpn); }
TokenSeq *glsl_expand(TokenSeq *ts, bool recursive) { TokenSeq *res = NULL; STACK_CHECK(); while (ts || !res) { if (!recursive && ts == NULL) ts = next_tokenseq(); if (ts == NULL) break; if (!glsl_tokenlist_contains(ts->hide, ts->token)) { Macro *m = glsl_macrolist_find(directive_macros, ts->token); if (m != NULL) { switch (m->type) { case MACRO_OBJECT: ts = glsl_tokenseq_destructive_reverse(subst(m->body, NULL, NULL, glsl_tokenlist_construct(ts->token, ts->hide), NULL), ts->next); continue; // effective tail call case MACRO_FUNCTION: if (!recursive && ts->next == NULL) ts->next = next_tokenseq(); if (ts->next && is_lparen(ts->next->token)) { int formal_count = glsl_tokenlist_length(m->args); int depth = 0; int count = 0; /* gather up actual parameters */ TokenSeq *tail = ts->next->next; TokenSeq *curr = NULL; TokenSeqList *actuals = NULL; while (true) { if (!recursive && tail == NULL) tail = next_tokenseq(); if (tail == NULL) glsl_compile_error(ERROR_PREPROCESSOR, 1, g_LineNumber, "mismatched parenthesis in macro invocation"); if (is_lparen(tail->token)) depth++; if (is_rparen(tail->token)) { if (depth == 0) break; else depth--; } if (is_comma(tail->token)) if (depth == 0) { actuals = glsl_tokenseqlist_construct(glsl_tokenseq_destructive_reverse(curr, NULL), actuals); count++; tail = tail->next; curr = NULL; continue; } curr = glsl_tokenseq_construct(tail->token, tail->hide, curr); tail = tail->next; } if (count > 0 || formal_count == 1 || curr != NULL) { actuals = glsl_tokenseqlist_construct(glsl_tokenseq_destructive_reverse(curr, NULL), actuals); count++; } /* check against arity of macro */ if (count == formal_count) { ts = glsl_tokenseq_destructive_reverse(subst(m->body, m->args, actuals, glsl_tokenlist_construct(ts->token, glsl_tokenlist_intersect(ts->hide, tail->hide)), NULL), tail->next); continue; // effective tail call } else glsl_compile_error(ERROR_PREPROCESSOR, 1, g_LineNumber, "arity mismatch in macro invocation"); } break; case MACRO_LINE: ts = glsl_tokenseq_construct(glsl_token_construct_ppnumberi(g_LineNumber), NULL, ts->next); break; case MACRO_FILE: ts = glsl_tokenseq_construct(glsl_token_construct_ppnumberi(g_FileNumber), NULL, ts->next); break; default: UNREACHABLE(); break; } } } res = glsl_tokenseq_construct(ts->token, ts->hide, res); ts = ts->next; } return glsl_tokenseq_destructive_reverse(res, NULL); }