summaryrefslogtreecommitdiffstats
path: root/src/List.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/List.vala')
-rw-r--r--src/List.vala114
1 files changed, 51 insertions, 63 deletions
diff --git a/src/List.vala b/src/List.vala
index 9340fd7..5706792 100644
--- a/src/List.vala
+++ b/src/List.vala
@@ -1,60 +1,65 @@
namespace Eva {
- public class List : Object, Term {
- private static List _empty;
-
- private Term? _head;
- private Term? _tail;
+ public interface List : Term {
+ private static Empty _empty;
public static List empty {
get {
if(_empty == null)
- _empty = new List.create_empty();
+ _empty = new Empty();
return _empty;
}
}
- public Term head {
- get {
- assert(!is_empty);
- return _head;
- }
- }
- public Term tail {
- get {
- assert(!is_empty);
- return _tail;
- }
+ public abstract bool is_empty { get; }
+
+ public static List from_list(Gee.List<Term> list) {
+ if(list.is_empty)
+ return empty;
+ else
+ return new Cons(list.first(), List.from_list(list[1:list.size]));
}
- public bool is_empty {
- get {
- if(this == _empty) {
- assert(_head == null && _tail == null);
+ private class Empty : Object, Term, List {
+ internal Empty() {}
+
+ public bool is_empty {
+ get {
return true;
}
+ }
+
+ public string to_string() {
+ return "[]";
+ }
+
+ 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);
+ }
else {
- assert(_head != null && _tail != null);
- return false;
+ return (o == this);
}
}
+
+ public void encode(Erl.Buffer buffer) {
+ buffer.encode_empty_list();
+ }
}
+ }
+
+ public class Cons : Object, Term, List {
+ public Term head { get; construct;}
+ public Term tail { get; construct;}
- public List(Term head0, Term tail0 = empty) {
- _head = head0;
- _tail = tail0;
- }
-
- private List.create_empty() {
- _head = null;
- _tail = null;
+ public bool is_empty {
+ get {
+ return false;
+ }
}
- public static List from_list(Gee.List<Term> list) {
- if(list.is_empty)
- return empty;
- else
- return new List(list.first(), List.from_list(list[1:list.size]));
+ public Cons(Term head0, Term tail0 = empty) {
+ Object(head: head0, tail: tail0);
}
protected bool do_match(Term o, Gee.Map<string, Term> vars, Gee.Map<string, string> aliases) {
@@ -62,18 +67,9 @@ namespace Eva {
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));
+ if(o is Cons) {
+ Cons c = o as Cons;
+ return (head.do_match(c.head, vars, aliases) && tail.do_match(c.tail, vars, aliases));
}
else if(o is String) {
return do_match(string_to_list((o as String).value), vars, aliases);
@@ -84,14 +80,11 @@ namespace Eva {
}
public string to_string() {
- if(is_empty)
- return "[]";
+ string ret = "[" + head.to_string();
- 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();
+ unowned Term rest;
+ for(rest = tail; rest is Cons; rest = (rest as Cons).tail) {
+ ret += "," + (rest as Cons).head.to_string();
}
if(rest != List.empty) {
@@ -102,14 +95,9 @@ namespace Eva {
}
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);
- }
+ buffer.encode_list_header(1);
+ head.encode(buffer);
+ tail.encode(buffer);
}
}
}