Class: Huebot::Compiler

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

Instance Method Summary collapse

Constructor Details

#initialize(device_mapper) ⇒ Compiler

Returns a new instance of Compiler.



3
4
5
# File 'lib/huebot/compiler.rb', line 3

def initialize(device_mapper)
  @device_mapper = device_mapper
end

Instance Method Details

#build(ir, default_name = nil) ⇒ Huebot::Program

Build a huebot program from an intermediate representation (a Hash).

Parameters:

  • ir (Hash)
  • default_name (String) (defaults to: nil)

    A name to use if one isn’t specified

Returns:



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
66
67
68
69
# File 'lib/huebot/compiler.rb', line 14

def build(ir, default_name = nil)
  ir = ir.clone
  prog = Huebot::Program.new
  prog.name = ir.delete("name") || default_name

  # loop/loops
  val_loop = ir.delete("loop") || ir.delete(:loop)
  prog.errors << "'loop' must be 'true' or 'false'." if !val_loop.nil? and ![true, false].include?(val_loop)
  prog.loop = val_loop == true

  val_loops = ir.delete("loops") || ir.delete(:loops)
  prog.errors << "'loops' must be a positive integer." if !val_loops.nil? and val_loops.to_i < 0
  prog.loops = val_loops.to_i

  prog.errors << "'loop' and 'loops' are mutually exclusive." if prog.loop? and prog.loops > 0

  # initial state
  if (val_init = ir.delete("initial") || ir.delete(:initial))
    errors, warnings, state = build_transition val_init
    prog.initial_state = state
    prog.errors += errors
    prog.warnings += warnings
  end

  # transitions
  if (val_trns = ir.delete("transitions") || ir.delete(:transitions))
    val_trns.each do |val_trn|
      errors, warnings, state = if val_trn["parallel"] || val_trn[:parallel]
                                  build_parallel_transition val_trn
                                else
                                  build_transition val_trn
                                end
      prog.transitions << state
      prog.errors += errors
      prog.warnings += warnings
    end
  end

  # final state
  if (val_fnl = ir.delete("final") || ir.delete(:final))
    errors, warnings, state = build_transition val_fnl
    prog.final_state = state
    prog.errors += errors
    prog.warnings += warnings
  end

  # be strict about extra crap
  if (unknown = ir.keys.map(&:to_s)).any?
    prog.errors << "Unrecognized values: #{unknown.join ', '}."
  end

  # Add any warnings
  prog.warnings << "'final' is defined but will never be reached because 'loop' is 'true'." if prog.final_state and prog.loop?

  prog
end