From 692d13cc1a6fda2776d0ad0b34e9fbff0bc2c55c Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sun, 21 Jun 2020 17:47:55 -0400 Subject: everything now working with blocks not returning values --- cgen.c | 7 ++++-- docs.sh | 7 ------ docs/00.md | 59 ------------------------------------------- docs/01.md | 18 ------------- docs/docs.css | 11 ++++++++ main.c | 1 + test.toc | 4 +-- tests/arr.toc | 70 +++++++++++++++++++++++++-------------------------- tests/arr2.toc | 70 +++++++++++++++++++++++++-------------------------- tests/arr3.toc | 62 ++++++++++++++++++++++----------------------- tests/arrs_slices.toc | 2 +- tests/defer.toc | 4 +-- tests/misc.toc | 4 +-- tests/new.toc | 2 +- tests/nms.toc | 2 +- tests/printf.toc | 2 +- tests/sizeof.toc | 4 +-- tests/varargs.toc | 4 +-- 18 files changed, 132 insertions(+), 201 deletions(-) delete mode 100755 docs.sh delete mode 100644 docs/00.md delete mode 100644 docs/01.md create mode 100644 docs/docs.css diff --git a/cgen.c b/cgen.c index 04f93c1..64f0306 100644 --- a/cgen.c +++ b/cgen.c @@ -1422,6 +1422,8 @@ static void cgen_fn(CGenerator *g, FnExpr *f) { } cgen_block(g, &f->body, CGEN_BLOCK_NOBRACES); + cgen_deferred_from_block(g, &f->body); + if (f->ret_decls) cgen_ret(g, NULL, NULL); /* for example, if function is fn() x: int, we need to generate return x; at the end */ cgen_writeln(g, "}"); g->block = prev_block; g->fn = prev_fn; @@ -1538,6 +1540,7 @@ static void cgen_decl(CGenerator *g, Declaration *d) { } } +/* pass NULL as returning_from if you don't want to run any deferred things */ static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr) { FnExpr *f = g->fn; if (ret_expr) { @@ -1559,7 +1562,7 @@ static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr) } } - cgen_deferred_up_to(g, returning_from); + if (returning_from) cgen_deferred_up_to(g, returning_from); if (f->ret_decls) { if (f->ret_type.kind == TYPE_TUPLE) { Expression tuple_expr = {0}; @@ -2083,7 +2086,7 @@ static void cgen_file(CGenerator *g, ParsedFile *f, Typer *tr) { } cgen_write(g, "/* code */\n"); - cgen_write(g, "int main() {\n\tmain_();\n\treturn 0;\n}\n\n"); + cgen_write(g, "int main(void) {\n\tmain_();\n\treturn 0;\n}\n\n"); /* function definitions */ arr_foreach(tr->all_fns, FnWithCtx, fn_ctx) { g->nms = fn_ctx->nms; diff --git a/docs.sh b/docs.sh deleted file mode 100755 index 7dcf5e1..0000000 --- a/docs.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -markdown README.md > README.html -echo README.md -for x in docs/*.md; do - markdown $x > $(dirname $x)/$(basename $x .md).html - echo $x -done diff --git a/docs/00.md b/docs/00.md deleted file mode 100644 index 4998684..0000000 --- a/docs/00.md +++ /dev/null @@ -1,59 +0,0 @@ -## Declarations - -In toc, declarations have the following syntax: -``` - :[:] [type] [= expression]; -``` - -The square brackets (`[]`) indicate something optional. - -All of the following statements -declare an new variable `x` which is an integer, and has a value of 0: -``` -x : int; -x : int = 0; -x := 0; -``` -Note that in the first of those statements, although no expression -is specified, it defaults to 0. This is not true in C, -and there will eventually probably be an option to -leave `x` uninitialized. - -If you wanted x to be a floating-point number, you could use: -``` -x : float; -x : float = 0; -x := 0.0; -``` - -Note that `0` can be used as both a `float` and an `int`eger, but -when no type is specified, it defaults to an `int`, whereas `0.0` -defaults to a `float`. - -Here are all of toc's builtin types and their ranges of values: - -- `int` - A 64-bit signed integer (always), -9223372036854775808 to 9223372036854775807 -- `i8` - An 8-bit signed integer, -128 to 128 -- `i16` - 16-bit signed integer, -32768 to 32767 -- `i32` - 32-bit signed integer, -2147483648 to 2147483647 -- `i64` - 64-bit signed integer (same as `int`, but more explicit about the size), -9223372036854775808 to 9223372036854775807 -- `u8` - An 8-bit unsigned integer, 0 to 255 -- `u16` - 16-bit unsigned integer, 0 to 65535 -- `u32` - 32-bit unsigned integer, 0 to 4294967295 -- `u64` - 64-bit unsigned integer, 0 to 18446744073709551615 -- `float` - A 32-bit floating-point number, -3.40282347e+38 to 3.40282347e+38 -- `f32` - A 32-bit floating-point number (same as `float`, but more explicit about the size) -- `f64` - A 64-bit floating-point number, -1.7976931348623157e+308 to 1.7976931348623157e+308 -- `bool` - A boolean value, either `false` or `true`. -- `char` - A character. The specific values are technically platform-dependent, but usually there are 256 of them. - -At the moment, it is not technically guaranteed that `f32`/`float` is actually 32-bit and that `f64` is actually 64-bit; they are platform dependent. Perhaps someday there will be a version of toc which does not compile to C, where that could be guaranteed. - -To make declarations constant, use `::` instead of `:`. e.g. - -``` -x ::= 5+3; -y :: float = 5.123; -``` - -Here, "constant" means constant at compile time, not read-only as it does in C. One interesting thing about toc is that normal functions can run at compile time, so pretty much any expression is a valid initializer for a constant, e.g. doing `x ::= some_function();` runs `some_function` at compile time, not at run time. diff --git a/docs/01.md b/docs/01.md deleted file mode 100644 index 816f3e6..0000000 --- a/docs/01.md +++ /dev/null @@ -1,18 +0,0 @@ -### A first program - -The `main` function in toc corresponds to the `main` function in C. This function is called when your program is run. So, this is a valid toc program which does nothing: - -``` -main ::= fn() { -}; -``` - -It declares a constant, `main`, which is a function with an empty body. Note that the syntax for declaring functions is the same as the syntax for declaring constants (it isn't something like `fn main() { ... }`). - -Assuming you have compiled the compiler (see `README.md` for instructions about that), you can compile it with - -``` -toc -``` - -You will get a file called `out.c`, which you can then put through your C compiler to get an executable file which does nothing. Congratulations! You've written your first toc program. diff --git a/docs/docs.css b/docs/docs.css new file mode 100644 index 0000000..98871a2 --- /dev/null +++ b/docs/docs.css @@ -0,0 +1,11 @@ +body { + font-family: sans-serif; +} +c { + font-family: monospace; +} +a, a:visited { + text-decoration: none; + color: #038083; +} + diff --git a/main.c b/main.c index 94c0379..b7e5fa5 100644 --- a/main.c +++ b/main.c @@ -19,6 +19,7 @@ enums unions bitwise operations --- +#compile_only for functions only used at compile time switch to / add as an alternative: libffi - better yet, inline assembly don't bother generating ret_ if nothing's deferred diff --git a/test.toc b/test.toc index 25c38d5..73d1ad1 100644 --- a/test.toc +++ b/test.toc @@ -1,5 +1,5 @@ -#include "std/io.toc", io; -#include "std/mem.toc"; +#include "tests/std/io.toc", io; +#include "tests/std/mem.toc"; z ::= nms { Foo ::= struct(f ::= fn() int { return 7; }) { diff --git a/tests/arr.toc b/tests/arr.toc index afcf340..d85b06d 100644 --- a/tests/arr.toc +++ b/tests/arr.toc @@ -3,55 +3,55 @@ // it would be nice if Arr.data.len == Arr.len (: but this will require some C code... Arr ::= fn (t :: Type) Type { - struct { - data : []t; - len, cap : int; - } + return struct { + data : []t; + len, cap : int; + }; }; arr_add ::= fn(t :: Type, a : &Arr(t), x : t) { - if a.len >= a.cap { - a.cap = a.cap * 2 + 2; - new_data := news(t, a.cap); - for i := 0..a.len-1 { - new_data[i] = a.data[i]; - } - a.data = new_data; + if a.len >= a.cap { + a.cap = a.cap * 2 + 2; + new_data := news(t, a.cap); + for i := 0..a.len-1 { + new_data[i] = a.data[i]; } - a.data[a.len] = x; - a.len += 1; + a.data = new_data; + } + a.data[a.len] = x; + a.len += 1; }; square ::= fn(t :: Type, x : t) t { - a : Arr(t); - for i := 1,2..2*x-1 { - arr_add(t, &a, i); - }; - sum := 0 as t; - for i := 0..a.len-1 { - sum += a.data[i]; - }; - sum + a : Arr(t); + for i := 1,2..2*x-1 { + arr_add(t, &a, i); + }; + sum := 0 as t; + for i := 0..a.len-1 { + sum += a.data[i]; + }; + return sum; }; ArrInt ::= Arr(int); inc ::= fn(t :: Type, x : t) t { - x + 1 + return x + 1; }; main ::= fn() { - arr : ArrInt; - farr : Arr(float); - for i := 1..100 { - arr_add(int, &arr, inc(int, square(int, i))); - arr_add(float, &farr, inc(float, square(float, i as float))); - } - for i := 0..arr.len - 1 { - puti(arr.data[i]); - } - for i := 0..farr.len - 1 { - putf(farr.data[i]); - } + arr : ArrInt; + farr : Arr(float); + for i := 1..100 { + arr_add(int, &arr, inc(int, square(int, i))); + arr_add(float, &farr, inc(float, square(float, i as float))); + } + for i := 0..arr.len - 1 { + puti(arr.data[i]); + } + for i := 0..farr.len - 1 { + putf(farr.data[i]); + } }; diff --git a/tests/arr2.toc b/tests/arr2.toc index 4d8ca82..7e29a95 100644 --- a/tests/arr2.toc +++ b/tests/arr2.toc @@ -3,55 +3,55 @@ // it would be nice if Arr.data.len == Arr.len (: but this will require some C code... Arr ::= fn (t :: Type) Type { - struct { - data : []t; - len, cap : int; - } + return struct { + data : []t; + len, cap : int; + }; }; arr_add ::= fn(t ::=, a : &Arr(t), x : t) { - if a.len >= a.cap { - a.cap = a.cap * 2 + 2; - new_data := news(t, a.cap); - for i := 0..a.len-1 { - new_data[i] = a.data[i]; - } - a.data = new_data; + if a.len >= a.cap { + a.cap = a.cap * 2 + 2; + new_data := news(t, a.cap); + for i := 0..a.len-1 { + new_data[i] = a.data[i]; } - a.data[a.len] = x; - a.len += 1; + a.data = new_data; + } + a.data[a.len] = x; + a.len += 1; }; square ::= fn(t ::=, x : t) t { - a : Arr(t); - for i := 1,2..2*x-1 { - arr_add(&a, i); - }; - sum := 0 as t; - for i := 0..a.len-1 { - sum += a.data[i]; - }; - sum + a : Arr(t); + for i := 1,2..2*x-1 { + arr_add(&a, i); + }; + sum := 0 as t; + for i := 0..a.len-1 { + sum += a.data[i]; + }; + return sum; }; // ArrInt ::= Arr(int); inc ::= fn(t ::=, x : t) t { - x + 1 + return x + 1; }; main ::= fn() { - arr : Arr(int); - farr : Arr(float); - for i := 1..100 { - arr_add(&arr, inc(square(i))); - arr_add(&farr, inc(square(i as float))); - } - for i := 0..arr.len - 1 { - puti(arr.data[i]); - } - for i := 0..farr.len - 1 { - putf(farr.data[i]); - } + arr : Arr(int); + farr : Arr(float); + for i := 1..100 { + arr_add(&arr, inc(square(i))); + arr_add(&farr, inc(square(i as float))); + } + for i := 0..arr.len - 1 { + puti(arr.data[i]); + } + for i := 0..farr.len - 1 { + putf(farr.data[i]); + } }; diff --git a/tests/arr3.toc b/tests/arr3.toc index 25c5554..246be65 100644 --- a/tests/arr3.toc +++ b/tests/arr3.toc @@ -3,50 +3,50 @@ arr_add ::= fn(t ::=, a : &Arr(t), x : t) { - if a.len >= a.cap { - a.cap = a.cap * 2 + 2; - new_data := news(t, a.cap); - for i := 0..a.len-1 { - new_data[i] = a.data[i]; - } - a.data = new_data; + if a.len >= a.cap { + a.cap = a.cap * 2 + 2; + new_data := news(t, a.cap); + for i := 0..a.len-1 { + new_data[i] = a.data[i]; } - a.data[a.len] = x; - a.len += 1; + a.data = new_data; + } + a.data[a.len] = x; + a.len += 1; }; square ::= fn(t ::=, x : t) t { - a : Arr(t); - for i := 1,2..2*x-1 { - arr_add(&a, i); - }; - sum := 0 as t; - for i := 0..a.len-1 { - sum += a.data[i]; - }; - sum + a : Arr(t); + for i := 1,2..2*x-1 { + arr_add(&a, i); + }; + sum := 0 as t; + for i := 0..a.len-1 { + sum += a.data[i]; + }; + return sum; }; ArrInt ::= Arr(int); inc ::= fn(t ::=, x : t) t { - x + 1 + return x + 1; }; main ::= fn() { - arr : ArrInt; - farr : Arr(float); - for i := 1..100 { - arr_add(&arr, inc(square(i))); - arr_add(&farr, inc(square(i as float))); - } - for i := 0..arr.len - 1 { - puti(arr.data[i]); - } - for i := 0..farr.len - 1 { - puti(farr.data[i] as int); - } + arr : ArrInt; + farr : Arr(float); + for i := 1..100 { + arr_add(&arr, inc(square(i))); + arr_add(&farr, inc(square(i as float))); + } + for i := 0..arr.len - 1 { + puti(arr.data[i]); + } + for i := 0..farr.len - 1 { + puti(farr.data[i] as int); + } }; Arr ::= struct (t :: Type) { diff --git a/tests/arrs_slices.toc b/tests/arrs_slices.toc index dc7526d..fce8816 100644 --- a/tests/arrs_slices.toc +++ b/tests/arrs_slices.toc @@ -36,7 +36,7 @@ thing ::= fn() int { defer dels(bar); fill_slice(&bar); b := sum_slice(&bar); - a+b + return a+b; } main ::= fn() { diff --git a/tests/defer.toc b/tests/defer.toc index 07ef9f7..e1262f0 100644 --- a/tests/defer.toc +++ b/tests/defer.toc @@ -7,14 +7,14 @@ plusone ::= fn(n : int) x := n { same ::= fn(n : int) int { x := n; defer x += 1; - x + return x; } thing1 ::= fn() (int, int) { x := 5; y := 6; defer x += 1; - x, y + return x, y; } thing2 ::= fn() x := 5, y := 6 { diff --git a/tests/misc.toc b/tests/misc.toc index 3673a07..04932e8 100644 --- a/tests/misc.toc +++ b/tests/misc.toc @@ -3,7 +3,7 @@ main ::= fn() { x ::= 3; #if x > 2 { - io.puts("Hello!"); + io.puts("Hello!"); } else { foo("yes"); } @@ -17,7 +17,7 @@ main ::= fn() { for x := a { total += x; } - total + return total; }; mk_arr ::= fn(x:int, y:int, z:int) a:[3]int { diff --git a/tests/new.toc b/tests/new.toc index 790a115..8535a5e 100644 --- a/tests/new.toc +++ b/tests/new.toc @@ -17,7 +17,7 @@ calculation ::= fn() int { total += *i; mem.del(i); mem.dels(ns); - total + return total; } main ::= fn() { diff --git a/tests/nms.toc b/tests/nms.toc index 32c2955..f5aa688 100644 --- a/tests/nms.toc +++ b/tests/nms.toc @@ -4,7 +4,7 @@ io ::= nms { n ::= nms { x := 1; - counter ::= fn() int { x += 1; x }; + counter ::= fn() int { x += 1; return x; }; }; diff --git a/tests/printf.toc b/tests/printf.toc index ede3012..a6ef348 100644 --- a/tests/printf.toc +++ b/tests/printf.toc @@ -18,7 +18,7 @@ tprintf_valid ::= fn(fmt :: []char, nargs: int) bool { } } } - count == nargs + return count == nargs; }; diff --git a/tests/sizeof.toc b/tests/sizeof.toc index 5a97985..a12648e 100644 --- a/tests/sizeof.toc +++ b/tests/sizeof.toc @@ -6,8 +6,8 @@ Point3D ::= struct { calculation ::= fn() int { p: Point3D; - (#sizeof Point3D) * (#sizeof typeof p) * (sizeof Point3D) * (sizeof typeof p) - * (#alignof Point3D) * (#alignof typeof p) * (alignof Point3D) * (alignof typeof p) + return (#sizeof Point3D) * (#sizeof typeof p) * (sizeof Point3D) * (sizeof typeof p) + * (#alignof Point3D) * (#alignof typeof p) * (alignof Point3D) * (alignof typeof p); } main ::= fn() { diff --git a/tests/varargs.toc b/tests/varargs.toc index 0885da4..ff315c6 100644 --- a/tests/varargs.toc +++ b/tests/varargs.toc @@ -9,7 +9,7 @@ sum ::= fn(x: ..) int { for a, i := x { total += a + i - i + 1; } - total - x.len + return total - x.len; }; sumc ::= fn(x:: ..) int { @@ -17,7 +17,7 @@ sumc ::= fn(x:: ..) int { for a, i := x { total += a + i - i + 1; } - total - x.len + return total - x.len; }; do_printing ::= fn(x::..) { -- cgit v1.2.3