mirror of
https://github.com/sigmasternchen/sql-brainfuck
synced 2025-03-14 23:49:00 +00:00
Add brainfuck interpreter
This commit is contained in:
commit
030d3b13e2
1 changed files with 115 additions and 0 deletions
115
brainfuck.sql
Normal file
115
brainfuck.sql
Normal file
|
@ -0,0 +1,115 @@
|
|||
CREATE TABLE input (
|
||||
input text
|
||||
);
|
||||
|
||||
INSERT INTO input VALUES ('');
|
||||
|
||||
CREATE TABLE program (
|
||||
program text
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO program VALUES ('>++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<+
|
||||
+.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-
|
||||
]<+.$');
|
||||
|
||||
|
||||
WITH RECURSIVE run_state
|
||||
(iteration, input, output, band, band_position, program, program_position, halted) AS (
|
||||
SELECT
|
||||
0,
|
||||
input,
|
||||
''::text,
|
||||
repeat('\000'::text, 10)::bytea,
|
||||
0,
|
||||
program,
|
||||
1,
|
||||
false
|
||||
FROM input
|
||||
CROSS JOIN program
|
||||
UNION ALL
|
||||
SELECT
|
||||
iteration + 1,
|
||||
CASE
|
||||
WHEN substring(program, program_position, 1) = ',' THEN substring(input from 2)
|
||||
ELSE input
|
||||
END,
|
||||
CASE
|
||||
WHEN substring(program, program_position, 1) = '.' THEN output || chr(get_byte(band, band_position))
|
||||
ELSE output
|
||||
END,
|
||||
CASE
|
||||
WHEN substring(program, program_position, 1) = ',' THEN set_byte(band, band_position, ascii(substring(input, 1, 1)))
|
||||
WHEN substring(program, program_position, 1) = '+' THEN set_byte(band, band_position, get_byte(band, band_position) + 1)
|
||||
WHEN substring(program, program_position, 1) = '-' THEN set_byte(band, band_position, get_byte(band, band_position) - 1)
|
||||
ELSE band
|
||||
END,
|
||||
CASE
|
||||
WHEN substring(program, program_position, 1) = '<' THEN band_position - 1
|
||||
WHEN substring(program, program_position, 1) = '>' THEN band_position + 1
|
||||
ELSE band_position
|
||||
END,
|
||||
program,
|
||||
CASE
|
||||
WHEN substring(program, program_position, 1) = '[' THEN
|
||||
CASE
|
||||
WHEN get_byte(band, band_position) = 0 THEN
|
||||
(
|
||||
WITH RECURSIVE forward_search (position, stack, done) AS (
|
||||
SELECT program_position + 1, 0, false
|
||||
UNION ALL
|
||||
SELECT
|
||||
position + 1,
|
||||
CASE
|
||||
WHEN substring(program, position, 1) = '[' THEN stack + 1
|
||||
WHEN substring(program, position, 1) = ']' THEN stack - 1
|
||||
ELSE stack
|
||||
END,
|
||||
substring(program, position, 1) = ']' AND stack = 0
|
||||
FROM forward_search
|
||||
WHERE NOT done
|
||||
)
|
||||
SELECT position
|
||||
FROM forward_search
|
||||
WHERE done
|
||||
)
|
||||
ELSE program_position + 1
|
||||
END
|
||||
WHEN substring(program, program_position, 1) = ']' THEN
|
||||
CASE
|
||||
WHEN get_byte(band, band_position) = 0 THEN program_position + 1
|
||||
ELSE
|
||||
(
|
||||
WITH RECURSIVE backward_search (position, stack, done) AS (
|
||||
SELECT program_position - 1, 0, false
|
||||
UNION ALL
|
||||
SELECT
|
||||
position - 1,
|
||||
CASE
|
||||
WHEN substring(program, position, 1) = ']' THEN stack + 1
|
||||
WHEN substring(program, position, 1) = '[' THEN stack - 1
|
||||
ELSE stack
|
||||
END,
|
||||
substring(program, position, 1) = '[' AND stack = 0
|
||||
FROM backward_search
|
||||
WHERE NOT done
|
||||
)
|
||||
SELECT position + 2
|
||||
FROM backward_search
|
||||
WHERE done
|
||||
)
|
||||
END
|
||||
ELSE program_position + 1
|
||||
END,
|
||||
substring(program, program_position, 1) = '$'
|
||||
FROM run_state
|
||||
WHERE NOT halted
|
||||
)
|
||||
SELECT iteration, output
|
||||
FROM run_state
|
||||
WHERE halted
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue