Format code.
This commit is contained in:
parent
c04997ad17
commit
5e93fa1963
|
@ -5,7 +5,7 @@ module Chalk
|
|||
class CodeGenerator
|
||||
include Emitter
|
||||
RETURN_REG = 14
|
||||
STACK_REG = 13
|
||||
STACK_REG = 13
|
||||
|
||||
def initialize(table, @function : TreeFunction)
|
||||
@registers = 0
|
||||
|
|
|
@ -26,8 +26,8 @@ module Chalk
|
|||
@logger.debug("Beginning constant folding")
|
||||
folder = ConstantFolder.new
|
||||
trees.map! do |tree|
|
||||
@logger.debug("Constant folding #{tree.name}")
|
||||
tree.apply(folder).as(TreeFunction)
|
||||
@logger.debug("Constant folding #{tree.name}")
|
||||
tree.apply(folder).as(TreeFunction)
|
||||
end
|
||||
@logger.debug("Done constant folding")
|
||||
return trees
|
||||
|
@ -47,9 +47,9 @@ module Chalk
|
|||
end
|
||||
|
||||
private def create_code(tree : TreeFunction, table)
|
||||
generator = CodeGenerator.new table, tree
|
||||
@logger.debug("Generating code for #{tree.name}")
|
||||
return generator.generate!
|
||||
generator = CodeGenerator.new table, tree
|
||||
@logger.debug("Generating code for #{tree.name}")
|
||||
return generator.generate!
|
||||
end
|
||||
|
||||
private def create_code(trees : Array(TreeFunction), table)
|
||||
|
@ -82,32 +82,32 @@ module Chalk
|
|||
context = InstructionContext.new table, instructions.size
|
||||
binary = instructions.map_with_index { |it, i| it.to_bin(context, i).to_u16 }
|
||||
binary.each do |inst|
|
||||
first = (inst >> 8).to_u8
|
||||
dest.write_byte(first)
|
||||
second = (inst & 0xff).to_u8
|
||||
dest.write_byte(second)
|
||||
first = (inst >> 8).to_u8
|
||||
dest.write_byte(first)
|
||||
second = (inst & 0xff).to_u8
|
||||
dest.write_byte(second)
|
||||
end
|
||||
end
|
||||
|
||||
private def collect_calls(table)
|
||||
open = Set(String).new
|
||||
done = Set(String).new
|
||||
open = Set(String).new
|
||||
done = Set(String).new
|
||||
|
||||
open << "main"
|
||||
while !open.empty?
|
||||
first = open.first
|
||||
open.delete first
|
||||
done << first
|
||||
open << "main"
|
||||
while !open.empty?
|
||||
first = open.first
|
||||
open.delete first
|
||||
done << first
|
||||
|
||||
entry = table[first]?
|
||||
raise "Unknown function" unless entry && entry.is_a?(FunctionEntry)
|
||||
next unless entry.function.is_a?(TreeFunction)
|
||||
entry = table[first]?
|
||||
raise "Unknown function" unless entry && entry.is_a?(FunctionEntry)
|
||||
next unless entry.function.is_a?(TreeFunction)
|
||||
|
||||
visitor = CallVisitor.new
|
||||
entry.function.accept(visitor)
|
||||
open.concat(visitor.calls - done)
|
||||
end
|
||||
return done
|
||||
visitor = CallVisitor.new
|
||||
entry.function.accept(visitor)
|
||||
open.concat(visitor.calls - done)
|
||||
end
|
||||
return done
|
||||
end
|
||||
|
||||
private def run_binary
|
||||
|
|
|
@ -1,75 +1,75 @@
|
|||
module Chalk
|
||||
module Emitter
|
||||
private def load(into, value)
|
||||
inst = LoadInstruction.new into, value.to_i32
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def loadr(into, from)
|
||||
inst = LoadRegInstruction.new into, from
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def op(op, into, from)
|
||||
inst = OpInstruction.new op, into, from
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def opr(op, into, from)
|
||||
inst = OpRegInstruction.new op, into, from
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def sne(l, r)
|
||||
inst = SkipNeInstruction.new l, r
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def jr(o)
|
||||
inst = JumpRelativeInstruction.new o
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def store(up_to)
|
||||
inst = StoreInstruction.new up_to
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def restore(up_to)
|
||||
inst = RestoreInstruction.new up_to
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def ret
|
||||
inst = ReturnInstruction.new
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def call(func)
|
||||
inst = CallInstruction.new func
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def setis
|
||||
inst = SetIStackInstruction.new
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def addi(reg)
|
||||
inst = AddIRegInstruction.new reg
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
module Emitter
|
||||
private def load(into, value)
|
||||
inst = LoadInstruction.new into, value.to_i32
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def loadr(into, from)
|
||||
inst = LoadRegInstruction.new into, from
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def op(op, into, from)
|
||||
inst = OpInstruction.new op, into, from
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def opr(op, into, from)
|
||||
inst = OpRegInstruction.new op, into, from
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def sne(l, r)
|
||||
inst = SkipNeInstruction.new l, r
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def jr(o)
|
||||
inst = JumpRelativeInstruction.new o
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def store(up_to)
|
||||
inst = StoreInstruction.new up_to
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def restore(up_to)
|
||||
inst = RestoreInstruction.new up_to
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def ret
|
||||
inst = ReturnInstruction.new
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def call(func)
|
||||
inst = CallInstruction.new func
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def setis
|
||||
inst = SetIStackInstruction.new
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
|
||||
private def addi(reg)
|
||||
inst = AddIRegInstruction.new reg
|
||||
@instructions << inst
|
||||
return inst
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
module Chalk
|
||||
class CallVisitor < Visitor
|
||||
property calls : Set(String)
|
||||
class CallVisitor < Visitor
|
||||
property calls : Set(String)
|
||||
|
||||
def initialize
|
||||
@calls = Set(String).new
|
||||
end
|
||||
|
||||
def visit(t : TreeCall)
|
||||
@calls << t.name
|
||||
end
|
||||
def initialize
|
||||
@calls = Set(String).new
|
||||
end
|
||||
|
||||
def visit(t : TreeCall)
|
||||
@calls << t.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,11 +8,11 @@ module Chalk
|
|||
end
|
||||
|
||||
class InstructionContext
|
||||
property table : Table
|
||||
property stack : Int32
|
||||
property table : Table
|
||||
property stack : Int32
|
||||
|
||||
def initialize(@table, @stack)
|
||||
end
|
||||
def initialize(@table, @stack)
|
||||
end
|
||||
end
|
||||
|
||||
class LoadInstruction < Instruction
|
||||
|
@ -29,7 +29,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
0x6000 | (register << 8) | value
|
||||
0x6000 | (register << 8) | value
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -48,7 +48,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
0x8000 | (into << 8) | (from << 4)
|
||||
0x8000 | (into << 8) | (from << 4)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -67,12 +67,12 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
case op
|
||||
when TokenType::OpAdd
|
||||
return 0x7000 | (into << 8) | value
|
||||
else
|
||||
raise "Invalid instruction"
|
||||
end
|
||||
case op
|
||||
when TokenType::OpAdd
|
||||
return 0x7000 | (into << 8) | value
|
||||
else
|
||||
raise "Invalid instruction"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -92,22 +92,22 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
code = 0
|
||||
case op
|
||||
when TokenType::OpAdd
|
||||
code = 4
|
||||
when TokenType::OpSub
|
||||
code = 5
|
||||
when TokenType::OpOr
|
||||
code = 1
|
||||
when TokenType::OpAnd
|
||||
code = 2
|
||||
when TokenType::OpXor
|
||||
code = 3
|
||||
else
|
||||
raise "Invalid instruction"
|
||||
end
|
||||
return 0x8000 | (into << 8) | (from << 4) | code
|
||||
code = 0
|
||||
case op
|
||||
when TokenType::OpAdd
|
||||
code = 4
|
||||
when TokenType::OpSub
|
||||
code = 5
|
||||
when TokenType::OpOr
|
||||
code = 1
|
||||
when TokenType::OpAnd
|
||||
code = 2
|
||||
when TokenType::OpXor
|
||||
code = 3
|
||||
else
|
||||
raise "Invalid instruction"
|
||||
end
|
||||
return 0x8000 | (into << 8) | (from << 4) | code
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -123,7 +123,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0xf055 | (up_to << 8)
|
||||
return 0xf055 | (up_to << 8)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -139,12 +139,12 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0xf065 | (up_to << 8)
|
||||
return 0xf065 | (up_to << 8)
|
||||
end
|
||||
end
|
||||
|
||||
class ReturnInstruction < Instruction
|
||||
def initialize()
|
||||
def initialize
|
||||
end
|
||||
|
||||
def to_s(io)
|
||||
|
@ -152,7 +152,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0x00ee
|
||||
return 0x00ee
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -167,7 +167,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0x1000 | ((offset + index) * 2 + 0x200)
|
||||
return 0x1000 | ((offset + index) * 2 + 0x200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -185,7 +185,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0x3000 | (left << 8) | right
|
||||
return 0x3000 | (left << 8) | right
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -203,7 +203,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0x4000 | (left << 8) | right
|
||||
return 0x4000 | (left << 8) | right
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -222,7 +222,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0x5000 | (left << 8) | (right << 4)
|
||||
return 0x5000 | (left << 8) | (right << 4)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -241,7 +241,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0x9000 | (left << 8) | (right << 4)
|
||||
return 0x9000 | (left << 8) | (right << 4)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -256,17 +256,17 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0x2000 | (i.table[name]?.as(FunctionEntry).addr * 2 + 0x200)
|
||||
return 0x2000 | (i.table[name]?.as(FunctionEntry).addr * 2 + 0x200)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class SetIStackInstruction < Instruction
|
||||
def to_s(io)
|
||||
io << "setis"
|
||||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0xa000 | (i.stack * 2 + 0x200)
|
||||
return 0xa000 | (i.stack * 2 + 0x200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -282,7 +282,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(i, index)
|
||||
return 0xf000 | (reg << 8) | 0x1e
|
||||
return 0xf000 | (reg << 8) | 0x1e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
module Chalk
|
||||
class Optimizer
|
||||
def initialize(instructions : Array(Instruction))
|
||||
@instructions = instructions.dup
|
||||
end
|
||||
|
||||
private def optimize!(range)
|
||||
offset = 0
|
||||
range.each do |index|
|
||||
if check_dead(@instructions[index + offset])
|
||||
@instructions.delete_at(index + offset)
|
||||
offset -= 1
|
||||
end
|
||||
end
|
||||
return offset
|
||||
end
|
||||
|
||||
private def optimize!
|
||||
block_boundaries = [ @instructions.size ]
|
||||
@instructions.each_with_index do |inst, i|
|
||||
if inst.is_a?(JumpRelativeInstruction)
|
||||
block_boundaries << (inst.offset + i)
|
||||
end
|
||||
end
|
||||
block_boundaries.sort!
|
||||
|
||||
previous = 0
|
||||
offset = 0
|
||||
block_boundaries.each do |boundary|
|
||||
range = (previous + offset)...(boundary + offset)
|
||||
offset += optimize!(range)
|
||||
previous = boundary
|
||||
end
|
||||
end
|
||||
class Optimizer
|
||||
def initialize(instructions : Array(Instruction))
|
||||
@instructions = instructions.dup
|
||||
end
|
||||
|
||||
private def optimize!(range)
|
||||
offset = 0
|
||||
range.each do |index|
|
||||
if check_dead(@instructions[index + offset])
|
||||
@instructions.delete_at(index + offset)
|
||||
offset -= 1
|
||||
end
|
||||
end
|
||||
return offset
|
||||
end
|
||||
|
||||
private def optimize!
|
||||
block_boundaries = [@instructions.size]
|
||||
@instructions.each_with_index do |inst, i|
|
||||
if inst.is_a?(JumpRelativeInstruction)
|
||||
block_boundaries << (inst.offset + i)
|
||||
end
|
||||
end
|
||||
block_boundaries.sort!
|
||||
|
||||
previous = 0
|
||||
offset = 0
|
||||
block_boundaries.each do |boundary|
|
||||
range = (previous + offset)...(boundary + offset)
|
||||
offset += optimize!(range)
|
||||
previous = boundary
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user