Skip to content

Commit

Permalink
Cleanup directory structure a bit, and fix bootstrapping bug (minor e…
Browse files Browse the repository at this point in the history
…Char issue).
  • Loading branch information
Charles Lowe committed Sep 17, 2008
1 parent 03ed737 commit 758634c
Show file tree
Hide file tree
Showing 15 changed files with 277 additions and 132 deletions.
6 changes: 2 additions & 4 deletions 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.
85 changes: 85 additions & 0 deletions Rakefile
@@ -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

2 changes: 2 additions & 0 deletions lib/ometa.rb
@@ -0,0 +1,2 @@
require 'ometa/runtime'
require 'ometa/bootstrap'
167 changes: 135 additions & 32 deletions bootstrap.rb → lib/ometa/bootstrap.rb
@@ -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")}))
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 758634c

Please sign in to comment.