diff options
| author | Matthew Hall <hallmatthew314@gmail.com> | 2022-09-07 00:05:23 +1200 |
|---|---|---|
| committer | Matthew Hall <hallmatthew314@gmail.com> | 2022-09-07 00:05:23 +1200 |
| commit | 97e3b4a9d7e995848341e53b2c002930c85d5c47 (patch) | |
| tree | 45299ac50115bc3cc87f546cbbc8ba7519813a61 /src/among_us/parser.cr | |
| parent | b5aecfbd9d32bf894ab82d7b594f91a5f59acb2a (diff) | |
Parser + boilerplate for Among Us
Diffstat (limited to 'src/among_us/parser.cr')
| -rw-r--r-- | src/among_us/parser.cr | 48 |
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 + |
