From f87943409c8ae2e9f6ed81e7a1cfc5109c16f31a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 10 Jul 2010 01:23:07 +0200 Subject: Split Term code to individual class sources --- src/Atom.vala | 54 +++++ src/Binary.vala | 38 ++++ src/CMakeLists.txt | 12 + src/Double.vala | 30 +++ src/Int.vala | 33 +++ src/List.vala | 130 +++++++++++ src/Pid.vala | 48 ++++ src/Port.vala | 46 ++++ src/Ref.vala | 66 ++++++ src/String.vala | 39 ++++ src/Term.vala | 630 ----------------------------------------------------- src/Tuple.vala | 67 ++++++ src/UInt.vala | 34 +++ src/Var.vala | 58 +++++ 14 files changed, 655 insertions(+), 630 deletions(-) create mode 100644 src/Atom.vala create mode 100644 src/Binary.vala create mode 100644 src/Double.vala create mode 100644 src/Int.vala create mode 100644 src/List.vala create mode 100644 src/Pid.vala create mode 100644 src/Port.vala create mode 100644 src/Ref.vala create mode 100644 src/String.vala create mode 100644 src/Tuple.vala create mode 100644 src/UInt.vala create mode 100644 src/Var.vala diff --git a/src/Atom.vala b/src/Atom.vala new file mode 100644 index 0000000..bb3a6fd --- /dev/null +++ b/src/Atom.vala @@ -0,0 +1,54 @@ +namespace Eva { + public class Atom : Object, Term { + public string value {get; construct;} + + public Atom(string v) { + assert(v.validate()); + Object(value: v); + } + + public string to_string() { + if(value.length == 0) + return "''"; + + bool special = false; + unichar c = value.get_char(); + + if(!c.islower()) + special = true; + + for(unowned string rest = value.next_char(); rest.length != 0 && !special; rest = rest.next_char()) { + c = rest.get_char(); + + if(!(c == '_' || c.isalnum())) + special = true; + } + + if(!special) { + return value; + } + else { + return "'" + value.replace("\\", "\\\\").replace("'", "\\'") + "'"; + } + } + + 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 Atom) { + return value == (o as Atom).value; + } + else { + return false; + } + } + + public void encode(Erl.Buffer buffer) { + char[]? array = string_to_array(value); + assert(array != null); + buffer.encode_atom(array); + } + } +} diff --git a/src/Binary.vala b/src/Binary.vala new file mode 100644 index 0000000..3ac988a --- /dev/null +++ b/src/Binary.vala @@ -0,0 +1,38 @@ +namespace Eva { + public class Binary : Object, Term { + public void* value {get; private set;} + public long len {get; private set;} + + public Binary(char[] v) { + value = Memory.dup(v, (uint)(sizeof(char)*v.length)); + len = v.length; + } + + public string to_string() { + return "#Bin"; + } + + 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 Binary) { + Binary b = o as Binary; + + if(b.len != len) + return false; + + return (Memory.cmp(value, b.value, len) == 0); + } + else { + return false; + } + } + + + public void encode(Erl.Buffer buffer) { + buffer.encode_binary((char*)value, len); + } + } +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4e7f0b2..92f8340 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,9 +3,21 @@ link_libraries(${GEE_LIBRARIES} ${GIO_LIBRARIES} ${ERL_LIBRARIES}) link_directories(${GEE_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${ERL_LIBRARY_DIRS}) vala_precompile(EVA_C + Atom.vala + Binary.vala + Double.vala + Int.vala + List.vala PacketHandler.vala + Pid.vala + Port.vala + String.vala + Ref.vala Term.vala + Tuple.vala + UInt.vala Util.vala + Var.vala PACKAGES gee-1.0 gio-2.0 diff --git a/src/Double.vala b/src/Double.vala new file mode 100644 index 0000000..0ca6866 --- /dev/null +++ b/src/Double.vala @@ -0,0 +1,30 @@ +namespace Eva { + public class Double : Object, Term { + public double value {get; construct;} + + public Double(double v) { + Object(value: v); + } + + public string to_string() { + return value.to_string(); + } + + 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 Double) { + return value == (o as Double).value; + } + else { + return false; + } + } + + public void encode(Erl.Buffer buffer) { + buffer.encode_double(value); + } + } +} diff --git a/src/Int.vala b/src/Int.vala new file mode 100644 index 0000000..5df3857 --- /dev/null +++ b/src/Int.vala @@ -0,0 +1,33 @@ +namespace Eva { + public class Int : Object, Term { + public long value {get; construct;} + + public Int(long v) { + Object(value: v); + } + + public string to_string() { + return value.to_string(); + } + + 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 Int) { + return value == (o as Int).value; + } + else if(o is UInt) { + return value == (o as UInt).value; + } + else { + return false; + } + } + + public void encode(Erl.Buffer buffer) { + buffer.encode_long(value); + } + } +} 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 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 list0 = new Gee.LinkedList(); + Object(list: list0); + tail = null; + } + + 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(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 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); + } + } +} diff --git a/src/Pid.vala b/src/Pid.vala new file mode 100644 index 0000000..3f71df7 --- /dev/null +++ b/src/Pid.vala @@ -0,0 +1,48 @@ +namespace Eva { + public class Pid : Object, Term { + public string node {get; construct;} + public uint num {get; construct;} + public uint serial {get; construct;} + public uint creation {get; construct;} + + public Pid(Erl.Pid pid) { + this.create(array_to_string(pid.node, Erl.MAXATOMLEN), pid.num, pid.serial, pid.creation); + } + + private Pid.create(string node0, uint num0, uint serial0, uint creation0) { + Object(node: node0, num: num0, serial: serial0, creation: creation0); + } + + public string to_string() { + return "<" + node + "." + num.to_string() + "." + serial.to_string() + ">"; + } + + 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 Pid)) + return false; + + Pid p = o as Pid; + + return (node == p.node && num == p.num && serial == p.serial && creation == p.creation); + } + + public void encode(Erl.Buffer buffer) { + Erl.Pid pid = Erl.Pid(); + char[]? nodedata = string_to_array(node); + assert(nodedata != null); + + Memory.copy(pid.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length)); + pid.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0; + + pid.num = num; + pid.serial = serial; + pid.creation = creation; + + buffer.encode_pid(pid); + } + } +} diff --git a/src/Port.vala b/src/Port.vala new file mode 100644 index 0000000..b67c808 --- /dev/null +++ b/src/Port.vala @@ -0,0 +1,46 @@ +namespace Eva { + public class Port : Object, Term { + public string node {get; construct;} + public uint id {get; construct;} + public uint creation {get; construct;} + + public Port(Erl.Port port) { + this.create(array_to_string(port.node, Erl.MAXATOMLEN), port.id, port.creation); + } + + private Port.create(string node0, uint id0, uint creation0) { + Object(node: node0, id: id0, creation: creation0); + } + + public string to_string() { + return "#Port"; + } + + 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 Port)) + return false; + + Port p = o as Port; + + return (node == p.node && id == p.id && creation == p.creation); + } + + public void encode(Erl.Buffer buffer) { + Erl.Port port = Erl.Port(); + char[]? nodedata = string_to_array(node); + assert(nodedata != null); + + Memory.copy(port.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length)); + port.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0; + + port.id = id; + port.creation = creation; + + buffer.encode_port(port); + } + } +} diff --git a/src/Ref.vala b/src/Ref.vala new file mode 100644 index 0000000..2510d78 --- /dev/null +++ b/src/Ref.vala @@ -0,0 +1,66 @@ +namespace Eva { + public class Ref : Object, Term { + public string node {get; construct;} + public int len {get; construct;} + public uint[] n {get; private set;} + public uint creation {get; construct;} + + public Ref(Erl.Ref reference) { + this.create(array_to_string(reference.node, Erl.MAXATOMLEN), reference.len, reference.n, reference.creation); + } + + private Ref.create(string node0, int len0, uint* n0, uint creation0) { + Object(node: node0, len: len0, creation: creation0); + + n = new uint[len]; + for(int i = 0; i < len; ++i) { + n[i] = n0[i]; + } + } + + public string to_string() { + return "#Ref"; + } + + 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 Ref)) + return false; + + Ref r = o as Ref; + + if(node != r.node || len != r.len || creation != r.creation) { + return false; + } + + for(int i = 0; i < len; ++i) { + if(n[i] != r.n[i]) + return false; + } + + return true; + } + + public void encode(Erl.Buffer buffer) { + Erl.Ref reference = Erl.Ref(); + char[]? nodedata = string_to_array(node); + assert(nodedata != null); + + Memory.copy(reference.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length)); + reference.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0; + + reference.len = len; + + for(int i = 0; i < len; ++i) { + reference.n[i] = n[i]; + } + + reference.creation = creation; + + buffer.encode_ref(reference); + } + } +} diff --git a/src/String.vala b/src/String.vala new file mode 100644 index 0000000..50563c2 --- /dev/null +++ b/src/String.vala @@ -0,0 +1,39 @@ +namespace Eva { + public class String : Object, Term { + public string value {get; construct;} + + public String(string v) { + Object(value: v); + } + + public string to_string() { + return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\""; + } + + 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 String) { + return (value == (o as String).value); + } + else if(o is List) { + return o.do_match(this, vars, aliases); + } + else { + return false; + } + } + + public void encode(Erl.Buffer buffer) { + char[]? array = string_to_array(value); + if(array != null) { + buffer.encode_string(array); + } + else { + string_to_list(value).encode(buffer); + } + } + } +} diff --git a/src/Term.vala b/src/Term.vala index f2799e9..6b08730 100644 --- a/src/Term.vala +++ b/src/Term.vala @@ -121,634 +121,4 @@ namespace Eva { } } - public class Int : Object, Term { - public long value {get; construct;} - - public Int(long v) { - Object(value: v); - } - - public string to_string() { - return value.to_string(); - } - - 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 Int) { - return value == (o as Int).value; - } - else if(o is UInt) { - return value == (o as UInt).value; - } - else { - return false; - } - } - - public void encode(Erl.Buffer buffer) { - buffer.encode_long(value); - } - } - - public class UInt : Object, Term { - public ulong value {get; construct;} - - public UInt(ulong v) { - Object(value: v); - } - - public string to_string() { - return value.to_string(); - } - - 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 Int) { - return value == (o as Int).value; - } - else if(o is UInt) { - return value == (o as UInt).value; - } - else { - return false; - } - } - - - public void encode(Erl.Buffer buffer) { - buffer.encode_ulong(value); - } - } - - public class Double : Object, Term { - public double value {get; construct;} - - public Double(double v) { - Object(value: v); - } - - public string to_string() { - return value.to_string(); - } - - 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 Double) { - return value == (o as Double).value; - } - else { - return false; - } - } - - public void encode(Erl.Buffer buffer) { - buffer.encode_double(value); - } - } - - public class Atom : Object, Term { - public string value {get; construct;} - - public Atom(string v) { - assert(v.validate()); - Object(value: v); - } - - public string to_string() { - if(value.length == 0) - return "''"; - - bool special = false; - unichar c = value.get_char(); - - if(!c.islower()) - special = true; - - for(unowned string rest = value.next_char(); rest.length != 0 && !special; rest = rest.next_char()) { - c = rest.get_char(); - - if(!(c == '_' || c.isalnum())) - special = true; - } - - if(!special) { - return value; - } - else { - return "'" + value.replace("\\", "\\\\").replace("'", "\\'") + "'"; - } - } - - 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 Atom) { - return value == (o as Atom).value; - } - else { - return false; - } - } - - public void encode(Erl.Buffer buffer) { - char[]? array = string_to_array(value); - assert(array != null); - buffer.encode_atom(array); - } - } - - public class Tuple : Object, Term { - private Term[] elements {get; set;} - - public Tuple(Term[] terms) { - elements = terms; - } - - public int size { - get { - return elements.length; - } - } - - public new unowned Term get(int i) { - assert(i >= 0 && i < size); - - return elements[i]; - } - - public string to_string() { - string ret = "{"; - bool first = true; - - foreach(Term term in elements) { - if(first) { - first = false; - ret += term.to_string(); - } - else { - ret += "," + term.to_string(); - } - } - - return ret + "}"; - } - - 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 Tuple)) - return false; - - Tuple t = o as Tuple; - - if(t.size != size) - return false; - - for(int i = 0; i < size; ++i) { - if(!this[i].do_match(t[i], vars, aliases)) - return false; - } - - return true; - } - - public void encode(Erl.Buffer buffer) { - buffer.encode_tuple_header(size); - - foreach(Term term in elements) { - term.encode(buffer); - } - } - } - - public class List : Object, Term { - private Term? _tail; - - public Gee.List 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 list0 = new Gee.LinkedList(); - Object(list: list0); - tail = null; - } - - 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(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 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); - } - } - - public class String : Object, Term { - public string value {get; construct;} - - public String(string v) { - Object(value: v); - } - - public string to_string() { - return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\""; - } - - 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 String) { - return (value == (o as String).value); - } - else if(o is List) { - return o.do_match(this, vars, aliases); - } - else { - return false; - } - } - - public void encode(Erl.Buffer buffer) { - char[]? array = string_to_array(value); - if(array != null) { - buffer.encode_string(array); - } - else { - string_to_list(value).encode(buffer); - } - } - } - - public class Binary : Object, Term { - public void* value {get; private set;} - public long len {get; private set;} - - public Binary(char[] v) { - value = Memory.dup(v, (uint)(sizeof(char)*v.length)); - len = v.length; - } - - public string to_string() { - return "#Bin"; - } - - 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 Binary) { - Binary b = o as Binary; - - if(b.len != len) - return false; - - return (Memory.cmp(value, b.value, len) == 0); - } - else { - return false; - } - } - - - public void encode(Erl.Buffer buffer) { - buffer.encode_binary((char*)value, len); - } - } - - public class Pid : Object, Term { - public string node {get; construct;} - public uint num {get; construct;} - public uint serial {get; construct;} - public uint creation {get; construct;} - - public Pid(Erl.Pid pid) { - this.create(array_to_string(pid.node, Erl.MAXATOMLEN), pid.num, pid.serial, pid.creation); - } - - private Pid.create(string node0, uint num0, uint serial0, uint creation0) { - Object(node: node0, num: num0, serial: serial0, creation: creation0); - } - - public string to_string() { - return "<" + node + "." + num.to_string() + "." + serial.to_string() + ">"; - } - - 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 Pid)) - return false; - - Pid p = o as Pid; - - return (node == p.node && num == p.num && serial == p.serial && creation == p.creation); - } - - public void encode(Erl.Buffer buffer) { - Erl.Pid pid = Erl.Pid(); - char[]? nodedata = string_to_array(node); - assert(nodedata != null); - - Memory.copy(pid.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length)); - pid.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0; - - pid.num = num; - pid.serial = serial; - pid.creation = creation; - - buffer.encode_pid(pid); - } - } - - public class Port : Object, Term { - public string node {get; construct;} - public uint id {get; construct;} - public uint creation {get; construct;} - - public Port(Erl.Port port) { - this.create(array_to_string(port.node, Erl.MAXATOMLEN), port.id, port.creation); - } - - private Port.create(string node0, uint id0, uint creation0) { - Object(node: node0, id: id0, creation: creation0); - } - - public string to_string() { - return "#Port"; - } - - 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 Port)) - return false; - - Port p = o as Port; - - return (node == p.node && id == p.id && creation == p.creation); - } - - public void encode(Erl.Buffer buffer) { - Erl.Port port = Erl.Port(); - char[]? nodedata = string_to_array(node); - assert(nodedata != null); - - Memory.copy(port.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length)); - port.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0; - - port.id = id; - port.creation = creation; - - buffer.encode_port(port); - } - } - - public class Ref : Object, Term { - public string node {get; construct;} - public int len {get; construct;} - public uint[] n {get; private set;} - public uint creation {get; construct;} - - public Ref(Erl.Ref reference) { - this.create(array_to_string(reference.node, Erl.MAXATOMLEN), reference.len, reference.n, reference.creation); - } - - private Ref.create(string node0, int len0, uint* n0, uint creation0) { - Object(node: node0, len: len0, creation: creation0); - - n = new uint[len]; - for(int i = 0; i < len; ++i) { - n[i] = n0[i]; - } - } - - public string to_string() { - return "#Ref"; - } - - 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 Ref)) - return false; - - Ref r = o as Ref; - - if(node != r.node || len != r.len || creation != r.creation) { - return false; - } - - for(int i = 0; i < len; ++i) { - if(n[i] != r.n[i]) - return false; - } - - return true; - } - - public void encode(Erl.Buffer buffer) { - Erl.Ref reference = Erl.Ref(); - char[]? nodedata = string_to_array(node); - assert(nodedata != null); - - Memory.copy(reference.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length)); - reference.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0; - - reference.len = len; - - for(int i = 0; i < len; ++i) { - reference.n[i] = n[i]; - } - - reference.creation = creation; - - buffer.encode_ref(reference); - } - } - - public class Var : Term, Object { - public string name {get; construct;} - - public Var(string name0) { - assert(name0.get_char() == '_' || name0.get_char().isupper()); - - Object(name: name0); - } - - public string to_string() { - return name; - } - - internal static string alias(string key, Gee.Map aliases) { - if(!(key in aliases)) - return key; - else - return alias(aliases[key], aliases); - } - - protected bool do_match(Term o, Gee.Map vars, Gee.Map aliases) { - string key = alias(name, aliases); - - if(o is Var) { - Var v = o as Var; - string vkey = alias(v.name, aliases); - - if(key == vkey) - return true; - - if(key in vars && vkey in vars) - return vars[key].do_match(vars[vkey], vars, aliases); - else if(!(vkey in vars)) { - aliases[vkey] = key; - return true; - } - else /* !(key in vars) */ { - aliases[key] = vkey; - return true; - } - } - else { - if(key in vars) { - return vars[key].do_match(o, vars, aliases); - } - else { - vars[key] = o; - return true; - } - } - } - - public void encode(Erl.Buffer buffer) { - assert_not_reached(); - } - } } diff --git a/src/Tuple.vala b/src/Tuple.vala new file mode 100644 index 0000000..097973f --- /dev/null +++ b/src/Tuple.vala @@ -0,0 +1,67 @@ +namespace Eva { + public class Tuple : Object, Term { + private Term[] elements {get; set;} + + public Tuple(Term[] terms) { + elements = terms; + } + + public int size { + get { + return elements.length; + } + } + + public new unowned Term get(int i) { + assert(i >= 0 && i < size); + + return elements[i]; + } + + public string to_string() { + string ret = "{"; + bool first = true; + + foreach(Term term in elements) { + if(first) { + first = false; + ret += term.to_string(); + } + else { + ret += "," + term.to_string(); + } + } + + return ret + "}"; + } + + 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 Tuple)) + return false; + + Tuple t = o as Tuple; + + if(t.size != size) + return false; + + for(int i = 0; i < size; ++i) { + if(!this[i].do_match(t[i], vars, aliases)) + return false; + } + + return true; + } + + public void encode(Erl.Buffer buffer) { + buffer.encode_tuple_header(size); + + foreach(Term term in elements) { + term.encode(buffer); + } + } + } +} diff --git a/src/UInt.vala b/src/UInt.vala new file mode 100644 index 0000000..a7ea4f8 --- /dev/null +++ b/src/UInt.vala @@ -0,0 +1,34 @@ +namespace Eva { + public class UInt : Object, Term { + public ulong value {get; construct;} + + public UInt(ulong v) { + Object(value: v); + } + + public string to_string() { + return value.to_string(); + } + + 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 Int) { + return value == (o as Int).value; + } + else if(o is UInt) { + return value == (o as UInt).value; + } + else { + return false; + } + } + + + public void encode(Erl.Buffer buffer) { + buffer.encode_ulong(value); + } + } +} diff --git a/src/Var.vala b/src/Var.vala new file mode 100644 index 0000000..1437ede --- /dev/null +++ b/src/Var.vala @@ -0,0 +1,58 @@ +namespace Eva { + public class Var : Object, Term { + public string name {get; construct;} + + public Var(string name0) { + assert(name0.get_char() == '_' || name0.get_char().isupper()); + + Object(name: name0); + } + + public string to_string() { + return name; + } + + internal static string alias(string key, Gee.Map aliases) { + if(!(key in aliases)) + return key; + else + return alias(aliases[key], aliases); + } + + protected bool do_match(Term o, Gee.Map vars, Gee.Map aliases) { + string key = alias(name, aliases); + + if(o is Var) { + Var v = o as Var; + string vkey = alias(v.name, aliases); + + if(key == vkey) + return true; + + if(key in vars && vkey in vars) + return vars[key].do_match(vars[vkey], vars, aliases); + else if(!(vkey in vars)) { + aliases[vkey] = key; + return true; + } + else /* !(key in vars) */ { + aliases[key] = vkey; + return true; + } + } + else { + if(key in vars) { + return vars[key].do_match(o, vars, aliases); + } + else { + vars[key] = o; + return true; + } + } + } + + public void encode(Erl.Buffer buffer) { + assert_not_reached(); + } + } +} -- cgit v1.2.3