From 6428c6cf7fc7d25ebbd0477c408dd95df374e143 Mon Sep 17 00:00:00 2001 From: Andre Wagner Date: Tue, 5 May 2026 16:26:34 -0500 Subject: [PATCH] . --- lua-temp/TODO.md | 2 +- lua-temp/tests.lua | 18 ++++++++++++++- lua-temp/tyche-vm.lua | 53 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/lua-temp/TODO.md b/lua-temp/TODO.md index 6c8f68a..71bcbb5 100644 --- a/lua-temp/TODO.md +++ b/lua-temp/TODO.md @@ -2,7 +2,6 @@ Progress of the Lua port: - [x] Assembler - [x] Basic VM execution -- [ ] Error handling strategy? - [ ] Logic/arithmetic expressions - [ ] Functions - [ ] Local variables @@ -20,6 +19,7 @@ Progress of the Lua port: - [ ] Tables - [ ] Garbage collection - [ ] Metatables +- [ ] Error handling - [ ] Closures/upvalues diff --git a/lua-temp/tests.lua b/lua-temp/tests.lua index 0463f3a..bb9bc9a 100644 --- a/lua-temp/tests.lua +++ b/lua-temp/tests.lua @@ -118,10 +118,21 @@ end ---------------------- -- -- --- VM STACK -- +-- VM ARITH -- -- -- ---------------------- +local function arith(a, b, op) + return VM:new():load(assemble(string.format([[ + .func 0 + pushi %d + pushi %d + %s + ret + ]], a, b, op))):call(0) +end + + do local vm = VM:new() -- vm.debug = true @@ -144,4 +155,9 @@ do assert_eq(vm:to_integer(-1), 5) end +do + assert_eq(arith(2, 5, 'sum'):to_integer(-1), 7) + assert_eq(arith(2, 5, 'sub'):to_integer(-1), -3) +end + print('End.') \ No newline at end of file diff --git a/lua-temp/tyche-vm.lua b/lua-temp/tyche-vm.lua index 42b96d9..5ef225b 100644 --- a/lua-temp/tyche-vm.lua +++ b/lua-temp/tyche-vm.lua @@ -1,5 +1,13 @@ local pprint = require('pprint') +local TYPES = { 'nil', 'integer', 'float', 'string', 'array', 'table', 'function', 'native_pointer' } +local TYPE_MAP = {}; for _,v in ipairs(TYPES) do TYPE_MAP[v] = true end + +local ARITH_LOGIC_OPS = { + sum=true, sub=true, mul=true, div=true, idiv=true, eq=true, neq=true, lt=true, lte=true, gt=true, gte=true, + ['and']=true, ['or']=true, xor=true, pow=true, shl=true, shr=true, mod=true +} + ---------------------- -- -- -- UTIL -- @@ -41,7 +49,7 @@ function Stack:top_fps() end function Stack:push(value) - assert(type(value) == 'table' and value.type) + assert(type(value) == 'table' and TYPE_MAP[value.type]) table.insert(self.stack, value) end @@ -144,6 +152,28 @@ function Code:next_instruction(function_id, pc) } end +---------------------- +-- -- +-- EXPR -- +-- -- +---------------------- + +local EXPR = {} + +-- initialize default +for op,_ in pairs(ARITH_LOGIC_OPS) do + EXPR[op] = {} + for _,type1 in ipairs(TYPES) do + EXPR[op][type1] = {} + for _,type2 in ipairs(TYPES) do + EXPR[op][type1][type2] = function(vm, a, b) error(string.format("Type mismatch for operation '%s': types '%s' and '%s'", op, type1, type2)) end + end + end +end + +EXPR.sum.integer.integer = function(vm, b, a) vm:push_integer(a + b) end +EXPR.sub.integer.integer = function(vm, b, a) vm:push_integer(a - b) end + ---------------------- -- -- -- VM -- @@ -228,16 +258,33 @@ function VM:_step() if self.debug then print('## ' .. loc.f_id .. ':' .. loc.pc .. ' ' .. op.operator .. ' ' .. (op.operand and op.operand or '')) end + -- + -- stack operations + -- + if op.operator == 'pushi' then self:push_integer(op.operand) - elseif op.operator == 'sum' then - self:push_integer(self.stack:pop().value + self.stack:pop().value) + + -- + -- logic/arithmetic operations + -- + + elseif ARITH_LOGIC_OPS[op.operator] then + local a = self.stack:pop() + local b = self.stack:pop() + EXPR[op.operator][a.type][b.type](self, a.value, b.value) + + -- + -- function management + --- + elseif op.operator == 'ret' then local v = self.stack:pop() self.stack:pop_fp() self.stack:push(v) return else + error("Unknown operator '" .. tostring(op.operator) .. "'") end