summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-14 20:00:19 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-14 20:00:19 -0500
commit1de39ba1ffdacf6841f925537b31b32a4101b632 (patch)
treeb321ca376cc9693136e609fa88aaaca3acc7afa3
parent62349b1f6d9f5948f856e26e3b0eef19567198fa (diff)
extern variable declarations
-rw-r--r--cgen.c2
-rw-r--r--decls_cgen.c31
-rw-r--r--identifiers.c1
-rw-r--r--location.c2
-rw-r--r--main.c5
-rw-r--r--package.c6
-rw-r--r--parse.c23
-rwxr-xr-xpoint.sh8
-rw-r--r--scope.c1
-rw-r--r--test.toc1
-rw-r--r--types.h2
11 files changed, 63 insertions, 19 deletions
diff --git a/cgen.c b/cgen.c
index 0c955e0..03f828d 100644
--- a/cgen.c
+++ b/cgen.c
@@ -254,7 +254,7 @@ static void cgen_ident_id(CGenerator *g, IdentID id) {
cgen_write(g, "a%lu_", (unsigned long)id);
}
-/* should declaration be a direct function declaration C (as opposed to using a function pointer or not being a function) */
+/* should this declaration be a direct function declaration C? (as opposed to using a function pointer or not being a function) */
static bool cgen_fn_is_direct(CGenerator *g, Declaration *d) {
return g->block == NULL && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1;
}
diff --git a/decls_cgen.c b/decls_cgen.c
index 32bc3f1..278971f 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -101,6 +101,37 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) {
case EXPR_CAST:
if (!cgen_decls_type(g, &e->cast.type))
return false;
+ break;
+ case EXPR_BINARY_OP: {
+ Type *lhs_type = &e->binary.lhs->type;
+ if (lhs_type->kind == TYPE_PTR)
+ lhs_type = lhs_type->ptr;
+ if (e->binary.op == BINARY_DOT && type_is_builtin(lhs_type, BUILTIN_PKG)) {
+ assert(e->binary.lhs->kind == EXPR_VAL);
+ Identifier ident = e->binary.dot.pkg_ident;
+ IdentDecl *idecl = ident_decl(ident);
+ assert(idecl);
+
+ if (idecl->kind == IDECL_DECL) {
+ Declaration *d = idecl->decl;
+ if (((d->flags & DECL_FOUND_VAL) && e->type.kind == TYPE_FN)
+ || (d->expr.kind == EXPR_FN)) {
+ /* extern function declaration */
+ break;
+ }
+ }
+ /* extern variable declaration */
+ cgen_write(g, "extern ");
+ if (!cgen_type_pre(g, &e->type, e->where))
+ return false;
+ cgen_write(g, " %s__", e->binary.lhs->val.pkg->c.prefix);
+ cgen_ident(g, ident);
+ if (!cgen_type_post(g, &e->type, e->where))
+ return false;
+ cgen_write(g, ";");
+ cgen_nl(g);
+ }
+ } break;
default:
break;
}
diff --git a/identifiers.c b/identifiers.c
index 6d1506d..c5a4ec1 100644
--- a/identifiers.c
+++ b/identifiers.c
@@ -56,6 +56,7 @@ static bool ident_str_eq_str(const char *s, const char *t) {
}
static inline bool ident_eq_str(Identifier i, const char *s) {
+ if (i->anonymous) return false;
return ident_str_eq_str(i->text, s);
}
diff --git a/location.c b/location.c
index 35952de..21e686e 100644
--- a/location.c
+++ b/location.c
@@ -10,7 +10,7 @@ static Location const LOCATION_NONE = {0};
static void fprint_location(FILE *out, Location location) {
if (!location.start) {
if (location.simple_location) {
- fprintf(out, "Line %lu of %s\n", (unsigned long)location.simple_location->line, location.simple_location->ctx->filename);
+ fprintf(out, "Line %lu of %s", (unsigned long)location.simple_location->line, location.simple_location->ctx->filename);
} else {
fprintf(out, "No location available.");
}
diff --git a/main.c b/main.c
index f508e74..1da2fd2 100644
--- a/main.c
+++ b/main.c
@@ -19,6 +19,7 @@
/*
TODO:
packages
+make sure (&Package).something works
---
X ::= newtype(int); or something
don't allow while {3; 5} (once break is added)
@@ -129,8 +130,8 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
#ifdef TOC_DEBUG
- printf("\n\n");
- fprint_parsed_file(stdout, &f);
+ /* printf("\n\n"); */
+ /* fprint_parsed_file(stdout, &f); */
#endif
FILE *out = fopen(out_filename, "w");
if (!out) {
diff --git a/package.c b/package.c
index fbb59be..2c645f4 100644
--- a/package.c
+++ b/package.c
@@ -152,7 +152,7 @@ static Location import_location(Importer *im) {
Location l;
l.start = NULL;
l.simple_location = imptr_malloc(im, sizeof *l.simple_location);
- l.simple_location->ctx = &im->err_ctx;
+ l.simple_location->ctx = im->err_ctx;
l.simple_location->line = (U32)import_vlq(im);
return l;
}
@@ -202,7 +202,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) {
Importer i = {0};
- ErrCtx *err_ctx = &i.err_ctx;
+ ErrCtx *err_ctx = i.err_ctx = allocr_malloc(allocr, sizeof *i.err_ctx);
idents_create(&p->idents);
i.pkg = p;
i.in = f;
@@ -921,7 +921,6 @@ 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);
@@ -977,6 +976,7 @@ static void import_decl(Importer *im, Declaration *d) {
d->expr.kind = EXPR_VAL;
d->expr.val = d->val;
}
+ d->flags &= (DeclFlags)~(DeclFlags)DECL_HAS_EXPR;
} else if (d->flags & DECL_HAS_EXPR) {
import_expr(im, &d->expr);
}
diff --git a/parse.c b/parse.c
index 288087c..cb105ab 100644
--- a/parse.c
+++ b/parse.c
@@ -2339,6 +2339,12 @@ static inline Type *decl_type_at_index(Declaration *d, int i) {
return ret;
}
+static bool ident_is_definitely_const(Identifier i) {
+ IdentDecl *idecl = ident_decl(i);
+ assert(idecl);
+ return idecl->kind == IDECL_DECL && (idecl->decl->flags & DECL_IS_CONST);
+}
+
static bool expr_is_definitely_const(Expression *e) {
switch (e->kind) {
@@ -2366,18 +2372,21 @@ static bool expr_is_definitely_const(Expression *e) {
return expr_is_definitely_const(e->unary.of);
case EXPR_BINARY_OP:
if (e->binary.op == BINARY_DOT) {
- return expr_is_definitely_const(e->binary.lhs);
+ if (!expr_is_definitely_const(e->binary.lhs))
+ return false;
+ Type *lhs_type = &e->binary.lhs->type;
+ if (lhs_type->kind == TYPE_PTR) lhs_type = lhs_type->ptr;
+ if (type_is_builtin(lhs_type, BUILTIN_PKG)) {
+ return ident_is_definitely_const(e->binary.dot.pkg_ident);
+ }
+ return true;
}
return expr_is_definitely_const(e->binary.lhs)
&& expr_is_definitely_const(e->binary.rhs);
case EXPR_SLICE:
return expr_is_definitely_const(e->slice.of);
- case EXPR_IDENT: {
- IdentDecl *idecl = ident_decl(e->ident);
- assert(idecl);
- return idecl->kind == IDECL_DECL
- && (idecl->decl->flags & DECL_IS_CONST);
- }
+ case EXPR_IDENT:
+ return ident_is_definitely_const(e->ident);
}
assert(0);
return false;
diff --git a/point.sh b/point.sh
index 4b5f3a5..8156f68 100755
--- a/point.sh
+++ b/point.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-valgrind -q ./toc point.toc -o point.c
-valgrind -q ./toc test.toc
-gcc point.c out.c -o a.out
-./a.out
+valgrind -q ./toc point.toc -o point.c || exit 1
+valgrind -q ./toc test.toc || exit 1
+gcc point.c out.c -o a.out -O0 -g || exit 1
+./a.out || exit 1
diff --git a/scope.c b/scope.c
index 92e2b40..0b583fa 100644
--- a/scope.c
+++ b/scope.c
@@ -27,6 +27,7 @@ static bool DEBUG_UNDERSCORE(add_ident_decls)(SOURCE_LOCATION_PARAMS Block *b, D
continue;
}
}
+
IdentDecl *idecl = ident_add_decl(*ident, d, b);
#ifdef TOC_DEBUG
idecl->src_file = src_file;
diff --git a/test.toc b/test.toc
index 168d124..79e07e8 100644
--- a/test.toc
+++ b/test.toc
@@ -12,4 +12,5 @@ point ::= pkg "point";
main ::= fn() {
x : point.Point = point.mk_point(y = 13, 14);
puti(x.x + x.y);
+ point.x = new(int,10);
}; \ No newline at end of file
diff --git a/types.h b/types.h
index ba48e59..86a0a31 100644
--- a/types.h
+++ b/types.h
@@ -805,7 +805,7 @@ typedef struct Importer {
Package *pkg;
Allocator *allocr;
Identifier *ident_map; /* [i] = value of identifier with ID i */
- ErrCtx err_ctx;
+ ErrCtx *err_ctx;
Declaration *decls;
size_t max_ident_id;
Location import_location;