diff options
-rw-r--r-- | arr.c | 86 | ||||
-rwxr-xr-x | arrtest | bin | 0 -> 21600 bytes | |||
-rw-r--r-- | blockarr.c | 10 | ||||
-rw-r--r-- | identifiers.c | 7 | ||||
-rw-r--r-- | tokenizer.c | 4 | ||||
-rw-r--r-- | types.h | 38 |
6 files changed, 105 insertions, 40 deletions
@@ -17,33 +17,105 @@ static inline size_t arr_len(void *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)); + ArrHeader *hdr = err_malloc(item_sz * n + sizeof(ArrHeader) + 1); /* +1 => prevent ptr overflow */ hdr->len = 0; hdr->cap = n; *arr = hdr->data; } else { ArrHeader *hdr = arr_hdr(*arr); hdr->cap = n; - hdr = realloc(hdr, item_sz * n + sizeof(ArrHeader)); + hdr = err_realloc(hdr, item_sz * n + sizeof(ArrHeader) + 1); if (hdr->len > hdr->cap) hdr->len = hdr->cap; *arr = 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) + 1); /* +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); + if (hdr->len > hdr->cap) hdr->len = hdr->cap; + *arr = hdr->data; + } +} + + +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_add_(void **arr, size_t item_sz) { ArrHeader *hdr; if (*arr == NULL) { - arr_resv_(*arr, 10, item_sz); + arr_resv_(arr, 10, item_sz); hdr = arr_hdr(*arr); } else { hdr = arr_hdr(*arr); if (hdr->len >= hdr->cap) { - arr_resv_(*arr, hdr->len * 2, item_sz); + arr_resv_(arr, hdr->len * 2, item_sz); 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, item_sz, a); + hdr = arr_hdr(*arr); + } + } + return &(((char *)hdr->data)[(hdr->len++) * item_sz]); +} + +static void arr_clear_(void **arr) { + if (*arr) { + free(arr_hdr(*arr)); + *arr = NULL; + } +} -#define arr_add(arr) arr_add_((void **)arr, sizeof **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; + } else { + return NULL; + } +} + +#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_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++) + +static void arr_test(void) { + int *foos = NULL; + for (int i = 0; i < 1000; i++) { + *(int *)arr_add(&foos) = i; + } + for (int i = 0; i < (int)arr_len(foos); i++) { + assert(foos[i] == i); + } + int lastx = -1; + arr_foreach(foos, int, x) { + assert(*x == lastx + 1); + lastx = *x; + } + arr_clear(&foos); +} Binary files differ@@ -9,7 +9,7 @@ Note: the block size must be a power of 2, to use right shifting instead of divi (for optimization)! */ static void block_arr_create(BlockArr *arr, int lg_block_sz, size_t item_sz) { - arr_create(&arr->blocks, sizeof(ArrBlock)); + arr->blocks = NULL; arr->item_sz = item_sz; arr->lg_block_sz = lg_block_sz; } @@ -17,7 +17,7 @@ static void block_arr_create(BlockArr *arr, int lg_block_sz, size_t item_sz) { static void *block_arr_add(BlockArr *arr) { ArrBlock *last_block; last_block = arr_last(&arr->blocks); - if (arr->blocks.data == NULL || + if (arr->blocks == NULL || (unsigned long)last_block->n >= (1UL << arr->lg_block_sz)) { ArrBlock *block; /* no blocks yet / ran out of blocks*/ @@ -36,13 +36,13 @@ static void *block_arr_add(BlockArr *arr) { static inline void *block_arr_get(BlockArr *arr, size_t index) { size_t block_index = index >> arr->lg_block_sz; - ArrBlock *block = (ArrBlock*)arr->blocks.data + block_index; + ArrBlock *block = &arr->blocks[block_index]; return (char*)block->data + arr->item_sz * index; } static void block_arr_free(BlockArr *arr) { - arr_foreach(&arr->blocks, ArrBlock, block) { + arr_foreach(arr->blocks, ArrBlock, block) { free(block->data); } - arr_free(&arr->blocks); + arr_clear(&arr->blocks); } diff --git a/identifiers.c b/identifiers.c index 104894b..bb9df98 100644 --- a/identifiers.c +++ b/identifiers.c @@ -145,21 +145,18 @@ static char *ident_to_str(Identifier i) { } static void ident_add_decl(Identifier i, struct Declaration *d, struct Block *b) { - if (!i->decls.item_sz) { - arr_create(&i->decls, sizeof(IdentDecl)); - } IdentDecl *id_decl = arr_add(&i->decls); id_decl->decl = d; id_decl->scope = b; } static IdentDecl *ident_decl(Identifier i) { - return i->decls.item_sz == 0 ? NULL : (IdentDecl*)arr_last(&i->decls); + return (IdentDecl *)arr_last(i->decls); } static void ident_tree_free(IdentTree *id) { if (!id) return; - arr_free(&id->decls); + arr_clear(&id->decls); for (int i = 0; i < TREE_NCHILDREN; i++) ident_tree_free(id->children[i]); } diff --git a/tokenizer.c b/tokenizer.c index 3393e0d..3b8ed6b 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -173,8 +173,8 @@ static void tokr_get_location(Tokenizer *tokr, Token *t) { } static void tokr_create(Tokenizer *t, Identifiers *idents, const char *filename) { - arr_create(&t->tokens, sizeof(Token)); - arr_reserve(&t->tokens, 256); + t->tokens = NULL; + arr_resv(&t->tokens, 256); allocr_create(&t->allocr); t->idents = idents; t->filename = filename; @@ -48,13 +48,6 @@ typedef struct { typedef struct { void *data; - size_t len; - size_t cap; - size_t item_sz; -} Array; - -typedef struct { - void *data; size_t n; /* number of things in this block so far */ void *last; /* last one of them */ } ArrBlock; @@ -63,7 +56,7 @@ typedef struct { size_t item_sz; int lg_block_sz; /* NOTE: dynamic array tends to over-allocate, so we're using our own */ - Array blocks; + ArrBlock *blocks; } BlockArr; typedef struct { @@ -85,7 +78,7 @@ typedef struct IdentTree { unsigned char index_in_parent; /* index of this in .parent.children */ struct IdentTree *parent; struct IdentTree *children[TREE_NCHILDREN]; - Array decls; /* array of declarations of this identifier */ + IdentDecl *decls; /* array of declarations of this identifier */ } IdentTree; typedef IdentTree *Identifier; @@ -198,7 +191,7 @@ typedef struct { typedef struct { Allocator allocr; - Array tokens; + Token *tokens; char *s; /* string being parsed */ const char *filename; LineNo line; @@ -243,9 +236,9 @@ typedef struct Type { union { BuiltinType builtin; struct { - Array types; /* [0] = ret_type, [1..] = param_types */ + struct Type *types; /* [0] = ret_type, [1..] = param_types */ } fn; - Array tuple; + struct Type *tuple; struct { struct Type *of; union { @@ -265,7 +258,7 @@ typedef struct Block { uint16_t flags; Location start; Location end; - Array stmts; + struct Statement *stmts; struct Block *parent; struct Expression *ret_expr; /* the return expression of this block, e.g. {foo(); 3} => 3 NULL for no expression. */ } Block; @@ -315,13 +308,16 @@ typedef enum { typedef struct { Directive which; - Array args; /* of Argument */ + struct Argument *args; } DirectExpr; typedef struct { struct Expression *fn; - Array args; /* of Argument; after typing, becomes of Expression */ + union { + struct Argument *args; + struct Expression *arg_exprs; + }; } CallExpr; typedef struct { @@ -336,8 +332,8 @@ typedef struct { } WhileExpr; typedef struct { - Array params; /* declarations of the parameters to this function */ - Array ret_decls; /* array of decls, if this has named return values. otherwise, len & data will be 0. */ + struct Declaration *params; /* declarations of the parameters to this function */ + struct Declaration *ret_decls; /* array of decls, if this has named return values. otherwise, NULL */ Type ret_type; Block body; } FnExpr; /* an expression such as fn(x: int) int { 2 * x } */ @@ -386,7 +382,7 @@ typedef struct Expression { }; } Expression; -typedef struct { +typedef struct Argument { Location where; Identifier name; /* NULL = no name */ Expression val; @@ -401,7 +397,7 @@ typedef struct { /* OPTIM: Instead of using dynamic arrays, do two passes. */ typedef struct Declaration { Location where; - Array idents; + Identifier *idents; Type type; uint16_t flags; Expression expr; @@ -421,7 +417,7 @@ typedef struct { } Return; #define STMT_FLAG_VOIDED_EXPR 0x01 /* the "4;" in fn () { 4; } is a voided expression, but the "4" in fn () int { 4 } is not */ -typedef struct { +typedef struct Statement { Location where; StatementKind kind; unsigned short flags; @@ -433,7 +429,7 @@ typedef struct { } Statement; typedef struct { - Array stmts; + Statement *stmts; } ParsedFile; typedef struct { |