namespace Eva { public class List : Object, Term { private static List _empty; private Term? _head; private Term? _tail; public static List empty { get { if(_empty == null) _empty = new List.create_empty(); return _empty; } } public Term head { get { assert(!is_empty); return _head; } } public Term tail { get { assert(!is_empty); return _tail; } } public bool is_empty { get { if(this == _empty) { assert(_head == null && _tail == null); return true; } else { assert(_head != null && _tail != null); return false; } } } public List(Term head0, Term tail0 = empty) { _head = head0; _tail = tail0; } private List.create_empty() { _head = null; _tail = null; } public static List from_list(Gee.List list) { if(list.is_empty) return empty; else return new List(list.first(), List.from_list(list[1:list.size])); } protected bool do_match(Term o, Gee.Map vars, Gee.Map aliases) { if(o is Var) { return o.do_match(this, vars, aliases); } if(o is List) { List l = o as List; if(is_empty && l.is_empty) return true; if(is_empty && !l.is_empty) return false; if(!is_empty && l.is_empty) return false; return (_head.do_match(l.head, vars, aliases) && _tail.do_match(l.tail, vars, aliases)); } else if(o is String) { return do_match(string_to_list((o as String).value), vars, aliases); } else { return false; } } public string to_string() { if(is_empty) return "[]"; string ret = "[" + _head.to_string(); Term rest = _tail; for(rest = _tail; rest is List && rest != List.empty; rest = (rest as List)._tail) { ret += "," + (rest as List)._head.to_string(); } if(rest != List.empty) { ret += "|" + rest.to_string(); } return ret + "]"; } public void encode(Erl.Buffer buffer) { if(is_empty) { buffer.encode_empty_list(); } else { buffer.encode_list_header(1); _head.encode(buffer); _tail.encode(buffer); } } } }