diff options
-rw-r--r-- | cgen.c | 7 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | parse.c | 94 | ||||
-rw-r--r-- | test.toc | 29 | ||||
-rw-r--r-- | types.c | 5 |
5 files changed, 80 insertions, 58 deletions
@@ -214,6 +214,9 @@ static inline void cgen_write(CGenerator *g, const char *fmt, ...) { va_start(args, fmt); vfprintf(cgen_writing_to(g), fmt, args); va_end(args); +#ifdef TOC_DEBUG + fflush(cgen_writing_to(g)); +#endif } static inline void cgen_nl(CGenerator *g) { @@ -2120,8 +2123,9 @@ static bool cgen_defs_stmt(CGenerator *g, Statement *s) { static bool cgen_defs_block(CGenerator *g, Block *b) { /* NOTE: since we exit as soon as there's an error for cgen, we don't need to make sure we - set g->block to the previous block + set g->block to the previous block if there's an error */ + Block *prev_block = g->block; g->block = b; arr_foreach(b->stmts, Statement, s) { if (!cgen_defs_stmt(g, s)) { @@ -2131,6 +2135,7 @@ static bool cgen_defs_block(CGenerator *g, Block *b) { if (b->ret_expr && !cgen_defs_expr(g, b->ret_expr)) { return false; } + g->block = prev_block; return true; } @@ -18,12 +18,15 @@ /* TODO: +the problem right now is that we're copying blocks but not updating our references to the copy + make eval_ptr_to_struct_field return a bool (just in case it successfully returns a NULL pointer) nms["foo"] make sure #export still works properly fix cgen_ident_to_str for unicode idents check for leaks --- +allow for circular dependencies in functions returning types---this will be complicated nice syntax for #including something into a namespace run stuff at compile time without assigning it to a constant #compile_only declarations @@ -779,12 +779,16 @@ static bool parser_is_definitely_type(Parser *p, Token **end) { return ret; } -static bool parse_block(Parser *p, Block *b) { +enum { + PARSE_BLOCK_DONT_CREATE_IDENTS = 0x01 +}; +static bool parse_block(Parser *p, Block *b, U8 flags) { Tokenizer *t = p->tokr; Block *prev_block = p->block; b->flags = 0; b->ret_expr = NULL; - idents_create(&b->idents, p->allocr, p->block); + if (!(flags & PARSE_BLOCK_DONT_CREATE_IDENTS)) + 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; @@ -865,7 +869,11 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) { } ++t->token; f->params = NULL; - bool ret = true; + bool success = true; + Block *prev_block = p->block; + /* enter block so that parameters' scope will be the function body */ + p->block = &f->body; + idents_create(&f->body.idents, p->allocr, &f->body); if (token_is_kw(t->token, KW_RPAREN)) { ++t->token; } else { @@ -874,14 +882,15 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) { arr_foreach(f->params, Declaration, param) { if (param->flags & DECL_FOREIGN) { err_print(param->where, "Parameters cannot be foreign."); - return false; + success = false; + goto ret; } } } if (t->token->kind == TOKEN_EOF) { tokr_err(t, "End of file encountered while parsing parameter list."); - return false; + success = false; goto ret; } if (token_is_kw(t->token, KW_LBRACE)) { @@ -894,15 +903,15 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) { arr_foreach(f->ret_decls, Declaration, d) { if ((d->flags & DECL_IS_CONST) || (d->flags & DECL_SEMI_CONST)) { err_print(d->where, "Named return values cannot be constant."); - return false; + success = false; goto ret; } if (d->flags & DECL_INFER) { err_print(d->where, "Can't infer the value of a named return value!"); - return false; + success = false; goto ret; } if (d->flags & DECL_FOREIGN) { err_print(d->where, "Named return values can't be foreign."); - return false; + success = false; goto ret; } } --t->token; /* move back to { */ @@ -911,13 +920,16 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) { f->ret_type.flags = 0; } else { if (!parse_type(p, &f->ret_type)) { - ret = false; + success = false; + goto ret; } } - if (!parse_block(p, &f->body)) - ret = false; + if (!parse_block(p, &f->body, PARSE_BLOCK_DONT_CREATE_IDENTS)) + success = false; + ret: f->body.flags |= BLOCK_IS_FN; - return ret; + p->block = prev_block; + return success; } static void fprint_expr(FILE *out, Expression *e); @@ -1070,7 +1082,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { e->kind = EXPR_NMS; ++t->token; - if (!parse_block(p, &n->body)) + if (!parse_block(p, &n->body, 0)) return false; goto success; } @@ -1087,7 +1099,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { } i->cond = parser_new_expr(p); if (!parse_expr(p, i->cond, cond_end)) return false; - if (!parse_block(p, &i->body)) return false; + if (!parse_block(p, &i->body, 0)) return false; IfExpr *curr = i; while (1) { bool is_else = token_is_kw(t->token, KW_ELSE); @@ -1110,7 +1122,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { if (is_else) { ++t->token; nexti->cond = NULL; - if (!parse_block(p, &nexti->body)) return false; + if (!parse_block(p, &nexti->body, 0)) return false; } else { /* elif */ ++t->token; @@ -1125,7 +1137,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { if (!parse_expr(p, cond, cond_end)) return false; nexti->cond = cond; - if (!parse_block(p, &nexti->body)) return false; + if (!parse_block(p, &nexti->body, 0)) return false; } next->where.end = t->token; curr = nexti; @@ -1153,7 +1165,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { if (!parse_expr(p, cond, cond_end)) return false; } - if (!parse_block(p, &w->body)) return false; + if (!parse_block(p, &w->body, 0)) return false; goto success; } case KW_FOR: { @@ -1162,6 +1174,9 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { fo->flags = 0; fo->value = NULL; fo->index = NULL; + Block *prev_block = p->block; + p->block = &fo->body; + idents_create(&p->block->idents, p->allocr, p->block); ++t->token; if (token_is_kw(t->token, KW_COLON) || (t->token->kind == TOKEN_IDENT @@ -1171,6 +1186,8 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { && token_is_kw(t->token + 3, KW_COLON))))) { if (t->token->kind == TOKEN_IDENT) { fo->value = parser_ident_insert(p, t->token->ident); + fo->value->decl_kind = IDECL_EXPR; + fo->value->expr = e; if (ident_eq_str(fo->value, "_")) /* ignore value */ fo->value = NULL; ++t->token; @@ -1178,39 +1195,41 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { ++t->token; if (t->token->kind == TOKEN_IDENT) { fo->index = parser_ident_insert(p, t->token->ident); + fo->index->decl_kind = IDECL_EXPR; + fo->index->expr = e; if (ident_eq_str(fo->index, "_")) /* ignore index */ fo->index = NULL; ++t->token; } else { tokr_err(t, "Expected identifier after , in for loop."); - return false; + goto for_fail; } } } if (!token_is_kw(t->token, KW_COLON)) { tokr_err(t, "Expected : following identifiers in for loop."); - return false; + goto for_fail; } ++t->token; if (token_is_kw(t->token, KW_COLON)) { tokr_err(t, "The variable(s) in a for loop cannot be constant."); - return false; + goto for_fail; } if (!token_is_kw(t->token, KW_EQ)) { fo->flags |= FOR_ANNOTATED_TYPE; if (!parse_type(p, &fo->type)) - return false; + goto for_fail; if (!token_is_kw(t->token, KW_EQ)) { tokr_err(t, "Expected = in for statement."); - return false; + goto for_fail; } } ++t->token; } - Token *first_end = expr_find_end(p, EXPR_CAN_END_WITH_COMMA|EXPR_CAN_END_WITH_DOTDOT|EXPR_CAN_END_WITH_LBRACE); - Expression *first = parser_new_expr(p); + Token *first_end; first_end = expr_find_end(p, EXPR_CAN_END_WITH_COMMA|EXPR_CAN_END_WITH_DOTDOT|EXPR_CAN_END_WITH_LBRACE); + Expression *first; first = parser_new_expr(p); if (!parse_expr(p, first, first_end)) - return false; + goto for_fail; if (token_is_kw(first_end, KW_LBRACE)) { fo->of = first; } else if (token_is_kw(first_end, KW_DOTDOT) || token_is_kw(first_end, KW_COMMA)) { @@ -1222,10 +1241,10 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { fo->range.step = parser_new_expr(p); Token *step_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE|EXPR_CAN_END_WITH_DOTDOT); if (!parse_expr(p, fo->range.step, step_end)) - return false; + goto for_fail; if (!token_is_kw(step_end, KW_DOTDOT)) { err_print(token_location(p->file, step_end), "Expected .. to follow step in for statement."); - return false; + goto for_fail; } } else { fo->range.step = NULL; @@ -1237,20 +1256,24 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { fo->range.to = parser_new_expr(p); Token *to_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE); if (!parse_expr(p, fo->range.to, to_end)) - return false; + goto for_fail; if (!token_is_kw(t->token, KW_LBRACE)) { tokr_err(t, "Expected { to open body of for statement."); - return false; + goto for_fail; } } } else { err_print(token_location(p->file, first_end), "Expected { or .. to follow expression in for statement."); - return false; + goto for_fail; } - if (!parse_block(p, &fo->body)) - return false; + 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; + return false; } default: break; } @@ -1770,7 +1793,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { if (token_is_kw(t->token, KW_LBRACE)) { /* it's a block */ e->kind = EXPR_BLOCK; - if (!parse_block(p, &e->block)) return false; + if (!parse_block(p, &e->block, 0)) return false; if (t->token != end) { tokr_err(t, "Expression continues after end of block."); /* TODO: improve this err message */ return false; @@ -2167,6 +2190,11 @@ static void fprint_block(FILE *out, Block *b) { } +static void print_block(Block *b) { + fprint_block(stdout, b); + printf("\n"); +} + static void fprint_fn_expr(FILE *out, FnExpr *f) { fprintf(out, "fn ("); arr_foreach(f->params, Declaration, decl) { @@ -1,27 +1,10 @@ -/* -io ::= nms { - #include "std/io.toc"; +// it would be nice if Arr.data.len == Arr.len (: but this will require some C code... +Arr ::= fn (t :: Type) Type { + struct { + data : t; + } }; -n ::= nms { - x := 1; - counter ::= fn() int { x += 1; x }; -}; - - main ::= fn() { - a := n.counter(); - b := n.counter(); - n.counter(); - c := n.counter(); - io.puti(a); - io.puti(b); - io.puti(c); + arr : Arr(int); }; -*/ - -x := 5; -main ::= fn() { - - x; -};
\ No newline at end of file @@ -374,7 +374,8 @@ static bool type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t) long nblocks = (long)arr_len(tr->blocks); long idx; for (idx = nblocks - 1; idx >= 0; --idx) { - Identifier translated = ident_translate(i, &tr->blocks[idx]->idents); + Block *b = tr->blocks[idx]; + Identifier translated = ident_translate(i, b ? &b->idents : tr->globals); if (!translated) continue; if (translated->decl_kind != IDECL_NONE) { i = *ident = translated; @@ -2184,6 +2185,7 @@ static bool types_expr(Typer *tr, Expression *e) { static bool types_block(Typer *tr, Block *b) { *(Block **)arr_add(&tr->blocks) = b; + tr->block = b; if (b->flags & BLOCK_FOUND_TYPES) return true; @@ -2219,6 +2221,7 @@ static bool types_block(Typer *tr, Block *b) { } ret: + tr->block = *(Block **)arr_last(tr->blocks); arr_remove_last(&tr->blocks); b->flags |= BLOCK_FOUND_TYPES; return success; |