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:
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) {