Commit | Line | Data |
---|---|---|
36e91db4 DM |
1 | library STD; |
2 | use STD.textio.all; | |
3 | library WORK; | |
4 | use WORK.types.all; | |
5 | ||
6 | package printer is | |
7 | procedure pr_str(ast: inout mal_val_ptr; readable: in boolean; result: out line); | |
8 | procedure pr_seq(start_ch: in string; end_ch: in string; delim: in string; a_seq: inout mal_seq_ptr; readable: in boolean; result: out line); | |
9 | end package printer; | |
10 | ||
11 | package body printer is | |
12 | ||
13 | procedure pr_string(val: inout line; readable: in boolean; result: out line) is | |
14 | variable s: line; | |
15 | variable src_i, dst_i: integer; | |
16 | begin | |
17 | if readable then | |
18 | s := new string(1 to val'length * 2); | |
19 | dst_i := 0; | |
20 | for src_i in val'range loop | |
21 | dst_i := dst_i + 1; | |
22 | case val(src_i) is | |
23 | when LF => | |
24 | s(dst_i) := '\'; | |
25 | dst_i := dst_i + 1; | |
26 | s(dst_i) := 'n'; | |
27 | when '"' => | |
28 | s(dst_i) := '\'; | |
29 | dst_i := dst_i + 1; | |
30 | s(dst_i) := '"'; | |
31 | when '\' => | |
32 | s(dst_i) := '\'; | |
33 | dst_i := dst_i + 1; | |
34 | s(dst_i) := '\'; | |
35 | when others => | |
36 | s(dst_i) := val(src_i); | |
37 | end case; | |
38 | end loop; | |
39 | result := new string'("" & '"' & s(1 to dst_i) & '"'); | |
40 | deallocate(s); | |
41 | else | |
42 | result := val; | |
43 | end if; | |
44 | end; | |
45 | ||
46 | procedure pr_str(ast: inout mal_val_ptr; readable: in boolean; result: out line) is | |
47 | variable l: line; | |
48 | begin | |
49 | case ast.val_type is | |
50 | when mal_nil => | |
51 | result := new string'("nil"); | |
52 | when mal_true => | |
53 | result := new string'("true"); | |
54 | when mal_false => | |
55 | result := new string'("false"); | |
56 | when mal_number => | |
57 | write(l, ast.number_val); | |
58 | result := l; | |
59 | when mal_symbol => | |
60 | result := ast.string_val; | |
61 | when mal_string => | |
62 | pr_string(ast.string_val, readable, result); | |
63 | when mal_keyword => | |
64 | result := new string'(":" & ast.string_val.all); | |
65 | when mal_list => | |
66 | pr_seq("(", ")", " ", ast.seq_val, readable, result); | |
67 | when mal_vector => | |
68 | pr_seq("[", "]", " ", ast.seq_val, readable, result); | |
69 | when mal_hashmap => | |
70 | pr_seq("{", "}", " ", ast.seq_val, readable, result); | |
71 | when mal_atom => | |
72 | pr_str(ast.seq_val(0), true, l); | |
73 | result := new string'("(atom " & l.all & ")"); | |
74 | when mal_nativefn => | |
75 | result := new string'("#<NativeFunction:" & ast.string_val.all & ">"); | |
76 | when mal_fn => | |
77 | result := new string'("#<MalFunction>"); | |
78 | end case; | |
79 | end procedure pr_str; | |
80 | ||
81 | procedure pr_seq(start_ch: in string; end_ch: in string; delim: in string; a_seq: inout mal_seq_ptr; readable: in boolean; result: out line) is | |
82 | variable s, element_s: line; | |
83 | begin | |
84 | s := new string'(start_ch); | |
85 | for i in a_seq'range loop | |
86 | pr_str(a_seq(i), readable, element_s); | |
87 | if i = 0 then | |
88 | s := new string'(s.all & element_s.all); | |
89 | else | |
90 | s := new string'(s.all & delim & element_s.all); | |
91 | end if; | |
92 | end loop; | |
93 | s := new string'(s.all & end_ch); | |
94 | result := s; | |
95 | end procedure pr_seq; | |
96 | ||
97 | end package body printer; |