| 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.)
|
|
|