summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arr.c19
-rwxr-xr-xarrtestbin21600 -> 0 bytes
-rw-r--r--main.c8
-rw-r--r--parse.c119
-rw-r--r--test.toc7
-rw-r--r--tests.c7
-rw-r--r--tokenizer.c2
-rw-r--r--types.c133
-rw-r--r--types.h2
9 files changed, 161 insertions, 136 deletions
diff --git a/arr.c b/arr.c
index 8bc66e2..ea29c8c 100644
--- a/arr.c
+++ b/arr.c
@@ -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_malloc(a, item_sz * n + sizeof(ArrHeader) + 1); /* +1 => prevent ptr overflow */
+ ArrHeader *hdr = allocr_realloc(a, NULL, item_sz * n + sizeof(ArrHeader)); /* +1 => prevent ptr overflow */
hdr->len = 0;
hdr->cap = n;
*arr = hdr->data;
} else {
ArrHeader *hdr = arr_hdr(*arr);
hdr->cap = n;
- hdr = allocr_realloc(a, hdr, item_sz * n + sizeof(ArrHeader) + 1);
+ hdr = allocr_realloc(a, hdr, item_sz * n + sizeof(ArrHeader));
if (hdr->len > hdr->cap) hdr->len = hdr->cap;
*arr = hdr->data;
}
@@ -49,6 +49,10 @@ static void arr_set_len_(void **arr, size_t n, size_t item_sz) {
arr_resv_(arr, n, item_sz);
arr_hdr(arr)->len = n;
}
+static void arr_set_lena_(void **arr, size_t n, size_t item_sz, Allocator *a) {
+ arr_resva_(arr, n, item_sz, a);
+ arr_hdr(arr)->len = n;
+}
static void *arr_add_(void **arr, size_t item_sz) {
ArrHeader *hdr;
@@ -89,20 +93,27 @@ static void arr_clear_(void **arr) {
static void *arr_last_(void *arr, size_t item_sz) {
if (arr) {
ArrHeader *hdr = arr_hdr(arr);
- return (char *)hdr->data + hdr->len * item_sz;
+ return hdr->len == 0 ? NULL : (char *)hdr->data + (hdr->len-1) * item_sz;
} else {
return NULL;
}
}
+/* OPTIM: shrink array */
+static void arr_remove_last_(void **arr, size_t item_sz) {
+ arr_hdr(*arr)->len--; (void)item_sz;
+}
+
#define arr_add(arr) arr_add_((void **)(arr), sizeof **(arr))
#define arr_adda(arr, allocr) 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))
#define arr_last(arr) arr_last_((void *)(arr), sizeof *(arr))
-#define arr_foreach(arr, type, var) for (type *var = arr, *var##_foreach_end = arr_last(arr); var != var##_foreach_end; var++)
+#define arr_foreach(arr, type, var) for (type *var = arr_len(arr) ? arr : NULL, *var##_foreach_end = arr_last(arr); var; var == var##_foreach_end ? var = NULL : var++)
+#define arr_remove_last(arr) arr_remove_last_((void **)(arr), sizeof **(arr))
static void arr_test(void) {
int *foos = NULL;
diff --git a/arrtest b/arrtest
deleted file mode 100755
index 135b534..0000000
--- a/arrtest
+++ /dev/null
Binary files differ
diff --git a/main.c b/main.c
index 29476e0..2fd777d 100644
--- a/main.c
+++ b/main.c
@@ -51,8 +51,8 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
- arr_foreach(&t.tokens, Token, token) {
- if (token != t.tokens.data)
+ arr_foreach(t.tokens, Token, token) {
+ if (token != t.tokens)
printf(" ");
fprint_token(stdout, token);
}
@@ -69,7 +69,7 @@ int main(int argc, char **argv) {
printf("\n\n-----\n\n");
- block_enter(NULL, &f.stmts); /* enter global scope */
+ block_enter(NULL, f.stmts); /* enter global scope */
Typer tr;
Evaluator ev;
evalr_create(&ev);
@@ -80,7 +80,7 @@ int main(int argc, char **argv) {
}
parse_printing_after_types = true;
fprint_parsed_file(stdout, &f);
- block_exit(NULL, &f.stmts); /* exit global scope */
+ block_exit(NULL, f.stmts); /* exit global scope */
tokr_free(&t);
diff --git a/parse.c b/parse.c
index 0ead4da..deda2dd 100644
--- a/parse.c
+++ b/parse.c
@@ -130,9 +130,9 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) {
case TYPE_FN: {
/* number of chars written */
size_t written = str_copy(buffer, bufsize, "fn (");
- Type *ret_type = t->fn.types.data;
+ Type *ret_type = t->fn.types;
Type *param_types = ret_type + 1;
- size_t nparams = t->fn.types.len - 1;
+ size_t nparams = arr_len(t->fn.types) - 1;
for (size_t i = 0; i < nparams; i++) {
if (i > 0)
written += str_copy(buffer + written, bufsize - written, ", ");
@@ -159,8 +159,8 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) {
} break;
case TYPE_TUPLE: {
size_t written = str_copy(buffer, bufsize, "(");
- arr_foreach(&t->tuple, Type, child) {
- if (child != t->tuple.data)
+ arr_foreach(t->tuple, Type, child) {
+ if (child != t->tuple)
written += str_copy(buffer + written, bufsize - written, ", ");
written += type_to_str_(child, buffer + written, bufsize - written);
}
@@ -186,10 +186,12 @@ static char *type_to_str(Type *t) {
return ret;
}
-static inline void *parser_arr_add(Parser *p, Array *a) {
- return arr_adda(a, &p->allocr);
+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))
+
static inline void *parser_malloc(Parser *p, size_t bytes) {
return allocr_malloc(&p->allocr, bytes);
}
@@ -300,7 +302,7 @@ static bool parse_type(Parser *p, Type *type) {
case KW_FN: {
/* function type */
type->kind = TYPE_FN;
- arr_create(&type->fn.types, sizeof(Type));
+ type->fn.types = NULL;
t->token++;
if (!token_is_kw(t->token, KW_LPAREN)) {
tokr_err(t, "Expected ( for function type.");
@@ -322,7 +324,7 @@ static bool parse_type(Parser *p, Type *type) {
}
}
t->token++; /* move past ) */
- Type *ret_type = type->fn.types.data;
+ Type *ret_type = type->fn.types;
/* if there's a symbol that isn't [ or (, that can't be the start of a type */
if ((t->token->kind == TOKEN_KW
&& t->token->kw <= KW_LAST_SYMBOL
@@ -355,7 +357,7 @@ static bool parse_type(Parser *p, Type *type) {
case KW_LPAREN:
/* tuple! */
type->kind = TYPE_TUPLE;
- arr_create(&type->tuple, sizeof(Type));
+ type->tuple = NULL;
t->token++; /* move past ( */
while (1) {
Type *child = parser_arr_add(p, &type->tuple);
@@ -407,7 +409,7 @@ static bool parse_block(Parser *p, Block *b) {
}
b->start = t->token->where;
t->token++; /* move past { */
- arr_create(&b->stmts, sizeof(Statement));
+ b->stmts = NULL;
bool ret = true;
b->ret_expr = NULL; /* default to no return unless overwritten later */
if (!token_is_kw(t->token, KW_RBRACE)) {
@@ -455,7 +457,7 @@ static bool parse_block(Parser *p, Block *b) {
static bool is_decl(Tokenizer *t);
-static bool parse_decl_list(Parser *p, Array *decls, DeclEndKind decl_end) {
+static bool parse_decl_list(Parser *p, Declaration **decls, DeclEndKind decl_end) {
Tokenizer *t = p->tokr;
bool ret = true;
bool first = true;
@@ -478,8 +480,7 @@ static bool parse_decl_list(Parser *p, Array *decls, DeclEndKind decl_end) {
static bool parse_fn_expr(Parser *p, FnExpr *f) {
Tokenizer *t = p->tokr;
- f->ret_decls.len = 0;
- f->ret_decls.data = NULL;
+ f->ret_decls = NULL;
/* only called when token is fn */
assert(token_is_kw(t->token, KW_FN));
t->token++;
@@ -488,7 +489,7 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) {
return false;
}
t->token++;
- arr_create(&f->params, sizeof(Declaration));
+ f->params = NULL;
bool ret = true;
if (token_is_kw(t->token, KW_RPAREN)) {
t->token++;
@@ -507,23 +508,22 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) {
f->ret_type.kind = TYPE_VOID;
f->ret_type.flags = 0;
} else if (is_decl(t)) {
- arr_create(&f->ret_decls, sizeof(Declaration));
+ f->ret_decls = NULL;
if (!parse_decl_list(p, &f->ret_decls, DECL_END_LBRACE_COMMA))
return false;
t->token--; /* move back to { */
- assert(f->ret_decls.len);
- if (f->ret_decls.len > 1 || ((Declaration *)f->ret_decls.data)[0].idents.len) {
+ if (arr_len(f->ret_decls) > 1 || arr_len(f->ret_decls[0].idents)) {
f->ret_type.kind = TYPE_TUPLE;
f->ret_type.flags = 0;
- arr_create(&f->ret_type.tuple, sizeof(Type));
- arr_foreach(&f->ret_decls, Declaration, decl) {
- for (size_t i = 0; i < decl->idents.len; i++) {
+ f->ret_type.tuple = NULL;
+ arr_foreach(f->ret_decls, Declaration, decl) {
+ for (size_t i = 0, len = arr_len(decl->idents); i < len; i++) {
Type *tuple_type = parser_arr_add(p, &f->ret_type.tuple);
*tuple_type = decl->type;
}
}
} else {
- f->ret_type = ((Declaration *)f->ret_decls.data)[0].type;
+ f->ret_type = f->ret_decls[0].type;
}
} else {
if (!parse_type(p, &f->ret_type)) {
@@ -537,11 +537,11 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) {
}
/* parses, e.g. "(3, 5, foo)" */
-static bool parse_args(Parser *p, Array *args) {
+static bool parse_args(Parser *p, Argument **args) {
Tokenizer *t = p->tokr;
Token *start = t->token;
assert(token_is_kw(start, KW_LPAREN));
- arr_create(args, sizeof(Argument));
+ *args = NULL;
t->token++; /* move past ( */
if (!token_is_kw(t->token, KW_RPAREN)) {
/* non-empty arg list */
@@ -1006,7 +1006,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
switch (token->kw) {
case KW_LPAREN:
if (square_level == 0 && paren_level == 0 && brace_level == 0
- && token != t->tokens.data
+ && token != t->tokens
&& token[-1].kind != TOKEN_DIRECT /* don't include directives */)
opening_bracket = token; /* maybe this left parenthesis opens the function call */
paren_level++;
@@ -1081,13 +1081,24 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
/* it's a directive */
e->kind = EXPR_DIRECT;
e->direct.which = t->token->direct;
+ e->direct.args = NULL;
if (token_is_kw(&t->token[1], KW_LPAREN)) {
+ Argument *args = NULL;
/* has args (but maybe it's just "#foo()") */
t->token++; /* move to ( */
- return parse_args(p, &e->direct.args);
+ if (!parse_args(p, &args)) return false;
+ arr_foreach(args, Argument, arg) {
+ if (arg->name != NULL) {
+ err_print(arg->where, "Directives cannot have named arguments.");
+ return false;
+ }
+ *(Expression *)arr_add(&e->direct.args) = arg->val;
+ }
+ arr_clear(&args);
+ return true;
} else {
/* no args */
- arr_create(&e->direct.args, sizeof(Expression));
+ e->direct.args = NULL;
t->token++;
return true;
}
@@ -1125,7 +1136,7 @@ static inline bool ends_decl(Token *t, DeclEndKind ends_with) {
static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, uint16_t flags) {
d->val = NULL;
d->where = p->tokr->token->where;
- arr_create(&d->idents, sizeof(Identifier));
+ d->idents = NULL;
Tokenizer *t = p->tokr;
d->flags = 0;
@@ -1307,7 +1318,7 @@ static void parser_from_tokenizer(Parser *p, Tokenizer *t) {
static bool parse_file(Parser *p, ParsedFile *f) {
Tokenizer *t = p->tokr;
- arr_create(&f->stmts, sizeof(Statement));
+ f->stmts = NULL;
bool ret = true;
while (t->token->kind != TOKEN_EOF) {
Statement *stmt = parser_arr_add(p, &f->stmts);
@@ -1344,7 +1355,7 @@ static void fprint_type(FILE *out, Type *t) {
static void fprint_block(FILE *out, Block *b) {
fprintf(out, "{\n");
- arr_foreach(&b->stmts, Statement, stmt) {
+ arr_foreach(b->stmts, Statement, stmt) {
fprint_stmt(out, stmt);
}
fprintf(out, "}");
@@ -1357,8 +1368,8 @@ static void fprint_block(FILE *out, Block *b) {
static void fprint_fn_expr(FILE *out, FnExpr *f) {
fprintf(out, "fn (");
- arr_foreach(&f->params, Declaration, decl) {
- if (decl != f->params.data)
+ arr_foreach(f->params, Declaration, decl) {
+ if (decl != f->params)
fprintf(out, ", ");
fprint_decl(out, decl);
}
@@ -1368,24 +1379,24 @@ static void fprint_fn_expr(FILE *out, FnExpr *f) {
fprint_block(out, &f->body);
}
-static void fprint_args(FILE *out, Array *args) {
+static void fprint_args(FILE *out, Argument *args) {
fprintf(out, "(");
- if (parse_printing_after_types) {
- assert(args->item_sz == sizeof(Expression));
- arr_foreach(args, Expression, arg) {
- if (arg != args->data) fprintf(out, ", ");
- fprint_expr(out, arg);
- }
- } else {
- assert(args->item_sz == sizeof(Argument));
- arr_foreach(args, Argument, arg) {
- if (arg != args->data) fprintf(out, ", ");
- if (arg->name) {
- fprint_ident(out, arg->name);
- fprintf(out, " = ");
- }
- fprint_expr(out, &arg->val);
+ arr_foreach(args, Argument, arg) {
+ if (arg != args) fprintf(out, ", ");
+ if (arg->name) {
+ fprint_ident(out, arg->name);
+ fprintf(out, " = ");
}
+ fprint_expr(out, &arg->val);
+ }
+ fprintf(out, ")");
+}
+
+static void fprint_arg_exprs(FILE *out, Expression *args) {
+ fprintf(out, "(");
+ arr_foreach(args, Expression, arg) {
+ if (arg != args) fprintf(out, ", ");
+ fprint_expr(out, arg);
}
fprintf(out, ")");
}
@@ -1457,7 +1468,11 @@ static void fprint_expr(FILE *out, Expression *e) {
break;
case EXPR_CALL:
fprint_expr(out, e->call.fn);
- fprint_args(out, &e->call.args);
+ if (parse_printing_after_types) {
+ fprint_arg_exprs(out, e->call.arg_exprs);
+ } else {
+ fprint_args(out, e->call.args);
+ }
break;
case EXPR_BLOCK:
fprint_block(out, &e->block);
@@ -1465,7 +1480,7 @@ static void fprint_expr(FILE *out, Expression *e) {
case EXPR_DIRECT:
fprintf(out, "#");
fprintf(out, "%s", directives[e->direct.which]);
- fprint_args(out, &e->direct.args);
+ fprint_arg_exprs(out, e->direct.args);
break;
}
if (parse_printing_after_types) {
@@ -1477,8 +1492,8 @@ static void fprint_expr(FILE *out, Expression *e) {
static void fprint_decl(FILE *out, Declaration *d) {
PARSE_PRINT_LOCATION(d->where);
- arr_foreach(&d->idents, Identifier, ident) {
- if (ident != d->idents.data) fprintf(out, ", ");
+ arr_foreach(d->idents, Identifier, ident) {
+ if (ident != d->idents) fprintf(out, ", ");
fprint_ident(out, *ident);
}
if (d->flags & DECL_FLAG_CONST) {
@@ -1520,7 +1535,7 @@ static void fprint_stmt(FILE *out, Statement *s) {
}
static void fprint_parsed_file(FILE *out, ParsedFile *f) {
- arr_foreach(&f->stmts, Statement, stmt) {
+ arr_foreach(f->stmts, Statement, stmt) {
fprint_stmt(out, stmt);
}
}
diff --git a/test.toc b/test.toc
index d7d9e72..be9340c 100644
--- a/test.toc
+++ b/test.toc
@@ -1,5 +1,12 @@
main @= fn() {
a : [('a' as u8 as f32) / 2 + 0.5 as i8 as &int as u64]int;
+
+ foo := fn(x : int) int {
+ 7
+ };
+
+ bar := foo(3);
+
// arr1 : ['a' as u8]int;
// arr2 : [main as u64]int;
// arr3 : [main as i64]int;
diff --git a/tests.c b/tests.c
index e9e0c31..8b200d8 100644
--- a/tests.c
+++ b/tests.c
@@ -34,16 +34,14 @@ static void allocr_test(void) {
for (int i = 0; i < nfoos2; i++)
assert(foos[i] == i);
- Array arr;
- arr_create(&arr, sizeof(int));
+ int *arr = NULL;
int n = 1000;
for (int i = 0; i < n; i++) {
int *p = arr_adda(&arr, &a);
*p = i;
}
- int *arr_data = arr.data;
for (int i = 0; i < n; i++) {
- assert(arr_data[i] == i);
+ assert(arr[i] == i);
}
allocr_free_all(&a);
@@ -51,4 +49,5 @@ static void allocr_test(void) {
static void test_all(void) {
allocr_test();
+ arr_test();
}
diff --git a/tokenizer.c b/tokenizer.c
index 3b8ed6b..b1b9cdc 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -487,7 +487,7 @@ static bool tokenize_string(Tokenizer *t, char *str) {
Token *token = tokr_add(t);
token->kind = TOKEN_EOF;
- t->token = t->tokens.data;
+ t->token = t->tokens;
return !has_err;
}
diff --git a/types.c b/types.c
index 8851693..f0b3107 100644
--- a/types.c
+++ b/types.c
@@ -1,7 +1,7 @@
typedef struct {
Allocator allocr;
Evaluator *evalr;
- Array in_decls; /* array of declarations we are currently inside */
+ Declaration **in_decls; /* array of declarations we are currently inside */
Block *block;
bool can_ret;
Type ret_type; /* the return type of the function we're currently parsing. */
@@ -21,17 +21,19 @@ 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 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) typer_arr_add_(tr, (void **)(a), sizeof **(a))
+
static bool add_ident_decls(Block *b, Declaration *d) {
bool ret = true;
- arr_foreach(&d->idents, Identifier, ident) {
- Array *decls = &(*ident)->decls;
- if (decls->len) {
+ arr_foreach(d->idents, Identifier, ident) {
+ IdentDecl **decls = &(*ident)->decls;
+ if (arr_len(*decls)) {
/* check that it hasn't been declared in this block */
- IdentDecl *prev = arr_last(decls);
+ IdentDecl *prev = arr_last(*decls);
if (prev->scope == b) {
err_print(d->where, "Re-declaration of identifier in the same block.");
info_print(prev->decl->where, "Previous declaration was here.");
@@ -45,11 +47,10 @@ static bool add_ident_decls(Block *b, Declaration *d) {
}
static void remove_ident_decls(Block *b, Declaration *d) {
- arr_foreach(&d->idents, Identifier, ident) {
+ arr_foreach(d->idents, Identifier, ident) {
IdentTree *id_info = *ident;
- Array *decls = &id_info->decls;
- assert(decls->item_sz);
- IdentDecl *last_decl = arr_last(decls);
+ IdentDecl **decls = &id_info->decls;
+ IdentDecl *last_decl = arr_last(*decls);
if (last_decl && last_decl->scope == b) {
arr_remove_last(decls); /* remove that declaration */
}
@@ -57,7 +58,7 @@ static void remove_ident_decls(Block *b, Declaration *d) {
}
/* pass NULL for block for global scope */
-static bool block_enter(Block *b, Array *stmts) {
+static bool block_enter(Block *b, Statement *stmts) {
bool ret = true;
arr_foreach(stmts, Statement, stmt) {
if (stmt->kind == STMT_DECL) {
@@ -69,7 +70,7 @@ static bool block_enter(Block *b, Array *stmts) {
return ret;
}
-static void block_exit(Block *b, Array *stmts) {
+static void block_exit(Block *b, Statement *stmts) {
/* OPTIM: figure out some way of not re-iterating over everything */
arr_foreach(stmts, Statement, stmt) {
if (stmt->kind == STMT_DECL) {
@@ -103,9 +104,9 @@ static bool type_eq(Type *a, Type *b) {
return a->builtin == b->builtin;
case TYPE_FN: {
- if (a->fn.types.len != b->fn.types.len) return false;
- Type *a_types = a->fn.types.data, *b_types = b->fn.types.data;
- for (size_t i = 0; i < a->fn.types.len; i++) {
+ if (arr_len(a->fn.types) != arr_len(b->fn.types)) return false;
+ Type *a_types = a->fn.types, *b_types = b->fn.types;
+ for (size_t i = 0; i < arr_len(a->fn.types); i++) {
if (!type_eq(&a_types[i], &b_types[i]))
return false;
@@ -113,9 +114,9 @@ static bool type_eq(Type *a, Type *b) {
return true;
}
case TYPE_TUPLE:
- if (a->tuple.len != b->tuple.len) return false;
- Type *a_types = a->tuple.data, *b_types = b->tuple.data;
- for (size_t i = 0; i < a->tuple.len; i++) {
+ if (arr_len(a->tuple) != arr_len(b->tuple)) return false;
+ Type *a_types = a->tuple, *b_types = b->tuple;
+ for (size_t i = 0; i < arr_len(a->tuple); i++) {
if (!type_eq(&a_types[i], &b_types[i]))
return false;
}
@@ -178,22 +179,21 @@ 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));
+ t->fn.types = NULL;
Type *ret_type = typer_arr_add(tr, &t->fn.types);
if (!type_resolve(tr, &f->ret_type))
return false;
*ret_type = f->ret_type;
- assert(f->params.item_sz == sizeof(Declaration));
- arr_foreach(&f->params, Declaration, decl) {
+ arr_foreach(f->params, Declaration, decl) {
if (!types_decl(tr, decl)) return false;
if (!type_resolve(tr, &decl->type))
return false;
- for (size_t i = 0; i < decl->idents.len; i++) {
+ for (size_t i = 0; i < arr_len(decl->idents); i++) {
Type *param_type = typer_arr_add(tr, &t->fn.types);
*param_type = decl->type;
}
}
- arr_foreach(&f->ret_decls, Declaration, decl) {
+ arr_foreach(f->ret_decls, Declaration, decl) {
if (!types_decl(tr, decl)) return false;
}
return true;
@@ -222,7 +222,7 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
}
/* are we inside this declaration? */
typedef Declaration *DeclarationPtr;
- arr_foreach(&tr->in_decls, DeclarationPtr, in_decl) {
+ arr_foreach(tr->in_decls, DeclarationPtr, in_decl) {
if (d == *in_decl) {
assert(d->flags & DECL_FLAG_HAS_EXPR); /* we can only be in decls with an expr */
if (d->expr.kind != EXPR_FN) { /* it's okay if a function references itself */
@@ -297,13 +297,13 @@ static bool type_resolve(Typer *tr, Type *t) {
t->arr.n = (UInteger)size;
} break;
case TYPE_FN:
- arr_foreach(&t->fn.types, Type, child_type) {
+ arr_foreach(t->fn.types, Type, child_type) {
if (!type_resolve(tr, child_type))
return false;
}
break;
case TYPE_TUPLE:
- arr_foreach(&t->tuple, Type, child_type) {
+ arr_foreach(t->tuple, Type, child_type) {
if (!type_resolve(tr, child_type))
return false;
}
@@ -433,24 +433,24 @@ static bool types_expr(Typer *tr, Expression *e) {
success = false;
goto fn_ret;
}
- bool has_named_ret_vals = e->fn.ret_decls.data != NULL;
+ bool has_named_ret_vals = e->fn.ret_decls != NULL;
if (has_named_ret_vals) {
/* set return type to void to not allow return values */
tr->ret_type.kind = TYPE_VOID;
tr->ret_type.flags = 0;
} else {
- tr->ret_type = *(Type *)t->fn.types.data;
+ tr->ret_type = t->fn.types[0];
}
tr->can_ret = true;
- arr_foreach(&f->params, Declaration, decl)
+ arr_foreach(f->params, Declaration, decl)
add_ident_decls(&f->body, decl);
- arr_foreach(&f->ret_decls, Declaration, decl)
+ arr_foreach(f->ret_decls, Declaration, decl)
add_ident_decls(&f->body, decl);
bool block_success = true;
block_success = types_block(tr, &e->fn.body);
- arr_foreach(&f->params, Declaration, decl)
+ arr_foreach(f->params, Declaration, decl)
remove_ident_decls(&f->body, decl);
- arr_foreach(&f->ret_decls, Declaration, decl)
+ arr_foreach(f->ret_decls, Declaration, decl)
remove_ident_decls(&f->body, decl);
if (!block_success) {
success = false;
@@ -458,7 +458,7 @@ static bool types_expr(Typer *tr, Expression *e) {
}
Expression *ret_expr = f->body.ret_expr;
assert(t->kind == TYPE_FN);
- Type *ret_type = t->fn.types.data;
+ Type *ret_type = t->fn.types;
if (ret_expr) {
if (!types_expr(tr, ret_expr)) {
success = false;
@@ -474,9 +474,9 @@ static bool types_expr(Typer *tr, Expression *e) {
goto fn_ret;
}
} else if (ret_type->kind != TYPE_VOID && !has_named_ret_vals) {
- Array stmts = e->fn.body.stmts;
- if (stmts.len) {
- Statement *last_stmt = (Statement *)stmts.data + (stmts.len - 1);
+ Statement *stmts = e->fn.body.stmts;
+ if (arr_len(stmts)) {
+ Statement *last_stmt = (Statement *)stmts + (arr_len(stmts) - 1);
if (last_stmt->kind == STMT_RET) {
/*
last statement is a return, so it doesn't matter that the function has no return value
@@ -623,7 +623,7 @@ static bool types_expr(Typer *tr, Expression *e) {
} else {
if (!types_expr(tr, f)) return false;
}
- arr_foreach(&c->args, Argument, arg) {
+ arr_foreach(c->args, Argument, arg) {
if (!types_expr(tr, &arg->val))
return false;
}
@@ -632,17 +632,15 @@ static bool types_expr(Typer *tr, Expression *e) {
err_print(e->where, "Calling non-function (type %s).", type);
return false;
}
- Type *ret_type = (Type *)f->type.fn.types.data;
+ Type *ret_type = f->type.fn.types;
Type *param_types = ret_type + 1;
- Argument *args = c->args.data;
- size_t nparams = f->type.fn.types.len - 1;
- size_t nargs = c->args.len;
+ Argument *args = c->args;
+ size_t nparams = arr_len(f->type.fn.types) - 1;
+ size_t nargs = arr_len(c->args);
bool ret = true;
FnExpr *fn_decl = NULL;
- Array new_args_arr;
- arr_create(&new_args_arr, sizeof(Expression));
- arr_set_len(&new_args_arr, nparams);
- Expression *new_args = new_args_arr.data;
+ Expression *new_args = NULL;
+ arr_set_lena(&new_args, nparams, &tr->allocr);
bool *params_set = typer_calloc(tr, nparams, sizeof *params_set);
if (f->kind == EXPR_IDENT) {
IdentDecl *decl = ident_decl(f->ident);
@@ -667,8 +665,8 @@ static bool types_expr(Typer *tr, Expression *e) {
had_named_arg = true;
long index = 0;
long arg_index = -1;
- arr_foreach(&fn_decl->params, Declaration, param) {
- arr_foreach(&param->idents, Identifier, ident) {
+ arr_foreach(fn_decl->params, Declaration, param) {
+ arr_foreach(param->idents, Identifier, ident) {
if (*ident == args[p].name) {
arg_index = index;
break;
@@ -710,9 +708,9 @@ static bool types_expr(Typer *tr, Expression *e) {
size_t index = 0;
assert(fn_decl); /* we can only miss an arg if we're using named/optional args */
- arr_foreach(&fn_decl->params, Declaration, param) {
+ arr_foreach(fn_decl->params, Declaration, param) {
bool is_required = !(param->flags & DECL_FLAG_HAS_EXPR);
- arr_foreach(&param->idents, Identifier, ident) {
+ arr_foreach(param->idents, Identifier, ident) {
if (index == i) {
if (is_required) {
char *s = ident_to_str(*ident);
@@ -728,9 +726,7 @@ static bool types_expr(Typer *tr, Expression *e) {
}
}
}
- free(params_set);
- arr_free(&c->args);
- c->args = new_args_arr;
+ c->arg_exprs = new_args;
*t = *ret_type;
break;
}
@@ -745,22 +741,19 @@ static bool types_expr(Typer *tr, Expression *e) {
}
} break;
case EXPR_DIRECT:
- /* type automatically set to unknown */
- arr_foreach(&e->direct.args, Argument, arg) {
- if (arg->name) {
- err_print(arg->where, "Directives should not have named arguments.");
- return false;
- }
- if (!types_expr(tr, &arg->val))
+ arr_foreach(e->direct.args, Expression, arg) {
+ if (!types_expr(tr, arg))
return false;
}
switch (e->direct.which) {
case DIRECT_C: {
- size_t n_args = e->direct.args.len;
+ size_t n_args = arr_len(e->direct.args);
if (n_args != 1) {
err_print(e->where, "#C call should have one string argument (got %lu arguments).", (unsigned long)n_args);
return false;
}
+ /* type automatically set to unknown */
+
/* TODO: when string types are added, check */
} break;
case DIRECT_COUNT: assert(0); return false;
@@ -928,11 +921,11 @@ static bool types_expr(Typer *tr, Expression *e) {
break;
case BINARY_COMMA: {
t->kind = TYPE_TUPLE;
- Array *tup_types = &t->tuple;
- arr_create(tup_types, sizeof(Type));
+ Type **tup_types = &t->tuple;
+ *tup_types = NULL;
if (lhs_type->kind == TYPE_TUPLE) {
/* tuple, x => tuple */
- arr_foreach(&lhs_type->tuple, Type, child) {
+ arr_foreach(lhs_type->tuple, Type, child) {
*(Type*)typer_arr_add(tr, tup_types) = *child;
}
} else {
@@ -941,7 +934,7 @@ static bool types_expr(Typer *tr, Expression *e) {
if (rhs_type->kind == TYPE_TUPLE) {
/* x, tuple => tuple */
- arr_foreach(&rhs_type->tuple, Type, child) {
+ arr_foreach(rhs_type->tuple, Type, child) {
*(Type*)typer_arr_add(tr, tup_types) = *child;
}
} else {
@@ -959,8 +952,8 @@ static bool types_block(Typer *tr, Block *b) {
bool success = true;
Block *prev_block = tr->block;
tr->block = b;
- if (!block_enter(b, &b->stmts)) return false;
- arr_foreach(&b->stmts, Statement, s) {
+ if (!block_enter(b, b->stmts)) return false;
+ arr_foreach(b->stmts, Statement, s) {
if (!types_stmt(tr, s))
success = false;
}
@@ -972,7 +965,7 @@ static bool types_block(Typer *tr, Block *b) {
success = false;
}
}
- block_exit(b, &b->stmts);
+ block_exit(b, b->stmts);
tr->block = prev_block;
return success;
}
@@ -1078,13 +1071,13 @@ 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 *));
+ tr->in_decls = NULL;
allocr_create(&tr->allocr);
}
static bool types_file(Typer *tr, ParsedFile *f) {
bool ret = true;
- arr_foreach(&f->stmts, Statement, s) {
+ arr_foreach(f->stmts, Statement, s) {
if (!types_stmt(tr, s)) {
ret = false;
}
diff --git a/types.h b/types.h
index 5a0af3b..64cfaf9 100644
--- a/types.h
+++ b/types.h
@@ -308,7 +308,7 @@ typedef enum {
typedef struct {
Directive which;
- struct Argument *args;
+ struct Expression *args;
} DirectExpr;