summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-17 21:07:15 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-17 21:07:15 -0500
commit09a23bab279ac54b365e50e84962fdc2125114b9 (patch)
tree9555d70171c111b3c151970bdd977d7c2713595d
parent3d3c0f04e26d3f07983601dc91714e3dca447206 (diff)
Location bug fix and (&Package).something
-rw-r--r--allocator.c2
-rw-r--r--main.c1
-rw-r--r--parse.c13
-rw-r--r--test.toc8
-rw-r--r--toc.c1
-rw-r--r--tokenizer.c5
-rw-r--r--types.c34
7 files changed, 46 insertions, 18 deletions
diff --git a/allocator.c b/allocator.c
index 3ad11c1..d1d1fed 100644
--- a/allocator.c
+++ b/allocator.c
@@ -8,7 +8,7 @@ static void *err_malloc(size_t bytes);
static void *err_calloc(size_t n, size_t sz);
static void *err_realloc(void *prev, size_t new_size);
#ifdef TOC_DEBUG
-/* #define NO_ALLOCATOR 1 /\* useful for debugging; valgrind checks writing past the end of a malloc, but that won't work with an allocator *\/ */
+#define NO_ALLOCATOR 1 /* useful for debugging; valgrind checks writing past the end of a malloc, but that won't work with an allocator */
#endif
/* number of bytes a page hold, not including the header */
#define PAGE_BYTES (16384 - sizeof(Page))
diff --git a/main.c b/main.c
index 3d942be..a98fbb2 100644
--- a/main.c
+++ b/main.c
@@ -18,7 +18,6 @@
/*
TODO:
-make sure (&Package).something works
C functions (#foreign)
#include
variadic fns
diff --git a/parse.c b/parse.c
index 6cd14ed..921a3b0 100644
--- a/parse.c
+++ b/parse.c
@@ -777,7 +777,6 @@ static bool parse_block(Parser *p, Block *b) {
++t->token; /* move past { */
b->stmts = NULL;
bool ret = true;
- b->ret_expr = NULL; /* default to no return unless overwritten later */
if (!token_is_kw(t->token, KW_RBRACE)) {
/* non-empty block */
while (1) {
@@ -946,7 +945,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
if (!parse_type(p, &e->typeval))
return false;
if (t->token == end) goto success;
- /* there's more stuff after. maybe it's, e.g. int, float */
+ /* there's more stuff after */
}
t->token = before;
if (end - t->token == 1) {
@@ -1400,7 +1399,9 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
++t->token;
Expression *of = parser_new_expr(p);
e->unary.of = of;
- return parse_expr(p, of, end);
+ if (!parse_expr(p, of, end))
+ return false;
+ goto success;
}
if (lowest_precedence_op->kw == KW_AS) {
@@ -1587,7 +1588,9 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
return false;
}
t->token = opening_bracket;
- return parse_args(p, &e->call.args);
+ if (!parse_args(p, &e->call.args))
+ return false;
+ goto success;
}
case KW_LSQUARE: {
Expression *arr = parser_new_expr(p);
@@ -1732,6 +1735,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
}
success:
e->where.end = t->token;
+ assert(t->token == end);
if (e->kind == EXPR_FN) {
e->fn->where = e->where;
@@ -1991,7 +1995,6 @@ static bool parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
tokr_skip_to_eof(t);
return false;
}
-
bool success = parse_expr(p, &s->expr, end);
/* go past end of expr regardless of whether successful or not */
diff --git a/test.toc b/test.toc
index c278703..d7654e3 100644
--- a/test.toc
+++ b/test.toc
@@ -1,5 +1,11 @@
-io ::= pkg "std/io";
+import ::= fn(x :: []char) &Package {
+ p ::= pkg x;
+ p_ptr ::= new(Package);
+ *p_ptr = p;
+ p_ptr
+};
main ::= fn() {
+ io ::= import("std/io");
io.puts("Hello, world!");
}; \ No newline at end of file
diff --git a/toc.c b/toc.c
index d62c111..153a19f 100644
--- a/toc.c
+++ b/toc.c
@@ -40,6 +40,7 @@
/* forward declarations for debugging */
static void print_val(Value v, Type *t);
+static void print_token(Token *t);
/* misc */
diff --git a/tokenizer.c b/tokenizer.c
index 72eb005..8aece94 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -118,6 +118,11 @@ static void fprint_token(FILE *out, Token *t) {
}
}
+static void print_token(Token *t) {
+ fprint_token(stdout, t);
+ printf("\n");
+}
+
static inline void tokr_nextchar(Tokenizer *t) {
if (*(t->s) == '\n') {
++t->line;
diff --git a/types.c b/types.c
index a6c02ba..11c40a4 100644
--- a/types.c
+++ b/types.c
@@ -1913,22 +1913,38 @@ static bool types_expr(Typer *tr, Expression *e) {
if (!types_expr(tr, lhs)) return false;
Type *struct_type = lhs_type;
if (struct_type->kind == TYPE_UNKNOWN) return true;
+ if (struct_type->kind == TYPE_PTR)
+ struct_type = struct_type->ptr;
+
if (type_is_builtin(struct_type, BUILTIN_PKG)) {
if (rhs->kind != EXPR_IDENT) {
err_print(rhs->where, "Expected identifier for package access, but got %s.",
expr_kind_to_str(rhs->kind));
return false;
}
- Value pkg_val;
- if (!eval_expr(tr->evalr, lhs, &pkg_val))
- return false;
- lhs->kind = EXPR_VAL;
- lhs->val = pkg_val;
- e->binary.dot.pkg_ident = ident_translate(rhs->ident, &pkg_val.pkg->idents);
+ {
+ Value pkg_val;
+ if (!eval_expr(tr->evalr, lhs, &pkg_val))
+ return false;
+ lhs->kind = EXPR_VAL;
+ if (lhs_type->kind == TYPE_PTR) {
+ /* that's a pointer to a package! */
+
+ /* soon it will be a package... */
+ lhs->type.kind = TYPE_BUILTIN;
+ lhs->type.builtin = BUILTIN_PKG;
+
+ eval_deref(&lhs->val, pkg_val.ptr, &lhs->type);
+ } else {
+ lhs->val = pkg_val;
+ }
+ }
+ Package *pkg = lhs->val.pkg;
+ e->binary.dot.pkg_ident = ident_translate(rhs->ident, &pkg->idents);
if (!e->binary.dot.pkg_ident) {
char *ident_name = ident_to_str(rhs->ident);
- err_print(e->where, "%s was not imported from package %s.", ident_name, pkg_val.pkg->name);
+ err_print(e->where, "%s was not imported from package %s.", ident_name, pkg->name);
free(ident_name);
return false;
}
@@ -1938,8 +1954,6 @@ static bool types_expr(Typer *tr, Expression *e) {
break;
}
- if (struct_type->kind == TYPE_PTR)
- struct_type = struct_type->ptr;
if (rhs->kind != EXPR_IDENT) {
err_print(rhs->where, "Expected identifier for struct member access, but got %s.",
expr_kind_to_str(rhs->kind));
@@ -2074,7 +2088,6 @@ static bool types_block(Typer *tr, Block *b) {
bool success = true;
if (!typer_block_enter(tr, b))
return false;
- b->ret_expr = NULL;
arr_foreach(b->stmts, Statement, s) {
if (!types_stmt(tr, s))
success = false;
@@ -2243,6 +2256,7 @@ static bool types_stmt(Typer *tr, Statement *s) {
if (!types_expr(tr, &s->expr)) {
return false;
}
+
if (s->expr.type.kind == TYPE_TUPLE && !(s->flags & STMT_EXPR_NO_SEMICOLON)) {
err_print(s->where, "Statement of a tuple is not allowed. Use a semicolon instead of a comma here.");
return false;