mirror of
https://github.com/kanaka/mal.git
synced 2024-09-20 01:57:09 +03:00
plsql: self-hosting. Long strings, refactor io.
This commit is contained in:
parent
6a08510367
commit
02936b429a
@ -82,12 +82,18 @@ FUNCTION read_string(M IN OUT NOCOPY mem_type,
|
||||
H IN OUT NOCOPY types.map_entry_table,
|
||||
args mal_seq_items_type) RETURN integer IS
|
||||
BEGIN
|
||||
RETURN reader.read_str(M, H, TREAT(M(args(1)) AS mal_str_type).val_str);
|
||||
IF M(args(1)).type_id = 5 THEN
|
||||
RETURN reader.read_str(M, H,
|
||||
TREAT(M(args(1)) AS mal_str_type).val_str);
|
||||
ELSE
|
||||
RETURN reader.read_str(M, H,
|
||||
TREAT(M(args(1)) AS mal_long_str_type).val_long_str);
|
||||
END IF;
|
||||
END;
|
||||
|
||||
FUNCTION readline(M IN OUT NOCOPY mem_type,
|
||||
prompt integer) RETURN integer IS
|
||||
input varchar2(4000);
|
||||
input CLOB;
|
||||
BEGIN
|
||||
input := stream_readline(TREAT(M(prompt) AS mal_str_type).val_str, 0);
|
||||
RETURN types.string(M, input);
|
||||
@ -101,10 +107,9 @@ END;
|
||||
|
||||
FUNCTION slurp(M IN OUT NOCOPY mem_type,
|
||||
args mal_seq_items_type) RETURN integer IS
|
||||
content varchar2(4000);
|
||||
content CLOB;
|
||||
BEGIN
|
||||
-- stream_writeline('here1: ' || TREAT(args(1) AS mal_str_type).val_str);
|
||||
content := file_open_and_read(TREAT(M(args(1)) AS mal_str_type).val_str);
|
||||
content := io.file_open_and_read(TREAT(M(args(1)) AS mal_str_type).val_str);
|
||||
content := REPLACE(content, '\n', chr(10));
|
||||
RETURN types.string(M, content);
|
||||
END;
|
||||
@ -398,7 +403,7 @@ FUNCTION seq(M IN OUT NOCOPY mem_type,
|
||||
val integer) RETURN integer IS
|
||||
type_id integer;
|
||||
new_val integer;
|
||||
str varchar2(4000);
|
||||
str CLOB;
|
||||
str_items mal_seq_items_type;
|
||||
BEGIN
|
||||
type_id := M(val).type_id;
|
||||
@ -466,7 +471,7 @@ FUNCTION do_core_func(M IN OUT NOCOPY mem_type,
|
||||
H IN OUT NOCOPY types.map_entry_table,
|
||||
fn integer,
|
||||
a mal_seq_items_type) RETURN integer IS
|
||||
fname varchar(100);
|
||||
fname varchar(256);
|
||||
idx integer;
|
||||
BEGIN
|
||||
IF M(fn).type_id <> 11 THEN
|
||||
|
@ -4,7 +4,7 @@
|
||||
PROMPT "env.sql start";
|
||||
|
||||
CREATE OR REPLACE TYPE env_item FORCE AS OBJECT (
|
||||
key varchar2(100),
|
||||
key varchar2(256),
|
||||
val integer
|
||||
) FINAL;
|
||||
/
|
||||
@ -113,7 +113,7 @@ CREATE OR REPLACE PACKAGE BODY env_pkg IS
|
||||
eeT env_entry_table,
|
||||
eidx integer,
|
||||
key integer) RETURN integer IS
|
||||
k varchar2(100);
|
||||
k varchar2(256);
|
||||
cnt integer;
|
||||
BEGIN
|
||||
k := TREAT(M(key) AS mal_str_type).val_str;
|
||||
@ -131,7 +131,7 @@ CREATE OR REPLACE PACKAGE BODY env_pkg IS
|
||||
eidx integer,
|
||||
key integer) RETURN integer IS
|
||||
found integer;
|
||||
k varchar2(100);
|
||||
k varchar2(256);
|
||||
BEGIN
|
||||
found := env_find(M, eeT, eidx, key);
|
||||
k := TREAT(M(key) AS mal_str_type).val_str;
|
||||
|
77
plsql/io.sql
77
plsql/io.sql
@ -8,8 +8,8 @@ END;
|
||||
CREATE TABLE stream (
|
||||
stream_id integer,
|
||||
open number(1,0), -- stream open (1) or closed (0)
|
||||
data varchar2(4000), -- queued stream data
|
||||
rl_prompt varchar2(4000) -- prompt for readline input
|
||||
data CLOB, -- queued stream data
|
||||
rl_prompt varchar2(256) -- prompt for readline input
|
||||
);
|
||||
|
||||
-- stdin
|
||||
@ -30,14 +30,30 @@ END;
|
||||
|
||||
CREATE TABLE file_io (
|
||||
path varchar2(1024), -- file to read/write
|
||||
data varchar2(4000), -- file data
|
||||
data CLOB, -- file data
|
||||
error varchar2(1024), -- any errors during read
|
||||
in_or_out varchar2(4) -- input ('in') or output ('out')
|
||||
);
|
||||
|
||||
-- ---------------------------------------------------------
|
||||
|
||||
CREATE OR REPLACE PROCEDURE stream_open(sid integer) AS
|
||||
CREATE OR REPLACE PACKAGE io IS
|
||||
PROCEDURE open(sid integer);
|
||||
PROCEDURE close(sid integer);
|
||||
FUNCTION read(sid integer DEFAULT 0) RETURN CLOB;
|
||||
FUNCTION readline(prompt varchar, sid integer DEFAULT 0) RETURN CLOB;
|
||||
PROCEDURE write(input CLOB, sid integer DEFAULT 1);
|
||||
PROCEDURE writeline(data CLOB, sid integer DEFAULT 1);
|
||||
FUNCTION wait_rl_prompt(sid integer DEFAULT 0) RETURN varchar;
|
||||
PROCEDURE wait_flushed(sid integer DEFAULT 1);
|
||||
FUNCTION file_open_and_read(path varchar) RETURN varchar;
|
||||
END io;
|
||||
/
|
||||
show errors;
|
||||
|
||||
CREATE OR REPLACE PACKAGE BODY io AS
|
||||
|
||||
PROCEDURE open(sid integer) AS
|
||||
BEGIN
|
||||
-- DBMS_OUTPUT.PUT_LINE('stream_open(' || sid || ') start');
|
||||
UPDATE stream SET data = '', rl_prompt = '', open = 1
|
||||
@ -45,9 +61,8 @@ BEGIN
|
||||
COMMIT;
|
||||
-- DBMS_OUTPUT.PUT_LINE('stream_open(' || sid || ') done');
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE stream_close(sid integer) AS
|
||||
PROCEDURE close(sid integer) AS
|
||||
BEGIN
|
||||
-- DBMS_OUTPUT.PUT_LINE('stream_close(' || sid || ') start');
|
||||
UPDATE stream SET rl_prompt = '', open = 0
|
||||
@ -55,16 +70,14 @@ BEGIN
|
||||
COMMIT;
|
||||
-- DBMS_OUTPUT.PUT_LINE('stream_close(' || sid || ') done');
|
||||
END;
|
||||
/
|
||||
|
||||
-- stream_read:
|
||||
-- read from stream stream_id in stream table. Waits until there is
|
||||
-- either data to return or the stream closes (NULL data). Returns
|
||||
-- NULL when stream is closed.
|
||||
CREATE OR REPLACE FUNCTION stream_read(sid integer DEFAULT 0)
|
||||
RETURN varchar IS
|
||||
FUNCTION read(sid integer DEFAULT 0) RETURN CLOB IS
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
input varchar(4000);
|
||||
input CLOB;
|
||||
isopen integer;
|
||||
sleep real;
|
||||
BEGIN
|
||||
@ -93,12 +106,10 @@ BEGIN
|
||||
END IF;
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
-- stream_readline:
|
||||
-- readline:
|
||||
-- set prompt and wait for readline style input on the stream
|
||||
CREATE OR REPLACE FUNCTION stream_readline(prompt varchar, sid integer DEFAULT 0)
|
||||
RETURN varchar IS
|
||||
FUNCTION readline(prompt varchar, sid integer DEFAULT 0) RETURN CLOB IS
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
BEGIN
|
||||
-- set prompt / request readline style input
|
||||
@ -106,36 +117,32 @@ BEGIN
|
||||
UPDATE stream SET rl_prompt = prompt WHERE stream_id = sid;
|
||||
COMMIT;
|
||||
|
||||
RETURN stream_read(sid);
|
||||
RETURN read(sid);
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE stream_write(input varchar, sid integer DEFAULT 1) AS
|
||||
PROCEDURE write(input CLOB, sid integer DEFAULT 1) AS
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
BEGIN
|
||||
-- LOCK TABLE stream IN EXCLUSIVE MODE;
|
||||
UPDATE stream SET data = data || input WHERE stream_id = sid;
|
||||
COMMIT;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE stream_writeline(data varchar, sid integer DEFAULT 1) AS
|
||||
PROCEDURE writeline(data CLOB, sid integer DEFAULT 1) AS
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
BEGIN
|
||||
stream_write(data || chr(10), sid);
|
||||
write(data || TO_CLOB(chr(10)), sid);
|
||||
END;
|
||||
/
|
||||
|
||||
-- ---------------------------------------------------------
|
||||
|
||||
-- wait_rl_prompt:
|
||||
-- wait for rl_prompt to be set on the given stream and return the
|
||||
-- rl_prompt value. Errors if stream is already closed.
|
||||
CREATE OR REPLACE FUNCTION stream_wait_rl_prompt(sid integer DEFAULT 0)
|
||||
RETURN varchar IS
|
||||
FUNCTION wait_rl_prompt(sid integer DEFAULT 0) RETURN varchar IS
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
isopen integer;
|
||||
prompt varchar(4000);
|
||||
prompt CLOB;
|
||||
sleep real;
|
||||
datas integer;
|
||||
BEGIN
|
||||
@ -145,7 +152,7 @@ BEGIN
|
||||
LOCK TABLE stream IN EXCLUSIVE MODE;
|
||||
SELECT open, rl_prompt INTO isopen, prompt
|
||||
FROM stream WHERE stream_id = sid;
|
||||
SELECT count(data) INTO datas FROM stream WHERE data IS NOT NULL;
|
||||
SELECT count(*) INTO datas FROM stream WHERE data IS NOT NULL;
|
||||
|
||||
IF isopen = 0 THEN
|
||||
raise_application_error(-20001,
|
||||
@ -168,9 +175,8 @@ BEGIN
|
||||
END IF;
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE stream_wait_flushed(sid integer DEFAULT 1) AS
|
||||
PROCEDURE wait_flushed(sid integer DEFAULT 1) AS
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
pending integer;
|
||||
sleep real;
|
||||
@ -178,8 +184,8 @@ BEGIN
|
||||
sleep := 0.05;
|
||||
WHILE true
|
||||
LOOP
|
||||
SELECT count(data) INTO pending FROM stream
|
||||
WHERE stream_id = sid AND data IS NOT NULL AND data <> '';
|
||||
SELECT count(*) INTO pending FROM stream
|
||||
WHERE stream_id = sid AND data IS NOT NULL;
|
||||
IF pending = 0 THEN RETURN; END IF;
|
||||
DBMS_LOCK.SLEEP(sleep);
|
||||
IF sleep < 0.5 THEN
|
||||
@ -187,15 +193,13 @@ BEGIN
|
||||
END IF;
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
-- ---------------------------------------------------------
|
||||
|
||||
CREATE OR REPLACE FUNCTION file_open_and_read(path varchar)
|
||||
RETURN varchar IS
|
||||
FUNCTION file_open_and_read(path varchar) RETURN varchar IS
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
sleep real;
|
||||
content varchar2(4000);
|
||||
content CLOB;
|
||||
error_msg varchar2(1024);
|
||||
BEGIN
|
||||
sleep := 0.05;
|
||||
@ -227,12 +231,13 @@ BEGIN
|
||||
END IF;
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE file_read_response(path varchar, data varchar) AS
|
||||
PROCEDURE file_read_response(path varchar, data varchar) AS
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
BEGIN
|
||||
UPDATE file_io SET data = data WHERE path = path;
|
||||
END;
|
||||
/
|
||||
|
||||
END io;
|
||||
/
|
||||
show errors;
|
||||
|
@ -17,5 +17,9 @@ SET DEFINE OFF;
|
||||
-- Print DBMS_OUTPUT.PUT_LINE debugcommands
|
||||
SET SERVEROUTPUT ON SIZE 30000;
|
||||
|
||||
-- Do not truncate or wrap CLOB output
|
||||
SET LONG 32767;
|
||||
SET LONGCHUNKSIZE 32767;
|
||||
|
||||
-- PROMPT 'Finish login.sql';
|
||||
|
||||
|
@ -22,7 +22,7 @@ FUNCTION pr_str_seq(M IN OUT NOCOPY mem_type,
|
||||
seq mal_seq_items_type, sep varchar2,
|
||||
print_readably boolean DEFAULT TRUE) RETURN varchar IS
|
||||
first integer := 1;
|
||||
str varchar2(4000) := '';
|
||||
str CLOB;
|
||||
BEGIN
|
||||
FOR i IN 1..seq.COUNT LOOP
|
||||
IF first = 1 THEN
|
||||
@ -41,7 +41,7 @@ FUNCTION pr_str_map(M IN OUT NOCOPY mem_type,
|
||||
print_readably boolean DEFAULT TRUE) RETURN varchar IS
|
||||
key varchar2(256);
|
||||
first integer := 1;
|
||||
str varchar2(4000) := '';
|
||||
str CLOB;
|
||||
BEGIN
|
||||
key := H(midx).FIRST();
|
||||
WHILE key IS NOT NULL LOOP
|
||||
@ -65,7 +65,7 @@ FUNCTION pr_str(M IN OUT NOCOPY mem_type,
|
||||
type_id integer;
|
||||
first integer := 1;
|
||||
i integer;
|
||||
str varchar2(4000);
|
||||
str CLOB;
|
||||
malfn malfunc_type;
|
||||
BEGIN
|
||||
type_id := M(ast).type_id;
|
||||
@ -76,8 +76,12 @@ BEGIN
|
||||
WHEN type_id = 2 THEN RETURN 'true';
|
||||
WHEN type_id = 3 THEN -- integer
|
||||
RETURN CAST(TREAT(M(ast) AS mal_int_type).val_int as varchar);
|
||||
WHEN type_id = 5 THEN -- string
|
||||
WHEN type_id IN (5,6) THEN -- string
|
||||
IF type_id = 5 THEN
|
||||
str := TREAT(M(ast) as mal_str_type).val_str;
|
||||
ELSE
|
||||
str := TREAT(M(ast) as mal_long_str_type).val_long_str;
|
||||
END IF;
|
||||
IF chr(127) = SUBSTR(str, 1, 1) THEN
|
||||
RETURN ':' || SUBSTR(str, 2, LENGTH(str)-1);
|
||||
ELSIF print_readably THEN
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
PROMPT "reader.sql start";
|
||||
|
||||
CREATE OR REPLACE TYPE tokens FORCE AS TABLE OF varchar2(4000);
|
||||
CREATE OR REPLACE TYPE tokens FORCE AS TABLE OF CLOB;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE TYPE readerT FORCE AS OBJECT (
|
||||
@ -44,7 +44,7 @@ CREATE OR REPLACE PACKAGE BODY reader AS
|
||||
|
||||
FUNCTION tokenize(str varchar) RETURN tokens IS
|
||||
re varchar2(100) := '[[:space:] ,]*(~@|[][{}()''`~@]|"(([\].|[^\"])*)"|;[^' || chr(10) || ']*|[^][[:space:] {}()''"`~@,;]*)';
|
||||
tok varchar2(4000);
|
||||
tok CLOB;
|
||||
toks tokens := tokens();
|
||||
cnt integer;
|
||||
BEGIN
|
||||
@ -66,8 +66,9 @@ END;
|
||||
FUNCTION read_atom(M IN OUT NOCOPY mem_type,
|
||||
rdr IN OUT NOCOPY readerT) RETURN integer IS
|
||||
str_id integer;
|
||||
str varchar2(4000);
|
||||
token varchar2(4000);
|
||||
str CLOB;
|
||||
token CLOB;
|
||||
istr varchar2(256);
|
||||
result integer;
|
||||
BEGIN
|
||||
token := rdr.next();
|
||||
@ -79,7 +80,8 @@ BEGIN
|
||||
ELSIF token = 'true' THEN -- true
|
||||
result := 3;
|
||||
ELSIF REGEXP_LIKE(token, '^-?[0-9][0-9]*$') THEN -- integer
|
||||
result := types.int(M, CAST(token AS integer));
|
||||
istr := token;
|
||||
result := types.int(M, CAST(istr AS integer));
|
||||
ELSIF REGEXP_LIKE(token, '^".*"') THEN -- string
|
||||
-- string
|
||||
str := SUBSTR(token, 2, LENGTH(token)-2);
|
||||
@ -110,7 +112,7 @@ FUNCTION read_seq(M IN OUT NOCOPY mem_type,
|
||||
rdr IN OUT NOCOPY readerT, type_id integer,
|
||||
first varchar, last varchar)
|
||||
RETURN integer IS
|
||||
token varchar2(4000);
|
||||
token CLOB;
|
||||
items mal_seq_items_type;
|
||||
BEGIN
|
||||
token := rdr.next();
|
||||
@ -143,7 +145,7 @@ END;
|
||||
FUNCTION read_form(M IN OUT NOCOPY mem_type,
|
||||
H IN OUT NOCOPY types.map_entry_table,
|
||||
rdr IN OUT NOCOPY readerT) RETURN integer IS
|
||||
token varchar2(4000);
|
||||
token CLOB;
|
||||
meta integer;
|
||||
midx integer;
|
||||
BEGIN
|
||||
|
@ -11,7 +11,7 @@ END mal;
|
||||
CREATE OR REPLACE PACKAGE BODY mal IS
|
||||
|
||||
FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
|
||||
-- read
|
||||
FUNCTION READ(line varchar) RETURN varchar IS
|
||||
@ -40,18 +40,18 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
BEGIN
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -15,7 +15,7 @@ CREATE OR REPLACE PACKAGE BODY mal IS
|
||||
FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
M mem_type; -- general mal value memory pool
|
||||
H types.map_entry_table; -- hashmap memory pool
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
|
||||
-- read
|
||||
FUNCTION READ(line varchar) RETURN integer IS
|
||||
@ -48,18 +48,18 @@ BEGIN
|
||||
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -17,7 +17,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
H types.map_entry_table; -- hashmap memory pool
|
||||
TYPE env_type IS TABLE OF integer INDEX BY varchar2(100);
|
||||
repl_env env_type;
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
|
||||
-- read
|
||||
FUNCTION READ(line varchar) RETURN integer IS
|
||||
@ -119,7 +119,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
|
||||
FUNCTION do_core_func(fn integer, args mal_seq_items_type)
|
||||
RETURN integer IS
|
||||
fname varchar(100);
|
||||
fname varchar(256);
|
||||
BEGIN
|
||||
IF M(fn).type_id <> 11 THEN
|
||||
raise_application_error(-20004,
|
||||
@ -154,18 +154,18 @@ BEGIN
|
||||
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -19,7 +19,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
E env_pkg.env_entry_table; -- mal env memory pool
|
||||
repl_env integer;
|
||||
x integer;
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
|
||||
-- read
|
||||
FUNCTION READ(line varchar) RETURN integer IS
|
||||
@ -72,7 +72,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
FUNCTION EVAL(ast integer, env integer) RETURN integer IS
|
||||
el integer;
|
||||
a0 integer;
|
||||
a0sym varchar2(100);
|
||||
a0sym varchar2(256);
|
||||
seq mal_seq_items_type;
|
||||
let_env integer;
|
||||
i integer;
|
||||
@ -150,7 +150,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
|
||||
FUNCTION do_core_func(fn integer, args mal_seq_items_type)
|
||||
RETURN integer IS
|
||||
fname varchar(100);
|
||||
fname varchar(256);
|
||||
BEGIN
|
||||
IF M(fn).type_id <> 11 THEN
|
||||
raise_application_error(-20004,
|
||||
@ -191,18 +191,18 @@ BEGIN
|
||||
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -20,7 +20,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
E env_pkg.env_entry_table; -- mal env memory pool
|
||||
repl_env integer;
|
||||
x integer;
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
core_ns core_ns_type;
|
||||
cidx integer;
|
||||
|
||||
@ -179,18 +179,18 @@ BEGIN
|
||||
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -20,7 +20,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
E env_pkg.env_entry_table; -- mal env memory pool
|
||||
repl_env integer;
|
||||
x integer;
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
core_ns core_ns_type;
|
||||
cidx integer;
|
||||
|
||||
@ -186,18 +186,18 @@ BEGIN
|
||||
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -20,7 +20,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
E env_pkg.env_entry_table; -- mal env memory pool
|
||||
repl_env integer;
|
||||
x integer;
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
core_ns core_ns_type;
|
||||
cidx integer;
|
||||
argv mal_seq_items_type;
|
||||
@ -243,18 +243,18 @@ BEGIN
|
||||
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -20,7 +20,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
E env_pkg.env_entry_table; -- mal env memory pool
|
||||
repl_env integer;
|
||||
x integer;
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
core_ns core_ns_type;
|
||||
cidx integer;
|
||||
argv mal_seq_items_type;
|
||||
@ -278,18 +278,18 @@ BEGIN
|
||||
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -20,7 +20,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
E env_pkg.env_entry_table; -- mal env memory pool
|
||||
repl_env integer;
|
||||
x integer;
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
core_ns core_ns_type;
|
||||
cidx integer;
|
||||
argv mal_seq_items_type;
|
||||
@ -337,18 +337,18 @@ BEGIN
|
||||
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -20,7 +20,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
E env_pkg.env_entry_table; -- mal env memory pool
|
||||
repl_env integer;
|
||||
x integer;
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
core_ns core_ns_type;
|
||||
cidx integer;
|
||||
argv mal_seq_items_type;
|
||||
@ -423,18 +423,18 @@ BEGIN
|
||||
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -20,7 +20,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
E env_pkg.env_entry_table; -- mal env memory pool
|
||||
repl_env integer;
|
||||
x integer;
|
||||
line varchar2(4000);
|
||||
line CLOB;
|
||||
core_ns core_ns_type;
|
||||
cidx integer;
|
||||
argv mal_seq_items_type;
|
||||
@ -162,7 +162,7 @@ FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
|
||||
args mal_seq_items_type;
|
||||
BEGIN
|
||||
WHILE TRUE LOOP
|
||||
-- stream_writeline('EVAL: ' || printer.pr_str(M, H, ast));
|
||||
-- io.writeline('EVAL: ' || printer.pr_str(M, H, ast));
|
||||
IF M(ast).type_id <> 8 THEN
|
||||
RETURN eval_ast(ast, env);
|
||||
END IF;
|
||||
@ -427,18 +427,18 @@ BEGIN
|
||||
line := REP('(println (str "Mal [" *host-language* "]"))');
|
||||
WHILE true LOOP
|
||||
BEGIN
|
||||
line := stream_readline('user> ', 0);
|
||||
IF line IS NULL THEN CONTINUE; END IF;
|
||||
line := io.readline('user> ', 0);
|
||||
IF line IS NULL OR line = EMPTY_CLOB() THEN CONTINUE; END IF;
|
||||
IF line IS NOT NULL THEN
|
||||
stream_writeline(REP(line));
|
||||
io.writeline(REP(line));
|
||||
END IF;
|
||||
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
IF SQLCODE = -20001 THEN -- io streams closed
|
||||
RETURN 0;
|
||||
END IF;
|
||||
stream_writeline('Error: ' || SQLERRM);
|
||||
stream_writeline(dbms_utility.format_error_backtrace);
|
||||
io.writeline('Error: ' || SQLERRM);
|
||||
io.writeline(dbms_utility.format_error_backtrace);
|
||||
END;
|
||||
END LOOP;
|
||||
END;
|
||||
|
@ -17,7 +17,7 @@ END;
|
||||
-- 3: integer
|
||||
-- 4: float
|
||||
-- 5: string
|
||||
-- 6: keyword (not used, uses prefixed string)
|
||||
-- 6: long string (CLOB)
|
||||
-- 7: symbol
|
||||
-- 8: list
|
||||
-- 9: vector
|
||||
@ -38,11 +38,17 @@ CREATE OR REPLACE TYPE mal_int_type FORCE UNDER mal_type (
|
||||
) FINAL;
|
||||
/
|
||||
|
||||
-- string/keyword (5), symbol (7)
|
||||
-- string/keyword (5,6), symbol (7)
|
||||
CREATE OR REPLACE TYPE mal_str_type FORCE UNDER mal_type (
|
||||
val_str varchar2(4000)
|
||||
) NOT FINAL;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE TYPE mal_long_str_type FORCE UNDER mal_str_type (
|
||||
val_long_str CLOB -- long character object (for larger than 4000 chars)
|
||||
) FINAL;
|
||||
/
|
||||
show errors;
|
||||
|
||||
-- list (8), vector (9)
|
||||
CREATE OR REPLACE TYPE mal_seq_items_type FORCE AS TABLE OF integer;
|
||||
@ -216,7 +222,7 @@ BEGIN
|
||||
WHEN atyp = 3 THEN
|
||||
RETURN TREAT(M(a) AS mal_int_type).val_int =
|
||||
TREAT(M(b) AS mal_int_type).val_int;
|
||||
WHEN atyp IN (5,7) THEN
|
||||
WHEN atyp IN (5,6,7) THEN
|
||||
IF TREAT(M(a) AS mal_str_type).val_str IS NULL AND
|
||||
TREAT(M(b) AS mal_str_type).val_str IS NULL THEN
|
||||
RETURN TRUE;
|
||||
@ -317,16 +323,26 @@ END;
|
||||
FUNCTION string(M IN OUT NOCOPY mem_type, name varchar) RETURN integer IS
|
||||
BEGIN
|
||||
M.EXTEND();
|
||||
IF LENGTH(name) <= 4000 THEN
|
||||
M(M.COUNT()) := mal_str_type(5, name);
|
||||
ELSE
|
||||
M(M.COUNT()) := mal_long_str_type(6, NULL, name);
|
||||
END IF;
|
||||
RETURN M.COUNT();
|
||||
END;
|
||||
|
||||
FUNCTION string_Q(M IN OUT NOCOPY mem_type, val integer) RETURN boolean IS
|
||||
str varchar2(4000);
|
||||
str CLOB;
|
||||
BEGIN
|
||||
IF M(val).type_id IN (5,6) THEN
|
||||
IF M(val).type_id = 5 THEN
|
||||
str := TREAT(M(val) AS mal_str_type).val_str;
|
||||
IF str IS NULL OR SUBSTR(str, 1, 1) <> chr(127) THEN
|
||||
ELSE
|
||||
str := TREAT(M(val) AS mal_long_str_type).val_long_str;
|
||||
END IF;
|
||||
IF str IS NULL OR
|
||||
str = EMPTY_CLOB() OR
|
||||
SUBSTR(str, 1, 1) <> chr(127) THEN
|
||||
RETURN TRUE;
|
||||
ELSE
|
||||
RETURN FALSE;
|
||||
@ -351,7 +367,7 @@ BEGIN
|
||||
END;
|
||||
|
||||
FUNCTION keyword_Q(M IN OUT NOCOPY mem_type, val integer) RETURN boolean IS
|
||||
str varchar2(4000);
|
||||
str CLOB;
|
||||
BEGIN
|
||||
IF M(val).type_id = 5 THEN
|
||||
str := TREAT(M(val) AS mal_str_type).val_str;
|
||||
|
@ -28,15 +28,15 @@ if [ -z "${SKIP_INIT}" ]; then
|
||||
fi
|
||||
|
||||
# open I/O streams
|
||||
echo -e "BEGIN stream_open(0); stream_open(1); END;\n/" \
|
||||
echo -e "BEGIN io.open(0); io.open(1); END;\n/" \
|
||||
| ${SQLPLUS} >/dev/null
|
||||
|
||||
# Stream from table to stdout
|
||||
(
|
||||
while true; do
|
||||
out="$(echo "SELECT stream_read(1) FROM dual;" \
|
||||
out="$(echo "SELECT io.read(1) FROM dual;" \
|
||||
| ${SQLPLUS} 2>/dev/null)" || break
|
||||
#echo "out: [${out}]"
|
||||
#echo "out: [${out}] (${#out})"
|
||||
echo "${out}"
|
||||
done
|
||||
) &
|
||||
@ -45,7 +45,7 @@ done
|
||||
(
|
||||
[ -r ${RL_HISTORY_FILE} ] && history -r ${RL_HISTORY_FILE}
|
||||
while true; do
|
||||
prompt=$(echo "SELECT stream_wait_rl_prompt(0) FROM dual;" \
|
||||
prompt=$(echo "SELECT io.wait_rl_prompt(0) FROM dual;" \
|
||||
| ${SQLPLUS} 2>/dev/null) || break
|
||||
# Prompt is returned single-quoted because sqlplus trims trailing
|
||||
# whitespace. Remove the single quotes from the beginning and end:
|
||||
@ -62,11 +62,11 @@ while true; do
|
||||
# Escape (double) single quotes per SQL norm
|
||||
line=${line//\'/\'\'}
|
||||
#echo "line: [${line}]"
|
||||
( echo -n "BEGIN stream_writeline('${line}', 0); END;";
|
||||
( echo -n "BEGIN io.writeline('${line}', 0); END;";
|
||||
echo -en "\n/" ) \
|
||||
| ${SQLPLUS} >/dev/null || break
|
||||
done
|
||||
echo -e "BEGIN stream_close(0); stream_close(1); END;\n/" \
|
||||
echo -e "BEGIN io.close(0); io.close(1); END;\n/" \
|
||||
| ${SQLPLUS} > /dev/null
|
||||
) <&0 >&1 &
|
||||
|
||||
@ -78,18 +78,25 @@ while true; do
|
||||
| ${SQLPLUS} 2>/dev/null \
|
||||
| grep -v "^no rows selected")" || break
|
||||
for f in ${files}; do
|
||||
if [ -r ${f} ]; then
|
||||
IFS= read -rd '' content < "${f}"
|
||||
content=${content//\'/\'\'}
|
||||
content=${content//$'\n'/\\n}
|
||||
#content=$(printf "%q" "$(cat ${f})")
|
||||
#content="${content#$}" # strip bash leading $
|
||||
echo "UPDATE file_io SET data = '${content}' WHERE path = '${f}' AND in_or_out = 'in';" \
|
||||
| ${SQLPLUS} >/dev/null
|
||||
else
|
||||
if [ ! -r ${f} ]; then
|
||||
echo "UPDATE file_io SET error = 'Cannot read ''${f}''' WHERE path = '${f}' AND in_or_out = 'in';" \
|
||||
| ${SQLPLUS} >/dev/null
|
||||
continue;
|
||||
fi
|
||||
IFS= read -rd '' content < "${f}"
|
||||
# sqlplus limits lines to 2499 characters so split the update
|
||||
# into chunks of the file ORed together over multiple lines
|
||||
query="UPDATE file_io SET data = TO_CLOB('')"
|
||||
while [ -n "${content}" ]; do
|
||||
chunk="${content:0:2000}"
|
||||
content="${content:${#chunk}}"
|
||||
chunk="${chunk//\'/\'\'}"
|
||||
chunk="${chunk//$'\n'/\\n}"
|
||||
query="${query}"$'\n'" || TO_CLOB('${chunk}')"
|
||||
done
|
||||
query="${query}"$'\n'" WHERE path = '${f}' AND in_or_out = 'in';"
|
||||
echo "${query}" | ${SQLPLUS} > /dev/null
|
||||
#echo "file read: ${f}: ${?}"
|
||||
done
|
||||
sleep 1
|
||||
done
|
||||
@ -112,6 +119,8 @@ else
|
||||
| ${SQLPLUS} > /dev/null
|
||||
res=$?
|
||||
fi
|
||||
echo -e "BEGIN stream_close(0); stream_close(1); END;\n/" \
|
||||
# TODO: fix this
|
||||
sleep 2
|
||||
echo -e "BEGIN io.close(0); io.close(1); END;\n/" \
|
||||
| ${SQLPLUS} > /dev/null
|
||||
exit ${res}
|
||||
|
Loading…
Reference in New Issue
Block a user