From 164dc59dde03de2acc71d2633693e69fc702c841 Mon Sep 17 00:00:00 2001 From: Dominic Grimm Date: Fri, 8 Jul 2022 21:56:07 +0200 Subject: [PATCH] Added embed macro --- src/cli/hence.cr | 3 ++- src/hence/assembler.cr | 24 ++++++++++++++++++++++-- src/hence/firmware.cr | 2 +- src/hence/parser.cr | 36 ++++++++++++++++++------------------ 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/cli/hence.cr b/src/cli/hence.cr index 420a191..ea71fcf 100644 --- a/src/cli/hence.cr +++ b/src/cli/hence.cr @@ -143,7 +143,8 @@ CLI = Commander::Command.new do |cmd| Hence::Firmware.from_yaml(File.read(opts.string["file"])) else Hence::Firmware::FIRMWARES[opts.string["firmware"]] - end.build_opcodes[:names] + end.build_opcodes[:names], + Hence::Assembler::Data.new(Path[args[0]]) ) File.write(args[1], bin) if args[1]? diff --git a/src/hence/assembler.cr b/src/hence/assembler.cr index 7645d62..9b3b55d 100644 --- a/src/hence/assembler.cr +++ b/src/hence/assembler.cr @@ -4,7 +4,7 @@ module Hence module Assembler extend self - def assemble(ast : Parser::AST, opcode_names : Hash(String, UInt8), data = Data.new) : Bytes + def assemble(ast : Parser::AST, opcode_names : Hash(String, UInt8), data : Data) : Bytes ast.body.each do |node| data.constants["OFFSET"] = Parser::AST::NumberArg.new(data.offset) @@ -36,7 +36,7 @@ module Hence data.bin end - class Data + class RawData property bin property offset property constants @@ -49,6 +49,18 @@ module Hence end end + class Data < RawData + property path + + def initialize( + @path : Path, + @bin = Bytes.new({{ 32 * 1024 }}), + @offset = 0_u16, + @constants = {} of String => Parser::AST::Arg + ) + end + end + MACROS = { "debug" => ->(data : Data, args : Array(Parser::AST::Arg)) do args.each do |arg| @@ -92,6 +104,14 @@ module Hence data.offset += 1 end end, + "embed" => ->(data : Data, args : Array(Parser::AST::Arg)) do + File.open(Path[String.new(args[0].resolve(data))].expand(data.path.dirname)) do |io| + io.getb_to_end.each_with_index do |val, i| + data.bin[data.offset + i] = val + end + data.offset += io.size + end + end, "include" => ->(_data : Data, _args : Array(Parser::AST::Arg)) do raise "Unimplemented" end, diff --git a/src/hence/firmware.cr b/src/hence/firmware.cr index 4e28721..a8ff266 100644 --- a/src/hence/firmware.cr +++ b/src/hence/firmware.cr @@ -65,7 +65,7 @@ module Hence {names: names, opcodes: opcodes} end - def compile(microcode_names : Hash(String, UInt8), data = Assembler::Data.new) : Bytes + def compile(microcode_names : Hash(String, UInt8), data = Assembler::RawData.new) : Bytes sorted_opcodes = build_opcodes[:opcodes].to_a.sort_by!(&.[0]) data.offset = (sorted_opcodes.last[0].to_u16 + 1) * 4 sorted_opcodes.each do |opc| diff --git a/src/hence/parser.cr b/src/hence/parser.cr index ac973d3..0ad2cb3 100644 --- a/src/hence/parser.cr +++ b/src/hence/parser.cr @@ -167,9 +167,9 @@ module Hence end abstract class Arg - abstract def resolve(data : Assembler::Data) : Bytes + abstract def resolve(data : Assembler::RawData) : Bytes - abstract def resolve_as_number(data : Assembler::Data) : UInt16 + abstract def resolve_as_number(data : Assembler::RawData) : UInt16 abstract def to_s : String end @@ -180,12 +180,12 @@ module Hence def initialize(@number : UInt16) end - def resolve(data : Assembler::Data) : Bytes + def resolve(data : Assembler::RawData) : Bytes n = Utils.split_u16(@number) Bytes[n[0], n[1]] end - def resolve_as_number(data : Assembler::Data) : UInt16 + def resolve_as_number(data : Assembler::RawData) : UInt16 @number end @@ -200,11 +200,11 @@ module Hence def initialize(@name : String) end - def resolve(data : Assembler::Data) : Bytes + def resolve(data : Assembler::RawData) : Bytes data.constants[@name].resolve(data) end - def resolve_as_number(data : Assembler::Data) : UInt16 + def resolve_as_number(data : Assembler::RawData) : UInt16 data.constants[@name].resolve_as_number(data) end @@ -219,11 +219,11 @@ module Hence def initialize(@bytes : Bytes) end - def resolve(data : Assembler::Data) : Bytes + def resolve(data : Assembler::RawData) : Bytes @bytes end - def resolve_as_number(data : Assembler::Data) : UInt16 + def resolve_as_number(data : Assembler::RawData) : UInt16 if @bytes.size == 1 @bytes[0].to_u16 else @@ -242,7 +242,7 @@ module Hence def initialize(@string : String) end - def resolve(data : Assembler::Data) : Bytes + def resolve(data : Assembler::RawData) : Bytes if @string.bytesize == 1 Bytes[0_u8, @string.bytes[0]] else @@ -250,7 +250,7 @@ module Hence end end - def resolve_as_number(data : Assembler::Data) : UInt16 + def resolve_as_number(data : Assembler::RawData) : UInt16 slice = resolve(data) Utils.merge_u8(slice[0], slice[1]) @@ -262,13 +262,13 @@ module Hence end abstract struct BinaryOperation - abstract def resolve(left : Arg, right : Arg, data : Assembler::Data) : Arg + abstract def resolve(left : Arg, right : Arg, data : Assembler::RawData) : Arg abstract def to_s : String end struct AddBinaryOperation < BinaryOperation - def resolve(left : Arg, right : Arg, data : Assembler::Data) : Arg + def resolve(left : Arg, right : Arg, data : Assembler::RawData) : Arg NumberArg.new(left.resolve_as_number(data) &+ right.resolve_as_number(data)) end @@ -278,7 +278,7 @@ module Hence end struct SubBinaryOperation < BinaryOperation - def resolve(left : Arg, right : Arg, data : Assembler::Data) : Arg + def resolve(left : Arg, right : Arg, data : Assembler::RawData) : Arg NumberArg.new(left.resolve_as_number(data) &- right.resolve_as_number(data)) end @@ -288,7 +288,7 @@ module Hence end struct MulBinaryOperation < BinaryOperation - def resolve(left : Arg, right : Arg, data : Assembler::Data) : Arg + def resolve(left : Arg, right : Arg, data : Assembler::RawData) : Arg NumberArg.new(left.resolve_as_number(data) &* right.resolve_as_number(data)) end @@ -298,7 +298,7 @@ module Hence end struct DivBinaryOperation < BinaryOperation - def resolve(left : Arg, right : Arg, data : Assembler::Data) : Arg + def resolve(left : Arg, right : Arg, data : Assembler::RawData) : Arg NumberArg.new(left.resolve_as_number(data) // right.resolve_as_number(data)) end @@ -308,7 +308,7 @@ module Hence end struct PowBinaryOperation < BinaryOperation - def resolve(left : Arg, right : Arg, data : Assembler::Data) : Arg + def resolve(left : Arg, right : Arg, data : Assembler::RawData) : Arg NumberArg.new(left.resolve_as_number(data) &** right.resolve_as_number(data)) end @@ -325,11 +325,11 @@ module Hence def initialize(@left : Arg, @right : Arg, @op : BinaryOperation) end - def resolve(data : Assembler::Data) : Bytes + def resolve(data : Assembler::RawData) : Bytes @op.resolve(@left, @right, data).resolve(data) end - def resolve_as_number(data : Assembler::Data) : UInt16 + def resolve_as_number(data : Assembler::RawData) : UInt16 @op.resolve(@left, @right, data).resolve_as_number(data) end