diff options
-rw-r--r-- | cgen.c | 2 | ||||
-rw-r--r-- | copy.c | 4 | ||||
-rw-r--r-- | decls_cgen.c | 4 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | parse.c | 5 | ||||
-rw-r--r-- | test.toc | 11 | ||||
-rw-r--r-- | types.c | 43 | ||||
-rw-r--r-- | types.h | 10 |
8 files changed, 61 insertions, 21 deletions
@@ -2168,7 +2168,7 @@ static void cgen_defs_stmt(CGenerator *g, Statement *s) { cgen_defs_stmt(g, s->defer); break; case STMT_USE: - cgen_defs_expr(g, s->use); + cgen_defs_expr(g, &s->use->expr); break; } } @@ -441,7 +441,9 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) { case STMT_CONT: break; case STMT_USE: - out->use = copy_expr_(c, in->use); + out->use = copier_malloc(c, sizeof *in->use); + *out->use = *in->use; + copy_expr(c, &out->use->expr, &in->use->expr); break; } } diff --git a/decls_cgen.c b/decls_cgen.c index 08d0727..5b4467b 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -164,7 +164,7 @@ static void cgen_sdecls_stmt(CGenerator *g, Statement *s) { cgen_sdecls_stmt(g, s->defer); break; case STMT_USE: - cgen_sdecls_expr(g, s->use); + cgen_sdecls_expr(g, &s->use->expr); break; } } @@ -399,7 +399,7 @@ static void cgen_decls_stmt(CGenerator *g, Statement *s) { cgen_decls_stmt(g, s->defer); break; case STMT_USE: - cgen_sdecls_expr(g, s->use); + cgen_sdecls_expr(g, &s->use->expr); break; } } @@ -8,11 +8,12 @@ /* TODO: -figure out why we're not getting redecl errors use - note: just keep an array of useds on the block - use with a decl, e.g. use p : Point; - make sure use works with functions and for, e.g. for use p := points + - exceptions (so that if you accidentally use something but have a function with the same + name you can still use the function) local structs should not be named in C for some reason forgetting a ; after #include causes a misleading unrecognized expression simplify eval macros with val_to_u/i64 @@ -2403,7 +2403,8 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { case KW_USE: { ++t->token; s->kind = STMT_USE; - if (!parse_expr(p, s->use = parser_malloc(p, sizeof *s->use), expr_find_end(p, 0))) + s->use = parser_malloc(p, sizeof *s->use); + if (!parse_expr(p, &s->use->expr, expr_find_end(p, 0))) return false; goto success; } @@ -2901,7 +2902,7 @@ static void fprint_stmt(FILE *out, Statement *s) { break; case STMT_USE: fprintf(out, "use "); - fprint_expr(out, s->use); + fprint_expr(out, &s->use->expr); break; } } @@ -1,4 +1,11 @@ #include "std/io.toc"; -puti ::= fn() { -} +x ::= 3; + + +main ::= fn() { + p ::= nms { + y := 5; + } + puti(p.x); +} @@ -534,6 +534,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { } } if (!generic) { + f->body.uses = NULL; if (!type_resolve(tr, &f->ret_type, f->where)) { success = false; goto ret; @@ -580,14 +581,11 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type * t->flags = 0; Identifier i = *ident; Block *b = tr->block; - bool undeclared = false; + bool undeclared = true; while (1) { /* for each block we are inside... */ /* OPTIM: only hash once */ Identifier translated = ident_translate(i, b ? &b->idents : tr->globals); - if (translated && translated->decl_kind == IDECL_NONE) - translated = NULL; - /* TODO: use */ - if (translated) { + if (ident_is_declared(translated)) { #if 0 printf("translated %s from\n", ident_to_str(i)); print_block_location(i->idents->body); @@ -595,12 +593,29 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type * print_block_location(translated->idents->body); #endif i = *ident = translated; - break; + undeclared = false; } + Use **uses = b ? b->uses : tr->uses; + + Use *previous_use_which_uses_i = NULL; + (void)previous_use_which_uses_i; + arr_foreach(uses, UsePtr, usep) { + Use *use = *usep; + Expression *e = &use->expr; + if (type_is_builtin(&e->type, BUILTIN_NMS)) { + + } else { + /* it's a struct */ + Type *struct_type = &e->type; + if (struct_type->kind == TYPE_PTR) + struct_type = struct_type->ptr; + assert(struct_type->kind == TYPE_STRUCT); + } + } + if (!undeclared) break; if (b) { b = b->parent; } else { - undeclared = true; break; } } @@ -1570,6 +1585,7 @@ static Status types_expr(Typer *tr, Expression *e) { ForExpr *fo = e->for_; bool in_header = true; *(ForExpr **)typer_arr_add(tr, &tr->in_fors) = fo; + fo->body.uses = NULL; typer_block_enter(tr, &fo->body); /* while this block is being typed, fo->body will be in tr->blocks twice. hopefully that doesn't mess anything up! */ if (fo->flags & FOR_IS_RANGE) { if (!types_expr(tr, fo->range.from)) goto for_fail; @@ -3132,6 +3148,10 @@ static Status types_block(Typer *tr, Block *b) { } b->flags |= BLOCK_FINDING_TYPES; + /* for and fn need to deal with their own useds, because you can use stuff in the header */ + if (b->kind != BLOCK_FOR && b->kind != BLOCK_FN) + b->uses = NULL; + typer_block_enter(tr, b); bool success = true; arr_foreach(b->stmts, Statement, s) { @@ -3499,7 +3519,8 @@ static Status types_stmt(Typer *tr, Statement *s) { } break; case STMT_USE: { - Expression *e = s->use; + Use *u = s->use; + Expression *e = &u->expr; if (!types_expr(tr, e)) return false; if (e->type.kind != TYPE_STRUCT && !type_is_builtin(&e->type, BUILTIN_NMS)) { @@ -3512,8 +3533,8 @@ static Status types_stmt(Typer *tr, Statement *s) { err_print(e->where, "You can't use this value. You should probably assign it to a variable."); return false; } - Statement **sp = arr_add(&tr->block->used); - *sp = s; + Use **up = arr_add(&tr->block->uses); + *up = u; } break; } s->flags |= STMT_TYPED; @@ -3539,11 +3560,13 @@ static void typer_create(Typer *tr, Evaluator *ev, File *file, ErrCtx *err_ctx, static Status types_file(Typer *tr, ParsedFile *f) { bool ret = true; tr->parsed_file = f; + tr->uses = NULL; arr_foreach(f->stmts, Statement, s) { if (!types_stmt(tr, s)) { ret = false; } } assert(tr->block == NULL); + assert(arr_len(tr->blocks) && tr->blocks[0] == NULL); return ret; } @@ -512,7 +512,7 @@ typedef struct Block { struct Expression *ret_expr; /* the return expression of this block, e.g. {foo(); 3} => 3 NULL for no expression. */ struct Block *parent; struct Statement **deferred; /* deferred stuff from this block; used by both eval and cgen */ - struct Statement **used; /* use statements (for types.c) */ + struct Use **uses; /* use statements (for types.c) */ } Block; enum { @@ -979,6 +979,11 @@ typedef struct { Expression text; } Message; +typedef struct Use { + Expression expr; +} Use; +typedef Use *UsePtr; + enum { STMT_EXPR_NO_SEMICOLON = 0x01, STMT_INC_TO_NMS = 0x01, @@ -996,7 +1001,7 @@ typedef struct Statement { Message *message; /* #error, #warn, #info */ Block *referring_to; /* for break/continue; set during typing */ struct Statement *defer; - Expression *use; + Use *use; }; } Statement; @@ -1049,6 +1054,7 @@ typedef struct Typer { Allocator *allocr; Evaluator *evalr; Identifiers *globals; + Use **uses; /* global used things */ ForExpr **in_fors; /* array of for loop headers we are currently inside */ Declaration **in_decls; /* array of declarations we are currently inside */ Block *block; |