develooper Front page | perl.cvs.parrot | Postings from December 2008

[svn:parrot] r34230 - branches/pctloop/compilers/pct/src/PAST

From:
tene
Date:
December 21, 2008 21:38
Subject:
[svn:parrot] r34230 - branches/pctloop/compilers/pct/src/PAST
Message ID:
20081222053824.0FA80CBA12@x12.develooper.com
Author: tene
Date: Sun Dec 21 21:38:22 2008
New Revision: 34230

Modified:
   branches/pctloop/compilers/pct/src/PAST/Compiler.pir

Log:
[pct]: First draft of loop refactor.

Modified: branches/pctloop/compilers/pct/src/PAST/Compiler.pir
==============================================================================
--- branches/pctloop/compilers/pct/src/PAST/Compiler.pir	(original)
+++ branches/pctloop/compilers/pct/src/PAST/Compiler.pir	Sun Dec 21 21:38:22 2008
@@ -38,6 +38,7 @@
 
 .include "cclass.pasm"
 .include "except_types.pasm"
+.include "except_severity.pasm"
 .include "interpinfo.pasm"
 
 .namespace [ 'PAST';'Compiler' ]
@@ -1386,44 +1387,42 @@
     .param pmc node
     .param pmc options         :slurpy :named
 
-    .local pmc ops
-    $P0 = get_hll_global ['POST'], 'Ops'
-    ops = $P0.'new'('node'=>node)
+    .local pmc post_ops
+    .local pmc pre, start, body
+    post_ops = get_hll_global ['POST'], 'Ops'
 
-    .local pmc looplabel, nextlabel, endlabel, undeflabel
-    $P0 = get_hll_global ['POST'], 'Label'
+    .local pmc post_label, coll_label, iter_label
+    post_label = get_hll_global ['POST'], 'Label'
     $S0 = self.'unique'('for_')
-    looplabel = $P0.'new'('result'=>$S0)
-    $S1 = concat $S0, '_next'
-    nextlabel = $P0.'new'('result'=>$S1)
-    $S2 = concat $S0, '_end'
-    endlabel = $P0.'new'('result'=>$S2)
-    $S3 = concat $S0, '_undef_iter'
-    undeflabel = $P0.'new'('result'=>$S3)
+    $S1 = concat $S0, '_collection_present'
+    coll_label = post_label.'new'('result'=>$S1)
+    $S1 = concat $S0, '_iter_true'
+    iter_label = post_label.'new'('result'=>$S1)
 
     .local pmc collpast, collpost
     collpast = node[0]
     collpost = self.'as_post'(collpast, 'rtype'=>'P')
-    ops.'push'(collpost)
+    pre = post_ops.'new'('node'=>collpast)
+    pre.'push'(collpost)
 
-    .local string iter, next_handler
+    .local string iter
     iter = self.'uniquereg'('P')
-    ops.'result'(iter)
+    pre.'result'(iter)
     $S0 = self.'uniquereg'('I')
-    ops.'push_pirop'('defined', $S0, collpost)
-    ops.'push_pirop'('unless', $S0, undeflabel)
-    next_handler = self.'uniquereg'('P')
-    ops.'push_pirop'('new', next_handler, "'ExceptionHandler'")
-    ops.'push_pirop'('set_addr', next_handler, nextlabel)
-    ops.'push_pirop'('callmethod', '"handle_types"', next_handler, .CONTROL_LOOP_NEXT)
-    ops.'push_pirop'('push_eh', next_handler)
-    ops.'push_pirop'('iter', iter, collpost)
-    ops.'push'(looplabel)
-    ops.'push_pirop'('unless', iter, endlabel)
+    pre.'push_pirop'('defined', $S0, collpost)
+    pre.'push_pirop'('if', $S0, coll_label)
+    self.'push_throw_typed'(pre, .CONTROL_LOOP_LAST)
+    pre.'push'(coll_label)
+    pre.'push_pirop'('iter', iter, collpost)
 
     .local pmc subpast
     subpast = node[1]
 
+    start = post_ops.'new'('node'=>subpast)
+    start.'push_pirop'('if', iter, iter_label)
+    self.'push_throw_typed'(start, .CONTROL_LOOP_LAST)
+    start.'push'(iter_label)
+
     ##  determine the number of elements to take at each iteration
     .local int arity
     arity = 1
@@ -1444,29 +1443,96 @@
   arity_loop:
     .local string nextval
     nextval = self.'uniquereg'('P')
-    ops.'push_pirop'('shift', nextval, iter)
+    start.'push_pirop'('shift', nextval, iter)
     if arity < 1 goto arity_end
     push arglist, nextval
     dec arity
     if arity > 0 goto arity_loop
   arity_end:
 
+    body = post_ops.'new'('node'=>subpast)
     .local pmc subpost
     subpast.'blocktype'('immediate')                       # FIXME
     subpost = self.'as_post'(subpast, 'rtype'=>'P', 'arglist'=>arglist)
-    ops.'push'(subpost)
-    ops.'push_pirop'('goto', looplabel)
+    body.'push'(subpost)
+    self.'push_throw_typed'(body, .CONTROL_LOOP_NEXT)
+
+    .local pmc ops
+    ops = self.'loop_helper'('pre'=>pre, 'start'=>start, 'body'=>body)
+    ops.'node'(node)
+    .return (ops)
+.end
+
+.sub 'loop_helper' :method
+    .param pmc pre :named('pre')
+    .param pmc start :named('start')
+    .param pmc body :named('body')
+
+    .local pmc post_ops, post_label
+    post_ops = get_hll_global ['POST'], 'Ops'
+    post_label = get_hll_global ['POST'], 'Label'
+
+    .local pmc ops
+    ops = post_ops.'new'()
+
+    .local pmc looplabel, startlabel, nextlabel, lastlabel, endlabel
+    $S0 = self.'unique'('loop_')
+    looplabel = post_label.'new'('result'=>$S0)
+    $S1 = concat $S0, '_start'
+    startlabel = post_label.'new'('result'=>$S1)
+    $S1 = concat $S0, '_next'
+    nextlabel = post_label.'new'('result'=>$S1)
+    $S1 = concat $S0, '_last'
+    lastlabel = post_label.'new'('result'=>$S1)
+    $S1 = concat $S0, '_end'
+    endlabel = post_label.'new'('result'=>$S1)
+
+    .local string next_handler, last_handler
+    next_handler = self.'uniquereg'('P')
+    ops.'push_pirop'('new', next_handler, "'ExceptionHandler'")
+    ops.'push_pirop'('set_addr', next_handler, nextlabel)
+    ops.'push_pirop'('callmethod', '"handle_types"', next_handler, .CONTROL_LOOP_NEXT)
+    ops.'push_pirop'('push_eh', next_handler)
+
+    last_handler = self.'uniquereg'('P')
+    ops.'push_pirop'('new', last_handler, "'ExceptionHandler'")
+    ops.'push_pirop'('set_addr', last_handler, lastlabel)
+    ops.'push_pirop'('callmethod', '"handle_types"', last_handler, .CONTROL_LOOP_LAST)
+    ops.'push_pirop'('push_eh', last_handler)
+
+    ops.'push'(pre)
+    ops.'push'(looplabel)
+    ops.'push'(start)
+    ops.'push'(startlabel)
+    ops.'push'(body)
+    self.'push_throw_typed'(ops, .CONTROL_LOOP_NEXT)
+
     ops.'push'(nextlabel)
     ops.'push_pirop'('.local pmc exception')
     ops.'push_pirop'('.get_results (exception)')
-    ops.'push_pirop'('set', next_handler, 0)
     ops.'push_pirop'('goto', looplabel)
+    ops.'push'(lastlabel)
+    ops.'push_pirop'('.local pmc exception')
+    ops.'push_pirop'('.get_results (exception)')
+    ops.'push_pirop'('goto', endlabel)
     ops.'push'(endlabel)
     ops.'push_pirop'('pop_eh')
-    ops.'push'(undeflabel)
+
     .return (ops)
 .end
 
+.sub 'push_throw_typed' :method
+    .param pmc ops
+    .param pmc type
+    .local string ex
+    ex = self.'uniquereg'('P')
+    ops.'push_pirop'('new', ex, "'Exception'")
+    $S0 = concat ex, '["type"]'
+    ops.'push_pirop'('set', $S0, type)
+    $S0 = concat ex, '["severity"]'
+    ops.'push_pirop'('set', $S0, .EXCEPT_NORMAL)
+    ops.'push_pirop'('throw', ex)
+.end
 
 =item list(PAST::Op node)
 



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About