summaryrefslogtreecommitdiff
path: root/gruel/src/lib/pmt
diff options
context:
space:
mode:
Diffstat (limited to 'gruel/src/lib/pmt')
-rw-r--r--gruel/src/lib/pmt/pmt.cc222
-rw-r--r--gruel/src/lib/pmt/pmt_int.h17
-rw-r--r--gruel/src/lib/pmt/pmt_io.cc25
-rw-r--r--gruel/src/lib/pmt/qa_pmt_prims.cc86
-rw-r--r--gruel/src/lib/pmt/qa_pmt_prims.h2
5 files changed, 345 insertions, 7 deletions
diff --git a/gruel/src/lib/pmt/pmt.cc b/gruel/src/lib/pmt/pmt.cc
index fd4035f75..f0e3c30a2 100644
--- a/gruel/src/lib/pmt/pmt.cc
+++ b/gruel/src/lib/pmt/pmt.cc
@@ -128,6 +128,12 @@ _vector(pmt_t x)
return dynamic_cast<pmt_vector*>(x.get());
}
+static pmt_tuple *
+_tuple(pmt_t x)
+{
+ return dynamic_cast<pmt_tuple*>(x.get());
+}
+
static pmt_uniform_vector *
_uniform_vector(pmt_t x)
{
@@ -497,6 +503,201 @@ pmt_vector_fill(pmt_t vector, pmt_t obj)
}
////////////////////////////////////////////////////////////////////////////
+// Tuples
+////////////////////////////////////////////////////////////////////////////
+
+pmt_tuple::pmt_tuple(size_t len)
+ : d_v(len)
+{
+}
+
+pmt_t
+pmt_tuple::ref(size_t k) const
+{
+ if (k >= length())
+ throw pmt_out_of_range("pmt_tuple_ref", pmt_from_long(k));
+ return d_v[k];
+}
+
+bool
+pmt_is_tuple(pmt_t obj)
+{
+ return obj->is_tuple();
+}
+
+pmt_t
+pmt_tuple_ref(const pmt_t &tuple, size_t k)
+{
+ if (!tuple->is_tuple())
+ throw pmt_wrong_type("pmt_tuple_ref", tuple);
+ return _tuple(tuple)->ref(k);
+}
+
+// for (i=0; i < 10; i++)
+// make_constructor()
+
+pmt_t
+pmt_make_tuple()
+{
+ return pmt_t(new pmt_tuple(0));
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0)
+{
+ pmt_tuple *t = new pmt_tuple(1);
+ t->_set(0, e0);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1)
+{
+ pmt_tuple *t = new pmt_tuple(2);
+ t->_set(0, e0);
+ t->_set(1, e1);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2)
+{
+ pmt_tuple *t = new pmt_tuple(3);
+ t->_set(0, e0);
+ t->_set(1, e1);
+ t->_set(2, e2);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3)
+{
+ pmt_tuple *t = new pmt_tuple(4);
+ t->_set(0, e0);
+ t->_set(1, e1);
+ t->_set(2, e2);
+ t->_set(3, e3);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4)
+{
+ pmt_tuple *t = new pmt_tuple(5);
+ t->_set(0, e0);
+ t->_set(1, e1);
+ t->_set(2, e2);
+ t->_set(3, e3);
+ t->_set(4, e4);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5)
+{
+ pmt_tuple *t = new pmt_tuple(6);
+ t->_set(0, e0);
+ t->_set(1, e1);
+ t->_set(2, e2);
+ t->_set(3, e3);
+ t->_set(4, e4);
+ t->_set(5, e5);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6)
+{
+ pmt_tuple *t = new pmt_tuple(7);
+ t->_set(0, e0);
+ t->_set(1, e1);
+ t->_set(2, e2);
+ t->_set(3, e3);
+ t->_set(4, e4);
+ t->_set(5, e5);
+ t->_set(6, e6);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7)
+{
+ pmt_tuple *t = new pmt_tuple(8);
+ t->_set(0, e0);
+ t->_set(1, e1);
+ t->_set(2, e2);
+ t->_set(3, e3);
+ t->_set(4, e4);
+ t->_set(5, e5);
+ t->_set(6, e6);
+ t->_set(7, e7);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8)
+{
+ pmt_tuple *t = new pmt_tuple(9);
+ t->_set(0, e0);
+ t->_set(1, e1);
+ t->_set(2, e2);
+ t->_set(3, e3);
+ t->_set(4, e4);
+ t->_set(5, e5);
+ t->_set(6, e6);
+ t->_set(7, e7);
+ t->_set(8, e8);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9)
+{
+ pmt_tuple *t = new pmt_tuple(10);
+ t->_set(0, e0);
+ t->_set(1, e1);
+ t->_set(2, e2);
+ t->_set(3, e3);
+ t->_set(4, e4);
+ t->_set(5, e5);
+ t->_set(6, e6);
+ t->_set(7, e7);
+ t->_set(8, e8);
+ t->_set(9, e9);
+ return pmt_t(t);
+}
+
+pmt_t
+pmt_to_tuple(const pmt_t &x)
+{
+ if (x->is_tuple()) // already one
+ return x;
+
+ size_t len = pmt_length(x);
+ pmt_tuple *t = new pmt_tuple(len);
+ pmt_t r = pmt_t(t);
+
+ if (x->is_vector()){
+ for (size_t i = 0; i < len; i++)
+ t->_set(i, _vector(x)->ref(i));
+ return r;
+ }
+
+ if (x->is_pair()){
+ pmt_t y = x;
+ for (size_t i = 0; i < len; i++){
+ t->_set(i, pmt_car(y));
+ y = pmt_cdr(y);
+ }
+ return r;
+ }
+
+ throw pmt_wrong_type("pmt_to_tuple", x);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
// Uniform Numeric Vectors
////////////////////////////////////////////////////////////////////////////
@@ -730,6 +931,19 @@ pmt_equal(const pmt_t& x, const pmt_t& y)
return true;
}
+ if (x->is_tuple() && y->is_tuple()){
+ pmt_tuple *xv = _tuple(x);
+ pmt_tuple *yv = _tuple(y);
+ if (xv->length() != yv->length())
+ return false;
+
+ for (unsigned i = 0; i < xv->length(); i++)
+ if (!pmt_equal(xv->_ref(i), yv->_ref(i)))
+ return false;
+
+ return true;
+ }
+
if (x->is_uniform_vector() && y->is_uniform_vector()){
pmt_uniform_vector *xv = _uniform_vector(x);
pmt_uniform_vector *yv = _uniform_vector(y);
@@ -759,11 +973,15 @@ pmt_length(const pmt_t& x)
if (x->is_uniform_vector())
return _uniform_vector(x)->length();
- if (x->is_null()) return 0;
+ if (x->is_tuple())
+ return _tuple(x)->length();
+
+ if (x->is_null())
+ return 0;
if (x->is_pair()) {
size_t length=1;
- pmt_t it = pmt_cdr(x);
+ pmt_t it = pmt_cdr(x);
while (pmt_is_pair(it)){
length++;
it = pmt_cdr(it);
diff --git a/gruel/src/lib/pmt/pmt_int.h b/gruel/src/lib/pmt/pmt_int.h
index ba865b418..7581845f8 100644
--- a/gruel/src/lib/pmt/pmt_int.h
+++ b/gruel/src/lib/pmt/pmt_int.h
@@ -51,6 +51,7 @@ public:
virtual bool is_complex() const { return false; }
virtual bool is_null() const { return false; }
virtual bool is_pair() const { return false; }
+ virtual bool is_tuple() const { return false; }
virtual bool is_vector() const { return false; }
virtual bool is_dict() const { return false; }
virtual bool is_any() const { return false; }
@@ -186,6 +187,22 @@ public:
pmt_t _ref(size_t k) const { return d_v[k]; }
};
+class pmt_tuple : public pmt_base
+{
+ std::vector<pmt_t> d_v;
+
+public:
+ pmt_tuple(size_t len);
+ //~pmt_tuple();
+
+ bool is_tuple() const { return true; }
+ pmt_t ref(size_t k) const;
+ size_t length() const { return d_v.size(); }
+
+ pmt_t _ref(size_t k) const { return d_v[k]; }
+ void _set(size_t k, pmt_t v) { d_v[k] = v; }
+};
+
class pmt_dict : public pmt_base
{
pmt_t d_alist; // list of (key . value) pairs
diff --git a/gruel/src/lib/pmt/pmt_io.cc b/gruel/src/lib/pmt/pmt_io.cc
index f5a82de0e..179e6b72c 100644
--- a/gruel/src/lib/pmt/pmt_io.cc
+++ b/gruel/src/lib/pmt/pmt_io.cc
@@ -80,16 +80,31 @@ pmt_write(pmt_t obj, std::ostream &port)
port << "(";
pmt_write_list_tail(obj, port);
}
+ else if (pmt_is_tuple(obj)){
+ port << "{";
+ size_t len = pmt_length(obj);
+ if (len > 0){
+ port << pmt_tuple_ref(obj, 0);
+ for (size_t i = 1; i < len; i++)
+ port << " " << pmt_tuple_ref(obj, i);
+ }
+ port << "}";
+ }
+ else if (pmt_is_vector(obj)){
+ port << "#(";
+ size_t len = pmt_length(obj);
+ if (len > 0){
+ port << pmt_vector_ref(obj, 0);
+ for (size_t i = 1; i < len; i++)
+ port << " " << pmt_vector_ref(obj, i);
+ }
+ port << ")";
+ }
else if (pmt_is_dict(obj)){
// FIXME
// port << "#<dict " << obj << ">";
port << "#<dict>";
}
- else if (pmt_is_vector(obj)){
- // FIXME
- // port << "#<vector " << obj << ">";
- port << "#<vector>";
- }
else if (pmt_is_uniform_vector(obj)){
// FIXME
// port << "#<uniform-vector " << obj << ">";
diff --git a/gruel/src/lib/pmt/qa_pmt_prims.cc b/gruel/src/lib/pmt/qa_pmt_prims.cc
index b81354721..899674bbb 100644
--- a/gruel/src/lib/pmt/qa_pmt_prims.cc
+++ b/gruel/src/lib/pmt/qa_pmt_prims.cc
@@ -193,6 +193,91 @@ qa_pmt_prims::test_vectors()
CPPUNIT_ASSERT_EQUAL(s0, pmt_vector_ref(v1, i));
}
+static void
+check_tuple(size_t len, const std::vector<pmt_t> &s, pmt_t t)
+{
+ CPPUNIT_ASSERT_EQUAL(true, pmt_is_tuple(t));
+ CPPUNIT_ASSERT_EQUAL(len, pmt_length(t));
+
+ for (size_t i = 0; i < len; i++)
+ CPPUNIT_ASSERT_EQUAL(s[i], pmt_tuple_ref(t, i));
+
+}
+
+void
+qa_pmt_prims::test_tuples()
+{
+ pmt_t v = pmt_make_vector(10, PMT_NIL);
+ std::vector<pmt_t> s(10);
+ for (size_t i = 0; i < 10; i++){
+ std::ostringstream os;
+ os << "s" << i;
+ s[i] = pmt_string_to_symbol(os.str());
+ pmt_vector_set(v, i, s[i]);
+ }
+
+
+ pmt_t t;
+
+ t = pmt_make_tuple();
+ check_tuple(0, s, t);
+
+ t = pmt_make_tuple(s[0]);
+ check_tuple(1, s, t);
+
+ CPPUNIT_ASSERT(pmt_is_vector(v));
+ CPPUNIT_ASSERT(!pmt_is_tuple(v));
+ CPPUNIT_ASSERT(pmt_is_tuple(t));
+ CPPUNIT_ASSERT(!pmt_is_vector(t));
+
+ t = pmt_make_tuple(s[0], s[1]);
+ check_tuple(2, s, t);
+
+ t = pmt_make_tuple(s[0], s[1], s[2]);
+ check_tuple(3, s, t);
+
+ t = pmt_make_tuple(s[0], s[1], s[2], s[3]);
+ check_tuple(4, s, t);
+
+ t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4]);
+ check_tuple(5, s, t);
+
+ t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5]);
+ check_tuple(6, s, t);
+
+ t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
+ check_tuple(7, s, t);
+
+ t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]);
+ check_tuple(8, s, t);
+
+ t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8]);
+ check_tuple(9, s, t);
+
+ t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);
+ check_tuple(10, s, t);
+
+ t = pmt_make_tuple(s[0], s[1], s[2]);
+ CPPUNIT_ASSERT_THROW(pmt_tuple_ref(t, 3), pmt_out_of_range);
+ CPPUNIT_ASSERT_THROW(pmt_vector_ref(t, 0), pmt_wrong_type);
+ CPPUNIT_ASSERT_THROW(pmt_tuple_ref(v, 0), pmt_wrong_type);
+
+ t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);
+ pmt_t t2 = pmt_to_tuple(v);
+ CPPUNIT_ASSERT_EQUAL(size_t(10), pmt_length(v));
+ CPPUNIT_ASSERT(pmt_equal(t, t2));
+ //std::cout << v << std::endl;
+ //std::cout << t2 << std::endl;
+
+
+ t = pmt_make_tuple(s[0], s[1], s[2]);
+ pmt_t list0 = pmt_list3(s[0], s[1], s[2]);
+ CPPUNIT_ASSERT_EQUAL(size_t(3), pmt_length(list0));
+ t2 = pmt_to_tuple(list0);
+ CPPUNIT_ASSERT_EQUAL(size_t(3), pmt_length(t2));
+ CPPUNIT_ASSERT(pmt_equal(t, t2));
+}
+
void
qa_pmt_prims::test_equivalence()
{
@@ -436,3 +521,4 @@ qa_pmt_prims::test_sets()
CPPUNIT_ASSERT(!pmt_subsetp(l2,l1));
CPPUNIT_ASSERT(!pmt_subsetp(l3,l2));
}
+
diff --git a/gruel/src/lib/pmt/qa_pmt_prims.h b/gruel/src/lib/pmt/qa_pmt_prims.h
index effb3a097..2fe473c43 100644
--- a/gruel/src/lib/pmt/qa_pmt_prims.h
+++ b/gruel/src/lib/pmt/qa_pmt_prims.h
@@ -35,6 +35,7 @@ class qa_pmt_prims : public CppUnit::TestCase {
CPPUNIT_TEST(test_complexes);
CPPUNIT_TEST(test_pairs);
CPPUNIT_TEST(test_vectors);
+ CPPUNIT_TEST(test_tuples);
CPPUNIT_TEST(test_equivalence);
CPPUNIT_TEST(test_misc);
CPPUNIT_TEST(test_dict);
@@ -53,6 +54,7 @@ class qa_pmt_prims : public CppUnit::TestCase {
void test_complexes();
void test_pairs();
void test_vectors();
+ void test_tuples();
void test_equivalence();
void test_misc();
void test_dict();