public override bool subst(ref Object a_term, VarBind binding) { System.Collections.Generic.List <Erlang.Object> result = new System.Collections.Generic.List <Erlang.Object>(); bool changed = false; foreach (Erlang.Object term in this.elems) { Erlang.Object obj = null; if (term.subst(ref obj, binding)) { result.Add(obj); } else { changed = true; result.Add(term); } } if (!changed) { return(false); } a_term = new Erlang.Tuple(result.ToArray()); return(true); }
public void merge(VarBind other) { foreach (KeyValuePair <string, Erlang.Object> kv in other.m_dict) { m_dict[kv.Key] = kv.Value; } }
public void TestFormatVariable() { var cases = new Dictionary <string, Erlang.TermType> { { "B", Erlang.TermType.Object }, { "B::int()", Erlang.TermType.Int }, { "B::integer()", Erlang.TermType.Int }, { "B::string()", Erlang.TermType.String }, { "B::atom()", Erlang.TermType.Atom }, { "B::float()", Erlang.TermType.Double }, { "B::double()", Erlang.TermType.Double }, { "B::binary()", Erlang.TermType.Binary }, { "B::bool()", Erlang.TermType.Boolean }, { "B::boolean()", Erlang.TermType.Boolean }, { "B::byte()", Erlang.TermType.Byte }, { "B::char()", Erlang.TermType.Char }, { "B::list()", Erlang.TermType.List }, { "B::tuple()", Erlang.TermType.Tuple }, { "B::pid()", Erlang.TermType.Pid }, { "B::ref()", Erlang.TermType.Ref }, { "B::reference()", Erlang.TermType.Ref }, { "B::port()", Erlang.TermType.Port } }; foreach (var p in cases) { Erlang.Object o = Erlang.Object.Format(p.Key); Assert.IsInstanceOf(typeof(Erlang.Var), o); Assert.AreEqual(p.Value, o.Cast <Erlang.Var>().VarTermType); } var pat1 = Erlang.Object.Format("{A::char(), B::tuple(), C::float(), D::list(), [E::string(), F::int()], G::bool()}"); var obj1 = Erlang.Object.Format("{$a, {1,2,3}, 10.0, [5,6], [\"abc\", 190], true}"); var binding = new Erlang.VarBind(); Assert.IsTrue(pat1.match(obj1, binding)); // Match unbound variables Assert.IsTrue(pat1.match(obj1, binding)); // Match bound variables var obj2 = Erlang.Object.Format("{$a, {1,2,3}, 20.0, [5,6], [\"abc\", 190], true}"); Assert.IsFalse(pat1.match(obj2, binding)); // Match bound variables binding.clear(); var obj3 = Erlang.Object.Format("{$a, {1,2,3}, 10.0, [5,6], [\"abc\", bad], false}"); Assert.IsFalse(pat1.match(obj3, binding)); }
/// <summary> /// Match a term against the patterns in the collection. /// The first successful match will result in invokation of the action /// associated with the pattern /// </summary> /// <param name="term">Term to match against patterns</param> /// <returns>ID of the pattern that matched, or -1 if there were no matches</returns> public int Match <TErlTerm>(TErlTerm term, params object[] args) where TErlTerm : ErlObject { var binding = new VarBind(); foreach (var p in m_patterns) { if (p.Term.match(term, binding)) { p.Action(p, term, binding, args); return(p.ID); } binding.clear(); } return(-1); }
public override bool match(Erlang.Object pattern, VarBind binding) { if (pattern is Erlang.Var) { pattern.match(this, binding); } else if (!(pattern is Erlang.Tuple)) { return(false); } Erlang.Tuple tup = pattern as Erlang.Tuple; if (arity() != tup.arity()) { return(false); } for (int i = 0; i < arity(); ++i) { if (!elems[i].match(tup[i], binding)) { return(false); } } return(true); }
public void TestMatchVariable() { var cases = new KeyValueList <string, Erlang.Object> { { "B", new Erlang.Int(1) }, { "B", new Erlang.Atom("abc") }, { "B", new Erlang.String("efg") }, { "B", new Erlang.Double(10.0) }, { "B::int()", new Erlang.Int(10) }, { "B::integer()", new Erlang.Int(20) }, { "B::string()", new Erlang.String("xxx") }, { "B::atom()", new Erlang.Atom("xyz") }, { "B::float()", new Erlang.Double(5.0) }, { "B::double()", new Erlang.Double(3.0) }, { "B::binary()", new Erlang.Binary(new byte[] { 1, 2, 3 }) }, { "B::bool()", new Erlang.Boolean(true) }, { "B::boolean()", new Erlang.Boolean(false) }, { "B::byte()", new Erlang.Byte(1) }, { "B::char()", new Erlang.Char('a') }, { "B::list()", new Erlang.List(1, 2, 3) }, { "B::tuple()", new Erlang.Tuple(new Erlang.Char('a'), 1, "aaa") }, { "B::pid()", new Erlang.Pid("xxx", 1, 2, 3) }, { "B::ref()", new Erlang.Ref("xxx", 1, 3) }, { "B::reference()", new Erlang.Ref("xxx", 1, 3) }, { "B::port()", new Erlang.Port("xxx", 1, 3) } }; foreach (var p in cases) { { Erlang.Object pat = Erlang.Object.Format(p.Key); Erlang.Object obj = p.Value; var binding = new Erlang.VarBind(); binding["B"] = obj; Assert.IsTrue(pat.match(obj, binding)); } { Erlang.Object pat = Erlang.Object.Format(p.Key); Erlang.Object obj = p.Value; var binding = new Erlang.VarBind(); Assert.IsTrue(pat.match(obj, binding)); var b = binding["B"]; Assert.AreEqual(obj.Type, b.Type); Assert.IsTrue(obj.Equals(b)); } } var revCases = cases.Reverse <KeyValuePair <string, Erlang.Object> >().ToList(); cases.Zip(revCases, (p1, p2) => { Erlang.Var pat = Erlang.Object.Format(p1.Key).AsVar(); Erlang.Object obj = p2.Value; var binding = new Erlang.VarBind(); if (pat.VarTermType == Erlang.TermType.Object || pat.VarTermType == obj.TermType) { Assert.IsTrue(pat.match(obj, binding)); } else { Assert.IsFalse(pat.match(obj, binding)); } return(false); }).ToList(); }