From dd3c2aa388026afcbcb987d9944c6f7207fb2d2c Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Thu, 16 Jan 2020 20:34:41 -0500 Subject: better packages. also started std/io pkg (wrote hello world in toc!) --- a.toc | 27 --------------------------- eval.c | 2 +- package.c | 28 +++++++++++++++------------- parse.c | 7 ++----- pkg.sh | 11 ++++++++--- std/arr.c | 23 +++++++++++++++++++++++ std/arr.toc | 27 +++++++++++++++++++++++++++ std/io.c | 42 ++++++++++++++++++++++++++++++++++++++++++ std/io.toc | 14 ++++++++++++++ test.toc | 15 ++++----------- types.c | 51 +++++++++++++++++++-------------------------------- types.h | 11 +++++------ 12 files changed, 160 insertions(+), 98 deletions(-) delete mode 100644 a.toc create mode 100644 std/arr.c create mode 100644 std/arr.toc create mode 100644 std/io.c create mode 100644 std/io.toc diff --git a/a.toc b/a.toc deleted file mode 100644 index b282224..0000000 --- a/a.toc +++ /dev/null @@ -1,27 +0,0 @@ -// array package -pkg "a"; - -#export Arr ::= fn (t :: Type) Type { - struct { - data : []t; - len, cap : int; - } -}; -#export arr_add ::= fn(t ::=, a : &Arr(t), x : t) { - if a.len >= a.cap { - a.cap = a.cap * 2 + 2; - new_data := new(t, a.cap); - each i := 0..a.len-1 { - new_data[i] = a.data[i]; - } - a.data = new_data; - } - a.data[a.len] = x; - a.len += 1; -}; - -#export arr_foreach ::= fn(t ::=, a : Arr(t), f : fn(&t)) { - each i := 0..a.len-1 { - f(&a.data[i]); - } -}; diff --git a/eval.c b/eval.c index e53f0e1..085e3f8 100644 --- a/eval.c +++ b/eval.c @@ -1556,7 +1556,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { *v = e->val; break; case EXPR_PKG: - v->pkg = e->pkg.name_ident->pkg; + assert(0); break; } return true; diff --git a/package.c b/package.c index bacd70e..38f8e26 100644 --- a/package.c +++ b/package.c @@ -15,7 +15,9 @@ static void import_expr(Importer *im, Expression *e); static void import_block(Importer *im, Block *b); static inline Expression *import_expr_(Importer *im); + static void exptr_create(Exporter *ex, FILE *out) { + /* construct full filename */ ex->out = out; ex->ident_id = 0; ex->exported_fns = NULL; @@ -203,7 +205,7 @@ 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, Identifiers *parent_idents, ErrCtx *parent_ctx, Location where) { +static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname, ErrCtx *parent_ctx, Location where) { Importer i = {0}; ErrCtx *err_ctx = i.err_ctx = allocr_malloc(allocr, sizeof *i.err_ctx); idents_create(&p->idents); @@ -235,7 +237,10 @@ static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname 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 = ident_get(parent_idents, pkg_name); + 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); @@ -438,10 +443,9 @@ static bool export_val_ptr(Exporter *ex, void *v, Type *type, Location where) { if (!export_type(ex, *(Type **)v, where)) return false; break; - case BUILTIN_PKG: { - Package *pkg = *(Package **)v; - export_ident(ex, pkg->name); - } break; + case BUILTIN_PKG: + /* TODO */ + break; } break; case TYPE_TUPLE: { @@ -736,12 +740,9 @@ static bool export_expr(Exporter *ex, Expression *e) { return false; } break; case EXPR_PKG: - if (found_type) { - export_ident(ex, e->pkg.name_ident); - } else { - if (!export_expr(ex, e->pkg.name_expr)) - return false; - } + assert(!found_type); + if (!export_expr(ex, e->pkg.name_expr)) + return false; break; case EXPR_SLICE: { SliceExpr *s = &e->slice; @@ -886,7 +887,8 @@ static void import_expr(Importer *im, Expression *e) { import_block(im, &w->body); } break; case EXPR_PKG: - /* TODO (see also: val) */ + assert(!found_type); + e->pkg.name_expr = import_expr_(im); break; case EXPR_SLICE: { SliceExpr *s = &e->slice; diff --git a/parse.c b/parse.c index cb105ab..6cd14ed 100644 --- a/parse.c +++ b/parse.c @@ -2247,11 +2247,8 @@ static void fprint_expr(FILE *out, Expression *e) { break; case EXPR_PKG: fprintf(out, "(pkg "); - if (found_type) { - fprint_ident(out, e->pkg.name_ident); - } else { - fprint_expr(out, e->pkg.name_expr); - } + assert(!found_type); + fprint_expr(out, e->pkg.name_expr); fprintf(out, ")"); break; } diff --git a/pkg.sh b/pkg.sh index b86c1ca..5f1d847 100755 --- a/pkg.sh +++ b/pkg.sh @@ -1,5 +1,10 @@ #!/bin/sh -valgrind -q ./toc $1.toc -o $1.c || exit 1 -valgrind -q ./toc test.toc || exit 1 -gcc out.c $1.c || exit 1 +std_things="io arr" +cd std +for thing in $std_things; do + valgrind --track-origins=yes --exit-on-first-error=yes --error-exitcode=1 -q ../toc $thing.toc -o $thing.c || exit 1 +done +cd .. +valgrind --track-origins=yes --exit-on-first-error=yes --error-exitcode=1 -q ./toc test.toc || exit 1 +gcc out.c std/*.c || exit 1 ./a.out diff --git a/std/arr.c b/std/arr.c new file mode 100644 index 0000000..2d2c03a --- /dev/null +++ b/std/arr.c @@ -0,0 +1,23 @@ +#include +#include +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef float f32; +typedef double f64; +typedef u8 bool; +typedef struct { void *data; i64 n; } slice_; +#define false ((bool)0) +#define true ((bool)1) +static slice_ mkslice_(void *data, i64 n) { slice_ ret; ret.data = data; ret.n = n; return ret; } +static void free_(void *data) { extern void free(void *data); free(data); } +static void *e__calloc(size_t n, size_t sz) { extern void *calloc(size_t n, size_t size); extern void abort(void); void *ret = calloc(n, sz); if (n && sz && !ret) { fprintf(stderr, "Out of memory.\n"); abort(); } return ret; } + + +/* declarations */ +/* code */ diff --git a/std/arr.toc b/std/arr.toc new file mode 100644 index 0000000..fcf6a45 --- /dev/null +++ b/std/arr.toc @@ -0,0 +1,27 @@ +// array package +pkg "arr"; + +#export Arr ::= fn (t :: Type) Type { + struct { + data : []t; + len, cap : int; + } +}; +#export arr_add ::= fn(t ::=, a : &Arr(t), x : t) { + if a.len >= a.cap { + a.cap = a.cap * 2 + 2; + new_data := new(t, a.cap); + each i := 0..a.len-1 { + new_data[i] = a.data[i]; + } + a.data = new_data; + } + a.data[a.len] = x; + a.len += 1; +}; + +#export arr_foreach ::= fn(t ::=, a : Arr(t), f : fn(&t)) { + each i := 0..a.len-1 { + f(&a.data[i]); + } +}; diff --git a/std/io.c b/std/io.c new file mode 100644 index 0000000..97d5d43 --- /dev/null +++ b/std/io.c @@ -0,0 +1,42 @@ +#include +#include +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef float f32; +typedef double f64; +typedef u8 bool; +typedef struct { void *data; i64 n; } slice_; +#define false ((bool)0) +#define true ((bool)1) +static slice_ mkslice_(void *data, i64 n) { slice_ ret; ret.data = data; ret.n = n; return ret; } +static void free_(void *data) { extern void free(void *data); free(data); } +static void *e__calloc(size_t n, size_t sz) { extern void *calloc(size_t n, size_t size); extern void abort(void); void *ret = calloc(n, sz); if (n && sz && !ret) { fprintf(stderr, "Out of memory.\n"); abort(); } return ret; } + + +/* declarations */ +void io__puti(i64 x); +void io__putf(f32 x); +void io__puts(slice_ x); +/* code */ +void io__puti(i64 x) { + printf("%ld\n", (long)x); +} + + +void io__putf(f32 x) { + printf("%f\n", (double)x); +} + + +void io__puts(slice_ x) { + fwrite(x.data, 1, x.n, stdout); + printf("\n"); +} + + diff --git a/std/io.toc b/std/io.toc new file mode 100644 index 0000000..68e9744 --- /dev/null +++ b/std/io.toc @@ -0,0 +1,14 @@ +pkg "io"; + +#export puti ::= fn(x: int) { + #C("printf(\"%ld\\n\", (long)x)"); +}; + +#export putf ::= fn(x: float) { + #C("printf(\"%f\\n\", (double)x)"); +}; + +#export puts ::= fn(x: []char) { + #C("fwrite(x.data, 1, x.n, stdout)"); + #C("printf(\"\\n\")"); +}; \ No newline at end of file diff --git a/test.toc b/test.toc index 759f19b..2770b9e 100644 --- a/test.toc +++ b/test.toc @@ -1,19 +1,12 @@ -puti ::= fn(x: int) { - #C("printf(\"%ld\\n\", (long)x); -"); -}; -putf ::= fn(x: float) { - #C("printf(\"%f\\n\", (double)x); -"); -}; - -arr ::= pkg "a"; +arr ::= pkg "std/arr"; +io ::= pkg "std/io"; putptri ::= fn(x: &int) { - puti(*x); + io.puti(*x); }; main ::= fn() { + io.puts("Hello, world!"); x : arr.Arr(int); arr.arr_add(&x, 10); arr.arr_add(&x, 20); diff --git a/types.c b/types.c index dba9820..c6ab0d3 100644 --- a/types.c +++ b/types.c @@ -981,33 +981,23 @@ 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'; - char *name_ptr = name_cstr; - Identifier name_ident = ident_insert(tr->idents, &name_ptr); - if (*name_ptr) { - err_print(name_expr->where, "Package name (\"%s\") is not a valid identifier.", - name_cstr); + /* TODO: only import packages once */ + Package *pkg = arr_add(&tr->pkgs); + 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; } - e->pkg.name_ident = name_ident; - if (!name_ident->pkg) { - char *filename = typer_malloc(tr, name_str_len + 5); - Package *pkg = name_ident->pkg = err_calloc(1, sizeof *pkg); - pkg->c.prefix = name_cstr; - memcpy(filename, name_str.data, name_str_len); - strcpy(filename + name_str.n, ".top"); - /* TODO: library paths */ - FILE *fp = fopen(filename, "rb"); - if (!fp) { - err_print(e->where, "Could not open package: %s (does this file exist?)", filename); - free(filename); - return false; - } - if (!import_pkg(tr->allocr, pkg, fp, filename, tr->idents, tr->err_ctx, e->where)) { - return false; - } - *(Package **)arr_add(&tr->pkgs) = pkg; - fclose(fp); + if (!import_pkg(tr->allocr, pkg, fp, filename, tr->err_ctx, e->where)) { + return false; } + e->kind = EXPR_VAL; + e->val.pkg = pkg; + fclose(fp); } break; case EXPR_EACH: { EachExpr *ea = e->each; @@ -1923,6 +1913,7 @@ static bool types_expr(Typer *tr, Expression *e) { case BINARY_DOT: { if (!types_expr(tr, lhs)) return false; Type *struct_type = lhs_type; + if (struct_type->kind == TYPE_UNKNOWN) return true; 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.", @@ -1936,12 +1927,10 @@ static bool types_expr(Typer *tr, Expression *e) { lhs->val = pkg_val; e->binary.dot.pkg_ident = ident_translate(rhs->ident, &pkg_val.pkg->idents); if (!e->binary.dot.pkg_ident) { - char *ident_name = ident_to_str(rhs->ident), - *pkg_name = ident_to_str(pkg_val.pkg->name); + char *ident_name = ident_to_str(rhs->ident); - err_print(e->where, "%s was not imported from package %s.", ident_name, pkg_name); + err_print(e->where, "%s was not imported from package %s.", ident_name, pkg_val.pkg->name); free(ident_name); - free(pkg_name); return false; } if (!type_of_ident(tr, e->where, e->binary.dot.pkg_ident, t)) { @@ -2367,10 +2356,8 @@ static bool types_file(Typer *tr, ParsedFile *f) { } static void typer_free(Typer *tr) { - typedef Package *PackagePtr; - arr_foreach(tr->pkgs, PackagePtr, pkg) { - package_free(*pkg); - free(*pkg); + arr_foreach(tr->pkgs, Package, pkg) { + package_free(pkg); } arr_clear(&tr->pkgs); } diff --git a/types.h b/types.h index ff80575..6fb68c2 100644 --- a/types.h +++ b/types.h @@ -660,10 +660,9 @@ typedef struct Expression { struct { Type type; } del; - union { - struct Expression *name_expr; /* before typing */ - Identifier name_ident; /* after typing */ - } pkg; + struct { + struct Expression *name_expr; + } pkg; /* only can exist before typing */ IfExpr if_; WhileExpr while_; EachExpr *each; @@ -769,7 +768,7 @@ typedef struct Evaluator { } Evaluator; typedef struct Package { - Identifier name; + char *name; /* package name, not file name */ Identifiers idents; Statement *stmts; struct { @@ -791,7 +790,7 @@ 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 */ + Package *pkgs; /* all packages which have been imported */ } Typer; typedef struct Exporter { -- cgit v1.2.3