diff options
-rw-r--r-- | cgen.c | 4 | ||||
-rw-r--r-- | identifiers.c | 16 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | parse.c | 12 | ||||
-rw-r--r-- | test.toc | 8 | ||||
-rw-r--r-- | types.c | 27 | ||||
-rw-r--r-- | types.h | 3 |
7 files changed, 54 insertions, 18 deletions
@@ -242,11 +242,11 @@ static void cgen_ident(CGenerator *g, Identifier i) { cgen_write(g, "%s", g->nms_prefix); } else { /* do prefix for references to siblings */ - if (g->nms && i->scope == &g->nms->body) { + if (g->nms && ident_scope(i) == &g->nms->body) { cgen_write(g, "%s", g->nms_prefix); } } - if (i == g->main_ident && i->decl_kind == IDECL_DECL && i->scope == NULL) { + if (i == g->main_ident && i->decl_kind == IDECL_DECL && ident_scope(i) == NULL) { /* don't conflict with C's main! */ cgen_write(g, "main__"); } else { diff --git a/identifiers.c b/identifiers.c index 1ad239a..60ab30e 100644 --- a/identifiers.c +++ b/identifiers.c @@ -27,9 +27,10 @@ static int is_ident(int c) { } /* Initialize Identifiers. */ -static void idents_create(Identifiers *ids, Allocator *allocr) { +static void idents_create(Identifiers *ids, Allocator *allocr, Block *scope) { str_hash_table_create(&ids->table, sizeof(IdentSlot) - sizeof(StrHashTableSlot), allocr); ids->rseed = 0x27182818; + ids->scope = scope; } /* advances s until a non-identifier character is reached, then returns the number of characters advanced */ @@ -85,6 +86,7 @@ static Identifier ident_insert(Identifiers *ids, char **s) { char *original = *s; size_t len = ident_str_len_advance(s); IdentSlot *slot = (IdentSlot *)str_hash_table_insert_(&ids->table, original, len); + slot->idents = ids; return slot; } @@ -148,21 +150,25 @@ static Identifier ident_get(Identifiers *ids, char *s) { } /* translate and insert if not already there */ -static Identifier ident_translate_forced(Identifier i, Identifiers *to_idents) { +static inline Identifier ident_translate_forced(Identifier i, Identifiers *to_idents) { char *p = i->str; return ident_insert(to_idents, &p); } /* translate but don't add it if it's not there */ -static Identifier ident_translate(Identifier i, Identifiers *to_idents) { +static inline Identifier ident_translate(Identifier i, Identifiers *to_idents) { return ident_get(to_idents, i->str); } /* returns true if i and j are equal, even if they're not in the same table */ -static bool ident_eq(Identifier i, Identifier j) { +static inline bool ident_eq(Identifier i, Identifier j) { return i->len == j->len && memcmp(i->str, j->str, i->len) == 0; } +static inline Block *ident_scope(Identifier i) { + return i->idents->scope; +} + #ifdef TOC_DEBUG static void idents_test(void) { Identifiers ids; @@ -170,7 +176,7 @@ static void idents_test(void) { char *s = b; Allocator a; allocr_create(&a); - idents_create(&ids, &a); + idents_create(&ids, &a, NULL); Identifier i1 = ident_insert(&ids, &s); assert(strs_equal(s, " bar")); char b2[] = "foo_variable+6"; @@ -81,7 +81,7 @@ int main(int argc, char **argv) { if (!contents) return EXIT_FAILURE; Identifiers globals; - idents_create(&globals, &main_allocr); + idents_create(&globals, &main_allocr, NULL); Tokenizer t; file.contents = contents; tokr_create(&t, &err_ctx, &main_allocr); @@ -784,7 +784,7 @@ static bool parse_block(Parser *p, Block *b) { Block *prev_block = p->block; b->flags = 0; b->ret_expr = NULL; - idents_create(&b->idents, p->allocr); + idents_create(&b->idents, p->allocr, p->block); if (!token_is_kw(t->token, KW_LBRACE)) { tokr_err(t, "Expected '{' to open block."); return false; @@ -957,7 +957,8 @@ static int op_precedence(Keyword op) { static Identifier parser_ident_insert(Parser *p, char *str) { Identifiers *idents = p->block ? &p->block->idents : p->globals; - return ident_insert(idents, &str); + Identifier i = ident_insert(idents, &str); + return i; } static bool parse_expr(Parser *p, Expression *e, Token *end) { @@ -1065,7 +1066,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { } case KW_NMS: { Namespace *n = &e->nms; - idents_create(&n->idents, p->allocr); + idents_create(&n->idents, p->allocr, p->block); e->kind = EXPR_NMS; ++t->token; @@ -1836,6 +1837,11 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla goto ret_false; } *ident = parser_ident_insert(p, t->token->ident); + { + Identifier i = *ident; + i->decl_kind = IDECL_DECL; + i->decl = d; + } ++t->token; if (token_is_kw(t->token, KW_COMMA)) { ++t->token; @@ -1,3 +1,4 @@ +/* io ::= nms { #include "std/io.toc"; }; @@ -17,3 +18,10 @@ main ::= fn() { io.puti(b); io.puti(c); }; +*/ + +x := 5; +main ::= fn() { + + x; +};
\ No newline at end of file @@ -365,14 +365,24 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { return success; } -static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { +/* may modify ident */ +static bool type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t) { t->flags = 0; + Identifier i = *ident; + assert(i->idents->scope == tr->block); + if (i->decl_kind == IDECL_NONE) { + long nblocks = (long)arr_len(tr->blocks); + for (long idx = nblocks - 1; idx >= 0; --idx) { + int x; + } + } + switch (i->decl_kind) { case IDECL_DECL: { Declaration *d = i->decl; bool captured = false; - if (i->scope != NULL && !(i->scope->flags & BLOCK_IS_NMS)) { - Block *decl_scope = i->scope; + if (ident_scope(i) != NULL && !(ident_scope(i)->flags & BLOCK_IS_NMS)) { + Block *decl_scope = ident_scope(i); if (!(decl_scope->flags & BLOCK_IS_NMS)) { /* go back through scopes */ for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) { @@ -433,7 +443,7 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { } else { /* let's type the declaration, and redo this (for evaling future functions) */ if (!types_decl(tr, d)) return false; - return type_of_ident(tr, where, i, t); + return type_of_ident(tr, where, ident, t); } return false; } @@ -1230,7 +1240,7 @@ static bool types_expr(Typer *tr, Expression *e) { } } break; case EXPR_IDENT: { - if (!type_of_ident(tr, e->where, e->ident, t)) return false; + if (!type_of_ident(tr, e->where, &e->ident, t)) return false; } break; case EXPR_CAST: { CastExpr *c = &e->cast; @@ -2087,9 +2097,11 @@ static bool types_expr(Typer *tr, Expression *e) { err_print(rhs->where, "%s is not a member of this namespace.", s); return false; } - if (!type_of_ident(tr, rhs->where, translated, t)) { + if (!type_of_ident(tr, rhs->where, &translated, t)) { return false; } + e->kind = EXPR_IDENT; + e->ident = translated; } else { char *s = type_to_str(lhs_type); err_print(e->where, "Operator . applied to type %s, which is not a structure or pointer to structure.", s); @@ -2159,8 +2171,10 @@ static bool types_expr(Typer *tr, Expression *e) { } static bool types_block(Typer *tr, Block *b) { + *(Block **)arr_add(&tr->blocks) = b; if (b->flags & BLOCK_FOUND_TYPES) return true; + bool success = true; arr_foreach(b->stmts, Statement, s) { if (!types_stmt(tr, s)) { @@ -2193,6 +2207,7 @@ static bool types_block(Typer *tr, Block *b) { } ret: + arr_remove_last(&tr->blocks); b->flags |= BLOCK_FOUND_TYPES; return success; } @@ -187,7 +187,7 @@ typedef struct IdentSlot { struct Declaration *decl; struct Expression *expr; /* for example, this identifier is declared in a for expression */ }; - struct Block *scope; /* NULL for file scope */ + struct Identifiers *idents; Value val; SOURCE_LOCATION U16 flags; @@ -215,6 +215,7 @@ typedef IdentSlot *IdentSlotPtr; typedef struct Identifiers { StrHashTable table; U32 rseed; + struct Block *scope; /* NULL for file scope */ } Identifiers; typedef enum { |