aboutsummaryrefslogtreecommitdiff
path: root/vb/core.vb
blob: 771d0cce3bab132f99d29b0850496cc4bf960d03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
Imports System
Imports System.IO
Imports System.Collections.Generic
Imports MalVal = Mal.types.MalVal
Imports MalConstant = Mal.types.MalConstant
Imports MalInt = Mal.types.MalInt
Imports MalSymbol = Mal.types.MalSymbol
Imports MalString = Mal.types.MalString
Imports MalList = Mal.types.MalList
Imports MalVector = Mal.types.MalVector
Imports MalHashMap = Mal.types.MalHashMap
Imports MalAtom = Mal.types.MalAtom
Imports MalFunc = Mal.types.MalFunc

Namespace Mal
    Public Class core
        Shared Nil As MalConstant = Mal.types.Nil
        Shared MalTrue As MalConstant = Mal.types.MalTrue
        Shared MalFalse As MalConstant = Mal.types.MalFalse

        ' Errors/Exceptions
        Shared Function mal_throw(a As MalList) As MalVal
            throw New Mal.types.MalException(a(0))
        End Function

        ' General functions
        Shared Function equal_Q(a As MalList) As MalVal
            If Mal.types._equal_Q(a(0), a(1)) Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        ' Scalar functions
        Shared Function nil_Q(a As MalList) As MalVal
            If a(0) Is Nil Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function true_Q(a As MalList) As MalVal
            If a(0) Is MalTrue Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function false_Q(a As MalList) As MalVal
            If a(0) Is MalFalse Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function symbol(a As MalList) As MalVal
            return new MalSymbol(DirectCast(a(0),MalString))
        End Function

        Shared Function symbol_Q(a As MalList) As MalVal
            If TypeOf a(0) Is MalSymbol Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function keyword(a As MalList) As MalVal
            Dim s As String = DirectCast(a(0),MalString).getValue()
            return new MalString(ChrW(&H029e) & s)
        End Function

        Shared Function keyword_Q(a As MalList) As MalVal
            If TypeOf a(0) Is MalString Then
                Dim s As String = DirectCast(a(0),MalString).getValue()
                If s.Substring(0,1) = Strings.ChrW(&H029e) Then
                    return MalTrue
                Else
                    return MalFalse
                End If
            Else
                return MalFalse
            End If
        End Function


        ' Number functions
        Shared Function lt(a As MalList) As MalVal
            return DirectCast(a(0),MalInt) <  DirectCast(a(1),MalInt)
        End Function
        Shared Function lte(a As MalList) As MalVal
            return DirectCast(a(0),MalInt) <= DirectCast(a(1),MalInt)
        End Function
        Shared Function gt(a As MalList) As MalVal
            return DirectCast(a(0),MalInt) >  DirectCast(a(1),MalInt)
        End Function
        Shared Function gte(a As MalList) As MalVal
            return DirectCast(a(0),MalInt) >= DirectCast(a(1),MalInt)
        End Function
        Shared Function plus(a As MalList) As MalVal
            return DirectCast(a(0),MalInt) +  DirectCast(a(1),MalInt)
        End Function
        Shared Function minus(a As MalList) As MalVal
            return DirectCast(a(0),MalInt) -  DirectCast(a(1),MalInt)
        End Function
        Shared Function mult(a As MalList) As MalVal
            return DirectCast(a(0),MalInt) *  DirectCast(a(1),MalInt)
        End Function
        Shared Function div(a As MalList) As MalVal
            return DirectCast(a(0),MalInt) /  DirectCast(a(1),MalInt)
        End Function

        Shared Function time_ms(a As MalList) As MalVal
            return New MalInt(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond)
        End Function

        ' String functions
        Shared Function pr_str(a As MalList) As MalVal
            return New MalString(printer._pr_str_args(a, " ", true))
        End Function

        Shared Function str(a As MalList) As MalVal
            return new MalString(printer._pr_str_args(a, "", false))
        End Function

        Shared Function prn(a As MalList) As MalVal
            Console.WriteLine(printer._pr_str_args(a, " ", true))
            return Nil
        End Function

        Shared Function println(a As MalList) As MalVal
            Console.WriteLine(printer._pr_str_args(a, " ", false))
            return Nil
        End Function

        Shared Function mal_readline(a As MalList) As MalVal
            Dim line As String
            line = readline.Readline(DirectCast(a(0),MalString).getValue())
            If line Is Nothing Then
                return types.Nil
            Else
                return New MalString(line)
            End If
        End Function

        Shared Function read_string(a As MalList) As MalVal
            return reader.read_str(DirectCast(a(0),MalString).getValue())
        End Function

        Shared Function slurp(a As MalList) As MalVal
            return New MalString(File.ReadAllText(DirectCast(a(0),MalString).getValue()))
        End Function


        ' List/Vector functions

        Shared Function list(a As MalList) As MalVal
            return New MalList(a.getValue())
        End Function

        Shared Function list_Q(a As MalList) As MalVal
            If TypeOf a(0) Is MalList And Not TypeOf a(0) Is MalVector Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function vector(a As MalList) As MalVal
            return New MalVector(a.getValue())
        End Function

        Shared Function vector_Q(a As MalList) As MalVal
            If TypeOf a(0) Is MalVector Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        ' HashMap functions
        Shared Function hash_map(a As MalList) As MalVal
            return New MalHashMap(a)
        End Function

        Shared Function hash_map_Q(a As MalList) As MalVal
            If TypeOf a(0) Is MalHashMap Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function contains_Q(a As MalList) As MalVal
            Dim key As String = DirectCast(a(1),MalString).getValue()
            Dim dict As Dictionary(Of String,MalVal) = DirectCast(a(0),MalHashMap).getValue()
            If dict.ContainsKey(key) Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function assoc(a As MalList) As MalVal
            Dim new_hm As MalHashMap = DirectCast(a(0),MalHashMap).copy()
            return new_hm.assoc_BANG(DirectCast(a.slice(1),MalList))
        End Function

        Shared Function dissoc(a As MalList) As MalVal
            Dim new_hm As MalHashMap = DirectCast(a(0),MalHashMap).copy()
            return new_hm.dissoc_BANG(DirectCast(a.slice(1),MalList))
        End Function

        Shared Function do_get(a As MalList) As MalVal
            Dim k As String = DirectCast(a(1),MalString).getValue()
            If a(0) Is Nil Then
                return Nil
            Else
                Dim dict As Dictionary(Of String,MalVal) = DirectCast(a(0),MalHashMap).getValue()
                If dict.ContainsKey(k) Then
                    return dict(k)
                Else
                    return Nil
                End If
            End If
        End Function

        Shared Function keys(a As MalList) As MalVal
            Dim dict As Dictionary(Of String,MalVal) = DirectCast(a(0),MalHashMap).getValue()
            Dim key_lst As MalList = New MalList()
            For Each key As String in dict.Keys
                key_lst.conj_BANG(new MalString(key))
            Next
            return key_lst
        End Function

        Shared Function vals(a As MalList) As MalVal
            Dim dict As Dictionary(Of String,MalVal) = DirectCast(a(0),MalHashMap).getValue()
            Dim val_lst As MalList = New MalList()
            For Each val As MalVal In dict.Values
                val_lst.conj_BANG(val)
            Next
            return val_lst
        End Function

        ' Sequence functions
        Shared Function sequential_Q(a As MalList) As MalVal
            If TypeOf a(0) Is MalList Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function cons(a As MalList) As MalVal
            Dim lst As New List(Of MalVal)
            lst.Add(a(0))
            lst.AddRange(DirectCast(a(1),MalList).getValue())
            return DirectCast(New MalList(lst),MalVal)
        End Function

        Shared Function concat(a As MalList) As MalVal
            If a.size() = 0 Then
                return new MalList()
            End If
            Dim lst As New List(Of MalVal)
            lst.AddRange(DirectCast(a(0),MalList).getValue())
            for i As Integer = 1 To a.size()-1
                lst.AddRange(DirectCast(a(i),MalList).getValue())
            Next
            return DirectCast(new MalList(lst),MalVal)
        End Function

        Shared Function nth(a As MalList) As MalVal
            Dim idx As Integer = DirectCast(a(1),MalInt).getValue()
            If (idx < DirectCast(a(0),MalList).size()) Then
                return DirectCast(a(0),MalList)( idx )
            Else
                throw new Mal.types.MalException(
                    "nth: index out of range")
            End If
        End Function

        Shared Function first(a As MalList) As MalVal
            return DirectCast(a(0),MalList)(0)
        End Function

        Shared Function rest(a As MalList) As MalVal
            return DirectCast(a(0),MalList).rest()
        End Function

        Shared Function empty_Q(a As MalList) As MalVal
            If DirectCast(a(0),MalList).size() = 0 Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function count(a As MalList) As MalVal
            If a(0) Is Nil Then
                return new MalInt(0)
            Else
                return new MalInt(DirectCast(a(0),MalList).size())
            End If
        End Function

        Shared Function conj(a As MalList) As MalVal
            Dim src_lst As List(Of MalVal) = DirectCast(a(0),MalList).getValue()
            Dim new_lst As New List(Of MalVal)
            new_lst.AddRange(src_lst)
            If TypeOf a(0) Is MalVector Then
                For i As Integer = 1 To a.size()-1
                    new_lst.Add(a(i))
                Next
                return new MalVector(new_lst)
            Else
                For i As Integer = 1 To a.size()-1
                    new_lst.Insert(0, a(i))
                Next
                return new MalList(new_lst)
            End If
        End Function


        ' General list related functions
        Shared Function apply(a As MalList) As MalVal
            Dim f As MalFunc = DirectCast(a(0),MalFunc)
            Dim lst As New List(Of MalVal)
            lst.AddRange(a.slice(1,a.size()-1).getValue())
            lst.AddRange(DirectCast(a(a.size()-1),MalList).getValue())
            return f.apply(New MalList(lst))
        End Function

        Shared Function map(a As MalList) As MalVal
            Dim f As MalFunc = DirectCast(a(0),MalFunc)
            Dim src_lst As List(Of MalVal) = DirectCast(a(1),MalList).getValue()
            Dim new_lst As New List(Of MalVal)
            for i As Integer = 0 To  src_lst.Count-1
                new_lst.Add(f.apply(New MalList(src_lst(i))))
            Next
            return new MalList(new_lst)
        End Function


        ' Metadata functions
        Shared Function atom(a As MalList) As MalVal
            return new MalAtom(a(0))
        End Function

        Shared Function meta(a As MalList) As MalVal
            return a(0).getMeta()
        End Function

        Shared Function with_meta(a As MalList) As MalVal
            return DirectCast(a(0),MalVal).copy().setMeta(a(1))
        End Function


        ' Atom functions
        Shared Function atom_Q(a As MalList) As MalVal
            If TypeOf a(0) Is MalAtom Then
                return MalTrue
            Else
                return MalFalse
            End If
        End Function

        Shared Function deref(a As MalList) As MalVal
            return DirectCast(a(0),MalAtom).getValue()
        End Function

        Shared Function reset_BANG(a As MalList) As MalVal
            return DirectCast(a(0),MalAtom).setValue(a(1))
        End Function

        Shared Function swap_BANG(a As MalList) As MalVal
            Dim atm As MalAtom = DirectCast(a(0),MalAtom)
            Dim f As MalFunc = DirectCast(a(1),MalFunc)
            Dim new_lst As New List(Of MalVal)
            new_lst.Add(atm.getValue())
            new_lst.AddRange(DirectCast(a.slice(2),MalList).getValue())
            return atm.setValue(f.apply(New MalList(new_lst)))
        End Function



        Shared Function ns As Dictionary(Of String, MalVal)
            Dim ns As New Dictionary(Of String, MalVal)

            ns.Add("=", New MalFunc(AddressOf equal_Q))
            ns.Add("throw", New MalFunc(AddressOf mal_throw))
            ns.Add("nil?", New MalFunc(AddressOf nil_Q))
            ns.Add("true?", New MalFunc(AddressOf true_Q))
            ns.Add("false?", New MalFunc(AddressOf false_Q))
            ns.Add("symbol", new MalFunc(AddressOf symbol))
            ns.Add("symbol?", New MalFunc(AddressOf symbol_Q))
            ns.Add("keyword", new MalFunc(AddressOf keyword))
            ns.Add("keyword?", New MalFunc(AddressOf keyword_Q))

            ns.Add("pr-str",New MalFunc(AddressOf pr_str))
            ns.Add("str", New MalFunc(AddressOf str))
            ns.Add("prn", New MalFunc(AddressOf prn))
            ns.Add("println", New MalFunc(AddressOf println))
            ns.Add("readline", New MalFunc(AddressOf mal_readline))
            ns.Add("read-string", New MalFunc(AddressOf read_string))
            ns.Add("slurp", New MalFunc(AddressOf slurp))
            ns.Add("<",  New MalFunc(AddressOf lt))
            ns.Add("<=", New MalFunc(AddressOf lte))
            ns.Add(">",  New MalFunc(AddressOf gt))
            ns.Add(">=", New MalFunc(AddressOf gte))
            ns.Add("+",  New MalFunc(AddressOf plus))
            ns.Add("-",  New MalFunc(AddressOf minus))
            ns.Add("*",  New MalFunc(AddressOf mult))
            ns.Add("/",  New MalFunc(AddressOf div))
            ns.Add("time-ms", New MalFunc(AddressOf time_ms))

            ns.Add("list",  New MalFunc(AddressOf list))
            ns.Add("list?", New MalFunc(AddressOf list_Q))
            ns.Add("vector", new MalFunc(AddressOf vector))
            ns.Add("vector?", New MalFunc(AddressOf vector_Q))
            ns.Add("hash-map", new MalFunc(AddressOf hash_map))
            ns.Add("map?", New MalFunc(AddressOf hash_map_Q))
            ns.Add("contains?", New MalFunc(AddressOf contains_Q))
            ns.Add("assoc", New MalFunc(AddressOf assoc))
            ns.Add("dissoc", New MalFunc(AddressOf dissoc))
            ns.Add("get", New MalFunc(AddressOf do_get))
            ns.Add("keys", New MalFunc(AddressOf keys))
            ns.Add("vals", New MalFunc(AddressOf vals))

            ns.Add("sequential?", New MalFunc(AddressOf sequential_Q))
            ns.Add("cons", New MalFunc(AddressOf cons))
            ns.Add("concat", New MalFunc(AddressOf concat))
            ns.Add("nth", New MalFunc(AddressOf nth))
            ns.Add("first", New MalFunc(AddressOf first))
            ns.Add("rest",  New MalFunc(AddressOf rest))
            ns.Add("empty?", New MalFunc(AddressOf empty_Q))
            ns.Add("count",New MalFunc(AddressOf  count))
            ns.Add("conj", New MalFunc(AddressOf conj))
            ns.Add("apply", New MalFunc(AddressOf apply))
            ns.Add("map", New MalFunc(AddressOf map))

            ns.Add("with-meta", New MalFunc(AddressOf with_meta))
            ns.Add("meta", New MalFunc(AddressOf meta))
            ns.Add("atom", new MalFunc(AddressOf atom))
            ns.Add("atom?", New MalFunc(AddressOf atom_Q))
            ns.Add("deref", New MalFunc(AddressOf deref))
            ns.Add("reset!", New MalFunc(AddressOf reset_BANG))
            ns.Add("swap!", New MalFunc(AddressOf swap_BANG))
            return ns
        End Function
    End Class
End Namespace