diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-17 21:07:15 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-17 21:07:15 -0500 |
commit | 09a23bab279ac54b365e50e84962fdc2125114b9 (patch) | |
tree | 9555d70171c111b3c151970bdd977d7c2713595d | |
parent | 3d3c0f04e26d3f07983601dc91714e3dca447206 (diff) |
Location bug fix and (&Package).something
-rw-r--r-- | allocator.c | 2 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | parse.c | 13 | ||||
-rw-r--r-- | test.toc | 8 | ||||
-rw-r--r-- | toc.c | 1 | ||||
-rw-r--r-- | tokenizer.c | 5 | ||||
-rw-r--r-- | types.c | 34 |
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)) @@ -18,7 +18,6 @@ /* TODO: -make sure (&Package).something works C functions (#foreign) #include variadic fns @@ -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 */ @@ -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 @@ -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; @@ -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; |