diff options
-rw-r--r-- | parse.c | 54 | ||||
-rw-r--r-- | test.toc | 61 | ||||
-rw-r--r-- | tests/defer.toc | 17 | ||||
-rw-r--r-- | tests/defer_expected | 4 | ||||
-rw-r--r-- | types.c | 16 |
5 files changed, 85 insertions, 67 deletions
@@ -270,13 +270,13 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { return written; } case TYPE_TUPLE: { - size_t written = str_copy(buffer, bufsize, "<"); + size_t written = str_copy(buffer, bufsize, "("); arr_foreach(t->tuple, Type, child) { if (child != t->tuple) written += str_copy(buffer + written, bufsize - written, ", "); written += type_to_str_(child, buffer + written, bufsize - written); } - written += str_copy(buffer + written, bufsize - written, ">"); + written += str_copy(buffer + written, bufsize - written, ")"); return written; } case TYPE_PTR: { @@ -510,10 +510,6 @@ static Status parse_type(Parser *p, Type *type, Location *where) { Type *param_type = parser_arr_add(p, &type->fn.types); Location type_where; if (!parse_type(p, param_type, &type_where)) return false; - if (param_type->kind == TYPE_TUPLE) { - err_print(type_where, "Functions cannot have tuples as parameters."); - return false; - } if (token_is_kw(t->token, KW_RPAREN)) break; if (!token_is_kw(t->token, KW_COMMA)) { @@ -552,10 +548,6 @@ static Status parse_type(Parser *p, Type *type, Location *where) { ++t->token; /* move past ] */ Location slice_where; if (!parse_type(p, type->slice, &slice_where)) return false; - if (type->slice->kind == TYPE_TUPLE) { - err_print(slice_where, "You cannot have a slice of tuples."); - return false; - } break; } Token *end = expr_find_end(p, 0); @@ -565,41 +557,7 @@ static Status parse_type(Parser *p, Type *type, Location *where) { type->arr.of = parser_malloc(p, sizeof *type->arr.of); Location of_where; if (!parse_type(p, type->arr.of, &of_where)) return false; - if (type->arr.of->kind == TYPE_TUPLE) { - err_print(of_where, "You cannot have an array of tuples."); - return false; - } } break; - case KW_LT: - /* tuple! */ - type->kind = TYPE_TUPLE; - type->tuple = NULL; - ++t->token; /* move past < */ - while (1) { - Type *child = parser_arr_add(p, &type->tuple); - Location child_where; - if (!parse_type(p, child, &child_where)) return false; - if (child->kind == TYPE_TUPLE) { - err_print(child_where, "Tuples cannot contain tuples."); - return false; - } - if (type_is_builtin(child, BUILTIN_VARARGS)) { - err_print(child_where, "Tuples cannot contain varargs."); - return false; - } - if (token_is_kw(t->token, KW_GT)) { /* we're done with the tuple */ - ++t->token; /* move past > */ - break; - } - if (token_is_kw(t->token, KW_COMMA)) { - ++t->token; /* move past , */ - continue; - } else { - tokr_err(t, "Expected , to list next tuple type or ) to end tuple type."); - return false; - } - } - break; case KW_AMPERSAND: { /* pointer */ type->kind = TYPE_PTR; @@ -607,10 +565,6 @@ static Status parse_type(Parser *p, Type *type, Location *where) { ++t->token; /* move past & */ Location ptr_where; if (!parse_type(p, type->ptr, &ptr_where)) return false; - if (type->ptr->kind == TYPE_TUPLE) { - err_print(ptr_where, "You cannot have a pointer to a tuple."); - return false; - } } break; case KW_STRUCT: { /* struct */ @@ -791,10 +745,6 @@ static bool parser_is_definitely_type(Parser *p, Token **end) { } } break; - case KW_LT: { - /* no expression can start with < */ - return true; - } break; case KW_FN: { ret = false; ++t->token; @@ -1,12 +1,65 @@ -#include "std/io.toc", io; -f ::= fn() (int, int) { +#include "io.toc", io; + +plusone ::= fn(n : int) x := n { + defer x += 1; +} + +same ::= fn(n : int) int { + x := n; + defer x += 1; + x +} + +thing1 ::= fn() (int, int) { x := 5; - y := 88; + y := 6; defer x += 1; x, y } + +thing2 ::= fn() x := 5, y := 6 { + defer x += 1; +} + main ::= fn() { - a,b := f(); + io.puti(plusone(3)); + io.puti(same(3)); + a, b := thing1(); + c, d := thing2(); io.puti(a); io.puti(b); + io.puti(c); + io.puti(d); + defer io.puts("deferred from main()"); + for i := 1..10 { + defer io.puts("deferred from for"); + io.puti(i); + if i == 2 { + defer io.puts("deferred from if1"); + defer io.puts("deferred from if2"); + defer io.puts("deferred from if3"); + defer io.puts("deferred from if4"); + defer io.puts("deferred from if5"); + defer io.puts("deferred from if6"); + defer io.puts("deferred from if7"); + defer io.puts("deferred from if8"); + continue; + } + if i == 8 { + break; + } + } + i := 0; + while { + defer io.puts("deferred from while"); + i += 1; + io.puti(i); + if i % 2 == 0 { continue; } + if i == 7 { + defer io.puts("deferred from if"); + break; + } + + } + io.puts("end of main()"); } diff --git a/tests/defer.toc b/tests/defer.toc index 32165e7..6c2a304 100644 --- a/tests/defer.toc +++ b/tests/defer.toc @@ -10,9 +10,26 @@ same ::= fn(n : int) int { x } +thing1 ::= fn() (int, int) { + x := 5; + y := 6; + defer x += 1; + x, y +} + +thing2 ::= fn() x := 5, y := 6 { + defer x += 1; +} + main ::= fn() { io.puti(plusone(3)); io.puti(same(3)); + a, b := thing1(); + c, d := thing2(); + io.puti(a); + io.puti(b); + io.puti(c); + io.puti(d); defer io.puts("deferred from main()"); for i := 1..10 { defer io.puts("deferred from for"); diff --git a/tests/defer_expected b/tests/defer_expected index 99b45e1..e678115 100644 --- a/tests/defer_expected +++ b/tests/defer_expected @@ -1,5 +1,9 @@ 4 3 +5 +6 +6 +6 1 deferred from for 2 @@ -459,12 +459,6 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { } } - if (param->type.kind == TYPE_TUPLE) { - err_print(param->where, "Functions can't have tuple parameters."); - success = false; - goto ret; - } - if (param->flags & DECL_HAS_EXPR) { if (param->expr.kind != EXPR_VAL) { Value val; @@ -2546,6 +2540,7 @@ static Status types_expr(Typer *tr, Expression *e) { return false; } if (of_type->kind == TYPE_TUPLE) { + /* necessary because x, y (where x and y are variables) is an l-value */ err_print(e->where, "Cannot take address of tuple."); return false; } @@ -2585,6 +2580,10 @@ static Status types_expr(Typer *tr, Expression *e) { err_print(of->where, "You can't apply typeof to varargs."); return false; } + if (of->type.kind == TYPE_TUPLE) { + err_print(of->where, "You can't apply typeof to a tuple."); + return false; + } e->kind = EXPR_TYPE; e->typeval = &of->type; t->kind = TYPE_BUILTIN; @@ -3175,11 +3174,6 @@ static Status types_decl(Typer *tr, Declaration *d) { /* don't resolve it because it's not really complete */ } else { if (!type_resolve(tr, val->type, d->where)) return false; - if (val->type->kind == TYPE_TUPLE) { - err_print(d->where, "You can't declare a new type to be a tuple."); - success = false; - goto ret; - } } } } else if (!(d->flags & DECL_IS_CONST) && t->kind == TYPE_FN && t->fn.constness) { |