From d571ebf04b3954e89b335cf9130f38eb20d03ce9 Mon Sep 17 00:00:00 2001 From: handa Date: Wed, 29 Apr 2009 02:48:24 +0000 Subject: [PATCH] *** empty log message *** --- M17N.cs | 20 +----- MDatabase.cs | 2 +- MPlist.cs | 6 +- MSymbol.cs | 122 ++++++++++++++-------------------- MText.cs | 205 +++++++++++++++++++++++++++++++++++++--------------------- plist.cs | 6 +- symbol.cs | 15 +++-- textprop.cs | 26 ++++---- 8 files changed, 209 insertions(+), 193 deletions(-) diff --git a/M17N.cs b/M17N.cs index fe469ae..a6f3b29 100644 --- a/M17N.cs +++ b/M17N.cs @@ -12,28 +12,10 @@ namespace M17N public static bool debug = false; - public static void DebugPrint (object arg) - { - if (debug) - Console.Write (arg); - } - - public static void DebugPrint (string fmt, object arg) + public static void DebugPrint (string fmt, params object[] arg) { if (debug) Console.Write (fmt, arg); } - - public static void DebugPrint (string fmt, object arg1, object arg2) - { - if (debug) - Console.Write (fmt, arg1, arg2); - } - - public static void DebugPrint (string fmt, object arg1, object arg2, object arg3) - { - if (debug) - Console.Write (fmt, arg1, arg2, arg3); - } } } diff --git a/MDatabase.cs b/MDatabase.cs index 74c3ff3..798599f 100644 --- a/MDatabase.cs +++ b/MDatabase.cs @@ -139,7 +139,7 @@ namespace M17N.Core private static MDatabaseDir[] DBDirs = new MDatabaseDir[3]; private const string SystemDirectory = "/usr/share/m17n"; - private readonly MSymbol Mversion = new MSymbol ("version"); + private readonly MSymbol Mversion = MSymbol.Of ("version"); /// Type of database private enum MDBType diff --git a/MPlist.cs b/MPlist.cs index b6da903..67977b3 100644 --- a/MPlist.cs +++ b/MPlist.cs @@ -418,7 +418,7 @@ namespace M17N.Core { string str = ReadSymbolName (); - val = new MSymbol ("-" + str); + val = MSymbol.Of ("-" + str); key = MSymbol.symbol; } } @@ -441,7 +441,7 @@ namespace M17N.Core { string str = ReadSymbolName (); - val = new MSymbol ("#" + (char) c + str); + val = MSymbol.Of ("#" + (char) c + str); key = MSymbol.symbol; } } @@ -455,7 +455,7 @@ namespace M17N.Core } else { - val = new MSymbol (ReadSymbolName ()); + val = MSymbol.Of (ReadSymbolName ()); key = MSymbol.symbol; } return true; diff --git a/MSymbol.cs b/MSymbol.cs index fe2a698..4aeffb4 100644 --- a/MSymbol.cs +++ b/MSymbol.cs @@ -1,68 +1,70 @@ using System; -using System.Collections; +using System.Collections.Generic; using M17N.Core; namespace M17N.Core { - public class MSymbol + public sealed class MSymbol { - static private Hashtable pool = new Hashtable (); + private static Dictionary pool + = new Dictionary (); - private class MSymbolData - { - public readonly string Name; - public readonly MTextProperty.Flags Flags; - public object Value; - public MPlist Plist; - - public MSymbolData (string name, MTextProperty.Flags flags) - { - Name = name; - Flags = flags; - } - } + public readonly string Name; + private MPlist Plist; + internal MProperty.Flags? flags; - private MSymbolData data; + public static MSymbol nil = MSymbol.Of ("nil"); + public static MSymbol t = MSymbol.Of ("t"); + public static MSymbol symbol = MSymbol.Of ("symbol"); + public static MSymbol mtext = MSymbol.Of ("mtext"); + public static MSymbol plist = MSymbol.Of ("plist"); + public static MSymbol integer = MSymbol.Of ("integer"); - public static MSymbol nil = new MSymbol ("nil"); - public static MSymbol t = new MSymbol ("t"); - public static MSymbol symbol = new MSymbol ("symbol"); - public static MSymbol mtext = new MSymbol ("mtext"); - public static MSymbol plist = new MSymbol ("plist"); - public static MSymbol integer = new MSymbol ("integer"); + private MSymbol (string name) + { + Name = name; + } - public MSymbol (string name) + public static MSymbol Of (string name) { - if (! pool.ContainsKey (name)) + lock (pool) { - data = new MSymbolData (name, MTextProperty.Flags.None); - pool.Add (name, data); + MSymbol sym; + + if (! pool.TryGetValue (name, out sym)) + { + sym = new MSymbol (name); + pool[name] = sym; + } + return sym; } - else - data = (MSymbolData) pool[name]; } - public MSymbol (string name, MTextProperty.Flags flags) + public static MSymbol PropertyKey (string name) { - if (! pool.ContainsKey (name)) - { - data = new MSymbolData (name, flags); - pool.Add (name, data); - } - else - { - if (((MSymbolData) pool[name]).Flags != flags) - throw new ArgumentException ("Invalid MTextProperty.Flags"); - } + MSymbol sym = MSymbol.Of (name); + + if (sym.flags == null) + sym.flags = MProperty.Flags.None;; + return sym; } - public MTextProperty.Flags TextPropertyFlags { get { return data.Flags; } } + public static MSymbol PropertyKey (string name, MProperty.Flags flags) + { + MSymbol sym = MSymbol.Of (name); + + if (sym.flags == null) + sym.flags = flags; + else if (sym.flags != flags) + throw new Exception ("Flags of PropertyKey mismatch"); + return sym; + } public override string ToString () { string str = ""; - foreach (char c in data.Name) + foreach (char c in Name) { if (c == '\\' || c == ' ' || c == '\'' || c == '\"' || c == ':') str += "\\"; @@ -71,47 +73,21 @@ namespace M17N.Core return str; } - public static bool operator== (MSymbol sym1, MSymbol sym2) - { - if (System.Object.ReferenceEquals(sym1, sym2)) - return true; - if (((object) sym1 == null) || ((object) sym2 == null)) - return false; - return sym1.data == sym2.data; - } - - public static bool operator!= (MSymbol sym1, MSymbol sym2) - { - return ! (sym1 == sym2); - } - - public override bool Equals (object sym) - { - if (sym == null) - return false; - return (this.data == ((MSymbol) sym).data); - } - - public override int GetHashCode () - { - return (data.Name.GetHashCode ()); - } - public MPlist Find (MSymbol key) { - return (data.Plist == null ? null : data.Plist.Find (key)); + return (Plist == null ? null : Plist.Find (key)); } public object Get (MSymbol key) { - return (data.Plist == null ? null : data.Plist.Get (key)); + return (Plist == null ? null : Plist.Get (key)); } public object Put (MSymbol key, object val) { - if (data.Plist == null) - data.Plist = new MPlist (); - return data.Plist.Put (key, val); + if (Plist == null) + Plist = new MPlist (); + return Plist.Put (key, val); } } } diff --git a/MText.cs b/MText.cs index c861720..5c9c778 100644 --- a/MText.cs +++ b/MText.cs @@ -19,7 +19,7 @@ namespace M17N.Core } #endif - public class MTextProperty + public class MProperty { [FlagsAttribute] public enum Flags @@ -37,10 +37,13 @@ namespace M17N.Core RearSticky = 2, /// This property is deleted from a span of text if the span is /// modified (i.e. a character is changed, a text is inserted, - /// some part is deleted). If this property is also FrontSticky - /// (or RearSticky), text insertion just before (or after) the - /// span also deletes this property from the span of text. - Sensitive = 4 + /// some part is deleted). This propery is also deleted if a + /// property of the same key is added, which means that this + /// property is not stackable. If this property is also + /// FrontSticky (or RearSticky), text insertion just before (or + /// after) the span also deletes this property from the span of + /// text. + Sensitive = 4, }; internal MSymbol key; @@ -49,12 +52,20 @@ namespace M17N.Core public MSymbol Key { get { return key; } } public object Val { get { return val; } } - public MTextProperty (MSymbol key, object val) + public MProperty (MSymbol key, object val) { + if (key.flags == null) + key.flags = MProperty.Flags.None; this.key = key; this.val = val; } + public MProperty (string name, object val) + { + key = MSymbol.PropertyKey (name); + this.val = val; + } + public override string ToString () { return key.ToString () + ":" + val; @@ -263,10 +274,11 @@ namespace M17N.Core return; foreach (MPlist plist in intervals) { + MInterval root = (MInterval) plist.Val; MPlist p = mt2.intervals.Find (plist.Key); MInterval i = p == null ? null : (MInterval) p.Val; - ((MInterval) plist.Val).Insert (pos, i, from, to); + root.Insert (pos, i, from, to); } foreach (MPlist plist in mt2.intervals) if (intervals.Find (plist.Key) == null) @@ -399,7 +411,12 @@ namespace M17N.Core if (nchars > 0) foreach (MPlist plist in intervals) - ((MInterval) plist.Val).Delete (from, to); + { + MInterval root = (MInterval) plist.Val; + root.Delete (from, to); + if (from > 0 && from < nchars) + root.MergeAfterChange (from, from); + } else intervals.Clear (); if (M17n.debug) @@ -415,11 +432,11 @@ namespace M17N.Core if (i == null) return null; - MTextProperty prop = i.Get (pos); + MProperty prop = i.Get (pos); return (prop != null ? prop.Val : null); } - public object GetProp (int pos, MSymbol key, out MTextProperty prop) + public object GetProp (int pos, MSymbol key, out MProperty prop) { check_pos (pos, false); @@ -430,24 +447,24 @@ namespace M17N.Core return (prop != null ? prop.Val : null); } - public object GetProp (int pos, MSymbol key, out MTextProperty[] array) + public object GetProp (int pos, MSymbol key, out MProperty[] array) { check_pos (pos, false); MInterval i = (MInterval) intervals.Get (key); if (i == null) return (array = null); - MTextProperty prop = i.Get (pos, out array); + MProperty prop = i.Get (pos, out array); return (prop != null ? prop.Val : null); } public void PushProp (int from, int to, MSymbol key, object val) { if (! check_range (from, to, true)) - PushProp (from, to, new MTextProperty (key, val)); + PushProp (from, to, new MProperty (key, val)); } - public void PushProp (int from, int to, MTextProperty prop) + public void PushProp (int from, int to, MProperty prop) { if (from < 0) { @@ -471,7 +488,11 @@ namespace M17N.Core else root = (MInterval) p.Val; + if (root.isSensitive) + root.PopSensitive (from, to); root.Push (from, to, prop); + root.MergeAfterChange (from, to); + root.Balance (); } } @@ -496,8 +517,12 @@ namespace M17N.Core if (p != null) { MInterval root = (MInterval) p.Val; - root.Pop (from, to); + if (root.isSensitive) + root.PopSensitive (from, to); + else + root.Pop (from, to); root.MergeAfterChange (from, to); + root.Balance (); } } } @@ -561,19 +586,17 @@ namespace M17N.Core } /// POS must be smaller than Length; - public MTextProperty Get (int pos) + public MProperty Get (int pos) { - MInterval i = find (pos); + MInterval i = find_head (pos); - if (i.To == pos) - i = i.Next; - return (i.Stack.IsEmpty ? null : (MTextProperty) i.Stack.Val); + return (i.Stack.IsEmpty ? null : (MProperty) i.Stack.Val); } /// POS must be smaller than Length; - public MTextProperty Get (int pos, out MTextProperty[] array) + public MProperty Get (int pos, out MProperty[] array) { - MInterval i = find (pos); + MInterval i = find_head (pos); if (i.To == pos) i = i.Next; @@ -582,12 +605,12 @@ namespace M17N.Core array = null; return null; } - array = new MTextProperty[i.Stack.Count]; + array = new MProperty[i.Stack.Count]; int idx; MPlist p; for (idx = 0, p = i.Stack; ! p.IsEmpty; idx++, p = p.Next) - array[idx] = (MTextProperty) p.Val; + array[idx] = (MProperty) p.Val; return array[0]; } @@ -604,20 +627,20 @@ namespace M17N.Core private bool isRearSticky { - get { return ((Key.TextPropertyFlags & MTextProperty.Flags.RearSticky) - != MTextProperty.Flags.None); } + get { return ((Key.flags & MProperty.Flags.RearSticky) + != MProperty.Flags.None); } } private bool isFrontSticky { - get { return ((Key.TextPropertyFlags & MTextProperty.Flags.FrontSticky) - != MTextProperty.Flags.None); } + get { return ((Key.flags & MProperty.Flags.FrontSticky) + != MProperty.Flags.None); } } - private bool isSensitive + public bool isSensitive { - get { return ((Key.TextPropertyFlags & MTextProperty.Flags.Sensitive) - != MTextProperty.Flags.None); } + get { return ((Key.flags & MProperty.Flags.Sensitive) + != MProperty.Flags.None); } } private void update_from_to () @@ -709,13 +732,23 @@ namespace M17N.Core } } - private MInterval find (int pos) + private MInterval find_head (int pos) { update_from_to (); if (pos < From) - return Left.find (pos); + return Left.find_head (pos); + if (pos >= To) + return Right.find_head (pos); + return this; + } + + private MInterval find_tail (int pos) + { + update_from_to (); + if (pos <= From) + return Left.find_tail (pos); if (pos > To) - return Right.find (pos); + return Right.find_tail (pos); return this; } @@ -736,29 +769,30 @@ namespace M17N.Core // c1 c2 left c1 private MInterval promote_right () { - int right_length = Right.Length; - MInterval c1; + MInterval c1 = Right.Left; + // Update Parent. if (Parent == null) mtext.intervals.Put (Key, Right); else if (Parent.Left == this) Parent.Left = Right; else Parent.Right = Right; + + // Update Right. Right.Parent = Parent; - c1 = Right.Left; Right.Left = this; + Right.Length += LeftLength + (To - From); + // Update this. Parent = Right; Right = c1; - Parent.Length += Length; - Length -= right_length; + Length = LeftLength + (To - From) + RightLength; + + // Update C1 if necessary. if (c1 != null) - { - c1.Parent = this; - Parent.Length -= c1.Length; - Length += c1.Length; - } + c1.Parent = this; + return Parent; } @@ -768,33 +802,34 @@ namespace M17N.Core // c1 c2 c2 right private MInterval promote_left () { - int left_length = Left.Length; - MInterval c1; + MInterval c2 = Left.Right; + // Update Parent. if (Parent == null) mtext.intervals.Put (Key, Left); else if (Parent.Left == this) Parent.Left = Left; else Parent.Right = Left; + + // Update Left. Left.Parent = Parent; - c1 = Left.Left; Left.Right = this; + Left.Length += (To - From) + RightLength; + // Update this. Parent = Left; - Left = c1; - Parent.Length += Length; - Length -= left_length; - if (c1 != null) - { - c1.Parent = this; - Parent.Length -= c1.Length; - Length += c1.Length; - } + Left = c2; + Length = LeftLength + (To - From) + RightLength; + + // Update C2 if necessary. + if (c2 != null) + c2.Parent = this; + return Parent; } - private MInterval balance () + public MInterval Balance () { MInterval i = this; @@ -812,8 +847,10 @@ namespace M17N.Core + i.Left.RightLength - i.Left.LeftLength); if (Math.Abs (new_diff) >= diff) break; + M17n.DebugPrint ("balancing #{0} by promoting left...", i.ID); i = i.promote_left (); - i.Right.balance (); + M17n.DebugPrint ("done\n"); + i.Right.Balance (); } else if (diff < 0) { @@ -821,9 +858,12 @@ namespace M17N.Core + i.Right.LeftLength - i.Right.RightLength); if (Math.Abs (new_diff) >= diff) break; + M17n.DebugPrint ("balancing #{0} by promoting right\n", i.ID); i = i.promote_right (); - i.Left.balance (); + i.Left.Balance (); } + else + break; } return i; } @@ -939,10 +979,8 @@ namespace M17N.Core len = Stack.IsEmpty ? end - start : 0; else { - MInterval i = interval.find (start); + MInterval i = interval.find_head (start); - if (i.To == start && i.Right != null) - i = i.Next; len = 0; while (i != null && mergeable (i)) { @@ -975,10 +1013,8 @@ namespace M17N.Core len = Stack.IsEmpty ? end - start : 0; else { - MInterval i = interval.find (end); + MInterval i = interval.find_tail (end); - if (i.From == end && i.Left != null) - i = i.Prev; len = 0; while (i != null && mergeable (i)) { @@ -1217,7 +1253,7 @@ namespace M17N.Core } } - public void Push (int start, int end, MTextProperty prop) + public void Push (int start, int end, MProperty prop) { update_from_to (); M17n.DebugPrint ("push({0} {1}) at ", start, end); DumpOne (false, true); @@ -1304,18 +1340,13 @@ namespace M17N.Core public void MergeAfterChange (int start, int end) { update_from_to (); - if (start < From) - { - Prev.MergeAfterChange (start, end); - return; - } - MInterval head = this, tail = this, i; + MInterval head = find_head (start), tail = head, i; - if (start == From && start > 0) + if (start == head.From && start > 0) { - i = Prev; - if (mergeable (i)) + i = head.Prev; + if (head.mergeable (i)) head = i; } while (tail.To < end) @@ -1375,6 +1406,30 @@ namespace M17N.Core } } + public void PopSensitive (int start, int end) + { + update_from_to (); + MInterval head = find_head (start); + MInterval tail = find_tail (end); + while (! head.Stack.IsEmpty && head.From > 0) + { + MInterval prev = head.Prev; + + if (prev.Stack.IsEmpty || head.Stack.Val != prev.Stack.Val) + break; + head = head.Prev; + } + while (! tail.Stack.IsEmpty && tail.To < mtext.Length) + { + MInterval next = tail.Next; + + if (next.Stack.IsEmpty || tail.Stack.Val != next.Stack.Val) + break; + tail = tail.Next; + } + Pop (head.From, tail.To); + } + private void DumpOne (bool with_prop, bool newline) { DumpOne (with_prop, newline, false); diff --git a/plist.cs b/plist.cs index 249f179..2b70511 100644 --- a/plist.cs +++ b/plist.cs @@ -8,8 +8,8 @@ public class Test { public static void Main() { - MSymbol sym1 = new MSymbol ("sym1"); - MSymbol sym2 = new MSymbol ("sym2"); + MSymbol sym1 = MSymbol.Of ("sym1"); + MSymbol sym2 = MSymbol.Of ("sym2"); MPlist plist = new MPlist (); MText mt1 = new MText ("abc"); MText mt2 = new MText ("ABC"); @@ -31,7 +31,7 @@ public class Test } plist = new MPlist (); - plist.Push (new MSymbol ("abc")); + plist.Push (MSymbol.Of ("abc")); plist.Push (new MText ("abc")); plist.Push (new MPlist ()); plist.Push (123); diff --git a/symbol.cs b/symbol.cs index f672b09..32be8e3 100644 --- a/symbol.cs +++ b/symbol.cs @@ -7,9 +7,9 @@ public class Test { public static void Main() { - MSymbol sym1 = new MSymbol ("symbol"); - MSymbol sym2 = new MSymbol ("symbol"); - MSymbol sym3 = new MSymbol ("another sym:bol"); + MSymbol sym1 = MSymbol.Of ("symbol"); + MSymbol sym2 = MSymbol.Of ("symbol"); + MSymbol sym3 = MSymbol.Of ("another sym:bol"); Console.WriteLine ("version {0}-{1}-{2}", M17n.MajorVersion, M17n.MinorVersion, M17n.ReleaseNumber); @@ -26,12 +26,13 @@ public class Test Console.WriteLine (sym2.Get (sym2) + "," + sym2.Get (sym3)); Console.WriteLine (sym3.Get (sym2)); - MSymbol sym4; + MSymbol sym4 = MSymbol.PropertyKey ("symbol"); try { - sym4 = new MSymbol ("symbol", MTextProperty.Flags.Sensitive); + sym4 = MSymbol.PropertyKey ("symbol", MProperty.Flags.Sensitive); } catch { - Console.WriteLine ("MTextProperty.Flags mismatch"); + Console.WriteLine ("MProperty.Flags mismatch"); } - sym4 = new MSymbol ("sensitive", MTextProperty.Flags.Sensitive); + sym4 = MSymbol.PropertyKey ("symbol", MProperty.Flags.None); + sym4 = MSymbol.PropertyKey ("symbol"); } } diff --git a/textprop.cs b/textprop.cs index 391e113..a184c94 100644 --- a/textprop.cs +++ b/textprop.cs @@ -8,13 +8,13 @@ public class Test const int LENGTH = 10; const int DEPTH = 10; static MText mt = new MText ("0123456789"); - static MSymbol key = new MSymbol ("k"); - static MSymbol val0 = new MSymbol ("0"); - static MSymbol val1 = new MSymbol ("1"); - static MSymbol val2 = new MSymbol ("2"); - static MTextProperty prop0 = new MTextProperty (key, val0); - static MTextProperty prop1 = new MTextProperty (key, val1); - static MTextProperty prop2 = new MTextProperty (key, val2); + static MSymbol key = MSymbol.Of ("k"); + static MSymbol val0 = MSymbol.Of ("0"); + static MSymbol val1 = MSymbol.Of ("1"); + static MSymbol val2 = MSymbol.Of ("2"); + static MProperty prop0 = new MProperty (key, val0); + static MProperty prop1 = new MProperty (key, val1); + static MProperty prop2 = new MProperty (key, val2); static int[] nvals = new int[LENGTH]; static MSymbol[,] valtable = new MSymbol[LENGTH, DEPTH + 1]; @@ -36,7 +36,7 @@ public class Test mt.PushProp (from, to, key, val); } - static void TestPushProp (int from, int to, MTextProperty prop) + static void TestPushProp (int from, int to, MProperty prop) { for (int i = from; i < to; i++) if (nvals[i] == DEPTH) @@ -113,7 +113,7 @@ public class Test { for (int i = 0; i < LENGTH; i++) { - MTextProperty[] array; + MProperty[] array; object val = mt.GetProp (i, key, out array); if (array == null) @@ -232,8 +232,8 @@ public class Test break; } - MTextProperty prop; - //MTextProperty prop = r.Next (2) == 0 ? prop0 : prop1; + MProperty prop; + //MProperty prop = r.Next (2) == 0 ? prop0 : prop1; switch (r.Next (3)) { case 0: @@ -263,9 +263,11 @@ public class Test break; } + if (M17n.debug) + mt.DumpPropNested (); + if (Compare () == false) { - mt.DumpPropNested (); Console.WriteLine (""); Dump (); Console.WriteLine ("Failed."); -- 1.7.10.4