aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-07-04 23:37:51 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2023-07-04 23:37:51 +0300
commite82c73d2b57e58894d8c93fc720559df6392d58b (patch)
tree3a637c10d0334e21ba3a75fbf5854d0f43efe07e
parent703e37ac56883f9a54b35960fde438c7cfba4592 (diff)
downloadbcgen-e82c73d2b57e58894d8c93fc720559df6392d58b.tar.gz
bcgen-e82c73d2b57e58894d8c93fc720559df6392d58b.zip
add loop example
-rwxr-xr-xbcgen4
-rw-r--r--bcode.c29
-rw-r--r--bcode.h3
-rw-r--r--example/Makefile17
-rwxr-xr-xexample/execbin0 -> 93744 bytes
-rw-r--r--example/main.c25
-rw-r--r--example/rules.py5
7 files changed, 79 insertions, 4 deletions
diff --git a/bcgen b/bcgen
index c7d1a7f..aeb5f56 100755
--- a/bcgen
+++ b/bcgen
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys
+import pathlib
def check_fmt(fmt):
assert(len(fmt) == 6)
@@ -86,6 +87,9 @@ class BCGen:
self.r = r
self.f = f
+ # make sure gen dir exists
+ pathlib.Path('gen').mkdir(exist_ok=True)
+
# clear out files
with open('gen/body.inc', 'w') as inc:
pass
diff --git a/bcode.c b/bcode.c
index b4f4231..1b0cba2 100644
--- a/bcode.c
+++ b/bcode.c
@@ -41,7 +41,7 @@ static void append(struct compile_state *cs, enum bcode_insn label, breg_t imm)
#define IMM s.imm[pc].g
#define DIMM s.imm[pc].f
-#define NEXT_INSN goto *s.op[pc++]
+#define NEXT_INSN goto *s.op[++pc]
#define JUMP(i) goto *s.op[pc = (i)]
static gbreg_t _run(struct compile_state *cs, bool init)
@@ -62,6 +62,7 @@ static gbreg_t _run(struct compile_state *cs, bool init)
const struct run_state s = cs->s;
size_t pc = 0;
JUMP(pc);
+
#include "gen/body.inc"
end: /* we assume there's always at least one general register */
@@ -76,13 +77,33 @@ gbreg_t run(struct compile_state *cs)
void init(struct compile_state *cs)
{
cs->labels = NULL;
- cs->s.imm = NULL;
- cs->s.op = NULL;
- cs->size = 0;
+ cs->size = 16;
+
+ cs->s.imm = malloc(cs->size * sizeof(*cs->s.imm));
+ assert(cs->s.imm);
+
+ cs->s.op = malloc(cs->size * sizeof(*cs->s.op));
+ assert(cs->s.op);
+
cs->pc = 0;
_run(cs, true);
}
+void end(struct compile_state *cs)
+{
+ PUSH_OP(END);
+}
+
+breg_t label(struct compile_state *cs)
+{
+ return (breg_t){.g = cs->pc};
+}
+
+void patch(struct compile_state *cs, breloc_t reloc, breg_t imm)
+{
+ cs->s.imm[reloc] = imm;
+}
+
void destroy(struct compile_state *cs)
{
free(cs->s.op);
diff --git a/bcode.h b/bcode.h
index e25d32a..730b8e7 100644
--- a/bcode.h
+++ b/bcode.h
@@ -28,7 +28,10 @@ struct compile_state {
gbreg_t run(struct compile_state *cs);
void init(struct compile_state *cs);
+void end(struct compile_state *cs);
void destroy(struct compile_state *cs);
+
+breg_t label(struct compile_state *cs);
void patch(struct compile_state *cs, breloc_t reloc, breg_t imm);
#endif /* BCGEN_BCODE_H */
diff --git a/example/Makefile b/example/Makefile
new file mode 100644
index 0000000..66c96a0
--- /dev/null
+++ b/example/Makefile
@@ -0,0 +1,17 @@
+CFLAGS = -Wall -Wextra -g -O2
+
+all: exec
+
+exec: bcode.o main.o
+ $(CC) $(CFLAGS) $^ -o $@
+
+bcode.o: ../bcode.c
+ $(CC) $(CFLAGS) -c $^ -o $@
+
+../bcode.c: rules.py
+ cd .. && ./bcgen example/rules.py
+ touch ../bcode.c # just to get make to wake up
+
+.PHONY: clean
+clean:
+ rm -rf *.o exec
diff --git a/example/exec b/example/exec
new file mode 100755
index 0000000..2189325
--- /dev/null
+++ b/example/exec
Binary files differ
diff --git a/example/main.c b/example/main.c
new file mode 100644
index 0000000..7ca152b
--- /dev/null
+++ b/example/main.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include "../bcode.h"
+
+int main()
+{
+ struct compile_state cs;
+ init(&cs);
+
+ select_movi(&cs, 2, 0); // i
+ select_movi(&cs, 1, 1000000000); // limit
+ select_movi(&cs, 0, 0); // total
+
+ breg_t l = label(&cs); // top
+ select_addr(&cs, 0, 0, 2); // add iter to total
+ select_addi(&cs, 2, 2, 1);
+ breloc_t r = select_bltr(&cs, 2, 1, 0); // 0 is placeholder value,
+ // should maybe add in an
+ // UNDEFINED macro or something
+ end(&cs);
+
+ patch(&cs, r, l);
+
+ printf("%llu\n", (unsigned long long)run(&cs));
+ destroy(&cs);
+}
diff --git a/example/rules.py b/example/rules.py
new file mode 100644
index 0000000..9c8d62e
--- /dev/null
+++ b/example/rules.py
@@ -0,0 +1,5 @@
+g = BCGen(r = 7, f = 0)
+g.rule('addr', '_RRR__', 'R0 = R1 + R2;')
+g.rule('addi', '_RR__I', 'R0 = R1 + IMM;')
+g.rule('movi', '_R___I', 'R0 = IMM;')
+g.rule('bltr', 'rRR__I', 'if (R0 < R1) JUMP(IMM);')