diff options
-rw-r--r-- | cgen.c | 14 | ||||
-rw-r--r-- | eval.c | 40 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | out.c | 11 | ||||
-rw-r--r-- | parse.c | 39 | ||||
-rw-r--r-- | test.toc | 3 | ||||
-rw-r--r-- | types.c | 57 | ||||
-rw-r--r-- | types.h | 14 |
8 files changed, 133 insertions, 50 deletions
@@ -91,6 +91,7 @@ static bool cgen_uses_ptr(Type *t) { case TYPE_BUILTIN: case TYPE_PTR: case TYPE_FN: + case TYPE_SLICE: case TYPE_VOID: case TYPE_UNKNOWN: return false; @@ -141,7 +142,7 @@ static bool cgen_type_pre(CGenerator *g, Type *t, Location where) { case BUILTIN_F64: cgen_write(g, "f64"); break; } break; case TYPE_PTR: - if (!cgen_type_pre(g, t->ptr.of, where)) + if (!cgen_type_pre(g, t->ptr, where)) return false; cgen_write(g, "(*"); break; @@ -159,6 +160,9 @@ static bool cgen_type_pre(CGenerator *g, Type *t, Location where) { } cgen_write(g, " (*"); break; + case TYPE_SLICE: + cgen_write(g, "slice_"); + break; case TYPE_VOID: cgen_write(g, "void"); break; case TYPE_UNKNOWN: err_print(t->where, "Can't determine type."); @@ -175,7 +179,7 @@ static bool cgen_type_post(CGenerator *g, Type *t, Location where) { switch (t->kind) { case TYPE_PTR: cgen_write(g, ")"); - if (!cgen_type_post(g, t->ptr.of, where)) + if (!cgen_type_post(g, t->ptr, where)) return false; break; case TYPE_ARR: @@ -221,6 +225,7 @@ static bool cgen_type_post(CGenerator *g, Type *t, Location where) { case TYPE_VOID: case TYPE_UNKNOWN: case TYPE_TUPLE: + case TYPE_SLICE: break; } return true; @@ -312,6 +317,7 @@ static bool cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E case TYPE_BUILTIN: case TYPE_FN: case TYPE_PTR: + case TYPE_SLICE: case TYPE_UNKNOWN: if (set_expr) { if (!cgen_expr(g, set_expr)) return false; @@ -771,6 +777,9 @@ static void cgen_zero_value(CGenerator *g, Type *t) { case TYPE_FN: cgen_write(g, "NULL"); break; + case TYPE_SLICE: + cgen_write(g, "{NULL, 0}"); + break; case TYPE_ARR: cgen_write(g, "{"); cgen_zero_value(g, t->arr.of); @@ -941,6 +950,7 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) { "typedef float f32;\n" "typedef double f64;\n" "typedef unsigned char bool;\n" + "typedef struct { void *data; u64 n; } slice_;\n" "#define false ((bool)0)\n" "#define true ((bool)1)\n\n\n"); cgen_block_enter(g, NULL); @@ -41,13 +41,15 @@ static size_t compiler_sizeof(Type *t) { case TYPE_BUILTIN: return compiler_sizeof_builtin(t->builtin); case TYPE_FN: - return sizeof(FnExpr *); + return sizeof t->fn; case TYPE_PTR: - return sizeof(void *); + return sizeof t->ptr; case TYPE_ARR: - return t->arr.n * compiler_sizeof(t->arr.of); + return sizeof t->arr; case TYPE_TUPLE: - return arr_len(t->tuple) * sizeof(Value); + return sizeof t->tuple; + case TYPE_SLICE: + return sizeof t->slice; case TYPE_VOID: case TYPE_UNKNOWN: return 0; @@ -82,6 +84,7 @@ static bool val_truthiness(Value *v, Type *t) { case TYPE_PTR: return v->ptr != NULL; 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; } assert(0); @@ -239,6 +242,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { default: assert(0); break; } break; + case TYPE_SLICE: case TYPE_VOID: case TYPE_UNKNOWN: case TYPE_TUPLE: @@ -257,6 +261,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: @@ -287,6 +292,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: @@ -303,6 +309,26 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { case TYPE_ARR: vout->arr = vin->arr; break; + case TYPE_SLICE: + case TYPE_FN: + case TYPE_UNKNOWN: + case TYPE_TUPLE: + case TYPE_VOID: + case TYPE_BUILTIN: + assert(0); break; + } + break; + case TYPE_SLICE: + switch (to->kind) { + case TYPE_PTR: + vout->ptr = vin->slice.data; + break; + case TYPE_ARR: + vout->arr = vin->slice.data; + break; + case TYPE_SLICE: + vout->slice = vin->slice; + break; case TYPE_FN: case TYPE_UNKNOWN: case TYPE_TUPLE: @@ -337,6 +363,9 @@ static void eval_deref(Value *v, void *ptr, Type *type) { case BUILTIN_BOOL: v->boolv = *(bool *)ptr; break; } break; + case TYPE_SLICE: + v->slice = *(Slice *)ptr; + break; case TYPE_VOID: case TYPE_UNKNOWN: assert(0); @@ -366,6 +395,9 @@ static void eval_deref_set(void *set, Value *to, Type *type) { case BUILTIN_BOOL: *(bool *)set = to->boolv; break; } break; + case TYPE_SLICE: + *(Slice *)set = to->slice; + break; case TYPE_VOID: case TYPE_UNKNOWN: assert(0); @@ -1,7 +1,8 @@ /* TODO: -slices -new run-time type resolution +fix casting for slice => ptr/arr +parameters can be passed as pointers +new returns a *slice* unicode variable names make sure initializers for global variables are compile-time constants structs @@ -11,6 +11,7 @@ typedef uint64_t u64; typedef float f32; typedef double f64; typedef unsigned char bool; +typedef struct { void *data; u64 n; } slice_; #define false ((bool)0) #define true ((bool)1) @@ -49,14 +50,8 @@ void main__(void) { a2_ = y; }(puti(a2_)); }; - i64( asdf[78636112]); { - i64( expr__[78636112]); { - size_t i;i64(*arr__in) = expr__; i64(*arr__out) = ((i64([78636112]))calloc(1, sizeof(i64([100]))); - for (i = 0; i < 78636112; i++) arr__out[i] = arr__in[i]; - }{ - size_t i;i64(*arr__in) = asdf; i64(*arr__out) = expr__; - for (i = 0; i < 78636112; i++) arr__out[i] = arr__in[i]; - }} + slice_ foo = {NULL, 0}; + slice_ bar = {NULL, 0}; }} @@ -180,6 +180,12 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { written += type_to_str_(t->arr.of, buffer + written, bufsize - written); return written; } break; + case TYPE_SLICE: { + size_t written = str_copy(buffer, bufsize, "["); + written += str_copy(buffer + written, bufsize - written, "]"); + written += type_to_str_(t->slice, buffer + written, bufsize - written); + return written; + } break; case TYPE_TUPLE: { size_t written = str_copy(buffer, bufsize, "("); arr_foreach(t->tuple, Type, child) { @@ -192,7 +198,7 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { } case TYPE_PTR: { size_t written = str_copy(buffer, bufsize, "&"); - written += type_to_str_(t->ptr.of, buffer + written, bufsize - written); + written += type_to_str_(t->ptr, buffer + written, bufsize - written); return written; } } @@ -371,10 +377,22 @@ static bool parse_type(Parser *p, Type *type) { break; } case KW_LSQUARE: { - /* array type */ - Token *start = t->token; + /* array/slice */ + type->where = t->token->where; type->kind = TYPE_ARR; t->token++; /* move past [ */ + if (token_is_kw(t->token, KW_RSQUARE)) { + /* slice */ + type->kind = TYPE_SLICE; + type->slice = parser_malloc(p, sizeof *type->slice); + t->token++; /* move past ] */ + if (!parse_type(p, type->slice)) return false; + if (type->slice->kind == TYPE_TUPLE) { + err_print(type->where, "You cannot have a slice of tuples."); + return false; + } + break; + } Token *end = expr_find_end(p, 0, NULL); type->arr.n_expr = parser_new_expr(p); if (!parse_expr(p, type->arr.n_expr, end)) return false; @@ -382,13 +400,10 @@ static bool parse_type(Parser *p, Type *type) { type->arr.of = parser_malloc(p, sizeof *type->arr.of); if (!parse_type(p, type->arr.of)) return false; if (type->arr.of->kind == TYPE_TUPLE) { - err_print(type->arr.of->where, "You cannot have an array of tuples."); + err_print(type->where, "You cannot have an array of tuples."); return false; } - type->flags = 0; - type->where = start->where; - break; - } + } break; case KW_LPAREN: /* tuple! */ type->kind = TYPE_TUPLE; @@ -417,11 +432,11 @@ static bool parse_type(Parser *p, Type *type) { case KW_AMPERSAND: /* pointer */ type->kind = TYPE_PTR; - type->ptr.of = parser_malloc(p, sizeof *type->ptr.of); + type->ptr = parser_malloc(p, sizeof *type->ptr); t->token++; /* move past & */ - if (!parse_type(p, type->ptr.of)) return false; - if (type->ptr.of->kind == TYPE_TUPLE) { - err_print(type->ptr.of->where, "You cannot have a pointer to a tuple."); + if (!parse_type(p, type->ptr)) return false; + if (type->ptr->kind == TYPE_TUPLE) { + err_print(type->ptr->where, "You cannot have a pointer to a tuple."); return false; } break; @@ -13,4 +13,7 @@ main @= fn() { while y < 10 { puti({y = y + 1; y}); } + foo : []int; + bar : []float; + };
\ No newline at end of file @@ -62,8 +62,10 @@ static bool type_eq(Type *a, Type *b) { case TYPE_ARR: if (a->arr.n != b->arr.n) return false; return type_eq(a->arr.of, b->arr.of); + case TYPE_SLICE: + return type_eq(a->slice, b->slice); case TYPE_PTR: - return type_eq(a->ptr.of, b->ptr.of); + return type_eq(a->ptr, b->ptr); } assert(0); return false; @@ -340,7 +342,11 @@ static bool type_resolve(Evaluator *ev, Type *t) { } break; case TYPE_PTR: - if (!type_resolve(ev, t->ptr.of)) + if (!type_resolve(ev, t->ptr)) + return false; + break; + case TYPE_SLICE: + if (!type_resolve(ev, t->slice)) return false; break; case TYPE_UNKNOWN: @@ -360,7 +366,10 @@ static bool types_type(Typer *tr, Type *t) { if (!types_type(tr, t->arr.of)) return false; break; case TYPE_PTR: - if (!types_type(tr, t->ptr.of)) return false; + if (!types_type(tr, t->ptr)) return false; + break; + case TYPE_SLICE: + if (!types_type(tr, t->slice)) return false; break; case TYPE_TUPLE: { arr_foreach(t->tuple, Type, x) @@ -396,6 +405,8 @@ static bool type_can_be_truthy(Type *t) { return false; case TYPE_PTR: return true; + case TYPE_SLICE: + return true; } assert(0); return false; @@ -424,13 +435,17 @@ static Status type_cast_status(Type *from, Type *to) { case BUILTIN_I64: case BUILTIN_U64: switch (to->kind) { - case TYPE_UNKNOWN: return STATUS_NONE; - case TYPE_VOID: return STATUS_ERR; - case TYPE_BUILTIN: return STATUS_NONE; - case TYPE_ARR: return STATUS_ERR; - case TYPE_PTR: return STATUS_WARN; - case TYPE_FN: return STATUS_ERR; - case TYPE_TUPLE: return STATUS_ERR; + case TYPE_BUILTIN: + case TYPE_UNKNOWN: + return STATUS_NONE; + case TYPE_PTR: + return STATUS_WARN; + case TYPE_FN: + case TYPE_TUPLE: + case TYPE_SLICE: + case TYPE_ARR: + case TYPE_VOID: + return STATUS_ERR; } break; case BUILTIN_F32: @@ -456,17 +471,23 @@ static Status type_cast_status(Type *from, Type *to) { return STATUS_WARN; if (to->kind == TYPE_PTR) return STATUS_NONE; - if (to->kind == TYPE_ARR && type_eq(to->arr.of, from->ptr.of)) + if (to->kind == TYPE_ARR && type_eq(from->ptr, to->arr.of)) return STATUS_NONE; if (to->kind == TYPE_FN) return STATUS_WARN; return STATUS_ERR; case TYPE_ARR: - if (to->kind == TYPE_PTR && type_eq(to->ptr.of, from->arr.of)) + if (to->kind == TYPE_PTR && type_eq(from->arr.of, to->ptr)) return STATUS_NONE; - if (to->kind == TYPE_ARR && !type_eq(to, from)) + if (to->kind == TYPE_ARR && !type_eq(from, to)) return STATUS_WARN; return STATUS_ERR; + case TYPE_SLICE: + if (to->kind == TYPE_PTR && type_eq(from->slice, to->ptr)) + return STATUS_NONE; + if (to->kind == TYPE_ARR && type_eq(from->slice, to->arr.of)) + return STATUS_NONE; + return STATUS_ERR; } assert(0); return STATUS_ERR; @@ -606,8 +627,8 @@ static bool types_expr(Typer *tr, Expression *e) { if (e->new.type.kind == TYPE_ARR) { *t = e->new.type; } else { - t->ptr.of = typer_malloc(tr, sizeof *t->ptr.of); - t->ptr.of = &e->new.type; + t->ptr = typer_malloc(tr, sizeof *t->ptr); + t->ptr = &e->new.type; } break; case EXPR_IF: { @@ -865,8 +886,8 @@ static bool types_expr(Typer *tr, Expression *e) { return false; } t->kind = TYPE_PTR; - t->ptr.of = typer_malloc(tr, sizeof *t->ptr.of); /* OPTIM */ - *t->ptr.of = *of_type; + t->ptr = typer_malloc(tr, sizeof *t->ptr); + *t->ptr = *of_type; break; case UNARY_DEREF: if (of_type->kind != TYPE_PTR) { @@ -876,7 +897,7 @@ static bool types_expr(Typer *tr, Expression *e) { return false; } - *t = *of_type->ptr.of; + *t = *of_type->ptr; break; case UNARY_DEL: if (of_type->kind != TYPE_PTR) { @@ -58,6 +58,11 @@ typedef struct { ArrBlock *blocks; } BlockArr; +typedef struct { + U64 n; + void *data; +} Slice; + typedef union Value { U8 u8; U16 u16; @@ -75,6 +80,7 @@ typedef union Value { void *arr; void *ptr; union Value *tuple; + Slice slice; } Value; #define IDECL_FLAG_HAS_VAL 0x01 @@ -229,7 +235,8 @@ typedef enum { TYPE_FN, TYPE_TUPLE, TYPE_ARR, - TYPE_PTR + TYPE_PTR, + TYPE_SLICE } TypeKind; typedef enum { @@ -267,9 +274,8 @@ typedef struct Type { struct Expression *n_expr; }; } arr; - struct { - struct Type *of; - } ptr; + struct Type *ptr; + struct Type *slice; }; } Type; |