summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-04-22 15:04:11 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-04-22 15:04:56 -0400
commit2df588fb6ebc77d067e390e5c70c5da0298a47b2 (patch)
tree75767a5bae269ec1790a830761a04ed4dfb64fcc
parent17709633dca5cb3d2b0b34a353bdf68c112c10e4 (diff)
improved arr system
-rw-r--r--allocator.c6
-rw-r--r--cgen.c24
-rw-r--r--copy.c24
-rw-r--r--data_structures.c222
-rw-r--r--decls_cgen.c6
-rw-r--r--eval.c43
-rw-r--r--foreign.c2
-rw-r--r--identifiers.c2
-rw-r--r--instance_table.c10
-rw-r--r--main.c20
-rw-r--r--parse.c81
-rwxr-xr-xtests/test.sh5
-rw-r--r--toc.c2
-rw-r--r--tokenizer.c16
-rw-r--r--types.c170
-rw-r--r--types.h9
16 files changed, 338 insertions, 304 deletions
diff --git a/allocator.c b/allocator.c
index 8baedb5..98005ef 100644
--- a/allocator.c
+++ b/allocator.c
@@ -74,7 +74,7 @@ static void *allocr_calloc(Allocator *a, size_t n, size_t sz) {
#endif
if (n == 0 || sz == 0) return NULL;
if (a == NULL) return err_calloc(n, sz);
- /* OPTIM: use calloc */
+ /* @OPTIM: use calloc */
size_t bytes = n * sz;
void *data = allocr_malloc(a, bytes);
memset(data, 0, bytes);
@@ -88,11 +88,11 @@ static void allocr_free(Allocator *a, void *data, size_t size) {
if (a == NULL) {
free(data);
}
- /* OPTIM */
+ /* @OPTIM */
(void)size;
}
-/* OPTIM */
+/* @OPTIM */
static void *allocr_realloc(Allocator *a, void *data, size_t old_size, size_t new_size) {
#if NO_ALLOCATOR
a = NULL;
diff --git a/cgen.c b/cgen.c
index 6511ce9..08631f5 100644
--- a/cgen.c
+++ b/cgen.c
@@ -265,7 +265,7 @@ static bool cgen_fn_is_direct(CGenerator *g, Declaration *d) {
static bool fn_has_instances(FnExpr *f) {
if (fn_has_any_const_params(f)) return true;
if (!arr_len(f->params)) return false;
- return type_is_builtin(&((Declaration *)arr_last(f->params))->type, BUILTIN_VARARGS);
+ return type_is_builtin(&arr_last(f->params).type, BUILTIN_VARARGS);
}
static bool cgen_uses_ptr(Type *t) {
@@ -392,7 +392,7 @@ static void cgen_type_post(CGenerator *g, Type *t) {
cgen_type_pre(g, x);
cgen_write(g, "(*)");
cgen_type_post(g, x);
- if (x != arr_last(ret_type->tuple)) {
+ if (x != arr_last_ptr(ret_type->tuple)) {
cgen_write(g, ", ");
}
}
@@ -509,7 +509,7 @@ static void cgen_val_ptr_pre(CGenerator *g, void *v, Type *t) {
cgen_val_ptr_pre(g, (char *)s->data + (U64)i * compiler_sizeof(t->slice), t->slice);
}
cgen_type_pre(g, t->slice);
- cgen_write(g, "(d%p_[])", v); /* TODO: improve this somehow? */
+ cgen_write(g, "(d%p_[])", v); /* @TODO: improve this somehow? */
cgen_type_post(g, t->slice);
cgen_write(g, " = {");
for (I64 i = 0; i < s->len; ++i) {
@@ -865,7 +865,7 @@ static void cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
cgen_ident_id(g, id);
cgen_type_post(g, type);
cgen_write(g, "; ");
- *(IdentID *)arr_add(&underscore_ids) = id;
+ arr_add(underscore_ids, id);
}
}
}
@@ -912,7 +912,7 @@ static void cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
cgen_write(g, "&(%s%d_)", prefix, i);
}
}
- arr_clear(&underscore_ids);
+ arr_clear(underscore_ids);
cgen_writeln(g, "); ");
} break;
case EXPR_IF:
@@ -1155,7 +1155,7 @@ static void cgen_expr_pre(CGenerator *g, Expression *e) {
cgen_nl(g);
} break;
case EXPR_VAL:
- /* TODO: don't make a variable for this if it's not needed */
+ /* @TODO: don't make a variable for this if it's not needed */
if (type_is_compileonly(&e->type))
break;
if (!cgen_is_type_simple(&e->type)) {
@@ -1245,7 +1245,7 @@ static void cgen_expr(CGenerator *g, Expression *e) {
Value fn_val = *decl_val_at_index(d, index);
FnExpr *fn = fn_val.fn;
Expression fn_expr;
- /* TODO: is this all really necessary? */
+ /* @TODO: is this all really necessary? */
fn_expr.kind = EXPR_FN;
fn_expr.fn = allocr_malloc(g->allocr, sizeof *fn_expr.fn);
@@ -1784,7 +1784,7 @@ static void cgen_block(CGenerator *g, Block *b, const char *ret_name, U16 flags)
--g->indent_lvl;
if (!(flags & CGEN_BLOCK_NOBRACES)) {
cgen_deferred_from_block(g, b);
- arr_clear(&b->deferred);
+ arr_clear(b->deferred);
cgen_write(g, "}");
if (b->c.break_lbl) {
cgen_lbl(g, b->c.break_lbl);
@@ -2019,7 +2019,7 @@ static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr)
tuple_expr.type = f->ret_type;
tuple_expr.kind = EXPR_TUPLE;
tuple_expr.tuple = NULL;
- arr_set_len(&tuple_expr.tuple, arr_len(f->ret_type.tuple));
+ arr_set_len(tuple_expr.tuple, arr_len(f->ret_type.tuple));
int idx = 0;
arr_foreach(f->ret_decls, Declaration, d) {
arr_foreach(d->idents, Identifier, ident) {
@@ -2032,7 +2032,7 @@ static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr)
}
}
cgen_set_tuple(g, NULL, NULL, "*ret__", &tuple_expr);
- arr_clear(&tuple_expr.tuple);
+ arr_clear(tuple_expr.tuple);
} else if (cgen_uses_ptr(&f->ret_type)) {
Expression expr = {0};
expr.flags = EXPR_FOUND_TYPE;
@@ -2068,7 +2068,7 @@ static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr)
static void cgen_stmt(CGenerator *g, Statement *s) {
#ifdef CGEN_EMIT_LINE_NUMBER_COMMENTS
- /* TODO: add compiler option for this */
+ /* @TODO: add compiler option for this */
cgen_write(g, "/* %s:%d */", s->where.ctx->filename, s->where.line);
#endif
switch (s->kind) {
@@ -2114,7 +2114,7 @@ static void cgen_stmt(CGenerator *g, Statement *s) {
cgen_writeln(g, ";");
} break;
case STMT_DEFER:
- *(Statement **)arr_add(&g->block->deferred) = s->defer;
+ arr_add(g->block->deferred, s->defer);
break;
case STMT_USE:
case STMT_MESSAGE:
diff --git a/copy.c b/copy.c
index ec64f54..2c746a1 100644
--- a/copy.c
+++ b/copy.c
@@ -41,7 +41,7 @@ static void copy_val(Allocator *a, Value *out, Value in, Type *t) {
if (t->builtin == BUILTIN_VARARGS) {
size_t n = arr_len(in.varargs);
out->varargs = NULL;
- arr_set_lena(&out->varargs, n, a);
+ arr_set_lena(out->varargs, n, a);
for (size_t i = 0; i < n; ++i) {
Copier c = copier_create(a, NULL); /* since the type is resolved, it doesn't matter that the block is wrong */
out->varargs[i].type = copy_type_(&c, in.varargs[i].type);
@@ -100,7 +100,7 @@ static void copy_struct(Copier *c, StructDef *out, StructDef *in) {
size_t nfields = arr_len(in->fields);
out->fields = NULL;
- arr_set_lena(&out->fields, nfields, c->allocr);
+ arr_set_lena(out->fields, nfields, c->allocr);
for (size_t i = 0; i < nfields; ++i) {
Field *fout = &out->fields[i];
Field *fin = &in->fields[i];
@@ -110,7 +110,7 @@ static void copy_struct(Copier *c, StructDef *out, StructDef *in) {
}
size_t nparams = arr_len(in->params);
out->params = NULL;
- arr_set_lena(&out->params, nparams, c->allocr);
+ arr_set_lena(out->params, nparams, c->allocr);
for (size_t i = 0; i < nparams; ++i) {
copy_decl(c, &out->params[i], &in->params[i]);
}
@@ -131,7 +131,7 @@ static void copy_type(Copier *c, Type *out, Type *in) {
case TYPE_FN: {
size_t ntypes = arr_len(in->fn.types);
out->fn.types = NULL;
- arr_set_lena(&out->fn.types, ntypes, c->allocr);
+ arr_set_lena(out->fn.types, ntypes, c->allocr);
for (size_t i = 0; i < ntypes; ++i) {
copy_type(c, &out->fn.types[i], &in->fn.types[i]);
}
@@ -139,7 +139,7 @@ static void copy_type(Copier *c, Type *out, Type *in) {
case TYPE_TUPLE: {
size_t ntypes = arr_len(in->tuple);
out->tuple = NULL;
- arr_set_lena(&out->tuple, ntypes, c->allocr);
+ arr_set_lena(out->tuple, ntypes, c->allocr);
for (size_t i = 0; i < ntypes; ++i) {
copy_type(c, &out->tuple[i], &in->tuple[i]);
}
@@ -210,13 +210,13 @@ static void copy_fn_expr(Copier *c, FnExpr *fout, FnExpr *fin, U8 flags) {
size_t i;
size_t nparam_decls = arr_len(fin->params);
fout->params = NULL;
- arr_set_lena(&fout->params, nparam_decls, c->allocr);
+ arr_set_lena(fout->params, nparam_decls, c->allocr);
for (i = 0; i < nparam_decls; ++i)
copy_decl(c, fout->params + i, fin->params + i);
size_t nret_decls = arr_len(fin->ret_decls);
if (fin->ret_decls) {
fout->ret_decls = NULL;
- arr_set_lena(&fout->ret_decls, nret_decls, c->allocr);
+ arr_set_lena(fout->ret_decls, nret_decls, c->allocr);
for (i = 0; i < nret_decls; ++i)
copy_decl(c, fout->ret_decls + i, fin->ret_decls + i);
}
@@ -308,7 +308,7 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) {
copy_expr(c, cout->fn = allocr_malloc(a, sizeof *cout->fn), cin->fn);
size_t nargs = arr_len(cin->args);
cout->arg_exprs = NULL;
- arr_set_lena(&cout->args, nargs, a);
+ arr_set_lena(cout->args, nargs, a);
for (size_t i = 0; i < nargs; ++i) {
Argument *arg_in = &cin->args[i];
Argument *arg_out = &cout->args[i];
@@ -322,7 +322,7 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) {
case EXPR_TUPLE: {
size_t nexprs = arr_len(in->tuple);
out->tuple = NULL;
- arr_set_lena(&out->tuple, nexprs, a);
+ arr_set_lena(out->tuple, nexprs, a);
for (size_t i = 0; i < nexprs; ++i)
copy_expr(c, out->tuple + i, in->tuple + i);
} break;
@@ -374,7 +374,7 @@ static void copy_decl(Copier *c, Declaration *out, Declaration *in) {
copy_type(c, &out->type, &in->type);
out->idents = NULL;
size_t nidents = arr_len(in->idents);
- arr_set_lena(&out->idents, nidents, c->allocr);
+ arr_set_lena(out->idents, nidents, c->allocr);
for (size_t i = 0; i < nidents; ++i) {
out->idents[i] = in->idents[i];
assert(c->block);
@@ -399,7 +399,7 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) {
*out->inc = *in->inc;
if (in->flags & STMT_TYPED) {
size_t nstmts = arr_len(in->inc->stmts);
- arr_set_lena(&out->inc->stmts, nstmts, c->allocr);
+ arr_set_lena(out->inc->stmts, nstmts, c->allocr);
for (size_t i = 0; i < nstmts; ++i) {
copy_stmt(c, &out->inc->stmts[i], &in->inc->stmts[i]);
}
@@ -448,7 +448,7 @@ static void copy_block(Copier *c, Block *out, Block *in, U8 flags) {
out->ret_expr = copy_expr_(c, in->ret_expr);
if (!(flags & COPY_BLOCK_DONT_CREATE_IDENTS))
idents_create(&out->idents, c->allocr, out);
- arr_set_lena(&out->stmts, nstmts, c->allocr);
+ arr_set_lena(out->stmts, nstmts, c->allocr);
for (size_t i = 0; i < nstmts; ++i) {
copy_stmt(c, &out->stmts[i], &in->stmts[i]);
}
diff --git a/data_structures.c b/data_structures.c
index 9bab854..e16ea0d 100644
--- a/data_structures.c
+++ b/data_structures.c
@@ -23,7 +23,6 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
-/* OPTIM: is it faster to store void *end? */
typedef struct ArrHeader {
size_t len;
size_t cap;
@@ -31,8 +30,7 @@ typedef struct ArrHeader {
} ArrHeader;
static inline ArrHeader *arr_hdr(void *arr) {
- ArrHeader *hdr = (ArrHeader *)((char *)arr - offsetof(ArrHeader, data));
- return hdr;
+ return (ArrHeader *)((char *)arr - offsetof(ArrHeader, data));
}
static inline size_t arr_len(void *arr) {
@@ -44,96 +42,114 @@ static inline void arr_zero_(void *arr, size_t item_sz) {
memset(arr, 0, item_sz * arr_len(arr));
}
-static void arr_resv_(void **arr, size_t n, size_t item_sz) {
- if (*arr == NULL) {
- ArrHeader *hdr = err_malloc(item_sz * n + sizeof(ArrHeader) + 1); /* +1 => prevent ptr overflow */
+static WarnUnusedResult void *arr_resv_(void *arr, size_t n, size_t item_sz) {
+ ArrHeader *hdr;
+ if (arr == NULL) {
+ hdr = err_malloc(item_sz * n + sizeof(ArrHeader));
hdr->len = 0;
hdr->cap = n;
- *arr = hdr->data;
} else {
- ArrHeader *hdr = arr_hdr(*arr);
+ hdr = arr_hdr(arr);
hdr->cap = n;
- hdr = err_realloc(hdr, item_sz * n + sizeof(ArrHeader) + 1);
+ hdr = err_realloc(hdr, item_sz * n + sizeof(ArrHeader));
if (hdr->len > hdr->cap) hdr->len = hdr->cap;
- *arr = hdr->data;
}
+ return hdr->data;
}
-static void arr_resva_(void **arr, size_t n, size_t item_sz, Allocator *a) {
- if (*arr == NULL) {
- ArrHeader *hdr = allocr_malloc(a, item_sz * n + sizeof(ArrHeader));
+static WarnUnusedResult void *arr_resva_(void *arr, size_t n, size_t item_sz, Allocator *a) {
+ ArrHeader *hdr;
+ if (arr == NULL) {
+ 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 = arr_hdr(arr);
hdr = allocr_realloc(a, hdr, item_sz * hdr->cap + sizeof(ArrHeader), item_sz * n + sizeof(ArrHeader));
hdr->cap = n;
if (hdr->len > hdr->cap) hdr->len = hdr->cap;
- *arr = hdr->data;
- }
+ }
+ return hdr->data;
}
-static void arr_clear_(void **arr) {
- if (*arr) {
- free(arr_hdr(*arr));
- *arr = NULL;
+
+/* accommodate one more element if necessary */
+static WarnUnusedResult void *arr_grow(void *arr, size_t item_sz) {
+ ArrHeader *hdr;
+ if (arr == NULL) {
+ hdr = err_malloc(sizeof *hdr + item_sz);
+ hdr->len = 0;
+ hdr->cap = 1;
+ } else {
+ hdr = arr_hdr(arr);
+ if (hdr->len >= hdr->cap) {
+ size_t new_size = sizeof *hdr + item_sz * (hdr->cap *= 2);
+ hdr = err_realloc(hdr, new_size);
+ }
}
+ return hdr->data;
}
-static void arr_cleara_(void **arr, size_t size, Allocator *allocr) {
- if (*arr) {
- ArrHeader *header = arr_hdr(*arr);
+static WarnUnusedResult void *arr_growa(void *arr, size_t item_sz, Allocator *allocr) {
+ ArrHeader *hdr;
+ if (arr == NULL) {
+ hdr = allocr_malloc(allocr, sizeof *hdr + item_sz);
+ hdr->len = 0;
+ hdr->cap = 1;
+ } else {
+ hdr = arr_hdr(arr);
+ if (hdr->len >= hdr->cap) {
+ size_t old_size = sizeof *hdr + item_sz * hdr->cap;
+ size_t new_size = sizeof *hdr + item_sz * hdr->cap * 2;
+ hdr = allocr_realloc(allocr, hdr, old_size, new_size);
+ hdr->cap *= 2;
+ }
+ }
+ return hdr->data;
+}
+
+static WarnUnusedResult void *arr_clear_(void *arr) {
+ if (arr) {
+ free(arr_hdr(arr));
+ }
+ return NULL;
+}
+
+static WarnUnusedResult void *arr_cleara_(void *arr, size_t size, Allocator *allocr) {
+ if (arr) {
+ ArrHeader *header = arr_hdr(arr);
allocr_free(allocr, header, header->cap * size);
- *arr = NULL;
}
+ return NULL;
}
-static void arr_set_len_(void **arr, size_t n, size_t item_sz) {
+static WarnUnusedResult void *arr_set_len_(void *arr, size_t n, size_t item_sz) {
if (n == 0) {
- arr_clear_(arr);
- return;
+ return arr_clear_(arr);
}
- if (n > arr_len(*arr)) {
- arr_resv_(arr, n, item_sz);
+ if (n > arr_len(arr)) {
+ arr = arr_resv_(arr, n, item_sz);
}
- arr_hdr(*arr)->len = n;
- /* OPTIM: shrink */
+ arr_hdr(arr)->len = n;
+ /* @OPTIM: shrink */
+ return arr;
}
-static void arr_set_lena_(void **arr, size_t n, size_t item_sz, Allocator *a) {
+static WarnUnusedResult void *arr_set_lena_(void *arr, size_t n, size_t item_sz, Allocator *a) {
if (n == 0) {
- arr_cleara_(arr, item_sz, a);
- return;
+ return arr_cleara_(arr, item_sz, a);
}
- arr_resva_(arr, n, item_sz, a);
- arr_hdr(*arr)->len = n;
+ arr = arr_resva_(arr, n, item_sz, a);
+ arr_hdr(arr)->len = n;
+ return arr;
}
-static void *arr_add_(void **arr, size_t item_sz) {
- ArrHeader *hdr;
- if (*arr == NULL) {
- arr_resv_(arr, 1, item_sz);
- hdr = arr_hdr(*arr);
- } else {
- hdr = arr_hdr(*arr);
- if (hdr->len >= hdr->cap) {
- arr_resv_(arr, hdr->len * 2 + 1, item_sz);
- hdr = arr_hdr(*arr);
- }
- }
+static void *arr_add_ptr_(void **arr, size_t item_sz) {
+ *arr = arr_grow(*arr, item_sz);
+ ArrHeader *hdr = arr_hdr(*arr);
return &(((char *)hdr->data)[(hdr->len++) * item_sz]);
}
-static void *arr_adda_(void **arr, size_t item_sz, Allocator *a) {
- ArrHeader *hdr;
- if (*arr == NULL) {
- arr_resva_(arr, 10, item_sz, a);
- hdr = arr_hdr(*arr);
- } else {
- hdr = arr_hdr(*arr);
- if (hdr->len >= hdr->cap) {
- arr_resva_(arr, hdr->len * 2 + 1, item_sz, a);
- hdr = arr_hdr(*arr);
- }
- }
+static void *arr_adda_ptr_(void **arr, size_t item_sz, Allocator *a) {
+ *arr = arr_growa(*arr, item_sz, a);
+ ArrHeader *hdr = arr_hdr(*arr);
return &(((char *)hdr->data)[(hdr->len++) * item_sz]);
}
@@ -156,35 +172,35 @@ static void *arr_end_(void *arr, size_t item_sz) {
}
}
-/* OPTIM: shrink array */
-static void arr_remove_last_(void **arr) {
- assert(arr_hdr(*arr)->len);
- if (--arr_hdr(*arr)->len == 0) {
- arr_clear_(arr);
+/* @OPTIM: shrink array */
+static WarnUnusedResult void *arr_remove_last_(void *arr) {
+ assert(arr_hdr(arr)->len);
+ if (--arr_hdr(arr)->len == 0) {
+ return arr_clear_(arr);
}
+ return arr;
}
-static void arr_remove_lasta_(void **arr, size_t item_sz, Allocator *a) {
- assert(arr_hdr(*arr)->len);
- if (--arr_hdr(*arr)->len == 0) {
- arr_cleara_(arr, item_sz, a);
+static WarnUnusedResult void *arr_remove_lasta_(void *arr, size_t item_sz, Allocator *a) {
+ assert(arr_hdr(arr)->len);
+ if (--arr_hdr(arr)->len == 0) {
+ return arr_cleara_(arr, item_sz, a);
}
+ return arr;
}
-static void arr_copya_(void **out, void *in, size_t item_sz, Allocator *a) {
+static WarnUnusedResult void *arr_copya_(void *out, void *in, size_t item_sz, Allocator *a) {
size_t len = arr_len(in);
- arr_resva_(out, len, item_sz, a);
- memcpy(*out, in, len * item_sz);
+ out = arr_resva_(out, len, item_sz, a);
+ memcpy(out, in, len * item_sz);
+ return out;
}
-#ifdef __GNUC__
-#define typeof __typeof__
-#endif
-
#if defined(__GNUC__) || defined(__TINYC__)
#define HAS_TYPEOF 1
+#define typeof __typeof__
#endif
#if HAS_TYPEOF
@@ -193,38 +209,42 @@ this is to cast the return value of arr_add so that gcc produces a warning if yo
do something like:
float *arr = NULL;
// ...
-int *x = arr_add(&arr);
+int *x = arr_add_ptr(&arr);
You shouldn't rely on this, though, e.g. by doing
-*arr_add(&arr) = 17;
+*arr_add_ptr(&arr) = 17;
*/
-#define arr_ptr_type(arr) __typeof__(*(arr))
+#define arr_ptr_type(arr) typeof(arr)
#else
#define arr_ptr_type(arr) void *
#endif
#define arr_zero(arr) arr_zero_(arr, sizeof *(arr))
-#define arr_add(arr) (arr_ptr_type(arr))arr_add_((void **)(arr), sizeof **(arr))
-#define arr_adda(arr, allocr) (arr_ptr_type(arr))arr_adda_((void **)(arr), sizeof **(arr), (allocr))
-#define arr_resv(arr, n) arr_resv_((void **)(arr), n, sizeof **(arr))
-#define arr_resva(arr, n, allocr) arr_resva_((void **)(arr), n, sizeof **(arr), (allocr))
-#define arr_set_len(arr, n) arr_set_len_((void **)(arr), n, sizeof **(arr))
-#define arr_set_lena(arr, n, a) arr_set_lena_((void **)(arr), n, sizeof **(arr), (a))
-#define arr_clear(arr) arr_clear_((void **)(arr)), (void)sizeof **arr /* second part makes sure most of the time that you don't accidentally call it without taking the address */
-#define arr_cleara(arr, allocr) arr_cleara_((void **)(arr), sizeof **(arr), (allocr))
-#define arr_last(arr) arr_last_((void *)(arr), sizeof *(arr))
+#define arr_add(arr, x) arr = arr_grow((arr), sizeof *(arr)), (arr)[arr_hdr(arr)->len++] = x
+#define arr_add_ptr(arr) (arr_ptr_type(arr))arr_add_ptr_((void **)(&arr), sizeof *(arr))
+#define arr_adda(arr, x, allocr) arr = arr_growa((arr), sizeof *(arr), (allocr)), (arr)[arr_hdr(arr)->len++] = x
+#define arr_adda_ptr(arr, allocr) (arr_ptr_type(arr))arr_adda_ptr_((void **)(&arr), sizeof *(arr), (allocr))
+#define arr_resv(arr, n) arr = arr_resv_((arr), n, sizeof *(arr))
+#define arr_resva(arr, n, allocr) arr = arr_resva_((arr), n, sizeof *(arr), (allocr))
+#define arr_set_len(arr, n) arr = arr_set_len_((arr), n, sizeof *(arr))
+#define arr_set_lena(arr, n, allocr) arr = arr_set_lena_((arr), n, sizeof *(arr), (allocr))
+#define arr_clear(arr) arr = arr_clear_(arr)
+#define arr_cleara(arr, allocr) arr = arr_cleara_((arr), sizeof *(arr), (allocr))
+#define arr_last(arr) arr[arr_len(arr)-1]
+#define arr_last_ptr(arr) arr_last_((arr), sizeof *(arr))
/* one past last, or NULL if empty */
-#define arr_end(arr) arr_end_((void *)(arr), sizeof *(arr))
+#define arr_end(arr) arr_end_((arr), sizeof *(arr))
#define arr_foreach(arr, type, var) for (type *var = (arr), *var##_foreach_end = arr_end(arr); var != var##_foreach_end; ++var)
-#define arr_foreach_reversed(arr, type, var) for (type *var = arr_last(arr), *var##_foreach_last = arr; var; var = var == var##_foreach_last ? NULL : (var-1))
-#define arr_remove_last(arr) arr_remove_last_((void **)(arr)), (void)sizeof **(arr)
-#define arr_remove_lasta(arr, a) arr_remove_lasta_((void **)(arr), sizeof **(arr), (a))
-#define arr_copya(out, in, a) do { assert(sizeof *(in) == sizeof **(out)); arr_copya_((void **)(out), (in), sizeof **(out), (a)); } while(0)
+#define arr_foreach_reversed(arr, type, var) for (type *var = arr_last_ptr(arr), *var##_foreach_last = arr; var; var = var == var##_foreach_last ? NULL : (var-1))
+#define arr_remove_last(arr) arr = arr_remove_last_(arr)
+#define arr_remove_lasta(arr, allocr) arr = arr_remove_lasta_((arr), sizeof *(arr), (allocr))
+#define arr_copya(out, in, allocr) do { assert(sizeof *(in) == sizeof *(out)); out = arr_copya_((out), (in), sizeof *(out), (allocr)); } while(0)
-#ifdef RUN_TESTS
+#if RUN_TESTS
+/* @TODO(eventually): more extensive test? */
static void arr_test(void) {
int *foos = NULL;
for (int i = 0; i < 10; ++i) {
- *(int *)arr_add(&foos) = i;
+ arr_add(foos, i);
}
for (int i = 0; i < (int)arr_len(foos); ++i) {
assert(foos[i] == i);
@@ -234,7 +254,7 @@ static void arr_test(void) {
assert(*x == lastx + 1);
lastx = *x;
}
- arr_clear(&foos);
+ arr_clear(foos);
}
#endif
@@ -281,7 +301,7 @@ static void str_hash_table_grow(StrHashTable *t) {
if (slots_cap <= 2 * t->nentries) {
StrHashTableSlot **new_slots = NULL;
size_t new_slots_cap = slots_cap * 2 + 10;
- arr_set_lena(&new_slots, new_slots_cap, t->allocr);
+ arr_set_lena(new_slots, new_slots_cap, t->allocr);
arr_zero(new_slots);
arr_foreach(t->slots, StrHashTableSlotPtr, slotp) {
StrHashTableSlot *slot = *slotp;
@@ -291,7 +311,7 @@ static void str_hash_table_grow(StrHashTable *t) {
*new_slot = slot;
}
}
- arr_cleara(&t->slots, t->allocr);
+ arr_cleara(t->slots, t->allocr);
t->slots = new_slots;
}
}
@@ -341,7 +361,7 @@ static void str_hash_table_free(StrHashTable *t) {
arr_foreach(t->slots, StrHashTableSlotPtr, slotp) {
allocr_free(t->allocr, *slotp, str_hash_table_slot_size(t));
}
- arr_cleara(&t->slots, t->allocr);
+ arr_cleara(t->slots, t->allocr);
}
static StrHashTableSlot *str_hash_table_get_(StrHashTable *t, const char *str, size_t len) {
@@ -357,7 +377,7 @@ static inline void *str_hash_table_get(StrHashTable *t, const char *str, size_t
return slot->data;
}
-#ifdef RUN_TESTS
+#if RUN_TESTS
static void str_hash_table_test(void) {
StrHashTable t;
str_hash_table_create(&t, sizeof(int), NULL);
diff --git a/decls_cgen.c b/decls_cgen.c
index 78f51a3..736df03 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -81,14 +81,14 @@ static void cgen_sdecls_expr(CGenerator *g, Expression *e) {
case EXPR_NMS: {
char *prefix_part = cgen_nms_prefix_part(g, e->nms);
size_t prefix_part_len = strlen(prefix_part);
- char const *prev_prefix = g->nms_prefixes ? *(char const **)arr_last(g->nms_prefixes)
+ char const *prev_prefix = g->nms_prefixes ? arr_last(g->nms_prefixes)
: "";
size_t prev_prefix_len = strlen(prev_prefix);
char *new_prefix = cgen_malloc(g, prev_prefix_len + prefix_part_len + 1);
memcpy(new_prefix, prev_prefix, prev_prefix_len);
memcpy(new_prefix + prev_prefix_len, prefix_part, prefix_part_len);
free(prefix_part);
- *(char const **)arr_add(&g->nms_prefixes) = new_prefix;
+ arr_add(g->nms_prefixes, new_prefix);
new_prefix[prev_prefix_len + prefix_part_len] = 0;
e->nms->c.prefix = new_prefix;
} break;
@@ -98,7 +98,7 @@ static void cgen_sdecls_expr(CGenerator *g, Expression *e) {
cgen_recurse_subexprs(g, e, cgen_sdecls_expr, cgen_sdecls_block, cgen_sdecls_decl);
}
if (e->kind == EXPR_NMS) {
- arr_remove_last(&g->nms_prefixes);
+ arr_remove_last(g->nms_prefixes);
}
}
diff --git a/eval.c b/eval.c
index 55c8db6..cb74e0f 100644
--- a/eval.c
+++ b/eval.c
@@ -205,7 +205,7 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) {
}
break;
case TYPE_FN:
- fprintf(f, "<function @ %p>", (void *)*(FnExpr **)p);
+ fprintf(f, "<function %p>", (void *)*(FnExpr **)p);
break;
case TYPE_TUPLE: {
Value *tuple = *(Value **)p;
@@ -217,7 +217,7 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) {
fprintf(f, ")");
} break;
case TYPE_ARR: {
- fprintf(f, "["); /* TODO: change? when array initializers are added */
+ fprintf(f, "["); /* @TODO: change? when array initializers are added */
size_t n = t->arr.n;
if (n > 5) n = 5;
for (size_t i = 0; i < n; ++i) {
@@ -233,7 +233,7 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) {
fprintf(f, "<pointer: %p>", *(void **)p);
break;
case TYPE_SLICE: {
- fprintf(f, "["); /* TODO: change? when slice initializers are added */
+ fprintf(f, "["); /* @TODO: change? when slice initializers are added */
Slice slice = *(Slice *)p;
I64 n = slice.len;
if (n > 5) n = 5;
@@ -247,7 +247,7 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) {
fprintf(f, "]");
} break;
case TYPE_STRUCT:
- fprintf(f, "["); /* TODO: change? when struct initializers are added */
+ fprintf(f, "["); /* @TODO: change? when struct initializers are added */
arr_foreach(t->struc->fields, Field, fi) {
if (fi != t->struc->fields)
fprintf(f, ", ");
@@ -670,7 +670,7 @@ static Value *ident_val(Evaluator *ev, Identifier i, Location where) {
return NULL; /* silently fail (something went wrong when we typed this decl) */
if (decl->flags & DECL_IS_PARAM) {
if (decl->val_stack) {
- Value *valp = *(Value **)arr_last(decl->val_stack);
+ Value *valp = arr_last(decl->val_stack);
if (arr_len(decl->idents) > 1)
return &valp->tuple[idx];
else
@@ -693,7 +693,7 @@ static Value *ident_val(Evaluator *ev, Identifier i, Location where) {
} else if (decl->flags & DECL_IS_CONST) {
return decl_val_at_index(decl, idx);
} else if (decl->val_stack) {
- Value *valp = *(Value **)arr_last(decl->val_stack);
+ Value *valp = arr_last(decl->val_stack);
if (arr_len(decl->idents) > 1)
return &valp->tuple[idx];
else
@@ -1041,8 +1041,8 @@ static Status eval_ident(Evaluator *ev, Identifier ident, Value *v, Location whe
}
static Value *decl_add_val(Declaration *d) {
- Value **valpp = arr_add(&d->val_stack);
- Value *valp = *valpp = err_malloc(sizeof *valp);
+ Value *valp = err_malloc(sizeof *valp);
+ arr_add(d->val_stack, valp);
if (arr_len(d->idents) > 1) {
valp->tuple = err_malloc(arr_len(d->idents) * sizeof *valp->tuple);
}
@@ -1051,8 +1051,7 @@ static Value *decl_add_val(Declaration *d) {
static void decl_remove_val(Declaration *d) {
assert(arr_len(d->val_stack));
- Value **valpp = arr_last(d->val_stack);
- Value *valp = *valpp;
+ Value *valp = arr_last(d->val_stack);
if (arr_len(d->idents) == 1 || d->type.kind == TYPE_TUPLE) {
val_free_ptr(valp, &d->type);
} else {
@@ -1062,7 +1061,7 @@ static void decl_remove_val(Declaration *d) {
free(valp->tuple);
free(valp);
}
- arr_remove_last(&d->val_stack);
+ arr_remove_last(d->val_stack);
}
static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
@@ -1252,8 +1251,8 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
case EXPR_FOR: {
ForExpr *fo = e->for_;
Declaration *header = &fo->header;
- Value **for_valpp = arr_add(&header->val_stack);
- Value *for_valp = *for_valpp = err_malloc(sizeof *for_valp);
+ Value *for_valp = err_malloc(sizeof *for_valp);
+ arr_add(header->val_stack, for_valp);
/* make a tuple */
Value for_val_tuple[2];
for_valp->tuple = for_val_tuple;
@@ -1353,7 +1352,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
++index->i64;
}
}
- arr_remove_last(&header->val_stack);
+ arr_remove_last(header->val_stack);
free(for_valp);
} break;
case EXPR_BLOCK:
@@ -1435,7 +1434,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
/* set varargs */
pval->varargs = NULL;
for (; arg != args_end; ++arg) {
- VarArg *varg = arr_add(&pval->varargs);
+ VarArg *varg = arr_add_ptr(pval->varargs);
if (!eval_expr(ev, arg, &varg->val))
return false;
varg->type = &arg->type;
@@ -1495,7 +1494,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
expr.ident = *ident;
if (!eval_expr(ev, &expr, &this_one))
return false;
- Value *element = arr_add(&tuple);
+ Value *element = arr_add_ptr(tuple);
Type *type = decl_type_at_index(d, i);
copy_val(NULL, element, this_one, type);
++i;
@@ -1503,7 +1502,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
}
if (arr_len(tuple) == 1) {
*v = tuple[0];
- arr_clear(&tuple);
+ arr_clear(tuple);
} else {
v->tuple = tuple;
}
@@ -1544,7 +1543,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
} else {
to = n;
}
- /* TODO: is this the best check? (Go also checks if from > to) */
+ /* @TODO: is this the best check? (Go also checks if from > to) */
if (to > n) {
err_print(e->where, "Slice index out of bounds (to = %lu, length = %lu).", (unsigned long)to, (unsigned long)n);
return false;
@@ -1665,7 +1664,7 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) {
break;
case STMT_INCLUDE: {
Include *i = stmt->inc;
- Statement *last_reached = arr_last(i->stmts);
+ Statement *last_reached = arr_last_ptr(i->stmts);
arr_foreach(i->stmts, Statement, sub) {
if (!eval_stmt(ev, sub))
return false;
@@ -1679,7 +1678,7 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) {
case STMT_MESSAGE:
break;
case STMT_DEFER:
- *(Statement **)arr_add(&ev->typer->block->deferred) = stmt->defer;
+ arr_add(ev->typer->block->deferred, stmt->defer);
break;
case STMT_USE:
break;
@@ -1692,7 +1691,7 @@ static Status eval_block(Evaluator *ev, Block *b, Value *v) {
ev->typer->block = b;
b->deferred = NULL;
bool success = true;
- Statement *last_reached = arr_last(b->stmts);
+ Statement *last_reached = arr_last_ptr(b->stmts);
arr_foreach(b->stmts, Statement, stmt) {
if (!eval_stmt(ev, stmt)) {
success = false;
@@ -1735,7 +1734,7 @@ static Status eval_block(Evaluator *ev, Block *b, Value *v) {
if (!eval_stmt(ev, stmt))
return false;
}
- arr_clear(&b->deferred);
+ arr_clear(b->deferred);
ev->returning = return_block;
ev->ret_val = return_val;
}
diff --git a/foreign.c b/foreign.c
index 6e25a77..788f87b 100644
--- a/foreign.c
+++ b/foreign.c
@@ -200,7 +200,7 @@ static bool arg_list_add(av_alist *arg_list, Value val, Type *type, Location whe
case TYPE_VOID:
case TYPE_TUPLE:
case TYPE_UNKNOWN:
- case TYPE_ARR: { /* TODO: maybe just pass pointer for arr? */
+ case TYPE_ARR: { /* @TODO: maybe just pass pointer for arr? */
char *s = type_to_str(type);
err_print(where, "Cannot pass type %s to foreign function.", s);
free(s);
diff --git a/identifiers.c b/identifiers.c
index bb30e36..2daa112 100644
--- a/identifiers.c
+++ b/identifiers.c
@@ -181,7 +181,7 @@ static inline Block *ident_scope(Identifier i) {
return i->idents->scope;
}
-#ifdef RUN_TESTS
+#if RUN_TESTS
static void idents_test(void) {
Identifiers ids;
char b[] = "foo_variable bar";
diff --git a/instance_table.c b/instance_table.c
index 6a06f4b..924ac1d 100644
--- a/instance_table.c
+++ b/instance_table.c
@@ -4,7 +4,7 @@
You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>.
*/
/*
- TODO: better hash functions, especially for integers
+ @TODO: better hash functions, especially for integers
(right now, nearby integers are close together in hash
space, which is bad with the way these hash tables
are designed)
@@ -22,7 +22,7 @@ static bool val_eq(Value u, Value v, Type *t);
static bool type_eq_exact(Type *t1, Type *t2);
static U64 f32_hash(F32 f) {
- /* OPTIM */
+ /* @OPTIM */
U64 hash = 0;
if (f < 0) {
hash = 0x9a6db29edcba8af4;
@@ -48,7 +48,7 @@ static U64 f32_hash(F32 f) {
}
static U64 f64_hash(F64 f) {
- /* OPTIM */
+ /* @OPTIM */
U64 hash = 0;
if (f < 0) {
hash = 0x9a6db29edcba8af4;
@@ -306,7 +306,7 @@ static bool val_eq(Value u, Value v, Type *t) {
and set already_exists accordingly
make sure v's data remains valid
*/
-/* OPTIM: store instances in a block array (remember that the pointers need to stay valid!) */
+/* @OPTIM: store instances in a block array (remember that the pointers need to stay valid!) */
static Instance *instance_table_adda(Allocator *a, HashTable *h, Value v, Type *t,
bool *already_exists) {
if (h->n * 2 >= h->cap) {
@@ -318,7 +318,7 @@ static Instance *instance_table_adda(Allocator *a, HashTable *h, Value v, Type *
for (U64 i = 0; i < h->cap; ++i) {
/* re-hash */
if (old_occupied[i]) {
- /* OPTIM: keep hashes around */
+ /* @OPTIM: keep hashes around */
U64 index = val_hash(old_data[i]->val, t) % new_cap;
while (new_occupied[index]) {
++index;
diff --git a/main.c b/main.c
index 24b1c79..38a014e 100644
--- a/main.c
+++ b/main.c
@@ -7,9 +7,8 @@
/* see development.md for development information */
/*
-TODO:
-arr_add_val
-arr_last_val
+@TODO:
+arr_add-val
test for use ...
test used ret decls
consider: don't do inference for function calls; get rid of was_expr -- now that we have struct params
@@ -19,6 +18,9 @@ use
- use with struct members (e.g. SuperPoint ::= struct { use p: Point; })
maybe change to #define check(x) do { if_unlikely(x) return 0; } while (0);
always use pointers in cgen'd non-range for loops (sometimes also indices)
+test:
+ _ := 5;
+ _ := 6;
is there a problem where we can get TYPE_UNKNOWN in cgen, triggering an assert(0)?
-simple example, but maybe try other stuff: x := #C("5");
-also make sure you can't do x:#C("5");
@@ -39,6 +41,7 @@ X ::= newtype(int); or something
any odd number of "s for a string
use point #except x;
optional -Wshadow
+format errors so that vim/emacs can jump to them
---
make sure that floating point literals are exact as possible
have some way of doing Infinity and s/qNaN (you can
@@ -46,6 +49,8 @@ make sure that floating point literals are exact as possible
once you have a bunch of test code:
- analyze memory usage by secretly passing __FILE__, __LINE__ to allocr_m/c/realloc
- try making more Expression members pointers
+- should val_stack be on the allocator? what about temporary arrays?
+ -->on the contrary, should in_decls be off the allocator?
- branch data: #define if(x) bool join(cond, __LINE__) = x; register_branch(__FILE__, __LINE__, cond); if (join(cond, __LINE__))
error on x ::= {return; 3}
struct param inference
@@ -65,9 +70,9 @@ passing untyped expressions to macros
#include "toc.c"
#if defined TOC_DEBUG && defined __GNU_LIBRARY__ && defined UNISTD_AVAILABLE
-#define BACKTRACE
+#define BACKTRACE 1
#endif
-#ifdef BACKTRACE
+#if BACKTRACE
#include <signal.h>
#include <execinfo.h>
@@ -104,12 +109,12 @@ static void signal_handler(int num) {
}
#endif
int main(int argc, char **argv) {
-#ifdef BACKTRACE
+#if BACKTRACE
program_name = argv[0];
signal(SIGABRT, signal_handler);
signal(SIGSEGV, signal_handler);
#endif
-#ifdef RUN_TESTS
+#if RUN_TESTS
printf("running tests...\n");
test_all();
#endif
@@ -233,4 +238,3 @@ int main(int argc, char **argv) {
fclose(out);
return 0;
}
-
diff --git a/parse.c b/parse.c
index 8b95aa4..47ea5bf 100644
--- a/parse.c
+++ b/parse.c
@@ -253,7 +253,7 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) {
if (def->params) {
written += str_copy(buffer + written, bufsize - written, "(");
arr_foreach(def->params, Declaration, param) {
- /* TODO: val to str */
+ /* @TODO: val to str */
if (param != def->params)
written += str_copy(buffer + written, bufsize - written, ", ");
written += str_copy(buffer + written, bufsize - written, "<argument>");
@@ -297,7 +297,7 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) {
return written;
}
case TYPE_EXPR:
- /* TODO: improve this... we're gonna need expr_to_str ): */
+ /* @TODO: improve this... we're gonna need expr_to_str ): */
return str_copy(buffer, bufsize, "<type expression>");
}
@@ -330,11 +330,10 @@ static inline void parser_put_end(Parser *p, Location *l) {
parser_set_end_to_token(p, l, p->tokr->token);
}
-static inline void *parser_arr_add_(Parser *p, void **a, size_t sz) {
- return arr_adda_(a, sz, p->allocr);
-}
-
-#define parser_arr_add(p, a) parser_arr_add_(p, (void **)(a), sizeof **(a))
+#define parser_arr_add_ptr(p, a) arr_adda_ptr(a, p->allocr)
+#define parser_arr_add(p, a, x) arr_adda(a, x, p->allocr)
+#define parser_arr_set_len(p, a, l) arr_set_lena(a, l, p->allocr)
+#define parser_arr_remove_last(p, a) arr_remove_lasta(a, p->allocr)
static inline void *parser_malloc(Parser *p, size_t bytes) {
return allocr_malloc(p->allocr, bytes);
@@ -424,14 +423,14 @@ static Token *expr_find_end(Parser *p, ExprEndFlags flags) {
}
if (token->kind == TOKEN_EOF) {
if (brace_level > 0) {
- tokr_err(t, "Opening brace { was never closed."); /* TODO: Find out where this is */
+ tokr_err(t, "Opening brace { was never closed."); /* @TODO: Find out where this is */
} else if (paren_level > 0) {
tokr_err(t, "Opening parenthesis ( was never closed.");
} else if (square_level > 0) {
tokr_err(t, "Opening square bracket [ was never closed.");
} else {
tokr_err(t, "Could not find end of expression (did you forget a semicolon?).");
- /* TODO: ? improve err message */
+ /* @TODO: ? improve err message */
}
t->token = token; /* don't try to continue */
return NULL;
@@ -455,7 +454,7 @@ static Status parse_args(Parser *p, Argument **args) {
info_print(token_location(p->file, start), "This is where the argument list starts.");
return false;
}
- Argument *arg = parser_arr_add(p, args);
+ Argument *arg = parser_arr_add_ptr(p, *args);
arg->where = parser_mk_loc(p);
/* named arguments */
if (t->token->kind == TOKEN_IDENT && token_is_kw(t->token + 1, KW_EQ)) {
@@ -485,7 +484,7 @@ static void correct_ret_type(Parser *p, Type *ret_type) {
size_t ntuple_members = arr_len(tuple_members);
ret_type->kind = TYPE_TUPLE;
ret_type->tuple = NULL;
- arr_set_lena(&ret_type->tuple, ntuple_members, p->allocr);
+ parser_arr_set_len(p, ret_type->tuple, ntuple_members);
for (size_t i = 0; i < ntuple_members; ++i) {
Type *out_type = &ret_type->tuple[i];
out_type->flags = 0;
@@ -525,11 +524,11 @@ static Status parse_type(Parser *p, Type *type, Location *where) {
tokr_err(t, "Expected ( to follow fn.");
return false;
}
- parser_arr_add(p, &type->fn.types); /* add return type */
+ parser_arr_add_ptr(p, type->fn.types); /* add return type */
++t->token;
if (!token_is_kw(t->token, KW_RPAREN)) {
while (1) {
- Type *param_type = parser_arr_add(p, &type->fn.types);
+ Type *param_type = parser_arr_add_ptr(p, type->fn.types);
Location type_where;
if (!parse_type(p, param_type, &type_where)) return false;
if (token_is_kw(t->token, KW_RPAREN))
@@ -623,7 +622,7 @@ static Status parse_type(Parser *p, Type *type, Location *where) {
goto struct_fail;
}
if ((param->flags & DECL_ANNOTATES_TYPE) && type_is_builtin(&param->type, BUILTIN_VARARGS)) {
- /* TODO(eventually) */
+ /* @TODO(eventually) */
err_print(param->where, "structs cannot have varargs parameters (yet).");
goto struct_fail;
}
@@ -823,14 +822,14 @@ static Status parse_block(Parser *p, Block *b, U8 flags) {
if (!token_is_kw(t->token, KW_RBRACE)) {
/* non-empty block */
while (1) {
- Statement *stmt = parser_arr_add(p, &b->stmts);
+ Statement *stmt = parser_arr_add_ptr(p, b->stmts);
bool was_a_statement;
bool success = parse_stmt(p, stmt, &was_a_statement);
if (!success) {
ret = false;
}
if (!was_a_statement) {
- arr_remove_lasta(&b->stmts, p->allocr);
+ parser_arr_remove_last(p, b->stmts);
}
if (token_is_kw(t->token, KW_RBRACE)) {
break;
@@ -861,7 +860,7 @@ static Status parse_decl_list(Parser *p, Declaration **decls, U16 flags) {
!token_is_kw(t->token - 1, KW_RPAREN) &&
!token_is_kw(t->token - 1, KW_LBRACE)))) {
first = false;
- Declaration *decl = parser_arr_add(p, decls);
+ Declaration *decl = parser_arr_add_ptr(p, *decls);
if (!parse_decl(p, decl, flags)) {
ret = false;
/* skip to end of list */
@@ -873,13 +872,19 @@ static Status parse_decl_list(Parser *p, Declaration **decls, U16 flags) {
/* split this declaration */
size_t nidents = arr_len(decl->idents);
for (size_t i = 1; i < nidents; ++i) {
- Declaration *new_decl = parser_arr_add(p, decls);
+ Declaration *new_decl = parser_arr_add_ptr(p, *decls);
*new_decl = *decl;
new_decl->idents = NULL;
- arr_set_lena(&new_decl->idents, 1, p->allocr);
+ parser_arr_set_len(p, new_decl->idents, 1);
new_decl->idents[0] = decl->idents[i];
}
- arr_set_lena(&decl->idents, 1, p->allocr);
+ parser_arr_set_len(p, decl->idents, 1);
+ }
+ }
+ /* correct ident decls because the pointers to declarations might have changed */
+ arr_foreach(*decls, Declaration, decl) {
+ arr_foreach(decl->idents, Identifier, ident) {
+ (*ident)->decl = decl;
}
}
return ret;
@@ -1470,8 +1475,10 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
FnType *fn_type = &fn_t->fn;
fn_type->constness = NULL;
fn_type->types = NULL;
- Type *ret_type = parser_arr_add(p, &fn_type->types);
- CType *ret_ctype = parser_arr_add(p, &fn->foreign.ctypes);
+ /* reserve space for return type (Type + CType) */
+ parser_arr_add_ptr(p, fn_type->types);
+ parser_arr_add_ptr(p, fn->foreign.ctypes);
+
Expression *name = fn->foreign.name_expr = parser_new_expr(p);
if (!parse_expr(p, name, expr_find_end(p, EXPR_CAN_END_WITH_COMMA)))
@@ -1506,8 +1513,8 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
}
++t->token;
while (!token_is_kw(t->token, KW_RPAREN)) {
- Type *type = parser_arr_add(p, &fn_type->types);
- CType *ctype = parser_arr_add(p, &fn->foreign.ctypes);
+ Type *type = parser_arr_add_ptr(p, fn_type->types);
+ CType *ctype = parser_arr_add_ptr(p, fn->foreign.ctypes);
if (!parse_c_type(p, ctype, type)) {
return false;
}
@@ -1521,6 +1528,9 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
return false;
}
}
+
+ Type *ret_type = &fn_type->types[0];
+ CType *ret_ctype = &fn->foreign.ctypes[0];
if (t->token == end) {
/* void */
ret_ctype->kind = CTYPE_NONE;
@@ -1765,14 +1775,14 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
if (lhs.kind == EXPR_TUPLE) {
e->tuple = lhs.tuple;
} else {
- *(Expression *)parser_arr_add(p, &e->tuple) = lhs;
+ parser_arr_add(p, e->tuple, lhs);
}
if (rhs.kind == EXPR_TUPLE) {
arr_foreach(rhs.tuple, Expression, r) {
- *(Expression *)parser_arr_add(p, &e->tuple) = *r;
+ parser_arr_add(p, e->tuple, *r);
}
} else {
- *(Expression *)parser_arr_add(p, &e->tuple) = rhs;
+ parser_arr_add(p, e->tuple, rhs);
}
goto success;
}
@@ -2042,7 +2052,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
e->kind = EXPR_BLOCK;
if (!parse_block(p, e->block = parser_malloc(p, sizeof *e->block), 0)) return false;
if (t->token != end) {
- tokr_err(t, "Expression continues after end of block."); /* TODO: improve this err message */
+ tokr_err(t, "Expression continues after end of block."); /* @TODO: improve this err message */
return false;
}
goto success;
@@ -2114,14 +2124,13 @@ static Status parse_decl(Parser *p, Declaration *d, U16 flags) {
}
while (1) {
- Identifier *ident = parser_arr_add(p, &d->idents);
if (t->token->kind != TOKEN_IDENT) {
tokr_err(t, "Cannot declare non-identifier (%s).", token_kind_to_str(t->token->kind));
goto ret_false;
}
- *ident = parser_ident_insert(p, t->token->ident);
- if (!(flags & PARSE_DECL_DONT_SET_IDECLS) && !ident_eq_str(*ident, "_")) {
- Identifier i = *ident;
+ Identifier i = parser_ident_insert(p, t->token->ident);
+ parser_arr_add(p, d->idents, i);
+ if (!(flags & PARSE_DECL_DONT_SET_IDECLS) && !ident_eq_str(i, "_")) {
if (!check_ident_redecl(p, i))
goto ret_false;
i->decl = d;
@@ -2425,7 +2434,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
d->where = s->where;
parser_put_end(p, &d->where); /* we haven't set s->where.end, so... */
d->flags |= DECL_HAS_EXPR|DECL_IS_CONST;
- *(Identifier *)parser_arr_add(p, &d->idents) = ident;
+ parser_arr_add(p, d->idents, ident);
if (!check_ident_redecl(p, ident)) {
tokr_skip_semicolon(t);
@@ -2443,7 +2452,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
body->where = s->where;
body->parent = p->block;
idents_create(&body->idents, p->allocr, body);
- Statement *inc_stmt = parser_arr_add(p, &body->stmts);
+ Statement *inc_stmt = parser_arr_add_ptr(p, body->stmts);
inc_stmt->kind = STMT_INCLUDE;
inc_stmt->flags = STMT_INC_TO_NMS;
inc_stmt->where = s->where;
@@ -2533,11 +2542,11 @@ static Status parse_file(Parser *p, ParsedFile *f) {
bool ret = true;
while (t->token->kind != TOKEN_EOF) {
bool was_a_statement;
- Statement *stmt = parser_arr_add(p, &f->stmts);
+ Statement *stmt = parser_arr_add_ptr(p, f->stmts);
if (!parse_stmt(p, stmt, &was_a_statement))
ret = false;
if (!was_a_statement)
- arr_remove_lasta(&f->stmts, p->allocr);
+ parser_arr_remove_last(p, f->stmts);
if (token_is_kw(t->token, KW_RBRACE)) {
tokr_err(t, "} without a matching {.");
return false;
diff --git a/tests/test.sh b/tests/test.sh
index 8df4c46..a603767 100755
--- a/tests/test.sh
+++ b/tests/test.sh
@@ -51,7 +51,7 @@ do_tests() {
printf '\x1b[92mpassed!\x1b[0m\n'
else
printf '\x1b[91mfailed!\x1b[0m\n'
- failed=true
+ exit 1
fi
done
}
@@ -60,6 +60,3 @@ for x in $tests; do
done
rm got a.out out.c
-if $failed; then
- exit 1
-fi
diff --git a/toc.c b/toc.c
index e51ed8d..5536dd8 100644
--- a/toc.c
+++ b/toc.c
@@ -138,7 +138,7 @@ static void cgen_sdecls_file(CGenerator *g, ParsedFile *f);
#include "cgen.c"
#include "decls_cgen.c"
-#ifdef RUN_TESTS
+#if RUN_TESTS
#include "tests.c"
#endif
diff --git a/tokenizer.c b/tokenizer.c
index f155b9f..cdbebd8 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -7,7 +7,7 @@
static inline const char *kw_to_str(Keyword k) { return keywords[k]; }
/* Returns KW_COUNT if it's not a keyword */
-/* OPTIM: don't use strncmp so much */
+/* @OPTIM: don't use strncmp so much */
static Keyword tokenize_kw(char **s) {
for (Keyword k = 0; k < KW_COUNT; k = k + 1) {
size_t len = strlen(keywords[k]);
@@ -127,7 +127,7 @@ static inline int char_as_hex_digit(char c) {
/* returns -1 if escape sequence is invalid */
static int tokr_esc_seq(Tokenizer *t) {
- /* TODO: octal (\032)? */
+ /* @TODO: octal (\032)? */
switch (*t->s) {
case '\'':
tokr_nextchar(t);
@@ -251,7 +251,7 @@ until everything is done
*/
static void tokr_create(Tokenizer *t, ErrCtx *err_ctx, Allocator *allocr) {
t->tokens = NULL;
- arr_resva(&t->tokens, 256, allocr);
+ arr_resva(t->tokens, 256, allocr);
t->allocr = allocr;
t->err_ctx = err_ctx;
}
@@ -261,7 +261,7 @@ static inline void *tokr_malloc(Tokenizer *t, size_t bytes) {
}
static Token *tokr_add(Tokenizer *t) {
- Token *token = arr_adda(&t->tokens, t->allocr);
+ Token *token = arr_adda_ptr(t->tokens, t->allocr);
tokr_put_start_pos(t, token);
return token;
}
@@ -328,7 +328,7 @@ static Status tokenize_file(Tokenizer *t, File *file) {
tokr_put_end_pos(t, &token);
token.kind = TOKEN_DIRECT;
token.direct = direct;
- *(Token *)arr_adda(&t->tokens, t->allocr) = token;
+ arr_adda(t->tokens, token, t->allocr);
continue;
}
--t->s; /* go back to # */
@@ -345,7 +345,7 @@ static Status tokenize_file(Tokenizer *t, File *file) {
tokr_put_end_pos(t, &token);
token.kind = TOKEN_KW;
token.kw = kw;
- *(Token *)arr_adda(&t->tokens, t->allocr) = token;
+ arr_adda(t->tokens, token, t->allocr);
continue;
}
}
@@ -407,7 +407,7 @@ static Status tokenize_file(Tokenizer *t, File *file) {
n->kind = NUM_LITERAL_FLOAT;
n->floatval = (Floating)n->intval;
}
- /* TODO: check if exceeding maximum exponent */
+ /* @TODO: check if exceeding maximum exponent */
int exponent = 0;
if (*t->s == '+')
tokr_nextchar(t); /* ignore + after e */
@@ -421,7 +421,7 @@ static Status tokenize_file(Tokenizer *t, File *file) {
exponent *= 10;
exponent += *t->s - '0';
}
- /* OPTIM: Slow for very large exponents (unlikely to happen) */
+ /* @OPTIM: Slow for very large exponents (unlikely to happen) */
for (int i = 0; i < exponent; ++i) {
if (negative_exponent)
n->floatval /= 10;
diff --git a/types.c b/types.c
index 4e87ac8..7437a9c 100644
--- a/types.c
+++ b/types.c
@@ -19,18 +19,17 @@ 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, void **arr, size_t sz) {
- return arr_adda_(arr, sz, tr->allocr);
-}
+#define typer_arr_add(tr, a, x) arr_adda(a, x, tr->allocr)
+#define typer_arr_add_ptr(tr, a) arr_adda_ptr(a, tr->allocr)
static inline void typer_block_enter(Typer *tr, Block *b) {
- *(Block **)arr_adda(&tr->blocks, tr->allocr) = b;
+ typer_arr_add(tr, tr->blocks, b);
tr->block = b;
}
static inline void typer_block_exit(Typer *tr) {
- arr_remove_lasta(&tr->blocks, tr->allocr);
- tr->block = *(Block **)arr_last(tr->blocks);
+ arr_remove_lasta(tr->blocks, tr->allocr);
+ tr->block = arr_last(tr->blocks);
}
static inline void construct_resolved_builtin_type(Type *t, BuiltinType builtin) {
@@ -183,7 +182,6 @@ static size_t compiler_sizeof(Type *t) {
}
-#define typer_arr_add(tr, a) typer_arr_add_(tr, (void **)(a), sizeof **(a))
/* are a and b EXACTLY equal (not counting flags)? */
static bool type_eq_exact(Type *a, Type *b) {
assert(a->flags & TYPE_IS_RESOLVED);
@@ -448,7 +446,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
t->kind = TYPE_FN;
t->fn.types = NULL;
- t->fn.constness = NULL; /* OPTIM: constness doesn't need to be a dynamic array */
+ t->fn.constness = NULL; /* @OPTIM: constness doesn't need to be a dynamic array */
t->flags = 0;
bool success = true;
bool entered_fn = false;
@@ -456,7 +454,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
FnExpr *prev_fn = tr->fn;
FnExpr fn_copy = {0};
- Declaration *last_param = arr_last(f->params);
+ Declaration *last_param = arr_last_ptr(f->params);
bool has_varargs = last_param && (last_param->flags & DECL_ANNOTATES_TYPE) && type_is_builtin(&last_param->type, BUILTIN_VARARGS);
if (has_varargs)
f->flags |= FN_EXPR_HAS_VARARGS;
@@ -469,7 +467,8 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
}
size_t idx = 0;
bool has_constant_params = false;
- Type *ret_type = typer_arr_add(tr, &t->fn.types);
+ /* reserve space for return type */
+ typer_arr_add_ptr(tr, t->fn.types);
tr->fn = f;
typer_block_enter(tr, &f->body);
f->body.uses = NULL;
@@ -516,12 +515,12 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
if (!t->fn.constness) {
has_constant_params = true;
for (size_t i = 0; i < idx; ++i) {
- *(Constness *)typer_arr_add(tr, &t->fn.constness) = CONSTNESS_NO;
+ typer_arr_add(tr, t->fn.constness, CONSTNESS_NO);
}
}
}
for (size_t i = 0; i < arr_len(param->idents); ++i) {
- Type *param_type = typer_arr_add(tr, &t->fn.types);
+ Type *param_type = typer_arr_add_ptr(tr, t->fn.types);
if (param->flags & (DECL_ANNOTATES_TYPE|DECL_FOUND_TYPE))
*param_type = param->type;
else
@@ -535,7 +534,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
} else {
constn = CONSTNESS_NO;
}
- *(Constness *)typer_arr_add(tr, &t->fn.constness) = constn;
+ typer_arr_add(tr, t->fn.constness, constn);
}
++idx;
}
@@ -560,7 +559,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
f->ret_type.tuple = NULL;
arr_foreach(f->ret_decls, Declaration, d) {
arr_foreach(d->idents, Identifier, i) {
- *(Type *)arr_add(&f->ret_type.tuple) = d->type;
+ typer_arr_add(tr, f->ret_type.tuple, d->type);
}
}
}
@@ -596,7 +595,11 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
}
t->flags |= TYPE_IS_RESOLVED;
}
- *ret_type = f->ret_type;
+
+ {
+ Type *ret_type = &t->fn.types[0];
+ *ret_type = f->ret_type;
+ }
ret:
/* cleanup */
@@ -619,7 +622,8 @@ top:;
Block *decl_scope = ident_scope(i);
if (decl_scope->kind != BLOCK_NMS) {
/* go back through scopes */
- for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) {
+ arr_foreach_reversed(tr->blocks, BlockPtr, block) {
+ if (*block == NULL || *block == decl_scope) break;
if ((*block)->kind == BLOCK_FN) {
captured = true;
break;
@@ -717,7 +721,7 @@ static Status add_block_to_struct(Typer *tr, Block *b, StructDef *s, Statement *
err_print(d->where, "struct members can't be inferred.");
return false;
}
- *(Statement *)typer_arr_add(tr, new_stmts) = *stmt;
+ typer_arr_add(tr, *new_stmts, *stmt);
} else {
if (flags & DECL_SEMI_CONST) {
err_print(d->where, "struct members can't be semi-constant.");
@@ -729,14 +733,14 @@ static Status add_block_to_struct(Typer *tr, Block *b, StructDef *s, Statement *
}
int i = 0;
arr_foreach(d->idents, Identifier, ident) {
- Field *field = typer_arr_add(tr, &s->fields);
+ Field *field = typer_arr_add_ptr(tr, s->fields);
field->where = d->where;
field->name = *ident;
field->type = decl_type_at_index(d, i);
++i;
}
- *(Statement *)typer_arr_add(tr, new_stmts) = *stmt;
+ typer_arr_add(tr, *new_stmts, *stmt);
}
if (b != &s->body) {
/* we need to translate d's identifiers to s's scope */
@@ -861,8 +865,7 @@ static Status type_resolve(Typer *tr, Type *t, Location where) {
}
if (!eval_expr(tr->evalr, sub, &typeval))
return false;
- Type *subtype = typer_arr_add(tr, &tuple);
- *subtype = *typeval.type;
+ typer_arr_add(tr, tuple, *typeval.type);
}
if (is_tuple_of_types) {
t->kind = TYPE_TUPLE;
@@ -1058,7 +1061,7 @@ static CastStatus type_cast_status(Type *from, Type *to) {
return CAST_STATUS_NONE;
if (to->kind == TYPE_FN)
return CAST_STATUS_WARN;
- /* TODO: Cast from ptr to arr */
+ /* @TODO: Cast from ptr to arr */
return CAST_STATUS_ERR;
case TYPE_ARR:
return CAST_STATUS_ERR;
@@ -1239,7 +1242,7 @@ static Status call_arg_param_order(FnExpr *fn, Type *fn_type, Argument *args, Lo
}
}
this_param = param;
- if (param > (Declaration *)arr_last(fn->params)) {
+ if (param > (Declaration *)arr_last_ptr(fn->params)) {
err_print(arg->where, "Too many arguments to function!");
info_print(fn->where, "Declaration is here.");
return false;
@@ -1411,7 +1414,7 @@ static Value get_builtin_val(BuiltinVal val) {
case BUILTIN_SIZEOF_SIZE_T:
v.i64 = (I64)sizeof(size_t);
break;
- /* TODO(eventually): fix these for cross compilation */
+ /* @TODO(eventually): fix these for cross compilation */
case BUILTIN_TSIZEOF_SHORT:
v.i64 = (I64)sizeof(short);
break;
@@ -1518,7 +1521,7 @@ static Status get_struct_constant(StructDef *struc, Identifier member, Expressio
}
static bool fn_type_has_varargs(FnType *f) {
- return type_is_builtin(arr_last(f->types), BUILTIN_VARARGS);
+ return type_is_builtin(arr_last_ptr(f->types), BUILTIN_VARARGS);
}
static Status types_expr(Typer *tr, Expression *e) {
@@ -1573,7 +1576,7 @@ static Status types_expr(Typer *tr, Expression *e) {
ForExpr *fo = e->for_;
Declaration *header = &fo->header;
- *(Declaration **)typer_arr_add(tr, &tr->in_decls) = header;
+ typer_arr_add(tr, tr->in_decls, header);
fo->body.uses = NULL;
typer_block_enter(tr, &fo->body);
bool annotated_index = true;
@@ -1588,13 +1591,13 @@ static Status types_expr(Typer *tr, Expression *e) {
annotated_index = false;
assert(nidents == 1);
/* turn value := arr to value, _ := arr to simplify things */
- *(Identifier *)arr_add(&header->idents) = ident_insert_with_len(typer_get_idents(tr), "_", 1);
+ typer_arr_add(tr, header->idents, ident_insert_with_len(typer_get_idents(tr), "_", 1));
}
}
Type *fo_type_tuple = NULL;
/* fo_type is (val_type, index_type) */
- arr_set_lena(&fo_type_tuple, 2, tr->allocr);
+ arr_set_lena(fo_type_tuple, 2, tr->allocr);
memset(fo_type_tuple, 0, 2*sizeof *fo_type_tuple);
Type *val_type = &fo_type_tuple[0];
Type *index_type = &fo_type_tuple[1];
@@ -1741,7 +1744,7 @@ static Status types_expr(Typer *tr, Expression *e) {
case BUILTIN_VARARGS: {
/* exit for body */
typer_block_exit(tr);
- arr_remove_lasta(&tr->in_decls, tr->allocr);
+ arr_remove_lasta(tr->in_decls, tr->allocr);
/* create one block, containing a block for each vararg */
/* e.g. for x := varargs { total += x; } => { { x := varargs[0]; total += x; } { x := varargs[0]; total += x; } } */
assert(fo->of->kind == EXPR_IDENT);
@@ -1756,7 +1759,7 @@ static Status types_expr(Typer *tr, Expression *e) {
b->stmts = NULL;
b->parent = tr->block;
b->where = e->where;
- arr_set_lena(&b->stmts, nvarargs, tr->allocr);
+ arr_set_lena(b->stmts, nvarargs, tr->allocr);
Statement *stmt = b->stmts;
size_t nstmts = arr_len(fo->body.stmts);
Declaration *header_decl = &fo->header;
@@ -1779,10 +1782,10 @@ static Status types_expr(Typer *tr, Expression *e) {
sub->stmts = NULL;
sub->where = e->where;
size_t total_nstmts = nstmts + has_val + has_index;
- arr_set_lena(&sub->stmts, total_nstmts, tr->allocr);
+ arr_set_lena(sub->stmts, total_nstmts, tr->allocr);
Copier copier = copier_create(tr->allocr, sub);
if (has_val) {
- /* TODO(eventually): don't put a decl in each block, just put one at the start */
+ /* @TODO(eventually): don't put a decl in each block, just put one at the start */
Statement *s = &sub->stmts[0];
s->flags = 0;
s->kind = STMT_DECL;
@@ -1792,7 +1795,7 @@ static Status types_expr(Typer *tr, Expression *e) {
Declaration *decl = s->decl = typer_calloc(tr, 1, sizeof *decl);
decl->where = fo->of->where;
Identifier ident = ident_translate_forced(val_ident, &sub->idents);
- *(Identifier *)arr_adda(&decl->idents, tr->allocr) = ident;
+ typer_arr_add(tr, decl->idents, ident);
ident->decl = decl;
decl->flags |= DECL_HAS_EXPR;
@@ -1806,7 +1809,7 @@ static Status types_expr(Typer *tr, Expression *e) {
index->where = fo->of->where;
}
if (has_index) {
- /* TODO(eventually): don't put a decl in each block, just put one at the start */
+ /* @TODO(eventually): don't put a decl in each block, just put one at the start */
Statement *s = &sub->stmts[has_val];
s->flags = 0;
s->kind = STMT_DECL;
@@ -1816,7 +1819,7 @@ static Status types_expr(Typer *tr, Expression *e) {
Declaration *decl = s->decl = typer_calloc(tr, 1, sizeof *decl);
decl->where = fo->of->where;
Identifier ident = ident_translate_forced(index_ident, &sub->idents);
- *(Identifier *)arr_adda(&decl->idents, tr->allocr) = ident;
+ typer_arr_add(tr, decl->idents, ident);
ident->decl = decl;
decl->flags |= DECL_HAS_EXPR;
@@ -1870,7 +1873,7 @@ static Status types_expr(Typer *tr, Expression *e) {
} else *val_type = *iter_type;
}
- arr_remove_lasta(&tr->in_decls, tr->allocr);
+ arr_remove_lasta(tr->in_decls, tr->allocr);
in_header = false;
assert(header->type.flags & TYPE_IS_RESOLVED);
@@ -1891,7 +1894,7 @@ static Status types_expr(Typer *tr, Expression *e) {
}break;
for_fail:
if (in_header)
- arr_remove_lasta(&tr->in_decls, tr->allocr);
+ arr_remove_lasta(tr->in_decls, tr->allocr);
typer_block_exit(tr);
return false;
}
@@ -1900,7 +1903,7 @@ static Status types_expr(Typer *tr, Expression *e) {
Identifier i = e->ident;
bool undeclared = true;
while (1) { /* for each block we are inside... */
- /* OPTIM: only hash once */
+ /* @OPTIM: only hash once */
Identifier translated = ident_translate(i, b ? &b->idents : tr->globals);
if (ident_is_declared(translated)) {
#if 0
@@ -2175,7 +2178,7 @@ static Status types_expr(Typer *tr, Expression *e) {
return false;
}
Type *arg_types = NULL;
- arr_set_len(&arg_types, nparams);
+ arr_set_len(arg_types, nparams);
Value *arg_vals = typer_malloc(tr, nparams * sizeof *arg_vals);
ErrCtx *err_ctx = tr->err_ctx;
size_t p = 0;
@@ -2184,10 +2187,10 @@ static Status types_expr(Typer *tr, Expression *e) {
bool is_tuple = arr_len(param->idents) > 1;
int ident_idx = 0;
/* temporarily add this instance to the stack, while we type the decl, in case you, e.g., pass t = float to struct(t::Type, u::t = "hello") */
- *(Location *)arr_add(&err_ctx->instance_stack) = e->where;
+ arr_add(err_ctx->instance_stack, e->where);
typer_block_enter(tr, &struc.body);
bool success = types_decl(tr, param);
- arr_remove_last(&err_ctx->instance_stack);
+ arr_remove_last(err_ctx->instance_stack);
typer_block_exit(tr);
if (!success) return false;
@@ -2211,7 +2214,7 @@ static Status types_expr(Typer *tr, Expression *e) {
return false;
}
if (is_tuple)
- *(Value *)arr_adda(&param_val.tuple, tr->allocr) = ident_val;
+ typer_arr_add(tr, param_val.tuple, ident_val);
else
param_val = ident_val;
arg_vals[p] = ident_val;
@@ -2249,12 +2252,12 @@ static Status types_expr(Typer *tr, Expression *e) {
Type struct_t = {0};
struct_t.kind = TYPE_STRUCT;
struct_t.struc = &inst->struc;
- *(Location *)arr_add(&err_ctx->instance_stack) = e->where;
+ arr_add(err_ctx->instance_stack, e->where);
Block *prev_block = tr->block;
tr->block = &inst->struc.body;
bool success = type_resolve(tr, &struct_t, e->where); /* resolve the struct */
tr->block = prev_block;
- arr_remove_last(&err_ctx->instance_stack);
+ arr_remove_last(err_ctx->instance_stack);
if (!success) return false;
inst->struc.instance_id = table->n;
@@ -2269,7 +2272,7 @@ static Status types_expr(Typer *tr, Expression *e) {
e->typeval->struc = &inst->struc;
t->kind = TYPE_BUILTIN;
t->builtin = BUILTIN_TYPE;
- arr_clear(&arg_types);
+ arr_clear(arg_types);
goto ret;
}
fn_decl = val.fn;
@@ -2302,11 +2305,11 @@ static Status types_expr(Typer *tr, Expression *e) {
}
arg_exprs = NULL;
- arr_set_lena(&arg_exprs, narg_exprs, tr->allocr);
+ arr_set_lena(arg_exprs, narg_exprs, tr->allocr);
if (fn_decl && !is_foreign) {
size_t i = 0;
- Declaration *last_param = arr_last(fn_decl->params);
+ Declaration *last_param = arr_last_ptr(fn_decl->params);
arr_foreach(fn_decl->params, Declaration, param) {
if (has_varargs && param == last_param) continue;
arr_foreach(param->idents, Identifier, ident) {
@@ -2375,7 +2378,7 @@ static Status types_expr(Typer *tr, Expression *e) {
long arg_out_idx = arg_out - arg_exprs; /* save and restore arg_out to prevent realloc from causing problems */
/* add more room (or if nvarargs_here == 0, remove room) for more varargs */
- arr_set_lena(&arg_exprs, narg_exprs, tr->allocr);
+ arr_set_lena(arg_exprs, narg_exprs, tr->allocr);
arg_out = arg_exprs + arg_out_idx;
for (size_t i = 0; i < nvarargs_here; ++i) {
VarArg *vararg = &varargs_here[i];
@@ -2431,8 +2434,8 @@ static Status types_expr(Typer *tr, Expression *e) {
if (has_varargs) {
/* set value of varargs param decl */
VarArg *varargs = NULL;
- arr_set_lena(&varargs, nvarargs, tr->allocr);
- Declaration *varargs_param = arr_last(fn_copy->params);
+ arr_set_lena(varargs, nvarargs, tr->allocr);
+ Declaration *varargs_param = arr_last_ptr(fn_copy->params);
DeclFlags is_const = varargs_param->flags & DECL_IS_CONST;
varargs_param->val.varargs = varargs;
for (int v = 0; v < (int)nvarargs; ++v) {
@@ -2469,16 +2472,13 @@ static Status types_expr(Typer *tr, Expression *e) {
arr_foreach(fn->params, Declaration, param) {
arr_foreach(param->idents, Identifier, ident) {
if (param->flags & DECL_INFER) {
- *(Identifier *)arr_add(&inferred_idents) = *ident;
+ arr_add(inferred_idents, *ident);
} else if ((param->flags & DECL_ANNOTATES_TYPE)
&& !type_is_builtin(&param->type, BUILTIN_VARARGS)) {
/* add to stuff infer can use */
- Type **p = arr_add(&decl_types);
- *p = &param->type;
- Type **q = arr_add(&arg_types);
- *q = &arg_exprs[i].type;
- Location *l = arr_add(&arg_wheres);
- *l = arg_exprs[i].where;
+ arr_add(decl_types, &param->type);
+ arr_add(arg_types, &arg_exprs[i].type);
+ arr_add(arg_wheres, arg_exprs[i].where);
}
++i;
}
@@ -2496,9 +2496,9 @@ static Status types_expr(Typer *tr, Expression *e) {
}
tr->block = prev;
- arr_clear(&inferred_idents);
- arr_clear(&arg_types);
- arr_clear(&decl_types);
+ arr_clear(inferred_idents);
+ arr_clear(arg_types);
+ arr_clear(decl_types);
{
Type *type = inferred_types;
@@ -2628,13 +2628,13 @@ static Status types_expr(Typer *tr, Expression *e) {
table_index_type.flags = TYPE_IS_RESOLVED;
table_index_type.kind = TYPE_TUPLE;
table_index_type.tuple = NULL;
- Type *u64t = typer_arr_add(tr, &table_index_type.tuple);
+ Type *u64t = typer_arr_add_ptr(tr, table_index_type.tuple);
u64t->was_expr = NULL;
u64t->flags = TYPE_IS_RESOLVED;
u64t->kind = TYPE_BUILTIN;
u64t->builtin = BUILTIN_U64;
table_index.tuple = NULL;
- Value *which_are_const_val = typer_arr_add(tr, &table_index.tuple);
+ Value *which_are_const_val = typer_arr_add_ptr(tr, table_index.tuple);
U64 *which_are_const = &which_are_const_val->u64;
*which_are_const = 0;
int semi_const_index = 0;
@@ -2645,8 +2645,8 @@ static Status types_expr(Typer *tr, Expression *e) {
Copier cop = copier_create(tr->allocr, tr->block);
if (is_vararg) {
/* create one additional table index member for varargs */
- Value *varargs_val = typer_arr_add(tr, &table_index.tuple);
- Type *varargs_type = typer_arr_add(tr, &table_index_type.tuple);
+ Value *varargs_val = typer_arr_add_ptr(tr, table_index.tuple);
+ Type *varargs_type = typer_arr_add_ptr(tr, table_index_type.tuple);
memset(varargs_type, 0, sizeof *varargs_type);
varargs_type->flags = TYPE_IS_RESOLVED;
varargs_type->kind = TYPE_BUILTIN;
@@ -2654,7 +2654,7 @@ static Status types_expr(Typer *tr, Expression *e) {
varargs_val->varargs = NULL;
for (; i < narg_exprs; ++i) {
arg = &arg_exprs[i];
- VarArg *varg = typer_arr_add(tr, &varargs_val->varargs);
+ VarArg *varg = typer_arr_add_ptr(tr, varargs_val->varargs);
varg->type = copy_type_(&cop, &arg->type);
if (is_const) {
copy_val(tr->allocr, &varg->val, arg->val, varg->type);
@@ -2673,8 +2673,8 @@ static Status types_expr(Typer *tr, Expression *e) {
*which_are_const |= ((U64)1) << semi_const_index;
++semi_const_index;
}
- Value *v = typer_arr_add(tr, &table_index.tuple);
- Type *type = typer_arr_add(tr, &table_index_type.tuple);
+ Value *v = typer_arr_add_ptr(tr, table_index.tuple);
+ Type *type = typer_arr_add_ptr(tr, table_index_type.tuple);
copy_type(&cop, type, &arg->type);
copy_val(tr->allocr, v, arg->val, type);
}
@@ -2682,8 +2682,8 @@ static Status types_expr(Typer *tr, Expression *e) {
bool instance_already_exists;
c->instance = instance_table_adda(tr->allocr, original_fn->instances, table_index, &table_index_type, &instance_already_exists);
if (instance_already_exists) {
- arr_cleara(&table_index_type.tuple, tr->allocr);
- arr_cleara(&table_index.tuple, tr->allocr);
+ arr_cleara(table_index_type.tuple, tr->allocr);
+ arr_cleara(table_index.tuple, tr->allocr);
} else {
c->instance->fn = fn_copy;
/* fix parameter and return types (they were kind of problematic before, because we didn't know about the instance) */
@@ -2692,12 +2692,12 @@ static Status types_expr(Typer *tr, Expression *e) {
/* if anything happens, make sure we let the user know that this happened while generating a fn */
ErrCtx *err_ctx = e->where.file->ctx;
- *(Location *)typer_arr_add(tr, &err_ctx->instance_stack) = e->where;
+ typer_arr_add(tr, err_ctx->instance_stack, e->where);
Block *prev_block = tr->block;
tr->block = fn_copy->body.parent;
bool success = types_fn(tr, c->instance->fn, &f->type, c->instance);
tr->block = prev_block;
- arr_remove_lasta(&err_ctx->instance_stack, tr->allocr);
+ arr_remove_lasta(err_ctx->instance_stack, tr->allocr);
if (!success) return false;
}
@@ -3156,10 +3156,9 @@ static Status types_expr(Typer *tr, Expression *e) {
t->kind = TYPE_TUPLE;
t->tuple = NULL;
arr_foreach(e->tuple, Expression, x) {
- Type *x_type = typer_arr_add(tr, &t->tuple);
if (!types_expr(tr, x))
return false;
- *x_type = x->type;
+ typer_arr_add(tr, t->tuple, x->type);
}
break;
case EXPR_SLICE: {
@@ -3258,14 +3257,14 @@ static Status types_block(Typer *tr, Block *b) {
goto ret;
}
} else {
- if (s != (Statement *)arr_last(b->stmts)) {
+ if (s != (Statement *)arr_last_ptr(b->stmts)) {
err_print(e->where, "Return value must be the last statement in a block.");
success = false;
goto ret;
}
b->ret_expr = typer_malloc(tr, sizeof *b->ret_expr);
*b->ret_expr = *e;
- arr_remove_lasta(&b->stmts, tr->allocr);
+ arr_remove_lasta(b->stmts, tr->allocr);
}
}
@@ -3293,8 +3292,7 @@ static Status types_decl(Typer *tr, Declaration *d) {
d->type.flags = 0;
return true;
}
- Declaration **dptr = typer_arr_add(tr, &tr->in_decls);
- *dptr = d;
+ typer_arr_add(tr, tr->in_decls, d);
if (d->flags & DECL_ANNOTATES_TYPE) {
/* type supplied */
assert(d->type.kind != TYPE_VOID); /* there's no way to annotate void */
@@ -3407,7 +3405,11 @@ static Status types_decl(Typer *tr, Declaration *d) {
arr_foreach(d->idents, Identifier, ip) {
Identifier i = *ip;
/* add to uses */
- Use **usep = arr_add(tr->block ? &tr->block->uses : &tr->uses);
+ Use **usep;
+ if (tr->block)
+ usep = typer_arr_add_ptr(tr, tr->block->uses);
+ else
+ usep = typer_arr_add_ptr(tr, tr->uses);
Use *use = *usep = typer_calloc(tr, 1, sizeof *use);
Expression *used = &use->expr;
used->kind = EXPR_IDENT;
@@ -3421,7 +3423,6 @@ static Status types_decl(Typer *tr, Declaration *d) {
if (n_idents == 1 && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_NMS) {
bool is_at_top_level = true;
- typedef Block *BlockPtr;
arr_foreach(tr->blocks, BlockPtr, b) {
if (*b && (*b)->kind != BLOCK_NMS) {
is_at_top_level = false;
@@ -3448,7 +3449,7 @@ static Status types_decl(Typer *tr, Declaration *d) {
d->type.was_expr = NULL;
d->type.kind = TYPE_UNKNOWN;
}
- arr_remove_lasta(&tr->in_decls, tr->allocr);
+ arr_remove_lasta(tr->in_decls, tr->allocr);
return success;
}
@@ -3644,8 +3645,10 @@ static Status types_stmt(Typer *tr, Statement *s) {
err_print(e->where, "You can't use this value. You should probably assign it to a variable.");
return false;
}
- Use **up = arr_add(tr->block ? &tr->block->uses : &tr->uses);
- *up = u;
+ if (tr->block)
+ typer_arr_add(tr, tr->block->uses, u);
+ else
+ typer_arr_add(tr, tr->uses, u);
} break;
}
s->flags |= STMT_TYPED;
@@ -3663,7 +3666,7 @@ static void typer_create(Typer *tr, Evaluator *ev, File *file, ErrCtx *err_ctx,
tr->in_decls = NULL;
tr->allocr = allocr;
tr->globals = idents;
- *(Block **)arr_adda(&tr->blocks, allocr) = NULL;
+ typer_arr_add(tr, tr->blocks, NULL);
str_hash_table_create(&tr->included_files, sizeof(IncludedFile), tr->allocr);
}
@@ -3676,7 +3679,6 @@ static Status types_file(Typer *tr, ParsedFile *f) {
ret = false;
}
}
- arr_clear(&tr->uses);
assert(tr->block == NULL);
assert(arr_len(tr->blocks) && tr->blocks[0] == NULL);
return ret;
diff --git a/types.h b/types.h
index ed8d792..92a4a5c 100644
--- a/types.h
+++ b/types.h
@@ -68,11 +68,13 @@ typedef U8 bool;
#endif
#if defined __GNUC__ && !defined NO_WARN_UNUSED_RESULT
-#define Status bool __attribute__((warn_unused_result))
+#define WarnUnusedResult __attribute__((warn_unused_result))
#else
-#define Status bool
+#define WarnUnusedResult
#endif
+#define Status bool WarnUnusedResult
+
typedef int8_t I8;
#define I8_MAX INT8_MAX
typedef int16_t I16;
@@ -493,6 +495,7 @@ typedef struct Block {
struct Statement **deferred; /* deferred stuff from this block; used by both eval and cgen */
struct Use **uses; /* use statements (for types.c) */
} Block;
+typedef Block *BlockPtr;
enum {
STRUCT_DEF_FOUND_OFFSETS = 0x01,
@@ -873,7 +876,7 @@ typedef struct Declaration {
/* for eval, for non-constant local decls: */
/* the pointers to values need to be fixed, which is why this isn't just Value *. */
- /* OPTIM: some block array of values somewhere which we can just use a pointer to, which is freed when the block is exited? */
+ /* @OPTIM: some block array of values somewhere which we can just use a pointer to, which is freed when the block is exited? */
Value **val_stack;
} Declaration;
typedef Declaration *DeclarationPtr;