summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-03 14:38:17 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-03 14:38:17 -0400
commit0e870cae655b5b7fdfb395797d13f0bbda8c2a8b (patch)
treed9e4b75349a76acbcd014c194ebff7f06cceab8c
parent19a52402126c96c759f416d65f7a1925c32aead5 (diff)
continued arr system
-rw-r--r--arr.c86
-rwxr-xr-xarrtestbin0 -> 21600 bytes
-rw-r--r--blockarr.c10
-rw-r--r--identifiers.c7
-rw-r--r--tokenizer.c4
-rw-r--r--types.h38
6 files changed, 105 insertions, 40 deletions
diff --git a/arr.c b/arr.c
index 6ec7db2..8bc66e2 100644
--- a/arr.c
+++ b/arr.c
@@ -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);
+}
diff --git a/arrtest b/arrtest
new file mode 100755
index 0000000..135b534
--- /dev/null
+++ b/arrtest
Binary files differ
diff --git a/blockarr.c b/blockarr.c
index 40e2edc..16ab041 100644
--- a/blockarr.c
+++ b/blockarr.c
@@ -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;
diff --git a/types.h b/types.h
index 5960e27..5a0af3b 100644
--- a/types.h
+++ b/types.h
@@ -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 {