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

Reply via email to