From e2eb4b6dfaedb86807871755db7473191adf2f0f Mon Sep 17 00:00:00 2001 From: anon Date: Sat, 11 Feb 2023 15:03:59 +0100 Subject: [PATCH] PLati: algo core --- PLati/algo.pks | 185 +++++++++++++++++++++++++++++++++++++++++++++++++ PLati/algo.pls | 70 ------------------- 2 files changed, 185 insertions(+), 70 deletions(-) create mode 100644 PLati/algo.pks delete mode 100644 PLati/algo.pls diff --git a/PLati/algo.pks b/PLati/algo.pks new file mode 100644 index 0000000..2549430 --- /dev/null +++ b/PLati/algo.pks @@ -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; diff --git a/PLati/algo.pls b/PLati/algo.pls deleted file mode 100644 index 79ff2f3..0000000 --- a/PLati/algo.pls +++ /dev/null @@ -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