summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-12-22 13:58:21 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-12-22 13:58:21 -0500
commit48361dc5b443b9fb03a07ab7cfc51accedcad518 (patch)
treeff109981f69b329ea260f841ce9056190560852e
parentb268bf59a6efbca460fef5bbd56f514df570a0bf (diff)
started exporting system
-rw-r--r--.gitignore1
-rw-r--r--abbrevs.txt3
-rw-r--r--export.c12
-rw-r--r--main.c6
-rw-r--r--parse.c18
-rw-r--r--test.toc34
-rw-r--r--toc.c1
-rw-r--r--tokenizer.c6
-rw-r--r--types.c7
-rw-r--r--types.h7
10 files changed, 58 insertions, 37 deletions
diff --git a/.gitignore b/.gitignore
index 7337ed8..4c9208d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
toc
a.out
out.c
+out.top
tests/**/*.c
tests/**/*.bin
vgcore* \ No newline at end of file
diff --git a/abbrevs.txt b/abbrevs.txt
index 96d41ae..3c25514 100644
--- a/abbrevs.txt
+++ b/abbrevs.txt
@@ -9,13 +9,14 @@ deref - dereference
direct - directive
eof - end of file
err - error
+eval - evaluate
evalr - evaluator
expr - expression
+exptr - exporter
fn - function
ident - identifier
kw - keyword
len - length
-mut - mutable
num - number
op - operator
param - parameter
diff --git a/export.c b/export.c
new file mode 100644
index 0000000..422bed4
--- /dev/null
+++ b/export.c
@@ -0,0 +1,12 @@
+static void exptr_create(Exporter *exptr, FILE *out) {
+ exptr->out = out;
+}
+
+static bool export_decl(Exporter *ex, Declaration *d) {
+ if (!ex) {
+ err_print(d->where, "Trying to export declaration, but a package output was not specified.");
+ return false;
+ }
+ putc((int)(d->idents[0]->id % 256), ex->out);
+ return true;
+}
diff --git a/main.c b/main.c
index 2c95b63..6cb0998 100644
--- a/main.c
+++ b/main.c
@@ -126,9 +126,14 @@ int main(int argc, char **argv) {
Typer tr;
Evaluator ev;
+ Exporter exptr;
evalr_create(&ev, &tr, &main_allocr);
typer_create(&tr, &ev, &main_allocr);
+ tr.exptr = &exptr;
+ FILE *out_pkg = fopen("out.top", "wb");
+ exptr_create(&exptr, out_pkg);
+
if (!block_enter(NULL, f.stmts, SCOPE_CHECK_REDECL)) /* enter global scope */
return false;
@@ -158,6 +163,7 @@ int main(int argc, char **argv) {
evalr_free(&ev);
fclose(out);
+ fclose(out_pkg);
idents_free(&file_idents);
}
diff --git a/parse.c b/parse.c
index f33131e..18f3e39 100644
--- a/parse.c
+++ b/parse.c
@@ -8,7 +8,8 @@ static bool parse_stmt(Parser *p, Statement *s);
enum {
PARSE_DECL_ALLOW_CONST_WITH_NO_EXPR = 0x01,
PARSE_DECL_ALLOW_SEMI_CONST = 0x02,
- PARSE_DECL_ALLOW_INFER
+ PARSE_DECL_ALLOW_INFER = 0x04,
+ PARSE_DECL_ALLOW_EXPORT = 0x08
};
static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, uint16_t flags);
static bool parse_decl_list(Parser *p, Declaration **decls, DeclEndKind decl_end);
@@ -1669,6 +1670,9 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
e->kind = EXPR_DALIGNOF;
single_arg = e->dalignof.of = parser_new_expr(p);
break;
+ case DIRECT_EXPORT:
+ err_print(t->token->where, "Unrecognized expression.");
+ return false;
case DIRECT_COUNT: assert(0); break;
}
if (single_arg) {
@@ -1737,6 +1741,11 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla
d->idents = NULL;
Tokenizer *t = p->tokr;
d->flags = 0;
+
+ if ((flags & PARSE_DECL_ALLOW_EXPORT) && token_is_direct(t->token, DIRECT_EXPORT)) {
+ d->flags |= DECL_EXPORT;
+ ++t->token;
+ }
while (1) {
Identifier *ident = parser_arr_add(p, &d->idents);
@@ -1858,6 +1867,11 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla
static bool is_decl(Tokenizer *t) {
Token *token = t->token;
+
+ /* you can only export declarations */
+ if (token_is_direct(token, DIRECT_EXPORT))
+ return true;
+
while (1) {
if (token->kind != TOKEN_IDENT) return false;
++token;
@@ -1904,7 +1918,7 @@ static bool parse_stmt(Parser *p, Statement *s) {
}
if (is_decl(t)) {
s->kind = STMT_DECL;
- if (!parse_decl(p, &s->decl, DECL_END_SEMICOLON, 0)) {
+ if (!parse_decl(p, &s->decl, DECL_END_SEMICOLON, PARSE_DECL_ALLOW_EXPORT)) {
return false;
}
return true;
diff --git a/test.toc b/test.toc
index 566aed9..ffac0c2 100644
--- a/test.toc
+++ b/test.toc
@@ -1,32 +1,2 @@
-puti ::= fn(x: int) {
- #C("printf(\"%ld\\n\", (long)x);
-");
-};
-putf ::= fn(x: float) {
- #C("printf(\"%f\\n\", (double)x);
-");
-};
-
-SuperArray ::= fn(n :: int, t :: Type) Type {
- struct {
- data: [n]t;
- field : t;
- }
-};
-
-checksum ::= fn(t ::=, n ::=, x:SuperArray(n,t)) t {
- total := 0 as t;
- each i := 0..n-1 {
- total += x.data[i];
- }
- total + x.field
-};
-
-Super ::= SuperArray(3, int);
-
-main ::= fn() {
-x: Super;
-x.data[0] = 3;
-x.field = 1932;
-puti(checksum(x));
-};
+#export
+asdf ::= 5; \ No newline at end of file
diff --git a/toc.c b/toc.c
index e58f4ec..dd8f4ac 100644
--- a/toc.c
+++ b/toc.c
@@ -42,6 +42,7 @@ static void print_val(Value v, Type *t);
#include "eval.c"
#include "infer.c"
+#include "export.c"
#include "types.c"
static bool cgen_decls_file(CGenerator *g, ParsedFile *f);
static bool typedefs_file(CGenerator *g, ParsedFile *f);
diff --git a/tokenizer.c b/tokenizer.c
index ae17a4d..6423eed 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -18,7 +18,7 @@ static const char *keywords[KW_COUNT] =
static inline const char *kw_to_str(Keyword k) { return keywords[k]; }
static const char *directives[DIRECT_COUNT] =
- {"C", "sizeof", "alignof"};
+ {"C", "sizeof", "alignof", "export"};
/* Returns KW_COUNT if it's not a keyword */
/* OPTIM: don't use strncmp so much */
@@ -62,6 +62,10 @@ static inline bool token_is_kw(Token *t, Keyword kw) {
return t->kind == TOKEN_KW && t->kw == kw;
}
+static inline bool token_is_direct(Token *t, Directive d) {
+ return t->kind == TOKEN_DIRECT && t->direct == d;
+}
+
static const char *token_kind_to_str(TokenKind t) {
switch (t) {
case TOKEN_KW: return "keyword";
diff --git a/types.c b/types.c
index be95204..9bde9e1 100644
--- a/types.c
+++ b/types.c
@@ -2021,7 +2021,11 @@ static bool types_decl(Typer *tr, Declaration *d) {
ret:
/* pretend we found the type even if we didn't to prevent too many errors */
d->flags |= DECL_FOUND_TYPE;
- if (!success) {
+ if (success) {
+ /* export it! */
+ if (!export_decl(tr->exptr, d))
+ success = false;
+ } else {
/* use unknown type if we didn't get the type */
d->type.flags = TYPE_IS_RESOLVED;
d->type.was_expr = NULL;
@@ -2086,6 +2090,7 @@ static void typer_create(Typer *tr, Evaluator *ev, Allocator *allocr) {
tr->blocks = NULL;
tr->fn = NULL;
tr->evalr = ev;
+ tr->exptr = NULL; /* by default, don't set an exporter */
tr->in_decls = NULL;
tr->in_expr_decls = NULL;
tr->allocr = allocr;
diff --git a/types.h b/types.h
index 91bc88b..245e6a0 100644
--- a/types.h
+++ b/types.h
@@ -201,6 +201,7 @@ typedef enum {
DIRECT_C,
DIRECT_SIZEOF,
DIRECT_ALIGNOF,
+ DIRECT_EXPORT,
DIRECT_COUNT
} Directive;
@@ -651,6 +652,7 @@ enum {
DECL_FOUND_VAL = 0x0040,
DECL_IS_PARAM = 0x0080,
DECL_INFER = 0x0100, /* infer the value (e.g. fn(t::Type=, x:t)) */
+ DECL_EXPORT = 0x0200
};
typedef U32 DeclFlags;
@@ -721,6 +723,7 @@ typedef struct Evaluator {
typedef struct Typer {
Allocator *allocr;
Evaluator *evalr;
+ struct Exporter *exptr;
Expression **in_expr_decls; /* an array of expressions whose declarations (e.g. each **x := foo**) we are currently inside */
Declaration **in_decls; /* array of declarations we are currently inside */
Block *block;
@@ -728,6 +731,10 @@ typedef struct Typer {
FnExpr *fn; /* the function we're currently parsing. */
} Typer;
+typedef struct Exporter {
+ FILE *out; /* .top (toc package) to output to */
+} Exporter;
+
typedef struct CGenerator {
Allocator *allocr;
FILE *outc;