Skip to content

Commit

Permalink
plpgsql: merge macroexpand into EVAL, add DEBUG-EVAL
Browse files Browse the repository at this point in the history
  • Loading branch information
asarhaddon committed Oct 24, 2024
1 parent ac666a1 commit 276634e
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 205 deletions.
8 changes: 1 addition & 7 deletions impls/plpgsql/envs.sql
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,9 @@ BEGIN
e := envs.find(env, symkey);
--RAISE NOTICE 'envs.find env: %, symkey: % -> e: %', env, symkey, e;
IF e IS NULL THEN
RAISE EXCEPTION '''%'' not found', symkey;
RETURN NULL;
ELSE
SELECT data -> symkey INTO result FROM envs.env WHERE env_id = e;
END IF;
RETURN result;
END; $$ LANGUAGE plpgsql;

-- envs.get
CREATE FUNCTION envs.get(env integer, key integer) RETURNS integer AS $$
BEGIN
RETURN envs.vget(env, types._valueToString(key));
END; $$ LANGUAGE plpgsql;
13 changes: 8 additions & 5 deletions impls/plpgsql/step2_eval.sql
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ BEGIN
RAISE EXCEPTION '''%'' not found', symkey;
END IF;
END;
WHEN type IN (8, 9) THEN
WHEN type = 9 THEN
BEGIN
SELECT val_seq INTO seq FROM types.value WHERE value_id = ast;
-- Evaluate each entry creating a new sequence
Expand Down Expand Up @@ -76,7 +76,7 @@ END; $$ LANGUAGE plpgsql;
CREATE FUNCTION mal.EVAL(ast integer, env hstore) RETURNS integer AS $$
DECLARE
type integer;
el integer;
a0 integer;
fname varchar;
args integer[];
result integer;
Expand All @@ -89,10 +89,13 @@ BEGIN
RETURN ast;
END IF;

el := mal.eval_ast(ast, env);
a0 := types._first(ast);
a0 := mal.EVAL(a0, env);
SELECT val_string INTO fname FROM types.value
WHERE value_id = types._first(el);
args := types._restArray(el);
WHERE value_id = a0;
FOR i in 0 .. types._count(ast) - 2 LOOP
args[i] := mal.EVAL(types._nth(ast, i+1), env);
END LOOP;
EXECUTE format('SELECT %s($1);', fname) INTO result USING args;
RETURN result;
END; $$ LANGUAGE plpgsql;
Expand Down
28 changes: 21 additions & 7 deletions impls/plpgsql/step3_env.sql
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ END; $$ LANGUAGE plpgsql;
CREATE FUNCTION mal.eval_ast(ast integer, env integer) RETURNS integer AS $$
DECLARE
type integer;
symkey varchar;
seq integer[];
eseq integer[];
hash hstore;
Expand All @@ -34,9 +35,13 @@ BEGIN
CASE
WHEN type = 7 THEN
BEGIN
result := envs.get(env, ast);
symkey := types._valueToString(ast);
result := envs.vget(env, symkey);
IF result IS NULL THEN
RAISE EXCEPTION '''%'' not found', symkey;
END IF;
END;
WHEN type IN (8, 9) THEN
WHEN type = 9 THEN
BEGIN
SELECT val_seq INTO seq FROM types.value WHERE value_id = ast;
-- Evaluate each entry creating a new sequence
Expand Down Expand Up @@ -77,12 +82,19 @@ DECLARE
let_env integer;
idx integer;
binds integer[];
el integer;
fname varchar;
args integer[];
cond integer;
result integer;
BEGIN
-- PERFORM writeline(format('EVAL: %s [%s]', pr_str(ast), ast));
cond := envs.vget(env, 'DEBUG-EVAL');
IF cond IS NOT NULL THEN
SELECT type_id INTO cond FROM types.value WHERE value_id = cond;
IF cond NOT IN (0, 1) THEN
PERFORM io.writeline(format('EVAL: %s [%s]', mal.PRINT(ast), ast));
END IF;
END IF;

SELECT type_id INTO type FROM types.value WHERE value_id = ast;
IF type <> 8 THEN
RETURN mal.eval_ast(ast, env);
Expand Down Expand Up @@ -119,10 +131,12 @@ BEGIN
END;
ELSE
BEGIN
el := mal.eval_ast(ast, env);
a0 := mal.EVAL(a0, env);
SELECT val_string INTO fname FROM types.value
WHERE value_id = types._first(el);
args := types._restArray(el);
WHERE value_id = a0;
FOR i in 0 .. types._count(ast) - 2 LOOP
args[i] := mal.EVAL(types._nth(ast, i+1), env);
END LOOP;
EXECUTE format('SELECT %s($1);', fname)
INTO result USING args;
RETURN result;
Expand Down
35 changes: 25 additions & 10 deletions impls/plpgsql/step4_if_fn_do.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ END; $$ LANGUAGE plpgsql;
CREATE FUNCTION mal.eval_ast(ast integer, env integer) RETURNS integer AS $$
DECLARE
type integer;
symkey varchar;
seq integer[];
eseq integer[];
hash hstore;
Expand All @@ -35,9 +36,13 @@ BEGIN
CASE
WHEN type = 7 THEN
BEGIN
result := envs.get(env, ast);
symkey := types._valueToString(ast);
result := envs.vget(env, symkey);
IF result IS NULL THEN
RAISE EXCEPTION '''%'' not found', symkey;
END IF;
END;
WHEN type IN (8, 9) THEN
WHEN type = 9 THEN
BEGIN
SELECT val_seq INTO seq FROM types.value WHERE value_id = ast;
-- Evaluate each entry creating a new sequence
Expand Down Expand Up @@ -78,8 +83,7 @@ DECLARE
let_env integer;
idx integer;
binds integer[];
el integer;
fn integer;
ignored integer;
fname varchar;
args integer[];
cond integer;
Expand All @@ -88,7 +92,14 @@ DECLARE
fenv integer;
result integer;
BEGIN
-- PERFORM writeline(format('EVAL: %s [%s]', pr_str(ast), ast));
cond := envs.vget(env, 'DEBUG-EVAL');
IF cond IS NOT NULL THEN
SELECT type_id INTO cond FROM types.value WHERE value_id = cond;
IF cond NOT IN (0, 1) THEN
PERFORM io.writeline(format('EVAL: %s [%s]', mal.PRINT(ast), ast));
END IF;
END IF;

SELECT type_id INTO type FROM types.value WHERE value_id = ast;
IF type <> 8 THEN
RETURN mal.eval_ast(ast, env);
Expand Down Expand Up @@ -125,8 +136,10 @@ BEGIN
END;
WHEN a0sym = 'do' THEN
BEGIN
el := mal.eval_ast(types._rest(ast), env);
RETURN types._nth(el, types._count(el)-1);
FOR i IN 1 .. types._count(ast) - 2 LOOP
ignored := mal.EVAL(types._nth(ast, i), env);
END LOOP;
RETURN mal.EVAL(types._nth(ast, types._count(ast)-1), env);
END;
WHEN a0sym = 'if' THEN
BEGIN
Expand All @@ -148,11 +161,13 @@ BEGIN
END;
ELSE
BEGIN
el := mal.eval_ast(ast, env);
a0 := mal.EVAL(a0, env);
SELECT type_id, val_string, ast_id, params_id, env_id
INTO type, fname, fast, fparams, fenv
FROM types.value WHERE value_id = types._first(el);
args := types._restArray(el);
FROM types.value WHERE value_id = a0;
FOR i in 0 .. types._count(ast) - 2 LOOP
args[i] := mal.EVAL(types._nth(ast, i+1), env);
END LOOP;
IF type = 11 THEN
EXECUTE format('SELECT %s($1);', fname)
INTO result USING args;
Expand Down
34 changes: 25 additions & 9 deletions impls/plpgsql/step5_tco.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ END; $$ LANGUAGE plpgsql;
CREATE FUNCTION mal.eval_ast(ast integer, env integer) RETURNS integer AS $$
DECLARE
type integer;
symkey varchar;
seq integer[];
eseq integer[];
hash hstore;
Expand All @@ -35,9 +36,13 @@ BEGIN
CASE
WHEN type = 7 THEN
BEGIN
result := envs.get(env, ast);
symkey := types._valueToString(ast);
result := envs.vget(env, symkey);
IF result IS NULL THEN
RAISE EXCEPTION '''%'' not found', symkey;
END IF;
END;
WHEN type IN (8, 9) THEN
WHEN type = 9 THEN
BEGIN
SELECT val_seq INTO seq FROM types.value WHERE value_id = ast;
-- Evaluate each entry creating a new sequence
Expand Down Expand Up @@ -78,8 +83,7 @@ DECLARE
let_env integer;
idx integer;
binds integer[];
el integer;
fn integer;
ignored integer;
fname varchar;
args integer[];
cond integer;
Expand All @@ -89,7 +93,15 @@ DECLARE
result integer;
BEGIN
LOOP
-- PERFORM writeline(format('EVAL: %s [%s]', pr_str(ast), ast));

cond := envs.vget(env, 'DEBUG-EVAL');
IF cond IS NOT NULL THEN
SELECT type_id INTO cond FROM types.value WHERE value_id = cond;
IF cond NOT IN (0, 1) THEN
PERFORM io.writeline(format('EVAL: %s [%s]', mal.PRINT(ast), ast));
END IF;
END IF;

SELECT type_id INTO type FROM types.value WHERE value_id = ast;
IF type <> 8 THEN
RETURN mal.eval_ast(ast, env);
Expand Down Expand Up @@ -128,7 +140,9 @@ BEGIN
END;
WHEN a0sym = 'do' THEN
BEGIN
PERFORM mal.eval_ast(types._slice(ast, 1, types._count(ast)-1), env);
FOR i IN 1 .. types._count(ast) - 2 LOOP
ignored := mal.EVAL(types._nth(ast, i), env);
END LOOP;
ast := types._nth(ast, types._count(ast)-1);
CONTINUE; -- TCO
END;
Expand All @@ -154,11 +168,13 @@ BEGIN
END;
ELSE
BEGIN
el := mal.eval_ast(ast, env);
a0 := mal.EVAL(a0, env);
SELECT type_id, val_string, ast_id, params_id, env_id
INTO type, fname, fast, fparams, fenv
FROM types.value WHERE value_id = types._first(el);
args := types._restArray(el);
FROM types.value WHERE value_id = a0;
FOR i in 0 .. types._count(ast) - 2 LOOP
args[i] := mal.EVAL(types._nth(ast, i+1), env);
END LOOP;
IF type = 11 THEN
EXECUTE format('SELECT %s($1);', fname)
INTO result USING args;
Expand Down
34 changes: 25 additions & 9 deletions impls/plpgsql/step6_file.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ END; $$ LANGUAGE plpgsql;
CREATE FUNCTION mal.eval_ast(ast integer, env integer) RETURNS integer AS $$
DECLARE
type integer;
symkey varchar;
seq integer[];
eseq integer[];
hash hstore;
Expand All @@ -35,9 +36,13 @@ BEGIN
CASE
WHEN type = 7 THEN
BEGIN
result := envs.get(env, ast);
symkey := types._valueToString(ast);
result := envs.vget(env, symkey);
IF result IS NULL THEN
RAISE EXCEPTION '''%'' not found', symkey;
END IF;
END;
WHEN type IN (8, 9) THEN
WHEN type = 9 THEN
BEGIN
SELECT val_seq INTO seq FROM types.value WHERE value_id = ast;
-- Evaluate each entry creating a new sequence
Expand Down Expand Up @@ -78,8 +83,7 @@ DECLARE
let_env integer;
idx integer;
binds integer[];
el integer;
fn integer;
ignored integer;
fname varchar;
args integer[];
cond integer;
Expand All @@ -89,7 +93,15 @@ DECLARE
result integer;
BEGIN
LOOP
-- PERFORM writeline(format('EVAL: %s [%s]', pr_str(ast), ast));

cond := envs.vget(env, 'DEBUG-EVAL');
IF cond IS NOT NULL THEN
SELECT type_id INTO cond FROM types.value WHERE value_id = cond;
IF cond NOT IN (0, 1) THEN
PERFORM io.writeline(format('EVAL: %s [%s]', mal.PRINT(ast), ast));
END IF;
END IF;

SELECT type_id INTO type FROM types.value WHERE value_id = ast;
IF type <> 8 THEN
RETURN mal.eval_ast(ast, env);
Expand Down Expand Up @@ -128,7 +140,9 @@ BEGIN
END;
WHEN a0sym = 'do' THEN
BEGIN
PERFORM mal.eval_ast(types._slice(ast, 1, types._count(ast)-1), env);
FOR i IN 1 .. types._count(ast) - 2 LOOP
ignored := mal.EVAL(types._nth(ast, i), env);
END LOOP;
ast := types._nth(ast, types._count(ast)-1);
CONTINUE; -- TCO
END;
Expand All @@ -154,11 +168,13 @@ BEGIN
END;
ELSE
BEGIN
el := mal.eval_ast(ast, env);
a0 := mal.EVAL(a0, env);
SELECT type_id, val_string, ast_id, params_id, env_id
INTO type, fname, fast, fparams, fenv
FROM types.value WHERE value_id = types._first(el);
args := types._restArray(el);
FROM types.value WHERE value_id = a0;
FOR i in 0 .. types._count(ast) - 2 LOOP
args[i] := mal.EVAL(types._nth(ast, i+1), env);
END LOOP;
IF type = 11 THEN
EXECUTE format('SELECT %s($1);', fname)
INTO result USING args;
Expand Down
Loading

0 comments on commit 276634e

Please sign in to comment.