using System;
+using System.Collections;
using M17N.Core;
namespace M17N.Core
{
- public class MPlist
+ public struct MProperty
{
- private MSymbol key;
- private object val;
+ internal MSymbol key;
+ internal object val;
+
+ public MSymbol Key { get { return this.key;} }
+ public object Val { get { return this.val; } }
+
+ public MProperty (MSymbol key, object val)
+ {
+ this.key = key;
+ this.val = val;
+ }
+ }
+
+ public class MPlist : IEnumerable
+ {
+ private MProperty prop;
private MPlist next;
public MPlist ()
{
- key = null;
- val = null;
- next = null;
+ prop = new MProperty (MSymbol.nil, null);
}
- public bool tailp { get { return (object) key == null; } }
+ public bool tailp { get { return prop.key == MSymbol.nil; } }
public new string ToString ()
{
for (MPlist p = this; ! p.tailp; p = p.next)
{
- str += (p == this ? "(" : " ") + p.key.ToString () + ":";
- if (p.val is MSymbol)
- str += ((MSymbol) p.val).ToString ();
- else if (p.val is MPlist)
- str += ((MPlist) p.val).ToString ();
+ str += (p == this ? "(" : " ") + p.prop.key.ToString () + ":";
+ if (p.prop.val is MSymbol)
+ str += ((MSymbol) p.prop.val).ToString ();
+ else if (p.prop.val is MPlist)
+ str += ((MPlist) p.prop.val).ToString ();
}
return str + ")";
}
if ((object) key == null)
return null;
for (MPlist p = this; ! p.tailp; p = p.next)
- if (p.key == key)
- return p.val;
+ if (p.prop.key == key)
+ return p.prop.val;
return null;
}
MPlist p;
for (p = this; ! p.tailp; p = p.next)
- if (p.key == key)
+ if (p.prop.key == key)
{
if (val != null)
- p.val = val;
+ p.prop.val = val;
else
p.pop ();
return val;
}
if (val != null)
{
- p.key = key;
- p.val = val;
+ p.prop.key = key;
+ p.prop.val = val;
p.next = new MPlist ();
}
return val;
{
MPlist p = new MPlist ();
- p.key = this.key;
- p.val = this.val;
+ p.prop.key = this.prop.key;
+ p.prop.val = this.prop.val;
p.next = this.next;
- this.key = key;
- this.val = val;
+ this.prop.key = key;
+ this.prop.val = val;
this.next = p;
return val;
if (tailp)
return null;
- object val = this.val;
+ object val = this.prop.val;
- this.key = this.next.key;
- this.val = this.next.val;
+ this.prop.key = this.next.prop.key;
+ this.prop.val = this.next.prop.val;
this.next = this.next.next;
return val;
}
for (p = this; ! p.tailp; p = p.next);
if (val != null)
{
- p.key = key;
- p.val = val;
+ p.prop.key = key;
+ p.prop.val = val;
p.next = new MPlist ();
}
return val;
}
+
+ public MPlist find (MSymbol key)
+ {
+ for (MPlist p = this; ! p.tailp; p = p.next)
+ if (p.prop.key == key)
+ return p;
+ return null;
+ }
+
+ // Implement IEnumerable interface.
+
+ public virtual IEnumerator GetEnumerator ()
+ {
+ return new Enumerator (this);
+ }
+
+ private class Enumerator : IEnumerator
+ {
+ private MPlist plist;
+ private MPlist current;
+
+ internal Enumerator (MPlist plist)
+ {
+ this.plist = plist;
+ }
+
+ public object Current
+ {
+ get {
+ if (current == null || current.tailp)
+ throw new InvalidOperationException ();
+ return current;
+ }
+ }
+
+ public void Reset ()
+ {
+ current = null;
+ }
+
+ public bool MoveNext ()
+ {
+ if (current == null)
+ current = plist;
+ else if (current.tailp)
+ return false;
+ else
+ current = current.next;
+ return true;
+ }
+ }
}
}