Added embed macro
This commit is contained in:
parent
9fa85297b9
commit
164dc59dde
4 changed files with 43 additions and 22 deletions
|
@ -143,7 +143,8 @@ CLI = Commander::Command.new do |cmd|
|
||||||
Hence::Firmware.from_yaml(File.read(opts.string["file"]))
|
Hence::Firmware.from_yaml(File.read(opts.string["file"]))
|
||||||
else
|
else
|
||||||
Hence::Firmware::FIRMWARES[opts.string["firmware"]]
|
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]?
|
File.write(args[1], bin) if args[1]?
|
||||||
|
|
|
@ -4,7 +4,7 @@ module Hence
|
||||||
module Assembler
|
module Assembler
|
||||||
extend self
|
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|
|
ast.body.each do |node|
|
||||||
data.constants["OFFSET"] = Parser::AST::NumberArg.new(data.offset)
|
data.constants["OFFSET"] = Parser::AST::NumberArg.new(data.offset)
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ module Hence
|
||||||
data.bin
|
data.bin
|
||||||
end
|
end
|
||||||
|
|
||||||
class Data
|
class RawData
|
||||||
property bin
|
property bin
|
||||||
property offset
|
property offset
|
||||||
property constants
|
property constants
|
||||||
|
@ -49,6 +49,18 @@ module Hence
|
||||||
end
|
end
|
||||||
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 = {
|
MACROS = {
|
||||||
"debug" => ->(data : Data, args : Array(Parser::AST::Arg)) do
|
"debug" => ->(data : Data, args : Array(Parser::AST::Arg)) do
|
||||||
args.each do |arg|
|
args.each do |arg|
|
||||||
|
@ -92,6 +104,14 @@ module Hence
|
||||||
data.offset += 1
|
data.offset += 1
|
||||||
end
|
end
|
||||||
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
|
"include" => ->(_data : Data, _args : Array(Parser::AST::Arg)) do
|
||||||
raise "Unimplemented"
|
raise "Unimplemented"
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -65,7 +65,7 @@ module Hence
|
||||||
{names: names, opcodes: opcodes}
|
{names: names, opcodes: opcodes}
|
||||||
end
|
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])
|
sorted_opcodes = build_opcodes[:opcodes].to_a.sort_by!(&.[0])
|
||||||
data.offset = (sorted_opcodes.last[0].to_u16 + 1) * 4
|
data.offset = (sorted_opcodes.last[0].to_u16 + 1) * 4
|
||||||
sorted_opcodes.each do |opc|
|
sorted_opcodes.each do |opc|
|
||||||
|
|
|
@ -167,9 +167,9 @@ module Hence
|
||||||
end
|
end
|
||||||
|
|
||||||
abstract class Arg
|
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
|
abstract def to_s : String
|
||||||
end
|
end
|
||||||
|
@ -180,12 +180,12 @@ module Hence
|
||||||
def initialize(@number : UInt16)
|
def initialize(@number : UInt16)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve(data : Assembler::Data) : Bytes
|
def resolve(data : Assembler::RawData) : Bytes
|
||||||
n = Utils.split_u16(@number)
|
n = Utils.split_u16(@number)
|
||||||
Bytes[n[0], n[1]]
|
Bytes[n[0], n[1]]
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve_as_number(data : Assembler::Data) : UInt16
|
def resolve_as_number(data : Assembler::RawData) : UInt16
|
||||||
@number
|
@number
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -200,11 +200,11 @@ module Hence
|
||||||
def initialize(@name : String)
|
def initialize(@name : String)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve(data : Assembler::Data) : Bytes
|
def resolve(data : Assembler::RawData) : Bytes
|
||||||
data.constants[@name].resolve(data)
|
data.constants[@name].resolve(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve_as_number(data : Assembler::Data) : UInt16
|
def resolve_as_number(data : Assembler::RawData) : UInt16
|
||||||
data.constants[@name].resolve_as_number(data)
|
data.constants[@name].resolve_as_number(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -219,11 +219,11 @@ module Hence
|
||||||
def initialize(@bytes : Bytes)
|
def initialize(@bytes : Bytes)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve(data : Assembler::Data) : Bytes
|
def resolve(data : Assembler::RawData) : Bytes
|
||||||
@bytes
|
@bytes
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve_as_number(data : Assembler::Data) : UInt16
|
def resolve_as_number(data : Assembler::RawData) : UInt16
|
||||||
if @bytes.size == 1
|
if @bytes.size == 1
|
||||||
@bytes[0].to_u16
|
@bytes[0].to_u16
|
||||||
else
|
else
|
||||||
|
@ -242,7 +242,7 @@ module Hence
|
||||||
def initialize(@string : String)
|
def initialize(@string : String)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve(data : Assembler::Data) : Bytes
|
def resolve(data : Assembler::RawData) : Bytes
|
||||||
if @string.bytesize == 1
|
if @string.bytesize == 1
|
||||||
Bytes[0_u8, @string.bytes[0]]
|
Bytes[0_u8, @string.bytes[0]]
|
||||||
else
|
else
|
||||||
|
@ -250,7 +250,7 @@ module Hence
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve_as_number(data : Assembler::Data) : UInt16
|
def resolve_as_number(data : Assembler::RawData) : UInt16
|
||||||
slice = resolve(data)
|
slice = resolve(data)
|
||||||
|
|
||||||
Utils.merge_u8(slice[0], slice[1])
|
Utils.merge_u8(slice[0], slice[1])
|
||||||
|
@ -262,13 +262,13 @@ module Hence
|
||||||
end
|
end
|
||||||
|
|
||||||
abstract struct BinaryOperation
|
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
|
abstract def to_s : String
|
||||||
end
|
end
|
||||||
|
|
||||||
struct AddBinaryOperation < BinaryOperation
|
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))
|
NumberArg.new(left.resolve_as_number(data) &+ right.resolve_as_number(data))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ module Hence
|
||||||
end
|
end
|
||||||
|
|
||||||
struct SubBinaryOperation < BinaryOperation
|
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))
|
NumberArg.new(left.resolve_as_number(data) &- right.resolve_as_number(data))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ module Hence
|
||||||
end
|
end
|
||||||
|
|
||||||
struct MulBinaryOperation < BinaryOperation
|
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))
|
NumberArg.new(left.resolve_as_number(data) &* right.resolve_as_number(data))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ module Hence
|
||||||
end
|
end
|
||||||
|
|
||||||
struct DivBinaryOperation < BinaryOperation
|
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))
|
NumberArg.new(left.resolve_as_number(data) // right.resolve_as_number(data))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ module Hence
|
||||||
end
|
end
|
||||||
|
|
||||||
struct PowBinaryOperation < BinaryOperation
|
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))
|
NumberArg.new(left.resolve_as_number(data) &** right.resolve_as_number(data))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -325,11 +325,11 @@ module Hence
|
||||||
def initialize(@left : Arg, @right : Arg, @op : BinaryOperation)
|
def initialize(@left : Arg, @right : Arg, @op : BinaryOperation)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve(data : Assembler::Data) : Bytes
|
def resolve(data : Assembler::RawData) : Bytes
|
||||||
@op.resolve(@left, @right, data).resolve(data)
|
@op.resolve(@left, @right, data).resolve(data)
|
||||||
end
|
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)
|
@op.resolve(@left, @right, data).resolve_as_number(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue