summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-04 23:02:42 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-04 23:02:42 -0400
commit2977dbc96fdb948e2543aad758a12bc31c450557 (patch)
treec6c61a174568a208101f37d08d0d041514f83ffb
parent51360274858bef53009bf1dd6619d7407277f642 (diff)
improved declarations (multiple types in one decl)
-rw-r--r--parse.c41
-rw-r--r--test.toc9
-rw-r--r--types.c82
-rw-r--r--types.h3
4 files changed, 94 insertions, 41 deletions
diff --git a/parse.c b/parse.c
index e79e72d..cd2c939 100644
--- a/parse.c
+++ b/parse.c
@@ -22,7 +22,6 @@ static const char *binary_op_to_str(BinaryOp b) {
case BINARY_MUL: return "*";
case BINARY_DIV: return "/";
case BINARY_SET: return "=";
- case BINARY_COMMA: return ",";
case BINARY_AT_INDEX: return "[]";
case BINARY_LT: return "<";
case BINARY_LE: return "<=";
@@ -927,8 +926,29 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
return true;
}
-
- BinaryOp op;
+ if (lowest_precedence_op->kw == KW_COMMA) {
+ Expression lhs, rhs;
+ if (!parse_expr(p, &lhs, lowest_precedence_op)) return false;
+ t->token = lowest_precedence_op + 1;
+ if (!parse_expr(p, &rhs, end)) return false;
+ /* create tuple expr out of lhs, rhs */
+ e->kind = EXPR_TUPLE;
+ e->tuple = NULL;
+ if (lhs.kind == EXPR_TUPLE) {
+ e->tuple = lhs.tuple;
+ } else {
+ *(Expression *)parser_arr_add(p, &e->tuple) = lhs;
+ }
+ if (rhs.kind == EXPR_TUPLE) {
+ arr_foreach(rhs.tuple, Expression, r) {
+ *(Expression *)parser_arr_add(p, &e->tuple) = *r;
+ }
+ } else {
+ *(Expression *)parser_arr_add(p, &e->tuple) = rhs;
+ }
+ return true;
+ }
+ BinaryOp op;
switch (lowest_precedence_op->kw) {
case KW_PLUS:
op = BINARY_ADD;
@@ -957,9 +977,6 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
case KW_EQ:
op = BINARY_SET;
break;
- case KW_COMMA:
- op = BINARY_COMMA;
- break;
case KW_ASTERISK:
op = BINARY_MUL;
break;
@@ -975,7 +992,6 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
}
e->binary.op = op;
e->kind = EXPR_BINARY_OP;
-
Expression *lhs = parser_new_expr(p);
e->binary.lhs = lhs;
if (!parse_expr(p, lhs, lowest_precedence_op)) {
@@ -987,8 +1003,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
e->binary.rhs = rhs;
if (!parse_expr(p, rhs, end)) {
return false;
- }
-
+ }
return true;
} else {
/* function calls, array accesses, etc. */
@@ -1483,6 +1498,14 @@ static void fprint_expr(FILE *out, Expression *e) {
case EXPR_BLOCK:
fprint_block(out, &e->block);
break;
+ case EXPR_TUPLE:
+ fprintf(out, "(");
+ arr_foreach(e->tuple, Expression, x) {
+ if (x != e->tuple) fprintf(out, ", ");
+ fprint_expr(out, x);
+ }
+ fprintf(out, ")");
+ break;
case EXPR_DIRECT:
fprintf(out, "#");
fprintf(out, "%s", directives[e->direct.which]);
diff --git a/test.toc b/test.toc
index 3696abe..639cfcf 100644
--- a/test.toc
+++ b/test.toc
@@ -1,3 +1,12 @@
main @= fn() {
x : [{ 3; 5 }] int;
+ foo, bar := 3, 5;
+ asjdfh, asdfkjh := 3.2, 91;
+ if foo {
+ bar;
+ } else {
+ foo;
+ }
+
+ test, test2 := (fn() {}), asjdfh * 2;
}; \ No newline at end of file
diff --git a/types.c b/types.c
index 2a7fd22..e6b7cdc 100644
--- a/types.c
+++ b/types.c
@@ -165,12 +165,17 @@ static bool expr_must_lval(Expression *e) {
case EXPR_BINARY_OP:
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;
+ case EXPR_TUPLE: {
+ /* x, y is an lval, but 3, "hello" is not. */
+ arr_foreach(e->tuple, Expression, x) {
+ if (!expr_must_lval(x))
+ return false;
+ }
+ return true;
+ } break;
default:
break;
}
@@ -240,7 +245,20 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
}
if (d->flags & DECL_FLAG_FOUND_TYPE) {
- *t = d->type;
+ if (d->type.kind == TYPE_TUPLE) {
+ /* get correct item in tuple */
+ long index = 0;
+ arr_foreach(d->idents, Identifier, decl_i) {
+ if (*decl_i == i) {
+ break;
+ }
+ index++;
+ assert(index < (long)arr_len(d->idents)); /* identifier got its declaration set to here, but it's not here */
+ }
+ *t = d->type.tuple[index];
+ } else {
+ *t = d->type;
+ }
return true;
} else {
if ((d->flags & DECL_FLAG_HAS_EXPR) && (d->expr.kind == EXPR_FN)) {
@@ -563,7 +581,10 @@ static bool types_expr(Typer *tr, Expression *e) {
bool has_else = false;
if (!types_block(tr, &curr->body))
return false;
- *t = curr->body.ret_expr->type;
+ if (curr->body.ret_expr)
+ *t = curr->body.ret_expr->type;
+ else
+ t->kind = TYPE_VOID;
while (1) {
if (curr->cond) {
if (!types_expr(tr, curr->cond))
@@ -583,7 +604,12 @@ static bool types_expr(Typer *tr, Expression *e) {
if (!types_block(tr, &nexti->body)) {
return false;
}
- *next_type = nexti->body.ret_expr->type;
+ if (nexti->body.ret_expr) {
+ *next_type = nexti->body.ret_expr->type;
+ } else {
+ next_type->kind = TYPE_VOID;
+ next_type->flags = 0;
+ }
if (!type_eq(curr_type, next_type)) {
char *currstr = type_to_str(curr_type);
char *nextstr = type_to_str(next_type);
@@ -926,30 +952,17 @@ static bool types_expr(Typer *tr, Expression *e) {
}
*t = *lhs_type->arr.of;
break;
- case BINARY_COMMA: {
- t->kind = TYPE_TUPLE;
- Type **tup_types = &t->tuple;
- *tup_types = NULL;
- if (lhs_type->kind == TYPE_TUPLE) {
- /* tuple, x => tuple */
- arr_foreach(lhs_type->tuple, Type, child) {
- *(Type*)typer_arr_add(tr, tup_types) = *child;
- }
- } else {
- *(Type*)typer_arr_add(tr, tup_types) = *lhs_type;
- }
-
- if (rhs_type->kind == TYPE_TUPLE) {
- /* x, tuple => tuple */
- arr_foreach(rhs_type->tuple, Type, child) {
- *(Type*)typer_arr_add(tr, tup_types) = *child;
- }
- } else {
- *(Type*)typer_arr_add(tr, tup_types) = *rhs_type;
- }
} break;
- }
} break;
+ case EXPR_TUPLE:
+ t->kind = TYPE_TUPLE;
+ t->tuple = NULL;
+ arr_foreach(e->tuple, Expression, x) {
+ Type *x_type = typer_arr_add(tr, &t->tuple);
+ types_expr(tr, x);
+ *x_type = x->type;
+ }
+ break;
}
return true;
@@ -989,6 +1002,10 @@ static bool types_decl(Typer *tr, Declaration *d) {
success = false;
goto ret;
}
+ } else {
+ /* if we can't find the type, default to unknown */
+ d->type.flags = 0;
+ d->type.kind = TYPE_UNKNOWN;
}
if (d->flags & DECL_FLAG_HAS_EXPR) {
if (!types_expr(tr, &d->expr)) {
@@ -1017,10 +1034,13 @@ static bool types_decl(Typer *tr, Declaration *d) {
}
}
}
+ size_t n_idents = arr_len(d->idents);
if (d->type.kind == TYPE_TUPLE) {
- /* TODO(eventually): Should this be allowed? */
- err_print(d->where, "Declaring a tuple is not allowed.");
- return false;
+ if (n_idents != arr_len(d->type.tuple)) {
+ err_print(d->where, "Expected to have %lu things declared in declaration, but got %lu.", (unsigned long)n_idents);
+ success = false;
+ goto ret;
+ }
}
ret:
/* pretend we found the type even if we didn't to prevent too many errors */
diff --git a/types.h b/types.h
index 25e4bc1..30b898a 100644
--- a/types.h
+++ b/types.h
@@ -276,6 +276,7 @@ typedef enum {
EXPR_NEW,
EXPR_CALL,
EXPR_BLOCK,
+ EXPR_TUPLE,
EXPR_DIRECT
} ExprKind;
@@ -293,7 +294,6 @@ typedef enum {
BINARY_SUB,
BINARY_MUL,
BINARY_DIV,
- BINARY_COMMA,
BINARY_GT,
BINARY_LT,
BINARY_GE,
@@ -376,6 +376,7 @@ typedef struct Expression {
FnExpr fn;
CastExpr cast;
Block block;
+ struct Expression *tuple;
};
} Expression;