tuscany-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jsdelf...@apache.org
Subject svn commit: r829699 - in /tuscany/cpp/sca: kernel/ modules/atom/ modules/eval/ modules/json/
Date Mon, 26 Oct 2009 05:13:06 GMT
Author: jsdelfino
Date: Mon Oct 26 05:13:06 2009
New Revision: 829699

URL: http://svn.apache.org/viewvc?rev=829699&view=rev
Log:
Minor refactoring, given each module its own namespace. Added utility functions to convert between values elements/attributes and fixed XML, ATOM and JSON serialization of lists.

Modified:
    tuscany/cpp/sca/kernel/element.hpp
    tuscany/cpp/sca/kernel/function.hpp
    tuscany/cpp/sca/kernel/kernel-test.cpp
    tuscany/cpp/sca/kernel/list.hpp
    tuscany/cpp/sca/kernel/value.hpp
    tuscany/cpp/sca/kernel/xml.hpp
    tuscany/cpp/sca/modules/atom/atom-test.cpp
    tuscany/cpp/sca/modules/atom/atom.hpp
    tuscany/cpp/sca/modules/eval/Makefile.am
    tuscany/cpp/sca/modules/eval/driver.hpp
    tuscany/cpp/sca/modules/eval/environment.hpp
    tuscany/cpp/sca/modules/eval/eval-shell.cpp
    tuscany/cpp/sca/modules/eval/eval-test.cpp
    tuscany/cpp/sca/modules/eval/eval.hpp
    tuscany/cpp/sca/modules/eval/primitive.hpp
    tuscany/cpp/sca/modules/eval/read.hpp
    tuscany/cpp/sca/modules/json/json-test.cpp
    tuscany/cpp/sca/modules/json/json.hpp

Modified: tuscany/cpp/sca/kernel/element.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/element.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/element.hpp (original)
+++ tuscany/cpp/sca/kernel/element.hpp Mon Oct 26 05:13:06 2009
@@ -60,6 +60,13 @@
 }
 
 /**
+ * Returns true if an element has children.
+ */
+const bool elementHasChildren(const list<value>& l) {
+    return !isNil(cddr(l));
+}
+
+/**
  * Returns the children of an element.
  */
 const list<value> elementChildren(const list<value>& l) {
@@ -70,15 +77,11 @@
  * Returns true if an element has a value.
  */
 const value elementHasValue(const list<value>& l) {
-    if (isNil(cddr(l)))
-        return false;
     const list<value> r = reverse(l);
-    if(isList(car(r))) {
-        const list<value> v = car(r);
-        if(isSymbol(car(v))) {
+    if (isSymbol(car(r)))
+        return false;
+    if(isList(car(r)) && isSymbol(car<value>(car(r))))
             return false;
-        }
-    }
     return true;
 }
 
@@ -90,36 +93,122 @@
 }
 
 /**
- * Converts a list of elements to a list of values.
+ * Convert an element to a value.
  */
-const list<value> elementsToValues(const list<value>& e) {
-    if (isNil(e))
-        return list<value>();
-    const value t = car(e);
+const bool elementToValueIsList(const value& v) {
+    if (!isList(v))
+        return false;
+    const list<value> l = v;
+    if(isNil(l))
+        return true;
+    return isList(car(l));
+}
+
+const value elementToValue(const value& t) {
+    const list<value> elementsToValues(const list<value>& e);
+
+    // Convert an attribute
     if (isTaggedList(t, attribute))
-        return cons<value>(mklist(attributeName(t), attributeValue(t)), elementsToValues(cdr(e)));
+        return mklist(attributeName(t), attributeValue(t));
+
+    // Convert an element
     if (isTaggedList(t, element)) {
-        if (elementHasValue(t))
-            return cons<value>(mklist(elementName(t), elementValue(t)), elementsToValues(cdr(e)));
-        return cons<value>(cons(elementName(t), elementsToValues(elementChildren(t))), elementsToValues(cdr(e)));
+
+        // Convert an element's value
+        if (elementHasValue(t)) {
+
+            // Convert a single value
+            if (!elementToValueIsList(elementValue(t)))
+                return mklist(elementName(t), elementValue(t));
+
+            // Convert a list value
+            return cons(elementName(t), mklist<value>(elementsToValues(elementValue(t))));
+        }
+
+        // Convert an element's children
+        return cons(elementName(t), elementsToValues(elementChildren(t)));
     }
-    return cons(t, elementsToValues(cdr(e)));
+
+    // Convert a value
+    if (!isList(t))
+        return t;
+    return elementsToValues(t);
 }
 
 /**
- * Converts a list of values to a list of elements.
+ * Convert a list of elements to a list of values.
  */
-const list<value> valuesToElements(const list<value>& e) {
+const bool elementToValueIsSymbol(const value& v) {
+    if (!isList(v))
+        return false;
+    const list<value> l = v;
+    if (isNil(l))
+        return false;
+    if (!isSymbol(car(l)))
+        return false;
+    return true;
+}
+
+const list<value> elementToValueGroupValues(const value& v, const list<value>& l) {
+    if (isNil(l) || !elementToValueIsSymbol(v) || !elementToValueIsSymbol(car(l))) {
+        return cons(v, l);
+    }
+    if (car<value>(car(l)) != car<value>(v)) {
+        return cons(v, l);
+    }
+    if (!elementToValueIsList(cadr<value>(car(l)))) {
+        const value g = mklist<value>(car<value>(v), mklist<value>(cdr<value>(v), cdr<value>(car(l))));
+        return elementToValueGroupValues(g, cdr(l));
+    }
+    const value g = mklist<value>(car<value>(v), cons<value>(cdr<value>(v), (list<value>)cadr<value>(car(l))));
+    return elementToValueGroupValues(g, cdr(l));
+
+}
+
+const list<value> elementsToValues(const list<value>& e) {
     if (isNil(e))
         return list<value>();
-    const value t = car(e);
-    if (isList(t)) {
+    const value v = elementToValue(car(e));
+    const list<value> n = elementsToValues(cdr(e));
+    return elementToValueGroupValues(elementToValue(car(e)), elementsToValues(cdr(e)));
+}
+
+/**
+ * Convert a value to an element.
+ */
+const value valueToElement(const value& t) {
+    const list<value> valuesToElements(const list<value>& l);
+
+    // Convert a name value pair
+    if (isList(t) && isSymbol(car<value>(t))) {
+        const value n = car<value>(t);
         const value v = cadr<value>(t);
+
+        // Convert a single value
         if (!isList(v))
-            return cons<value>(mklist(attribute, car<value>(t), v), valuesToElements(cdr(e)));
-        return cons<value>(cons(element, cons(car<value>(t), valuesToElements(cdr<value>(t)))), valuesToElements(cdr(e)));
+            return mklist(element, n, v);
+
+        // Convert a list value
+        if (!isSymbol(car<value>(v)))
+            return cons(element, cons(n, mklist<value>(valuesToElements(v))));
+
+        // Convert a nested name value pair value
+        return cons(element, cons(n, valuesToElements(cdr<value>(t))));
     }
-    return cons(t, valuesToElements(cdr(e)));
+
+    // Convert a value
+    if (!isList(t))
+        return t;
+    return valuesToElements(t);
+}
+
+/**
+ * Convert a list of values to a list of elements.
+ */
+const list<value> valuesToElements(const list<value>& l) {
+    if (isNil(l))
+        return list<value>();
+    return cons<value>(valueToElement(car(l)), valuesToElements(cdr(l)));
 }
 
 /**
@@ -130,19 +219,19 @@
     const list<value> select;
     selectorLambda(const list<value>& s) : select(s) {
     }
-    const bool eval(const list<value>& s, const list<value> v) const {
+    const bool evalApply(const list<value>& s, const list<value> v) const {
         if (isNil(s))
             return true;
         if (isNil(v))
             return false;
         if (car(s) != car(v))
             return false;
-        return eval(cdr(s), cdr(v));
+        return evalApply(cdr(s), cdr(v));
     }
     const bool operator()(const value& v) const {
         if (!isList(v))
             return false;
-        return eval(select, v);
+        return evalApply(select, v);
     }
 };
 

Modified: tuscany/cpp/sca/kernel/function.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/function.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/function.hpp (original)
+++ tuscany/cpp/sca/kernel/function.hpp Mon Oct 26 05:13:06 2009
@@ -139,7 +139,7 @@
 
     const lambda& operator=(const lambda& l) {
         if (this == &l)
-        return *this;
+            return *this;
         callable = l.callable;
         return *this;
     }
@@ -150,7 +150,7 @@
 
     const bool operator==(const lambda& l) const {
         if (this == &l)
-        return true;
+            return true;
         return callable == l.callable;
     }
 

Modified: tuscany/cpp/sca/kernel/kernel-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/kernel-test.cpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/kernel-test.cpp (original)
+++ tuscany/cpp/sca/kernel/kernel-test.cpp Mon Oct 26 05:13:06 2009
@@ -34,6 +34,7 @@
 #include "slist.hpp"
 #include "parallel.hpp"
 #include "value.hpp"
+#include "element.hpp"
 #include "xml.hpp"
 #include "monad.hpp"
 
@@ -67,6 +68,12 @@
     assert(incf(1) == 11);
     assert(mapLambda(incf, 1) == 11);
     assert(mapLambda(inc(10), 1) == 11);
+
+    lambda<int(int)> l;
+    l = incf;
+    assert(l(1) == 11);
+    l = square;
+    assert(l(2) == 4);
     return true;
 }
 
@@ -115,11 +122,23 @@
     return true;
 }
 
+bool testSet() {
+    list<int> l = mklist(1, 2, 3);
+    setCar(l, 4);
+    setCdr(l, mklist(5, 6));
+    assert(car(l) == 4);
+    assert(cadr(l) == 5);
+    assert(caddr(l) == 6);
+    assert(isNil(cdddr(l)));
+    return true;
+}
+
 bool testListGC() {
     resetLambdaCounters();
     resetListCounters();
     countElements = 0;
     testCons();
+    testSet();
     assert(countLambdas == 0);
     assert(countlists == 0);
     assert(countElements == 0);
@@ -133,7 +152,7 @@
 
     std::ostringstream os2;
     os2 << mklist(1, 2, 3);
-    assert(os2.str() == "(1, (2, (3, ())))");
+    assert(os2.str() == "(1, 2, 3)");
     return true;
 }
 
@@ -329,18 +348,6 @@
     return true;
 }
 
-bool testElement() {
-    const list<value> ad = mklist<value>(mklist<value>(attribute, "city", std::string("san francisco")), mklist<value>(attribute, "state", std::string("ca")));
-    const list<value> ac = mklist<value>(mklist<value>(attribute, "id", std::string("1234")), mklist<value>(attribute, "balance", 1000));
-    const list<value> cr = mklist<value>(mklist<value> (attribute, "name", std::string("jdoe")), cons<value>(element, cons<value>("address", ad)), cons<value>(element, cons<value>("account", ac)));
-    const list<value> c = mklist<value>(cons<value>(element, cons<value>("customer", cr)));
-
-    const list<value> v = elementsToValues(c);
-    const list<value> e = valuesToElements(v);
-    assert(e == c);
-    return true;
-}
-
 double fib_aux(double n, double a, double b) {
     if(n == 0.0)
         return a;
@@ -487,9 +494,12 @@
 "<name>jdoe</name>"
 "<address><city>san francisco</city><state>ca</state></address>"
 "<account><id>1234</id><balance>1000</balance></account>"
+"<account><id>6789</id><balance>2000</balance></account>"
+"<account><id>4567</id><balance>3000</balance></account>"
 "</customer>"
 "\n";
 
+
 const bool isName(const value& token) {
     return isTaggedList(token, attribute) && attributeName(token) == "name";
 }
@@ -534,6 +544,44 @@
     return true;
 }
 
+bool testElement() {
+    {
+        const list<value> ad = mklist<value>(mklist<value>("city", std::string("san francisco")), mklist<value>("state", std::string("ca")));
+        const list<value> ac1 = mklist<value>(mklist<value>("id", std::string("1234")), mklist<value>("balance", 1000));
+        const list<value> ac2 = mklist<value>(mklist<value>("id", std::string("6789")), mklist<value>("balance", 2000));
+        const list<value> ac3 = mklist<value>(mklist<value>("id", std::string("4567")), mklist<value>("balance", 3000));
+        {
+            const list<value> c = mklist<value>(mklist<value>("customer", mklist<value>("name", std::string("jdoe")), cons<value>("address", ad), mklist<value>("account", mklist<value>(ac1, ac2, ac3))));
+            const list<value> e = valuesToElements(c);
+            const list<value> v = elementsToValues(e);
+            assert(v == c);
+
+            std::ostringstream os;
+            writeXML<std::ostringstream*>(xmlWriter, &os, e);
+            assert(os.str() == customerXML);
+        }
+        {
+            const list<value> c = mklist<value>(mklist<value>("customer", mklist<value>("name", std::string("jdoe")), cons<value>("address", ad), cons<value>("account", ac1), cons<value>("account", ac2), cons<value>("account", ac3)));
+            const list<value> e = valuesToElements(c);
+            const list<value> v = elementsToValues(e);
+
+            std::ostringstream os;
+            writeXML<std::ostringstream*>(xmlWriter, &os, e);
+            assert(os.str() == customerXML);
+        }
+    }
+    {
+        std::istringstream is(customerXML);
+        const list<value> c = readXML(streamList(is));
+        const list<value> v = elementsToValues(c);
+        const list<value> e = valuesToElements(v);
+        std::ostringstream os;
+        writeXML<std::ostringstream*>(xmlWriter, &os, e);
+        assert(os.str() == customerXML);
+    }
+    return true;
+}
+
 const id<int> idF(const int v) {
     return v * 2;
 }
@@ -644,6 +692,7 @@
     tuscany::testLambda();
     tuscany::testLambdaGC();
     tuscany::testCons();
+    tuscany::testSet();
     tuscany::testListGC();
     tuscany::testOut();
     tuscany::testEquals();

Modified: tuscany/cpp/sca/kernel/list.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/list.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/list.hpp (original)
+++ tuscany/cpp/sca/kernel/list.hpp Mon Oct 26 05:13:06 2009
@@ -114,7 +114,10 @@
 
     template<typename X> friend const bool isNil(const list<X>& p);
     template<typename X> friend const X car(const list<X>& p);
-    template<typename X> friend list<X> const cdr(const list<X>& p);
+    template<typename X> friend const list<X> cdr(const list<X>& p);
+    template<typename X> friend const bool setCar(list<X>& p, const X& car);
+    template<typename X> friend const bool setCdr(list<X>& p, const list<X>& cdr);
+    template<typename X> friend const bool setCdr(list<X>& p, const lambda<list<X> ()>& cdr);
 
 private:
     T car;
@@ -131,10 +134,19 @@
 /**
  * Write a list to an output stream.
  */
-template<typename X> std::ostream& operator<<(std::ostream& out, const list<X>& l) {
+template<typename T> std::ostream& operator<<(std::ostream& out, const list<T>& l) {
     if(isNil(l))
         return out << "()";
-    return out << "(" << car(l) << ", " << cdr(l) << ")";
+    out << "(";
+    list<T> ml = l;
+    while(true) {
+        out << car(ml);
+        ml = cdr(ml);
+        if (isNil(ml))
+            break;
+        out << ", ";
+    }
+    return out << ")";
 }
 
 /**
@@ -194,6 +206,13 @@
 }
 
 /**
+ * Construct a list of six values.
+ */
+template<typename T> const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) {
+    return cons(a, cons(b, cons(c, cons(d, cons(e, mklist(f))))));
+}
+
+/**
  * Returns the car of a list.
  */
 template<typename T> const T car(const list<T>& p) {
@@ -203,11 +222,36 @@
 /**
  * Returns the cdr of a list.
  */
-template<typename T> list<T> const cdr(const list<T>& p) {
+template<typename T> const list<T> cdr(const list<T>& p) {
     return p.cdr();
 }
 
 /**
+ * Sets the car of a list.
+ */
+template<typename T> const bool setCar(list<T>& p, const T& car) {
+    p.car = car;
+    return true;
+}
+
+/**
+ * Sets the cdr of a list.
+ */
+template<typename T> const bool setCdr(list<T>& p, const list<T>& c) {
+    p.cdr = result(c);
+    return true;
+}
+
+/**
+ * Sets the cdr of a list to a lambda function.
+ */
+template<typename T> const bool setCdr(list<T>& p, const lambda<list<T> ()>& cdr) {
+    p.cdr = cdr;
+    return true;
+}
+
+
+/**
  * Returns the car of the cdr of a list.
  */
 template<typename T> const T cadr(const list<T>& p) {
@@ -415,25 +459,6 @@
     return mklist<list<T> >(unzipKeys(l), unzipValues(l));
 }
 
-/**
- * Pretty print a list.
- */
-template<typename T> std::ostream& print(const list<T>& l, std::ostream& os) {
-    os << "(";
-    if (!isNil(l)) {
-        list<T> ml = l;
-        while(true) {
-            os << car(ml);
-            ml = cdr(ml);
-            if (isNil(ml))
-                break;
-            os << ", ";
-        }
-    }
-    os << ")";
-    return os;
-}
-
 }
 
 #endif /* tuscany_list_hpp */

Modified: tuscany/cpp/sca/kernel/value.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/value.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/value.hpp (original)
+++ tuscany/cpp/sca/kernel/value.hpp Mon Oct 26 05:13:06 2009
@@ -324,24 +324,24 @@
 std::ostream& operator<<(std::ostream& out, const value& v) {
     switch(v.type) {
     case value::List:
-        return out << "List::" << v.lst()();
+        return out << v.lst()();
     case value::Lambda:
-        return out << "Lambda::" << v.func();
+        return out << "lambda::" << v.func();
     case value::Symbol:
-        return out << "Symbol::" << v.str()();
+        return out << "symbol::" << v.str()();
     case value::String:
-        return out << "String::" << '\"' << v.str()() << '\"';
+        return out << "string::" << '\"' << v.str()() << '\"';
     case value::Number:
-        return out << "Number::" << v.num()();
+        return out << "number::" << v.num()();
     case value::Boolean:
         if(v.boo()())
-            return out << "Boolean::" << "true";
+            return out << "bool::" << "true";
         else
-            return out << "Boolean::" << "false";
+            return out << "bool::" << "false";
     case value::Character:
-        return out << "Character::" << v.chr()();
+        return out << "char::" << v.chr()();
     default:
-        return out << "Undefined";
+        return out << "undefined";
     }
 }
 
@@ -383,28 +383,5 @@
     return false;
 }
 
-/**
- * Pretty print a list of values.
- */
-std::ostream& print(const list<value>& l, std::ostream& os) {
-    os << "(";
-    if (!isNil(l)) {
-        list<value> ml = l;
-        while(true) {
-            const value v = car(ml);
-            if (isList(v))
-                print(list<value>(v), os);
-            else
-                os << v;
-            ml = cdr(ml);
-            if (isNil(ml))
-                break;
-            os << ", ";
-        }
-    }
-    os << ")";
-    return os;
-}
-
 }
 #endif /* tuscany_value_hpp */

Modified: tuscany/cpp/sca/kernel/xml.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/xml.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/xml.hpp (original)
+++ tuscany/cpp/sca/kernel/xml.hpp Mon Oct 26 05:13:06 2009
@@ -32,6 +32,7 @@
 #include <libxml/globals.h>
 #include <string>
 #include "list.hpp"
+#include "slist.hpp"
 #include "value.hpp"
 #include "element.hpp"
 #include "monad.hpp"
@@ -47,7 +48,7 @@
         None = 0, Element = 1, Attribute = 2, Text = 3, EndElement = 15, Identifier = 100, End = 101
     };
 
-    XMLReader(xmlTextReaderPtr xml) : xml(xml), tokenType(None) {
+    XMLReader(xmlTextReaderPtr xml) : xml(xml), tokenType(None), isEmptyElement(false), hasValue(false), hasAttributes(false) {
         xmlTextReaderSetParserProp(xml, XML_PARSER_DEFAULTATTRS, 1);
         xmlTextReaderSetParserProp(xml, XML_PARSER_SUBST_ENTITIES, 1);
     }
@@ -204,9 +205,16 @@
  */
 const char* encoding = "UTF-8";
 
+
 /**
  * Write a list of XML element or attribute tokens.
  */
+const list<value> expandElementValues(const value& n, const list<value>& l) {
+    if (isNil(l))
+        return list<value>();
+    return cons<value>(value(cons<value>(element, cons<value>(n, (list<value>)car(l)))), expandElementValues(n, cdr(l)));
+}
+
 const failable<bool, std::string> writeList(const list<value>& l, const xmlTextWriterPtr xml) {
     if (isNil(l))
         return true;
@@ -219,23 +227,50 @@
 
     } else if (isTaggedList(token, element)) {
 
-        // Write an element
-        if (xmlTextWriterStartElement(xml, (const xmlChar*)std::string(elementName(token)).c_str()) < 0)
-            return std::string("xmlTextWriterStartElement failed");
-
-        // Write its children
-        const failable<bool, std::string> w = writeList(elementChildren(token), xml);
-        if (!hasValue(w))
-            return w;
+        // Write an element containing a value
+        if (elementHasValue(token)) {
+            const value v = elementValue(token);
+            if (isList(v)) {
+
+                // Write an element per entry in a list of values
+                const list<value> e = expandElementValues(elementName(token), v);
+                writeList(e, xml);
+
+            } else {
+
+                // Write an element with a single value
+                if (xmlTextWriterStartElement(xml, (const xmlChar*)std::string(elementName(token)).c_str()) < 0)
+                    return std::string("xmlTextWriterStartElement failed");
+
+                // Write its children
+                const failable<bool, std::string> w = writeList(elementChildren(token), xml);
+                if (!hasValue(w))
+                    return w;
+
+                if (xmlTextWriterEndElement(xml) < 0)
+                    return std::string("xmlTextWriterEndElement failed");
+            }
+        }
+        else {
 
-        if (xmlTextWriterEndElement(xml) < 0)
-            return std::string("xmlTextWriterEndElement failed");
+            // Write an element
+            if (xmlTextWriterStartElement(xml, (const xmlChar*)std::string(elementName(token)).c_str()) < 0)
+                return std::string("xmlTextWriterStartElement failed");
+
+            // Write its children
+            const failable<bool, std::string> w = writeList(elementChildren(token), xml);
+            if (!hasValue(w))
+                return w;
 
+            if (xmlTextWriterEndElement(xml) < 0)
+                return std::string("xmlTextWriterEndElement failed");
+        }
     } else {
 
         // Write XML text
         if (xmlTextWriterWriteString(xml, (const xmlChar*)std::string(token).c_str()) < 0)
             return std::string("xmlTextWriterWriteString failed");
+
     }
 
     // Go on

Modified: tuscany/cpp/sca/modules/atom/atom-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/atom/atom-test.cpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/atom/atom-test.cpp (original)
+++ tuscany/cpp/sca/modules/atom/atom-test.cpp Mon Oct 26 05:13:06 2009
@@ -31,8 +31,9 @@
 #include "atom.hpp"
 
 namespace tuscany {
+namespace atom {
 
-std::ostringstream* atomWriter(std::ostringstream* os, const std::string& s) {
+std::ostringstream* writer(std::ostringstream* os, const std::string& s) {
     (*os) << s;
     return os;
 }
@@ -49,22 +50,49 @@
         "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>"
         "</entry>\n");
 
-bool testATOMEntry() {
+std::string incompleteEntry("<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+        "<title>item</title><content type=\"text/xml\">"
+        "<Item xmlns=\"http://services/\">"
+        "<name xmlns=\"\">Orange</name>"
+        "<price xmlns=\"\">3.55</price>"
+        "</Item>"
+        "</content>"
+        "</entry>");
+
+std::string completedEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+        "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+        "<title type=\"text\">item</title>"
+        "<id></id>"
+        "<content type=\"application/xml\">"
+        "<Item xmlns=\"http://services/\">"
+        "<name xmlns=\"\">Orange</name>"
+        "<price xmlns=\"\">3.55</price>"
+        "</Item>"
+        "</content><link href=\"\"/>"
+        "</entry>\n");
+
+bool testEntry() {
     {
         const list<value> i = list<value>() << element << "item"
                 << (list<value>() << element << "name" << std::string("Apple"))
                 << (list<value>() << element << "price" << std::string("$2.99"));
         const list<value> a = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
         std::ostringstream os;
-        writeATOMEntry<std::ostringstream*>(atomWriter, &os, a);
+        writeEntry<std::ostringstream*>(writer, &os, a);
         assert(os.str() == itemEntry);
     }
     {
-        const list<value> a = readATOMEntry(mklist(itemEntry));
+        const list<value> a = readEntry(mklist(itemEntry));
         std::ostringstream os;
-        writeATOMEntry<std::ostringstream*>(atomWriter, &os, a);
+        writeEntry<std::ostringstream*>(writer, &os, a);
         assert(os.str() == itemEntry);
     }
+    {
+        const list<value> a = readEntry(mklist(incompleteEntry));
+        std::ostringstream os;
+        writeEntry<std::ostringstream*>(writer, &os, a);
+        assert(os.str() == completedEntry);
+    }
     return true;
 }
 
@@ -100,16 +128,16 @@
         "</entry>"
         "</feed>\n");
 
-bool testATOMFeed() {
+bool testFeed() {
     {
         std::ostringstream os;
-        writeATOMFeed<std::ostringstream*>(atomWriter, &os, mklist<value>("Feed", "1234"));
+        writeFeed<std::ostringstream*>(writer, &os, mklist<value>("Feed", "1234"));
         assert(os.str() == emptyFeed);
     }
     {
-        const list<value> a = readATOMFeed(mklist(emptyFeed));
+        const list<value> a = readFeed(mklist(emptyFeed));
         std::ostringstream os;
-        writeATOMFeed<std::ostringstream*>(atomWriter, &os, a);
+        writeFeed<std::ostringstream*>(writer, &os, a);
         assert(os.str() == emptyFeed);
     }
     {
@@ -124,25 +152,41 @@
                         << (list<value>() << element << "price" << "$3.55")));
         const list<value> a = cons<value>("Feed", cons<value>("1234", i));
         std::ostringstream os;
-        writeATOMFeed<std::ostringstream*>(atomWriter, &os, a);
+        writeFeed<std::ostringstream*>(writer, &os, a);
         assert(os.str() == itemFeed);
     }
     {
-        const list<value> a = readATOMFeed(mklist(itemFeed));
+        const list<value> i = list<value>()
+                << (list<value>() << "item" << "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
+                    << valueToElement(list<value>() << "item"
+                        << (list<value>() << "name" << "Apple")
+                        << (list<value>() << "price" << "$2.99")))
+                << (list<value>() << "item" << "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
+                    << valueToElement(list<value>() << "item"
+                        << (list<value>() << "name" << "Orange")
+                        << (list<value>() << "price" << "$3.55")));
+        const list<value> a = cons<value>("Feed", cons<value>("1234", i));
         std::ostringstream os;
-        writeATOMFeed<std::ostringstream*>(atomWriter, &os, a);
+        writeFeed<std::ostringstream*>(writer, &os, a);
+        assert(os.str() == itemFeed);
+    }
+    {
+        const list<value> a = readFeed(mklist(itemFeed));
+        std::ostringstream os;
+        writeFeed<std::ostringstream*>(writer, &os, a);
         assert(os.str() == itemFeed);
     }
     return true;
 }
 
 }
+}
 
 int main() {
     std::cout << "Testing..." << std::endl;
 
-    tuscany::testATOMEntry();
-    tuscany::testATOMFeed();
+    tuscany::atom::testEntry();
+    tuscany::atom::testFeed();
 
     std::cout << "OK" << std::endl;
 

Modified: tuscany/cpp/sca/modules/atom/atom.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/atom/atom.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/atom/atom.hpp (original)
+++ tuscany/cpp/sca/modules/atom/atom.hpp Mon Oct 26 05:13:06 2009
@@ -33,40 +33,43 @@
 #include "xml.hpp"
 
 namespace tuscany {
+namespace atom {
 
 /**
  * Convert a list of elements to a list of values representing an ATOM entry.
  */
-const list<value> atomEntry(const list<value>& e) {
-    const list<value> t = filter<value>(selector(mklist<value>(element, "title")), e);
-    const list<value> i = filter<value>(selector(mklist<value>(element, "id")), e);
-    const list<value> c = filter<value>(selector(mklist<value>(element, "content")), e);
-    return mklist<value>(elementValue(car(t)), elementValue(car(i)), cadr(elementChildren(car(c))));
+const list<value> entry(const list<value>& e) {
+    const list<value> lt = filter<value>(selector(mklist<value>(element, "title")), e);
+    const value t = isNil(lt)? value(std::string("")) : elementValue(car(lt));
+    const list<value> li = filter<value>(selector(mklist<value>(element, "id")), e);
+    const value i = isNil(li)? value(std::string("")) : elementValue(car(li));
+    const list<value> lc = filter<value>(selector(mklist<value>(element, "content")), e);
+    return mklist<value>(t, i, cadr(elementChildren(car(lc))));
 }
 
 /**
  * Convert a list of elements to a list of values representing ATOM entries.
  */
-const list<value> atomEntries(const list<value>& e) {
+const list<value> entries(const list<value>& e) {
     if (isNil(e))
         return list<value>();
-    return cons<value>(atomEntry(car(e)), atomEntries(cdr(e)));
+    return cons<value>(entry(car(e)), entries(cdr(e)));
 }
 
 /**
  * Convert a list of strings to a list of values representing an ATOM entry.
  */
-const failable<list<value>, std::string> readATOMEntry(const list<std::string>& ilist) {
+const failable<list<value>, std::string> readEntry(const list<std::string>& ilist) {
     const list<value> e = readXML(ilist);
     if (isNil(e))
         return std::string("Empty entry");
-    return atomEntry(car(e));
+    return entry(car(e));
 }
 
 /**
  * Convert a list of strings to a list of values representing an ATOM feed.
  */
-const failable<list<value>, std::string> readATOMFeed(const list<std::string>& ilist) {
+const failable<list<value>, std::string> readFeed(const list<std::string>& ilist) {
     const list<value> f = readXML(ilist);
     if (isNil(f))
         return std::string("Empty feed");
@@ -75,14 +78,14 @@
     const list<value> e = filter<value>(selector(mklist<value>(element, "entry")), car(f));
     if (isNil(e))
         return mklist<value>(elementValue(car(t)), elementValue(car(i)));
-    return cons<value>(elementValue(car(t)), cons(elementValue(car(i)), atomEntries(e)));
+    return cons<value>(elementValue(car(t)), cons(elementValue(car(i)), entries(e)));
 }
 
 /**
  * Convert a list of values representing an ATOM entry to a list of elements.
  * The first two values in the list are the entry title and id.
  */
-const list<value> atomEntryElement(const list<value>& l) {
+const list<value> entryElement(const list<value>& l) {
     return list<value>()
         << element << "entry" << (list<value>() << attribute << "xmlns" << "http://www.w3.org/2005/Atom")
         << (list<value>() << element << "title" << (list<value>() << attribute << "type" << "text") << car(l))
@@ -94,30 +97,30 @@
 /**
  * Convert a list of values representing ATOM entries to a list of elements.
  */
-const list<value> atomEntriesElements(const list<value>& l) {
+const list<value> entriesElements(const list<value>& l) {
     if (isNil(l))
         return list<value>();
-    return cons<value>(atomEntryElement(car(l)), atomEntriesElements(cdr(l)));
+    return cons<value>(entryElement(car(l)), entriesElements(cdr(l)));
 }
 
 /**
  * Convert a list of values representing an ATOM entry to an ATOM entry.
  * The first two values in the list are the entry id and title.
  */
-template<typename R> const failable<R, std::string> writeATOMEntry(const lambda<R(R, std::string)>& reduce, const R& initial, const list<value>& l) {
-    return writeXML<R>(reduce, initial, mklist<value>(atomEntryElement(l)));
+template<typename R> const failable<R, std::string> writeEntry(const lambda<R(R, std::string)>& reduce, const R& initial, const list<value>& l) {
+    return writeXML<R>(reduce, initial, mklist<value>(entryElement(l)));
 }
 
 /**
  * Convert a list of values representing an ATOM entry to a list of strings.
  * The first two values in the list are the entry id and title.
  */
-const list<std::string> writeATOMList(const list<std::string>& listSoFar, const std::string& s) {
+const list<std::string> writeStrings(const list<std::string>& listSoFar, const std::string& s) {
     return cons(s, listSoFar);
 }
 
-const failable<list<std::string>, std::string> writeATOMEntry(const list<value>& l) {
-    const failable<list<std::string>, std::string> ls = writeATOMEntry<list<std::string> >(writeATOMList, list<std::string>(), l);
+const failable<list<std::string>, std::string> writeEntry(const list<value>& l) {
+    const failable<list<std::string>, std::string> ls = writeEntry<list<std::string> >(writeStrings, list<std::string>(), l);
     if (!hasValue(ls))
         return ls;
     return reverse(list<std::string>(ls));
@@ -127,14 +130,14 @@
  * Convert a list of values representing an ATOM feed to an ATOM feed.
  * The first two values in the list are the feed id and title.
  */
-template<typename R> const failable<R, std::string> writeATOMFeed(const lambda<R(R, std::string)>& reduce, const R& initial, const list<value>& l) {
+template<typename R> const failable<R, std::string> writeFeed(const lambda<R(R, std::string)>& reduce, const R& initial, const list<value>& l) {
     const list<value> f = list<value>()
         << element << "feed" << (list<value>() << attribute << "xmlns" << "http://www.w3.org/2005/Atom")
         << (list<value>() << element << "title" << (list<value>() << attribute << "type" << "text") << car(l))
         << (list<value>() << element << "id" << cadr(l));
     if (isNil(cddr(l)))
         return writeXML<R>(reduce, initial, mklist<value>(f));
-    const list<value> fe = append(f, atomEntriesElements(cddr(l)));
+    const list<value> fe = append(f, entriesElements(cddr(l)));
     return writeXML<R>(reduce, initial, mklist<value>(fe));
 }
 
@@ -142,13 +145,14 @@
  * Convert a list of values representing an ATOM feed to a list of strings.
  * The first two values in the list are the feed id and title.
  */
-const failable<list<std::string>, std::string> writeATOMFeed(const list<value>& l) {
-    const failable<list<std::string>, std::string> ls = writeATOMFeed<list<std::string> >(writeATOMList, list<std::string>(), l);
+const failable<list<std::string>, std::string> writeFeed(const list<value>& l) {
+    const failable<list<std::string>, std::string> ls = writeFeed<list<std::string> >(writeStrings, list<std::string>(), l);
     if (!hasValue(ls))
         return ls;
     return reverse(list<std::string>(ls));
 }
 
 }
+}
 
 #endif /* tuscany_atom_hpp */

Modified: tuscany/cpp/sca/modules/eval/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/eval/Makefile.am?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/eval/Makefile.am (original)
+++ tuscany/cpp/sca/modules/eval/Makefile.am Mon Oct 26 05:13:06 2009
@@ -27,3 +27,6 @@
 
 eval_shell_SOURCES = eval-shell.cpp
 eval_shell_LDADD = -lpthread -L${LIBXML2_LIB} -lxml2
+
+TESTS = eval-test
+

Modified: tuscany/cpp/sca/modules/eval/driver.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/eval/driver.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/eval/driver.hpp (original)
+++ tuscany/cpp/sca/modules/eval/driver.hpp Mon Oct 26 05:13:06 2009
@@ -31,6 +31,7 @@
 #include "eval.hpp"
 
 namespace tuscany {
+namespace eval {
 
 const std::string evalOutputPrompt("; ");
 const std::string evalInputPrompt("=> ");
@@ -57,7 +58,7 @@
     value input = read(in);
     if (isNil(input))
         return input;
-    const value output = eval(input, globalEnv);
+    const value output = evalApply(input, globalEnv);
     announceOutput(out, evalOutputPrompt);
     userPrint(out, output);
     return evalDriverLoop(in, out, globalEnv);
@@ -71,4 +72,5 @@
 }
 
 }
+}
 #endif /* tuscany_eval_driver_hpp */

Modified: tuscany/cpp/sca/modules/eval/environment.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/eval/environment.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/eval/environment.hpp (original)
+++ tuscany/cpp/sca/modules/eval/environment.hpp Mon Oct 26 05:13:06 2009
@@ -31,10 +31,10 @@
 #include "value.hpp"
 #include "primitive.hpp"
 
-namespace tuscany
-{
+namespace tuscany {
+namespace eval {
 
-typedef value Frame;
+typedef list<value> Frame;
 typedef list<value> Env;
 
 const value trueSymbol("true");
@@ -130,28 +130,37 @@
     return car(cdr(cdr((list<value> )exp)));
 }
 
-const Frame addBindingToFrame(const value& var, const value& val, const Frame& frame) {
-    return cons(value(cons(var, frameVariables(frame))), cons(val, frameValues(frame)));
-}
-
-const Env defineVariable(const value& var, const value& val, Env& env) {
-    return cons(addBindingToFrame(var, val, firstFrame(env)), cdr(env));
-}
+const bool addBindingToFrame(const value& var, const value& val, Frame& frame) {
+    //frame = cons(value(cons(var, frameVariables(frame))), cons(val, frameValues(frame)));
+    setCar(frame, (value)cons(var, frameVariables(frame)));
+    setCdr(frame, cons(val, frameValues(frame)));
+    return true;
+}
+
+const bool defineVariable(const value& var, const value& val, Env& env) {
+    Frame frame = firstFrame(env);
+    addBindingToFrame(var, val, frame);
+    setCar(env, value(frame));
+    return true;
+}
+
+struct environmentReference {
+    const Env env;
+    environmentReference(const Env& env) : env(env) {
+    }
+    const Env& operator()() const {
+        return env;
+    }
+};
 
 const Env extendEnvironment(const list<value>& vars, const list<value>& vals, const Env& baseEnv) {
-//    if(length(vars) == length(vals))
-//    else if(length(vars) < length(vals))
-//        std::cout << "Too many arguments supplied " << vars << " " << vals << "\n";
-//    else
-//        std::cout << "Too few arguments supplied " << vars << " " << vals << "\n";
-//    return baseEnv;
-    return cons(makeFrame(vars, vals), baseEnv);
+    return cons(value(makeFrame(vars, vals)), lambda<list<value>()>(environmentReference(baseEnv)));
 }
 
 const Env setupEnvironment() {
     Env env = extendEnvironment(primitiveProcedureNames(), primitiveProcedureObjects(), theEmptyEnvironment());
-    env = defineVariable(trueSymbol, true, env);
-    env = defineVariable(falseSymbol, false, env);
+    defineVariable(trueSymbol, true, env);
+    defineVariable(falseSymbol, false, env);
     return env;
 }
 
@@ -178,4 +187,5 @@
 }
 
 }
+}
 #endif /* tuscany_eval_environment_hpp */

Modified: tuscany/cpp/sca/modules/eval/eval-shell.cpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/eval/eval-shell.cpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/eval/eval-shell.cpp (original)
+++ tuscany/cpp/sca/modules/eval/eval-shell.cpp Mon Oct 26 05:13:06 2009
@@ -30,6 +30,6 @@
 #include "driver.hpp"
 
 int main() {
-    tuscany::evalDriverRun(std::cin, std::cout);
+    tuscany::eval::evalDriverRun(std::cin, std::cout);
     return 0;
 }

Modified: tuscany/cpp/sca/modules/eval/eval-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/eval/eval-test.cpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/eval/eval-test.cpp (original)
+++ tuscany/cpp/sca/modules/eval/eval-test.cpp Mon Oct 26 05:13:06 2009
@@ -30,6 +30,7 @@
 #include "driver.hpp"
 
 namespace tuscany {
+namespace eval {
 
 bool testEnv() {
     Env globalEnv = list<value>();
@@ -109,6 +110,11 @@
   "(define (testLambda) (if (= 4 (sqrt 2)) (display \"testLambda ok\") (error \"testLambda\"))) "
   "(testLambda)");
 
+const std::string testSchemeForward(
+  "(define (testLambda) (if (= 4 (sqrt 2)) (display \"testForward ok\") (error \"testForward\"))) "
+  "(define sqrt (lambda (x) (* x x))) "
+  "(testLambda)");
+
 bool contains(const std::string& str, const std::string& pattern) {
     return str.find(pattern) != str.npos;
 }
@@ -129,13 +135,14 @@
     assert(contains(evalOutput(testSchemeBegin), "testBegin1 ok"));
     assert(contains(evalOutput(testSchemeBegin), "testBegin2 ok"));
     assert(contains(evalOutput(testSchemeLambda), "testLambda ok"));
+    //assert(contains(evalOutput(testSchemeForward), "testForward ok"));
     return true;
 }
 
 bool testEvalExpr() {
     const value exp = mklist<value>("+", 2, 3);
     Env env = setupEnvironment();
-    const value r = eval(exp, env);
+    const value r = evalApply(exp, env);
     assert(r == value(5));
     return true;
 }
@@ -160,16 +167,17 @@
 }
 
 }
+}
 
 int main() {
     std::cout << "Testing..." << std::endl;
 
-    tuscany::testEnv();
-    tuscany::testEnvGC();
-    tuscany::testRead();
-    tuscany::testEval();
-    tuscany::testEvalExpr();
-    tuscany::testEvalGC();
+    tuscany::eval::testEnv();
+    tuscany::eval::testEnvGC();
+    tuscany::eval::testRead();
+    tuscany::eval::testEval();
+    tuscany::eval::testEvalExpr();
+    tuscany::eval::testEvalGC();
 
     std::cout << "OK" << std::endl;
     return 0;

Modified: tuscany/cpp/sca/modules/eval/eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/eval/eval.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/eval/eval.hpp (original)
+++ tuscany/cpp/sca/modules/eval/eval.hpp Mon Oct 26 05:13:06 2009
@@ -33,10 +33,10 @@
 #include "read.hpp"
 #include "environment.hpp"
 
-namespace tuscany
-{
+namespace tuscany {
+namespace eval {
 
-const value eval(const value& exp, Env& env);
+const value evalApply(const value& exp, Env& env);
 
 const value compoundProcedureSymbol("compound-procedure");
 const value procedureSymbol("procedure");
@@ -89,7 +89,7 @@
 const list<value> listOfValues(const list<value> exps, Env& env) {
     if(isNil(exps))
         return list<value> ();
-    return cons(eval(car(exps), env), listOfValues(cdr(exps), env));
+    return cons(evalApply(car(exps), env), listOfValues(cdr(exps), env));
 }
 
 const value applyOperat(const value& exp) {
@@ -134,8 +134,8 @@
 
 const value evalSequence(const list<value>& exps, Env& env) {
     if(isLastExp(exps))
-        return eval(firstExp(exps), env);
-    eval(firstExp(exps), env);
+        return evalApply(firstExp(exps), env);
+    evalApply(firstExp(exps), env);
     return evalSequence(restExp(exps), env);
 }
 
@@ -219,17 +219,17 @@
 }
 
 value evalIf(const value& exp, Env& env) {
-    if(isTrue(eval(ifPredicate(exp), env)))
-        return eval(ifConsequent(exp), env);
-    return eval(ifAlternative(exp), env);
+    if(isTrue(evalApply(ifPredicate(exp), env)))
+        return evalApply(ifConsequent(exp), env);
+    return evalApply(ifAlternative(exp), env);
 }
 
 const value evalDefinition(const value& exp, Env& env) {
-    env = defineVariable(definitionVariable(exp), eval(definitionValue(exp), env), env);
+    defineVariable(definitionVariable(exp), evalApply(definitionValue(exp), env), env);
     return definitionVariable(exp);
 }
 
-const value eval(const value& exp, Env& env) {
+const value evalApply(const value& exp, Env& env) {
     if(isSelfEvaluating(exp))
         return exp;
     if(isQuoted(exp))
@@ -241,22 +241,23 @@
     if(isBegin(exp))
         return evalSequence(beginActions(exp), env);
     if(isCond(exp))
-        return eval(condToIf(exp), env);
+        return evalApply(condToIf(exp), env);
     if(isLambda(exp))
         return makeProcedure(lambdaParameters(exp), lambdaBody(exp), env);
     if(isVariable(exp))
         return lookupVariableValue(exp, env);
     if(isApply(exp)) {
-        list<value> applyOperandValues = eval(applyOperand(exp), env);
-        return applyProcedure(eval(applyOperat(exp), env), applyOperandValues);
+        list<value> applyOperandValues = evalApply(applyOperand(exp), env);
+        return applyProcedure(evalApply(applyOperat(exp), env), applyOperandValues);
     }
     if(isApplication(exp)) {
         list<value> operandValues = listOfValues(operands(exp), env);
-        return applyProcedure(eval(operat(exp), env), operandValues);
+        return applyProcedure(evalApply(operat(exp), env), operandValues);
     }
     std::cout << "Unknown expression type " << exp << "\n";
     return value();
 }
 
 }
+}
 #endif /* tuscany_eval_eval_hpp */

Modified: tuscany/cpp/sca/modules/eval/primitive.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/eval/primitive.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/eval/primitive.hpp (original)
+++ tuscany/cpp/sca/modules/eval/primitive.hpp Mon Oct 26 05:13:06 2009
@@ -31,8 +31,8 @@
 #include "list.hpp"
 #include "value.hpp"
 
-namespace tuscany
-{
+namespace tuscany {
+namespace eval {
 
 const value primitiveSymbol("primitive");
 const value quoteSymbol("'");
@@ -190,4 +190,5 @@
 }
 
 }
+}
 #endif /* tuscany_eval_primitive_hpp */

Modified: tuscany/cpp/sca/modules/eval/read.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/eval/read.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/eval/read.hpp (original)
+++ tuscany/cpp/sca/modules/eval/read.hpp Mon Oct 26 05:13:06 2009
@@ -35,8 +35,8 @@
 #include "value.hpp"
 #include "primitive.hpp"
 
-namespace tuscany
-{
+namespace tuscany {
+namespace eval {
 
 const value rightParenthesis(mklist<value>(")"));
 const value leftParenthesis(mklist<value>("("));
@@ -180,4 +180,5 @@
 }
 
 }
+}
 #endif /* tuscany_eval_read_hpp */

Modified: tuscany/cpp/sca/modules/json/json-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/json/json-test.cpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/json/json-test.cpp (original)
+++ tuscany/cpp/sca/modules/json/json-test.cpp Mon Oct 26 05:13:06 2009
@@ -31,6 +31,7 @@
 #include "json.hpp"
 
 namespace tuscany {
+namespace json {
 
 bool testJSEval() {
     JSONContext cx;
@@ -56,49 +57,75 @@
         const list<value> cr = mklist<value>(mklist<value> (attribute, "name", std::string("jdoe")), cons<value>(element, cons<value>("address", ad)), cons<value>(element, cons<value>("account", ac)));
         const list<value> c = mklist<value>(cons<value>(element, cons<value>("customer", cr)));
         std::ostringstream os;
-        writeJSON<std::ostringstream*>(cx, jsonWriter, &os, c);
+        write<std::ostringstream*>(cx, jsonWriter, &os, c);
         assert(os.str() == "{\"customer\":{\"name\":\"jdoe\",\"address\":{\"city\":\"san francisco\",\"state\":\"ca\"},\"account\":{\"id\":\"1234\",\"balance\":1000}}}");
     }
     {
         const list<value> phones = mklist<value> (std::string("408-1234"), std::string("650-1234"));
-        const list<value> l = mklist<value> (mklist<value> (element, "phones", phones), mklist<value> (attribute, "lastName", std::string("test\ttab")), mklist<value> (attribute, "firstName", std::string("test1")));
+        const list<value> l = mklist<value> (mklist<value> (element, "phones", phones), mklist<value> (element, "lastName", std::string("test\ttab")), mklist<value> (element, "firstName", std::string("test1")));
 
         std::ostringstream os;
-        writeJSON<std::ostringstream*>(cx, jsonWriter, &os, l);
+        write<std::ostringstream*>(cx, jsonWriter, &os, l);
         assert(os.str() == "{\"phones\":[\"408-1234\",\"650-1234\"],\"lastName\":\"test\\u0009tab\",\"firstName\":\"test1\"}");
 
         std::istringstream is(os.str());
         const list<std::string> il = streamList(is);
-        const list<value> r = readJSON(cx, il);
+        const list<value> r = read(cx, il);
         assert(r == l);
 
         std::ostringstream wos;
-        write(writeJSON(cx, r), wos);
+        write(write(cx, r), wos);
         assert(wos.str() == os.str());
     }
     return true;
 }
 
 bool testJSONRPC() {
-    const std::string lm("{\"id\": 1, \"method\": \"system.listMethods\", \"params\": []}");
     JSONContext cx;
-    const list<value> e = readJSON(cx, mklist(lm));
-    const list<value> v = elementsToValues(e);
-
-    assert(assoc<value>("id", v) == mklist<value>("id", 1));
-    assert(assoc<value>("method", v) == mklist<value>("method", std::string("system.listMethods")));
-    assert(assoc<value>("params", v) == mklist<value>("params", list<value>()));
+    {
+        const std::string lm("{\"id\": 1, \"method\": \"system.listMethods\", \"params\": []}");
+        const list<value> e = read(cx, mklist(lm));
+        const list<value> v = elementsToValues(e);
+        assert(assoc<value>("id", v) == mklist<value>("id", 1));
+        assert(assoc<value>("method", v) == mklist<value>("method", std::string("system.listMethods")));
+        assert(assoc<value>("params", v) == mklist<value>("params", list<value>()));
+    }
+    {
+        const std::string i("{\"id\":3,\"result\":[{\"price\":\"$2.99\",\"name\":\"Apple\"},{\"price\":\"$3.55\",\"name\":\"Orange\"},{\"price\":\"$1.55\",\"name\":\"Pear\"}]}");
+        const list<value> e = read(cx, mklist(i));
+        const std::string i2("{\"id\":3,\"result\":{\"0\":{\"price\":\"$2.99\",\"name\":\"Apple\"},\"1\":{\"price\":\"$3.55\",\"name\":\"Orange\"},\"2\":{\"price\":\"$1.55\",\"name\":\"Pear\"}}}");
+        const list<value> e2 = read(cx, mklist(i));
+        assert(e == e2);
+    }
+    {
+        const std::string i("{\"id\":3,\"result\":[{\"price\":\"$2.99\",\"name\":\"Apple\"},{\"price\":\"$3.55\",\"name\":\"Orange\"},{\"price\":\"$1.55\",\"name\":\"Pear\"}]}");
+        const list<value> e = read(cx, mklist(i));
+        std::ostringstream os;
+        write(write(cx, e), os);
+        assert(os.str() == i);
+        const list<value> v = elementsToValues(e);
+        const list<value> r = valuesToElements(v);
+        assert(r == e);
+    }
+    {
+        const list<value> r = mklist<value>(mklist<value>("id", 1), mklist<value>("result", mklist<value>(std::string("Service.get"), std::string("Service.getTotal"))));
+        const list<value> e = valuesToElements(r);
+        std::ostringstream os;
+        write(write(cx, e), os);
+        assert(os.str() == "{\"id\":1,\"result\":[\"Service.get\",\"Service.getTotal\"]}");
+    }
     return true;
 }
 
 }
+}
 
 int main() {
     std::cout << "Testing..." << std::endl;
 
-    tuscany::testJSEval();
-    tuscany::testJSON();
-    tuscany::testJSONRPC();
+    tuscany::json::testJSEval();
+    tuscany::json::testJSON();
+    tuscany::json::testJSONRPC();
 
     std::cout << "OK" << std::endl;
 

Modified: tuscany/cpp/sca/modules/json/json.hpp
URL: http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/json/json.hpp?rev=829699&r1=829698&r2=829699&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/json/json.hpp (original)
+++ tuscany/cpp/sca/modules/json/json.hpp Mon Oct 26 05:13:06 2009
@@ -35,6 +35,7 @@
 #include "monad.hpp"
 
 namespace tuscany {
+namespace json {
 
 /**
  * Report JSON errors.
@@ -155,7 +156,7 @@
     jsval idv;
     JS_IdToValue(cx, id, &idv);
     if(JSVAL_IS_STRING(idv)) {
-        const value type = isList(val)? element : attribute;
+        const value type = isList(val)? element : element;
         return jsPropertiesToValues(cx, cons<value> (mklist<value> (type, JS_GetStringBytes(JSVAL_TO_STRING(idv)), val), propertiesSoFar), o, i);
     }
     return jsPropertiesToValues(cx, cons(val, propertiesSoFar), o, i);
@@ -194,25 +195,25 @@
 /**
  * Consumes JSON strings and populates a JS object.
  */
-failable<bool, std::string> consumeJSON(const JSONContext& cx, JSONParser* parser, const list<std::string>& ilist) {
+failable<bool, std::string> consume(const JSONContext& cx, JSONParser* parser, const list<std::string>& ilist) {
     if (isNil(ilist))
         return true;
     JSString* jstr = JS_NewStringCopyZ(cx, car(ilist).c_str());
     if(!JS_ConsumeJSONText(cx, parser, JS_GetStringChars(jstr), JS_GetStringLength(jstr)))
         return "JS_ConsumeJSONText failed";
-    return consumeJSON(cx, parser, cdr(ilist));
+    return consume(cx, parser, cdr(ilist));
 }
 
 /**
  * Convert a list of strings representing a JSON document to a list of values.
  */
-const failable<list<value>, std::string> readJSON(const JSONContext& cx, const list<std::string>& ilist) {
+const failable<list<value>, std::string> read(const JSONContext& cx, const list<std::string>& ilist) {
     jsval val;
     JSONParser* parser = JS_BeginJSONParse(cx, &val);
     if(parser == NULL)
         return std::string("JS_BeginJSONParse failed");
 
-    const failable<bool, std::string> consumed = consumeJSON(cx, parser, ilist);
+    const failable<bool, std::string> consumed = consume(cx, parser, ilist);
 
     if(!JS_FinishJSONParse(cx, parser, JSVAL_NULL))
         return std::string("JS_FinishJSONParse failed");
@@ -235,6 +236,36 @@
 }
 
 /**
+ * Returns true if a list represents a JS array.
+ */
+const bool isJSArray(const list<value>& l) {
+    if(isNil(l))
+        return false;
+    const value v = car(l);
+    if(isList(v)) {
+        const list<value> p = v;
+        if(isSymbol(car(p)))
+            return false;
+    }
+    return true;
+}
+
+
+
+/**
+ * Converts a list of values to JS properties.
+ */
+JSObject* valuesToJSProperties(const JSONContext& cx, JSObject* o, const list<value>& l) {
+    const jsval valueToJSVal(const JSONContext& cx, const value& val);
+    if(isNil(l))
+        return o;
+    const list<value> p = car(l);
+    jsval pv = valueToJSVal(cx, caddr(p));
+    JS_SetProperty(cx, o, ((std::string)cadr(p)).c_str(), &pv);
+    return valuesToJSProperties(cx, o, cdr(l));
+}
+
+/**
  * Converts a value to a JS val.
  */
 const jsval valueToJSVal(const JSONContext& cx, const value& val) {
@@ -250,7 +281,9 @@
         return DOUBLE_TO_JSVAL(JS_NewDouble(cx, (double)val));
     }
     case value::List: {
-        return OBJECT_TO_JSVAL(valuesToJSElements(cx, JS_NewArrayObject(cx, 0, NULL), val, 0));
+        if (isJSArray(val))
+            return OBJECT_TO_JSVAL(valuesToJSElements(cx, JS_NewArrayObject(cx, 0, NULL), val, 0));
+        return OBJECT_TO_JSVAL(valuesToJSProperties(cx, JS_NewObject(cx, NULL, NULL, NULL), val));
     }
     default: {
         return JSVAL_VOID;
@@ -297,9 +330,9 @@
 /**
  * Context passed to the JSON write callback function.
  */
-template<typename R> class JSONWriteContext {
+template<typename R> class WriteContext {
 public:
-    JSONWriteContext(const JSONContext& cx, const lambda<R(R, std::string)>& reduce, const R& accum) : cx(cx), reduce(reduce), accum(accum) {
+    WriteContext(const JSONContext& cx, const lambda<R(R, std::string)>& reduce, const R& accum) : cx(cx), reduce(reduce), accum(accum) {
     }
     const JSONContext& cx;
     const lambda<R(R, std::string)> reduce;
@@ -310,7 +343,7 @@
  * Called by JS_Stringify to write JSON out.
  */
 template<typename R> JSBool writeCallback(const jschar *buf, uint32 len, void *data) {
-    JSONWriteContext<R>& wcx = *(static_cast<JSONWriteContext<R>*> (data));
+    WriteContext<R>& wcx = *(static_cast<WriteContext<R>*> (data));
     JSString* jstr = JS_NewUCStringCopyN(wcx.cx, buf, len);
     wcx.accum = wcx.reduce(wcx.accum, std::string(JS_GetStringBytes(jstr), JS_GetStringLength(jstr)));
     return JS_TRUE;
@@ -319,14 +352,14 @@
 /**
  * Convert a list of values to a JSON document.
  */
-template<typename R> const failable<R, std::string> writeJSON(const JSONContext& cx, const lambda<R(R, std::string)>& reduce, const R& initial, const list<value>& l) {
+template<typename R> const failable<R, std::string> write(const JSONContext& cx, const lambda<R(R, std::string)>& reduce, const R& initial, const list<value>& l) {
     JSObject* o = JS_NewObject(cx, NULL, NULL, NULL);
     jsval val = OBJECT_TO_JSVAL(o);
     const failable<bool, std::string> w = writeList(cx, l, o);
     if (!hasValue(w))
         return std::string(w);
 
-    JSONWriteContext<R> wcx(cx, reduce, initial);
+    WriteContext<R> wcx(cx, reduce, initial);
     if (!JS_Stringify(cx, &val, NULL, JSVAL_NULL, writeCallback<R>, &wcx))
         return std::string("JS_Stringify failed");
     return wcx.accum;
@@ -335,17 +368,18 @@
 /**
  * Convert a list of values to a list of strings representing a JSON document.
  */
-const list<std::string> writeJSONList(const list<std::string>& listSoFar, const std::string& s) {
+const list<std::string> writeStrings(const list<std::string>& listSoFar, const std::string& s) {
     return cons(s, listSoFar);
 }
 
-const failable<list<std::string>, std::string> writeJSON(const JSONContext& cx, const list<value>& l) {
-    const failable<list<std::string>, std::string> ls = writeJSON<list<std::string> >(cx, writeJSONList, list<std::string>(), l);
+const failable<list<std::string>, std::string> write(const JSONContext& cx, const list<value>& l) {
+    const failable<list<std::string>, std::string> ls = write<list<std::string> >(cx, writeStrings, list<std::string>(), l);
     if (!hasValue(ls))
         return ls;
     return reverse(list<std::string>(ls));
 }
 
 }
+}
 
 #endif /* tuscany_json_hpp */



Mime
View raw message