diff options
-rw-r--r-- | cgen.c | 1 | ||||
-rw-r--r-- | copy.c | 2 | ||||
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | parse.c | 9 | ||||
-rw-r--r-- | std/arr.toc | 43 | ||||
-rw-r--r-- | test.toc | 31 | ||||
-rw-r--r-- | tests/misc.toc | 46 | ||||
-rw-r--r-- | types.c | 28 | ||||
-rw-r--r-- | types.h | 1 |
9 files changed, 107 insertions, 56 deletions
@@ -1219,6 +1219,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { Value fn_val = *decl_val_at_index(d, index); FnExpr *fn = fn_val.fn; Expression fn_expr; + /* TODO: is this all really necessary? */ fn_expr.kind = EXPR_FN; fn_expr.fn = allocr_malloc(g->allocr, sizeof *fn_expr.fn); @@ -420,9 +420,9 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) { static void copy_block(Copier *c, Block *out, Block *in, U8 flags) { assert(!(in->flags & BLOCK_FINDING_TYPES)); - Identifiers out_idents = out->idents; *out = *in; + out->parent = c->block; if (flags & COPY_BLOCK_DONT_CREATE_IDENTS) out->idents = out_idents; /* reset Identifiers */ size_t nstmts = arr_len(in->stmts); @@ -645,6 +645,8 @@ static Value *ident_val(Identifier i) { return valp; } else { /* struct parameter */ + printf("--%p\n",decl); + assert(decl->flags & DECL_FOUND_VAL); if (arr_len(decl->idents) > 1) return &decl->val.tuple[idx]; else @@ -612,6 +612,7 @@ static Status parse_type(Parser *p, Type *type, Location *where) { memset(&struc->scope, 0, sizeof struc->scope); idents_create(&struc->scope.idents, p->allocr, &struc->scope); memset(&struc->instances, 0, sizeof struc->instances); + struc->scope.parent = p->block; Block *prev_block = p->block; p->block = &struc->scope; @@ -852,6 +853,8 @@ static Status parse_block(Parser *p, Block *b, U8 flags) { Block *prev_block = p->block; b->flags = 0; b->ret_expr = NULL; + assert(p->block != b); + b->parent = p->block; p->block = b; if (!(flags & PARSE_BLOCK_DONT_CREATE_IDENTS)) idents_create(&b->idents, p->allocr, p->block); @@ -952,6 +955,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { bool success = true; Block *prev_block = p->block; /* enter block so that parameters' scope will be the function body */ + f->body.parent = p->block; p->block = &f->body; idents_create(&f->body.idents, p->allocr, &f->body); if (token_is_kw(t->token, KW_RPAREN)) { @@ -996,6 +1000,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { goto ret; } } + p->block = prev_block; /* be nice to parse_block */ if (!parse_block(p, &f->body, PARSE_BLOCK_DONT_CREATE_IDENTS)) success = false; ret: @@ -1426,6 +1431,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { fo->value = NULL; fo->index = NULL; Block *prev_block = p->block; + fo->body.parent = p->block; p->block = &fo->body; idents_create(&p->block->idents, p->allocr, p->block); ++t->token; @@ -1522,9 +1528,9 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { goto for_fail; } e->where.end = t->token; /* temporarily set end so that redeclaration errors aren't messed up */ + p->block = prev_block; if (!parse_block(p, &fo->body, PARSE_BLOCK_DONT_CREATE_IDENTS)) goto for_fail; - p->block = prev_block; goto success; for_fail: p->block = prev_block; @@ -2445,6 +2451,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { Block *body = &e->nms->body; body->flags |= BLOCK_IS_NMS; body->where = s->where; + body->parent = p->block; idents_create(&body->idents, p->allocr, body); Statement *inc_stmt = parser_arr_add(p, &body->stmts); inc_stmt->kind = STMT_INCLUDE; diff --git a/std/arr.toc b/std/arr.toc index 24fdf9f..779de48 100644 --- a/std/arr.toc +++ b/std/arr.toc @@ -1,20 +1,29 @@ -Arr ::= fn (t :: Type) Type { - struct { - data : []t; - cap : int; +// this could be made quite a bit faster with realloc + +Arr ::= struct (t :: Type) { + data : []t; + cap : int; +}; + +resv ::= fn(t ::=, a : &Arr(t), n: int) { + if a.cap >= n { + return; + } + new_data := new(t, a.cap); + new_data.len = a.data.len; + for x, i := &new_data { + *x = a.data[i]; } + a.data = new_data; + a.cap = n; }; -arr_add ::= fn(t ::=, a : &Arr(t), x : t) { - if a.data.len >= a.cap { - a.cap = a.cap * 2 + 2; - new_data := new(t, a.cap); - new_data.len = a.data.len; - for i := 0..a.data.len-1 { - new_data[i] = a.data[i]; - } - a.data = new_data; - } - a.data.len += 1; - a.data[a.data.len-1] = x; + +add ::= fn(t ::=, a : &Arr(t), x : t) { + if a.data.len >= a.cap { + resv(&a, a.cap * 2 + 2); + } + a.data.len += 1; + a.data[a.data.len-1] = x; }; -arr_len ::= fn(t ::=, a : Arr(t)) int { a.data.len }; + +len ::= fn(t ::=, a : Arr(t)) int { a.data.len }; @@ -1,17 +1,34 @@ -arr_sum ::= fn(n::=, t::=, a:[n]t) t { +/* +#include "std/io.toc", io; +#include "std/arr.toc", arr; + +arr_sum ::= fn(n::=, t::=, a:arr.Arr(t)) t { total := 0 as t; - for x := a { + for x := a.data { total += x; } total }; -mk_arr ::= fn(x:int, y:int, z:int) a:[3]int { - a[0] = x; - a[1] = y; - a[2] = z; +mk_arr ::= fn(x:int, y:int, z:int) a:arr.Arr(int) { + arr.add(&a, x); + arr.add(&a, y); + arr.add(&a, z); +}; + +main ::= fn() { + a := mk_arr(1,2,3); + io.puti(arr.len(a)); + io.puti(arr_sum(a)); +}; +*/ + +foo ::= fn(x::int) Type { + struct { + a: [x]int; + } }; main ::= fn() { - arr_sum(mk_arr(1,2,3)); + f: foo(5); };
\ No newline at end of file diff --git a/tests/misc.toc b/tests/misc.toc index d66972f..a9f6dc1 100644 --- a/tests/misc.toc +++ b/tests/misc.toc @@ -1,27 +1,29 @@ #include "io.toc", io; -arr_sum ::= fn(n::=, t::=, a:[n]t) t { - total := 0 as t; - for x := a { - total += x; +main ::= fn() { + x ::= 3; + #if x > 2 { + io.puts("Hello!"); + } else { + foo("yes"); } - total -}; -mk_arr ::= fn(x:int, y:int, z:int) a:[3]int { - a[0] = x; - a[1] = y; - a[2] = z; -}; + io.puti(arr_sum(mk_arr(5,89,22))); + io.puti(arr_sum(mk_arr(1,2,3))); + io.puti(arr_sum(mk_arr(z=0, 0, 0))); + + arr_sum ::= fn(n::=, t::=, a:[n]t) t { + total := 0 as t; + for x := a { + total += x; + } + total + }; -main ::= fn() { - x ::= 3; - #if x > 2 { - io.puts("Hello!"); - } else { - foo("yes"); - } - io.puti(arr_sum(mk_arr(5,89,22))); - io.puti(arr_sum(mk_arr(1,2,3))); - io.puti(arr_sum(mk_arr(z=0, 0, 0))); -};
\ No newline at end of file + mk_arr ::= fn(x:int, y:int, z:int) a:[3]int { + a[0] = x; + a[1] = y; + a[2] = z; + }; + +}; @@ -567,14 +567,12 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type * #endif #endif if (i->decl_kind == IDECL_NONE) { - long nblocks = (long)arr_len(tr->blocks); - long idx; - for (idx = nblocks - 1; idx >= 0; --idx) { - Block *b = tr->blocks[idx]; + Block *b = tr->block; + bool undeclared = false; + while (1) { /* OPTIM: only hash once */ - Identifier translated = ident_translate(i, b ? &b->idents : tr->globals); - if (!translated) continue; - if (translated->decl_kind != IDECL_NONE) { + Identifier translated = ident_translate(i, b ? &b->idents : tr->globals); + if (translated && translated->decl_kind != IDECL_NONE) { /* printf("translated %s from\n", ident_to_str(i)); */ /* print_block_location(i->idents->scope); */ /* printf(" to \n"); */ @@ -583,8 +581,14 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type * i = *ident = translated; break; } + if (b) { + b = b->parent; + } else { + undeclared = true; + break; + } } - if (idx == -1) { + if (undeclared) { char *s = ident_to_str(i); err_print(where, "Undeclared identifier: %s", s); free(s); @@ -1649,6 +1653,7 @@ static Status types_expr(Typer *tr, Expression *e) { e->kind = EXPR_BLOCK; e->block = typer_calloc(tr, 1, sizeof *e->block); e->block->where = e->where; + e->block->parent = tr->block; idents_create(&e->block->idents, tr->allocr, e->block); } goto expr_block; @@ -1858,7 +1863,10 @@ static Status types_expr(Typer *tr, Expression *e) { struct_t.kind = TYPE_STRUCT; struct_t.struc = &inst->struc; *(Location *)arr_add(&err_ctx->instance_stack) = e->where; + Block *prev_block = tr->block; + tr->block = &inst->struc.scope; bool success = type_resolve(tr, &struct_t, e->where); /* resolve the struct */ + tr->block = prev_block; arr_remove_last(&err_ctx->instance_stack); if (!success) return false; @@ -2062,6 +2070,7 @@ static Status types_expr(Typer *tr, Expression *e) { arg_exprs[i].flags = EXPR_FOUND_TYPE; arg_exprs[i].val = val_copy; param_decl->flags |= DECL_FOUND_VAL; + printf("%p\n",param_decl); copy_val(tr->allocr, ¶m_decl->val, &val_copy, type); if (!(param_decl->flags & DECL_ANNOTATES_TYPE)) { param_decl->type = *type; @@ -2156,7 +2165,10 @@ static Status types_expr(Typer *tr, Expression *e) { /* if anything happens, make sure we let the user know that this happened while generating a fn */ ErrCtx *err_ctx = e->where.file->ctx; *(Location *)typer_arr_add(tr, &err_ctx->instance_stack) = e->where; + Block *prev_block = tr->block; + tr->block = fn_copy->body.parent; bool success = types_fn(tr, c->instance->fn, &f->type, c->instance); + tr->block = prev_block; arr_remove_lasta(&err_ctx->instance_stack, tr->allocr); if (!success) return false; arr_cleara(&table_index_type.tuple, tr->allocr); @@ -490,6 +490,7 @@ typedef struct Block { Identifiers idents; struct Statement *stmts; struct Expression *ret_expr; /* the return expression of this block, e.g. {foo(); 3} => 3 NULL for no expression. */ + struct Block *parent; } Block; enum { |