diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-04 23:02:42 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-04 23:02:42 -0400 |
commit | 2977dbc96fdb948e2543aad758a12bc31c450557 (patch) | |
tree | c6c61a174568a208101f37d08d0d041514f83ffb | |
parent | 51360274858bef53009bf1dd6619d7407277f642 (diff) |
improved declarations (multiple types in one decl)
-rw-r--r-- | parse.c | 41 | ||||
-rw-r--r-- | test.toc | 9 | ||||
-rw-r--r-- | types.c | 82 | ||||
-rw-r--r-- | types.h | 3 |
4 files changed, 94 insertions, 41 deletions
@@ -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]); @@ -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 @@ -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 */ @@ -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; |