Known Limitations¶
Due to the way ipt works it can’t accept all code which Igor Pro allows. In some cases this was also done to avoid excessive effort for what we considered niche issues.
And some limitations are listed here according to our philosophy.
UTF8 source code¶
ipt can only read source files that are encoded in UTF-8 or ASCII. All non UTF-8 code must therefore converted to UTF-8 first.
You can convert the encoding using Igor Pro by following these steps:
Open the code file in Igor Pro
On the bottom left corner of the text editor is a button that tells you the current encoding. Click on it.
A new window opens and asks you to select an encoding. Select
UTF-8.
Click on
Convert to Encoding
Save your file.
Statements outside of functions¶
All statements have to be inside a function, a macro or inside the call statement of a menu item.
print 1 // not supported in ipt, ignored in Igor Pro
Function foo()
print 2 // supported in ipt and Igor Pro
End
Statements before the first case of a switch statement¶
A switch statement is used to execute code depending on a variable or string. Similar like a long chain of if statements but nicer to read. In Igor Pro you can write any statement before the first case of a switch statement. Such code is not allowed according to the documentation but it is ignored by the Igor Pro parser. In ipt such code is not allowed.
switch(var)
print "before" // not supported in ipt, ignored in Igor Pro
case 1:
print "first case"
break
endswitch
Unbalanced parenthesis¶
In Igor Pro it is possible to omit closing parenthesis or add additional ones at certain places. In ipt all parenthesis must be balanced! Unbalanced parenthesis are treated as a parsing error.
// note the missing parenthesis here: -------------------------v
MatrixOP/FREE rms = sqrt(sumSqr(data - avg[0]) / numRows(data)
Context breaking #if statements¶
#if denotes if the contained code should be compiled or not. This
is done in Igor Pro before the contained code is compiled. In ipt all code
is compiled into an AST first.
Therefore some code has to be written differently:
switch(var)
case 1:
#if condition
case 2:
#endif
print "<=2"
endswitch
switch(var)
#if condition
case 2:
#endif
case 1:
print "<=2"
endswitch
Other statements have to be refactored:
// Difficult to understand even for the user
if(var)
print "some work"
#if condition
endif
#endif
print "other work"
#if !condition
endif
#endif
// A variant on how this can be refactored
if(var)
print "some work"
print "other work"
else
#if condition
print "other work"
#endif
endif
End Function and End Macro¶
Those are not supported in ipt and not allowed according to the Igor
documentation. The Igor Pro parser itself ignores everything after the End.
If you want to mark if this is a macro or function, just use EndMacro for
macros (as documented) or write a normal comment.
Function test()
End Function
Superfluous #else branches¶
In some scenarios it is possible to have multiple #else expressions in Igor
Pro. This is not supported in ipt.
#if condition
Function TestA() // will be visible if condition != 0
End
#else
Function TestB() // will be visible if condition == 0
End
#else
Function TestC() // will never be visible
End
#endif
Omitting commas in function arguments¶
Each argument of a function call must be delimited with a single comma. In Igor Pro its possible to omit some of them.
stringmatch(S_MarqueeWin"Graph")
// missing comma here: ^
No delimiter between operation arguments¶
Ipt expects at least one whitespace character or comma between operation arguments and cannot parse them without one.
sprintf cmd"format %s"name
We recommend putting a comma between each operation argument and adding a single space after each one.
sprintf cmd, "format %s", name
Whitespace between function name and argument parenthesis¶
Ipt cannot parse function calls with a whitespace between the function name and the argument parenthesis.
PadString ("", 10, 0x20)
Similar is for string or wave access:
waveName [1]
stringName [1, 2]
If you have some cases like this in your code base, ipt might show some unrelated errors to the function call.
Superfluous commas in declarations¶
Igor Pro allows commas between the type and the first name, allthough the documentation doesn’t support that idea. In ipt this isn’t supported.
STRUCT MyStructureName, myStr
// superfluous comma: ^
Division in some operation arguments¶
The symbol / is used in Igor for division and as a marker for operation
flags. Some operations can also have argument flags that are only applied
to that specific argument.
Only certain operations do allow flags for their arguments and ipt does only
allow flags for these operations. If a flag is allowed for the current argument,
ipt consideres every / as a start of the argument flag and no division is
allowed.
// considered as the start of the argument flag
// v
Differentiate/EP=0 sourcewave/D=testwave
// ^^^^^^^^^^^
// (argument flag)
You can circumvent this limitation by surrounding the expression with parenthesis:
// Lets ignore that this code is invalid Igor code but this is how you would
// circumvent the limitations for arguments that do allow operation flags
// and you want to have a division:
// v
Differentiate/EP=0 (sourcewave/D)
If this argument is a key value pair, all / are considered as
argument flags in the key part and all / are considered as division in the
value part.
// This argument consists of a key value pair and has two / with different
// usages: start of flag division
// v v
Make $nameForOutputWave/WAVE=w = p / 2.0
// ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^
// key of argument value of argument
If argument flags are not allowed (default in most cases) all / are parsed
as divisions.
// Always a division:
// v
print nameOfVar / 2
Operators in flag values¶
Flags can have values attached like in /Name=value. In ipt you cannot
use operations like +, -, * or / in value. If you
want to use them, you have to surround it with parentheses as in /Name=(value1 + value2).
This is the case for most operations in Igor Pro.
If you use reference strings you can always use the + operator to add more
parts (like /Name=$part1 + part2) . Although good style suggests to write that in
a separate statement.
AS and VS as variable names¶
AS and VS are used as reserved keywords in operations and ipt doesn’t
allow their usage as variable names. This limitation doesn’t exists in Igor Pro.
Encrypted code¶
Encrypted code is not supported in ipt and results in a parsing error.
Double assignments¶
Double assignments are not allowed and will be treated as a parsing error. In Igor Pro its allowed in some operations currently:
MatrixOp/O wv1=wv2=sum(w)
Return values in macros¶
According to the Igor Pro documentation return can not be used inside
macros. In ipt this is considered a parsing error, in Igor Pro that is ignored.
Macro Test()
return 1 // no return value allowed
EndMacro
Some global statements require whitespaces¶
The global statements #include, #pragma, #ifdef, #ifndef,
#if, #elif and #define must have at least one whitespace character
following:
#include "tools"
Recursive re-evaluation of linting rules¶
Some linting rules do not produce the optimal fix for the given code. This can happen if another rule can be applied to the first rule’s fix, or if the behavior of a rule changes if the fix were present in the first place. To illustrate this, let’s assume we have the following code:
if(condition1)
if(condition2)
return result1
else
return result2
endif
else
print "something"
endif
After calling ipt lint for the first time, we get the following result:
ipt lint --fix¶if(condition1)
if(condition2)
return result1
endif
return result2
else
print "something"
endif
And calling ipt lint again, we get:
ipt lint --fix¶if(condition1)
if(condition2)
return result1
endif
return result2
endif
print "something"
This recursive dependency is not limited to the applied fixes. This can also apply to linting error messages, as it can be seen here:
switch(value)
case CASE_1:
if(condition)
return result1
else
return result2
endif
endswitch
In the first iteration of calling ipt lint you will get an error message
from the rule CodeStyleFallthroughCaseRequireComment that a break is
missing for the switch case CASE_1. This is because the rule only checks
top-level statements and does not create a full control flow graph.
ipt lint --fix¶switch(value)
case CASE_1:
if(condition)
return result1
endif
return result2
endswitch
After calling ipt lint again on the previous output of ipt lint --fix, there
will be no longer an error message from the rule
CodeStyleFallthroughCaseRequireComment.
This limitation does only apply to ipt lint --fix. If you do not specify
--fix, there is no implication. The best workaround for this limitation is,
to just execute ipt lint --fix multiple times until they are no changes to
the fixed files and use the error messages from the last iteration.