plsql: self-hosting. Long strings, refactor io.
[jackhill/mal.git] / plsql / env.sql
1 -- ---------------------------------------------------------
2 -- env.sql
3
4 PROMPT "env.sql start";
5
6 CREATE OR REPLACE TYPE env_item FORCE AS OBJECT (
7 key varchar2(256),
8 val integer
9 ) FINAL;
10 /
11
12 CREATE OR REPLACE TYPE env_data FORCE IS TABLE OF env_item;
13 /
14
15 CREATE OR REPLACE TYPE env_type FORCE AS OBJECT (
16 idx integer,
17 outer_idx integer,
18 data env_data
19 );
20 /
21
22 CREATE OR REPLACE TYPE env_mem_type FORCE IS TABLE OF env_type;
23 /
24
25 CREATE OR REPLACE PACKAGE env_pkg IS
26 TYPE env_entry IS TABLE OF integer INDEX BY varchar2(256);
27 TYPE env_entry_table IS TABLE OF env_entry;
28
29 FUNCTION env_new(M IN OUT NOCOPY mem_type,
30 eeT IN OUT NOCOPY env_entry_table,
31 outer_idx integer DEFAULT NULL)
32 RETURN integer;
33 FUNCTION env_new(M IN OUT NOCOPY mem_type,
34 eeT IN OUT NOCOPY env_entry_table,
35 outer_idx integer,
36 binds integer,
37 exprs mal_seq_items_type)
38 RETURN integer;
39 FUNCTION env_set(M IN OUT NOCOPY mem_type,
40 eeT IN OUT NOCOPY env_entry_table,
41 eidx integer,
42 key integer,
43 val integer) RETURN integer;
44 FUNCTION env_find(M IN OUT NOCOPY mem_type,
45 eeT env_entry_table,
46 eidx integer,
47 key integer) RETURN integer;
48 FUNCTION env_get(M IN OUT NOCOPY mem_type,
49 eeT env_entry_table,
50 eidx integer,
51 key integer) RETURN integer;
52 END env_pkg;
53 /
54 show errors;
55
56 CREATE OR REPLACE PACKAGE BODY env_pkg IS
57 FUNCTION env_new(M IN OUT NOCOPY mem_type,
58 eeT IN OUT NOCOPY env_entry_table,
59 outer_idx integer DEFAULT NULL)
60 RETURN integer IS
61 eidx integer;
62 BEGIN
63 eeT.EXTEND();
64 eidx := eeT.COUNT();
65 eeT(eidx)('**OUTER**') := outer_idx;
66 RETURN eidx;
67 END;
68
69 FUNCTION env_new(M IN OUT NOCOPY mem_type,
70 eeT IN OUT NOCOPY env_entry_table,
71 outer_idx integer,
72 binds integer,
73 exprs mal_seq_items_type)
74 RETURN integer IS
75 eidx integer;
76 i integer;
77 bs mal_seq_items_type;
78 BEGIN
79 eeT.EXTEND();
80 eidx := eeT.COUNT();
81 eeT(eidx)('**OUTER**') := outer_idx;
82 IF binds IS NOT NULL THEN
83 bs := TREAT(M(binds) AS mal_seq_type).val_seq;
84 FOR i IN 1..bs.COUNT LOOP
85 IF TREAT(M(bs(i)) AS mal_str_type).val_str = '&' THEN
86 eeT(eidx)(TREAT(M(bs(i+1)) AS mal_str_type).val_str) :=
87 types.slice(M, exprs, i-1);
88 EXIT;
89 ELSE
90 eeT(eidx)(TREAT(M(bs(i)) AS mal_str_type).val_str) :=
91 exprs(i);
92 END IF;
93 END LOOP;
94 END IF;
95 RETURN eidx;
96 END;
97
98 FUNCTION env_set(M IN OUT NOCOPY mem_type,
99 eeT IN OUT NOCOPY env_entry_table,
100 eidx integer,
101 key integer,
102 val integer) RETURN integer IS
103 k varchar2(256);
104 i integer;
105 cnt integer;
106 BEGIN
107 k := TREAT(M(key) AS mal_str_type).val_str;
108 eeT(eidx)(k) := val;
109 RETURN val;
110 END;
111
112 FUNCTION env_find(M IN OUT NOCOPY mem_type,
113 eeT env_entry_table,
114 eidx integer,
115 key integer) RETURN integer IS
116 k varchar2(256);
117 cnt integer;
118 BEGIN
119 k := TREAT(M(key) AS mal_str_type).val_str;
120 IF eeT(eidx).EXISTS(k) THEN
121 RETURN eidx;
122 ELSIF eeT(eidx)('**OUTER**') IS NOT NULL THEN
123 RETURN env_find(M, eeT, eeT(eidx)('**OUTER**'), key);
124 ELSE
125 RETURN NULL;
126 END IF;
127 END;
128
129 FUNCTION env_get(M IN OUT NOCOPY mem_type,
130 eeT env_entry_table,
131 eidx integer,
132 key integer) RETURN integer IS
133 found integer;
134 k varchar2(256);
135 BEGIN
136 found := env_find(M, eeT, eidx, key);
137 k := TREAT(M(key) AS mal_str_type).val_str;
138 IF found IS NOT NULL THEN
139 RETURN eeT(found)(k);
140 ELSE
141 raise_application_error(-20005,
142 '''' || k || ''' not found', TRUE);
143 END IF;
144 END;
145 END env_pkg;
146 /
147 show errors;
148
149
150 PROMPT "env.sql finished";