summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Binary.vala14
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Double.vala28
-rw-r--r--src/Int.vala28
-rw-r--r--src/List.vala114
-rw-r--r--src/Numeric.vala9
-rw-r--r--src/PacketHandler.vala4
-rw-r--r--src/Parse.vala11
-rw-r--r--src/Term.vala7
-rw-r--r--src/UInt.vala28
-rw-r--r--src/Util.vala2
11 files changed, 164 insertions, 82 deletions
diff --git a/src/Binary.vala b/src/Binary.vala
index 3ac988a..11ad775 100644
--- a/src/Binary.vala
+++ b/src/Binary.vala
@@ -1,10 +1,16 @@
namespace Eva {
public class Binary : Object, Term {
- public void* value {get; private set;}
+ public void* data {get; private set;}
public long len {get; private set;}
+ public string string_value {
+ owned get{
+ return binary_to_string(data, len);
+ }
+ }
+
public Binary(char[] v) {
- value = Memory.dup(v, (uint)(sizeof(char)*v.length));
+ data = Memory.dup(v, (uint)(sizeof(char)*v.length));
len = v.length;
}
@@ -23,7 +29,7 @@ namespace Eva {
if(b.len != len)
return false;
- return (Memory.cmp(value, b.value, len) == 0);
+ return (Memory.cmp(data, b.data, len) == 0);
}
else {
return false;
@@ -32,7 +38,7 @@ namespace Eva {
public void encode(Erl.Buffer buffer) {
- buffer.encode_binary((char*)value, len);
+ buffer.encode_binary(data, len);
}
}
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bbe5c19..f6208a6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,6 +8,7 @@ vala_precompile(EVA_C
Double.vala
Int.vala
List.vala
+ Numeric.vala
PacketHandler.vala
Parse.vala
Pid.vala
diff --git a/src/Double.vala b/src/Double.vala
index 0ca6866..924d5f6 100644
--- a/src/Double.vala
+++ b/src/Double.vala
@@ -1,7 +1,33 @@
namespace Eva {
- public class Double : Object, Term {
+ public class Double : Object, Term, Numeric {
public double value {get; construct;}
+ public int int_value {
+ get {
+ return (int)value;
+ }
+ }
+ public uint uint_value {
+ get {
+ return (uint)value;
+ }
+ }
+ public long long_value {
+ get {
+ return (long)value;
+ }
+ }
+ public ulong ulong_value {
+ get {
+ return (ulong)value;
+ }
+ }
+ public double double_value {
+ get {
+ return value;
+ }
+ }
+
public Double(double v) {
Object(value: v);
}
diff --git a/src/Int.vala b/src/Int.vala
index 5df3857..b881a2c 100644
--- a/src/Int.vala
+++ b/src/Int.vala
@@ -1,7 +1,33 @@
namespace Eva {
- public class Int : Object, Term {
+ public class Int : Object, Term, Numeric {
public long value {get; construct;}
+ public int int_value {
+ get {
+ return (int)value;
+ }
+ }
+ public uint uint_value {
+ get {
+ return (uint)value;
+ }
+ }
+ public long long_value {
+ get {
+ return value;
+ }
+ }
+ public ulong ulong_value {
+ get {
+ return value;
+ }
+ }
+ public double double_value {
+ get {
+ return value;
+ }
+ }
+
public Int(long v) {
Object(value: v);
}
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);
}
}
}
diff --git a/src/Numeric.vala b/src/Numeric.vala
new file mode 100644
index 0000000..c4f8c07
--- /dev/null
+++ b/src/Numeric.vala
@@ -0,0 +1,9 @@
+namespace Eva {
+ public interface Numeric : Term {
+ public abstract int int_value { get; }
+ public abstract uint uint_value { get; }
+ public abstract long long_value { get; }
+ public abstract ulong ulong_value { get; }
+ public abstract double double_value { get; }
+ }
+}
diff --git a/src/PacketHandler.vala b/src/PacketHandler.vala
index 0f5cd3c..b2ef1f7 100644
--- a/src/PacketHandler.vala
+++ b/src/PacketHandler.vala
@@ -3,6 +3,7 @@ namespace Eva {
private DataInputStream istream;
private DataOutputStream ostream;
private int sizeLength;
+ private bool running = false;
public signal void received_term(Term term);
@@ -37,7 +38,7 @@ namespace Eva {
}
private async void receive() throws Error {
- while(true) {
+ while(running) {
while(istream.get_available() < sizeLength) {
yield istream.fill_async((ssize_t)(sizeLength - istream.get_available()), 0, null);
}
@@ -71,6 +72,7 @@ namespace Eva {
}
public void start() {
+ running = true;
receive.begin();
}
}
diff --git a/src/Parse.vala b/src/Parse.vala
index 18741cc..79b4cea 100644
--- a/src/Parse.vala
+++ b/src/Parse.vala
@@ -1,5 +1,6 @@
namespace Eva {
- internal static Term? parse(string str, ref va_list va) {
+ internal static Term? parse(string str, ...) {
+ va_list va = va_list();
string s = str.chomp();
if(s.length == 0)
@@ -305,11 +306,11 @@ namespace Eva {
switch(c) {
case ']':
- return new List(head);
+ return new Cons(head);
case ',':
- return new List(head, parse_list_tail(ref str, ref va));
+ return new Cons(head, parse_list_tail(ref str, ref va));
case '|':
- Term ret = new List(head, parse_term(ref str, ref va));
+ Term ret = new Cons(head, parse_term(ref str, ref va));
str = str.chug();
if(str.length == 0 || str.get_char() != ']')
@@ -417,6 +418,8 @@ namespace Eva {
case 'f':
case 'd':
return new Double(va.arg<double>());
+ case 'w':
+ return va.arg<Term>();
default:
return null;
}
diff --git a/src/Term.vala b/src/Term.vala
index 9490af5..4b1215d 100644
--- a/src/Term.vala
+++ b/src/Term.vala
@@ -127,12 +127,7 @@ namespace Eva {
tail = do_decode(buffer, ref index);
}
- return new List(head, tail);
- }
-
- public static Term? parse(string str, ...) {
- va_list va = va_list();
- return Eva.parse(str, ref va);
+ return new Cons(head, tail);
}
}
}
diff --git a/src/UInt.vala b/src/UInt.vala
index a7ea4f8..84e09aa 100644
--- a/src/UInt.vala
+++ b/src/UInt.vala
@@ -1,7 +1,33 @@
namespace Eva {
- public class UInt : Object, Term {
+ public class UInt : Object, Term, Numeric {
public ulong value {get; construct;}
+ public int int_value {
+ get {
+ return (int)value;
+ }
+ }
+ public uint uint_value {
+ get {
+ return (uint)value;
+ }
+ }
+ public long long_value {
+ get {
+ return (long)value;
+ }
+ }
+ public ulong ulong_value {
+ get {
+ return value;
+ }
+ }
+ public double double_value {
+ get {
+ return value;
+ }
+ }
+
public UInt(ulong v) {
Object(value: v);
}
diff --git a/src/Util.vala b/src/Util.vala
index 28cce58..e840a07 100644
--- a/src/Util.vala
+++ b/src/Util.vala
@@ -36,7 +36,7 @@ namespace Eva {
return List.empty;
}
else {
- return new List(new UInt(str.get_char()), string_to_list(str.next_char()));
+ return new Cons(new UInt(str.get_char()), string_to_list(str.next_char()));
}
}
}