|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://angg.twu.net/LUA/Arith2.lua.html
-- http://angg.twu.net/LUA/Arith2.lua
-- (find-angg "LUA/Arith2.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun a () (interactive) (find-angg "LUA/Arith2.lua"))
-- (defun o () (interactive) (find-angg "LUA/Arith1.lua"))
--
-- «.top-down-parser» (to "top-down-parser")
Tokens = Class {
fromcs = function (str) return Tokens(split(str, "(.)")) end,
fromws = function (str) return Tokens(split(str)) end,
type = "Tokens",
__tostring = function (tks) return tks:tostring() end,
__index = {
torect1 = function (tks, i)
return Rect.from(tks[i].."\n"..i)
end,
torect = function (tks, i, j)
i, j = i or 1, j or #tks
local out = tks:torect1(i)
for k=i+1,j do out = out.." "..tks:torect1(k) end
return out
end,
torectp = function (tks) return tks:torect() .. " pos=" .. tks.pos end,
tostring1 = function (tks, i, j, sep)
return table.concat(tks, sep or tks.sep or "", i or 1, j or #tks)
end,
tostring = function (tks, i, j)
return tks:torect(i or 1, j or #tks):tostring()
end,
tostringp = function (tks) return tks:torectp():tostring() end,
sub = function (tks, i, j) return TokenSeq.from(tks, i, j) end,
},
}
TokenSeq = Class {
type = "TokenSeq",
from = function (tks, i, j) return TokenSeq {tks=tks, i=i, j=j} end,
__tostring = function (ts) return ts:tostring1() end,
__concat = function (tsl, tsr) return tsl:glue(tsr) end,
__index = {
tostring1 = function (ts) return ts.tks:tostring1(ts.i, ts.j) end,
tostring = function (ts) return ts.tks:tostring (ts.i, ts.j) end,
glue = function (tsl, tsr) return TokenSeq.from(tsl.tks, tsl.i, tsr.j) end,
},
}
-- (find-dn6 "stacks.lua" "Stack")
--
Stack = Class {
type = "Stack",
new = function () return Stack {} end,
--
__tostring = function (s) return mapconcat(tostring, s, " ") end,
__index = {
push = function (s, o) table.insert(s, o); return s end,
pushs = function (s, ...) for _,o in ipairs({...}) do s:push(o) end; return s end,
--
check = function (s) assert(#s>0, s.msg or "Empty stack"); return s end,
drop = function (s) s:check(); s[#s]=nil; return s end,
dropn = function (s, n) for i=1,n do s:drop() end; return s end,
dropuntil = function (s, n) while #s>n do s:drop() end; return s end,
clear = function (s) return s:dropn(#s) end,
--
pop = function (s) return s[#s], s:dropn(1) end,
pop2 = function (s) return s[#s-1], s[#s], s:dropn(2) end,
pop3 = function (s) return s[#s-2], s[#s-1], s[#s], s:dropn(3) end,
pop4 = function (s) return s[#s-3], s[#s-2], s[#s-1], s[#s], s:dropn(4) end,
--
pick = function (s, offset) return s[#s-offset] end,
pock = function (s, offset, o) s[#s-offset] = o; return s end,
},
}
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Arith2.lua"
tks = Tokens.fromcs "(1+2)*3^(4+5)"
tks.pos = 1
= tks
= tks:sub(3,5)
= tks:sub(3,5):tostring1()
= tks:sub(3,5):tostring()
s = Stack.new()
s:pushs(22, 44)
= s
s = Stack.new()
s:pushs(tks:sub(3,6), tks:sub(7,9))
= s
--]]
Vocab = Class {
type = "Vocab",
fmt = "%12s %s",
new = function () return Vocab {_ = SetL.new()} end,
__tostring = function (v) return v:tostring() end,
__index = {
add1 = function (v, key, src)
v._:add(key, Code.vc(" o => " .. src))
end,
},
}
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Arith2.lua"
v = Vocab.new()
v:add1("foo", "bar")
v:add1("plic", "ploc")
v:add1("a", "b")
= v._:ksc()
= v._:get("foo")
= v._:get("foo").src
= v._:get("foo").code
--]]
-- «top-down-parser» (to ".top-down-parser")
parse_n = function (pos)
if tks[pos]:match("[0-9]") then
return "ok", pos+1, sub(pos, pos)
end
end
parse_plus = function (pos)
if tks[pos] == "+" then
return "ok", pos+1, sub(pos, pos)
end
end
parse_openp = function (pos)
if tks[pos] == "(" then
return "ok", pos+1, sub(pos, pos)
end
end
parse_closep = function (pos)
if tks[pos] == ")" then
return "ok", pos+1, sub(pos, pos)
end
end
--
parse_plusnorp = function (pos)
local ok1,pos1,o1 = parse_plus(pos)
if not ok1 then return end
local ok2,pos2,o2 = parse_norp(pos1)
if not ok2 then return end
return ok2, pos2, sub(pos,pos2-1)
end
parse_plusnorps = function (pos)
local pos1 = pos
while true do
local ok2,pos2,o2 = parse_plusnorp(pos1)
if ok2 then
pos1 = pos2
else
return "ok",pos1,sub(pos,pos1-1)
end
end
end
parse_norps = function (pos)
local ok1,pos1,o1 = parse_norp(pos)
if not ok1 then return end
local ok2,pos2,o2 = parse_plusnorps(pos1)
return ok2, pos2, sub(pos,pos2-1)
end
parse_norp = function (pos)
local ok1,pos1,o1 = parse_n(pos)
if ok1 then return ok1,pos1,o1 end
local ok1,pos1,o1 = parse_p(pos)
if ok1 then return ok1,pos1,o1 end
end
parse_p = function (pos)
local ok1,pos1,o1 = parse_openp(pos)
if not ok1 then return end
local ok2,pos2,o2 = parse_norps(pos1)
if not ok2 then return end
local ok3,pos3,o3 = parse_closep(pos2)
if ok3 then return "ok", pos3, sub(pos, pos3-1) end
end
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Arith2.lua"
= id(2,3,4)
= 1 and id(2,3,4)
tks = Tokens.fromcs "(1+2+3)+4+(5+6)"
tks.pos = 1
= tks
sub = function (i, j) return tks:sub(i, j) end
= parse_openp(1)
= parse_n(2)
= parse_plus(3)
= parse_n(4)
= parse_closep(5)
= parse_p(1) -- =(
= parse_plusnorp(3)
= parse_plusnorps(3)
= parse_norp(2)
= parse_norp(4)
= parse_norps(2)
= parse_norp(1)
= parse_norps(1)
--]]
-- Local Variables:
-- coding: utf-8-unix
-- End: