Adding member template to smart pointer.
[lispp.git] / LispObj.h
blob166da256d5420e1e5190d4c135b85c666d80e039
2 #ifndef H_LISP_OBJ
3 #define H_LISP_OBJ
5 #include <cassert>
6 #include <ostream>
7 #include <vector>
8 #include <string>
9 #include <algorithm>
11 namespace Lisp
16 enum eObjectType
18 eBaseObj = 0,
19 eNullObj,
20 eStringObj,
21 eConsObj,
22 eFixnumObj,
23 eFloatnumObj,
24 eSymbolObj,
25 ePackageObj,
26 eFunctionObj
30 typedef signed char s8;
31 typedef signed short s16;
32 typedef signed int s32;
33 typedef signed long s64;
34 typedef signed long long s128;
36 typedef unsigned char u8;
37 typedef unsigned short u16;
38 typedef unsigned int u32;
39 typedef unsigned long u64;
40 typedef unsigned long long u128;
42 typedef float f32;
43 typedef double f64;
45 typedef u8 CharType;
46 typedef u32 FixnumType;
47 typedef f32 FloatnumType;
48 typedef void * (*PrimitivePtr)(void *);
50 struct LispObj;
52 // smart pointer for pointing at lisp objects
53 template <typename T> class ObjPtr
55 public:
56 typedef T* ActualPtrType;
57 explicit ObjPtr( T* o ) : p_(o) {};
58 // ~ObjPtr( ) { delete p_; }
59 T* operator->() { return get(); };
60 T& operator*() { return *get(); };
62 template class<D>
63 operator ObjPtr<D>()
65 return ObjPtr<D>(p_);
68 private:
69 T* get()
71 return p_;
74 void set(void *p)
76 p_ = reinterpret_cast<T*>(p);
79 T* p_;
81 template <typename ActualT, typename CharT, typename FixnumT, typename FloatnumT, typename PrimType, typename PtrType>
82 friend class TLispValue;
85 // this is what we use to point at a lisp object
86 typedef ObjPtr<LispObj> PointerType;
88 // straight primitive call with no environment / args
89 class PrimitiveType
91 public:
92 explicit Primitive(PrimitivePtr f) : fn_(f) {}
93 PointerType operator()(PointerType**p)
95 return fn_(p):
97 private:
98 PrimitivePtr fn_;
101 // object data with a tag
102 template <typename T, typename D, template <typename> class C>
103 class TaggedObjData
105 public:
107 typedef T TagType;
108 typedef D ValueType;
109 typedef C<D> ValueContainerType;
111 T tag;
112 ValueContainerType values;
115 // T needs to implement sthing which will transform a tag to a
116 // object type
117 eObjectType getType()
119 return T::getType(tag);
122 // Container needs to be sanely indexable
123 D& operator[](std::size_t i)
125 return values[i];
128 const D& operator[](std::size_t i) const
130 return values[i];
133 // container must have capacity
134 void resize(std::size_t s)
136 values.reserve(s);
137 values.resize(s);
140 // must be able to tell what that capacity is
141 std::size_t size() const
143 return values.size();
149 // Primitive unboxed values (this must be POD)
150 template <typename ActualT, typename CharT, typename FixnumT, typename FloatnumT, typename PrimT, typename PtrT, typename ActualPtrT> class TLispValue
152 public:
153 ActualT value;
155 // need to be ablue to convert between ActualType and these types
156 operator PtrT()
158 // pure evil!
159 ActualPtrT* ptr = reinterpret_cast<ActualPtrT*>(&value);
160 return PtrT(*ptr);
163 // we can't overload by return type, so we use value conversion instead
164 operator FixnumT()
166 return value;
169 operator FloatnumT()
171 return *(static_cast<FloatnumT*>(&value));
174 operator CharT()
176 return *(static_cast<CharT*>(&value));
179 operator PrimT()
181 return *(static_cast<PrimT*>(&value));
184 // operator=, but then is this POD ?
185 TLispValue& operator=(PtrT ptr)
187 ActualPtrT* lhsptr = static_cast<ActualPtrT*>(&value);
188 *lhsptr = ptr.get();
189 return *this;
192 TLispValue& operator=(FixnumT fn)
194 value = fn;
195 return *this;
198 TLispValue& set(FloatnumT fn)
200 (*static_cast<FloatnumT*>(&value)) = fn;
201 return *this;
204 TLispValue& operator=(CharT ch)
206 (*static_cast<CharT*>(&value)) = ch;
207 return *this;
210 TLispValue& operator=(PrimT prim)
212 (*static_cast<PrimT*>(&value)) = prim;
213 return *this;
221 // tag types (this doesn't have to be POD, but its advisable)
222 template <typename T> class Tag
224 T tagValue;
226 void setType(eObjectType tag)
228 tagValue = static_cast<eObjectType>(tagValue);
231 eObjectType getType()
233 static_cast<eObjectType>(tagValue);
237 typedef Tag<u8> LispTag;
238 typedef TLispValue<u128, CharType, FixnumType, FloatnumType, PrimitiveType, PointerType, LispObj*> LispValue;
241 // TO DO -- template template parameters?
243 struct LispObj {
244 TaggedObjData<Tag<unsigned char>, LispValue, std::vector> object;
252 } // end namespace lisp
255 #endif