| 1 | Imports System |
| 2 | Imports System.IO |
| 3 | Imports System.Collections.Generic |
| 4 | Imports Mal |
| 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 | |
| 13 | Namespace Mal |
| 14 | Class step2_eval |
| 15 | ' read |
| 16 | Shared Function READ(str As String) As MalVal |
| 17 | Return reader.read_str(str) |
| 18 | End Function |
| 19 | |
| 20 | ' eval |
| 21 | Shared Function eval_ast(ast As MalVal, env As Dictionary(Of String, MalVal)) As MalVal |
| 22 | If TypeOf ast Is MalSymbol Then |
| 23 | Dim sym As MalSymbol = DirectCast(ast, MalSymbol) |
| 24 | return env.Item(sym.getName()) |
| 25 | Else If TypeOf ast Is MalList Then |
| 26 | Dim old_lst As MalList = DirectCast(ast, MalList) |
| 27 | Dim new_lst As MalList |
| 28 | If ast.list_Q() Then |
| 29 | new_lst = New MalList |
| 30 | Else |
| 31 | new_lst = DirectCast(New MalVector, MalList) |
| 32 | End If |
| 33 | Dim mv As MalVal |
| 34 | For Each mv in old_lst.getValue() |
| 35 | new_lst.conj_BANG(EVAL(mv, env)) |
| 36 | Next |
| 37 | return new_lst |
| 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)) |
| 43 | Next |
| 44 | return New MalHashMap(new_dict) |
| 45 | Else |
| 46 | return ast |
| 47 | End If |
| 48 | return ast |
| 49 | End Function |
| 50 | |
| 51 | Shared Function EVAL(orig_ast As MalVal, env As Dictionary(Of String, MalVal)) As MalVal |
| 52 | 'Console.WriteLine("EVAL: {0}", printer._pr_str(orig_ast, true)) |
| 53 | If not orig_ast.list_Q() Then |
| 54 | return eval_ast(orig_ast, env) |
| 55 | End If |
| 56 | |
| 57 | ' apply list |
| 58 | Dim ast As MalList = DirectCast(orig_ast, MalList) |
| 59 | If ast.size() = 0 Then |
| 60 | return ast |
| 61 | End If |
| 62 | Dim a0 As MalVal = ast(0) |
| 63 | Dim el As MalList = DirectCast(eval_ast(ast, env), MalList) |
| 64 | Dim f As MalFunc = DirectCast(el(0), MalFunc) |
| 65 | Return f.apply(el.rest()) |
| 66 | End Function |
| 67 | |
| 68 | ' print |
| 69 | Shared Function PRINT(exp As MalVal) As String |
| 70 | return printer._pr_str(exp, TRUE) |
| 71 | End Function |
| 72 | |
| 73 | ' repl |
| 74 | Shared repl_env As Dictionary(Of String, MalVal) |
| 75 | |
| 76 | Shared Function REP(str As String) As String |
| 77 | Return PRINT(EVAL(READ(str), repl_env)) |
| 78 | End Function |
| 79 | |
| 80 | Shared Function add(a As MalList) As MalVal |
| 81 | Return DirectCast(a.Item(0),MalInt) + DirectCast(a.Item(1),MalInt) |
| 82 | End Function |
| 83 | |
| 84 | Shared Function minus(a As MalList) As MalVal |
| 85 | Return DirectCast(a.Item(0),MalInt) - DirectCast(a.Item(1),MalInt) |
| 86 | End Function |
| 87 | |
| 88 | Shared Function mult(a As MalList) As MalVal |
| 89 | Return DirectCast(a.Item(0),MalInt) * DirectCast(a.Item(1),MalInt) |
| 90 | End Function |
| 91 | |
| 92 | Shared Function div(a As MalList) As MalVal |
| 93 | Return DirectCast(a.Item(0),MalInt) / DirectCast(a.Item(1),MalInt) |
| 94 | End Function |
| 95 | |
| 96 | Shared Function Main As Integer |
| 97 | Dim args As String() = Environment.GetCommandLineArgs() |
| 98 | |
| 99 | repl_env = New Dictionary(Of String, MalVal) |
| 100 | repl_env.Add("+", New MalFunc(AddressOf add)) |
| 101 | repl_env.Add("-", New MalFunc(AddressOf minus)) |
| 102 | repl_env.Add("*", New MalFunc(AddressOf mult)) |
| 103 | repl_env.Add("/", New MalFunc(AddressOf div)) |
| 104 | |
| 105 | |
| 106 | If args.Length > 1 AndAlso args(1) = "--raw" Then |
| 107 | Mal.readline.SetMode(Mal.readline.Modes.Raw) |
| 108 | End If |
| 109 | |
| 110 | ' repl loop |
| 111 | Dim line As String |
| 112 | Do |
| 113 | Try |
| 114 | line = Mal.readline.Readline("user> ") |
| 115 | If line is Nothing Then |
| 116 | Exit Do |
| 117 | End If |
| 118 | If line = "" Then |
| 119 | Continue Do |
| 120 | End If |
| 121 | Catch e As IOException |
| 122 | Console.WriteLine("IOException: " & e.Message) |
| 123 | End Try |
| 124 | Try |
| 125 | Console.WriteLine(REP(line)) |
| 126 | Catch e as Exception |
| 127 | Console.WriteLine("Error: " & e.Message) |
| 128 | Console.WriteLine(e.StackTrace) |
| 129 | Continue Do |
| 130 | End Try |
| 131 | Loop While True |
| 132 | End function |
| 133 | End Class |
| 134 | End Namespace |