summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arr.c7
-rw-r--r--eval.c17
-rw-r--r--package.c101
-rw-r--r--parse.c19
-rw-r--r--test.toc14
5 files changed, 95 insertions, 63 deletions
diff --git a/arr.c b/arr.c
index c6591d9..5b005ef 100644
--- a/arr.c
+++ b/arr.c
@@ -21,6 +21,10 @@ static inline size_t arr_len(void *arr) {
return arr_hdr(arr)->len;
}
+static inline void arr_zero_(void *arr, size_t item_sz) {
+ memset(arr, 0, item_sz * arr_len(arr));
+}
+
static void arr_resv_(void **arr, size_t n, size_t item_sz) {
if (*arr == NULL) {
ArrHeader *hdr = err_malloc(item_sz * n + sizeof(ArrHeader) + 1); /* +1 => prevent ptr overflow */
@@ -175,6 +179,7 @@ You shouldn't rely on this, though, e.g. by doing
#define arr_ptr_type(arr) void *
#endif
+#define arr_zero(arr) arr_zero_(arr, sizeof *(arr))
#define arr_add(arr) (arr_ptr_type(arr))arr_add_((void **)(arr), sizeof **(arr))
#define arr_adda(arr, allocr) (arr_ptr_type(arr))arr_adda_((void **)(arr), sizeof **(arr), (allocr))
#define arr_resv(arr, n) arr_resv_((void **)(arr), n, sizeof **(arr))
@@ -190,7 +195,7 @@ You shouldn't rely on this, though, e.g. by doing
#define arr_remove_last(arr) arr_remove_last_((void **)(arr)), (void)sizeof **(arr)
#define arr_remove_lasta(arr, a) arr_remove_lasta_((void **)(arr), sizeof **(arr), (a))
#define arr_copya(out, in, a) do { assert(sizeof *(in) == sizeof **(out)); arr_copya_((void **)(out), (in), sizeof **(out), (a)); } while(0)
-
+
#ifdef TOC_DEBUG
static void arr_test(void) {
int *foos = NULL;
diff --git a/eval.c b/eval.c
index 4215aa1..0a6a0ec 100644
--- a/eval.c
+++ b/eval.c
@@ -970,7 +970,6 @@ static void eval_numerical_bin_op(Value lhs, Type *lhs_type, BinaryOp op, Value
}
}
-
static Value val_zero(Type *t) {
Value val = {0};
switch (t->kind) {
@@ -985,7 +984,21 @@ static Value val_zero(Type *t) {
}
return val;
}
-
+
+static Value val_alloc(Allocator *a, Type *t) {
+ Value val;
+ switch (t->kind) {
+ case TYPE_STRUCT:
+ val.struc = allocr_malloc(a, compiler_sizeof(t));
+ break;
+ case TYPE_ARR:
+ val.arr = allocr_calloc(a, t->arr.n, compiler_sizeof(t->arr.of));
+ break;
+ default: break;
+ }
+ return val;
+}
+
static bool val_is_nonnegative(Value *v, Type *t) {
switch (t->builtin) {
case BUILTIN_BOOL: assert(0); return false;
diff --git a/package.c b/package.c
index 4968d9b..0d7074b 100644
--- a/package.c
+++ b/package.c
@@ -155,7 +155,13 @@ static Location import_location(Importer *im) {
return l;
}
+/* handles NULL */
static inline void export_ident(Exporter *ex, Identifier i) {
+ if (!i) {
+ export_vlq(ex, 0);
+ return;
+ }
+
if (!i->export_id) {
i->export_id = ++ex->ident_id;
}
@@ -167,14 +173,6 @@ static inline Identifier import_ident(Importer *im) {
return im->ident_map[id];
}
-static inline void export_optional_ident(Exporter *ex, Identifier i) {
- bool has_i = i != NULL;
- export_bool(ex, has_i);
- if (has_i) {
- export_ident(ex, i);
- }
-}
-
static const U8 toc_package_indicator[3] = {116, 111, 112};
/* writes the header */
@@ -376,7 +374,8 @@ static void import_type(Importer *im, Type *type) {
} break;
case TYPE_STRUCT: {
U64 struct_id = import_vlq(im);
- type->struc = &im->structs[struct_id];
+ assert(struct_id);
+ type->struc = &im->structs[struct_id - 1];
} break;
case TYPE_EXPR:
import_expr(im, type->expr = imptr_new_expr(im));
@@ -478,10 +477,45 @@ static bool export_val_ptr(Exporter *ex, void *val, Type *type, Location where)
return true;
}
+static void import_val_ptr(Importer *im, void *v, Type *type) {
+ switch (type->kind) {
+ case TYPE_VOID: break;
+ case TYPE_BUILTIN:
+ switch (type->builtin) {
+ case BUILTIN_I8: *(I8 *)v = import_i8(im); break;
+ case BUILTIN_U8: *(U8 *)v = import_u8(im); break;
+ case BUILTIN_I16: *(I16 *)v = import_i16(im); break;
+ case BUILTIN_U16: *(U16 *)v = import_u16(im); break;
+ case BUILTIN_I32: *(I32 *)v = import_i32(im); break;
+ case BUILTIN_U32: *(U32 *)v = import_u32(im); break;
+ case BUILTIN_I64: *(I64 *)v = import_i64(im); break;
+ case BUILTIN_U64: *(U64 *)v = import_u64(im); break;
+ case BUILTIN_F32: *(F32 *)v = import_f32(im); break;
+ case BUILTIN_F64: *(F64 *)v = import_f64(im); break;
+ case BUILTIN_BOOL: *(bool *)v = import_bool(im); break;
+ case BUILTIN_CHAR: *(char *)v = import_char(im); break;
+ case BUILTIN_TYPE:
+ import_type(im, *(Type **)v = imptr_new_type(im));
+ break;
+ case BUILTIN_PKG:
+ /* TODO */
+ assert(0);
+ break;
+ }
+ }
+}
+
static inline bool export_val(Exporter *ex, Value val, Type *type, Location where) {
return export_val_ptr(ex, val_get_ptr(&val, type), type, where);
}
+static inline Value import_val(Importer *im, Type *type) {
+ Value val;
+ val = val_alloc(im->allocr, type);
+ import_val_ptr(im, val_get_ptr(&val, type), type);
+ return val;
+}
+
static inline bool export_optional_val(Exporter *ex, Value *val, Type *type, Location where) {
bool has_val = val != NULL;
export_bool(ex, has_val);
@@ -637,8 +671,8 @@ static bool export_expr(Exporter *ex, Expression *e) {
export_u8(ex, ea->flags);
if (!export_type(ex, &ea->type, e->where))
return false;
- export_optional_ident(ex, ea->index);
- export_optional_ident(ex, ea->value);
+ export_ident(ex, ea->index);
+ export_ident(ex, ea->value);
if (ea->flags & EACH_IS_RANGE) {
if (!export_expr(ex, ea->range.from))
return false;
@@ -668,12 +702,6 @@ static void import_expr(Importer *im, Expression *e) {
}
-enum {
- DECL_EXPORT_NONE,
- DECL_EXPORT_EXPR,
- DECL_EXPORT_VAL
-};
-
static bool export_decl(Exporter *ex, Declaration *d) {
assert(ex->started);
possibly_static_assert(sizeof d->flags == 2);
@@ -705,25 +733,12 @@ static bool export_decl(Exporter *ex, Declaration *d) {
if (!export_type(ex, &d->type, d->where))
return false;
}
-
- U8 constness = 0;
- if (d->flags & DECL_IS_CONST) constness = 1;
- else if (d->flags & DECL_SEMI_CONST) constness = 2;
- export_u8(ex, constness);
-
- U8 expr_kind = DECL_EXPORT_NONE;
- if (d->flags & DECL_HAS_EXPR)
- expr_kind = DECL_EXPORT_EXPR;
- if (d->flags & DECL_FOUND_VAL)
- expr_kind = DECL_EXPORT_VAL;
-
- export_u8(ex, expr_kind);
- if (expr_kind == DECL_EXPORT_EXPR) {
- if (!export_expr(ex, &d->expr))
- return false;
- } else if (expr_kind == DECL_EXPORT_VAL) {
+ if (d->flags & DECL_FOUND_VAL) {
if (!export_val(ex, d->val, &d->type, d->where))
return false;
+ } else if (d->flags & DECL_HAS_EXPR) {
+ if (!export_expr(ex, &d->expr))
+ return false;
}
return true;
}
@@ -737,8 +752,14 @@ static void import_decl(Importer *im, Declaration *d) {
for (size_t i = 0; i < n_idents; ++i) {
d->idents[i] = import_ident(im);
}
- import_type(im, &d->type);
- printf("%s\n",type_to_str(&d->type));
+ if (d->flags & DECL_FOUND_TYPE) {
+ import_type(im, &d->type);
+ }
+ if (d->flags & DECL_FOUND_VAL) {
+ d->val = import_val(im, &d->type);
+ print_val(d->val, &d->type);
+ } else if (d->flags & DECL_HAS_EXPR) {
+ }
exit(0);
}
@@ -798,6 +819,9 @@ static bool export_fn(Exporter *ex, FnExpr *f) {
}
static bool export_struct(Exporter *ex, StructDef *s) {
+ export_ident(ex, s->name);
+ if (s->name)
+ *(Identifier *)arr_add(&ex->exported_idents) = s->name;
export_len(ex, arr_len(s->fields));
arr_foreach(s->fields, Field, f) {
export_ident(ex, f->name);
@@ -808,6 +832,7 @@ static bool export_struct(Exporter *ex, StructDef *s) {
}
static void import_struct(Importer *im, StructDef *s) {
+ s->name = import_ident(im);
size_t nfields = import_arr(im, &s->fields);
for (size_t i = 0; i < nfields; ++i) {
s->fields[i].name = import_ident(im);
@@ -890,6 +915,10 @@ static bool import_footer(Importer *im) {
}
size_t n_structs = import_arr(im, &im->structs);
+#ifdef TOC_DEBUG
+ /* for debugging: so that struct names show up as "anonymous struct" if they haven't been imported yet */
+ arr_zero(im->structs);
+#endif
for (i = 0; i < n_structs; ++i) {
import_struct(im, &im->structs[i]);
}
diff --git a/parse.c b/parse.c
index 787c091..2ed7473 100644
--- a/parse.c
+++ b/parse.c
@@ -185,10 +185,6 @@ static void fprint_expr(FILE *out, Expression *expr);
/* returns the number of characters written, not including the null character */
static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) {
- /* if ((t->flags & TYPE_IS_RESOLVED) && t->was_expr) { */
- /* /\* TODO: improve this (see also: case TYPE_EXPR) *\/ */
- /* return str_copy(buffer, bufsize, "<type expression>"); */
- /* } */
switch (t->kind) {
case TYPE_VOID:
return str_copy(buffer, bufsize, "void");
@@ -228,14 +224,13 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) {
return written;
}
case TYPE_STRUCT: {
- /* size_t written = str_copy(buffer, bufsize, "struct { "); */
- /* arr_foreach(t->struc->fields, Field, f) { */
- /* written += type_to_str_(f->type, buffer + written, bufsize - written); */
- /* written += str_copy(buffer + written, bufsize - written, "; "); */
- /* } */
- /* written += str_copy(buffer + written, bufsize - written, " }"); */
- /* TODO: show name or something (to allow circular dependencies)? */
- return str_copy(buffer, bufsize, "struct { ... }");
+ if (t->struc->name) {
+ char *namestr = ident_to_str(t->struc->name);
+ size_t bytes = str_copy(buffer, bufsize, namestr);
+ free(namestr);
+ return bytes;
+ }
+ return str_copy(buffer, bufsize, "anonymous struct");
}
case TYPE_ARR: {
diff --git a/test.toc b/test.toc
index 2333245..53bae45 100644
--- a/test.toc
+++ b/test.toc
@@ -9,16 +9,6 @@ putf ::= fn(x: float) {
-// point ::= pkg "point";
-Foo ::= struct { x, y : int; };
+point ::= pkg "point";
-f ::= fn(t :: Type) int {
- 5 as t
-}
-;
-main ::= fn() {
- i ::= int;
- puti(f(i));
-
-
-};
+main ::= fn() {}; \ No newline at end of file