Switching to micro manual implementation
[lispp.git] / LispObj.h
blob9496aec145cf11e6329d2c8a623e72baba02cac3
2 #ifndef H_LISP_OBJ
3 #define H_LISP_OBJ
5 #include <cassert>
6 #include <ostream>
7 #include <vector>
8 #include <map>
9 #include <string>
10 #include <algorithm>
11 #include <boost/variant.hpp>
12 #include <boost/tr1/memory.hpp>
14 namespace Lisp
17 typedef signed char s8;
18 typedef signed short s16;
19 typedef signed int s32;
20 typedef signed long s64;
21 typedef signed long long s128;
23 typedef unsigned char u8;
24 typedef unsigned short u16;
25 typedef unsigned int u32;
26 typedef unsigned long u64;
27 typedef unsigned long long u128;
29 typedef float f32;
30 typedef double f64;
34 // placeholder type
35 struct NullType {
36 private:
37 const u32 dead_;
38 public:
39 NullType() : dead_(0xDEADBEEF)
46 template <typename T> class TUnboxedType
48 private:
49 T data_;
50 public:
51 TUnboxedType() {
55 TUnboxedType(const TUnboxedType<T>& other) : data_(other.data_)
60 T& operator=(const TUnboxedType<T>& other)
62 data_ = other.data_;
65 operator T()
67 return data_;
70 const bool isBoxed() const
72 return false;
76 class CharType : public TUnboxedType<u8>
81 class FixnumType : public TUnboxedType<u32>
85 class FloatnumType : public TUnboxedType<f32>
89 template <typename T> class TBoxedType
91 private:
92 boost::shared_ptr<T> pointer_;
93 public:
94 TBoxedType() : pointer_(new T)
98 TBoxedType(const TUnboxedType<T>& other) : pointer_(other.pointer_)
102 T& operator=(const TBoxedType<T>& other)
104 pointer_ = other.pointer_;
107 T* operator->()
109 return pointer_.operator->();
112 T& operator*()
114 return pointer_.operator*();
117 const bool isBoxed() const
119 return true;
124 // Simple unboxable Lisp Value
125 template <typename CharT, typename FixnumT, typename FloatnumT, typename PrimT, typename ObjRefT> class TLispValue
127 public:
128 typedef CharT LispCharT;
129 typedef FixnumT LispFixnumT;
130 typedef FloatnumT LispFloatnumT;
131 typedef PrimT LispPrimT;
132 typedef ObjRefT LispObjRefT;
134 boost::variant< CharT, FixnumT, FloatnumT, PrimT, ObjRefT> value_;
136 CharT getChar() {
137 return boost::get< CharT>(value_);
140 FixnumT getFixnum() {
141 return boost::get< FixnumT>(value_);
144 FloatnumT getFloatNum() {
145 return boost::get< FloatnumT>(value_);
148 PrimT getPrim() {
149 return boost::get< PrimT>(value_);
153 // instantiate lisp value
154 struct LispValue : public TLispValue<u8, u32, f32, NullType, boost::shared_ptr<void*> >
158 // Compound lisp object
159 template <typename ListT, typename MapT, typename ArrayT> class TLispObj
160 : public boost::variant<ListT, MapT, ArrayT>
162 public:
163 const bool isCompound() const {
164 return true;
169 struct LispObject : public TLispObj<std::list<LispValue>, std::map<std::string, LispValue>, std::vector<LispValue> >
174 class IsRefCompoundVisitor : public boost::static_visitor<>
176 bool isCompound_;
178 template <typename T>
179 void operator()(T& operand)
181 isCompound_ = operand->isCompound();
186 // reference to a lisp object: can either contain the value itself or a pointer to a compound value
187 template <typename LispValueT, typename LispObjT> class LispObjRefT : public boost::variant< LispValueT, boost::shared_ptr<LispObjT> >
189 public:
191 const bool isCompoundRef() const {
192 IsRefCompoundVisitor visitor;
193 boost::apply_visitor(this);
194 return visitor.isCompound_;
198 class LispObjRef : public LispObjRefT< LispValue, LispObject >
205 // This is our container primitive, the equivalent of a cons cell structured list
206 template <typename D, template <typename> class C>
207 class TLispObjContainer
209 public:
211 typedef D ValueType;
212 typedef C<D> ValueContainerType;
214 typename D::LispCharT getChar(std::size_t i)
216 return values[i].getChar();
219 typename D::LispFixnumT getFixnum(std::size_t i)
221 return values[i].getFixnum();
224 typename D::LispFloatnumT getFloatNum(std::size_t i)
226 return values[i].getFloatNum();
229 typename D::LispObjRefT getObjRef(std::size_t i)
231 return values[i].getObjRef();
234 ValueContainerType values;
236 // container must have capacity
237 void resize(std::size_t s)
239 values.reserve(s);
240 values.resize(s);
243 // must be able to tell what that capacity is
244 std::size_t size() const
246 return values.size();
251 struct LispObjContainer {
252 TLispObjContainer<LispValue, std::vector> objects;
255 } // end namespace lisp
258 #endif