Module: Emfrp::NodeCheck

Extended by:
NodeCheck
Included in:
NodeCheck
Defined in:
lib/emfrp/pre_convert/node_check.rb

Instance Method Summary collapse

Instance Method Details

#circular_check(nodes, inputs, node) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/emfrp/pre_convert/node_check.rb', line 29

def circular_check(nodes, inputs, node)
  node[:mark] = true
  node[:params].each do |x|
    if x.is_a?(NodeRef) && !x[:last] && !inputs.find{|i| i[:name] == x[:name]}
      depended_node = nodes.select{|y| y[:name] == x[:name]}.first
      unless depended_node
        PreConvert.err(:undef, "Undefined node `#{x[:as][:desc]}` is referred:\n", x)
      end
      if depended_node[:mark] == true
        trace = ([x] + get_trace(node)).reverse
        s = "[#{trace.rotate(-1).map{|x| "`#{x[:name][:desc]}`"}.join(" -> ")} -> ...]"
        PreConvert.err(:circular, "Circular node-dependency #{s} is detected.\n", *trace)
      end
      depended_node[:prev] = node
      circular_check(nodes, inputs, depended_node)
    end
  end
  node[:mark] = false
end

#get_trace(node) ⇒ Object



49
50
51
52
53
54
55
56
57
58
# File 'lib/emfrp/pre_convert/node_check.rb', line 49

def get_trace(node)
  trace = []
  n = node
  until n[:prev] == nil || trace.include?(n)
    ref = n[:prev][:params].find{|param| param.is_a?(NodeRef) && param[:as] == n[:name]}
    trace << ref
    n = n[:prev]
  end
  return trace
end

#node_check(top) ⇒ Object



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

def node_check(top)
  top[:nodes].each do |n|
    n[:params].each do |node_ref|
      if node_ref.is_a?(NodeRef) && node_ref[:last]
        depended_node = (top[:nodes] + top[:inputs]).select{|x| x[:name] == node_ref[:name]}.first
        unless depended_node[:init_exp]
          PreConvert.err(:noinit, "Node `#{node_ref[:name][:desc]}` having no init-exp is referred with @last:\n", node_ref)
        end
      end
    end
  end
  top[:nodes].each do |n|
    n[:mark] = false
    n[:prev] = nil
  end
  top[:nodes].each do |n|
    circular_check(top[:nodes], top[:inputs], n)
  end
  top[:nodes].each do |n|
    n.delete(:mark)
    n.delete(:prev)
  end
end