Skip to content

robertfeldt/meta_compile

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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. A more readable and commented version of the specification file is available here. It also has better error handling both when used from the command line and when compiling (but it is longer, 73 loc for the spec and 328 loc for the generated compiler).

There is also a more useful meta compiler, based on the readable one, which accepts regexps and comments in the syntax file. Here is an example syntax file for a compiler that uses both regexps and comments.

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 meta_compile

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/meta_compile syntaxes/meta_to_ruby_minimal.meta > 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/meta_to_ruby_minimal.meta > 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/meta_to_ruby_minimal.meta > t3.rb

and this should convince us:

    diff t2.rb t3.rb

Limitations

  • Rudimentary error handling/reports while compiling/parsing

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 boot_regexp

Then we create a compiler for the assignments syntax:

    ruby bin/metac_regexp syntaxes/assignments.meta > 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. :)

FAQ

Q1. Why did you skip implementing numbers in the minimal compiler?

Since it is so easy to implement with the regexp-capable compiler later. See the example compiler for assignments above, for example.

About

A meta compilation framework à la Meta-II by Val Schorre

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published