From 6282d536074ad69f58f8d806e93c5ad949c560cc Mon Sep 17 00:00:00 2001 From: handa Date: Fri, 16 Oct 2009 05:48:50 +0000 Subject: [PATCH] *** empty log message *** --- MExpression.cs | 883 ------------------------------------------------------- MInputMethod.cs | 72 +++-- XmlExpr.cs | 261 +++++++++------- xex.xml | 9 +- xml.cs | 106 +++++++ 5 files changed, 304 insertions(+), 1027 deletions(-) delete mode 100644 MExpression.cs create mode 100644 xml.cs diff --git a/MExpression.cs b/MExpression.cs deleted file mode 100644 index d8fbadf..0000000 --- a/MExpression.cs +++ /dev/null @@ -1,883 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Xml; - -using M17N; -using M17N.Core; - -namespace M17N.Core -{ - public class MExpression - { - private static MSymbol Mvarref = "symbol-value"; - private static MSymbol Mdefun = "defun"; - private static MSymbol Mcond = "cond"; - private static MSymbol Mprogn = "progn"; - private static MSymbol Mwhen = "when"; - - public class Domain - { - private Domain parent; - internal MPlist functions = new MPlist (); - internal MPlist bindings = new MPlist (); - private Stack boundaries = new Stack (); - internal Translator translator; - public object context; - - internal Domain () - { - boundaries.Push (bindings); - } - - public Domain (object context) : this (basic, context) { } - - public Domain (Domain parent, object context) - { - this.parent = parent; - this.context = context; - boundaries.Push (bindings); - } - - public void AddTranslator (Translator translator) - { - if (this.translator == null) - this.translator = translator; - else - this.translator += translator; - } - - public void Bind (MSymbol sym, object value) - { - bindings = bindings.Cons (sym, value); - } - - public MPlist SetBoundary () - { - boundaries.Push (bindings); - return bindings; - } - - public void UnboundTo (MPlist boundary) - { - while (boundary != boundaries.Pop ()); - while (bindings != boundary) - bindings = bindings.next; - } - - public void Defun (string name, Builtin builtin, int min_arg, int max_arg) - { - Defun (name, builtin, min_arg, max_arg, false); - } - - public void Defun (string name, Builtin builtin, int min_arg, int max_arg, - bool specialp) - { - MSymbol sym = name; - Function func = (Function) functions.Get (sym); - - if (func != null) - { - if (func.min_arg < min_arg || func.max_arg > max_arg) - throw new Exception ("Incompatible argument numbers to override: " - + name); - func.builtin = builtin; - func.lambda = null; - func.min_arg = min_arg; - func.max_arg = max_arg; - func.specialp = specialp; - } - else - { - func = new Function (sym, builtin, min_arg, max_arg, specialp); - functions = functions.Cons (sym, func); - } - } - - public void Defun (MSymbol sym, MPlist args, MPlist body) - { - Function func = (Function) functions.Get (sym); - - if (func != null) - { - int nargs = args == null ? 0 : args.Count; - - if (func.min_arg < nargs || func.max_arg > nargs) - throw new Exception ("Incompatible argument numbers to override: " - + sym); - func.lambda.SetArgs (args); - func.lambda.SetBody (body, this); - func.builtin = null; - } - else - { - func = new Function (sym, args, body, this); - functions = functions.Cons (sym, func); - } - } - - public void Defun (XmlNode node) - { - MSymbol sym = node.Attributes["id"].Value; - Function func = (Function) functions.Get (sym); - - if (func != null) - { - XmlNode args = node.FirstChild; - int nargs = args.Name == "args" ? args.ChildNodes.Count : 0; - - if (func.min_arg < nargs || func.max_arg > nargs) - throw new Exception ("Incompatible argument numbers to override: " - + sym); - func.lambda.Set (node, this); - func.builtin = null; - } - else - { - func = new Function (sym, node, this); - functions = functions.Cons (sym, func); - } - } - - internal Function GetFunc (MSymbol name) - { - Function func = (Function) functions.Get (name); - - if (func == null) - { - if (parent != null) - return parent.GetFunc (name); - throw new Exception ("Unknown function: " + name); - } - return func; - } - - public bool CopyFunc (Domain domain, MSymbol name) - { - Function func = (Function) functions.Get (name); - if (func == null) - return false; - domain.functions = domain.functions.Cons (name, func); - return true; - } - - public void CopyFunc (Domain domain) - { - foreach (MPlist p in functions) - domain.functions = domain.functions.Cons (p.key, p.val); - } - - public object GetValue (MSymbol name) - { - MPlist slot = bindings.Find (name); - - if (slot == null) - { - if (parent != null) - return parent.GetValue (name); - throw new Exception ("Unbound variable: " + name); - } - return slot.val; - } - - public object SetValue (MSymbol name, object val) - { - MPlist boundary = boundaries.Peek (); - - for (MPlist plist = bindings; plist != boundary; plist = plist.next) - if (plist.key == name) - { - plist.val = val; - return val; - } - bindings = bindings.Cons (name, val); - return val; - } - - public bool IsBound (MSymbol name) - { - return (bindings.Find (name) != null); - } - - public void Translate (MPlist plist) - { - if (parent != null) - parent.Translate (plist); - if (translator != null) - for (MPlist p = plist; ! p.IsEmpty; p = p.next) - translator (p, this); - } - - public override string ToString () - { - string str = "<(functions"; - foreach (MPlist p in functions) - str += " " + p.key; - str += ") (bindings " + bindings + ")"; - if (context != null) - str += " (" + context + ")"; - str += ">"; - return str; - } - } - - public delegate object Builtin (MExpression[] args, Domain domain); - public delegate void Translator (MPlist plist, Domain domain); - - internal class Function - { - internal class Lambda - { - internal MSymbol[] args; - internal MExpression[] body; - - public Lambda (MPlist args, MPlist body, Domain domain) - { - SetArgs (args); - SetBody (body, domain); - } - - public Lambda (XmlNode node, Domain domain) - { - Set (node, domain); - } - - public void SetArgs (MPlist args) - { - int len = args == null ? 0 : args.Count; - - if (this.args == null) - this.args = new MSymbol[len]; - for (int i = 0; i < len; i++, args = args.next) - this.args[i] = args.Symbol; - } - - public void SetBody (MPlist body, Domain domain) - { - int len = body == null ? 0 : body.Count; - if (this.body == null) - this.body = new MExpression[len]; - for (int i = 0; i < len; i++, body = body.next) - { - domain.Translate (body); - this.body[i] = new MExpression (body.key, body.val, domain); - } - } - - public void Set (XmlNode node, Domain domain) - { - XmlNodeList body = node.ChildNodes; - int idx = 0; - - if (body[0].Name == "args") - { - XmlNodeList args = body[0].ChildNodes; - if (this.args == null) - this.args = new MSymbol[args.Count]; - for (int i = 0; i < args.Count; i++) - this.args[i] = args[i].InnerText; - idx++; - } - else if (this.args == null) - this.args = new MSymbol[0]; - if (this.body == null) - this.body = new MExpression[body.Count - idx]; - for (int i = 0; idx < body.Count; i++, idx++) - this.body[i] = new MExpression (body[idx], domain); - } - } - - public readonly MSymbol Name; - public Builtin builtin; - public int min_arg, max_arg; - internal Lambda lambda; - public bool specialp = false; - - internal static Function ignore, varref, block; - - public Function (MSymbol name, Builtin builtin, - int min_arg, int max_arg, bool specialp) - { - Name = name; - this.builtin = builtin; - this.min_arg = min_arg; - this.max_arg = max_arg; - this.specialp = specialp; - } - - internal Function (MSymbol name, MPlist args, MPlist body, - Domain domain) - { - Name = name; - lambda = new Lambda (args, body, domain); - this.min_arg = this.max_arg = lambda.args.Length; - } - - internal Function (MSymbol name, XmlNode node, Domain domain) - { - Name = name; - lambda = new Lambda (node, domain); - this.min_arg = this.max_arg = lambda.args.Length; - } - - private Function () - { - Name = MSymbol.nil; - } - - static Function () - { - ignore = new Function (); - varref = new Function (Mvarref, get_value, 1, 1, true); - block = new Function (Mprogn, progn, 0, -1, true); - } - - private static object get_value (MExpression[] args, Domain domain) - { - return domain.GetValue ((MSymbol) args[0].val); - } - - public object Call (MExpression[] args, Domain domain) - { - if (builtin != null) - { - if (! specialp) - foreach (MExpression e in args) - e.Eval (domain); - return builtin (args, domain); - } - if (lambda == null) - return null; - MPlist orig_bindings = domain.bindings; - object result = false; - try { - int i = 0; - foreach (MSymbol arg in lambda.args) - domain.Bind (arg, args[i++].Eval (domain)); - foreach (MExpression e in lambda.body) - result = e.Eval (domain); - } finally { - domain.bindings = orig_bindings; - } - return result; - } - } - - private static Domain basic; - - static MExpression () - { - basic = new Domain (); - - basic.Defun ("set", set_value, 2, 2, true); - basic.Defun ("=", set_value, 2, 2, true); - basic.Defun ("!", not, 1, 1, false); - basic.Defun ("+", plus, 2, -1, false); - basic.Defun ("*", multi, 2, -1, false); - basic.Defun ("-", minus, 1, -1, false); - basic.Defun ("/", divide, 2, -1, false); - basic.Defun ("%", percent, 2, -1, false); - basic.Defun ("|", logior, 2, -1, false); - basic.Defun ("&", logand, 2, -1, false); - basic.Defun ("+=", pluseq, 2, -1, true); - basic.Defun ("*=", multieq, 2, -1, true); - basic.Defun ("-=", minuseq, 2, -1, true); - basic.Defun ("/=", divideeq, 2, -1, true); - basic.Defun ("%=", percenteq, 2, -1, true); - basic.Defun ("|=", logioreq, 2, -1, true); - basic.Defun ("&=", logandeq, 2, -1, true); - basic.Defun ("<<", lshift, 2, 2, false); - basic.Defun (">>", rshift, 2, 2, false); - basic.Defun ("<<=", lshifteq, 2, 2, true); - basic.Defun (">>=", rshifteq, 2, 2, true); - basic.Defun ("==", eq, 2, -1, false); - basic.Defun ("!=", noteq, 2, 2, false); - basic.Defun ("<", less, 2, -1, false); - basic.Defun ("<=", lesseq, 2, -1, false); - basic.Defun (">", more, 2, -1, false); - basic.Defun (">=", moreeq, 2, -1, false); - basic.Defun ("progn", progn, 0, -1, true); - basic.Defun ("if", ifclause, 2, -1, true); - basic.Defun ("when", whenclause, 1, -1, true); - basic.Defun ("while", whileclause, 1, -1, true); - - basic.AddTranslator (new Translator (translate_cond)); - } - - private static object set_value (MExpression[] args, Domain domain) - { - return domain.SetValue ((MSymbol) args[0].args[0].val, - args[1].Eval (domain)); - } - - private static object not (MExpression[] args, Domain domain) - { - if (args[0].val is int) - return (int) args[0].val == 0; - if (args[0].val is bool) - return ! ((bool) args[0].val); - return true; - } - - private static object plus (MExpression[] args, Domain domain) - { - if (args[0].val is int) - { - int n = 0; - foreach (MExpression e in args) - n += (int) e.val; - return n; - } - else if (args[0].val is MText) - { - MText mt = new MText (); - foreach (MExpression e in args) - mt += (MText) e.val; - return mt; - } - throw new Exception ("Not an integer nor MText: " + args[0].val); - } - - private static object multi (MExpression[] args, Domain domain) - { - int n = 1; - foreach (MExpression e in args) - n *= (int) e.val; - return n; - } - - private static object minus (MExpression[] args, Domain domain) - { - int n = (int) args[0].val; - if (args.Length == 1) - return - n; - for (int i = 1; i < args.Length; i++) - n -= (int) args[i].val; - return n; - } - - private static object divide (MExpression[] args, Domain domain) - { - int n = (int) args[0].val; - for (int i = 1; i < args.Length; i++) - n /= (int) args[i].val; - return n; - } - - private static object percent (MExpression[] args, Domain domain) - { - int n = (int) args[0].val; - for (int i = 1; i < args.Length; i++) - n %= (int) args[i].val; - return n; - } - - private static object logior (MExpression[] args, Domain domain) - { - int n = 0; - foreach (MExpression e in args) - n |= (int) e.val; - return n; - } - - private static object logand (MExpression[] args, Domain domain) - { - int n = 0; - foreach (MExpression e in args) - n &= (int) e.val; - return n; - } - - private static object pluseq (MExpression[] args, Domain domain) - { - MSymbol sym = (MSymbol) args[0].args[0].val; - object val = domain.GetValue (sym); - - if (val is int) - { - int n = (int) val; - for (int i = 1; i < args.Length; i++) - n += (int) args[i].Eval (domain); - val = n; - } - else if (val is MText) - { - MText mt = (MText) val; - for (int i = 1; i < args.Length; i++) - mt.Cat ((MText) args[i].Eval (domain)); - val = mt; - } - domain.SetValue (sym, val); - return val; - } - - private static object multieq (MExpression[] args, Domain domain) - { - MSymbol sym = (MSymbol) args[0].args[0].val; - int n = (int) domain.GetValue (sym); - - for (int i = 1; i < args.Length; i++) - n *= (int) args[i].Eval (domain); - return domain.SetValue (sym, (object) n); - } - - private static object minuseq (MExpression[] args, Domain domain) - { - MSymbol sym = (MSymbol) args[0].args[0].val; - int n = (int) domain.GetValue (sym); - - for (int i = 1; i < args.Length; i++) - n -= (int) args[i].Eval (domain); - return domain.SetValue (sym, (object) n); - } - - private static object divideeq (MExpression[] args, Domain domain) - { - MSymbol sym = (MSymbol) args[0].args[0].val; - int n = (int) domain.GetValue (sym); - - for (int i = 1; i < args.Length; i++) - n /= (int) args[i].Eval (domain); - return domain.SetValue (sym, (object) n); - } - - private static object percenteq (MExpression[] args, Domain domain) - { - MSymbol sym = (MSymbol) args[0].args[0].val; - int n = (int) domain.GetValue (sym); - - for (int i = 1; i < args.Length; i++) - n %= (int) args[i].Eval (domain); - return domain.SetValue (sym, (object) n); - } - - private static object logioreq (MExpression[] args, Domain domain) - { - MSymbol sym = (MSymbol) args[0].args[0].val; - int n = (int) domain.GetValue (sym); - - for (int i = 1; i < args.Length; i++) - n |= (int) args[i].Eval (domain); - return domain.SetValue (sym, (object) n); - } - - private static object logandeq (MExpression[] args, Domain domain) - { - MSymbol sym = (MSymbol) args[0].args[0].val; - int n = (int) domain.GetValue (sym); - - for (int i = 1; i < args.Length; i++) - n &= (int) args[i].Eval (domain); - return domain.SetValue (sym, (object) n); - } - - private static object lshift (MExpression[] args, Domain domain) - { - return (int) args[0].val << (int) args[1].val; - } - - private static object lshifteq (MExpression[] args, Domain domain) - { - MSymbol sym = (MSymbol) args[0].args[0].val; - int n = (int) domain.GetValue (sym); - - n <<= (int) args[1].Eval (domain); - return domain.SetValue (sym, (object) n); - } - - private static object rshift (MExpression[] args, Domain domain) - { - return (int) args[0].val >> (int) args[1].val; - } - - private static object rshifteq (MExpression[] args, Domain domain) - { - MSymbol sym = (MSymbol) args[0].args[0].val; - int n = (int) domain.GetValue (sym); - - n >>= (int) args[1].Eval (domain); - return domain.SetValue (sym, (object) n); - } - - private static object eq (MExpression[] args, Domain domain) - { - int n = (int) args[0].val; - - for (int i = 1; i < args.Length; i++) - if (n != (int) args[i].val) - return false; - return true; - } - - private static object noteq (MExpression[] args, Domain domain) - { - return ((int) args[0].val != (int) args[1].val); - } - - private static object less (MExpression[] args, Domain domain) - { - int n = (int) args[0].val; - - for (int i = 1; i < args.Length; i++) - { - int n1 = (int) args[i].val; - if (n >= n1) - return false; - n = n1; - } - return true; - } - - private static object lesseq (MExpression[] args, Domain domain) - { - int n = (int) args[0].val; - for (int i = 1; i < args.Length; i++) - { - int n1 = (int) args[i].val; - if (n > n1) - return false; - n = n1; - } - return true; - } - - private static object more (MExpression[] args, Domain domain) - { - int n = (int) args[0].val; - for (int i = 1; i < args.Length; i++) - { - int n1 = (int) args[i].val; - if (n <= n1) - return false; - n = n1; - } - return true; - } - - private static object moreeq (MExpression[] args, Domain domain) - { - int n = (int) args[0].val; - for (int i = 1; i < args.Length; i++) - { - int n1 = (int) args[i].val; - if (n < n1) - return false; - n = n1; - } - return true; - } - - private static object progn (MExpression[] args, Domain domain) - { - object result = false; - - foreach (MExpression e in args) - result = e.Eval (domain); - return result; - } - - private static bool check_condition (MExpression condition, Domain domain) - { - object result = condition.Eval (domain); - return (result is bool ? (bool) result - : result is int ? ((int) result) != 0 - : true); - } - - private static object ifclause (MExpression[] args, Domain domain) - { - object result = false; - - if (check_condition (args[0], domain)) - result = args[1].Eval (domain); - else - for (int i = 2; i < args.Length; i++) - result = args[i].Eval (domain); - return result; - } - - private static object whenclause (MExpression[] args, Domain domain) - { - object result = false; - - if (check_condition (args[0], domain)) - for (int i = 1; i < args.Length; i++) - result = args[i].Eval (domain); - return result; - } - - private static object whileclause (MExpression[] args, Domain domain) - { - while (check_condition (args[0], domain)) - for (int i = 1; i < args.Length; i++) - args[i].Eval (domain); - return false; - } - - // (cond (COND1 ...) (COND2 ...) ...) - // => (cond (when COND1 ...) (when COND2 ...) ...) - private static void translate_cond (MPlist plist, Domain domain) - { - if (plist.IsPlist) - { - plist = plist.Plist; - if (plist.IsSymbol && plist.Symbol == Mcond) - { - plist.val = Mprogn; - for (plist = plist.next; ! plist.IsEmpty; plist = plist.next) - { - if (! plist.IsPlist) - throw new Exception ("Invalid cond form: " + plist); - plist.Plist.Push (MSymbol.symbol, Mwhen); - } - } - } - } - - private Function function; - private MExpression[] args; - private object val; - - public MExpression[] Args { get { return args; } } - public object Val { get { return val; } } - - private MExpression (object val) - { - this.val = val; - } - - // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | PROGN - // FUNCALL = '(' SYMBOL EXPR* ')' - // PROGN = '(' EXPR * ')' - private MExpression (MSymbol key, object val, Domain domain) - { - if (key == MSymbol.symbol) - { - function = Function.varref; - args = new MExpression[1]; - args[0] = new MExpression (val); - } - else if (key == MSymbol.integer - || key == MSymbol.mtext) - { - this.val = val; - } - else if (key == MSymbol.plist) - { - MPlist p = (MPlist) val; - - if (p.IsSymbol) - { - MSymbol sym = p.Symbol; - - if (sym == Mdefun) - { - p = p.next; - if (! p.IsSymbol) - throw new Exception ("Invalid function argument: " - + p.val); - sym = p.Symbol; - p = p.next; - if (! p.IsPlist) - throw new Exception ("Invalid function argument: " - + p.val); - domain.Defun (sym, p.Plist, p.next); - // This Mexpression is just a dummy. - } - else - { - function = domain.GetFunc (sym); - p = p.next; - int nargs = p.Count; - if (nargs < function.min_arg - || (function.max_arg >= 0 && nargs > function.max_arg)) - throw new Exception ("Invalid number of arguments to: " - + sym + " " + nargs); - args = new MExpression[nargs]; - for (int i = 0; i < nargs; i++, p = p.next) - { - domain.Translate (p); - args[i] = new MExpression (p.key, p.val, domain); - } - } - } - else - { - args = new MExpression[1]; - args[0] = new MExpression (p, domain); - } - } - else - throw new Exception ("Invalid expression: " + key + ":" + val); - } - - public MExpression (MPlist plist, Domain domain) - { - function = Function.block; - args = new MExpression[plist.Count]; - for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next) - { - domain.Translate (plist); - args[i] = new MExpression (plist.key, plist.val, domain); - } - } - - public MExpression (XmlNode node, Domain domain) - { - MSymbol sym = node.Name; - - function = domain.GetFunc (sym); - - XmlAttributeCollection attrs = node.Attributes; - - int nargs = attrs.Count + node.ChildNodes.Count; - if (nargs < function.min_arg - || (function.max_arg >= 0 && nargs > function.max_arg)) - throw new Exception ("Invalid number of arguments: " + node.InnerXml); - args = new MExpression[nargs]; - int i; - for (i = 0; i < attrs.Count; i++) - { - string str = sttrs[i].Value; - - } - } - - public object Eval (Domain domain) - { - if (function == null) - { - if (val is MSymbol) - val = domain.GetValue ((MSymbol) val); - } - else - val = function.Call (args, domain); - return val; - } - - public override string ToString () - { - string str; - - if (function != null) - { - str = "(" + function.Name.Name; - if (args != null) - foreach (MExpression e in args) - str += " " + e.ToString (); - str += ")"; - } - else if (val != null) - { - if (val is MText) - str = "\"" + (string) ((MText) val) + "\""; - else - str = val.ToString (); - } - else - str = "()"; - return str; - } - } -} diff --git a/MInputMethod.cs b/MInputMethod.cs index f2fe910..60e48d0 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -946,12 +946,28 @@ namespace M17N.Input index += GroupLength - (Column + 1); } - public void Select (int col) + public object Select (int col) { int maxcol = GroupLength - 1; if (col > maxcol) col = maxcol; index = index - Column + col; + return Current; + } + + public object Select (Selector selector) + { + switch (selector.Tag) + { + case '<': First (); break; + case '>': Last (); break; + case '-': Prev (); break; + case '+': Next (); break; + case '[': PrevGroup (); break; + case ']': NextGroup (); break; + default: break; + } + return Current; } public override string ToString () @@ -969,22 +985,20 @@ namespace M17N.Input static Selector () { selectors = new Dictionary (); - MSymbol[] symlist = new MSymbol[] { "@<", "@=", "@>", "@-", "@+", - "@[", "@]" }; - foreach (MSymbol s in symlist) - selectors[s] = new Selector (s); - selectors["@first"] = new Selector ('<'); - selectors["@current"] = new Selector ('='); - selectors["@last"] = new Selector ('>'); - selectors["@previous"] = new Selector ('-'); - selectors["@next"] = new Selector ('+'); - selectors["@previous-candidate-change"] = new Selector ('['); - selectors["@next-candidate-change"] = new Selector (']'); + selectors ["@<"] = selectors["@first"] = new Selector ('<'); + selectors ["@="] = selectors["@current"] = new Selector ('='); + selectors ["@>"] = selectors["@last"] = new Selector ('>'); + selectors ["@-"] = selectors["@previous"] = new Selector ('-'); + selectors ["@+"] = selectors["@next"] = new Selector ('+'); + selectors ["@["] = selectors["@previous-candidate-change"] + = new Selector ('['); + selectors ["@]"] = selectors["@next-candidate-change"] + = new Selector (']'); } - private char tag; + private readonly char tag; - private Selector (MSymbol sym) { tag = sym.Name[1]; } + public char Tag { get { return tag; } } private Selector (char tag) { this.tag = tag; } @@ -1000,20 +1014,6 @@ namespace M17N.Input throw new Exception ("Invalid selector name: " + name); return selector; } - - public void Select (Candidates candidates) - { - switch (tag) - { - case '<': candidates.First (); break; - case '>': candidates.Last (); break; - case '-': candidates.Prev (); break; - case '+': candidates.Next (); break; - case '[': candidates.PrevGroup (); break; - case ']': candidates.NextGroup (); break; - default: break; - } - } } internal class Map @@ -2043,7 +2043,7 @@ namespace M17N.Input if (! p.IsSymbol) continue; - domain.Defun ((Xex.Symbol) p.Symbol.Name, false, null, null, true); + domain.Defun ((Xex.Symbol) p.Symbol.Name, null, null, true); } for (MPlist pl = plist; ! pl.IsEmpty; pl = pl.next) if (pl.IsPlist) @@ -2052,7 +2052,7 @@ namespace M17N.Input if (! p.IsSymbol) continue; - domain.Defun ((Xex.Symbol) p.Symbol.Name, false, null, + domain.Defun ((Xex.Symbol) p.Symbol.Name, null, parse_actions (p.next, false), false); } } @@ -2157,9 +2157,9 @@ namespace M17N.Input if (args[0].IsInt) candidate = can.Select (args[0].Intval); else - candidate = ((Selector) args[0].Objval).Select (can); + candidate = can.Select ((Selector) args[0].Objval); if (candidate is MText) - ic.insert ((MTtext) candidate, can); + ic.insert ((MText) candidate, can); else ic.insert ((int) candidate, can); } @@ -2450,8 +2450,7 @@ namespace M17N.Input preedit.Ins (from, c); if (candidates != null) { - preedit.PushProp (cursor_pos - 1, cursor_pos, - Mcandidates, candidates); + preedit.PushProp (from, from + 1, Mcandidates, candidates); changed |= (ChangedStatus.Preedit | ChangedStatus.CursorPos | CandidateAll); } @@ -2464,12 +2463,11 @@ namespace M17N.Input preedit[from, to] = mt; if (candidates != null) { - preedit.PushProp (cursor_pos - mt.Length, cursor_pos, - Mcandidates, candidates); + preedit.PushProp (from, from + mt.Length, Mcandidates, candidates); changed |= (ChangedStatus.Preedit | ChangedStatus.CursorPos | CandidateAll); } - adjust_markers (from, to, mt.Length); + adjust_markers (from, to, mt == null ? 0 : mt.Length); } internal void insert (int c, Candidates candidates) diff --git a/XmlExpr.cs b/XmlExpr.cs index a07ab65..ba26919 100644 --- a/XmlExpr.cs +++ b/XmlExpr.cs @@ -93,7 +93,6 @@ namespace System.Xml.Expression private static Symbol Qdefun = "defun"; private static Symbol Qfname = "fname"; private static Symbol Qargs = "args"; - private static Symbol Qargs_unevalled = "args-unevalled"; private static Symbol Qfixed = "fixed"; private static Symbol Qoptional = "optional"; private static Symbol Qrest = "rest"; @@ -103,7 +102,7 @@ namespace System.Xml.Expression private static Symbol Qdescription = "description"; private static Symbol Qrange = "range"; - public abstract class Function + internal abstract class Function { public Symbol name; public int min_arg, max_arg; @@ -170,60 +169,135 @@ namespace System.Xml.Expression } } - internal class Lambda : Function + private static void parse_head (Domain domain, XmlNode node, + out Symbol name, + out int min_arg, out int max_arg, + out Variable[] args) + { + int nfixed = 0; + int noptional = 0; + int nrest = 0; + name = node.Attributes[Qfname].Value; + + node = node.FirstChild; + if (node != null && node.Name == Qargs) + { + XmlNode n; + for (n = node.FirstChild; n != null; n = n.NextSibling) + { + if (n.Name == Qfixed) + nfixed++; + else if (n.Name == Qoptional) + noptional++; + else if (n.Name == Qrest) + nrest++; + else + throw new Exception ("Invalid argument type: " + n); + } + min_arg = nfixed; + max_arg = nfixed + noptional + nrest; + args = new Variable[max_arg]; + n = node.FirstChild; + for (int i = 0; i < max_arg; n = n.NextSibling) + args[i++] = domain.Defvar ((Symbol) n.Attributes[0].Value); + if (nrest == 1) + max_arg = - max_arg; + } + else + { + min_arg = max_arg = 0; + args = null; + } + } + + private static void parse_body (Domain domain, XmlNode node, + out Term[] body) + { + for (node = node.FirstChild; node != null; node = node.NextSibling) + if (node.Name != Qdescription + && node.Name != Qargs) + break; + int nterms = 0; + for (XmlNode n = node; n != null; n = n.NextSibling) + nterms++; + if (nterms > 0) + { + body = new Term[nterms]; + for (nterms = 0; node != null; node = node.NextSibling, nterms++) + body[nterms] = new Term (domain, node); + } + else + body = null; + } + + internal class Macro : Function { - internal bool args_evalled; internal Variable[] args; internal Term[] body; - public Lambda (Domain domain, XmlNode node) + public Macro (Domain domain, XmlNode node) { - int nfixed = 0; - int noptional = 0; - int nrest = 0; - name = node.Attributes[Qfname].Value; - - node = node.FirstChild; - if (node != null - && (node.Name == Qargs || node.Name == Qargs_unevalled)) - { - XmlNode n; - args_evalled = node.Name == Qargs; - for (n = node.FirstChild; n != null; n = n.NextSibling) - { - if (n.Name == Qfixed) - nfixed++; - else if (n.Name == Qoptional) - noptional++; - else if (n.Name == Qrest) - nrest++; - else - throw new Exception ("Invalid argument type: " + n); - } - min_arg = nfixed; - max_arg = nfixed + noptional + nrest; - args = new Variable[max_arg]; - n = node.FirstChild; - for (int i = 0; i < max_arg; n = n.NextSibling) - args[i++] = domain.Defvar ((Symbol) n.Attributes[0].Value); - if (nrest == 1) - max_arg = - max_arg; - } - else + parse_head (domain, node, out name, out min_arg, out max_arg, + out args); + } + + public void SetBody (Domain domain, XmlNode node) + { + parse_body (domain, node, out body); + } + + public override Term Call (Domain domain, Variable vari, Term[] args) + { + Bindings current = domain.bindings; + Term result = Zero; + + try { + int i; + Term[] newargs = new Term[args.Length]; + for (i = 0; i < min_arg; i++) + newargs[i] = args[i].Eval (domain); + args = newargs; + for (i = 0; i < min_arg; i++) + domain.Bind (this.args[i], args[i]); + if (body != null) { - min_arg = max_arg = 0; + try { + domain.Catch (CatchTag.Return); + foreach (Term term in body) + { + result = term.Eval (domain); + if (domain.Thrown) + return result; + } + } finally { + domain.Uncatch (); + } } + } finally { + domain.UnboundTo (current); + } + return result; + } + } + + internal class Lambda : Function + { + internal Variable[] args; + internal Term[] body; + + public Lambda (Domain domain, XmlNode node) + { + parse_head (domain, node, out name, out min_arg, out max_arg, + out args); } - public Lambda (Domain domain, Symbol name, - bool args_evalled, Symbol[] args) + public Lambda (Domain domain, Symbol name, Symbol[] args) { int nfixed = 0; int noptional = 0; int nrest = 0; this.name = name; - this.args_evalled = args_evalled; if (args != null) { int i = 0; @@ -257,20 +331,7 @@ namespace System.Xml.Expression public void SetBody (Domain domain, XmlNode node) { - for (node = node.FirstChild; node != null; node = node.NextSibling) - if (node.Name != Qdescription - && node.Name != Qargs - && node.Name != Qargs_unevalled) - break; - int nterms = 0; - for (XmlNode n = node; n != null; n = n.NextSibling) - nterms++; - if (nterms > 0) - { - body = new Term[nterms]; - for (nterms = 0; node != null; node = node.NextSibling, nterms++) - body[nterms] = new Term (domain, node); - } + parse_body (domain, node, out body); } public void SetBody (Term[] body) @@ -285,7 +346,7 @@ namespace System.Xml.Expression try { int i; - if (args_evalled) + if (args != null) { Term[] newargs = new Term[args.Length]; for (i = 0; i < min_arg; i++) @@ -297,8 +358,7 @@ namespace System.Xml.Expression if (body != null) { try { - if (args_evalled) - domain.Catch (CatchTag.Return); + domain.Catch (CatchTag.Return); foreach (Term term in body) { result = term.Eval (domain); @@ -306,8 +366,7 @@ namespace System.Xml.Expression return result; } } finally { - if (args_evalled) - domain.Uncatch (); + domain.Uncatch (); } } } finally { @@ -718,6 +777,9 @@ namespace System.Xml.Expression public void DefTerm (Symbol name, TermParser parser) { + if (termtypes.ContainsKey (name) + || functions.ContainsKey (name)) + throw new Exception ("already defined: " + name); termtypes[name] = new TermType (name, parser); } @@ -725,6 +787,8 @@ namespace System.Xml.Expression int min_arg, int max_arg, params string[] aliases) { Symbol name = str; + if (termtypes.ContainsKey (name)) + throw new Exception ("already defined as termtype: " + name); Function func = new Function.Subroutine (builtin, name, setvar, min_arg, max_arg); functions[name] = func; @@ -737,6 +801,8 @@ namespace System.Xml.Expression params string[] aliases) { Symbol name = str; + if (termtypes.ContainsKey (name)) + throw new Exception ("already defined as termtype: " + name); Function func = new Function.SpecialForm (builtin, name, min_arg, max_arg); functions[name] = func; @@ -749,14 +815,16 @@ namespace System.Xml.Expression functions[(Symbol) alias] = functions[(Symbol) str]; } - public void Defun (Symbol name, bool args_evalled, - Symbol[] args, Term[] body, bool prototype) + public void Defun (Symbol name, Symbol[] args, Term[] body, + bool prototype) { Function func; + if (termtypes.ContainsKey (name)) + throw new Exception ("already defined as termtype: " + name); if (prototype || ! functions.TryGetValue (name, out func)) { - func = new Function.Lambda (this, name, args_evalled, args); + func = new Function.Lambda (this, name, args); functions[name] = func; } if (! prototype) @@ -766,6 +834,8 @@ namespace System.Xml.Expression public void Defun (XmlNode node, bool prototype) { Symbol name = node.Attributes[Qfname].Value; + if (termtypes.ContainsKey (name)) + throw new Exception ("already defined as termtype: " + name); Function func; if (prototype || ! functions.TryGetValue (name, out func)) @@ -782,6 +852,22 @@ namespace System.Xml.Expression functions[func.name] = func; } + public void Defmacro (XmlNode node, bool prototype) + { + Symbol name = node.Attributes[Qfname].Value; + if (termtypes.ContainsKey (name)) + throw new Exception ("already defined as termtype: " + name); + Function func; + + if (prototype || ! functions.TryGetValue (name, out func)) + { + func = new Function.Macro (this, node); + functions[name] = func; + } + if (! prototype) + ((Function.Macro) func).SetBody (this, node); + } + public Variable Defvar (XmlNode node) { Symbol name = node.Attributes[0].Value; @@ -1598,61 +1684,38 @@ namespace System.Xml.Expression internal Variable vari; internal Term[] args; - private Funcall (Function func, Variable vari, Term[] args) - { - this.func = func; - this.vari = vari; - this.args = args; - } - - public Funcall (Domain domain, Symbol fname, Term[] args) - { - func = domain.GetFunc (fname); - if (args != null) - { - int nargs = args.Length; - if (nargs < func.min_arg - || (func.max_arg >= 0 && nargs > func.max_arg)) - throw new Exception ("Invalid number of arguments to: " - + fname + " " + nargs); - } - this.args = args; - } - - public Funcall (Domain domain, Symbol fname, Symbol vname, Term[] args) + public Funcall (Function func, Variable vari, Term[] args) { - func = domain.GetFunc (fname); if (args != null) { int nargs = args.Length; if (nargs < func.min_arg || (func.max_arg >= 0 && nargs > func.max_arg)) throw new Exception ("Invalid number of arguments to: " - + fname + " " + nargs); + + func.name + " " + nargs); } + this.func = func; + this.vari = vari; this.args = args; - if (vname != Qnull) - vari = domain.GetVar (vname, true); } internal static TermValue parser (Domain domain, XmlNode node) { Symbol fname = node.Name; - Symbol vname = Qnull; XmlAttribute attr; if (fname == Qfuncall) fname = node.Attributes[Qfname].Value; + Function func = domain.GetFunc (fname); + Variable vari; attr = node.Attributes[Qvname]; - if (attr != null) - vname = attr.Value; - + vari = attr == null ? null : domain.GetVar (attr.Value, true); XmlNodeList nlist = node.ChildNodes; int nargs = nlist.Count; Term[] args = new Term[nargs]; for (int i = 0; i < nargs; i++) args[i] = new Term (domain, nlist[i]); - return new Funcall (domain, fname, vname, args); + return new Funcall (func, vari, args); } public override Term Eval (Domain domain) @@ -1749,16 +1812,16 @@ namespace System.Xml.Expression // ... public Term (Domain domain, Symbol fname, Term[] args) - { - intval = 0; - objval = new Funcall (domain, fname, args); - } + : this (domain, fname, Qnull, args) { } // ... public Term (Domain domain, Symbol fname, Symbol vname, Term[] args) { intval = 0; - objval = new Funcall (domain, fname, vname, args); + + Function func = domain.GetFunc (fname); + Variable vari = vname == Qnull ? null : domain.GetVar (vname, true); + objval = new Funcall (func, vari, args); } public object Objval { diff --git a/xex.xml b/xex.xml index ef86e97..4db06fb 100644 --- a/xex.xml +++ b/xex.xml @@ -13,13 +13,8 @@ - - - - - - + @@ -63,7 +58,5 @@ ?a?b 1 - 11 - diff --git a/xml.cs b/xml.cs new file mode 100644 index 0000000..deba9b7 --- /dev/null +++ b/xml.cs @@ -0,0 +1,106 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Xml; +using Mvp.Xml.XInclude; + +public class Test +{ + static void read_element (XmlTextReader reader) + { + bool cont = true; + + Console.Write ("\n(" + reader.Name); + if (reader.MoveToFirstAttribute ()) + { + do { + Console.Write (" (" + reader.Name + " " + reader.Value + ")"); + } while (reader.MoveToNextAttribute ()); + reader.MoveToElement (); + } + while (cont && reader.Read ()) + switch (reader.NodeType) + { + case XmlNodeType.Element: + if (reader.Name == "doxygen") + reader.Skip (); + else + read_element (reader); + break; + case XmlNodeType.Text: + Console.Write ("\n\"" + reader.Value + "\""); + break; + case XmlNodeType.EndElement: + cont = false; + break; + } + Console.Write (")"); + } + + static void print_node (XmlNode node) + { + XmlAttributeCollection acol = node.Attributes; + if (acol != null) + { + XmlAttribute a = node.Attributes["key"]; + if (a != null) + Console.Write (a.Value); + } + Console.Write ("\n("); + switch (node.NodeType) + { + case XmlNodeType.Element: + Console.Write (node.Name); + XmlAttributeCollection attrs = node.Attributes; + foreach (XmlAttribute attr in attrs) + Console.Write (" ({0} {1})", attr.Name, attr.Value); + break; + case XmlNodeType.Text: + Console.WriteLine ("\n\"{0}\"", node.Value); + break; + default: + Console.WriteLine ("\n{0}", node.NodeType); + break; + } + node = node.FirstChild; + while (node != null) + { + print_node (node); + node = node.NextSibling; + } + Console.Write (")"); + } + + + public static void Main (string[] args) + { + FileStream stream; + XmlTextReader reader; + XmlDocument doc; + +#if false + stream = File.OpenRead ("/usr/local/work/m17n-db-xml/MIM/ispell.mimx"); + reader = new XmlTextReader (stream); + doc = new XmlDocument (); + reader.WhitespaceHandling = WhitespaceHandling.None; + reader.Read (); + Console.WriteLine (reader.Name + ":" + reader.NodeType); + while (reader.NodeType != XmlNodeType.Element) + reader.Read (); + doc.LoadXml ("<" + reader.Name + "/>"); + reader.Read (); + while (reader.NodeType != XmlNodeType.Element + || reader.Name != args[0]) + reader.Skip (); + doc.DocumentElement.InsertAfter (doc.ReadNode (reader), null); + print_node (doc.DocumentElement); + reader.Close (); + stream.Dispose (); +#else + doc = new XmlDocument (xex); + XmlReader read = new XIncludingReader (XmlReader.Create (args[0])); + doc.Load (read); + print_node (doc.DocumentElement); +#endif + } +} \ No newline at end of file -- 1.7.10.4