Please enable JavaScript to view this site.

A-Shell Consolidated Reference

The ability to mix string and numeric variables within expressions, which is a common feature of ASB, depends largely on the ability of the compiler to determine when a string-to-numeric or number-to-string conversion is required. For example, the following statement…

If X = Y then P = Q

… could result in multiple compilation variations, depending on the types of the variables involved.  If X is a numeric variable and Y is a string variable, then the compiler will insert a val(Y) to convert Y to a number so that it can be compared directly with X. Similarly, if P is a string variable and Q is a numeric variable or expression, the compiler will insert a str(Q) to convert Q from a number to a string to be able to assign it to the string variable P. So, the statement gets compiled as:

If X = val(Y) then P = str(Q)

In the case of dynamic structures, there is no way for the compiler to determine the member data types since they won’t have been defined yet. In order to avoid paralysis by indecision, it simply assumes that all structure members are of type string. This can lead to misunderstandings when doing arithmetic on numeric members of dynstructs. To avoid such misunderstandings, you have to keep reminding yourself that whenever a dynstruct member appears in an expression, it will be treated like a string, i.e. as if there was a str() function around it in the case of numeric variables.

The main case where this is likely to give you the unintended result is when making assignments to a numeric dynstruct variable from an expression involving the "+" operator, which acts as concatenation when it occurs within a string expression.  For example, assuming ds.qty is a numeric variable, consider:

ds.qty = 1 + 2     ! sets ds.qty to 12 ("1" + "2"), not 3

The problem is that since the compiler thinks that ds.qty is a string variable, it compiles the expression 1 + 2 as a string expression—i.e. string concatenation. At runtime that value "12" gets converted to numeric form to match the ds.qty type.

A workaround is to just use a temporary variable that the compiler knows is numeric, e.g.

MAP1 value,f

value = 1 + 2

ds.qty = value

 

Another workaround is to use one of the Explicit Plus Operators, e.g.

ds.qty = 1 #+ 2          ! force 1 + 2 to be treated as addition (3)

Yet another is to use the NUMEXPR() system function, e.g.

ds.qty = NUMEXPR(1 + 2)  ! for expression to be numeric (3)

A variation of the problem occurs in a PRINT statement, since the compiler determines the type of each expression by the first term in the expression.  Consider…

ds.qty = 3

? ds.qty + 1    ! prints 31 ("3" + "1")

 

Note that there is no problem with mixing numeric and string variables or expressions in a PRINT statement, as long as they are in separate terms. The problem above is caused by the fact that ds.qty + 1 is a single term.

Aside from using a temporary variable, another workaround is possible in this kind of situation, using a numeric function, e.g.

Function Fn’Val(value as f8:inputonly) as f8

    Fn’Val = value

EndFunction

 

? Fn’Val(ds.qty) + 1

In the above case, the compiler knows that Fn’Val() is numeric, and it doesn’t need to make any assumptions about the types of the parameters—whether function or subroutine—since the parameter passing mechanism provides all of the necessary information for the receiver to do all of the necessary conversions. The compiler recognizes that Fn’Val is a numeric function, by the lack of a $ suffix, so it treats the expression Fn’Val(ds.qty) + 1 as numeric and performs addition instead of concatenation. But beware: this trick doesn’t work for assignment statements, since in that context, the destination variable type determines the type of the expression on the right side of the assignment operator.

Other than the string concatenation vs addition problem, for the most part the runtime system will be able to resolve the confusion left by the compiler incorrectly assuming that all dynstruct members are strings.

Also See