diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2023-11-14 13:14:42 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2023-11-14 13:14:42 +0200 |
| commit | 294dd992f84f609e6ffcb58e49efb2ef1908e1a8 (patch) | |
| tree | 23aea55fb647443972765f1eca05d24c0db25ebf | |
| parent | b00da3db7c1d7f1e16b2e0446234dc42d54b8708 (diff) | |
| download | ek-294dd992f84f609e6ffcb58e49efb2ef1908e1a8.tar.gz ek-294dd992f84f609e6ffcb58e49efb2ef1908e1a8.zip | |
make memory tracking more dumb
| -rw-r--r-- | include/ek/ast.h | 34 | ||||
| -rw-r--r-- | src/actualize.c | 148 | ||||
| -rw-r--r-- | src/ast.c | 527 | ||||
| -rw-r--r-- | src/compiler.c | 1 | ||||
| -rw-r--r-- | src/debug.c | 3 | ||||
| -rw-r--r-- | src/lexer.l | 6 | ||||
| -rw-r--r-- | src/parser.y | 18 | ||||
| -rw-r--r-- | src/scope.c | 20 |
8 files changed, 124 insertions, 633 deletions
diff --git a/include/ek/ast.h b/include/ek/ast.h index 6b19f88..66acc08 100644 --- a/include/ek/ast.h +++ b/include/ek/ast.h @@ -207,12 +207,10 @@ enum ast_ctrl_kind { /** Constant value kind. */ enum ast_const_kind { - /** Integer, u64 */ + /** Integer, i27 */ AST_CONST_INTEGER, /** String. */ AST_CONST_STRING, - /** Float, f64. */ - AST_CONST_FLOAT, }; /** Type representation. */ @@ -527,6 +525,10 @@ struct ast_return { struct ast_node *defers; }; +enum ast_primitive { + AST_VOID, AST_I9, AST_I27 +}; + /** * Type. * I'm not entirely happy with the current type system, for one @@ -555,7 +557,7 @@ struct ast_type { } _id; struct { - struct ast_node *id; + enum ast_primitive type; } _primitive; /** Array type. */ @@ -956,7 +958,7 @@ struct ast_node *gen_ctrl(enum ast_ctrl_kind kind, struct src_loc loc); struct ast_node *gen_macro_construct(struct ast_node *id, struct ast_node *params, struct ast_node *body); -struct ast_node *gen_macro_expand(struct ast_node *id, struct ast_node *args); +struct ast_node *gen_macro_expand(struct ast_node *id, struct ast_node *args, struct src_loc loc); struct ast_node *gen_type_construct(struct ast_node *id, struct ast_node *params, @@ -998,8 +1000,9 @@ struct ast_node *gen_switch(struct ast_node *cond, struct ast_node *cases); */ struct ast_node *gen_case(struct ast_node *expr, struct ast_node *body); +struct ast_node *gen_primitive(enum ast_primitive type, struct src_loc loc); /** - * Generate Ek type. + * Generate Ek type (besides primitive). * * @param kind Type kind. * @param id Name of type. @@ -1211,22 +1214,6 @@ int identical_ast_nodes(int exact, struct ast_node *left, struct ast_node *right); /** - * Destroy AST node. - * Frees members of AST node as well, but not \c next nodes. - * - * @param node AST node to destroy. - */ -void destroy_ast_node(struct ast_node *node); - -/** - * Destroy AST tree. - * Frees members and \c next nodes. - * - * @param root AST tree to destroy. - */ -void destroy_ast_tree(struct ast_node *root); - -/** * Dump textual representation of AST to stdout. * * @param depth How many spaces to prepend. @@ -1303,4 +1290,7 @@ struct ast_node *ast_last_node(struct ast_node *list); */ struct ast_node *ast_block_last(struct ast_node *block); +void destroy_ast_nodes(); +const char *primitive_str(enum ast_primitive type); + #endif /* AST_H */ diff --git a/src/actualize.c b/src/actualize.c index 932fc7a..cc7d117 100644 --- a/src/actualize.c +++ b/src/actualize.c @@ -59,67 +59,23 @@ static int is_void(struct ast_node *type) if (AST_TYPE(type).kind != AST_TYPE_PRIMITIVE) return 0; - struct ast_node *id = AST_PRIMITIVE_TYPE(type).id; - if (strcmp(id->_id.id, "void") != 0) - return 0; - - return 1; + return AST_PRIMITIVE_TYPE(type).type == AST_VOID; } static struct ast_node *void_type() { - char *void_str = strdup("void"); - if (!void_str) { - internal_error("couldn't allocate void string"); - return NULL; - } - - struct ast_node *void_id = gen_id(void_str, NULL_LOC()); - if (!void_id) { - internal_error("couldn't allocate void id"); - free(void_str); - return NULL; - } - - struct ast_node *void_type = gen_type(AST_TYPE_PRIMITIVE, void_id, NULL, NULL); - if (!void_type) { - internal_error("couldn't allocate void type"); - destroy_ast_node(void_id); - return NULL; - } - - ast_set_flags(void_type, AST_FLAG_ACTUAL); - - void_type->type = void_type; - return void_type; + struct ast_node *v = gen_primitive(AST_VOID, NULL_LOC()); + ast_set_flags(v, AST_FLAG_ACTUAL); + v->type = v; + return v; } static struct ast_node *i27_type() { - char *i27_str = strdup("i27"); - if (!i27_str) { - internal_error("couldn't allocate i27 string"); - return NULL; - } - - struct ast_node *i27_id = gen_id(i27_str, NULL_LOC()); - if (!i27_id) { - internal_error("couldn't allocate i27 id"); - free(i27_str); - return NULL; - } - - struct ast_node *i27_type = gen_type(AST_TYPE_PRIMITIVE, i27_id, NULL, NULL); - if (!i27_type) { - internal_error("couldn't allocate i27 type"); - destroy_ast_node(i27_id); - return NULL; - } - - ast_set_flags(i27_type, AST_FLAG_ACTUAL); - - i27_type->type = i27_type; - return i27_type; + struct ast_node *a = gen_primitive(AST_I27, NULL_LOC()); + ast_set_flags(a, AST_FLAG_ACTUAL); + a->type = a; + return a; } static int push_defer(struct act_state *state, struct ast_node *expr) @@ -263,8 +219,6 @@ static int eval_const_if(struct scope *scope, struct ast_node *node) return -1; } - destroy_ast_tree(cond); - if (eval) { /* condition evaluated true, so keep the if block */ struct ast_node *body = node->_if.body; @@ -273,15 +227,11 @@ static int eval_const_if(struct scope *scope, struct ast_node *node) /* an if must have a body, otherwise the parser messed up */ assert(body); - destroy_ast_tree(node->_if.els); - *node = *body; free(body); return 0; } - destroy_ast_tree(node->_if.body); - struct ast_node *els = node->_if.els; if (els) { *node = *els; @@ -327,7 +277,6 @@ static int analyze_file_visibility(struct scope *scope, struct ast_node *node) const char *file = AST_IMPORT(node).file; ret |= process_file(&scope, ast_flags(node, AST_FLAG_PUBLIC), file); - destroy_ast_tree(node); break; } @@ -379,7 +328,6 @@ static int analyze_file_visibility(struct scope *scope, struct ast_node *node) } case AST_EMPTY: { - destroy_ast_tree(node); break; } @@ -433,10 +381,10 @@ static int structs_match(struct ast_node *a, struct ast_node *b) static int primitives_match(struct ast_node *a, struct ast_node *b) { - struct ast_node *a_id = AST_PRIMITIVE_TYPE(a).id; - struct ast_node *b_id = AST_PRIMITIVE_TYPE(b).id; + enum ast_primitive at = AST_PRIMITIVE_TYPE(a).type; + enum ast_primitive bt = AST_PRIMITIVE_TYPE(b).type; - return strcmp(AST_ID(a_id).id, AST_ID(b_id).id) == 0; + return at == bt; } int types_match(struct ast_node *a, struct ast_node *b) @@ -657,7 +605,6 @@ static int actualize_macro_call(struct act_state *state, if (replace_id(body, param, arg)) { semantic_error(scope->fctx, call, "failed replacing params with args"); - destroy_ast_tree(body); arg->next = next_arg; return -1; } @@ -671,12 +618,9 @@ static int actualize_macro_call(struct act_state *state, if (param || arg) { /* TODO: internal error more like */ semantic_error(scope->fctx, call, "uneven number of arguments"); - destroy_ast_tree(body); return -1; } - destroy_ast_tree(call->_call.id); - destroy_ast_tree(call->_call.args); *call = *body; free(body); /* actualize the new content */ @@ -777,7 +721,6 @@ static int actualize_proc(struct act_state *state, if (!act_flags(state, ACT_ONLY_TYPES)) { ret = scope_add_actual(scope, actual); if (ret) { - destroy_ast_tree(actual); return ret; } } @@ -824,8 +767,6 @@ static int actualize_proc(struct act_state *state, if (undefined_gotos(&new_state, scope)) ret = -1; - destroy_act_state(&new_state); - /* TODO: should ret be checked between each stage? */ if (ret) return ret; @@ -1067,7 +1008,6 @@ static int actualize_type(struct act_state *state, EXIT_ACT(-1); assert(AST_TYPE(type).next == NULL); - destroy_ast_node(AST_ID_TYPE(type).id); if (exists->node_type == AST_ALIAS) { AST_TYPE(type).aliased = exists; AST_TYPE(type) = AST_TYPE(exists); @@ -1176,43 +1116,12 @@ static int integral_type(struct ast_node *type) return 0; /* here would be awesome with an enum of our base types */ - struct ast_node *primitive = AST_PRIMITIVE_TYPE(type).id; - const char *type_str = AST_ID(primitive).id; - if (strcmp(type_str, "u8")) - return 1; - - if (strcmp(type_str, "u16")) - return 1; - - if (strcmp(type_str, "u32")) - return 1; - - if (strcmp(type_str, "u64")) - return 1; - - if (strcmp(type_str, "i8")) - return 1; - - if (strcmp(type_str, "i16")) - return 1; - - if (strcmp(type_str, "i32")) - return 1; - - if (strcmp(type_str, "i64")) - return 1; - - if (strcmp(type_str, "usize")) - return 1; - - if (strcmp(type_str, "isize")) - return 1; - - if (strcmp(type_str, "f32")) - return 1; - - if (strcmp(type_str, "f64")) - return 1; + enum ast_primitive p = AST_PRIMITIVE_TYPE(type).type; + switch (p) { + case AST_I9: return 1; + case AST_I27: return 1; + default: return 0; + } return 0; } @@ -1660,7 +1569,6 @@ static void actualize_goto_defer(struct ast_node *got, struct ast_node *label) /* fuck, I actually need the one previous to this */ assert(prev_defer->next == goto_defers); prev_defer->next = NULL; - destroy_ast_node(goto_defers); } /* nothing to do */ @@ -2069,26 +1977,6 @@ void replace_type(struct ast_node *type, struct ast_node *from, if (types_match(type, from)) { assert(type->_type.next == NULL); struct ast_node *clone = clone_ast_node(to); - /* TODO: unsure if this is everything */ - switch (type->_type.kind) { - case AST_TYPE_ID: - destroy_ast_node(AST_ID_TYPE(type).id); - break; - - case AST_TYPE_STRUCT: - destroy_ast_node(AST_STRUCT_TYPE(type).def); - break; - - case AST_TYPE_ENUM: - destroy_ast_node(AST_ENUM_TYPE(type).def); - break; - - case AST_TYPE_TYPEOF: - destroy_ast_node(AST_TYPEOF_TYPE(type).expr); - break; - - default: - } *type = *clone; free(clone); return; @@ -17,10 +17,60 @@ #include <ek/ast.h> #include <ek/scope.h> +static struct { + size_t n; + size_t s; + struct ast_node **v; +} ast_nodes = {0}; + +static void destroy_ast_node(struct ast_node *node) +{ + if (!node) + return; + + switch (node->node_type) { + case AST_ID: free((void *)AST_ID(node).id); break; + case AST_CONST: + if (AST_CONST(node).kind == AST_CONST_STRING) + free((void *)AST_CONST(node).str); + break; + default: + } + + free(node); +} + +void destroy_ast_nodes() +{ + for (size_t i = 0; i < ast_nodes.n; ++i) + destroy_ast_node(ast_nodes.v[i]); + + free(ast_nodes.v); +} + +/* eventually we might want to pass in a context or something */ +static struct ast_node *create_ast_node() +{ + if (ast_nodes.s == 0) { + ast_nodes.s = 1; + ast_nodes.n = 0; + ast_nodes.v = calloc(1, sizeof(struct ast_node *)); + } + + else if (ast_nodes.n >= ast_nodes.s) { + ast_nodes.s *= 2; + ast_nodes.v = realloc(ast_nodes.v, ast_nodes.s * sizeof(struct ast_node *)); + } + + struct ast_node *n = calloc(1, sizeof(struct ast_node)); + ast_nodes.v[ast_nodes.n++] = n; + return n; +} + /** @todo alloc should maybe also keep track of all nodes in a vector or * something and mass free all AST at a time to keep my sanity */ #define ALLOC_NODE(n, type) \ - struct ast_node *n = calloc(1, sizeof(struct ast_node)); \ + struct ast_node *n = create_ast_node(); \ if (!n) { \ fprintf(stderr, "failed allocating" type "\n"); \ return NULL; \ @@ -46,32 +96,16 @@ struct ast_node *gen_arr_access(struct ast_node *base, struct ast_node *idx, str return n; } -void destroy_arr_access(struct ast_node *arr_access) -{ - assert(arr_access->node_type == AST_ARR_ACCESS); - destroy_ast_node(AST_ARR_ACCESS(arr_access).base); - destroy_ast_node(AST_ARR_ACCESS(arr_access).idx); - free(arr_access); -} - -struct ast_node *gen_macro_expand(struct ast_node *id, struct ast_node *args) +struct ast_node *gen_macro_expand(struct ast_node *id, struct ast_node *args, struct src_loc loc) { ALLOC_NODE(n, "macro_expand"); n->node_type = AST_MACRO_EXPAND; - n->_macro_expand.id = id; - n->_macro_expand.args = args; - n->loc = id->loc; + AST_MACRO_EXPAND(n).id = id; + AST_MACRO_EXPAND(n).args = args; + n->loc = loc; return n; } -void destroy_macro_expand(struct ast_node *n) -{ - assert(n->node_type == AST_MACRO_EXPAND); - destroy_ast_node(n->_macro_expand.id); - destroy_ast_node(n->_macro_expand.args); - free(n); -} - struct ast_node *gen_type_construct(struct ast_node *id, struct ast_node *params, struct ast_node *body, @@ -86,14 +120,6 @@ struct ast_node *gen_type_construct(struct ast_node *id, return n; } -void destroy_type_construct(struct ast_node *type_construct) -{ - destroy_ast_node(AST_TYPE_CONSTRUCT(type_construct).id); - destroy_ast_node(AST_TYPE_CONSTRUCT(type_construct).params); - destroy_ast_node(AST_TYPE_CONSTRUCT(type_construct).body); - free(type_construct); -} - struct ast_node *gen_type_expand(struct ast_node *id, struct ast_node *args, struct src_loc loc) @@ -106,15 +132,6 @@ struct ast_node *gen_type_expand(struct ast_node *id, return n; } -void destroy_type_expand(struct ast_node *n) -{ - assert(n->node_type == AST_TYPE_EXPAND); - destroy_ast_node(AST_TYPE_EXPAND(n).id); - destroy_ast_node(AST_TYPE_EXPAND(n).args); - free(n); -} - - struct ast_node *gen_binop(enum ast_binops op, struct ast_node *left, struct ast_node *right, @@ -129,14 +146,6 @@ struct ast_node *gen_binop(enum ast_binops op, return n; } -void destroy_binop(struct ast_node *binop) -{ - assert(binop->node_type == AST_BINOP); - destroy_ast_node(binop->binop.left); - destroy_ast_node(binop->binop.right); - free(binop); -} - struct ast_node *gen_unop(enum ast_unops op, struct ast_node *expr) { ALLOC_NODE(n, "unop"); @@ -147,13 +156,6 @@ struct ast_node *gen_unop(enum ast_unops op, struct ast_node *expr) return n; } -void destroy_unop(struct ast_node *unop) -{ - assert(unop->node_type == AST_UNOP); - destroy_ast_node(unop->_unop.expr); - free(unop); -} - struct ast_node *gen_call(struct ast_node *id, struct ast_node *args) { ALLOC_NODE(n, "call"); @@ -164,14 +166,6 @@ struct ast_node *gen_call(struct ast_node *id, struct ast_node *args) return n; } -void destroy_call(struct ast_node *call) -{ - assert(call->node_type == AST_CALL); - destroy_ast_node(call->_call.id); - DESTROY_LIST(call->_call.args); - free(call); -} - struct ast_node *gen_id(const char *id, struct src_loc loc) { ALLOC_NODE(n, "id"); @@ -181,13 +175,6 @@ struct ast_node *gen_id(const char *id, struct src_loc loc) return n; } -void destroy_id(struct ast_node *id) -{ - assert(id->node_type == AST_ID); - free((void *)id->_id.id); - free(id); -} - struct ast_node *gen_assign(struct ast_node *to, struct ast_node *from) { ALLOC_NODE(n, "assign"); @@ -197,14 +184,6 @@ struct ast_node *gen_assign(struct ast_node *to, struct ast_node *from) return n; } -static void destroy_assign(struct ast_node *assign) -{ - assert(assign->node_type == AST_ASSIGN); - destroy_ast_node(assign->_assign.to); - destroy_ast_node(assign->_assign.from); - free(assign); -} - struct ast_node *gen_init(struct ast_node *body) { ALLOC_NODE(n, "struct init"); @@ -214,13 +193,6 @@ struct ast_node *gen_init(struct ast_node *body) return n; } -static void destroy_init(struct ast_node *init) -{ - assert(init->node_type == AST_INIT); - DESTROY_LIST(init->_init.body); - free(init); -} - struct ast_node *gen_int(long long integer) { ALLOC_NODE(n, "int"); @@ -239,24 +211,6 @@ struct ast_node *gen_string(const char *str) return n; } -struct ast_node *gen_float(double dbl) -{ - ALLOC_NODE(n, "float"); - n->node_type = AST_CONST; - n->_const.kind = AST_CONST_FLOAT; - n->_const.dbl = dbl; - return n; -} - -void destroy_const(struct ast_node *cons) -{ - assert(cons->node_type == AST_CONST); - if (cons->_const.kind == AST_CONST_STRING) - free((void *)cons->_const.str); - - free(cons); -} - struct ast_node *gen_while(struct ast_node *cond, struct ast_node *body) { ALLOC_NODE(n, "while"); @@ -266,14 +220,6 @@ struct ast_node *gen_while(struct ast_node *cond, struct ast_node *body) return n; } -void destroy_while(struct ast_node *whil) -{ - assert(whil->node_type == AST_WHILE); - destroy_ast_node(whil->_while.cond); - DESTROY_LIST(whil->_while.body); - free(whil); -} - struct ast_node *gen_for(struct ast_node *pre, struct ast_node *cond, struct ast_node *post, struct ast_node *body) { @@ -286,16 +232,6 @@ struct ast_node *gen_for(struct ast_node *pre, struct ast_node *cond, return n; } -void destroy_for(struct ast_node *fo) -{ - assert(fo->node_type == AST_FOR); - destroy_ast_node(fo->_for.pre); - destroy_ast_node(fo->_for.cond); - destroy_ast_node(fo->_for.post); - DESTROY_LIST(fo->_for.body); - free(fo); -} - struct ast_node *gen_return(struct ast_node *expr) { ALLOC_NODE(n, "return"); @@ -306,14 +242,6 @@ struct ast_node *gen_return(struct ast_node *expr) return n; } -void destroy_return(struct ast_node *retur) -{ - assert(retur->node_type == AST_RETURN); - destroy_ast_node(retur->_return.expr); - DESTROY_LIST(retur->_return.defers); - free(retur); -} - struct ast_node *gen_goto(struct ast_node *label) { ALLOC_NODE(n, "goto"); @@ -323,13 +251,6 @@ struct ast_node *gen_goto(struct ast_node *label) return n; } -void destroy_goto(struct ast_node *got) -{ - assert(got->node_type == AST_GOTO); - destroy_ast_node(got->_goto.label); - free(got); -} - struct ast_node *gen_dot(struct ast_node *expr, struct ast_node *id) { ALLOC_NODE(n, "dot"); @@ -339,14 +260,6 @@ struct ast_node *gen_dot(struct ast_node *expr, struct ast_node *id) return n; } -void destroy_dot(struct ast_node *dot) -{ - assert(dot->node_type == AST_DOT); - destroy_ast_node(dot->_dot.expr); - destroy_ast_node(dot->_dot.id); - free(dot); -} - struct ast_node *gen_label(struct ast_node *id) { ALLOC_NODE(n, "label"); @@ -356,13 +269,6 @@ struct ast_node *gen_label(struct ast_node *id) return n; } -void destroy_label(struct ast_node *label) -{ - assert(label->node_type == AST_LABEL); - destroy_ast_node(label->_label.id); - free(label); -} - struct ast_node *gen_ctrl(enum ast_ctrl_kind kind, struct src_loc loc) { ALLOC_NODE(n, "ctrl"); @@ -372,11 +278,6 @@ struct ast_node *gen_ctrl(enum ast_ctrl_kind kind, struct src_loc loc) return n; } -void destroy_ctrl(struct ast_node *ctrl) -{ - free(ctrl); -} - struct ast_node *gen_fetch(struct ast_node *id, struct ast_node *type) { ALLOC_NODE(n, "fetch"); @@ -387,14 +288,6 @@ struct ast_node *gen_fetch(struct ast_node *id, struct ast_node *type) return n; } -static void destroy_fetch(struct ast_node *fetch) -{ - assert(fetch->node_type == AST_FETCH); - destroy_ast_node(fetch->_fetch.id); - destroy_ast_node(fetch->_fetch.type); - free(fetch); -} - struct ast_node *gen_macro_construct(struct ast_node *id, struct ast_node *params, struct ast_node *body) @@ -408,15 +301,6 @@ struct ast_node *gen_macro_construct(struct ast_node *id, return n; } -void destroy_macro_construct(struct ast_node *macro) -{ - assert(macro->node_type == AST_MACRO_CONSTRUCT); - destroy_ast_node(AST_MACRO_CONSTRUCT(macro).id); - DESTROY_LIST(AST_MACRO_CONSTRUCT(macro).params); - DESTROY_LIST(AST_MACRO_CONSTRUCT(macro).body); - free(macro); -} - struct ast_node *gen_if(struct ast_node *cond, struct ast_node *body, struct ast_node *els) { @@ -428,15 +312,6 @@ struct ast_node *gen_if(struct ast_node *cond, struct ast_node *body, return n; } -void destroy_if(struct ast_node *i) -{ - assert(i->node_type == AST_IF); - destroy_ast_node(i->_if.cond); - DESTROY_LIST(i->_if.body); - destroy_ast_node(i->_if.els); - free(i); -} - struct ast_node *gen_switch(struct ast_node *cond, struct ast_node *cases) { ALLOC_NODE(n, "switch"); @@ -447,14 +322,6 @@ struct ast_node *gen_switch(struct ast_node *cond, struct ast_node *cases) return n; } -void destroy_switch(struct ast_node *switc) -{ - assert(switc->node_type == AST_SWITCH); - destroy_ast_node(switc->_switch.cond); - DESTROY_LIST(switc->_switch.cases); - free(switc); -} - struct ast_node *gen_case(struct ast_node *cond, struct ast_node *body) { ALLOC_NODE(n, "case"); @@ -469,12 +336,14 @@ struct ast_node *gen_case(struct ast_node *cond, struct ast_node *body) return n; } -void destroy_case(struct ast_node *cas) +struct ast_node *gen_primitive(enum ast_primitive type, struct src_loc loc) { - assert(cas->node_type == AST_CASE); - destroy_ast_node(cas->_case.cond); - DESTROY_LIST(cas->_case.body); - free(cas); + ALLOC_NODE(n, "primitive"); + n->node_type = AST_TYPE; + AST_TYPE(n).kind = AST_TYPE_PRIMITIVE; + AST_PRIMITIVE_TYPE(n).type = type; + n->loc = loc; + return n; } struct ast_node *gen_type(enum ast_type_kind kind, @@ -486,10 +355,6 @@ struct ast_node *gen_type(enum ast_type_kind kind, n->node_type = AST_TYPE; AST_TYPE(n).kind = kind; switch (kind) { - case AST_TYPE_PRIMITIVE: - AST_PRIMITIVE_TYPE(n).id = t0; - break; - case AST_TYPE_TRAIT: AST_TRAIT_TYPE(n).def = t0; break; @@ -523,55 +388,11 @@ struct ast_node *gen_type(enum ast_type_kind kind, AST_SIGN_TYPE(n).params = t0; AST_SIGN_TYPE(n).ret = t1; break; - } - - return n; -} - -void destroy_type(struct ast_node *type) -{ - assert(type->node_type == AST_TYPE); - switch (type->_type.kind) { - case AST_TYPE_PRIMITIVE: - destroy_ast_node(AST_PRIMITIVE_TYPE(type).id); - break; - - case AST_TYPE_TRAIT: - break; - - case AST_TYPE_ID: - destroy_ast_node(AST_ID_TYPE(type).id); - break; - - case AST_TYPE_ARR: - destroy_ast_node(AST_ARR_TYPE(type).size); - destroy_ast_node(AST_ARR_TYPE(type).base); - break; - - case AST_TYPE_TYPEOF: - destroy_ast_node(AST_TYPEOF_TYPE(type).expr); - break; - - case AST_TYPE_POINTER: - destroy_ast_node(AST_PTR_TYPE(type).base); - break; - - case AST_TYPE_STRUCT: - destroy_ast_node(AST_STRUCT_TYPE(type).def); - break; - - case AST_TYPE_ENUM: - destroy_ast_node(AST_ENUM_TYPE(type).def); - break; - case AST_TYPE_SIGN: - DESTROY_LIST(AST_SIGN_TYPE(type).params); - destroy_ast_node(AST_SIGN_TYPE(type).ret); - break; + default: abort(); } - destroy_ast_node(AST_TYPE(type).next); - free(type); + return n; } struct ast_node *gen_block(struct ast_node *body) @@ -582,14 +403,6 @@ struct ast_node *gen_block(struct ast_node *body) return n; } -void destroy_block(struct ast_node *block) -{ - assert(block->node_type == AST_BLOCK); - DESTROY_LIST(block->_block.body); - DESTROY_LIST(block->_block.defers); - free(block); -} - struct ast_node *gen_sizeof(struct ast_node *expr) { ALLOC_NODE(n, "sizeof"); @@ -599,12 +412,6 @@ struct ast_node *gen_sizeof(struct ast_node *expr) return n; } -void destroy_sizeof(struct ast_node *sizeo) -{ - assert(sizeo->node_type == AST_SIZEOF); - destroy_ast_node(sizeo->_sizeof.expr); - free(sizeo); -} struct ast_node *gen_as(struct ast_node *type) { ALLOC_NODE(n, "as"); @@ -614,13 +421,6 @@ struct ast_node *gen_as(struct ast_node *type) return n; } -void destroy_as(struct ast_node *as) -{ - assert(as->node_type == AST_AS); - destroy_ast_node(as->_as.type); - free(as); -} - struct ast_node *gen_defer(struct ast_node *expr) { ALLOC_NODE(n, "defer"); @@ -652,15 +452,6 @@ struct ast_node *gen_var(struct ast_node *id, struct ast_node *type, return n; } -void destroy_var(struct ast_node *var) -{ - assert(var->node_type == AST_VAR); - destroy_ast_node(var->_var.id); - destroy_ast_node(var->_var.type); - destroy_ast_node(var->_var.init); - free(var); -} - struct ast_node *gen_proc(struct ast_node *id, struct ast_node *sign, struct ast_node *body) { @@ -673,15 +464,6 @@ struct ast_node *gen_proc(struct ast_node *id, struct ast_node *sign, return n; } -void destroy_proc(struct ast_node *proc) -{ - assert(proc->node_type == AST_PROC); - destroy_ast_node(proc->_proc.id); - DESTROY_LIST(proc->_proc.sign); - DESTROY_LIST(proc->_proc.body); - free(proc); -} - struct ast_node *gen_struct(struct ast_node *id, struct ast_node *generics, struct ast_node *body) { @@ -697,15 +479,6 @@ struct ast_node *gen_struct(struct ast_node *id, return n; } -void destroy_struct(struct ast_node *struc) -{ - assert(struc->node_type == AST_STRUCT); - destroy_ast_node(struc->_struct.id); - DESTROY_LIST(struc->_struct.generics); - DESTROY_LIST(struc->_struct.body); - free(struc); -} - struct ast_node *gen_enum(struct ast_node *id, struct ast_node *type, struct ast_node *body) { @@ -719,15 +492,6 @@ struct ast_node *gen_enum(struct ast_node *id, struct ast_node *type, return n; } -void destroy_enum(struct ast_node *enu) -{ - assert(enu->node_type == AST_ENUM); - destroy_ast_node(enu->_enum.id); - destroy_ast_node(enu->_enum.type); - DESTROY_LIST(enu->_enum.body); - free(enu); -} - struct ast_node *gen_cast(struct ast_node *expr, struct ast_node *type) { ALLOC_NODE(n, "cast"); @@ -737,14 +501,6 @@ struct ast_node *gen_cast(struct ast_node *expr, struct ast_node *type) return n; } -void destroy_cast(struct ast_node *cast) -{ - assert(cast->node_type == AST_CAST); - destroy_ast_node(cast->_cast.expr); - destroy_ast_node(cast->_cast.type); - free(cast); -} - struct ast_node *gen_val(struct ast_node *id, struct ast_node *val) { ALLOC_NODE(n, "val"); @@ -755,14 +511,6 @@ struct ast_node *gen_val(struct ast_node *id, struct ast_node *val) return n; } -void destroy_val(struct ast_node *val) -{ - assert(val->node_type == AST_VAL); - destroy_ast_node(val->_val.id); - destroy_ast_node(val->_val.val); - free(val); -} - struct ast_node *gen_alias(struct ast_node *id, struct ast_node *type) { ALLOC_NODE(n, "alias"); @@ -773,14 +521,6 @@ struct ast_node *gen_alias(struct ast_node *id, struct ast_node *type) return n; } -void destroy_alias(struct ast_node *alias) -{ - assert(alias->node_type == AST_ALIAS); - destroy_ast_node(alias->_alias.id); - destroy_ast_node(alias->_alias.type); - free(alias); -} - struct ast_node *gen_trait(struct ast_node *id, struct ast_node *body) { ALLOC_NODE(n, "trait"); @@ -791,21 +531,6 @@ struct ast_node *gen_trait(struct ast_node *id, struct ast_node *body) return n; } -void destroy_trait(struct ast_node *trait) -{ - assert(trait->node_type == AST_TRAIT); - destroy_ast_node(trait->_trait.id); - DESTROY_LIST(trait->_trait.body); - - struct trait_implemented *prev = trait->_trait.impl_by, *cur; - if (prev) - do { - cur = prev->next; - free(prev); - } while ((prev = cur)); - free(trait); -} - struct ast_node *gen_import(const char *file) { ALLOC_NODE(n, "import"); @@ -815,13 +540,6 @@ struct ast_node *gen_import(const char *file) return n; } -void destroy_import(struct ast_node *import) -{ - assert(import->node_type == AST_IMPORT); - free((void *)import->_import.file); - free(import); -} - struct ast_node *gen_embed(const char *file) { ALLOC_NODE(n, "embed"); @@ -831,13 +549,6 @@ struct ast_node *gen_embed(const char *file) return n; } -void destroy_embed(struct ast_node *embed) -{ - assert(embed->node_type == AST_EMBED); - free((void *)embed->_embed.file); - free(embed); -} - struct ast_node *gen_empty() { ALLOC_NODE(n, "empty"); @@ -846,67 +557,6 @@ struct ast_node *gen_empty() return n; } -void destroy_empty(struct ast_node *empty) -{ - assert(empty->node_type == AST_EMPTY); - free(empty); -} - -void destroy_ast_node(struct ast_node *node) -{ - if (!node) - return; - - assert(node->node_type); - - switch (node->node_type) { - case AST_TYPE_EXPAND: destroy_type_expand(node); break; - case AST_TYPE_CONSTRUCT: destroy_type_construct(node); break; - case AST_FETCH: destroy_fetch(node); break; - case AST_ASSIGN: destroy_assign(node); break; - case AST_INIT: destroy_init(node); break; - case AST_SIZEOF: destroy_sizeof(node); break; - case AST_DOT: destroy_dot(node); break; - case AST_BINOP: destroy_binop(node); break; - case AST_UNOP: destroy_unop(node); break; - case AST_CALL: destroy_call(node); break; - case AST_CAST: destroy_cast(node); break; - case AST_MACRO_CONSTRUCT: destroy_macro_construct(node); break; - case AST_MACRO_EXPAND: destroy_macro_expand(node); break; - case AST_PROC: destroy_proc(node); break; - case AST_GOTO: destroy_goto(node); break; - case AST_LABEL: destroy_label(node); break; - case AST_VAR: destroy_var(node); break; - case AST_IF: destroy_if(node); break; - case AST_FOR: destroy_for(node); break; - case AST_WHILE: destroy_while(node); break; - case AST_CTRL: destroy_ctrl(node); break; - case AST_RETURN: destroy_return(node); break; - case AST_TYPE: destroy_type(node); break; - case AST_BLOCK: destroy_block(node); break; - case AST_IMPORT: destroy_import(node); break; - case AST_DEFER: destroy_defer(node); break; - case AST_EMBED: destroy_embed(node); break; - case AST_ENUM: destroy_enum(node); break; - case AST_STRUCT: destroy_struct(node); break; - case AST_VAL: destroy_val(node); break; - case AST_SWITCH: destroy_switch(node); break; - case AST_CASE: destroy_case(node); break; - case AST_CONST: destroy_const(node); break; - case AST_ALIAS: destroy_alias(node); break; - case AST_TRAIT: destroy_trait(node); break; - case AST_ID: destroy_id(node); break; - case AST_AS: destroy_as(node); break; - case AST_EMPTY: destroy_empty(node); break; - case AST_ARR_ACCESS: destroy_arr_access(node); break; - } -} - -void destroy_ast_tree(struct ast_node *root) -{ - DESTROY_LIST(root); -} - void ast_set_flags(struct ast_node *node, enum ast_flag flags) { node->flags |= flags; @@ -1012,6 +662,18 @@ static void dump_flags(struct ast_node *node) printf(" FALLTHROUGH"); } +const char *primitive_str(enum ast_primitive type) +{ + switch (type) { + case AST_VOID: return "void"; + case AST_I9: return "i9"; + case AST_I27: return "i27"; + default: return "unimp"; + } + + return "unimp"; +} + static void __dump_ast(int depth, struct ast_node *node) { switch (node->node_type) { @@ -1232,8 +894,7 @@ static void __dump_ast(int depth, struct ast_node *node) switch (node->_type.kind) { case AST_TYPE_PRIMITIVE: - printf(" PRIMITIVE\n"); - dump_ast(depth + 1, AST_PRIMITIVE_TYPE(node).id); + printf(" PRIMITIVE %s\n", primitive_str(AST_PRIMITIVE_TYPE(node).type)); break; case AST_TYPE_TRAIT: @@ -1544,7 +1205,8 @@ struct ast_node *clone_ast_node(struct ast_node *node) case AST_MACRO_EXPAND: new = gen_macro_expand( clone_ast_node(AST_MACRO_EXPAND(node).id), - clone_ast_node(AST_MACRO_EXPAND(node).args)); + clone_ast_node(AST_MACRO_EXPAND(node).args), + node->loc); break; case AST_CAST: new = gen_cast(clone_ast_node(node->_cast.expr), @@ -1595,10 +1257,7 @@ struct ast_node *clone_ast_node(struct ast_node *node) * correctly... */ switch (node->_type.kind) { case AST_TYPE_PRIMITIVE: - new = gen_type(AST_TYPE_PRIMITIVE, - clone_ast_node(AST_PRIMITIVE_TYPE(node).id), - NULL, - NULL); + new = gen_primitive(AST_PRIMITIVE_TYPE(node).type, node->loc); break; case AST_TYPE_TRAIT: @@ -1708,10 +1367,6 @@ struct ast_node *clone_ast_node(struct ast_node *node) case AST_CONST_STRING: new = gen_string(strdup(node->_const.str)); break; - - case AST_CONST_FLOAT: - new = gen_float(node->_const.dbl); - break; } break; @@ -1983,7 +1638,7 @@ static int identical_type_trait(int exact, struct ast_node *a, struct ast_node * static int identical_type_primitive(int exact, struct ast_node *a, struct ast_node *b) { - return identical_ast_nodes(exact, AST_PRIMITIVE_TYPE(a).id, AST_PRIMITIVE_TYPE(b).id); + return AST_PRIMITIVE_TYPE(a).type == AST_PRIMITIVE_TYPE(b).type; } static int identical_type_typeof(int exact, struct ast_node *a, @@ -2130,16 +1785,6 @@ static int identical_const(int exact, struct ast_node *a, struct ast_node *b) break; - case AST_CONST_FLOAT: - /* NaNs aren't comparable */ - if (isnan(a->_const.dbl) && isnan(b->_const.dbl)) - break; - - if (a->_const.dbl != b->_const.dbl) - return 0; - - break; - case AST_CONST_STRING: if (strcmp(a->_const.str, b->_const.str) != 0) return 0; @@ -2537,20 +2182,11 @@ static int call_on_type_enum(int (*call)(struct ast_node *, return ret; } -static int call_on_type_primitive(int (*call)(struct ast_node *, void *), - struct ast_node *node, void *data) -{ - int ret = 0; - ret |= call(AST_PRIMITIVE_TYPE(node).id, data); - return ret; -} - static int call_on_type(int (*call)(struct ast_node *, void *), struct ast_node *node, void *data) { int ret = 0; switch (node->_type.kind) { - case AST_TYPE_PRIMITIVE: ret = call_on_type_primitive(call, node, data); break; case AST_TYPE_ENUM: ret = call_on_type_enum(call, node, data); break; case AST_TYPE_TRAIT: ret = call_on_type_trait(call, node, data); break; case AST_TYPE_ID: ret = call_on_type_id(call, node, data); break; @@ -2559,6 +2195,7 @@ static int call_on_type(int (*call)(struct ast_node *, case AST_TYPE_STRUCT: ret = call_on_type_struct(call, node, data); break; case AST_TYPE_SIGN: ret = call_on_type_sign(call, node, data); break; case AST_TYPE_POINTER: break; + case AST_TYPE_PRIMITIVE: break; } return ret; diff --git a/src/compiler.c b/src/compiler.c index 607618e..5ad67c3 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -175,5 +175,6 @@ int compile(const char *file) { ret = actualize_main(root); /** @todo backend */ destroy_scope(root); + destroy_ast_nodes(); return ret; } diff --git a/src/debug.c b/src/debug.c index f145234..e6e2b60 100644 --- a/src/debug.c +++ b/src/debug.c @@ -230,8 +230,7 @@ static void _type_str(FILE *fp, struct ast_node *type) } case AST_TYPE_PRIMITIVE: { - struct ast_node *id = AST_PRIMITIVE_TYPE(type).id; - fprintf(fp, "%s", AST_ID(id).id); + fprintf(fp, "%s", primitive_str(AST_PRIMITIVE_TYPE(type).type)); break; } diff --git a/src/lexer.l b/src/lexer.l index bcfa5be..a446c49 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -37,7 +37,6 @@ INT {HEX}|{DEC}|{OCT}|{BIN} HEXF [+-]?0[xX][0-9a-fA-F]+([pP][+-]?[0-9]+) DECF [+-]?[0-9]+[.]([eE]?[+-]?[0-9]+)?[fF]? -FLOAT {HEXF}|{DECF}|inf|nan ID [_a-zA-Z][_a-zA-Z0-9]* APPLY {ID}[[:space:]]*! @@ -186,11 +185,6 @@ STRING \"(\\.|[^"\\])*\" return INT; } -{FLOAT} { - yylval->dbl = strtod(yytext, 0); - return FLOAT; -} - {ID} { yylval->str = yytext; return ID; diff --git a/src/parser.y b/src/parser.y index 6975041..ad08cf8 100644 --- a/src/parser.y +++ b/src/parser.y @@ -28,7 +28,6 @@ %union { struct ast_node *node; long long integer; - double dbl; char *str; }; @@ -149,9 +148,6 @@ /* array stuff */ %nterm <node> arr arr_inits arr_init -%destructor {} FLOAT INT STRING ID APPLY -%destructor { destroy_ast_tree($$); } <*> - %{ /** Modifies the signature of yylex to fit our parser better. */ @@ -364,7 +360,6 @@ const_unop const_expr : "(" const_expr ")" { $$ = $2; } | INT { $$ = gen_int($1); } - | FLOAT { $$ = gen_float($1); } | const_binop | const_unop | id @@ -373,11 +368,9 @@ const_expr expr : expr "." id { $$ = gen_dot($1, $3); } | "..." id { $$ = $2; } - | INT { $$ = gen_int($1); $$->loc = src_loc(@$); } - | FLOAT { $$ = gen_float($1); $$->loc = src_loc(@$); } + | INT { $$ = gen_int($1); } | STRING { $$ = gen_string(clone_string($1)); - $$->loc = src_loc(@$); } | "(" expr ")" { $$ = $2; } | expr "(" args ")" { $$ = gen_call($1, $3); } @@ -429,7 +422,6 @@ statelet /* If we're failing to parse a statement in a block, continue by trying to * parse the next statement in the block */ if (next_interesting_feature(&yylval, &yylloc, scanner, parser)) { - destroy_ast_node($$); YYABORT; } yyclearin; @@ -644,8 +636,8 @@ anon_union : "union" "{" members "}" { $$ = gen_struct(NULL, NULL, $3); } macro_expand - : apply "(" ")" { $$ = gen_macro_expand($1, NULL); } - | apply "(" args ")" { $$ = gen_macro_expand($1, $3); } + : apply "(" ")" { $$ = gen_macro_expand($1, NULL, src_loc(@$)); } + | apply "(" args ")" { $$ = gen_macro_expand($1, $3, src_loc(@$)); } tagged_struct : "struct" id "{" members "}" { @@ -681,7 +673,7 @@ trait } type_param - : id id + : id id { $$ = gen_var($2, $1, NULL); } type_params : type_param "," type_params { $$ = $1; $1->next = $3; } @@ -754,8 +746,6 @@ top /* ignore any content inside a top level thing and just move onto * the next one */ if (next_interesting_feature(&yylval, &yylloc, scanner, parser)) { - /* remove previously allocated node if we're out of input */ - destroy_ast_node($$); YYABORT; } yyclearin; diff --git a/src/scope.c b/src/scope.c index 2b8ef12..369a89b 100644 --- a/src/scope.c +++ b/src/scope.c @@ -330,7 +330,7 @@ int scope_add_var(struct scope *scope, struct ast_node *var) return -1; } - struct visible *visible = create_var(scope, AST_VAR(var).id, var); + create_var(scope, AST_VAR(var).id, var); if (scope_flags(scope, SCOPE_FILE) && ast_flags(var, AST_FLAG_PUBLIC)) return scope_add_var(scope->parent, var); @@ -340,18 +340,13 @@ int scope_add_var(struct scope *scope, struct ast_node *var) int scope_add_type(struct scope *scope, struct ast_node *id, struct ast_node *type) { struct ast_node *exists = file_scope_find_type(scope, id); - /* redefining a type to itself is allowed, and might be necessary for - * some generics operations. I'll have to double check this later, - * though */ if (exists) { semantic_error(scope->fctx, type, "type redefined"); semantic_info(scope->fctx, exists, "previously here"); return -1; } - /* during a redefine, if it's redefined to public should it be - * propagated upward? Probably not, but dunno for sure yet */ - struct visible *visible = create_type(scope, id, type); + create_type(scope, id, type); if (scope_flags(scope, SCOPE_FILE) && ast_flags(type, AST_FLAG_PUBLIC)) return scope_add_type(scope->parent, id, type); @@ -823,7 +818,8 @@ struct ast_node *file_scope_resolve_macro(struct scope *scope, struct ast_node * } /* this might be useful somewhere else as well */ -static const char *default_types[] = {"void", "i9", "i27"}; +static enum ast_primitive default_types[] = {AST_VOID, AST_I9, AST_I27}; +static const char *default_names[] = {"void", "i9", "i27"}; /* TODO: add error checking */ int scope_add_defaults(struct scope *root) @@ -831,12 +827,8 @@ int scope_add_defaults(struct scope *root) for (size_t i = 0; i < sizeof(default_types) / sizeof(default_types[0]); ++i) { - const char *type = default_types[i]; - struct ast_node *n = gen_id(strdup(type), NULL_LOC()); - if (!n) - return -1; - - struct ast_node *a = gen_type(AST_TYPE_PRIMITIVE, n, NULL, NULL); + struct ast_node *n = gen_id(strdup(default_names[i]), NULL_LOC()); + struct ast_node *a = gen_primitive(default_types[i], NULL_LOC()); if (!a) return -1; |
