Format code.
This commit is contained in:
		
							parent
							
								
									c04997ad17
								
							
						
					
					
						commit
						5e93fa1963
					
				| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user