CodeTree - Code generation

synopsis

Code generation allows to generate ruby code from a CodeTree. Similarly to evaluation, there’s two ways to generate code: the object way and the functional way.

object generation

In object generation (object_compile and object_proc methods), the expression

(function arg0, arg1, ..., argn)

recursively generates code like:

arg0.function(arg1, ..., argn)

The special ‘?’ operator leads to the evaluation of a variable name (Symbol) on a scope object (default name to ‘scope’) using a given scope method (default to :[]):

CodeTree::parse{ x }.object_compile
# => "scope[:x]"

Therefore,

expr = CodeTree::parse{ (x + y).to_s }   
# => (to_s (+ x, y))

expr.object_compile
# => "scope[:x].+(scope[:y]).to_s()"

expr.object_compile("hash", :fetch)             
# => "hash.fetch(:x).+(hash.fetch(:y)).to_s()"

The object_proc method generates a Proc instance with the equivalent code. The scope method can also be specified:

expr = CodeTree::parse{ (x + y).to_s }   
# => (to_s (+ x, y))

expr.object_proc(:fetch)
# => <Proc...>

proc.call(:x => 3, :y => 25)
# => "28"

functional generation

In functional generation (functional_compile and functional_proc methods), the expression

(function arg0, arg1, ..., argn)

recursively generates code as

receiver.function(arg0, arg1, ..., argn)

The receiver object name can be specified as first argument. The special ‘?’ operator leads to the evaluation of a variable name (Symbol) on a scope object (default name to ‘scope’) using a given scope method (default to :[]):

CodeTree::parse{ x }.functional_compile
# => "scope[:x]"

Therefore,

expr = CodeTree::parse{ (display (concat x, y)) }    
# => (display (concat x, y))

expr.functional_compile('rcv', 'hash', :fetch)              
# => "rcv.display(rcv.concat(hash.fetch(:x), hash.fetch(:y)))"

The functional_proc method generates a Proc instance with the equivalent code. The scope method can also be specified:

expr = CodeTree::parse{ (display (concat x, y)) }   
# => (to_s (+ x, y))

expr.functional_proc(:fetch)
# => <Proc...>

proc.call(some_receiver_object, :x => 3, :y => 25)
# => "28"