summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Term.vala109
1 files changed, 72 insertions, 37 deletions
diff --git a/src/Term.vala b/src/Term.vala
index 5c27e7f..e0033d6 100644
--- a/src/Term.vala
+++ b/src/Term.vala
@@ -8,13 +8,23 @@ namespace Eva {
public Gee.Map<string, Term>? match(Term o) {
Gee.Map<string, Term> vars = new Gee.HashMap<string, Term>();
- if(!do_match(o, vars))
+ Gee.Map<string, string> aliases = new Gee.HashMap<string, string>();
+ if(!do_match(o, vars, aliases)) {
return null;
- else
+ }
+ else {
+ foreach(string a in aliases.keys) {
+ string v = Var.alias(a, aliases);
+
+ if(v in vars)
+ vars[a] = vars[v];
+ }
+
return vars;
+ }
}
- protected abstract bool do_match(Term o, Gee.Map<string, Term> vars);
+ protected abstract bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases);
public abstract void encode(Erl.Buffer buffer);
@@ -122,9 +132,9 @@ namespace Eva {
return value.to_string();
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(o is Int) {
@@ -154,9 +164,9 @@ namespace Eva {
return value.to_string();
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(o is Int) {
@@ -187,9 +197,9 @@ namespace Eva {
return value.to_string();
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(o is Double) {
@@ -238,9 +248,9 @@ namespace Eva {
}
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(o is Atom) {
@@ -283,9 +293,9 @@ namespace Eva {
return ret + "}";
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(!(o is Tuple))
@@ -297,7 +307,7 @@ namespace Eva {
return false;
for(int i = 0; i < value.size; ++i) {
- if(!value[i].do_match(t.value[i], vars))
+ if(!value[i].do_match(t.value[i], vars, aliases))
return false;
}
@@ -340,9 +350,9 @@ namespace Eva {
tail = null;
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(o is List) {
@@ -352,13 +362,13 @@ namespace Eva {
return false;
if((tail == null) != (l.tail == null))
return false;
- if(tail != null && !tail.do_match(l.tail, vars))
+ if(tail != null && !tail.do_match(l.tail, vars, aliases))
return false;
Gee.Iterator<Term> lt = l.list.iterator();
lt.first();
foreach(Term t in list) {
- if(!t.do_match(lt.get(), vars))
+ if(!t.do_match(lt.get(), vars, aliases))
return false;
lt.next();
@@ -453,16 +463,16 @@ namespace Eva {
return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(o is String) {
return (value == (o as String).value);
}
else if(o is List) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
else {
return false;
@@ -493,9 +503,9 @@ namespace Eva {
return "#Bin";
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(o is Binary) {
@@ -535,9 +545,9 @@ namespace Eva {
return "<" + node + "." + num.to_string() + "." + serial.to_string() + ">";
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(!(o is Pid))
@@ -581,9 +591,9 @@ namespace Eva {
return "#Port";
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(!(o is Port))
@@ -632,9 +642,9 @@ namespace Eva {
return "#Ref";
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
if(o is Var) {
- return o.do_match(this, vars);
+ return o.do_match(this, vars, aliases);
}
if(!(o is Ref))
@@ -687,17 +697,42 @@ namespace Eva {
return name;
}
- protected bool do_match(Term o, Gee.Map<string, Term> vars) {
- if(o is Var) {
- return name == (o as Var).name;
- }
+ internal static string alias(string key, Gee.Map<string, string> aliases) {
+ if(!(key in aliases))
+ return key;
+ else
+ return alias(aliases[key], aliases);
+ }
+
+ protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
+ string key = alias(name, aliases);
- if(name in vars) {
- return vars[name].do_match(o, vars);
+ if(o is Var) {
+ Var v = o as Var;
+ string vkey = alias(v.name, aliases);
+
+ if(key == vkey)
+ return true;
+
+ if(key in vars && vkey in vars)
+ return vars[key].do_match(vars[vkey], vars, aliases);
+ else if(!(vkey in vars)) {
+ aliases[vkey] = key;
+ return true;
+ }
+ else /* !(key in vars) */ {
+ aliases[key] = vkey;
+ return true;
+ }
}
else {
- vars[name] = o;
- return true;
+ if(key in vars) {
+ return vars[key].do_match(o, vars, aliases);
+ }
+ else {
+ vars[key] = o;
+ return true;
+ }
}
}