diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-11 14:05:02 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-11 14:05:02 -0500 |
commit | f369bf19b729d3e25056b562b04efbc2361bf7e8 (patch) | |
tree | bf592e2461235382fe8e8b04f20d78cbddc50f75 | |
parent | 5ad9c18a635b25dcc3a8edce8fffa8462abd6520 (diff) |
importing some values!
-rw-r--r-- | arr.c | 7 | ||||
-rw-r--r-- | eval.c | 17 | ||||
-rw-r--r-- | package.c | 101 | ||||
-rw-r--r-- | parse.c | 19 | ||||
-rw-r--r-- | test.toc | 14 |
5 files changed, 95 insertions, 63 deletions
@@ -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; @@ -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; @@ -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]); } @@ -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: { @@ -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 |