*** empty log message ***
authorhanda <handa>
Wed, 14 Jan 2009 00:08:26 +0000 (00:08 +0000)
committerhanda <handa>
Wed, 14 Jan 2009 00:08:26 +0000 (00:08 +0000)
MPlist.cs
MText.cs
temp.cs

index ffdea57..0295da9 100644 (file)
--- a/MPlist.cs
+++ b/MPlist.cs
@@ -3,20 +3,32 @@ using M17N.Core;
 
 namespace M17N.Core
 {
+  public struct MProperty
+  {
+    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
   {
-    private MSymbol key;
-    private object val;
+    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 ()
     {
@@ -24,11 +36,11 @@ namespace M17N.Core
 
       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 + ")";
     }
@@ -38,8 +50,8 @@ namespace M17N.Core
       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;
     }
 
@@ -48,18 +60,18 @@ namespace M17N.Core
       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;
@@ -69,11 +81,11 @@ namespace M17N.Core
     {
       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;
@@ -84,10 +96,10 @@ namespace M17N.Core
       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;
     }
@@ -99,8 +111,8 @@ namespace M17N.Core
       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;
index 12e482c..de090a9 100644 (file)
--- a/MText.cs
+++ b/MText.cs
@@ -1,5 +1,7 @@
 using System;
 using System.Text;
+using System.Collections;
+using System.Collections.Generic;
 using M17N.Core;
 
 namespace M17N.Core
@@ -16,37 +18,41 @@ namespace M17N.Core
   }
 #endif
 
+  public class MTextProperty
+  {
+    internal MProperty prop;
+    internal bool front_sticky;
+    internal bool rear_sticky;
+    internal bool merginable;
+    public MProperty Prop { get { return prop; } }
+    public bool FrontSticky { get { return front_sticky; } }
+    public bool RearSticky { get { return rear_sticky; } }
+    public bool Merginable { get { return merginable; } }
+
+    public MTextProperty (bool front_sticky, bool rear_sticky)
+    {
+      this.front_sticky = front_sticky;
+      this.rear_sticky = rear_sticky;
+    }
+    public MTextProperty (bool front_sticky, bool rear_sticky, bool merginable)
+    {
+      this.front_sticky = front_sticky;
+      this.rear_sticky = rear_sticky;
+      this.merginable = merginable;
+    }
+  }
+
   public class MText
   {
 #if false
     public enum MTextFormat format;
 #endif
 
-    private class MTextPlist : MPlist
-    {
-      public class MInterval
-      {
-       MPlist stack;
-       int nprops;
-       public int start, end;
-       public MInterval prev, next;
-      }
-
-      MInterval head, tail;
-
-      public MTextPlist (MText mt)
-      {
-       head = tail = new MInterval ();
-       head.start = 0;
-       head.end = mt.sb.Length;
-      }
-    }
-
     private StringBuilder sb;
     private int nchars;
     private int cache_pos;
     private int cache_idx;
-    private MTextPlist plist;
+    private MInterval root_interval;
     private bool unmodifiable;
 
     private static UTF8Encoding utf8 = new UTF8Encoding ();
@@ -217,13 +223,13 @@ namespace M17N.Core
       return (new MText (sb.ToString ()));
     }
 
-    public MText ins (int pos, ref MText mt)
+    public MText ins (int pos, MText mt)
     {
       insert (pos, mt, 0, mt.nchars);
       return this;
     }
 
-    public MText ins (int pos, ref MText mt, int from, int to)
+    public MText ins (int pos, MText mt, int from, int to)
     {
       insert (pos, mt, from, to);
       return this;
@@ -235,9 +241,160 @@ namespace M17N.Core
       nchars -= to - from;
       return this;
     }
-  }
 
-  public class MTextProperty
-  {
+    private class MInterval
+    {
+      // Start and end positions of the MText covered of this interval
+      // and its children.  The values are actually (4N +- 1), where N
+      // is a non-negative integer representing a position relative to
+      // the parent interval.
+      private int total_start, total_end;
+      // Stack of MTextProperty
+      private Stack<MTextProperty> stack;
+      // Number of child nodes
+      private int nodes;
+      private MInterval left, right, parent;
+
+      private int Start {
+       get {
+         return (left == null ? total_start : total_start + left.total_end);
+       }
+      }
+
+      private int End {
+       get {
+         return (right == null ? total_end : total_start + right.total_start);
+       }
+      }
+
+      private MInterval Left {
+       get {
+         MInterval interval;
+
+         if (left != null)
+           {
+             for (interval = left; interval.right != null;
+                  interval = interval.right);
+           }
+         else
+           {
+             for (interval = parent;
+                  interval != null && interval.total_start == total_start;
+                  interval = interval.parent);
+           }
+         return interval;
+       }
+      }
+
+      private MInterval Right {
+       get {
+         MInterval interval;
+
+         if (right != null)
+           {
+             for (interval = right; interval.left != null;
+                  interval = interval.left);
+           }
+         else
+           {
+             for (interval = parent;
+                  interval != null && interval.total_end == total_end;
+                  interval = interval.parent);
+           }
+         return interval;
+       }
+      }
+
+      private static int MakePosition (int pos, bool front_inclusive)
+      {
+       return (pos << 2) + (front_inclusive ? -1 : 1);
+      }
+
+      private MInterval (int start, int end)
+      {
+       if (start > end)
+         throw new Exception ("Invalid Interval Range");
+       this.total_start = (start << 2) + 1;
+       this.total_end = (end << 2) + -1;
+       this.stack = new Stack<MTextProperty> ();
+       this.nodes = 1;
+      }
+
+      public MInterval (int start, bool front_inclusive,
+                       int end, bool rear_inclusive)
+      {
+       if (start > end)
+         throw new Exception ("Invalid Interval Range");
+       this.total_start = (start << 2) + (front_inclusive ? -1 : 1);
+       this.total_end = (end << 2) + (rear_inclusive ? 1 : -1);
+       this.stack = new Stack<MTextProperty> ();
+       this.nodes = 1;
+      }
+
+      public void Push (MTextProperty prop, int start, int end)
+      {
+       start <<= 2;
+       if (prop.FrontSticky)
+         start--;
+       else
+         start++;
+       end <<= 2;
+       if (prop.RearSticky)
+         end++;
+       else
+         end--;
+       if (start >= end)
+         throw new Exception ("Invalid Text Property Range");
+
+       push (prop, start, end);
+      }
+
+      private MInterval divide_right (int pos)
+      {
+       MInterval interval = new MInterval (pos, End);
+
+       return interval;
+      }
+
+      private MInterval divide_left (int pos)
+      {
+       MInterval interval = new MInterval (Start, pos);
+
+       return interval;
+      }
+
+      private void push (MTextProperty prop, int start, int end)
+      {
+       int this_start = Start;
+       int this_end = End;
+
+       if (start < this_start)
+         {
+           if (end <= this_start)
+             Left.push (prop, start, end);
+           else
+             {
+               Left.push (prop, start, this_start);
+               if (end < this_end)
+                 {
+                   divide_right (end);
+                   stack.Push (prop);
+                 }
+               else
+                 {
+                   stack.Push (prop);
+                   if (this_end < end)
+                     Right.Push (prop, this_end, end);
+                 }
+             }
+         }
+       else if (start < this_end)
+         {
+           divide_right (start).Push (prop, start, end);
+         }
+       else
+         Right.Push (prop, start, end);
+      }
+    }
   }
 }
diff --git a/temp.cs b/temp.cs
index a5cf1d5..d327f3a 100644 (file)
--- a/temp.cs
+++ b/temp.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using M17N.Core;
 
 public class Test
@@ -17,9 +18,11 @@ public class Test
     mt[1] = 'b';
     Console.WriteLine (mt2);
 
-    int[] ary = {1, 2, 3};
-
-    Array.ForEach<int> (ary, delegate (int o) { Console.WriteLine (o); });
+    List<int> list = new List<int>();
 
+    list.Add (1);
+    list.Add (2);
+    for (int i = 0; i < 2; i++)
+      Console.WriteLine (list[i]);
   }
 }