C# version of m17n-lib
[m17n/m17n-lib-cs.git] / MSymbol.cs
1 using System;
2 using M17N;
3
4 namespace M17N
5 {
6   public class MPlist
7   {
8     private MSymbol key;
9     private object val;
10     private MPlist next;
11
12     public MPlist ()
13     {
14       key = null;
15       val = null;
16       next = null;
17     }
18
19     public bool tailp { get { return (object) key == null; } }
20
21     public new string ToString ()
22     {
23       string str = "";
24
25       for (MPlist p = this; ! p.tailp; p = p.next)
26         {
27           str += (p == this ? "(" : " ") + p.key.ToString () + ":";
28           if (p.val is MSymbol)
29             str += ((MSymbol) p.val).ToString ();
30           else if (p.val is MPlist)
31             str += ((MPlist) p.val).ToString ();
32         }
33       return str + ")";
34     }
35
36     public object get (MSymbol key)
37     {
38       if ((object) key == null)
39         return null;
40       for (MPlist p = this; ! p.tailp; p = p.next)
41         if (p.key == key)
42           return p.val;
43       return null;
44     }
45
46     public object put (MSymbol key, object val)
47     {
48       MPlist p;
49
50       for (p = this; ! p.tailp; p = p.next)
51         if (p.key == key)
52           {
53             if (val != null)
54               p.val = val;
55             else
56               p.pop ();
57             return val;
58           }
59       if (val != null)
60         {
61           p.key = key;
62           p.val = val;
63           p.next = new MPlist ();
64         }
65       return val;
66     }
67
68     public object push (MSymbol key, object val)
69     {
70       MPlist p = new MPlist ();
71
72       p.key = this.key;
73       p.val = this.val;
74       p.next = this.next;
75       this.key = key;
76       this.val = val;
77       this.next = p;
78
79       return val;
80     }
81
82     public object pop ()
83     {
84       if (tailp)
85         return null;
86
87       object val = this.val;
88
89       this.key = this.next.key;
90       this.val = this.next.val;
91       this.next = this.next.next;
92       return val;
93     }
94
95     public object add (MSymbol key, object val)
96     {
97       MPlist p;
98
99       for (p = this; ! p.tailp; p = p.next);
100       if (val != null)
101         {
102           p.key = key;
103           p.val = val;
104           p.next = new MPlist ();
105         }
106       return val;
107     }
108   }
109
110   public class MSymbol
111   {
112     internal class MSymbolData
113     {
114       public string name;
115       public MPlist plist;
116       public MSymbolData next;
117
118       public MSymbolData (string name, MSymbolData next)
119       {
120         this.name = name;
121         this.next = next;
122       }
123     }
124
125     static internal class MSymbolPool
126     {
127       const int MSYMBOL_POOL_SIZE = 1024;
128       static MSymbolData[] pool = new MSymbolData[MSYMBOL_POOL_SIZE];
129       static int[] used = new int[MSYMBOL_POOL_SIZE];
130       
131       static public MSymbolData get_data (string name)
132       {
133         MSymbolData data;
134
135         if (used[0] > 0)
136           {
137             data = pool[0];
138             for (int i = 0; i < used[0]; i++, data = data.next)
139               if (data.name == name)
140                 return data;
141           }
142         pool[0] = data = new MSymbolData (name, pool[0]);
143         used[0]++;
144         return data;
145       }
146     }
147
148     static public MSymbol nil = new MSymbol ("nil");
149     static public MSymbol t = new MSymbol ("t");
150
151     private MSymbolData data;
152
153     public MSymbol (string name)
154     {
155       data = MSymbolPool.get_data (name);
156     }
157
158     public new string ToString () { return data.name; }
159
160     public new bool Equals (object sym) { return ((object) this == sym); }
161
162     public new int GetHashCode () { return 0; }
163
164     public static bool operator== (MSymbol sym1, MSymbol sym2)
165     {
166       return ((object) sym1.data == (object) sym2.data);
167     }
168
169     public static bool operator!= (MSymbol sym1, MSymbol sym2)
170     {
171       return ((object) sym1.data != (object) sym2.data);
172     }
173
174     public object get (MSymbol key)
175     {
176       return (data.plist == null ? null : data.plist.get (key));
177     }
178
179     public object put (MSymbol key, object val)
180     {
181       if (data.plist == null)
182         data.plist = new MPlist ();
183       return data.plist.put (key, val);
184     }
185   }
186
187   public class MTextProperty
188   {
189   }
190
191   public enum MTextFormat
192   {
193     MTEXT_FORMAT_US_ASCII,
194     MTEXT_FORMAT_UTF_8,
195     MTEXT_FORMAT_UTF_16BE,
196     MTEXT_FORMAT_UTF_16LE,
197     MTEXT_FORMAT_UTF_32BE,
198     MTEXT_FORMAT_UTF_32LE,
199   }
200
201   public class MText
202   {
203     private class MTextPlist : MPlist
204     {
205       public class MInterval
206       {
207         public MPlist stack;
208         public int nprops;
209         public int start, end;
210         public MInterval prev, next;
211       }
212
213       MInterval head, tail;
214
215       public MTextPlist (MText mt)
216       {
217         head = tail = new MInterval ();
218         head.start = 0;
219         head.end = mt.nchars;
220       }
221     }
222
223     private string str;
224     private int nchars;
225     private int nunits;
226     private int cache_pos;
227     private int cache_idx;
228     private MTextPlist plist;
229
230     public MText (byte str, MTextFormat format)
231     {
232       
233     }
234   }
235
236
237   public class Test
238   {
239     public static void Main()
240     {
241       MSymbol sym1, sym2;
242
243       sym1 = new MSymbol ("abc");
244       Console.WriteLine (sym1.ToString ());
245       sym2 = new MSymbol ("abc");
246       Console.WriteLine (sym2.ToString ());
247       Console.WriteLine (sym1 == sym2 ? "OK" : "NO");
248       sym1.put (MSymbol.nil, MSymbol.t);
249
250       MPlist p = new MPlist ();
251
252       p.put (MSymbol.t, sym1);
253       p.push (MSymbol.t, sym2);
254
255       MPlist pp = new MPlist ();
256       pp.put (MSymbol.t, p);
257       Console.WriteLine (pp.ToString ());
258       Console.WriteLine (p.get (MSymbol.t));
259     }
260   }
261 }