static struct ast_node* if_expr(void *opaque) { struct ast_node_if *if_node; struct ast_node_stub *stub_node; struct ast_node *expr; struct ast_node *stmt_node; struct ast_node *_else; struct scope_ctx helper; if (!match(TOKEN_LPARENTH)) { error_msg("error: `(' expected after if"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } expr = or_expr(); if (expr == NULL) { error_msg("error: expression expected after `('"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } if (!match(TOKEN_RPARENTH)) { error_msg("error: `)' expected after exprssion"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } if (opaque == NULL) { memset(&helper, 0, sizeof(helper)); helper.is_cond++; } else { helper = *(struct scope_ctx *)opaque; helper.is_cond++; } stmt_node = stmt(&helper); if (stmt_node == NULL) { error_msg("error: statment expected after `)'"); stub_node = ast_node_stub(); return AST_NODE(stub_node); } _else = NULL; if (match(TOKEN_ELSE)) _else = stmt(&helper); if_node = ast_node_if(expr, stmt_node, _else); helper.is_cond--; return AST_NODE(if_node); }
static struct ast_node* while_expr(void *opaque) { struct ast_node_stub *stub_node; struct ast_node_while *while_node; struct ast_node *expr; struct ast_node *_stmt; struct scope_ctx helper; if (!match(TOKEN_LPARENTH)) { error_msg("errorr: `(' expected after while"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } expr = or_expr(); if (expr == NULL) { error_msg("error: NULL expression in while()"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } if (!match(TOKEN_RPARENTH)) { error_msg("error: `)' expected after while("); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } if (opaque) { helper = *(struct scope_ctx *)opaque; helper.is_cycle++; } else { memset(&helper, 0, sizeof(helper)); helper.is_cycle++; } _stmt = stmt(&helper); if (_stmt == NULL) { error_msg("error: statmet expected after while()"); stub_node = ast_node_stub(); return AST_NODE(stub_node); } while_node = ast_node_while(expr, _stmt); helper.is_cycle--; return AST_NODE(while_node); }
static struct ast_node* access_node(char *name) { struct ast_node_stub *stub_node; struct ast_node_access *ac_node; struct ast_node *idx; struct symbol *sym; sym = symbol_table_lookup_all(name); if (sym == NULL) { error_msg("error: no such symbol"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } /* `[' */ consume_token(); ac_node = ast_node_access(sym->v_type, sym->name); do { idx = or_expr(); if (idx == NULL) { error_msg("error: empty index"); sync_stream(); goto ac_error; } ast_node_access_add(ac_node, idx); if (current_token != TOKEN_RBRACKET) { error_msg("error: missed `]'"); sync_stream(); goto ac_error; } /* `]' */ consume_token(); } while (match(TOKEN_LBRACKET)); return AST_NODE(ac_node); ac_error: ast_node_unref(AST_NODE(ac_node)); stub_node = ast_node_stub(); return AST_NODE(stub_node); }
static struct ast_node* expr(void) { struct ast_node *lvalue; struct ast_node *rvalue; struct ast_node_assign *assign; lvalue = or_expr(); if (current_token != TOKEN_EQUALITY) return lvalue; /* `=' */ consume_token(); switch(lvalue->type) { case NODE_TYPE_ID: case NODE_TYPE_ACCESS: break; default: error_msg("error: rvalue assignmet"); sync_stream(); return lvalue; } rvalue = or_expr(); if (!rvalue) { error_msg("error: expression expected `='"); sync_stream(); rvalue = (struct ast_node *)ast_node_stub(); } assign = ast_node_assign(lvalue, rvalue); return AST_NODE(assign); }
static struct ast_node* term_expr(void) { struct ast_node *node; if (!match(TOKEN_LPARENTH)) return term(); node = or_expr(); if (!match(TOKEN_RPARENTH)) error_msg("error: missed `)'"); return node; }
int64_t expr() { int64_t val; nsym = 0; lastsym = (SYM*)NULL; if (token=='#') NextToken(); val = or_expr(); // We only care about the symbol if relocatable output is being generated. // Setting the symbol to NULL will result in no rel records being output. if (nsym > 1 || !rel_out) lastsym = (SYM *)NULL; return val; }
static struct ast_node* function_call(char *name) { struct function *func_ctx; struct ast_node_func_call *func_call; struct ast_node_stub *stub_node; struct ast_node *arg; int nargs = 0; func_ctx = function_table_lookup(name); consume_token(); if (func_ctx == NULL) { error_msg("unknown function"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } func_call = ast_node_func_call(func_ctx->name); while (!match(TOKEN_RPARENTH)) { if (match(TOKEN_EOL)) { error_msg("EOL in function call"); sync_stream(); goto free; } arg = or_expr(); if (arg == NULL) { error_msg("error: function argument expected"); sync_stream(); goto free; } nargs++; ast_node_func_call_add_arg(func_call, arg); if (current_token != TOKEN_RPARENTH && !match(TOKEN_COMMA)) { error_msg("error: missed comma"); sync_stream(); goto free; } } if (func_ctx->nargs != nargs) { error_msg("error: unmatched arguments count"); sync_stream(); goto free; } return AST_NODE(func_call); free: ast_node_unref(AST_NODE(func_call)); stub_node = ast_node_stub(); return AST_NODE(stub_node); }
static struct ast_node* process_matrix(void) { struct ast_node_stub *stub_node; struct ast_node **elem; struct ast_node *node; int row, col, len; int prev_col; int i; elem = NULL; node = NULL; row = col = 1; len = prev_col = 0; while (TRUE) { node = or_expr(); if (node == NULL) { error_msg("expr expected"); sync_stream(); goto err; } elem = urealloc(elem, ++len*sizeof(struct ast_node *)); elem[len - 1] = node; switch(current_token) { case TOKEN_COMMA: consume_token(); col++; continue; case TOKEN_SEMICOLON: consume_token(); if (prev_col == 0) prev_col = col; else if (prev_col != col) { error_msg("incompatible column count"); sync_stream(); goto err; } col = 1; row++; continue; case TOKEN_RBRACKET: consume_token(); break; default: error_msg("syntax error"); sync_stream(); goto err; } break; } if (row == 1 || col == 1) node = (struct ast_node *)ast_node_vector(elem, len); else node = (struct ast_node *) ast_node_matrix(elem, row, col); return node; err: if (node != NULL) ast_node_unref(node); if (elem != NULL) for (i = 0; i < len; i++) ast_node_unref(elem[i]); stub_node = ast_node_stub(); return AST_NODE(stub_node); }
static struct ast_node* for_expr(void *opaque) { struct ast_node_for *for_node; struct ast_node_stub *stub_node; struct ast_node *expr1; struct ast_node *expr2; struct ast_node *expr3; struct ast_node *_stmt; struct scope_ctx helper; if (!match(TOKEN_LPARENTH)) { error_msg("error: `(' expected after for"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } expr1 = expr(); if (!match(TOKEN_SEMICOLON)) { error_msg("error: `;' expected after for("); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } expr2 = or_expr(); if (!match(TOKEN_SEMICOLON)) { error_msg("error: `;' expected after for(;"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } expr3 = expr(); if (!match(TOKEN_RPARENTH)) { error_msg("error: `)' expected after for(;;"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } if (opaque) { helper = *(struct scope_ctx *)opaque; helper.is_cycle++; } else { memset(&helper, 0, sizeof(helper)); helper.is_cycle++; } _stmt = stmt(&helper); if (_stmt == NULL) { error_msg("error: stmt expected after for(;;)"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } for_node = ast_node_for(expr1, expr2, expr3, _stmt); helper.is_cycle--; return AST_NODE(for_node); }
void abstract_expression( const predicatest &predicates, exprt &expr, const namespacet &ns) { if(expr.type().id()!=ID_bool) throw "abstract_expression expects expression of type Boolean"; simplify(expr, ns); if(is_valid(expr, ns)) { // If expr is valid, we can abstract it as 'true' expr.make_true(); } else if(is_unsatisfiable(expr, ns)) { // If expr is unsatisfiable, we can abstract it as 'false' expr.make_false(); } else if(expr.id()==ID_and || expr.id()==ID_or || expr.id()==ID_implies || expr.id()==ID_xor) { Forall_operands(it, expr) abstract_expression(predicates, *it, ns); } else if(expr.id()==ID_not) { assert(expr.operands().size()==1); abstract_expression(predicates, expr.op0(), ns); // remove double negation if(expr.op0().id()==ID_not && expr.op0().operands().size()==1) { exprt tmp; tmp.swap(expr.op0().op0()); expr.swap(tmp); } } else if(expr.id()==ID_if) { assert(expr.operands().size()==3); Forall_operands(it, expr) abstract_expression(predicates, *it, ns); exprt true_expr(ID_and, bool_typet()); true_expr.copy_to_operands(expr.op0(), expr.op1()); exprt false_expr(ID_and, bool_typet()); false_expr.copy_to_operands(gen_not(expr.op0()), expr.op2()); exprt or_expr(ID_or, bool_typet()); or_expr.move_to_operands(true_expr, false_expr); expr.swap(or_expr); } else if(expr.id()==ID_equal || expr.id()==ID_notequal) { if(expr.operands().size()!=2) throw expr.id_string()+" takes two operands"; // Is it equality on Booleans? if(expr.op0().type().id()==ID_bool && expr.op1().type().id()==ID_bool) { // leave it in Forall_operands(it, expr) abstract_expression(predicates, *it, ns); } else // other types, make it a predicate { if(has_non_boolean_if(expr)) { lift_if(expr); abstract_expression(predicates, expr, ns); } else make_it_a_predicate(predicates, expr, ns); } } else if(expr.is_constant()) { // leave it as is } else if(has_non_boolean_if(expr)) { lift_if(expr); abstract_expression(predicates, expr, ns); } else { make_it_a_predicate(predicates, expr, ns); } }