Class: OrigenVerilog::Preprocessor::Processor

Inherits:
OrigenVerilog::Processor show all
Defined in:
lib/origen_verilog/preprocessor/processor.rb

Defined Under Namespace

Classes: Define

Instance Method Summary collapse

Methods inherited from OrigenVerilog::Processor

#handler_missing, #inline, #process, #process_all

Instance Method Details

#on_define(node) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/origen_verilog/preprocessor/processor.rb', line 29

def on_define(node)
  n = node.find(:name)
  name = n.to_a[0]
  if a = n.find(:arguments)
    args = a.to_a
  end
  if n = node.find(:text)
    text = n.to_a.first
  end
  env[name] = Define.new(name: name, args: args, text: text)
  nil
end

#on_else(node) ⇒ Object Also known as: on_elsif



105
106
107
# File 'lib/origen_verilog/preprocessor/processor.rb', line 105

def on_else(node)
  # Do nothing, will be processed by the ifdef handler if required
end

#on_ifdef(node) ⇒ Object Also known as: on_ifndef



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
83
84
85
86
87
88
# File 'lib/origen_verilog/preprocessor/processor.rb', line 46

def on_ifdef(node)
  elsif_nodes = node.find_all(:elsif)
  else_node = node.find(:else)
  enable, *nodes = *node

  # The number of lines needs to be tracked here and blank lines (nil) are injected in place
  # of un-enabled ifdef branches so that the source file line numbers will be reported correctly
  # later in the Verilog parse stage
  prelines = 0
  postlines = 0

  if node.type == :ifdef ? env[enable] : !env[enable]
    content = process_all(nodes)
  else
    prelines += node.number_of_lines + 1
  end

  elsif_nodes.each do |elsif_node|
    enable, *nodes = *elsif_node
    if !content && env[enable]
      content = process_all(nodes)
    else
      if content
        postlines += elsif_node.number_of_lines + 1
      else
        prelines += elsif_node.number_of_lines + 1
      end
    end
  end

  if else_node
    if content
      postlines += else_node.number_of_lines + 1
    else
      content = process_all(else_node.children)
    end
  end

  prelines = node.updated(:text_block, ["\n" * prelines])
  postlines = node.updated(:text_block, ["\n" * postlines])

  inline([prelines] + (content || []) + [postlines])
end

#on_include(node) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/origen_verilog/preprocessor/processor.rb', line 10

def on_include(node)
  path = node.to_a[0]
  file = path if File.exist?(path)
  unless file
    dir = ([Dir.pwd] + Array(env[:source_dirs])).find do |dir|
      f = File.join(dir, path)
      File.exist?(f)
    end
    file = File.join(dir, path) if dir
  end
  unless file
    puts "The file #{path} could not be found!"
    puts "#{node.file}:#{node.line_number}"
    exit 1
  end
  nodes = process(Parser.parse_file(file)).children
  node.updated(:file, [file] + nodes)
end

#on_macro_reference(node) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/origen_verilog/preprocessor/processor.rb', line 91

def on_macro_reference(node)
  if define = env[node.to_a[0]]
    if a = node.find(:arguments)
      args = a.to_a
    end
    node.updated(:text_block, [define.value(node, args)])

  else
    puts "A reference has been made to macro #{node.to_a[0]} but it hasn't been defined yet!"
    puts "#{node.file}:#{node.line_number}"
    exit 1
  end
end

#on_undef(node) ⇒ Object



42
43
44
# File 'lib/origen_verilog/preprocessor/processor.rb', line 42

def on_undef(node)
  env[node.to_a[0]] = nil
end

#run(ast, env) ⇒ Object



4
5
6
7
8
# File 'lib/origen_verilog/preprocessor/processor.rb', line 4

def run(ast, env)
  @env = env
  ast = process(ast)
  Concatenator.new.run(ast)
end