summaryrefslogtreecommitdiffstats
path: root/src/List.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/List.vala')
-rw-r--r--src/List.vala130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/List.vala b/src/List.vala
new file mode 100644
index 0000000..e215db4
--- /dev/null
+++ b/src/List.vala
@@ -0,0 +1,130 @@
+namespace Eva {
+ public class List : Object, Term {
+ private Term? _tail;
+
+ public Gee.List<Term?> list {get; construct;}
+ public Term? tail {
+ get {
+ return _tail;
+ }
+ set {
+ if(value is List) {
+ List l = value as List;
+
+ list.add_all(l.list);
+ _tail = l._tail;
+ }
+ else {
+ _tail = value;
+ }
+ }
+ }
+
+ public List() {
+ Gee.List<Term?> list0 = new Gee.LinkedList<Term?>();
+ Object(list: list0);
+ tail = null;
+ }
+
+ 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, aliases);
+ }
+
+ if(o is List) {
+ List l = o as List;
+
+ if(list.size != l.list.size)
+ return false;
+ if((tail == null) != (l.tail == null))
+ return false;
+ 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, aliases))
+ return false;
+
+ lt.next();
+ }
+
+ return true;
+ }
+ else if(o is String) {
+ if(tail != null)
+ return false;
+
+ string s = "";
+
+ foreach(Term t in list) {
+ unichar c;
+
+ if(t is Int) {
+ Int i = t as Int;
+ if(i.value < 0 || i.value > 255)
+ return false;
+
+ c = (unichar)i.value;
+ }
+ else if(t is UInt) {
+ UInt i = t as UInt;
+ if(i.value > 255)
+ return false;
+
+ c = (unichar)i.value;
+ }
+ else {
+ return false;
+ }
+
+ string buf = string.nfill(6, 0);
+ c.to_utf8(buf);
+
+ s += buf;
+ }
+
+ return (s == (o as String).value);
+ }
+ else {
+ return false;
+ }
+ }
+
+ public string to_string() {
+ string ret = "[";
+ bool first = true;
+
+ foreach(Term term in list) {
+ if(first) {
+ first = false;
+ ret += term.to_string();
+ }
+ else {
+ ret += "," + term.to_string();
+ }
+ }
+
+ if(tail != null)
+ ret += "|" + tail.to_string();
+
+ return ret + "]";
+ }
+
+ public void encode(Erl.Buffer buffer) {
+ if(!list.is_empty) {
+ buffer.encode_list_header(list.size);
+
+ foreach(Term term in list) {
+ term.encode(buffer);
+ }
+ }
+
+ if(tail == null)
+ buffer.encode_empty_list();
+ else
+ tail.encode(buffer);
+ }
+ }
+}