From 71e2027ab8dab5ceb87982b95436dedd855e778e Mon Sep 17 00:00:00 2001 From: anon <anon@anon.anon> Date: Mon, 13 Feb 2023 13:39:26 +0100 Subject: [PATCH] PLati: algo compiles --- PLati/algo.pks | 124 +++++++++++++++++++++++++------------------------ 1 file changed, 63 insertions(+), 61 deletions(-) diff --git a/PLati/algo.pks b/PLati/algo.pks index a5dcb5b..3253625 100644 --- a/PLati/algo.pks +++ b/PLati/algo.pks @@ -15,73 +15,72 @@ CREATE OR REPLACE PACKAGE algo AS PROCEDURE do_eval (opr1 ASTRING, oper CHAR, opr2 ASTRING); - PROCEDURE pop (head INT); - PROCEDURE push (head INT); + PROCEDURE pop (head IN OUT INT); + PROCEDURE push (head IN OUT INT); - FUNCTION jump (head INT, jmp INT, dest ASTRING, push CHAR) RETURN BOOLEAN; - PROCEDURE call_ (head INT, jmp INT, dest ASTRING, is_push BOOLEAN); + FUNCTION jump (head IN OUT INT, jmp INT, dest ASTRING, push CHAR) RETURN BOOLEAN; + PROCEDURE call_ (head IN OUT INT, dest ASTRING, is_push BOOLEAN); END; / CREATE OR REPLACE PACKAGE BODY algo AS PROCEDURE init IS 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', '') - ; + INSERT INTO vars VALUES ('eval', ''); + INSERT INTO vars VALUES ('ret', ''); + INSERT INTO vars VALUES ('argv-0', ''); + INSERT INTO vars VALUES ('argv-1', ''); + INSERT INTO vars VALUES ('argv-2', ''); + INSERT INTO vars VALUES ('argv-3', ''); + INSERT INTO vars VALUES ('argv-4', ''); + INSERT INTO vars VALUES ('argv-5', ''); + INSERT INTO vars VALUES ('argv-6', ''); + INSERT INTO vars VALUES ('argv-7', ''); + INSERT INTO vars VALUES ('argv-8', ''); + INSERT INTO vars VALUES ('argv-9', ''); END; PROCEDURE assign_ ( - name_ VARCHAR(128), - val VARCHAR(128) + name_ ASTRING, + val ASTRING ) IS BEGIN - INSERT INTO vars (name_, val); + INSERT INTO vars VALUES (name_, val); END; - FUNCTION arref AS ASTRING (s ASTRING) - DECLARE + FUNCTION arref (s ASTRING) RETURN ASTRING AS p INT; subs ASTRING; + s_ ASTRING := s; BEGIN WHILE TRUE LOOP - p = INSTR(s, '-', -1); - IF p THEN - subs := s.SUBSTR(p); - s := REPLACE(s, subs, deref_(subs)); + p := INSTR(s_, '-', -1); + IF p != 0 THEN + subs := SUBSTR(s_, p); + s_ := REPLACE(s_, subs, deref_(subs)); ELSE EXIT; END IF; END LOOP; - RETURN s; + RETURN s_; END; - FUNCTION deref_ AS ASTRING (s ASTRING) + FUNCTION deref_ (s ASTRING) RETURN ASTRING AS varval ASTRING; + s_ ASTRING := s; BEGIN - s := arref(s); - SELECT value INTO varval FROM vars WHERE name = s; + s_ := arref(s_); + SELECT value INTO varval FROM vars WHERE name = s_; RETURN varval; EXCEPTION WHEN OTHERS THEN - RETURN s; + RETURN s_; END; - FUNCTION aint AS INT (s ASTRING) + FUNCTION aint (s ASTRING) RETURN INT AS sign_ BOOLEAN := TRUE; i INT := 0; buf ASTRING := ''; @@ -89,30 +88,31 @@ CREATE OR REPLACE PACKAGE BODY algo AS WHILE TRUE LOOP CASE SUBSTR(s, i, 1) WHEN '-' THEN - sign := NOT(XOR(sign, FALSE)); + sign_ := NOT(XOR(sign_, FALSE)); WHEN '+' THEN - sign := NOT(XOR(sign, TRUE)); + 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); + FOR h IN i .. LENGTH(s) LOOP + IF SUBSTR(s, i, 1) IN ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') THEN + buf := buf + SUBSTR(s, h+i, 1); END IF; END LOOP; - RETURN TO_NUMBER(buf) * (IF sign_ THEN 1 ELSE -1 END IF); + IF sign_ THEN + RETURN TO_NUMBER(buf) * 1; + ELSE + RETURN TO_NUMBER(buf) * -1; + END IF; END; - PROCEDURE do_eval (opr1 ASTRING, oper CHAR, opr2 ASTRING) - DECLARE + PROCEDURE do_eval (opr1 ASTRING, oper CHAR, opr2 ASTRING) AS res ASTRING := ''; BEGIN CASE oper @@ -120,66 +120,68 @@ CREATE OR REPLACE PACKAGE BODY algo AS res := opr1; WHEN '.' THEN res := CONCAT(opr1, opr2); - WHEN '-' THEN - res := aint(opr1) - aint(opr2); + -- #placeholder<oper> ELSE NULL; END CASE; - UPDATE vars SET (value, res) WHERE name = 'eval'; + UPDATE vars SET value = res WHERE name = 'eval'; END; - PROCEDURE pop (head INT) - DECLARE + PROCEDURE pop (head IN OUT INT) AS EMPTY_STACK EXCEPTION; + cbp INT; BEGIN - IF SELECT COUNT(bp) FROM callstack = 1 THEN + SELECT COUNT(bp) INTO cbp FROM callstack; + IF cbp = 1 THEN RAISE EMPTY_STACK; - END IF + 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); + SELECT bp INTO head FROM callstack WHERE rowid = (SELECT MAX(rowid) FROM callstack); head := head + 1; END; - PROCEDURE push (head INT) + PROCEDURE push (head IN OUT INT) AS BEGIN - UPDATE callstack SET (bp, head) WHERE rowid = (SELECT MAX(rowid) FROM callstack); + UPDATE callstack SET bp = head WHERE rowid = (SELECT MAX(rowid) FROM callstack); INSERT INTO callstack VALUES (0); END; - FUNCTION jump AS BOOLEAN (head INT, jmp INT, dest ASTRING, push CHAR) - DECLARE - ret BOOLEAN = FALSE; + FUNCTION jump (head IN OUT INT, jmp INT, dest ASTRING, push CHAR) RETURN BOOLEAN AS + ret BOOLEAN := FALSE; + evalval ASTRING; BEGIN CASE jmp WHEN 0 THEN - EXIT; + NULL; WHEN 1 THEN call_(head, dest, (push != EMPTY_VAL)); ret := TRUE; WHEN 2 THEN - IF SELECT value FROM vars WHERE name = 'eval' = TRUE_ THEN + SELECT value INTO evalval FROM vars WHERE name = 'eval'; + IF evalval = 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 + SELECT value INTO evalval FROM vars WHERE name = 'eval'; + IF evalval = FALSE_ THEN call_(head, dest, (push != EMPTY_VAL)); ret := TRUE; END IF; END CASE; RETURN ret; END; - PROCEDURE call_ (head INT, jmp INT, dest ASTRING, is_push BOOLEAN) + PROCEDURE call_ (head IN OUT INT, dest ASTRING, is_push BOOLEAN) AS BEGIN IF dest = 'return' THEN pop(head); RETURN; END IF; - IF is_push THEN push(head) END IF; + IF is_push THEN push(head); END IF; head := TO_NUMBER(deref_(head)); END;