diff options
Diffstat (limited to 'cpp/sca/runtime/core/src')
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/function.hpp | 51 | ||||
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/gc.hpp | 26 | ||||
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/list.hpp | 63 | ||||
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/parallel.hpp | 283 | ||||
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/value.hpp | 212 |
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 */ |