class Brainclusterfuck::Compiler
Attributes
bytecode[R]
Public Class Methods
new(tokens)
click to toggle source
# File lib/brainclusterfuck/compiler.rb, line 9 def initialize(tokens) raise CompileError, "No tokens supplied" if tokens.size == 0 @bytecode = tokens.map do |token| process_token(token) end resolve_loops! end
Public Instance Methods
squeeze_operations!()
click to toggle source
Merge consecutive modify value or modify pointer operations
# File lib/brainclusterfuck/compiler.rb, line 20 def squeeze_operations! modifying_bytecode_length do compressed = [@bytecode.shift] @bytecode.each do |opcode| last = compressed[-1] if opcode.can_squeeze_with?(last) compressed[-1] = opcode.squeeze_with(last) else compressed << opcode end end @bytecode = compressed end end
Private Instance Methods
modifying_bytecode_length() { || ... }
click to toggle source
# File lib/brainclusterfuck/compiler.rb, line 38 def modifying_bytecode_length(&blk) unresolve_loops! yield resolve_loops! end
process_token(token)
click to toggle source
# File lib/brainclusterfuck/compiler.rb, line 67 def process_token(token) case token when :v_incr Opcodes::ModifyValue.new(1, 1) when :v_decr Opcodes::ModifyValue.new(-1, 1) when :p_incr Opcodes::ModifyPointer.new(1, 1) when :p_decr Opcodes::ModifyPointer.new(-1, 1) when :print Opcodes::Print.new when :loop_start Opcodes::LoopStartPlaceholder.new when :loop_end Opcodes::LoopEndPlaceholder.new else raise CompileError, "Don't know how to handle token: #{token}" end end
resolve_loops!()
click to toggle source
# File lib/brainclusterfuck/compiler.rb, line 44 def resolve_loops! loop_stack = [] @bytecode.each_with_index do |op, index| if op.is_a?(Opcodes::LoopStartPlaceholder) loop_stack.push(op: op, index: index) elsif op.is_a?(Opcodes::LoopEndPlaceholder) raise PrematurelyTerminatedLoopError if loop_stack.empty? opening = loop_stack.pop num_operations = index - opening[:index] - 1 @bytecode[opening[:index]] = Opcodes::LoopStart.new(num_operations) @bytecode[index] = Opcodes::LoopEnd.new(num_operations) end end raise UnterminatedLoopError unless loop_stack.empty? end
unresolve_loops!()
click to toggle source
# File lib/brainclusterfuck/compiler.rb, line 63 def unresolve_loops! @bytecode.map! { |op| op.unresolve_loop } end