From 7dfcdf50dda531095f1b1235fafa002457107e6c Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sun, 22 Dec 2019 14:32:49 -0500 Subject: more exporting --- binfile.c | 31 +++++++++++++++++++++++++++++++ export.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- parse.c | 5 +++-- test.toc | 4 ++-- toc.c | 4 ++-- tokenizer.c | 8 ++++---- types.c | 8 +++++--- types.h | 12 +++++------- 8 files changed, 107 insertions(+), 21 deletions(-) create mode 100644 binfile.c diff --git a/binfile.c b/binfile.c new file mode 100644 index 0000000..8a45084 --- /dev/null +++ b/binfile.c @@ -0,0 +1,31 @@ +#define BINFILE_PORTABLE 1 + +static inline void write_u8(FILE *fp, U8 u8) { + putc(u8, fp); +} + +/* + note: a bit of testing seems to reveal that the portable versions for u16/32 are faster than fwrite + (but this is not the case for u64). + */ + +static inline void write_u16(FILE *fp, U16 u16) { + putc(u16 & 0xFF, fp); + putc(u16 >> 8, fp); +} + +static inline void write_u32(FILE *fp, U32 u32) { + write_u16(fp, u32 & 0xFFFF); + write_u16(fp, (U16)(u32 >> 16)); +} + +static void write_u64(FILE *fp, U64 u64) { +#if BINFILE_PORTABLE + write_u32(fp, u64 & 0xFFFFFFFF); + write_u32(fp, (U32)(u64 >> 32)); +#else + fwrite(&u64, sizeof u64, 1, fp); +#endif +} + + diff --git a/export.c b/export.c index 422bed4..571701e 100644 --- a/export.c +++ b/export.c @@ -1,5 +1,39 @@ +/* + Copyright (C) 2019 Leo Tenenbaum. + This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever. + You should have received a copy of the GNU General Public License along with toc. If not, see . +*/ static void exptr_create(Exporter *exptr, FILE *out) { exptr->out = out; + exptr->export_locations = true; +} + +static void export_u8(Exporter *ex, U8 u8) { + write_u8(ex->out, u8); +} + +static void export_u16(Exporter *ex, U16 u16) { + write_u16(ex->out, u16); +} + +static void export_u32(Exporter *ex, U32 u32) { + write_u32(ex->out, u32); +} + +static void export_u64(Exporter *ex, U64 u64) { + write_u64(ex->out, u64); +} + +static void export_location(Exporter *ex, Location where) { + if (ex->export_locations) { + export_u32(ex, where.line); + export_u32(ex, where.pos); + } +} + +static void export_ident(Exporter *ex, Identifier i) { + assert(i->id); + export_u64(ex, i->id); } static bool export_decl(Exporter *ex, Declaration *d) { @@ -7,6 +41,26 @@ static bool export_decl(Exporter *ex, Declaration *d) { 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); + export_location(ex, d->where); + if (arr_len(d->idents) > 65535) { + err_print(d->where, "Too many identifiers in a declaration (the maximum is 65535)."); + return false; + } + export_u16(ex, (U16)arr_len(d->idents)); + arr_foreach(d->idents, Identifier, ident) { + export_ident(ex, *ident); + } + + U8 constness = 0; + if (d->flags & DECL_IS_CONST) constness = 1; + else if (d->flags & DECL_SEMI_CONST) constness = 2; + export_u8(ex, constness); + + U8 expr_kind = 0; + if (d->flags & DECL_HAS_EXPR) expr_kind = 1; /* export expression */ + if (d->flags & DECL_FOUND_VAL) expr_kind = 2; /* export value */ + export_u8(ex, expr_kind); + + return true; } diff --git a/parse.c b/parse.c index 18f3e39..23bad30 100644 --- a/parse.c +++ b/parse.c @@ -1737,14 +1737,15 @@ static inline bool ends_decl(Token *t, DeclEndKind ends_with) { } static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 flags) { - d->where = p->tokr->token->where; - d->idents = NULL; Tokenizer *t = p->tokr; + d->where = t->token->where; + d->idents = NULL; d->flags = 0; if ((flags & PARSE_DECL_ALLOW_EXPORT) && token_is_direct(t->token, DIRECT_EXPORT)) { d->flags |= DECL_EXPORT; ++t->token; + d->where = t->token->where; } while (1) { diff --git a/test.toc b/test.toc index ffac0c2..edb175d 100644 --- a/test.toc +++ b/test.toc @@ -1,2 +1,2 @@ -#export -asdf ::= 5; \ No newline at end of file +foo ::= 7; +#export asdf, dsajkhf, sadjkfh ::= 5; \ No newline at end of file diff --git a/toc.c b/toc.c index dd8f4ac..a60d667 100644 --- a/toc.c +++ b/toc.c @@ -24,6 +24,7 @@ /* forward declarations for debugging */ static void print_val(Value v, Type *t); +/* utilities */ #include "allocator.c" #include "arr.c" #include "location.c" @@ -33,13 +34,12 @@ static void print_val(Value v, Type *t); #include "str.c" #include "instance_table.c" #include "copy.c" +#include "binfile.c" #include "identifiers.c" #include "tokenizer.c" #include "parse.c" #include "scope.c" - - #include "eval.c" #include "infer.c" #include "export.c" diff --git a/tokenizer.c b/tokenizer.c index 6423eed..5d245d9 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -150,7 +150,7 @@ static void tokenization_err(Tokenizer *t, const char *fmt, ...) { Location where; where.line = t->line; where.ctx = t->err_ctx; - where.pos = (CodePos)(t->s - where.ctx->str); + where.pos = (U32)(t->s - where.ctx->str); va_start(args, fmt); err_vprint(where, fmt, args); va_end(args); @@ -189,7 +189,7 @@ static void tokr_err_( static void tokr_put_location(Tokenizer *tokr, Token *t) { t->where.line = tokr->line; t->where.ctx = tokr->err_ctx; - t->where.pos = (CodePos)(tokr->s - t->where.ctx->str); + t->where.pos = (U32)(tokr->s - t->where.ctx->str); } static void tokr_get_location(Tokenizer *tokr, Token *t) { @@ -278,7 +278,7 @@ static bool tokenize_string(Tokenizer *t, char *str) { /* it's a directive */ Token *token = tokr_add(t); tokr_put_location(t, token); - token->where.pos = (CodePos)(start_s - token->where.ctx->str); + token->where.pos = (U32)(start_s - token->where.ctx->str); token->kind = TOKEN_DIRECT; token->direct = direct; continue; @@ -295,7 +295,7 @@ static bool tokenize_string(Tokenizer *t, char *str) { /* it's a keyword */ Token *token = tokr_add(t); tokr_put_location(t, token); - token->where.pos = (CodePos)(start_s - token->where.ctx->str); + token->where.pos = (U32)(start_s - token->where.ctx->str); token->kind = TOKEN_KW; token->kw = kw; continue; diff --git a/types.c b/types.c index 9bde9e1..075c8de 100644 --- a/types.c +++ b/types.c @@ -2022,9 +2022,11 @@ static bool types_decl(Typer *tr, Declaration *d) { /* pretend we found the type even if we didn't to prevent too many errors */ d->flags |= DECL_FOUND_TYPE; if (success) { - /* export it! */ - if (!export_decl(tr->exptr, d)) - success = false; + if (d->flags & DECL_EXPORT) { + /* 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; diff --git a/types.h b/types.h index 245e6a0..3fd0fa2 100644 --- a/types.h +++ b/types.h @@ -50,10 +50,7 @@ typedef double F64; #define F32_FMT "%.16f" #define F64_FMT "%.16f" -typedef U32 IdentID; /* identifier ID for cgen (anonymous variables) */ - -typedef U32 LineNo; -typedef U32 CodePos; +typedef U32 IdentID; /* identifier ID for cgen (anonymous variables). not to be confused with IdentTree.id */ #define join(a,b) a##b @@ -70,8 +67,8 @@ typedef U32 CodePos; typedef struct Location { - LineNo line; - CodePos pos; /* position in ctx->str */ + U32 line; + U32 pos; /* position in ctx->str */ struct ErrCtx *ctx; } Location; @@ -304,7 +301,7 @@ typedef struct Tokenizer { Token *tokens; char *s; /* string being parsed */ ErrCtx *err_ctx; - LineNo line; + U32 line; Token *token; /* token currently being processed */ Identifiers *idents; } Tokenizer; @@ -733,6 +730,7 @@ typedef struct Typer { typedef struct Exporter { FILE *out; /* .top (toc package) to output to */ + bool export_locations; } Exporter; typedef struct CGenerator { -- cgit v1.2.3