Class: TPPlus::Interpreter

Inherits:
Object
  • Object
show all
Defined in:
lib/tp_plus/interpreter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeInterpreter

Returns a new instance of Interpreter.



7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/tp_plus/interpreter.rb', line 7

def initialize
  @line_count    = 0
  @source_line_count = 0
  @nodes         = []
  @labels        = {}
  @namespaces    = {}
  @variables     = {}
  @constants     = {}
  @position_data = {}
  @header_data   = {}
  @current_label = 99
end

Instance Attribute Details

#constantsObject (readonly)

Returns the value of attribute constants.



6
7
8
# File 'lib/tp_plus/interpreter.rb', line 6

def constants
  @constants
end

#header_dataObject

Returns the value of attribute header_data.



5
6
7
# File 'lib/tp_plus/interpreter.rb', line 5

def header_data
  @header_data
end

#labelsObject (readonly)

Returns the value of attribute labels.



6
7
8
# File 'lib/tp_plus/interpreter.rb', line 6

def labels
  @labels
end

#line_countObject

Returns the value of attribute line_count.



5
6
7
# File 'lib/tp_plus/interpreter.rb', line 5

def line_count
  @line_count
end

#namespacesObject (readonly)

Returns the value of attribute namespaces.



6
7
8
# File 'lib/tp_plus/interpreter.rb', line 6

def namespaces
  @namespaces
end

#nodesObject

Returns the value of attribute nodes.



5
6
7
# File 'lib/tp_plus/interpreter.rb', line 5

def nodes
  @nodes
end

#position_dataObject

Returns the value of attribute position_data.



5
6
7
# File 'lib/tp_plus/interpreter.rb', line 5

def position_data
  @position_data
end

#source_line_countObject (readonly)

Returns the value of attribute source_line_count.



6
7
8
# File 'lib/tp_plus/interpreter.rb', line 6

def source_line_count
  @source_line_count
end

#variablesObject (readonly)

Returns the value of attribute variables.



6
7
8
# File 'lib/tp_plus/interpreter.rb', line 6

def variables
  @variables
end

Instance Method Details

#add_constant(identifier, node) ⇒ Object



54
55
56
57
58
# File 'lib/tp_plus/interpreter.rb', line 54

def add_constant(identifier, node)
  raise "Constant #{identifier} already defined" if @constants[identifier.to_sym]

  @constants[identifier.to_sym] = node
end

#add_label(identifier) ⇒ Object



42
43
44
45
# File 'lib/tp_plus/interpreter.rb', line 42

def add_label(identifier)
  raise "Label @#{identifier} already defined" if @labels[identifier.to_sym]
  @labels[identifier.to_sym] = next_label
end

#add_namespace(name, block) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/tp_plus/interpreter.rb', line 34

def add_namespace(name, block)
  if @namespaces[name.to_sym].nil?
    @namespaces[name.to_sym] = TPPlus::Namespace.new(name, block)
  else
    @namespaces[name.to_sym].reopen!(block)
  end
end

#add_var(identifier, node) ⇒ Object



47
48
49
50
51
52
# File 'lib/tp_plus/interpreter.rb', line 47

def add_var(identifier, node)
  raise "Variable #{identifier} already defined" if @variables[identifier.to_sym]

  @variables[identifier.to_sym] = node
  node.comment = identifier
end

#define_labelsObject



80
81
82
83
84
# File 'lib/tp_plus/interpreter.rb', line 80

def define_labels
  @nodes.select {|n| n.is_a? Nodes::LabelDefinitionNode}.each do |n|
    add_label(n.identifier)
  end
end

#evalObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/tp_plus/interpreter.rb', line 123

def eval
  s = ""
  last_node = nil

  define_labels

  @source_line_count = 0

  @nodes.each do |n|
    @source_line_count += 1 unless n.is_a?(Nodes::TerminatorNode) && !last_node.is_a?(Nodes::TerminatorNode)
    raise if n.is_a?(String)

    res = n.eval(self)

    # preserve whitespace
    if n.is_a?(Nodes::TerminatorNode) && last_node.is_a?(Nodes::TerminatorNode)
      s += " ;\n"
    end
    last_node = n
    # end preserve whitespace

    next if res.nil?

    s += "#{res} ;\n"
  end
  s
rescue RuntimeError => e
  raise "Runtime error on line #{@source_line_count}:\n#{e}"
end

#get_constant(identifier) ⇒ Object



74
75
76
77
78
# File 'lib/tp_plus/interpreter.rb', line 74

def get_constant(identifier)
  raise "Constant (#{identifier}) not defined" if @constants[identifier.to_sym].nil?

  @constants[identifier.to_sym]
end

#get_namespace(identifier) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/tp_plus/interpreter.rb', line 60

def get_namespace(identifier)
  if ns = @namespaces[identifier.to_sym]
    return ns
  end

  false
end

#get_var(identifier) ⇒ Object



68
69
70
71
72
# File 'lib/tp_plus/interpreter.rb', line 68

def get_var(identifier)
  raise "Variable (#{identifier}) not defined" if @variables[identifier.to_sym].nil?

  @variables[identifier.to_sym]
end

#load_environment(string) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/tp_plus/interpreter.rb', line 20

def load_environment(string)
  scanner = TPPlus::Scanner.new
  parser = TPPlus::Parser.new(scanner, self)
  scanner.scan_setup(string)
  parser.parse
  eval
rescue RuntimeError => e
  raise "Runtime error in environment on line #{@source_line_count}:\n#{e}"
end

#next_labelObject



30
31
32
# File 'lib/tp_plus/interpreter.rb', line 30

def next_label
  @current_label += 1
end

#pos_return(position_hash) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/tp_plus/interpreter.rb', line 101

def pos_return(position_hash)
  s = ""
  if position_hash[:config].is_a?(Hash)
    s << %(   GP#{position_hash[:group]}:
  UF : #{position_hash[:uframe]}, UT : #{position_hash[:utool]},  CONFIG : '#{position_hash[:config][:flip] ? 'F' : 'N'} #{position_hash[:config][:up] ? 'U' : 'D'} #{position_hash[:config][:top] ? 'T' : 'B'}, #{position_hash[:config][:turn_counts].join(', ')}',
  X = #{position_hash[:components][:x]} mm, Y = #{position_hash[:components][:y]} mm, Z = #{position_hash[:components][:z]} mm,
  W = #{position_hash[:components][:w]} deg, P = #{position_hash[:components][:p]} deg, R = #{position_hash[:components][:r]} deg)
  else
    s << %(   GP#{position_hash[:group]}:
  UF : #{position_hash[:uframe]}, UT : #{position_hash[:utool]})
    if position_hash[:components].is_a?(Hash)
      position_hash[:components].each_with_index do |key, joint|
        s << %(, \n)
        s << %(\tJ#{key} = #{joint[1]} deg)
      end
      s << %(\n)
    end
  end

  return s
end

#pos_sectionObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/tp_plus/interpreter.rb', line 86

def pos_section
  return "" if @position_data.empty?
  return "" if @position_data[:positions].empty?

  @position_data[:positions].inject("") do |s,p|
    s << %(P[#{p[:id]}:"#{p[:comment]}"]{\n)

    p[:mask].each do |q|
      s << pos_return(q)
    end

    s << %(\n};\n)
  end
end