summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-04 17:43:46 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-04 17:43:46 -0400
commit51360274858bef53009bf1dd6619d7407277f642 (patch)
tree522b3cb09e5882ac488c7b089944e3f707dab58e
parent4030c4239542d1b668c2f328f7142b9796973ddd (diff)
improved arr_add and fixed bug
-rw-r--r--arr.c27
-rw-r--r--blockarr.c17
-rwxr-xr-xbuild.sh5
-rw-r--r--identifiers.c12
-rw-r--r--main.c2
-rw-r--r--test.toc29
-rw-r--r--tests.c2
-rw-r--r--tokenizer.c7
-rw-r--r--types.h5
9 files changed, 68 insertions, 38 deletions
diff --git a/arr.c b/arr.c
index 7a0ffa9..ae34ebc 100644
--- a/arr.c
+++ b/arr.c
@@ -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))
diff --git a/blockarr.c b/blockarr.c
index 16ab041..cc06774 100644
--- a/blockarr.c
+++ b/blockarr.c
@@ -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);
+}
diff --git a/build.sh b/build.sh
index 134f8da..657d50d 100755
--- a/build.sh
+++ b/build.sh
@@ -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);
+}
diff --git a/main.c b/main.c
index 9cca0f2..e77b6cb 100644
--- a/main.c
+++ b/main.c
@@ -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;
diff --git a/test.toc b/test.toc
index f8b8059..3696abe 100644
--- a/test.toc
+++ b/test.toc
@@ -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
diff --git a/tests.c b/tests.c
index e6e5949..3e08f4a 100644
--- a/tests.c
+++ b/tests.c
@@ -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);
diff --git a/types.h b/types.h
index 498e7f0..25e4bc1 100644
--- a/types.h
+++ b/types.h
@@ -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