├── BrainFuck.sql └── README.md /BrainFuck.sql: -------------------------------------------------------------------------------- 1 | -- Brain Fuck interpreter in SQL 2 | 3 | DECLARE @Code VARCHAR(MAX) = ', [>,] < [.<]'; 4 | DECLARE @Input VARCHAR(MAX) = '!dlroW olleH'; 5 | 6 | -- Creates a "BrainFuck" DataBase. 7 | -- CREATE DATABASE BrainFuck; 8 | 9 | -- Creates the Source code table. 10 | DECLARE @CodeTable TABLE ( 11 | [Id] INT IDENTITY(1,1) PRIMARY KEY NOT NULL, 12 | [Command] CHAR(1) NOT NULL 13 | ); 14 | 15 | -- Populates the source code into the CodeTable. 16 | DECLARE @CodeLen INT = LEN(@Code); 17 | DECLARE @CodePos INT = 0; 18 | DECLARE @CodeChar CHAR(1); 19 | 20 | WHILE @CodePos < @CodeLen 21 | BEGIN 22 | SET @CodePos = @CodePos + 1; 23 | SET @CodeChar = SUBSTRING(@Code, @CodePos, 1); 24 | IF @CodeChar IN ('+', '-', '>', '<', ',', '.', '[', ']') 25 | INSERT INTO @CodeTable ([Command]) VALUES (@CodeChar) 26 | END 27 | 28 | -- Creates the Input table. 29 | DECLARE @InputTable TABLE ( 30 | [Id] INT IDENTITY(1,1) PRIMARY KEY NOT NULL, 31 | [Char] CHAR(1) NOT NULL 32 | ); 33 | 34 | -- Populates the input text into the InputTable. 35 | DECLARE @InputLen INT = LEN(@Input); 36 | DECLARE @InputPos INT = 0; 37 | 38 | WHILE @InputPos < @InputLen 39 | BEGIN 40 | SET @InputPos = @InputPos + 1; 41 | INSERT INTO @InputTable ([Char]) 42 | VALUES (SUBSTRING(@Input, @InputPos, 1)) 43 | END 44 | 45 | -- Creates the Output table. 46 | DECLARE @OutputTable TABLE ( 47 | [Id] INT IDENTITY(1,1) PRIMARY KEY NOT NULL, 48 | [Char] CHAR(1) NOT NULL 49 | ); 50 | 51 | -- Creates the Buffer table. 52 | DECLARE @BufferTable TABLE ( 53 | [Id] INT IDENTITY(1,1) PRIMARY KEY NOT NULL, 54 | [Memory] INT DEFAULT 0 NOT NULL 55 | ); 56 | INSERT INTO @BufferTable ([Memory]) 57 | VALUES (0); 58 | 59 | DECLARE @CodeLength INT = (SELECT COUNT(*) FROM @CodeTable); 60 | DECLARE @CodeIndex INT = 0; 61 | DECLARE @Pointer INT = 1; 62 | DECLARE @InputIndex INT = 0; 63 | DECLARE @Command CHAR(1); 64 | DECLARE @Depth INT; 65 | 66 | WHILE @CodeIndex < @CodeLength 67 | BEGIN 68 | -- Read the next command. 69 | SET @CodeIndex = @CodeIndex + 1; 70 | SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex); 71 | 72 | -- Increment the pointer. 73 | IF @Command = '>' 74 | BEGIN 75 | SET @Pointer = @Pointer + 1; 76 | IF (SELECT [Id] FROM @BufferTable WHERE [Id] = @Pointer) IS NULL 77 | INSERT INTO @BufferTable ([Memory]) VALUES (0); 78 | END 79 | 80 | -- Decrement the pointer. 81 | ELSE IF @Command = '<' 82 | SET @Pointer = @Pointer - 1; 83 | 84 | -- Increment the byte at the pointer. 85 | ELSE IF @Command = '+' 86 | UPDATE @BufferTable SET [Memory] = [Memory] + 1 WHERE [Id] = @Pointer; 87 | 88 | -- Decrement the byte at the pointer. 89 | ELSE IF @Command = '-' 90 | UPDATE @BufferTable SET [Memory] = [Memory] - 1 WHERE [Id] = @Pointer; 91 | 92 | -- Output the byte at the pointer. 93 | ELSE IF @Command = '.' 94 | INSERT INTO @OutputTable ([Char]) (SELECT CHAR([Memory]) FROM @BufferTable WHERE [Id] = @Pointer); 95 | 96 | -- Input a byte and store it in the byte at the pointer. 97 | ELSE IF @Command = ',' 98 | BEGIN 99 | SET @InputIndex = @InputIndex + 1; 100 | UPDATE @BufferTable SET [Memory] = COALESCE((SELECT ASCII([Char]) FROM @InputTable WHERE [Id] = @InputIndex), 0) WHERE [Id] = @Pointer; 101 | END 102 | 103 | -- Jump forward past the matching ] if the byte at the pointer is zero. 104 | ELSE IF @Command = '[' AND COALESCE((SELECT [Memory] FROM @BufferTable WHERE [Id] = @Pointer), 0) = 0 105 | BEGIN 106 | SET @Depth = 1; 107 | WHILE @Depth > 0 108 | BEGIN 109 | SET @CodeIndex = @CodeIndex + 1; 110 | SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex); 111 | IF @Command = '[' SET @Depth = @Depth + 1; 112 | ELSE IF @Command = ']' SET @Depth = @Depth - 1; 113 | END 114 | END 115 | 116 | -- Jump backward to the matching [ unless the byte at the pointer is zero. 117 | ELSE IF @Command = ']' AND COALESCE((SELECT [Memory] FROM @BufferTable WHERE [Id] = @Pointer), 0) != 0 118 | BEGIN 119 | SET @Depth = 1; 120 | WHILE @Depth > 0 121 | BEGIN 122 | SET @CodeIndex = @CodeIndex - 1; 123 | SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex); 124 | IF @Command = ']' SET @Depth = @Depth + 1; 125 | ELSE IF @Command = '[' SET @Depth = @Depth - 1; 126 | END 127 | END 128 | END; 129 | 130 | DECLARE @Output VARCHAR(MAX); 131 | SELECT @Output = COALESCE(@Output, '') + [Char] 132 | FROM @OutputTable; 133 | 134 | PRINT @Output; 135 | Go 136 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BrainFuck-SQL 2 | BrainFuck Interpreter in SQL 3 | 4 | Developer: Forex Software Ltd https://forexsb.com 5 | 6 | This code uses only memory variables and tables. It doesn't modify the database. You can connect it to any MS SQL DB. 7 | 8 | ![BrainFuck in LinkPad](https://image-holder.forexsb.com/store/BrainFuck-interpretter-in-SQL.png) 9 | 10 | 11 | 12 | Modification: 13 | 14 | - Set your BrainFuck code in line 3. 15 | - Set your input in line 4. 16 | 17 | --------------------------------------------------------------------------------