class HDLRuby::Checker
Describes a HDLRuby
code checker.
Public Class Methods
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
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
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 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 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 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
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
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
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
Gets the assigned variable in code
.
# File lib/HDLRuby/hruby_check.rb, line 206 def get_assign_variable(code) return code[1][1] end
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 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 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 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
Gets the line of a code.
# File lib/HDLRuby/hruby_check.rb, line 248 def get_line(code) return code[2][0] end
Gets the variable name of a code.
# File lib/HDLRuby/hruby_check.rb, line 253 def get_name(code) return code[1] end
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
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
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
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
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
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
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
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
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
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
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
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
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
Displays the full syntax tree.
# File lib/HDLRuby/hruby_check.rb, line 27 def show(output = $stout) pp(@code,output) end