meta_compile
A meta compilation framework for Ruby à la Meta-II by Val Schorre.
This uses a C version of Meta-II developed by Long Nguyen to bootstrap a Ruby version from a fully self-contained, 26 (non-empty) line specification file. The generated Ruby Meta-II compiler file is 231 lines of Ruby code.
Install
Clone the git repo and then run:
rake bootstrap
and it will bootstrap and print info about each step. This requires gcc, rake and a recent ruby.
If you only want the finished result you can just install as a gem:
gem install
since it is available on rubygems.org.
Manually verifying that it is a meta compiler
In your local copy of the git repo, use the pre-generated binary to compile the specification file to a ruby file:
bin/ syntaxes/. > t.rb
This generates a t.rb which is itself a compiler for meta syntax specs. So lets use it to generate itself:
ruby t.rb syntaxes/. > t2.rb
And ensure they are really the same:
diff t.rb t2.rb
To be really sure we can try the generated t2.rb as a meta-compiler:
ruby t2.rb syntaxes/. > t3.rb
and this should convince us:
diff t2.rb t3.rb
Limitations
- Very bad/little error handling
Ok, now what?
Once the first meta compiler is up and running we can evolve the language. For example I made a change so Ruby regexps can be used instead of only string literals. Note that we need to use a stepping stone syntax file before we can create a new meta compiler that accepts the new syntax.
Let's use this to compile programs which can only contain assignments of numbers to variables:
.syntax assignments
assignments = as *as;
as = /\w+/ <'address ' $> ':=' ex1 <'store'> ';';
ex1 = /\d+/ <'literal ' $>;
.end
The new thing here compared to the original Meta-II syntax is the two Regexp's (in as and ex1). First we need to bootstrap the meta compiler that accepts regexps:
rake bootstrap_re
Then we create a compiler for the assignments syntax:
ruby bin/ syntaxes/assignments. > tas.rb
We now have a compiler for assignments and if we apply it to the file:
a := 137;
b := 4;
by running the command:
ruby tas.rb inputs/assignments.input1
it prints:
address a
literal 137
store
address d
literal 4
store
Not bad. :)