Format code.

This commit is contained in:
Danila Fedorin 2018-07-27 23:27:13 -07:00
parent c04997ad17
commit 5e93fa1963
6 changed files with 180 additions and 180 deletions

View File

@ -5,7 +5,7 @@ module Chalk
class CodeGenerator class CodeGenerator
include Emitter include Emitter
RETURN_REG = 14 RETURN_REG = 14
STACK_REG = 13 STACK_REG = 13
def initialize(table, @function : TreeFunction) def initialize(table, @function : TreeFunction)
@registers = 0 @registers = 0

View File

@ -26,8 +26,8 @@ module Chalk
@logger.debug("Beginning constant folding") @logger.debug("Beginning constant folding")
folder = ConstantFolder.new folder = ConstantFolder.new
trees.map! do |tree| trees.map! do |tree|
@logger.debug("Constant folding #{tree.name}") @logger.debug("Constant folding #{tree.name}")
tree.apply(folder).as(TreeFunction) tree.apply(folder).as(TreeFunction)
end end
@logger.debug("Done constant folding") @logger.debug("Done constant folding")
return trees return trees
@ -47,9 +47,9 @@ module Chalk
end end
private def create_code(tree : TreeFunction, table) private def create_code(tree : TreeFunction, table)
generator = CodeGenerator.new table, tree generator = CodeGenerator.new table, tree
@logger.debug("Generating code for #{tree.name}") @logger.debug("Generating code for #{tree.name}")
return generator.generate! return generator.generate!
end end
private def create_code(trees : Array(TreeFunction), table) private def create_code(trees : Array(TreeFunction), table)
@ -82,32 +82,32 @@ module Chalk
context = InstructionContext.new table, instructions.size context = InstructionContext.new table, instructions.size
binary = instructions.map_with_index { |it, i| it.to_bin(context, i).to_u16 } binary = instructions.map_with_index { |it, i| it.to_bin(context, i).to_u16 }
binary.each do |inst| binary.each do |inst|
first = (inst >> 8).to_u8 first = (inst >> 8).to_u8
dest.write_byte(first) dest.write_byte(first)
second = (inst & 0xff).to_u8 second = (inst & 0xff).to_u8
dest.write_byte(second) dest.write_byte(second)
end end
end end
private def collect_calls(table) private def collect_calls(table)
open = Set(String).new open = Set(String).new
done = Set(String).new done = Set(String).new
open << "main" open << "main"
while !open.empty? while !open.empty?
first = open.first first = open.first
open.delete first open.delete first
done << first done << first
entry = table[first]? entry = table[first]?
raise "Unknown function" unless entry && entry.is_a?(FunctionEntry) raise "Unknown function" unless entry && entry.is_a?(FunctionEntry)
next unless entry.function.is_a?(TreeFunction) next unless entry.function.is_a?(TreeFunction)
visitor = CallVisitor.new visitor = CallVisitor.new
entry.function.accept(visitor) entry.function.accept(visitor)
open.concat(visitor.calls - done) open.concat(visitor.calls - done)
end end
return done return done
end end
private def run_binary private def run_binary

View File

@ -1,75 +1,75 @@
module Chalk module Chalk
module Emitter module Emitter
private def load(into, value) private def load(into, value)
inst = LoadInstruction.new into, value.to_i32 inst = LoadInstruction.new into, value.to_i32
@instructions << inst @instructions << inst
return 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
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 end

View File

@ -1,13 +1,13 @@
module Chalk module Chalk
class CallVisitor < Visitor class CallVisitor < Visitor
property calls : Set(String) property calls : Set(String)
def initialize def initialize
@calls = Set(String).new @calls = Set(String).new
end
def visit(t : TreeCall)
@calls << t.name
end
end end
def visit(t : TreeCall)
@calls << t.name
end
end
end end

View File

@ -8,11 +8,11 @@ module Chalk
end end
class InstructionContext class InstructionContext
property table : Table property table : Table
property stack : Int32 property stack : Int32
def initialize(@table, @stack) def initialize(@table, @stack)
end end
end end
class LoadInstruction < Instruction class LoadInstruction < Instruction
@ -29,7 +29,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
0x6000 | (register << 8) | value 0x6000 | (register << 8) | value
end end
end end
@ -48,7 +48,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
0x8000 | (into << 8) | (from << 4) 0x8000 | (into << 8) | (from << 4)
end end
end end
@ -67,12 +67,12 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
case op case op
when TokenType::OpAdd when TokenType::OpAdd
return 0x7000 | (into << 8) | value return 0x7000 | (into << 8) | value
else else
raise "Invalid instruction" raise "Invalid instruction"
end end
end end
end end
@ -92,22 +92,22 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
code = 0 code = 0
case op case op
when TokenType::OpAdd when TokenType::OpAdd
code = 4 code = 4
when TokenType::OpSub when TokenType::OpSub
code = 5 code = 5
when TokenType::OpOr when TokenType::OpOr
code = 1 code = 1
when TokenType::OpAnd when TokenType::OpAnd
code = 2 code = 2
when TokenType::OpXor when TokenType::OpXor
code = 3 code = 3
else else
raise "Invalid instruction" raise "Invalid instruction"
end end
return 0x8000 | (into << 8) | (from << 4) | code return 0x8000 | (into << 8) | (from << 4) | code
end end
end end
@ -123,7 +123,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0xf055 | (up_to << 8) return 0xf055 | (up_to << 8)
end end
end end
@ -139,12 +139,12 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0xf065 | (up_to << 8) return 0xf065 | (up_to << 8)
end end
end end
class ReturnInstruction < Instruction class ReturnInstruction < Instruction
def initialize() def initialize
end end
def to_s(io) def to_s(io)
@ -152,7 +152,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0x00ee return 0x00ee
end end
end end
@ -167,7 +167,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0x1000 | ((offset + index) * 2 + 0x200) return 0x1000 | ((offset + index) * 2 + 0x200)
end end
end end
@ -185,7 +185,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0x3000 | (left << 8) | right return 0x3000 | (left << 8) | right
end end
end end
@ -203,7 +203,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0x4000 | (left << 8) | right return 0x4000 | (left << 8) | right
end end
end end
@ -222,7 +222,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0x5000 | (left << 8) | (right << 4) return 0x5000 | (left << 8) | (right << 4)
end end
end end
@ -241,7 +241,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0x9000 | (left << 8) | (right << 4) return 0x9000 | (left << 8) | (right << 4)
end end
end end
@ -256,7 +256,7 @@ module Chalk
end end
def to_bin(i, index) 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
end end
@ -266,7 +266,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0xa000 | (i.stack * 2 + 0x200) return 0xa000 | (i.stack * 2 + 0x200)
end end
end end
@ -282,7 +282,7 @@ module Chalk
end end
def to_bin(i, index) def to_bin(i, index)
return 0xf000 | (reg << 8) | 0x1e return 0xf000 | (reg << 8) | 0x1e
end end
end end
end end

View File

@ -1,36 +1,36 @@
module Chalk module Chalk
class Optimizer class Optimizer
def initialize(instructions : Array(Instruction)) def initialize(instructions : Array(Instruction))
@instructions = instructions.dup @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
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 end