Class: Spitewaste::Assembler

Inherits:
Object
  • Object
show all
Defined in:
lib/spitewaste/assembler.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(program, **options) ⇒ Assembler

Returns a new instance of Assembler.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/spitewaste/assembler.rb', line 5

def initialize program, **options
  format = options[:format]
  format ||= Spitewaste.guess_format program
  unless i[whitespace wsassembly assembly spitewaste].include? format
    raise ArgumentError, "unknown format for parse: #{format}"
  end

  @parser =
    case format
    when :whitespace
      WhitespaceParser
    when :assembly
      AssemblyParser
    else # used for both Spitewaste and Whitespace assembly
      SpitewasteParser
    end

  parser = @parser.new(program, **options).tap &:parse
  @instructions = parser.instructions
  @src = parser.src if format == :spitewaste
end

Instance Attribute Details

#instructionsObject (readonly)

Returns the value of attribute instructions.



3
4
5
# File 'lib/spitewaste/assembler.rb', line 3

def instructions
  @instructions
end

#parserObject (readonly)

Returns the value of attribute parser.



3
4
5
# File 'lib/spitewaste/assembler.rb', line 3

def parser
  @parser
end

#srcObject (readonly)

Returns the value of attribute src.



3
4
5
# File 'lib/spitewaste/assembler.rb', line 3

def src
  @src
end

Instance Method Details

#assemble!(format:, io: STDOUT, **options) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/spitewaste/assembler.rb', line 27

def assemble! format:, io: STDOUT, **options
  unless i[whitespace wsassembly assembly codegen image].include? format
    raise ArgumentError, "unknown format for emit: #{format}"
  end

  emitter =
    case format
    when :whitespace
      WhitespaceEmitter
    when :wsassembly
      WSAssemblyEmitter
    when :codegen
      CodegenEmitter
    when :image
      ImageEmitter
    else
      AssemblyEmitter
    end
  emitter.new(format == :wsassembly ? @src : @instructions, **options).emit io: io
end

#try_elide_mainObject



48
49
50
51
52
53
54
# File 'lib/spitewaste/assembler.rb', line 48

def try_elide_main
  if @instructions.first == [:label, 0]
    @instructions.shift unless @instructions.any? { |op, arg|
      arg == 0 && i[jump jz jn call].include?(op)
    }
  end
end