If TypeOf ast Is MalList Then
Dim a0 As MalVal = DirectCast(ast,MalList)(0)
If TypeOf a0 Is MalSymbol AndAlso _
- env.find(DirectCast(a0,MalSymbol).getName()) IsNot Nothing Then
- Dim mac As MalVal = env.do_get(DirectCast(a0,MalSymbol).getName())
+ env.find(DirectCast(a0,MalSymbol)) IsNot Nothing Then
+ Dim mac As MalVal = env.do_get(DirectCast(a0,MalSymbol))
If TypeOf mac Is MalFunc AndAlso _
DirectCast(mac,MalFunc).isMacro() Then
return True
Shared Function macroexpand(ast As MalVal, env As MalEnv) As MalVal
While is_macro_call(ast, env)
Dim a0 As MalSymbol = DirectCast(DirectCast(ast,MalList)(0),MalSymbol)
- Dim mac As MalFunc = DirectCast(env.do_get(a0.getName()),MalFunc)
+ Dim mac As MalFunc = DirectCast(env.do_get(a0),MalFunc)
ast = mac.apply(DirectCast(ast,MalList).rest())
End While
return ast
Shared Function eval_ast(ast As MalVal, env As MalEnv) As MalVal
If TypeOf ast Is MalSymbol Then
- Dim sym As MalSymbol = DirectCast(ast, MalSymbol)
- return env.do_get(sym.getName())
+ return env.do_get(DirectCast(ast, MalSymbol))
Else If TypeOf ast Is MalList Then
Dim old_lst As MalList = DirectCast(ast, MalList)
Dim new_lst As MalList
' apply list
Dim expanded As MalVal = macroexpand(orig_ast, env)
if not expanded.list_Q() Then
- return expanded
+ return eval_ast(expanded, env)
End If
Dim ast As MalList = DirectCast(expanded, MalList)
Dim a1 As MalVal = ast(1)
Dim a2 As MalVal = ast(2)
Dim res As MalVal = EVAL(a2, env)
- env.do_set(DirectCast(a1,MalSymbol).getName(), res)
+ env.do_set(DirectCast(a1,MalSymbol), res)
return res
Case "let*"
Dim a1 As MalVal = ast(1)
For i As Integer = 0 To (DirectCast(a1,MalList)).size()-1 Step 2
key = DirectCast(DirectCast(a1,MalList)(i),MalSymbol)
val = DirectCast(a1,MalList)(i+1)
- let_env.do_set(key.getName(), EVAL(val, let_env))
+ let_env.do_set(key, EVAL(val, let_env))
Next
orig_ast = a2
env = let_env
Dim a2 As MalVal = ast(2)
Dim res As MalVal = EVAL(a2, env)
DirectCast(res,MalFunc).setMacro()
- env.do_set(DirectCast(a1,MalSymbol).getName(), res)
+ env.do_set(DirectCast(a1,MalSymbol), res)
return res
Case "macroexpand"
Dim a1 As MalVal = ast(1)
DirectCast(a2,MalList).slice(1,2),
New MalList(exc)))
End If
- Throw e
End If
+ Throw e
End Try
Case "do"
eval_ast(ast.slice(1, ast.size()-1), env)
' core.vb: defined using VB.NET
For Each entry As KeyValuePair(Of String,MalVal) In core.ns()
- repl_env.do_set(entry.Key, entry.Value)
+ repl_env.do_set(new MalSymbol(entry.Key), entry.Value)
Next
- repl_env.do_set("eval", new MalFunc(AddressOf do_eval))
+ repl_env.do_set(new MalSymbol("eval"), new MalFunc(AddressOf do_eval))
+ Dim fileIdx As Integer = 1
+ If args.Length > 1 AndAlso args(1) = "--raw" Then
+ Mal.readline.SetMode(Mal.readline.Modes.Raw)
+ fileIdx = 2
+ End If
Dim argv As New MalList()
- For i As Integer = 0 To args.Length()-1
+ For i As Integer = fileIdx+1 To args.Length-1
argv.conj_BANG(new MalString(args(i)))
Next
- repl_env.do_set("*ARGV*", argv)
+ repl_env.do_set(new MalSymbol("*ARGV*"), argv)
' core.mal: defined using the language itself
- REP("(def! *host-language* ""VB.NET"")")
REP("(def! not (fn* (a) (if a false true)))")
REP("(def! load-file (fn* (f) (eval (read-string (str ""(do "" (slurp f) "")"")))))")
REP("(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw ""odd number of forms to cond"")) (cons 'cond (rest (rest xs)))))))")
REP("(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))")
- Dim fileIdx As Integer = 1
- If args.Length > 1 AndAlso args(1) = "--raw" Then
- Mal.readline.SetMode(Mal.readline.Modes.Raw)
- fileIdx = 2
- End If
If args.Length > fileIdx Then
REP("(load-file """ & args(fileIdx) & """)")
return 0
' repl loop
Dim line As String
- REP("(println (str ""Mal ["" *host-language* ""]""))")
Do
Try
line = Mal.readline.Readline("user> ")