summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-04-19 00:15:38 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-04-19 00:15:38 -0400
commit89ae387576966f9faa89efa6f859dc8b25e3ba76 (patch)
treea9084778984e7df8b8a052e339b77fc9b7313ff4
parent5f283d3a468f821e431c2d7dbdff17cea2b69f3f (diff)
new for system: typing
-rw-r--r--main.c8
-rw-r--r--parse.c22
-rw-r--r--test.toc4
-rw-r--r--types.c34
4 files changed, 39 insertions, 29 deletions
diff --git a/main.c b/main.c
index 7f64537..401c115 100644
--- a/main.c
+++ b/main.c
@@ -10,15 +10,17 @@
TODO:
replace weird EXPR_FOR system with just a declaration- would make "for use p := points" easier.
need to fix:
- - types.c
- cgen.c
- eval.c
- copy.c
-do we need the possibility that IdentSlot.decl is NULL?
EXPR_IDENT should be a string before typing, also struct member accesses
-make sure we set Expression.where in stuff like the EXPR_FOR for varargs (i.e. places where we construct expressions)
+do we need the possibility that IdentSlot.decl is NULL?
use
- use with struct members (e.g. SuperPoint ::= struct { use p: Point; })
+maybe change to #define check(x) do { if_unlikely(x) return 0; } while (0);
+is there a problem where we can get TYPE_UNKNOWN in cgen, triggering an assert(0)?
+ -simple example, but maybe try other stuff: x := #C("5");
+ -also make sure you can't do x:#C("5");
local structs should not be named in C
simplify eval macros with val_to_u/i64
&&, ||
diff --git a/parse.c b/parse.c
index 98ba59a..6445fc2 100644
--- a/parse.c
+++ b/parse.c
@@ -1388,15 +1388,25 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
Block *prev_block = p->block;
fo->body.parent = p->block;
p->block = &fo->body;
+ Declaration *header_decl = &fo->header;
idents_create(&p->block->idents, p->allocr, p->block);
++t->token;
- if (!parse_decl(p, &fo->header, PARSE_DECL_IGNORE_EXPR | DECL_CAN_END_WITH_LBRACE))
- goto for_fail;
- if (arr_len(fo->header.idents) > 2) {
- parser_put_end(p, &fo->header.where);
- err_print(fo->header.where, "Expected at most 2 identifiers in for declaration (index and value) but got %lu.",
- (unsigned long)arr_len(fo->header.idents));
+ if (!parse_decl(p, header_decl, PARSE_DECL_IGNORE_EXPR | DECL_CAN_END_WITH_LBRACE))
goto for_fail;
+
+ {
+ size_t nidents = arr_len(header_decl->idents);
+ if (nidents > 2) {
+ parser_put_end(p, &header_decl->where);
+ err_print(header_decl->where, "Expected at most 2 identifiers in for declaration (index and value) but got %lu.",
+ (unsigned long)nidents);
+ goto for_fail;
+ }
+ if (nidents < 2) {
+ assert(nidents == 1);
+ /* turn value := arr to value, _ := arr to simplify things */
+ *(Identifier *)arr_add(&header_decl->idents) = parser_ident_insert(p, "_");
+ }
}
if (!token_is_kw(t->token, KW_EQ)) {
tokr_err(t, "Expected = to follow for declaration.");
diff --git a/test.toc b/test.toc
index 2eacef8..f9e5a50 100644
--- a/test.toc
+++ b/test.toc
@@ -1,5 +1,5 @@
main ::= fn() {
- for i := 1..10 {
-
+ a : [5]int;
+ for x := a {
}
}
diff --git a/types.c b/types.c
index 5f6f0ba..ffdd5d0 100644
--- a/types.c
+++ b/types.c
@@ -1522,7 +1522,6 @@ static Status types_expr(Typer *tr, Expression *e) {
ForExpr *fo = e->for_;
Declaration *header = &fo->header;
*(Declaration **)typer_arr_add(tr, &tr->in_decls) = header;
- bool in_header = true;
if (header->flags & DECL_ANNOTATES_TYPE) {
fo->type = &header->type;
@@ -1644,8 +1643,14 @@ static Status types_expr(Typer *tr, Expression *e) {
arr_set_lena(&b->stmts, nvarargs, tr->allocr);
Statement *stmt = b->stmts;
size_t nstmts = arr_len(fo->body.stmts);
- bool has_val = fo->value != NULL;
- bool has_index = fo->index != NULL;
+ Declaration *header_decl = &fo->header;
+
+ assert(arr_len(header_decl->idents) == 2);
+ Identifier val_ident = header_decl->idents[0];
+ Identifier index_ident = header_decl->idents[1];
+ bool has_val = !ident_eq_str(val_ident, "_");
+ bool has_index = !ident_eq_str(index_ident, "_");
+
for (size_t i = 0; i < nvarargs; ++i, ++stmt) {
/* create sub-block #i */
memset(stmt, 0, sizeof *stmt);
@@ -1670,9 +1675,8 @@ static Status types_expr(Typer *tr, Expression *e) {
/* declare value */
Declaration *decl = s->decl = typer_calloc(tr, 1, sizeof *decl);
decl->where = fo->of->where;
- Identifier ident = ident_translate_forced(fo->value, &sub->idents);
+ Identifier ident = ident_translate_forced(val_ident, &sub->idents);
*(Identifier *)arr_adda(&decl->idents, tr->allocr) = ident;
- ident->decl_kind = IDECL_DECL;
ident->decl = decl;
decl->flags |= DECL_HAS_EXPR;
@@ -1695,9 +1699,8 @@ static Status types_expr(Typer *tr, Expression *e) {
/* declare value */
Declaration *decl = s->decl = typer_calloc(tr, 1, sizeof *decl);
decl->where = fo->of->where;
- Identifier ident = ident_translate_forced(fo->index, &sub->idents);
+ Identifier ident = ident_translate_forced(index_ident, &sub->idents);
*(Identifier *)arr_adda(&decl->idents, tr->allocr) = ident;
- ident->decl_kind = IDECL_DECL;
ident->decl = decl;
decl->flags |= DECL_HAS_EXPR;
@@ -1742,12 +1745,12 @@ static Status types_expr(Typer *tr, Expression *e) {
if (header->flags & DECL_ANNOTATES_TYPE) {
if (!type_eq(iter_type, fo->type)) {
char *exp = type_to_str(iter_type);
- char *got = type_to_str(&fo->type);
+ char *got = type_to_str(fo->type);
err_print(e->where, "Expected to iterate over type %s, but it was annotated as iterating over type %s.");
free(exp); free(got);
goto for_fail;
}
- } else fo->type = *iter_type;
+ } else fo->type = iter_type;
}
if ((fo->flags & FOR_IS_RANGE) && fo->range.step) {
Value *stepval = typer_malloc(tr, sizeof *fo->range.stepval);
@@ -1755,12 +1758,10 @@ static Status types_expr(Typer *tr, Expression *e) {
info_print(fo->range.step->where, "Note that the step of a for loop must be a compile-time constant.");
goto for_fail;
}
- val_cast(stepval, &fo->range.step->type, stepval, &fo->type);
+ val_cast(stepval, &fo->range.step->type, stepval, fo->type);
fo->range.stepval = stepval;
}
- arr_remove_lasta(&tr->in_fors, tr->allocr);
- in_header = false;
if (!types_block(tr, &fo->body)) goto for_fail;
if (fo->body.ret_expr) {
err_print(fo->body.ret_expr->where, "for loops can't return values -- you're missing a semicolon (;)");
@@ -1772,8 +1773,6 @@ static Status types_expr(Typer *tr, Expression *e) {
typer_block_exit(tr);
break;
for_fail:
- if (in_header)
- arr_remove_lasta(&tr->in_fors, tr->allocr);
typer_block_exit(tr);
return false;
};
@@ -2760,8 +2759,9 @@ static Status types_expr(Typer *tr, Expression *e) {
BinaryOp o = e->binary.op;
if (o != BINARY_DOT) {
- if (!types_expr(tr, lhs)
- || !types_expr(tr, rhs))
+ bool lhs_success = types_expr(tr, lhs);
+ bool rhs_success = types_expr(tr, rhs);
+ if (!(lhs_success && rhs_success))
return false;
if (lhs_type->kind == TYPE_UNKNOWN || rhs_type->kind == TYPE_UNKNOWN) {
return true;
@@ -2793,7 +2793,6 @@ static Status types_expr(Typer *tr, Expression *e) {
assert(lhs_type->flags & TYPE_IS_RESOLVED);
assert(rhs_type->flags & TYPE_IS_RESOLVED);
-
if (o == BINARY_SET) {
valid = type_eq(lhs_type, rhs_type);
} else {
@@ -3525,7 +3524,6 @@ static void typer_create(Typer *tr, Evaluator *ev, File *file, ErrCtx *err_ctx,
tr->file = file;
tr->err_ctx = err_ctx;
tr->in_decls = NULL;
- tr->in_fors = NULL;
tr->allocr = allocr;
tr->globals = idents;
*(Block **)arr_adda(&tr->blocks, allocr) = NULL;