24 MAL_FALSE
= MalFalse
()
32 return MalNumber
(val
=atoi
(s
))
60 func count
(obj
) { return numberof
(*obj.val
); }
63 seq
= count
(obj
) <= 1 ?
[] : ((*obj.val
)(2:))
64 return MalList
(val
=&seq)
72 func hashmap_obj_to_key
(obj
) {
73 if
(structof
(obj
) == MalString
) return
"str:" + obj.val
74 else if
(structof
(obj
) == MalSymbol
) return
"sym:" + obj.val
75 else if
(structof
(obj
) == MalKeyword
) return
"key:" + obj.val
76 else error
, "Unsupported obj type for hash key"
79 func hashmap_key_to_obj
(key
) {
80 type_str
= strpart
(key
, 1:4)
81 val
= strpart
(key
, 5:)
82 if
(type_str
== "str:") return MalString
(val
=val
)
83 else if
(type_str
== "sym:") return MalSymbol
(val
=val
)
84 else if
(type_str
== "key:") return MalKeyword
(val
=val
)
85 else error
, "Unsupported key type"
88 func array_to_hashmap
(seq
)
90 if
(numberof
(seq
) % 2 != 0) return MalError
(message
="Odd number of elements in hashmap")
92 for
(i
= 1; i
<= numberof
(seq
); i
+= 2) {
93 hash_set
, h
, hashmap_obj_to_key
(*seq
(i
)), *seq
(i
+ 1)
95 return MalHashmap
(val
=&h)
98 struct MalNativeFunction
{
116 func is_macro
(obj
) { return
(structof
(obj
) == MalFunction
&& obj.macro); }
122 func new_boolean
(b
) {
123 if
(b
) return MAL_TRUE
127 func equal_seq
(seq_a
, seq_b
) {
128 if
(numberof
(seq_a
) != numberof
(seq_b
)) return
0
129 for
(i
= 1; i
<= numberof
(seq_a
); ++i
) {
130 if
(!equal
(*seq_a
(i
), *seq_b
(i
))) return
0
135 func equal_hash
(hm_a
, hm_b
) {
136 if
(numberof
(*hm_a.keys
) != numberof
(*hm_b.keys
)) return
0
137 for
(i
= 1; i
<= numberof
(*hm_a.keys
); ++i
) {
138 key_a
= (*hm_a.keys
)(i
)
139 val_a
= *((*hm_a.vals
)(i
))
140 val_b
= hash_get
(hm_b
, key_a
)
141 if
(is_void
(val_b
) ||
!equal
(val_a
, val_b
)) return
0
149 if
(ta
== MalNil
) return tb
== MalNil
150 else if
(ta
== MalTrue
) return tb
== MalTrue
151 else if
(ta
== MalFalse
) return tb
== MalFalse
152 else if
(ta
== MalNumber
) return tb
== MalNumber
&& a.val == b.val
153 else if
(ta
== MalSymbol
) return tb
== MalSymbol
&& a.val == b.val
154 else if
(ta
== MalString
) return tb
== MalString
&& a.val == b.val
155 else if
(ta
== MalKeyword
) return tb
== MalKeyword
&& a.val == b.val
156 else if
(ta
== MalList || ta
== MalVector
) {
157 return
(tb
== MalList || tb
== MalVector
) && equal_seq(*(a.val), *(b.val))
159 else if
(ta
== MalHashmap
) return tb
== MalHashmap
&& equal_hash(*a.val, *b.val)
163 func streplaceall
(s
, pattern
, subst
)
165 return streplace
(s
, strfind
(pattern
, s
, n
=999), subst
)