summaryrefslogtreecommitdiff
path: root/src/brainfuck
diff options
context:
space:
mode:
Diffstat (limited to 'src/brainfuck')
-rw-r--r--src/brainfuck/brainfuck.cr14
-rw-r--r--src/brainfuck/parser.cr30
-rw-r--r--src/brainfuck/program.cr14
3 files changed, 57 insertions, 1 deletions
diff --git a/src/brainfuck/brainfuck.cr b/src/brainfuck/brainfuck.cr
index 78c504c..b75ad1c 100644
--- a/src/brainfuck/brainfuck.cr
+++ b/src/brainfuck/brainfuck.cr
@@ -13,5 +13,19 @@ module Brainfuck
LoopStart
LoopEnd
end
+
+ def self.opcode_from_char(c : Char) : Opcode?
+ case c
+ when '>' then Opcode::PtrRight
+ when '<' then Opcode::PtrLeft
+ when '+' then Opcode::Inc
+ when '-' then Opcode::Dec
+ when '.' then Opcode::Out
+ when ',' then Opcode::In
+ when '[' then Opcode::LoopStart
+ when ']' then Opcode::LoopEnd
+ else nil
+ end
+ end
end
diff --git a/src/brainfuck/parser.cr b/src/brainfuck/parser.cr
index b937f73..df381e3 100644
--- a/src/brainfuck/parser.cr
+++ b/src/brainfuck/parser.cr
@@ -1,5 +1,33 @@
+require "./brainfuck.cr"
+require "../util.cr"
+
class Brainfuck::Parser
- def initialize()
+ 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
diff --git a/src/brainfuck/program.cr b/src/brainfuck/program.cr
new file mode 100644
index 0000000..cf4a097
--- /dev/null
+++ b/src/brainfuck/program.cr
@@ -0,0 +1,14 @@
+require "./parser.cr"
+
+class Brainfuck::Program
+ def initialize(@parser : Brainfuck::Parser)
+ end
+
+ def interpret
+ puts @parser.parse
+ end
+
+ def compile
+ end
+end
+