parrotcode: Parrot abstract syntax tree | |
Contents | Compilers |
PAST - Parrot abstract syntax tree
This file implements the various abstract syntax tree nodes for compiling programs in Parrot.
PAST::Node
is the base class for all PAST nodes,
and is derived from PCT::Node.
A node has an array component to hold its children,
and a hash component for its attributes.
However,
we tend to use accessor methods for accessing the node's attributes instead of accessing the hash directly.
Every PAST node inherits name
,
source
,
and pos
attributes from PCT::Node
.
The name
attribute is the node's name,
if any,
while source
and pos
are used to identify the location in the original source code for the node.
The source
and pos
values are generally set by the node
method inherited from PCT::Node
.
Other node attributes are generally defined by subclasses of PAST::Node
.
lvalue
attribute,
which indicates whether this variable is being used in an lvalue context.PAST::Val
nodes represent constant values in the abstract syntax tree.
The name
attribute represents the value of the node.
PAST::Var
nodes represent variables within the abstract syntax tree.
The variable name (if any) is given as the node's name
attribute.
isdecl
attribute (for lexical variables) to flag
.
A true value of isdecl
indicates that the variable given by this node is to be created within the current lexical scope.
Otherwise,
the node refers to a lexical variable from an outer scope.
namespace
.
Useful only for variables with a scope
of 'package'.
slurpy
attribute (for parameter variables) to flag
.
A true value of slurpy
indicates that the parameter variable given by this node is to be created as a slurpy parameter (consuming all remaining arguments passed in).
type
indicates either the type of the value to create for the node or (future implementation) a PAST tree to create the value.
type
indicates the type of aggregate to create for the base if the base doesn't specify its own 'viviself' attribute.PAST::Op
nodes represent the operations in an abstract syntax tree.
The primary function of the node is given by its pasttype
,
secondary functions may be given by the node's name
,
pirop
,
or other attributes.
PAST::Op
node's pasttype
determines the type of operation to be performed.
Predefined values of pasttype
are:assign - Copy the value of the node's second child into the variable expression given by its first child.bind - Bind the variable given by the node's first child to the value given by its second child.if - Evaluate the first child; if the first child is true then evaluate the second child (if any) otherwise evaluate the third child (if any).
If either the second or third child are missing,
then they evaluate as the result of the first child.unless - Same as 'if' above,
but reverse the evaluation of the second and third children nodes.while - Evaluate the first child,
if the result is true then evaluate the second child and repeat.until - Evaluate the first child,
if the result is false then evaluate the second child and repeat.for - Iterate over the first child.
For each element,
invoke the sub in the second child,
passing the element as the only parameter.call - Call a subroutine,
passing the results of any child nodes as arguments.
The subroutine to be called is given by the node's name
attribute,
if the node has no name
attribute then the first child is assumed to evaluate to a callable sub.pirop - Execute the named PIR opcode,
passing the results of any children nodes as arguments.inline - Execute the sequence of PIR statements given by the node's inline
attribute (a string).
See the inline
method below for details.callmethod - Invokes a method on an object,
using children nodes as arguments.
If the node has a name
attribute,
then the first child is the invocant and any remaining children are arguments.
If the node doesn't have a name
attribute,
then the first child evaluates to the method to be called,
the second child is the invocant,
and the remaining children are arguments to the method call.try - (preliminary) Execute the code given by the first child,
and if any exceptions occur then handle them using the code given by the second child.If a node doesn't have a value set for pasttype
,
then it assumes "pirop" if its pirop
attribute is set,
otherwise it assumes "call".
pasttype
is "inline".
The code
argument is PIR text to be inserted in the final generated code sequence.
Sequences of "%0",
"%1",
"%2",
...
"%9" in code
are replaced with the evaluated results of the first,
second,
third,
...,
tenth children nodes.
(If you need more than ten arguments to your inline PIR,
consider making it a subroutine call instead.)The register to hold the result of the inline PIR operation is given by "%r",
"%t",
or "%u" in the code
string:
%r - Generate a unique PMC register for the result. %t - Generate a unique PMC register for the result, and initialize it with an object of type C<returns> before the execution of the inline PIR. %u - Re-use the first child's PMC (%0) if it's a temporary result, otherwise same as %t above. %v - (void) Re-use the first child's PMC (%0) as the result of this operation.
PAST::Op
attributes based on entries in hash
. Typically hash
is an entry in the operator precedence table, and the attributes being set correspond to traits in the grammar.PAST::Stmts
is a container of PAST::Node
without any specific methods.
PAST::Block
nodes represent lexical scopes within an abstract syntax tree, and roughly translate to individual Parrot subroutines. A PAST::Block
node nested within another PAST::Block
node acts like a nested lexical scope.
If the block has a name
attribute, that becomes the name of the resulting Parrot sub, otherwise a unique name is automatically generated for the block.
if
, while
, and other similar statements).
value
. The exception handler can be any PAST tree. The special (string) value "return_pir" generates code to handle CONTROL_RETURN
exceptions.
past
. The load initializer is a set of operations to be performed as soon as the block is compiled/loaded. For convenience, requests to loadinit
autovivify an empty PAST::Stmts
node if one does not already exist.Within the load initializer, the block
PMC register is automatically initialized to refer to the block itself (to enable attaching properties, adding the block as a method, storing in a symbol table, etc.).
namespace
argument can be either a string or an array of strings.
hll
for this block.
name
in the current block. The HLL is free to select any symbol attributes desired, although the 'scope' attribute is typically used to assist with lexical scoping of PAST::Var nodes.If no named arguments are given, returns the current attribute hash for symbol name
.
symbol
above). If no named arguments are given, returns the default attribute hash itself.Currently we just use the '' entry of the symbol hash to store the default attributes, but it's probably not safe to rely on this behavior in the future.
symbol
method above.
name
instead of the standard PAST compiler.
subid
is provided, then sets the subid for this block. Returns the current subid for the block, generating a unique subid for the block if one does not already exist.
Patrick Michaud <pmichaud@pobox.com> is the author and maintainer. Please send patches and suggestions to the Parrot porters or Perl 6 compilers mailing lists.
2006-11-20 Patrick Michaud added first draft of POD documentation. 2007-11-21 Re-implementation with pdd26 compliance, compiler toolkit
Copyright (C) 2006-2008, The Perl Foundation.
|