class HDLRuby::Checker

Describes a HDLRuby code checker.

Public Class Methods

new(code,filename = nil) click to toggle source

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

# 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

Public Instance Methods

assign_check(code = @code) click to toggle source

Check for invalid assignments in code.

# File lib/HDLRuby/hruby_check.rb, line 258
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) click to toggle source

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.

# File lib/HDLRuby/hruby_check.rb, line 288
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) click to toggle source

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

# File lib/HDLRuby/hruby_check.rb, line 159
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) click to toggle source

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

# File lib/HDLRuby/hruby_check.rb, line 193
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) click to toggle source

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

# File lib/HDLRuby/hruby_check.rb, line 133
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_require_relatives(code = @code) click to toggle source

Gets all the require_relative files of code.

# File lib/HDLRuby/hruby_check.rb, line 79
def get_all_require_relatives(code = @code)
    if code.is_a?(Array) then
        require_relatives = (code.select { |sub| is_require_relative?(sub) }).map! do |sub|
            get_require_relative(sub)
        end
        code.each do |sub|
            require_relatives += get_all_require_relatives(sub)
        end
        return require_relatives
    else
        return []
    end
end
get_all_requires(code = @code) click to toggle source

Gets all the required files of code.

# File lib/HDLRuby/hruby_check.rb, line 64
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) click to toggle source

Gets all the systems of code.

# File lib/HDLRuby/hruby_check.rb, line 105
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) click to toggle source

Gets the assigned variable in code.

# File lib/HDLRuby/hruby_check.rb, line 206
def get_assign_variable(code)
    return code[1][1]
end
get_hdr_declares(code) click to toggle source

Gets the HDLRuby names declared from code.

Note: assumes code is indeed a declaration.

# File lib/HDLRuby/hruby_check.rb, line 235
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) click to toggle source

Get the system of an include in code.

# File lib/HDLRuby/hruby_check.rb, line 153
def get_include_system(code)
    return code[2][1][1]
end
get_inherit_systems(code) click to toggle source

Get the inherted systems of an inheritance in code.

# File lib/HDLRuby/hruby_check.rb, line 179
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) click to toggle source

Get the system of an instance in code.

# File lib/HDLRuby/hruby_check.rb, line 127
def get_instance_system(code)
    return code[1][1]
end
get_line(code) click to toggle source

Gets the line of a code.

# File lib/HDLRuby/hruby_check.rb, line 248
def get_line(code)
    return code[2][0]
end
get_name(code) click to toggle source

Gets the variable name of a code.

# File lib/HDLRuby/hruby_check.rb, line 253
def get_name(code)
    return code[1]
end
get_require(code) click to toggle source

Gets the required file from code.

# File lib/HDLRuby/hruby_check.rb, line 57
def get_require(code)
    # return (code[0][2][1][0][1][1][1])
    return (code[2][1][0][1][1][1])
end
Also aliased as: get_require_relative
get_require_relative(code)
Alias for: get_require
get_system(code) click to toggle source

Gets the system name in code.

# File lib/HDLRuby/hruby_check.rb, line 100
def get_system(code)
    return code[2][1][0][1][1][1]
end
has_name_deep?(code, name) click to toggle source

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

# 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) click to toggle source

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

# File lib/HDLRuby/hruby_check.rb, line 227
def is_hdr_declare?(code, systems)
    return is_system?(code) || is_signal_declare?(code) ||
        is_instance_declare?(code, systems)
end
is_include?(code,systems) click to toggle source

Tells is code is an include of one of systems.

# File lib/HDLRuby/hruby_check.rb, line 141
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) click to toggle source

Tells is code is an inheritance of one of systems.

# File lib/HDLRuby/hruby_check.rb, line 167
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) click to toggle source

Tells is code is an instance of one of systems.

# File lib/HDLRuby/hruby_check.rb, line 114
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) click to toggle source

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

# File lib/HDLRuby/hruby_check.rb, line 220
def is_instance_declare?(code,systems)
    return code[0] == :command &&
        systems.find {|sys| has_name_deep?(code,sys) }
end
is_require?(code) click to toggle source

Tells if code is a require description.

# 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_require_relative?(code) click to toggle source

Tells if code is require_relative description.

# File lib/HDLRuby/hruby_check.rb, line 49
def is_require_relative?(code)
    # return code[0] && (code[0][0] == :command) &&
    #        (code[0][1][1] == "require_relative")
    return code && (code[0] == :command) &&
           (code[1][1] == "require_relative")
end
is_signal_declare?(code) click to toggle source

Tells if code is a signal declaration.

# File lib/HDLRuby/hruby_check.rb, line 211
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) click to toggle source

Tells if code is a system description.

# File lib/HDLRuby/hruby_check.rb, line 94
def is_system?(code)
    return code.is_a?(Array) && (code[0] == :command) &&
                                (code[1][1] == "system")
end
is_variable_assign?(code) click to toggle source

Tells if code is a variable assignment.

# File lib/HDLRuby/hruby_check.rb, line 201
def is_variable_assign?(code)
    return (code[0] == :assign) && (code[1][1][0] == :@ident)
end
show(output = $stout) click to toggle source

Displays the full syntax tree.

# File lib/HDLRuby/hruby_check.rb, line 27
def show(output = $stout)
    pp(@code,output)
end