Class: HDLRuby::Checker

Inherits:
Object
  • Object
show all
Defined in:
lib/HDLRuby/hruby_check.rb

Overview

Describes a HDLRuby code checker.

Instance Method Summary collapse

Constructor Details

#initialize(code, filename = nil) ⇒ Checker

Create a new checker on +code+ string, from +filename+ file. Returns a list of error and the related object and method.



19
20
21
22
23
24
# File 'lib/HDLRuby/hruby_check.rb', line 19

def initialize(code,filename = nil)
    @code = Ripper.sexp(code.to_s,filename ? filename : "-", 1)
    @code ||= [] # In case the parse failed
    @filename = filename
    # puts "@code=#{@code}"
end

Instance Method Details

#assign_check(code = @code) ⇒ Object

Check for invalid assignments in +code+.



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/HDLRuby/hruby_check.rb', line 234

def assign_check(code = @code)
    system_check = false # Flag telling if the internal of a system
                         # is reached.
    hdr_names = []       # The existing HDLRuby names, they cannot be
                         # used as Ruby variables.
    code.each do |subcode|
        if system_check then
            # Internal of a system, do a specific check.
            assign_check_in_system(subcode,hdr_names.clone)
            system_check = false
        elsif subcode.is_a?(Array) then
            if (self.is_hdr_declare?(code,hdr_names)) then
                # New HDLRuby name, add them to the hdr names.
                hdr_names.concat(self.get_hdr_declares(code))
            end
            if self.is_system?(subcode) then
                # The current subcode is a system, the next one will
                # be its internal.
                system_check = true
            else
                # Go on cheking recursively.
                self.assign_check(subcode)
            end
        end
    end
end

#assign_check_in_system(code, hdr_names) ⇒ Object

Check for invalid assignments in +code+ assuming being within a system. For that purpose assigned names are look for in +hdr_names+ that includes the current HDLRuby names.



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/HDLRuby/hruby_check.rb', line 264

def assign_check_in_system(code, hdr_names)
    # puts "hdr_names=#{hdr_names}"
    if (self.is_hdr_declare?(code,hdr_names)) then
        # New HDLRuby names, add them to the hdr names.
        hdr_names.concat(self.get_hdr_declares(code))
    elsif (self.is_variable_assign?(code)) then
        var = self.get_assign_variable(code)
        # puts "var=#{var} and hdr_names=#{hdr_names}"
        if hdr_names.include?(var[1]) then
            # An HDLRuby name is overwritten.
            if @filename then
                warn("*WARNING* In file '#{@filename}': ")
            else
                warn("*WARNING*")
            end
            warn("Potential invalid assignment for '#{self.get_name(var)}' at line #{self.get_line(var)}")
        end
    else
        # Go on checking recursively.
        code.each do |subcode|
            if subcode.is_a?(Array) then
                self.assign_check_in_system(subcode,hdr_names)
            end
        end
    end
end

#get_all_includes(systems, code = @code) ⇒ Object

Get all the include in +code+ of +systems+. NOTE: return the sub code describing the include.



135
136
137
138
139
140
# File 'lib/HDLRuby/hruby_check.rb', line 135

def get_all_includes(systems,code = @code)
    return [] unless code.is_a?(Array)
    return code.reduce([]) do |ar,sub|
        ar + get_all_includes(systems,sub)
    end + (code.select { |sub| is_include?(sub,systems) }).to_a
end

#get_all_inherits(systems, code = @code) ⇒ Object

Get all the inherited system in +code+ of +systems+. NOTE: return the sub code describing the include.



169
170
171
172
173
174
# File 'lib/HDLRuby/hruby_check.rb', line 169

def get_all_inherits(systems,code = @code)
    return [] unless code.is_a?(Array)
    return code.reduce([]) do |ar,sub|
        ar + get_all_inherits(systems,sub)
    end + (code.select { |sub| is_inherit?(sub,systems) }).to_a
end

#get_all_instances(systems, code = @code) ⇒ Object

Get all the instances in +code+ of +systems+. NOTE: return the sub code describing the instantiation.



109
110
111
112
113
114
# File 'lib/HDLRuby/hruby_check.rb', line 109

def get_all_instances(systems,code = @code)
    return [] unless code.is_a?(Array)
    return code.reduce([]) do |ar,sub|
        ar + get_all_instances(systems,sub)
    end + (code.select { |sub| is_instance?(sub,systems) }).to_a
end

#get_all_requires(code = @code) ⇒ Object

Gets all the required files of +code+.



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/HDLRuby/hruby_check.rb', line 55

def get_all_requires(code = @code)
    if code.is_a?(Array) then
        requires = (code.select { |sub| is_require?(sub) }).map! do |sub|
            get_require(sub)
        end
        code.each do |sub|
            requires += get_all_requires(sub)
        end
        return requires
    else
        return []
    end
end

#get_all_systems(code = @code) ⇒ Object

Gets all the required files of +code+.



81
82
83
84
85
86
87
# File 'lib/HDLRuby/hruby_check.rb', line 81

def get_all_systems(code = @code)
    return [] unless code.is_a?(Array)
    return code.reduce([]) {|ar,sub| ar + get_all_systems(sub) } +
        (code.select { |sub| is_system?(sub) }).map! do |sub|
            get_system(sub)
        end
end

#get_assign_variable(code) ⇒ Object

Gets the assigned variable in +code+.



182
183
184
# File 'lib/HDLRuby/hruby_check.rb', line 182

def get_assign_variable(code)
    return code[1][1]
end

#get_hdr_declares(code) ⇒ Object

Gets the HDLRuby names declared from +code+.

Note: assumes code is indeed a declaration.



211
212
213
214
215
216
217
218
219
220
221
# File 'lib/HDLRuby/hruby_check.rb', line 211

def get_hdr_declares(code)
    if code.is_a?(Array) then
        if code[0] == :@ident then
            return [ code[1] ]
        else
            return code.map {|elem| get_hdr_declares(elem) }.flatten
        end
    else
        return []
    end
end

#get_include_system(code) ⇒ Object

Get the system of an include in +code+.



129
130
131
# File 'lib/HDLRuby/hruby_check.rb', line 129

def get_include_system(code)
    return code[2][1][1]
end

#get_inherit_systems(code) ⇒ Object

Get the inherted systems of an inheritance in +code+.



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/HDLRuby/hruby_check.rb', line 155

def get_inherit_systems(code)
    res = []
    code[2][1][1..-1].each do |field|
        if (field[0] == :command) then
            res << field[1][1]
        elsif (field[0] == :method_add_arg) then
            res << field[1][1][1]
        end
    end
    return res
end

#get_instance_system(code) ⇒ Object

Get the system of an instance in +code+.



103
104
105
# File 'lib/HDLRuby/hruby_check.rb', line 103

def get_instance_system(code)
    return code[1][1]
end

#get_line(code) ⇒ Object

Gets the line of a code.



224
225
226
# File 'lib/HDLRuby/hruby_check.rb', line 224

def get_line(code)
    return code[2][0]
end

#get_name(code) ⇒ Object

Gets the variable name of a code.



229
230
231
# File 'lib/HDLRuby/hruby_check.rb', line 229

def get_name(code)
    return code[1]
end

#get_require(code) ⇒ Object

Gets the required file from +code+.



49
50
51
52
# File 'lib/HDLRuby/hruby_check.rb', line 49

def get_require(code)
    # return (code[0][2][1][0][1][1][1])
    return (code[2][1][0][1][1][1])
end

#get_system(code) ⇒ Object

Gets the system name in +code+.



76
77
78
# File 'lib/HDLRuby/hruby_check.rb', line 76

def get_system(code)
    return code[2][1][0][1][1][1]
end

#has_name_deep?(code, name) ⇒ Boolean

Tells if +name+ is included in one of the field or subfield of +code+.

Returns:

  • (Boolean)


33
34
35
36
37
38
# File 'lib/HDLRuby/hruby_check.rb', line 33

def has_name_deep?(code, name)
    # Checks recursively.
    return code.find do |field|
        field.is_a?(Array) ? has_name_deep?(field,name) : field == name
    end
end

#is_hdr_declare?(code, systems) ⇒ Boolean

Tells if +code+ is an HDLRuby declaration of a signal or an instance of one of +systems+.

Returns:

  • (Boolean)


203
204
205
206
# File 'lib/HDLRuby/hruby_check.rb', line 203

def is_hdr_declare?(code, systems)
    return is_system?(code) || is_signal_declare?(code) ||
        is_instance_declare?(code, systems)
end

#is_include?(code, systems) ⇒ Boolean

Tells is +code+ is an include of one of +systems+.

Returns:

  • (Boolean)


117
118
119
120
121
122
123
124
125
126
# File 'lib/HDLRuby/hruby_check.rb', line 117

def is_include?(code,systems)
    # Ensures systems is an array.
    systems = [*systems]
    # Check for each system.
    return systems.any? do |system|
        code.is_a?(Array) && (code[0] == :command) &&
                             (code[1][1] == "include") &&
                             (code[2][1][1] == system)
    end
end

#is_inherit?(code, systems) ⇒ Boolean

Tells is +code+ is an inheritance of one of +systems+.

Returns:

  • (Boolean)


143
144
145
146
147
148
149
150
151
152
# File 'lib/HDLRuby/hruby_check.rb', line 143

def is_inherit?(code,systems)
    # Ensures systems is an array.
    systems = [*systems]
    # Check for each system.
    return systems.any? do |system|
        code.is_a?(Array) && (code[0] == :command) &&
                             (code[1][1] == "system") &&
                             (has_name_deep?(code[2][1][1..-1],system))
    end
end

#is_instance?(code, systems) ⇒ Boolean

Tells is +code+ is an instance of one of +systems+.

Returns:

  • (Boolean)


90
91
92
93
94
95
96
97
98
99
100
# File 'lib/HDLRuby/hruby_check.rb', line 90

def is_instance?(code,systems)
    # puts "is_instance? with #{code}"
    # Ensures systems is an array.
    systems = [*systems]
    # Check for each system.
    return systems.any? do |system|
        code.is_a?(Array) && 
            ( (code[0] == :command) || (code[0] == :fcall) ) &&
            (code[1][1] == system)
    end
end

#is_instance_declare?(code, systems) ⇒ Boolean

Tells if +code+ is an instance declaration of one of +systems+.

Returns:

  • (Boolean)


196
197
198
199
# File 'lib/HDLRuby/hruby_check.rb', line 196

def is_instance_declare?(code,systems)
    return code[0] == :command &&
        systems.find {|sys| has_name_deep?(code,sys) }
end

#is_require?(code) ⇒ Boolean

Tells if +code+ is a require description.

Returns:

  • (Boolean)


41
42
43
44
45
46
# File 'lib/HDLRuby/hruby_check.rb', line 41

def is_require?(code)
    # return code[0] && (code[0][0] == :command) &&
    #        (code[0][1][1] == "require")
    return code && (code[0] == :command) &&
           (code[1][1] == "require")
end

#is_signal_declare?(code) ⇒ Boolean

Tells if +code+ is a signal declaration.

Returns:

  • (Boolean)


187
188
189
190
191
192
193
# File 'lib/HDLRuby/hruby_check.rb', line 187

def is_signal_declare?(code)
    return [:command,:command_call].include?(code[0]) &&
        ( has_name_deep?(code,"input") ||
          has_name_deep?(code,"output") ||
          has_name_deep?(code,"inout") ||
          has_name_deep?(code,"inner") )
end

#is_system?(code) ⇒ Boolean

Tells if +code+ is a system description.

Returns:

  • (Boolean)


70
71
72
73
# File 'lib/HDLRuby/hruby_check.rb', line 70

def is_system?(code)
    return code.is_a?(Array) && (code[0] == :command) &&
                                (code[1][1] == "system")
end

#is_variable_assign?(code) ⇒ Boolean

Tells if +code+ is a variable assignment.

Returns:

  • (Boolean)


177
178
179
# File 'lib/HDLRuby/hruby_check.rb', line 177

def is_variable_assign?(code)
    return (code[0] == :assign) && (code[1][1][0] == :@ident)
end

#show(output = $stout) ⇒ Object

Displays the full syntax tree.



27
28
29
# File 'lib/HDLRuby/hruby_check.rb', line 27

def show(output = $stout)
    pp(@code,output)
end