summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--cgen.c16
-rw-r--r--decls_cgen.c45
-rw-r--r--package.c2
-rw-r--r--point.toc4
-rw-r--r--types.c18
-rw-r--r--types.h2
7 files changed, 61 insertions, 27 deletions
diff --git a/.gitignore b/.gitignore
index bf94226..a7b3e40 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@ tests/**/*.bin
vgcore*
TAGS
tags
+*.o
diff --git a/cgen.c b/cgen.c
index cdeeec5..e2996de 100644
--- a/cgen.c
+++ b/cgen.c
@@ -12,6 +12,7 @@ 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);
@@ -467,10 +468,18 @@ static bool cgen_should_gen_fn(FnExpr *f) {
}
}
+static void cgen_full_fn_name(CGenerator *g, FnExpr *f, U64 instance) {
+ cgen_fn_name(g, f);
+ if (instance) {
+ cgen_fn_instance_number(g, instance);
+ }
+}
+
/* unless f has const/semi-const args, instance and which_are_const can be set to 0 */
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 ");
@@ -480,10 +489,11 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instanc
if (!cgen_type_pre(g, &f->ret_type, where)) return false;
cgen_write(g, " ");
}
- cgen_fn_name(g, f);
- if (instance) {
- cgen_fn_instance_number(g, instance);
+ if (f->export.id) {
+ assert(pkg_name);
+ cgen_write(g, "%s__", pkg_name);
}
+ cgen_full_fn_name(g, f, instance);
if (!out_param) {
if (!cgen_type_post(g, &f->ret_type, where)) return false;
}
diff --git a/decls_cgen.c b/decls_cgen.c
index 61840a6..94e65df 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -7,6 +7,28 @@ static bool cgen_decls_stmt(CGenerator *g, Statement *s);
static bool cgen_decls_block(CGenerator *g, Block *b);
static bool cgen_decls_decl(CGenerator *g, Declaration *d);
+static bool cgen_fn_decl(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) {
+ if (cgen_should_gen_fn(f)) {
+ if (!fn_enter(f, 0))
+ return false;
+ if (!cgen_fn_header(g, f, where, instance, which_are_const))
+ return false;
+ cgen_write(g, ";");
+ cgen_nl(g);
+ fn_exit(f);
+ char *pkg_name = g->evalr->typer->pkg_name;
+ if (pkg_name && f->export.id) {
+ /* allow use of function without referring to package in this file */
+ cgen_write(g, "#define ");
+ cgen_full_fn_name(g, f, instance);
+ cgen_write(g, " %s__", pkg_name);
+ cgen_full_fn_name(g, f, instance);
+ cgen_nl(g);
+ }
+ }
+ return true;
+}
+
static bool cgen_decls_fn_instances(CGenerator *g, Expression *e) {
assert(e->kind == EXPR_FN);
FnExpr *f = e->fn;
@@ -17,8 +39,7 @@ static bool cgen_decls_fn_instances(CGenerator *g, Expression *e) {
if (cgen_should_gen_fn(&(*data)->fn)) {
(*data)->fn.c.name = f->c.name;
(*data)->fn.c.id = f->c.id;
-
- if (!cgen_fn_header(g, &(*data)->fn, e->where, (*data)->c.id, (*data)->val.tuple[0].u64))
+ if (!cgen_fn_decl(g, &(*data)->fn, e->where, (*data)->c.id, (*data)->val.tuple[0].u64))
return false;
cgen_write(g, ";");
cgen_nl(g);
@@ -42,14 +63,8 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) {
if (!cgen_decls_fn_instances(g, e))
return false;
} else {
- if (cgen_should_gen_fn(e->fn)) {
- fn_enter(e->fn, 0);
- if (!cgen_fn_header(g, e->fn, e->where, 0, 0))
- return false;
- cgen_write(g, ";");
- cgen_nl(g);
- fn_exit(e->fn);
- }
+ if (!cgen_fn_decl(g, e->fn, e->where, 0, 0))
+ return false;
}
} break;
case EXPR_TYPE: {
@@ -108,14 +123,8 @@ static bool cgen_decls_decl(CGenerator *g, Declaration *d) {
if (!cgen_decls_fn_instances(g, &d->expr))
return false;
} else {
- if (cgen_should_gen_fn(d->expr.fn)) {
- fn_enter(d->expr.fn, 0);
- if (!cgen_fn_header(g, d->expr.fn, d->where, 0, 0))
- return false;
- cgen_write(g, ";");
- cgen_nl(g);
- fn_exit(d->expr.fn);
- }
+ if (!cgen_fn_decl(g, d->expr.fn, d->expr.where, 0, 0))
+ return false;
}
cgen_recurse_subexprs(g, (&d->expr), cgen_decls_expr, cgen_decls_block, cgen_decls_decl);
} else {
diff --git a/package.c b/package.c
index bef9a76..f1844b5 100644
--- a/package.c
+++ b/package.c
@@ -110,6 +110,7 @@ static void exptr_start(Exporter *ex, const char *pkg_name, size_t pkg_name_len)
export_u64(ex, 0); /* placeholder for identifier 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) {
@@ -558,6 +559,7 @@ static bool export_struct(Exporter *ex, StructDef *s) {
/* does NOT close the file */
static bool exptr_finish(Exporter *ex) {
long ident_offset = ftell(ex->out);
+
fseek(ex->out, 7L, SEEK_SET);
export_u64(ex, (U64)ident_offset);
fseek(ex->out, 0L, SEEK_END);
diff --git a/point.toc b/point.toc
index ede3c7c..27f58f0 100644
--- a/point.toc
+++ b/point.toc
@@ -8,3 +8,7 @@ pkg "point";
p.x = x;
p.y = y;
};
+
+mk_point2 ::= fn(x, y:int) p: Point {
+ p = mk_point(x*x, y*y);
+}; \ No newline at end of file
diff --git a/types.c b/types.c
index 50da073..a0c3c1a 100644
--- a/types.c
+++ b/types.c
@@ -2116,6 +2116,7 @@ static void typer_create(Typer *tr, Evaluator *ev, Allocator *allocr) {
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;
*(Block **)arr_adda(&tr->blocks, allocr) = NULL;
}
@@ -2137,13 +2138,18 @@ static bool types_file(Typer *tr, ParsedFile *f, char *code) {
return false;
Slice pkg_name_slice = pkg_name.slice;
char *pkg_name_str = pkg_name_slice.data;
- I64 pkg_name_len = pkg_name_slice.n;
- if (pkg_name_len < 0) {
- err_print(f->pkg_name->where, "Package name has a negative length (" I64_FMT ")!", pkg_name_len);
+ 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;
}
- char *pkg_file_name = err_malloc((size_t)pkg_name_len+5);
- sprintf(pkg_file_name, "%s.top", pkg_name_str);
+ 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 = err_malloc(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);
@@ -2152,7 +2158,7 @@ static bool types_file(Typer *tr, ParsedFile *f, char *code) {
}
free(pkg_file_name);
exptr_create(tr->exptr, pkg_fp, code);
- exptr_start(tr->exptr, pkg_name_str, (size_t)pkg_name_len);
+ exptr_start(tr->exptr, pkg_name_str, pkg_name_len);
}
arr_foreach(f->stmts, Statement, s) {
if (!types_stmt(tr, s)) {
diff --git a/types.h b/types.h
index a612368..8979475 100644
--- a/types.h
+++ b/types.h
@@ -755,6 +755,7 @@ 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;
} Typer;
@@ -779,6 +780,7 @@ 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;
} CGenerator;