aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-11-14 13:14:42 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2023-11-14 13:14:42 +0200
commit294dd992f84f609e6ffcb58e49efb2ef1908e1a8 (patch)
tree23aea55fb647443972765f1eca05d24c0db25ebf /src
parentb00da3db7c1d7f1e16b2e0446234dc42d54b8708 (diff)
downloadek-294dd992f84f609e6ffcb58e49efb2ef1908e1a8.tar.gz
ek-294dd992f84f609e6ffcb58e49efb2ef1908e1a8.zip
make memory tracking more dumb
Diffstat (limited to 'src')
-rw-r--r--src/actualize.c148
-rw-r--r--src/ast.c527
-rw-r--r--src/compiler.c1
-rw-r--r--src/debug.c3
-rw-r--r--src/lexer.l6
-rw-r--r--src/parser.y18
-rw-r--r--src/scope.c20
7 files changed, 112 insertions, 611 deletions
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;
diff --git a/src/ast.c b/src/ast.c
index b3164c0..5187066 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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;