duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit cd8f5c8841d67357f4c6b91c74b14aac0a1d89e6
parent c6fb28d0a7df1c5ea9b68f2b51a26f2e3cf44a76
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Wed,  1 Jun 2022 13:51:40 -0400

Add word definitions and jumps

Diffstat:
M.gitignore | 1+
MMakefile | 2+-
Masm.py | 57+++++++++++++++++++++++++++++++++++++++++++++------------
Mdusk.c | 7++++---
Mforth.txt | 3++-
Mops.txt | 2+-
6 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1 +1,2 @@ /dusk +/forth.bin diff --git a/Makefile b/Makefile @@ -5,7 +5,7 @@ all: $(TARGETS) forth.bin: forth.txt asm.py ./asm.py forth.txt > $@ -dusk: dusk.c forth.bin +dusk: dusk.c forth.bin ops.txt $(CC) $(CFLAGS) dusk.c $(LDFLAGS) -o $@ .PHONY: clean diff --git a/asm.py b/asm.py @@ -4,25 +4,58 @@ import sys import struct -out = sys.stdout.buffer.write +ops = open('ops.txt', 'rb').read().split(b',') +ops = [s.strip() for s in ops] +ops = {name:i for i, name in enumerate(ops)} +tokens = open(sys.argv[1], 'rb').read().split() +tokens = [s.strip() for s in reversed(tokens)] +outbuf = bytearray() +prevword = 0 +words = {} # name:pc +labels = {} # name:pc + +def out(fmt, *args): + outbuf.extend(struct.pack(fmt, *args)) + +def pc(): + return len(outbuf) + def lit(s): # parse a literal - if len(s) == 3 and s[0] == "'" and s[2] == "'": - return ord(s[1]) + if len(s) == 3 and s[0] == ord("'") and s[2] == ord("'"): + return s[1] + elif s.isdigit(): + return int(s) return None -ops = open('ops.txt', 'r').read().split(',') -ops = [s.strip() for s in ops] -ops = {name:i for i, name in enumerate(ops)} -tokens = open(sys.argv[1], 'r').read().split() -tokens = [s.strip() for s in tokens] -for t in tokens: +def nextt(): + return tokens.pop() + +def newword(): + global prevword + name = nextt() + count = len(name) + out(f'<{count}sib', name, prevword, count) + prevword = pc() + words[name] = prevword + +while tokens: + t = nextt() if t in ops: - out(struct.pack('b', ops[t])) + out('b', ops[t]) + elif t == b':': + newword() + elif t.startswith(b'lbl'): + labels[t] = pc() + out('<i', 0) else: n = lit(t) if n is None: + t = t.decode() print(f"invalid token {t}", file=sys.stderr) - break + sys.exit(1) else: - out(struct.pack('<i', n)) + out('<bi', ops[b'PUSHi'], n) +n = labels[b'lblboot'] +outbuf[n:n+4] = struct.pack('<i', words[b'BOOT']) +sys.stdout.buffer.write(outbuf) diff --git a/dusk.c b/dusk.c @@ -52,13 +52,14 @@ static void lblxt() { pushRS(ip); ip = pop(); lblnext(); } static void PUSHi() { push(pc32()); } /* flow - idx 3 */ -static void BYE() { running = 0; } +static void JMPi() { pc = gc(pc); } +static void bye() { running = 0; } -/* I/O - idx 4 */ +/* I/O - idx 5 */ static void emit() { putchar(pop()); } static void key() { push(getchar()); } -static void (*ops[6])() = { +static void (*ops[7])() = { #include "ops.txt" }; diff --git a/forth.txt b/forth.txt @@ -1 +1,2 @@ -PUSHi 'f' emit PUSHi 'o' emit PUSHi 'o' emit BYE +JMPi lblboot +: BOOT 'f' emit 'o' emit 'o' emit bye diff --git a/ops.txt b/ops.txt @@ -1,4 +1,4 @@ lblnext, lblxt, PUSHi, -BYE, +JMPi, bye, emit, key