1 #ifndef INCLUDE_TYPES_H
2 #define INCLUDE_TYPES_H
9 class malEmptyInputException
: public std::exception
{ };
11 class malValue
: public RefCounted
{
14 TRACE_OBJECT("Creating malValue %p\n", this);
16 malValue(malValuePtr meta
) : m_meta(meta
) {
17 TRACE_OBJECT("Creating malValue %p\n", this);
20 TRACE_OBJECT("Destroying malValue %p\n", this);
23 malValuePtr
withMeta(malValuePtr meta
) const;
24 virtual malValuePtr
doWithMeta(malValuePtr meta
) const = 0;
25 malValuePtr
meta() const;
29 bool isEqualTo(const malValue
* rhs
) const;
31 virtual malValuePtr
eval(malEnvPtr env
);
33 virtual String
print(bool readably
) const = 0;
36 virtual bool doIsEqualTo(const malValue
* rhs
) const = 0;
42 T
* value_cast(malValuePtr obj
, const char* typeName
) {
43 T
* dest
= dynamic_cast<T
*>(obj
.ptr());
44 MAL_CHECK(dest
!= NULL
, "%s is not a %s",
45 obj
->print(true).c_str(), typeName
);
49 #define VALUE_CAST(Type, Value) value_cast<Type>(Value, #Type)
50 #define DYNAMIC_CAST(Type, Value) (dynamic_cast<Type*>((Value).ptr()))
51 #define STATIC_CAST(Type, Value) (static_cast<Type*>((Value).ptr()))
53 #define WITH_META(Type) \
54 virtual malValuePtr doWithMeta(malValuePtr meta) const { \
55 return new Type(*this, meta); \
58 class malConstant : public malValue {
60 malConstant(String name
) : m_name(name
) { }
61 malConstant(const malConstant
& that
, malValuePtr meta
)
62 : malValue(meta
), m_name(that
.m_name
) { }
64 virtual String
print(bool readably
) const { return m_name
; }
66 virtual bool doIsEqualTo(const malValue
* rhs
) const {
67 return this == rhs
; // these are singletons
70 WITH_META(malConstant
);
76 class malInteger
: public malValue
{
78 malInteger(int value
) : m_value(value
) { }
79 malInteger(const malInteger
& that
, malValuePtr meta
)
80 : malValue(meta
), m_value(that
.m_value
) { }
82 virtual String
print(bool readably
) const {
83 return std::to_string(m_value
);
86 int value() const { return m_value
; }
88 virtual bool doIsEqualTo(const malValue
* rhs
) const {
89 return m_value
== static_cast<const malInteger
*>(rhs
)->m_value
;
92 WITH_META(malInteger
);
98 class malStringBase
: public malValue
{
100 malStringBase(const String
& token
)
102 malStringBase(const malStringBase
& that
, malValuePtr meta
)
103 : malValue(meta
), m_value(that
.value()) { }
105 virtual String
print(bool readably
) const { return m_value
; }
107 String
value() const { return m_value
; }
110 const String m_value
;
113 class malString
: public malStringBase
{
115 malString(const String
& token
)
116 : malStringBase(token
) { }
117 malString(const malString
& that
, malValuePtr meta
)
118 : malStringBase(that
, meta
) { }
120 virtual String
print(bool readably
) const;
122 String
escapedValue() const;
124 virtual bool doIsEqualTo(const malValue
* rhs
) const {
125 return value() == static_cast<const malString
*>(rhs
)->value();
128 WITH_META(malString
);
131 class malKeyword
: public malStringBase
{
133 malKeyword(const String
& token
)
134 : malStringBase(token
) { }
135 malKeyword(const malKeyword
& that
, malValuePtr meta
)
136 : malStringBase(that
, meta
) { }
138 virtual bool doIsEqualTo(const malValue
* rhs
) const {
139 return value() == static_cast<const malKeyword
*>(rhs
)->value();
142 WITH_META(malKeyword
);
145 class malSymbol
: public malStringBase
{
147 malSymbol(const String
& token
)
148 : malStringBase(token
) { }
149 malSymbol(const malSymbol
& that
, malValuePtr meta
)
150 : malStringBase(that
, meta
) { }
152 virtual malValuePtr
eval(malEnvPtr env
);
154 virtual bool doIsEqualTo(const malValue
* rhs
) const {
155 return value() == static_cast<const malSymbol
*>(rhs
)->value();
158 WITH_META(malSymbol
);
161 class malSequence
: public malValue
{
163 malSequence(malValueVec
* items
);
164 malSequence(malValueIter begin
, malValueIter end
);
165 malSequence(const malSequence
& that
, malValuePtr meta
);
166 virtual ~malSequence();
168 virtual String
print(bool readably
) const;
170 malValueVec
* evalItems(malEnvPtr env
) const;
171 int count() const { return m_items
->size(); }
172 bool isEmpty() const { return m_items
->empty(); }
173 malValuePtr
item(int index
) const { return (*m_items
)[index
]; }
175 malValueIter
begin() const { return m_items
->begin(); }
176 malValueIter
end() const { return m_items
->end(); }
178 virtual bool doIsEqualTo(const malValue
* rhs
) const;
180 virtual malValuePtr
conj(malValueIter argsBegin
,
181 malValueIter argsEnd
) const = 0;
183 malValuePtr
first() const;
184 virtual malValuePtr
rest() const;
187 malValueVec
* const m_items
;
190 class malList
: public malSequence
{
192 malList(malValueVec
* items
) : malSequence(items
) { }
193 malList(malValueIter begin
, malValueIter end
)
194 : malSequence(begin
, end
) { }
195 malList(const malList
& that
, malValuePtr meta
)
196 : malSequence(that
, meta
) { }
198 virtual String
print(bool readably
) const;
199 virtual malValuePtr
eval(malEnvPtr env
);
201 virtual malValuePtr
conj(malValueIter argsBegin
,
202 malValueIter argsEnd
) const;
207 class malVector
: public malSequence
{
209 malVector(malValueVec
* items
) : malSequence(items
) { }
210 malVector(malValueIter begin
, malValueIter end
)
211 : malSequence(begin
, end
) { }
212 malVector(const malVector
& that
, malValuePtr meta
)
213 : malSequence(that
, meta
) { }
215 virtual malValuePtr
eval(malEnvPtr env
);
216 virtual String
print(bool readably
) const;
218 virtual malValuePtr
conj(malValueIter argsBegin
,
219 malValueIter argsEnd
) const;
221 WITH_META(malVector
);
224 class malApplicable
: public malValue
{
227 malApplicable(malValuePtr meta
) : malValue(meta
) { }
229 virtual malValuePtr
apply(malValueIter argsBegin
,
230 malValueIter argsEnd
,
231 malEnvPtr env
) const = 0;
234 class malHash
: public malValue
{
236 typedef std::map
<String
, malValuePtr
> Map
;
238 malHash(malValueIter argsBegin
, malValueIter argsEnd
, bool isEvaluated
);
239 malHash(const malHash::Map
& map
);
240 malHash(const malHash
& that
, malValuePtr meta
)
241 : malValue(meta
), m_map(that
.m_map
), m_isEvaluated(that
.m_isEvaluated
) { }
243 malValuePtr
assoc(malValueIter argsBegin
, malValueIter argsEnd
) const;
244 malValuePtr
dissoc(malValueIter argsBegin
, malValueIter argsEnd
) const;
245 bool contains(malValuePtr key
) const;
246 malValuePtr
eval(malEnvPtr env
);
247 malValuePtr
get(malValuePtr key
) const;
248 malValuePtr
keys() const;
249 malValuePtr
values() const;
251 virtual String
print(bool readably
) const;
253 virtual bool doIsEqualTo(const malValue
* rhs
) const;
259 const bool m_isEvaluated
;
262 class malBuiltIn
: public malApplicable
{
264 typedef malValuePtr (ApplyFunc
)(const String
& name
,
265 malValueIter argsBegin
,
266 malValueIter argsEnd
,
269 malBuiltIn(const String
& name
, ApplyFunc
* handler
)
270 : m_name(name
), m_handler(handler
) { }
272 malBuiltIn(const malBuiltIn
& that
, malValuePtr meta
)
273 : malApplicable(meta
), m_name(that
.m_name
), m_handler(that
.m_handler
) { }
275 virtual malValuePtr
apply(malValueIter argsBegin
,
276 malValueIter argsEnd
,
277 malEnvPtr env
) const;
279 virtual String
print(bool readably
) const {
280 return STRF("#builtin-function(%s)", m_name
.c_str());
283 virtual bool doIsEqualTo(const malValue
* rhs
) const {
284 return this == rhs
; // these are singletons
287 String
name() const { return m_name
; }
289 WITH_META(malBuiltIn
);
293 ApplyFunc
* m_handler
;
296 class malLambda
: public malApplicable
{
298 malLambda(const StringVec
& bindings
, malValuePtr body
, malEnvPtr env
);
299 malLambda(const malLambda
& that
, malValuePtr meta
);
300 malLambda(const malLambda
& that
, bool isMacro
);
302 virtual malValuePtr
apply(malValueIter argsBegin
,
303 malValueIter argsEnd
,
304 malEnvPtr env
) const;
306 malValuePtr
getBody() const { return m_body
; }
307 malEnvPtr
makeEnv(malValueIter argsBegin
, malValueIter argsEnd
) const;
309 virtual bool doIsEqualTo(const malValue
* rhs
) const {
310 return this == rhs
; // do we need to do a deep inspection?
313 virtual String
print(bool readably
) const {
314 return STRF("#user-%s(%p)", m_isMacro
? "macro" : "function", this);
317 bool isMacro() const { return m_isMacro
; }
319 virtual malValuePtr
doWithMeta(malValuePtr meta
) const;
322 const StringVec m_bindings
;
323 const malValuePtr m_body
;
324 const malEnvPtr m_env
;
325 const bool m_isMacro
;
328 class malAtom
: public malValue
{
330 malAtom(malValuePtr value
) : m_value(value
) { }
331 malAtom(const malAtom
& that
, malValuePtr meta
)
332 : malValue(meta
), m_value(that
.m_value
) { }
334 virtual bool doIsEqualTo(const malValue
* rhs
) const {
335 return this->m_value
->isEqualTo(rhs
);
338 virtual String
print(bool readably
) const {
339 return "(atom " + m_value
->print(readably
) + ")";
342 malValuePtr
deref() const { return m_value
; }
344 malValuePtr
reset(malValuePtr value
) { return m_value
= value
; }
353 malValuePtr
atom(malValuePtr value
);
354 malValuePtr
boolean(bool value
);
355 malValuePtr
builtin(const String
& name
, malBuiltIn::ApplyFunc handler
);
356 malValuePtr
falseValue();
357 malValuePtr
hash(malValueIter argsBegin
, malValueIter argsEnd
,
359 malValuePtr
hash(const malHash::Map
& map
);
360 malValuePtr
integer(int value
);
361 malValuePtr
integer(const String
& token
);
362 malValuePtr
keyword(const String
& token
);
363 malValuePtr
lambda(const StringVec
&, malValuePtr
, malEnvPtr
);
364 malValuePtr
list(malValueVec
* items
);
365 malValuePtr
list(malValueIter begin
, malValueIter end
);
366 malValuePtr
list(malValuePtr a
);
367 malValuePtr
list(malValuePtr a
, malValuePtr b
);
368 malValuePtr
list(malValuePtr a
, malValuePtr b
, malValuePtr c
);
369 malValuePtr
macro(const malLambda
& lambda
);
370 malValuePtr
nilValue();
371 malValuePtr
string(const String
& token
);
372 malValuePtr
symbol(const String
& token
);
373 malValuePtr
trueValue();
374 malValuePtr
vector(malValueVec
* items
);
375 malValuePtr
vector(malValueIter begin
, malValueIter end
);
378 #endif // INCLUDE_TYPES_H