summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-13 10:28:00 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-13 10:28:00 -0500
commit7acba740b69b690faf7db621ae2b7d1cd69d3766 (patch)
tree1af07bf00dd025af88f832e3ea93a6b0cd074f6a
parent46e58f70eb8fde8741705d5ae20692187d915cbc (diff)
more packages
-rw-r--r--cgen.c36
-rw-r--r--decls_cgen.c8
-rw-r--r--identifiers.c2
-rw-r--r--main.c3
-rw-r--r--package.c26
-rw-r--r--point.toc13
-rw-r--r--sdecls_cgen.c1
-rw-r--r--test.toc2
-rw-r--r--types.c21
-rw-r--r--types.h5
10 files changed, 84 insertions, 33 deletions
diff --git a/cgen.c b/cgen.c
index 1236148..f43d468 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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;
diff --git a/main.c b/main.c
index f5a7398..f508e74 100644
--- a/main.c
+++ b/main.c
@@ -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"
diff --git a/package.c b/package.c
index 7024bd8..bf0ae54 100644
--- a/package.c
+++ b/package.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;
}
}
diff --git a/point.toc b/point.toc
index 57be671..643a9f8 100644
--- a/point.toc
+++ b/point.toc
@@ -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 {
diff --git a/test.toc b/test.toc
index f557425..1adf562 100644
--- a/test.toc
+++ b/test.toc
@@ -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
diff --git a/types.c b/types.c
index 07b46d9..2d6f6d4 100644
--- a/types.c
+++ b/types.c
@@ -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;
}
diff --git a/types.h b/types.h
index 4bea917..4ee9a44 100644
--- a/types.h
+++ b/types.h
@@ -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;