summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c79
-rw-r--r--main.c3
-rw-r--r--out.c11
-rw-r--r--test.toc11
-rw-r--r--types.h3
5 files changed, 97 insertions, 10 deletions
diff --git a/cgen.c b/cgen.c
index 59e2598..2180e6a 100644
--- a/cgen.c
+++ b/cgen.c
@@ -80,6 +80,10 @@ static inline void cgen_writeln(CGenerator *g, const char *fmt, ...) {
cgen_nl(g);
}
+static void cgen_ident_id(CGenerator *g, IdentID id) {
+ cgen_write(g, "a%lu_", (unsigned long)id);
+}
+
/* should declaration be a direct function declaration C (as opposed to using a function pointer or not being a function) */
static bool cgen_fn_is_direct(CGenerator *g, Declaration *d) {
return g->block == NULL && (d->flags & DECL_FLAG_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1;
@@ -109,6 +113,7 @@ static void cgen_ident(CGenerator *g, Identifier i) {
} else {
cgen_indent(g);
IdentDecl *idecl = ident_decl(i);
+ assert(idecl);
if (idecl->flags & IDECL_FLAG_CGEN_PTR)
cgen_write(g, "(*");
fprint_ident(cgen_writing_to(g), i);
@@ -121,9 +126,6 @@ static char *cgen_ident_to_str(Identifier i) {
return ident_to_str(i);
}
-static void cgen_ident_id(CGenerator *g, IdentID id) {
- cgen_write(g, "a%lu_", (unsigned long)id);
-}
/* buffer should be at least 32 bytes */
static inline void cgen_ident_id_to_str(char *buffer, IdentID id) {
@@ -1029,13 +1031,78 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) {
return true;
}
+static bool cgen_val(CGenerator *g, Value *v, Type *t, Location where) {
+ switch (t->kind) {
+ case TYPE_TUPLE:
+ case TYPE_VOID:
+ assert(0);
+ return false;
+ case TYPE_UNKNOWN:
+ err_print(where, "Cannot determine type.");
+ return false;
+ case TYPE_ARR:
+ err_print(where, "Not implemented yet."); /* TODO */
+ return false;
+ case TYPE_SLICE:
+ err_print(where, "Not implemented yet."); /* TODO (similar to above) */
+ return false;
+ case TYPE_FN:
+ cgen_ident_id(g, v->fn->c.id);
+ break;
+ case TYPE_PTR:
+ /* TODO: maybe just gen the whole expression? */
+ err_print(where, "Cannot bring compile time pointer to runtime.");
+ return false;
+ case TYPE_BUILTIN:
+ switch (t->builtin) {
+ case BUILTIN_I8: cgen_write(g, "%"PRId8, v->i8); break;
+ case BUILTIN_U8: cgen_write(g, "%"PRIu8, v->u8); break;
+ case BUILTIN_I16: cgen_write(g, "%"PRId16, v->i16); break;
+ case BUILTIN_U16: cgen_write(g, "%"PRIu16, v->u16); break;
+ case BUILTIN_I32: cgen_write(g, "%"PRId32, v->i32); break;
+ case BUILTIN_U32: cgen_write(g, "%"PRIu32, v->u32); break;
+ case BUILTIN_I64: cgen_write(g, "%"PRId64, v->i64); break;
+ case BUILTIN_U64: cgen_write(g, "%"PRIu64, v->u64); break;
+ case BUILTIN_F32: cgen_write(g, F32_FMT, v->f32); break;
+ case BUILTIN_F64: cgen_write(g, F64_FMT, v->f64); break;
+ case BUILTIN_CHAR: cgen_write(g, "\\x%02x", v->charv); break;
+ case BUILTIN_BOOL: cgen_write(g, "%s", v->boolv ? true : false); break;
+ }
+ break;
+ }
+ return true;
+}
+
static bool cgen_decl(CGenerator *g, Declaration *d) {
if (cgen_fn_is_direct(g, d)) {
cgen_fn(g, &d->expr.fn, d->where);
- } else if (d->flags & DECL_FLAG_CONST) {
- /* TODO? */
+ } else if ((d->flags & DECL_FLAG_CONST) || g->block == NULL) {
+ if (d->type.kind == TYPE_TUPLE) {
+ long idx = 0;
+ arr_foreach(d->idents, Identifier, i) {
+ if (!cgen_type_pre(g, &d->type.tuple[idx], d->where)) return false;
+ cgen_write(g, " ");
+ cgen_ident(g, *i);
+ if (!cgen_type_post(g, &d->type.tuple[idx], d->where)) return false;
+ cgen_write(g, " = ");
+ if (!cgen_val(g, &d->val.tuple[idx], &d->type.tuple[idx], d->where))
+ return false;
+ idx++;
+ }
+ cgen_write(g, ";");
+ cgen_nl(g);
+ } else {
+ if (!cgen_type_pre(g, &d->type, d->where)) return false;
+ cgen_write(g, " ");
+ cgen_ident(g, d->idents[0]);
+ if (!cgen_type_post(g, &d->type, d->where)) return false;
+ cgen_write(g, " = ");
+ if (!cgen_val(g, &d->val, &d->type, d->where))
+ return false;
+ cgen_write(g, ";");
+ cgen_nl(g);
+ }
} else {
- /* TODO: Globals just cgen val */
for (size_t idx = 0; idx < arr_len(d->idents); idx++) {
Identifier *i = &d->idents[idx];
Type *t = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx] : &d->type;
diff --git a/main.c b/main.c
index 2f335e1..11fdeb4 100644
--- a/main.c
+++ b/main.c
@@ -1,8 +1,7 @@
/*
TODO:
-fix constants
-bf interpreter (& other tests)
error on failed calloc in output
+bf interpreter (& other tests)
unicode variable names
make sure initializers for global variables are compile-time constants
structs
diff --git a/out.c b/out.c
index e733d42..a1950de 100644
--- a/out.c
+++ b/out.c
@@ -19,6 +19,7 @@ static slice_ mkslice_(void *data, u64 n) { slice_ ret; ret.data = data; ret.n =
/* declarations */
void puti(i64 x);
+void putf(f32 x);
i64 foo(void);
void main__(void);
/* code */
@@ -35,6 +36,12 @@ void puti(i64 x) {
}
+void putf(f32 x) {
+
+ printf("%f\n", (double)x);
+}
+
+
i64 foo(void) {
i64 N; {
@@ -56,6 +63,10 @@ i64 foo(void) {
void main__(void) {
+ i64 N = 5;
+ (puti(N));
+ f32 M = 1.4320000410079956;
+ (putf(M));
i64( x[11]) = {0};
(puti((foo())));
}
diff --git a/test.toc b/test.toc
index 3e017db..40ddbe5 100644
--- a/test.toc
+++ b/test.toc
@@ -5,6 +5,10 @@ puti @= fn(x: int) {
#C("printf(\"%ld\\n\", (long)x)");
};
+putf @= fn(x: float) {
+ #C("printf(\"%f\\n\", (double)x)");
+};
+
foo @= fn() int {
N := 10;
numbers := new(int, N);
@@ -17,8 +21,11 @@ foo @= fn() int {
};
main @= fn() {
- // N @= 5;
- // puti(N);
+ N @= 5;
+ puti(N);
+ M @= 1.432;
+ putf(M);
x : [foo()]int;
puti(foo());
+
};
diff --git a/types.h b/types.h
index e3a251e..c213ff7 100644
--- a/types.h
+++ b/types.h
@@ -25,6 +25,9 @@ typedef int64_t I64;
typedef float F32;
typedef double F64;
+#define F32_FMT "%.16f"
+#define F64_FMT "%.16f"
+
typedef U32 IdentID; /* identifier ID for cgen (anonymous variables) */
typedef uint32_t LineNo;