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