diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-22 14:33:30 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-22 14:33:30 -0400 |
commit | 23f5ed268667dbcdefaa903c3395ec4c580661b9 (patch) | |
tree | 9bc4c9511e51bc3cb1dfdc414e6a12d3b58c3749 | |
parent | be4bd7b281c821b7a57bb2b33761c85b161d97e2 (diff) |
fixed constants
-rw-r--r-- | cgen.c | 79 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | out.c | 11 | ||||
-rw-r--r-- | test.toc | 11 | ||||
-rw-r--r-- | types.h | 3 |
5 files changed, 97 insertions, 10 deletions
@@ -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; @@ -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 @@ -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()))); } @@ -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()); + }; @@ -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; |