Skip to content

Instantly share code, notes, and snippets.

@threeifbywhiskey
Last active August 19, 2016 01:45
Show Gist options
  • Save threeifbywhiskey/9619262 to your computer and use it in GitHub Desktop.
Save threeifbywhiskey/9619262 to your computer and use it in GitHub Desktop.
This is a brainfuck interpreter written using little more than lambdas, numbers, and a whole lot of symbols.
SIZE = -> coll {
coll == [] || coll == '' ? 0 : 1 + SIZE[coll[1..-1]]
}
MAP = -> coll, &fn {
coll == [] ? [] : [fn[coll[0]]] + MAP[coll[1..-1], &fn]
}
KEYS = -> hash { MAP[[*hash], &-> h { h[ 0] }] }
VALUES = -> hash { MAP[[*hash], &-> h { h[-1] }] }
INVERT = -> hash {
ks, vs = KEYS[hash], VALUES[hash]
sz = SIZE[ks]
ret = {}
i = 0
(inverter = -> {
ret[vs[i]] = ks[i]
(i += 1) == sz ? ret : inverter[]
})[]
}
MERGE = -> a, b {
all = [*a] + [*b]
sz = SIZE[all]
ret = {}
i = 0
(merger = -> {
ret[all[i][0]] = all[i][1]
(i += 1) == sz ? ret : merger[]
})[]
}
brainfuck = -> prog {
tape = []
sz = SIZE[prog]
pc = bp = i = 0
jumps, stack = {}, []
(jumper = -> {
prog[i] == '[' ? (stack << i) : 0
prog[i] == ']' ? (jumps[stack[-1]] = i; stack = stack[0..-2]) : 0
(i += 1) == sz ? 0 : jumper[]
})[]
jumps = jumps == {} ? {} : MERGE[jumps, INVERT[jumps]]
(brainfuck_p = -> {
prog[pc] ==
'+' ? (tape[bp] ||= 0; tape[bp] += 1) : prog[pc] ==
'-' ? (tape[bp] ||= 0; tape[bp] -= 1) : prog[pc] ==
'>' ? (bp += 1) : prog[pc] ==
'<' ? (bp -= 1) : prog[pc] ==
'[' ? (pc = (tape[bp] || 0) == 0 ? jumps[pc] : pc) : prog[pc] ==
']' ? (pc = (tape[bp] || 0) != 0 ? jumps[pc] : pc) : prog[pc] ==
'.' ? ($> << ('' << tape[bp])) : 0
(pc += 1) == sz ? prog : brainfuck_p[]
})[]
}
brainfuck[File.read('hw.bf')]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment