From 9740be13dd7008b4acbd8dcf7682ef8aedecdaa7 Mon Sep 17 00:00:00 2001 From: Stefan O'Rear Date: Wed, 8 Sep 2010 15:56:21 -0700 Subject: [PATCH] Simplify representation and construction of lists --- lib/Cursor.cs | 38 +++----- lib/Kernel.cs | 100 ++++++++++++++++++-- lib/SAFE.setting | 215 ++++++++++++++++++++++-------------------- src/CgOp.pm | 8 ++ src/CodeGen.pm | 10 +- src/Niecza/Actions.pm | 4 + src/Sig.pm | 7 +- 7 files changed, 242 insertions(+), 140 deletions(-) diff --git a/lib/Cursor.cs b/lib/Cursor.cs index dfca84f4..1a08f7ad 100644 --- a/lib/Cursor.cs +++ b/lib/Cursor.cs @@ -57,13 +57,9 @@ public struct State { if (return_one) { return Kernel.Take(th, Kernel.NewROScalar(EMPTYP)); } else { - DynObject obs = new DynObject(LLArrayMO); - obs.SetSlot("value", new List()); - DynObject its = new DynObject(LLArrayMO); - its.SetSlot("value", new List()); DynObject lst = new DynObject(ListMO); - lst.SetSlot("items", Kernel.NewROScalar(obs)); - lst.SetSlot("rest", Kernel.NewROScalar(its)); + lst.SetSlot("items", new VarDeque()); + lst.SetSlot("rest", new VarDeque()); lst.SetSlot("flat", Kernel.NewROScalar(Kernel.AnyP)); th.caller.resultSlot = Kernel.NewRWListVar(lst); } @@ -197,7 +193,6 @@ public struct State { } public static DynMetaObject ListMO; - public static DynMetaObject LLArrayMO; public static DynMetaObject GatherIteratorMO; public static IP6 EMPTYP; public Frame End(Frame th) { @@ -205,22 +200,18 @@ public struct State { return Kernel.Take(th, Kernel.NewROScalar(MakeCursor())); } else { return_one = true; - DynObject obs = new DynObject(LLArrayMO); - List ks = new List(); - ks.Add(Kernel.NewROScalar(MakeCursor())); - obs.SetSlot("value", ks); + VarDeque ks = new VarDeque(); + ks.Push(Kernel.NewROScalar(MakeCursor())); DynObject it = new DynObject(GatherIteratorMO); it.SetSlot("value", Kernel.NewRWScalar(Kernel.AnyP)); it.SetSlot("next", Kernel.NewRWScalar(Kernel.AnyP)); it.SetSlot("valid", Kernel.NewRWScalar(Kernel.AnyP)); it.SetSlot("frame", Kernel.NewRWScalar(th)); - DynObject its = new DynObject(LLArrayMO); - List iss = new List(); - iss.Add(Kernel.NewROScalar(it)); - its.SetSlot("value", iss); + VarDeque iss = new VarDeque(); + iss.Push(Kernel.NewROScalar(it)); DynObject lst = new DynObject(ListMO); - lst.SetSlot("items", Kernel.NewROScalar(obs)); - lst.SetSlot("rest", Kernel.NewROScalar(its)); + lst.SetSlot("items", ks); + lst.SetSlot("rest", iss); lst.SetSlot("flat", Kernel.NewROScalar(Kernel.AnyP)); th.caller.resultSlot = Kernel.NewRWListVar(lst); } @@ -286,16 +277,11 @@ public Cursor(IP6 proto, string text) int l = backing_ca.Length; int p = pos; - DynObject obs = new DynObject(RxFrame.LLArrayMO); - List ks = new List(); - obs.SetSlot("value", ks); - - DynObject its = new DynObject(RxFrame.LLArrayMO); - its.SetSlot("value", new List()); + VarDeque ks = new VarDeque(); DynObject lst = new DynObject(RxFrame.ListMO); - lst.SetSlot("items", Kernel.NewROScalar(obs)); - lst.SetSlot("rest", Kernel.NewROScalar(its)); + lst.SetSlot("items", ks); + lst.SetSlot("rest", new VarDeque()); lst.SetSlot("flat", Kernel.NewROScalar(Kernel.AnyP)); if (p != 0 && p != l && CC.Word.Accepts(backing[p]) && @@ -306,7 +292,7 @@ public Cursor(IP6 proto, string text) while (p != l && Char.IsWhiteSpace(backing, p)) { p++; } if (Trace) Console.WriteLine("* match at {0} to {1}", pos, p); - ks.Add(Kernel.NewROScalar(At(p))); + ks.Push(Kernel.NewROScalar(At(p))); } return Kernel.NewROScalar(lst); diff --git a/lib/Kernel.cs b/lib/Kernel.cs index b61ecde9..cf15daed 100644 --- a/lib/Kernel.cs +++ b/lib/Kernel.cs @@ -762,10 +762,10 @@ public class Kernel { return new Variable(true, true, true, null, container); } - public static List SlurpyHelper(Frame th, int from) { - List lv = new List(); + public static VarDeque SlurpyHelper(Frame th, int from) { + VarDeque lv = new VarDeque(); for (int i = from; i < th.pos.Length; i++) { - lv.Add(th.pos[i]); + lv.Push(th.pos[i]); } return lv; } @@ -811,10 +811,8 @@ public class Kernel { DynObject dyl = lst as DynObject; if (dyl == null) goto slow; if (dyl.klass != ListMO) goto slow; - Variable itemsv = (Variable) dyl.GetSlot("items"); - IP6 itemso = (IP6) UnboxAny(itemsv.container); - List itemsl = (List) UnboxAny(itemso); - if (itemsl.Count == 0) goto slow; + VarDeque itemsl = (VarDeque) dyl.GetSlot("items"); + if (itemsl.Count() == 0) goto slow; th.resultSlot = itemsl[0]; return th; @@ -1053,6 +1051,94 @@ public class FatalException : ExceptionPacket { public override IP6 Payload() { return payload; } public override Frame Process(Frame t) { return t; } } + + public sealed class VarDeque { + private Variable[] data; + private int head; + private int count; + + public int Count() { return count; } + + public VarDeque() { + data = new Variable[8]; + } + + public VarDeque(VarDeque tp) { + data = (Variable[]) tp.data.Clone(); + head = tp.head; + count = tp.count; + } + + public VarDeque(Variable[] parcel) { + int cap = 8; + while (cap <= parcel.Length) cap *= 2; + data = new Variable[cap]; + Array.Copy(parcel, 0, data, 0, parcel.Length); + count = parcel.Length; + } + + private int fixindex(int index) { + int rix = index + head; + if (rix >= data.Length) rix -= data.Length; + return rix; + } + + private int fixindexc(int index) { + if (index >= count) + throw new IndexOutOfRangeException(); + return fixindex(index); + } + + public Variable this[int index] { + get { return data[fixindexc(index)]; } + set { data[fixindexc(index)] = value; } + } + + public void Push(Variable vr) { + checkgrow(); + data[fixindex(count++)] = vr; + } + + public Variable Pop() { + int index = fixindex(--count); + Variable d = data[index]; + data[index] = null; + return d; + } + + public void Unshift(Variable vr) { + checkgrow(); + head--; + count++; + if (head < 0) head += data.Length; + data[head] = vr; + } + + public Variable Shift() { + int index = head++; + if (head == data.Length) head = 0; + count--; + Variable d = data[index]; + data[index] = null; + return d; + } + + private void checkgrow() { + if (count == data.Length - 1) { + Variable[] ndata = new Variable[data.Length * 2]; + int z1 = data.Length - head; + if (z1 >= count) { + Array.Copy(data, head, ndata, 0, count); + } else { + Array.Copy(data, head, ndata, 0, z1); + int z2 = count - z1; + Array.Copy(data, 0, ndata, z1, z2); + } + data = ndata; + head = 0; + } + } + } } // The root setting diff --git a/lib/SAFE.setting b/lib/SAFE.setting index 954140b3..8e49c03e 100644 --- a/lib/SAFE.setting +++ b/lib/SAFE.setting @@ -388,7 +388,7 @@ PRE-INIT { Mu.HOW.add-method("new", anon method new() { Q:CgOp { (rawscall Kernel.DefaultNew (@ (l self))) } }); - Any.HOW.add-method("flat", anon method flat() { self, }); + Any.HOW.add-method("flat", anon method flat() { (self,).flat }); Any.HOW.add-method("ACCEPTS", anon method ACCEPTS($t) { self === $t }); Any.HOW.add-method('!butWHENCE', anon method !butWHENCE($cr) { @@ -407,10 +407,6 @@ PRE-INIT { anon method does($obj, $role) { self.isa($obj, $role) }); #no roles yet } -# boxes a List. SCHLIEMEL WAS HERE -# we can't use sigs on push and unshift because $x loses the flat bit -# this underlies Parcel and List. It looks a lot like RPA. - # Parcel: immutable list of boxes which have no context - may flatten, may # autovivify, don't rebind or push/shift/etc # List: mutable list of boxes without much context. accessing off end returns @@ -418,48 +414,6 @@ PRE-INIT { # Seq: mutable list of boxes which are taken to be read-only scalars. The .Seq # coercion makes the elements of a List read-only and maybe fetches them too. # Array: mutable list of read-write scalar boxes -my class LLArray { - method push is rawcall { Q:CgOp { (prog - [rawcall (unbox List (@ (pos 0))) Add (pos 1)] [pos 0]) } } - method pop() { Q:CgOp { (withtypes $f Variable $lv List - [l $lv (unbox List (@ (l self)))] - [l $f (getindex (- (getfield Count (l $lv)) (int 1)) (l $lv))] - [rawcall (l $lv) RemoveAt (- (getfield Count (l $lv)) (int 1))] - [l $f]) } } - method shift() { Q:CgOp { (withtypes $f Variable $lv List - [l $lv (unbox List (@ (l self)))] - [l $f (getindex (int 0) (l $lv))] - [rawcall (l $lv) RemoveAt (int 0)] - [l $f]) } } - method unshift is rawcall { Q:CgOp { (prog - [rawcall (unbox List (@ (pos 0))) Insert (int 0) (pos 1)] - [pos 0]) } } - method first-flattens() { Q:CgOp { - (box Bool (getfield islist (getindex (int 0) - (unbox List (@ (l self)))))) } } - method elems() { Q:CgOp { - (box Num (cast Double (getfield Count (unbox List - (@ (l self)))))) } } - method Bool() { ?( self.elems ) } - method new is rawcall { Q:CgOp { - (letn list (rawnew List) - max (getfield Length (getfield pos (callframe))) - i (int 1) - [whileloop 0 0 (< (l i) (l max)) - (prog - [rawcall (l list) Add (pos (l i))] - [l i (+ (l i) (int 1))])] - [box LLArray (l list)]) - } } - method at-pos($i) { - Q:CgOp { (getindex (cast Int32 (unbox Double (@ (l $i)))) - (unbox List (@ (l self)))) } - } - method clone() { Q:CgOp { - (box LLArray (rawnew List - (unbox List (@ (l self))))) - } } -} my class Iterator { has $.valid; @@ -499,9 +453,7 @@ sub unfold-list($l) { } sub unfold($fn) { - my @l := List.RAWCREATE("flat", 1, "items", LLArray.new(), - "rest", LLArray.new(unfold-iter($fn))); - @l; + List.SETUP(True, (&infix:<,>(unfold-iter($fn)))); } sub flat(*@x) { @x } @@ -509,17 +461,20 @@ sub flat(*@x) { @x } my class Whatever { } my class Parcel is Cool { - # $!ll + # $!value -> Variable[] - method flat() { - List.RAWCREATE("flat", 1, "items", LLArray.new(), "rest", $!ll.clone); - } + method flat() { List.SETUP(True, self) } + method list() { List.SETUP(False, self) } + + method elems() { Q:CgOp { + (box Num (cast Double (getfield Length + (unbox 'Variable[]' (@ {self}))))) + } } method iterator() { - my $ll = $!ll; my $it = Iterator.RAWCREATE("valid", 1, "value", Any, "next", Any); $it.value = EMPTY; - my $ix = ($ll.elems - 1); + my $ix = ($.elems - 1); while $ix >= 0 { my $nit = Iterator.RAWCREATE("valid", 1, "next", Any); @@ -527,8 +482,10 @@ my class Parcel is Cool { $it = $nit; Q:CgOp { (prog - [rawcall (cast DynObject (@ (l $it))) SetSlot - (clr_string value) (methodcall (l $ll) at-pos (l $ix))] + [rawcall (cast DynObject (@ {$it})) SetSlot + (clr_string value) (getindex + (cast Int32 (unbox Double (@ {$ix}))) + (unbox 'Variable[]' (@ {self})))] [null Variable]) }; $ix--; @@ -538,9 +495,12 @@ my class Parcel is Cool { } } -sub infix:<,>(*@v) { - my @r := Parcel.RAWCREATE("ll", Q:CgOp { (varattr rest (@ (l @v))) }); - @r; +sub infix:<,> is rawcall { + Q:CgOp { (newrwlistvar (@ (box Parcel (getfield pos (callframe))))) }; +} + +sub unitem is rawcall { + Q:CgOp { (newrwlistvar (@ (pos 0))) } } # Maybe this should be a constant, but constants are currently forced to @@ -548,7 +508,7 @@ sub infix:<,>(*@v) { sub Nil { state @n; START { - @n := Parcel.RAWCREATE("ll", LLArray.new); + @n := &infix:<,>(); } @n; } @@ -558,34 +518,85 @@ my class List is Cool { has @!rest; has $!flat; method flat() { - my @y := ($!flat ?? self !! self.RAWCREATE("flat", 1, - "items", LLArray.new(), "rest", LLArray.new(self.iterator))); - @y; + unitem($!flat ?? self !! self.SETUP(True, (&infix:<,>(self.iterator)))); } - method list() { my @y := self; @y } + method list() { unitem(self) } - method clone() { - self.RAWCREATE("flat", $!flat, "items", $!items.clone, "rest", - $!rest.clone); - } + method clone() { Q:CgOp { + (letn dys (cast DynObject (@ {self})) + new (rawnew DynObject (getfield klass (l dys))) + (rawcall (l new) SetSlot (s flat) + (rawcall (l dys) GetSlot (s flat))) + (rawcall (l new) SetSlot (s items) (rawnew VarDeque + (cast VarDeque (rawcall (l dys) GetSlot (s items))))) + (rawcall (l new) SetSlot (s rest) (rawnew VarDeque + (cast VarDeque (rawcall (l dys) GetSlot (s rest))))) + (newrwlistvar (l new))) + } } + + method SETUP($flat, $parcel) { Q:CgOp { + (letn new (rawnew DynObject (rawcall (@ {self}) GetMO)) + (rawcall (l new) SetSlot (s flat) {$flat}) + (rawcall (l new) SetSlot (s rest) (rawnew VarDeque + (unbox 'Variable[]' (@ {$parcel})))) + (rawcall (l new) SetSlot (s items) (rawnew VarDeque)) + (newrwlistvar (l new))) + } } method Seq() { - Seq.RAWCREATE("flat", 1, "items", LLArray.new, - "rest", LLArray.new(self.iterator)); + Seq.SETUP(True, (&infix:<,>(self.iterator))); } #| Takes an object and applies whatever semantics the List subclass #| needs to apply on stuff out of the iterator stack method !elem is rawcall { Q:CgOp { (pos 1) } } + sub first-rest-flattens($self) { Q:CgOp { + (box Bool (getfield islist (getindex (i 0) (cast VarDeque (rawcall (cast DynObject (@ {$self})) GetSlot (s rest)))))) + } } + + sub has-iterators($self) { Q:CgOp { + (box Bool (!= (i 0) (rawcall (cast VarDeque (rawcall (cast DynObject (@ {$self})) GetSlot (s rest))) Count))) + } } + + sub count-items($self) { Q:CgOp { + (box Num (cast Double (rawcall (cast VarDeque (rawcall (cast DynObject (@ {$self})) GetSlot (s items))) Count))) + } } + + sub shift-iterator($self) { Q:CgOp { + (rawcall (cast VarDeque (rawcall (cast DynObject (@ {$self})) GetSlot (s rest))) Shift) + } } + + sub shift-item($self) { Q:CgOp { + (rawcall (cast VarDeque (rawcall (cast DynObject (@ {$self})) GetSlot (s items))) Shift) + } } + + method !item-at-pos($ix) { Q:CgOp { + (getindex (cast Int32 (unbox Double (@ {$ix}))) (cast VarDeque (rawcall (cast DynObject (@ {self})) GetSlot (s items)))) + } } + + sub pop-item($self) { Q:CgOp { + (rawcall (cast VarDeque (rawcall (cast DynObject (@ {$self})) GetSlot (s items))) Pop) + } } + + sub push-iterator is rawcall { Q:CgOp { + (prog (rawcall (cast VarDeque (rawcall (cast DynObject (@ (pos 0))) GetSlot (s rest))) Push (pos 1)) (null Variable)) + } } + + sub push-item is rawcall { Q:CgOp { + (prog (rawcall (cast VarDeque (rawcall (cast DynObject (@ (pos 0))) GetSlot (s items))) Push (pos 1)) (null Variable)) + } } + + sub unshift-iterator is rawcall { Q:CgOp { + (prog (rawcall (cast VarDeque (rawcall (cast DynObject (@ (pos 0))) GetSlot (s rest))) Unshift (pos 1)) (null Variable)) + } } + method !fill($nr) { - my $i = $!items; - my $r = $!rest; - while $i.elems < $nr && $r { - if $!flat && $r.first-flattens { - $r.unshift($r.shift.iterator); + while count-items(self) < $nr && has-iterators(self) { + if $!flat && first-rest-flattens(self) { + unshift-iterator(self, shift-iterator(self).iterator); } else { - my $v := $r.shift; + my $v := shift-iterator(self); if $v.^isa(EMPTY) { # Discard summarily @@ -596,22 +607,22 @@ my class List is Cool { # we can't push anything onto items because it might be # EMPTY if ! $v.value.^isa(EMPTY) { - $r.unshift($v.next); - $r.unshift($v.value); + unshift-iterator(self, $v.next); + unshift-iterator(self, $v.value); } } else { - $i.push(self!elem($v)); + push-item(self, self!elem($v)); } } } - $i.elems >= $nr; + count-items(self) >= $nr; } method Bool() { self!fill(1) } method shift() { self!fill(1); - $!items.shift; + shift-item(self); } method eager() { @@ -619,14 +630,14 @@ my class List is Cool { self; } - method head { self!fill(1) ?? $!items.at-pos(0) !! Any } + method head { self!fill(1) ?? self!item-at-pos(0) !! Any } - method elems() { self!fill(1000_000_000); $!items.elems; } + method elems() { self!fill(1000_000_000); count-items(self); } method Numeric () { self.elems } method at-pos($i) { self!fill($i + 1); - $!items.at-pos($i); + self!item-at-pos($i); } method iterator() { unfold-list(self.clone) } @@ -642,11 +653,11 @@ my class List is Cool { method Str() { self.join(" ") } method push(*@items) { - $!rest.push(@items.Seq.eager.iterator) + push-iterator(self, @items.Seq.eager.iterator) } method pop() { self.eager; - $!items.pop; + pop-item(self); } } @@ -750,36 +761,40 @@ my class Seq is List { my class Array is List { method new() { - Array.RAWCREATE("flat", 1, "items", LLArray.new, "rest", LLArray.new); + Array.SETUP(True, &infix:<,>()) } method LISTSTORE(*@in) { # fetch everything NOW in case self is mentioned my $inn := @in.Seq.eager; - $!items = Q:CgOp { (varattr items (@ (l $inn))) }; - self; + Q:CgOp { (prog + (rawcall (cast DynObject (@ {self})) SetSlot (s items) + (rawcall (cast DynObject (@ {$inn})) GetSlot (s items))) + (null Variable)) + }; + unitem(self); } method !extend is rawcall { Q:CgOp { - (letn i (unbox List (getattr items (@ (pos 0)))) + (letn i (cast VarDeque (getslot (s items) (@ (pos 0)))) ct (- (cast Int32 (unbox Double (@ (pos 1)))) - (getfield Count (l i))) + (rawcall (l i) Count)) (ternary (>= (l ct) (int 0)) [prog] [die "Autovivification collision"]) (whileloop 0 0 (!= (l ct) (int 0)) (prog (l ct (- (l ct) (int 1))) - (rawcall (l i) Add (newrwscalar (@ (l Any)))))) - (rawcall (l i) Add (pos 2)) + (rawcall (l i) Push (newrwscalar (@ {Any}))))) + (rawcall (l i) Push (pos 2)) (null Variable)) }; } method at-pos($ix) { self!fill($ix+1) - ?? $!items.at-pos($ix) + ?? self!item-at-pos($ix) !! Any!butWHENCE(sub () is rawcall { self!extend($ix, Q:CgOp { (pos 0) }); }); @@ -867,10 +882,8 @@ my class GatherIterator is Iterator { } sub _gather($fr) { - my @l := List.RAWCREATE("flat", True, "items", LLArray.new, "rest", - LLArray.new(GatherIterator.RAWCREATE("frame", $fr, "valid", False, - "value", Any, "next", Any))); - @l; + List.SETUP(True, (&infix:<,>(GatherIterator.RAWCREATE("frame", $fr, + "valid", False, "value", Any, "next", Any)))); } sub take($p) { # should be \|$p @@ -942,8 +955,6 @@ PRE-INIT { (prog (rawsset RxFrame.EMPTYP (@ {EMPTY})) (rawsset RxFrame.ListMO (getfield klass (cast DynObject (@ {List})))) - (rawsset RxFrame.LLArrayMO (getfield klass - (cast DynObject (@ {LLArray})))) (rawsset RxFrame.GatherIteratorMO (getfield klass (cast DynObject (@ {GatherIterator})))) (null Variable)) diff --git a/src/CgOp.pm b/src/CgOp.pm index 0a4c38e9..baff6a68 100644 --- a/src/CgOp.pm +++ b/src/CgOp.pm @@ -391,6 +391,14 @@ use warnings; fetch(varattr($_[0], $_[1])); } + sub getslot { + rawcall(cast('DynObject', $_[1]), 'GetSlot', $_[0]); + } + + sub setslot { + rawcall(cast('DynObject', $_[1]), 'SetSlot', $_[0], $_[2]); + } + sub varattr { CgOp::Primitive->new(op => [ 'attr_var', $_[0] ], zyg => [ $_[1] ], is_cps_call => 1); diff --git a/src/CodeGen.pm b/src/CodeGen.pm index 67b7ff75..514a3d0b 100644 --- a/src/CodeGen.pm +++ b/src/CodeGen.pm @@ -16,6 +16,7 @@ use 5.010; Does => [m => 'Boolean'], GetTypeName => [m => 'String'], GetTypeObject=> [m => 'IP6'], + GetMO => [m => 'DynMetaObject'], IsDefined => [m => 'Boolean'], HOW => [c => 'IP6'] }, DynObject => @@ -90,6 +91,12 @@ use 5.010; SimpleWS => [m => 'Variable'] }, 'Lexer' => { Run => [m => 'Int32[]'] }, + 'VarDeque' => + { Push => [m => 'Void'], + Unshift => [m => 'Void'], + Pop => [m => 'Variable'], + Shift => [m => 'Variable'], + Count => [m => 'Int32'] }, 'System.IO.File.ReadAllText' => [m => 'System.String'], @@ -105,7 +112,7 @@ use 5.010; 'Kernel.Process' => [f => 'Variable'], 'Kernel.Global' => [f => 'Variable'], 'Kernel.PackageLookup' => [m => 'Variable'], - 'Kernel.SlurpyHelper' => [m => 'List'], + 'Kernel.SlurpyHelper' => [m => 'VarDeque'], 'Kernel.Bind' => [c => 'Void'], 'Kernel.BindNewScalar' => [c => 'Variable'], 'Kernel.BindNewList' => [c => 'Variable'], @@ -615,6 +622,7 @@ use 5.010; } my ($obj, $ix, $oty, $ixty) = $self->_popn(2); my $ty = ($oty =~ /^Dictionary<.*,(.*)>$/) ? $1 : + ($oty =~ /^VarDeque$/) ? 'Variable' : ($oty =~ /^(.*)\[\]$/) ? $1 : ($oty =~ /^List<(.*)>$/) ? $1 : die "type inference needs more hacks $oty"; diff --git a/src/Niecza/Actions.pm b/src/Niecza/Actions.pm index 2ee06ca4..bbd73c0a 100644 --- a/src/Niecza/Actions.pm +++ b/src/Niecza/Actions.pm @@ -1653,6 +1653,10 @@ my %opshortcut = ( 'w', [ 'wrap' ], 'ns', [ 'newscalar' ], 'nsw', [ 'newrwscalar' ], + 's', [ 'clr_string' ], + 'i', [ 'int' ], + 'b', [ 'bool' ], + 'd', [ 'double' ], '==', [ 'compare', '==' ], '!=', [ 'compare', '!=' ], '>=', [ 'compare', '>=' ], '<=', [ 'compare', '<=' ], '<', [ 'compare', '<' ], '>', [ 'compare', '>' ], diff --git a/src/Sig.pm b/src/Sig.pm index 56fe501a..0e94e43f 100644 --- a/src/Sig.pm +++ b/src/Sig.pm @@ -38,11 +38,10 @@ use 5.010; CgOp::rawcall($do, 'SetSlot', CgOp::clr_string('flat'), CgOp::box('Bool', CgOp::bool(1))), CgOp::rawcall($do, 'SetSlot', CgOp::clr_string('items'), - CgOp::box('LLArray', CgOp::rawnew('List'))), + CgOp::rawnew('VarDeque')), CgOp::rawcall($do, 'SetSlot', CgOp::clr_string('rest'), - CgOp::box('LLArray', - CgOp::rawscall('Kernel.SlurpyHelper', - CgOp::callframe, CgOp::letvar('!ix')))), + CgOp::rawscall('Kernel.SlurpyHelper', + CgOp::callframe, CgOp::letvar('!ix'))), CgOp::newscalar($do))}); }