Commit 07581b65 authored by Jamie A. Jennings's avatar Jamie A. Jennings

Rewrote stack adt to be about 7x faster. Might look for other shunting-yard...

Rewrote stack adt to be about 7x faster.  Might look for other shunting-yard optimizations, although currently the compilation (not the parsing) is likely taking up all the time in e:load()
parent 0b7f589b
......@@ -43,31 +43,39 @@ local list = require("list")
local map = list.map
local filter = list.filter
local stack_mt =
{ __index = {push = function(self, elt)
self.top = self.top + 1
self[self.top]=elt
return
end,
pop = function(self)
local top = self.top
local elt = self[top]
if top > 0 then self.top = top - 1; end
return elt
end,
peek = function(self)
return self[self.top]
end,
is_empty = function(self)
return self.top==0
end,
to_list = function(self)
for i=self.top+1, #self do self[i]=nil; end
self.top = nil
return self
end}
}
local function new_stack()
local data = {}
local top = 0
return {push = function(elt)
top = top + 1
data[top]=elt
return
end,
pop = function()
local elt = data[top]
if top > 0 then top = top - 1; end
return elt
end,
peek = function()
return data[top]
end,
is_empty = function()
return top==0
end,
to_list = function()
local ls = {}
for i=1,top do ls[i] = data[i]; end
return ls
end}
data.top = 0
setmetatable(data, stack_mt)
return data
end
-- TEMP:
STACK = new_stack
local function is_atmosphere(pt)
return not common.not_atmosphere(pt)
......@@ -243,8 +251,8 @@ end
-- expression and associate them with that expression.
local function pop_exp(exps)
local items = {}
while (not exps.is_empty()) do
local item = exps.pop()
while (not exps:is_empty()) do
local item = exps:pop()
table.insert(items, item)
if not is_atmosphere(item) then break; end
end
......@@ -307,27 +315,27 @@ function shunting_yard_explist(subs, attribute_table)
local opstack = new_stack()
for _, e in ipairs(subs) do
if is_atmosphere(e) then
exps.push(e)
exps:push(e)
elseif e.type == "operator" then
while not should_push(e.data, opstack.peek(), attribute_table) do
while not should_push(e.data, opstack:peek(), attribute_table) do
-- To produce a postfix sequence of exps and ops, as original
-- shunting yard algorithm did:
-- exps.push(opstack.pop())
-- exps:push(opstack:pop())
-- Instead, we will convert to prefix in tree form. Would be
-- simpler except that there's atmosphere on the exps stack.
exps.push(make_prefix_tree(opstack.pop(), exps))
exps:push(make_prefix_tree(opstack:pop(), exps))
end
opstack.push(e)
opstack:push(e)
else
exps.push(shunting_yard_exp(e, attribute_table))
exps:push(shunting_yard_exp(e, attribute_table))
end
end
while not opstack.is_empty() do
while not opstack:is_empty() do
-- To produce a postfix sequence of exps and ops:
-- exps.push(opstack.pop())
exps.push(make_prefix_tree(opstack.pop(), exps))
-- exps:push(opstack:pop())
exps:push(make_prefix_tree(opstack:pop(), exps))
end
return exps.to_list()
return exps:to_list()
end
function shunting_yard(exp)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment