static struct s_apply *s_apply(struct symtab *tab, struct p_ex_fn *fn) { struct s_apply *app; app = malloc(sizeof(*app)); app->fn = s_expr(tab, fn->fn); app->nargs = 0; app->args = s_apply_args(tab, fn->args, &app->nargs); return app; }
static struct s_apply_args *s_apply_args(struct symtab *tab, struct p_ex_fn_args *p, int *nargs) { struct s_apply_args *s; if (p == NULL) return NULL; (*nargs)++; s = malloc(sizeof(*s)); s->ex = s_expr(tab, p->ex); s->next = s_apply_args(tab, p->next, nargs); return s; }
static struct s_fn_decl *s_fn_decl(struct p_fn_decl *p) { struct s_fn_decl *s; struct symtab *tab; tab = symtab_new(NULL); s = malloc(sizeof(*s)); s->name = p->name; s_arg_list(tab, s->name, p->args); s->body = s_expr(tab, p->body); symtab_free(tab); return s; }
void visit(Mod const* e) { std::cout << "(% "; s_expr(e->e1); s_expr(e->e2); std::cout << "\b)"; };
void visit(Div const* e) { std::cout << "(/ "; s_expr(e->e1); s_expr(e->e2); std::cout << "\b)"; };
void visit(Mul const* e) { std::cout << "(* "; s_expr(e->e1); s_expr(e->e2); std::cout << "\b)"; };
void visit(Sub const* e) { std::cout << "(- "; s_expr(e->e1); s_expr(e->e2); std::cout << "\b)"; };
void visit(Add const* e) { std::cout << "(+ "; s_expr(e->e1); s_expr(e->e2); std::cout << "\b)"; };
static struct s_expr *s_expr(struct symtab *tab, struct p_expr *p) { struct s_expr *ex, *s; int i, children; ex = malloc(sizeof(*ex)); children = 0; switch (p->type) { case T_ID: s = symtab_get(tab, p->id); if (s == NULL) { ex->type = S_EXPR_LABEL; ex->id = p->id; } else { free(ex); ex = s; } break; case T_INT: ex->type = S_EXPR_IMMEDIATE; ex->n = p->num; break; case T_FN: ex->type = S_EXPR_APPLICATION; ex->app = s_apply(tab, p->fn); break; case T_LBRACK: case T_NEG: children = 1; break; case T_ADD: case T_SUB: case T_MUL: case T_DIV: case T_MOD: case T_AND: case T_OR: case T_XOR: case T_EQ: case T_NE: case T_GT: case T_LT: case T_COMMA: children = 2; break; case T_QUES: children = 3; break; default: ice("unknown expression type `%s'", lx_names[p->type]); } if (children > 0) { ex->op = p->type; switch (children) { case 1: ex->type = S_EXPR_UNARY_OPERATION; break; case 2: ex->type = S_EXPR_BINARY_OPERATION; break; case 3: ex->type = S_EXPR_CONDITIONAL; break; default: ice("can't expression with %d children", children); } for (i=0; i<children; i++) ex->child[i] = s_expr(tab, p->child[i]); } return ex; }