summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c38
-rw-r--r--decls_cgen.c10
-rw-r--r--main.c1
-rw-r--r--test.toc48
4 files changed, 51 insertions, 46 deletions
diff --git a/cgen.c b/cgen.c
index 5e5054e..56ceb20 100644
--- a/cgen.c
+++ b/cgen.c
@@ -257,6 +257,12 @@ static inline void cgen_writeln(CGenerator *g, const char *fmt, ...) {
cgen_nl(g);
}
+static inline void cgen_char(CGenerator *g, char c) {
+ if (isprint(c) && c != '"')
+ cgen_write(g, "%c", c);
+ else
+ cgen_write(g, "\\x%02x", c);
+}
/* should this 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 || g->block->kind == BLOCK_NMS) && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1;
@@ -509,16 +515,25 @@ static void cgen_val_ptr_pre(CGenerator *g, void *v, Type *t) {
for (I64 i = 0; i < s->len; ++i) {
cgen_val_ptr_pre(g, (char *)s->data + (U64)i * compiler_sizeof(t->slice), t->slice);
}
+ cgen_write(g, "static ");
cgen_type_pre(g, t->slice);
cgen_write(g, "(d%p_[])", v); /* @TODO: improve this somehow? */
cgen_type_post(g, t->slice);
- cgen_write(g, " = {");
- for (I64 i = 0; i < s->len; ++i) {
- if (i) cgen_write(g, ", ");
- cgen_val_ptr(g, (char *)s->data + (U64)i * compiler_sizeof(t->slice), t->slice);
+ cgen_write(g, " = ");
+ if (type_is_builtin(t->slice, BUILTIN_CHAR)) {
+ char *p = s->data;
+ cgen_write(g, "\"");
+ for (I64 i = 0; i < s->len; ++i, ++p)
+ cgen_char(g, *p);
+ cgen_writeln(g, "\";");
+ } else {
+ cgen_write(g, "{");
+ for (I64 i = 0; i < s->len; ++i) {
+ if (i) cgen_write(g, ", ");
+ cgen_val_ptr(g, (char *)s->data + (U64)i * compiler_sizeof(t->slice), t->slice);
+ }
+ cgen_writeln(g, "};");
}
- cgen_write(g, "};");
- cgen_nl(g);
} break;
case TYPE_ARR:
for (size_t i = 0; i < t->arr.n; ++i) {
@@ -588,7 +603,11 @@ static void cgen_val_ptr(CGenerator *g, void *v, Type *t) {
case BUILTIN_U64: cgen_write(g, U64_FMT, *(U64 *)v); break;
case BUILTIN_F32: cgen_write(g, F32_FMT "f", *(F32 *)v); break;
case BUILTIN_F64: cgen_write(g, F64_FMT, *(F64 *)v); break;
- case BUILTIN_CHAR: cgen_write(g, "'\\x%02x'", *(char *)v); break;
+ case BUILTIN_CHAR:
+ cgen_write(g, "'");
+ cgen_char(g, *(char *)v);
+ cgen_write(g, "'");
+ break;
case BUILTIN_BOOL: cgen_write(g, "%s", *(bool *)v ? "true" : "false"); break;
case BUILTIN_TYPE:
case BUILTIN_NMS:
@@ -1222,10 +1241,7 @@ static void cgen_expr(CGenerator *g, Expression *e) {
char *p = e->strl.str;
cgen_write(g, "mkslice_(\"");
for (size_t i = 0; i < e->strl.len; ++i, ++p) {
- if (isprint(*p) && *p != '"')
- cgen_write(g, "%c", *p);
- else
- cgen_write(g, "\\x%02x", *p);
+ cgen_char(g, *p);
}
cgen_write(g, "\", %lu)", (unsigned long)e->strl.len);
} break;
diff --git a/decls_cgen.c b/decls_cgen.c
index 736df03..608b9fb 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -345,16 +345,20 @@ static void cgen_decls_decl(CGenerator *g, Declaration *d) {
for (int i = 0, n_idents = (int)arr_len(d->idents); i < n_idents; ++i) {
Identifier ident = d->idents[i];
Type *type = decl_type_at_index(d, i);
+ Value *val = NULL;
+ if (d->flags & DECL_HAS_EXPR)
+ assert(d->flags & DECL_FOUND_VAL);
+ if (d->flags & DECL_FOUND_VAL)
+ val = decl_val_at_index(d, i);
if (!type_is_compileonly(type)) {
+ if (val) cgen_val_pre(g, val, type);
if (!(d->flags & DECL_EXPORT))
cgen_write(g, "static ");
cgen_type_pre(g, type);
cgen_write(g, " ");
cgen_ident(g, ident);
cgen_type_post(g, type);
- if (d->flags & DECL_HAS_EXPR) {
- assert(d->flags & DECL_FOUND_VAL);
- Value *val = decl_val_at_index(d, i);
+ if (val) {
cgen_write(g, " = ");
cgen_val(g, val, type);
} else {
diff --git a/main.c b/main.c
index b397804..c02fa6a 100644
--- a/main.c
+++ b/main.c
@@ -8,7 +8,6 @@
/*
@TODO:
-make sure global slices work
allow `use ???;` if an error has already occurred
if something gets included into a namespace, and its typing fails, the namespace should still be of type namespace, not ???
make sure you can do a[i] where a is &[5]int or &[]char or something
diff --git a/test.toc b/test.toc
index 990e8a4..2433499 100644
--- a/test.toc
+++ b/test.toc
@@ -1,37 +1,23 @@
-//#include "std/io.toc";
-
#include "std/io.toc";
-c_add ::= fn(x:int, y:int) int {
- #C("x+y")
+#include "std/mem.toc";
+
+generate_numbers ::= fn() []int {
+ nums := news(int, 10);
+ for n, i := &nums {
+ *n = i*i;
+ }
+ nums
}
+hw := "hello, world!";
+nums := generate_numbers();
+
main ::= fn() {
- {
- xs : [5]Point;
- for use x, i := &xs {
- z = c_add(i*i, i*i*i) as f32;
- }
- for use x := xs {
- puti(z as int);
- }
- Point ::= struct {
- x: int;
- y: int;
- z: f32;
- }
- }
- {
- xs : [5]Point;
- for use x, i := &xs {
- z = c_add(i*i, i*i*i) as f32;
- }
- for use x := xs {
- puti(z as int);
- }
- Point ::= struct {
- x: int;
- y: int;
- z: f32;
- }
+ hw[0] = 'j';
+ nums[5] = 183;
+ puts(hw);
+ for x := nums {
+ puti(x);
}
+
}