Added embed macro

This commit is contained in:
Dominic Grimm 2022-07-08 21:56:07 +02:00
parent 9fa85297b9
commit 164dc59dde
No known key found for this signature in database
GPG key ID: A6C051C716D2CE65
4 changed files with 43 additions and 22 deletions

View file

@ -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]?

View file

@ -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,

View file

@ -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|

View file

@ -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