Class: MicroCisc::Compile::Statement
- Inherits:
-
Object
- Object
- MicroCisc::Compile::Statement
- Defined in:
- lib/micro_cisc/compile/statement.rb
Constant Summary collapse
- SUGAR_REGEX =
/(?<name>(\$|&)[^\s\[\]]+)\s+(?<op>as|=)\s+(?<param>.+)/
- FUNCTION_REGEX =
/(?<stack>[^\s\[\]]+)\s*(\[(?<words>[0-9]+)\]){0,1}\s+<=\s+(?<label>[a-zA-Z_][a-zA-Z0-9_\-@$!%]*)\s*\(\s*(?<args>[^)]*)/
- IMM_REGEX =
/ (0x){0,1}(?<imm_val>[0-9A-Fa-f])\.imm/
Instance Attribute Summary collapse
-
#minimal ⇒ Object
readonly
Returns the value of attribute minimal.
-
#original ⇒ Object
readonly
Returns the value of attribute original.
Instance Method Summary collapse
- #create_variable(name, arg) ⇒ Object
- #filter_comments(instruction) ⇒ Object
-
#initialize(label_generator, statement, sugar) ⇒ Statement
constructor
A new instance of Statement.
- #parse ⇒ Object
- #parse_function_call ⇒ Object
Constructor Details
#initialize(label_generator, statement, sugar) ⇒ Statement
Returns a new instance of Statement.
9 10 11 12 13 14 |
# File 'lib/micro_cisc/compile/statement.rb', line 9 def initialize(label_generator, statement, sugar) @label_generator = label_generator @original = statement @minimal = filter_comments(statement) @sugar = sugar end |
Instance Attribute Details
#minimal ⇒ Object (readonly)
Returns the value of attribute minimal.
7 8 9 |
# File 'lib/micro_cisc/compile/statement.rb', line 7 def minimal @minimal end |
#original ⇒ Object (readonly)
Returns the value of attribute original.
7 8 9 |
# File 'lib/micro_cisc/compile/statement.rb', line 7 def original @original end |
Instance Method Details
#create_variable(name, arg) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/micro_cisc/compile/statement.rb', line 27 def create_variable(name, arg) if arg.end_with?("mem") || arg.end_with?("reg") name = name[1..-1] arg = arg[0..-4] @sugar["$#{name}"] = "#{arg}mem" @sugar["&#{name}"] = "#{arg}reg" else @sugar[name] = arg end end |
#filter_comments(instruction) ⇒ Object
16 17 18 19 20 21 22 23 24 25 |
# File 'lib/micro_cisc/compile/statement.rb', line 16 def filter_comments(instruction) # Remove all inline comments instruction = instruction.to_s.strip.gsub(/\/[^\/]*\//, '') # Remove all word comments instruction = instruction.gsub(/'[^\s]*/, '') # Remove all line comments instruction = instruction.gsub(/#.*/, '') # Single space instruction.gsub(/\s+/, ' ') end |
#parse ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/micro_cisc/compile/statement.rb', line 39 def parse if FUNCTION_REGEX =~ @minimal parse_function_call elsif SUGAR_REGEX =~ @minimal match = SUGAR_REGEX.match(@minimal) name = match['name'] if match['op'] == 'as' create_variable(name, match['param']) [] elsif match['op'] == '=' @minimal = match['param'] instruction = Instruction.new(@label_generator, minimal, original, @sugar) dest = instruction.dest if [1, 2, 3].include?(dest) create_variable(name, "#{dest}.mem") else dest -= 4 if dest > 4 create_variable(name, "#{dest}.reg") end [instruction] else raise ArgumentError, "Invalid syntax declaration: #{@minimal}" end else [Instruction.new(@label_generator, @minimal, original, @sugar)] end end |
#parse_function_call ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/micro_cisc/compile/statement.rb', line 67 def parse_function_call match = FUNCTION_REGEX.match(@minimal) label = match['label'] stack = match['stack'] stack = @sugar[stack] if @sugar[stack] raise ArgumentError, "Invalid stack param, mem register expected: #{stack}" unless stack =~ /^[1-3]\.mem$/ stackp = stack.sub('mem', 'reg') return_words = match['words'].to_i args = match['args'].split(',').map(&:strip) instructions = [] if return_words > 0 instruction = "copy #{stackp} -#{return_words}.imm #{stackp}" instructions << Instruction.new(@label_generator, instruction, " #{instruction} # return vars - #{original}", @sugar) end instruction = "copy 0.reg #{args.size + 2}.imm #{stack} push" instructions << Instruction.new(@label_generator, instruction, " #{instruction} # return addr - #{original}", @sugar) stack_delta = 1 + return_words args = args.each do |arg| arg = arg.split(' ').map { |a| @sugar[a] || a }.join(' ') is_stack = arg.start_with?(stack) if is_stack offset = stack_delta if arg_imm = IMM_REGEX.match(arg) arg_imm = arg_imm['imm_val'].to_i(16) arg = arg.sub(IMM_REGEX, '') else arg_imm = 0 end offset_immediate = (offset + arg_imm) > 0 ? " #{(offset + arg_imm)}.imm" : '' arg = "#{arg}#{offset_immediate}" end instruction = "copy #{arg} #{stack} push" stack_delta += 1 instructions << Instruction.new(@label_generator, instruction, " #{instruction} # push arg - #{original}", @sugar) end instruction = "copy 0.reg #{label}.disp 0.reg" instructions << Instruction.new(@label_generator, instruction, " #{instruction} # call - #{original}", @sugar) instructions end |