require "commander" require "../hence" CLI = Commander::Command.new do |cmd| cmd.use = "hence" cmd.long = "Hence assembler and emulator" cmd.run do puts cmd.help end # ameba:disable Lint/ShadowingOuterLocalVar cmd.commands.add do |cmd| cmd.use = "version" cmd.short = "Prins current hence version" cmd.long = cmd.short cmd.run do puts Hence::VERSION end end # ameba:disable Lint/ShadowingOuterLocalVar cmd.commands.add do |cmd| cmd.use = "firmware" cmd.short = "Firmware utility" cmd.long = cmd.short cmd.flags.add do |flag| flag.name = "file" flag.long = "--file" flag.default = false flag.description = "Load firmware from file" flag.persistent = true end # ameba:disable Lint/ShadowingOuterLocalVar cmd.commands.add do |cmd| cmd.use = "ls" cmd.short = "Lists available firmwares" cmd.long = cmd.short cmd.run do puts Hence::Firmware::FIRMWARES.keys.join("\n") end end # ameba:disable Lint/ShadowingOuterLocalVar cmd.commands.add do |cmd| cmd.use = "compile [out]" cmd.short = "Compiles a firmware" cmd.long = cmd.short cmd.flags.add do |flag| flag.name = "dump" flag.long = "--dump" flag.default = false flag.description = "Hexdumps the firmware" end cmd.run do |opts, args| bin = if opts.bool["file"] Hence::Firmware.from_yaml(File.read(args[0])) else Hence::Firmware::FIRMWARES[args[0]] end.compile(Hence::Microcode::MICROCODE_NAMES) File.write(args[1], bin) if args[1]? puts bin.hexdump if opts.bool["dump"] end end # ameba:disable Lint/ShadowingOuterLocalVar cmd.commands.add do |cmd| cmd.use = "doc [out]" cmd.short = "Generates documentation for a firmware" cmd.long = cmd.short cmd.flags.add do |flag| flag.name = "dump" flag.long = "--dump" flag.default = false flag.description = "Hexdumps the firmware" end cmd.run do |opts, args| doc = if opts.bool["file"] Hence::Firmware.from_yaml(File.read(args[0])) else Hence::Firmware::FIRMWARES[args[0]] end.to_s File.write(args[1], doc) if args[1]? puts doc if opts.bool["dump"] end end end # ameba:disable Lint/ShadowingOuterLocalVar cmd.commands.add do |cmd| cmd.use = "parse " cmd.short = "Parses source code" cmd.long = cmd.short cmd.run do |_opts, args| # ameba:disable Lint/DebugCalls pp Hence::Parser.parse(File.read(args[0])) end end # ameba:disable Lint/ShadowingOuterLocalVar cmd.commands.add do |cmd| cmd.use = "assemble [out]" cmd.short = "Compiles assembly code into a binary" cmd.long = cmd.short cmd.flags.add do |flag| flag.name = "firmware" flag.short = "-f" flag.long = "--firmware" flag.default = "default" flag.description = "Custom firmware" end cmd.flags.add do |flag| flag.name = "file" flag.long = "--file" flag.default = false flag.description = "Load firmware from YAML definition file" end cmd.flags.add do |flag| flag.name = "dump" flag.long = "--dump" flag.default = false flag.description = "Hexdumps the binary" end cmd.run do |opts, args| bin = Hence::Assembler.assemble( Hence::Parser.parse(File.read(args[0])), if opts.bool["file"] Hence::Firmware.from_yaml(File.read(opts.string["file"])) else Hence::Firmware::FIRMWARES[opts.string["firmware"]] end.build_opcodes[:names], Hence::Assembler::Data.new(Path[args[0]]) ) File.write(args[1], bin) if args[1]? puts bin.hexdump if opts.bool["dump"] end end # ameba:disable Lint/ShadowingOuterLocalVar cmd.commands.add do |cmd| cmd.use = "run " cmd.short = "Runs a binary" cmd.long = cmd.short cmd.flags.add do |flag| flag.name = "firmware" flag.short = "-f" flag.long = "--firmware" flag.default = "default" flag.description = "Custom firmware" end cmd.flags.add do |flag| flag.name = "file" flag.long = "--file" flag.default = false flag.description = "Load firmware from file" end cmd.run do |opts, args| bin = Bytes.new({{ 32 * 1024 }}) File.open(args[0]) do |file| file.gets_to_end.to_slice.copy_to(bin) end Hence::Emulator.emulate( Hence::Emulator::Data.new( bin, if opts.bool["file"] buffer = Bytes.new({{ 32 * 1024 }}) File.open(opts.string["firmware"]) do |file| file.gets_to_end.to_slice.copy_to(buffer) end buffer else Hence::Firmware::FIRMWARES[opts.string["firmware"]].compile(Hence::Microcode::MICROCODE_NAMES) end ) ) end end end Commander.run(CLI, ARGV)