From 3b28d9cb8a760bc0ee2e49cd6f96dc6014afb9ba Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 17 Mar 2020 16:16:23 -0400 Subject: started defer --- Makefile | 7 +++++++ README.md | 2 +- cgen.c | 3 +++ copy.c | 3 +++ decls_cgen.c | 6 ++++++ parse.c | 11 +++++++++++ test.toc | 4 +++- toc.c | 1 - types.c | 8 ++++++++ types.h | 7 +++++-- 10 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f568f2a --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +toc: *.[ch] + ./build.sh +release: *.[ch] + ./build.sh release + +clean: + rm toc diff --git a/README.md b/README.md index 0bd8f54..f409b19 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ See `docs` for more information (in progress). `tests` has some test programs written in `toc`. -To compile the compiler on a Unix-y system, just run `./build.sh release`. You can supply a compiler by running `CC=tcc ./build.sh release`, or build it in debug mode without the `release`. To disable compile time foreign function support (which you will need to do if you don't have ffcall/dl), prefix this with `COMPILE_TIME_FOREIGN_FN_SUPPORT=no`. +To compile the compiler on a Unix-y system, just run `./build.sh release` (or `make release`). You can supply a compiler by running `CC=tcc ./build.sh release`, or build it in debug mode without the `release`. To disable compile time foreign function support (which you will need to do if you don't have ffcall/dl), prefix this with `COMPILE_TIME_FOREIGN_FN_SUPPORT=no`. On other systems, you can just compile main.c with a C compiler. `toc` uses several C99 and a couple of C11 features, so it might not work on all compilers. But it does compile on quite a few, including `clang`, `gcc`, and `tcc`. It can also be compiled as if it were C++, so and `g++` can also compile it (it does rely on implicit casting of `void *` though). MSVC can also compile toc. The *outputted* code should be C99-compliant. diff --git a/cgen.c b/cgen.c index d1ebab7..3595ed4 100644 --- a/cgen.c +++ b/cgen.c @@ -2067,6 +2067,9 @@ static void cgen_defs_stmt(CGenerator *g, Statement *s) { case STMT_CONT: case STMT_MESSAGE: break; + case STMT_DEFER: + cgen_defs_stmt(g, s->defer); + break; } } diff --git a/copy.c b/copy.c index f99d880..3919e46 100644 --- a/copy.c +++ b/copy.c @@ -433,6 +433,9 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) { case STMT_MESSAGE: copy_expr(c, &out->message.text, &in->message.text); break; + case STMT_DEFER: + copy_stmt(c, out->defer = allocr_malloc(c->allocr, sizeof *out->defer), in->defer); + break; case STMT_BREAK: case STMT_CONT: break; diff --git a/decls_cgen.c b/decls_cgen.c index 371d91f..048dd9d 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -159,6 +159,9 @@ static void cgen_sdecls_stmt(CGenerator *g, Statement *s) { break; case STMT_MESSAGE: break; + case STMT_DEFER: + cgen_sdecls_stmt(g, s->defer); + break; } } @@ -430,6 +433,9 @@ static void cgen_decls_stmt(CGenerator *g, Statement *s) { case STMT_CONT: case STMT_MESSAGE: break; + case STMT_DEFER: + cgen_decls_stmt(g, s->defer); + break; } } diff --git a/parse.c b/parse.c index 290bb5d..7c6fe7d 100644 --- a/parse.c +++ b/parse.c @@ -2448,6 +2448,13 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { return false; } goto success; + case KW_DEFER: + s->kind = STMT_DEFER; + ++t->token; + s->defer = parser_malloc(p, sizeof *s->defer); + if (!parse_stmt(p, s->defer, was_a_statement)) + return false; + goto success; default: break; } } else if (t->token->kind == TOKEN_DIRECT) { @@ -2932,6 +2939,10 @@ static void fprint_stmt(FILE *out, Statement *s) { case STMT_CONT: fprintf(out, "continue;"); break; + case STMT_DEFER: + fprintf(out, "defer "); + fprint_stmt(out, s->defer); + break; } } diff --git a/test.toc b/test.toc index f953cfe..66dfe61 100644 --- a/test.toc +++ b/test.toc @@ -1,3 +1,5 @@ +#include "std/io.toc"; main ::= fn() { - x ::= {return; 3} + defer puts("bye"); + puts("hello"); } diff --git a/toc.c b/toc.c index 75c25b1..6c1932d 100644 --- a/toc.c +++ b/toc.c @@ -4,7 +4,6 @@ You should have received a copy of the GNU General Public License along with toc. If not, see . */ - /* NOTE: Structure of the toc compiler: diff --git a/types.c b/types.c index 2d2d63a..9766997 100644 --- a/types.c +++ b/types.c @@ -3395,6 +3395,14 @@ static Status types_stmt(Typer *tr, Statement *s) { return false; } } break; + case STMT_DEFER: + if (!types_stmt(tr, s->defer)) + return false; + if (s->defer->kind == STMT_DEFER) { + err_print(s->where, "You can't defer a defer!"); + return false; + } + break; } s->flags |= STMT_TYPED; return true; diff --git a/types.h b/types.h index fbd3386..b2efa50 100644 --- a/types.h +++ b/types.h @@ -298,6 +298,7 @@ typedef enum { KW_RETURN, KW_BREAK, KW_CONTINUE, + KW_DEFER, KW_FN, KW_AS, KW_STRUCT, @@ -333,7 +334,7 @@ static const char *const keywords[KW_COUNT] = "+", "-", "*", "!", "&", "/", "%", "..", ".", "=", "if", "elif", "else", "while", "for", "return", "break", - "continue", "fn", "as", "struct", + "continue", "defer", "fn", "as", "struct", "int", "i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "float", "f32", "f64", "Type", "Namespace", @@ -913,7 +914,8 @@ typedef enum { STMT_BREAK, STMT_CONT, STMT_INCLUDE, - STMT_MESSAGE + STMT_MESSAGE, + STMT_DEFER } StatementKind; enum { @@ -978,6 +980,7 @@ typedef struct Statement { Include inc; Message message; /* #error, #warn, #info */ Block *referring_to; /* for break/continue; set during typing */ + struct Statement *defer; }; } Statement; -- cgit v1.2.3