Skip to content

Commit

Permalink
Simplify representation and construction of lists
Browse files Browse the repository at this point in the history
  • Loading branch information
sorear committed Sep 8, 2010
1 parent ffb2ed0 commit 9740be1
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 140 deletions.
38 changes: 12 additions & 26 deletions lib/Cursor.cs
Expand Up @@ -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<Variable>());
DynObject its = new DynObject(LLArrayMO);
its.SetSlot("value", new List<Variable>());
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);
}
Expand Down Expand Up @@ -197,30 +193,25 @@ public struct State {
}

public static DynMetaObject ListMO;
public static DynMetaObject LLArrayMO;
public static DynMetaObject GatherIteratorMO;
public static IP6 EMPTYP;
public Frame End(Frame th) {
if (return_one) {
return Kernel.Take(th, Kernel.NewROScalar(MakeCursor()));
} else {
return_one = true;
DynObject obs = new DynObject(LLArrayMO);
List<Variable> ks = new List<Variable>();
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<Variable> iss = new List<Variable>();
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);
}
Expand Down Expand Up @@ -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<Variable> ks = new List<Variable>();
obs.SetSlot("value", ks);

DynObject its = new DynObject(RxFrame.LLArrayMO);
its.SetSlot("value", new List<Variable>());
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]) &&
Expand All @@ -306,7 +292,7 @@ public Cursor(IP6 proto, string text)
while (p != l && Char.IsWhiteSpace(backing, p)) { p++; }
if (Trace)
Console.WriteLine("* match <ws> at {0} to {1}", pos, p);
ks.Add(Kernel.NewROScalar(At(p)));
ks.Push(Kernel.NewROScalar(At(p)));
}

return Kernel.NewROScalar(lst);
Expand Down
100 changes: 93 additions & 7 deletions lib/Kernel.cs
Expand Up @@ -762,10 +762,10 @@ public class Kernel {
return new Variable(true, true, true, null, container);
}

public static List<Variable> SlurpyHelper(Frame th, int from) {
List<Variable> lv = new List<Variable>();
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;
}
Expand Down Expand Up @@ -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<Variable> itemsl = (List<Variable>) 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;

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 9740be1

Please sign in to comment.