summaryrefslogtreecommitdiff
path: root/src/brainfuck/parser.cr
blob: df381e383792d4d35c1af6e81c96e8e98db0e255 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
require "./brainfuck.cr"
require "../util.cr"

class Brainfuck::Parser
  def initialize(code_io : IO)
    @raw_code = code_io.gets_to_end
    code_io.close # just in case
  end

  def parse
    loop_depth = 0
    code = [] of Opcode
    @raw_code.chars.each do |c|
      op = Brainfuck.opcode_from_char(c)
      unless op.nil?
        if loop_depth == 0 && op == Opcode::LoopEnd
          raise Util::ParserError.new("Missing loop entrance(s)")
        end

        loop_depth -= 1 if op == Opcode::LoopEnd
        loop_depth += 1 if op == Opcode::LoopStart
        code << op
      end
    end

    unless loop_depth == 0
      raise Util::ParserError.new("Missing loop exit(s)")
    end

    return code
  end
end