From efdd8b44b2fcc7fcf4f7ba37ac4045793be8fecd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 11 Jul 2010 12:03:52 +0200 Subject: Many API improvements and more bugfixes --- src/Binary.vala | 14 ++++-- src/CMakeLists.txt | 1 + src/Double.vala | 28 +++++++++++- src/Int.vala | 28 +++++++++++- src/List.vala | 114 ++++++++++++++++++++++--------------------------- src/Numeric.vala | 9 ++++ src/PacketHandler.vala | 4 +- src/Parse.vala | 11 +++-- src/Term.vala | 7 +-- src/UInt.vala | 28 +++++++++++- src/Util.vala | 2 +- 11 files changed, 164 insertions(+), 82 deletions(-) create mode 100644 src/Numeric.vala 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 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 vars, Gee.Map 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 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 vars, Gee.Map 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()); + case 'w': + return va.arg(); 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())); } } } -- cgit v1.2.3