summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c2
-rw-r--r--parse.c20
-rw-r--r--test.toc11
-rw-r--r--types.c36
4 files changed, 42 insertions, 27 deletions
diff --git a/main.c b/main.c
index 05a16ce..77c4208 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,7 @@
/*
TODO:
+get rid of multiple types in one decl (no a, b := twofn();)
+casting
re-do cgen
*/
#include "toc.c"
diff --git a/parse.c b/parse.c
index f38c8bf..d805869 100644
--- a/parse.c
+++ b/parse.c
@@ -1371,15 +1371,26 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndType ends_with, uint16_
return ret;
}
+static bool is_decl(Tokenizer *t) {
+ Token *token = t->token;
+ while (1) {
+ if (token->kind != TOKEN_IDENT) return false;
+ token++;
+ if (token->kind != TOKEN_KW) return false;
+ if (token->kw == KW_COLON || token->kw == KW_AT)
+ return true;
+ if (token->kw != KW_COMMA) return false;
+ token++;
+ }
+}
+
static bool parse_stmt(Parser *p, Statement *s) {
Tokenizer *t = p->tokr;
s->flags = 0;
if (t->token->kind == TOKEN_EOF)
tokr_err(t, "Expected statement.");
s->where = t->token->where;
- /*
- TODO: statements such as 3, 5; will not work.
- */
+
if (token_is_kw(t->token, KW_RETURN)) {
s->kind = STMT_RET;
t->token++;
@@ -1404,8 +1415,7 @@ static bool parse_stmt(Parser *p, Statement *s) {
t->token = end + 1;
return success;
}
- if (token_is_kw(t->token + 1, KW_COLON) || token_is_kw(t->token + 1, KW_COMMA)
- || token_is_kw(t->token + 1, KW_AT)) {
+ if (is_decl(t)) {
s->kind = STMT_DECL;
if (!parse_decl(p, &s->decl, DECL_END_SEMICOLON, 0)) {
return false;
diff --git a/test.toc b/test.toc
index 2bdce87..7df50d5 100644
--- a/test.toc
+++ b/test.toc
@@ -1,11 +1,8 @@
main @= fn() {
- //foo @= fn(x: int) { return; };
// b := !(5 > 3 && 4 <= 3 && 3 >= 2 || 0 == 1 || 5 != 3);
- b := !(5 < 3);
- a := (5 == 3);
- C @= 3 != 4;
- //x @= !!!!!!!false;
-
-// foo := 5 < 3;
+ foo : [3]int;
+ // x, foo[0], foo[1] = 3, 5;
+ x :, y := 0;
+ x = 3.5;
};
diff --git a/types.c b/types.c
index 6acb752..5980290 100644
--- a/types.c
+++ b/types.c
@@ -146,7 +146,13 @@ static bool expr_must_lval(Expression *e) {
if (e->unary.op == UNARY_DEREF) return true;
break;
case EXPR_BINARY_OP:
- if (e->binary.op == BINARY_AT_INDEX) return true;
+ switch (e->binary.op) {
+ case BINARY_AT_INDEX: return true;
+ case BINARY_COMMA:
+ /* x, y is an lval, but 3, "hello" is not. */
+ return expr_must_lval(e->binary.lhs) && expr_must_lval(e->binary.rhs);
+ default: break;
+ }
break;
default:
break;
@@ -218,13 +224,13 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
if (d->flags & DECL_FLAG_FOUND_TYPE) {
if (d->idents.len > 1) {
/* it's a tuple! */
-
+ long index = 0;
arr_foreach(&d->idents, Identifier, decl_i) {
if (*decl_i == i) {
- long index = (long)(decl_i - (Identifier*)d->idents.data);
*t = ((Type*)d->type.tuple.data)[index];
return true;
}
+ index++;
}
assert(0);
return false;
@@ -238,10 +244,12 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
if (!type_of_fn(tr, d->expr.fn, t)) return false;
return true;
} else {
- char *s = ident_to_str(i);
- err_print(where, "Use of identifier %s before its declaration.\nNote that it is only possible to use a constant function before it is directly declared (e.g. x @= fn() {}).", s);
- info_print(d->where, "%s will be declared here.", s);
- free(s);
+ if (location_after(d->where, where)) {
+ char *s = ident_to_str(i);
+ err_print(where, "Use of identifier %s before its declaration.\nNote that it is only possible to use a constant function before it is directly declared (e.g. x @= fn() {}).", s);
+ info_print(d->where, "%s will be declared here.", s);
+ free(s);
+ } /* else, there should have been an error earlier */
return false;
}
}
@@ -599,6 +607,7 @@ static bool types_expr(Typer *tr, Expression *e) {
match = false;
}
}
+ if (!type_eq(lhs_type, rhs_type)) match = false;
if (match) {
switch (e->binary.op) {
case BINARY_SET:
@@ -623,14 +632,10 @@ static bool types_expr(Typer *tr, Expression *e) {
/* promote to float */
t->builtin = BUILTIN_F32;
}
- } else if (type_eq(lhs_type, rhs_type)) {
- if (!lhs_is_flexible)
- *t = *lhs_type;
- else
- *t = *rhs_type;
- } else {
- match = false;
- }
+ } else if (!lhs_is_flexible)
+ *t = *lhs_type;
+ else
+ *t = *rhs_type;
} break;
}
}
@@ -737,6 +742,7 @@ static bool types_decl(Typer *tr, Declaration *d) {
goto ret;
}
d->type = d->expr.type;
+ d->type.flags &= ~TYPE_FLAG_FLEXIBLE; /* x := 5; => x is not flexible */
}
if (d->flags & DECL_FLAG_CONST) {
if (!d->val) {