summaryrefslogtreecommitdiff
path: root/src/brainfuck/parser.cr
diff options
context:
space:
mode:
authorMatthew Hall <hallmatthew314@gmail.com>2022-09-02 21:03:42 +1200
committerMatthew Hall <hallmatthew314@gmail.com>2022-09-02 21:03:42 +1200
commit4dd4e596ae6e5da84f2ce4296cbf9c030efe69bb (patch)
tree401bf737a26c3cac4a32cf4862180d6288f9c010 /src/brainfuck/parser.cr
parentdd2bcbdadf2068723bdd88729d295171b0291cd2 (diff)
Can read code from STDIN, can parse brainfuck
Diffstat (limited to 'src/brainfuck/parser.cr')
-rw-r--r--src/brainfuck/parser.cr30
1 files changed, 29 insertions, 1 deletions
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