cron 957d425609 turtle/tlang: add run builtin
This changes how code is executed a bit, code from the stack is popped to an execution stack before.
This makes global executed functions and anonymous ones identical.
Not super well tested as always :]
2020-11-03 07:06:59 +00:00

100 lines
2.3 KiB
Lua

local tlang = {}
tlang.lex = dofile("tlang_lex.lua")
tlang.parse = dofile("tlang_parse.lua")
tlang.builtins, tlang.gassign, tlang.step = dofile("tlang_vm.lua")
-- TODO
--[[
code shouldnt require a final whitespace
lexer should include line/character number in symbols
error messages
maps shouldnt require whitespace around [ and ]
maps should be able to have out of order number indexes (like [1 2 3 10:"Out of order"])
map.key accessing syntax
--]]
function tlang.run(state)
while true do
local more = tlang.step(state)
if more == true or more == nil then
-- continue along
elseif type(more) == "string" then
print(more) -- error
elseif more == false then
return -- done
else
print("Unknown error, tlang.step returned: " .. tostring(more))
end
end
end
local function assign_many(state, source)
for k, v in pairs(source) do
tlang.gassign(state, k, v)
end
end
-- convert a lua value into a tlang literal
function tlang.valconv(value)
local t = type(value)
if t == "string" then
return {type = "string", value = value}
elseif t == "number" then
return {type = "number", value = value}
elseif t == "table" then
local map = {}
for k, v in pairs(value) do
map[k] = tlang.valconv(v)
end
return {type = "map", value = map}
end
end
function tlang.get_state(code)
local lexed = tlang.lex(code)
local parsed = tlang.parse(lexed)
return {
locals = {{
pc = {sg = 1, pos = "__ast__", elem = 1},
v__src__ = tlang.valconv(code),
v__lex__ = tlang.valconv(lexed),
v__ast__ = {type = "code", value = parsed}}},
stack = {},
code_stack = {},
builtins = tlang.builtins,
wait_target = nil,
nextpop = false
}
end
function tlang.exec(code)
local state = tlang.get_state(code)
tlang.run(state)
end
local complex = [[{dup *} `square =
-5.42 square
"Hello, world!" print
[1 2 3 str:"String"]
]]
local number = "-4.2123"
local simple = "{dup *}"
local map = "[this:2 that:3]"
local square = [[{dup *} `square =
5 square print]]
local square_run = "5 {dup *} run print"
tlang.exec(square_run)
return tlang