static struct AstNode *parse_special( struct DomNode *dom, struct ParserState *state) { struct AstNode *result; if ((!err_state() && (result = parse_do_block(dom, state))) || (!err_state() && (result = parse_match(dom, state))) || (!err_state() && (result = parse_if(dom, state))) || (!err_state() && (result = parse_while(dom, state))) || (!err_state() && (result = parse_func_def(dom, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_AND, ast_make_spec_bool_and, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_OR, ast_make_spec_bool_or, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_SET_OF, ast_make_spec_set_of, state))) || (!err_state() && (result = parse_binary(dom, DOM_RES_RANGE_OF, ast_make_spec_range_of, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_ARRAY_OF, ast_make_spec_array_of, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_TUPLE_OF, ast_make_spec_tuple_of, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_POINTER_TO, ast_make_spec_pointer_to, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_FUNCTION, ast_make_spec_function_type, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_TYPE_PRODUCT, ast_make_spec_type_product, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_TYPE_UNION, ast_make_spec_type_union, state))) || (!err_state() && (result = parse_bind(dom, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_PTR, ast_make_spec_ptr, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_PEEK, ast_make_spec_peek, state))) || (!err_state() && (result = parse_binary(dom, DOM_RES_POKE, ast_make_spec_poke, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_BEGIN, ast_make_spec_begin, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_END, ast_make_spec_end, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_INC, ast_make_spec_inc, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_SUCC, ast_make_spec_succ, state)))) { return result; } else { return NULL; } }
static int parse_unary(struct _asm_context *asm_context, int64_t *num, int operation) { char token[TOKENLEN]; int token_type; int64_t temp; struct _var var; var_set_int(&var, 0); token_type = tokens_get(asm_context, token, TOKENLEN); //printf("parse_unary: %s token_type=%d(%d)\n", token, token_type, TOKEN_NUMBER); if (IS_TOKEN(token,'-')) { if (parse_unary(asm_context, &temp, OPER_MINUS) == -1) { return -1; } } else if (IS_TOKEN(token,'~')) { if (parse_unary(asm_context, &temp, OPER_NOT) != 0) { return -1; } } else if (token_type == TOKEN_NUMBER) { temp = atoll(token); } else if (IS_TOKEN(token, '(')) { if (eval_expression_ex(asm_context, &var) != 0) { return -1; } if (var.type != VAR_INT) { print_error("Non-integer number in expression", asm_context); return -1; } temp = var_get_int64(&var); token_type = tokens_get(asm_context, token, TOKENLEN); if (IS_NOT_TOKEN(token,')')) { print_error_unexp(token, asm_context); return -1; } } else { print_error_unexp(token, asm_context); return -1; } if (operation == OPER_NOT) { *num = ~temp; } else if (operation == OPER_MINUS) { *num = -temp; } else { print_error_internal(NULL, __FILE__, __LINE__); return -1; } return 0; }
struct node *parse_term(struct compiler *compiler) { struct node *result = parse_unary(compiler); while(lexer_current(compiler) == T_MUL || lexer_current(compiler) == T_DIV) { struct node *node = alloc_node(compiler, N_BINARY_OP); node->op = lexer_current(compiler); node->left = result; lexer_next(compiler); node->right = parse_unary(compiler); result = node; } return result; }
static bool parse_mul(ExprParseState *state) { CHECK_ERROR(parse_unary(state)); for (;;) { switch (state->token) { case '*': CHECK_ERROR(parse_next_token(state) && parse_unary(state)); parse_add_func(state, OPCODE_FUNC2, 2, op_mul); break; case '/': CHECK_ERROR(parse_next_token(state) && parse_unary(state)); parse_add_func(state, OPCODE_FUNC2, 2, op_div); break; default: return true; } } }
static BtorNode * parse_proxy (BtorBTORParser * parser, int len) { return parse_unary (parser, len, btor_copy_exp); }
static BtorNode * parse_dec (BtorBTORParser * parser, int len) { return parse_unary (parser, len, btor_dec_exp); }
static int eval_expression_go(struct _asm_context *asm_context, struct _var *var, struct _operator *last_operator) { char token[TOKENLEN]; int token_type; struct _var var_stack[3]; int var_stack_ptr = 1; struct _operator operator; int last_token_was_op = -1; #ifdef DEBUG printf("Enter eval_expression_go, var=%d/%f/%d\n", var_get_int32(var), var_get_float(var), var_get_type(var)); #endif memcpy(&operator, last_operator, sizeof(struct _operator)); VAR_COPY(&var_stack[0], var); while(1) { #ifdef DEBUG printf("eval_expression> going to grab a token\n"); #endif token_type = tokens_get(asm_context, token, TOKENLEN); #ifdef DEBUG printf("eval_expression> token=%s var_stack_ptr=%d\n", token, var_stack_ptr); #endif // Issue 15: Return an error if a stack is full with noe operator. if (var_stack_ptr == 3 && operator.operation == OPER_UNSET) { return -1; } if (token_type == TOKEN_QUOTED) { if (token[0] == '\\') { int e = tokens_escape_char(asm_context, (unsigned char *)token); if (e == 0) return -1; if (token[e+1] != 0) { print_error("Quoted literal too long.", asm_context); return -1; } sprintf(token, "%d", token[e]); } else { if (token[1]!=0) { print_error("Quoted literal too long.", asm_context); return -1; } sprintf(token, "%d", token[0]); } token_type = TOKEN_NUMBER; } // Open and close parenthesis if (IS_TOKEN(token,'(')) { if (last_token_was_op == 0 && operator.operation != OPER_UNSET) { operate(&var_stack[var_stack_ptr-2], &var_stack[var_stack_ptr-1], last_operator); var_stack_ptr--; operator.operation = OPER_UNSET; VAR_COPY(var, &var_stack[var_stack_ptr-1]); tokens_push(asm_context, token, token_type); return 0; } if (operator.operation == OPER_UNSET && var_stack_ptr == 2) { // This is probably the x(r12) case.. so this is actually okay VAR_COPY(var, &var_stack[var_stack_ptr-1]); tokens_push(asm_context, token, token_type); return 0; } struct _var paren_var; struct _operator paren_operator; paren_operator.precedence = PREC_UNSET; paren_operator.operation = OPER_UNSET; memset(&paren_var, 0, sizeof(struct _var)); if (eval_expression_go(asm_context, &paren_var, &paren_operator) != 0) { return -1; } last_token_was_op = 0; #ifdef DEBUG printf("Paren got back %d/%f/%d\n", var_get_int32(&paren_var), var_get_float(&paren_var), var_get_type(&paren_var)); #endif VAR_COPY(&var_stack[var_stack_ptr++], &paren_var); token_type = tokens_get(asm_context, token, TOKENLEN); if (!(token[1] == 0 && token[0] == ')')) { print_error("No matching ')'", asm_context); return -1; } continue; } if (IS_TOKEN(token,')')) { tokens_push(asm_context, token, token_type); break; } // End of expression if (IS_TOKEN(token,',') || IS_TOKEN(token,']') || token_type == TOKEN_EOF || IS_TOKEN(token,'.')) { tokens_push(asm_context, token, token_type); break; } if (token_type == TOKEN_EOL) { //asm_context->tokens.line++; tokens_push(asm_context, token, token_type); break; } // Read number if (token_type == TOKEN_NUMBER) { last_token_was_op = 0; if (var_stack_ptr == 3) { print_error_unexp(token, asm_context); return -1; } var_set_int(&var_stack[var_stack_ptr++], atoll(token)); } else if (token_type == TOKEN_FLOAT) { if (var_stack_ptr == 3) { print_error_unexp(token, asm_context); return -1; } var_set_float(&var_stack[var_stack_ptr++], atof(token)); } else if (token_type == TOKEN_SYMBOL) { last_token_was_op = 1; struct _operator operator_prev; memcpy(&operator_prev, &operator, sizeof(struct _operator)); if (get_operator(token, &operator) == -1) { print_error_unexp(token, asm_context); return -1; } // Issue 15: 2015-July-21 mkohn - If operator is ~ then reverse // the next number. if (operator.operation == OPER_NOT) { int64_t num; if (parse_unary(asm_context, &num, OPER_NOT) != 0) { return -1; } if (var_stack_ptr == 3) { print_error_unexp(token, asm_context); return -1; } var_set_int(&var_stack[var_stack_ptr++], num); memcpy(&operator, &operator_prev, sizeof(struct _operator)); last_token_was_op = 0; continue; } // Stack pointer probably shouldn't be less than 2 if (var_stack_ptr == 0) { printf("Error: Unexpected operator '%s' at %s:%d\n", token, asm_context->tokens.filename, asm_context->tokens.line); return -1; } #ifdef DEBUG printf("TOKEN %s: precedence %d %d\n", token, last_operator->precedence, operator.precedence); #endif if (last_operator->precedence == PREC_UNSET) { memcpy(last_operator, &operator, sizeof(struct _operator)); } else if (last_operator->precedence > operator.precedence) { if (eval_expression_go(asm_context, &var_stack[var_stack_ptr-1], &operator) == -1) { return -1; } } else { operate(&var_stack[var_stack_ptr-2], &var_stack[var_stack_ptr-1], last_operator); var_stack_ptr--; memcpy(last_operator, &operator, sizeof(struct _operator)); } } else { if (asm_context->pass != 1) { print_error_unexp(token, asm_context); } return -1; } } #ifdef DEBUG printf("going to leave operation=%d\n", last_operator->operation); PRINT_STACK() #endif if (last_operator->operation != OPER_UNSET) { operate(&var_stack[var_stack_ptr-2], &var_stack[var_stack_ptr-1], last_operator); var_stack_ptr--; } VAR_COPY(var, &var_stack[var_stack_ptr-1]); return 0; }
static bool parse_unary(ExprParseState *state) { int i; switch (state->token) { case '+': return parse_next_token(state) && parse_unary(state); case '-': CHECK_ERROR(parse_next_token(state) && parse_unary(state)); parse_add_func(state, OPCODE_FUNC1, 1, op_negate); return true; case '(': return parse_next_token(state) && parse_expr(state) && state->token == ')' && parse_next_token(state); case TOKEN_NUMBER: parse_add_op(state, OPCODE_CONST, 1)->arg.dval = state->tokenval; return parse_next_token(state); case TOKEN_ID: /* Parameters: search in reverse order in case of duplicate names - * the last one should win. */ for (i = state->param_names_len - 1; i >= 0; i--) { if (STREQ(state->tokenbuf, state->param_names[i])) { parse_add_op(state, OPCODE_PARAMETER, 1)->arg.ival = i; return parse_next_token(state); } } /* Ordinary builtin constants. */ for (i = 0; builtin_consts[i].name; i++) { if (STREQ(state->tokenbuf, builtin_consts[i].name)) { parse_add_op(state, OPCODE_CONST, 1)->arg.dval = builtin_consts[i].value; return parse_next_token(state); } } /* Ordinary builtin functions. */ for (i = 0; builtin_ops[i].name; i++) { if (STREQ(state->tokenbuf, builtin_ops[i].name)) { int args = parse_function_args(state); return parse_add_func(state, builtin_ops[i].op, args, builtin_ops[i].funcptr); } } /* Specially supported functions. */ if (STREQ(state->tokenbuf, "min")) { int cnt = parse_function_args(state); CHECK_ERROR(cnt > 0); parse_add_op(state, OPCODE_MIN, 1 - cnt)->arg.ival = cnt; return true; } if (STREQ(state->tokenbuf, "max")) { int cnt = parse_function_args(state); CHECK_ERROR(cnt > 0); parse_add_op(state, OPCODE_MAX, 1 - cnt)->arg.ival = cnt; return true; } return false; default: return false; } }