From: handa Date: Fri, 18 Sep 2009 13:07:28 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=8a17409fb12437f25e19caa83c588d1f2e616ec1;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/XmlExpr.cs b/XmlExpr.cs index 86048c8..3c1594b 100644 --- a/XmlExpr.cs +++ b/XmlExpr.cs @@ -104,8 +104,8 @@ namespace System.Xml.Expression private static Name Nrange = "range"; private static Name Nprogn = "progn"; - private static Name Nloop = "loop"; - private static Name Nfunction = "function"; + private static Name Nbreak = "break"; + private static Name Nreturn = "return"; internal abstract class Function { @@ -145,7 +145,11 @@ namespace System.Xml.Expression Term[] newargs = new Term[args.Length]; for (int i = 0; i < args.Length; i++) - newargs[i] = args[i].Eval (domain); + { + newargs[i] = args[i].Eval (domain); + if (domain.Catched) + return newargs[i]; + } return builtin (domain, vari, newargs); } } @@ -247,8 +251,19 @@ namespace System.Xml.Expression for (i = 0; i < min_arg; i++) domain.Bind (this.args[i], args[i]); if (body != null) - foreach (Term term in body) - result = term.Eval (domain); + { + try { + domain.Catch (Nreturn); + foreach (Term term in body) + { + result = term.Eval (domain); + if (domain.Catched) + return result; + } + } finally { + domain.Uncatch (); + } + } } finally { domain.UnboundTo (current); } @@ -389,18 +404,6 @@ namespace System.Xml.Expression } #endif - internal struct CatchTag - { - public readonly Name name; - public readonly int count; - - public CatchTag (Name name, int count) - { - this.name = name; - this.count = count; - } - } - public class Domain { public object context; @@ -409,8 +412,8 @@ namespace System.Xml.Expression internal Dictionary functions; internal Dictionary variables; internal Bindings bindings; - internal Stack catch_list = new Stack (); - private int catch_count = 0; + private Stack catch_stack = new Stack (); + private int catch_count = -1; internal Domain () { @@ -442,32 +445,43 @@ namespace System.Xml.Expression internal void Catch (Name name) { - catch_list.Push (new CatchTag (name, catchcount++)); + catch_stack.Push (name); + catch_count++; + Console.WriteLine ("catch {0}", catch_count); } internal bool Catched { - get { return catch_list.Peek ().count == catchcount; } + get { + Console.WriteLine ("catched {0} {1}", + catch_stack.Count, + catch_count); + return catch_stack.Count == catch_count; } } internal void ThrowReturn () { - CatchTag tag = catch_list.Peek (); - while (tag.name != Nreturn) + Name tag = catch_stack.Peek (); + while (tag != Nreturn) { - catch_list.Pop (); - tag = catch_list.Peek (); + catch_stack.Pop (); + tag = catch_stack.Peek (); } - catchcount = tag.count; + catch_count = catch_stack.Count - 1; } internal void ThrowBreak () { - catch_list.Peek ().count = catchcount; + Name tag = catch_stack.Peek (); + if (tag != Nbreak) + throw new Exception ("No outer loop to break"); + catch_count = catch_stack.Count - 1; } internal void Uncatch () { - catch_list.Pop (); + catch_stack.Pop (); + catch_count = catch_stack.Count; + Console.WriteLine ("uncatch {0}", catch_count); } public void DefSubr (Builtin builtin, string str, bool setvar, @@ -1075,39 +1089,23 @@ namespace System.Xml.Expression return result; } - private static Term break_clause (Domain domain, Variable vari, Term[] args) + private static Term return_clause (Domain domain, Variable vari, Term[] args) { - Stack clist = domain.catch_list; - if (clist.Count == 0) - throw new Exception ("No outer loop to break"); - CatchTag tag = clist.Peek (); - if (tag.name != Nloop) - throw new Exception ("No outer loop to break"); - domain.depth = tag.depth; + domain.ThrowReturn (); return args.Length == 0 ? Zero : args[0]; } - private static Term return_clause (Domain domain, Variable vari, Term[] args) + private static Term break_clause (Domain domain, Variable vari, Term[] args) { - Stack clist = domain.catch_list; - - while (clist.Count > 0) - { - CatchTag tag = clist.Pop (); - if (tag.name == Nfunction) - { - domain.depth = tag.depth; - return = args.Length == 0 ? Zero : args[0]; - } - } + domain.ThrowBreak (); return args.Length == 0 ? Zero : args[0]; } private static Term loop_clause (Domain domain, Variable vari, Term[] args) { - domain.Catch (Nloop); Term result = Zero; try { + domain.Catch (Nbreak); while (! domain.Catched) foreach (Term arg in args) { @@ -1123,10 +1121,20 @@ namespace System.Xml.Expression private static Term while_clause (Domain domain, Variable vari, Term[] args) { - while (args[0].Eval (domain).IsTrue) - for (int i = 1; i < args.Length; i++) - args[i].Eval (domain); - return Zero; + Term result = Zero; + try { + domain.Catch (Nbreak); + while (! domain.Catched && args[0].Eval (domain).IsTrue) + for (int i = 1; i < args.Length; i++) + { + result = args[i].Eval (domain); + if (domain.Catched) + break; + } + } finally { + domain.Uncatch (); + } + return result; } private static Term cond_clause (Domain domain, Variable vari, Term[] args) @@ -1149,20 +1157,32 @@ namespace System.Xml.Expression private static Term foreach_clause (Domain domain, Variable vari, Term[] args) { - List list = args[0].Listval; + List list = args[0].Eval (domain).Listval; Bindings current = domain.bindings; + Term result = Zero; - foreach (Term term in list) - { - domain.Bind (vari, term); - try { - for (int i = 1; i < args.Length; i++) - args[i].Eval (domain); - } finally { - domain.UnboundTo (current); + try { + domain.Catch (Nbreak); + foreach (Term term in list) + { + domain.Bind (vari, term); + try { + for (int i = 1; i < args.Length; i++) + { + result = args[i].Eval (domain); + if (domain.Catched) + break; + } + } finally { + domain.UnboundTo (current); + } + if (domain.Catched) + break; } - } - return Zero; + } finally { + domain.Uncatch (); + } + return result; } private static Term quote_clause (Domain domain, Variable vari, Term[] args) @@ -1486,8 +1506,17 @@ namespace System.Xml.Expression Term result = Zero; domain.depth = 0; - foreach (Term term in terms) - result = term.Eval (domain); + try { + domain.Catch (Nreturn); + foreach (Term term in terms) + { + result = term.Eval (domain); + if (domain.Catched) + break; + } + } finally { + domain.Uncatch (); + } return result; } diff --git a/xex.cs b/xex.cs index 09f5669..1ea49e0 100644 --- a/xex.cs +++ b/xex.cs @@ -11,7 +11,7 @@ public class Test Xexpression.Domain domain = new Xexpression.Domain (null); Xexpression xex = new Xexpression ("xex.xml", domain); - Xexpression.debug_level = 0; + Xexpression.debug_level = 10; Console.WriteLine (xex); Console.WriteLine (xex.Eval (domain)); } diff --git a/xex.xml b/xex.xml index 6f24c55..95511b0 100644 --- a/xex.xml +++ b/xex.xml @@ -22,6 +22,21 @@ + + + + + + + + + + 0 + returned + 1 + + + 10 ABC