diff --git a/examples/gno.land/p/demo/bf/bf.gno b/examples/gno.land/p/demo/bf/bf.gno new file mode 100644 index 00000000000..83fed3436d6 --- /dev/null +++ b/examples/gno.land/p/demo/bf/bf.gno @@ -0,0 +1,74 @@ +package bf + +import ( + "strings" +) + +const maxlen = 30000 + +func Execute(code string) string { + var ( + memory = make([]byte, maxlen) // memory tape + pointer = 0 // initial memory pointer + buf strings.Builder + ) + + // Loop through each character in the code + for i := 0; i < len(code); i++ { + switch code[i] { + case '>': + // Increment memory pointer + pointer++ + if pointer >= maxlen { + pointer = 0 + } + case '<': + // Decrement memory pointer + pointer-- + if pointer < 0 { + pointer = maxlen - 1 + } + case '+': + // Increment the byte at the memory pointer + memory[pointer]++ + case '-': + // Decrement the byte at the memory pointer + memory[pointer]-- + case '.': + // Output the byte at the memory pointer + buf.WriteByte(memory[pointer]) + case ',': + // Input a byte and store it in the memory + panic("unsupported") + // fmt.Scan(&memory[pointer]) + case '[': + // Jump forward past the matching ']' if the byte at the memory pointer is zero + if memory[pointer] == 0 { + braceCount := 1 + for braceCount > 0 { + i++ + if code[i] == '[' { + braceCount++ + } else if code[i] == ']' { + braceCount-- + } + } + } + case ']': + // Jump backward to the matching '[' if the byte at the memory pointer is nonzero + if memory[pointer] != 0 { + braceCount := 1 + for braceCount > 0 { + i-- + if code[i] == ']' { + braceCount++ + } else if code[i] == '[' { + braceCount-- + } + } + i-- // Move back one more to compensate for the upcoming increment in the loop + } + } + } + return buf.String() +} diff --git a/examples/gno.land/p/demo/bf/bf_test.gno b/examples/gno.land/p/demo/bf/bf_test.gno new file mode 100644 index 00000000000..1be4a86ac33 --- /dev/null +++ b/examples/gno.land/p/demo/bf/bf_test.gno @@ -0,0 +1,35 @@ +package bf + +import ( + "bytes" + "testing" +) + +func TestExecuteBrainfuck(t *testing.T) { + testCases := []struct { + name string + code string + expected string + }{ + { + name: "hello", + code: "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.", + expected: "Hello World", + }, + { + name: "increment", + code: "+++++ +++++ [ > +++++ ++ < - ] > +++++ .", + expected: "K", + }, + // Add more test cases as needed + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := Execute(tc.code) + if result != tc.expected { + t.Errorf("Expected output: %s, but got: %s", tc.expected, result) + } + }) + } +} diff --git a/examples/gno.land/p/demo/bf/doc.gno b/examples/gno.land/p/demo/bf/doc.gno new file mode 100644 index 00000000000..6494b34fd4a --- /dev/null +++ b/examples/gno.land/p/demo/bf/doc.gno @@ -0,0 +1,18 @@ +// Package bf implements a minimalist Brainfuck virtual machine in Gno. +// +// Brainfuck is an esoteric programming language known for its simplicity and minimalistic design. +// It operates on an array of memory cells, with a memory pointer that can move left or right. +// The language consists of eight commands: > < + - . , [ ]. +// +// Usage: +// To execute Brainfuck code, use the Execute function and provide the code as a string. +// +// code := "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------." +// output := bf.Execute(code) +// +// Note: +// This implementation is a minimalist version and may not handle all edge cases or advanced features of the Brainfuck language. +// +// Reference: +// For more information on Brainfuck, refer to the Wikipedia page: https://en.wikipedia.org/wiki/Brainfuck +package bf // import "gno.land/p/demo/bf" diff --git a/examples/gno.land/p/demo/bf/gno.mod b/examples/gno.land/p/demo/bf/gno.mod new file mode 100644 index 00000000000..b887582196c --- /dev/null +++ b/examples/gno.land/p/demo/bf/gno.mod @@ -0,0 +1 @@ +module gno.land/p/demo/bf diff --git a/examples/gno.land/p/demo/bf/run.gno b/examples/gno.land/p/demo/bf/run.gno new file mode 100644 index 00000000000..ebf7cb63928 --- /dev/null +++ b/examples/gno.land/p/demo/bf/run.gno @@ -0,0 +1,8 @@ +package bf + +// for `gno run` +func main() { + code := "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------." + // TODO: code = os.Args... + Execute(code) +}