summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-05 00:27:44 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-05 00:27:44 -0500
commit0fff6ef4013795e90322343f30fc144e7e422d9b (patch)
tree48cced164f021d92a263b5e46103aa90c99b4ec9
parent6cd1d263377dedb49510b65fd983552bc1b40cb3 (diff)
exporting identifiers
-rw-r--r--eval.c2
-rw-r--r--identifiers.c71
-rw-r--r--main.c12
-rw-r--r--package.c44
-rw-r--r--parse.c10
-rw-r--r--test.toc2
-rw-r--r--tokenizer.c2
-rw-r--r--types.h5
8 files changed, 83 insertions, 65 deletions
diff --git a/eval.c b/eval.c
index 66995ce..c022699 100644
--- a/eval.c
+++ b/eval.c
@@ -338,7 +338,7 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) {
arr_foreach(t->struc->fields, Field, fi) {
if (fi != t->struc->fields)
fprintf(f, ", ");
- fprint_ident(f, fi->name);
+ fprint_ident_debug(f, fi->name);
fprintf(f, ": ");
fprint_val_ptr(f, (char *)p + fi->offset, fi->type);
}
diff --git a/identifiers.c b/identifiers.c
index c40d360..a7750a7 100644
--- a/identifiers.c
+++ b/identifiers.c
@@ -41,7 +41,6 @@ static Identifier ident_new(Identifiers *ids, Identifier parent, unsigned char i
if (parent)
tree->depth = (uint16_t)(parent->depth + 1);
tree->index_in_parent = index_in_parent;
- tree->id = 0;
return tree;
}
@@ -71,8 +70,6 @@ static Identifier ident_insert(Identifiers *ids, char **s) {
IdentTree *tree = ids->root;
while (1) {
if (!isident(**s)) {
- if (!tree->id)
- tree->id = ++ids->nidents;
return tree;
}
int c = ident_char_to_uchar(**s);
@@ -92,32 +89,43 @@ static Identifier ident_insert(Identifiers *ids, char **s) {
}
}
+static inline size_t ident_len(Identifier i) {
+ return (size_t)(i->depth / 2);
+}
-static void fprint_ident(FILE *out, Identifier id) {
- Identifier i = id;
- size_t chars = 0;
- while (i->parent) {
- i = i->parent->parent; /* to go up one character, we need to go to the grandparent */
- ++chars;
- }
- printf("%lu-",(unsigned long)id->id);
- char *s = malloc(chars + 1);
- char *p = s + chars;
- i = id;
- *p-- = '\0';
+static char *ident_to_str(Identifier i) {
+ size_t i_len = ident_len(i);
+ char *str = err_malloc(i_len + 1);
+ str += i_len;
+ *str = 0;
while (i->parent) {
- int c_low = i->parent->index_in_parent;
- int c_high = i->index_in_parent;
- char c = (char)ident_uchar_to_char(c_low + (c_high << 4));
- *p-- = c;
- i = i->parent->parent;
+ --str;
+ unsigned char c_high = i->index_in_parent;
+ unsigned char c_low = i->parent->index_in_parent;
+ char c = (char)ident_uchar_to_char((int)c_low + ((int)c_high << 4));
+ *str = c;
+ i = i->parent->parent; /* go to grandparent (prev char) */
}
- fprintf(out, "%s", s);
- free(s);
+
+ return str;
+}
+
+static void fprint_ident(FILE *out, Identifier id) {
+ char *str = ident_to_str(id);
+ fprintf(out, "%s", str);
+ free(str);
+}
+
+static void fprint_ident_debug(FILE *out, Identifier id) {
+#ifdef TOC_DEBUG
+ if (id->export_id)
+ printf(U64_FMT "-", id->export_id);
+#endif
+ fprint_ident(out, id);
}
static void print_ident(Identifier id) {
- fprint_ident(stdout, id);
+ fprint_ident_debug(stdout, id);
printf("\n");
}
@@ -154,23 +162,6 @@ static Identifier ident_get(Identifiers *ids, const char *s) {
return tree;
}
-static char *ident_to_str(Identifier i) {
- size_t i_len = (size_t)(i->depth / 2); /* length = depth / 2 */
- char *str = err_malloc(i_len + 1);
- str += i_len;
- *str = 0;
- while (i->parent) {
- --str;
- unsigned char c_high = i->index_in_parent;
- unsigned char c_low = i->parent->index_in_parent;
- char c = (char)ident_uchar_to_char((int)c_low + ((int)c_high << 4));
- *str = c;
- i = i->parent->parent; /* go to grandparent (prev char) */
- }
-
- return str;
-}
-
static IdentDecl *ident_add_decl(Identifier i, struct Declaration *d, struct Block *b) {
IdentDecl *id_decl = arr_add(&i->decls);
id_decl->decl = d;
diff --git a/main.c b/main.c
index e9d7bd5..bcdec84 100644
--- a/main.c
+++ b/main.c
@@ -78,15 +78,15 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
fclose(in);
- Identifiers file_idents;
- idents_create(&file_idents);
+ Identifiers idents;
+ idents_create(&idents);
Tokenizer t;
Allocator main_allocr;
allocr_create(&main_allocr);
ErrCtx err_ctx = {0};
err_ctx.filename = in_filename;
err_ctx.enabled = true;
- tokr_create(&t, &file_idents, &err_ctx, &main_allocr);
+ tokr_create(&t, &idents, &err_ctx, &main_allocr);
if (!tokenize_string(&t, contents)) {
err_fprint(TEXT_IMPORTANT("Errors occured while preprocessing.\n"));
@@ -127,8 +127,6 @@ int main(int argc, char **argv) {
exptr_create(&exptr, out_pkg);
exptr.export_locations = false;
exptr_start(&exptr, contents);
- /* export_len(&exptr, 1782); */
- /* export_u8(&exptr, 0xab); */
#endif
if (!block_enter(NULL, f.stmts, SCOPE_CHECK_REDECL)) /* enter global scope */
return false;
@@ -156,7 +154,7 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
CGenerator g;
- cgen_create(&g, out, &file_idents, &ev, &main_allocr);
+ cgen_create(&g, out, &idents, &ev, &main_allocr);
if (!cgen_file(&g, &f)) {
fclose(out);
err_fprint(TEXT_IMPORTANT("Errors occured while generating C code.\n"));
@@ -170,7 +168,7 @@ int main(int argc, char **argv) {
evalr_free(&ev);
fclose(out);
- idents_free(&file_idents);
+ idents_free(&idents);
return 0;
}
diff --git a/package.c b/package.c
index 204a925..a050d90 100644
--- a/package.c
+++ b/package.c
@@ -10,6 +10,15 @@ static bool export_decl(Exporter *ex, Declaration *d);
static bool export_block(Exporter *ex, Block *b);
static bool export_expr(Exporter *ex, Expression *e);
+static void exptr_create(Exporter *ex, FILE *out) {
+ ex->out = out;
+ ex->ident_id = 0;
+ ex->export_locations = true;
+ ex->exported_fns = NULL;
+ ex->exported_structs = NULL;
+ ex->exported_idents = NULL;
+}
+
static inline void export_u8(Exporter *ex, U8 u8) {
write_u8(ex->out, u8);
}
@@ -67,8 +76,10 @@ static void export_location(Exporter *ex, Location where) {
}
static inline void export_ident(Exporter *ex, Identifier i) {
- assert(i->id);
- export_vlq(ex, (U64)i->id);
+ if (!i->export_id) {
+ i->export_id = ++ex->ident_id;
+ }
+ export_vlq(ex, i->export_id);
}
static inline void export_optional_ident(Exporter *ex, Identifier i) {
@@ -83,13 +94,6 @@ static inline void export_len(Exporter *ex, size_t len) {
export_vlq(ex, (U64)len);
}
-static void exptr_create(Exporter *ex, FILE *out) {
- ex->out = out;
- ex->export_locations = true;
- ex->exported_fns = NULL;
- ex->exported_structs = NULL;
-}
-
/* writes the header */
static void exptr_start(Exporter *ex, char *code) {
const U8 toc[3] = {116, 111, 99}; /* "toc" in ASCII */
@@ -440,6 +444,16 @@ static bool export_decl(Exporter *ex, Declaration *d) {
err_print(d->where, "Can't export declaration of unknown type.");
return false;
}
+ if (d->flags & DECL_EXPORT) {
+ arr_foreach(d->idents, Identifier, ident) {
+ if (!(*ident)->export_name) {
+ Identifier *iptr = arr_add(&ex->exported_idents);
+ *iptr = *ident;
+ (*ident)->export_name = true;
+ }
+ }
+ }
+
export_location(ex, d->where);
export_len(ex, arr_len(d->idents));
arr_foreach(d->idents, Identifier, ident) {
@@ -533,6 +547,15 @@ static bool export_struct(Exporter *ex, StructDef *s) {
/* does NOT close the file */
static bool exptr_finish(Exporter *ex) {
+ export_len(ex, arr_len(ex->exported_idents));
+ arr_foreach(ex->exported_idents, Identifier, ident) {
+ Identifier i = *ident;
+ assert(i->export_name);
+ export_vlq(ex, i->export_id);
+ export_len(ex, ident_len(i));
+ fprint_ident(ex->out, i);
+ }
+
export_len(ex, arr_len(ex->exported_fns));
typedef FnExpr *FnExprPtr;
arr_foreach(ex->exported_fns, FnExprPtr, f) {
@@ -551,5 +574,8 @@ static bool exptr_finish(Exporter *ex) {
if (ferror(ex->out)) {
warn_print(LOCATION_NONE, "An error occured while writing the package output. It may be incorrect.");
}
+
+ arr_clear(&ex->exported_idents);
+
return true;
}
diff --git a/parse.c b/parse.c
index 6776d95..b754f3f 100644
--- a/parse.c
+++ b/parse.c
@@ -2026,7 +2026,7 @@ static void fprint_args(FILE *out, Argument *args) {
arr_foreach(args, Argument, arg) {
if (arg != args) fprintf(out, ", ");
if (arg->name) {
- fprint_ident(out, arg->name);
+ fprint_ident_debug(out, arg->name);
fprintf(out, " = ");
}
fprint_expr(out, &arg->val);
@@ -2065,7 +2065,7 @@ static void fprint_expr(FILE *out, Expression *e) {
fprint_char_literal(out, e->charl);
break;
case EXPR_IDENT:
- fprint_ident(out, e->ident);
+ fprint_ident_debug(out, e->ident);
break;
case EXPR_BINARY_OP: {
fprintf(out, "(");
@@ -2114,11 +2114,11 @@ static void fprint_expr(FILE *out, Expression *e) {
EachExpr *ea = e->each;
fprintf(out, "each ");
if (ea->index) {
- fprint_ident(out, ea->index);
+ fprint_ident_debug(out, ea->index);
} else fprintf(out, "_");
fprintf(out, ", ");
if (ea->value) {
- fprint_ident(out, ea->value);
+ fprint_ident_debug(out, ea->value);
} else fprintf(out, "_");
fprintf(out, " :");
if (ea->flags & EACH_ANNOTATED_TYPE)
@@ -2212,7 +2212,7 @@ static void fprint_decl(FILE *out, Declaration *d) {
PARSE_PRINT_LOCATION(d->where);
arr_foreach(d->idents, Identifier, ident) {
if (ident != d->idents) fprintf(out, ", ");
- fprint_ident(out, *ident);
+ fprint_ident_debug(out, *ident);
}
if (d->flags & DECL_IS_CONST) {
fprintf(out, "::");
diff --git a/test.toc b/test.toc
index 2a666a0..f7db673 100644
--- a/test.toc
+++ b/test.toc
@@ -1,7 +1,7 @@
Foo ::= struct {
x: int;
};
-main ::= fn() Foo {
+#export main ::= fn() Foo {
g ::= fn() int { 3 };
a : [3]int;
b := a[1:3];
diff --git a/tokenizer.c b/tokenizer.c
index 7abf56b..d2bf87f 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -88,7 +88,7 @@ static void fprint_token(FILE *out, Token *t) {
break;
case TOKEN_IDENT:
fprintf(out, "identifier: %p: ", (void*)t->ident);
- fprint_ident(out, t->ident);
+ fprint_ident_debug(out, t->ident);
break;
case TOKEN_LITERAL_NUM:
fprintf(out, "number: ");
diff --git a/types.h b/types.h
index e608950..82b1c08 100644
--- a/types.h
+++ b/types.h
@@ -185,7 +185,8 @@ typedef struct IdentTree {
/* zero value is an empty trie */
uint16_t depth;
unsigned char index_in_parent; /* index of this in .parent.children */
- U64 id; /* 0 if there's no actual identifier here, otherwise unique positive integer associated with this identifier */
+ bool export_name; /* is this identifier's name important? */
+ U64 export_id; /* 0 if there's no exported identifier here, otherwise unique positive integer associated with this identifier */
struct IdentTree *parent;
struct IdentTree *children[TREE_NCHILDREN];
IdentDecl *decls; /* array of declarations of this identifier */
@@ -757,8 +758,10 @@ typedef struct Typer {
typedef struct Exporter {
FILE *out; /* .top (toc package) to output to */
bool export_locations;
+ U64 ident_id;
FnExpr **exported_fns;
StructDef **exported_structs;
+ Identifier *exported_idents; /* (only those whose names are exported) */
} Exporter;
typedef struct CGenerator {