Sming Evaluator DSL Specification
Evaluator implements a DSL to allow computed values for various settings at compile time.
The intended purpose is to enable safe parsing of expressions involving environment variables.
A simplistic evaluation can be done using eval() but that has security implications,
and accessing environment variables is quite clunky.
2. Language Syntax
2.1 Literals and Types
Integers & Floats: Standard numeric literals (e.g., 100, 3.14).
Hexadecimal: Environment variables starting with 0x are automatically cast to integers.
Strings: Single or double-quoted literals (e.g., ‘esp32’, “enabled”) and formatted-strings (e.g. “f’{value:02x}’”)
Booleans: Case-sensitive True and False keywords.
Lists: Useful for expressions such as
"value in ['a', 'b', 'c']"Sets: Can be used to remove duplicates, e.g.
"{1, 1, 2, 5, 2, 20}"resolves to"{1, 2, 5, 20}"
2.2 Arithmetic & Bitwise
2.3 Logical Aliases
The evaluator pre-processes C-style tokens into Python logical keywords:
2.4 Comparison & Membership
Operator |
Description |
Example |
|---|---|---|
== |
Equality |
CPU_COUNT == 4 |
> , < |
Greater/Less Than |
BAUD > 9600 |
>= , <= |
Greater/Less or Equal |
VERSION >= 2.0 |
in |
Substring Match |
‘esp’ in CHIP |
not in |
Negative Substring Match |
‘beta’ not in VERSION |
in |
Set membership |
CHIP in [‘esp32’, ‘esp8266’] |
3. Control Flow (Ternary Logic)
The DSL uses the Python ternary structure. An else clause is mandatory.
Syntax: [result_if_true] if [condition] else [result_if_false]
Example:
"HIGH_SPEED" if (BAUD >= 115200 || FORCE_FAST == "1") else "LOW_SPEED"
4. Built-in Functions
The following whitelisted functions are available. Function calls are validated for correct argument counts via signature inspection before execution.
pow2(x): Returns 2 raised to the power of x.
log2(x): Returns the base-2 logarithm of x.
align_up(val, align): Rounds val up to the next align boundary.
min(…): Returns the minimum value of the arguments.
max(…): Returns the maximum value of the arguments.
Applications may extend this by modifying the functions property.
5. Environment Variables & Truthiness
Variables are pulled from os.environ. When used in a conditional if or with !, the following “Truthiness” rules apply to strings:
Falsy: “0”, “False”, “no”, “off”, or “” (empty string).
Truthy: Any other value (e.g., “1”, “True”, “esp32”).
6. Security Guardrails
The Evaluator prevents common Python injection attacks through a strict “Fail-Closed” model:
No Attribute Access: The “.” operator is forbidden. Attempting to call methods (e.g., os.system()) or access object properties (e.g., obj.class) results in an “Unsupported function call type: Attribute” or “Unsupported syntax: Attribute” error.
No Multi-Statement Logic: Semicolons (;) and newlines are rejected by the parser (mode=’eval’).
No Imports: Keywords like import or from are not supported in the expression grammar.
Whitelisted Nodes: Only specific AST nodes (BinOp, UnaryOp, BoolOp, Compare, IfExp, Call, Constant, Name) are evaluated.
Example expressions
"True if 'esp32' in SMING_SOC else False"
"'HIGH_SPEED' if COM_SPEED > 115200 else 'LOW_SPEED'"
"f'{RBOOT_ROM0_ADDR:08x}'"
Exceptions
Errors will result in an exception, for example:
Unsupported function call type: Attribute: Triggered by attempting to use a “.” in a function call.
Forbidden function call: open: Triggered by attempting to call a function not in the whitelist.
Function
pow2expects 1 arguments (got 3): Triggered by incorrect argument counts.Variable ‘VAR’ is not defined: Does not exist in environment and not provided via
get_variablecallback.