3 Imports System
.Collections
.Generic
5 Imports MalVal
= Mal
.types
.MalVal
6 Imports MalInt
= Mal
.types
.MalInt
7 Imports MalSymbol
= Mal
.types
.MalSymbol
8 Imports MalList
= Mal
.types
.MalList
9 Imports MalVector
= Mal
.types
.MalVector
10 Imports MalHashMap
= Mal
.types
.MalHashMap
11 Imports MalFunc
= Mal
.types
.MalFunc
12 Imports MalEnv
= Mal
.env
.Env
17 Shared
Function READ(str
As String) As MalVal
18 Return reader
.read_str(str
)
22 Shared
Function eval_ast(ast
As MalVal
, env
As MalEnv
) As MalVal
23 If TypeOf ast Is MalSymbol
Then
24 return env
.do_get(DirectCast(ast
, MalSymbol
))
25 Else If TypeOf ast Is MalList
Then
26 Dim old_lst
As MalList
= DirectCast(ast
, MalList
)
27 Dim new_lst
As MalList
31 new_lst
= DirectCast(New MalVector
, MalList
)
34 For Each mv
in old_lst
.getValue()
35 new_lst
.conj_BANG(EVAL(mv
, env
))
38 Else If TypeOf ast Is MalHashMap
Then
39 Dim new_dict
As New Dictionary(Of
String, MalVal
)
40 Dim entry
As KeyValuePair(Of
String, MalVal
)
41 For Each entry
in DirectCast(ast
,MalHashMap
).getValue()
42 new_dict
.Add(entry
.Key
, EVAL(DirectCast(entry
.Value
,MalVal
), env
))
44 return New MalHashMap(new_dict
)
51 ' TODO: move to types.vb when it is ported
54 Public params
As MalList
56 Function fn(args
as MalList
) As MalVal
57 return EVAL(ast
, new MalEnv(env
, params
, args
))
61 Shared
Function EVAL(orig_ast
As MalVal
, env
As MalEnv
) As MalVal
64 'Console.WriteLine("EVAL: {0}", printer._pr_str(orig_ast, true))
65 If not orig_ast
.list_Q() Then
66 return eval_ast(orig_ast
, env
)
70 Dim ast
As MalList
= DirectCast(orig_ast
, MalList
)
71 If ast
.size() = 0 Then
74 Dim a0
As MalVal
= ast(0)
76 If TypeOf a0 is MalSymbol
Then
77 a0sym
= DirectCast(a0
,MalSymbol
).getName()
84 Dim a1
As MalVal
= ast(1)
85 Dim a2
As MalVal
= ast(2)
86 Dim res
As MalVal
= EVAL(a2
, env
)
87 env
.do_set(DirectCast(a1
,MalSymbol
), res
)
90 Dim a1
As MalVal
= ast(1)
91 Dim a2
As MalVal
= ast(2)
94 Dim let_env
As new MalEnv(env
)
95 For i
As Integer = 0 To (DirectCast(a1
,MalList
)).size()-1 Step
2
96 key
= DirectCast(DirectCast(a1
,MalList
)(i
),MalSymbol
)
97 val
= DirectCast(a1
,MalList
)(i
+1)
98 let_env
.do_set(key
, EVAL(val
, let_env
))
103 eval_ast(ast
.slice(1, ast
.size()-1), env
)
104 orig_ast
= ast(ast
.size()-1)
106 Dim a1
As MalVal
= ast(1)
107 Dim cond
As MalVal
= EVAL(a1
, env
)
108 If cond Is Mal
.types
.Nil
or cond Is Mal
.types
.MalFalse
Then
109 ' eval false slot form
110 If ast
.size() > 3 Then
116 ' eval true slot form
121 Dim fc
As New FClosure()
123 fc
.params
= DirectCast(ast(1),MalLIst
)
125 Dim f
As Func(Of MalList
, MalVal
) = AddressOf fc
.fn
126 Dim mf
As new MalFunc(ast(2), env
,
127 DirectCast(ast(1),MalList
), f
)
128 return DirectCast(mf
,MalVal
)
130 Dim el
As MalList
= DirectCast(eval_ast(ast
, env
), MalList
)
131 Dim f
As MalFunc
= DirectCast(el(0), MalFunc
)
132 Dim fnast
As MalVal
= f
.getAst()
133 If not fnast Is
Nothing
135 env
= f
.genEnv(el
.rest())
137 Return f
.apply(el
.rest())
145 Shared
Function PRINT(exp
As MalVal
) As String
146 return printer
._pr_str(exp
, TRUE)
150 Shared repl_env
As MalEnv
152 Shared
Function REP(str
As String) As String
153 Return PRINT(EVAL(READ(str
), repl_env
))
156 Shared
Function Main
As Integer
157 Dim args
As String() = Environment
.GetCommandLineArgs()
159 repl_env
= New MalEnv(Nothing)
161 ' core.vb: defined using VB.NET
162 For Each entry
As KeyValuePair(Of
String,MalVal
) In core
.ns()
163 repl_env
.do_set(new MalSymbol(entry
.Key
), entry
.Value
)
166 ' core.mal: defined using the language itself
167 REP("(def! not (fn* (a) (if a false true)))")
169 If args
.Length
> 1 AndAlso
args(1) = "--raw" Then
170 Mal
.readline
.SetMode(Mal
.readline
.Modes
.Raw
)
177 line
= Mal
.readline
.Readline("user> ")
178 If line is
Nothing Then
184 Catch e
As IOException
185 Console
.WriteLine("IOException: " & e
.Message
)
188 Console
.WriteLine(REP(line
))
190 Console
.WriteLine("Error: " & e
.Message
)
191 Console
.WriteLine(e
.StackTrace
)