Class: Voodoo::Compiler

Inherits:
Object
  • Object
show all
Defined in:
lib/voodoo/compiler.rb

Overview

Voodoo compiler driver. The compiler driver reads input from a parser (see Voodoo::Parser), feeds it to a code generator (see Voodoo::CommonCodeGenerator), and writes the generated code.

An example of its usage can be found on the main page for the Voodoo module.

Defined Under Namespace

Classes: Error

Instance Method Summary collapse

Constructor Details

#initialize(parser, code_generator, output) ⇒ Compiler

Initializes a compiler.

Parameters:

parser

the parser to be used (see Voodoo::Parser)

code_generator

the code generator to be used (see Voodoo::CommonCodeGenerator)

output

an IO object. The generated code will be written to it



33
34
35
36
37
# File 'lib/voodoo/compiler.rb', line 33

def initialize parser, code_generator, output
  @parser = parser
  @generator = code_generator
  @output = output
end

Instance Method Details

#compileObject

Performs the compilation.



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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/voodoo/compiler.rb', line 40

def compile
  section = :code
  errors = []
  while true
    begin
      statement = @parser.parse_top_level

      break if statement == nil
      next if statement.empty?

      case statement[0]
      when :section
        section = statement[1]
      else
        @generator.add section, statement
      end

    rescue Parser::MultipleErrors => e
      errors.concat e.errors

    rescue Parser::ParseError => e
      errors << e
    end

    if errors.length >= 100
      # Too many errors, give up.
      raise Error.new(errors)
    end
  end

  undefined_symbols = @generator.undefined_symbols
  unless undefined_symbols.empty?
    msg = "The following symbols are used, but have not been defined" +
      " or imported:\n" + undefined_symbols.to_a.sort!.join(" ")
    errors << RuntimeError.new(msg)
  end

  if errors.empty?
    @generator.write @output
  else
    raise Error.new(errors)
  end
end