commit 030d3b13e22e9aa1af5e76470019c7c0c20323af Author: Sigma Date: Tue Sep 17 22:30:15 2024 +0200 Add brainfuck interpreter diff --git a/brainfuck.sql b/brainfuck.sql new file mode 100644 index 0000000..b624cc3 --- /dev/null +++ b/brainfuck.sql @@ -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 + + + + +