diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-04 17:43:46 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-04 17:43:46 -0400 |
commit | 51360274858bef53009bf1dd6619d7407277f642 (patch) | |
tree | 522b3cb09e5882ac488c7b089944e3f707dab58e | |
parent | 4030c4239542d1b668c2f328f7142b9796973ddd (diff) |
improved arr_add and fixed bug
-rw-r--r-- | arr.c | 27 | ||||
-rw-r--r-- | blockarr.c | 17 | ||||
-rwxr-xr-x | build.sh | 5 | ||||
-rw-r--r-- | identifiers.c | 12 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | test.toc | 29 | ||||
-rw-r--r-- | tests.c | 2 | ||||
-rw-r--r-- | tokenizer.c | 7 | ||||
-rw-r--r-- | types.h | 5 |
9 files changed, 68 insertions, 38 deletions
@@ -104,8 +104,31 @@ 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) +#ifdef __GNUC__ +#define typeof __typeof__ +#endif + +#if defined(__GNUC__) || defined(__TINYC__) +#define HAS_TYPEOF 1 +#endif + +#if HAS_TYPEOF +/* +this is to cast the return value of arr_add so that gcc produces a warning if you +do something like: +float *arr = NULL; +// ... +int *x = arr_add(&arr); +You shouldn't rely on this, though, e.g. by doing +*arr_add(&arr) = 17; + */ +#define arr_ptr_type(arr) __typeof__(*(arr)) +#else +#define arr_ptr_type(arr) void * +#endif + +#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)) @@ -16,7 +16,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); + last_block = arr_last(arr->blocks); if (arr->blocks == NULL || (unsigned long)last_block->n >= (1UL << arr->lg_block_sz)) { ArrBlock *block; @@ -46,3 +46,18 @@ static void block_arr_free(BlockArr *arr) { } arr_clear(&arr->blocks); } + +static void block_arr_test(void) { + BlockArr a; + int *ps[100]; + block_arr_create(&a, 3, sizeof(int)); + for (int i = 0; i < 100; i++) { + int *p = block_arr_add(&a); + *p = i; + ps[i] = p; + } + for (int i = 0; i < 100; i++) { + assert(*ps[i] == i); + } + block_arr_free(&a); +} @@ -1,5 +1,8 @@ #!/bin/bash -CC=gcc +if [[ $CC == "" ]]; then + CC=gcc +fi + # Possible extra build flags # these are for compiling the compiler, and NOT for compiling the program itself. diff --git a/identifiers.c b/identifiers.c index bb9df98..d7ad02d 100644 --- a/identifiers.c +++ b/identifiers.c @@ -30,7 +30,7 @@ static Identifier ident_new(Identifiers *ids, Identifier parent, unsigned char i tree->parent = NULL; for (size_t i = 0; i < TREE_NCHILDREN; i++) tree->children[i] = NULL; - tree->decls.data = NULL; + tree->decls = NULL; #endif tree->parent = parent; if (parent) @@ -165,3 +165,13 @@ static void idents_free(Identifiers *ids) { ident_tree_free(ids->root); block_arr_free(&ids->trees); } + +static void idents_test(void) { + Identifiers ids; + char b[] = "foo_variable bar"; + char *s = b; + idents_create(&ids); + ident_insert(&ids, &s); + assert(strcmp(s, " bar") == 0); + idents_free(&ids); +} @@ -1,6 +1,5 @@ /* TODO: -whiles should not return values, unless they have no condition call fns at compile time finish evaluator improve casting: do you really need "as"? @@ -43,7 +42,6 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } fclose(in); - Identifiers file_idents; idents_create(&file_idents); Tokenizer t; @@ -1,28 +1,3 @@ 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); - - a238674 : [if 5 - 5 { 12 } else { 6 }]int; - a2394823 : [{ 3; 7 }]int; - gfdsdgf : [ while { 3 } ]int; - // arr1 : ['a' as u8]int; - // arr2 : [main as u64]int; - // arr3 : [main as i64]int; - // N @= (-10 + (97 as char as u8 as f32)) as u32; - // arr4 : [N]int; - // arr5 : [main as u64]int; - // arr6 : [main as u64 as fn() as u64]int; - // arr7 : [main as u64 as fn() int as u64]int; - - // str @= "foo"; - // arr8 : [(str[0] as u32) + (str[1] as u32) + (str[2] as u32)]int; - // asdf @= new int; - // arr9 : [asdf as u64]int; - // arr10 : [main as &i32 as u64]int; - // arr11 : [((main as &u64) as [4]u64)[3]]int; -}; + x : [{ 3; 5 }] int; +};
\ No newline at end of file @@ -25,4 +25,6 @@ static void allocr_test(void) { static void test_all(void) { allocr_test(); arr_test(); + block_arr_test(); + idents_test(); } diff --git a/tokenizer.c b/tokenizer.c index b1b9cdc..2f1c145 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -194,14 +194,13 @@ static bool tokenize_string(Tokenizer *t, char *str) { int has_err = 0; t->s = str; t->line = 1; - while (1) { - if (*t->s == 0) break; + if (*t->s == 0) break; if (isspace(*t->s)) { tokr_nextchar(t); continue; } - + if (*t->s == '/') { /* maybe it's a comment */ int is_comment = 1; @@ -470,7 +469,7 @@ static bool tokenize_string(Tokenizer *t, char *str) { tokr_nextchar(t); /* move past closing " */ continue; } - + if (isident(*t->s)) { /* it's an identifier */ Token *token = tokr_add(t); @@ -2,6 +2,11 @@ typedef int64_t Integer; typedef uint64_t UInteger; typedef long double Floating; /* OPTIM: Switch to double, but make sure floating-point literals are right */ +#if __STDC_VERSION__ < 201112 +/* assume long double has the strictest alignment */ +typedef long double max_align_t; +#endif + #define INTEGER_MAX INT64_MAX #define UINTEGER_MAX UINT64_MAX #define INTEGER_FMT "%"PRId64 |