diff options
-rw-r--r-- | arr.c | 19 | ||||
-rwxr-xr-x | arrtest | bin | 21600 -> 0 bytes | |||
-rw-r--r-- | main.c | 8 | ||||
-rw-r--r-- | parse.c | 119 | ||||
-rw-r--r-- | test.toc | 7 | ||||
-rw-r--r-- | tests.c | 7 | ||||
-rw-r--r-- | tokenizer.c | 2 | ||||
-rw-r--r-- | types.c | 133 | ||||
-rw-r--r-- | types.h | 2 |
9 files changed, 161 insertions, 136 deletions
@@ -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 Binary files differdeleted file mode 100755 index 135b534..0000000 --- a/arrtest +++ /dev/null @@ -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); @@ -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); } } @@ -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; @@ -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; } @@ -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(¶m->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(¶m->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; } @@ -308,7 +308,7 @@ typedef enum { typedef struct { Directive which; - struct Argument *args; + struct Expression *args; } DirectExpr; |