}
}
- public KeySeq (List<Xex.Term> list)
+ public KeySeq (Xex.Term[] args)
{
- foreach (Xex.Term term in list)
+ foreach (Xex.Term term in args)
{
if (term.IsName)
keyseq.Add (new Key ((MSymbol) term.Nameval.name));
str += " " + p.key;
return str + ")";
}
+
+ public Xex.Term Call (MSymbol method, MInputContext ic, Xex.Term[] args)
+ {
+ if (assembly == null)
+ {
+ try {
+ assembly = Assembly.LoadFrom (name + ".dll");
+ } catch {
+ return Xex.Zero;
+ }
+ Type t = assembly.GetType ("Plugin");
+ for (MPlist p = plugin.methods; ! p.IsEmpty; p = p.next)
+ p.Set (p.key, t.GetMethod (p.key.Name));
+ }
+
+ MethodInfo method_info = (MethodInfo) methods.Get (method);
+ if (method_info == null)
+ return Xex.Zero;
+ Xex.Term result = (Xex.Term) method_info.Invoke (null, args);
+ return result.Eval ();
+ }
+ }
+
+ internal class PluginMethod : Function
+ {
+ public Plugin plugin;
+ public MSymbol method;
+
+ public PluginMethod (Plugin plugin, MSymbol name)
+ : base ((Name) name.name, 0, -1)
+ {
+ this.plugin = plugin;
+ method = name.name.Substring (plugin.name.Length + 1);
+ }
+
+ public override Term Call (Xex.Domain domain, Xex.Variable vari,
+ Xex.Term[] args)
+ {
+ Xex.Term[] args = (Xex.Term[]) args.Clone ();
+ for (int i = 0; i < args.Length; i++)
+ {
+ args[i] = args[i].Eval (domain);
+ if (domain.Thrown)
+ return args[i];
+ }
+ return plugin.Call (method, (MIntutContext) domain.context, args);
+ }
}
+ internal class PluginCall : Xex.TermValue
+ {
+ PluginMethod method;
+ Xex.Term[] args;
+
+ public PluginCall (Plugin plugin, MSymbol entry, Xex.Term[] args)
+ {
+ this.plugin = plugin;
+ this.entry = entry;
+ this.args = args;
+ }
+
+ public override Xex.Term Eval (Xex.Domain domain)
+ {
+ Xex.Term[] args = new Xex.Term[this.args.Length];
+ for (int i = 0; i < args.Length; i++)
+ args[i] = this.args[i].Eval (domain);
+ return plugin.Call (entry, args);
+ }
+ }
+
+ internal abstract class Marker : Xex.TermValue
+ {
+ MSymbol name;
+ MInputContext ic;
+
+ public Marker (MSymbol name, MInputContext ic)
+ {
+ this.name = name;
+ this.ic = ic;
+ }
+
+ public abstract int Position { get; set; }
+ }
+
+ internal class NamedMarker : Marker
+ {
+ int position;
+
+ public NamedMaker (MSymbol name, MInputContext ic) : base (name, ic)
+ {
+ ic.markers.Put (name, this);
+ }
+
+ public override int Position {
+ get { return position; }
+ set { position = value; }
+ }
+ }
+
+ internal class SystemMarker : Marker
+ {
+ public SystemMarker (MSymbol name, MInputContext ic) : base (name, ic)
+ {
+ }
+
+ public override int Position {
+ get {
+ switch (name.Name[1])
+ {
+ case '<': return 0;
+ case '>': return ic.preedit.Length;
+ case '-': return ic.cursor_pos - 1;
+ case '+': return ic.cursor_pos + 1;
+ case '[':
+ if (ic.cursor_pos > 0)
+ {
+ int pos = ic.cursor_os;
+ int to;
+ ic.preedit.FindProp (MInputMethod.Mcandidates, pos - 1,
+ out pos, out to);
+ return pos;
+ }
+ return 0;
+ case ']':
+ if (ic.cursor_pos < ic.preedit.Length - 1)
+ {
+ int pos = ic.cursor_pos;
+ int from;
+ ic.preedit.FindProp (MInputMethod.Mcandidates, pos,
+ out from, out pos);
+ return pos;
+ }
+ return ic.preedit.Length;
+ default:
+ return name.Name[1] - '0';
+ }
+ }
+ set {
+ throw new Exception ("Can't set predefined marker: " + name);
+ }
+ }
+ }
+
internal class Map
{
public MSymbol name;
im_domain.DefSubr (Fcommit, "commit", true, 0, 0);
im_domain.DefSubr (Funhandle, "unhandle", true, 0, 0);
im_domain.DefSubr (Fshift, "shift", true, 1, 1);
- im_domain.DefSubr (Fcall, "call", true, 2, -1);
im_domain.DefSubr (Fmarker, "marker", true, 1, 1);
im_domain.DefSubr (Fchar_at, "char-at", true, 1, 1);
im_domain.DefSubr (Fkeyseq, "keyseq", true, 1, -1);
}
private static Xex.Term Fmark (Xex.Domain domain, Xex.Variable vari,
- Xex.Term[] args)
+ Xex.Term[] args)
{
- ((MInputContext) domain.context).mark (args[0]);
+ ((MInputContext) domain.context).mark ((Marker) args[0].Objval);
return args[0];
}
private static Xex.Term Fkeyseq (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- return new KeySeq (args[0].Listval);
+ return new KeySeq (args);
}
private static Xex.Term Fpushback (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
((MInputContext) domain.context).commit ();
- return Xex.Zero;
+ args = new Xex.Term[2];
+ args[0] = args[1] = catch_tag;
+ return Xex.Fthrow (domain, vari, args);
}
private static Xex.Term Fshift (Xex.Domain domain, Xex.Variable vari,
return args[0];
}
- private static Xex.Term Fcall (Xex.Domain domain, Xex.Variable vari, Xex.Term[] args)
- {
- MSymbol module = (MSymbol) args[0].Args[0].Val;
- MSymbol method = (MSymbol) args[1].Args[0].Val;
- MPlist arglist = new MPlist ();
-
- for (int i = 2; i < args.Length; i++)
- {
- object val = args[i].Eval (domain);
-
- if (val is int)
- arglist.Add (MSymbol.integer, val);
- else if (val is MSymbol)
- arglist.Add (MSymbol.symbol, val);
- else if (val is MText)
- arglist.Add (MSymbol.mtext, val);
- else if (val is MPlist)
- arglist.Add (MSymbol.plist, val);
- else
- throw new Exception ("Invalid argument to {0}/{1}: {2}",
- module, method, val);
- }
- return ((MInputContext) domain.context).call (module, method, arglist);
- }
-
public override string ToString ()
{
string str = (String.Format ("({0} (title \"{1}\")", tag, title));
public override Term Call (Domain domain, Variable vari, Term[] args)
{
- Term[] newargs = new Term[args.Length];
-
+ args = (Term[]) args.Clone ();
for (int i = 0; i < args.Length; i++)
{
- newargs[i] = args[i].Eval (domain);
+ args[i] = args[i].Eval (domain);
if (domain.Thrown)
- return newargs[i];
+ return args[i];
}
- return builtin (domain, vari, newargs);
+ return builtin (domain, vari, args);
}
}
}
}
- public class Variable : Object
+ public class Variable : TermValue
{
public readonly Name name;
public string desc;
result.objval = list;
return result;
}
- vari.val.objval = list;
return vari.val;
}
return TermTerm;
}
- private static Term Fcatch (Domain domain, Variable vari, Term[] args)
+ public static Term Fcatch (Domain domain, Variable vari, Term[] args)
{
Term result = Zero;
try {
return result;
}
- private static Term Fthrow (Domain domain, Variable vari, Term[] args)
+ public static Term Fthrow (Domain domain, Variable vari, Term[] args)
{
domain.ThrowTag (new CatchTag (args[0].Nameval));
return (args.Length == 1 ? Zero : args[1]);
}
- public class Object
+ public class TermValue
{
public virtual Term Eval (Domain domain) { return new Term (this); }
}
- private class Funcall : Object
+ private class Funcall : TermValue
{
internal Function func;
internal Variable vari;
public Term (string str) { intval = 0; objval = str; }
public Term (List<Term> list) { intval = 0; objval = list; }
public Term (Term term) { intval = term.intval; objval = term.objval; }
- public Term (Object obj) { intval = 0; objval = obj; }
+ public Term (TermValue obj) { intval = 0; objval = obj; }
public Term (XmlNode node, Domain domain)
{
}
}
- public int Objval {
+ public object Objval {
get {
if (objval == null)
throw new Exception ("term is an integer: " + this);
return this;
if (objval is List<Term>)
return new Term ((List<Term>) objval);
- if (objval is Object)
- return ((Object) objval).Eval (domain);
+ if (objval is TermValue)
+ return ((TermValue) objval).Eval (domain);
throw new Exception ("invalid Term object: " + objval);
}