From cc17665ae2fcaa5efae55dcc78b905f0e7432faa Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sun, 27 Oct 2019 00:32:11 -0400 Subject: switching to just declaring types --- cgen.c | 21 +++++++++--------- decls_cgen.c | 1 + eval.c | 27 +++++++++++++++++++---- parse.c | 70 +++++++++++++++++++++++------------------------------------- test.toc | 2 +- types.c | 35 +++++++++++++++++------------- types.h | 17 ++++++--------- 7 files changed, 90 insertions(+), 83 deletions(-) diff --git a/cgen.c b/cgen.c index 6ba6cad..e98224b 100644 --- a/cgen.c +++ b/cgen.c @@ -101,6 +101,7 @@ static bool cgen_uses_ptr(Type *t) { case TYPE_SLICE: case TYPE_VOID: case TYPE_UNKNOWN: + case TYPE_TYPE: return false; } assert(0); @@ -178,7 +179,8 @@ static bool cgen_type_pre(CGenerator *g, Type *t, Location where) { err_print(where, "Can't determine type."); return false; case TYPE_TUPLE: - /* We should never try to generate a tuple */ + case TYPE_TYPE: + /* We should never try to generate this type */ assert(0); return false; } @@ -251,6 +253,7 @@ static bool cgen_type_post(CGenerator *g, Type *t, Location where) { case TYPE_VOID: case TYPE_UNKNOWN: case TYPE_TUPLE: + case TYPE_TYPE: case TYPE_SLICE: break; } @@ -403,6 +406,7 @@ static bool cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E return false; break; case TYPE_VOID: + case TYPE_TYPE: assert(0); return false; } @@ -501,6 +505,7 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, case EXPR_CAST: case EXPR_NEW: case EXPR_DIRECT: + case EXPR_TYPE: assert(0); return false; } @@ -710,6 +715,7 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { case EXPR_IDENT: case EXPR_FN: case EXPR_DIRECT: + case EXPR_TYPE: break; case EXPR_TUPLE: arr_foreach(e->tuple, Expression, x) @@ -922,6 +928,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) { /* the only time this should happen is if you're stating a tuple, e.g. 3, 5;, but we've errored about that before (the comma operator does not exist in toc!) */ + case EXPR_TYPE: assert(0); break; case EXPR_FN: { @@ -988,6 +995,7 @@ static void cgen_zero_value(CGenerator *g, Type *t) { cgen_zero_value(g, t->arr.of); cgen_write(g, "}"); break; + case TYPE_TYPE: case TYPE_VOID: case TYPE_UNKNOWN: case TYPE_TUPLE: @@ -1061,6 +1069,7 @@ static bool cgen_val_ptr_pre(CGenerator *g, void *v, Type *t, Location where) { } break; case TYPE_FN: + case TYPE_TYPE: case TYPE_UNKNOWN: case TYPE_TUPLE: case TYPE_VOID: @@ -1075,6 +1084,7 @@ static bool cgen_val_ptr(CGenerator *g, void *v, Type *t, Location where) { switch (t->kind) { case TYPE_TUPLE: case TYPE_VOID: + case TYPE_TYPE: assert(0); return false; case TYPE_UNKNOWN: @@ -1260,15 +1270,6 @@ static bool cgen_stmt(CGenerator *g, Statement *s) { cgen_write(g, ";"); cgen_nl(g); break; - case STMT_TDECL: - cgen_write(g, "typedef "); - if (!cgen_type_pre(g, &s->tdecl.type, s->where)) return false; - cgen_write(g, " "); - cgen_ident(g, s->tdecl.name); - if (!cgen_type_post(g, &s->tdecl.type, s->where)) return false; - cgen_write(g, ";"); - cgen_nl(g); - break; case STMT_RET: if (!cgen_ret(g, s->ret.flags & RET_FLAG_EXPR ? &s->ret.expr : NULL)) return false; diff --git a/decls_cgen.c b/decls_cgen.c index 0ef0451..58d8667 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -64,6 +64,7 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) { if (!cgen_decls_block(g, &e->fn.body)) return false; break; + case EXPR_TYPE: case EXPR_DIRECT: case EXPR_NEW: case EXPR_IDENT: diff --git a/eval.c b/eval.c index fffc833..445e5c8 100644 --- a/eval.c +++ b/eval.c @@ -55,6 +55,8 @@ static size_t compiler_sizeof(Type *t) { return sizeof(Value *); case TYPE_SLICE: return sizeof(Slice); + case TYPE_TYPE: + return sizeof(Type *); case TYPE_VOID: case TYPE_UNKNOWN: return 0; @@ -90,7 +92,9 @@ static bool val_truthiness(Value *v, Type *t) { case TYPE_FN: return v->fn != NULL; case TYPE_ARR: return t->arr.n > 0; case TYPE_SLICE: return v->slice.n > 0; - case TYPE_TUPLE: break; + case TYPE_TYPE: + case TYPE_TUPLE: + break; } assert(0); return false; @@ -158,6 +162,7 @@ static void val_copy(Evaluator *ev, Value *dest, Value *src, Type *t) { case TYPE_SLICE: case TYPE_VOID: case TYPE_UNKNOWN: + case TYPE_TYPE: *dest = *src; break; case TYPE_ARR: { @@ -187,6 +192,7 @@ static void *val_ptr_to_free(Value *v, Type *t) { case TYPE_SLICE: case TYPE_VOID: case TYPE_UNKNOWN: + case TYPE_TYPE: return NULL; case TYPE_ARR: return v->arr; @@ -282,7 +288,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { case TYPE_VOID: assert(0); break; case TYPE_UNKNOWN: assert(0); break; case TYPE_TUPLE: assert(0); break; - + case TYPE_TYPE: assert(0); break; case TYPE_BUILTIN: switch (to->kind) { case TYPE_BUILTIN: @@ -307,6 +313,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { case TYPE_TUPLE: case TYPE_FN: case TYPE_ARR: + case TYPE_TYPE: assert(0); break; } @@ -326,6 +333,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { case TYPE_VOID: case TYPE_ARR: case TYPE_BUILTIN: + case TYPE_TYPE: assert(0); break; } break; @@ -355,6 +363,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { case TYPE_UNKNOWN: case TYPE_TUPLE: case TYPE_VOID: + case TYPE_TYPE: assert(0); break; } @@ -374,6 +383,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { case TYPE_TUPLE: case TYPE_VOID: case TYPE_BUILTIN: + case TYPE_TYPE: assert(0); break; } break; @@ -393,6 +403,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { case TYPE_TUPLE: case TYPE_VOID: case TYPE_BUILTIN: + case TYPE_TYPE: assert(0); break; } break; @@ -425,6 +436,9 @@ static void eval_deref(Value *v, void *ptr, Type *type) { case TYPE_SLICE: v->slice = *(Slice *)ptr; break; + case TYPE_TYPE: + v->type = *(Type **)ptr; + break; case TYPE_VOID: case TYPE_UNKNOWN: assert(0); @@ -457,6 +471,9 @@ static void eval_deref_set(void *set, Value *to, Type *type) { case TYPE_SLICE: *(Slice *)set = to->slice; break; + case TYPE_TYPE: + *(Type **)set = to->type; + break; case TYPE_VOID: case TYPE_UNKNOWN: assert(0); @@ -636,8 +653,8 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { assert(e->binary.lhs->type.kind == TYPE_BUILTIN); \ switch (builtin) { \ eval_binary_bool_op_nums(builtin, op); \ - default:printf("%d\n",(int)builtin); \ - assert(!"Invalid builtin to "#op); break; \ + default: \ + assert(!("Invalid builtin to "#op)[0]); break; \ }} #define eval_binary_bool_op(op) \ @@ -966,6 +983,8 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { v->slice.n = 0; } } break; + case EXPR_TYPE: + v->type = &e->typeval; } return true; } diff --git a/parse.c b/parse.c index c3a0694..652f1bc 100644 --- a/parse.c +++ b/parse.c @@ -23,6 +23,7 @@ static const char *expr_kind_to_str(ExprKind k) { case EXPR_BLOCK: return "block"; case EXPR_IDENT: return "identifier"; case EXPR_SLICE: return "slice"; + case EXPR_TYPE: return "type"; } assert(0); return ""; @@ -202,6 +203,8 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { written += type_to_str_(t->ptr, buffer + written, bufsize - written); return written; } + case TYPE_TYPE: + return str_copy(buffer, bufsize, ""); } assert(0); @@ -1412,46 +1415,30 @@ static bool parse_stmt(Parser *p, Statement *s) { if (t->token->kind == TOKEN_EOF) tokr_err(t, "Expected statement."); s->where = t->token->where; - if (t->token->kind == TOKEN_KW) { - switch (t->token->kw) { - case KW_RETURN: { - s->kind = STMT_RET; + if (token_is_kw(t->token, KW_RETURN)) { + s->kind = STMT_RET; + t->token++; + s->ret.flags = 0; + if (token_is_kw(t->token, KW_SEMICOLON)) { + /* return with no expr */ t->token++; - s->ret.flags = 0; - if (token_is_kw(t->token, KW_SEMICOLON)) { - /* return with no expr */ - t->token++; - return true; - } - s->ret.flags |= RET_FLAG_EXPR; - Token *end = expr_find_end(p, 0, NULL); - if (!end) { - while (t->token->kind != TOKEN_EOF) t->token++; /* move to end of file */ - return false; - } - if (!token_is_kw(end, KW_SEMICOLON)) { - err_print(end->where, "Expected ';' at end of return statement."); - t->token = end->kind == TOKEN_EOF ? end : end + 1; - return false; - } - bool success = parse_expr(p, &s->ret.expr, end); - t->token = end + 1; - return success; + return true; } - case KW_NEWTYPE: - s->kind = STMT_TDECL; - t->token++; - if (t->token->kind != TOKEN_IDENT) { - tokr_err(t, "Expected identifier after \"newtype\"."); - tokr_skip_semicolon(t); - } - s->tdecl.name = t->token->ident; - t->token++; - if (!parse_type(p, &s->tdecl.type)) - return false; - return true; - default: break; + s->ret.flags |= RET_FLAG_EXPR; + Token *end = expr_find_end(p, 0, NULL); + if (!end) { + while (t->token->kind != TOKEN_EOF) t->token++; /* move to end of file */ + return false; } + if (!token_is_kw(end, KW_SEMICOLON)) { + err_print(end->where, "Expected ';' at end of return statement."); + t->token = end->kind == TOKEN_EOF ? end : end + 1; + return false; + } + bool success = parse_expr(p, &s->ret.expr, end); + t->token = end + 1; + return success; + } if (is_decl(t)) { s->kind = STMT_DECL; @@ -1672,6 +1659,9 @@ static void fprint_expr(FILE *out, Expression *e) { if (s->to) fprint_expr(out, s->to); fprintf(out, "]"); } break; + case EXPR_TYPE: + fprint_type(out, &e->typeval); + break; } if (parse_printing_after_types) { fprintf(out, ":"); @@ -1719,12 +1709,6 @@ static void fprint_stmt(FILE *out, Statement *s) { fprint_expr(out, &s->ret.expr); fprintf(out, ";\n"); break; - case STMT_TDECL: - fprintf(out, "newtype "); - fprint_ident(out, s->tdecl.name); - fprintf(out, " "); - fprint_type(out, &s->tdecl.type); - break; } } diff --git a/test.toc b/test.toc index 0304979..7aaeb3a 100644 --- a/test.toc +++ b/test.toc @@ -13,7 +13,7 @@ putf @= fn(x: float) { "); }; -newtype Foo int +Foo @= int; main @= fn() { // x : Foo; diff --git a/types.c b/types.c index d2bed5c..f2f4baf 100644 --- a/types.c +++ b/types.c @@ -40,6 +40,7 @@ static bool type_eq(Type *a, Type *b) { switch (a->kind) { case TYPE_VOID: return true; case TYPE_UNKNOWN: assert(0); return false; + case TYPE_TYPE: return true; case TYPE_BUILTIN: return a->builtin == b->builtin; case TYPE_FN: { @@ -98,10 +99,6 @@ static bool expr_arr_must_mut(Expression *e) { err_print(e->where, "Cannot modify a constant array."); return false; } - if (d->flags & DECL_FLAG_PARAM) { - err_print(e->where, "Parameters are immutable."); - return false; - } } return true; case EXPR_CAST: case EXPR_CALL: @@ -134,6 +131,7 @@ static bool expr_arr_must_mut(Expression *e) { case EXPR_LITERAL_INT: case EXPR_BINARY_OP: case EXPR_DIRECT: + case EXPR_TYPE: break; } assert(0); @@ -186,7 +184,8 @@ static bool expr_must_lval(Expression *e) { case EXPR_CALL: case EXPR_DIRECT: case EXPR_BLOCK: - case EXPR_SLICE: { + case EXPR_SLICE: + case EXPR_TYPE: { err_print(e->where, "Cannot use %s as l-value.", expr_kind_to_str(e->kind)); return false; } @@ -353,6 +352,7 @@ static bool type_resolve(Typer *tr, Type *t) { break; case TYPE_UNKNOWN: case TYPE_VOID: + case TYPE_TYPE: case TYPE_BUILTIN: break; } @@ -363,19 +363,14 @@ static bool type_resolve(Typer *tr, Type *t) { static bool type_can_be_truthy(Type *t) { switch (t->kind) { case TYPE_VOID: - return false; - case TYPE_UNKNOWN: - return true; - case TYPE_BUILTIN: - return true; - case TYPE_FN: - return true; case TYPE_TUPLE: - return false; case TYPE_ARR: + case TYPE_TYPE: return false; + case TYPE_FN: + case TYPE_UNKNOWN: + case TYPE_BUILTIN: case TYPE_PTR: - return true; case TYPE_SLICE: return true; } @@ -394,7 +389,9 @@ static Status type_cast_status(Type *from, Type *to) { return STATUS_NONE; switch (from->kind) { case TYPE_UNKNOWN: return STATUS_NONE; - case TYPE_VOID: return STATUS_ERR; + case TYPE_TYPE: + case TYPE_VOID: + return STATUS_ERR; case TYPE_BUILTIN: switch (from->builtin) { case BUILTIN_I8: @@ -412,6 +409,7 @@ static Status type_cast_status(Type *from, Type *to) { case TYPE_PTR: return STATUS_WARN; case TYPE_FN: + case TYPE_TYPE: case TYPE_TUPLE: case TYPE_SLICE: case TYPE_ARR: @@ -917,6 +915,10 @@ static bool types_expr(Typer *tr, Expression *e) { bool valid = false; if (o == BINARY_SET) { valid = type_eq(lhs_type, rhs_type); + if (lhs_type->kind == TYPE_TYPE) { + err_print(e->where, "Cannot set type."); + return false; + } } else { /* numerical binary ops */ if (lhs_type->kind == rhs_type->kind && lhs_type->kind == TYPE_BUILTIN @@ -1047,6 +1049,9 @@ static bool types_expr(Typer *tr, Expression *e) { } break; } + case EXPR_TYPE: + t->kind = TYPE_TYPE; + break; } e->type.flags |= TYPE_FLAG_RESOLVED; return true; diff --git a/types.h b/types.h index 537c845..4265310 100644 --- a/types.h +++ b/types.h @@ -84,6 +84,7 @@ typedef union Value { void *ptr; union Value *tuple; Slice slice; + struct Type *type; } Value; #define IDECL_FLAG_HAS_VAL 0x01 @@ -241,7 +242,8 @@ typedef enum { TYPE_TUPLE, TYPE_ARR, TYPE_PTR, - TYPE_SLICE + TYPE_SLICE, + TYPE_TYPE } TypeKind; typedef enum { @@ -313,7 +315,8 @@ typedef enum { EXPR_BLOCK, EXPR_TUPLE, EXPR_DIRECT, - EXPR_SLICE + EXPR_SLICE, + EXPR_TYPE } ExprKind; typedef enum { @@ -441,6 +444,7 @@ typedef struct Expression { IdentID block_ret_id; }; struct Expression *tuple; + Type typeval; }; } Expression; @@ -471,8 +475,7 @@ typedef struct Declaration { typedef enum { STMT_DECL, STMT_EXPR, - STMT_RET, - STMT_TDECL + STMT_RET } StatementKind; #define RET_FLAG_EXPR 0x01 @@ -481,18 +484,12 @@ typedef struct { Expression expr; } Return; -typedef struct { - Identifier name; - Type type; -} TypeDecl; - #define STMT_FLAG_VOIDED_EXPR 0x01 /* the "4;" in fn () { 4; } is a voided expression, but the "4" in fn () int { 4 } is not */ typedef struct Statement { Location where; StatementKind kind; U16 flags; union { - TypeDecl tdecl; Declaration decl; Expression expr; Return ret; -- cgit v1.2.3