diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-13 10:28:00 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-13 10:28:00 -0500 |
commit | 7acba740b69b690faf7db621ae2b7d1cd69d3766 (patch) | |
tree | 1af07bf00dd025af88f832e3ea93a6b0cd074f6a | |
parent | 46e58f70eb8fde8741705d5ae20692187d915cbc (diff) |
more packages
-rw-r--r-- | cgen.c | 36 | ||||
-rw-r--r-- | decls_cgen.c | 8 | ||||
-rw-r--r-- | identifiers.c | 2 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | package.c | 26 | ||||
-rw-r--r-- | point.toc | 13 | ||||
-rw-r--r-- | sdecls_cgen.c | 1 | ||||
-rw-r--r-- | test.toc | 2 | ||||
-rw-r--r-- | types.c | 21 | ||||
-rw-r--r-- | types.h | 5 |
10 files changed, 84 insertions, 33 deletions
@@ -479,7 +479,6 @@ static void cgen_full_fn_name(CGenerator *g, FnExpr *f, U64 instance) { static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) { bool out_param = cgen_uses_ptr(&f->ret_type); bool any_params = false; - char *pkg_name = g->evalr->typer->pkg_name; assert(cgen_should_gen_fn(f)); if (!f->export.id) /* local to this translation unit */ cgen_write(g, "static "); @@ -490,8 +489,8 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instanc cgen_write(g, " "); } if (f->export.id) { - assert(pkg_name); - cgen_write(g, "%s__", pkg_name); + assert(g->pkg_prefix); + cgen_write(g, "%s__", g->pkg_prefix); } cgen_full_fn_name(g, f, instance); if (!out_param) { @@ -1123,6 +1122,8 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { return false; break; case EXPR_VAL: + if (type_is_compileonly(&e->type)) + break; if (!cgen_val_pre(g, e->val, &e->type, e->where)) return false; if (!cgen_type_pre(g, &e->type, e->where)) return false; @@ -1276,13 +1277,20 @@ static bool cgen_expr(CGenerator *g, Expression *e) { handled = true; break; case BINARY_DOT: { - 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(g, e->binary.dot.field->name); - cgen_write(g, ")"); - handled = true; + if (type_is_builtin(&e->binary.lhs->type, BUILTIN_PKG)) { + assert(e->binary.lhs->kind == EXPR_VAL); + cgen_write(g, "%s__", e->binary.lhs->val.pkg->c.prefix); + 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(g, e->binary.dot.field->name); + cgen_write(g, ")"); + handled = true; + } } break; } if (handled) break; @@ -1750,10 +1758,10 @@ static bool cgen_decl(CGenerator *g, Declaration *d) { for (int idx = 0, nidents = (int)arr_len(d->idents); idx < nidents; ++idx) { Identifier i = d->idents[idx]; Type *type = decl_type_at_index(d, idx); - Value *val = decl_val_at_index(d, idx); - if (type_is_compileonly(type)) { - continue; + if (type_is_compileonly(&d->type)) { + continue; } + Value *val = decl_val_at_index(d, idx); if (g->block == NULL && g->fn == NULL && !i->export_name) cgen_write(g, "static "); if (has_expr) { @@ -1964,6 +1972,8 @@ 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 */ diff --git a/decls_cgen.c b/decls_cgen.c index 179d55f..ddb9540 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -160,11 +160,19 @@ static bool cgen_decls_decl(CGenerator *g, Declaration *d) { if (!cgen_type_pre(g, type, d->where)) return false; cgen_write(g, " "); + if (ident->export_name) { + cgen_write(g, "%s__", g->pkg_prefix); + } cgen_ident(g, ident); if (!cgen_type_post(g, type, d->where)) return false; cgen_write(g, ";"); cgen_nl(g); + cgen_write(g, "#define "); + cgen_ident(g, ident); + cgen_write(g, " %s__", g->pkg_prefix); + cgen_ident(g, ident); + cgen_nl(g); } } } diff --git a/identifiers.c b/identifiers.c index 9b9fff0..07b0d74 100644 --- a/identifiers.c +++ b/identifiers.c @@ -100,7 +100,7 @@ static Identifier ident_new_anonymous(Identifiers *ids) { /* advances past identifier */ static Identifier ident_insert(Identifiers *ids, char **s) { size_t nslots = arr_len(ids->slots); - if (nslots <= ids->nidents) { + if (nslots <= 2*ids->nidents) { IdentSlot **slots = ids->slots; /* reserve more space */ IdentSlot **new_slots = NULL; @@ -18,7 +18,6 @@ /* TODO: -compile without -Wno-unused-function packages --- X ::= newtype(int); or something @@ -27,7 +26,7 @@ better printing of types (take was_expr into account) any odd number of "s for a string make sure futurely/currently-declared types are only used by pointer/slice allow omission of trailing ; in foo ::= fn() {}? - */ +*/ #include "toc.c" @@ -292,17 +292,21 @@ static bool export_type(Exporter *ex, Type *type, Location where) { if (!export_type(ex, type->arr.of, where)) return false; break; - case TYPE_FN: - export_len(ex, arr_len(type->fn.types)); + 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); - /* [implied] if (type->fn.constness) */ - possibly_static_assert(sizeof(Constness) == 1); /* future-proofing */ - arr_foreach(type->fn.constness, Constness, c) - export_u8(ex, *c); - break; + + 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; if (struc->export.id == 0) { @@ -373,8 +377,9 @@ static void import_type(Importer *im, Type *type) { import_type(im, &type->fn.types[i]); bool has_constness = import_bool(im); if (has_constness) { - type->fn.constness = imptr_malloc(im, ntypes * sizeof *type->fn.constness); - for (i = 0; i < ntypes; ++i) + 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; @@ -916,6 +921,7 @@ static void export_ident_name(Exporter *ex, Identifier ident) { } static bool export_decl(Exporter *ex, Declaration *d) { + print_location(d->where); assert(ex->started); possibly_static_assert(sizeof d->flags == 2); export_u16(ex, d->flags); @@ -1166,10 +1172,12 @@ static bool import_footer(Importer *im) { 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; } 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; } } @@ -1,5 +1,9 @@ pkg "point"; + +#export Point ::= struct { + x, y: int; +}; bar ::= fn() []int { x:[]int = new(int,20); each p, i := &x { @@ -11,20 +15,19 @@ bar ::= fn() []int { #export x ::= bar(); -#export Point ::= struct { - x, y: int; -}; #export mk_point ::= fn(x, y: int) p : Point { p.x = x; p.y = y; }; + mk_point2 ::= fn(x, y:int) p: Point { p = mk_point(x*x, y*y); }; #export foo ::= fn(x :: int) int { - k : Point = 95; - p:=x[3]; + // k : Point = 95; + // p:=x[3]; }; +#export a:=5;
\ No newline at end of file diff --git a/sdecls_cgen.c b/sdecls_cgen.c index 1b333d6..2fe366c 100644 --- a/sdecls_cgen.c +++ b/sdecls_cgen.c @@ -20,6 +20,7 @@ static bool cgen_sdecls_type(CGenerator *g, Type *type) { /* we've already done this */ } else { cgen_write(g, "struct "); + if (sdef->name->imported) sdef->name = NULL; /* don't use imported names */ if (sdef->name) { cgen_ident(g, sdef->name); } else { @@ -12,5 +12,5 @@ putf ::= fn(x: float) { point ::= pkg "point"; main ::= fn() { - x : point.Point; + x : point.Point = point.mk_point(13, 14); };
\ No newline at end of file @@ -981,12 +981,18 @@ 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'; - Identifier name_ident = ident_insert(tr->idents, &name_cstr); - assert(!*name_cstr); + 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); + 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 */ @@ -1931,7 +1937,18 @@ static bool types_expr(Typer *tr, Expression *e) { Value pkg_val; if (!eval_expr(tr->evalr, lhs, &pkg_val)) return false; + lhs->kind = EXPR_VAL; + 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); + + err_print(e->where, "%s was not imported from package %s.", ident_name, pkg_name); + free(ident_name); + free(pkg_name); + return false; + } if (!type_of_ident(tr, e->where, e->binary.dot.pkg_ident, t)) { return false; } @@ -172,6 +172,7 @@ typedef struct IdentDecl { typedef struct IdentSlot { bool export_name; /* is this identifier's name important? */ bool anonymous; /* is this identifier not part of a tree? */ + bool imported; /* was this identifier imported from a package? */ char *text; /* actual name of the identifier */ size_t len; /* length of name */ U64 export_id; /* 0 if there's no exported identifier here, otherwise unique positive integer associated with this identifier */ @@ -766,6 +767,9 @@ typedef struct Package { Identifier name; Identifiers idents; Statement *stmts; + struct { + char *prefix; /* prefix for C things (not incl. __) */ + } c; } Package; typedef struct Typer { @@ -821,6 +825,7 @@ typedef struct CGenerator { Exporter *exptr; Identifier main_ident; Identifiers *idents; + char *pkg_prefix; } CGenerator; |