diff options
-rw-r--r-- | cgen.c | 5 | ||||
-rw-r--r-- | development.md | 37 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | test.toc | 5 | ||||
-rw-r--r-- | toc.c | 31 | ||||
-rw-r--r-- | types.c | 25 | ||||
-rw-r--r-- | types.h | 2 |
7 files changed, 72 insertions, 35 deletions
@@ -2096,11 +2096,12 @@ static void cgen_stmt(CGenerator *g, Statement *s) { cgen_lbl(g, b->c.cont_lbl); cgen_writeln(g, ";"); } break; - case STMT_MESSAGE: - break; case STMT_DEFER: *(Statement **)arr_add(&g->block->deferred) = s->defer; break; + case STMT_USE: + case STMT_MESSAGE: + break; } } diff --git a/development.md b/development.md new file mode 100644 index 0000000..6021532 --- /dev/null +++ b/development.md @@ -0,0 +1,37 @@ +## Guide to toc's source code + +This document is intended for people who would like to develop toc. + +Structure of the toc compiler: +tokenizer => parser => typing (types.c) => cgen + +toc tries to continue even after the first error. +If one stage fails, the following ones do not +start. + +toc's memory management works using an allocator which never frees anything. +This is because most of toc's data is kept around until the end of the program anyways. +Use the allocator for "permanent" allocations, and err\_malloc/calloc/realloc for temporary +allocations (to avoid having it take up space for a long time). + +Because of this, memory leaks can happen if the compilation fails at any point, but they +should not happen if the compilation succeeds. Usually if there's an error +which causes a memory leak, it will be very small. + +Functions which can fail (i.e. print an error message and stop) return a Status, +which is a bool, but GCC warns about not using the return value. + +The fixed-width types U8/16/32/64 and I8/16/32/64 have been defined. +data\_structures.c contains a dynamic array implementation which is very useful. +Many of the members of the types below are dynamic arrays. + + +### Notes + +Identifiers are kept in a hash table in the block in which they reside. +They are resolved during typing (i.e. each identifier is associated with its +declaration). + +It is assumed that the number of identifiers in a declaration, or parameters to a function +will fit in an int, since a function with (at least) 32768 parameters is ridiculous. + @@ -4,7 +4,7 @@ You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ -/* see toc.c for development information */ +/* see development.md for development information */ /* TODO: @@ -2,6 +2,11 @@ Point ::= struct { x, y: int; } +mkpoint ::= fn(x, y: int) p: Point { + p.x = x; + p.y = y; +} + main ::= fn() { p: Point; use p; @@ -4,37 +4,6 @@ You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ -/* - NOTE: - Structure of the toc compiler: - tokenizer => parser => typing (types.c) => cgen - (lexing) - - toc tries to continue even after the first error. - If one stage fails, the following ones do not - start. - - toc's memory management works using an allocator which never frees anything. - This is because most of toc's data is kept around until the end of the program anyways. - Use the allocator for "permanent" allocations, and err_malloc/calloc/realloc for temporary - allocations (to avoid having it take up space for a long time). - - Because of this, memory leaks can happen if the compilation fails at any point, but they - should not happen if the compilation succeeds. Usually if there's an error - which causes a memory leak, it will be very small. - - Functions which can fail (i.e. print an error message and stop) return a Status, - which is a bool, but GCC warns about not using the return value. - - The fixed-width types U8/16/32/64 and I8/16/32/64 have been defined. - data_structures.c contains a dynamic array implementation which is very useful. - Many of the members of the types below are dynamic arrays. - - It is assumed that the number of identifiers in a declaration, or parameters to a function - will fit in an int, since a function with (at least) 32768 parameters is ridiculous. -*/ - - /* Includes all of toc's files */ #include <assert.h> #include <ctype.h> @@ -3315,6 +3315,13 @@ static Status types_decl(Typer *tr, Declaration *d) { return success; } +static bool expr_is_usable(Expression *e) { + if (e->kind == EXPR_IDENT) return true; + if (e->kind == EXPR_BINARY_OP && e->binary.op == BINARY_DOT) + return expr_is_usable(e->binary.lhs); + return false; +} + static Status types_stmt(Typer *tr, Statement *s) { if (s->flags & STMT_TYPED) return true; switch (s->kind) { @@ -3474,6 +3481,24 @@ static Status types_stmt(Typer *tr, Statement *s) { return false; } break; + case STMT_USE: { + Expression *e = &s->use; + if (!types_expr(tr, e)) + return false; + if (e->type.kind != TYPE_STRUCT && !type_is_builtin(&e->type, BUILTIN_NMS)) { + char *str = type_to_str(&e->type); + err_print(s->where, "You cannot use something of type %s (only Namespaces and structs).", str); + free(str); + return false; + } + if (!expr_is_usable(e)) { + err_print(e->where, "You can't use this value. You should probably assign it to a variable."); + return false; + } + UsedExpr *u = arr_add(&tr->used); + u->scope = tr->block; + u->stmt = s; + } break; } s->flags |= STMT_TYPED; return true; @@ -1056,7 +1056,7 @@ typedef struct Typer { ParsedFile *parsed_file; Namespace *nms; StrHashTable included_files; /* maps to IncludedFile */ - UsedExpr *used; /* things which are currently being `use`d */ + UsedExpr *used; /* things which are currently being `use`d. dynamic array NOT on the allocator. */ } Typer; typedef struct CGenerator { |