go/brainfuck

log tags | changeset raw browse | file diff annotate file log raw

view bf.go @ 2:ddcf4bca3fd6

Capitalized
author yiyus@1936
date Tue Nov 24 20:31:30 2009 +0100 (2009-11-24 ago)
parents fb4dee2a5872
children

1 // Copyright 2009 JGL
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 /*
6 Brainfuck virtual machines.
8 Commands:
9 > increment the data pointer (to point to the next cell to the right).
10 < decrement the data pointer (to point to the next cell to the left).
11 + increment (increase by one) the byte at the data pointer.
12 - decrement (decrease by one) the byte at the data pointer.
13 . output the value of the byte at the data pointer.
14 , accept one byte of input, storing its value in the byte at the data pointer.
15 [ if the byte at the data pointer is zero, then instead of moving the instruction
16 pointer forward to the next command, jump it forward to the command after
17 the matching ] command*.
18 ] if the byte at the data pointer is nonzero, then instead of moving the instruction
19 pointer forward to the next command, jump it back to the command after the
20 matching [ command*.
22 ToDo: Implement Read/Write methods as an alternative to channels
24 See also: http://golang.org/test/turing.go (many thanks to the author of this code!)
25 */
27 package brainfuck
29 // BrainFuckVM represents the input and output of the virtual machine
30 type BrainFuckVM struct {
31 In chan byte;
32 Out chan byte;
33 }
35 func (bf BrainFuckVM) core(prog []byte, size int) {
36 a := make([]byte, size);
37 if len(prog) == 0 || size == 0 {
38 return
39 }
40 p := 0;
41 pc := 0;
42 for {
43 switch prog[pc] {
44 case '>':
45 p++
46 case '<':
47 p--
48 case '+':
49 a[p]++
50 case '-':
51 a[p]--
52 case '.':
53 bf.Out<- a[p]
54 case ',':
55 // test/turing.go cannot do this!
56 a[p] = <-bf.In
57 case '[':
58 if a[p] == 0 {
59 for nest := 1; nest > 0; pc++ {
60 switch prog[pc+1] {
61 case ']':
62 nest--
63 case '[':
64 nest++
65 }
66 }
67 }
68 case ']':
69 if a[p] != 0 {
70 for nest := -1; nest < 0; pc-- {
71 switch prog[pc-1] {
72 case ']':
73 nest--
74 case '[':
75 nest++
76 }
77 }
78 }
79 }
80 pc++;
81 if pc == len(prog) {
82 return
83 }
84 }
85 }
87 // BrainFucker launchs a new virtual machine with the specified
88 // program and memory and return a BrainFuckVM struct to
89 // access to its I/O ports
90 func BrainFucker(prog []byte, size int) *BrainFuckVM {
91 bf := new(BrainFuckVM);
92 bf.In = make(chan byte);
93 bf.Out= make(chan byte);
94 go bf.core(prog, size);
95 return bf;
96 }