Permalink
Browse files

Cleanup directory structure a bit, and fix bootstrapping bug (minor e…

…Char issue).
  • Loading branch information...
1 parent 03ed737 commit 758634c94e4dda2ba3ae79874753b617f83a815c Charles Lowe committed Sep 17, 2008
View
6 README
@@ -1,12 +1,10 @@
= About
-Briefly what OMeta is
+Briefly what OMeta is, some links to the ometajs stuff.
= TODO
-* finish bootstrapping.
-* add in optimization pass by default, with some flags.
* perhaps cache compiled rb files as "#{ometa_filename}.rb.cache" or
similar, and use them based on mtime / flag combination.
* try to optimize some more. profile wasn't particularly illuminating.
-
+* then write some actual tests.
View
@@ -0,0 +1,85 @@
+$:.unshift File.dirname(__FILE__) + '/lib'
+require 'ometa'
+
+module Bootstrap
+ class BootstrapError < StandardError
+ end
+
+ BOOTSTRAP_GRAMMARS = %w[
+ null_opt.ometa
+ andor_opt.ometa
+ ometa_opt.ometa
+ bsruby_parser.ometa
+ bsruby_translator.ometa
+ ometa_parser.ometa
+ ometa_translator.ometa
+ ]
+
+ module_function
+
+ class V0 < Object
+ end
+
+ def single root=V0
+ puts "bootstrapping ometa using #{root.inspect}"
+ all = ''
+
+ BOOTSTRAP_GRAMMARS.each do |filename|
+ puts " - #{filename}"
+ grammar = File.read(File.dirname(__FILE__) + '/ometa/' + filename)
+ ast = root.const_get('OMetaParser').matchAllwith(grammar, 'grammar')
+ ast = root.const_get('OMetaOptimizer').matchwith(ast, 'optimizeGrammar')
+ str = root.const_get('RubyOMetaTranslator').matchwith(ast, 'trans')
+ # this hack remains at the moment...
+ str.gsub! /initialize/, 'initialize_hook'
+ # test its evaluable
+ obj = eval(str)
+ # that gives us its name
+ name = obj.instance_variable_get :@name
+ all << "#{name} = " << str << "\n\n"
+ end
+
+ all
+ end
+
+ # we could also check for AST equivalence, but for now source equivalence will do.
+ # note that we create the bootstrapped objects within the Bootstrap module, not as
+ # anonymous objects as they refer to each other by name. anonymous module didn't
+ # seem to work, but maybe i was doing something wrong...
+ def bootstrap
+ v1 = single
+ eval "module V1; #{v1}; end"
+ v2 = single V1
+ eval "module V2; #{v2}; end"
+ v3 = single V2
+ eval "module V3; #{v3}; end"
+ raise BootstrapError, 'second and third builds not equivalent' unless v2 == v3
+ v3
+ end
+end
+
+desc 'rebuild bootstrap.rb from the core ometa grammar files'
+task :bootstrap do
+ # this is kind of like make bootstrap in gcc. the idea is to go through
+ # the whole "compilation" of ometa -> rb 3 times, and ensure that the
+ # 2nd and 3rd produce the same results. then we replace with our new
+ # bootstrap code.
+ begin
+ str = Bootstrap.bootstrap
+ rescue Bootstrap::BootstrapError
+ puts "unable to bootstrap - #{$!}"
+ exit 1
+ end
+ puts 'bootstrap successful!'
+ open File.dirname(__FILE__) + '/lib/ometa/bootstrap.rb', 'w' do |f|
+ f.puts <<-end
+#
+# this file was automatically generated by `rake bootstrap' at #{Time.now}.
+# do not modify
+#
+
+ end
+ f.puts str
+ end
+end
+
View
@@ -0,0 +1,2 @@
+require 'ometa/runtime'
+require 'ometa/bootstrap'
@@ -1,43 +1,145 @@
-require 'runtime'
+#
+# this file was automatically generated by `rake bootstrap' at Wed Sep 17 23:04:22 +1000 2008.
+# do not modify
+#
-class String
- def toProgramString
- inspect
- end
+NullOptimizer = Class.new(OMeta) do
+@name = "NullOptimizer"
+def setHelped
+
+return @_didSomething = true
+end
+
+def helped
+
+return _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")}))
+end
+
+def optimize
+x = nil
+return (proc{x=_apply("trans");_apply("helped");return x}).call
+end
+
+def Or
+xs = nil
+return (proc{xs=_many(proc{return _apply("trans")});return ['Or'].concat(xs)}).call
+end
+
+def And
+xs = nil
+return (proc{xs=_many(proc{return _apply("trans")});return ['And'].concat(xs)}).call
+end
+
+def Many
+x = nil
+return (proc{x=_apply("trans");return ['Many', x]}).call
+end
+
+def Many1
+x = nil
+return (proc{x=_apply("trans");return ['Many1', x]}).call
+end
+
+def Set
+n = v = nil
+return (proc{n=_apply("anything");v=_apply("trans");return ['Set', n, v]}).call
+end
+
+def Not
+x = nil
+return (proc{x=_apply("trans");return ['Not', x]}).call
+end
+
+def Lookahead
+x = nil
+return (proc{x=_apply("trans");return ['Lookahead', x]}).call
+end
+
+def Form
+x = nil
+return (proc{x=_apply("trans");return ['Form', x]}).call
end
-class BSRubyParser < OMeta
- def eChar
- c = nil
- return _or((proc{return (proc{_applyWithArgs("exactly","\\");c=_apply("char");return eval("\"\\" + c + "\"")}).call}),(proc{return _apply("char")}))
- end
+def Rule
+name = ls = body = nil
+return (proc{name=_apply("anything");ls=_apply("anything");body=_apply("trans");return ['Rule', name, ls, body]}).call
+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
- end
+def initialize_hook
- def expr
- spaces
- tsString
- end
+return @_didSomething = false
+end
+end
- def semAction
- spaces
- _many(proc {
- _not proc { _applyWithArgs 'seq', "\n" }
- anything
- }).join
- 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}))
+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}))
end
-class BSRubyTranslator < OMeta
- def trans
- anything
- 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
+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
+end
+
+def optimizeRule
+r = r = nil
+return (proc{r=_apply("anything");_many(proc{return r=_applyWithArgs("foreign",AndOrOptimizer,"optimize",r)});return r}).call
+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")}))
+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
+end
+
+def expr
+
+return (proc{_apply("spaces");return _apply("tsString")}).call
+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
+end
+end
+
+BSRubyTranslator = Class.new(OMeta) do
+@name = "BSRubyTranslator"
+def trans
+
+return _apply("anything")
+end
end
-class OMetaParser < OMeta
+OMetaParser = Class.new(OMeta) do
+@name = "OMetaParser"
def nameFirst
return _or((proc{return _applyWithArgs("exactly","_")}),(proc{return _applyWithArgs("exactly","$")}),(proc{return _apply("letter")}))
@@ -60,7 +162,7 @@ def name
def eChar
c = nil
-return _or((proc{return (proc{_applyWithArgs("exactly","\\");c=_apply("char");return eval("\"\\" + c + "\"")}).call}),(proc{return _apply("char")}))
+return _or((proc{return (proc{_applyWithArgs("exactly","\\");c=_apply("char");return { 'n' => "\n", 't' => "\t", 'r' => "\r", '\'' => "'", '\"' => '"', '\\' => '\\' }[c]}).call}),(proc{return _apply("char")}))
end
def tsString
@@ -174,7 +276,8 @@ def grammar
end
end
-class RubyOMetaTranslator < OMeta
+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
Oops, something went wrong.

0 comments on commit 758634c

Please sign in to comment.