summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c1
-rw-r--r--package.c75
-rw-r--r--std/io.toc8
-rw-r--r--test.toc19
-rw-r--r--types.c22
-rw-r--r--types.h13
6 files changed, 79 insertions, 59 deletions
diff --git a/main.c b/main.c
index 0f12fbb..311b967 100644
--- a/main.c
+++ b/main.c
@@ -139,7 +139,6 @@ int main(int argc, char **argv) {
free(contents - 1); /* -1 because we put a 0 byte at the beginning */
allocr_free_all(&main_allocr);
evalr_free(&ev);
- typer_free(&tr);
fclose(out);
idents_free(&idents);
return 0;
diff --git a/package.c b/package.c
index a102a47..42ab5bf 100644
--- a/package.c
+++ b/package.c
@@ -238,9 +238,21 @@ static void exptr_start(Exporter *ex, const char *pkg_name, size_t pkg_name_len)
}
/* where = where was this imported. don't free fname while imported stuff is in use. */
-static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname, ErrCtx *parent_ctx, Location where) {
+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;
@@ -248,6 +260,8 @@ static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname
i.pkg = p;
i.in = f;
i.import_location = where;
+
+
/* read header */
U8 toc[3];
toc[0] = import_u8(&i);
@@ -257,7 +271,7 @@ static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname
toc[1] != toc_package_indicator[1] ||
toc[2] != toc_package_indicator[2]) {
err_print(where, "%s is not a toc package file.", fname);
- return false;
+ goto err;
}
U32 version_written = import_u32(&i);
if (version_written != TOP_FMT_VERSION) {
@@ -281,8 +295,9 @@ static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname
long decls_offset = ftell(f);
fseek(f, (long)footer_offset, SEEK_SET);
/* read footer */
- if (!import_footer(&i))
- return false;
+ if (!import_footer(&i)) {
+ goto err;
+ }
fseek(f, decls_offset, SEEK_SET);
/* read declarations */
size_t ndecls = import_u32(&i);
@@ -297,13 +312,19 @@ static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname
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));
- return false;
+ goto err;
}
free(i.ident_map);
+ i.ident_map = NULL;
if (!block_enter(NULL, p->stmts, 0))
- return false;
+ goto err;
+ fclose(f);
+ return p;
+ err:
+ free(i.ident_map);
+ fclose(f);
+ return NULL;
- return true;
}
/* needs to handle unresolved AND resolved types! (for fns with const params) */
@@ -450,7 +471,7 @@ static bool export_val_ptr(Exporter *ex, void *v, Type *type, Location where) {
return false;
break;
case BUILTIN_PKG:
- /* TODO */
+ export_cstr(ex, (*(Package **)v)->filename);
break;
}
break;
@@ -505,8 +526,8 @@ static bool export_val_ptr(Exporter *ex, void *v, Type *type, Location where) {
return true;
}
-static inline Value import_val(Importer *im, Type *type);
-static void import_val_ptr(Importer *im, void *v, Type *type) {
+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:
@@ -526,10 +547,14 @@ static void import_val_ptr(Importer *im, void *v, Type *type) {
case BUILTIN_TYPE:
import_type(im, *(Type **)v = imptr_new_type(im));
break;
- case BUILTIN_PKG:
- /* TODO */
- assert(0);
- 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: {
@@ -537,7 +562,7 @@ static void import_val_ptr(Importer *im, void *v, Type *type) {
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]);
+ (*vals)[i] = import_val(im, &type->tuple[i], where);
}
} break;
case TYPE_ARR: {
@@ -545,14 +570,14 @@ static void import_val_ptr(Importer *im, void *v, Type *type) {
U64 n = type->arr.n;
char *ptr = v;
for (U64 i = 0; i < n; ++i) {
- import_val_ptr(im, ptr, type->arr.of);
+ 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);
+ import_val_ptr(im, (char *)v + f->offset, &f->type, where);
}
} break;
case TYPE_FN:
@@ -567,7 +592,7 @@ static void import_val_ptr(Importer *im, void *v, Type *type) {
} 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);
+ import_val_ptr(im, ptr, type->slice, where);
ptr += item_size;
}
}
@@ -585,10 +610,10 @@ static inline bool export_val(Exporter *ex, Value val, Type *type, Location wher
return export_val_ptr(ex, val_get_ptr(&val, type), type, where);
}
-static inline Value import_val(Importer *im, Type *type) {
+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);
+ import_val_ptr(im, val_get_ptr(&val, type), type, where);
return val;
}
@@ -602,10 +627,10 @@ static inline bool export_optional_val(Exporter *ex, Value *val, Type *type, Loc
}
}
-static inline Value *import_optional_val(Importer *im, Type *type) {
+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);
+ *val = import_val(im, type, where);
return val;
}
return NULL;
@@ -865,7 +890,7 @@ static void import_expr(Importer *im, Expression *e) {
e->binary.rhs = import_expr_(im);
break;
case EXPR_VAL:
- e->val = import_val(im, &e->type);
+ e->val = import_val(im, &e->type, e->where);
break;
case EXPR_TUPLE:
import_arr(im, &e->tuple);
@@ -939,7 +964,7 @@ static void import_expr(Importer *im, Expression *e) {
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);
+ fo->range.stepval = import_optional_val(im, &fo->type, e->where);
} else {
fo->range.step = import_optional_expr(im);
}
@@ -1008,7 +1033,7 @@ static void import_decl(Importer *im, Declaration *d) {
import_type(im, &d->type);
}
if (d->flags & DECL_FOUND_VAL) {
- d->val = import_val(im, &d->type);
+ 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;
diff --git a/std/io.toc b/std/io.toc
index 147834f..e9d73d6 100644
--- a/std/io.toc
+++ b/std/io.toc
@@ -33,4 +33,12 @@ stdout_fwrite ::= fn(data: &u8, size: u64, nmemb: u64) {
#export 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 4274d97..341642f 100644
--- a/test.toc
+++ b/test.toc
@@ -1,16 +1,11 @@
arr ::= pkg "std/arr";
io ::= pkg "std/io";
main ::= fn() {
-#include "incstuff.toc";
- {
- #include "incstuff.toc";
-
- }
- s : [1]char;
- s[0] = (arr.arr_len(x) as char) + '0';
- io.puts(s[:]);
- for c := x.data {
- s[0] = c;
- io.puts(s[:]);
- }
+ 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);
}; \ No newline at end of file
diff --git a/types.c b/types.c
index c5f0d47..0cab515 100644
--- a/types.c
+++ b/types.c
@@ -1123,23 +1123,16 @@ static bool types_expr(Typer *tr, Expression *e) {
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';
- /* TODO: only import packages once */
- Package *pkg = arr_add(&tr->pkgs);
- char *filename = typer_malloc(tr, name_str_len + 6);
+ 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 */
- FILE *fp = fopen(filename, "rb");
- if (!fp) {
- err_print(e->where, "Could not open package: %s (does this file exist?)", filename);
- return false;
- }
- if (!import_pkg(tr->allocr, pkg, fp, filename, tr->err_ctx, e->where)) {
+ 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;
- fclose(fp);
} break;
case EXPR_FOR: {
ForExpr *fo = e->for_;
@@ -2529,7 +2522,7 @@ 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;
- tr->pkgs = NULL;
+ pkgmgr_create(tr->pkgmgr);
tr->fn = NULL;
tr->evalr = ev;
tr->err_ctx = err_ctx;
@@ -2594,10 +2587,3 @@ static bool types_file(Typer *tr, ParsedFile *f) {
}
return ret;
}
-
-static void typer_free(Typer *tr) {
- arr_foreach(tr->pkgs, Package, pkg) {
- package_free(pkg);
- }
- arr_clear(&tr->pkgs);
-}
diff --git a/types.h b/types.h
index 17184ea..e9a2a6e 100644
--- a/types.h
+++ b/types.h
@@ -898,14 +898,19 @@ typedef struct Evaluator {
} Evaluator;
typedef struct Package {
- char *name; /* package name, not file name */
+ char *name;
+ const char *filename;
Identifiers idents;
Statement *stmts;
struct {
- char *prefix; /* prefix for C things (not incl. __) */
+ char *prefix; /* prefix for C things (not including __) */
} c;
} Package;
+typedef struct PackageManager {
+ StrHashTable pkgs;
+} PackageManager;
+
typedef struct Typer {
Allocator *allocr;
Evaluator *evalr;
@@ -920,8 +925,8 @@ typedef struct Typer {
ErrCtx *err_ctx;
/* for checking for problematic struct circular dependencies */
bool *is_reference_stack;
- Package *pkgs; /* all packages which have been imported */
ParsedFile *parsed_file;
+ PackageManager pkgmgr;
} Typer;
typedef struct Exporter {
@@ -949,8 +954,10 @@ typedef struct Importer {
Location import_location;
StructDef *structs;
FnExpr *fns;
+ PackageManager *pkgmgr;
} Importer;
+
typedef struct CGenerator {
Allocator *allocr;
FILE *outc;