diff options
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | cgen.c | 51 | ||||
-rw-r--r-- | copy.c | 3 | ||||
-rw-r--r-- | decls_cgen.c | 53 | ||||
-rw-r--r-- | eval.c | 44 | ||||
-rw-r--r-- | foreign.c | 6 | ||||
-rw-r--r-- | instance_table.c | 6 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | package.c | 1353 | ||||
-rw-r--r-- | parse.c | 47 | ||||
-rw-r--r-- | std/arr.toc | 11 | ||||
-rw-r--r-- | std/io.toc | 12 | ||||
-rw-r--r-- | test.toc | 27 | ||||
-rw-r--r-- | toc.c | 1 | ||||
-rw-r--r-- | tokenizer.c | 3 | ||||
-rw-r--r-- | types.c | 151 | ||||
-rw-r--r-- | types.h | 50 |
17 files changed, 58 insertions, 1767 deletions
@@ -27,7 +27,7 @@ if [ "$1" = "" ]; then fi fi -DEBUG_FLAGS="-O0 -g3 -pipe $WARNINGS -std=c11 -DTOC_DEBUG" +DEBUG_FLAGS="-O0 -no-pie -gdwarf-2 -pipe $WARNINGS -std=c11 -DTOC_DEBUG" RELEASE_FLAGS="-O3 -s -DNDEBUG $WARNINGS -std=c11" if [ "$1" = "release" ]; then @@ -12,7 +12,6 @@ static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Evaluator *e g->indent_lvl = 0; g->idents = ids; g->allocr = allocr; - g->exptr = ev->typer->exptr; } static bool cgen_stmt(CGenerator *g, Statement *s); @@ -62,7 +61,6 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d); case EXPR_LITERAL_STR: \ case EXPR_LITERAL_CHAR: \ case EXPR_LITERAL_FLOAT: \ - case EXPR_PKG: \ break; \ case EXPR_UNARY_OP: \ if (!f(g, e->unary.of)) return false; \ @@ -288,13 +286,6 @@ static inline void cgen_ident_simple(CGenerator *g, Identifier i) { } static void cgen_ident(CGenerator *g, Identifier i) { - IdentDecl *idecl = ident_decl(i); - if (idecl && idecl->kind == IDECL_DECL && (idecl->decl->flags & DECL_EXPORT)) { - assert(g->pkg_prefix); - cgen_write(g, "%s__", g->pkg_prefix); - } else if (i->from_pkg) { - cgen_write(g, "%s__", i->from_pkg->c.prefix); - } if (i == g->main_ident) { /* don't conflict with C's main! */ cgen_write(g, "main__"); @@ -338,7 +329,6 @@ static bool cgen_type_pre(CGenerator *g, Type *t, Location where) { case BUILTIN_F32: cgen_write(g, "f32"); break; case BUILTIN_F64: cgen_write(g, "f64"); break; case BUILTIN_TYPE: - case BUILTIN_PKG: assert(0); break; } break; case TYPE_PTR: @@ -772,7 +762,6 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, case EXPR_C: case EXPR_BUILTIN: case EXPR_TYPE: - case EXPR_PKG: assert(0); return false; } @@ -1241,7 +1230,6 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { case EXPR_FN: case EXPR_C: case EXPR_TYPE: - case EXPR_PKG: break; } return true; @@ -1373,19 +1361,14 @@ static bool cgen_expr(CGenerator *g, Expression *e) { handled = true; break; case BINARY_DOT: { - if (type_is_builtin(&e->binary.lhs->type, BUILTIN_PKG)) { - assert(e->binary.lhs->kind == EXPR_VAL); - cgen_ident(g, e->binary.dot.pkg_ident); - handled = true; - } else { - cgen_write(g, "("); - cgen_expr(g, e->binary.lhs); - bool is_ptr = e->binary.lhs->type.kind == TYPE_PTR; - cgen_write(g, is_ptr ? "->" :"."); - cgen_ident_simple(g, e->binary.dot.field->name); - cgen_write(g, ")"); - handled = true; - } + + cgen_write(g, "("); + cgen_expr(g, e->binary.lhs); + bool is_ptr = e->binary.lhs->type.kind == TYPE_PTR; + cgen_write(g, is_ptr ? "->" :"."); + cgen_ident_simple(g, e->binary.dot.field->name); + cgen_write(g, ")"); + handled = true; } break; } if (handled) break; @@ -1586,7 +1569,6 @@ static bool cgen_expr(CGenerator *g, Expression *e) { a tuple, e.g. 3, 5;, but we've errored about that before */ case EXPR_TYPE: - case EXPR_PKG: assert(0); break; case EXPR_FN: { @@ -1863,7 +1845,6 @@ static bool cgen_val_ptr(CGenerator *g, void *v, Type *t, Location where) { case BUILTIN_CHAR: cgen_write(g, "'\\x%02x'", *(char *)v); break; case BUILTIN_BOOL: cgen_write(g, "%s", *(bool *)v ? "true" : "false"); break; case BUILTIN_TYPE: - case BUILTIN_PKG: assert(0); break; } @@ -2071,18 +2052,6 @@ static bool cgen_defs_expr(CGenerator *g, Expression *e) { if (e->kind == EXPR_FN) { if (!cgen_defs_fn(g, e->fn, &e->type)) return false; - } else if (e->kind == EXPR_BINARY_OP) { - if (e->binary.op == BINARY_DOT && type_is_builtin(&e->binary.lhs->type, BUILTIN_PKG) - && e->type.kind == TYPE_FN) { - Identifier ident = e->binary.dot.pkg_ident; - Declaration *d = ident_decl(ident)->decl; - FnExpr *f = (d->flags & DECL_FOUND_VAL) ? d->val.fn : d->expr.fn; - if (fn_has_any_const_params(f)) { - /* define instances */ - if (!cgen_defs_fn(g, f, &e->type)) - return false; - } - } } cgen_recurse_subexprs(g, e, cgen_defs_expr, cgen_defs_block, cgen_defs_decl); return true; @@ -2138,7 +2107,6 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) { g->block = NULL; g->fn = NULL; g->file = f; - g->pkg_prefix = g->evalr->typer->pkg_name; /* TODO: don't include stdio.h with posix file descriptors @@ -2168,8 +2136,7 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) { if (!cgen_decls_file(g, f)) return false; cgen_write(g, "/* code */\n"); - if (!f->pkg_name) - cgen_write(g, "int main() {\n\tmain__();\n\treturn 0;\n}\n\n"); + cgen_write(g, "int main() {\n\tmain__();\n\treturn 0;\n}\n\n"); arr_foreach(f->stmts, Statement, s) { if (!cgen_defs_stmt(g, s)) return false; @@ -265,9 +265,6 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) { if (sin->to) sout->to = copy_expr_(c, sin->to); } break; - case EXPR_PKG: - out->pkg.name_expr = copy_expr_(c, in->pkg.name_expr); - break; case EXPR_TYPE: copy_type(c, &out->typeval, &in->typeval); break; diff --git a/decls_cgen.c b/decls_cgen.c index b0382b5..c62b02f 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -113,59 +113,6 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) { Type *lhs_type = &e->binary.lhs->type; if (lhs_type->kind == TYPE_PTR) lhs_type = lhs_type->ptr; - if (e->binary.op == BINARY_DOT && type_is_builtin(lhs_type, BUILTIN_PKG)) { - Identifier ident = e->binary.dot.pkg_ident; - IdentDecl *idecl = ident_decl(ident); - assert(idecl); - assert(idecl->kind == IDECL_DECL); - Declaration *d = idecl->decl; - if (e->type.kind == TYPE_FN) { - FnExpr *f = NULL; - if (d->flags & DECL_FOUND_VAL) - f = d->val.fn; - else if (d->expr.kind == EXPR_FN) - f = d->expr.fn; - if (f) { - if (fn_has_any_const_params(f)) { - /* declare the instances */ - f->c.name = ident; - if (!cgen_fn_decl(g, f, &e->type)) - return false; - } else { - bool out_param = cgen_uses_ptr(&f->ret_type); - /* extern function declaration */ - cgen_write(g, "extern "); - if (out_param) { - cgen_write(g, "void"); - } else { - if (!cgen_type_pre(g, &f->ret_type, e->where)) - return false; - } - cgen_write(g, " "); - cgen_ident(g, ident); - if (!cgen_fn_args(g, f, 0, 0)) - return false; - if (!out_param) { - if (!cgen_type_post(g, &f->ret_type, e->where)) - return false; - } - cgen_write(g, ";"); - cgen_nl(g); - } - break; - } - } - /* extern variable declaration */ - cgen_write(g, "extern "); - if (!cgen_type_pre(g, &e->type, e->where)) - return false; - cgen_write(g, " "); - cgen_ident(g, ident); - if (!cgen_type_post(g, &e->type, e->where)) - return false; - cgen_write(g, ";"); - cgen_nl(g); - } } break; default: break; @@ -53,7 +53,6 @@ static size_t compiler_sizeof_builtin(BuiltinType b) { case BUILTIN_CHAR: return sizeof(char); /* = 1 */ case BUILTIN_BOOL: return sizeof(bool); case BUILTIN_TYPE: return sizeof(Type *); - case BUILTIN_PKG: return sizeof(Package *); } assert(0); return 0; @@ -162,7 +161,6 @@ static bool builtin_truthiness(Value *v, BuiltinType b) { case BUILTIN_BOOL: return v->boolv; case BUILTIN_CHAR: return v->charv != 0; case BUILTIN_TYPE: - case BUILTIN_PKG: break; } assert(0); return false; @@ -300,10 +298,6 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) { case BUILTIN_F64: fprintf(f, F64_FMT, *(F64 *)p); break; case BUILTIN_CHAR: fprint_char_literal(f, *(char *)p); break; case BUILTIN_BOOL: fprintf(f, "%s", *(bool *)p ? "true" : "false"); break; - case BUILTIN_PKG: { - Package *pkg = *(Package **)p; - fprintf(f, "<package at %p>", (void *)pkg); - } break; case BUILTIN_TYPE: fprint_type(f, *(Type **)p); break; @@ -434,7 +428,7 @@ static void val_free(Value *v, Type *t) { builtin_casts_to_num(low); \ case BUILTIN_CHAR: vout->charv = (char)vin->low; break; \ case BUILTIN_BOOL: vout->boolv = vin->low != 0; break; \ - case BUILTIN_PKG: case BUILTIN_TYPE: assert(0); break; \ + case BUILTIN_TYPE: assert(0); break; \ } break #define builtin_float_casts(low, up) \ @@ -443,7 +437,7 @@ static void val_free(Value *v, Type *t) { builtin_casts_to_num(low); \ case BUILTIN_BOOL: vout->boolv = vin->low != 0.0f; break; \ case BUILTIN_CHAR: \ - case BUILTIN_PKG: case BUILTIN_TYPE: \ + case BUILTIN_TYPE: \ assert(0); break; \ } break @@ -473,12 +467,10 @@ static void val_builtin_cast(Value *vin, BuiltinType from, Value *vout, BuiltinT case BUILTIN_F64: case BUILTIN_BOOL: case BUILTIN_TYPE: - case BUILTIN_PKG: assert(0); break; } break; case BUILTIN_TYPE: - case BUILTIN_PKG: assert(0); break; } @@ -554,7 +546,6 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { case BUILTIN_F32: case BUILTIN_F64: case BUILTIN_TYPE: - case BUILTIN_PKG: assert(0); break; } break; @@ -629,9 +620,6 @@ static void eval_deref(Value *v, void *ptr, Type *type) { case BUILTIN_TYPE: v->type = *(Type **)ptr; break; - case BUILTIN_PKG: - v->pkg = *(Package **)ptr; - break; } break; case TYPE_SLICE: @@ -670,9 +658,6 @@ static void eval_deref_set(void *set, Value *to, Type *type) { case BUILTIN_TYPE: *(Type **)set = to->type; break; - case BUILTIN_PKG: - *(Package **)set = to->pkg; - break; } break; case TYPE_SLICE: @@ -747,7 +732,11 @@ static void *eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr) { return NULL; void *struc_data; if (is_ptr) { - struc_data = *(void **)struc.ptr; + struc_data = struc.ptr; + if (struc_data == NULL) { + err_print(dot_expr->where, "Attempt to dereference NULL pointer."); + return false; + } } else { struc_data = struc.struc; } @@ -936,7 +925,7 @@ static void eval_numerical_bin_op(Value lhs, Type *lhs_type, BinaryOp op, Value val_cast(&lhs, lhs_type, &lhs, cast_to); \ val_cast(&rhs, rhs_type, &rhs, cast_to); \ assert(lhs_type->kind == TYPE_BUILTIN); \ - switch (builtin) { \ + switch (cast_to->builtin) { \ eval_binary_bool_op_nums(builtin, op); \ default: \ assert(!("Invalid builtin to "#op)[0]); break; \ @@ -1181,11 +1170,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { if (!eval_expr(ev, rhs_expr, &rhs)) return false; switch (e->binary.op) { case BINARY_DOT: { - if (type_is_builtin(&lhs_expr->type, BUILTIN_PKG)) { - if (!eval_ident(ev, e->binary.dot.pkg_ident, v, rhs_expr->where)) - return false; - break; - } void *ptr = eval_ptr_to_struct_field(ev, e); if (!ptr) return false; eval_deref(v, ptr, &e->type); @@ -1316,7 +1300,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { boolt.builtin = BUILTIN_BOOL; Value cont; eval_numerical_bin_op(lhs, &fo->type, step_is_negative ? BINARY_GE : BINARY_LE, rhs, &fo->range.to->type, &cont, &boolt); - if (!cont.boolv) break; } if (value_val) *value_val = x; @@ -1447,8 +1430,9 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { fn = &e->call.instance->fn; } else { Value fnv; - if (!eval_expr(ev, e->call.fn, &fnv)) + if (!eval_expr(ev, e->call.fn, &fnv)) { return false; + } fn = fnv.fn; } if (fn->flags & FN_EXPR_FOREIGN) { @@ -1464,11 +1448,10 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { return false; break; } - /* make sure function body is typed before calling it */ - if (!types_block(ev->typer, &fn->body)) + if (!types_block(ev->typer, &fn->body)) { return false; - + } /* NOTE: we're not calling fn_enter because we're manually entering the function */ /* set parameter values */ @@ -1607,9 +1590,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { case EXPR_VAL: *v = e->val; break; - case EXPR_PKG: - assert(0); - break; } return true; } @@ -139,9 +139,6 @@ static bool arg_list_start(av_alist *arg_list, void (*fn)(), Value *return_val, case BUILTIN_TYPE: av_start_ptr(*arg_list, fn, Type *, &return_val->type); break; - case BUILTIN_PKG: - av_start_ptr(*arg_list, fn, Package *, &return_val->pkg); - break; } break; case TYPE_STRUCT: { @@ -237,9 +234,6 @@ static bool arg_list_add(av_alist *arg_list, Value *val, Type *type, Location wh case BUILTIN_BOOL: av_uchar(*arg_list, val->boolv); break; - case BUILTIN_PKG: - av_ptr(*arg_list, Package *, val->pkg); - break; case BUILTIN_TYPE: av_ptr(*arg_list, Type *, val->type); break; diff --git a/instance_table.c b/instance_table.c index f67b901..9527cec 100644 --- a/instance_table.c +++ b/instance_table.c @@ -142,10 +142,6 @@ static U64 val_ptr_hash(void *v, Type *t) { case BUILTIN_BOOL: return (U64)*(bool *)v; case BUILTIN_TYPE: return type_hash(*(Type **)v); - case BUILTIN_PKG: { - Package *pkg = *(Package **)v; - return (U64)pkg; - } break; } assert(0); return 0; @@ -222,8 +218,6 @@ static bool val_ptr_eq(void *u, void *v, Type *t) { bool ret = type_eq(*(Type **)u, *(Type **)v); return ret; } - case BUILTIN_PKG: - return *(Package **)u == *(Package **)v; } break; case TYPE_VOID: @@ -100,13 +100,8 @@ int main(int argc, char **argv) { Typer tr; Evaluator ev; - Exporter exptr = {0}; evalr_create(&ev, &tr, &main_allocr); typer_create(&tr, &ev, &err_ctx, &main_allocr, &idents); -#ifdef TOC_DEBUG - exptr.export_all_ident_names = true; -#endif - tr.exptr = &exptr; if (!block_enter(NULL, f.stmts, SCOPE_CHECK_REDECL)) /* enter global scope */ return EXIT_FAILURE; diff --git a/package.c b/package.c deleted file mode 100644 index 42ab5bf..0000000 --- a/package.c +++ /dev/null @@ -1,1353 +0,0 @@ -/* - Copyright (C) 2019, 2020 Leo Tenenbaum. - This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever. - You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. -*/ - -#define TOP_FMT_VERSION 0 - -static bool export_decl(Exporter *ex, Declaration *d); -static bool export_block(Exporter *ex, Block *b); -static bool export_expr(Exporter *ex, Expression *e); -static bool export_fn(Exporter *ex, FnExpr *f); -static bool import_footer(Importer *i); -static void import_decl(Importer *im, Declaration *d); -static void import_expr(Importer *im, Expression *e); -static void import_block(Importer *im, Block *b); -static FnExpr *import_fn(Importer *im); -static void export_decl_external(Exporter *ex, Declaration *d); -static inline Expression *import_expr_(Importer *im); -static bool export_struct(Exporter *ex, StructDef *s); -static StructDef *import_struct(Importer *im); - - -static void exptr_create(Exporter *ex, FILE *out, const char *filename, ErrCtx *err_ctx) { - /* construct full filename */ - ex->out = out; - ex->exporting_to.ctx = err_ctx; - ex->exporting_to.filename = filename; - ex->ident_id = 0; - ex->nexported_fns = 0; - ex->nexported_structs = 0; - ex->exported_idents = NULL; - ex->started = false; - ex->code = NULL; -} - -static inline void *imptr_malloc(Importer *i, size_t n) { - return allocr_malloc(i->allocr, n); -} - -static inline void *imptr_calloc(Importer *i, size_t n, size_t s) { - return allocr_calloc(i->allocr, n, s); -} - -static inline void export_u8(Exporter *ex, U8 u8) { - write_u8(ex->out, u8); -} -static inline U8 import_u8(Importer *i) { - return read_u8(i->in); -} -static inline void export_i8(Exporter *ex, I8 i8) { - write_i8(ex->out, i8); -} -static inline I8 import_i8(Importer *i) { - return read_i8(i->in); -} -static inline void export_u16(Exporter *ex, U16 u16) { - write_u16(ex->out, u16); -} -static inline U16 import_u16(Importer *i) { - return read_u16(i->in); -} -static inline void export_i16(Exporter *ex, I16 i16) { - write_i16(ex->out, i16); -} -static inline I16 import_i16(Importer *i) { - return read_i16(i->in); -} -static inline void export_u32(Exporter *ex, U32 u32) { - write_u32(ex->out, u32); -} -static inline U32 import_u32(Importer *i) { - return read_u32(i->in); -} -static inline void export_i32(Exporter *ex, I32 i32) { - write_i32(ex->out, i32); -} -static inline I32 import_i32(Importer *i) { - return read_i32(i->in); -} -static inline void export_u64(Exporter *ex, U64 u64) { - write_u64(ex->out, u64); -} -static inline U64 import_u64(Importer *i) { - return read_u64(i->in); -} -static inline void export_i64(Exporter *ex, I64 i64) { - write_i64(ex->out, i64); -} -static inline I64 import_i64(Importer *i) { - return read_i64(i->in); -} -static inline void export_f32(Exporter *ex, F32 f32) { - write_f32(ex->out, f32); -} -static inline F32 import_f32(Importer *i) { - return read_f32(i->in); -} -static inline void export_f64(Exporter *ex, F64 f64) { - write_f64(ex->out, f64); -} -static inline F64 import_f64(Importer *i) { - return read_f64(i->in); -} -static inline void export_bool(Exporter *ex, bool b) { - write_bool(ex->out, b); -} -static inline bool import_bool(Importer *i) { - return read_bool(i->in); -} -static inline void export_char(Exporter *ex, char c) { - write_char(ex->out, c); -} -static inline char import_char(Importer *i) { - return read_char(i->in); -} -static inline void export_vlq(Exporter *ex, U64 x) { - write_vlq(ex->out, x); -} -static inline U64 import_vlq(Importer *i) { - return read_vlq(i->in); -} -static inline void export_len(Exporter *ex, size_t len) { - export_vlq(ex, (U64)len); -} -static inline size_t import_len(Importer *i) { - return (size_t)import_vlq(i); -} - - -static size_t import_arr_(Importer *im, void **arr, size_t sz) { - *arr = NULL; - size_t len = import_len(im); - arr_set_lena_(arr, len, sz, im->allocr); - return len; -} -/* -reads length and allocates an array of that length -returns length -*/ -#define import_arr(im, arr) import_arr_(im, (void **)arr, sizeof **(arr)) - -static inline void export_str(Exporter *ex, const char *str, size_t len) { -#ifdef TOC_DEBUG - for (size_t i = 0; i < len; ++i) - export_char(ex, *str++); -#else - fwrite(str, 1, len, ex->out); -#endif -} - -static inline char *import_str(Importer *i, size_t len) { - char *str = imptr_malloc(i, len+1); - str[len] = 0; - fread(str, 1, len, i->in); - return str; -} - -static inline void export_cstr(Exporter *ex, const char *str) { - size_t len = strlen(str); - export_len(ex, len); - export_str(ex, str, len); -} - -static inline char *import_cstr(Importer *i) { - size_t len = import_len(i); - return import_str(i, len); -} - - -static void export_location(Exporter *ex, Location where) { - /* for now, we only export the line */ - export_vlq(ex, (U64)where.start->pos.line); -} -static Location import_location(Importer *im) { - Location l; - l.file = im->importing_from; - l.start = NULL; - l.simple_location.line = (U32)import_vlq(im); - return l; -} - -static void export_ident_name(Exporter *ex, Identifier ident) { - if (ident->export_name) return; - *(Identifier *)arr_add(&ex->exported_idents) = ident; - ident->export_name = true; -} - - -/* handles NULL */ -static inline void export_ident(Exporter *ex, Identifier i) { - if (!i) { - export_vlq(ex, 0); - return; - } - IdentDecl *idecl = ident_decl(i); - - if (idecl && idecl->scope == NULL && idecl->kind == IDECL_DECL) { - /* make sure this is exported */ - export_decl_external(ex, idecl->decl); - } - if (!i->export_id) { - i->export_id = ++ex->ident_id; - } - export_vlq(ex, i->export_id); - if (ex->export_all_ident_names) - export_ident_name(ex, i); -} -static inline Identifier import_ident(Importer *im) { - U64 id = import_vlq(im); - assert(id <= im->max_ident_id); - return im->ident_map[id]; -} - -static const U8 toc_package_indicator[3] = {116, 111, 112}; - -/* writes the header */ -static void exptr_start(Exporter *ex, const char *pkg_name, size_t pkg_name_len) { - const char *code = ex->code; - ex->decls_to_export = NULL; - ex->started = true; - export_u8(ex, toc_package_indicator[0]); - export_u8(ex, toc_package_indicator[1]); - export_u8(ex, toc_package_indicator[2]); - export_u32(ex, TOP_FMT_VERSION); - assert(ftell(ex->out) == 7L); - export_u64(ex, 0); /* placeholder for footer offset in file */ - export_len(ex, pkg_name_len); - export_str(ex, pkg_name, pkg_name_len); - - bool has_code = code != NULL; - export_bool(ex, has_code); - if (has_code) { - size_t len = strlen(code); - export_len(ex, len); - export_str(ex, code, len); - } -} - -/* where = where was this imported. don't free fname while imported stuff is in use. */ -static Package *import_pkg(PackageManager *pkgmgr, Allocator *allocr, const char *fname, ErrCtx *parent_ctx, Location where) { - - Package *p = str_hash_table_get(&pkgmgr->pkgs, fname, strlen(fname)); - if (p) return p; - p = str_hash_table_insert(&pkgmgr->pkgs, fname, strlen(fname)); - p->filename = fname; - FILE *f = fopen(fname, "r"); - if (!f) { - err_print(where, "Could not open package file: %s.", fname); - return NULL; - } - - Importer i = {0}; - i.allocr = allocr; - i.pkgmgr = pkgmgr; - i.importing_from = imptr_calloc(&i, 1, sizeof *i.importing_from); - i.importing_from->filename = fname; - i.importing_from->ctx = parent_ctx; - idents_create(&p->idents); - i.pkg = p; - i.in = f; - i.import_location = where; - - - /* read header */ - U8 toc[3]; - toc[0] = import_u8(&i); - toc[1] = import_u8(&i); - toc[2] = import_u8(&i); - if (toc[0] != toc_package_indicator[0] || - toc[1] != toc_package_indicator[1] || - toc[2] != toc_package_indicator[2]) { - err_print(where, "%s is not a toc package file.", fname); - goto err; - } - U32 version_written = import_u32(&i); - if (version_written != TOP_FMT_VERSION) { - warn_print(where, "Warning: toc version mismatch. Package was created with version " U32_FMT " but version " STRINGIFY(TOP_FMT_VERSION) " is being used.\n" - "The package may be read incorrectly.", - version_written); - } - U64 footer_offset = import_u64(&i); - size_t pkg_name_len = import_len(&i); - char *pkg_name = import_str(&i, pkg_name_len); - p->name = allocr_malloc(allocr, pkg_name_len + 1); - p->c.prefix = p->name; - memcpy(p->name, pkg_name, pkg_name_len); - p->name[pkg_name_len] = 0; - bool has_code = import_bool(&i); - if (has_code) { - size_t code_len = import_len(&i); - char *code = import_str(&i, code_len); - i.importing_from->contents = code; - } - long decls_offset = ftell(f); - fseek(f, (long)footer_offset, SEEK_SET); - /* read footer */ - if (!import_footer(&i)) { - goto err; - } - fseek(f, decls_offset, SEEK_SET); - /* read declarations */ - size_t ndecls = import_u32(&i); - p->stmts = NULL; - /* printf("%lu decls\n",ndecls); */ - for (size_t idx = 0; idx < ndecls; ++idx) { - /* printf("-importing one @ %lu\n",ftell(i.in)); */ - Statement *s = arr_add(&p->stmts); - s->kind = STMT_DECL; - import_decl(&i, &s->decl); - } - - if (ftell(i.in) != (long)footer_offset) { - err_print(where, "Something strange happened when importing this package. Expected to be at byte #%ld but actually at byte #%ld.", (long)footer_offset, ftell(i.in)); - goto err; - } - free(i.ident_map); - i.ident_map = NULL; - if (!block_enter(NULL, p->stmts, 0)) - goto err; - fclose(f); - return p; - err: - free(i.ident_map); - fclose(f); - return NULL; - -} - -/* needs to handle unresolved AND resolved types! (for fns with const params) */ -static bool export_type(Exporter *ex, Type *type, Location where) { - if (type->kind == TYPE_BUILTIN) { - export_u8(ex, (U8)((int)type->builtin + TYPE_COUNT)); - } else { - export_u8(ex, (U8)type->kind); - } - assert(sizeof type->flags == 1); - export_u8(ex, type->flags); - switch (type->kind) { - case TYPE_VOID: - case TYPE_UNKNOWN: - case TYPE_BUILTIN: - break; - case TYPE_PTR: export_type(ex, type->ptr, where); break; - case TYPE_SLICE: export_type(ex, type->slice, where); break; - case TYPE_TUPLE: - export_len(ex, arr_len(type->tuple)); - arr_foreach(type->tuple, Type, sub) - if (!export_type(ex, sub, where)) - return false; - break; - case TYPE_ARR: - if (type->flags & TYPE_IS_RESOLVED) - export_vlq(ex, type->arr.n); - else - if (!export_expr(ex, type->arr.n_expr)) - return false; - - if (!export_type(ex, type->arr.of, where)) - return false; - break; - case TYPE_FN: { - size_t ntypes = arr_len(type->fn.types); - export_len(ex, ntypes); - arr_foreach(type->fn.types, Type, sub) - if (!export_type(ex, sub, where)) - return false; - export_bool(ex, type->fn.constness != NULL); - - if (type->fn.constness) { - possibly_static_assert(sizeof(Constness) == 1); /* future-proofing */ - size_t nparams = ntypes - 1; - for (size_t i = 0; i < nparams; ++i) - export_u8(ex, type->fn.constness[i]); - } - } break; - case TYPE_STRUCT: { - StructDef *struc = type->struc; - export_struct(ex, struc); - } break; - case TYPE_EXPR: - if (!export_expr(ex, type->expr)) - return false; - break; - } - return true; -} - -static inline Type *imptr_new_type(Importer *im) { - return imptr_calloc(im, 1, sizeof(Type)); -} -static inline Expression *imptr_new_expr(Importer *im) { - return imptr_calloc(im, 1, sizeof(Expression)); -} - -static void import_type(Importer *im, Type *type) { - U8 kind = import_u8(im); - if (kind > TYPE_COUNT) { - type->kind = TYPE_BUILTIN; - type->builtin = (BuiltinType)(kind - TYPE_COUNT); - } else { - type->kind = (TypeKind)kind; - } - type->flags = import_u8(im); - unsigned is_resolved = type->flags & TYPE_IS_RESOLVED; - switch (type->kind) { - case TYPE_VOID: - case TYPE_BUILTIN: - case TYPE_UNKNOWN: - break; - case TYPE_PTR: - import_type(im, type->ptr = imptr_new_type(im)); - break; - case TYPE_SLICE: - import_type(im, type->slice = imptr_new_type(im)); - break; - case TYPE_TUPLE: { - size_t ntypes = import_arr(im, &type->tuple); - for (size_t i = 0; i < ntypes; ++i) { - import_type(im, &type->tuple[i]); - } - } break; - case TYPE_ARR: - if (is_resolved) - type->arr.n = import_vlq(im); - else - type->arr.n_expr = import_expr_(im); - import_type(im, type->arr.of = imptr_new_type(im)); - break; - case TYPE_FN: { - size_t i, ntypes = import_arr(im, &type->fn.types); - for (i = 0; i < ntypes; ++i) - import_type(im, &type->fn.types[i]); - bool has_constness = import_bool(im); - if (has_constness) { - size_t nparams = ntypes - 1; - type->fn.constness = imptr_malloc(im, nparams * sizeof *type->fn.constness); - for (i = 0; i < nparams; ++i) - type->fn.constness[i] = import_u8(im); - } else type->fn.constness = NULL; - } break; - case TYPE_STRUCT: { - type->struc = import_struct(im); - } break; - case TYPE_EXPR: - type->expr = import_expr_(im); - break; - } -} - -static bool export_val(Exporter *ex, Value val, Type *type, Location where); -static bool export_val_ptr(Exporter *ex, void *v, Type *type, Location where) { - switch (type->kind) { - case TYPE_VOID: break; - case TYPE_BUILTIN: - switch (type->builtin) { - case BUILTIN_I8: export_i8(ex, *(I8 *)v); break; - case BUILTIN_U8: export_u8(ex, *(U8 *)v); break; - case BUILTIN_I16: export_i16(ex, *(I16 *)v); break; - case BUILTIN_U16: export_u16(ex, *(U16 *)v); break; - case BUILTIN_I32: export_i32(ex, *(I32 *)v); break; - case BUILTIN_U32: export_u32(ex, *(U32 *)v); break; - case BUILTIN_I64: export_i64(ex, *(I64 *)v); break; - case BUILTIN_U64: export_u64(ex, *(U64 *)v); break; - case BUILTIN_F32: export_f32(ex, *(F32 *)v); break; - case BUILTIN_F64: export_f64(ex, *(F64 *)v); break; - case BUILTIN_BOOL: export_bool(ex, *(bool *)v); break; - case BUILTIN_CHAR: export_char(ex, *(char *)v); break; - case BUILTIN_TYPE: - if (!export_type(ex, *(Type **)v, where)) - return false; - break; - case BUILTIN_PKG: - export_cstr(ex, (*(Package **)v)->filename); - break; - } - break; - case TYPE_TUPLE: { - size_t n = arr_len(type->tuple); - Value *vals = *(Value **)v; - for (size_t i = 0; i < n; ++i) { - if (!export_val(ex, vals[i], &type->tuple[i], where)) - return false; - } - } break; - case TYPE_PTR: - err_print(where, "Cannot export pointer."); - return false; - case TYPE_ARR: { - size_t item_size = compiler_sizeof(type->arr.of); - char *ptr = v; - for (U64 i = 0; i < type->arr.n; ++i) { - if (!export_val_ptr(ex, ptr, type->arr.of, where)) - return false; - ptr += item_size; - } - } break; - case TYPE_STRUCT: - eval_struct_find_offsets(type->struc); - arr_foreach(type->struc->fields, Field, f) { - if (!export_val_ptr(ex, (char *)v + f->offset, &f->type, where)) - return false; - } - break; - case TYPE_SLICE: { - Slice slice = *(Slice *)v; - I64 n = slice.n; - size_t item_size = compiler_sizeof(type->slice); - export_i64(ex, n); - char *ptr = slice.data; - for (I64 i = 0; i < n; ++i) { - if (!export_val_ptr(ex, ptr, type->slice, where)) - return false; - ptr += item_size; - } - } break; - case TYPE_FN: - if (!export_fn(ex, *(FnExpr **)v)) - return false; - break; - case TYPE_UNKNOWN: - case TYPE_EXPR: - assert(0); - return false; - } - return true; -} - -static inline Value import_val(Importer *im, Type *type, Location where); -static void import_val_ptr(Importer *im, void *v, Type *type, Location where) { - 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: { - char *fname = import_cstr(im); - Package *pkg = *(Package **)v = import_pkg(im->pkgmgr, im->allocr, fname, im->err_ctx, where); - if (!pkg) { - /* TODO: make this bool */ - return; - } - } break; - } - break; - case TYPE_TUPLE: { - Value **vals = (Value **)v; - size_t n = arr_len(type->tuple); - *vals = imptr_malloc(im, n * sizeof **vals); - for (size_t i = 0; i < n; ++i) { - (*vals)[i] = import_val(im, &type->tuple[i], where); - } - } break; - case TYPE_ARR: { - size_t item_size = compiler_sizeof(type->arr.of); - U64 n = type->arr.n; - char *ptr = v; - for (U64 i = 0; i < n; ++i) { - import_val_ptr(im, ptr, type->arr.of, where); - ptr += item_size; - } - } break; - case TYPE_STRUCT: { - eval_struct_find_offsets(type->struc); - arr_foreach(type->struc->fields, Field, f) { - import_val_ptr(im, (char *)v + f->offset, &f->type, where); - } - } break; - case TYPE_FN: - *(FnExpr **)v = import_fn(im); - break; - case TYPE_SLICE: { - Slice *slice = v; - I64 n = slice->n = import_i64(im); - size_t item_size = compiler_sizeof(type->slice); - if (n <= 0) { - slice->data = NULL; - } else { - char *ptr = slice->data = imptr_malloc(im, (U64)n * item_size); - for (I64 i = 0; i < n; ++i) { - import_val_ptr(im, ptr, type->slice, where); - ptr += item_size; - } - } - } break; - case TYPE_PTR: - case TYPE_UNKNOWN: - case TYPE_EXPR: - 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, Location where) { - Value val; - val = val_alloc(im->allocr, type); - import_val_ptr(im, val_get_ptr(&val, type), type, where); - 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); - if (has_val) { - return export_val(ex, *val, type, where); - } else { - return true; - } -} - -static inline Value *import_optional_val(Importer *im, Type *type, Location where) { - if (import_bool(im)) { - Value *val = imptr_malloc(im, sizeof *val); - *val = import_val(im, type, where); - return val; - } - return NULL; -} - -/* e can be NULL! */ -static inline bool export_optional_expr(Exporter *ex, Expression *e) { - bool has_e = e != NULL; - export_bool(ex, has_e); - if (has_e) - return export_expr(ex, e); - else - return true; -} - -static inline Expression *import_optional_expr(Importer *im) { - if (import_bool(im)) { - return import_expr_(im); - } - return NULL; -} - -static bool export_expr(Exporter *ex, Expression *e) { - possibly_static_assert(sizeof e->flags == 1); - export_u8(ex, (U8)e->flags); - assert(e->kind < 256); - export_u8(ex, (U8)e->kind); - export_location(ex, e->where); - unsigned found_type = e->flags & EXPR_FOUND_TYPE; - if (found_type) { - if (!export_type(ex, &e->type, e->where)) - return false; - } - switch (e->kind) { - case EXPR_LITERAL_INT: - /* smaller int literals are more common */ - export_vlq(ex, e->intl); - break; - case EXPR_LITERAL_FLOAT: - if (!found_type || (e->type.flags & TYPE_IS_FLEXIBLE) || e->type.builtin == BUILTIN_F64) - export_f64(ex, (F64)e->floatl); - else - export_f32(ex, (F32)e->floatl); - break; - case EXPR_LITERAL_BOOL: - export_bool(ex, e->booll); - break; - case EXPR_LITERAL_CHAR: - export_char(ex, e->charl); - break; - case EXPR_LITERAL_STR: - export_len(ex, e->strl.len); - fwrite(e->strl.str, 1, e->strl.len, ex->out); - break; - case EXPR_C: - if (!export_expr(ex, e->c.code)) - return false; - break; - case EXPR_BUILTIN: - if (found_type) { - possibly_static_assert(BUILTIN_VAL_COUNT <= 256); - export_u8(ex, (U8)e->builtin.which.val); - } else { - if (!export_expr(ex, e->builtin.which.expr)) - return false; - } - break; - case EXPR_IDENT: - export_ident(ex, e->ident); - break; - case EXPR_UNARY_OP: - export_u8(ex, (U8)e->unary.op); - if (!export_expr(ex, e->unary.of)) - return false; - break; - case EXPR_BINARY_OP: - export_u8(ex, (U8)e->binary.op); - if (!export_expr(ex, e->binary.lhs)) - return false; - if (!export_expr(ex, e->binary.rhs)) - return false; - break; - case EXPR_VAL: - if (!export_val(ex, e->val, &e->type, e->where)) - return false; - break; - case EXPR_TUPLE: - export_len(ex, arr_len(e->tuple)); - arr_foreach(e->tuple, Expression, item) - if (!export_expr(ex, item)) - return false; - break; - case EXPR_TYPE: - if (!export_type(ex, &e->typeval, e->where)) - return false; - break; - case EXPR_FN: - if (!export_fn(ex, e->fn)) - return false; - break; - case EXPR_BLOCK: - if (!export_block(ex, &e->block)) - return false; - break; - case EXPR_NEW: - if (!export_type(ex, &e->new.type, e->where)) - return false; - if (!export_optional_expr(ex, e->new.n)) - return false; - break; - case EXPR_CAST: - if (!export_expr(ex, e->cast.expr) - || !export_type(ex, &e->cast.type, e->where)) - return false; - break; - case EXPR_CALL: { - CallExpr *c = &e->call; - if (!export_expr(ex, c->fn)) - return false; - if (found_type) { - export_len(ex, arr_len(c->arg_exprs)); - arr_foreach(c->arg_exprs, Expression, arg) - if (!export_expr(ex, arg)) - return false; - } else { - export_len(ex, arr_len(c->args)); - arr_foreach(c->args, Argument, arg) { - export_location(ex, arg->where); - export_ident(ex, arg->name); - if (!export_expr(ex, &arg->val)) - return false; - } - } - } break; - case EXPR_IF: { - IfExpr *i = &e->if_; - if (!export_optional_expr(ex, i->cond)) - return false; - if (!export_block(ex, &i->body)) return false; - if (!export_optional_expr(ex, i->next_elif)) - return false; - } break; - case EXPR_WHILE: { - WhileExpr *w = &e->while_; - if (!export_optional_expr(ex, w->cond)) - return false; - if (!export_block(ex, &w->body)) - return false; - } break; - case EXPR_PKG: - assert(!found_type); - if (!export_expr(ex, e->pkg.name_expr)) - return false; - break; - case EXPR_SLICE: { - SliceExpr *s = &e->slice; - if (!export_expr(ex, s->of)) return false; - if (!export_optional_expr(ex, s->from)) - return false; - if (!export_optional_expr(ex, s->to)) - return false; - } break; - case EXPR_FOR: { - ForExpr *fo = e->for_; - if (!for_enter(e)) - return false; - possibly_static_assert(sizeof fo->flags == 1); - export_u8(ex, fo->flags); - if ((fo->flags & FOR_ANNOTATED_TYPE) || found_type) - if (!export_type(ex, &fo->type, e->where)) - goto for_fail; - export_ident(ex, fo->index); - export_ident(ex, fo->value); - if (fo->flags & FOR_IS_RANGE) { - if (!export_expr(ex, fo->range.from)) - goto for_fail; - if (!export_optional_expr(ex, fo->range.to)) - goto for_fail; - if (found_type) { - if (!export_optional_val(ex, fo->range.stepval, &fo->type, e->where)) - goto for_fail; - } else { - if (!export_optional_expr(ex, fo->range.step)) - goto for_fail; - } - } else { - if (!export_expr(ex, fo->of)) - goto for_fail; - } - if (!export_block(ex, &fo->body)) - goto for_fail; - for_exit(e); - } break; - for_fail: - for_exit(e); - return false; - } - return true; -} - -/* returns a pointer, unlinke import_expr */ -static inline Expression *import_expr_(Importer *im) { - Expression *e = imptr_new_expr(im); - import_expr(im, e); - return e; -} - -static void import_expr(Importer *im, Expression *e) { - e->flags = import_u8(im); - e->kind = import_u8(im); - e->where = import_location(im); - unsigned found_type = e->flags & EXPR_FOUND_TYPE; - if (found_type) { - import_type(im, &e->type); - } - switch (e->kind) { - case EXPR_LITERAL_INT: - e->intl = import_vlq(im); - break; - case EXPR_LITERAL_FLOAT: - if (!found_type || (e->type.flags & TYPE_IS_FLEXIBLE) || e->type.builtin == BUILTIN_F64) - e->floatl = (Floating)import_f64(im); - else - e->floatl = (Floating)import_f32(im); - break; - case EXPR_LITERAL_BOOL: - e->booll = import_bool(im); - break; - case EXPR_LITERAL_CHAR: - e->charl = import_char(im); - break; - case EXPR_LITERAL_STR: { - size_t len = import_len(im); - fread(e->strl.str = malloc(len), 1, len, im->in); - } break; - case EXPR_C: - e->c.code = import_expr_(im); - break; - case EXPR_BUILTIN: - if (found_type) { - possibly_static_assert(BUILTIN_VAL_COUNT <= 256); - e->builtin.which.val = import_u8(im); - } else { - e->builtin.which.expr = import_expr_(im); - } - break; - case EXPR_IDENT: - e->ident = import_ident(im); - break; - case EXPR_UNARY_OP: - e->unary.op = import_u8(im); - e->unary.of = import_expr_(im); - break; - case EXPR_BINARY_OP: - e->binary.op = import_u8(im); - e->binary.lhs = import_expr_(im); - e->binary.rhs = import_expr_(im); - break; - case EXPR_VAL: - e->val = import_val(im, &e->type, e->where); - break; - case EXPR_TUPLE: - import_arr(im, &e->tuple); - arr_foreach(e->tuple, Expression, sub) { - import_expr(im, sub); - } - break; - case EXPR_TYPE: - import_type(im, &e->typeval); - break; - case EXPR_FN: - e->fn = import_fn(im); - break; - case EXPR_BLOCK: - import_block(im, &e->block); - break; - case EXPR_NEW: - import_type(im, &e->new.type); - e->new.n = import_optional_expr(im); - break; - case EXPR_CAST: - e->cast.expr = import_expr_(im); - import_type(im, &e->cast.type); - break; - case EXPR_CALL: { - CallExpr *c = &e->call; - memset(c, 0, sizeof *c); - c->fn = import_expr_(im); - if (found_type) { - import_arr(im, &c->arg_exprs); - arr_foreach(c->arg_exprs, Expression, arg) - import_expr(im, arg); - } else { - import_arr(im, &c->args); - arr_foreach(c->args, Argument, arg) { - arg->where = import_location(im); - arg->name = import_ident(im); - import_expr(im, &arg->val); - } - } - } break; - case EXPR_IF: { - IfExpr *i = &e->if_; - i->cond = import_optional_expr(im); - import_block(im, &i->body); - i->next_elif = import_optional_expr(im); - } break; - case EXPR_WHILE: { - WhileExpr *w = &e->while_; - w->cond = import_optional_expr(im); - import_block(im, &w->body); - } break; - case EXPR_PKG: - assert(!found_type); - e->pkg.name_expr = import_expr_(im); - break; - case EXPR_SLICE: { - SliceExpr *s = &e->slice; - s->of = import_expr_(im); - s->from = import_optional_expr(im); - s->to = import_optional_expr(im); - } break; - case EXPR_FOR: { - ForExpr *fo = e->for_ = imptr_calloc(im, 1, sizeof *fo); - fo->flags = import_u8(im); - if ((fo->flags & FOR_ANNOTATED_TYPE) || found_type) - import_type(im, &fo->type); - fo->index = import_ident(im); - fo->value = import_ident(im); - if (fo->flags & FOR_IS_RANGE) { - fo->range.from = import_expr_(im); - fo->range.to = import_optional_expr(im); - if (found_type) { - fo->range.stepval = import_optional_val(im, &fo->type, e->where); - } else { - fo->range.step = import_optional_expr(im); - } - } else { - fo->of = import_expr_(im); - } - import_block(im, &fo->body); - } break; - } -} - -static bool export_decl(Exporter *ex, Declaration *d) { - if (d->flags & DECL_MARKED_FOR_EXPORTING) { - arr_foreach(d->idents, Identifier, ident) { - export_ident_name(ex, *ident); - } - } - - assert(ex->started); - possibly_static_assert(sizeof d->flags == 2); - export_u16(ex, d->flags); - - if ((d->flags & DECL_FOUND_TYPE) && d->type.kind == TYPE_UNKNOWN) { - err_print(d->where, "Can't export declaration of unknown type."); - return false; - } - - export_location(ex, d->where); - export_len(ex, arr_len(d->idents)); - arr_foreach(d->idents, Identifier, ident) { - export_ident(ex, *ident); - } - - if (d->flags & (DECL_FOUND_TYPE | DECL_ANNOTATES_TYPE)) { - if (!export_type(ex, &d->type, d->where)) - return false; - } - 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; - } else if (d->flags & DECL_FOREIGN) { - if (!(d->flags & DECL_FOUND_TYPE)) { - if (!export_expr(ex, d->foreign.name)) - return false; - if (!export_expr(ex, d->foreign.lib)) - return false; - } - } - return true; -} - -static void import_decl(Importer *im, Declaration *d) { - possibly_static_assert(sizeof d->flags == 2); - d->flags = import_u16(im); - d->flags &= (DeclFlags)~(DeclFlags)DECL_EXPORT; - d->where = import_location(im); - d->idents = NULL; - size_t n_idents = import_arr(im, &d->idents); - for (size_t i = 0; i < n_idents; ++i) { - d->idents[i] = import_ident(im); - } - if (d->flags & (DECL_FOUND_TYPE | DECL_ANNOTATES_TYPE)) { - import_type(im, &d->type); - } - if (d->flags & DECL_FOUND_VAL) { - d->val = import_val(im, &d->type, d->where); - if (d->flags & DECL_HAS_EXPR) { - d->expr.kind = EXPR_VAL; - d->expr.val = d->val; - } - d->flags &= (DeclFlags)~(DeclFlags)DECL_HAS_EXPR; - } else if (d->flags & DECL_HAS_EXPR) { - import_expr(im, &d->expr); - } else if (d->flags & DECL_FOREIGN) { - if (!(d->flags & DECL_FOUND_TYPE)) { - d->foreign.name = import_expr_(im); - d->foreign.lib = import_expr_(im); - } - } -} - -/* exports a declaration. to be used by other files instead of export_decl. */ -static void export_decl_external(Exporter *ex, Declaration *d) { - if (!(d->flags & DECL_MARKED_FOR_EXPORTING)) { - d->flags |= DECL_MARKED_FOR_EXPORTING; - *(Declaration **)arr_add(&ex->decls_to_export) = d; - } -} - -static bool export_stmt(Exporter *ex, Statement *s) { - possibly_static_assert(sizeof s->flags == 1); - export_u8(ex, s->flags); - export_u8(ex, (U8)s->kind); - export_location(ex, s->where); - switch (s->kind) { - case STMT_EXPR: - if (!export_expr(ex, &s->expr)) - return false; - break; - case STMT_DECL: - if (!export_decl(ex, &s->decl)) - return false; - break; - case STMT_RET: { - possibly_static_assert(sizeof s->ret.flags == 1); - export_u8(ex, (U8)s->ret.flags); - if (s->ret.flags & RET_HAS_EXPR) - if (!export_expr(ex, &s->ret.expr)) - return false; - } break; - case STMT_INCLUDE: - if (s->flags & STMT_TYPED) { - export_len(ex, arr_len(s->inc.stmts)); - arr_foreach(s->inc.stmts, Statement, sub) - if (!export_stmt(ex, sub)) - return false; - } else { - if (!export_expr(ex, &s->inc.filename)) - return false; - } - break; - } - return true; -} - -static void import_stmt(Importer *im, Statement *s) { - s->flags = import_u8(im); - s->kind = import_u8(im); - s->where = import_location(im); - switch (s->kind) { - case STMT_EXPR: - import_expr(im, &s->expr); - break; - case STMT_DECL: - import_decl(im, &s->decl); - break; - case STMT_INCLUDE: - if (s->flags & STMT_TYPED) { - import_arr(im, &s->inc.stmts); - arr_foreach(s->inc.stmts, Statement, sub) - import_stmt(im, sub); - } else { - import_expr(im, &s->inc.filename); - } - break; - case STMT_RET: - s->ret.flags = import_u8(im); - if (s->ret.flags & RET_HAS_EXPR) - import_expr(im, &s->expr); - break; - } - /* fprint_stmt(stdout, s); printf("\n"); */ -} - -static bool export_block(Exporter *ex, Block *b) { - if (!block_enter(b, b->stmts, 0)) - return false; - - possibly_static_assert(sizeof b->flags == 1); - export_u8(ex, b->flags); - export_location(ex, b->where); - export_len(ex, arr_len(b->stmts)); - arr_foreach(b->stmts, Statement, s) { - if (!export_stmt(ex, s)) - goto err; - } - if (!export_optional_expr(ex, b->ret_expr)) - goto err; - - block_exit(b, b->stmts); - return true; - err: - block_exit(b, b->stmts); - return false; -} - -static void import_block(Importer *im, Block *b) { - b->flags = import_u8(im); - b->where = import_location(im); - import_arr(im, &b->stmts); - arr_foreach(b->stmts, Statement, s) { - import_stmt(im, s); - } - b->ret_expr = import_optional_expr(im); -} - -static bool export_fn(Exporter *ex, FnExpr *f) { - - export_bool(ex, f->export.id == 0); - if (f->export.id == 0) { - f->export.id = ++ex->nexported_fns; - export_vlq(ex, f->export.id); - if (!fn_enter(f, 0)) - return false; - - possibly_static_assert(sizeof f->flags == 1); - export_u8(ex, f->flags); - if (f->flags & FN_EXPR_FOREIGN) { - export_cstr(ex, f->foreign.name); - export_cstr(ex, f->foreign.lib); - } else { - export_location(ex, f->where); - export_len(ex, arr_len(f->params)); - arr_foreach(f->params, Declaration, param) { - if (!export_decl(ex, param)) - goto err; - arr_foreach(param->idents, Identifier, ident) { - export_ident_name(ex, *ident); - } - } - if (!export_type(ex, &f->ret_type, f->where)) - goto err; - export_len(ex, arr_len(f->ret_decls)); - arr_foreach(f->ret_decls, Declaration, ret_decl) - if (!export_decl(ex, ret_decl)) - goto err; - if (!export_block(ex, &f->body)) - goto err; - } - fn_exit(f); - return true; - err: - fn_exit(f); - return false; - } else { - export_vlq(ex, f->export.id); - return true; - } -} - -static FnExpr *import_fn(Importer *im) { - FnExpr *f; - if (import_bool(im)) { - /* import function definition */ - f = &im->fns[import_vlq(im)]; - f->flags = import_u8(im); - if (f->flags & FN_EXPR_FOREIGN) { - f->foreign.name = import_cstr(im); - f->foreign.lib = import_cstr(im); - } else { - f->where = import_location(im); - import_arr(im, &f->params); - arr_foreach(f->params, Declaration, param) { - import_decl(im, param); - } - import_type(im, &f->ret_type); - import_arr(im, &f->ret_decls); - arr_foreach(f->ret_decls, Declaration, ret_decl) - import_decl(im, ret_decl); - import_block(im, &f->body); - } - } else { - f = &im->fns[import_vlq(im)]; - } - return f; -} - -static bool export_struct(Exporter *ex, StructDef *s) { - export_bool(ex, s->export.id == 0); - if (s->export.id == 0) { - s->export.id = ++ex->nexported_structs; - export_vlq(ex, s->export.id); - export_ident(ex, s->name); - if (s->name) - export_ident_name(ex, s->name); - export_len(ex, arr_len(s->fields)); - arr_foreach(s->fields, Field, f) { - export_ident(ex, f->name); - export_ident_name(ex, f->name); - if (!export_type(ex, &f->type, s->where)) - return false; - } - } else { - export_vlq(ex, s->export.id); - } - return true; -} - -static StructDef *import_struct(Importer *im) { - StructDef *s; - if (import_bool(im)) { - s = &im->structs[import_vlq(im)]; - 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); - import_type(im, &s->fields[i].type); - } - } else { - s = &im->structs[import_vlq(im)]; - } - return s; -} - -/* does NOT close the file */ -static bool exptr_finish(Exporter *ex) { - long ndecls_offset = ftell(ex->out); - export_u32(ex, 0); - /* NOTE: arr_len(ex->decls_to_export) may change during loop! */ - for (size_t i = 0; i < arr_len(ex->decls_to_export); ++i) { - /* printf("-exporting one at %lu\n",ftell(ex->out)); */ - Declaration *d = ex->decls_to_export[i]; - if (!export_decl(ex, d)) - return false; - } - { - long back = ftell(ex->out); - fseek(ex->out, ndecls_offset, SEEK_SET); - /* printf("%lu decls\n",arr_len(ex->decls_to_export)); */ - export_u32(ex, (U32)arr_len(ex->decls_to_export)); - fseek(ex->out, back, SEEK_SET); - } - - long footer_offset = ftell(ex->out); - export_vlq(ex, ex->nexported_fns); - export_vlq(ex, ex->nexported_structs); - /* export total number of identifiers */ - export_vlq(ex, ex->ident_id); - /* export number of identifiers *whose names matter* */ - export_len(ex, arr_len(ex->exported_idents)); - arr_foreach(ex->exported_idents, Identifier, ident) { - Identifier i = *ident; - assert(i->export_name); - export_vlq(ex, i->export_id); - export_len(ex, i->len); - fprint_ident(ex->out, i); - } - - fseek(ex->out, 7L, SEEK_SET); - export_u64(ex, (U64)footer_offset); - arr_clear(&ex->exported_idents); - - if (ferror(ex->out)) { - Location none = {0}; - none.file = &ex->exporting_to; - warn_print(none, "An error occured while writing the package output. It may be incorrect."); - } - - return true; -} - -static bool import_footer(Importer *im) { - size_t i; - - /* +1 because indexing starts at 1 */ - U32 nfns = (U32)import_vlq(im); - im->fns = imptr_calloc(im, nfns+1, sizeof *im->fns); - U32 nstructs = (U32)import_vlq(im); - im->structs = imptr_calloc(im, nstructs+1, sizeof *im->structs); - - im->max_ident_id = import_vlq(im); - - im->ident_map = err_calloc(im->max_ident_id + 1, sizeof *im->ident_map); - size_t n_named_idents = import_len(im); - for (i = 0; i < n_named_idents; ++i) { - U64 id = import_vlq(im); - size_t name_len = import_vlq(im); - char *name = imptr_malloc(im, name_len+1); - name[name_len] = 0; - fread(name, 1, name_len, im->in); - im->ident_map[id] = ident_insert(&im->pkg->idents, &name); - im->ident_map[id]->imported = true; - im->ident_map[id]->from_pkg = im->pkg; - } - for (i = 1; i <= im->max_ident_id; ++i) { - if (!im->ident_map[i]) { - im->ident_map[i] = ident_new_anonymous(&im->pkg->idents); - im->ident_map[i]->imported = true; - im->ident_map[i]->from_pkg = im->pkg; - } - } - - if (ferror(im->in)) { - warn_print(im->import_location, "An error occured while reading the package. It may be incorrect."); - } - - return true; -} - -static void package_free(Package *pkg) { - idents_free(&pkg->idents); - arr_clear(&pkg->stmts); -} @@ -48,7 +48,6 @@ static const char *expr_kind_to_str(ExprKind k) { case EXPR_SLICE: return "slice"; case EXPR_TYPE: return "type"; case EXPR_VAL: return "value"; - case EXPR_PKG: return "package"; } assert(0); return ""; @@ -152,7 +151,6 @@ static int kw_to_builtin_type(Keyword kw) { case KW_F64: return BUILTIN_F64; case KW_BOOL: return BUILTIN_BOOL; case KW_CHAR: return BUILTIN_CHAR; - case KW_PACKAGE: return BUILTIN_PKG; case KW_TYPE: return BUILTIN_TYPE; default: return -1; } @@ -173,7 +171,6 @@ static Keyword builtin_type_to_kw(BuiltinType t) { case BUILTIN_F64: return KW_F64; case BUILTIN_BOOL: return KW_BOOL; case BUILTIN_CHAR: return KW_CHAR; - case BUILTIN_PKG: return KW_PACKAGE; case BUILTIN_TYPE: return KW_TYPE; } assert(0); @@ -1040,12 +1037,6 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { Token *start = t->token; /* TODO: consider moving this after ops, so that "if true { 5 } else { 3 } as f32" is possible */ if (t->token->kind == TOKEN_KW) switch (t->token->kw) { - case KW_PKG: - ++t->token; - e->kind = EXPR_PKG; - if (!parse_expr(p, e->pkg.name_expr = parser_malloc(p, sizeof *e->pkg.name_expr), expr_find_end(p, 0))) - return false; - goto success; case KW_FN: { /* this is a function */ e->kind = EXPR_FN; @@ -2029,33 +2020,6 @@ static bool parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { t->token = end + 1; return success; } - case KW_PKG: { - /* declaration of package name */ - Expression *pkg_name = parser_new_expr(p); - ++t->token; - Token *end = expr_find_end(p, 0); - if (!end || !token_is_kw(end, KW_SEMICOLON)) { - tokr_err(t, "No semicolon at end of package name."); - tokr_skip_to_eof(t); - return false; - } - if (p->block) { - tokr_err(t, "You must set the package name at global scope."); - t->token = end + 1; - return false; - } - if (p->parsed_file->pkg_name) { - tokr_err(t, "You've already set the package name."); - info_print(p->parsed_file->pkg_name->where, "The package name was previously set here."); - t->token = end + 1; - return false; - } - p->parsed_file->pkg_name = pkg_name; - bool success = parse_expr(p, pkg_name, end); - t->token = end + 1; - *was_a_statement = false; - return success; - } default: break; } } else if (t->token->kind == TOKEN_DIRECT) { @@ -2114,7 +2078,6 @@ static void parser_create(Parser *p, Tokenizer *t, Allocator *allocr) { static bool parse_file(Parser *p, ParsedFile *f) { Tokenizer *t = p->tokr; f->stmts = NULL; - f->pkg_name = NULL; p->file = t->file; p->parsed_file = f; bool ret = true; @@ -2352,12 +2315,6 @@ static void fprint_expr(FILE *out, Expression *e) { case EXPR_VAL: fprint_val(out, e->val, &e->type); break; - case EXPR_PKG: - fprintf(out, "(pkg "); - assert(!found_type); - fprint_expr(out, e->pkg.name_expr); - fprintf(out, ")"); - break; } if (found_type) { fprintf(out, ":"); @@ -2479,7 +2436,6 @@ static bool expr_is_definitely_const(Expression *e) { case EXPR_LITERAL_BOOL: case EXPR_TYPE: case EXPR_VAL: - case EXPR_PKG: return true; case EXPR_IF: case EXPR_WHILE: @@ -2501,9 +2457,6 @@ static bool expr_is_definitely_const(Expression *e) { return false; Type *lhs_type = &e->binary.lhs->type; if (lhs_type->kind == TYPE_PTR) lhs_type = lhs_type->ptr; - if (type_is_builtin(lhs_type, BUILTIN_PKG)) { - return ident_is_definitely_const(e->binary.dot.pkg_ident); - } return true; } return expr_is_definitely_const(e->binary.lhs) diff --git a/std/arr.toc b/std/arr.toc index 12d44f5..24fdf9f 100644 --- a/std/arr.toc +++ b/std/arr.toc @@ -1,13 +1,10 @@ -// array package -pkg "arr"; - -#export Arr ::= fn (t :: Type) Type { +Arr ::= fn (t :: Type) Type { struct { data : []t; cap : int; } }; -#export arr_add ::= fn(t ::=, a : &Arr(t), x : t) { +arr_add ::= fn(t ::=, a : &Arr(t), x : t) { if a.data.len >= a.cap { a.cap = a.cap * 2 + 2; new_data := new(t, a.cap); @@ -17,7 +14,7 @@ pkg "arr"; } a.data = new_data; } - a.data[a.data.len] = x; a.data.len += 1; + a.data[a.data.len-1] = x; }; -#export arr_len ::= fn(t ::=, a : Arr(t)) int { a.data.len }; +arr_len ::= fn(t ::=, a : Arr(t)) int { a.data.len }; @@ -1,5 +1,3 @@ -pkg "io"; - get_type_with_size ::= fn(size :: i64) Type { if size == 1 { i8 } elif size == 2 { i16 } @@ -30,15 +28,7 @@ stdout_fwrite ::= fn(data: &u8, size: u64, nmemb: u64) { c_fwrite(data, size as c_size_t, nmemb as c_size_t, #builtin("stdout")); }; -#export puts ::= fn(x: []char) { +puts ::= fn(x: []char) { stdout_fwrite(&x[0] as &u8, 1, x.len as u64); toc_putchar('\n'); }; - -arr ::= pkg "arr"; - -#export puts_arr ::= fn(x: arr.Arr([]char)) { - for s := x.data { - puts(s); - } -};
\ No newline at end of file @@ -1,11 +1,20 @@ -arr ::= pkg "std/arr"; -io ::= pkg "std/io"; +#include "std/arr.toc"; +#include "std/io.toc"; + +do_thing ::= fn() int { + x: Arr([]char); + arr_add(&x, "HI"); + arr_add(&x, "Hello"); + arr_add(&x, "How's"); + arr_add(&x, "it"); + arr_add(&x, "going"); + for a := x.data { + puts(a); + } + 3 +}; + main ::= fn() { - x: arr.Arr([]char); - arr.arr_add(&x, "HI"); - arr.arr_add(&x, "Hello"); - arr.arr_add(&x, "How's"); - arr.arr_add(&x, "it"); - arr.arr_add(&x, "going"); - io.puts_arr(x); + x ::= do_thing(); + do_thing(); };
\ No newline at end of file @@ -124,7 +124,6 @@ static char *read_entire_file(Allocator *a, ErrCtx *ectx, const char *filename) #include "foreign.c" #include "eval.c" #include "infer.c" -#include "package.c" #include "types.c" static bool cgen_decls_file(CGenerator *g, ParsedFile *f); static bool cgen_sdecls_file(CGenerator *g, ParsedFile *f); diff --git a/tokenizer.c b/tokenizer.c index dc194ca..b34bc65 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -14,8 +14,7 @@ static const char *const keywords[KW_COUNT] = "int", "i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "float", "f32", "f64", "Type", "Package", - "char", "bool", "true", "false", - "pkg"}; + "char", "bool", "true", "false"}; static inline const char *kw_to_str(Keyword k) { return keywords[k]; } @@ -172,8 +172,7 @@ static bool expr_must_lval(Expression *e) { case EXPR_BLOCK: case EXPR_SLICE: case EXPR_TYPE: - case EXPR_VAL: - case EXPR_PKG: { + case EXPR_VAL: { err_print(e->where, "Cannot use %s as l-value.", expr_kind_to_str(e->kind)); return false; } @@ -183,7 +182,7 @@ static bool expr_must_lval(Expression *e) { } -/* does this type have a Type or a Package in it? (e.g. [5]Type, &&Package) */ +/* does this type have a Type or a Package in it? (e.g. [5]Type, &&Type) */ static bool type_is_compileonly(Type *t) { assert(t->flags & TYPE_IS_RESOLVED); switch (t->kind) { @@ -191,7 +190,7 @@ static bool type_is_compileonly(Type *t) { case TYPE_UNKNOWN: return false; case TYPE_BUILTIN: - return t->builtin == BUILTIN_PKG || t->builtin == BUILTIN_TYPE; + return t->builtin == BUILTIN_TYPE; case TYPE_PTR: return type_is_compileonly(t->ptr); case TYPE_SLICE: @@ -612,7 +611,6 @@ static bool type_can_be_truthy(Type *t) { case TYPE_BUILTIN: switch (t->builtin) { case BUILTIN_TYPE: - case BUILTIN_PKG: return false; case BUILTIN_I8: case BUILTIN_U8: @@ -678,7 +676,6 @@ static Status type_cast_status(Type *from, Type *to) { case BUILTIN_BOOL: case BUILTIN_CHAR: return STATUS_NONE; - case BUILTIN_PKG: case BUILTIN_TYPE: return STATUS_ERR; } @@ -710,7 +707,6 @@ static Status type_cast_status(Type *from, Type *to) { return STATUS_NONE; case BUILTIN_CHAR: case BUILTIN_TYPE: - case BUILTIN_PKG: return STATUS_ERR; } assert(0); @@ -722,7 +718,6 @@ static Status type_cast_status(Type *from, Type *to) { case BUILTIN_BOOL: return type_can_be_truthy(to) ? STATUS_NONE : STATUS_ERR; case BUILTIN_TYPE: - case BUILTIN_PKG: return STATUS_ERR; } break; @@ -1063,14 +1058,16 @@ static bool types_expr(Typer *tr, Expression *e) { e->flags |= EXPR_FOUND_TYPE; /* even if failed, pretend we found the type */ switch (e->kind) { case EXPR_FN: { - if (!type_of_fn(tr, e->fn, &e->type, 0)) + if (!type_of_fn(tr, e->fn, &e->type, 0)) { return false; + } if (fn_has_any_const_params(e->fn)) { HashTable z = {0}; e->fn->instances = z; } else { - if (!types_fn(tr, e->fn, &e->type, NULL)) + if (!types_fn(tr, e->fn, &e->type, NULL)) { return false; + } } } break; case EXPR_LITERAL_INT: @@ -1099,41 +1096,6 @@ static bool types_expr(Typer *tr, Expression *e) { t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_CHAR; break; - case EXPR_PKG: { - t->kind = TYPE_BUILTIN; - t->builtin = BUILTIN_PKG; - Expression *name_expr = e->pkg.name_expr; - if (!types_expr(tr, name_expr)) return false; - if (!type_is_slicechar(&name_expr->type)) { - char *s = type_to_str(&name_expr->type); - err_print(name_expr->where, "Package name is not of type []char (as it should be), but of type %s.", s); - free(s); - return false; - } - Value name_val; - if (!eval_expr(tr->evalr, name_expr, &name_val)) - return false; - - Slice name_str = name_val.slice; - if (name_str.n < 0) { - err_print(name_expr->where, "Package name has negative length (" I64_FMT ")!", name_str.n); - return false; - } - size_t name_str_len = (size_t)name_str.n; - char *name_cstr = typer_malloc(tr, name_str_len + 1); - memcpy(name_cstr, name_str.data, name_str_len); - name_cstr[name_str.n] = '\0'; - char *filename = typer_malloc(tr, name_str_len + 6); - memcpy(filename, name_str.data, name_str_len); - strcpy(filename + name_str.n, ".top"); - /* TODO: package paths */ - Package *pkg = import_pkg(&tr->pkgmgr, tr->allocr, filename, tr->err_ctx, e->where); - if (!pkg) { - return false; - } - e->kind = EXPR_VAL; - e->val.pkg = pkg; - } break; case EXPR_FOR: { ForExpr *fo = e->for_; *(Expression **)typer_arr_add(tr, &tr->in_expr_decls) = e; @@ -2069,45 +2031,6 @@ static bool types_expr(Typer *tr, Expression *e) { if (struct_type->kind == TYPE_UNKNOWN) return true; if (struct_type->kind == TYPE_PTR) struct_type = struct_type->ptr; - - if (type_is_builtin(struct_type, BUILTIN_PKG)) { - if (rhs->kind != EXPR_IDENT) { - err_print(rhs->where, "Expected identifier for package access, but got %s.", - expr_kind_to_str(rhs->kind)); - return false; - } - { - Value pkg_val; - if (!eval_expr(tr->evalr, lhs, &pkg_val)) - return false; - lhs->kind = EXPR_VAL; - if (lhs_type->kind == TYPE_PTR) { - /* that's a pointer to a package! */ - - /* soon it will be a package... */ - lhs->type.kind = TYPE_BUILTIN; - lhs->type.builtin = BUILTIN_PKG; - - eval_deref(&lhs->val, pkg_val.ptr, &lhs->type); - } else { - lhs->val = pkg_val; - } - } - Package *pkg = lhs->val.pkg; - e->binary.dot.pkg_ident = ident_translate(rhs->ident, &pkg->idents); - if (!e->binary.dot.pkg_ident) { - char *ident_name = ident_to_str(rhs->ident); - - err_print(e->where, "%s was not imported from package %s.", ident_name, pkg->name); - free(ident_name); - return false; - } - if (!type_of_ident(tr, e->where, e->binary.dot.pkg_ident, t)) { - return false; - } - break; - } - if (rhs->kind != EXPR_IDENT) { err_print(rhs->where, "Expected identifier for struct member access, but got %s.", expr_kind_to_str(rhs->kind)); @@ -2279,8 +2202,8 @@ static bool types_block(Typer *tr, Block *b) { } static bool types_decl(Typer *tr, Declaration *d) { - bool success = true; if (d->flags & DECL_FOUND_TYPE) return true; + bool success = true; if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_TYPE @@ -2418,17 +2341,7 @@ static bool types_decl(Typer *tr, Declaration *d) { ret: /* pretend we found the type even if we didn't to prevent too many errors */ d->flags |= DECL_FOUND_TYPE; - if (success) { - if (d->flags & DECL_EXPORT) { - /* export it! */ - if (!tr->pkg_name) { - err_print(d->where, "Declaration marked for exporting, but no package output was specified."); - success = false; - } else { - export_decl_external(tr->exptr, d); - } - } - } else { + if (!success) { /* use unknown type if we didn't get the type */ d->type.flags = TYPE_IS_RESOLVED; d->type.was_expr = NULL; @@ -2452,8 +2365,9 @@ static bool types_stmt(Typer *tr, Statement *s) { } break; case STMT_DECL: - if (!types_decl(tr, &s->decl)) + if (!types_decl(tr, &s->decl)) { return false; + } break; case STMT_RET: if (!tr->fn) { @@ -2522,14 +2436,12 @@ static bool types_stmt(Typer *tr, Statement *s) { static void typer_create(Typer *tr, Evaluator *ev, ErrCtx *err_ctx, Allocator *allocr, Identifiers *idents) { tr->block = NULL; tr->blocks = NULL; - pkgmgr_create(tr->pkgmgr); tr->fn = NULL; tr->evalr = ev; tr->err_ctx = err_ctx; tr->exptr = NULL; /* by default, don't set an exporter */ tr->in_decls = NULL; tr->in_expr_decls = NULL; - tr->pkg_name = NULL; tr->allocr = allocr; tr->idents = idents; tr->is_reference_stack = NULL; @@ -2538,52 +2450,11 @@ static void typer_create(Typer *tr, Evaluator *ev, ErrCtx *err_ctx, Allocator *a static bool types_file(Typer *tr, ParsedFile *f) { bool ret = true; - FILE *pkg_fp = NULL; tr->parsed_file = f; - if (f->pkg_name) { - Value pkg_name; - if (!types_expr(tr, f->pkg_name)) - return false; - if (!type_is_slicechar(&f->pkg_name->type)) { - char *typestr = type_to_str(&f->pkg_name->type); - err_print(f->pkg_name->where, "Package names must be of type []char, but this is of type %s.", typestr); - free(typestr); - return false; - } - if (!eval_expr(tr->evalr, f->pkg_name, &pkg_name)) - return false; - Slice pkg_name_slice = pkg_name.slice; - char *pkg_name_str = pkg_name_slice.data; - if (pkg_name_slice.n < 0) { - err_print(f->pkg_name->where, "Package name has a negative length (" I64_FMT ")!", pkg_name_slice.n); - return false; - } - size_t pkg_name_len = (size_t)pkg_name_slice.n; - - char *pkg_name_cstr = typer_malloc(tr, pkg_name_len+1); - memcpy(pkg_name_cstr, pkg_name_str, pkg_name_len); - pkg_name_cstr[pkg_name_len] = 0; - tr->pkg_name = pkg_name_cstr; - char *pkg_file_name = typer_malloc(tr, pkg_name_len+5); - sprintf(pkg_file_name, "%s.top", pkg_name_cstr); - pkg_fp = fopen(pkg_file_name, "wb"); - if (!pkg_fp) { - err_print(f->pkg_name->where, "Could not open package output file: %s.", pkg_file_name); - free(pkg_file_name); - return false; - } - exptr_create(tr->exptr, pkg_fp, pkg_file_name, tr->err_ctx); - exptr_start(tr->exptr, pkg_name_str, pkg_name_len); - } - arr_foreach(f->stmts, Statement, s) { if (!types_stmt(tr, s)) { ret = false; } } - if (pkg_fp) { - exptr_finish(tr->exptr); - fclose(pkg_fp); - } return ret; } @@ -163,7 +163,6 @@ typedef union Value { union Value *tuple; Slice slice; struct Type *type; - struct Package *pkg; } Value; enum { @@ -194,8 +193,6 @@ typedef struct IdentSlot { bool anonymous; /* is this identifier not part of a tree? */ bool imported; /* was this identifier imported from a package? */ U64 export_id; /* 0 if there's no exported identifier here, otherwise unique positive integer associated with this identifier */ - struct Package *from_pkg; - struct Package *pkg; /* NULL if this is not associated with a package */ IdentDecl *decls; /* array of declarations of this identifier */ } IdentSlot; @@ -303,7 +300,6 @@ typedef enum { KW_BOOL, KW_TRUE, KW_FALSE, - KW_PKG, KW_COUNT } Keyword; @@ -405,8 +401,7 @@ typedef enum { BUILTIN_F64, BUILTIN_CHAR, BUILTIN_BOOL, - BUILTIN_TYPE, - BUILTIN_PKG + BUILTIN_TYPE } BuiltinType; @@ -513,7 +508,6 @@ typedef enum { EXPR_BUILTIN, EXPR_SLICE, EXPR_TYPE, - EXPR_PKG, /* a value (it's useful to have this). right now they don't work with cgen_set_tuple @@ -734,7 +728,6 @@ typedef struct Expression { struct Expression *rhs; union { Field *field; /* for struct. */ - Identifier pkg_ident; /* for Package. */ } dot; } binary; CallExpr call; @@ -752,9 +745,6 @@ typedef struct Expression { struct { Type type; } del; - struct { - struct Expression *name_expr; - } pkg; /* can only exist before typing */ IfExpr if_; WhileExpr while_; ForExpr *for_; @@ -856,7 +846,6 @@ typedef struct Statement { typedef struct ParsedFile { Statement *stmts; - Expression *pkg_name; } ParsedFile; typedef struct Parser { @@ -907,10 +896,6 @@ typedef struct Package { } c; } Package; -typedef struct PackageManager { - StrHashTable pkgs; -} PackageManager; - typedef struct Typer { Allocator *allocr; Evaluator *evalr; @@ -921,43 +906,12 @@ typedef struct Typer { Block *block; Block **blocks; /* dyn array of all the block's we're in ([0] = NULL for global scope) */ FnExpr *fn; /* the function we're currently parsing. */ - char *pkg_name; ErrCtx *err_ctx; /* for checking for problematic struct circular dependencies */ bool *is_reference_stack; ParsedFile *parsed_file; - PackageManager pkgmgr; } Typer; -typedef struct Exporter { - FILE *out; /* .top (toc package) to output to */ - bool started; - bool export_all_ident_names; /* export every identifier's name, not just the important ones */ - U64 ident_id; - File exporting_to; - U32 nexported_structs; - U32 nexported_fns; - Identifier *exported_idents; /* (only those whose names are exported) */ - Declaration **decls_to_export; /* declarations which need to be exported at some point */ - const char *code; -} Exporter; - -typedef struct Importer { - FILE *in; - File *importing_from; - Package *pkg; - Allocator *allocr; - Identifier *ident_map; /* [i] = value of identifier with ID i */ - ErrCtx *err_ctx; - Declaration *decls; - size_t max_ident_id; - Location import_location; - StructDef *structs; - FnExpr *fns; - PackageManager *pkgmgr; -} Importer; - - typedef struct CGenerator { Allocator *allocr; FILE *outc; @@ -968,10 +922,8 @@ typedef struct CGenerator { Block *block; FnExpr *fn; /* which function are we in? (NULL for none) - not used during decls */ Evaluator *evalr; - Exporter *exptr; Identifier main_ident; Identifiers *idents; - char *pkg_prefix; } CGenerator; #ifdef TOC_DEBUG |