SKILL Lint Features
Listed below are some of the SKILL Lint features.
Check the Number of Function Arguments
SKILL Lint checks that the number of arguments passed to a function is correct by verifying it against a previously-known definition of the function from a previous SKILL Lint session or a previous declaration. SKILL Lint delays checking the number of arguments until it finds the procedure definition.
If a procedure is used in a file before it is defined in the same file and the number of arguments to the procedure changes, it may be necessary to run SKILL Lint twice to get accurate results because the first run will use the previous declaration of the procedure.
Check Function and Global Variable Prefixes
Functions and global variables used in SKILL code are expected to be prefixed with a suitable string. You type these strings in the Package Prefixes field on the
The naming policy for functions and global variables is as follows:
- Cadence-official SKILL functions and global variables must start with a lower-case character, while three characters and all lower-case are preferred. Cadence-official SKILL functions include those functions that are documented and supported.
- Customer SKILL functions and global variables, and any functions that are not documented or supported, must start with an upper-case character.
-
Functions or global variables must start with the required prefix, or the prefix plus an optional lower-case character followed immediately by an upper-case character or an underscore,
_. The optional lower-case character must be one of the following:b,c,e,f,i,m, orv. So, the two syntax forms for the functions or variables will be as follows:-
prefix + ([
A-Z] | '_') + rest -
prefix + ('
b' | 'c' | 'e' | 'f' | 'i' | 'm' | 'v') + ([A-Z], '_') + rest
Examples:
EV1varis flagged because the character afterEV1v'a' is not ([A-Z] | '_').
EV1vAris not flagged because the letter afterEV1v'A' is ([A-Z] | '_').
EV1v_ris not flagged because the letter afterEV1v'_' is in ([A-Z] | '_').
EV1d_ris flagged because the letter afterEV1'd' is not in the accepted set.
EV1_aris not flagged because the letter afterEV1is '_'. -
prefix + ([
You can turn off strict checking by disabling the STRICT
Check SKILL Operators
SKILL Lint reports the SKILL operators used in the SKILL code. The following operators are supported in SKILL:
- &&, ||, !, <<, and >> (logical operators)
- ~, &, ~&, ^, ~^, |, and ~| (bitwise logical operators)
- <, <=, >, >=, ==, != (relational operators)
- **, *, /, +, -, ++s, s++, --s, s--, - (arithmetic operators)
- = (assignment operator)
- : (range operator)
Check Redefinition of Write-protected Functions and Macros
SKILL Lint reports an error if the input name of an expression, defun, defmacro, mprocedure, nprocedure, or procedure is the name of a write-protected function or macro. For example, SKILL Lint will report an error for the following code because lindex is a write-protected function:
procedure( lindex(@optional (input1 "hello") (input2 "hi") ) printf("\n%s %s" input1 input2)
)
Check Files Based on the Extension of the Input File (*.il/ *.ils/ *.scm)
SKILL Lint performs SKILL or SKILL++ language checks based on the extension, .il, .ils, or .scm of the input file for sklint. If the extension of the input file is .il, SKILL Lint applies SKILL language checks and if the extension of the input file is .ils, SKILL Lint applies SKILL++ language checks. It also applies SKILL++ language checks for the files with the extension .scm.
For example, SKILL Lint will report errors if the Scheme code displayed below is included in a file with extension .il.
defun( f1 (a b) let( (f (lambda((x) x*x)) ) (f a+b)
)
Execute Code Blocks Placed Inside inSkill() and inScheme()
Before describing the following feature, it is important to reiterate that in the SKILL programming environment, Scheme mode describes SKILL++ code that is saved in a file with the .ils extension or enclosed in the inScheme() function. Similarly, SKILL mode describes SKILL code saved in a file with .il extension or enclosed in the inSkill() function.
Starting from IC6.1.6, SKILL Lint executes source code placed in the inScheme() function as SKILL++ language code even if the code is placed in a file with extension *.il. For example, SKILL Lint executes the following Scheme code correctly even though it is placed inside a file with extension .il
(let (v1 v2) v1 = v2 = 0 (inScheme vf = (lambda () 'some_value))
) ; "vf" global Scheme function is defined inside inScheme() block
SKILL Lint understands the code (in Bold) as SKILL++ or Scheme code. In this example, vf is considered a Scheme function and not as a symbol.
Consider the following example where the code is placed inside a file with extension .ils
(let (v1 v2) v1 = v2 = 0 (inSkill vf = (lambda () 'some_value))
) ; "vf" global Scheme function is defined inside inScheme() block
SKILL Lint understands the code (in Bold) as SKILL code. In this example, SKILL Lint will report errors because the expression related to vf function is in basic SKILL, which does not support local functions.
Check For Matching Global and Local Variable Names
SKILL Lint allows the name of a local variable to match that of a global variable and does not report the variable as being used before definition in a let assignment. In the example below, the name VAR has been used for both local and global variables.
(defvar VAR)
(defun ListGen (n)
(let ( (VAR (cons n VAR)) )
(info "The value of local variable VAR: %L\n" VAR)
(setq VAR (if (plusp n) (ListGen (sub1 n)) (cdr VAR)))
)
)
(info "Global variable VAR before function call: %L\n" VAR)
(info "Function call result: %L\n" (ListGen 3))
(info "Global variable VAR after function call: %L\n" VAR)
After the lint run, the following output is printed in the CIW:
Global variable VAR before function call: nil
The value of local variable VAR: (3)
The value of local variable VAR: (2 3)
The value of local variable VAR: (1 2 3)
The value of local variable VAR: (0 1 2 3)
Function call result: (1 2 3)
Global variable VAR after function call: nil
SKILL Lint understands that the variable VAR has been used as both global and local variable and does not report a warning on line 3 for it being used before available in a let assignment.
Support Local Functions in the Scheme Mode
In the Scheme mode (files with extension .ils), SKILL Lint recognizes local functions to be defined inside let, letseq, letrec, setq, flet, and labels blocks. This means that SKILL Lint allows local functions to be added as a list of valid variables and does not report them as unused variables even if they are not referenced or used. In the example shown below, f1 is a local function that is considered as a variable in the let block.
let( (
((f1 lambda(() println("f1()")))
f1()
SKILL Lint applies special checks for Scheme code (files with extension .ils/.scm), if a function is defined as global function/procedure or if a local function is not defined inside the let, letseq, or letrec block.
Support Local Arguments in the Scheme Mode
In the Scheme mode, SKILL Lint recognizes local arguments defined via @key, @optional, and @aux options. For example, the following constructs are valid in the Scheme mode:
procedure( test1( arg11 @key (arg12 arg11) )
(progn
(println "In function test1")
(assert arg11 == arg12)
)
)
procedure( test2( arg21 @optional (arg22 arg21) )
(progn
(println "In function test2")
(assert arg21 == arg22)
)
)
(defun test11 ( arg111 @key (arg112 arg111) )
(progn
(println "In function test11")
(assert arg111 == arg112)
)
)
(defun test21 ( arg211 @optional (arg212 arg211) )
(progn
(println "In function test21")
(assert arg211 == arg212)
)
)
(inScheme
(defun smartlessp2 (arg1 arg2 @aux fn)
(cond
((and (numberp arg1) (numberp arg2)) (setq fn lessp) )
((and (symstrp arg1) (symstrp arg2)) (setq fn alphalessp) )
)
(if fn (fn arg1 arg2) -1)
)
(defvar A (list 3.0 1.0 "as" "df" 7))
(defvar B (list 1.0 5.0 "asd" "ca" "gh"))
(info "Test AUX:\n")
(foreach (itA itB) A B (info "%L < %L: %L\n" itA itB (smartlessp2 itA itB)))
)
Support Assignment of Functions as Variables in Scheme Mode
In the Scheme mode, SKILL Lint recognizes the use of local functions as variables that are defined inside the setq, getq, getd, putd, and defun and procedure blocks. See the following examples.
This example shows the assignment of a variable to a function in a setq block. SKILL Lint considers the function smartless() as a local function in the Scheme mode.
defun( smartless (arg1 arg2)
let( ( (fn nil) (ret nil) )
if( (and (numberp arg1) (numberp arg2))
then
setq( fn lessp)
else
(when (and (symstrp arg1) (symstrp arg2))
setq( fn alphalessp))
)
(when fn (setq ret (fn arg1 arg2)))
ret
)
)
In this example, SKILL Lint considers the code ((getq obj1 funcObj) val) as a function call.
inScheme( defun( funcInst (x) x*x)
defstruct( myStruct funcObj)
defclass( testClass () ((intVar @initarg intVar)))
let( (obj classObj obj1 (val 3))
setq( obj (make_myStruct ?funcObj funcInst))
setq( classObj (makeInstance 'testClass ?intVar obj))
setq( obj1 (getq classObj intVar))
info( "%L\n" ((getq obj1 funcObj) val))
)
)
In the following example, the function myFunc1() is defined as a local function that has one argument. SKILL Lint considers myFunc1 as a function and checks for the number of input arguments.
let( ()
putd( 'myFunc1 (getd 'exp))
)
info( "Result: %L\n" (myFunc1 1 2))
In this example, SKILL Lint considers exp() as a local function.
putd( 'myFunc2 exp)
In the following example, smartlessp() is defined by using the defun() function and then assigned to a variable newFn. In the Scheme mode, SKILL Lint considers the variable, newFn, as a SKILL++ function. This new SKILL++ function, newFn, is further assigned to another variable func1. Therefore, SKILL Lint considers both newFn and func1 as SKILL++ functions.
defun( smartlessp (arg1 arg2)
let( ( fn )
cond(
((and (numberp arg1) (numberp arg2)) (setq fn lessp) )
((and (symstrp arg1) (symstrp arg2)) (setq fn alphalessp) )
)
(if fn (fn arg1 arg2) -1)
)
)
newFn = smartlessp
func1 = newFn
info( "A: %L\n" (newFn (list 1) (list 2)))
info( "B: %L\n" (newFn 1 2))
info( "C: %L\n" (newFn "str2" "str3"))
Support of SKILL++ Features in SKILL Lint
SKILL Lint supports the following SKILL++ features:
-
Recognizes multi-methods or methods specialized on more than one argument, such as the
@before,@after, and@aroundmethods. -
Considers an argument of the
defmethodbeginning with an underscore `_? as a valid character and generates only aninfomessage. In the earlier releases, SKILL Lint treated such arguments as invalid and generated warnings. - Displays warning messages if functions are incorrectly referenced as SKILL public functions and not as SKILL++ functions.
-
Recognizes multiple inheritance of classes created using
defclass.
Related Topics
SKILL Lint PASS/FAIL and IQ Algorithms
Return to top