summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c2
-rw-r--r--copy.c4
-rw-r--r--decls_cgen.c4
-rw-r--r--main.c3
-rw-r--r--parse.c5
-rw-r--r--test.toc11
-rw-r--r--types.c43
-rw-r--r--types.h10
8 files changed, 61 insertions, 21 deletions
diff --git a/cgen.c b/cgen.c
index f84474a..8fb7468 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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;
}
}
diff --git a/copy.c b/copy.c
index 3e2e720..ed05534 100644
--- a/copy.c
+++ b/copy.c
@@ -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;
}
}
diff --git a/main.c b/main.c
index 1d49ea6..e636f16 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/parse.c b/parse.c
index 1cf18bf..4c81213 100644
--- a/parse.c
+++ b/parse.c
@@ -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;
}
}
diff --git a/test.toc b/test.toc
index f0004fa..e7bd007 100644
--- a/test.toc
+++ b/test.toc
@@ -1,4 +1,11 @@
#include "std/io.toc";
-puti ::= fn() {
-}
+x ::= 3;
+
+
+main ::= fn() {
+ p ::= nms {
+ y := 5;
+ }
+ puti(p.x);
+}
diff --git a/types.c b/types.c
index 93e0c24..e16fd22 100644
--- a/types.c
+++ b/types.c
@@ -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;
}
diff --git a/types.h b/types.h
index db1534f..f216197 100644
--- a/types.h
+++ b/types.h
@@ -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;