vb: add seq and string?
[jackhill/mal.git] / vb / core.vb
CommitLineData
ee7cd585
JM
1Imports System
2Imports System.IO
3Imports System.Collections.Generic
4Imports MalVal = Mal.types.MalVal
5Imports MalConstant = Mal.types.MalConstant
6Imports MalInt = Mal.types.MalInt
7Imports MalSymbol = Mal.types.MalSymbol
8Imports MalString = Mal.types.MalString
9Imports MalList = Mal.types.MalList
10Imports MalVector = Mal.types.MalVector
11Imports MalHashMap = Mal.types.MalHashMap
12Imports MalAtom = Mal.types.MalAtom
13Imports MalFunc = Mal.types.MalFunc
14
15Namespace Mal
16 Public Class core
17 Shared Nil As MalConstant = Mal.types.Nil
18 Shared MalTrue As MalConstant = Mal.types.MalTrue
19 Shared MalFalse As MalConstant = Mal.types.MalFalse
20
21 ' Errors/Exceptions
22 Shared Function mal_throw(a As MalList) As MalVal
23 throw New Mal.types.MalException(a(0))
24 End Function
25
26 ' General functions
27 Shared Function equal_Q(a As MalList) As MalVal
28 If Mal.types._equal_Q(a(0), a(1)) Then
29 return MalTrue
30 Else
31 return MalFalse
32 End If
33 End Function
34
35 ' Scalar functions
36 Shared Function nil_Q(a As MalList) As MalVal
37 If a(0) Is Nil Then
38 return MalTrue
39 Else
40 return MalFalse
41 End If
42 End Function
43
44 Shared Function true_Q(a As MalList) As MalVal
45 If a(0) Is MalTrue Then
46 return MalTrue
47 Else
48 return MalFalse
49 End If
50 End Function
51
52 Shared Function false_Q(a As MalList) As MalVal
53 If a(0) Is MalFalse Then
54 return MalTrue
55 Else
56 return MalFalse
57 End If
58 End Function
59
60 Shared Function symbol(a As MalList) As MalVal
61 return new MalSymbol(DirectCast(a(0),MalString))
62 End Function
63
64 Shared Function symbol_Q(a As MalList) As MalVal
65 If TypeOf a(0) Is MalSymbol Then
66 return MalTrue
67 Else
68 return MalFalse
69 End If
70 End Function
71
25dff298
DM
72 Shared Function string_Q(a As MalList) As MalVal
73 If TypeOf a(0) Is MalString Then
74 Dim s As String = DirectCast(a(0),MalString).getValue()
75 If s.Length = 0 Then
76 return MalTrue
77 Elseif s.Substring(0,1) = Strings.ChrW(&H029e) Then
78 return MalFalse
79 Else
80 return MalTrue
81 End If
82 Else
83 return MalFalse
84 End If
85 End Function
86
b8ee29b2
JM
87 Shared Function keyword(a As MalList) As MalVal
88 Dim s As String = DirectCast(a(0),MalString).getValue()
89 return new MalString(ChrW(&H029e) & s)
90 End Function
91
92 Shared Function keyword_Q(a As MalList) As MalVal
93 If TypeOf a(0) Is MalString Then
94 Dim s As String = DirectCast(a(0),MalString).getValue()
25dff298
DM
95 If s.Length = 0 Then
96 return MalFalse
97 Elseif s.Substring(0,1) = Strings.ChrW(&H029e) Then
b8ee29b2
JM
98 return MalTrue
99 Else
100 return MalFalse
101 End If
102 Else
103 return MalFalse
104 End If
105 End Function
106
ee7cd585
JM
107
108 ' Number functions
109 Shared Function lt(a As MalList) As MalVal
110 return DirectCast(a(0),MalInt) < DirectCast(a(1),MalInt)
111 End Function
112 Shared Function lte(a As MalList) As MalVal
113 return DirectCast(a(0),MalInt) <= DirectCast(a(1),MalInt)
114 End Function
115 Shared Function gt(a As MalList) As MalVal
116 return DirectCast(a(0),MalInt) > DirectCast(a(1),MalInt)
117 End Function
118 Shared Function gte(a As MalList) As MalVal
119 return DirectCast(a(0),MalInt) >= DirectCast(a(1),MalInt)
120 End Function
121 Shared Function plus(a As MalList) As MalVal
122 return DirectCast(a(0),MalInt) + DirectCast(a(1),MalInt)
123 End Function
124 Shared Function minus(a As MalList) As MalVal
125 return DirectCast(a(0),MalInt) - DirectCast(a(1),MalInt)
126 End Function
127 Shared Function mult(a As MalList) As MalVal
128 return DirectCast(a(0),MalInt) * DirectCast(a(1),MalInt)
129 End Function
130 Shared Function div(a As MalList) As MalVal
131 return DirectCast(a(0),MalInt) / DirectCast(a(1),MalInt)
132 End Function
133
134 Shared Function time_ms(a As MalList) As MalVal
135 return New MalInt(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond)
136 End Function
137
138 ' String functions
139 Shared Function pr_str(a As MalList) As MalVal
140 return New MalString(printer._pr_str_args(a, " ", true))
141 End Function
142
143 Shared Function str(a As MalList) As MalVal
144 return new MalString(printer._pr_str_args(a, "", false))
145 End Function
146
147 Shared Function prn(a As MalList) As MalVal
148 Console.WriteLine(printer._pr_str_args(a, " ", true))
149 return Nil
150 End Function
151
152 Shared Function println(a As MalList) As MalVal
153 Console.WriteLine(printer._pr_str_args(a, " ", false))
154 return Nil
155 End Function
156
157 Shared Function mal_readline(a As MalList) As MalVal
158 Dim line As String
159 line = readline.Readline(DirectCast(a(0),MalString).getValue())
160 If line Is Nothing Then
161 return types.Nil
162 Else
163 return New MalString(line)
164 End If
165 End Function
166
167 Shared Function read_string(a As MalList) As MalVal
168 return reader.read_str(DirectCast(a(0),MalString).getValue())
169 End Function
170
171 Shared Function slurp(a As MalList) As MalVal
172 return New MalString(File.ReadAllText(DirectCast(a(0),MalString).getValue()))
173 End Function
174
175
176 ' List/Vector functions
177
178 Shared Function list(a As MalList) As MalVal
179 return New MalList(a.getValue())
180 End Function
181
182 Shared Function list_Q(a As MalList) As MalVal
183 If TypeOf a(0) Is MalList And Not TypeOf a(0) Is MalVector Then
184 return MalTrue
185 Else
186 return MalFalse
187 End If
188 End Function
189
190 Shared Function vector(a As MalList) As MalVal
191 return New MalVector(a.getValue())
192 End Function
193
194 Shared Function vector_Q(a As MalList) As MalVal
195 If TypeOf a(0) Is MalVector Then
196 return MalTrue
197 Else
198 return MalFalse
199 End If
200 End Function
201
202 ' HashMap functions
203 Shared Function hash_map(a As MalList) As MalVal
204 return New MalHashMap(a)
205 End Function
206
207 Shared Function hash_map_Q(a As MalList) As MalVal
208 If TypeOf a(0) Is MalHashMap Then
209 return MalTrue
210 Else
211 return MalFalse
212 End If
213 End Function
214
215 Shared Function contains_Q(a As MalList) As MalVal
216 Dim key As String = DirectCast(a(1),MalString).getValue()
217 Dim dict As Dictionary(Of String,MalVal) = DirectCast(a(0),MalHashMap).getValue()
218 If dict.ContainsKey(key) Then
219 return MalTrue
220 Else
221 return MalFalse
222 End If
223 End Function
224
225 Shared Function assoc(a As MalList) As MalVal
226 Dim new_hm As MalHashMap = DirectCast(a(0),MalHashMap).copy()
227 return new_hm.assoc_BANG(DirectCast(a.slice(1),MalList))
228 End Function
229
230 Shared Function dissoc(a As MalList) As MalVal
231 Dim new_hm As MalHashMap = DirectCast(a(0),MalHashMap).copy()
232 return new_hm.dissoc_BANG(DirectCast(a.slice(1),MalList))
233 End Function
234
235 Shared Function do_get(a As MalList) As MalVal
236 Dim k As String = DirectCast(a(1),MalString).getValue()
237 If a(0) Is Nil Then
238 return Nil
239 Else
240 Dim dict As Dictionary(Of String,MalVal) = DirectCast(a(0),MalHashMap).getValue()
241 If dict.ContainsKey(k) Then
242 return dict(k)
243 Else
244 return Nil
245 End If
246 End If
247 End Function
248
249 Shared Function keys(a As MalList) As MalVal
250 Dim dict As Dictionary(Of String,MalVal) = DirectCast(a(0),MalHashMap).getValue()
251 Dim key_lst As MalList = New MalList()
252 For Each key As String in dict.Keys
253 key_lst.conj_BANG(new MalString(key))
254 Next
255 return key_lst
256 End Function
257
258 Shared Function vals(a As MalList) As MalVal
259 Dim dict As Dictionary(Of String,MalVal) = DirectCast(a(0),MalHashMap).getValue()
260 Dim val_lst As MalList = New MalList()
261 For Each val As MalVal In dict.Values
262 val_lst.conj_BANG(val)
263 Next
264 return val_lst
265 End Function
266
267 ' Sequence functions
268 Shared Function sequential_Q(a As MalList) As MalVal
269 If TypeOf a(0) Is MalList Then
270 return MalTrue
271 Else
272 return MalFalse
273 End If
274 End Function
275
276 Shared Function cons(a As MalList) As MalVal
277 Dim lst As New List(Of MalVal)
278 lst.Add(a(0))
279 lst.AddRange(DirectCast(a(1),MalList).getValue())
280 return DirectCast(New MalList(lst),MalVal)
281 End Function
282
283 Shared Function concat(a As MalList) As MalVal
284 If a.size() = 0 Then
285 return new MalList()
286 End If
287 Dim lst As New List(Of MalVal)
288 lst.AddRange(DirectCast(a(0),MalList).getValue())
289 for i As Integer = 1 To a.size()-1
290 lst.AddRange(DirectCast(a(i),MalList).getValue())
291 Next
292 return DirectCast(new MalList(lst),MalVal)
293 End Function
294
295 Shared Function nth(a As MalList) As MalVal
b8ee29b2
JM
296 Dim idx As Integer = DirectCast(a(1),MalInt).getValue()
297 If (idx < DirectCast(a(0),MalList).size()) Then
298 return DirectCast(a(0),MalList)( idx )
299 Else
300 throw new Mal.types.MalException(
301 "nth: index out of range")
302 End If
ee7cd585
JM
303 End Function
304
305 Shared Function first(a As MalList) As MalVal
283779ea
DM
306 If a(0) Is Nil Then
307 return Nil
308 Else
309 return DirectCast(a(0),MalList)(0)
310 End If
ee7cd585
JM
311 End Function
312
313 Shared Function rest(a As MalList) As MalVal
283779ea
DM
314 If a(0) Is Nil Then
315 return new MalList()
316 Else
317 return DirectCast(a(0),MalList).rest()
318 End If
ee7cd585
JM
319 End Function
320
321 Shared Function empty_Q(a As MalList) As MalVal
322 If DirectCast(a(0),MalList).size() = 0 Then
323 return MalTrue
324 Else
325 return MalFalse
326 End If
327 End Function
328
329 Shared Function count(a As MalList) As MalVal
b8ee29b2
JM
330 If a(0) Is Nil Then
331 return new MalInt(0)
332 Else
333 return new MalInt(DirectCast(a(0),MalList).size())
334 End If
ee7cd585
JM
335 End Function
336
337 Shared Function conj(a As MalList) As MalVal
338 Dim src_lst As List(Of MalVal) = DirectCast(a(0),MalList).getValue()
339 Dim new_lst As New List(Of MalVal)
340 new_lst.AddRange(src_lst)
341 If TypeOf a(0) Is MalVector Then
342 For i As Integer = 1 To a.size()-1
343 new_lst.Add(a(i))
344 Next
345 return new MalVector(new_lst)
346 Else
347 For i As Integer = 1 To a.size()-1
348 new_lst.Insert(0, a(i))
349 Next
350 return new MalList(new_lst)
351 End If
352 End Function
353
25dff298
DM
354 Shared Function seq(a As MalList) As MalVal
355 If a(0) Is Nil Then
356 return Nil
357 Elseif TypeOf a(0) is MalVector Then
358 If DirectCast(a(0),MalVector).size() = 0 Then
359 return Nil
360 End If
361 return new MalList(DirectCast(a(0),MalVector).getValue())
362 Elseif TypeOf a(0) is MalList Then
363 If DirectCast(a(0),MalList).size() = 0 Then
364 return Nil
365 End If
366 return a(0)
367 Elseif TypeOf a(0) is MalString Then
368 Dim s As String = DirectCast(a(0),MalString).getValue()
369 If s.Length = 0 Then
370 return Nil
371 End If
372 Dim chars_list As New List(Of MalVal)
373 For Each c As Char In s
374 chars_list.Add(new MalString(c.ToString()))
375 Next
376 return new MalList(chars_list)
377 Else
378 return Nil
379 End If
380 End Function
ee7cd585
JM
381
382 ' General list related functions
383 Shared Function apply(a As MalList) As MalVal
384 Dim f As MalFunc = DirectCast(a(0),MalFunc)
385 Dim lst As New List(Of MalVal)
386 lst.AddRange(a.slice(1,a.size()-1).getValue())
387 lst.AddRange(DirectCast(a(a.size()-1),MalList).getValue())
388 return f.apply(New MalList(lst))
389 End Function
390
391 Shared Function map(a As MalList) As MalVal
392 Dim f As MalFunc = DirectCast(a(0),MalFunc)
393 Dim src_lst As List(Of MalVal) = DirectCast(a(1),MalList).getValue()
394 Dim new_lst As New List(Of MalVal)
395 for i As Integer = 0 To src_lst.Count-1
396 new_lst.Add(f.apply(New MalList(src_lst(i))))
397 Next
398 return new MalList(new_lst)
399 End Function
400
401
402 ' Metadata functions
403 Shared Function atom(a As MalList) As MalVal
404 return new MalAtom(a(0))
405 End Function
406
407 Shared Function meta(a As MalList) As MalVal
408 return a(0).getMeta()
409 End Function
410
411 Shared Function with_meta(a As MalList) As MalVal
412 return DirectCast(a(0),MalVal).copy().setMeta(a(1))
413 End Function
414
415
416 ' Atom functions
417 Shared Function atom_Q(a As MalList) As MalVal
418 If TypeOf a(0) Is MalAtom Then
419 return MalTrue
420 Else
421 return MalFalse
422 End If
423 End Function
424
425 Shared Function deref(a As MalList) As MalVal
426 return DirectCast(a(0),MalAtom).getValue()
427 End Function
428
429 Shared Function reset_BANG(a As MalList) As MalVal
430 return DirectCast(a(0),MalAtom).setValue(a(1))
431 End Function
432
433 Shared Function swap_BANG(a As MalList) As MalVal
434 Dim atm As MalAtom = DirectCast(a(0),MalAtom)
435 Dim f As MalFunc = DirectCast(a(1),MalFunc)
436 Dim new_lst As New List(Of MalVal)
437 new_lst.Add(atm.getValue())
438 new_lst.AddRange(DirectCast(a.slice(2),MalList).getValue())
439 return atm.setValue(f.apply(New MalList(new_lst)))
440 End Function
441
442
443
444 Shared Function ns As Dictionary(Of String, MalVal)
445 Dim ns As New Dictionary(Of String, MalVal)
446
447 ns.Add("=", New MalFunc(AddressOf equal_Q))
448 ns.Add("throw", New MalFunc(AddressOf mal_throw))
449 ns.Add("nil?", New MalFunc(AddressOf nil_Q))
450 ns.Add("true?", New MalFunc(AddressOf true_Q))
451 ns.Add("false?", New MalFunc(AddressOf false_Q))
452 ns.Add("symbol", new MalFunc(AddressOf symbol))
453 ns.Add("symbol?", New MalFunc(AddressOf symbol_Q))
25dff298 454 ns.Add("string?", New MalFunc(AddressOf string_Q))
b8ee29b2
JM
455 ns.Add("keyword", new MalFunc(AddressOf keyword))
456 ns.Add("keyword?", New MalFunc(AddressOf keyword_Q))
ee7cd585
JM
457
458 ns.Add("pr-str",New MalFunc(AddressOf pr_str))
459 ns.Add("str", New MalFunc(AddressOf str))
460 ns.Add("prn", New MalFunc(AddressOf prn))
461 ns.Add("println", New MalFunc(AddressOf println))
462 ns.Add("readline", New MalFunc(AddressOf mal_readline))
463 ns.Add("read-string", New MalFunc(AddressOf read_string))
464 ns.Add("slurp", New MalFunc(AddressOf slurp))
465 ns.Add("<", New MalFunc(AddressOf lt))
466 ns.Add("<=", New MalFunc(AddressOf lte))
467 ns.Add(">", New MalFunc(AddressOf gt))
468 ns.Add(">=", New MalFunc(AddressOf gte))
469 ns.Add("+", New MalFunc(AddressOf plus))
470 ns.Add("-", New MalFunc(AddressOf minus))
471 ns.Add("*", New MalFunc(AddressOf mult))
472 ns.Add("/", New MalFunc(AddressOf div))
473 ns.Add("time-ms", New MalFunc(AddressOf time_ms))
474
475 ns.Add("list", New MalFunc(AddressOf list))
476 ns.Add("list?", New MalFunc(AddressOf list_Q))
477 ns.Add("vector", new MalFunc(AddressOf vector))
478 ns.Add("vector?", New MalFunc(AddressOf vector_Q))
479 ns.Add("hash-map", new MalFunc(AddressOf hash_map))
480 ns.Add("map?", New MalFunc(AddressOf hash_map_Q))
481 ns.Add("contains?", New MalFunc(AddressOf contains_Q))
482 ns.Add("assoc", New MalFunc(AddressOf assoc))
483 ns.Add("dissoc", New MalFunc(AddressOf dissoc))
484 ns.Add("get", New MalFunc(AddressOf do_get))
485 ns.Add("keys", New MalFunc(AddressOf keys))
486 ns.Add("vals", New MalFunc(AddressOf vals))
487
488 ns.Add("sequential?", New MalFunc(AddressOf sequential_Q))
489 ns.Add("cons", New MalFunc(AddressOf cons))
490 ns.Add("concat", New MalFunc(AddressOf concat))
491 ns.Add("nth", New MalFunc(AddressOf nth))
492 ns.Add("first", New MalFunc(AddressOf first))
493 ns.Add("rest", New MalFunc(AddressOf rest))
494 ns.Add("empty?", New MalFunc(AddressOf empty_Q))
495 ns.Add("count",New MalFunc(AddressOf count))
496 ns.Add("conj", New MalFunc(AddressOf conj))
25dff298 497 ns.Add("seq", New MalFunc(AddressOf seq))
ee7cd585
JM
498 ns.Add("apply", New MalFunc(AddressOf apply))
499 ns.Add("map", New MalFunc(AddressOf map))
500
501 ns.Add("with-meta", New MalFunc(AddressOf with_meta))
502 ns.Add("meta", New MalFunc(AddressOf meta))
503 ns.Add("atom", new MalFunc(AddressOf atom))
504 ns.Add("atom?", New MalFunc(AddressOf atom_Q))
505 ns.Add("deref", New MalFunc(AddressOf deref))
506 ns.Add("reset!", New MalFunc(AddressOf reset_BANG))
507 ns.Add("swap!", New MalFunc(AddressOf swap_BANG))
508 return ns
509 End Function
510 End Class
511End Namespace