summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-06 14:32:15 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-06 14:32:15 -0500
commitdea1ae517bd01e3f21db9e338264417cd6cbea51 (patch)
tree32c42d1b72512a9ab13f3241b04e58d73df605b5
parent81840d518d8b170128e5867274c91dda0db3e4f6 (diff)
changed syntax for tuples to allow for complicated types
-rw-r--r--cgen.c15
-rw-r--r--copy.c4
-rw-r--r--eval.c42
-rw-r--r--infer.c1
-rw-r--r--instance_table.c1
-rw-r--r--package.c5
-rw-r--r--parse.c38
-rw-r--r--test.toc22
-rw-r--r--types.c17
-rw-r--r--types.h5
10 files changed, 87 insertions, 63 deletions
diff --git a/cgen.c b/cgen.c
index e2996de..958b781 100644
--- a/cgen.c
+++ b/cgen.c
@@ -63,6 +63,7 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d);
case EXPR_LITERAL_STR: \
case EXPR_LITERAL_CHAR: \
case EXPR_LITERAL_FLOAT: \
+ case EXPR_PKG: \
break; \
case EXPR_UNARY_OP: \
if (!f(g, e->unary.of)) return false; \
@@ -238,6 +239,7 @@ static bool cgen_uses_ptr(Type *t) {
case TYPE_TYPE:
return false;
case TYPE_EXPR:
+ case TYPE_PKG:
break;
}
assert(0);
@@ -328,6 +330,7 @@ static bool cgen_type_pre(CGenerator *g, Type *t, Location where) {
case TYPE_TUPLE:
case TYPE_TYPE:
case TYPE_EXPR:
+ case TYPE_PKG:
/* We should never try to generate this type */
assert(0);
return false;
@@ -401,6 +404,7 @@ static bool cgen_type_post(CGenerator *g, Type *t, Location where) {
case TYPE_STRUCT:
break;
case TYPE_EXPR:
+ case TYPE_PKG:
assert(0);
break;
}
@@ -426,6 +430,7 @@ static bool type_contains_type(Type *t) {
case TYPE_BUILTIN:
case TYPE_VOID:
case TYPE_UNKNOWN:
+ case TYPE_PKG:
return false;
case TYPE_TYPE:
return true;
@@ -624,6 +629,7 @@ static bool cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E
case TYPE_VOID:
case TYPE_TYPE:
case TYPE_EXPR:
+ case TYPE_PKG:
assert(0);
return false;
}
@@ -721,6 +727,8 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
cgen_write(g, "; ");
}
break;
+
+ /* things which can never be tuples */
case EXPR_SLICE:
case EXPR_IDENT:
case EXPR_LITERAL_INT:
@@ -737,6 +745,7 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
case EXPR_DSIZEOF:
case EXPR_DALIGNOF:
case EXPR_TYPE:
+ case EXPR_PKG:
assert(0);
return false;
}
@@ -1147,10 +1156,12 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) {
case EXPR_DSIZEOF:
case EXPR_DALIGNOF:
case EXPR_TYPE:
+ case EXPR_PKG:
break;
case EXPR_TUPLE:
arr_foreach(e->tuple, Expression, x)
if (!cgen_expr_pre(g, x)) return false;
+ break;
}
return true;
}
@@ -1444,6 +1455,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
a tuple, e.g. 3, 5;, but we've errored about that before
*/
case EXPR_TYPE:
+ case EXPR_PKG:
assert(0);
break;
case EXPR_FN: {
@@ -1518,6 +1530,7 @@ static void cgen_zero_value(CGenerator *g, Type *t) {
case TYPE_UNKNOWN:
case TYPE_TUPLE:
case TYPE_EXPR:
+ case TYPE_PKG:
assert(0);
break;
}
@@ -1662,6 +1675,7 @@ static bool cgen_val_ptr_pre(CGenerator *g, void *v, Type *t, Location where) {
case TYPE_STRUCT:
break;
case TYPE_EXPR:
+ case TYPE_PKG:
assert(0);
return false;
}
@@ -1676,6 +1690,7 @@ static bool cgen_val_ptr(CGenerator *g, void *v, Type *t, Location where) {
case TYPE_VOID:
case TYPE_EXPR:
case TYPE_TYPE:
+ case TYPE_PKG:
assert(0);
return false;
case TYPE_UNKNOWN:
diff --git a/copy.c b/copy.c
index 343b74f..1b3c5ac 100644
--- a/copy.c
+++ b/copy.c
@@ -79,6 +79,7 @@ static void copy_type(Copier *c, Type *out, Type *in) {
switch (in->kind) {
case TYPE_BUILTIN:
case TYPE_TYPE:
+ case TYPE_PKG:
case TYPE_VOID:
case TYPE_UNKNOWN:
break;
@@ -266,6 +267,9 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) {
if (sin->to)
copy_expr(c, sout->to = allocr_malloc(a, sizeof *sout->to), sin->to);
} break;
+ case EXPR_PKG:
+ copy_expr(c, out->pkg.name = allocr_malloc(a, sizeof *out->pkg.name), in->pkg.name);
+ break;
case EXPR_TYPE:
copy_type(c, &out->typeval, &in->typeval);
break;
diff --git a/eval.c b/eval.c
index c022699..ded9b5b 100644
--- a/eval.c
+++ b/eval.c
@@ -180,6 +180,7 @@ static bool val_truthiness(Value *v, Type *t) {
case TYPE_TUPLE:
case TYPE_STRUCT:
case TYPE_EXPR:
+ case TYPE_PKG:
break;
}
assert(0);
@@ -252,6 +253,7 @@ static void *val_get_ptr(Value *v, Type *t) {
case TYPE_SLICE:
case TYPE_TYPE:
case TYPE_TUPLE:
+ case TYPE_PKG:
return v;
case TYPE_ARR:
return v->arr;
@@ -368,6 +370,7 @@ static void *val_ptr_to_free(Value *v, Type *t) {
case TYPE_SLICE:
case TYPE_VOID:
case TYPE_TYPE:
+ case TYPE_PKG:
case TYPE_UNKNOWN:
return NULL;
case TYPE_ARR:
@@ -475,6 +478,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) {
case TYPE_TYPE:
case TYPE_STRUCT:
case TYPE_EXPR:
+ case TYPE_PKG:
assert(0); break;
case TYPE_BUILTIN:
switch (to->kind) {
@@ -503,6 +507,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) {
case TYPE_FN:
case TYPE_ARR:
case TYPE_TYPE:
+ case TYPE_PKG:
assert(0);
break;
}
@@ -516,15 +521,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) {
case TYPE_FN:
vout->fn = vin->fn;
break;
- case TYPE_SLICE:
- case TYPE_UNKNOWN:
- case TYPE_TUPLE:
- case TYPE_VOID:
- case TYPE_ARR:
- case TYPE_BUILTIN:
- case TYPE_TYPE:
- case TYPE_STRUCT:
- case TYPE_EXPR:
+ default:
assert(0); break;
}
break;
@@ -550,13 +547,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) {
case TYPE_FN:
vout->fn = vin->ptr;
break;
- case TYPE_SLICE:
- case TYPE_UNKNOWN:
- case TYPE_TUPLE:
- case TYPE_VOID:
- case TYPE_EXPR:
- case TYPE_TYPE:
- case TYPE_STRUCT:
+ default:
assert(0);
break;
}
@@ -570,15 +561,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) {
case TYPE_ARR:
vout->arr = vin->arr;
break;
- case TYPE_EXPR:
- case TYPE_SLICE:
- case TYPE_FN:
- case TYPE_UNKNOWN:
- case TYPE_TUPLE:
- case TYPE_VOID:
- case TYPE_BUILTIN:
- case TYPE_TYPE:
- case TYPE_STRUCT:
+ default:
assert(0); break;
}
break;
@@ -593,14 +576,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) {
case TYPE_SLICE:
vout->slice = vin->slice;
break;
- case TYPE_FN:
- case TYPE_UNKNOWN:
- case TYPE_TUPLE:
- case TYPE_VOID:
- case TYPE_BUILTIN:
- case TYPE_EXPR:
- case TYPE_TYPE:
- case TYPE_STRUCT:
+ default:
assert(0); break;
}
break;
diff --git a/infer.c b/infer.c
index d43c31f..5046eda 100644
--- a/infer.c
+++ b/infer.c
@@ -84,6 +84,7 @@ static bool infer_from_type(Typer *tr, Type *match, Type *to, Identifier *idents
case TYPE_UNKNOWN:
case TYPE_BUILTIN:
case TYPE_TYPE:
+ case TYPE_PKG:
break; /* nothing we can do here */
case TYPE_TUPLE: {
if (to->kind != TYPE_TUPLE) return true;
diff --git a/instance_table.c b/instance_table.c
index 2e73860..3c859ac 100644
--- a/instance_table.c
+++ b/instance_table.c
@@ -96,6 +96,7 @@ static U64 type_hash(Type *t) {
case TYPE_VOID:
case TYPE_UNKNOWN:
case TYPE_TYPE:
+ case TYPE_PKG:
return hash;
case TYPE_TUPLE:
arr_foreach(t->tuple, Type, sub)
diff --git a/package.c b/package.c
index f1844b5..8c8ee77 100644
--- a/package.c
+++ b/package.c
@@ -126,6 +126,7 @@ static bool export_type(Exporter *ex, Type *type, Location where) {
switch (type->kind) {
case TYPE_VOID:
case TYPE_TYPE:
+ case TYPE_PKG:
case TYPE_UNKNOWN:
break;
case TYPE_PTR: export_type(ex, type->ptr, where); break;
@@ -404,6 +405,10 @@ static bool export_expr(Exporter *ex, Expression *e) {
if (!export_block(ex, &w->body))
return false;
} break;
+ case EXPR_PKG:
+ if (!export_expr(ex, e->pkg.name))
+ return false;
+ break;
case EXPR_SLICE: {
SliceExpr *s = &e->slice;
if (!export_expr(ex, s->of)) return false;
diff --git a/parse.c b/parse.c
index b410e66..24253f0 100644
--- a/parse.c
+++ b/parse.c
@@ -49,6 +49,7 @@ static const char *expr_kind_to_str(ExprKind k) {
case EXPR_SLICE: return "slice";
case EXPR_TYPE: return "type";
case EXPR_VAL: return "value";
+ case EXPR_PKG: return "package";
}
assert(0);
return "";
@@ -266,6 +267,8 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) {
}
case TYPE_TYPE:
return str_copy(buffer, bufsize, "<type>");
+ case TYPE_PKG:
+ return str_copy(buffer, bufsize, "pkg");
case TYPE_EXPR:
/* TODO: improve this... we're gonna need expr_to_str ): */
return str_copy(buffer, bufsize, "<type expression>");
@@ -449,12 +452,11 @@ static bool parse_type(Parser *p, Type *type) {
}
}
/* Not a builtin */
- if (t->token->kw == KW_TYPE) {
+ switch (t->token->kw) {
+ case KW_TYPE:
type->kind = TYPE_TYPE;
++t->token;
break;
- }
- switch (t->token->kw) {
case KW_FN: {
/* function type */
type->kind = TYPE_FN;
@@ -529,11 +531,11 @@ static bool parse_type(Parser *p, Type *type) {
return false;
}
} break;
- case KW_LPAREN:
+ case KW_LT:
/* tuple! */
type->kind = TYPE_TUPLE;
type->tuple = NULL;
- ++t->token; /* move past ( */
+ ++t->token; /* move past < */
while (1) {
Type *child = parser_arr_add(p, &type->tuple);
if (!parse_type(p, child)) return false;
@@ -541,8 +543,8 @@ static bool parse_type(Parser *p, Type *type) {
err_print(child->where, "Tuples cannot contain tuples.");
return false;
}
- if (token_is_kw(t->token, KW_RPAREN)) { /* we're done with the tuple */
- ++t->token; /* move past ) */
+ 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)) {
@@ -612,19 +614,19 @@ static bool parse_type(Parser *p, Type *type) {
}
break;
default:
- tokr_err(t, "Unrecognized type.");
- return false;
+ goto type_expr;
}
break;
default:
+ type_expr: {
/* TYPE_EXPR */
- if (parse_expr(p, type->expr = parser_new_expr(p),
- expr_find_end(p, (ExprEndFlags)-1 /* end as soon as possible */))) {
+ Token *end = expr_find_end(p, (ExprEndFlags)-1 /* end as soon as possible */);
+ if (parse_expr(p, type->expr = parser_new_expr(p), end)) {
type->kind = TYPE_EXPR;
} else {
- tokr_err(t, "Unrecognized type.");
return false;
}
+ } break;
}
return true;
@@ -1023,6 +1025,12 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
Token *start = t->token;
/* TODO: consider moving this after ops, so that "if true { 5 } else { 3 } as f32" is possible */
if (t->token->kind == TOKEN_KW) switch (t->token->kw) {
+ case KW_PKG:
+ ++t->token;
+ e->kind = EXPR_PKG;
+ if (!parse_expr(p, e->pkg.name = parser_malloc(p, sizeof *e->pkg.name), expr_find_end(p, 0)))
+ return false;
+ return true;
case KW_FN: {
/* this is a function */
e->kind = EXPR_FN;
@@ -2241,6 +2249,11 @@ static void fprint_expr(FILE *out, Expression *e) {
case EXPR_VAL:
fprint_val(out, e->val, &e->type);
break;
+ case EXPR_PKG:
+ fprintf(out, "(pkg ");
+ fprint_expr(out, e->pkg.name);
+ fprintf(out, ")");
+ break;
}
if (found_type) {
fprintf(out, ":");
@@ -2338,6 +2351,7 @@ static bool expr_is_definitely_const(Expression *e) {
case EXPR_DALIGNOF:
case EXPR_TYPE:
case EXPR_VAL:
+ case EXPR_PKG:
return true;
case EXPR_IF:
case EXPR_WHILE:
diff --git a/test.toc b/test.toc
index f6bac2f..b143ad4 100644
--- a/test.toc
+++ b/test.toc
@@ -1,11 +1,17 @@
-f ::= g();
-
-x ::= 3;
-
-g ::= fn() int { x };
+puti ::= fn(x: int) {
+ #C("printf(\"%ld\\n\", (long)x);
+");
+};
+putf ::= fn(x: float) {
+ #C("printf(\"%f\\n\", (double)x);
+");
+};
+foo ::= fn() <int, int> {
+ x, y := 3, 5;
+ x, y
+};
main ::= fn() {
- #C("printf(\"%ld\\n\", (long)x)");
- a := g();
- #C("printf(\"%ld\\n\", (long)a)");
+ a, b := foo();
+ puti(a); puti(b);
}; \ No newline at end of file
diff --git a/types.c b/types.c
index a0c3c1a..143dbec 100644
--- a/types.c
+++ b/types.c
@@ -52,6 +52,7 @@ static bool type_eq(Type *a, Type *b) {
case TYPE_VOID: return true;
case TYPE_UNKNOWN: assert(0); return false;
case TYPE_TYPE: return true;
+ case TYPE_PKG: return true;
case TYPE_BUILTIN:
return a->builtin == b->builtin;
case TYPE_STRUCT: return a->struc == b->struc;
@@ -177,7 +178,8 @@ static bool expr_must_lval(Expression *e) {
case EXPR_BLOCK:
case EXPR_SLICE:
case EXPR_TYPE:
- case EXPR_VAL: {
+ case EXPR_VAL:
+ case EXPR_PKG: {
err_print(e->where, "Cannot use %s as l-value.", expr_kind_to_str(e->kind));
return false;
}
@@ -528,6 +530,7 @@ static bool type_resolve(Typer *tr, Type *t, Location where) {
case TYPE_UNKNOWN:
case TYPE_VOID:
case TYPE_TYPE:
+ case TYPE_PKG:
case TYPE_BUILTIN:
break;
}
@@ -546,6 +549,7 @@ static bool type_can_be_truthy(Type *t) {
case TYPE_ARR:
case TYPE_TYPE:
case TYPE_STRUCT:
+ case TYPE_PKG:
return false;
case TYPE_FN:
case TYPE_UNKNOWN:
@@ -577,6 +581,7 @@ static Status type_cast_status(Type *from, Type *to) {
case TYPE_STRUCT:
case TYPE_TYPE:
case TYPE_VOID:
+ case TYPE_PKG:
return STATUS_ERR;
case TYPE_BUILTIN:
switch (from->builtin) {
@@ -594,16 +599,8 @@ static Status type_cast_status(Type *from, Type *to) {
return STATUS_NONE;
case TYPE_PTR:
return STATUS_WARN;
- case TYPE_FN:
- case TYPE_TYPE:
- case TYPE_TUPLE:
- case TYPE_SLICE:
- case TYPE_STRUCT:
- case TYPE_ARR:
- case TYPE_VOID:
+ default:
return STATUS_ERR;
- case TYPE_EXPR:
- assert(0);
}
break;
case BUILTIN_F32:
diff --git a/types.h b/types.h
index 8979475..147ee44 100644
--- a/types.h
+++ b/types.h
@@ -334,6 +334,7 @@ typedef enum {
TYPE_PTR,
TYPE_SLICE,
TYPE_TYPE,
+ TYPE_PKG,
TYPE_EXPR, /* just use this expression as the type. this kind of type doesn't exist after resolving. */
TYPE_STRUCT
#define TYPE_COUNT (TYPE_STRUCT+1)
@@ -456,6 +457,7 @@ typedef enum {
EXPR_DALIGNOF,
EXPR_SLICE,
EXPR_TYPE,
+ EXPR_PKG,
/*
a value (it's useful to have this).
right now they don't work with cgen_set_tuple
@@ -641,6 +643,9 @@ typedef struct Expression {
struct {
Type type;
} del;
+ struct {
+ struct Expression *name;
+ } pkg;
IfExpr if_;
WhileExpr while_;
EachExpr *each;