PLati: algo compiles
This commit is contained in:
parent
fd57b438be
commit
71e2027ab8
124
PLati/algo.pks
124
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user