c2compiler icon indicating copy to clipboard operation
c2compiler copied to clipboard

compiler: improve Value handling and expression evaluator

Open chqrlie opened this issue 8 months ago • 4 comments

AST values:

  • add getValue() type methods for literal expr nodes, returning a Value
  • add Value.castAs() type method
  • add ValueKind.Error for invalid result and evaluation errors
  • add Value factories for unsigned, signed, float, boolean and error

Simplify ctv_analyser:

  • remove hard coded strings in Limits array
  • dispatch to more getValue() handlers

Expression evaluator:

  • move generator/c/c_generator_pure_call.c2 to ast/ast_evaluator.c2
  • support indirect pure functions calls including recursive

Improve C generator:

  • add Generator.need_const_expr, used for static intializers
  • add Generator.emitConstExpr() to force pure function calls evaluation
  • simplify initializer generation
  • pass Diags object for code generation errors

chqrlie avatar May 04 '25 16:05 chqrlie

A big change.. took me a while to parse it.. Overall I like it. Many small TODO's cleaned etc.

2 issues i see:

  • generator should not have a Diags. All diagnostics are done during the analyser phase.
  • This patch changes behaviour of: u8 b= 1; u8 a = b + 200; // should not give an error..

bvdberg avatar May 05 '25 17:05 bvdberg

A big change.. took me a while to parse it.. Overall I like it. Many small TODO's cleaned etc.

Yes, and an initial step for a full blown emulator. I shall first support pure functions using only arithmetic operators but allowing for local variables and calls to other pure functions.

2 issues i see:

  • generator should not have a Diags. All diagnostics are done during the analyser phase.

All diagnostics are done during the analyser phase, but some errors can still occur during the generation phase, such as file system errors, and in the case of pure functions, I implemented a limitation on the complexity and recursion depth to handle pathological cases gracefully. Reporting these errors directly via a console object seems less correct than using a Diags object which allows for location reporting.

  • This patch changes behaviour of: u8 b= 1; u8 a = b + 200; // should not give an error.

Yes I am aware of this. Truncation does occur if b is larger than 55. Can you summarize which implicit conversion losses are considered acceptable and which aren't?

The current system is approximate because it mixes tests about the type size and signedness and knowledge of the constant values and their sign.

I am working on a more precise analyser that would be more accurate and conformant: 2 << 31 should be reported as an arithmetic overflow, worse even, u32 TWO = 2; static_assert(TWO << 31, 0) fails, not because of overflow but because TWO << 31 has the value 4294967296, which is inconsistent with what the generated C code will compute: assert(TWO << 31, 0) will succeed.

chqrlie avatar May 05 '25 19:05 chqrlie

I usually keep the same as in C, an u8 = u8 + (literal); is allowed as long as the literal fits an u8. Idem for other types

bvdberg avatar May 10 '25 13:05 bvdberg

2 open issues:

  • c_generator still relies on Diags
  • ast_evaluator should not be part of AST, but of analyser_utils (like ctv_analyser)

bvdberg avatar May 26 '25 09:05 bvdberg