From: handa Date: Wed, 5 Aug 2009 14:32:33 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=c25c3228ff23992a3c4f58f83f10af1252de732d;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MExpression.cs b/MExpression.cs index 560a6b1..f482088 100644 --- a/MExpression.cs +++ b/MExpression.cs @@ -9,7 +9,8 @@ namespace M17N.Core { public class MExpression { - public delegate object Evaluator (object[] args, MPlist bindings); + public delegate object Evaluator (object[] args, MPlist bindings, + object context); internal delegate void PrettyPrinter (Function func, string indent, object[] args); @@ -114,20 +115,21 @@ namespace M17N.Core return slot; } - public object Call (object[] args, MPlist bindings) + public object Call (object[] args, MPlist bindings, object context) { if (name == MSymbol.nil) return args[0]; if (eval != null) - return eval (args, bindings); + return eval (args, bindings, context); MPlist arg_symbols = (MPlist) data[0]; for (int i = 0; i < args.Length; i++, arg_symbols = arg_symbols.next) bindings = bindings.Cons (arg_symbols.Symbol, - ((MExpression) args[i]).Eval (bindings)); + ((MExpression) args[i]).Eval (bindings, + context)); object result = 0; for (int i = 1; i < data.Length; i++) - result = ((MExpression) data[i]).Eval (bindings); + result = ((MExpression) data[i]).Eval (bindings, context); return result; } @@ -156,96 +158,106 @@ namespace M17N.Core Console.Write (")"); } - private static object get_value (object[] args, MPlist bindings) + private static object get_value (object[] args, MPlist bindings, + object context) { return find_binding (args, bindings).val; } - private static object set_value (object[] args, MPlist bindings) + private static object set_value (object[] args, MPlist bindings, + object context) { MSymbol var = (MSymbol) args[0]; MPlist slot = bindings.Find (var); if (slot == null) slot = bindings.Push (var, null); - slot.val = ((MExpression) args[1]).Eval (bindings); + slot.val = ((MExpression) args[1]).Eval (bindings, context); if (slot.val is MText) slot.val = ((MText) slot.val).Dup (); return slot.val; } - private static object plus (object[] args, MPlist bindings) + private static object plus (object[] args, MPlist bindings, + object context) { - object val = ((MExpression) args[0]).Eval (bindings); + object val = ((MExpression) args[0]).Eval (bindings, context); if (val is int) { int n = 0; foreach (MExpression e in args) - n += (int) e.Eval (bindings); + n += (int) e.Eval (bindings, context); val = n; } else if (val is MText) { MText mt = new MText (); foreach (MExpression e in args) - mt += (MText) e.Eval (bindings); + mt += (MText) e.Eval (bindings, context); val = mt; } return val; } - private static object multi (object[] args, MPlist bindings) + private static object multi (object[] args, MPlist bindings, + object context) { int n = 1; foreach (MExpression e in args) - n *= (int) e.Eval (bindings); + n *= (int) e.Eval (bindings, context); return n; } - private static object minus (object[] args, MPlist bindings) + private static object minus (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); if (args.Length == 1) return - n; for (int i = 1; i < args.Length; i++) - n -= (int) ((MExpression) args[i]).Eval (bindings); + n -= (int) ((MExpression) args[i]).Eval (bindings, context); return n; } - private static object divide (object[] args, MPlist bindings) + private static object divide (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); for (int i = 1; i < args.Length; i++) - n /= (int) ((MExpression) args[i]).Eval (bindings); + n /= (int) ((MExpression) args[i]).Eval (bindings, context); return n; } - private static object percent (object[] args, MPlist bindings) + private static object percent (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); for (int i = 1; i < args.Length; i++) - n %= (int) ((MExpression) args[i]).Eval (bindings); + n %= (int) ((MExpression) args[i]).Eval (bindings, context); return n; } - private static object logior (object[] args, MPlist bindings) + private static object logior (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); for (int i = 1; i < args.Length; i++) - n |= (int) ((MExpression) args[i]).Eval (bindings); + n |= (int) ((MExpression) args[i]).Eval (bindings, context); return n; } - private static object logand (object[] args, MPlist bindings) + private static object logand (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); for (int i = 1; i < args.Length; i++) - n &= (int) ((MExpression) args[i]).Eval (bindings); + n &= (int) ((MExpression) args[i]).Eval (bindings, context); return n; } - private static object pluseq (object[] args, MPlist bindings) + private static object pluseq (object[] args, MPlist bindings, + object context) { MPlist slot = find_binding (args, bindings); object val = slot.val; @@ -254,124 +266,137 @@ namespace M17N.Core { int n = (int) val; for (int i = 1; i < args.Length; i++) - n += (int) ((MExpression) args[i]).Eval (bindings); + n += (int) ((MExpression) args[i]).Eval (bindings, context); slot.val = n; } else if (val is MText) { MText mt = (MText) val; for (int i = 1; i < args.Length; i++) - mt.Cat ((MText) ((MExpression) args[i]).Eval (bindings)); + mt.Cat ((MText) ((MExpression) args[i]).Eval (bindings, context)); } return slot.val; } - private static object multieq (object[] args, MPlist bindings) + private static object multieq (object[] args, MPlist bindings, + object context) { MPlist slot = find_binding (args, bindings); int n = (int) slot.val; for (int i = 1; i < args.Length; i++) - n *= (int) ((MExpression) args[i]).Eval (bindings); + n *= (int) ((MExpression) args[i]).Eval (bindings, context); return (slot.val = n); } - private static object minuseq (object[] args, MPlist bindings) + private static object minuseq (object[] args, MPlist bindings, + object context) { MPlist slot = find_binding (args, bindings); int n = (int) slot.val; for (int i = 1; i < args.Length; i++) - n -= (int) ((MExpression) args[i]).Eval (bindings); + n -= (int) ((MExpression) args[i]).Eval (bindings, context); return (slot.val = n); } - private static object divideeq (object[] args, MPlist bindings) + private static object divideeq (object[] args, MPlist bindings, + object context) { MPlist slot = find_binding (args, bindings); int n = (int) slot.val; for (int i = 1; i < args.Length; i++) - n /= (int) ((MExpression) args[i]).Eval (bindings); + n /= (int) ((MExpression) args[i]).Eval (bindings, context); return (slot.val = n); } - private static object percenteq (object[] args, MPlist bindings) + private static object percenteq (object[] args, MPlist bindings, + object context) { MPlist slot = find_binding (args, bindings); int n = (int) slot.val; for (int i = 1; i < args.Length; i++) - n %= (int) ((MExpression) args[i]).Eval (bindings); + n %= (int) ((MExpression) args[i]).Eval (bindings, context); return (slot.val = n); } - private static object logioreq (object[] args, MPlist bindings) + private static object logioreq (object[] args, MPlist bindings, + object context) { MPlist slot = find_binding (args, bindings); int n = (int) slot.val; for (int i = 1; i < args.Length; i++) - n |= (int) ((MExpression) args[i]).Eval (bindings); + n |= (int) ((MExpression) args[i]).Eval (bindings, context); return (slot.val = n); } - private static object logandeq (object[] args, MPlist bindings) + private static object logandeq (object[] args, MPlist bindings, + object context) { MPlist slot = find_binding (args, bindings); int n = (int) slot.val; for (int i = 1; i < args.Length; i++) - n &= (int) ((MExpression) args[i]).Eval (bindings); + n &= (int) ((MExpression) args[i]).Eval (bindings, context); return (slot.val = n); } - private static object lshift (object[] args, MPlist bindings) + private static object lshift (object[] args, MPlist bindings, + object context) { - int n1 = (int) ((MExpression) args[0]).Eval (bindings); - int n2 = (int) ((MExpression) args[1]).Eval (bindings); + int n1 = (int) ((MExpression) args[0]).Eval (bindings, context); + int n2 = (int) ((MExpression) args[1]).Eval (bindings, context); return n1 << n2; } - private static object lshifteq (object[] args, MPlist bindings) + private static object lshifteq (object[] args, MPlist bindings, + object context) { MPlist slot = find_binding (args, bindings); int n1 = (int) slot.val; - int n2 = (int) ((MExpression) args[1]).Eval (bindings); + int n2 = (int) ((MExpression) args[1]).Eval (bindings, context); return (slot.val = (n1 << n2)); } - private static object rshift (object[] args, MPlist bindings) + private static object rshift (object[] args, MPlist bindings, + object context) { - int n1 = (int) ((MExpression) args[0]).Eval (bindings); - int n2 = (int) ((MExpression) args[1]).Eval (bindings); + int n1 = (int) ((MExpression) args[0]).Eval (bindings, context); + int n2 = (int) ((MExpression) args[1]).Eval (bindings, context); return n1 >> n2; } - private static object rshifteq (object[] args, MPlist bindings) + private static object rshifteq (object[] args, MPlist bindings, + object context) { MPlist slot = find_binding (args, bindings); int n1 = (int) slot.val; - int n2 = (int) ((MExpression) args[1]).Eval (bindings); + int n2 = (int) ((MExpression) args[1]).Eval (bindings, context); return (slot.val = (n1 >> n2)); } - private static object eq (object[] args, MPlist bindings) + private static object eq (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); for (int i = 1; i < args.Length; i++) - if (n != (int) ((MExpression) args[i]).Eval (bindings)) + if (n != (int) ((MExpression) args[i]).Eval (bindings, context)) return 0; return 1; } - private static object noteq (object[] args, MPlist bindings) + private static object noteq (object[] args, MPlist bindings, + object context) { - int n1 = (int) ((MExpression) args[0]).Eval (bindings); - int n2 = (int) ((MExpression) args[1]).Eval (bindings); + int n1 = (int) ((MExpression) args[0]).Eval (bindings, context); + int n2 = (int) ((MExpression) args[1]).Eval (bindings, context); return (n1 != n2); } - private static object less (object[] args, MPlist bindings) + private static object less (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); for (int i = 1; i < args.Length; i++) { - int n1 = (int) ((MExpression) args[i]).Eval (bindings); + int n1 = (int) ((MExpression) args[i]).Eval (bindings, context); if (n >= n1) return 0; n = n1; @@ -379,12 +404,13 @@ namespace M17N.Core return 1; } - private static object lesseq (object[] args, MPlist bindings) + private static object lesseq (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); for (int i = 1; i < args.Length; i++) { - int n1 = (int) ((MExpression) args[i]).Eval (bindings); + int n1 = (int) ((MExpression) args[i]).Eval (bindings, context); if (n > n1) return 0; n = n1; @@ -392,12 +418,13 @@ namespace M17N.Core return 1; } - private static object more (object[] args, MPlist bindings) + private static object more (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); for (int i = 1; i < args.Length; i++) { - int n1 = (int) ((MExpression) args[i]).Eval (bindings); + int n1 = (int) ((MExpression) args[i]).Eval (bindings, context); if (n <= n1) return 0; n = n1; @@ -405,12 +432,13 @@ namespace M17N.Core return 1; } - private static object moreeq (object[] args, MPlist bindings) + private static object moreeq (object[] args, MPlist bindings, + object context) { - int n = (int) ((MExpression) args[0]).Eval (bindings); + int n = (int) ((MExpression) args[0]).Eval (bindings, context); for (int i = 1; i < args.Length; i++) { - int n1 = (int) ((MExpression) args[i]).Eval (bindings); + int n1 = (int) ((MExpression) args[i]).Eval (bindings, context); if (n < n1) return 0; n = n1; @@ -418,12 +446,13 @@ namespace M17N.Core return 1; } - private static object progn (object[] args, MPlist bindings) + private static object progn (object[] args, MPlist bindings, + object context) { object result = null; foreach (MExpression e in args) - result = e.Eval (bindings); + result = e.Eval (bindings, context); return result; } @@ -445,20 +474,22 @@ namespace M17N.Core Console.Write (")"); } - private static bool check_condition (MExpression e, MPlist bindings) + private static bool check_condition (MExpression e, MPlist bindings, + object context) { - object result = e.Eval (bindings); + object result = e.Eval (bindings, context); return (! (result is int) || (int) result != 0); } - private static object cond (object[] args, MPlist bindings) + private static object cond (object[] args, MPlist bindings, + object context) { foreach (MExpression[] elist in args) - if (check_condition (elist[0], bindings)) + if (check_condition (elist[0], bindings, context)) { object result = 0; for (int i = 1; i < elist.Length; i++) - result = elist[i].Eval (bindings); + result = elist[i].Eval (bindings, context); return result; } return 0; @@ -486,15 +517,16 @@ namespace M17N.Core Console.Write (")"); } - private static object ifclause (object[] args, MPlist bindings) + private static object ifclause (object[] args, MPlist bindings, + object context) { object result = 0; - if (check_condition ((MExpression) args[0], bindings)) - result = ((MExpression) args[1]).Eval (bindings); + if (check_condition ((MExpression) args[0], bindings, context)) + result = ((MExpression) args[1]).Eval (bindings, context); else for (int i = 2; i < args.Length; i++) - result = ((MExpression) args[i]).Eval (bindings); + result = ((MExpression) args[i]).Eval (bindings, context); return result; } @@ -514,13 +546,14 @@ namespace M17N.Core Console.Write (")"); } - private static object whileclause (object[] args, MPlist bindings) + private static object whileclause (object[] args, MPlist bindings, + object context) { object result = 0; - while (check_condition ((MExpression) args[0], bindings)) + while (check_condition ((MExpression) args[0], bindings, context)) for (int i = 1; i < args.Length; i++) - result = ((MExpression) args[i]).Eval (bindings); + result = ((MExpression) args[i]).Eval (bindings, context); return result; } @@ -545,7 +578,8 @@ namespace M17N.Core Console.Write (")"); } - public static object define_function (object[] args, MPlist bindings) + public static object define_function (object[] args, MPlist bindings, + object context) { FunctionTable table = (FunctionTable) args[0]; MSymbol sym = (MSymbol) args[1]; @@ -631,7 +665,7 @@ namespace M17N.Core args[1] = name; args[2] = new MPlist (); args[3] = expr; - Function.define_function (args, null); + Function.define_function (args, null, null); } private static Function Defun (string name, Evaluator evaluator, @@ -794,7 +828,7 @@ namespace M17N.Core args[i++] = p.val; } if (function == Function.defun) - function.Call (args, null); + function.Call (args, null, null); } public MExpression (MSymbol sym) @@ -811,9 +845,9 @@ namespace M17N.Core args[0] = obj; } - public object Eval (MPlist bindings) + public object Eval (MPlist bindings, object context) { - return function.Call (args, bindings); + return function.Call (args, bindings, context); } private void pp (string indent) diff --git a/MInputMethod.cs b/MInputMethod.cs index ee0bfae..78f91ff 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -27,7 +27,7 @@ namespace M17N.Input private static MSymbol Mat_plus = MSymbol.Of ("@+"); private static MSymbol Mat_open_square_bracket = MSymbol.Of ("@["); private static MSymbol Mat_close_square_bracket = MSymbol.Of ("@]"); - + private static MSymbol Minsert = MSymbol.Of ("insert"); internal class Variable { @@ -51,7 +51,7 @@ namespace M17N.Input private static MSymbol char_to_symbol (int c) { - return MSymbol.Of (String.Format ("#%X", c)); + return MSymbol.Of (String.Format ("#{0:X}", c)); } public KeySeq (MPlist plist) @@ -96,7 +96,10 @@ namespace M17N.Input else submaps.TryGetValue (keys[index], out sub); if (sub == null) - submaps[keys[index]] = sub = new Map (); + { + MSymbol sym = keys[index]; + submaps[sym] = sub = new Map (); + } if (index + 1 < keys.Length) sub.Add (keys, index + 1, actions); else @@ -123,7 +126,8 @@ namespace M17N.Input = new Dictionary (); } - private static Dictionary im_table; + private static Dictionary im_table + = new Dictionary (); private static MExpression.FunctionTable global_table = new MExpression.FunctionTable (); @@ -151,50 +155,50 @@ namespace M17N.Input { MExpression.Defun (global_table, "insert", new MExpression.Evaluator (insert), - 2, 2, typeof (MInputContext), typeof (MExpression)); + 1, 1, typeof (MExpression)); MExpression.Defun (global_table, "candidates", new MExpression.Evaluator (insert_candidates), - 2, 2, typeof (MInputContext), typeof (object)); + 1, 1, typeof (object)); MExpression.Defun (global_table, "delete", new MExpression.Evaluator (delete), - 2, 2, typeof (MInputContext), typeof (object)); + 1, 1, typeof (object)); MExpression.Defun (global_table, "select", new MExpression.Evaluator (select), - 2, 2, typeof (MInputContext), typeof (object)); + 1, 1, typeof (object)); MExpression.Defun (global_table, "show", new MExpression.Evaluator (show), - 1, 1, typeof (MInputContext)); + 0, 0); MExpression.Defun (global_table, "hide", new MExpression.Evaluator (hide), - 1, 1, typeof (MInputContext)); + 0, 0); MExpression.Defun (global_table, "move", new MExpression.Evaluator (move), - 2, 2, typeof (MInputContext), typeof (object)); + 1, 1, typeof (object)); MExpression.Defun (global_table, "mark", new MExpression.Evaluator (mark), - 2, 2, typeof (MInputContext), typeof (MSymbol)); + 1, 1, typeof (MSymbol)); MExpression.Defun (global_table, "pushback", new MExpression.Evaluator (pushback), - 2, 2, typeof (MInputContext), typeof (object)); + 1, 1, typeof (object)); MExpression.Defun (global_table, "pop", new MExpression.Evaluator (pop), - 1, 1, typeof (MInputContext)); + 0, 0); MExpression.Defun (global_table, "undo", new MExpression.Evaluator (undo), - 2, 2, typeof (MInputContext), typeof (object)); + 0, 1, typeof (object)); MExpression.Defun (global_table, "commit", new MExpression.Evaluator (commit), - 1, 1, typeof (MInputContext)); + 0, 0); MExpression.Defun (global_table, "unhandle", new MExpression.Evaluator (unhandle), - 1, 1, typeof (MInputContext)); + 0, 0); MExpression.Defun (global_table, "shift", new MExpression.Evaluator (shift), - 2, 2, typeof (MInputContext), typeof (MSymbol)); + 1, 1, typeof (MSymbol)); MExpression.Defun (global_table, "call", new MExpression.Evaluator (call), - 3, -1, typeof (MInputContext), typeof (MSymbol), - typeof (MSymbol), typeof (object)); + 2, -1, typeof (MSymbol), typeof (MSymbol), + typeof (object)); } private MInputMethod (MDatabase.Tag tag) @@ -311,14 +315,25 @@ namespace M17N.Input { if (! plist.IsPlist) return; - MPlist p = plist.Plist.Cons (MSymbol.symbol, Minput_method); - MDatabase.Tag tag = new MDatabase.Tag (ref p); - MInputMethod im; - try { - im_table.TryGetValue (tag, out im); - } catch { + MPlist p = plist.Plist; + MSymbol language, name, extra; + language = p.Symbol; + p = p.next; + if (! p.IsSymbol) + name = extra = MSymbol.nil; + else + { + name = p.Symbol; + p = p.next; + if (! p.IsSymbol) + extra = MSymbol.nil; + else + extra = p.Symbol; + } + + MInputMethod im = MInputMethod.Get (language, name, extra); + if (im == null) return; - } plist = plist.next; if (! plist.IsSymbol) return; @@ -379,6 +394,47 @@ namespace M17N.Input } } + private static void regulalize_command (MPlist plist) + { + if (plist.IsSymbol) + { + MSymbol sym = plist.Symbol; + + if (sym == MSymbol.Of ("add")) + plist.val = MSymbol.Of ("+="); + regulalize_actions (plist.next); + } + } + + private static void regulalize_actions (MPlist plist) + { + for (; ! plist.IsEmpty; plist = plist.next) + { + if (plist.IsMText) + { + MText mt = plist.Text; + MPlist p = new MPlist (); + p.Add (MSymbol.symbol, Minsert); + p.Add (MSymbol.mtext, mt); + plist.key = MSymbol.plist; + plist.val = p; + } + else if (plist.IsInteger) + { + int c = plist.Integer; + MPlist p = new MPlist (); + p.Add (MSymbol.symbol, Minsert); + p.Add (MSymbol.integer, c); + plist.key = MSymbol.plist; + plist.val = p; + } + else if (plist.IsPlist) + { + + } + } + } + private void parse_maps (MPlist plist) { for (; ! plist.IsEmpty; plist = plist.next) @@ -395,20 +451,22 @@ namespace M17N.Input { if (! pl.IsPlist) continue; + MPlist p = pl.Plist; KeySeq keys; - if (pl.IsMText) - keys = new KeySeq (pl.Text); - else if (pl.IsPlist) - keys = new KeySeq (pl.Plist); + if (p.IsMText) + keys = new KeySeq (p.Text); + else if (p.IsPlist) + keys = new KeySeq (p.Plist); else continue; if (keys.keys.Length == 0 && keys.keys[0] == null) continue; - pl = pl.next; - if (pl.IsEmpty) + p = p.next; + if (p.IsEmpty) continue; - MExpression expr = new MExpression (pl, local_table); + regulalize_actions (p); + MExpression expr = new MExpression (p, local_table); map.Add (keys, 0, expr); } } @@ -443,13 +501,18 @@ namespace M17N.Input MPlist p = pl.Plist; if (! p.IsSymbol) continue; - state.branches[p.Symbol] - = new MExpression (p.next, local_table); + MSymbol map_name = p.Symbol; + p = p.next; + if (! p.IsEmpty) + regulalize_actions (p); + state.branches[map_name] + = new MExpression (p, local_table); } } } - public MInputMethod Get (MSymbol language, MSymbol name, MSymbol extra) + public static MInputMethod Get (MSymbol language, MSymbol name, + MSymbol extra) { MDatabase.Tag tag = new MDatabase.Tag (Minput_method, language, name, extra); @@ -458,7 +521,8 @@ namespace M17N.Input return im; try { im = new MInputMethod (tag); - } catch { + } catch (Exception e) { + Console.WriteLine (e); im = null; } return im; @@ -504,10 +568,11 @@ namespace M17N.Input adjust_markers (ic, from, to, mt); } - private static object insert (object[] args, MPlist bindings) + private static object insert (object[] args, MPlist bindings, + object context) { - MInputContext ic = (MInputContext) args[0]; - object arg = ((MExpression) args[1]).Eval (bindings); + MInputContext ic = (MInputContext) context; + object arg = ((MExpression) args[0]).Eval (bindings, ic); if (arg is int) preedit_replace (ic, ic.cursor_pos, ic.cursor_pos, (int) arg); @@ -522,82 +587,87 @@ namespace M17N.Input { private class Block { - public Block Prev, Next; public int Index; public object Data; - public Block (Block prev, int index, MPlist plist) + public Block (int index, MPlist plist) { - Prev = prev; - if (prev != null) - prev.Next = this; Index = index; - Data = plist.IsMText ? plist.Text : plist.Plist; + if (plist.IsMText) + Data = plist.Text; + else + Data = plist.Plist; } public int Count { - get { return (data is MText - ? ((MText) data).Length - : ((MPlist) data).Count); } + get { return (Data is MText + ? ((MText) Data).Length + : ((MPlist) Data).Count); } } - public Block First + public object this[int i] { get { - Block b; - for (b = this; b.Prev != null; b = n.Prev); - return b; + if (Data is MText) return ((MText) Data)[i]; + return ((MPlist) Data)[i]; } } + } - public Block Last - { - get { - Block b; - for (b = this; b.Next != null; b = n.Next); - return b; - } - } + private Block[] blocks; + private int row = 0; + private int index = 0; + public object[] group; - public object this[int i] - { - get { return (data is MText - ? ((MText) data)[i] - : ((MPlist) data)[i]); } - } + private bool IsFixed { get { return group != null; } } + private int Total { + get { + Block last = blocks[blocks.Length - 1]; + return last.Index + last.Count; } } - private Block block; - private int current_index = -1; - private int total_count = 0; - private object[] group = null; + public int Column { + get { return (IsFixed ? index % group.Length + : index - blocks[row].Index); } + } - public Candidates (MPlist list, int column) - { - if (column > 0) - group = new object[column]; - Block b = null; - int index; - for (index = 0; ! list.IsEmpty; list = list.next) - { - b = new Block (b, index, list); - if (index == 0) - block = b; - index += b.Count; - } - total_count = index; + public object Group { + get { return (IsFixed ? group : blocks[row].Data); } } - public int InGroupIndex + public int GroupLength { get { - return (group == null - ? current_index - block.Index - : current_index % group.Length); + if (IsFixed) + { + int nitems = group.Length; + int start = index - (index % nitems); + int total = Total; + return (start + nitems <= total ? nitems : total - start); + } + return blocks[row].Count; } } + public object Current { + get { + return (IsFixed ? group[index % group.Length] + : blocks[row][index - blocks[row].Index]); + } + } + + public Candidates (MPlist list, int column) + { + int nblocks = list.Count; + + blocks = new Block[nblocks]; + for (int i = 0, start = 0; i < nblocks; i++, list = list.next) + start += (blocks[i] = new Block (index, list)).Count; + if (column > 0) + group = new object[column]; + } + public static void Detach (MInputContext ic) { ic.preedit.PopProp (0, ic.preedit.Length, Mcandidates); @@ -612,208 +682,137 @@ namespace M17N.Input // number of valid candidates in "group". Update "block" if // necessary. Return "group". - private object fill_group (int index, out int nitems) + private int fill_group (int start) { - int column = group.Length; + int nitems = group.Length; + int r = row; + Block b = blocks[r]; - if (index > block.Index + column) - block = block.Last; - while (index < block.Index) - block = block.Prev; + if (start < b.Index) + while (start < b.Index) + b = blocks[--r]; + else + while (start >= b.Index + b.Count) + b = blocks[++r]; + row = r; - Block b = block; int count = b.Count; - int inblock = index - b.Index; - for (nitems = 0; ntimes < column; ntimes++) + start -= b.Index; + for (int i = 0; i < nitems; i++, start++) { - group[nitems] = b[inblock++]; - if (inblock >= count) + if (start >= count) { - b = b.Next; - if (b == null) - break; + r++; + if (r == blocks.Length) + return i; + b = blocks[r]; count = b.Count; - inblock = 0; + start = 0; } + group[i] = b[start]; } - return group; + return nitems; } - // Update "block" to what contains the first candidate of the - // previous candidate-group, update "current_index", and update - // "group" if necessary. Return the previous candidate-group. - // Set NITEMS to the number of valid candidates contained in - // that group. + // Update "row" to what contains the first candidate of + // the previous candidate-group, update "current_index", and + // update "group" if necessary. Return the previous + // candidate-group. Set NITEMS to the number of valid + // candidates contained in that group. - public object PrevGroup (out int nitems, out int ingroup) + public int PrevGroup () { - object val; + int nitems; + int col = Column; - ingroup = InGroupIndex; - if (group == null) + if (IsFixed) { - block = (block.Prev != null) ? block.Prev : block.Last; - current_index = block.Index; - nitems = block.Count; - val = block.Data; + nitems = group.Length; + if ((index -= col + nitems) < 0) + index = (Total / nitems) * nitems; + nitems = fill_group (index); } else { - nitems = group.Length; - current_index -= ingroup + nitems; - if (current_index < 0) - current_index = (total_count / nitems) * nitems; - val = fill_group (current_index, out nitems); + row = row > 0 ? row-- : blocks.Length - 1; + nitems = blocks[row].Count; + index = blocks[row].Index; } - if (ingroup >= nitems) - ingroup = nitems - 1; - current_index += ingroup; - return val; + index += col < nitems ? col : nitems - 1; + return nitems; } - public object NextGroup (out int nitems) + public int NextGroup () { - int ingroup = InGroupIndex; - object val; + int nitems; + int col = Column; - nitems = 0; - if (group == null) + if (IsFixed) { - block = (block.Next != null) ? block.Next : block.First; - current_index = block.Index; - nitems = block.Count; - val = block.Data; + nitems = group.Length; + if ((index += nitems - col) >= Total) + index = 0; + nitems = fill_group (index); } else { - nitems = group.Length; - current_index += column - ingroup; - if (current_index >= total_count) - current_index = 0; - val = fill_group (current_index, out nitems); + row = row < blocks.Length - 1 ? row + 1 : 0; + nitems = blocks[row].Count; + index = blocks[row].Count; } - if (ingroup >= nitems) - ingroup = nitems - 1; - current_index += ingroup; - return val; + index += col < nitems ? col : nitems - 1; + return nitems; } - public object Next (out int nitems) + public void Prev () { - int ingroup = InGroupIndex + 1; - object val; - int index = current_index + 1; + int col = Column; - nitems = group == null ? block.Count : group.Length; - - if (ingroup >= nitems) + if (col == 0) { - val = NextGroup (out nitems); - current_index = index < total_count ? index : 0; - return val; - } - if (group == null) - { - nitems = block.Count; - val = block.Data; + int nitems = PrevGroup (); + index += col < nitems - 1 ? col : nitems - 1; } else - { - nitems = group.Length; - val = group; - } - current_index++; - return val; + index--; } - public object Prev (out int nitems) + public void Next () { - int ingroup = InGroupIndex - 1; - object val; - int index = current_index - 1; + int col = Column; + int nitems = GroupLength; - if (ingroup < 0) - { - val = PrevGroup (out nitems); - current_index = index >= 0 ? index : total_count - 1; - return val; - } - if (group == null) + if (col == nitems - 1) { - nitems = block.Count; - val = block.Data; + nitems = NextGroup (); + index -= Column; } else - { - nitems = group.Length; - val = group; - } - current_index--; - return val; + index++; } - public object First (out int nitems) + public void First () { - if (group == null) - { - nitems = block.Count; - current_index = block.Index; - return block.Data; - } - nitems = group.Length; - current_index = (current_index / nitems) * nitems; - return group; + index -= Column; } - public object Last (out int nitems) + public void Last () { - if (group == null) - { - nitems = block.Count; - current_index = block.Index + block.Count - 1;; - return block.Data; - } - nitems = group.Length; - current_index = (current_index / nitems) * nitems + nitems - 1; - return group; + index += GroupLength - (Column + 1); } - public object Select (int index, out int ingroup, out int len) + public void Select (int col) { - if (index < current_index) - - - MPlist prev; - return find_group (index, out ingroup_index, out text_len, out prev); + int maxcol = GroupLength - 1; + if (col > maxcol) + col = maxcol; + index = index - Column + col; } - private MPlist find_group (int index, out int ingroup_index, - out int text_len, out MPlist previous) + public void Update (MInputContext ic) { - MPlist p; - int i = 0; + int from, to; - for (p = list, previous = null; ! p.IsEmpty; previous = p, p = p.next) - { - int len = p.IsMText ? p.Text.Length : p.Plist.Count; - if (index < i + len) - break; - i += len; - } - ingroup_index = index - i; - if (p.IsMText) - text_len = 1; - else - text_len = p.Plist[ingroup_index].Text.Length; - return p; - } - - private void Update (MInputContext ic, object group, int ingroup) - { - int from, to, len; - - if (current_index == index) - return; if (ic.candidates == null) { from = ic.cursor_pos; @@ -825,47 +824,13 @@ namespace M17N.Input from = ic.candidate_from; to = ic.candidate_to; } - group = - p = find_group (index, out ingroup, out len, out prev); - to = from + len; - if (p.IsMText) - preedit_replace (ic, from, to, p.Text[ingroup]); - else - preedit_replace (ic, from, to, p.Plist[ingroup].Text); - ic.preedit.PushProp (from, to, Mcandidates, this); - ic.cursor_pos = to; - ic.candidate_from = from; - ic.candidate_to = to; - ic.preedit_changed = true; - ic.cursor_pos_changed = true; - ic.candidate_changed = true; - } - private void Update (MInputContext ic, int index) - { - int from, to, len; - object group; + object candidate = ic.candidates.Current; - if (current_index == index) - return; - if (ic.candidates == null) - { - from = ic.cursor_pos; - to = ic.cursor_pos; - ic.candidates = this; - } - else - { - from = ic.candidate_from; - to = ic.candidate_to; - } - group = - p = find_group (index, out ingroup, out len, out prev); - to = from + len; - if (p.IsMText) - preedit_replace (ic, from, to, p.Text[ingroup]); + if (candidate is MText) + preedit_replace (ic, from, to, (MText) candidate); else - preedit_replace (ic, from, to, p.Plist[ingroup].Text); + preedit_replace (ic, from, to, (int) candidate); ic.preedit.PushProp (from, to, Mcandidates, this); ic.cursor_pos = to; ic.candidate_from = from; @@ -874,35 +839,28 @@ namespace M17N.Input ic.cursor_pos_changed = true; ic.candidate_changed = true; } - - public void Prev (MInputContext ic) {} - public void Next (MInputContext ic) {} - public void First (MInputContext ic) {} - public void Last (MInputContext ic) {} - public void PrevGroup (MInputContext ic) {} - public void NextGroup (MInputContext ic) {} - public void Select (MInputContext ic, int index) {} - } - private static object insert_candidates (object[] args, MPlist bindings) + private static object insert_candidates (object[] args, MPlist bindings, + object context) { - MInputContext ic = (MInputContext) args[0]; - MPlist list = (MPlist) args[1]; + MInputContext ic = (MInputContext) context; + MPlist list = (MPlist) args[0]; int column = 0; MPlist slot = (MPlist) bindings.Find (Mcandidates_group_size); if (slot != null) column = slot.Integer; - Candidates candidtes = new Candidates (list); - candidates.Update (ic, 0); + Candidates candidates = new Candidates (list, column); + candidates.Update (ic); return 1; } - private static object select (object[] args, MPlist bindings) + private static object select (object[] args, MPlist bindings, + object context) { - MInputContext ic = (MInputContext) args[0]; - object arg = args[1]; + MInputContext ic = (MInputContext) context; + object arg = args[0]; if (ic.candidates == null) return 0; @@ -911,35 +869,50 @@ namespace M17N.Input MSymbol sym = (MSymbol) arg; if (sym == Mat_less_than) - ic.candidates.Update (ic, 0); + ic.candidates.First (); else if (sym == Mat_greater_than) - ic.candidates.Update (ic, -1); + ic.candidates.Last (); else if (sym == Mat_minus) - ic.candidates.Prev (ic); + ic.candidates.Prev (); else if (sym == Mat_plus) - ic.candidates.Next (ic); + ic.candidates.Next (); else if (sym == Mat_open_square_bracket) - ic.candidates.PrevGroup (ic); + ic.candidates.PrevGroup (); else if (sym == Mat_close_square_bracket) - ic.candidates.NextGroup (ic); + ic.candidates.NextGroup (); + else + return 0; } else if (arg is int) - ic.candidates.SelectInGroup (ic, (int) arg); + ic.candidates.Select ((int) arg); + ic.candidates.Update (ic); return 0; } - private static object delete (object[] args, MPlist bindings) { return 1; } - private static object show (object[] args, MPlist bindings) { return 1; } - private static object hide (object[] args, MPlist bindings) { return 1; } - private static object move (object[] args, MPlist bindings) { return 1; } - private static object mark (object[] args, MPlist bindings) { return 1; } - private static object pushback (object[] args, MPlist bindings) { return 1; } - private static object pop (object[] args, MPlist bindings) { return 1; } - private static object undo (object[] args, MPlist bindings) { return 1; } - private static object commit (object[] args, MPlist bindings) { return 1; } - private static object unhandle (object[] args, MPlist bindings) { return 1; } - private static object shift (object[] args, MPlist bindings) { return 1; } - private static object call (object[] args, MPlist bindings) { return 1; } + private static object delete (object[] args, MPlist bindings, + object context) { return 1; } + private static object show (object[] args, MPlist bindings, + object context) { return 1; } + private static object hide (object[] args, MPlist bindings, + object context) { return 1; } + private static object move (object[] args, MPlist bindings, + object context) { return 1; } + private static object mark (object[] args, MPlist bindings, + object context) { return 1; } + private static object pushback (object[] args, MPlist bindings, + object context) { return 1; } + private static object pop (object[] args, MPlist bindings, + object context) { return 1; } + private static object undo (object[] args, MPlist bindings, + object context) { return 1; } + private static object commit (object[] args, MPlist bindings, + object context) { return 1; } + private static object unhandle (object[] args, MPlist bindings, + object context) { return 1; } + private static object shift (object[] args, MPlist bindings, + object context) { return 1; } + private static object call (object[] args, MPlist bindings, + object context) { return 1; } } public class MInputContext @@ -976,9 +949,9 @@ namespace M17N.Input private MText following_text; private bool key_unhandled; - internal MPlist GetCandidates (out int ingroup_index, out int text_len) + internal object GetCandidates (out int column) { - ingroup_index = text_len = 0; + column = 0; if (cursor_pos == 0) return null; MInputMethod.Candidates candidates @@ -986,8 +959,8 @@ namespace M17N.Input MInputMethod.Mcandidates); if (candidates == null) return null; - return candidates.FindGroup (candidate_index, - out ingroup_index, out text_len); + column = candidates.Column; + return candidates.Current; } } } diff --git a/Makefile b/Makefile index 9097d70..994a248 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ EXAMPLE = symbol.exe plist.exe chartab.exe text.exe textprop.exe database.exe \ TEST = rearsticky.exe frontsticky.exe bothsticky.exe \ sensitive.exe frontsensitive.exe rearsensitive.exe -DEBUG_FLAG = +DEBUG_FLAG = -debug all: ${DLL} ${EXAMPLE} ${TEST} @@ -23,10 +23,13 @@ M17NCore.dll: M17N.dll ${CORE_SRC} M17NExpr.dll: M17N.dll M17NCore.dll ${EXPR_SRC} $(CS) $(DEBUG_FLAG) -out:$@ -t:library -r:M17N.dll -r:M17NCore.dll ${EXPR_SRC} -M17NIM.dll: M17N.dll M17NCore.dll M17NExpr.dll ${INPUT_SRC} +M17NIM.dll: ${INPUT_SRC} M17N.dll M17NCore.dll M17NExpr.dll $(CS) $(DEBUG_FLAG) -out:$@ -t:library -r:M17N.dll -r:M17NCore.dll -r:M17NExpr.dll ${INPUT_SRC} -input.exe: %.cs +input.exe: input.cs ${DLL} + $(CS) $(DEBUG_FLAG) -codepage:65001 -r:M17N.dll -r:M17NCore -r:M17NExpr -r:M17NIM.dll $< + +expr.exe: expr.cs $(CS) $(DEBUG_FLAG) -codepage:65001 -r:M17N.dll -r:M17NCore -r:M17NExpr -r:M17NIM.dll $< %.exe: %.cs diff --git a/expr.cs b/expr.cs index 07aca8b..43d6bec 100644 --- a/expr.cs +++ b/expr.cs @@ -38,7 +38,7 @@ public class Test } Console.WriteLine (bindings); expr.PrettyPrint (); - Console.WriteLine ("\n => " + expr.Eval (bindings)); + Console.WriteLine ("\n => " + expr.Eval (bindings, null)); Console.WriteLine (bindings); } }