Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 326855

Summary: provide constant expression evaluator
Product: z_Archived Reporter: Henrik Lindberg <henrik.lindberg>
Component: b3Assignee: Project Inbox <b3.engine-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: P3    
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:
Bug Depends on:    
Bug Blocks: 306547, 307011    

Description Henrik Lindberg CLA 2010-10-02 21:38:41 EDT
Provide a constant expression evaluator.

Suggested implementation:
Use a polymorphic dispatcher.
Use a return type of ConstantResult with an indicator if expression was constant as evaluation of a constant expression is the same as detecting if an expression is constant and it allows computation of "null" result.

The constant expression evaluator is useful when computing "unreachable code" and similar.

A simple implementation could support operators directly (i.e. + - * / etc), but to be really useful it needs to be able to call system functions, use lists and arrays etc. This requires access to B3Engine for the special purpose of evaluating constants (as the system functions require a context).

as an example
if [1,2 3] == [1,2,3] then foo() else bar() endif;

should result in an unreachable code error for the else part.

Constant detection can get quite complicated:

if [ {|10}, {|20+30} ].collect(f | f.evaluate()) ~= [ _, 50 ] then foo() else bar() endif; 

System functions would need to be able to answer if they produce a constant result given constant input.
Comment 1 Henrik Lindberg CLA 2010-10-03 18:35:55 EDT
Implementing a constant expression evaluator turned out to be a quite simple exercise since the relevant system, arithmetic and relational functions could be used without an execution context. In total 229 lines of code.

A simple implementation is now available in org.eclipse.b3.backend.evaluator.B3ConstantEvaluator.
It supports:
Arithmetic: + - * / unary - (numbers) 
String : + (concatenation of strings and string/number combinations)
Relational: all relational operations except matches

expressions: &&, ||, !, val

literal values : strings, numbers, ANY

All other expressions are considered to be variable.

It is possible to enhance the constant evaluator with support for constant lists and maps, lambdas that return constant values, etc, but it should be good enough to capture common developer mistakes.

In revision 1328.