From 2471375f800dd2480ef7c1e76800a50898d90120 Mon Sep 17 00:00:00 2001 From: wowlikon Date: Wed, 29 Oct 2025 11:26:16 +0300 Subject: [PATCH] init --- .gitignore | 3 ++ README.md | 23 ++++++++++++++ brainfuck.yml | 28 +++++++++++++++++ example/hw.bf | 1 + go.mod | 3 ++ src/main.go | 69 ++++++++++++++++++++++++++++++++++++++++++ src/serialization.go | 63 +++++++++++++++++++++++++++++++++++++++ src/validation.go | 71 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 261 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 brainfuck.yml create mode 100644 example/hw.bf create mode 100644 go.mod create mode 100644 src/main.go create mode 100644 src/serialization.go create mode 100644 src/validation.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c86206a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin +*.bin +*.bfc \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e1703f0 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Brainfuck **!DRAFT!** 🚧 + +Π˜Π½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ для brainfuck, насписаный Π½Π° golang с Π»ΠΈΠ½Ρ‚Π΅Ρ€ΠΎΠΌ ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ функциями + +> [!WARNING] +> This is a WIP project, anything can be changed and/or broken without any notification beforehand + +НовыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ: +* ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ + * сборка ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ„Π°ΠΉΠ»ΠΎΠ² + * промСТуточная компиляция Π² Π±Π°ΠΉΡ‚-ΠΊΠΎΠ΄ с Π΄Π°ΠΌΠΏΠΎΠΌ статичСских Π΄Π°Π½Π½Ρ‹Ρ… + * сохранСниС/Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π΄Π°ΠΌΠΏΠ° Π»Π΅Π½Ρ‚Ρ‹ + * кастомный Ρ€Π°Π·ΠΌΠ΅Ρ€ Π»Π΅Π½Ρ‚Ρ‹ памяти + * Ρ€Π΅ΠΆΠΈΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с UTF-8 +* Бинтаксис + * Π»ΠΈΠ½Ρ‚Π΅Ρ€ ΠΊΠΎΠ΄Π° + * ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ + * ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π² +* Π”Ρ€ΡƒΠ³ΠΎΠ΅ + * созданиС/Ρ‡Ρ‚Π΅Π½ΠΈΠ΅/ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅/ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ² + * ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° http[s] запросов + * Π²Ρ‹ΠΏΠΎΠ»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄ Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅ + * Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ³ΠΎ brainfuck ΠΊΠΎΠ΄Π° diff --git a/brainfuck.yml b/brainfuck.yml new file mode 100644 index 0000000..16d8ceb --- /dev/null +++ b/brainfuck.yml @@ -0,0 +1,28 @@ +brainfuck: + unicode: true + memory_cells: 30000 + load_dump: 'data_in.bin' + save_dump: 'data_out.bin' + sorces: + - 'example/hw.bf' + compiled: 'bin/hw.bfc' + lint: + - brackets + level: 'error' + expected: '=1' + - operators + level: 'warning' + expected: '=1' + - loop_depth + level: 'warning' + expected: '<=100' + - loop_depth + level: 'error' + expected: '<=255' + - pointer_balance + level: 'error' + expected: '<0' + - pointer_balance + level: 'warning' + expected: '>30000' + \ No newline at end of file diff --git a/example/hw.bf b/example/hw.bf new file mode 100644 index 0000000..a1bc012 --- /dev/null +++ b/example/hw.bf @@ -0,0 +1 @@ +++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>., \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f8f39a8 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/wowlikon/go-brainfuck + +go 1.25.3 diff --git a/src/main.go b/src/main.go new file mode 100644 index 0000000..d4bb753 --- /dev/null +++ b/src/main.go @@ -0,0 +1,69 @@ +package main + +import ( + "flag" + "fmt" + "os" +) + +const VersionCode = 1 + +func main() { + cells := flag.Int("m", 30000, "cell count") + unicode := flag.Bool("u", false, "use unicode") + compile := flag.Bool("c", false, "compile to .bfc") + + flag.Parse() + + args := flag.Args() + var file string + if len(args) > 0 { + file = args[0] + } else { + fmt.Println("Ошибка: Ρ„Π°ΠΉΠ» Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½.") + os.Exit(1) + } + + fmt.Printf("Cells: %d\nUTF: %v\nCompile: %v\n", cells, unicode, compile) + + firstArray := []byte{0x01, 0x02, 0x03, 0x04, 0x05} + secondArray := []byte{0xAA, 0xBB, 0xCC} + + save(file, firstArray, secondArray) + load(file) + + fmt.Println() + + fmt.Println(validateBrackets("[][][]")) + fmt.Println(validateBrackets("[[[]]]")) + fmt.Println(validateBrackets("[[[][]]]")) + fmt.Println(validateBrackets("[")) + fmt.Println(validateBrackets("]")) + fmt.Println(validateBrackets("][")) + fmt.Println(validateBrackets("[]")) + + fmt.Println() + + fmt.Println(validateOperators("+-<>-+.,[]")) + fmt.Println(validateOperators("+-<>-+.,()")) + fmt.Println(validateOperators("hello")) + + fmt.Println() + + fmt.Println(validateLoopDepth("+++---")) + fmt.Println(validateLoopDepth("+++[->+<]")) + fmt.Println(validateLoopDepth("[[[")) + fmt.Println(validateLoopDepth("[]")) + fmt.Println(validateLoopDepth("[[][]]")) + fmt.Println(validateLoopDepth("[[[]][]]")) + fmt.Println(validateLoopDepth("[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]")) + + fmt.Println() + + fmt.Println(validatePointerBalance("+++---")) + fmt.Println(validatePointerBalance("---+++")) + fmt.Println(validatePointerBalance("++++++")) + fmt.Println(validatePointerBalance("++++[]")) + fmt.Println(validatePointerBalance("----[]")) + fmt.Println(validatePointerBalance("+-+-[]")) +} diff --git a/src/serialization.go b/src/serialization.go new file mode 100644 index 0000000..8264722 --- /dev/null +++ b/src/serialization.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "encoding/binary" + "os" +) + +func save(filepath string, data1 []byte, data2 []byte) error { + file, err := os.Create(filepath) + if err != nil { + panic(err) + } + defer file.Close() + + err = binary.Write(file, binary.BigEndian, uint32(len(data1))) + if err != nil { + return err + } + + _, err = file.Write(data1) + if err != nil { + return err + } + + _, err = file.Write(data2) + if err != nil { + return err + } + + return nil +} + +func load(filepath string) ([]byte, []byte, error) { + file, err := os.Open(filepath) + if err != nil { + return nil, nil, err + } + defer file.Close() + + var data1ArraySize uint32 + err = binary.Read(file, binary.BigEndian, &data1ArraySize) + if err != nil { + return nil, nil, err + } + + data1Array := make([]byte, data1ArraySize) + _, err = file.Read(data1Array) + if err != nil { + return nil, nil, err + } + + data2Array, err := os.ReadFile(filepath) + if err != nil { + return nil, nil, err + } + + data2Array = data2Array[4+data1ArraySize:] + fmt.Printf("Π Π°Π·ΠΌΠ΅Ρ€ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ массива: %d\n", data1ArraySize) + fmt.Printf("ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ массив: %v\n", data1Array) + fmt.Printf("Π’Ρ‚ΠΎΡ€ΠΎΠΉ массив: %v\n", data2Array) + return data1Array, data2Array, nil +} \ No newline at end of file diff --git a/src/validation.go b/src/validation.go new file mode 100644 index 0000000..7173b89 --- /dev/null +++ b/src/validation.go @@ -0,0 +1,71 @@ +package main + +import ( + // "fmt" +) + +func validateBrackets(src string) int { + count := 0 + for _, c := range src { + if c == '[' { + count++ + } else if c == ']' { + count-- + if count < 0 { + return 0 + } + } + } + if count == 0 { + return 1 + } + return 0 +} + +func validateOperators(src string) int { + for i, c := range src { + switch c { + case '+', '-', '<', '>', '[', ']', ',', '.': break; + default: return i; + } + } + return -1 +} + +func validateLoopDepth(src string) int { + if validateBrackets(src) == 0 { + return -1 + } + max_depth := 0 + current_depth := 0 + for _, c := range src { + if c == '[' { + current_depth++ + } else if c == ']' { + current_depth-- + } + max_depth = max(max_depth, current_depth) + } + return max_depth +} + +func validatePointerBalance(src string) int { + max_index := 0 + pointer_index := 0 + for _, c := range src { + if c == '[' || c == ']' { + break + } else if c == '+' { + pointer_index++ + max_index = max(max_index, pointer_index) + } else if c == '-' { + pointer_index-- + return -1 + } + } + return max_index +} + +func validateSourceLength(src string) int { + return len(src) +} \ No newline at end of file