Permalink
Browse files

Finish implementation of "loop"

  • Loading branch information...
1 parent ac5d754 commit 7b248acedd982f6792f1cb215e369dd9ecedc181 @sorear committed Feb 19, 2011
Showing with 39 additions and 17 deletions.
  1. +38 −17 src/niecza
  2. +1 −0 t/run_spectests
View
@@ -241,24 +241,11 @@ method statement_control:unless ($/) {
method statement_control:loop ($/) {
my $body = self.block_to_immediate($/, 'loop', $<block>.ast);
# XXX wrong interpretation
- my $init = $0 && $0[0]<e1>[0];
- my $cond = $0 && $0[0]<e2>[0];
- my $step = $0 && $0[0]<e3>[0];
+ my $init = $0 && $0[0]<e1>[0] ?? $0[0]<e1>[0].ast !! Any;
+ my $cond = $0 && $0[0]<e2>[0] ?? $0[0]<e2>[0].ast !! Any;
+ my $step = $0 && $0[0]<e3>[0] ?? $0[0]<e3>[0].ast !! Any;
- if $step {
- $body = ::Op::StatementList.new(|node($/),
- children => [ $body, $step.ast ]);
- }
-
- $body = ::Op::WhileLoop.new(|node($/), :!once, :!until,
- check => ($cond ?? $cond.ast !! mklex($/, 'True')), body => $body);
-
- if $init {
- $body = ::Op::StatementList.new(|node($/),
- children => [ $init.ast, $body ]);
- }
-
- make $body;
+ make ::Op::GeneralLoop.new(|node($/), :$body, :$init, :$cond, :$step);
}
}
@@ -295,6 +282,40 @@ class Control is Op {
$.payload.cgop($body));
}
}
+
+class GeneralLoop is Op {
+ has $.init; # Op
+ has $.cond; # Op
+ has $.step; # Op
+ has $.body; # Op
+
+ method zyg() { grep &defined, $.init, $.cond, $.step, $.body }
+ method ctxzyg($) {
+ ($.init ?? ($.init, 0) !! ()),
+ ($.cond ?? ($.cond, 1) !! ()),
+ ($.step ?? ($.step, 0) !! ()),
+ $.body, 0
+ }
+
+ method code($body) { self.code_labelled($body,'') }
+ method code_labelled($body, $l) {
+ my $id = ::GLOBAL::NieczaActions.genid;
+
+ CgOp.prog(
+ ($.init ?? CgOp.sink($.init.cgop($body)) !! ()),
+ CgOp.whileloop(0, 0,
+ ($.cond ?? CgOp.obj_getbool($.cond.cgop($body)) !!
+ CgOp.bool(1)),
+ CgOp.prog(
+ CgOp.sink(CgOp.xspan("redo$id", "next$id", 0,
+ $.body.cgop($body), 1, $l, "next$id",
+ 2, $l, "last$id", 3, $l, "redo$id")),
+ ($.step ?? CgOp.sink($.step.cgop($body)) !! ()))),
+ CgOp.label("last$id"),
+ CgOp.corelex('Nil'));
+ }
+}
+
}
augment class Op::WhileLoop { #OK exist
View
@@ -28,6 +28,7 @@ prove -e 't/fudgeandrun' \
../roast/S04-statements/gather.t \
../roast/S04-statements/if.t \
../roast/S04-statements/last.t \
+ ../roast/S04-statements/loop.t \
../roast/S04-statements/map-and-sort-in-for.t \
../roast/S04-statements/next.t \
../roast/S04-statements/no-implicit-block.t \

0 comments on commit 7b248ac

Please sign in to comment.