pyfcstm.model.expr
Expression handling utilities for mathematical expressions and evaluation.
This module defines an expression system used by the DSL layer to model, evaluate, and serialize mathematical expressions. Expressions are represented as an object tree with support for literals, variables, unary/binary/conditional operators, and unary mathematical functions. Each expression can be evaluated by supplying variable values, converted into DSL AST nodes, and inspected for variable usage.
The module contains the following public components:
Expr- Abstract base class for all expressions.Integer- Integer literal expression.Float- Floating-point literal expression with constant recognition.Boolean- Boolean literal expression.Op- Base class for operator expressions.UnaryOp- Unary operator expression.BinaryOp- Binary operator expression.ConditionalOp- Ternary conditional expression.UFunc- Unary mathematical function expression.Variable- Variable reference expression.parse_expr_node_to_expr()- Convert DSL AST nodes to expression objects.parse_expr_from_string()- Parse DSL expression strings to expression objects.parse_expr()- Unified parser supporting multiple input types.
Note
Operator precedence is respected when converting to AST nodes. Parentheses are inserted automatically to preserve evaluation order.
Example:
>>> from pyfcstm.model.expr import Variable, Integer, BinaryOp, UFunc
>>> expr = BinaryOp(x=Variable("x"), op="+", y=Integer(2))
>>> expr(x=3)
5
>>> func_expr = UFunc(func="sqrt", x=Integer(9))
>>> func_expr()
3.0
>>> # Parse expressions from DSL strings
>>> from pyfcstm.model.expr import parse_expr_from_string
>>> expr = parse_expr_from_string("x * 2 + 3", mode='numeric')
>>> expr(x=5)
13
>>> # Unified parsing with parse_expr
>>> from pyfcstm.model.expr import parse_expr
>>> expr = parse_expr("x + 5") # from string
>>> expr = parse_expr(expr) # from Expr object (returns directly)
__all__
- pyfcstm.model.expr.__all__ = ['Expr', 'Integer', 'Float', 'Boolean', 'Op', 'UnaryOp', 'BinaryOp', 'ConditionalOp', 'UFunc', 'Variable', 'parse_expr_node_to_expr', 'parse_expr_from_string', 'parse_expr']
Built-in mutable sequence.
If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.
Expr
- class pyfcstm.model.expr.Expr[source]
Base class for all expressions.
This abstract class defines the common interface for all expression types. It provides methods for traversing the expression tree, evaluating expressions, and converting expressions to AST nodes. The class supports operator overloading for building complex expressions using natural Python syntax.
Operator Support:
The Expr class provides comprehensive operator overloading for building DSL expressions using Python syntax. All operators automatically convert their operands using
parse_expr(), supporting Expr objects, Python literals (bool, int, float), DSL strings, and DSL AST nodes.Arithmetic Operators:
expr + other- Additionexpr - other- Subtractionexpr * other- Multiplicationexpr / other- Divisionexpr % other- Moduloexpr ** other- Exponentiation-expr- Unary negation+expr- Unary positive
Bitwise Operators:
expr << other- Left shiftexpr >> other- Right shiftexpr & other- Bitwise ANDexpr | other- Bitwise ORexpr ^ other- Bitwise XOR
Comparison Operators:
expr < other- Less thanexpr <= other- Less than or equalexpr > other- Greater thanexpr >= other- Greater than or equalexpr.eq(other)- Equality (==) - method form to avoid conflict with Python’s object equalityexpr.ne(other)- Not equal (!=) - method form to avoid conflict with Python’s object inequality
Logical Operators:
expr.and_(other)- Logical AND (&&)expr.or_(other)- Logical OR (||)expr.not_()- Logical NOT (!)
Note: Python’s
and/orkeywords cannot be overloaded, and&/|operators are reserved for bitwise operations. Use the method forms instead.Conditional Operator:
expr.select(true_value, false_value)- Ternary operator (? :)expr.if_then_else(true_value, false_value)- Alias for select()
Reverse Operators:
All binary operators support reverse operations (e.g.,
5 + expr) through corresponding__radd__,__rsub__, etc. magic methods.- Return type:
Example:
>>> from pyfcstm.model.expr import Variable >>> x = Variable("x") >>> y = Variable("y") >>> >>> # Arithmetic operations >>> expr = x * 2 + y >>> expr(x=3, y=4) 10 >>> >>> # Comparison and logical operations >>> expr = (x > 0).and_(y > 0) >>> expr(x=5, y=10) True >>> >>> # Conditional expression >>> expr = (x > 0).select(x, -x) # abs(x) >>> expr(x=-5) 5 >>> >>> # Complex nested expression >>> expr = (x > y).select(x, y) # max(x, y) >>> expr(x=10, y=5) 10
- __add__(other: Any) BinaryOp[source]
Addition operator (+).
Creates a binary addition expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x + 5 >>> expr(x=10) 15
- __and__(other: Any) BinaryOp[source]
Bitwise AND operator (&).
Creates a binary bitwise AND expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x & 0xFF >>> expr(x=0x1234) 52
- __call__(**kwargs: Any) Any[source]
Evaluate the expression with given variable values.
- Parameters:
kwargs – Variable name to value mapping
- Returns:
Result of the expression evaluation
- __ge__(other: Any) BinaryOp[source]
Greater than or equal operator (>=).
Creates a binary greater than or equal comparison expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x >= 5 >>> expr(x=5) True
- __gt__(other: Any) BinaryOp[source]
Greater than operator (>).
Creates a binary greater than comparison expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x > 5 >>> expr(x=10) True
- __le__(other: Any) BinaryOp[source]
Less than or equal operator (<=).
Creates a binary less than or equal comparison expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x <= 10 >>> expr(x=10) True
- __lshift__(other: Any) BinaryOp[source]
Left shift operator (<<).
Creates a binary left shift expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x << 2 >>> expr(x=5) 20
- __lt__(other: Any) BinaryOp[source]
Less than operator (<).
Creates a binary less than comparison expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x < 10 >>> expr(x=5) True
- __mod__(other: Any) BinaryOp[source]
Modulo operator (%).
Creates a binary modulo expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x % 3 >>> expr(x=10) 1
- __mul__(other: Any) BinaryOp[source]
Multiplication operator (*).
Creates a binary multiplication expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x * 2 >>> expr(x=5) 10
- __neg__() UnaryOp[source]
Unary negation operator (-).
Creates a unary negation expression.
- Returns:
Unary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = -x >>> expr(x=5) -5
- __or__(other: Any) BinaryOp[source]
Bitwise OR operator (|).
Creates a binary bitwise OR expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x | 0x0F >>> expr(x=0xF0) 255
- __pos__() UnaryOp[source]
Unary positive operator (+).
Creates a unary positive expression.
- Returns:
Unary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = +x >>> expr(x=5) 5
- __pow__(other: Any) BinaryOp[source]
Power operator (**).
Creates a binary exponentiation expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x ** 2 >>> expr(x=3) 9
- __radd__(other: Any) BinaryOp[source]
Reverse addition operator (+).
Enables addition when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 5 + x >>> expr(x=10) 15
- __rand__(other: Any) BinaryOp[source]
Reverse bitwise AND operator (&).
Enables bitwise AND when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 0xFF & x >>> expr(x=0x1234) 52
- __rlshift__(other: Any) BinaryOp[source]
Reverse left shift operator (<<).
Enables left shift when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 5 << x >>> expr(x=2) 20
- __rmod__(other: Any) BinaryOp[source]
Reverse modulo operator (%).
Enables modulo when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 10 % x >>> expr(x=3) 1
- __rmul__(other: Any) BinaryOp[source]
Reverse multiplication operator (*).
Enables multiplication when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 3 * x >>> expr(x=4) 12
- __ror__(other: Any) BinaryOp[source]
Reverse bitwise OR operator (|).
Enables bitwise OR when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 0xF0 | x >>> expr(x=0x0F) 255
- __rpow__(other: Any) BinaryOp[source]
Reverse power operator (**).
Enables exponentiation when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 2 ** x >>> expr(x=3) 8
- __rrshift__(other: Any) BinaryOp[source]
Reverse right shift operator (>>).
Enables right shift when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 20 >> x >>> expr(x=2) 5
- __rshift__(other: Any) BinaryOp[source]
Right shift operator (>>).
Creates a binary right shift expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x >> 1 >>> expr(x=10) 5
- __rsub__(other: Any) BinaryOp[source]
Reverse subtraction operator (-).
Enables subtraction when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 10 - x >>> expr(x=3) 7
- __rtruediv__(other: Any) BinaryOp[source]
Reverse division operator (/).
Enables division when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 20 / x >>> expr(x=4) 5.0
- __rxor__(other: Any) BinaryOp[source]
Reverse bitwise XOR operator (^).
Enables bitwise XOR when the expression is on the right side. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Left operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = 0xFF ^ x >>> expr(x=0xAA) 85
- __str__() str[source]
Get string representation of the expression.
The string representation is derived from the AST node serialization.
- Returns:
String representation
- Return type:
str
- __sub__(other: Any) BinaryOp[source]
Subtraction operator (-).
Creates a binary subtraction expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x - 3 >>> expr(x=10) 7
- __truediv__(other: Any) BinaryOp[source]
Division operator (/).
Creates a binary division expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x / 2 >>> expr(x=10) 5.0
- __xor__(other: Any) BinaryOp[source]
Bitwise XOR operator (^).
Creates a binary bitwise XOR expression. The operand is automatically converted using
parse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x ^ 0xFF >>> expr(x=0xAA) 85
- and_(other: Any) BinaryOp[source]
Logical AND (&&).
This method creates a logical AND expression. It cannot use the
&operator as that is reserved for bitwise AND operations.- Parameters:
other (Any) – Right operand
- Returns:
Binary operation expression with ‘&&’ operator
- Return type:
Example:
>>> x = Variable("x") >>> y = Variable("y") >>> expr = x.gt(0).and_(y.gt(0)) # Creates: (x > 0) && (y > 0) >>> expr(x=5, y=10) True >>> expr(x=5, y=-1) False
- eq(other: Any) BinaryOp[source]
Equality comparison (==).
This method creates an equality comparison expression. It cannot use the
__eq__magic method as that conflicts with Python’s object equality comparison. The operand is automatically converted usingparse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x.eq(5) # Creates: x == 5 >>> expr(x=5) True >>> expr(x=10) False
- if_then_else(true_value: Any, false_value: Any) ConditionalOp[source]
Conditional (ternary) operator (? :) - alias for select.
This is an alias for
select(). It creates a conditional expression that evaluates totrue_valueif the condition is true, otherwisefalse_value.- Parameters:
true_value (Any) – Expression to evaluate if condition is true
false_value (Any) – Expression to evaluate if condition is false
- Returns:
Conditional operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x.gt(0).if_then_else(x, -x) # Creates: (x > 0) ? x : -x >>> expr(x=5) 5 >>> expr(x=-3) 3
- list_variables() List[Variable][source]
List all unique variables used in this expression.
Variables are identified by name, and the first occurrence of each name is preserved in the returned list.
- ne(other: Any) BinaryOp[source]
Not equal comparison (!=).
This method creates a not-equal comparison expression. It cannot use the
__ne__magic method as that conflicts with Python’s object inequality comparison. The operand is automatically converted usingparse_expr().- Parameters:
other (Any) – Right operand (Expr, literal, string, or AST node)
- Returns:
Binary operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x.ne(5) # Creates: x != 5 >>> expr(x=10) True >>> expr(x=5) False
- not_() UnaryOp[source]
Logical NOT (!).
This method creates a logical NOT expression. Python’s
notkeyword cannot be overloaded, so this method provides the functionality.- Returns:
Unary operation expression with ‘!’ operator
- Return type:
Example:
>>> x = Variable("x") >>> expr = x.eq(0).not_() # Creates: !(x == 0) >>> expr(x=5) True >>> expr(x=0) False
- or_(other: Any) BinaryOp[source]
Logical OR (||).
This method creates a logical OR expression. It cannot use the
|operator as that is reserved for bitwise OR operations.- Parameters:
other (Any) – Right operand
- Returns:
Binary operation expression with ‘||’ operator
- Return type:
Example:
>>> x = Variable("x") >>> y = Variable("y") >>> expr = x.gt(0).or_(y.gt(0)) # Creates: (x > 0) || (y > 0) >>> expr(x=5, y=-1) True >>> expr(x=-1, y=-2) False
- select(true_value: Any, false_value: Any) ConditionalOp[source]
Conditional (ternary) operator (? :).
This method creates a conditional expression that evaluates to
true_valueif the condition is true, otherwisefalse_value.- Parameters:
true_value (Any) – Expression to evaluate if condition is true
false_value (Any) – Expression to evaluate if condition is false
- Returns:
Conditional operation expression
- Return type:
Example:
>>> x = Variable("x") >>> expr = x.gt(0).select(x, -x) # Creates: (x > 0) ? x : -x >>> expr(x=5) 5 >>> expr(x=-3) 3
Integer
Float
Boolean
Op
- class pyfcstm.model.expr.Op[source]
Base class for all operator expressions.
This abstract class provides common functionality for operator expressions.
- property op_mark: str
Get the operator mark for precedence lookup.
- Returns:
Operator mark
- Return type:
str
- Raises:
NotImplementedError – Must be implemented by subclasses
BinaryOp
UnaryOp
UFunc
ConditionalOp
Variable
parse_expr_node_to_expr
- pyfcstm.model.expr.parse_expr_node_to_expr(node: Expr) Expr[source]
Parse an AST expression node into an
Exprobject.This function converts DSL expression nodes into the corresponding expression objects. Literal nodes become literal expressions, operators are mapped to their corresponding expression classes, and parentheses are flattened.
- Parameters:
node (dsl_nodes.Expr) – AST expression node
- Returns:
Corresponding expression object
- Return type:
- Raises:
TypeError – If the node type is not recognized
Example:
>>> ast_node = dsl_nodes.Integer(raw="42") >>> expr = parse_expr_node_to_expr(ast_node) >>> isinstance(expr, Integer) True >>> expr.value 42
parse_expr_from_string
- pyfcstm.model.expr.parse_expr_from_string(expr_string: str, mode: Literal['generic', 'numeric', 'logical'] = 'generic') Expr[source]
Parse a DSL expression string into an
Exprobject.This function parses a DSL expression string using one of three grammar entry points based on the specified mode:
'generic'- Usesgeneric_expressionrule (accepts both numeric and conditional expressions)'numeric'- Usesnum_expressionrule (arithmetic, bitwise, variables, functions, ternary)'logical'- Usescond_expressionrule (comparisons, logical operators, boolean literals)
- Parameters:
expr_string (str) – DSL expression string to parse
mode (str, optional) – Parsing mode, one of
'generic','numeric', or'logical', defaults to'generic'
- Returns:
Parsed expression object
- Return type:
- Raises:
ValueError – If mode is not one of the valid options
pyfcstm.dsl.error.GrammarParseError – If parsing fails
Example:
>>> from pyfcstm.model.expr import parse_expr_from_string >>> # Generic mode (default) - accepts both numeric and logical >>> expr = parse_expr_from_string("x + 5") >>> isinstance(expr, BinaryOp) True >>> expr = parse_expr_from_string("x > 5 && y < 10") >>> isinstance(expr, BinaryOp) True >>> # Numeric mode - arithmetic and bitwise operations >>> expr = parse_expr_from_string("x * 2 + 3", mode='numeric') >>> isinstance(expr, BinaryOp) True >>> expr = parse_expr_from_string("sqrt(x ** 2 + y ** 2)", mode='numeric') >>> isinstance(expr, UFunc) True >>> # Logical mode - boolean expressions >>> expr = parse_expr_from_string("x > 5 && y < 10", mode='logical') >>> isinstance(expr, BinaryOp) True >>> expr = parse_expr_from_string("!flag || (a == b)", mode='logical') >>> isinstance(expr, BinaryOp) True
parse_expr
- pyfcstm.model.expr.parse_expr(expr_input: Any, mode: Literal['generic', 'numeric', 'logical'] = 'generic') Expr[source]
Parse various input types into an
Exprobject.This function provides a unified interface for parsing expressions from multiple input types. It accepts DSL AST nodes, expression strings, or existing Expr objects.
- Parameters:
expr_input (Any) – Input to parse - can be: -
Exprobject: returned directly without modification -dsl_nodes.ExprAST node: converted usingparse_expr_node_to_expr()-str: parsed usingparse_expr_from_string()with the specified mode -bool: converted toBooleanliteral -int: converted toIntegerliteral -float: converted toFloatliteralmode (Literal['generic', 'numeric', 'logical'], optional) – Parsing mode for string inputs, one of
'generic','numeric', or'logical', defaults to'generic'
- Returns:
Parsed expression object
- Return type:
- Raises:
TypeError – If input type is not supported
ValueError – If mode is invalid (for string inputs)
pyfcstm.dsl.error.GrammarParseError – If string parsing fails
Warning
The
modeparameter only affects string inputs. If a non-default mode is specified with an Expr object or AST node input, a warning will be issued.Example:
>>> from pyfcstm.model.expr import parse_expr, Variable, Integer, BinaryOp >>> from pyfcstm.dsl.node import Integer as IntNode >>> # Parse from Expr object (returns directly) >>> expr_obj = BinaryOp(x=Variable("x"), op="+", y=Integer(5)) >>> result = parse_expr(expr_obj) >>> result is expr_obj True >>> # Parse from DSL AST node >>> ast_node = IntNode(raw="42") >>> expr = parse_expr(ast_node) >>> isinstance(expr, Integer) True >>> # Parse from string >>> expr = parse_expr("x + 5") >>> isinstance(expr, BinaryOp) True >>> expr = parse_expr("x > 5 && y < 10", mode='logical') >>> isinstance(expr, BinaryOp) True >>> # Parse from Python literals >>> expr = parse_expr(42) >>> isinstance(expr, Integer) True >>> expr = parse_expr(3.14) >>> isinstance(expr, Float) True >>> expr = parse_expr(True) >>> isinstance(expr, Boolean) True