summaryrefslogtreecommitdiffstats
path: root/cpp/sca/runtime
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2009-09-26 21:31:26 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2009-09-26 21:31:26 +0000
commitc39d4c6d143697ee8982df0833499a8de934dd9a (patch)
treecbc758f3921459c0f11a96f24f5ef251db0bf367 /cpp/sca/runtime
parent8eb242943144ad5ea57c7471e4a3e199bf5687d5 (diff)
Refactored the value class. Cleaned up usage of namespaces to remove side effects from includes. Added a few util functions to help work with threads. Added synchronizations to make pointers thread safe. Adjusted store sample to refactoring.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@819220 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/sca/runtime')
-rw-r--r--cpp/sca/runtime/core/src/tuscany/function.hpp51
-rw-r--r--cpp/sca/runtime/core/src/tuscany/gc.hpp26
-rw-r--r--cpp/sca/runtime/core/src/tuscany/list.hpp63
-rw-r--r--cpp/sca/runtime/core/src/tuscany/parallel.hpp283
-rw-r--r--cpp/sca/runtime/core/src/tuscany/value.hpp212
5 files changed, 481 insertions, 154 deletions
diff --git a/cpp/sca/runtime/core/src/tuscany/function.hpp b/cpp/sca/runtime/core/src/tuscany/function.hpp
index e0e8889dad..caba5211b9 100644
--- a/cpp/sca/runtime/core/src/tuscany/function.hpp
+++ b/cpp/sca/runtime/core/src/tuscany/function.hpp
@@ -23,14 +23,12 @@
#define tuscany_function_hpp
/**
- * Lambda function type, used to represent service operations.
+ * Lambda function type.
*/
#include <iostream>
#include "gc.hpp"
-using std::ostream;
-
namespace tuscany {
/**
@@ -50,15 +48,13 @@ bool resetLambdaCounters() {
}
bool printLambdaCounters() {
- using std::cout;
- using std::endl;
- cout << "countLambdas " << countLambdas << endl;
- cout << "countELambdas " << countELambdas << endl;
- cout << "countFLambdas " << countFLambdas << endl;
- cout << "countCLambdas " << countCLambdas << endl;
- cout << "countProxies " << countProxies << endl;
- cout << "countFProxies " << countFProxies << endl;
- cout << "countCProxies " << countCProxies << endl;
+ std::cout << "countLambdas " << countLambdas << std::endl;
+ std::cout << "countELambdas " << countELambdas << std::endl;
+ std::cout << "countFLambdas " << countFLambdas << std::endl;
+ std::cout << "countCLambdas " << countCLambdas << std::endl;
+ std::cout << "countProxies " << countProxies << std::endl;
+ std::cout << "countFProxies " << countFProxies << std::endl;
+ std::cout << "countCProxies " << countCProxies << std::endl;
return true;
}
@@ -81,11 +77,11 @@ public:
}
unsigned int acquire() {
- return ++refCount;
+ return __sync_add_and_fetch(&refCount, 1);
}
unsigned int release() {
- return --refCount;
+ return __sync_sub_and_fetch(&refCount, 1);
}
template<typename F> class Proxy: public Callable {
@@ -95,7 +91,7 @@ public:
countFProxies ++;
}
- Proxy(const Proxy& p) : function(p.function) {
+ explicit Proxy(const Proxy& p) : function(p.function) {
countProxies++;
countCProxies ++;
}
@@ -166,14 +162,14 @@ public:
return (*callable)(std::forward<P>(p)...);
}
- template<typename S> friend ostream& operator<<(ostream&, const lambda<S>&);
+ template<typename S> friend std::ostream& operator<<(std::ostream&, const lambda<S>&);
private:
typedef Callable<R,P...> CallableType;
gc_counting_ptr<CallableType> callable;
};
-template<typename S> ostream& operator<<(ostream& out, const lambda<S>& l) {
+template<typename S> std::ostream& operator<<(std::ostream& out, const lambda<S>& l) {
return out << "lambda::" << l.callable;
}
@@ -187,23 +183,22 @@ template<typename R, typename... P> lambda<R(P...)> makeLambda(const R (* const
/**
* Curry a lambda function.
*/
-template<typename R, typename T, typename... P> class Curried {
-private:
- const T v;
- const lambda<R(T, P...)>f;
-
+template<typename R, typename T, typename... P> class curried {
public:
- Curried(const lambda<R(T, P...)>& f, const T& v): v(v), f(f) {
+ curried(const lambda<R(T, P...)>& f, const T& v): v(v), f(f) {
}
const R operator()(P... p) const {
return f(v, std::forward<P>(p)...);
}
+private:
+ const T v;
+ const lambda<R(T, P...)>f;
};
template<typename R, typename T, typename... P> const lambda<R(P...)> curry(const lambda<R(T, P...)>& f, const T& t) {
- return (lambda<R(P...)>)Curried<R, T, P...>(f, t);
+ return (lambda<R(P...)>)curried<R, T, P...>(f, t);
}
template<typename R, typename T, typename U, typename... P> const lambda<R(P...)> curry(const lambda<R(T, U, P...)>& f, const T& t, const U& u) {
@@ -217,14 +212,16 @@ template<typename R, typename T, typename U, typename V, typename... P> const la
/**
* A lambda function that returns the given value.
*/
-template<typename T> struct unitReturn {
- const T v;
- unitReturn(const T& v) :
+template<typename T> class unitReturn {
+public:
+ explicit unitReturn(const T& v) :
v(v) {
}
const T operator()() const {
return v;
}
+private:
+ const T v;
};
template<typename T> const lambda<T()> unit(const T& v) {
diff --git a/cpp/sca/runtime/core/src/tuscany/gc.hpp b/cpp/sca/runtime/core/src/tuscany/gc.hpp
index 803ec31643..b0ed42a474 100644
--- a/cpp/sca/runtime/core/src/tuscany/gc.hpp
+++ b/cpp/sca/runtime/core/src/tuscany/gc.hpp
@@ -26,9 +26,7 @@
* Garbage collected pointer.
*/
-#include <ostream>
-
-using std::ostream;
+#include <iostream>
namespace tuscany
{
@@ -81,7 +79,7 @@ public:
return countingRef->ptr;
}
- template<typename X> friend ostream& operator<<(ostream&, const gc_ptr<X>&);
+ template<typename X> friend std::ostream& operator<<(std::ostream&, const gc_ptr<X>&);
private:
struct CountingRef {
@@ -95,12 +93,13 @@ private:
void acquire(CountingRef* ref) throw() {
if(ref)
- ++ref->count;
+ __sync_add_and_fetch(&ref->count, 1);
}
void release() throw() {
if(countingRef) {
- if(--countingRef->count == 0) {
+ unsigned rc = __sync_sub_and_fetch(&countingRef->count, 1);
+ if(rc == 0) {
delete countingRef->ptr;
delete countingRef;
}
@@ -108,7 +107,7 @@ private:
}
};
-template<typename T> ostream& operator<<(ostream& out, const gc_ptr<T>& p) {
+template<typename T> std::ostream& operator<<(std::ostream& out, const gc_ptr<T>& p) {
return out << p.countingRef->ptr;
}
@@ -163,7 +162,7 @@ public:
return countingRef->ptr;
}
- template<typename X> friend ostream& operator<<(ostream&, const gc_aptr<X>&);
+ template<typename X> friend std::ostream& operator<<(std::ostream&, const gc_aptr<X>&);
private:
struct CountingRef {
@@ -177,12 +176,13 @@ private:
void acquire(CountingRef* ref) throw() {
if(ref)
- ++ref->count;
+ __sync_add_and_fetch(&ref->count, 1);
}
void release() throw() {
if(countingRef) {
- if(--countingRef->count == 0) {
+ unsigned rc = __sync_sub_and_fetch(&countingRef->count, 1);
+ if(rc == 0) {
delete[] countingRef->ptr;
delete countingRef;
}
@@ -190,7 +190,7 @@ private:
}
};
-template<typename T> ostream& operator<<(ostream& out, const gc_aptr<T>& p) {
+template<typename T> std::ostream& operator<<(std::ostream& out, const gc_aptr<T>& p) {
return out << p.countingRef->ptr;
}
@@ -242,7 +242,7 @@ public:
return ptr;
}
- template<typename X> friend ostream& operator<<(ostream&, const gc_counting_ptr<X>&);
+ template<typename X> friend std::ostream& operator<<(std::ostream&, const gc_counting_ptr<X>&);
private:
T* ptr;
@@ -261,7 +261,7 @@ private:
}
};
-template<typename T> ostream& operator<<(ostream& out, const gc_counting_ptr<T>& p) {
+template<typename T> std::ostream& operator<<(std::ostream& out, const gc_counting_ptr<T>& p) {
return out << p.ptr;
}
diff --git a/cpp/sca/runtime/core/src/tuscany/list.hpp b/cpp/sca/runtime/core/src/tuscany/list.hpp
index e180ad6134..ef493b19ca 100644
--- a/cpp/sca/runtime/core/src/tuscany/list.hpp
+++ b/cpp/sca/runtime/core/src/tuscany/list.hpp
@@ -29,8 +29,6 @@
#include <iostream>
#include "function.hpp"
-using std::ostream;
-
namespace tuscany {
long countlists = 0;
@@ -44,12 +42,10 @@ bool resetlistCounters() {
}
bool printlistCounters() {
- using std::cout;
- using std::endl;
- cout << "countlists " << countlists << endl;
- cout << "countElists " << countElists << endl;
- cout << "countIlists " << countIlists << endl;
- cout << "countClists " << countClists << endl;
+ std::cout << "countlists " << countlists << std::endl;
+ std::cout << "countElists " << countElists << std::endl;
+ std::cout << "countIlists " << countIlists << std::endl;
+ std::cout << "countClists " << countClists << std::endl;
return true;
}
@@ -57,12 +53,10 @@ bool printlistCounters() {
* A car/cdr lisp-like pair, base structure to construct lists.
*/
-template<typename T> struct list {
- bool nil;
- T car;
- lambda<list<T> ()> cdr;
+template<typename T> class list {
+public:
- list(const T car, const lambda<list<T> ()> cdr) :
+ list(const T car, const lambda<list<T> ()>& cdr) :
nil(false), car(car), cdr(cdr) {
countlists++;
countIlists++;
@@ -111,8 +105,11 @@ template<typename T> struct list {
return !this->operator==(p);
}
- template<typename X> friend ostream& operator<<(ostream&, const list<X>&);
+ template<typename X> friend std::ostream& operator<<(std::ostream&, const list<X>&);
+ bool nil;
+ T car;
+ lambda<list<T> ()> cdr;
};
/**
@@ -125,7 +122,7 @@ template<typename T> const bool isNil(const list<T>& p) {
/**
* Write a list to an output stream.
*/
-template<typename X> ostream& operator<<(ostream& out, const list<X>& l) {
+template<typename X> std::ostream& operator<<(std::ostream& out, const list<X>& l) {
if(l == list<X> ())
return out << "()";
return out << "(" << car(l) << ", " << cdr(l) << ")";
@@ -195,6 +192,13 @@ template<typename T> const T cadr(const list<T>& p) {
}
/**
+ * Returns the car of the cdr of the cdr of a list.
+ */
+template<typename T> const T caddr(const list<T>& p) {
+ return car(cdr(cdr(p)));
+}
+
+/**
* Returns the cdr of a cdr of a list.
*/
template<typename T> const list<T> cddr(const list<T>& p) {
@@ -202,6 +206,13 @@ template<typename T> const list<T> cddr(const list<T>& p) {
}
/**
+ * Returns the cdr of a cdr of the cdr of a list.
+ */
+template<typename T> const list<T> cdddr(const list<T>& p) {
+ return cdr(cdr(cdr(p)));
+}
+
+/**
* Returns the length of a list.
*/
template<typename T> struct lengthRef {
@@ -258,7 +269,7 @@ template<typename T, typename R> const list<R> map(const lambda<R(T)>& f, const
*/
template<typename T, typename R> struct reduceAccumulate {
const lambda<R(R, T)> f;
- reduceAccumulate(const lambda<R(R, T)>& f) :
+ explicit reduceAccumulate(const lambda<R(R, T)>& f) :
f(f) {
}
R operator()(const R& acc, const list<T>& p) const {
@@ -344,5 +355,25 @@ template<typename T> const list<T> assoc(const T& k, const list<list<T> >& p) {
return assoc(k, cdr(p));
}
+/**
+ * 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 */
diff --git a/cpp/sca/runtime/core/src/tuscany/parallel.hpp b/cpp/sca/runtime/core/src/tuscany/parallel.hpp
new file mode 100644
index 0000000000..c0d578e281
--- /dev/null
+++ b/cpp/sca/runtime/core/src/tuscany/parallel.hpp
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+#ifndef tuscany_parallel_hpp
+#define tuscany_parallel_hpp
+
+/**
+ * Simple parallel work execution functions.
+ */
+
+#include <pthread.h>
+#include <sys/syscall.h>
+#include "function.hpp"
+
+namespace tuscany {
+
+/**
+ * Returns the current thread id.
+ */
+unsigned int threadId() {
+ return syscall(__NR_gettid);
+}
+
+/**
+ * Represents a value which will be know in the future.
+ */
+template<typename T> class future {
+
+private:
+ template<typename X> class futureValue {
+ public:
+ futureValue() :
+ refCount(0), hasValue(false) {
+ pthread_mutex_init(&valueMutex, NULL);
+ pthread_cond_init(&valueCond, NULL);
+ }
+
+ ~futureValue() {
+ pthread_mutex_destroy(&valueMutex);
+ pthread_cond_destroy(&valueCond);
+ }
+
+ unsigned int acquire() {
+ return __sync_add_and_fetch(&refCount, 1);
+ }
+
+ unsigned int release() {
+ return __sync_sub_and_fetch(&refCount, 1);
+ }
+
+ bool set(const T& v) {
+ pthread_mutex_lock(&valueMutex);
+ if(hasValue) {
+ pthread_mutex_unlock(&valueMutex);
+ return false;
+ }
+ hasValue = true;
+ value = v;
+ pthread_mutex_unlock(&valueMutex);
+ pthread_cond_broadcast(&valueCond);
+ return true;
+ }
+
+ const T get() {
+ pthread_mutex_lock(&valueMutex);
+ while(!hasValue) {
+ pthread_cond_wait(&valueCond, &valueMutex);
+ }
+ const T& v = value;
+ pthread_mutex_unlock(&valueMutex);
+ return v;
+ }
+
+ private:
+ unsigned refCount;
+ pthread_mutex_t valueMutex;
+ pthread_cond_t valueCond;
+ bool hasValue;
+ X value;
+ };
+
+ gc_counting_ptr<futureValue<T> > fvalue;
+
+ template<typename X> friend const X get(const future<X>& f);
+ template<typename X> friend bool set(const future<X>& f, const X& v);
+
+public:
+ future() : fvalue(new futureValue<T>()) {
+ //std::cout << "future() threadId " << threadId() << "\n";
+ }
+
+ ~future() {
+ //std::cout << "~future() threadId " << threadId() << "\n";
+ }
+
+ future(const future& f) : fvalue(f.fvalue) {
+ //std::cout << "future(const future& f) threadId " << threadId() << "\n";
+ }
+
+ const future& operator=(const future& f) {
+ //std::cout << "future::operator=(const future& f) threadId " << threadId() << "\n";
+ if (&f == this)
+ return *this;
+ fvalue = f.fvalue;
+ return *this;
+ }
+
+ const future& operator=(const T& v) const {
+ fvalue->set(v);
+ return *this;
+ }
+
+ operator const T() const {
+ return fvalue->get();
+ }
+
+};
+
+/**
+ * A bounded thread safe queue.
+ */
+template<typename T> class queue {
+public:
+ explicit queue(int max) : max(max), size(0), tail(0), head(0), values(new T[max]) {
+ pthread_mutex_init(&mutex, NULL);
+ pthread_cond_init(&full, NULL);
+ pthread_cond_init(&empty, NULL);
+ }
+
+ ~queue() {
+ pthread_mutex_destroy(&mutex);
+ pthread_cond_destroy(&full);
+ pthread_cond_destroy(&empty);
+ }
+
+private:
+ const int max;
+ int size;
+ int tail;
+ int head;
+ pthread_mutex_t mutex;
+ pthread_cond_t full;
+ pthread_cond_t empty;
+ gc_aptr<T> values;
+
+ template<typename X> friend const int enqueue(queue<X>& q, const X& v);
+ template<typename X> friend const X dequeue(queue<X>& q);
+};
+
+/**
+ * Adds an element to the tail of the queue.
+ */
+template<typename T> const int enqueue(queue<T>&q, const T& v) {
+ pthread_mutex_lock(&q.mutex);
+ while(q.size == q.max)
+ pthread_cond_wait(&q.full, &q.mutex);
+ q.values[q.tail] = v;
+ q.tail = (q.tail + 1) % q.max;
+ q.size++;
+ pthread_mutex_unlock(&q.mutex);
+ pthread_cond_broadcast(&q.empty);
+ return q.size;
+}
+
+/**
+ * Returns the element at the head of the queue.
+ */
+template<typename T> const T dequeue(queue<T>& q) {
+ pthread_mutex_lock(&q.mutex);
+ while(q.size == 0)
+ pthread_cond_wait(&q.empty, &q.mutex);
+ const T v = q.values[q.head];
+ q.head = (q.head + 1) % q.max;
+ q.size--;
+ pthread_mutex_unlock(&q.mutex);
+ pthread_cond_broadcast(&q.full);
+ return v;
+}
+
+/**
+ * The worker thread function.
+ */
+void *workerThreadFunc(void *arg) {
+ queue<lambda<bool()> >* work = reinterpret_cast<queue<lambda<bool()> >*>(arg);
+ while(dequeue(*work)())
+ ;
+ return NULL;
+}
+
+/**
+ * Returns a list of worker threads.
+ */
+const list<pthread_t> makeWorkerThreads(queue<lambda<bool()> >& queue, const int count) {
+ if (count == 0)
+ return list<pthread_t>();
+ pthread_t thread;
+ pthread_create(&thread, NULL, workerThreadFunc, &queue);
+ return cons(thread, makeWorkerThreads(queue, count - 1));
+}
+
+/**
+ * A worker, implemented with a work queue and a pool of threads.
+ */
+class worker {
+public:
+ explicit worker(int max) : work(queue<lambda<bool()> >(max)), threads(makeWorkerThreads(work, max)) {
+ }
+
+private:
+ queue<lambda<bool()> > work;
+ const list<pthread_t> threads;
+
+ template<typename X> friend const future<X> submit(worker& w, const lambda<X()>& func);
+ friend const bool shutdown(worker& w);
+};
+
+/**
+ * Function used to wrap work submitted to a worker.
+ */
+template<typename R> bool submitFunc(const lambda<R()>& func, const future<R>& fut) {
+ fut = func();
+ return true;
+}
+
+/**
+ * Submits work to a worker.
+ */
+template<typename R> const future<R> submit(worker& w, const lambda<R()>& func) {
+ const future<R> fut;
+ const lambda<bool()> f = curry(lambda<bool(lambda<R()>, future<R>)>(submitFunc<R>), func, fut);
+ enqueue(w.work, f);
+ return fut;
+}
+
+/**
+ * Enqueues shutdown requests.
+ */
+const bool shutdownEnqueue(const list<pthread_t>& threads, queue<lambda<bool()> >& work) {
+ if (threads == list<pthread_t>())
+ return true;
+ enqueue(work, unit(false));
+ return shutdownEnqueue(cdr(threads), work);
+}
+
+/**
+ * Waits for shut down threads to terminate.
+ */
+const bool shutdownJoin(const list<pthread_t>& threads) {
+ if (threads == list<pthread_t>())
+ return true;
+ pthread_join(car(threads), NULL);
+ return shutdownJoin(cdr(threads));
+}
+
+/**
+ * Shutdown a worker.
+ */
+const bool shutdown(worker& w) {
+ shutdownEnqueue(w.threads, w.work);
+ shutdownJoin(w.threads);
+ return true;
+}
+
+}
+#endif /* tuscany_parallel_hpp */
diff --git a/cpp/sca/runtime/core/src/tuscany/value.hpp b/cpp/sca/runtime/core/src/tuscany/value.hpp
index e92a9178ca..ca4bd06ca6 100644
--- a/cpp/sca/runtime/core/src/tuscany/value.hpp
+++ b/cpp/sca/runtime/core/src/tuscany/value.hpp
@@ -27,16 +27,11 @@
*/
#include <string>
-#include <ostream>
+#include <iostream>
#include "gc.hpp"
#include "function.hpp"
#include "list.hpp"
-using std::string;
-using std::ostream;
-using std::cout;
-using std::endl;
-
namespace tuscany
{
@@ -51,72 +46,70 @@ bool resetValueCounters() {
}
bool printValueCounters() {
- using std::cout;
- using std::endl;
- cout << "countValues " << countValues << endl;
- cout << "countEValues " << countEValues << endl;
- cout << "countCValues " << countCValues << endl;
- cout << "countVValues " << countVValues << endl;
+ std::cout << "countValues " << countValues << std::endl;
+ std::cout << "countEValues " << countEValues << std::endl;
+ std::cout << "countCValues " << countCValues << std::endl;
+ std::cout << "countVValues " << countVValues << std::endl;
return true;
}
-class Value;
+class value;
-class Value {
+class value {
public:
enum ValueType {
Undefined, Symbol, String, List, Number, Boolean, Character, Lambda
};
- Value() :
- type(Value::Undefined) {
+ value() :
+ type(value::Undefined) {
countValues++;
countEValues++;
}
- Value(const Value& v) {
+ value(const value& v) {
countValues++;
countCValues++;
type = v.type;
switch(type) {
- case Value::List:
+ case value::List:
lst() = v.lst();
- case Value::Lambda:
+ case value::Lambda:
func() = v.func();
- case Value::Symbol:
+ case value::Symbol:
str() = v.str();
- case Value::String:
+ case value::String:
str() = v.str();
- case Value::Number:
+ case value::Number:
num() = v.num();
- case Value::Boolean:
+ case value::Boolean:
boo() = v.boo();
- case Value::Character:
+ case value::Character:
chr() = v.chr();
default:
break;
}
}
- const Value& operator=(const Value& v) {
+ const value& operator=(const value& v) {
if(this == &v)
return *this;
type = v.type;
switch(type) {
- case Value::List:
+ case value::List:
lst() = v.lst();
- case Value::Lambda:
+ case value::Lambda:
func() = v.func();
- case Value::Symbol:
+ case value::Symbol:
str() = v.str();
- case Value::String:
+ case value::String:
str() = v.str();
- case Value::Number:
+ case value::Number:
num() = v.num();
- case Value::Boolean:
+ case value::Boolean:
boo() = v.boo();
- case Value::Character:
+ case value::Character:
chr() = v.chr();
default:
break;
@@ -124,122 +117,122 @@ public:
return *this;
}
- virtual ~Value() {
+ virtual ~value() {
countValues--;
}
- Value(const lambda<Value(list<Value>&)>& func) :
- type(Value::Lambda), data(vdata(func)) {
+ explicit value(const lambda<value(list<value>&)>& func) :
+ type(value::Lambda), data(vdata(func)) {
countValues++;
countVValues++;
}
- Value(const string& str) :
- type(Value::String), data(vdata(unit(str))) {
+ explicit value(const std::string& str) :
+ type(value::String), data(vdata(unit(str))) {
countValues++;
countVValues++;
}
- Value(const char* str) :
- type(Value::Symbol), data(vdata(unit(string(str)))) {
+ explicit value(const char* str) :
+ type(value::Symbol), data(vdata(unit(std::string(str)))) {
countValues++;
countVValues++;
}
- Value(const list<Value>& lst) :
- type(Value::List), data(vdata(unit(lst))) {
+ explicit value(const list<value>& lst) :
+ type(value::List), data(vdata(unit(lst))) {
countValues++;
countVValues++;
}
- Value(const double num) :
- type(Value::Number), data(vdata(unit(num))) {
+ explicit value(const double num) :
+ type(value::Number), data(vdata(unit(num))) {
countValues++;
countVValues++;
}
- Value(const int num) :
- type(Value::Number), data(vdata(unit((double)num))) {
+ explicit value(const int num) :
+ type(value::Number), data(vdata(unit((double)num))) {
countValues++;
countVValues++;
}
- Value(const bool boo) :
- type(Value::Boolean), data(vdata(unit(boo))) {
+ explicit value(const bool boo) :
+ type(value::Boolean), data(vdata(unit(boo))) {
countValues++;
countVValues++;
}
- Value(const char chr) :
- type(Value::Character), data(vdata(unit(chr))) {
+ explicit value(const char chr) :
+ type(value::Character), data(vdata(unit(chr))) {
countValues++;
countVValues++;
}
- const bool operator!=(const Value& v) const {
+ const bool operator!=(const value& v) const {
return !this->operator==(v);
}
- const bool operator==(const Value& v) const {
+ const bool operator==(const value& v) const {
if(this == &v)
return true;
if(type != v.type)
return false;
switch(type) {
- case Value::Undefined:
+ case value::Undefined:
return true;
- case Value::List:
+ case value::List:
return lst()() == v.lst()();
- case Value::Lambda:
+ case value::Lambda:
return func() == v.func();
- case Value::Symbol:
+ case value::Symbol:
return str()() == v.str()();
- case Value::String:
+ case value::String:
return str()() == v.str()();
- case Value::Number:
+ case value::Number:
return num()() == v.num()();
- case Value::Boolean:
+ case value::Boolean:
return boo()() == v.boo()();
- case Value::Character:
+ case value::Character:
return chr()() == v.chr()();
default:
return false;
}
}
- const Value operator()(list<Value>& args) const {
+ const value operator()(list<value>& args) const {
return func()(args);
}
- operator string() const {
+ operator const std::string() const {
return str()();
}
- operator double() const {
+ operator const double() const {
return num()();
}
- operator int() const {
+ operator const int() const {
return num()();
}
- operator bool() const {
+ operator const bool() const {
return boo()();
}
- operator char() const {
+ operator const char() const {
return chr()();
}
- operator list<Value>() const {
+ operator const list<value>() const {
return lst()();
}
- operator lambda<Value(list<Value>&)>() const {
+ operator const lambda<value(list<value>&)>() const {
return func();
}
- friend ostream& operator<<(ostream&, const Value&);
+ friend std::ostream& operator<<(std::ostream&, const value&);
ValueType type;
lambda<char()> data;
@@ -265,77 +258,100 @@ private:
return vdata<char()> ();
}
- lambda<string()>& str() const {
- return vdata<string()> ();
+ lambda<std::string()>& str() const {
+ return vdata<std::string()> ();
}
- lambda<list<Value>()>& lst() const {
- return vdata<list<Value>()> ();
+ lambda<list<value>()>& lst() const {
+ return vdata<list<value>()> ();
}
- lambda<Value(list<Value>&)>& func() const {
- return vdata<Value(list<Value>&)> ();
+ lambda<value(list<value>&)>& func() const {
+ return vdata<value(list<value>&)> ();
}
};
-ostream& operator<<(ostream& out, const Value& v) {
+std::ostream& operator<<(std::ostream& out, const value& v) {
switch(v.type) {
- case Value::List:
+ case value::List:
return out << "List::" << v.lst()();
- case Value::Lambda:
+ case value::Lambda:
return out << "Lambda::" << v.func();
- case Value::Symbol:
+ case value::Symbol:
return out << "Symbol::" << v.str()();
- case Value::String:
+ case value::String:
return out << "String::" << '\'' << v.str()() << '\'';
- case Value::Number:
+ case value::Number:
return out << "Number::" << v.num()();
- case Value::Boolean:
+ case value::Boolean:
if(v.boo()())
return out << "Boolean::" << "true";
else
return out << "Boolean::" << "false";
- case Value::Character:
+ case value::Character:
return out << "Character::" << v.chr()();
default:
return out << "Undefined";
}
}
-const bool isNull(const Value& value) {
- return value.type == Value::Undefined;
+const bool isNil(const value& value) {
+ return value.type == value::Undefined;
}
-const bool isString(const Value& value) {
- return value.type == Value::String;
+const bool isString(const value& value) {
+ return value.type == value::String;
}
-const bool isSymbol(const Value& value) {
- return value.type == Value::Symbol;
+const bool isSymbol(const value& value) {
+ return value.type == value::Symbol;
}
-const bool isList(const Value& value) {
- return value.type == Value::List;
+const bool isList(const value& value) {
+ return value.type == value::List;
}
-const bool isNumber(const Value& value) {
- return value.type == Value::Number;
+const bool isNumber(const value& value) {
+ return value.type == value::Number;
}
-const bool isBoolean(const Value& value) {
- return value.type == Value::Boolean;
+const bool isBoolean(const value& value) {
+ return value.type == value::Boolean;
}
-const bool isCharacter(const Value& value) {
- return value.type == Value::Character;
+const bool isCharacter(const value& value) {
+ return value.type == value::Character;
}
-const bool isTaggedList(const Value& exp, Value tag) {
+const bool isTaggedList(const value& exp, value tag) {
if(isList(exp))
- return car((list<Value> )exp) == tag;
+ return car((list<value> )exp) == tag;
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 */