From 1de39ba1ffdacf6841f925537b31b32a4101b632 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 14 Jan 2020 20:00:19 -0500 Subject: extern variable declarations --- cgen.c | 2 +- decls_cgen.c | 31 +++++++++++++++++++++++++++++++ identifiers.c | 1 + location.c | 2 +- main.c | 5 +++-- package.c | 6 +++--- parse.c | 23 ++++++++++++++++------- point.sh | 8 ++++---- scope.c | 1 + test.toc | 1 + types.h | 2 +- 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; -- cgit v1.2.3