summaryrefslogtreecommitdiff
path: root/src/among_us/parser.cr
diff options
context:
space:
mode:
authorMatthew Hall <hallmatthew314@gmail.com>2022-09-07 00:05:23 +1200
committerMatthew Hall <hallmatthew314@gmail.com>2022-09-07 00:05:23 +1200
commit97e3b4a9d7e995848341e53b2c002930c85d5c47 (patch)
tree45299ac50115bc3cc87f546cbbc8ba7519813a61 /src/among_us/parser.cr
parentb5aecfbd9d32bf894ab82d7b594f91a5f59acb2a (diff)
Parser + boilerplate for Among Us
Diffstat (limited to 'src/among_us/parser.cr')
-rw-r--r--src/among_us/parser.cr48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/among_us/parser.cr b/src/among_us/parser.cr
new file mode 100644
index 0000000..84894bd
--- /dev/null
+++ b/src/among_us/parser.cr
@@ -0,0 +1,48 @@
+require "../util.cr"
+require "./among_us.cr"
+
+struct AmongUs::Parser
+ def initialize(code_io : IO)
+ @raw_code = code_io.gets_to_end
+ code_io.close
+ end
+
+ def parse : Array(Instruction)
+ tokens = @raw_code.split
+ instructions = [] of Instruction
+ color_seen = false
+ sus_safe = false
+
+ tokens.each do |token|
+ case token.upcase
+ when "WHO?"
+ instructions << Command::WHO
+ when "WHERE?"
+ instructions << Command::WHERE
+ else
+ i = parse_instruction(token)
+ if i.nil?
+ raise Util::ParserError.new("Failed to parse command/color '#{token}'")
+ end
+ instructions << i
+ end
+
+ color_seen = true if instructions[-1].is_a?(Color)
+ if instructions[-1] == Command::SUS && !sus_safe
+ unless color_seen
+ raise Util::ParserError.new("Provided program uses SUS command, but no colors are provided before first SUS")
+ end
+ sus_safe = true
+ end
+ end
+
+ return instructions
+ end
+
+ private def parse_instruction(str : String) : Instruction?
+ i = Command.parse?(str)
+ return i unless i.nil?
+ Color.parse?(str)
+ end
+end
+