Commit | Line | Data |
---|---|---|
18a94a9f CM |
1 | with Ada.Command_Line; |
2 | with Ada.Exceptions; | |
3 | with Ada.Text_IO; | |
4 | with Ada.IO_Exceptions; | |
5 | with Core; | |
6 | with Envs; | |
7 | with Evaluation; | |
8 | with Printer; | |
9 | with Reader; | |
10 | with Types; | |
11 | ||
12 | procedure Step9_Try is | |
13 | ||
14 | function Read (Param : String) return Types.Mal_Handle is | |
15 | begin | |
16 | return Reader.Read_Str (Param); | |
17 | end Read; | |
18 | ||
19 | ||
20 | -- Eval can't be here because there are function pointers that point | |
21 | -- at it. Thus it must be at library level. See evaluation.ads | |
22 | ||
23 | ||
24 | function Print (Param : Types.Mal_Handle) return String is | |
25 | begin | |
26 | return Printer.Pr_Str (Param); | |
27 | end Print; | |
28 | ||
29 | function Rep (Param : String) return String is | |
30 | AST, Evaluated_AST : Types.Mal_Handle; | |
31 | begin | |
32 | ||
33 | AST := Read (Param); | |
34 | ||
35 | if Types.Is_Null (AST) then | |
36 | return ""; | |
37 | else | |
38 | Evaluated_AST := Evaluation.Eval (AST, Envs.Get_Current); | |
39 | return Print (Evaluated_AST); | |
40 | end if; | |
41 | ||
42 | end Rep; | |
43 | ||
44 | S : String (1..Reader.Max_Line_Len); | |
45 | Last : Natural; | |
46 | Cmd_Args : Natural; | |
47 | Command_Args : Types.Mal_Handle; | |
48 | Command_List : Types.List_Ptr; | |
49 | File_Processed : Boolean := False; | |
50 | ||
51 | begin | |
52 | ||
53 | -- Core init also creates the first environment. | |
54 | -- This is needed for the def!'s below. | |
55 | Core.Init; | |
56 | ||
57 | declare | |
58 | Not_S : String := | |
59 | Rep ("(def! not (fn* (a) (if a false true)))"); | |
60 | LF_S : String := | |
61 | Rep ("(def! load-file (fn* (f) (eval (read-string (str ""(do "" (slurp f) "")"")))))"); | |
62 | Cond_S : String := | |
63 | 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)))))))"); | |
64 | Or_S : String := | |
65 | 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))))))))"); | |
66 | pragma Unreferenced (Not_S, LF_S, Cond_S, Or_S); | |
67 | begin | |
68 | null; | |
69 | end; | |
70 | ||
71 | Cmd_Args := 0; | |
72 | Command_Args := Types.New_List_Mal_Type (Types.List_List); | |
73 | Command_List := Types.Deref_List (Command_Args); | |
74 | ||
75 | while Ada.Command_Line.Argument_Count > Cmd_Args loop | |
76 | ||
77 | Cmd_Args := Cmd_Args + 1; | |
78 | if Ada.Command_Line.Argument (Cmd_Args) = "-d" then | |
79 | Evaluation.Debug := True; | |
80 | elsif Ada.Command_Line.Argument (Cmd_Args) = "-e" then | |
81 | Envs.Debug := True; | |
82 | else | |
83 | if not File_Processed then | |
84 | -- declare | |
85 | -- F_S : String := | |
86 | ADa.Text_IO.Put_Line ( | |
87 | Rep ("(load-file """ & Ada.Command_Line.Argument (Cmd_Args) & """)") | |
88 | ); | |
89 | -- begin | |
90 | -- null; | |
91 | -- end; | |
92 | File_Processed := True; | |
93 | else | |
94 | Command_List.Append | |
51fa7633 | 95 | (Types.New_Symbol_Mal_Type (Ada.Command_Line.Argument (Cmd_Args))); |
18a94a9f CM |
96 | end if; |
97 | end if; | |
98 | ||
99 | end loop; | |
100 | ||
101 | Envs.Set (Envs.Get_Current, "*ARGV*", Command_Args); | |
102 | ||
103 | loop | |
104 | begin | |
105 | Ada.Text_IO.Put ("user> "); | |
106 | Ada.Text_IO.Get_Line (S, Last); | |
107 | Ada.Text_IO.Put_Line (Rep (S (1..Last))); | |
108 | exception | |
109 | when Ada.IO_Exceptions.End_Error => raise; | |
110 | when E : others => | |
111 | Ada.Text_IO.Put_Line | |
112 | (Ada.Text_IO.Standard_Error, | |
113 | Ada.Exceptions.Exception_Information (E)); | |
114 | end; | |
115 | end loop; | |
116 | ||
117 | exception | |
118 | when Ada.IO_Exceptions.End_Error => null; | |
119 | -- i.e. exit without textual output | |
120 | end Step9_Try; |