compiler

Unnamed Compiled Systems Language Project
git clone http://frotz.net/git/compiler.git
Log | Files | Refs

commit bd7b4a25f295fa9041078f9cb4a9865ac84bad19
parent 742ee50f187bff7a6bb2a9f4d523b2cf7c74b08a
Author: Brian Swetland <swetland@frotz.net>
Date:   Tue, 25 May 2021 20:20:53 -0700

rewriter: a bit more transmogrifcation progress

- better error reporting in rewriter
- simple preproc tool to all #if C use in compiler.c
  (for stuff that can't easily be machine transformed)
- update makefile

Diffstat:
MMakefile | 20++++++++++++++++++--
Msrc/compiler.c | 54+++++++++++++++++++++++++++++++++---------------------
Asrc/preproc.c | 31+++++++++++++++++++++++++++++++
Msrc/rewriter.c | 38+++++++++++++++++++++++++++++++-------
4 files changed, 113 insertions(+), 30 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,12 +4,28 @@ all: bin/compiler bin/fs bin/r5d bin/r5e bin/mkinstab out/test/summary.txt clean: rm -rf bin out -CFLAGS := -Wall -O2 -g -Iexternal/oberon-risc-emu -Isrc +out/compiler.src: out/compiler.txt bin/rewriter + @mkdir -p out + bin/rewriter out/compiler.txt > out/compiler.src + +out/compiler.txt: src/compiler.c bin/preproc + @mkdir -p out + bin/preproc < src/compiler.c > out/compiler.txt + +CFLAGS := -Wall -O2 -g -Iexternal/oberon-risc-emu -Isrc -fno-builtin CC := gcc bin/compiler: src/compiler.c src/risc5dis.c out/risc5ins.h @mkdir -p bin - $(CC) -o $@ $(CFLAGS) src/compiler.c src/risc5dis.c + $(CC) -o $@ $(CFLAGS) -Wno-unused-result -DC src/compiler.c src/risc5dis.c + +bin/rewriter: src/rewriter.c + @mkdir -p bin + $(CC) -o $@ $(CFLAGS) src/rewriter.c + +bin/preproc: src/preproc.c + @mkdir -p bin + $(CC) -o $@ $(CFLAGS) src/preproc.c bin/fs: src/fs.c src/fs.h @mkdir -p bin diff --git a/src/compiler.c b/src/compiler.c @@ -1,6 +1,7 @@ // Copyright 2020, Brian Swetland <swetland@frotz.net> // Licensed under the Apache License, Version 2.0. +#if C #include <stdio.h> #include <stdlib.h> #include <stdarg.h> @@ -15,12 +16,19 @@ #include "risc5.h" +// builtin types #define nil 0 - typedef uint32_t u32; typedef int32_t i32; typedef uint8_t u8; +// rewriter only handles single word types +typedef uint32_t token_t; +typedef char* str; +typedef char** args; +typedef uint32_t* u32ptr; +#endif + enum { FNMAXARGS = 8, }; // token classes (tok & tcMASK) @@ -29,7 +37,7 @@ enum { tcAEQOP = 0x20, tcMEQOP = 0x28, tcMASK = 0xF8, }; -typedef enum { +enum { // EndMarks, Braces, Brackets Parens tEOF, tEOL, tOBRACE, tCBRACE, tOBRACK, tCBRACK, tOPAREN, tCPAREN, // RelOps (do not reorder) @@ -53,9 +61,9 @@ typedef enum { tIDN, tNUM, tSTR, // used internal to the lexer but never returned tSPC, tINV, tDQT, tSQT, tMSC, -} token_t; +}; -char *tnames[] = { +str tnames[] = { "<EOF>", "<EOL>", "{", "}", "[", "]", "(", ")", "==", "!=", "<", "<=", ">", ">=", "", "", "+", "-", "|", "^", "", "", "", "", @@ -115,14 +123,6 @@ enum { mMUL, mDIV, mMOD, mAND, mANN, mLSL, mLSR, }; // MulOps u8 invert_relop_tab[6] = { rNE, rEQ, rGE, rGT, rLE, rLT, }; -typedef struct StringRec* String; -typedef struct ObjectRec* Object; -typedef struct ScopeRec* Scope; -typedef struct FixupRec* Fixup; -typedef struct TypeRec* Type; -typedef struct ItemRec* Item; -typedef struct CtxRec* Ctx; - typedef struct StringRec StringRec; typedef struct ObjectRec ObjectRec; typedef struct ScopeRec ScopeRec; @@ -131,6 +131,14 @@ typedef struct TypeRec TypeRec; typedef struct ItemRec ItemRec; typedef struct CtxRec CtxRec; +typedef struct StringRec* String; +typedef struct ObjectRec* Object; +typedef struct ScopeRec* Scope; +typedef struct FixupRec* Fixup; +typedef struct TypeRec* Type; +typedef struct ItemRec* Item; +typedef struct CtxRec* Ctx; + struct StringRec { String next; u32 len; @@ -216,7 +224,7 @@ enum { tUndefined, }; -const char* type_id_tab[] = { +str type_id_tab[] = { "void", "byte", "bool", "int32", "nil", "*", "[]", "[]", "struct", "func", "undef", }; @@ -242,7 +250,7 @@ enum { // r a b iFunc, }; -const char* item_id_tab[] = { "Const", "Reg", "RegInd", "Comp", "Func" }; +str item_id_tab[] = { "Const", "Reg", "RegInd", "Comp", "Func" }; void print_item(Item x); @@ -597,7 +605,11 @@ bool compatible_type(Type dst, Type src, Item x) { void dump_file_line(const char* fn, u32 offset); +#if C void error(const char *fmt, ...) { +#else +void error(const char *fmt) { +#endif va_list ap; fprintf(stderr,"%s:%d: ", ctx.filename, ctx.linenumber); @@ -635,7 +647,7 @@ void load(const char* filename) { ctx.byteoffset = 0; } -int unhex(u32 ch) { +i32 unhex(u32 ch) { if ((ch >= '0') && (ch <= '9')) { return ch - '0'; } @@ -1513,7 +1525,7 @@ u32 parse_init_constexpr(Type type) { return x.a; } -u32 parse_array_init(Object var, u32* data, u32 dmax, u32 sz) { +u32 parse_array_init(Object var, u32ptr data, u32 dmax, u32 sz) { memset(data, 0, dmax); u32 n = 0; while (true) { @@ -1534,7 +1546,7 @@ u32 parse_array_init(Object var, u32* data, u32 dmax, u32 sz) { return n; } -void parse_struct_init(Object var, u32* data) { +void parse_struct_init(Object var, u32ptr data) { memset(data, 0, var->type->size); while (true) { if (ctx.tok == tCBRACE) { @@ -2811,10 +2823,10 @@ void gen_trace_code(const char* msg, u32 pc) { } // ================================================================ -int main(int argc, char **argv) { - const char *outname = "out.bin"; - const char *lstname = nil; - const char *srcname = nil; +i32 main(int argc, args argv) { + str outname = "out.bin"; + str lstname = nil; + str srcname = nil; bool dump = false; bool scan_only = false; diff --git a/src/preproc.c b/src/preproc.c @@ -0,0 +1,31 @@ +// Copyright 2021, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. + +#include <stdio.h> +#include <string.h> + +int main(int argc, char** argv) { + char line[1024]; + int discard = 0; + + while (fgets(line, 1024, stdin) != NULL) { + if (strncmp(line, "#if C", 5) == 0) { + discard = 1; + continue; + } + if (strncmp(line, "#else", 5) == 0) { + discard = 0; + continue; + } + if (strncmp(line, "#endif", 6) == 0) { + discard = 0; + continue; + } + if (discard) { + continue; + } + fputs(line, stdout); + } + return 0; +} + diff --git a/src/rewriter.c b/src/rewriter.c @@ -213,6 +213,32 @@ void init_ctx() { make_keyword("continue", tCONTINUE); } +void dump_file_line(const char* fn, u32 offset) { + int fd = open(fn, O_RDONLY); + if (fd < 0) { + return; + } + if (lseek(fd, offset, SEEK_SET) != offset) { + close(fd); + return; + } + char line[256]; + int r = read(fd, line, 255); + if (r > 0) { + line[r] = 0; + int n = 0; + while (n < r) { + if (line[n] == '\n') { + line[n] = 0; + break; + } + n++; + } + fprintf(stderr, "\n%s", line); + } + close(fd); +} + void error(const char *fmt, ...) { va_list ap; @@ -220,6 +246,9 @@ void error(const char *fmt, ...) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); + if (ctx.linenumber > 0) { + dump_file_line(ctx.filename, ctx.lineoffset); + } fprintf(stderr, "\n\n"); exit(1); } @@ -271,6 +300,7 @@ u32 scan() { } ctx.cc = ctx.iobuffer[ctx.ionext]; ctx.ionext++; + ctx.byteoffset++; return ctx.cc; } @@ -665,13 +695,7 @@ void parse_array(String type, String name) { } void parse_program() { - nextq(); - - // use the first enum as the mark of when we're past any - // C-only boilerplate - while (ctx.tok != tENUM) { - nextq(); - } + next(); for (;;) { if (ctx.tok == tENUM) {