prepare for later
[jackhill/mal.git] / plsql / printer.sql
1 -- ---------------------------------------------------------
2 -- printer.sql
3
4 CREATE OR REPLACE PACKAGE printer IS
5 FUNCTION pr_str_seq(M IN OUT NOCOPY types.mal_table,
6 H IN OUT NOCOPY types.map_entry_table,
7 seq mal_vals, sep varchar2,
8 print_readably boolean DEFAULT TRUE) RETURN varchar;
9 FUNCTION pr_str(M IN OUT NOCOPY types.mal_table,
10 H IN OUT NOCOPY types.map_entry_table,
11 ast integer,
12 print_readably boolean DEFAULT TRUE) RETURN varchar;
13 END printer;
14 /
15 show errors;
16
17 CREATE OR REPLACE PACKAGE BODY printer AS
18
19 FUNCTION pr_str_seq(M IN OUT NOCOPY types.mal_table,
20 H IN OUT NOCOPY types.map_entry_table,
21 seq mal_vals, sep varchar2,
22 print_readably boolean DEFAULT TRUE) RETURN varchar IS
23 first integer := 1;
24 str CLOB;
25 BEGIN
26 FOR i IN 1..seq.COUNT LOOP
27 IF first = 1 THEN
28 first := 0;
29 ELSE
30 str := str || sep;
31 END IF;
32 str := str || pr_str(M, H, seq(i), print_readably);
33 END LOOP;
34 RETURN str;
35 END;
36
37 FUNCTION pr_str_map(M IN OUT NOCOPY types.mal_table,
38 H IN OUT NOCOPY types.map_entry_table,
39 midx integer, sep varchar2,
40 print_readably boolean DEFAULT TRUE) RETURN varchar IS
41 key varchar2(256);
42 first integer := 1;
43 str CLOB;
44 BEGIN
45 key := H(midx).FIRST();
46 WHILE key IS NOT NULL LOOP
47 IF first = 1 THEN
48 first := 0;
49 ELSE
50 str := str || sep;
51 END IF;
52 str := str || pr_str(M, H, types.string(M, key), print_readably);
53 str := str || ' ' || pr_str(M, H, H(midx)(key), print_readably);
54 key := H(midx).NEXT(key);
55 END LOOP;
56 RETURN str;
57 END;
58
59
60 FUNCTION pr_str(M IN OUT NOCOPY types.mal_table,
61 H IN OUT NOCOPY types.map_entry_table,
62 ast integer,
63 print_readably boolean DEFAULT TRUE) RETURN varchar IS
64 type_id integer;
65 first integer := 1;
66 i integer;
67 str CLOB;
68 malfn mal_func_T;
69 BEGIN
70 type_id := M(ast).type_id;
71 -- io.writeline('pr_str type: ' || type_id);
72 CASE
73 WHEN type_id = 0 THEN RETURN 'nil';
74 WHEN type_id = 1 THEN RETURN 'false';
75 WHEN type_id = 2 THEN RETURN 'true';
76 WHEN type_id = 3 THEN -- integer
77 RETURN CAST(TREAT(M(ast) AS mal_int_T).val_int as varchar);
78 WHEN type_id IN (5,6) THEN -- string
79 IF type_id = 5 THEN
80 str := TREAT(M(ast) as mal_str_T).val_str;
81 ELSE
82 str := TREAT(M(ast) as mal_long_str_T).val_long_str;
83 END IF;
84 IF chr(127) = SUBSTR(str, 1, 1) THEN
85 RETURN ':' || SUBSTR(str, 2, LENGTH(str)-1);
86 ELSIF print_readably THEN
87 str := REPLACE(str, chr(92), '\\');
88 str := REPLACE(str, '"', '\"');
89 str := REPLACE(str, chr(10), '\n');
90 RETURN '"' || str || '"';
91 ELSE
92 RETURN str;
93 END IF;
94 RETURN TREAT(M(ast) AS mal_str_T).val_str;
95 WHEN type_id = 7 THEN -- symbol
96 RETURN TREAT(M(ast) AS mal_str_T).val_str;
97 WHEN type_id = 8 THEN -- list
98 RETURN '(' || pr_str_seq(M, H,
99 TREAT(M(ast) AS mal_seq_T).val_seq, ' ',
100 print_readably) || ')';
101 WHEN type_id = 9 THEN -- vector
102 RETURN '[' || pr_str_seq(M, H,
103 TREAT(M(ast) AS mal_seq_T).val_seq, ' ',
104 print_readably) || ']';
105 WHEN type_id = 10 THEN -- hash-map
106 RETURN '{' || pr_str_map(M, H,
107 TREAT(M(ast) AS mal_map_T).map_idx, ' ',
108 print_readably) || '}';
109 WHEN type_id = 11 THEN -- native function
110 RETURN '#<function ' ||
111 TREAT(M(ast) AS mal_str_T).val_str ||
112 '>';
113 WHEN type_id = 12 THEN -- mal function
114 malfn := TREAT(M(ast) AS mal_func_T);
115 RETURN '(fn* ' || pr_str(M, H, malfn.params, print_readably) ||
116 ' ' || pr_str(M, H, malfn.ast, print_readably) || ')';
117 WHEN type_id = 13 THEN -- atom
118 RETURN '(atom ' ||
119 pr_str(M, H, TREAT(M(ast) AS mal_atom_T).val, print_readably) ||
120 ')';
121 ELSE
122 RETURN 'unknown';
123 END CASE;
124 END;
125
126 END printer;
127 /
128 show errors;