diff options
-rw-r--r-- | cgen.c | 80 | ||||
-rw-r--r-- | decls_cgen.c | 31 | ||||
-rw-r--r-- | eval.c | 10 | ||||
-rw-r--r-- | out.c | 2 | ||||
-rw-r--r-- | parse.c | 19 | ||||
-rw-r--r-- | types.c | 1 | ||||
-rw-r--r-- | types.h | 8 |
7 files changed, 124 insertions, 27 deletions
@@ -1,6 +1,8 @@ typedef struct { FILE *outc; - long ident_counter; + unsigned long ident_counter; + ParsedFile *file; + Block *block; } CGenerator; static void cgen_create(CGenerator *g, FILE *out) { @@ -8,6 +10,29 @@ static void cgen_create(CGenerator *g, FILE *out) { g->ident_counter = 0; } +static void cgen_block_enter(CGenerator *g, Block *b) { + g->block = b; + Statement *stmts; + if (b == NULL) { + stmts = g->file->stmts; + } else { + stmts = b->stmts; + } + block_enter(b, stmts); +} + +static void cgen_block_exit(CGenerator *g, Block *into) { + Block *b = g->block; + Statement *stmts; + if (b == NULL) { + stmts = g->file->stmts; + } else { + stmts = b->stmts; + } + block_exit(b, stmts); + g->block = into; +} + static inline FILE *cgen_writing_to(CGenerator *g) { return g->outc; /* for now */ } @@ -19,9 +44,58 @@ static void cgen_write(CGenerator *g, const char *fmt, ...) { va_end(args); } -static void cgen_decls_file(CGenerator *g, ParsedFile *f); -static void cgen_file(CGenerator *g, ParsedFile *f) { +static bool cgen_type_post(CGenerator *g, Type *t, Location where); +static bool cgen_type_pre(CGenerator *g, Type *t, Location where) { + switch (t->kind) { + case TYPE_BUILTIN: + switch (t->builtin) { + case BUILTIN_I8: cgen_write(g, "i8"); break; + case BUILTIN_I16: cgen_write(g, "i16"); break; + case BUILTIN_I32: cgen_write(g, "i32"); break; + case BUILTIN_I64: cgen_write(g, "i64"); break; + case BUILTIN_U8: cgen_write(g, "u8"); break; + case BUILTIN_U16: cgen_write(g, "u16"); break; + case BUILTIN_U32: cgen_write(g, "u32"); break; + case BUILTIN_U64: cgen_write(g, "u64"); break; + case BUILTIN_CHAR: cgen_write(g, "char"); break; + case BUILTIN_BOOL: cgen_write(g, "bool"); break; + case BUILTIN_F32: cgen_write(g, "f32"); break; + case BUILTIN_F64: cgen_write(g, "f64"); break; + } + case TYPE_VOID: cgen_write(g, "void"); break; + case TYPE_UNKNOWN: + err_print(t->where, "Can't determine type."); + break; + } +} + +static bool cgen_type_post(CGenerator *g, Type *t, Location where) { +} + +static bool cgen_fn_header(CGenerator *g, FnExpr *f, Identifier name, long id) { +} + +static bool cgen_decls_file(CGenerator *g, ParsedFile *f); + +static bool cgen_file(CGenerator *g, ParsedFile *f) { + g->file = f; + cgen_write(g, "#include <stdint.h>\n" + "typedef int8_t i8;\n" + "typedef int16_t i16;\n" + "typedef int32_t i32;\n" + "typedef int64_t i64;\n" + "typedef uint8_t u8;\n" + "typedef uint16_t u16;\n" + "typedef uint32_t u32;\n" + "typedef uint64_t u64;\n" + "typedef float f32;\n" + "typedef double f64;\n" + "typedef unsigned char bool;\n" + "#define false ((bool)0)\n" + "#define true ((bool)1)\n\n\n"); + cgen_block_enter(g, NULL); cgen_decls_file(g, f); cgen_write(g, "/* code */\n"); + cgen_block_exit(g, NULL); } diff --git a/decls_cgen.c b/decls_cgen.c index bce26c7..881240c 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -1,17 +1,42 @@ -static void cgen_decls_stmt(CGenerator *g, Statement *s) { +static bool cgen_decls_expr(CGenerator *g, Expression *e) { +} + +static bool cgen_decls_block(CGenerator *g, Block *b) { +} + +static bool cgen_decls_decl(CGenerator *g, Declaration *d) { + if ((d->flags & DECL_FLAG_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1) { + d->expr.fn.name = d->idents[0]; + if (!cgen_fn_header(g, &d->expr.fn)) + return false; + cgen_write(g, ";"); + if (!cgen_decls_block(g, &d->expr.fn.body)) + return false; + } else if (d->flags & DECL_FLAG_HAS_EXPR) { + if (!cgen_decls_expr(g, &d->expr)) + return false; + } +} + +static bool cgen_decls_stmt(CGenerator *g, Statement *s) { switch (s->kind) { case STMT_DECL: + if (!cgen_decls_decl(g, &s->decl)) + return false; break; case STMT_EXPR: break; case STMT_RET: break; } + return true; } -static void cgen_decls_file(CGenerator *g, ParsedFile *f) { +static bool cgen_decls_file(CGenerator *g, ParsedFile *f) { cgen_write(g, "/* declarations */\n"); arr_foreach(f->stmts, Statement, s) { - cgen_decls_stmt(g, s); + if (!cgen_decls_stmt(g, s)) + return false; } + return true; } @@ -30,7 +30,6 @@ static size_t compiler_sizeof_builtin(BuiltinType b) { case BUILTIN_F64: return sizeof(F64); case BUILTIN_CHAR: return sizeof(char); /* = 1 */ case BUILTIN_BOOL: return sizeof(bool); - case BUILTIN_TYPE_COUNT: break; } assert(0); return 0; @@ -71,7 +70,6 @@ static bool builtin_truthiness(Value *v, BuiltinType b) { case BUILTIN_F64: return v->f64 != 0; case BUILTIN_BOOL: return v->boolv; case BUILTIN_CHAR: return v->charv != 0; - case BUILTIN_TYPE_COUNT: break; } assert(0); return false; } @@ -171,7 +169,6 @@ static void u64_to_val(Value *v, BuiltinType v_type, U64 x) { builtin_casts_to_num(low); \ case BUILTIN_CHAR: vout->charv = (char)vin->low; break; \ case BUILTIN_BOOL: vout->boolv = vin->low != 0; break; \ - case BUILTIN_TYPE_COUNT: assert(0); break; \ } break #define builtin_float_casts(low, up) \ @@ -180,7 +177,7 @@ static void u64_to_val(Value *v, BuiltinType v_type, U64 x) { builtin_casts_to_num(low); \ case BUILTIN_BOOL: vout->boolv = vin->low != 0.0f; break; \ case BUILTIN_CHAR: \ - case BUILTIN_TYPE_COUNT: assert(0); break; \ + assert(0); break; \ } break static void val_builtin_cast(Value *vin, BuiltinType from, Value *vout, BuiltinType to) { @@ -208,11 +205,9 @@ static void val_builtin_cast(Value *vin, BuiltinType from, Value *vout, BuiltinT case BUILTIN_F32: case BUILTIN_F64: case BUILTIN_BOOL: - case BUILTIN_TYPE_COUNT: assert(0); break; } break; - case BUILTIN_TYPE_COUNT: assert(0); break; } } @@ -280,7 +275,6 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { case BUILTIN_CHAR: case BUILTIN_F32: case BUILTIN_F64: - case BUILTIN_TYPE_COUNT: assert(0); break; } break; @@ -341,7 +335,6 @@ static void eval_deref(Value *v, void *ptr, Type *type) { case BUILTIN_F64: v->f64 = *(F64 *)ptr; break; case BUILTIN_CHAR: v->charv = *(char *)ptr; break; case BUILTIN_BOOL: v->boolv = *(bool *)ptr; break; - case BUILTIN_TYPE_COUNT: assert(0); break; } break; case TYPE_VOID: @@ -371,7 +364,6 @@ static void eval_deref_set(void *set, Value *to, Type *type) { case BUILTIN_F64: *(F64 *)set = to->f64; break; case BUILTIN_CHAR: *(char *)set = to->charv; break; case BUILTIN_BOOL: *(bool *)set = to->boolv; break; - case BUILTIN_TYPE_COUNT: assert(0); break; } break; case TYPE_VOID: @@ -1,2 +1,2 @@ /* declarations */ -/* code */ +;/* code */ @@ -74,8 +74,8 @@ static bool type_builtin_is_numerical(BuiltinType b) { } -/* returns BUILTIN_TYPE_COUNT on failure */ -static BuiltinType kw_to_builtin_type(Keyword kw) { +/* returns -1 on failure */ +static int kw_to_builtin_type(Keyword kw) { switch (kw) { case KW_I8: return BUILTIN_I8; case KW_I16: return BUILTIN_I16; @@ -91,8 +91,9 @@ static BuiltinType kw_to_builtin_type(Keyword kw) { case KW_F64: return BUILTIN_F64; case KW_BOOL: return BUILTIN_BOOL; case KW_CHAR: return BUILTIN_CHAR; - default: return BUILTIN_TYPE_COUNT; + default: return -1; } + return -1; } static Keyword builtin_type_to_kw(BuiltinType t) { @@ -109,7 +110,6 @@ static Keyword builtin_type_to_kw(BuiltinType t) { case BUILTIN_F64: return KW_F64; case BUILTIN_BOOL: return KW_BOOL; case BUILTIN_CHAR: return KW_CHAR; - case BUILTIN_TYPE_COUNT: break; } assert(0); return KW_COUNT; @@ -291,10 +291,13 @@ static bool parse_type(Parser *p, Type *type) { switch (t->token->kind) { case TOKEN_KW: type->kind = TYPE_BUILTIN; - type->builtin = kw_to_builtin_type(t->token->kw); - if (type->builtin != BUILTIN_TYPE_COUNT) { - t->token++; - break; + { + int b = kw_to_builtin_type(t->token->kw); + if (b != -1) { + type->builtin = b; + t->token++; + break; + } } /* Not a builtin */ switch (t->token->kw) { @@ -367,7 +367,6 @@ static Status type_cast_status(Type *from, Type *to) { return STATUS_ERR; case BUILTIN_BOOL: return type_can_be_truthy(to); - case BUILTIN_TYPE_COUNT: assert(0); break; } break; case TYPE_TUPLE: return STATUS_ERR; @@ -242,8 +242,7 @@ typedef enum { BUILTIN_F32, BUILTIN_F64, BUILTIN_CHAR, - BUILTIN_BOOL, - BUILTIN_TYPE_COUNT + BUILTIN_BOOL } BuiltinType; #define TYPE_FLAG_FLEXIBLE 0x01 @@ -356,6 +355,11 @@ typedef struct FnExpr { struct Declaration *ret_decls; /* array of decls, if this has named return values. otherwise, NULL */ Type ret_type; Block body; + struct { + /* if name = NULL, this is an anonymous function, and id will be the ID of the fn. */ + Identifier name; + unsigned long id; + } c; } FnExpr; /* an expression such as fn(x: int) int { 2 * x } */ typedef struct { |