From dea1ae517bd01e3f21db9e338264417cd6cbea51 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Mon, 6 Jan 2020 14:32:15 -0500 Subject: changed syntax for tuples to allow for complicated types --- cgen.c | 15 +++++++++++++++ copy.c | 4 ++++ eval.c | 42 +++++++++--------------------------------- infer.c | 1 + instance_table.c | 1 + package.c | 5 +++++ parse.c | 38 ++++++++++++++++++++++++++------------ test.toc | 22 ++++++++++++++-------- types.c | 17 +++++++---------- types.h | 5 +++++ 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, ""); + 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, ""); @@ -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() { + 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; -- cgit v1.2.3