This commit is contained in:
2026-05-09 13:26:13 -05:00
parent 554a7b55c5
commit 610491c1d7
3 changed files with 51 additions and 16 deletions

View File

@@ -45,8 +45,8 @@ Function operations:
Table and array operations:
16 getkv Get table's value based on key (pull 1 value, push 1 value)
17 setkv Set table's key and value (pull 2 values from stack)
a8 c8 e8 geta Get array's position value
a9 c9 e9 seta Set array's position value
a8 c8 e8 geti Get array's position value
a9 c9 e9 seti Set array's position value
18 appnd Add value to the end of array
19 next Push the next pair into the stack (for loops)
1a smt Set value metatable

View File

@@ -341,21 +341,21 @@ do TEST "VM: GC strings"
end
do TEST "VM: arrays"
local vm = VM.new():set_debug(true):load(assemble [
local vm = VM.new():set_debug(true):load(assemble [[
.func 0
newa
pushi 10
seta 0
seti 0
pushi 20
seta 1
seti 1
pushi 30
seta 2
geta 1
]):call(0)
seti 2
geti 1
ret
]]):call(0)
print(vm:debug_heap())
assert_eq(vm:to_integer(-1), 20)
assert_eq(vm:is(-2, 'array'), true)
assert_eq(vm.heap:size(), 1)
end

View File

@@ -29,6 +29,8 @@ local function validate_value(v)
assert(type(v.value) == 'number' and v.value >= 0, "function must be a positive number")
elseif v.type == 'string' then
assert(type(v.ref) == 'number' or type(v.const_ref) == 'number')
elseif v.type == 'array' then
assert(type(v.ref) == 'number')
end
end
@@ -228,6 +230,7 @@ function Heap:add_value(value)
end
function Heap:get_value(key)
assert(type(key) == 'number')
return self.items[key]
end
@@ -307,6 +310,11 @@ function VM:push_nil()
return self
end
function VM:new_array()
self.stack:push({ type = 'array', ref = self.heap:add_value({}) })
return self
end
--
-- information
--
@@ -316,6 +324,8 @@ function VM:stack_sz()
end
function VM:is(idx, type_)
assert(type(idx) == "number")
assert(TYPE_MAP[type_])
return self.stack[idx].type == type_
end
@@ -337,6 +347,14 @@ function VM:_extract_string(value)
end
end
function VM:_extract_array(value)
assert(value)
assert(value.type == 'array')
local array = self.heap:get_value(value.ref)
if type(array) ~= 'table' then error('Expected array') end
return self.heap:get_value(value.ref)
end
function VM:to_string(idx)
local value = self.stack[idx]
if value.type ~= 'string' then error("Type error: not a string") end
@@ -348,6 +366,11 @@ function VM:format_value(v)
return tostring(v.value)
elseif v.type == 'string' then
return self_:extract_string(v)
elseif v.type == 'array' then
local array = self:_extract_array(v)
local tbl = {}
for _,vv in ipairs(array) do table.insert(tbl, self:format_value(vv)) end
return "[" .. table.concat(tbl, ', ') .. "]"
elseif v.type == 'function' then
return '@' .. tostring(v.value)
elseif v.type == 'nil' then
@@ -365,7 +388,7 @@ function VM:debug_stack()
for _,fp in pairs(self.stack.fps) do
if i == fp then table.insert(ss, '^ ') end
end
table.insert(ss, '[' .. self:format_value(v) .. '] ')
table.insert(ss, self:format_value(v) .. ' ')
end
return table.concat(ss)
end
@@ -373,12 +396,7 @@ end
function VM:debug_heap()
local ss = { "Heap:\n" }
for k,v in pairs(self.heap.items) do
table.insert(ss, string.format(" [%X] = ", k))
if type(v) == 'string' then
table.insert(ss, '"' .. v .. '"')
else
error('Unsupported value in heap')
end
table.insert(ss, string.format(" [%X] = %s", k, pprint.pformat(v)))
table.insert(ss, "\n")
end
return table.concat(ss)
@@ -459,6 +477,9 @@ function VM:_step()
error('REAL consts not supported for now.')
end
elseif op.operator == 'newa' then
self:new_array()
elseif op.operator == 'pop' then
self.stack:pop()
@@ -485,6 +506,20 @@ function VM:_step()
local a = self.stack[op.operand]
self.stack:push(a)
--
-- table and array operations
--
elseif op.operator == 'seti' then
local array_ref = self.stack[-2]
local array = self:_extract_array(array_ref)
array[op.operand+1] = self.stack:pop()
elseif op.operator == 'geti' then
local array_ref = self.stack[-1]
local array = self:_extract_array(array_ref)
self.stack:push(array[op.operand+1])
--
-- logic/arithmetic operations
--