7 -- ---------------------------------------------------------
8 -- step1_read_print.sql
11 CREATE FUNCTION READ(line
varchar)
14 RETURN read_str(line
);
15 END; $$
LANGUAGE plpgsql
;
18 CREATE FUNCTION eval_ast(ast
integer, env hstore
)
31 SELECT type_id
INTO type FROM value WHERE value_id
= ast
;
35 symkey
:= _valueToString(ast
);
37 result := env
-> symkey
;
39 RAISE
EXCEPTION '''%'' not found', symkey
;
42 WHEN type IN (8, 9) THEN
44 SELECT val_seq
INTO seq
FROM value WHERE value_id
= ast
;
45 -- Evaluate each entry creating a new sequence
46 FOR i
IN 1 ..
COALESCE(array_length(seq
, 1), 0) LOOP
47 eseq
[i
] := EVAL(seq
[i
], env
);
49 INSERT INTO value (type_id
, val_seq
) VALUES (type, eseq
)
50 RETURNING value_id
INTO result;
54 SELECT val_hash
INTO hash
FROM value WHERE value_id
= ast
;
55 -- Evaluate each value for every key/value
56 FOR kv
IN SELECT * FROM each(hash
) LOOP
57 e
:= EVAL(CAST(kv.
value AS integer), env
);
59 ehash
:= hstore(kv.
key, CAST(e
AS varchar));
61 ehash
:= ehash ||
hstore(kv.
key, CAST(e
AS varchar));
64 INSERT INTO value (type_id
, val_hash
) VALUES (type, ehash
)
65 RETURNING value_id
INTO result;
72 END; $$
LANGUAGE plpgsql
;
74 CREATE FUNCTION EVAL(ast
integer, env hstore
)
83 SELECT type_id
INTO type FROM value WHERE value_id
= ast
;
85 RETURN eval_ast(ast
, env
);
88 el
:= eval_ast(ast
, env
);
89 SELECT val_string
INTO fname
FROM value WHERE value_id
= _first(el
);
90 args
:= _restArray(el
);
91 EXECUTE format('SELECT %s($1);', fname
) INTO result USING args
;
93 END; $$
LANGUAGE plpgsql
;
96 CREATE FUNCTION PRINT(exp integer)
100 END; $$
LANGUAGE plpgsql
;
105 CREATE FUNCTION mal_intop(op
varchar, args
integer[])
106 RETURNS integer AS $$
107 DECLARE a
integer; b
integer; result integer;
109 SELECT val_int
INTO a
FROM value WHERE value_id
= args
[1];
110 SELECT val_int
INTO b
FROM value WHERE value_id
= args
[2];
111 EXECUTE format('INSERT INTO value (type_id, val_int) VALUES (3, $1 %s $2)
112 RETURNING value_id;', op
) INTO result USING a
, b
;
114 END; $$
LANGUAGE plpgsql
;
116 CREATE FUNCTION mal_add(args
integer[]) RETURNS integer AS $$
117 BEGIN RETURN mal_intop('+', args
); END; $$
LANGUAGE plpgsql
;
118 CREATE FUNCTION mal_subtract(args
integer[]) RETURNS integer AS $$
119 BEGIN RETURN mal_intop('-', args
); END; $$
LANGUAGE plpgsql
;
120 CREATE FUNCTION mal_multiply(args
integer[]) RETURNS integer AS $$
121 BEGIN RETURN mal_intop('*', args
); END; $$
LANGUAGE plpgsql
;
122 CREATE FUNCTION mal_divide(args
integer[]) RETURNS integer AS $$
123 BEGIN RETURN mal_intop('/', args
); END; $$
LANGUAGE plpgsql
;
126 CREATE FUNCTION REP(env hstore
, line
varchar)
127 RETURNS varchar AS $$
129 RETURN PRINT(EVAL(READ(line
), env
));
130 END; $$
LANGUAGE plpgsql
;
132 CREATE FUNCTION MAIN_LOOP(pwd
varchar)
133 RETURNS integer AS $$
139 repl_env
:= hstore(ARRAY[
140 '+', _function('mal_add'),
141 '-', _function('mal_subtract'),
142 '*', _function('mal_multiply'),
143 '/', _function('mal_divide')]);
146 line
:= readline('user> ', 0);
147 IF line
IS NULL THEN RETURN 0; END IF;
149 output := REP(repl_env
, line
);
150 PERFORM
writeline(output);
153 EXCEPTION WHEN OTHERS THEN
154 PERFORM
writeline('Error: ' || SQLERRM
);
157 END; $$
LANGUAGE plpgsql
;