include 'parser/walker'
include 'peg/sexp'
m = walker.new
m.init = { ast |
my.ast = ast
}
m.prototype.write = {
my.process my.ast
}
m.prototype.walk_sexps = { nodes |
w = my
nodes.map { n |
true? sexp?(n)
{ w.process n }
{ true? n.array?
{ n.map { i | w.process i } }
{ n }
}
}
}
m.prototype.unhandled = { node |
args = walk_sexps node.nodes
"#{node.name}(#{args.join(',')})"
}
m.walk :grammar { node |
w = my
"peg.new {\n#{node.nodes.map({ n | w.process n }).join("\n")}\n}"
}
m.walk :str { node |
"str(\"#{node.last}\")"
}
m.walk :regex { node |
"reg(/#{node.last}/)"
}
m.walk :rule_def { node |
" set(:#{node.nodes.deq}, #{walk_sexps(node.nodes).join(',')})"
}
m.walk :rule_ref { node |
"ref(:#{node.last})"
}
m.walk :label { node |
name = node.nodes.deq
"label(:#{name}, #{walk_sexps(node.nodes).join(',')})"
}
m.walk :seq { node |
l = node.nodes.last.name
true? l == :squish || { l == :action }
{
action = process node.nodes.pop
true? node.nodes.length == 1
{ "action(#{walk_sexps(node.nodes).join(',')}, #{action})" }
{ "action(seq(#{walk_sexps(node.nodes).join(',')}), #{action})" }
}
{
"seq(#{walk_sexps(node.nodes).join(', ')})"
}
}
m.walk :squish { node |
"{ my.squish #{node.last} }"
}
export m, :peg_writer