summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2010-07-09 09:28:27 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2010-07-09 09:28:27 +0200
commit074ad834c10410f54297f726a668d4403f92f8ec (patch)
tree7f06ac5aa26e55f3f442221fb41c4019e12738d2 /src
parent46c0f539112cd19628dc0305d3556111099a04da (diff)
downloadeva-074ad834c10410f54297f726a668d4403f92f8ec.tar
eva-074ad834c10410f54297f726a668d4403f92f8ec.zip
Implemented pattern matching
Diffstat (limited to 'src')
-rw-r--r--src/Term.vala121
1 files changed, 105 insertions, 16 deletions
diff --git a/src/Term.vala b/src/Term.vala
index 46c03b3..5c27e7f 100644
--- a/src/Term.vala
+++ b/src/Term.vala
@@ -1,7 +1,20 @@
namespace Eva {
public interface Term : Object {
public abstract string to_string();
- public abstract bool equals(Term o);
+
+ public bool equals(Term o) {
+ return (match(o) != null);
+ }
+
+ public Gee.Map<string, Term>? match(Term o) {
+ Gee.Map<string, Term> vars = new Gee.HashMap<string, Term>();
+ if(!do_match(o, vars))
+ return null;
+ else
+ return vars;
+ }
+
+ protected abstract bool do_match(Term o, Gee.Map<string, Term> vars);
public abstract void encode(Erl.Buffer buffer);
@@ -109,7 +122,11 @@ namespace Eva {
return value.to_string();
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(o is Int) {
return value == (o as Int).value;
}
@@ -137,7 +154,11 @@ namespace Eva {
return value.to_string();
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(o is Int) {
return value == (o as Int).value;
}
@@ -166,7 +187,11 @@ namespace Eva {
return value.to_string();
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(o is Double) {
return value == (o as Double).value;
}
@@ -213,7 +238,11 @@ namespace Eva {
}
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(o is Atom) {
return value == (o as Atom).value;
}
@@ -254,7 +283,11 @@ namespace Eva {
return ret + "}";
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(!(o is Tuple))
return false;
@@ -264,7 +297,7 @@ namespace Eva {
return false;
for(int i = 0; i < value.size; ++i) {
- if(!value[i].equals(t.value[i]))
+ if(!value[i].do_match(t.value[i], vars))
return false;
}
@@ -307,7 +340,11 @@ namespace Eva {
tail = null;
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(o is List) {
List l = o as List;
@@ -315,13 +352,13 @@ namespace Eva {
return false;
if((tail == null) != (l.tail == null))
return false;
- if(tail != null && !tail.equals(l.tail))
+ if(tail != null && !tail.do_match(l.tail, vars))
return false;
Gee.Iterator<Term> lt = l.list.iterator();
lt.first();
foreach(Term t in list) {
- if(!t.equals(lt.get()))
+ if(!t.do_match(lt.get(), vars))
return false;
lt.next();
@@ -416,12 +453,16 @@ namespace Eva {
return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(o is String) {
return (value == (o as String).value);
}
else if(o is List) {
- return o.equals(this);
+ return o.do_match(this, vars);
}
else {
return false;
@@ -452,7 +493,11 @@ namespace Eva {
return "#Bin";
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(o is Binary) {
Binary b = o as Binary;
@@ -490,7 +535,11 @@ namespace Eva {
return "<" + node + "." + num.to_string() + "." + serial.to_string() + ">";
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(!(o is Pid))
return false;
@@ -532,7 +581,11 @@ namespace Eva {
return "#Port";
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(!(o is Port))
return false;
@@ -579,7 +632,11 @@ namespace Eva {
return "#Ref";
}
- public bool equals(Term o) {
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return o.do_match(this, vars);
+ }
+
if(!(o is Ref))
return false;
@@ -616,4 +673,36 @@ namespace Eva {
buffer.encode_ref(reference);
}
}
+
+ public class Var : Term, Object {
+ public string name {get; construct;}
+
+ public Var(string name0) {
+ assert(name0.get_char() == '_' || name0.get_char().isupper());
+
+ Object(name: name0);
+ }
+
+ public string to_string() {
+ return name;
+ }
+
+ protected bool do_match(Term o, Gee.Map<string, Term> vars) {
+ if(o is Var) {
+ return name == (o as Var).name;
+ }
+
+ if(name in vars) {
+ return vars[name].do_match(o, vars);
+ }
+ else {
+ vars[name] = o;
+ return true;
+ }
+ }
+
+ public void encode(Erl.Buffer buffer) {
+ assert_not_reached();
+ }
+ }
}