# TODO: Write documentation for `Flint` require "option_parser" require "./util.cr" require "./brainfuck/*" require "./thue/*" module Flint VERSION = "0.1.1" def self.main execution_mode = :interpret chosen_language = nil memory_size = nil source_file = nil read_stdin = false parser = OptionParser.new do |parser| parser.banner = "Basic usage: flint [LANGUAGE] [OPTIONS] [FILE]" parser.on("brainfuck", "select brainfuck as the language") do chosen_language = :brainfuck memory_size = Brainfuck::DEFAULT_TAPE_SIZE parser.banner = "Usage: flint brainfuck [OPTIONS] [FILE]" parser.on("-t CELLS", "--tape-size=CELLS", "specify the number of memory cells in the tape, defaults to 30,000") do |_cells| memory_size = _cells.to_i end end parser.on("thue", "select Thue as the language") do chosen_language = :thue parser.banner = "Usage: flint thue [OPTIONS] [FILE]" # no thue-specific options yet end parser.on("-h", "--help", "show this help and exit") do puts parser exit(0) end parser.on("-i", "--interpet", "interpet the provided source code, implied by default, overridden by '-c' or '--compile'") { nil } parser.on("-c", "--compile", "produce a binary or different source code file instead of interpeting the code, overrides an explicit '-i' or '--intepret' flag") do execution_mode = :compile end parser.on("--stdin", "read source code from STDIN instead of a file") do read_stdin = true end parser.unknown_args do |_args| source_file = _args[0] unless _args.empty? end end parser.parse if read_stdin source_io = STDIN elsif source_file # compilier complains without the not_nil! source_io = File.new(source_file.not_nil!) else puts "ERROR: No source file chosen" puts parser exit(1) end case chosen_language when :brainfuck bf_parser = Brainfuck::Parser.new(source_io) program = Brainfuck::Program.new(bf_parser, memory_size) when :thue thue_parser = Thue::Parser.new(source_io) program = Thue::Program.new(thue_parser) else puts "ERROR: No language chosen" puts parser exit(1) end begin program.not_nil!.interpret rescue ex : Util::ParserError puts "Caught ParserError" puts ex.message exit(1) rescue ex : Brainfuck::MemoryError puts "Caught MemoryError" puts ex.message end end end Flint.main