{
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);
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;
}
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;
{
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;
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;
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;
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;
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;
}
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;
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;
}
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;
}
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];
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,
args[i++] = p.val;
}
if (function == Function.defun)
- function.Call (args, null);
+ function.Call (args, null, null);
}
public MExpression (MSymbol sym)
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)
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
{
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)
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
= new Dictionary<MSymbol, MExpression> ();
}
- private static Dictionary<MDatabase.Tag, MInputMethod> im_table;
+ private static Dictionary<MDatabase.Tag, MInputMethod> im_table
+ = new Dictionary<MDatabase.Tag, MInputMethod> ();
private static MExpression.FunctionTable global_table
= new MExpression.FunctionTable ();
{
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)
{
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;
}
}
+ 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)
{
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);
}
}
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);
return im;
try {
im = new MInputMethod (tag);
- } catch {
+ } catch (Exception e) {
+ Console.WriteLine (e);
im = null;
}
return im;
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);
{
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);
// 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;
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;
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;
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
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
MInputMethod.Mcandidates);
if (candidates == null)
return null;
- return candidates.FindGroup (candidate_index,
- out ingroup_index, out text_len);
+ column = candidates.Column;
+ return candidates.Current;
}
}
}