summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--parse.c54
-rw-r--r--test.toc61
-rw-r--r--tests/defer.toc17
-rw-r--r--tests/defer_expected4
-rw-r--r--types.c16
5 files changed, 85 insertions, 67 deletions
diff --git a/parse.c b/parse.c
index 5818eb3..df49dbb 100644
--- a/parse.c
+++ b/parse.c
@@ -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;
diff --git a/test.toc b/test.toc
index c185a7f..6c2a304 100644
--- a/test.toc
+++ b/test.toc
@@ -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
diff --git a/types.c b/types.c
index cee5698..d67596f 100644
--- a/types.c
+++ b/types.c
@@ -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) {