From b6cf5163c8a3a8acec2eb0cc56d00394b652691e Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sun, 5 Apr 2020 15:54:27 -0400 Subject: use working for ordinary decls but not for parameters yet --- main.c | 4 ++++ parse.c | 46 +++++++++++++++++++++++++++------------------- test.toc | 11 ++--------- types.c | 20 ++++++++++++++++++-- types.h | 3 ++- 5 files changed, 53 insertions(+), 31 deletions(-) diff --git a/main.c b/main.c index a644ae4..a78648b 100644 --- a/main.c +++ b/main.c @@ -8,8 +8,11 @@ /* TODO: +fix tcc warnings about dubious pointer conversions +just use MaxAlign and remove long double--now we're using less memory use - use with a decl, e.g. use p : Point; + - use with struct members - 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) @@ -27,6 +30,7 @@ unions switch to / add as an alternative: libffi X ::= newtype(int); or something any odd number of "s for a string +optional -Wshadow --- make sure that floating point literals are exact as possible have some way of doing Infinity and s/qNaN (you can diff --git a/parse.c b/parse.c index 19b402b..f1bddc7 100644 --- a/parse.c +++ b/parse.c @@ -2154,6 +2154,11 @@ static Status parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 f ++t->token; } + if (token_is_kw(t->token, KW_USE)) { + d->flags |= DECL_USE; + ++t->token; + } + while (1) { Identifier *ident = parser_arr_add(p, &d->idents); if (t->token->kind != TOKEN_IDENT) { @@ -2314,6 +2319,10 @@ static bool is_decl(Tokenizer *t) { if (token_is_direct(token, DIRECT_EXPORT)) return true; + /* use decls, e.g. use p: Point */ + if (token_is_kw(token, KW_USE)) + ++token; + while (1) { if (token->kind != TOKEN_IDENT) return false; ++token; @@ -2335,12 +2344,17 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { s->where = parser_mk_loc(p); s->flags = 0; *was_a_statement = true; - if (t->token->kind == TOKEN_KW) { + if (is_decl(t)) { + s->kind = STMT_DECL; + if (!parse_decl(p, s->decl = parser_malloc(p, sizeof *s->decl), DECL_END_SEMICOLON, PARSE_DECL_ALLOW_EXPORT)) { + return false; + } + } else if (t->token->kind == TOKEN_KW) { switch (t->token->kw) { case KW_SEMICOLON: *was_a_statement = false; ++t->token; - goto success; + break; case KW_RETURN: { s->kind = STMT_RET; ++t->token; @@ -2349,7 +2363,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { if (token_is_kw(t->token, KW_SEMICOLON)) { /* return with no expr */ ++t->token; - goto success; + break; } r->flags |= RET_HAS_EXPR; Token *end = expr_find_end(p, 0); @@ -2365,7 +2379,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { bool parsed = parse_expr(p, &r->expr, end); t->token = end + 1; if (!parsed) return false; - goto success; + break; } case KW_BREAK: s->kind = STMT_BREAK; @@ -2375,7 +2389,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { tokr_skip_semicolon(t); return false; } - goto success; + break; case KW_CONTINUE: s->kind = STMT_CONT; ++t->token; @@ -2384,7 +2398,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { tokr_skip_semicolon(t); return false; } - goto success; + break; case KW_DEFER: { if (p->block == NULL) { tokr_err(t, "You can't defer something at global scope."); @@ -2400,7 +2414,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { err_print(token_location(p->file, deferred_start), "Empty defer"); return false; } - goto success; + break; } case KW_USE: { ++t->token; @@ -2408,9 +2422,9 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { s->use = parser_malloc(p, sizeof *s->use); if (!parse_expr(p, &s->use->expr, expr_find_end(p, 0))) return false; - goto success; + break; } - default: break; + default: goto stmt_expr; } } else if (t->token->kind == TOKEN_DIRECT) { switch (t->token->direct) { @@ -2482,7 +2496,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { return false; } ++t->token; - goto success; + break; } break; case DIRECT_ERROR: case DIRECT_WARN: @@ -2508,18 +2522,13 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { tokr_skip_semicolon(t); return false; } - goto success; + break; } default: - break; - } - } - if (is_decl(t)) { - s->kind = STMT_DECL; - if (!parse_decl(p, s->decl = parser_malloc(p, sizeof *s->decl), DECL_END_SEMICOLON, PARSE_DECL_ALLOW_EXPORT)) { - return false; + goto stmt_expr; } } else { + stmt_expr: s->kind = STMT_EXPR; Token *end = expr_find_end(p, 0); if (!end) { @@ -2539,7 +2548,6 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { if (!valid) return false; } - success: parser_put_end(p, &s->where); return true; } diff --git a/test.toc b/test.toc index bb0f972..d8f9f00 100644 --- a/test.toc +++ b/test.toc @@ -1,20 +1,15 @@ -#include "std/io.toc"; - Point ::= struct { x, y: float; } sqrt ::= fn(x: float) a := x/2 { - q ::= x; - y ::= a; for _ := 0..20 { a = (x + a * a) / (2 * a); } } -normalize ::= fn(p: &Point) { - use p; +normalize ::= fn(use p: &Point) { sqdist := x * x + y * y; one_over_dist := 1/sqrt(sqdist); x *= one_over_dist; @@ -24,12 +19,10 @@ normalize ::= fn(p: &Point) { printf ::= #foreign("printf", "libc.so.6") fn(#C &"const char", #C ..); main ::= fn() { - p: Point; - use p; + use p: Point; x = 10; y = 20; normalize(&p); fmt := "%f %f\n\0"; printf(&fmt[0], p.x, p.y); } - diff --git a/types.c b/types.c index 0dcd4d1..e86bf40 100644 --- a/types.c +++ b/types.c @@ -3371,7 +3371,22 @@ static Status types_decl(Typer *tr, Declaration *d) { goto ret; } } - + + if (d->flags & DECL_USE) { + int idx = 0; + arr_foreach(d->idents, Identifier, ip) { + Identifier i = *ip; + /* add to uses */ + Use **usep = arr_add(tr->block ? &tr->block->uses : &tr->uses); + Use *use = *usep = typer_calloc(tr, 1, sizeof *use); + Expression *used = &use->expr; + used->kind = EXPR_IDENT; + used->flags = EXPR_FOUND_TYPE; + used->type = *decl_type_at_index(d, idx++); + used->ident = i; + } + } + if (n_idents == 1 && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_NMS) { bool is_at_top_level = true; typedef Block *BlockPtr; @@ -3597,7 +3612,7 @@ 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; } - Use **up = arr_add(&tr->block->uses); + Use **up = arr_add(tr->block ? &tr->block->uses : &tr->uses); *up = u; } break; } @@ -3630,6 +3645,7 @@ static Status types_file(Typer *tr, ParsedFile *f) { ret = false; } } + arr_clear(&tr->uses); assert(tr->block == NULL); assert(arr_len(tr->blocks) && tr->blocks[0] == NULL); return ret; diff --git a/types.h b/types.h index e347cad..9affa5e 100644 --- a/types.h +++ b/types.h @@ -887,7 +887,8 @@ enum { DECL_FOUND_VAL = 0x0040, DECL_INFER = 0x0080, /* infer the value (e.g. fn(t::Type=, x:t)) */ DECL_EXPORT = 0x0100, - DECL_IS_PARAM = 0x0200 + DECL_IS_PARAM = 0x0200, + DECL_USE = 0x0400 /* e.g. use p: Point */ }; typedef U16 DeclFlags; -- cgit v1.2.3