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
;
46 typedef u32 FixnumType
;
47 typedef f32 FloatnumType
;
48 typedef void * (*PrimitivePtr
)(void *);
52 // smart pointer for pointing at lisp objects
53 template <typename T
> class ObjPtr
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(); };
76 p_
= reinterpret_cast<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
92 explicit Primitive(PrimitivePtr f
) : fn_(f
) {}
93 PointerType
operator()(PointerType
**p
)
101 // object data with a tag
102 template <typename T
, typename D
, template <typename
> class C
>
109 typedef C
<D
> ValueContainerType
;
112 ValueContainerType values
;
115 // T needs to implement sthing which will transform a tag to a
117 eObjectType
getType()
119 return T::getType(tag
);
122 // Container needs to be sanely indexable
123 D
& operator[](std::size_t i
)
128 const D
& operator[](std::size_t i
) const
133 // container must have capacity
134 void resize(std::size_t 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
155 // need to be ablue to convert between ActualType and these types
159 ActualPtrT
* ptr
= reinterpret_cast<ActualPtrT
*>(&value
);
163 // we can't overload by return type, so we use value conversion instead
171 return *(static_cast<FloatnumT
*>(&value
));
176 return *(static_cast<CharT
*>(&value
));
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
);
192 TLispValue
& operator=(FixnumT fn
)
198 TLispValue
& set(FloatnumT fn
)
200 (*static_cast<FloatnumT
*>(&value
)) = fn
;
204 TLispValue
& operator=(CharT ch
)
206 (*static_cast<CharT
*>(&value
)) = ch
;
210 TLispValue
& operator=(PrimT prim
)
212 (*static_cast<PrimT
*>(&value
)) = prim
;
221 // tag types (this doesn't have to be POD, but its advisable)
222 template <typename T
> class Tag
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?
244 TaggedObjData
<Tag
<unsigned char>, LispValue
, std::vector
> object
;
252 } // end namespace lisp