diff --git a/src/chalk/codegen.cr b/src/chalk/codegen.cr index a9b6669..0a54bc8 100644 --- a/src/chalk/codegen.cr +++ b/src/chalk/codegen.cr @@ -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 diff --git a/src/chalk/compiler.cr b/src/chalk/compiler.cr index 55e377c..605f3ae 100644 --- a/src/chalk/compiler.cr +++ b/src/chalk/compiler.cr @@ -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 diff --git a/src/chalk/emitter.cr b/src/chalk/emitter.cr index d48dda4..e2f4c7d 100644 --- a/src/chalk/emitter.cr +++ b/src/chalk/emitter.cr @@ -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 diff --git a/src/chalk/function_finder.cr b/src/chalk/function_finder.cr index 59c8b27..7683396 100644 --- a/src/chalk/function_finder.cr +++ b/src/chalk/function_finder.cr @@ -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 diff --git a/src/chalk/ir.cr b/src/chalk/ir.cr index a10dfbb..73b9ecf 100644 --- a/src/chalk/ir.cr +++ b/src/chalk/ir.cr @@ -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 diff --git a/src/chalk/optimizer.cr b/src/chalk/optimizer.cr index 6bb71ba..6eaafa6 100644 --- a/src/chalk/optimizer.cr +++ b/src/chalk/optimizer.cr @@ -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