.
This commit is contained in:
@@ -2,7 +2,6 @@ Progress of the Lua port:
|
|||||||
|
|
||||||
- [x] Assembler
|
- [x] Assembler
|
||||||
- [x] Basic VM execution
|
- [x] Basic VM execution
|
||||||
- [ ] Error handling strategy?
|
|
||||||
- [ ] Logic/arithmetic expressions
|
- [ ] Logic/arithmetic expressions
|
||||||
- [ ] Functions
|
- [ ] Functions
|
||||||
- [ ] Local variables
|
- [ ] Local variables
|
||||||
@@ -20,6 +19,7 @@ Progress of the Lua port:
|
|||||||
- [ ] Tables
|
- [ ] Tables
|
||||||
- [ ] Garbage collection
|
- [ ] Garbage collection
|
||||||
- [ ] Metatables
|
- [ ] Metatables
|
||||||
|
- [ ] Error handling
|
||||||
- [ ] Closures/upvalues
|
- [ ] Closures/upvalues
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
do
|
||||||
local vm = VM:new()
|
local vm = VM:new()
|
||||||
-- vm.debug = true
|
-- vm.debug = true
|
||||||
@@ -144,4 +155,9 @@ do
|
|||||||
assert_eq(vm:to_integer(-1), 5)
|
assert_eq(vm:to_integer(-1), 5)
|
||||||
end
|
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.')
|
print('End.')
|
||||||
@@ -1,5 +1,13 @@
|
|||||||
local pprint = require('pprint')
|
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 --
|
-- UTIL --
|
||||||
@@ -41,7 +49,7 @@ function Stack:top_fps()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Stack:push(value)
|
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)
|
table.insert(self.stack, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -144,6 +152,28 @@ function Code:next_instruction(function_id, pc)
|
|||||||
}
|
}
|
||||||
end
|
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 --
|
-- 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
|
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
|
if op.operator == 'pushi' then
|
||||||
self:push_integer(op.operand)
|
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
|
elseif op.operator == 'ret' then
|
||||||
local v = self.stack:pop()
|
local v = self.stack:pop()
|
||||||
self.stack:pop_fp()
|
self.stack:pop_fp()
|
||||||
self.stack:push(v)
|
self.stack:push(v)
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
|
|
||||||
error("Unknown operator '" .. tostring(op.operator) .. "'")
|
error("Unknown operator '" .. tostring(op.operator) .. "'")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user