static struct ast_node* continue_expr(void *opaque) { struct ast_node_continue *continue_node; struct ast_node_stub *stub_node; struct scope_ctx helper; if (opaque == NULL) { error_msg("error: `continue' outside loop"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } helper = *(struct scope_ctx *)opaque; if (!helper.is_cycle) { error_msg("error: `continue' outside loop`"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } continue_node = ast_node_continue(); return AST_NODE(continue_node); }
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* break_expr(void *opaque) { struct ast_node_stub *stub_node; struct ast_node_break *break_node; struct scope_ctx *helper; if (opaque == NULL) { error_msg("error: `break' outside loop"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } helper = (struct scope_ctx *)opaque; if (!helper->is_cycle) { error_msg("error: `break' outside loop"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } break_node = ast_node_break(); return AST_NODE(break_node); }
static struct ast_node* process_scope(void *opaque) { struct ast_node *stmt; struct ast_node_stub *stub_node; struct scope_ctx *helper; if (opaque == NULL) { error_msg("error: unexpected symbol"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } helper = (struct scope_ctx *)opaque; if (!helper->is_cycle && !helper->is_cond) { error_msg("error: scope outside context"); stub_node = ast_node_stub(); return AST_NODE(stub_node); } stmt = stmts(opaque); return stmt; }
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 GtkTreePath * ast_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter) { GtkTreePath *path; AstNode *root = AST_NODE(tree_model); AstNode *node = AST_NODE(iter->user_data); path = gtk_tree_path_new(); while (node != root) { gtk_tree_path_prepend_index(path, node->index); node = node->parent; } return path; }
struct ast_node* process_function(void *opaque) { char *name; struct ast_node_stub *stub_node; if (!match(TOKEN_ID)) { error_msg("error: function name expected after `function'"); sync_stream(); goto exit; } name = ustrdup(lex_prev.id); if (current_token != TOKEN_LPARENTH) { error_msg("error: `(' expected"); sync_stream(); goto exit; } process_args(name); exit: stub_node = ast_node_stub(); return AST_NODE(stub_node); }
struct ast_node* token_id(char *name) { struct ast_node *node; struct symbol *sym; switch (current_token) { case TOKEN_LPARENTH : node = function_call(name); break; case TOKEN_LBRACKET: node = access_node(name); break; default: sym = symbol_table_lookup_all(name); if (sym == NULL) { sym = symbol_new(name, VALUE_TYPE_UNKNOWN); symbol_table_global_put_symbol(sym); } node = (struct ast_node *)ast_node_id(name); break; } return AST_NODE(node); }
static struct ast_node* end_scope_expr(void *opaque) { struct ast_node_stub *stub_node; struct ast_node_end_scope *scope_node; if (opaque == NULL) { error_msg("error: unexpected symbol"); stub_node = ast_node_stub(); return AST_NODE(stub_node); } scope_node = ast_node_end_scope(); return AST_NODE(scope_node); }
struct ast_node* process_return_node(void *opaque) { struct ast_node *ret_val; struct ast_node_return *_return; if (!opaque) { error_msg("error: return outside function"); sync_stream(); ret_val = (struct ast_node *)ast_node_stub(); return AST_NODE(ret_val); } ret_val = sum_expr(); _return = ast_node_return(ret_val); return AST_NODE(_return); }
static struct ast_node* rel_expr(void) { struct ast_node *left; struct ast_node *right; struct ast_node_op *op_node; opcode_type_t opcode; left = sum_expr(); if (left == NULL) return NULL; switch(current_token) { case TOKEN_EQ: consume_token(); opcode = OPCODE_EQ; break; case TOKEN_LT: consume_token(); opcode = OPCODE_LT; break; case TOKEN_GT: consume_token(); opcode = OPCODE_GT; break; case TOKEN_LE: consume_token(); opcode = OPCODE_LE; break; case TOKEN_GE: consume_token(); opcode = OPCODE_GE; break; case TOKEN_NE: consume_token(); opcode = OPCODE_NE; break; default: return left; } right = sum_expr(); if (right == NULL) { error_msg("error: expression expected"); right = (struct ast_node *)ast_node_stub(); sync_stream(); } op_node = ast_node_rel_op(opcode, left, right); return AST_NODE(op_node); }
struct ast_node* process_local_declaration(void *opaque) { struct scope_ctx helper; struct ast_node_stub *stub_node; struct symbol *var; if (opaque == NULL) { error_msg("error: `local' outside function"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } helper = *(struct scope_ctx *)opaque; if (!helper.is_func) { error_msg("error: `local' outside function"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } while (!match(TOKEN_EOL)) { if (match(TOKEN_ID)) { var = symbol_new(lex_prev.id, VALUE_TYPE_UNKNOWN); symbol_table_put_symbol(var); } if (current_token != TOKEN_EOL && !match(TOKEN_COMMA)) { error_msg("error: `,' expected after variable"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } } stub_node = ast_node_stub(); return AST_NODE(stub_node); }
static struct ast_node* unknown_expr(void *opaque) { struct ast_node_stub *node; error_msg("error: unknown expression"); sync_stream(); node = ast_node_stub(); return AST_NODE(node); }
static struct ast_node* term(void) { struct ast_node_const *_const; struct ast_node *node; if (match(TOKEN_ID)) { node = token_id(lex_prev.id); return node; } else if (match(TOKEN_DOUBLE)) { _const = ast_node_const(VALUE_TYPE_DIGIT, &lex_prev.real); return AST_NODE(_const); } else if (match(TOKEN_STRING)) { _const = ast_node_const(VALUE_TYPE_STRING, lex_prev.string); return AST_NODE(_const); } else if (match(TOKEN_LBRACKET)) { node = process_matrix(); return node; } return NULL; }
static void ast_return_do_print(AstNode *self, FILE *out, int indention) { assert(AST_IS_RETURN(self)); assert(out); fprintf(out, " return "); AstReturn *ret = (AstReturn *)self; if (ret->return_value != NULL) { ast_node_print(AST_NODE(ret->return_value), out, indention); } fprintf(out, "\n"); }
static gboolean ast_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path) { AstNode *node; gint *indices, depth; int i; node = AST_NODE(tree_model); indices = gtk_tree_path_get_indices(path); depth = gtk_tree_path_get_depth(path); for (i = 0; i < depth; i++) node = ast_nth_child(node, indices[i]); return ast_set_iter(iter, node); }
static struct ast_node* other_expr(void *opaque) { struct ast_node *node; struct ast_node_stub *stub_node; node = expr(); if (node == NULL) { if (current_token != TOKEN_EOL) { error_msg("error: unexpected symbol"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } } return 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* 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* 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); }
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); }