Commit | Line | Data |
---|---|---|
ee7cd585 JM |
1 | Imports System |
2 | Imports System.Collections.Generic | |
3 | Imports System.Text.RegularExpressions | |
4 | Imports Mal | |
5 | ||
6 | namespace Mal | |
7 | Public Class types | |
8 | ' | |
10f0bf41 | 9 | ' Exceptions/Errors |
ee7cd585 JM |
10 | ' |
11 | Public Class MalThrowable | |
12 | Inherits Exception | |
13 | Public Sub New() | |
14 | MyBase.New() | |
15 | End Sub | |
16 | Public Sub New(msg As String) | |
17 | MyBase.New(msg) | |
18 | End Sub | |
19 | End Class | |
20 | Public Class MalError | |
21 | Inherits MalThrowable | |
22 | Public Sub New(msg As String) | |
23 | MyBase.New(msg) | |
24 | End Sub | |
25 | End Class | |
26 | Public Class MalContinue | |
27 | Inherits MalThrowable | |
28 | End Class | |
29 | ||
30 | ' Thrown by throw function | |
31 | Public Class MalException | |
32 | Inherits MalThrowable | |
33 | Private value As MalVal | |
34 | ||
35 | 'string Message | |
36 | Public Sub New(new_value As MalVal) | |
37 | value = new_value | |
38 | End Sub | |
39 | Public Sub New(new_value As String) | |
40 | MyBase.New(new_value) | |
41 | value = New MalString(new_value) | |
42 | End Sub | |
43 | Public Function getValue() As MalVal | |
44 | return value | |
45 | End Function | |
46 | End Class | |
47 | ||
48 | ' | |
49 | ' General functions | |
50 | ' | |
51 | Public Shared Function _equal_Q(a As MalVal, b As MalVal) As Boolean | |
52 | Dim ota As Type = a.GetType() | |
53 | Dim otb As Type = b.GetType() | |
54 | If not (ota = otb Or | |
55 | (TypeOf a Is MalList and TypeOf b Is MalList)) Then | |
56 | return False | |
57 | Else | |
58 | If TypeOf a Is MalInt Then | |
59 | return DirectCast(a,MalInt).getValue() = | |
60 | DirectCast(b,MalInt).getValue() | |
61 | Else If TypeOf a Is MalSymbol Then | |
62 | return DirectCast(a,MalSymbol).getName() = | |
63 | DirectCast(b,MalSymbol).getName() | |
64 | Else If TypeOf a Is MalString Then | |
65 | return DirectCast(a,MalString).getValue() = | |
66 | DirectCast(b,MalString).getValue() | |
67 | Else If TypeOf a Is MalList Then | |
68 | If DirectCast(a,MalList).size() <> | |
69 | DirectCast(b,MalList).size() | |
70 | return False | |
71 | End If | |
72 | for i As Integer = 0 To DirectCast(a,MalList).size()-1 | |
73 | If not _equal_Q(DirectCast(a,MalList)(i), | |
74 | DirectCast(b,MalList)(i)) | |
75 | return False | |
76 | End If | |
77 | Next | |
78 | return True | |
1f8c4c84 JM |
79 | Else If TypeOf a Is MalHashMap Then |
80 | Dim ahm As Dictionary(Of String,MalVal) = DirectCast(a,MalHashMap).getValue() | |
81 | Dim bhm As Dictionary(Of String,MalVal) = DirectCast(b,MalHashMap).getValue() | |
82 | For Each key As String in ahm.keys | |
83 | If not bhm.ContainsKey(key) Then | |
84 | return False | |
85 | End If | |
86 | If not _equal_Q(DirectCast(a,MalHashMap).getValue()(key), | |
87 | DirectCast(b,MalHashMap).getValue()(key)) | |
88 | return False | |
89 | End If | |
90 | Next | |
91 | return True | |
ee7cd585 JM |
92 | Else |
93 | return a Is b | |
94 | End If | |
95 | End If | |
96 | End Function | |
97 | ||
98 | ||
99 | Public MustInherit Class MalVal | |
100 | Private meta As MalVal = Nil | |
101 | Public Overridable Function copy() As MalVal | |
102 | return DirectCast(Me.MemberwiseClone(),MalVal) | |
103 | End Function | |
104 | ||
105 | ' Default is just to call regular toString() | |
106 | Public Overridable Function ToString() As String | |
107 | throw New MalException("ToString called on abstract MalVal") | |
108 | End Function | |
109 | Public Overridable Function ToString(print_readably As Boolean) As String | |
110 | return Me.ToString() | |
111 | End Function | |
112 | Public Function getMeta() As MalVal | |
113 | return meta | |
114 | End Function | |
115 | Public Function setMeta(m As MalVal) As MalVal | |
116 | meta = m | |
117 | return Me | |
118 | End Function | |
119 | Public Overridable Function list_Q() As Boolean | |
120 | return False | |
121 | End Function | |
122 | End Class | |
123 | ||
124 | Public Class MalConstant | |
125 | Inherits MalVal | |
126 | Private value As String | |
127 | Public Sub New(name As String) | |
128 | value = name | |
129 | End Sub | |
130 | Public Shadows Function copy() As MalConstant | |
131 | return Me | |
132 | End Function | |
133 | ||
134 | Public Overrides Function ToString() As String | |
135 | return value | |
136 | End Function | |
137 | Public Overrides Function ToString(print_readably As Boolean) As String | |
138 | return value | |
139 | End Function | |
140 | End Class | |
141 | ||
142 | Public Shared Nil As MalConstant = New MalConstant("nil") | |
143 | Public Shared MalTrue As MalConstant = New MalConstant("true") | |
144 | Public Shared MalFalse As MalConstant = New MalConstant("false") | |
145 | ||
146 | Public Class MalInt | |
147 | Inherits MalVal | |
148 | Private value As Int64 | |
149 | Public Sub New(v As Int64) | |
150 | value = v | |
151 | End Sub | |
152 | Public Shadows Function copy() As MalInt | |
153 | return Me | |
154 | End Function | |
155 | ||
156 | Public Function getValue() As Int64 | |
157 | return value | |
158 | End Function | |
159 | Public Overrides Function ToString() As String | |
160 | return value.ToString() | |
161 | End Function | |
162 | Public Overrides Function ToString(print_readably As Boolean) As String | |
163 | return value.ToString() | |
164 | End Function | |
165 | Public Shared Operator <(a As MalInt, b As Malint) As MalConstant | |
166 | If a.getValue() < b.getValue() Then | |
167 | return MalTrue | |
168 | Else | |
169 | return MalFalse | |
170 | End If | |
171 | End Operator | |
172 | Public Shared Operator <=(a As MalInt, b As Malint) As MalConstant | |
173 | If a.getValue() <= b.getValue() Then | |
174 | return MalTrue | |
175 | Else | |
176 | return MalFalse | |
177 | End If | |
178 | End Operator | |
179 | Public Shared Operator >(a As MalInt, b As Malint) As MalConstant | |
180 | If a.getValue() > b.getValue() Then | |
181 | return MalTrue | |
182 | Else | |
183 | return MalFalse | |
184 | End If | |
185 | End Operator | |
186 | Public Shared Operator >=(a As MalInt, b As Malint) As MalConstant | |
187 | If a.getValue() >= b.getValue() Then | |
188 | return MalTrue | |
189 | Else | |
190 | return MalFalse | |
191 | End If | |
192 | End Operator | |
193 | Public Shared Operator +(a As MalInt, b As Malint) As MalInt | |
194 | return new MalInt(a.getValue() + b.getValue()) | |
195 | End Operator | |
196 | Public Shared Operator -(a As MalInt, b As Malint) As MalInt | |
197 | return new MalInt(a.getValue() - b.getValue()) | |
198 | End Operator | |
199 | Public Shared Operator *(a As MalInt, b As Malint) As MalInt | |
200 | return new MalInt(a.getValue() * b.getValue()) | |
201 | End Operator | |
202 | Public Shared Operator /(a As MalInt, b As Malint) As MalInt | |
203 | return new MalInt(a.getValue() / b.getValue()) | |
204 | End Operator | |
205 | End Class | |
206 | ||
207 | Public Class MalSymbol | |
208 | Inherits MalVal | |
209 | Private value As String | |
210 | Public Sub New(v As String) | |
211 | value = v | |
212 | End Sub | |
213 | Public Sub New(v As MalString) | |
214 | value = v.getValue() | |
215 | End Sub | |
216 | Public Shadows Function copy() As MalSymbol | |
217 | return Me | |
218 | End Function | |
219 | ||
220 | Public Function getName() As String | |
221 | return value | |
222 | End Function | |
223 | Public Overrides Function ToString() As String | |
224 | return value | |
225 | End Function | |
226 | Public Overrides Function ToString(print_readably As Boolean) As String | |
227 | return value | |
228 | End Function | |
229 | End Class | |
230 | ||
231 | Public Class MalString | |
232 | Inherits MalVal | |
233 | Private value As String | |
234 | Public Sub New(v As String) | |
235 | value = v | |
236 | End Sub | |
237 | Public Shadows Function copy() As MalString | |
238 | return Me | |
239 | End Function | |
240 | ||
241 | Public Function getValue() As String | |
242 | return value | |
243 | End Function | |
244 | Public Overrides Function ToString() As String | |
245 | return """" & value & """" | |
246 | End Function | |
247 | Public Overrides Function ToString(print_readably As Boolean) As String | |
b8ee29b2 JM |
248 | If value.Length > 0 AndAlso value(0) = ChrW(&H029e) Then |
249 | return ":" & value.Substring(1) | |
250 | Else If print_readably Then | |
ee7cd585 JM |
251 | return """" & _ |
252 | value.Replace("\", "\\") _ | |
253 | .Replace("""", "\""") _ | |
254 | .Replace(Environment.NewLine, "\n") & _ | |
255 | """" | |
256 | Else | |
257 | return value | |
258 | End If | |
259 | End Function | |
260 | End Class | |
261 | ||
262 | ||
263 | Public Class MalList | |
264 | Inherits MalVal | |
265 | Public start As String = "(" | |
266 | Public last As String = ")" | |
267 | Private value As List(Of MalVal) | |
268 | Public Sub New() | |
269 | value = New List(Of MalVal) | |
270 | End Sub | |
271 | Public Sub New(val As List(Of MalVal)) | |
272 | value = val | |
273 | End Sub | |
274 | Public Sub New(ParamArray mvs() As MalVal) | |
275 | value = New List(Of MalVal) | |
276 | conj_BANG(mvs) | |
277 | End Sub | |
278 | ||
279 | Public Function getValue() As List(Of MalVal) | |
280 | return value | |
281 | End Function | |
282 | Public Overrides Function list_Q() As Boolean | |
283 | return True | |
284 | End Function | |
285 | ||
286 | Public Overrides Function ToString() As String | |
287 | return start & printer.join(value, " ", true) & last | |
288 | End Function | |
289 | Public Overrides Function ToString(print_readably As Boolean) As String | |
290 | return start & printer.join(value, " ", print_readably) & last | |
291 | End Function | |
292 | ||
293 | Public Function conj_BANG(ParamArray mvs() As MalVal) As MalList | |
294 | For i As Integer = 0 To mvs.Length-1 | |
295 | value.Add(mvs(i)) | |
296 | Next | |
297 | return Me | |
298 | End Function | |
299 | ||
300 | Public Function size() As Int64 | |
301 | return value.Count | |
302 | End Function | |
303 | Public Function nth(ByVal idx As Integer) As MalVal | |
304 | If value.Count > idx Then | |
305 | return value(idx) | |
306 | Else | |
307 | return Nil | |
308 | End If | |
309 | End Function | |
310 | Default Public ReadOnly Property Item(idx As Integer) As MalVal | |
311 | Get | |
312 | If value.Count > idx then | |
313 | return value(idx) | |
314 | Else | |
315 | return Nil | |
316 | End If | |
317 | End Get | |
318 | End Property | |
319 | Public Function rest() As MalList | |
320 | If size() > 0 Then | |
321 | return New MalList(value.GetRange(1, value.Count-1)) | |
322 | Else | |
323 | return New MalList() | |
324 | End If | |
325 | End Function | |
326 | Public Overridable Function slice(start As Int64) As MalList | |
327 | return New MalList(value.GetRange(start, value.Count-start)) | |
328 | End Function | |
329 | Public Overridable Function slice(start As Int64, last As Int64) As MalList | |
330 | return New MalList(value.GetRange(start, last-start)) | |
331 | End Function | |
332 | End Class | |
333 | ||
334 | Public Class MalVector | |
335 | Inherits MalList | |
336 | ' ' Same implementation except for instantiation methods | |
337 | Public Sub New() | |
338 | MyBase.New() | |
339 | start = "[" | |
340 | last = "]" | |
341 | End Sub | |
342 | Public Sub New(val As List(Of MalVal)) | |
343 | MyBase.New(val) | |
344 | start = "[" | |
345 | last = "]" | |
346 | End Sub | |
347 | ||
348 | Public Overrides Function list_Q() As Boolean | |
349 | return False | |
350 | End Function | |
351 | ||
352 | Public Overrides Function slice(start As Int64, last As Int64) As MalList | |
353 | Dim val As List(Of MalVal) = Me.getValue() | |
354 | return New MalVector(val.GetRange(start, val.Count-start)) | |
355 | End Function | |
356 | End Class | |
357 | ||
358 | Public Class MalHashMap | |
359 | Inherits MalVal | |
360 | Private value As Dictionary(Of string, MalVal) | |
361 | Public Sub New(val As Dictionary(Of String, MalVal)) | |
362 | value = val | |
363 | End Sub | |
364 | Public Sub New(lst As MalList) | |
365 | value = New Dictionary(Of String, MalVal) | |
366 | assoc_BANG(lst) | |
367 | End Sub | |
368 | Public Shadows Function copy() As MalHashMap | |
369 | Dim new_self As MalHashMap = DirectCast(Me.MemberwiseClone(),MalHashMap) | |
370 | new_self.value = New Dictionary(Of String, MalVal)(value) | |
371 | return new_self | |
372 | End Function | |
373 | ||
374 | Public Function getValue() As Dictionary(Of String, MalVal) | |
375 | return value | |
376 | End Function | |
377 | ||
378 | Public Overrides Function ToString() As String | |
379 | return "{" & printer.join(value, " ", true) & "}" | |
380 | End Function | |
381 | Public Overrides Function ToString(print_readably As Boolean) As String | |
382 | return "{" & printer.join(value, " ", print_readably) & "}" | |
383 | End Function | |
384 | ||
385 | Public Function assoc_BANG(lst As MalList) As MalHashMap | |
386 | For i As Integer = 0 To lst.size()-1 Step 2 | |
387 | value(DirectCast(lst(i),MalString).getValue()) = lst(i+1) | |
388 | Next | |
389 | return Me | |
390 | End Function | |
391 | ||
392 | Public Function dissoc_BANG(lst As MalList) As MalHashMap | |
393 | for i As Integer = 0 To lst.size()-1 | |
394 | value.Remove(DirectCast(lst.nth(i),MalString).getValue()) | |
395 | Next | |
396 | return Me | |
397 | End Function | |
398 | End Class | |
399 | ||
400 | Public Class MalAtom | |
401 | Inherits MalVal | |
402 | Private value As MalVal | |
403 | Public Sub New(val As MalVal) | |
404 | value = val | |
405 | End Sub | |
406 | 'Public MalAtom copy() { return New MalAtom(value) } | |
407 | Public Function getValue() As MalVal | |
408 | return value | |
409 | End Function | |
410 | Public Function setValue(val As MalVal) As MalVal | |
411 | value = val | |
412 | return value | |
413 | End Function | |
414 | Public Overrides Function ToString() As String | |
415 | return "(atom " & printer._pr_str(value, true) & ")" | |
416 | End Function | |
417 | Public Overrides Function ToString(print_readably As Boolean) As String | |
418 | return "(atom " & printer._pr_str(value, print_readably) & ")" | |
419 | End Function | |
420 | End Class | |
421 | ||
422 | Public Class MalFunc | |
423 | Inherits MalVal | |
424 | Private fn As Func(Of MalList, MalVal) = Nothing | |
425 | Private ast As MalVal = Nothing | |
426 | Private env As Mal.env.Env = Nothing | |
427 | Private fparams As MalList | |
428 | Private macro As Boolean = False | |
429 | Public Sub New(new_fn As Func(Of MalList, MalVal)) | |
430 | fn = new_fn | |
431 | End Sub | |
432 | Public Sub New(new_ast As MalVal, new_env As Mal.env.Env, | |
433 | new_fparams As MalList, new_fn As Func(Of MalList, MalVal)) | |
434 | fn = new_fn | |
435 | ast = new_ast | |
436 | env = new_env | |
437 | fparams = new_fparams | |
438 | End Sub | |
439 | ||
440 | Public Overrides Function ToString() As String | |
441 | If Not ast Is Nothing Then | |
442 | return "<fn* " & Mal.printer._pr_str(fparams,true) & | |
443 | " " & Mal.printer._pr_str(ast, true) & ">" | |
444 | Else | |
445 | return "<builtin_function " & fn.ToString() & ">" | |
446 | End If | |
447 | End Function | |
448 | ||
449 | Public Function apply(args As MalList) As MalVal | |
450 | return fn(args) | |
451 | End Function | |
452 | ||
453 | Public Function getAst() As MalVal | |
454 | return ast | |
455 | End Function | |
456 | Public Function getEnv() As Mal.env.Env | |
457 | return env | |
458 | End Function | |
459 | Public Function getFParams() As MalList | |
460 | return fparams | |
461 | End Function | |
462 | Public Function genEnv(args As MalList) As Mal.env.Env | |
463 | return New Mal.env.Env(env, fparams, args) | |
464 | End Function | |
465 | Public Function isMacro() As Boolean | |
466 | return macro | |
467 | End Function | |
468 | Public Sub setMacro() | |
469 | macro = true | |
470 | End Sub | |
471 | End Class | |
472 | End Class | |
473 | End Namespace |