summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c80
-rw-r--r--decls_cgen.c31
-rw-r--r--eval.c10
-rw-r--r--out.c2
-rw-r--r--parse.c19
-rw-r--r--types.c1
-rw-r--r--types.h8
7 files changed, 124 insertions, 27 deletions
diff --git a/cgen.c b/cgen.c
index 7f1d323..21baef7 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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;
}
diff --git a/eval.c b/eval.c
index 2613c28..71f8888 100644
--- a/eval.c
+++ b/eval.c
@@ -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:
diff --git a/out.c b/out.c
index b4c1d29..69820de 100644
--- a/out.c
+++ b/out.c
@@ -1,2 +1,2 @@
/* declarations */
-/* code */
+;/* code */
diff --git a/parse.c b/parse.c
index a4a5b2b..f0fe705 100644
--- a/parse.c
+++ b/parse.c
@@ -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) {
diff --git a/types.c b/types.c
index e556723..24f31bd 100644
--- a/types.c
+++ b/types.c
@@ -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;
diff --git a/types.h b/types.h
index 95ad902..6c65a0a 100644
--- a/types.h
+++ b/types.h
@@ -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 {