Dynamic expression evaluation
- Ivaylo Fiziev
- 7 days ago
- 3 min read

Expressions are everywhere - we use them when expressing conditions, formulas, logic. But how do we position them in the code? We literally embed them in the code (hardcoded). Once there they cannot be changed without changing the code itself. Most of the time this is just fine since the logic is designed for a specific use case and it covers it well. In Process Simulate this logic becomes part of the prototype of the component and this might be a problem! In case you need to change the code for a specific instance of this prototype, you are done. Once changed it will affect all instances of the component. The only thing you can change on the instance level are the signals connected to the inputs and outputs, also the default values. But sometimes this just isn't enough.
Imagine a situation where the user would like to type an expression in a dialog box, then have the result of this expression drive the logic in the code. For each instance he can set a different expression if needed. In essence the same prototype will behave differently for each instance despite being the same. Sounds weird right? This is possible thanks to the dynamic expression evaluation that is typical for most of the scripting languages out there. The expression in this case is just a string that is being evaluated at runtime. Just a function call. Yes. It is that simple.
Let's see an example:
FUNCTION_BLOCK "MAIN"
VERSION:1.0
VAR_INPUT
expression : STRING := 'SIM_TIME() > 500';
END_VAR
VAR_TEMP
result : BOOL;
END_VAR
BEGIN
EVAL(EXPR:=#expression, RES=>#result); // evaluate the expression
if #result then
; // do something here
end_if;
END_FUNCTION_BLOCK
The expression is provided as pure text as a default value of a string variable. This means it can be part of the instance data. The code however is the same for all instances. Something more: The expression can be modified by the code at runtime.
The expression can contain variables, functions, literals and all valid SCL operators.
The type of the result depends on the type of the expression. In the case of arithmetic types the result will be cast to the type of the variable you provide for the output parameter. In the case of non-arithmetic types it is expected that the type of the output parameter matches the type of the expression. If the type of the output is not correct an error will be reported. If the expression text contains a syntax/semantic error it will be reported.
All nice stuff.
Now the downsides:
a) Dynamic expression evaluation could be slow if you are constantly changing the expression at runtime. Internally it tries to minimize parsing in the case where you use the same expression over and over again. So although it is possible, avoid modifying the expression on every script execution.
b) Dynamic expression evaluation is a door for hacks. Imagine you have a custom function that brings down Process Simulate on purpose and you use it in a dynamic expression. The problem is that everyone can do this ... even unintentionally.
c) You cannot debug a script function when used in a dynamic expression. Why? The debugger is simply not aware of it. It shows only functions referenced in the code. It does not analyze the strings ... if you use the same function in the code, then you have a chance for debugging.
d) You should know the type of the expression in advance for the code to work. Imagine you expect a Boolean expression (like in the example above) and the expression actually returns an array. In this case you'll get an error. This is more the result of SCL being a strongly typed language.
e) In case you call a function that takes string arguments, you will have to reevaluate your need. Escape sequences are still not supported so it is not possible to put a string inside another string. e.g. '"FUNC"('arg')'
So much about dynamic expressions. Process Simulate 2509 will have the EVAL function OOTB.
Let's wait to see if it helps or not.
Bye!
Comments