*** empty log message ***
authorhanda <handa>
Mon, 30 Mar 2009 11:40:48 +0000 (11:40 +0000)
committerhanda <handa>
Mon, 30 Mar 2009 11:40:48 +0000 (11:40 +0000)
MPlist.cs
MSymbol.cs
MText.cs
Makefile
temp.cs [deleted file]
test-mtext.cs [new file with mode: 0644]
test-plist.cs [new file with mode: 0644]
test-sym.cs [new file with mode: 0644]

index 7c81701..23ef0a1 100644 (file)
--- a/MPlist.cs
+++ b/MPlist.cs
@@ -11,10 +11,10 @@ namespace M17N.Core
     private MPlist next;
 
     public MPlist ()
-    {
-      Key = MSymbol.nil;
-      Val = null;
-    }
+      {
+       Key = MSymbol.nil;
+       Val = null;
+      }
 
     private MPlist (MSymbol key, object val)
       {
@@ -23,20 +23,37 @@ namespace M17N.Core
       }
 
     public bool IsEmpty { get { return next == null; } }
+    public MPlist Next { get { return next; } }
 
-    public new string ToString ()
+    public int Count
     {
-      string str = "";
-
-      for (MPlist p = this; ! p.IsEmpty; p = p.next)
+      get
        {
-         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 ();
+         int i = 0;
+
+         for (MPlist p = this; p.next != null; i++, p = p.next);
+         return i;
        }
-      return str + ")";
+    }
+
+    public MPlist Clone ()
+    {
+      MPlist plist = new MPlist (), pl = plist;
+
+      for (MPlist p = this; p.next != null; p = p.next)
+       pl = pl.add (p.Key, p.Val);
+      return plist;
+    }
+
+    public override string ToString ()
+    {
+       string str = "";
+
+       for (MPlist p = this; ! p.IsEmpty; p = p.next)
+         {
+           str += (p == this ? "(" : " ") + p.Key + ":" + p.Val;
+         }
+       return str + ")";
     }
 
     public MPlist find (MSymbol key)
@@ -97,6 +114,7 @@ namespace M17N.Core
     }
 
     // Implement IEnumerable interface.
+    //   foreach (MPlist p in plist) { ... }
 
     public virtual IEnumerator GetEnumerator ()
     {
index 67fa7e9..30f80d4 100644 (file)
@@ -36,7 +36,18 @@ namespace M17N.Core
        data = (MSymbolData) pool[name];
     }
 
-    public override string ToString () { return data.name; }
+    public override string ToString ()
+    {
+      string str = "";
+
+      foreach (char c in data.name)
+       {
+         if (c == '\\' || c == ' ' || c == '\'' || c == '\"')
+           str += "\\";
+         str += c;
+       }
+      return str;
+    }
 
     public override bool Equals (Object sym)
     {
index ff29503..a86bc29 100644 (file)
--- a/MText.cs
+++ b/MText.cs
@@ -22,27 +22,50 @@ namespace M17N.Core
   {
     internal MSymbol key;
     internal object val;
-    private bool front_sticky;
-    private bool rear_sticky;
+
+    [FlagsAttribute]
+    internal enum Flag : byte
+      {
+       None =          0,
+       FrontSticky =   1,
+       RearSticky =    2,
+       Sensitive =     4
+      };
+    internal Flag flags;
 
     public MSymbol Key { get { return key; } }
     public object Val { get { return val; } }
-    public bool FrontSticky { get { return front_sticky; } }
-    public bool RearSticky { get { return rear_sticky; } }
+    public bool FrontSticky
+    {
+      get { return (flags & Flag.FrontSticky) != Flag.None; }
+    }
+    public bool RearSticky
+    {
+      get { return (flags & Flag.RearSticky) != Flag.None; }
+    }
+    public bool Sensitive
+    {
+      get { return (flags & Flag.Sensitive) != Flag.None; }
+    }
 
     public MTextProperty (MSymbol key, object val)
     {
       this.key = key;
       this.val = val;
+      flags |= Flag.RearSticky;
     }
 
     public MTextProperty (MSymbol key, object val,
-                         bool front_sticky, bool rear_sticky)
+                         bool front_sticky, bool rear_sticky, bool sensitive)
     {
       this.key = key;
       this.val = val;
-      this.front_sticky = front_sticky;
-      this.rear_sticky = rear_sticky;
+      if (front_sticky)
+       flags |= Flag.FrontSticky;
+      if (rear_sticky)
+       flags |= Flag.RearSticky;
+      if (sensitive)
+       flags |= Flag.Sensitive;
     }
   }
 
@@ -136,7 +159,7 @@ namespace M17N.Core
       return this.sb.ToString ().CompareTo (other.sb.ToString ());
     }
 
-    public override String ToString () { return sb.ToString (); }
+    public override String ToString () { return "\"" + sb.ToString () + "\""; }
 
     private static bool surrogate_high_p (char c)
     {
@@ -357,7 +380,7 @@ namespace M17N.Core
       private int total_length;
       private int from, to;
       private MSymbol key;
-      private Stack<MTextProperty> stack;
+      private MPlist stack;
       private MInterval left, right, parent;
       private MText mtext;
 
@@ -367,7 +390,7 @@ namespace M17N.Core
          throw new Exception ("Invalid interval length");
        this.key = key;
        total_length = length;
-       stack = new Stack<MTextProperty> ();
+       stack = new MPlist ();
       }
 
       public MInterval (MSymbol key, MText mt)
@@ -377,39 +400,43 @@ namespace M17N.Core
        total_length = mt.sb.Length;
        from = 0;
        to = total_length;
-       stack = new Stack<MTextProperty> ();
+       stack = new MPlist ();
       }
 
       public MTextProperty get (int pos)
       {
        MInterval i = find (pos);
 
-       return (i.stack.Count > 0 ? i.stack.Peek () : null);
+       return (i.stack.IsEmpty ? null : (MTextProperty) i.stack.Val);
       }
 
       public MTextProperty get (int pos, out MTextProperty[] array)
       {
        MInterval i = find (pos);
 
-       if (i.stack.Count == 0)
+       if (i.stack.IsEmpty)
          {
            array = null;
            return null;
          }
-       array = i.stack.ToArray ();
-       return i.stack.Peek ();
+       array = new MTextProperty[i.stack.Count];
+
+       int idx;
+       MPlist p;
+       for (idx = 0, p = i.stack; ! p.IsEmpty; idx++, p = p.Next)
+         array[idx] = (MTextProperty) p.Val;
+       return array[idx - 1];
       }
 
-      private MInterval (MSymbol key, int length, Stack<MTextProperty> stack)
+      private MInterval (MSymbol key, int length, MPlist stack)
       {
        this.key = key;
        total_length = length;
        from = 0;
        to = total_length;
-       stack = new Stack<MTextProperty> (stack);
+       this.stack = stack.Clone ();
       }
 
-
       private void update_from_to ()
       {
        if (parent != null)
@@ -429,17 +456,17 @@ namespace M17N.Core
        get { return (right == null ? 0 : right.total_length); }
       }
 
-      private MInterval LeftMostNode
+      private MInterval left_most_node
       {
-       get { return (left == null ? this : left.LeftMostNode); }
+       get { return (left == null ? this : left.left_most_node); }
       }
 
-      private MInterval RightMostNode
+      private MInterval right_most_node
       {
-       get { return (right == null ? this : right.RightMostNode); }
+       get { return (right == null ? this : right.right_most_node); }
       }
 
-      private MInterval LeftNode {
+      private MInterval prev {
        get {
          MInterval i;
 
@@ -451,7 +478,7 @@ namespace M17N.Core
        }
       }
 
-      private MInterval RightNode {
+      private MInterval next {
        get {
          MInterval i;
 
@@ -635,81 +662,131 @@ namespace M17N.Core
        return interval;
       }
 
+      private void remove_properties (MTextProperty.Flag flags)
+      {
+       for (MPlist p = stack; ! p.IsEmpty;)
+         {
+           MTextProperty prop = (MTextProperty) p.Val;
+
+           if ((prop.flags & flags) == flags)
+             p.pop ();
+           else
+             p = p.Next;
+         }
+      }
+
+      private void merge_properties (MPlist plist, MTextProperty.Flag flags)
+      {
+       if (left != null)
+         left.merge_properties (plist, flags);
+       if (right != null)
+         right.merge_properties (plist, flags);
+       for (MPlist p = plist; ! p.IsEmpty; p = p.Next)
+         {
+           MTextProperty prop = (MTextProperty) p.Val;
+
+           if ((prop.flags & flags) == flags
+               && stack.get (prop.Key) == null)
+             stack.push (prop.key, prop);
+         }
+      }
+
       public void insert (int pos, MInterval interval)
       {
        update_from_to ();
-       if (pos < from)
+       if (pos < from || (pos == from && left == null && pos > 0))
          {
-           LeftNode.insert (pos, interval);
+           prev.insert (pos, interval);
            return;
          }
-       if (pos >= to)
+       if (pos > to || (pos == to && right == null && next != null))
          {
-           RightNode.insert (pos, interval);
+           next.insert (pos, interval);
            return;
          }
-       if (pos > from)
+       if (pos > from && pos < to)
          {
+           remove_properties (MTextProperty.Flag.Sensitive);
            divide_right (pos).insert (pos, interval);
            return;
          }         
-
-       // POS == FROM
-       if (left != null && LeftNode.stack.Count > 0)
+       if (pos == from)
          {
-           Stack<MTextProperty> s = new Stack<MTextProperty> ();
-
-           foreach (MTextProperty p in LeftNode.stack)
-             if (p.RearSticky)
-               s.Push (p);
-           if (s.Count > 0)
+           if (pos > 0)
              {
-               for (MInterval i = interval.LeftMostNode;
-                    i != null && i.stack.Count == 0;
-                    i = i.LeftNode)
-                 foreach (MTextProperty p in s)
-                   i.stack.Push (p);
+               prev.remove_properties
+                 (MTextProperty.Flag.Sensitive|MTextProperty.Flag.RearSticky);
+               interval.merge_properties
+                 (prev.stack, MTextProperty.Flag.RearSticky);
              }
-         }
-       if (stack.Count > 0)
-         {
-           Stack<MTextProperty> s = new Stack<MTextProperty> ();
-
-           foreach (MTextProperty p in stack)
-             if (p.FrontSticky)
-               s.Push (p);
-           if (s.Count > 0)
+           remove_properties
+             (MTextProperty.Flag.Sensitive|MTextProperty.Flag.FrontSticky);
+           interval.merge_properties
+             (stack, MTextProperty.Flag.FrontSticky);
+
+           // INTERVAL is ready to insert.
+           //
+           //    .-this-.   ==>          .-this-.
+           // left-.                  left-.
+           //     child                  .-interval
+           //                         child
+
+           if (pos > 0)
              {
-               for (MInterval i = interval.RightMostNode;
-                    i != null && i.stack.Count == 0;
-                    i = i.RightNode)
-                 foreach (MTextProperty p in s)
-                   i.stack.Push (p);
+               MInterval i = left.right_most_node;
+       
+               i.left = interval;
+               interval.parent = i;
+               for (; i != null; i = i.parent)
+                 i.total_length += interval.total_length;
              }
-         }
-
-       // INTERVAL is ready to insert.
-       //
-       //    .-this-.   ==>          .-this-.
-       // left-.                  left-.
-       //     child                  interval
-       //                         child
+           else
+             {
+               left = interval;
 
-       if (left != null)
-         {
-           MInterval i = left.RightMostNode;
-       
-           i.left = interval;
-           interval.parent = i;
-           for (; i != null; i = i.parent)
-             i.total_length += interval.total_length;
+               for (MInterval i = this; i != null; i = i.parent)
+                 i.total_length += interval.total_length;
+             }
          }
-       else
+       else                    // pos == to
          {
-           left = interval;
+           if (right != null)
+             {
+               MInterval left_most = right.left_most_node;
 
-           for (MInterval i = this; i != null; i = i.parent)
-             i.total_length += interval.total_length;
+               left_most.remove_properties
+                 (MTextProperty.Flag.Sensitive|MTextProperty.Flag.FrontSticky);
+               interval.merge_properties
+                 (stack, MTextProperty.Flag.FrontSticky);
+             }
+           remove_properties
+             (MTextProperty.Flag.Sensitive|MTextProperty.Flag.RearSticky);
+           interval.merge_properties
+             (stack, MTextProperty.Flag.RearSticky);
+
+           // INTERVAL is ready to insert.
+           //
+           //    .-this-.   ==>          .-this-.
+           //         .-right                 .-right
+           //     child                  interval-.
+           //                                    child
+
+           if (right != null)
+             {
+               MInterval i = right.left_most_node;
+       
+               i.left = interval;
+               interval.parent = i;
+               for (; i != null; i = i.parent)
+                 i.total_length += interval.total_length;
+             }
+           else
+             {
+               right = interval;
+
+               for (MInterval i = this; i != null; i = i.parent)
+                 i.total_length += interval.total_length;
+             }
          }
       }
 
@@ -807,7 +884,7 @@ namespace M17N.Core
          divide_left (from);
        if (end < to)
          divide_right (end);
-       stack.Push (prop);
+       stack.push (prop.key, prop);
        return prop;
       }
     }
index 93cc1ff..3151245 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 CORE_SRC = MSymbol.cs MPlist.cs MText.cs
 CS=gmcs
 
-all: M17N.exe temp.exe
+all: M17N.exe test-sym.exe test-plist.exe test-mtext.exe
 
 M17NCore.dll: ${CORE_SRC}
        $(CS) /out:$@ /t:library ${CORE_SRC}
@@ -9,8 +9,14 @@ M17NCore.dll: ${CORE_SRC}
 M17N.exe: M17N.cs M17NCore.dll
        $(CS) /r:M17NCore M17N.cs
 
-temp.exe: temp.cs M17NCore.dll
-       $(CS) -codepage:65001 /r:M17NCore temp.cs
+test-mtext.exe: test-mtext.cs M17NCore.dll
+       $(CS) -codepage:65001 /r:M17NCore test-mtext.cs
+
+test-sym.exe: test-sym.cs M17NCore.dll
+       $(CS) -codepage:65001 /r:M17NCore test-sym.cs
+
+test-plist.exe: test-plist.cs M17NCore.dll
+       $(CS) -codepage:65001 /r:M17NCore test-plist.cs
 
 clean:
        rm -f *.dll *.exe
diff --git a/temp.cs b/temp.cs
deleted file mode 100644 (file)
index e212bf7..0000000
--- a/temp.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-using M17N.Core;
-
-public class Test
-{
-  public static void Main()
-  {
-    String str = "a𝄀あc";
-    MText mt = new MText (str);
-
-    Console.WriteLine ("{0}, Length={1}", mt, mt.Length);
-    foreach (int c in mt)
-      Console.WriteLine ("U+{0:X4}", c);
-    Console.WriteLine (mt + new MText ("漢字"));
-
-    MText mt2 = mt.dup ();
-    mt[1] = 'b';
-    Console.WriteLine (mt);
-    Console.WriteLine (mt2);
-  }
-}
diff --git a/test-mtext.cs b/test-mtext.cs
new file mode 100644 (file)
index 0000000..e212bf7
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using M17N.Core;
+
+public class Test
+{
+  public static void Main()
+  {
+    String str = "a𝄀あc";
+    MText mt = new MText (str);
+
+    Console.WriteLine ("{0}, Length={1}", mt, mt.Length);
+    foreach (int c in mt)
+      Console.WriteLine ("U+{0:X4}", c);
+    Console.WriteLine (mt + new MText ("漢字"));
+
+    MText mt2 = mt.dup ();
+    mt[1] = 'b';
+    Console.WriteLine (mt);
+    Console.WriteLine (mt2);
+  }
+}
diff --git a/test-plist.cs b/test-plist.cs
new file mode 100644 (file)
index 0000000..0730a28
--- /dev/null
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using M17N.Core;
+
+public class Test
+{
+  public static void Main()
+  {
+    MSymbol sym = new MSymbol ("symbol");
+    MPlist plist = new MPlist ();
+    MText mt = new MText ("abc");
+
+    plist.put (sym, mt);
+
+    Console.WriteLine (plist);
+  }
+}
diff --git a/test-sym.cs b/test-sym.cs
new file mode 100644 (file)
index 0000000..c0e4a9f
--- /dev/null
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using M17N.Core;
+
+public class Test
+{
+  public static void Main()
+  {
+    MSymbol sym1 = new MSymbol ("symbol");
+    MSymbol sym2 = new MSymbol ("symbol");
+    MSymbol sym3 = new MSymbol ("another symbol");
+
+    Console.WriteLine ("sym1 = {0}", sym1);
+    Console.WriteLine ("sym2 = {0}", sym2);
+    Console.WriteLine ("sym3 = {0}", sym3);
+    Console.WriteLine ("sym1 {0} sym2", sym1 == sym2 ? "==" : "!=");
+    Console.WriteLine ("sym1 {0} sym3", sym1 == sym3 ? "==" : "!=");
+
+    sym1.put (sym2, "prop1");
+    sym1.put (sym3, "prop2");
+    Console.WriteLine (sym1.get (sym2) + "," + sym1.get (sym3));
+    Console.WriteLine (sym2.get (sym2) + "," + sym2.get (sym3));
+    Console.WriteLine (sym3.get (sym2));
+  }
+}