Author: pmichaud
Date: Mon Aug 18 05:17:43 2008
New Revision: 30298
Modified:
trunk/compilers/pct/src/PAST/Compiler.pir
trunk/compilers/pct/src/PAST/Node.pir
Log:
[pct]: Add 'loadinit' attribute and code generation to PAST::Block nodes
Modified: trunk/compilers/pct/src/PAST/Compiler.pir
==============================================================================
--- trunk/compilers/pct/src/PAST/Compiler.pir (original)
+++ trunk/compilers/pct/src/PAST/Compiler.pir Mon Aug 18 05:17:43 2008
@@ -38,6 +38,7 @@
.include "cclass.pasm"
.include "except_types.pasm"
+.include "interpinfo.pasm"
.namespace [ 'PAST::Compiler' ]
@@ -636,6 +637,20 @@
bpost.'push'($P0)
sub_done:
+ ## generate any loadinit code for the sub
+ $I0 = exists node['loadinit']
+ unless $I0 goto loadinit_done
+ .local pmc lipast, lipost
+ lipast = node.'loadinit'()
+ lipost = self.'as_post'(lipast, 'rtype'=>'v')
+ $P0 = get_hll_global ['POST'], 'Sub'
+ lipost = $P0.'new'('outer'=>bpost, 'pirflags'=>':load :init')
+ lipost.'push_pirop'('.local pmc', 'block')
+ lipost.'push_pirop'('interpinfo', '$P20', .INTERPINFO_CURRENT_SUB)
+ lipost.'push_pirop'('callmethod', 'get_outer', '$P20', 'result'=>'block')
+ bpost.'push'(lipost)
+ loadinit_done:
+
## restore previous outer scope and symtable
set_global '$?SUB', outerpost
setattribute self, '%!symtable', outersym
Modified: trunk/compilers/pct/src/PAST/Node.pir
==============================================================================
--- trunk/compilers/pct/src/PAST/Node.pir (original)
+++ trunk/compilers/pct/src/PAST/Node.pir Mon Aug 18 05:17:43 2008
@@ -439,7 +439,7 @@
=item blocktype([STRING type])
Get/set the type of the block. The currently understood values
-are 'declaration' and 'immediate'. 'Declaration' indicates
+are 'declaration', 'immediate', and 'method'. 'Declaration' indicates
that a block is simply being defined at this point, while
'immediate' indicates a block that is to be immediately
executed when it is evaluated in the AST (e.g., the immediate
@@ -460,7 +460,7 @@
Get/set the control exception handler for this block to C<value>.
The exception handler can be any PAST tree. The special (string)
-value "return" generates code to handle C<CONTROL_RETURN> exceptions.
+value "return_pir" generates code to handle C<CONTROL_RETURN> exceptions.
=cut
@@ -471,6 +471,35 @@
.end
+=item loadinit([past])
+
+Get/set the "load initializer" for this block to C<past>.
+The load initializer is a set of operations to be performed
+as soon as the block is compiled/loaded. For convenience,
+requests to C<loadinit> autovivify an empty C<PAST::Stmts>
+node if one does not already exist.
+
+Within the load initializer, the C<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.).
+
+=cut
+
+.sub 'loadinit' :method
+ .param pmc value :optional
+ .param int has_value :opt_flag
+ if has_value goto getset_value
+ $I0 = exists self['loadinit']
+ if $I0 goto getset_value
+ $P0 = get_hll_global ['PAST'], 'Stmts'
+ value = $P0.'new'()
+ has_value = 1
+ getset_value:
+ .return self.'attr'('loadinit', value, has_value)
+.end
+
+
=item namespace([namespace])
Get/set the namespace for this block. The C<namespace> argument