Last active
April 11, 2026 12:00
-
-
Save magicoal-nerb/46a986812227f2dd6f91b790be5f3036 to your computer and use it in GitHub Desktop.
trvth.... example bytecode system for a friend
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --!strict | |
| local kOp = { ['v'] = 1, ['^'] = 2, ['>'] = 3, ['x'] = 4, ['='] = 5 } | |
| export type OpCode = { ret: number, a: number, b: number, op: number } | |
| export type State = { | |
| var: (string) -> number, | |
| reg: () -> number, | |
| emit: (ret: number, a: number, b: number, op: number) -> (), | |
| next: () -> string, | |
| peek: () -> string, | |
| regs: number, | |
| list: { OpCode }, | |
| } | |
| local function state(str: string, regs: number): State | |
| local match = str:gmatch("[^%s]") | |
| local current = match() :: string | |
| local vars = {} :: { string } | |
| local list = {} :: { OpCode } | |
| return { | |
| list = list, | |
| regs = regs, | |
| var = function(x: string): number | |
| local idx = table.find(vars, x) | |
| if idx then | |
| return idx | |
| end | |
| table.insert(vars, x) | |
| return #vars | |
| end, | |
| reg = function(): number | |
| regs += 1 | |
| return regs | |
| end, | |
| emit = function(ret: number, a: number, b: number, op: number) | |
| table.insert(list, { ret = ret, a = a, b = b, op = op }) | |
| end, | |
| next = function() | |
| current = match() :: string | |
| return current | |
| end, | |
| peek = function() | |
| return current | |
| end | |
| } | |
| end | |
| local function expression(state: State): number | |
| if state.peek() == '!' then | |
| -- expr ::= '!' expr | |
| state.next() | |
| local ret = parse(state, 0) | |
| local reg = state.reg() | |
| state.emit(reg, ret, 0, 6) | |
| return reg | |
| elseif state.peek() == '(' then | |
| -- expr ::= '(' expr ')' | |
| state.next() | |
| local ret = parse(state, 0) | |
| state.next() | |
| return ret | |
| end | |
| -- expr ::= literal | |
| local ret = state.var(state.peek()) | |
| state.next() | |
| return ret | |
| end | |
| function parse(state: State, precedence: number) | |
| local current = expression(state) | |
| repeat | |
| -- expr ::= expr OP expr | |
| local peek = state.peek() | |
| local op = kOp[peek] | |
| if not op or op <= precedence then | |
| return current | |
| end | |
| local reg = state.reg() | |
| state.next() | |
| state.emit(reg, current, parse(state, precedence), op) | |
| current = reg | |
| until false | |
| return current | |
| end | |
| local function evaluate(state: State) | |
| parse(state, 0) | |
| local regs = state.regs | |
| local size = state.reg() - 1 | |
| local reg = table.create(size, false) | |
| local out = {} :: { string } | |
| for i = bit32.lshift(1, regs) - 1, 0, -1 do | |
| for j = 1, regs do | |
| reg[j] = bit32.btest(i, bit32.lshift(1, regs - j)) | |
| table.insert(out, reg[j] and 'T ' or 'F ') | |
| end | |
| for i, code in state.list do | |
| local op = code.op | |
| if op == 1 then | |
| -- or | |
| reg[code.ret] = reg[code.a] or reg[code.b] | |
| elseif op == 2 then | |
| -- and | |
| reg[code.ret] = reg[code.a] and reg[code.b] | |
| elseif op == 3 then | |
| -- implies | |
| reg[code.ret] = not reg[code.a] or reg[code.b] | |
| elseif op == 4 then | |
| -- xor | |
| local a = reg[code.a] | |
| local b = reg[code.b] | |
| reg[code.ret] = if a and b then false else a or b | |
| elseif op == 5 then | |
| -- bidirectional | |
| reg[code.ret] = reg[code.a] == reg[code.b] | |
| elseif op == 6 then | |
| -- not | |
| reg[code.ret] = not reg[code.a] | |
| else | |
| error("not an opcode") | |
| end | |
| table.insert(out, reg[code.ret] and 'T ' or 'F ') | |
| end | |
| table.insert(out, reg[size] and 'T\n' or 'F\n') | |
| end | |
| print(table.concat(out, '')) | |
| end | |
| evaluate(state("p > q", 2)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment