TinyExpression v1.4.15 provides 6 execution backends. This document describes their differences, selection contract, and recommended usage.
| Backend | Class | Status | Strategy |
|---|---|---|---|
JAVA_CODE |
JavaCodeCalculatorV3 |
Production | Parse → generate Java → javac → load → invoke |
JAVA_CODE_LEGACY_ASTCREATOR |
LegacyAstCreatorJavaCodeCalculator |
Frozen (reference) | Same as above with pre-refactor AST creator |
AST_EVALUATOR |
AstEvaluatorCalculator |
Production | Parse → AST → tree-walking interpreter |
DSL_JAVA_CODE |
DslJavaCodeCalculator |
Generated-only | P4 AST → typed Java emitter → javac |
P4_AST_EVALUATOR |
P4AstEvaluatorCalculator |
PRIMARY (P4) | UBNF parser → P4 AST → type-safe evaluator |
P4_DSL_JAVA_CODE |
P4DslJavaCodeCalculator |
Migration target (P4) | UBNF parser → P4 AST → DSL Java emitter |
The current production JavaCode baseline.
- Class:
JavaCodeCalculatorV3 - Change policy: Main target for new feature additions on the JavaCode path
- How it works: Translates the formula into Java source code, compiles it in-memory via
javax.tools.JavaCompiler, loads the class viaMemoryClassLoader, and invokes it withCalculationContext - Pros: Fastest execution after compilation; JIT-optimized
- Cons: Compilation overhead at first call; in-memory
javacdependency
Pre-refactor comparison baseline.
- Class:
LegacyAstCreatorJavaCodeCalculator,LegacyOperatorOperandTreeCreator - Change policy: Frozen — only minimal compatibility patches allowed
- Purpose: Regression baseline for verifying
JAVA_CODErefactors produce identical results
Generated P4 AST traversal evaluator.
- Class:
AstEvaluatorCalculator - Failure contract: P4 parse or evaluation gaps fail explicitly; this backend never switches to a handwritten evaluator or Java-code generator
- Change policy: Expanding generated-AST coverage is the primary target
- Pros: No compilation overhead; suitable for lightweight deployments
- Cons: Slightly slower than
JAVA_CODEfor hot paths; unsupported grammar is an explicit error
Generated-only DSL Java emitter.
- Class:
DslJavaCodeCalculator - Change policy: Migration target for expanding native DSL Java emitter coverage
- How it works: Maps the formula to the generated P4 AST and emits Java through
P4TypedJavaCodeEmitter; unsupported syntax fails explicitly - Runtime markers:
_tinyDslJavaNativeEmitterUsed = true_tinyExecutionImplementation = p4-typed-emitter_tinyExecutionBridgeImplementation = false
Type-safe UBNF-generated parser with AST evaluation.
- Class:
P4AstEvaluatorCalculator - Change policy: Expanding P4 grammar coverage; primary reference for LSP/DAP
- How it works: Uses the UBNF-generated
TinyExpressionP4Parsersto produce a sealed-interface P4 AST, then evaluates it viaP4TypedAstEvaluator - Advantage over AST_EVALUATOR: No regex in LSP/DAP; fully
instanceof-based dispatch; compile-time exhaustiveness - Limitation: Syntax outside the P4 grammar fails explicitly
Type-safe UBNF-generated parser with DSL Java code emission.
- Class:
P4DslJavaCodeCalculator - Change policy: Migration target toward fully generated DSL evaluator
- How it works: P4 parser → P4 AST → DSL Java emitter
- Global default:
FormulaInfoAdditionalFields.setExecutionBackend(...)— default isJAVA_CODE - Per-formula override:
executionBackendorbackendkey inFormulaInfo - Implementation mapping:
CalculatorCreatorRegistry.forBackend(ExecutionBackend)
| Alias | Backend |
|---|---|
token |
JAVA_CODE |
legacy-astcreator, ootc |
JAVA_CODE_LEGACY_ASTCREATOR |
ast |
AST_EVALUATOR |
dsl-javacode |
DSL_JAVA_CODE |
p4-ast, p4-ast-evaluator |
P4_AST_EVALUATOR |
p4-dsl-javacode, p4-dsl-java-code |
P4_DSL_JAVA_CODE |
All 6 backends must return equivalent values for the same input. Key requirements:
- All 6 backends produce equivalent values for supported corpus (MUST)
AST_EVALUATORandDSL_JAVA_CODEmust not invoke handwritten fallback implementations (MUST)P4_AST_EVALUATORandP4_DSL_JAVA_CODEmust match the other 4 backends (MUST)- Formulas not covered by the P4 grammar must fail explicitly (MUST)
When running in DAP debug mode, the following variables are exposed:
| Variable | Description |
|---|---|
parity.JAVA_CODE |
Result from JAVA_CODE backend |
parity.AST_EVALUATOR |
Result from AST_EVALUATOR backend |
parity.P4_AST_EVALUATOR |
Result from P4_AST_EVALUATOR backend |
parity.equalAll |
true if all 6 backends agree |
All backends set these context markers after execution:
| Marker | Description |
|---|---|
_tinyExecutionBackend |
Backend name used |
_tinyExecutionMode |
Execution mode |
_tinyExecutionImplementation |
Implementation variant |
_tinyExecutionBridgeImplementation |
Always false for generated-only backends |
- Keep the global default as
JAVA_CODE - Test specific formulas with
P4_AST_EVALUATORto verify coverage - Override per-formula:
backend:P4_AST_EVALUATOR - Compare
parity.equalAllin DAP debug before full migration - Do not change
JAVA_CODE_LEGACY_ASTCREATOR— treat it as immutable reference
- When adding syntax or runtime features: update
JAVA_CODEandAST_EVALUATORfirst - Keep changes to
JAVA_CODE_LEGACY_ASTCREATORto a minimum - Do not reuse backend names (MUST NOT)
- When changing backend behavior contracts: update this document and parity tests simultaneously
- P4 backends do not yet cover all language features (incremental expansion in progress)
JAVA_CODE_LEGACY_ASTCREATORis frozenBigDecimalandBigIntegerarithmetic in expressions has limited support
- architecture.md — how backends connect to parser and AST layers
- decisions/ADR-001-p4-primary.md — why P4 was promoted to PRIMARY