parrotcode: Untitled | |
Contents | Language Implementations | Perl6 |
IMCC.pm is still a "ball of mud" at the moment, but context propagation has been moved to Context.pm. Next for refactoring is symbol handling.
Context should not be propagated during code generation, as the context propagation pass handles this. This rule is broken for hyper-operators, since I can't think of a good way to handle them using context.
Code is generated by a depth-first recursive traversal of the op tree.
Each node type should define a val
function to be called by its parent node.
This function should gather values from child nodes (by calling their val
functions),
then emit the code for the node's operation (using P6C::Compiler::code
).
Code is appended to the current function in the order in which it is generated,
so subnodes must be evaluated in the proper order.
val
should return one of the following:
Node types that can act as lvalues should define an assign
function that takes an unevaluated rvalue tree and a context structure.
This function should return a PMC register or array ref (like val
) if (like an assignment) it serves as both an lvalue and an rvalue.
If P6C::IMCC
is imported with the ":external" flag,
it will define the following interface,
used by the driver:
init
destroys all functions and globals,
resets the current function,
and reinitializes builtins.main
,
and the code for any builtin functions (see P6C::Builtins
).
emit
will fail if you have not defined main
.If P6C::IMCC
is imported with the ":all" flag,
it exports an internal interface.
The compiler maintains a "current function" (could be generalized to "current scope") in which code is emitted, locals are declared, and symbol lookups begin. The following functions manipulate the current function context.
$x
to the current function.$name
.
If $name
exists,
it will be overwritten.
In such cases,
a warning will be omitted unless the {'weak'} flag is set.$name
is defined (i.e.
not just "declared").$name
,
even if it has no code.$name
,
returning the name of the previously active function.
Function $name
should exist before this is called.This is a primitive symbol table. Which is okay, since Parrot doesn't have stashes yet. Hopefully the interface will be useful when things get more complicated.
$var
.
Warns if $var
is already defined.
$var
will be initialized to a new PMC of type $type
(or PerlUndef
if type is not given) before main
is called.$var
,
returning its IMCC name.$var
of type $type
.
Warns if $var
is already defined.
If $type
is a PMC type,
$var
will automatically be initialized.$var
.$var
,
a P6C::variable
,
returning a PMC register containing its value.
Currently findvar
looks at the active function's parameters,
then locals,
then globals (which don't exist,
so it won't find anything there).
Returns undef if the variable is not found.
$isglobal
is currently unused.Note that the "labels" here aren't necessarily simple addresses in the code; while this may sometimes be the case, creating some labels may involve taking a continuation, and jumping to labels may involve throwing an exception and unwinding the call stack.
XXX: Labels and try/CATCH currently use different mechanisms, contrary to Apocalypse 4. Exceptions are implemented with continuations, and are therefore much more expensive than labels, which use simple jumps. Eventually, either continuations will have to become much lighter-weight, or the compiler will have to determine when a jump is sufficient, and when a continuation or exception is required. This implementation means that you can't mix gotos and exceptions without Bad Things happening.
The name
argument is a label name,
and may be undefined for typed loop labels (e.g.
"next").
The type
argument should be one of the following:
Label handling functions:
name
or type
may be omitted.name
or type
may be omitted.name
or type
may be omitted.$x
until the next call to set_topic
,
or until the end of the current scope,
whichever is first.
Note that $x
is a variable,
not a value.$str
is given,
include it as part of the identifier.$str
.$type
,
which should be "int",
"num",
"str",
or some PMC type.
If $type
is a PMC type,
the register will be initialized with a new value.
If $type
is omitted,
it default to PerlUndef
.The following functions generate useful and common pieces of code.
$counter
as the repetition count.
The loop will iterate over values between 0 and $counter - 1,
inclusive.
$counter
will be used as the iteration variable,
so it can be used in indexing expressions in the loop body.$val
in the right way for context $ctx
.
In array context,
that means create a single-element array containing the scalar.@$vals
,
which are assumed to be in list context.
The results are concatenated into a single array,
whose name is returned.A node representing a rule.
mode
param.P6C::IMCC::prefix for prefix operators (function calls, return statements, if/for/while/given, etc.)
|