LispSymbol.h compiles.
[lispp.git] / LispObj.h
blob77ac53a8e2b672c596a4472b668bbe0b6dfc09f6
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;
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 <typename D>
63 operator ObjPtr<D>()
65 return ObjPtr<D>(p_);
68 private:
69 explicit ObjPtr( void* o ) : p_(static_cast<T*>(o)) {};
71 T* get() const
73 return p_;
76 void set(const void *p)
78 p_ = reinterpret_cast<T*>(p);
81 T* p_;
83 template <typename ActualT, typename CharT, typename FixnumT, typename FloatnumT, typename PrimType, typename PtrType>
84 friend class TLispValue;
87 // this is what we use to point at a lisp object
88 typedef ObjPtr<LispObj> PointerType;
91 // straight primitive call with no environment / args
92 template <typename ArgPointer, template <typename> class ArgContainer>
93 class PrimitiveT
95 public:
96 // err..what does a smart pointer to a pointer look like?
97 typedef PointerType (*PrimitivePtr)(ArgContainer<ArgPointer>& args);
99 explicit PrimitiveT(PrimitivePtr f) : fn_(f) {}
100 PointerType operator()(ArgContainer<ArgPointer>& p)
102 return fn_(p);
104 private:
105 PrimitivePtr fn_;
108 typedef PrimitiveT< ObjPtr<LispObj>, std::vector > PrimitiveType;
112 // Primitive unboxed values (this must be POD)
113 template <typename ActualT, typename CharT, typename FixnumT, typename FloatnumT, typename PrimT, typename PtrT> class TLispValue
115 public:
116 ActualT value;
118 TLispValue()
122 // need to be ablue to convert between ActualType and these types
123 operator PtrT() const
125 // convert it to a void * and construct a PtrT() around it
126 return PtrT(reinterpret_cast<void*>(value));
130 // we can't overload by return type, so we use value conversion instead
131 operator FixnumT() const
133 return value;
136 operator FloatnumT() const
138 return *(static_cast<FloatnumT*>(&value));
141 operator CharT() const
143 return *(static_cast<CharT*>(&value));
146 operator PrimT() const
148 return *(static_cast<PrimT*>(&value));
151 TLispValue(const PtrT& ptr)
153 value = reinterpret_cast<ActualT>(reinterpret_cast<void*>(ptr.get()));
156 TLispValue& operator=(const PtrT& ptr)
158 value = reinterpret_cast<ActualT>(reinterpret_cast<void*>(ptr.get()));
159 return *this;
162 TLispValue(const FixnumT& fn)
164 value = fn;
167 TLispValue& operator=(const FixnumT& fn)
169 value = fn;
170 return *this;
173 TLispValue(const FloatnumT& fn)
175 (*static_cast<FloatnumT*>(&value)) = fn;
178 TLispValue& set(const FloatnumT& fn)
180 (*static_cast<FloatnumT*>(&value)) = fn;
181 return *this;
184 TLispValue(const CharT& ch)
186 (*static_cast<FloatnumT*>(&value)) = ch;
189 TLispValue& operator=(const CharT& ch)
191 (*static_cast<CharT*>(&value)) = ch;
192 return *this;
195 TLispValue(const PrimT& prim)
197 (*static_cast<FloatnumT*>(&value)) = prim;
200 TLispValue& operator=(const PrimT& prim)
202 (*static_cast<PrimT*>(&value)) = prim;
203 return *this;
209 // tag types (this doesn't have to be POD, but its advisable)
210 template <typename T> class Tag
212 private:
213 T tagValue;
215 public:
216 void setType(eObjectType tag)
218 tagValue = static_cast<eObjectType>(tagValue);
221 eObjectType getType()
223 static_cast<eObjectType>(tagValue);
227 typedef Tag<u8> LispTag;
228 typedef TLispValue<u128, CharType, FixnumType, FloatnumType, PrimitiveType, PointerType> LispValue;
231 // container of object data with a tag
232 template <typename T, typename D, template <typename> class C>
233 class TaggedObjData
235 public:
237 typedef T TagType;
238 typedef D ValueType;
239 typedef C<D> ValueContainerType;
241 T tag;
242 ValueContainerType values;
244 // T needs to implement sthing which will transform a tag to a
245 // object type
246 eObjectType getType()
248 return tag.getType(tag);
251 void setType(eObjectType type)
253 return tag.setType(type);
256 // container must have capacity
257 void resize(std::size_t s)
259 values.reserve(s);
260 values.resize(s);
263 // must be able to tell what that capacity is
264 std::size_t size() const
266 return values.size();
271 // TO DO -- template template parameters?
273 struct LispObj {
274 TaggedObjData<Tag<unsigned char>, LispValue, std::vector> object;
282 } // end namespace lisp
285 #endif