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