summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-09-29 20:36:14 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-09-29 20:36:14 -0400
commitc8e6972ee18a95db544980513f619567a3bc171e (patch)
tree8f5882e9371d2d400958ecf03651792611c5f3ff
parented62db5344e1fb39f17883c69bd398d18758f29b (diff)
finished replacing err_malloc with allocators; now there are no memory leaks!
-rw-r--r--abbrevs.txt1
-rw-r--r--allocator.c36
-rw-r--r--arr.c6
-rw-r--r--eval.c39
-rw-r--r--identifiers.c9
-rw-r--r--main.c34
-rw-r--r--parse.c28
-rw-r--r--test.toc26
-rw-r--r--tests.c5
-rw-r--r--tokenizer.c21
-rw-r--r--types.c61
11 files changed, 170 insertions, 96 deletions
diff --git a/abbrevs.txt b/abbrevs.txt
index d5a3a68..d907681 100644
--- a/abbrevs.txt
+++ b/abbrevs.txt
@@ -6,6 +6,7 @@ deref - dereference
direct - directive
eof - end of file
err - error
+evalr - evaluator
expr - expression
fn - function
ident - identifier
diff --git a/allocator.c b/allocator.c
index f10c703..2b6b0b3 100644
--- a/allocator.c
+++ b/allocator.c
@@ -4,10 +4,15 @@ typedef struct Page {
max_align_t data[];
} Page;
+typedef struct DynPage {
+ struct DynPage **self;
+ max_align_t data[];
+} DynPage;
+
typedef struct {
Page *first;
Page *last;
- void **dyn; /* array of void*s for dynamic memory */
+ DynPage **dyn;
size_t dyn_len;
size_t dyn_cap;
} Allocator;
@@ -17,6 +22,8 @@ typedef struct {
static void allocr_create(Allocator *a) {
a->first = a->last = NULL;
+ a->dyn = NULL;
+ a->dyn_len = a->dyn_cap = 0;
}
static void *allocr_malloc(Allocator *a, size_t bytes) {
@@ -42,14 +49,36 @@ static void *allocr_malloc(Allocator *a, size_t bytes) {
}
}
-static void *allocr_calloc(Allocator *a, size_t bytes) {
+static void *allocr_calloc(Allocator *a, size_t n, size_t sz) {
+ /* OPTIM: use calloc */
+ size_t bytes = n * sz;
void *data = allocr_malloc(a, bytes);
memset(data, 0, bytes);
return data;
}
-/* IMPORTANT: this can only be called with data which was originally allocated with allocr_realloc(a, NULL, x) */
+/* IMPORTANT: this can only be called with data which was originally allocated with allocr_realloc(a, NULL, x)
+ */
static void *allocr_realloc(Allocator *a, void *data, size_t new_size) {
+ if (data) {
+ DynPage *page = (DynPage *)((char *)data - offsetof(DynPage, data));
+ page = err_realloc(page, new_size + sizeof(DynPage));
+ *page->self = page;
+ return page->data;
+ } else {
+ if (a->dyn_len >= a->dyn_cap) {
+ a->dyn_cap = 2 * (a->dyn_len + 1);
+ a->dyn = realloc(a->dyn, a->dyn_cap * sizeof(DynPage *));
+ for (size_t i = 0; i < a->dyn_len; i++) {
+ a->dyn[i]->self = &a->dyn[i];
+ }
+ }
+ DynPage *page = err_malloc(sizeof(DynPage) + new_size);
+ page->self = &a->dyn[a->dyn_len];
+ *page->self = page;
+ a->dyn_len++;
+ return page->data;
+ }
return NULL;
}
@@ -62,4 +91,5 @@ static void allocr_free_all(Allocator *a) {
for (size_t i = 0; i < a->dyn_len; i++) {
free(a->dyn[i]);
}
+ free(a->dyn);
}
diff --git a/arr.c b/arr.c
index fa337e8..ff94377 100644
--- a/arr.c
+++ b/arr.c
@@ -18,7 +18,7 @@ static inline void arr_reserve(Array *arr, size_t n) {
static inline void arr_reservea(Array *arr, size_t n, Allocator *a) {
arr->cap = n;
- arr->data = allocr_realloc(a, arr->data, n);
+ arr->data = allocr_realloc(a, arr->data, arr->item_sz * arr->cap);
}
/* like arr_reserve, but sets the length of the array too */
@@ -64,10 +64,6 @@ static void arr_clear(Array *arr) {
static void arr_remove_last(Array *arr) {
/* OPTIM (memory): Shorten array. */
arr->len--;
- if (!arr->len) {
- arr_clear(arr);
- }
-
}
static void arr_free(Array *arr) {
diff --git a/eval.c b/eval.c
index 8274da8..9dd2f62 100644
--- a/eval.c
+++ b/eval.c
@@ -12,6 +12,22 @@ typedef enum {
#define VAL_FLAG_FN_NULL 0x01 /* is this function null? */
+typedef struct {
+ Allocator allocr;
+} Evaluator;
+
+static void evalr_create(Evaluator *ev) {
+ allocr_create(&ev->allocr);
+}
+
+static void evalr_free(Evaluator *ev) {
+ allocr_free_all(&ev->allocr);
+}
+
+static inline void *evalr_malloc(Evaluator *ev, size_t bytes) {
+ return allocr_malloc(&ev->allocr, bytes);
+}
+
typedef double FloatVal;
typedef struct {
@@ -348,7 +364,7 @@ static inline void val_promote_to_float(Value *v) {
}
/* NOTE: expr must be typed before it can be evaluated */
-static bool eval_expr(Expression *e, Value *v) {
+static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
switch (e->kind) {
case EXPR_LITERAL_FLOAT:
v->kind = VAL_FLOAT;
@@ -380,7 +396,7 @@ static bool eval_expr(Expression *e, Value *v) {
case EXPR_UNARY_OP: {
Expression *of_expr = e->unary.of;
Value of;
- if (!eval_expr(of_expr, &of)) return false;
+ if (!eval_expr(ev, of_expr, &of)) return false;
switch (e->unary.op) {
case UNARY_MINUS: {
assert(e->type.kind == TYPE_BUILTIN);
@@ -421,8 +437,8 @@ static bool eval_expr(Expression *e, Value *v) {
Expression *lhs_expr = of_expr->binary.lhs;
Expression *rhs_expr = of_expr->binary.rhs;
Value lhs, rhs;
- if (!eval_expr(lhs_expr, &lhs)
- || !eval_expr(rhs_expr, &rhs))
+ if (!eval_expr(ev, lhs_expr, &lhs)
+ || !eval_expr(ev, rhs_expr, &rhs))
return false;
assert(lhs.kind == VAL_ARR && (rhs.kind == VAL_INT || rhs.kind == VAL_UINT));
v->ptr = (char *)lhs.arr.data + (Integer)sizeof_val_kind(lhs.arr_kind)
@@ -471,8 +487,8 @@ static bool eval_expr(Expression *e, Value *v) {
case EXPR_BINARY_OP: {
Value lhs, rhs;
/* NOTE: this will need to change for short-circuiting */
- if (!eval_expr(e->binary.lhs, &lhs)) return false;
- if (!eval_expr(e->binary.rhs, &rhs)) return false;
+ if (!eval_expr(ev, e->binary.lhs, &lhs)) return false;
+ if (!eval_expr(ev, e->binary.rhs, &rhs)) return false;
if (e->type.kind != TYPE_BUILTIN) {
err_print(e->where, "Operators can only be applied to builtin types.");
return false;
@@ -608,8 +624,8 @@ static bool eval_expr(Expression *e, Value *v) {
return false;
}
if (!d->val) {
- d->val = err_malloc(sizeof *d->val); /* OPTIM */
- if (!eval_expr(&d->expr, d->val))
+ d->val = evalr_malloc(ev, sizeof *d->val); /* OPTIM */
+ if (!eval_expr(ev, &d->expr, d->val))
return false;
}
*v = *d->val;
@@ -626,12 +642,12 @@ static bool eval_expr(Expression *e, Value *v) {
break;
}
Value cond;
- if (!eval_expr(i->cond, &cond))
+ if (!eval_expr(ev, i->cond, &cond))
return false;
if (eval_truthiness(&cond)) {
if (!eval_block(&i->body, v)) return false;
} else if (i->next_elif) {
- if (!eval_expr(i->next_elif, v)) return false;
+ if (!eval_expr(ev, i->next_elif, v)) return false;
} else {
v->kind = VAL_VOID;
}
@@ -641,7 +657,7 @@ static bool eval_expr(Expression *e, Value *v) {
return eval_block(&e->block, v);
case EXPR_CAST: {
Value cast_val;
- if (!eval_expr(e->cast.expr, &cast_val)) return false;
+ if (!eval_expr(ev, e->cast.expr, &cast_val)) return false;
if (!val_cast(e->where, v, cast_val, &e->cast.type)) return false;
break;
}
@@ -665,3 +681,4 @@ static bool eval_expr(Expression *e, Value *v) {
}
return true;
}
+
diff --git a/identifiers.c b/identifiers.c
index 6eafc41..08a205c 100644
--- a/identifiers.c
+++ b/identifiers.c
@@ -60,6 +60,7 @@ static Identifier ident_new(Identifiers *ids, Identifier parent, unsigned char i
tree->parent = NULL;
for (size_t i = 0; i < TREE_NCHILDREN; i++)
tree->children[i] = NULL;
+ tree->decls.data = NULL;
#endif
tree->parent = parent;
if (parent)
@@ -186,6 +187,14 @@ static IdentDecl *ident_decl(Identifier i) {
return i->decls.item_sz == 0 ? NULL : (IdentDecl*)arr_last(&i->decls);
}
+static void ident_tree_free(IdentTree *id) {
+ if (!id) return;
+ arr_free(&id->decls);
+ for (int i = 0; i < TREE_NCHILDREN; i++)
+ ident_tree_free(id->children[i]);
+}
+
static void idents_free(Identifiers *ids) {
+ ident_tree_free(ids->root);
block_arr_free(&ids->trees);
}
diff --git a/main.c b/main.c
index b55b70c..6faeb9d 100644
--- a/main.c
+++ b/main.c
@@ -14,7 +14,6 @@ int main(int argc, char **argv) {
#ifdef TOC_DEBUG
test_all();
#endif
- return 0;
if (argc < 2) {
fprintf(stderr, "Please specify an input file.\n");
return EXIT_FAILURE;
@@ -67,38 +66,31 @@ int main(int argc, char **argv) {
err_fprint(TEXT_IMPORTANT("Errors occured while parsing.\n"));
return EXIT_FAILURE;
}
-
+ tokr_free_tokens(&t);
fprint_parsed_file(stdout, &f);
-
+
printf("\n\n-----\n\n");
block_enter(NULL, &f.stmts); /* enter global scope */
- if (!types_file(&f)) {
+ Typer tr;
+ Evaluator ev;
+ evalr_create(&ev);
+ typer_create(&tr, &ev);
+ if (!types_file(&tr, &f)) {
err_fprint(TEXT_IMPORTANT("Errors occured while determining types.\n"));
return EXIT_FAILURE;
}
parse_printing_after_types = true;
fprint_parsed_file(stdout, &f);
+ block_exit(NULL, &f.stmts); /* exit global scope */
tokr_free(&t);
-
-
-
- /* TODO (eventually): use a tmp file (don't overwrite old output if there's an error) */
- /* const char *c_out_filename = "out.c"; */
- /* const char *h_out_filename = "out.h"; */
- /* FILE *c_out = fopen(c_out_filename, "w"); */
- /* FILE *h_out = fopen(h_out_filename, "w"); */
- /* CGenerator cgen; */
- /* cgen_create(&cgen, &file_idents, c_out, h_out, h_out_filename); */
- /* if (!cgen_file(&cgen, &f)) { */
- /* err_fprint(TEXT_IMPORTANT("Errors occured while generating C code.\n")); */
- /* return EXIT_FAILURE; */
- /* } */
-
- block_exit(NULL, &f.stmts); /* exit global scope */
+
free(contents);
-
+
+ parser_free(&p);
+ typer_free(&tr);
+ evalr_free(&ev);
/* fclose(c_out); */
/* fclose(h_out); */
idents_free(&file_idents);
diff --git a/parse.c b/parse.c
index be46485..0391a27 100644
--- a/parse.c
+++ b/parse.c
@@ -428,17 +428,20 @@ static char *type_to_str(Type *t) {
return ret;
}
-/*
- allocate a new expression.
-*/
-static Expression *parser_new_expr(Parser *p) {
- return allocr_malloc(&p->allocr, sizeof(Expression));
+static inline void *parser_arr_add(Parser *p, Array *a) {
+ return arr_adda(a, &p->allocr);
}
-static void *parser_arr_add(Parser *p, Array *a) {
- return arr_adda(a, &p->allocr);
+static inline void *parser_malloc(Parser *p, size_t bytes) {
+ return allocr_malloc(&p->allocr, bytes);
}
+/*
+ allocate a new expression.
+*/
+static inline Expression *parser_new_expr(Parser *p) {
+ return parser_malloc(p, sizeof(Expression));
+}
/* TODO: check that we check which thing ends it everywhere */
@@ -586,7 +589,7 @@ static bool parse_type(Parser *p, Type *type) {
type->arr.n_expr = parser_new_expr(p);
if (!parse_expr(p, type->arr.n_expr, end)) return false;
t->token = end + 1; /* go past ] */
- type->arr.of = err_malloc(sizeof *type->arr.of); /* OPTIM */
+ type->arr.of = parser_malloc(p, sizeof *type->arr.of);
if (!parse_type(p, type->arr.of)) return false;
type->flags = 0;
type->where = start->where;
@@ -616,7 +619,7 @@ static bool parse_type(Parser *p, Type *type) {
case KW_AMPERSAND:
/* pointer */
type->kind = TYPE_PTR;
- type->ptr.of = err_malloc(sizeof *type->ptr.of); /* OPTIM */
+ type->ptr.of = parser_malloc(p, sizeof *type->ptr.of);
t->token++; /* move past & */
if (!parse_type(p, type->ptr.of)) return false;
break;
@@ -1565,7 +1568,6 @@ static void parser_free(Parser *p) {
allocr_free_all(&p->allocr);
}
-
#define PARSE_PRINT_LOCATION(l) //fprintf(out, "[l%lu]", (unsigned long)(l).line);
/* in theory, this shouldn't be global, but these functions are mostly for debugging anyways */
@@ -1577,7 +1579,9 @@ static void fprint_decl(FILE *out, Declaration *d);
static void fprint_type(FILE *out, Type *t) {
PARSE_PRINT_LOCATION(t->where);
- fprintf(out, "%s", type_to_str(t));
+ char *s = type_to_str(t);
+ fprintf(out, "%s", s);
+ free(s);
}
@@ -1763,5 +1767,3 @@ static void fprint_parsed_file(FILE *out, ParsedFile *f) {
fprint_stmt(out, stmt);
}
}
-
-/* TODO: Freeing parser (remember to free args) */
diff --git a/test.toc b/test.toc
index c8a03b4..689e554 100644
--- a/test.toc
+++ b/test.toc
@@ -1,17 +1,17 @@
main @= fn() {
- // arr1 : ['a' as u8]int;
- // arr2 : [main as u64]int;
- // arr3 : [main as i64]int;
- // N @= (-10 + (97 as char as f32)) as u32;
- // arr4 : [N]int;
- // arr5 : [main as u64]int;
- // // arr6 : [main as u64 as fn() as u64]int;FIXME
- // arr7 : [main as u64 as fn() int as u64]int;
+ arr1 : ['a' as u8]int;
+ arr2 : [main as u64]int;
+ arr3 : [main as i64]int;
+ N @= (-10 + (97 as char as f32)) as u32;
+ arr4 : [N]int;
+ arr5 : [main as u64]int;
+ // arr6 : [main as u64 as fn() as u64]int;FIXME
+ arr7 : [main as u64 as fn() int as u64]int;
- // str @= "foo";
- // arr8 : [(str[0] as u32) + (str[1] as u32) + (str[2] as u32)]int;
- // asdf @= new int;
- // arr9 : [asdf as u64]int;
- // arr10 : [main as &i32 as u64]int;
+ str @= "foo";
+ arr8 : [(str[0] as u32) + (str[1] as u32) + (str[2] as u32)]int;
+ asdf @= new int;
+ arr9 : [asdf as u64]int;
+ arr10 : [main as &i32 as u64]int;
arr11 : [((main as &u64) as [4]u64)[3]]int;
};
diff --git a/tests.c b/tests.c
index 6b22cd1..e9e0c31 100644
--- a/tests.c
+++ b/tests.c
@@ -11,7 +11,7 @@ static void allocr_test(void) {
for (int i = 0; i < nfoos; i++)
assert(foos[i] == i);
int nbars = x;
- int *bars = allocr_calloc(&a, (size_t)nbars * sizeof(int));
+ int *bars = allocr_calloc(&a, (size_t)nbars, sizeof(int));
for (int i = 0; i < nbars; i++)
assert(bars[i] == 0);
for (int i = 0; i < nbars; i++)
@@ -38,7 +38,8 @@ static void allocr_test(void) {
arr_create(&arr, sizeof(int));
int n = 1000;
for (int i = 0; i < n; i++) {
- *(int *)arr_adda(&arr, &a) = i;
+ int *p = arr_adda(&arr, &a);
+ *p = i;
}
int *arr_data = arr.data;
for (int i = 0; i < n; i++) {
diff --git a/tokenizer.c b/tokenizer.c
index 7adb7d5..8807b33 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -153,6 +153,7 @@ typedef struct {
} Token;
typedef struct {
+ Allocator allocr;
Array tokens;
char *s; /* string being parsed */
const char *filename;
@@ -161,14 +162,10 @@ typedef struct {
Identifiers *idents;
} Tokenizer;
-
-
static inline bool token_is_kw(Token *t, Keyword kw) {
return t->kind == TOKEN_KW && t->kw == kw;
}
-
-
static const char *token_kind_to_str(TokenKind t) {
switch (t) {
case TOKEN_KW: return "keyword";
@@ -288,10 +285,15 @@ static void tokr_get_location(Tokenizer *tokr, Token *t) {
static void tokr_create(Tokenizer *t, Identifiers *idents, const char *filename) {
arr_create(&t->tokens, sizeof(Token));
arr_reserve(&t->tokens, 256);
+ allocr_create(&t->allocr);
t->idents = idents;
t->filename = filename;
}
+static inline void *tokr_malloc(Tokenizer *t, size_t bytes) {
+ return allocr_malloc(&t->allocr, bytes);
+}
+
static Token *tokr_add(Tokenizer *t) {
Token *token = arr_add(&t->tokens);
tokr_put_location(t, token);
@@ -552,7 +554,7 @@ static bool tokenize_string(Tokenizer *t, char *str) {
len++;
tokr_nextchar(t);
}
- char *strlit = err_malloc(len + 1);
+ char *strlit = tokr_malloc(t, len + 1);
char *strptr = strlit;
tokr_get_location(t, token);
tokr_nextchar(t); /* past opening " */
@@ -599,7 +601,12 @@ static bool tokenize_string(Tokenizer *t, char *str) {
return !has_err;
}
-/* Does NOT free string literals!!! */
-static void tokr_free(Tokenizer *t) {
+/* ONLY frees tokens, not string literals. You can call this followed by tokr_free. */
+static void tokr_free_tokens(Tokenizer *t) {
arr_clear(&t->tokens);
}
+
+static void tokr_free(Tokenizer *t) {
+ tokr_free_tokens(t);
+ allocr_free_all(&t->allocr);
+}
diff --git a/types.c b/types.c
index b277b8a..d6f62b5 100644
--- a/types.c
+++ b/types.c
@@ -1,4 +1,6 @@
typedef struct {
+ Allocator allocr;
+ Evaluator *evalr;
Array in_decls; /* array of declarations we are currently inside */
Block *block;
bool can_ret;
@@ -11,6 +13,18 @@ static bool types_expr(Typer *tr, Expression *e);
static bool types_block(Typer *tr, Block *b);
static bool type_resolve(Typer *tr, Type *t);
+static inline void *typer_malloc(Typer *tr, size_t bytes) {
+ return allocr_malloc(&tr->allocr, bytes);
+}
+
+static inline void *typer_calloc(Typer *tr, size_t n, size_t sz) {
+ return allocr_calloc(&tr->allocr, n, sz);
+}
+
+static inline void *typer_arr_add(Typer *tr, Array *arr) {
+ return arr_adda(arr, &tr->allocr);
+}
+
static bool add_ident_decls(Block *b, Declaration *d) {
bool ret = true;
arr_foreach(&d->idents, Identifier, ident) {
@@ -165,7 +179,7 @@ static bool expr_must_lval(Expression *e) {
static bool type_of_fn(Typer *tr, FnExpr *f, Type *t) {
t->kind = TYPE_FN;
arr_create(&t->fn.types, sizeof(Type));
- Type *ret_type = arr_add(&t->fn.types);
+ Type *ret_type = typer_arr_add(tr, &t->fn.types);
if (!type_resolve(tr, &f->ret_type))
return false;
*ret_type = f->ret_type;
@@ -175,7 +189,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t) {
if (!type_resolve(tr, &decl->type))
return false;
for (size_t i = 0; i < decl->idents.len; i++) {
- Type *param_type = arr_add(&t->fn.types);
+ Type *param_type = typer_arr_add(tr, &t->fn.types);
*param_type = decl->type;
}
}
@@ -267,7 +281,7 @@ static bool type_resolve(Typer *tr, Type *t) {
free(s);
return false;
}
- if (!eval_expr(n_expr, &val)) return false; /* resolve N */
+ if (!eval_expr(tr->evalr, n_expr, &val)) return false; /* resolve N */
Integer size = val.intv;
if (size < 0) {
err_print(t->arr.n_expr->where, "Negative array length (" INTEGER_FMT ")", size);
@@ -411,7 +425,7 @@ static bool types_expr(Typer *tr, Expression *e) {
case EXPR_LITERAL_STR:
t->kind = TYPE_ARR;
t->arr.n = e->strl.len;
- t->arr.of = err_malloc(sizeof *t->arr.of);
+ t->arr.of = typer_malloc(tr, sizeof *t->arr.of);
t->arr.of->flags = TYPE_FLAG_RESOLVED;
t->arr.of->kind = TYPE_BUILTIN;
t->arr.of->builtin = BUILTIN_CHAR;
@@ -442,7 +456,7 @@ static bool types_expr(Typer *tr, Expression *e) {
} break;
case EXPR_NEW:
t->kind = TYPE_PTR;
- t->ptr.of = err_malloc(sizeof *t->ptr.of);
+ t->ptr.of = typer_malloc(tr, sizeof *t->ptr.of);
t->ptr.of = &e->new.type;
if (!type_resolve(tr, t))
return false;
@@ -534,7 +548,7 @@ static bool types_expr(Typer *tr, Expression *e) {
arr_create(&new_args_arr, sizeof(Expression));
arr_set_len(&new_args_arr, nparams);
Expression *new_args = new_args_arr.data;
- bool *params_set = calloc(nparams, sizeof *params_set);
+ bool *params_set = typer_calloc(tr, nparams, sizeof *params_set);
if (f->kind == EXPR_IDENT) {
IdentDecl *decl = ident_decl(f->ident);
assert(decl);
@@ -684,7 +698,7 @@ static bool types_expr(Typer *tr, Expression *e) {
return false;
}
t->kind = TYPE_PTR;
- t->ptr.of = err_malloc(sizeof *t->ptr.of); /* OPTIM */
+ t->ptr.of = typer_malloc(tr, sizeof *t->ptr.of); /* OPTIM */
*t->ptr.of = *of_type;
break;
case UNARY_DEREF:
@@ -819,19 +833,19 @@ static bool types_expr(Typer *tr, Expression *e) {
if (lhs_type->kind == TYPE_TUPLE) {
/* tuple, x => tuple */
arr_foreach(&lhs_type->tuple, Type, child) {
- *(Type*)arr_add(tup_types) = *child;
+ *(Type*)typer_arr_add(tr, tup_types) = *child;
}
} else {
- *(Type*)arr_add(tup_types) = *lhs_type;
+ *(Type*)typer_arr_add(tr, tup_types) = *lhs_type;
}
if (rhs_type->kind == TYPE_TUPLE) {
/* x, tuple => tuple */
arr_foreach(&rhs_type->tuple, Type, child) {
- *(Type*)arr_add(tup_types) = *child;
+ *(Type*)typer_arr_add(tr, tup_types) = *child;
}
} else {
- *(Type*)arr_add(tup_types) = *rhs_type;
+ *(Type*)typer_arr_add(tr, tup_types) = *rhs_type;
}
} break;
}
@@ -866,7 +880,7 @@ static bool types_block(Typer *tr, Block *b) {
static bool types_decl(Typer *tr, Declaration *d) {
bool success = true;
if (d->flags & DECL_FLAG_FOUND_TYPE) goto ret;
- Declaration **dptr = arr_add(&tr->in_decls);
+ Declaration **dptr = typer_arr_add(tr, &tr->in_decls);
*dptr = d;
if (d->flags & DECL_FLAG_ANNOTATES_TYPE) {
/* type supplied */
@@ -898,8 +912,8 @@ static bool types_decl(Typer *tr, Declaration *d) {
}
if (d->flags & DECL_FLAG_CONST) {
if (!d->val) {
- d->val = err_malloc(sizeof *d->val); /* OPTIM */
- if (!eval_expr(&d->expr, d->val)) {
+ d->val = typer_malloc(tr, sizeof *d->val); /* OPTIM */
+ if (!eval_expr(tr->evalr, &d->expr, d->val)) {
success = false;
goto ret;
}
@@ -963,19 +977,24 @@ static bool types_stmt(Typer *tr, Statement *s) {
return true;
}
-static void typer_create(Typer *tr) {
+static void typer_create(Typer *tr, Evaluator *ev) {
tr->block = NULL;
tr->can_ret = false;
+ tr->evalr = ev;
arr_create(&tr->in_decls, sizeof(Declaration *));
+ allocr_create(&tr->allocr);
}
-static bool types_file(ParsedFile *f) {
- Typer tr;
- typer_create(&tr);
+static bool types_file(Typer *tr, ParsedFile *f) {
+ bool ret = true;
arr_foreach(&f->stmts, Statement, s) {
- if (!types_stmt(&tr, s)) {
- return false;
+ if (!types_stmt(tr, s)) {
+ ret = false;
}
}
- return true;
+ return ret;
+}
+
+static void typer_free(Typer *tr) {
+ allocr_free_all(&tr->allocr);
}