diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-16 20:55:18 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-16 20:55:18 -0400 |
commit | 63ea50be35afb6d7b9dbcd20fe3c31de6187858e (patch) | |
tree | 6356cb27f1285379aa5c46d7863ba7a25364e3f2 | |
parent | 6855c6e752e4e4f2f37702477a3b461a51bbc614 (diff) |
updated tests, fixed bugs
-rw-r--r-- | cgen.c | 61 | ||||
-rw-r--r-- | decls_cgen.c | 10 | ||||
-rw-r--r-- | eval.c | 3 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | std/mem.toc | 10 | ||||
-rw-r--r-- | test.toc | 19 | ||||
-rw-r--r-- | tests/arr.toc | 3 | ||||
-rw-r--r-- | tests/arr2.toc | 3 | ||||
-rw-r--r-- | tests/arr3.toc | 3 | ||||
-rw-r--r-- | tests/bf.toc | 26 | ||||
-rw-r--r-- | tests/mem.toc | 23 | ||||
-rw-r--r-- | tests/new.toc | 27 | ||||
-rw-r--r-- | tests/new_expected | 2 | ||||
-rwxr-xr-x | tests/test.sh | 1 |
14 files changed, 128 insertions, 64 deletions
@@ -138,34 +138,39 @@ static void cgen_defs_decl(CGenerator *g, Declaration *d); } -#define cgen_recurse_subtypes(f, g, type) \ - switch (type->kind) { \ - case TYPE_STRUCT: \ - /* don't descend into fields */ \ - break; \ - case TYPE_FN: \ - arr_foreach(type->fn.types, Type, sub) { \ - f(g, sub); \ - } \ - break; \ - case TYPE_TUPLE: \ - arr_foreach(type->tuple, Type, sub) \ - f(g, sub); \ - break; \ - case TYPE_ARR: \ - f(g, type->arr.of); \ - break; \ - case TYPE_SLICE: \ - f(g, type->slice); \ - break; \ - case TYPE_PTR: \ - f(g, type->ptr); \ - break; \ - case TYPE_VOID: \ - case TYPE_BUILTIN: \ - case TYPE_UNKNOWN: \ - break; \ - case TYPE_EXPR: assert(0); \ +#define cgen_recurse_subtypes(f, g, type) \ + switch (type->kind) { \ + case TYPE_STRUCT: \ + /* don't descend into fields */ \ + break; \ + case TYPE_FN: \ + if (type->kind == TYPE_FN && (type->fn.constness || fn_type_has_varargs(&type->fn))) { \ + /* we don't want to do this, because it's a template-y thing */ \ + } \ + else { \ + arr_foreach(type->fn.types, Type, sub) { \ + f(g, sub); \ + } \ + } \ + break; \ + case TYPE_TUPLE: \ + arr_foreach(type->tuple, Type, sub) \ + f(g, sub); \ + break; \ + case TYPE_ARR: \ + f(g, type->arr.of); \ + break; \ + case TYPE_SLICE: \ + f(g, type->slice); \ + break; \ + case TYPE_PTR: \ + f(g, type->ptr); \ + break; \ + case TYPE_VOID: \ + case TYPE_BUILTIN: \ + case TYPE_UNKNOWN: \ + break; \ + case TYPE_EXPR: assert(0); \ } diff --git a/decls_cgen.c b/decls_cgen.c index 045367e..371d91f 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -12,15 +12,11 @@ static void cgen_decls_decl(CGenerator *g, Declaration *d); /* i is the name for this type, NULL if not available */ static void cgen_sdecls_type(CGenerator *g, Type *type) { - if (!(type->flags & TYPE_IS_RESOLVED)) /* non-instance constant fn parameter type */ - return; if (type->kind == TYPE_STRUCT) { StructDef *sdef = type->struc; /* we'll actually define the struct later; here we can just declare it */ - if (sdef->flags & STRUCT_DEF_CGEN_DECLARED) { - /* we've already done this */ - } else { + if ((sdef->flags & STRUCT_DEF_RESOLVED) && !(sdef->flags & STRUCT_DEF_CGEN_DECLARED)) { cgen_write(g, "struct "); if (!sdef->name) { sdef->c.id = ++g->ident_counter; @@ -173,11 +169,9 @@ static void cgen_sdecls_file(CGenerator *g, ParsedFile *f) { } static void cgen_decls_type(CGenerator *g, Type *type) { - if (!(type->flags & TYPE_IS_RESOLVED)) /* non-instance constant fn parameter type */ - return; if (type->kind == TYPE_STRUCT) { StructDef *sdef = type->struc; - if (!(sdef->flags & STRUCT_DEF_CGEN_DEFINED)) { + if ((sdef->flags & STRUCT_DEF_RESOLVED) && !(sdef->flags & STRUCT_DEF_CGEN_DEFINED)) { /* generate struct definition */ cgen_write(g, "struct "); cgen_struct_name(g, sdef); @@ -748,8 +748,7 @@ static Status eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr, void if (!eval_address_of(ev, dot_expr->binary.lhs, &ptr)) return false; /* access struct data */ - Identifier ident = dot_expr->binary.rhs->ident; - assert(ident_eq_str(ident, "data")); + assert(ident_eq_str(dot_expr->binary.rhs->ident, "data")); *p = &((Slice *)ptr)->data; } else { void *ptr; @@ -8,7 +8,6 @@ /* TODO: -- make new(s) and del functions! defer use &&, || diff --git a/std/mem.toc b/std/mem.toc index 06890b5..5e8c5fa 100644 --- a/std/mem.toc +++ b/std/mem.toc @@ -1,14 +1,14 @@ -// TODO: check for failed malloc -malloc ::= #foreign("malloc", "libc.so.6") fn(#C size_t) #C &"void"; +// TODO: check for failed calloc +calloc ::= #foreign("calloc", "libc.so.6") fn(#C size_t, #C size_t) #C &"void"; free ::= #foreign("free", "libc.so.6") fn(#C &"void"); new ::= fn(t :: Type) &t { - malloc((sizeof t) as u64) + calloc(1, (sizeof t) as u64) } -news ::= fn(t :: Type, n :: int) []t { +news ::= fn(t :: Type, n : int) []t { s: []t; - s.data = malloc((n * sizeof t) as u64); + s.data = calloc(n as u64, (sizeof t) as u64); s.len = n; s } @@ -1,18 +1,27 @@ #include "std/mem.toc", mem; #include "std/io.toc", io; -main ::= fn() { + +calculation ::= fn() int { + total := 0; i := mem.new(int); *i = 3; - io.puti(*i); ns := mem.news(int, 10); for n, i := &ns { - *n = i; + if i % 2 == 0 { + *n = i; + } } for n := ns { - io.puti(n); + total += n; } + total += *i; mem.del(i); mem.dels(ns); + total } -main(); +main ::= fn() { + io.puti(calculation()); + x ::= calculation(); + io.puti(x); +} diff --git a/tests/arr.toc b/tests/arr.toc index eee514a..5fb8328 100644 --- a/tests/arr.toc +++ b/tests/arr.toc @@ -1,3 +1,4 @@ +#include "mem.toc"; puti ::= fn(x: int) { //tcc's giving me "incompatible types for redefinition of 'printf'" for some reason (even though the declarations have the exact same type) #C("#ifndef __TINYC__ @@ -25,7 +26,7 @@ Arr ::= fn (t :: Type) Type { arr_add ::= fn(t :: Type, a : &Arr(t), x : t) { if a.len >= a.cap { a.cap = a.cap * 2 + 2; - new_data := new(t, a.cap); + new_data := news(t, a.cap); for i := 0..a.len-1 { new_data[i] = a.data[i]; } diff --git a/tests/arr2.toc b/tests/arr2.toc index e016cf2..9d6aa34 100644 --- a/tests/arr2.toc +++ b/tests/arr2.toc @@ -1,3 +1,4 @@ +#include "mem.toc"; puti ::= fn(x: int) { #C("#ifndef __TINYC__ extern int printf(const char *fmt, ...); @@ -26,7 +27,7 @@ Arr ::= fn (t :: Type) Type { arr_add ::= fn(t ::=, a : &Arr(t), x : t) { if a.len >= a.cap { a.cap = a.cap * 2 + 2; - new_data := new(t, a.cap); + new_data := news(t, a.cap); for i := 0..a.len-1 { new_data[i] = a.data[i]; } diff --git a/tests/arr3.toc b/tests/arr3.toc index a6d1b14..cfbbc5a 100644 --- a/tests/arr3.toc +++ b/tests/arr3.toc @@ -1,4 +1,5 @@ #include "io.toc"; +#include "mem.toc"; Arr ::= struct (t :: Type) { data: []t; @@ -9,7 +10,7 @@ Arr ::= struct (t :: Type) { arr_add ::= fn(t ::=, a : &Arr(t), x : t) { if a.len >= a.cap { a.cap = a.cap * 2 + 2; - new_data := new(t, a.cap); + new_data := news(t, a.cap); for i := 0..a.len-1 { new_data[i] = a.data[i]; } diff --git a/tests/bf.toc b/tests/bf.toc index e1f8781..d300bc9 100644 --- a/tests/bf.toc +++ b/tests/bf.toc @@ -1,7 +1,9 @@ +#include "mem.toc"; + readfile ::= fn(filename: []char) []char { #C("extern void *fopen(char *name, char const *mode); extern char *fgets(char *buf, size_t sz, void *f);"); fp : &u8 = #C("fopen(&(((char *)filename.data)[0]), \"r\")"); - contents : []char; + contents := news(char, 1); contents_sz : int; contents_len : int; buffer : [1024]char; @@ -13,13 +15,13 @@ readfile ::= fn(filename: []char) []char { if contents_sz < contents_len + buffer_len { old_contents := contents; contents_sz = 2*contents_sz + 1024; - contents = new(char, contents_sz); + contents = news(char, contents_sz); i := 0; while i < contents_len { contents[i] = old_contents[i]; i = i + 1; } - del(old_contents); + dels(old_contents); } i := 0; while i < buffer_len { @@ -44,7 +46,7 @@ runfile ::= fn(filename: []char) { #C("extern int putchar(int c);"); code := readfile(filename); tape_sz := 3; - tape := new(int, tape_sz); + tape := news(int, tape_sz); ptr := tape_sz / 2; i := 0; while code[i] { @@ -58,28 +60,28 @@ runfile ::= fn(filename: []char) { ptr = ptr + 1; if ptr >= tape_sz { // extend to the right - newtape := new(int, 2*tape_sz); + newtape := news(int, 2*tape_sz); j := 0; while j < tape_sz { newtape[j] = tape[j]; j = j + 1; } tape_sz = tape_sz * 2; - del(tape); + dels(tape); tape = newtape; } } elif code[i] == '<' { ptr = ptr - 1; if ptr < 0 { // extend to the left - newtape := new(int, 2*tape_sz); + newtape := news(int, 2*tape_sz); j := 0; while j < tape_sz { newtape[j+tape_sz] = tape[j]; j = j + 1; } tape_sz = tape_sz * 2; - del(tape); + dels(tape); tape = newtape; ptr = ptr + tape_sz; } @@ -110,11 +112,11 @@ runfile ::= fn(filename: []char) { } i = i + 1; } - del(tape); - del(code); + dels(tape); + dels(code); }; main ::= fn() { - runfile("bf_hw0"); - runfile("bf_hw1"); + runfile("bf_hw0\0"); + runfile("bf_hw1\0"); }; diff --git a/tests/mem.toc b/tests/mem.toc new file mode 100644 index 0000000..5e8c5fa --- /dev/null +++ b/tests/mem.toc @@ -0,0 +1,23 @@ +// TODO: check for failed calloc +calloc ::= #foreign("calloc", "libc.so.6") fn(#C size_t, #C size_t) #C &"void"; +free ::= #foreign("free", "libc.so.6") fn(#C &"void"); + +new ::= fn(t :: Type) &t { + calloc(1, (sizeof t) as u64) +} + +news ::= fn(t :: Type, n : int) []t { + s: []t; + s.data = calloc(n as u64, (sizeof t) as u64); + s.len = n; + s +} + +// TODO(eventually): use type information to make this just one function +del ::= fn(t::=, x: &t) { + free(x); +} + +dels ::= fn(t::=, x: []t) { + free(x.data); +}
\ No newline at end of file diff --git a/tests/new.toc b/tests/new.toc new file mode 100644 index 0000000..bb6a5fa --- /dev/null +++ b/tests/new.toc @@ -0,0 +1,27 @@ +#include "mem.toc", mem; +#include "io.toc", io; + +calculation ::= fn() int { + total := 0; + i := mem.new(int); + *i = 3; + ns := mem.news(int, 10); + for n, i := &ns { + if i % 2 == 0 { + *n = i; + } + } + for n := ns { + total += n; + } + total += *i; + mem.del(i); + mem.dels(ns); + total +} + +main ::= fn() { + io.puti(calculation()); + x ::= calculation(); + io.puti(x); +} diff --git a/tests/new_expected b/tests/new_expected new file mode 100644 index 0000000..c1eee21 --- /dev/null +++ b/tests/new_expected @@ -0,0 +1,2 @@ +23 +23 diff --git a/tests/test.sh b/tests/test.sh index 5e4535a..8adf412 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -3,6 +3,7 @@ tests='bf control_flow sizeof +new arr arr2 arr3 |