diff options
Diffstat (limited to 'src/List.vala')
-rw-r--r-- | src/List.vala | 130 |
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); + } + } +} |