Paste: Lua Stack Language Bootstrapping
Author: | Capital |
Mode: | lua |
Date: | Wed, 27 Dec 2023 08:09:19 |
Plain Text |
_F = {}
DS, POS = { n = 0 }, 1
LOAD = function (code) return assert(load(code)) end
EVAL = function (code) (LOAD(code))() end
TOS = function (s) return s[s.n] end
POP = function (s) local x = TOS(s) s[s.n], s.n = nil, s.n - 1 return x end
PSH = function (s, x) s.n = s.n + 1 s[s.n] = x end
local __tostring = function (self) return self:compile() end
LUA_QUOTE = function (source)
return setmetatable(
{ source = source
, func = assert(load(source))
, interpret
= function (self) self.func() end
, compile
= function (self) return self.source end
}, {__tostring = __tostring})
end
LUPA_QUOTE = function (body)
return setmetatable(
{ body = body
, interpret
= function (self)
for _, item in self.body do
item:interpret()
end
end
, compile
= function (self)
local code = {}
for _, item in self.body do
code[#code+1] = item:compile()
end
return table.concat(code, "\n")
end
}, {__tostring = __tostring})
end
WORD = function (args)
return setmetatable(
{ name = args.name
, def = args.def
, parsing = (args.parsing ~= nil) and args.parsing or false
, interpret
= function (self)
self.def:interpret()
end
, compile
= function (self)
return self.def:compile()
end
}, {__tostring = __tostring})
end
NOP = WORD{ name = "NOP", def = LUA_QUOTE("") }
function parse_pattern(pat)
local capture, newpos = PROG:match(pat, POS)
if newpos then POS = newpos return capture end
end
function parse_squote () return parse_pattern("^(')()") end
function parse_dquote () return parse_pattern("^(\")()") end
function parse_word () return parse_squote() or
parse_dquote() or
parse_pattern("^([^ \t\n]+)()") end
function parse_spaces () return parse_pattern("^([ \t]*)()") end
function parse_nl () return parse_pattern("^(\n)()") end
function parse_to_nl () return parse_pattern("^([^\n]*)()") end
function parse_word_or_nl () return parse_word() or parse_nl() end
function get_word () parse_spaces() return parse_word() end
function get_word_or_nl () parse_spaces() return parse_word_or_nl() end
_F["%L"] = WORD{name = "%L", def = LUA_QUOTE([[ parse_spaces() EVAL(parse_to_nl()) ]]), parsing = true}
RUNNING = true MODES = {}
RUN = function() while RUNNING do INTERPRET() end end
INTERPRET_WORD = function()
if _F[word] then _F[word]:interpret() return true end
end
INTERPRET_NUMBER = function()
local n = tonumber(word) if n then PSH(DS, n) return true end
end
INTERPRET = function()
word = get_word_or_nl() or ""
local _ = INTERPRET_WORD() or INTERPRET_NUMBER() or error("Can't interpret: " .. word)
end
PROG = [=[
%L _F["\n"] = NOP -- Enable us to handle new lines
%L -- Enable use to handle the of the input stream
%L _F[""] = WORD{ name = "HALT", def = LUA_QUOTE([[ RUNNING = false ]]) }
%L
%L
%L
%L _F["L["] = WORD{ name = "L[", def = LUA_QUOTE([[ PSH(DS, LUA_QUOTE(parse_pattern("^(.-)%s]()"))) ]]), parsing = true }
%L _F["'"] = WORD{ name = "'", def = LUA_QUOTE([[ PSH(DS, parse_word()) ]]), parsing = true }
%L
%L
%L _F["DEFINE"] = WORD{ name = "DEFINE", def = LUA_QUOTE([[ local name = POP(DS) _F[name] = WORD{ name = name, def = POP(DS) } ]]) }
%L
L[ POP(DS):interpret() ] 'CALL DEFINE
L[ local x, q = POP2(DS) q:interpret() PSH(DS, x) ] 'DIP DEFINE
L[ local b, f, t = POP3(DS) if b then PSH(DS, t) else PSH(DS, f) end ] '? DEFINE
%L -- This is enough to write a primitive hello, world
L[ print("Hello, World!") ] CALL
]=]
POS = 1
MODE = "interpret"
RUN()
New Annotation