mirror of
https://github.com/kanaka/mal.git
synced 2024-11-11 00:52:44 +03:00
149 lines
4.1 KiB
SQL
149 lines
4.1 KiB
SQL
-- ---------------------------------------------------------
|
|
-- env.sql
|
|
|
|
CREATE OR REPLACE TYPE env_item FORCE AS OBJECT (
|
|
key varchar2(256),
|
|
val integer
|
|
) FINAL;
|
|
/
|
|
|
|
CREATE OR REPLACE TYPE env_data FORCE IS TABLE OF env_item;
|
|
/
|
|
|
|
CREATE OR REPLACE TYPE env_T FORCE AS OBJECT (
|
|
idx integer,
|
|
outer_idx integer,
|
|
data env_data
|
|
);
|
|
/
|
|
|
|
CREATE OR REPLACE TYPE env_mem_T FORCE IS TABLE OF env_T;
|
|
/
|
|
|
|
CREATE OR REPLACE PACKAGE env_pkg IS
|
|
TYPE env_entry IS TABLE OF integer INDEX BY varchar2(256);
|
|
TYPE env_entry_table IS TABLE OF env_entry;
|
|
|
|
FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
|
|
eeT IN OUT NOCOPY env_entry_table,
|
|
outer_idx integer DEFAULT NULL)
|
|
RETURN integer;
|
|
FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
|
|
eeT IN OUT NOCOPY env_entry_table,
|
|
outer_idx integer,
|
|
binds integer,
|
|
exprs mal_vals)
|
|
RETURN integer;
|
|
FUNCTION env_set(M IN OUT NOCOPY types.mal_table,
|
|
eeT IN OUT NOCOPY env_entry_table,
|
|
eidx integer,
|
|
key integer,
|
|
val integer) RETURN integer;
|
|
FUNCTION env_find(M IN OUT NOCOPY types.mal_table,
|
|
eeT env_entry_table,
|
|
eidx integer,
|
|
key integer) RETURN integer;
|
|
FUNCTION env_get(M IN OUT NOCOPY types.mal_table,
|
|
eeT env_entry_table,
|
|
eidx integer,
|
|
key integer) RETURN integer;
|
|
END env_pkg;
|
|
/
|
|
show errors;
|
|
|
|
|
|
CREATE OR REPLACE PACKAGE BODY env_pkg IS
|
|
|
|
FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
|
|
eeT IN OUT NOCOPY env_entry_table,
|
|
outer_idx integer DEFAULT NULL)
|
|
RETURN integer IS
|
|
eidx integer;
|
|
BEGIN
|
|
eeT.EXTEND();
|
|
eidx := eeT.COUNT();
|
|
eeT(eidx)('**OUTER**') := outer_idx;
|
|
RETURN eidx;
|
|
END;
|
|
|
|
FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
|
|
eeT IN OUT NOCOPY env_entry_table,
|
|
outer_idx integer,
|
|
binds integer,
|
|
exprs mal_vals)
|
|
RETURN integer IS
|
|
eidx integer;
|
|
i integer;
|
|
bs mal_vals;
|
|
BEGIN
|
|
eeT.EXTEND();
|
|
eidx := eeT.COUNT();
|
|
eeT(eidx)('**OUTER**') := outer_idx;
|
|
IF binds IS NOT NULL THEN
|
|
bs := TREAT(M(binds) AS mal_seq_T).val_seq;
|
|
FOR i IN 1..bs.COUNT LOOP
|
|
IF TREAT(M(bs(i)) AS mal_str_T).val_str = '&' THEN
|
|
eeT(eidx)(TREAT(M(bs(i+1)) AS mal_str_T).val_str) :=
|
|
types.slice(M, exprs, i-1);
|
|
EXIT;
|
|
ELSE
|
|
eeT(eidx)(TREAT(M(bs(i)) AS mal_str_T).val_str) :=
|
|
exprs(i);
|
|
END IF;
|
|
END LOOP;
|
|
END IF;
|
|
RETURN eidx;
|
|
END;
|
|
|
|
FUNCTION env_set(M IN OUT NOCOPY types.mal_table,
|
|
eeT IN OUT NOCOPY env_entry_table,
|
|
eidx integer,
|
|
key integer,
|
|
val integer) RETURN integer IS
|
|
k varchar2(256);
|
|
i integer;
|
|
cnt integer;
|
|
BEGIN
|
|
k := TREAT(M(key) AS mal_str_T).val_str;
|
|
eeT(eidx)(k) := val;
|
|
RETURN val;
|
|
END;
|
|
|
|
FUNCTION env_find(M IN OUT NOCOPY types.mal_table,
|
|
eeT env_entry_table,
|
|
eidx integer,
|
|
key integer) RETURN integer IS
|
|
k varchar2(256);
|
|
cnt integer;
|
|
BEGIN
|
|
k := TREAT(M(key) AS mal_str_T).val_str;
|
|
IF eeT(eidx).EXISTS(k) THEN
|
|
RETURN eidx;
|
|
ELSIF eeT(eidx)('**OUTER**') IS NOT NULL THEN
|
|
RETURN env_find(M, eeT, eeT(eidx)('**OUTER**'), key);
|
|
ELSE
|
|
RETURN NULL;
|
|
END IF;
|
|
END;
|
|
|
|
FUNCTION env_get(M IN OUT NOCOPY types.mal_table,
|
|
eeT env_entry_table,
|
|
eidx integer,
|
|
key integer) RETURN integer IS
|
|
found integer;
|
|
k varchar2(256);
|
|
BEGIN
|
|
found := env_find(M, eeT, eidx, key);
|
|
k := TREAT(M(key) AS mal_str_T).val_str;
|
|
IF found IS NOT NULL THEN
|
|
RETURN eeT(found)(k);
|
|
ELSE
|
|
raise_application_error(-20005,
|
|
'''' || k || ''' not found', TRUE);
|
|
END IF;
|
|
END;
|
|
|
|
END env_pkg;
|
|
/
|
|
show errors;
|