summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-29 11:27:37 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-29 11:27:37 -0500
commitd79ac12de0ceb4ff82f486c26608b754b145f0fc (patch)
treec20bb457b7ad2a9ac9e99483d58cdcb58351e6b8
parentc4c91e3444c4a530761f900d4f7268801e5cc55d (diff)
got rid of packages.
-rwxr-xr-xbuild.sh2
-rw-r--r--cgen.c51
-rw-r--r--copy.c3
-rw-r--r--decls_cgen.c53
-rw-r--r--eval.c44
-rw-r--r--foreign.c6
-rw-r--r--instance_table.c6
-rw-r--r--main.c5
-rw-r--r--package.c1353
-rw-r--r--parse.c47
-rw-r--r--std/arr.toc11
-rw-r--r--std/io.toc12
-rw-r--r--test.toc27
-rw-r--r--toc.c1
-rw-r--r--tokenizer.c3
-rw-r--r--types.c151
-rw-r--r--types.h50
17 files changed, 58 insertions, 1767 deletions
diff --git a/build.sh b/build.sh
index 1dac15c..6dadf63 100755
--- a/build.sh
+++ b/build.sh
@@ -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
diff --git a/cgen.c b/cgen.c
index f11a94a..4c86f63 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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;
diff --git a/copy.c b/copy.c
index 0a034f6..02c23e4 100644
--- a/copy.c
+++ b/copy.c
@@ -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;
diff --git a/eval.c b/eval.c
index 32804e0..8019f4f 100644
--- a/eval.c
+++ b/eval.c
@@ -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;
}
diff --git a/foreign.c b/foreign.c
index a5b63e7..b55a908 100644
--- a/foreign.c
+++ b/foreign.c
@@ -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:
diff --git a/main.c b/main.c
index 311b967..496c3cc 100644
--- a/main.c
+++ b/main.c
@@ -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);
-}
diff --git a/parse.c b/parse.c
index 50ebdee..0334dd1 100644
--- a/parse.c
+++ b/parse.c
@@ -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 };
diff --git a/std/io.toc b/std/io.toc
index e9d73d6..dab2aea 100644
--- a/std/io.toc
+++ b/std/io.toc
@@ -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
diff --git a/test.toc b/test.toc
index 341642f..9046e3a 100644
--- a/test.toc
+++ b/test.toc
@@ -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
diff --git a/toc.c b/toc.c
index 9bb497e..99e4f5e 100644
--- a/toc.c
+++ b/toc.c
@@ -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]; }
diff --git a/types.c b/types.c
index 0cab515..3e038e6 100644
--- a/types.c
+++ b/types.c
@@ -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;
}
diff --git a/types.h b/types.h
index e9a2a6e..15643e8 100644
--- a/types.h
+++ b/types.h
@@ -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