summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c5
-rw-r--r--development.md37
-rw-r--r--main.c2
-rw-r--r--test.toc5
-rw-r--r--toc.c31
-rw-r--r--types.c25
-rw-r--r--types.h2
7 files changed, 72 insertions, 35 deletions
diff --git a/cgen.c b/cgen.c
index 8a06c57..3f4157a 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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.
+
diff --git a/main.c b/main.c
index d60b10d..86916d1 100644
--- a/main.c
+++ b/main.c
@@ -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:
diff --git a/test.toc b/test.toc
index 8e611c0..2b44207 100644
--- a/test.toc
+++ b/test.toc
@@ -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;
diff --git a/toc.c b/toc.c
index 1b5ce6d..e51ed8d 100644
--- a/toc.c
+++ b/toc.c
@@ -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>
diff --git a/types.c b/types.c
index 109fa68..a669bf7 100644
--- a/types.c
+++ b/types.c
@@ -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;
diff --git a/types.h b/types.h
index 0b0fcbb..710faf8 100644
--- a/types.h
+++ b/types.h
@@ -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 {