Edited at

brainf*ckを書いてみた

More than 5 years have passed since last update.


brainfuck.rb

class Tape

def initialize
@position = 0
@tape = [0]
end

def get
@tape[@position]
end

def set(val)
@tape[@position] = val
end

def inc
@tape[@position] += 1
end

def dec
@tape[@position] -= 1
end

def advance
@position += 1
@tape.push(0) if @tape.size <= @position
end

def devance
@position -= 1
end
end

def mainloop(program, map)
pc = 0
tape = Tape.new

while (pc < program.size)
c = program[pc]
case c
when '+'
tape.inc
when '-'
tape.dec
when '>'
tape.advance
when '<'
tape.devance
when '['
pc = map[pc] if tape.get == 0
when ']'
pc = map[pc] if tape.get != 0
when '.'
print tape.get.chr
when ','
end
pc += 1
end
end

def parse(program)
parsed = []
map = {}
stack = []
keywords = ['[',']','<','>','+','-',',','.']

pc = 0
program.each_byte do |c|
c = c.chr
next unless keywords.include?(c)
parsed.push c
if c == '['
stack.push pc
elsif c == ']'
left = stack.pop
right = pc
map[left] = right
map[right] = left
end
pc += 1
end

return parsed.join(''), map
end

def run(input)
program, map = parse(input)
mainloop(program, map)
end

open(ARGV[0]) do |f|
run(f.read)
end



brainfuck.js

var Tape = function() {

this.tape = [0];
this.position = 0;
this.inc = function(){ this.tape[this.position]++; };
this.dec = function(){ this.tape[this.position]--; };
this.advance = function(){
this.position++;
if(this.tape.length <= this.position)
this.tape.push(0);
};
this.devance = function(){ this.position--; };
this.get = function(){ return this.tape[this.position]; };
this.set = function(val){ this.tape[this.position] = val; };
}

function mainloop(program, map){
var tape = new Tape(),
pc = 0;
while(pc < program.length) {
var c = program[pc];
switch(c) {
case '+':
tape.inc();
break;
case '-':
tape.dec();
break;
case '>':
tape.advance();
break;
case '<':
tape.devance();
break;
case '.':
process.stdout.write(String.fromCharCode(tape.get()));
break;
case ',':
break;
case '[':
if(tape.get() === 0)
pc = map[String(pc)];
break;
case ']':
if(tape.get() !== 0)
pc = map[String(pc)];
break;
}
pc++;
}
}

function parse(program){
var keywords = ['[',']','<','>','+','-',',','.'],
parsed = [],
map = {},
stack = [],
pc = 0;
program.split('').forEach(function(c){
if (keywords.indexOf(c) > -1) {
parsed.push(c);
if(c === '['){
stack.push(pc);
}else if(c === ']'){
var left = stack.pop(),
right = pc;
map[left] = right;
map[right] = left;
}
pc++;
}
});
return {parsed:parsed.join(''),map:map}
}
function run(input){
var data = parse(input);
mainloop(data['parsed'], data['map']);
}

var fs = require('fs');

fs.readFile(process.argv[2], 'utf-8', function(err, data){
if(err) throw err;
run(data);
});