Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
229 lines (172 sloc) 5.48 KB
use("core")
use("define")
use("control-flow")
use("dynamic")
use("particles")
use("comparison")
use("node")
require("kpeg")
require("set")
actions = dynamic
setups = dynamic
vars = dynamic
rule = dynamic
rule-vars = dynamic
const-name(c: Atomy::AST::Constant) = c name to-s
const-name(c: Atomy::AST::ScopedConstant) = const-name(c parent) + "::" + c name to-s
const-name(c: Atomy::AST::ToplevelConstant) = "::" + c name to-s
process-val(g, `(%((~grammar).) ~(x)(~*args))) = do:
`(~g foreign-invoke(
~(grammar text)
~(x text)
~(args collect .show join(", "))))
process-val(g, `(~a %((~grammar).) ~(x)(~*args))) = do:
`(~g seq(
~process-val(g, a),
~g foreign-invoke(
~(grammar text)
~(x text)
~(args collect .show join(", ")))))
process-val(g, `(%((~grammar).) ~x)) = do:
`(~g foreign-invoke(~(grammar text), ~(x text)))
process-val(g, `(~a %((~grammar).) ~x)) = do:
`(~g seq(~process-val(g, a), ~g foreign-invoke(~(grammar text), ~(x text))))
process-val(g, `((~v)= ~name)) = do:
val = process-val(g, v)
when(^rule-vars): ^rule-vars << name text
`(~g t(~val, ~(name text to-s)))
process-val(g, `(~a (~v)= ~name)) = do:
val = process-val(g, v)
when(^rule-vars): ^rule-vars << name text
`(~g seq(~process-val(g, a), ~g t(~val, ~(name text to-s))))
process-val(g, `(~a ~b)) =
`(~g seq(~process-val(g, a), ~process-val(g, b)))
process-val(g, `(~a | ~b)) =
process-val(g, `[~a, ~b])
process-val(g, `[~*xs]) = do:
original = ^rule-vars
new = Set new
choices =
xs collect [x]:
let(rule-vars = original dup):
choice = process-val(g, x)
new merge(^rule-vars - original)
choice
^rule-vars merge(new)
`(~g any(~*choices))
process-val(g, a: `{ ~*bs }) =
if(^actions)
then:
vars = ^rule-vars to-a
call = "actions[" + ^actions size to-s + "][" + vars collect .to-s join(", ") + "]"
^actions << [a, vars]
`(~g action(~call))
else:
`(~g action({ ~*bs }))
process-val(g, `(<(~x)>)) = do:
val = process-val(g, x)
when(^rule-vars): ^rule-vars << .text
`(~g collect(~val))
process-val(g, `(@<(~x)>)) =
`(~g bounds(~process-val(g, x)))
process-val(g, s: Atomy::AST::String) =
`(~g str(~s))
process-val(g, `(/(~(b: Atomy::AST::String))/)) =
`(~g reg(~(b raw)))
process-val(g, c: Atomy::AST::Call) = do:
args = "(" + c arguments collect .show join(", ") + ")"
`(~g ref(~(c name text to-s), nil, ~args))
process-val(g, `@~(c: Atomy::AST::Call)) = do:
args = "(" + c arguments collect .show join(", ") + ")"
`(~g invoke(~(c name text to-s), ~args))
process-val(g, `^~(c: Atomy::AST::Call)) = do:
args = "(" + c arguments collect .show join(", ") + ")"
`(~g foreign-invoke("parent", ~(c name text to-s), ~args))
process-val(g, w: Atomy::AST::Word) =
`(~g ref(~(w text to-s)))
process-val(g, `@~(w: Atomy::AST::Word)) = do:
`(~g invoke(~(w text to-s)))
process-val(g, `^~(w: Atomy::AST::Word)) = do:
`(~g foreign-invoke("parent", ~(w text to-s)))
process-val(g, `((~v)?)) =
`(~g maybe(~process-val(g, v)))
process-val(g, `((~v)+)) =
`(~g many(~process-val(g, v)))
process-val(g, `((~v)*)) =
`(~g kleene(~process-val(g, v)))
process-val(g, `&~v) =
`(~g andp(~process-val(g, v)))
process-val(g, `!~v) =
`(~g notp(~process-val(g, v)))
process-val(g, '_) =
`(~g dot)
process-val(_, s) =
raise(ArgumentError, "unknown operator: " + s to-sexp inspect)
Atomy::AST open:
ast(ParserDefiner(@source))
ParserDefiner bytecode(g) := do:
g push-rubinius
g push-literal(.__parser_init__)
g push-literal(Rubinius::Compiler compile-string(@source))
g push-scope
g push-self
g send(.attach-method, 4)
g pop
g push-self
g send(.__parser_init__, 0)
macro(grammar: ~*body): names [g]:
b = body collect [n]:
n match:
`%%{ ~*xs } -> do:
call =
if(^setups)
then:
^setups << `{ ~*xs }
"setups[" + (^setups size - 1) to-s + "][]"
else:
`{ ~*xs }
`(~g add-setup(~g action(~call)))
`(%~name := ~const) ->
`(~g add-foreign-grammar(~(name text to-s), ~const-name(const)))
`(%~name = ~expr) -> do:
-- TODO: fix this, yo
call =
if(^vars)
then:
^vars << `{ ~*xs }
"vars[" + (^vars size - 1) to-s + "][]"
else:
`{ ~*xs }
`(~g set-variable(~(name text to-s), call))
`(~(name)(~*args) := ~val) -> do:
let(rule = name text,
rule-vars = ::Set new(args collect .text)):
`(~g set(~(name text to-s)
~process-val(g, val)
~(args collect [x]: x text to-s)))
`(~name := ~val) -> do:
let(rule = name text,
rule-vars = ::Set new):
`(~g set(~(name text to-s), ~process-val(g, val)))
_ -> `unknown(~n)
`(::KPeg::Grammar new tap [~g]: ~*b)
macro(parser(~name): ~*grammar):
let(actions = [],
setups = [],
vars = []):
g = `(grammar: ~*grammar) evaluate
acts =
^actions collect [action, as]:
args = as collect [a]: Atomy::AST::Word new(0, a)
`([~*args] ~action)
def =
Atomy::AST::ParserDefiner new(
node line
::KPeg::CodeGenerator new(const-name(name), g) output)
`(do:
~name = ::KPeg::CompiledParser class:
{ self } setups := @setups ||= ~^setups
{ self } vars := @vars ||= ~^vars
actions := @actions ||= ~acts
~def
~name)
Jump to Line
Something went wrong with that request. Please try again.