PLati: algo core

This commit is contained in:
anon 2023-02-11 15:03:59 +01:00
parent cb84abe4cf
commit e2eb4b6dfa
2 changed files with 185 additions and 70 deletions

185
PLati/algo.pks Normal file
View File

@ -0,0 +1,185 @@
CREATE OR REPLACE PACKAGE algo
CREATE OR REPLACE SUBTYPE ASTRING IS VARCHAR(128);
-- ###
EMPTY_VAL CONSTANT CHAR(1) := '0';
TRUE_ CONSTANT CHAR(4) := 'true';
FALSE_ CONSTANT CHAR(5) := 'false';
-- ###
CREATE OR REPLACE PROCEDURE init;
CREATE OR REPLACE PROCEDURE assign_ (name_ ASTRING, val ASTRING);
CREATE OR REPLACE FUNCTION arref IS ASTRING (s ASTRING);
CREATE OR REPLACE FUNCTION deref_ IS ASTRING (s ASTRING);
CREATE OR REPLACE FUNCTION aint IS INT (s ASTRING);
CREATE OR REPLACE PROCEDURE do_eval (opr1 ASTRING, oper CHAR, opr2 ASTRING);
CREATE OR REPLACE PROCEDURE pop (head INT);
CREATE OR REPLACE PROCEDURE push (head INT);
CREATE OR REPLACE FUNCTION jump IS BOOLEAN (head INT, jmp INT, dest ASTRING, push CHAR);
CREATE OR REPLACE PROCEDURE call_ (head INT, jmp INT, dest ASTRING, is_push BOOLEAN);
END algo;
CREATE OR REPLACE PACKAGE BODY algo AS
CREATE OR REPLACE PROCEDURE init
BEGIN
REPLACE INTO TABLE vars VALUES
('eval', ''),
('ret', ''),
('argv-0', ''),
('argv-1', ''),
('argv-2', ''),
('argv-3', ''),
('argv-4', ''),
('argv-5', ''),
('argv-6', ''),
('argv-7', ''),
('argv-8', ''),
('argv-9', '')
;
END
CREATE OR REPLACE PROCEDURE assign_ (
name_ VARCHAR(128),
val VARCHAR(128)
)
BEGIN
INSERT INTO vars (name_, val);
END
CREATE OR REPLACE FUNCTION arref AS ASTRING (s ASTRING)
DECLARE
p INT;
subs ASTRING;
BEGIN
WHILE TRUE LOOP
p = INSTR(s, '-', -1);
IF p THEN
subs := s.SUBSTR(p);
s := REPLACE(s, subs, deref_(subs));
ELSE
EXIT;
END IF;
END LOOP;
RETURN s;
END;
CREATE OR REPLACE FUNCTION deref_ AS ASTRING (s ASTRING)
varval ASTRING;
BEGIN
s := arref(s);
SELECT value INTO varval FROM vars WHERE name = s;
RETURN varval;
EXCEPTION
WHEN OTHERS THEN
RETURN s;
END;
CREATE OR REPLACE FUNCTION aint AS INT (s ASTRING)
sign_ BOOLEAN := TRUE;
i INT := 0;
buf ASTRING := '';
BEGIN
WHILE TRUE LOOP
CASE SUBSTR(s, i, 1)
WHEN '-' THEN
sign := NOT(XOR(sign, FALSE));
WHEN '+' THEN
sign := NOT(XOR(sign, TRUE));
ELSE
EXIT;
END CASE;
i := i + 1;
END LOOP;
s := REPLACE(s, SUBSTR(s, 0, i));
FOR index IN 0 .. LENGTH(s) LOOP
IF SUBSTR(index, 1) IN ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') THEN
buf := ret + SUBSTR(index, 1);
END IF;
END LOOP;
RETURN TO_NUMBER(buf) * (IF sign_ THEN 1 ELSE -1 END IF);
END;
CREATE OR REPLACE PROCEDURE do_eval (opr1 ASTRING, oper CHAR, opr2 ASTRING)
DECLARE
res ASTRING := '';
BEGIN
CASE oper
WHEN EMPTY_VAL THEN
res := opr1;
WHEN '.' THEN
res := CONCAT(opr1, opr2);
WHEN '-' THEN
res := aint(opr1) - aint(opr2);
ELSE
NULL;
END CASE;
UPDATE vars SET (value, res) WHERE name = 'eval';
END;
CREATE OR REPLACE PROCEDURE pop (head INT)
DECLARE
EMPTY_STACK EXCEPTION;
BEGIN
IF SELECT COUNT(bp) FROM callstack = 1 THEN
RAISE EMPTY_STACK;
END IF
DELETE FROM callstack WHERE rowid = (SELECT MAX(rowid) FROM callstack);
SELECT bp INTO HEAD FROM callstack WHERE rowid = (SELECT MAX(rowid) FROM callstack);
head := head + 1;
END;
CREATE OR REPLACE PROCEDURE push (head INT)
BEGIN
UPDATE callstack SET (bp, head) WHERE rowid = (SELECT MAX(rowid) FROM callstack);
INSERT INTO callstack VALUES (0);
END;
CREATE OR REPLACE FUNCTION jump AS BOOLEAN (head INT, jmp INT, dest ASTRING, push CHAR)
DECLARE
ret BOOLEAN = FALSE;
BEGIN
CASE jmp
WHEN 0 THEN
EXIT;
WHEN 1 THEN
call_(head, dest, (push != EMPTY_VAL));
ret := TRUE;
WHEN 2 THEN
IF SELECT value FROM vars WHERE name = 'eval' = TRUE_ THEN
call_(head, dest, (push != EMPTY_VAL));
ret := TRUE;
END IF;
WHEN 3 THEN
IF SELECT value FROM vars WHERE name = 'eval' = FALSE_ THEN
call_(head, dest, (push != EMPTY_VAL));
ret := TRUE;
END IF;
END CASE;
RETURN ret;
END;
CREATE OR REPLACE PROCEDURE call_ (head INT, jmp INT, dest ASTRING, is_push BOOLEAN)
BEGIN
IF dest = 'return' THEN
pop(head);
RETURN;
END IF;
IF is_push THEN push(head) END IF;
head := TO_NUMBER(deref_(head));
END;
END algo;

View File

@ -1,70 +0,0 @@
CREATE OR REPLACE PROCEDURE init
BEGIN
REPLACE INTO TABLE vars VALUES
('eval', ''),
('ret', ''),
('argv-0', ''),
('argv-1', ''),
('argv-2', ''),
('argv-3', ''),
('argv-4', ''),
('argv-5', ''),
('argv-6', ''),
('argv-7', ''),
('argv-8', ''),
('argv-9', '')
;
END
CREATE OR REPLACE FUNCTION arref AS VARCHAR(128)
BEGIN
NULL;
END
CREATE OR REPLACE FUNCTION deref_ AS VARCHAR(128)
BEGIN
NULL;
END
CREATE OR REPLACE FUNCTION aint AS INT
BEGIN
NULL;
END
CREATE OR REPLACE PROCEDURE do_eval
BEGIN
NULL;
END
CREATE OR REPLACE PROCEDURE pop
DECLARE
EMPTY_STACK EXCEPTION;
BEGIN
IF SELECT COUNT(bp) FROM callstack = 1 THEN
RAISE EMPTY_STACK;
END IF
DELETE FROM TABLE WHERE rowid = (SELECT MAX(rowid) FROM table);
-- head = callstack.top().bp + 1;
END
CREATE OR REPLACE PROCEDURE push
BEGIN
NULL;
-- INSERT INTO
END
CREATE OR REPLACE FUNCTION jump AS BOOLEAN
DECLARE
ret BOOLEAN = FALSE;
BEGIN
NULL;
END
CREATE OR REPLACE PROCEDURE call
BEGIN
NULL;
END