summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-04-05 15:54:27 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-04-05 15:54:27 -0400
commitb6cf5163c8a3a8acec2eb0cc56d00394b652691e (patch)
treef09b48bf93adb8531325753f4c0ef99598caf5f3
parent03b8a56d4611fb3f3a5472519ab12809b373d2d4 (diff)
use working for ordinary decls but not for parameters yet
-rw-r--r--main.c4
-rw-r--r--parse.c46
-rw-r--r--test.toc11
-rw-r--r--types.c20
-rw-r--r--types.h3
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;