This topic has missing or partial documentation. Please help us improve it.
Once the parser has finished calling
process_* methods an
abstract syntax tree is created. The syntax tree represents the
abstract syntactic structure of the parsed source code. Each node in
the tree denotes a construct in the source code. This tree is composed of instances
of classes defined in lib/compiler/ast/ directory.
Each of these classes inherits from
Node class defines a few methods that are utilized
by the subclasses (eg. pos(g) which records the line number for debugging purposes).
The AST classes usually define at least 3 methods:
process_*methods in the previous stage
The easiest way to see the AST that gets created is to call
on a string containing the code, eg:
irb(main):002:0> "a = 1".to_ast => #<Rubinius::AST::LocalVariableAssignment:0xf70 @value=#<Rubinius::AST::FixnumLiteral:0xf74 @value=1 @line=1> @name=:a @variable=nil @line=1>
or compile the code and pass the -A option:
rbx compile -A -e "def hello;end" Script @name: __script__ @file: "(snippet)" @body: \ Define @name: hello @line: 1 @arguments: \ FormalArguments @defaults: nil @names: \ @block_arg: nil @optional: \ @splat: nil @line: 1 @required: \ @body: \ Block @line: 1 @array: \ NilLiteral @line: 1
Similarily it's possible to get a representation of the syntax tree as s-expressions:
irb(main):002:0> "a = 1".to_sexp => [:lasgn, :a, [:lit, 1]]
or pass the -S option to compile:
rbx compile -S -e "def hello;end" [:script, [:defn, :hello, [:args], [:scope, [:block, [:nil]]]]]
The AST is a nested structure where nodes contain other nodes. For
hello method defined above is composed of a
Define in its
@body which in turns contains
FormalArguments in its
Block in its
Block node contains only the
NilLiteral in its
NilLiteral node is a leaf node, it doesn't contain other nodes.
Note that the following
rbx compile -S -e ":foo if :bar" [:script, [:if, [:lit, :bar], [:lit, :foo], nil]]
and the same
if expression but written differently
rbx compile -S -e "if :bar then :foo; end" [:script, [:if, [:lit, :bar], [:lit, :foo], nil]]
produce exactly the same syntax tree. Because the tree doesn't represent every detail that appears in the real syntax it is called "abstract".
There are two ways to customize this stage of the compilation process. The easiest way to customize the creation of the AST is through AST Transforms.
You can also subclass the Melbourne processor and define your own
handlers for the
process_ methods. This is an advanced topic that is
not yet documented.