diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-03 22:44:02 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-03 22:44:02 -0400 |
commit | 4030c4239542d1b668c2f328f7142b9796973ddd (patch) | |
tree | d46384c848a484a6242de8aa6c346c781505569f | |
parent | 39b4b36741bb63fe1bd6da945fc5553ff648d97a (diff) |
fixed bug & added while infinite loops (now only they can have ret exprs)
-rw-r--r-- | allocator.c | 34 | ||||
-rw-r--r-- | arr.c | 4 | ||||
-rw-r--r-- | eval.c | 9 | ||||
-rw-r--r-- | parse.c | 26 | ||||
-rw-r--r-- | test.toc | 12 | ||||
-rw-r--r-- | tests.c | 25 | ||||
-rw-r--r-- | types.c | 11 | ||||
-rw-r--r-- | types.h | 8 |
8 files changed, 43 insertions, 86 deletions
diff --git a/allocator.c b/allocator.c index 6add3cf..4dc05c8 100644 --- a/allocator.c +++ b/allocator.c @@ -4,8 +4,6 @@ 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) { @@ -39,29 +37,11 @@ static void *allocr_calloc(Allocator *a, size_t n, size_t sz) { return data; } -/* 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; +/* OPTIM */ +static void *allocr_realloc(Allocator *a, void *data, size_t old_size, size_t new_size) { + void *ret = allocr_malloc(a, new_size); + memcpy(ret, data, old_size); + return ret; } static void allocr_free_all(Allocator *a) { @@ -70,8 +50,4 @@ static void allocr_free_all(Allocator *a) { free(page); page = next; } - for (size_t i = 0; i < a->dyn_len; i++) { - free(a->dyn[i]); - } - free(a->dyn); } @@ -31,14 +31,14 @@ static void arr_resv_(void **arr, size_t n, size_t item_sz) { } static void arr_resva_(void **arr, size_t n, size_t item_sz, Allocator *a) { if (*arr == NULL) { - ArrHeader *hdr = allocr_realloc(a, NULL, item_sz * n + sizeof(ArrHeader)); /* +1 => prevent ptr overflow */ + ArrHeader *hdr = allocr_malloc(a, item_sz * n + sizeof(ArrHeader)); hdr->len = 0; hdr->cap = n; *arr = hdr->data; } else { ArrHeader *hdr = arr_hdr(*arr); + hdr = allocr_realloc(a, hdr, item_sz * hdr->cap + sizeof(ArrHeader), item_sz * n + sizeof(ArrHeader)); hdr->cap = n; - hdr = allocr_realloc(a, hdr, item_sz * n + sizeof(ArrHeader)); if (hdr->len > hdr->cap) hdr->len = hdr->cap; *arr = hdr->data; } @@ -426,11 +426,12 @@ static void eval_expr(Evaluator *ev, Expression *e, Value *v) { case EXPR_WHILE: { Value cond; WhileExpr *w = &e->while_; - bool looped_once = false; while (1) { - eval_expr(ev, w->cond, &cond); - if (!val_truthiness(&cond, &w->cond->type)) - break; + if (w->cond) { + eval_expr(ev, w->cond, &cond); + if (!val_truthiness(&cond, &w->cond->type)) + break; + } eval_block(ev, &w->body, v); } } break; @@ -736,17 +736,23 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { e->kind = EXPR_WHILE; WhileExpr *w = &e->while_; t->token++; - Token *cond_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE, NULL); - if (!cond_end) return false; - if (!token_is_kw(cond_end, KW_LBRACE)) { - t->token = cond_end; - tokr_err(t, "Expected { to open while body."); - return false; + if (token_is_kw(t->token, KW_LBRACE)) { + /* infinite loop */ + w->cond = NULL; + } else { + Token *cond_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE, NULL); + if (!cond_end) return false; + if (!token_is_kw(cond_end, KW_LBRACE)) { + t->token = cond_end; + tokr_err(t, "Expected { to open while body."); + return false; + } + Expression *cond = parser_new_expr(p); + w->cond = cond; + + if (!parse_expr(p, cond, cond_end)) + return false; } - Expression *cond = parser_new_expr(p); - w->cond = cond; - if (!parse_expr(p, cond, cond_end)) - return false; if (!parse_block(p, &w->body)) return false; return true; } @@ -1,15 +1,15 @@ main @= fn() { - a : [('a' as u8 as f32) / 2 + 0.5 as i8 as &int as u64]int; + // a : [('a' as u8 as f32) / 2 + 0.5 as i8 as &int as u64]int; - foo := fn(x : int) int { - 7 - }; + // foo := fn(x : int) int { + // 7 + // }; - bar := foo(3); + // bar := foo(3); a238674 : [if 5 - 5 { 12 } else { 6 }]int; a2394823 : [{ 3; 7 }]int; - gfdsdgf : [ while 3 { 5 }]int; + gfdsdgf : [ while { 3 } ]int; // arr1 : ['a' as u8]int; // arr2 : [main as u64]int; // arr3 : [main as i64]int; @@ -19,31 +19,6 @@ static void allocr_test(void) { for (int i = 0; i < nbars; i++) assert(bars[i] == i); } - - int nfoos1 = 5; - int *foos = allocr_realloc(&a, NULL, (size_t)nfoos1 * sizeof(int)); - for (int i = 0; i < nfoos1; i++) - foos[i] = i; - for (int i = 0; i < nfoos1; i++) - assert(foos[i] == i); - - int nfoos2 = 10; - foos = allocr_realloc(&a, foos, (size_t)nfoos2 * sizeof(int)); - for (int i = nfoos1; i < nfoos2; i++) - foos[i] = i; - for (int i = 0; i < nfoos2; i++) - assert(foos[i] == i); - - int *arr = NULL; - int n = 1000; - for (int i = 0; i < n; i++) { - int *p = arr_adda(&arr, &a); - *p = i; - } - for (int i = 0; i < n; i++) { - assert(arr[i] == i); - } - allocr_free_all(&a); } @@ -607,12 +607,19 @@ static bool types_expr(Typer *tr, Expression *e) { case EXPR_WHILE: { WhileExpr *w = &e->while_; bool ret = true; - if (!types_expr(tr, w->cond)) + if (w->cond && !types_expr(tr, w->cond)) ret = false; if (!types_block(tr, &w->body)) ret = false; if (!ret) return false; - *t = w->body.ret_expr->type; + if (w->cond != NULL && w->body.ret_expr != NULL) { + err_print(e->where, "A finite loop can't have a return expression (for an infinite loop, use while { ... })."); + return false; + } + if (w->body.ret_expr) + *t = w->body.ret_expr->type; + else + t->kind = TYPE_VOID; } break; case EXPR_CALL: { CallExpr *c = &e->call; @@ -33,17 +33,9 @@ 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; - DynPage **dyn; - size_t dyn_len; - size_t dyn_cap; } Allocator; typedef struct { |