Merge pull request #380 from bjh21/bjh21-bbc-basic
[jackhill/mal.git] / vb / types.vb
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 '
9 ' Exceptions/Errors
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
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
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
248 If value.Length > 0 AndAlso value(0) = ChrW(&H029e) Then
249 return ":" & value.Substring(1)
250 Else If print_readably Then
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