private static MSymbol Mmap_list = "map-list";
private static MSymbol Mstate = "state";
internal static MSymbol Mcandidates = "candidates";
+ private static MSymbol Mat_minus_zero = "@-0";
private static Xex.Symbol Qmap = "map";
private static Xex.Symbol Qrule = "rule";
private static Xex.Symbol Qinsert = "insert";
private static Xex.Symbol Qinsert_candidates = "insert-candidates";
private static Xex.Symbol Qchar_at = "char-at";
- private static Xex.Symbol Qat_minus_zero = "@-0";
private static Xex.Symbol Qselect = "select";
private static Xex.Symbol Qdelete = "delete";
private static Xex.Symbol Qshift = "shift";
internal abstract class Marker : Xex.TermValue
{
- private Xex.Symbol name;
+ private MSymbol name;
- private Marker (Xex.Symbol name)
+ private Marker (MSymbol name)
{
this.name = name;
}
public abstract int Position (Context ic);
+
public virtual void Mark (Context ic)
{
throw new Exception ("Can't set predefined marker: " + name);
{
return ic.preedit[Position (ic)];
}
- public override Xex.TermValue Clone () { return this; }
+
+ public override string ToString () { return name.Name; }
public static Xex.TermValue parser (Xex.Domain domain, XmlNode node)
{
- return Get ((Xex.Symbol) node.InnerText);
+ return Get ((MSymbol) node.InnerText);
}
public class Named : Marker
{
- public Named (Xex.Symbol name) : base (name) { }
+ public Named (MSymbol name) : base (name) { }
public override int Position (Context ic)
{
- int pos;
-
- if (ic.marker_positions.TryGetValue (this, out pos))
- return pos;
- return 0;
+ MPlist p = ic.marker_positions.Find (name);
+ return (p == null ? 0 : p.Integer);
}
public override void Mark (Context ic)
{
- ic.marker_positions[this] = ic.cursor_pos;
+ ic.marker_positions.Put (name, ic.cursor_pos);
}
}
public class Predefined : Marker
{
char tag;
- public Predefined (Xex.Symbol name) : base (name)
+
+ public Predefined (MSymbol name) : base (name)
{
tag = ((string) name)[1];
}
{
private int pos;
- public PredefinedAbsolute (Xex.Symbol name) : base (name)
+ public PredefinedAbsolute (MSymbol name) : base (name)
{
if (! int.TryParse (((string) name).Substring (1), out pos))
throw new Exception ("Invalid marker name: " + name);
{
private int distance;
- public PredefinedSurround (Xex.Symbol name) : base (name)
+ public PredefinedSurround (MSymbol name) : base (name)
{
if (! int.TryParse (((string) name).Substring (2), out distance))
throw new Exception ("Invalid marker name: " + name);
}
}
- static internal Dictionary<Xex.Symbol,Predefined> predefined_markers;
+ static internal Dictionary<MSymbol,Predefined> predefined_markers;
static Marker ()
{
- predefined_markers = new Dictionary<Xex.Symbol, Predefined> ();
- Xex.Symbol[] symlist
- = new Xex.Symbol[] {"@<", "@>", "@-", "@+", "@[", "@]" };
- foreach (Xex.Symbol s in symlist)
+ predefined_markers = new Dictionary<MSymbol, Predefined> ();
+ MSymbol[] symlist = new MSymbol[] {"@<", "@>", "@-", "@+", "@[", "@]" };
+ foreach (MSymbol s in symlist)
predefined_markers[s] = new Predefined (s);
}
- public static Marker Get (Xex.Symbol name)
+ public static Marker Get (MSymbol name)
{
- string str = name;
+ string str = name.Name;
if (str[0] == '@')
{
Predefined pred;
throw new Exception ("Invalid marker name: " + name);
if (Char.IsDigit (str[1]))
return new PredefinedAbsolute (name);
- if (str.Length == 2 || name == Qat_minus_zero
+ if (str.Length == 2 || name == Mat_minus_zero
|| ! (str[1] == '-' || str[1] == '+'))
throw new Exception ("Invalid marker name: " + name);
return new PredefinedSurround (name);
return selector;
}
- public override Xex.TermValue Clone () { return this; }
-
public void Select (Candidates candidates)
{
switch (tag)
if (plist.IsInteger && func != Qmark)
args[0] = new Xex.Term (plist.Integer);
else if (plist.IsSymbol)
- args[0] = new Xex.Term (Marker.Get ((Xex.Symbol) plist.Symbol.Name));
+ args[0] = new Xex.Term (Marker.Get (plist.Symbol));
else
throw new Exception ("Invalid arg to " + func + ": " + plist);
return new Xex.Term (domain, func, args);
}
- private Xex.Term parse_char_at (Xex.Symbol name)
+ private Xex.Term parse_char_at (MSymbol name)
{
Xex.Term[] args = new Xex.Term[1];
args[0] = new Xex.Term (Marker.Get (name));
return parse_insert (plist);
if (! p.IsSymbol)
throw new Exception ("Invalid action: " + p);
- Xex.Symbol name = p.Symbol.Name;
+ MSymbol sym = p.Symbol;
+ Xex.Symbol name = sym.Name;
p = p.next;
if (name == Qcond)
return parse_cond (p);
if (name == Qshift)
return parse_shift (p);
if (((string) name)[0] == '@')
- return parse_char_at (name);
+ return parse_char_at (sym);
if (name == Qset || name == Qadd || name == Qsub
|| name == Qmul || name == Qdiv)
{
Candidates can = ((Context) domain.context).candidates;
if (can != null)
- ((Selector) args[0].Objval).Select (can);
+ {
+ if (args[0].IsInt)
+ can.Select (args[0].Intval);
+ else
+ ((Selector) args[0].Objval).Select (can);
+ }
return args[0];
}
private MText produced = new MText ();
internal MText preedit = new MText ();
internal int cursor_pos;
- internal Dictionary<Marker, int> marker_positions
- = new Dictionary<Marker, int> ();
+ internal MPlist marker_positions = new MPlist ();
internal Candidates candidates;
private int candidate_from, candidate_to;
// Index into KEYS specifying the next key to handle.
internal int key_head;
- private int commit_key_head;
internal MText preceding_text = new MText ();
internal MText following_text = new MText ();
internal ChangedStatus changed;
+ private void set_cursor (string prefix, int pos)
+ {
+ cursor_pos = pos;
+ }
+
internal void reset ()
{
status = im.initial_state.title;
produced.Del ();
preedit.Del ();
- cursor_pos = 0;
+ set_cursor ("reset", 0);
marker_positions.Clear ();
candidates = null;
candidate_show = false;
keymap = im.initial_state.keymap;
keys.keyseq.Clear ();
- key_head = commit_key_head = 0;
preceding_text.Del ();
following_text.Del ();
: ((MText) inserted).Length);
int diff = ins - (to - from);
- foreach (Marker m in marker_positions.Keys)
+ for (MPlist p = marker_positions; ! p.IsEmpty; p = p.next)
{
- int pos = marker_positions[m];
+ int pos = p.Integer;
if (pos > from)
- {
- if (pos >= to)
- marker_positions[m] = pos + diff;
- else
- marker_positions[m] = from;
- }
+ p.Set (p.Key, pos >= to ? pos + diff : from);
}
if (cursor_pos >= to)
- cursor_pos += diff;
+ set_cursor ("adjust", cursor_pos + diff);
else if (cursor_pos > from)
- cursor_pos = from;
+ set_cursor ("adjust", from);
}
private void preedit_replace (int from, int to, int c)
}
preedit.PushProp (candidate_from, candidate_to,
Mcandidates, this);
- cursor_pos = candidate_from;
+ set_cursor ("update-candidate", candidate_to);
changed |= (ChangedStatus.Preedit | ChangedStatus.CursorPos
| CandidateAll);
}
pos = preedit.Length;
if (pos != cursor_pos)
{
- cursor_pos = pos;
+ set_cursor ("move", pos);
changed |= ChangedStatus.Preedit;
}
}
internal void commit ()
{
produced.Cat (preedit);
- preedit.Del ();
+ preedit_replace (0, preedit.Length, null);
changed |= ChangedStatus.Preedit;
}
if (this.state.title != state.title)
this.changed |= ChangedStatus.StateTitle;
this.state = state;
+ keymap = state.keymap;
}
public Context (MInputMethod im)
domain.RestoreValues (state_var_values);
preedit.Del ();
preedit.Ins (0, state_preedit);
- key_head = state_key_head;
- cursor_pos = state_pos;
+ set_cursor ("restore", state_pos);
}
private bool handle_key ()
{
- State current_state = state;
+ Console.Write ("\nHandle ({0}[{1}]) in {2}",
+ keys, key_head, state.name);
+
Keymap sub = keymap.Lookup (keys, ref key_head);
if (sub != keymap)
{
+ restore_state ();
keymap = sub;
if (keymap.map_actions != null)
{
- restore_state ();
if (! take_actions (keymap.map_actions))
return false;
}
}
else
{
+ State current_state = state;
+
if (keymap.branch_actions != null)
{
if (! take_actions (keymap.branch_actions))
return key_unhandled;
}
- public bool Produced (out MText mt)
- {
- mt = produced;
- return (produced.Length > 0);
- }
+ public MText Preedit { get { return preedit; } }
+ public MText Produced { get { return produced; } }
// Return value:
// true: All keys are handled and there's no text to commit.
key_unhandled = true;
break;
}
- if (++count == 100)
+ if (++count == 10)
break;
}
keys.keyseq.RemoveRange (0, key_head);
+ key_head = 0;
if ((changed & ChangedStatus.Preedit) != ChangedStatus.None
&& PreeditChanged != null)
CandidateChanged (this, callback_arg);
}
+ Console.Write ("\nPreedit(\"{0}\"/{1}), Produced({2})",
+ preedit, cursor_pos, produced);
+
return (! key_unhandled && produced.Length == 0);
}
}
public override Term Call (Domain domain, Variable vari, Term[] args)
{
- args = (Term[]) args.Clone ();
- for (int i = 0; i < args.Length; i++)
+ if (args != null)
{
- args[i] = args[i].Eval (domain);
- if (domain.Thrown)
- return args[i];
+ args = (Term[]) args.Clone ();
+ for (int i = 0; i < args.Length; i++)
+ {
+ args[i] = args[i].Eval (domain);
+ if (domain.Thrown)
+ return args[i];
+ }
}
return builtin (domain, vari, args);
}
}
}
- public Lambda (Domain domain, Symbol name, bool args_evalled, Symbol[] args)
+ public Lambda (Domain domain, Symbol name,
+ bool args_evalled, Symbol[] args)
{
int nfixed = 0;
int noptional = 0;
public abstract class TermValue
{
public virtual Term Eval (Domain domain) { return new Term (this); }
- public abstract TermValue Clone ();
+ public virtual TermValue Clone () { return this; }
}
private class Funcall : TermValue
public override Term Eval (Domain domain)
{
- domain.DebugWrite (true, "(({0}", func.name);
- for (int i = 0; i < args.Length; i++)
- domain.DebugWrite (false, " {0}", args[i].ToString ());
- domain.DebugWrite (false, ")");
+ domain.DebugWrite (true, ToString ());
domain.depth++;
Term result = func.Call (domain, vari, args);
domain.depth--;
{
string str = "<" + func.name;
if (vari != null)
- str += " \"vname=" + vari.name + "\"";
+ str += " vname=\"" + vari.name + "\"";
if (args == null)
return str + "/>";
str += ">";
- foreach (Term e in args)
- str += e;
+ if (func is Function.SpecialForm)
+ str += "...";
+ else
+ foreach (Term e in args)
+ str += e;
return (str + "</" + func.name + ">");
}
}