Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implement let, temp, TEMP

  • Loading branch information...
commit 28de0b83e556e8928be2f2ab8c7b900651b85087 1 parent f755930
@sorear authored
View
26 lib/Builtins.cs
@@ -2017,4 +2017,30 @@ class CrossSource: ItemSource {
public static Variable pstash_bind_key(P6any st, string key, Variable to) {
return Kernel.UnboxAny<StashCursor>(st).Raw(key, to);
}
+
+ static SubInfo TEMP_SI = new SubInfo("KERNEL Scalar.TEMP", TEMP_C);
+ static Frame TEMP_C(Frame th) {
+ ((Variable)th.outer.lex0).Store((P6any)th.outer.lex1);
+ return th.Return();
+ }
+
+ public static Variable temporize(Variable v, Frame fr, int mode) {
+ int type = (mode & 1) != 0 ? LeaveHook.UNDO : LeaveHook.UNDO + LeaveHook.KEEP;
+ if ((mode & 2) != 0) {
+ fr.PushLeave(type, v.Fetch());
+ }
+ else if (v.islist) {
+ fr.PushLeave(type, Kernel.RunInferior(v.Fetch().InvokeMethod(
+ Kernel.GetInferiorRoot(), "TEMP",
+ new Variable[] { v }, null)).Fetch());
+ }
+ else {
+ Frame o = new Frame();
+ o.lex0 = v;
+ o.lex1 = v.Fetch();
+ fr.PushLeave(type, Kernel.MakeSub(TEMP_SI, o));
+ }
+
+ return v;
+ }
}
View
1  lib/Kernel.cs
@@ -1319,6 +1319,7 @@ public class Frame: P6any {
reusable_child.ip = 0;
reusable_child.resultSlot = null;
reusable_child.lexn = (info.nspill != 0) ? new object[info.nspill] : null;
+ reusable_child.on_leave = null;
reusable_child.lex = null;
reusable_child.lex0 = null;
reusable_child.lex1 = null;
View
40 src/niecza
@@ -139,6 +139,14 @@ packagey:
}
}
+class Op::Temporize is Op {
+ has Op $.var;
+ has Int $.mode;
+ method zyg() { $!var }
+ method code($body) { CgOp.temporize($!var.code($body), CgOp.callframe,
+ CgOp.int($!mode)) }
+}
+
class Op::IndirectVar is Op {
has Op $.name;
has Bool $.bind_ro;
@@ -159,7 +167,37 @@ augment class Metamodel {
enum Phaser < INIT END UNIT_INIT KEEP UNDO LEAVE ENTER PRE POST CATCH CONTROL >;
}
+class Operator::Let is Operator {
+ method with_args($/, *@args) {
+ $*CURLEX<!sub>.noninlinable;
+ return ::Op::Temporize.new(|node($/), mode => 1, var => @args[0]);
+ }
+}
+
+augment class Operator::Temp {
+ method with_args($/, *@args) {
+ my $rarg = @args[0];
+ if !$rarg.^isa(::Op::ContextVar) || $rarg.uplevel {
+ $*CURLEX<!sub>.noninlinable;
+ return ::Op::Temporize.new(|node($/), mode => 0, var => $rarg);
+ }
+ my $hash = substr($rarg.name,0,1) eq '%';
+ my $list = substr($rarg.name,0,1) eq '@';
+ $*CURLEX<!sub>.add_my_name($rarg.name, :$hash, :$list);
+ mkcall($/, '&infix:<=>',
+ ::Op::Lexical.new(name => $rarg.name, :$hash, :$list),
+ ::Op::ContextVar.new(name => $rarg.name, uplevel => 1));
+ }
+}
+
augment class NieczaActions {
+method statement_control:TEMP ($/) {
+ $*CURLEX<!sub>.noninlinable;
+ make ::Op::Temporize.new(|node($/), mode => 2,
+ var => self.inliney_call($/, $<block>.ast));
+}
+method prefix:let ($/) { make ::Operator::Let.new }
+
sub phaser($/, $ph, :$unique, :$topic, :$csp) {
my $sub = $<blast>.ast;
$sub.outer.noninlinable;
@@ -589,7 +627,7 @@ method variable($/) {
}
-CgOp._register_ops: < who sc_root sc_indir
+CgOp._register_ops: < who sc_root sc_indir temporize
>;
my $usage = q:to/EOM/;
View
2  t/spectest.data
@@ -59,6 +59,8 @@ S03-operators/subscript-vs-lt.t
S03-smartmatch/any-any.t
S03-smartmatch/any-bool.t
S03-smartmatch/any-str.t
+S04-blocks-and-statements/let.t
+S04-blocks-and-statements/temp.t
S04-declarations/multiple.t
S04-declarations/my.t
S04-declarations/state.t
Please sign in to comment.
Something went wrong with that request. Please try again.