Skip to content
Browse files

First of the incremental optimizations (this one gets about 25%):

- remove some unnecessary proc { ... }.call stuff, and cleanup the translated
  ruby source.
- add _x variants of some of the runtime modifier functions, that use blocks
  instead of procs. then deleted the originals. will rename back later.
  • Loading branch information...
1 parent 758634c commit 0b1123a4956f8e88b1c5c52d60046c046fed42a9 Charles Lowe committed Sep 18, 2008
Showing with 127 additions and 108 deletions.
  1. +3 −0 README
  2. +21 −3 Rakefile
  3. +68 −68 lib/ometa/bootstrap.rb
  4. +23 −25 lib/ometa/runtime.rb
  5. +12 −12 ometa/ometa_translator.ometa
View
3 README
@@ -8,3 +8,6 @@ Briefly what OMeta is, some links to the ometajs stuff.
similar, and use them based on mtime / flag combination.
* try to optimize some more. profile wasn't particularly illuminating.
* then write some actual tests.
+* i think that super is actually broken at the moment, and its not used
+ in the standard grammar. the js one uses it, so could test with that.
+
View
24 Rakefile
@@ -20,12 +20,12 @@ module Bootstrap
class V0 < Object
end
- def single root=V0
- puts "bootstrapping ometa using #{root.inspect}"
+ def single root=V0, quiet=false
+ puts "bootstrapping ometa using #{root.inspect}" unless quiet
all = ''
BOOTSTRAP_GRAMMARS.each do |filename|
- puts " - #{filename}"
+ puts " - #{filename}" unless quiet
grammar = File.read(File.dirname(__FILE__) + '/ometa/' + filename)
ast = root.const_get('OMetaParser').matchAllwith(grammar, 'grammar')
ast = root.const_get('OMetaOptimizer').matchwith(ast, 'optimizeGrammar')
@@ -83,3 +83,21 @@ task :bootstrap do
end
end
+desc 'Simple benchmark'
+task :bench do
+ # all we do is run the complete bootstrap 3 times.
+ # this currently takes about 44-48 seconds currently on my laptop (~1.4Ghz single core).
+ # they're pretty simple grammars, so ideally this'd take more like a few seconds...
+ # ok after using _x* variant functions which use blocks instead of procs, and removing
+ # some other unnecessary procs, we get this down to 30 s. this also has the nice side
+ # effect of reducing the size of bootstrap.rb from 13kb down to 10kb.
+ # can get it down to 28 with a bit more of that. will now try inlining _or() alternations
+ # to avoid the only remaining need for procs. if that doesn't have an appreciable impact,
+ # (eg > 5s), i'll revert it and focus on runtime.rb, which is probably where the slowness
+ # is - implementation of streams, memoization, the _apply function etc.
+ # just tested it on ruby1.9, and the speed was the same.
+ t = Time.now
+ 3.times { Bootstrap.single Bootstrap::V0, true }
+ puts "3 bootstraps took #{Time.now - t} seconds"
+end
+
View
136 lib/ometa/bootstrap.rb
@@ -1,361 +1,361 @@
#
-# this file was automatically generated by `rake bootstrap' at Wed Sep 17 23:04:22 +1000 2008.
+# this file was automatically generated by `rake bootstrap' at Thu Sep 18 00:52:06 +1000 2008.
# do not modify
#
NullOptimizer = Class.new(OMeta) do
@name = "NullOptimizer"
def setHelped
-return @_didSomething = true
+@_didSomething = true
end
def helped
-return _pred(@_didSomething)
+_pred(@_didSomething)
end
def trans
t = ans = nil
-return _or((proc{return (proc{_form(proc{return (proc{t=_apply("anything");_pred(respond_to?(t));return ans=_applyWithArgs("apply",t)}).call});return ans}).call}),(proc{return _apply("anything")}))
+_or(proc { (_xform { (t = _apply("anything");_pred(respond_to?(t));ans = _applyWithArgs("apply",t)) };ans) }, proc { _apply("anything") })
end
def optimize
x = nil
-return (proc{x=_apply("trans");_apply("helped");return x}).call
+(x = _apply("trans");_apply("helped");x)
end
def Or
xs = nil
-return (proc{xs=_many(proc{return _apply("trans")});return ['Or'].concat(xs)}).call
+(xs = _xmany { _apply("trans") };['Or'].concat(xs))
end
def And
xs = nil
-return (proc{xs=_many(proc{return _apply("trans")});return ['And'].concat(xs)}).call
+(xs = _xmany { _apply("trans") };['And'].concat(xs))
end
def Many
x = nil
-return (proc{x=_apply("trans");return ['Many', x]}).call
+(x = _apply("trans");['Many', x])
end
def Many1
x = nil
-return (proc{x=_apply("trans");return ['Many1', x]}).call
+(x = _apply("trans");['Many1', x])
end
def Set
n = v = nil
-return (proc{n=_apply("anything");v=_apply("trans");return ['Set', n, v]}).call
+(n = _apply("anything");v = _apply("trans");['Set', n, v])
end
def Not
x = nil
-return (proc{x=_apply("trans");return ['Not', x]}).call
+(x = _apply("trans");['Not', x])
end
def Lookahead
x = nil
-return (proc{x=_apply("trans");return ['Lookahead', x]}).call
+(x = _apply("trans");['Lookahead', x])
end
def Form
x = nil
-return (proc{x=_apply("trans");return ['Form', x]}).call
+(x = _apply("trans");['Form', x])
end
def Rule
name = ls = body = nil
-return (proc{name=_apply("anything");ls=_apply("anything");body=_apply("trans");return ['Rule', name, ls, body]}).call
+(name = _apply("anything");ls = _apply("anything");body = _apply("trans");['Rule', name, ls, body])
end
def initialize_hook
-return @_didSomething = false
+@_didSomething = false
end
end
AndOrOptimizer = Class.new(NullOptimizer) do
@name = "AndOrOptimizer"
def And
x = xs = nil
-return _or((proc{return (proc{x=_apply("trans");_apply("end");_apply("setHelped");return x}).call}),(proc{return (proc{xs=_applyWithArgs("transInside","And");return ['And'].concat(xs)}).call}))
+_or(proc { (x = _apply("trans");_apply("end");_apply("setHelped");x) }, proc { (xs = _applyWithArgs("transInside","And");['And'].concat(xs)) })
end
def Or
x = xs = nil
-return _or((proc{return (proc{x=_apply("trans");_apply("end");_apply("setHelped");return x}).call}),(proc{return (proc{xs=_applyWithArgs("transInside","Or");return ['Or'].concat(xs)}).call}))
+_or(proc { (x = _apply("trans");_apply("end");_apply("setHelped");x) }, proc { (xs = _applyWithArgs("transInside","Or");['Or'].concat(xs)) })
end
def transInside
t = xs = ys = x = xs = nil
-return (proc{t=_apply("anything");return _or((proc{return (proc{_form(proc{return (proc{_applyWithArgs("exactly",t);return xs=_applyWithArgs("transInside",t)}).call});ys=_applyWithArgs("transInside",t);_apply("setHelped");return xs.concat(ys)}).call}),(proc{return (proc{x=_apply("trans");xs=_applyWithArgs("transInside",t);return [x].concat(xs)}).call}),(proc{return []}))}).call
+(t = _apply("anything");_or(proc { (_xform { (_applyWithArgs("exactly",t);xs = _applyWithArgs("transInside",t)) };ys = _applyWithArgs("transInside",t);_apply("setHelped");xs.concat(ys)) }, proc { (x = _apply("trans");xs = _applyWithArgs("transInside",t);[x].concat(xs)) }, proc { [] }))
end
end
OMetaOptimizer = Class.new(OMeta) do
@name = "OMetaOptimizer"
def optimizeGrammar
n = sn = rs = nil
-return (proc{_form(proc{return (proc{_applyWithArgs("exactly","Grammar");n=_apply("anything");sn=_apply("anything");return rs=_many(proc{return _apply("optimizeRule")})}).call});return ['Grammar', n, sn].concat(rs)}).call
+(_xform { (_applyWithArgs("exactly","Grammar");n = _apply("anything");sn = _apply("anything");rs = _xmany { _apply("optimizeRule") }) };['Grammar', n, sn].concat(rs))
end
def optimizeRule
r = r = nil
-return (proc{r=_apply("anything");_many(proc{return r=_applyWithArgs("foreign",AndOrOptimizer,"optimize",r)});return r}).call
+(r = _apply("anything");_xmany { r = _applyWithArgs("foreign",AndOrOptimizer,"optimize",r) };r)
end
end
BSRubyParser = Class.new(OMeta) do
@name = "BSRubyParser"
def eChar
c = nil
-return _or((proc{return (proc{_applyWithArgs("exactly","\\");c=_apply("char");return { 'n' => "\n", 't' => "\t", 'r' => "\r", '\'' => "'", '\"' => '"', '\\' => '\\' }[c]}).call}),(proc{return _apply("char")}))
+_or(proc { (_applyWithArgs("exactly","\\");c = _apply("char");{ 'n' => "\n", 't' => "\t", 'r' => "\r", '\'' => "'", '\"' => '"', '\\' => '\\' }[c]) }, proc { _apply("char") })
end
def tsString
xs = nil
-return (proc{_applyWithArgs("exactly","'");xs=_many(proc{return (proc{_not(proc{return _applyWithArgs("exactly","'")});return _apply("eChar")}).call});_applyWithArgs("exactly","'");return xs.join('')}).call
+(_applyWithArgs("exactly","'");xs = _xmany { (_xnot { _applyWithArgs("exactly","'") };_apply("eChar")) };_applyWithArgs("exactly","'");xs.join(''))
end
def expr
-return (proc{_apply("spaces");return _apply("tsString")}).call
+(_apply("spaces");_apply("tsString"))
end
def semAction
xs = nil
-return (proc{_apply("spaces");xs=_many(proc{return (proc{_not(proc{return _applyWithArgs("seq","\n")});return _apply("anything")}).call});return xs.join('')}).call
+(_apply("spaces");xs = _xmany { (_xnot { _applyWithArgs("seq","\n") };_apply("anything")) };xs.join(''))
end
end
BSRubyTranslator = Class.new(OMeta) do
@name = "BSRubyTranslator"
def trans
-return _apply("anything")
+_apply("anything")
end
end
OMetaParser = Class.new(OMeta) do
@name = "OMetaParser"
def nameFirst
-return _or((proc{return _applyWithArgs("exactly","_")}),(proc{return _applyWithArgs("exactly","$")}),(proc{return _apply("letter")}))
+_or(proc { _applyWithArgs("exactly","_") }, proc { _applyWithArgs("exactly","$") }, proc { _apply("letter") })
end
def nameRest
-return _or((proc{return _apply("nameFirst")}),(proc{return _apply("digit")}))
+_or(proc { _apply("nameFirst") }, proc { _apply("digit") })
end
def tsName
xs = nil
-return (proc{xs=_applyWithArgs("firstAndRest","nameFirst","nameRest");return xs.join('')}).call
+(xs = _applyWithArgs("firstAndRest","nameFirst","nameRest");xs.join(''))
end
def name
-return (proc{_apply("spaces");return _apply("tsName")}).call
+(_apply("spaces");_apply("tsName"))
end
def eChar
c = nil
-return _or((proc{return (proc{_applyWithArgs("exactly","\\");c=_apply("char");return { 'n' => "\n", 't' => "\t", 'r' => "\r", '\'' => "'", '\"' => '"', '\\' => '\\' }[c]}).call}),(proc{return _apply("char")}))
+_or(proc { (_applyWithArgs("exactly","\\");c = _apply("char");{ 'n' => "\n", 't' => "\t", 'r' => "\r", '\'' => "'", '\"' => '"', '\\' => '\\' }[c]) }, proc { _apply("char") })
end
def tsString
xs = nil
-return (proc{_applyWithArgs("exactly","'");xs=_many(proc{return (proc{_not(proc{return _applyWithArgs("exactly","'")});return _apply("eChar")}).call});_applyWithArgs("exactly","'");return xs.join('')}).call
+(_applyWithArgs("exactly","'");xs = _xmany { (_xnot { _applyWithArgs("exactly","'") };_apply("eChar")) };_applyWithArgs("exactly","'");xs.join(''))
end
def characters
xs = nil
-return (proc{_applyWithArgs("exactly","`");_applyWithArgs("exactly","`");xs=_many(proc{return (proc{_not(proc{return (proc{_applyWithArgs("exactly","'");return _applyWithArgs("exactly","'")}).call});return _apply("eChar")}).call});_applyWithArgs("exactly","'");_applyWithArgs("exactly","'");return ['App', 'seq', xs.join('').toProgramString()]}).call
+(_applyWithArgs("exactly","`");_applyWithArgs("exactly","`");xs = _xmany { (_xnot { (_applyWithArgs("exactly","'");_applyWithArgs("exactly","'")) };_apply("eChar")) };_applyWithArgs("exactly","'");_applyWithArgs("exactly","'");['App', 'seq', xs.join('').toProgramString()])
end
def sCharacters
xs = nil
-return (proc{_applyWithArgs("exactly","\"");xs=_many(proc{return (proc{_not(proc{return _applyWithArgs("exactly","\"")});return _apply("eChar")}).call});_applyWithArgs("exactly","\"");return ['App', 'token', xs.join('').toProgramString()]}).call
+(_applyWithArgs("exactly","\"");xs = _xmany { (_xnot { _applyWithArgs("exactly","\"") };_apply("eChar")) };_applyWithArgs("exactly","\"");['App', 'token', xs.join('').toProgramString()])
end
def string
xs = nil
-return (proc{xs=_or((proc{return (proc{_or((proc{return _applyWithArgs("exactly","#")}),(proc{return _applyWithArgs("exactly","`")}));return _apply("tsName")}).call}),(proc{return _apply("tsString")}));return ['App', 'exactly', xs.toProgramString()]}).call
+(xs = _or(proc { (_or(proc { _applyWithArgs("exactly","#") }, proc { _applyWithArgs("exactly","`") });_apply("tsName")) }, proc { _apply("tsString") });['App', 'exactly', xs.toProgramString()])
end
def number
sign = ds = nil
-return (proc{sign=_or((proc{return _applyWithArgs("exactly","-")}),(proc{return (proc{_apply("empty");return ''}).call}));ds=_many1(proc{return _apply("digit")});return ['App', 'exactly', sign + ds.join('')]}).call
+(sign = _or(proc { _applyWithArgs("exactly","-") }, proc { (_apply("empty");'') });ds = _xmany1 { _apply("digit") };['App', 'exactly', sign + ds.join('')])
end
def keyword
xs = nil
-return (proc{xs=_apply("anything");_applyWithArgs("token",xs);_not(proc{return _apply("letterOrDigit")});return xs}).call
+(xs = _apply("anything");_applyWithArgs("token",xs);_xnot { _apply("letterOrDigit") };xs)
end
def hostExpr
r = nil
-return (proc{r=_applyWithArgs("foreign",BSRubyParser,"expr");return _applyWithArgs("foreign",BSRubyTranslator,"trans",r)}).call
+(r = _applyWithArgs("foreign",BSRubyParser,"expr");_applyWithArgs("foreign",BSRubyTranslator,"trans",r))
end
def atomicHostExpr
r = nil
-return (proc{r=_applyWithArgs("foreign",BSRubyParser,"semAction");return _applyWithArgs("foreign",BSRubyTranslator,"trans",r)}).call
+(r = _applyWithArgs("foreign",BSRubyParser,"semAction");_applyWithArgs("foreign",BSRubyTranslator,"trans",r))
end
def args
xs = nil
-return _or((proc{return (proc{_applyWithArgs("token","(");xs=_applyWithArgs("listOf","hostExpr",",");_applyWithArgs("token",")");return xs}).call}),(proc{return (proc{_apply("empty");return []}).call}))
+_or(proc { (_applyWithArgs("token","(");xs = _applyWithArgs("listOf","hostExpr",",");_applyWithArgs("token",")");xs) }, proc { (_apply("empty");[]) })
end
def application
rule = as = nil
-return (proc{rule=_apply("name");as=_apply("args");return ['App', rule].concat(as)}).call
+(rule = _apply("name");as = _apply("args");['App', rule].concat(as))
end
def semAction
x = nil
-return (proc{_or((proc{return _applyWithArgs("token","!")}),(proc{return _applyWithArgs("token","->")}));x=_apply("atomicHostExpr");return ['Act', x]}).call
+(_or(proc { _applyWithArgs("token","!") }, proc { _applyWithArgs("token","->") });x = _apply("atomicHostExpr");['Act', x])
end
def semPred
x = nil
-return (proc{_applyWithArgs("token","?");x=_apply("atomicHostExpr");return ['Pred', x]}).call
+(_applyWithArgs("token","?");x = _apply("atomicHostExpr");['Pred', x])
end
def expr
xs = nil
-return (proc{xs=_applyWithArgs("listOf","expr4","|");return ['Or'].concat(xs)}).call
+(xs = _applyWithArgs("listOf","expr4","|");['Or'].concat(xs))
end
def expr4
xs = nil
-return (proc{xs=_many(proc{return _apply("expr3")});return ['And'].concat(xs)}).call
+(xs = _xmany { _apply("expr3") };['And'].concat(xs))
end
def optIter
x = nil
-return (proc{x=_apply("anything");return _or((proc{return (proc{_applyWithArgs("token","*");return ['Many', x]}).call}),(proc{return (proc{_applyWithArgs("token","+");return ['Many1', x]}).call}),(proc{return (proc{_apply("empty");return x}).call}))}).call
+(x = _apply("anything");_or(proc { (_applyWithArgs("token","*");['Many', x]) }, proc { (_applyWithArgs("token","+");['Many1', x]) }, proc { (_apply("empty");x) }))
end
def expr3
x = x = n = n = nil
-return _or((proc{return (proc{x=_apply("expr2");x=_applyWithArgs("optIter",x);return _or((proc{return (proc{_applyWithArgs("exactly",":");n=_apply("name");return (@locals << n; ['Set', n, x])}).call}),(proc{return (proc{_apply("empty");return x}).call}))}).call}),(proc{return (proc{_applyWithArgs("token",":");n=_apply("name");return (@locals << n; ['Set', n, ['App', 'anything']])}).call}))
+_or(proc { (x = _apply("expr2");x = _applyWithArgs("optIter",x);_or(proc { (_applyWithArgs("exactly",":");n = _apply("name");(@locals << n; ['Set', n, x])) }, proc { (_apply("empty");x) })) }, proc { (_applyWithArgs("token",":");n = _apply("name");(@locals << n; ['Set', n, ['App', 'anything']])) })
end
def expr2
x = x = nil
-return _or((proc{return (proc{_applyWithArgs("token","~");x=_apply("expr2");return ['Not', x]}).call}),(proc{return (proc{_applyWithArgs("token","&");x=_apply("expr1");return ['Lookahead', x]}).call}),(proc{return _apply("expr1")}))
+_or(proc { (_applyWithArgs("token","~");x = _apply("expr2");['Not', x]) }, proc { (_applyWithArgs("token","&");x = _apply("expr1");['Lookahead', x]) }, proc { _apply("expr1") })
end
def expr1
x = x = x = nil
-return _or((proc{return _apply("application")}),(proc{return _apply("semAction")}),(proc{return _apply("semPred")}),(proc{return (proc{x=_or((proc{return _applyWithArgs("keyword","undefined")}),(proc{return _applyWithArgs("keyword","nil")}),(proc{return _applyWithArgs("keyword","true")}),(proc{return _applyWithArgs("keyword","false")}));return ['App', 'exactly', x]}).call}),(proc{return (proc{_apply("spaces");return _or((proc{return _apply("characters")}),(proc{return _apply("sCharacters")}),(proc{return _apply("string")}),(proc{return _apply("number")}))}).call}),(proc{return (proc{_applyWithArgs("token","[");x=_apply("expr");_applyWithArgs("token","]");return ['Form', x]}).call}),(proc{return (proc{_applyWithArgs("token","(");x=_apply("expr");_applyWithArgs("token",")");return x}).call}))
+_or(proc { _apply("application") }, proc { _apply("semAction") }, proc { _apply("semPred") }, proc { (x = _or(proc { _applyWithArgs("keyword","undefined") }, proc { _applyWithArgs("keyword","nil") }, proc { _applyWithArgs("keyword","true") }, proc { _applyWithArgs("keyword","false") });['App', 'exactly', x]) }, proc { (_apply("spaces");_or(proc { _apply("characters") }, proc { _apply("sCharacters") }, proc { _apply("string") }, proc { _apply("number") })) }, proc { (_applyWithArgs("token","[");x = _apply("expr");_applyWithArgs("token","]");['Form', x]) }, proc { (_applyWithArgs("token","(");x = _apply("expr");_applyWithArgs("token",")");x) })
end
def ruleName
-return _or((proc{return _apply("name")}),(proc{return (proc{_apply("spaces");return _apply("tsString")}).call}))
+_or(proc { _apply("name") }, proc { (_apply("spaces");_apply("tsString")) })
end
def rule
n = x = xs = nil
-return (proc{_lookahead(proc{return n=_apply("ruleName")});@locals = [];x=_applyWithArgs("rulePart",n);xs=_many(proc{return (proc{_applyWithArgs("token",",");return _applyWithArgs("rulePart",n)}).call});return ['Rule', n, @locals, ['Or', x].concat(xs)]}).call
+(_xlookahead { n = _apply("ruleName") };@locals = [];x = _applyWithArgs("rulePart",n);xs = _xmany { (_applyWithArgs("token",",");_applyWithArgs("rulePart",n)) };['Rule', n, @locals, ['Or', x].concat(xs)])
end
def rulePart
rn = n = b1 = b2 = nil
-return (proc{rn=_apply("anything");n=_apply("ruleName");_pred(n == rn);b1=_apply("expr4");return _or((proc{return (proc{_applyWithArgs("token","=");b2=_apply("expr");return ['And', b1, b2]}).call}),(proc{return (proc{_apply("empty");return b1}).call}))}).call
+(rn = _apply("anything");n = _apply("ruleName");_pred(n == rn);b1 = _apply("expr4");_or(proc { (_applyWithArgs("token","=");b2 = _apply("expr");['And', b1, b2]) }, proc { (_apply("empty");b1) }))
end
def grammar
n = sn = rs = nil
-return (proc{_applyWithArgs("keyword","ometa");n=_apply("name");sn=_or((proc{return (proc{_applyWithArgs("token","<:");return _apply("name")}).call}),(proc{return (proc{_apply("empty");return OMeta}).call}));_applyWithArgs("token","{");rs=_applyWithArgs("listOf","rule",",");_applyWithArgs("token","}");return ['Grammar', n, sn].concat(rs)}).call
+(_applyWithArgs("keyword","ometa");n = _apply("name");sn = _or(proc { (_applyWithArgs("token","<:");_apply("name")) }, proc { (_apply("empty");OMeta) });_applyWithArgs("token","{");rs = _applyWithArgs("listOf","rule",",");_applyWithArgs("token","}");['Grammar', n, sn].concat(rs))
end
end
RubyOMetaTranslator = Class.new(OMeta) do
@name = "RubyOMetaTranslator"
def trans
t = ans = nil
-return (proc{_form(proc{return (proc{t=_apply("anything");return ans=_applyWithArgs("apply",t)}).call});return ans}).call
+(_xform { (t = _apply("anything");ans = _applyWithArgs("apply",t)) };ans)
end
def App
args = rule = args = rule = nil
-return _or((proc{return (proc{_applyWithArgs("exactly","super");args=_many1(proc{return _apply("anything")});return ['_superApplyWithArgs(', args.join(','), ')'].join('')}).call}),(proc{return (proc{rule=_apply("anything");args=_many1(proc{return _apply("anything")});return ['_applyWithArgs("', rule, '",', args.join(','), ')'].join('')}).call}),(proc{return (proc{rule=_apply("anything");return ['_apply("', rule, '")'] .join('')}).call}))
+_or(proc { (_applyWithArgs("exactly","super");args = _xmany1 { _apply("anything") };['_superApplyWithArgs(', args.join(','), ')'].join('')) }, proc { (rule = _apply("anything");args = _xmany1 { _apply("anything") };['_applyWithArgs("', rule, '",', args.join(','), ')'].join('')) }, proc { (rule = _apply("anything");['_apply("', rule, '")'] .join('')) })
end
def Act
expr = nil
-return (proc{expr=_apply("anything");return expr}).call
+(expr = _apply("anything");expr)
end
def Pred
expr = nil
-return (proc{expr=_apply("anything");return ['_pred(', expr, ')'] .join('')}).call
+(expr = _apply("anything");"_pred(#{expr})")
end
def Or
xs = nil
-return (proc{xs=_many(proc{return _apply("transFn")});return ['_or(', xs.join(','), ')'] .join('')}).call
+(xs = _xmany { _apply("transFn") };"_or(#{xs * ', '})")
end
def And
xs = y = nil
-return _or((proc{return (proc{xs=_many(proc{return _applyWithArgs("notLast","trans")});y=_apply("trans");return (( xs.push('return ' + y); ['(proc{', xs.join(';'), '}).call'].join('') ))}).call}),(proc{return '(proc{})'}))
+_or(proc { (xs = _xmany { _applyWithArgs("notLast","trans") };y = _apply("trans");"(#{(xs + [y]) * ';'})") }, proc { "proc {}" })
end
def Many
x = nil
-return (proc{x=_apply("trans");return ['_many(proc{return ', x, '})'] .join('')}).call
+(x = _apply("trans");"_xmany { #{x} }")
end
def Many1
x = nil
-return (proc{x=_apply("trans");return ['_many1(proc{return ', x, '})'] .join('')}).call
+(x = _apply("trans");"_xmany1 { #{x} }")
end
def Set
n = v = nil
-return (proc{n=_apply("anything");v=_apply("trans");return [n, '=', v].join('')}).call
+(n = _apply("anything");v = _apply("trans");"#{n} = #{v}")
end
def Not
x = nil
-return (proc{x=_apply("trans");return ['_not(proc{return ', x, '})'] .join('')}).call
+(x = _apply("trans");"_xnot { #{x} }")
end
def Lookahead
x = nil
-return (proc{x=_apply("trans");return ['_lookahead(proc{return ', x, '})'] .join('')}).call
+(x = _apply("trans");"_xlookahead { #{x} }")
end
def Form
x = nil
-return (proc{x=_apply("trans");return ['_form(proc{return ', x, '})'] .join('')}).call
+(x = _apply("trans");"_xform { #{x} }")
end
def Rule
name = ls = body = nil
-return (proc{name=_apply("anything");ls=_apply("locals");body=_apply("trans");return ["def ", name, "\n", ls, "\nreturn ", body, "\nend\n"] .join('')}).call
+(name = _apply("anything");ls = _apply("locals");body = _apply("trans");"def #{name}\n#{ls}\n#{body}\nend\n")
end
def Grammar
name = sName = rules = nil
-return (proc{name=_apply("anything");sName=_apply("anything");rules=_many(proc{return _apply("trans")});return ["Class.new(", sName, ") do\n@name = ", name.inspect, "\n", rules.join("\n"), 'end'] .join('')}).call
+(name = _apply("anything");sName = _apply("anything");rules = _xmany { _apply("trans") };["Class.new(", sName, ") do\n@name = ", name.inspect, "\n", rules.join("\n"), 'end'] .join(''))
end
def locals
vs = nil
-return _or((proc{return (proc{_form(proc{return vs=_many1(proc{return _apply("anything")})});return vs.map { |v| "#{v} = " }.join + 'nil'}).call}),(proc{return (proc{_form(proc{return (proc{})});return ''}).call}))
+_or(proc { (_xform { vs = _xmany1 { _apply("anything") } };vs.map { |v| "#{v} = " }.join + 'nil') }, proc { (_xform { proc {} };'') })
end
def transFn
x = nil
-return (proc{x=_apply("trans");return ['(proc{return ', x, '})'] .join('')}).call
+(x = _apply("trans");"proc { #{x} }")
end
end
View
48 lib/ometa/runtime.rb
@@ -6,7 +6,7 @@ class Fail < StandardError
end
class Character < String
- undef_method :each
+ undef_method :each if ''.respond_to?(:each)
class StringWrapper
include Enumerable
@@ -225,23 +225,22 @@ def _pred(b)
raise Fail
end
- def _not(x)
+ def _xnot
oldInput = @input.copy
begin
- x.call
+ yield
rescue Fail
- else
- raise Fail
+ @input = oldInput
+ return true
end
- @input = oldInput
- return true
+ raise Fail
end
- def _lookahead(x)
+ def _xlookahead
oldInput = @input.copy
- r = x.call
+ r = yield
@input = oldInput
- return r
+ r
end
def _or(*args)
@@ -256,33 +255,33 @@ def _or(*args)
raise Fail
end
- def _many(x, *ans)
+ def _xmany(*ans)
while true
oldInput = @input.copy
begin
- ans << x.call
+ ans << yield
next
rescue Fail
end
@input = oldInput
break
end
- return ans
+ ans
end
- def _many1(x)
- _many x, x.call
+ def _xmany1(&block)
+ _xmany block.call, &block
end
- def _form(x)
+ def _xform
v = _apply "anything"
raise Fail unless v.respond_to? :each
oldInput = @input
@input = LazyStream.new UNDEFINED, UNDEFINED, ReadStream.new(v)
- r = x.call
+ r = yield
_apply "end"
@input = oldInput
- return v
+ v
end
#// some basic rules
@@ -293,7 +292,7 @@ def anything
end
def end
- _not proc { return _apply("anything") }
+ _xnot { _apply("anything") }
end
def empty
@@ -337,7 +336,7 @@ def space
end
def spaces
- _many proc{ _apply("space") }
+ _xmany { _apply("space") }
end
def digit
@@ -373,7 +372,7 @@ def letterOrDigit
def firstAndRest
first = _apply 'anything'
rest = _apply 'anything'
- _many proc { _apply rest }, _apply(first)
+ _xmany(_apply(first)) { _apply rest }
end
def seq
@@ -388,7 +387,7 @@ def seq
def notLast
rule = _apply("anything")
r = _apply(rule)
- _lookahead(proc { return _apply(rule) })
+ _xlookahead { _apply(rule) }
return r
end
@@ -434,11 +433,10 @@ def listOf
delim = _apply("anything")
_or(proc {
r = _apply(rule)
- _many(proc {
+ _xmany(r) {
_applyWithArgs("token", delim)
_apply(rule)
- },
- r)
+ }
},
proc { [] }
)
View
24 ometa/ometa_translator.ometa
@@ -10,34 +10,34 @@ ometa RubyOMetaTranslator {
,
Act :expr -> expr
,
- Pred :expr -> ['_pred(', expr, ')'] .join('')
+ Pred :expr -> "_pred(#{expr})"
,
- Or transFn*:xs -> ['_or(', xs.join(','), ')'] .join('')
+ Or transFn*:xs -> "_or(#{xs * ', '})"
,
- And notLast('"trans"')*:xs trans:y -> (( xs.push('return ' + y); ['(proc{', xs.join(';'), '}).call'].join('') ))
+ And notLast('"trans"')*:xs trans:y -> "(#{(xs + [y]) * ';'})"
,
- And -> '(proc{})'
+ And -> "proc {}"
,
- Many trans:x -> ['_many(proc{return ', x, '})'] .join('')
+ Many trans:x -> "_xmany { #{x} }"
,
- Many1 trans:x -> ['_many1(proc{return ', x, '})'] .join('')
+ Many1 trans:x -> "_xmany1 { #{x} }"
,
- Set :n trans:v -> [n, '=', v].join('')
+ Set :n trans:v -> "#{n} = #{v}"
,
- Not trans:x -> ['_not(proc{return ', x, '})'] .join('')
+ Not trans:x -> "_xnot { #{x} }"
,
- Lookahead trans:x -> ['_lookahead(proc{return ', x, '})'] .join('')
+ Lookahead trans:x -> "_xlookahead { #{x} }"
,
- Form trans:x -> ['_form(proc{return ', x, '})'] .join('')
+ Form trans:x -> "_xform { #{x} }"
,
- Rule :name locals:ls trans:body -> ["def ", name, "\n", ls, "\nreturn ", body, "\nend\n"] .join('')
+ Rule :name locals:ls trans:body -> "def #{name}\n#{ls}\n#{body}\nend\n"
,
Grammar :name :sName
trans*:rules -> ["Class.new(", sName, ") do\n@name = ", name.inspect, "\n", rules.join("\n"), 'end'] .join('')
,
locals = [anything+:vs] -> vs.map { |v| "#{v} = " }.join + 'nil'
| [] -> ''
,
- transFn = trans:x -> ['(proc{return ', x, '})'] .join('')
+ transFn = trans:x -> "proc { #{x} }"
}

0 comments on commit 0b1123a

Please sign in to comment.
Something went wrong with that request. Please try again.