-
Notifications
You must be signed in to change notification settings - Fork 78
feat(typeck): implement constant folding for integer literal type preservation #649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| BitXor => Self::new(self.data ^ r.data), | ||
| Shr => Self::new(self.data.wrapping_shr(r.data.try_into().unwrap_or(usize::MAX))), | ||
| Shl => Self::new(self.data.wrapping_shl(r.data.try_into().unwrap_or(usize::MAX))), | ||
| Sar => Self::new(self.data.arithmetic_shr(r.data.try_into().unwrap_or(usize::MAX))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is >>> which only works on fixed types, we should rename this to sometihng so we dont forget its useless
| BitOr => Self::new(self.data | r.data), | ||
| BitAnd => Self::new(self.data & r.data), | ||
| BitXor => Self::new(self.data ^ r.data), | ||
| Shr => Self::new(self.data.wrapping_shr(r.data.try_into().unwrap_or(usize::MAX))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be arithmetic_shr depending on sign
| } | ||
|
|
||
| /// Returns whether the value is negative. | ||
| pub fn is_negative(&self) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably be is_signed and be a constant value. then data should be I256 and is_negative will be I256's is_negative (last bit set). this way all ops are easier to keep track of, since they become regular two's complement
This enables distinguishing edge cases like 127 (fits in int8) from 128 (doesn't fit), which is needed for correct implicit and explicit integer conversions. - Changed internal storage from `u8` (bytes 0-32) to `u16` (bits 0-256) - `TypeSize::new()` now takes bits directly - Added `new_fb_bytes()` for fixed-bytes types that take byte counts - `bits()` returns stored value, `bytes()` computes `ceil(bits/8)` - `mk_ty_int_literal` no longer rounds to multiples of 8 Closes #650 Unblocks #647 #648 #649
addc964 to
e4c688d
Compare
d3a3036 to
a1f3e12
Compare
e4c688d to
d621ddf
Compare
a1f3e12 to
9ee451e
Compare
Add implicit type coercion for integer literals (IntLiteral) to typed integers (uint/int). The coercion rules are: - IntLiteral -> uint: Allowed if the literal is non-negative and fits in the target size (size.bits() <= target.bits()) - IntLiteral -> int: Allowed with strict inequality (size.bits() < target.bits()) for non-negative values due to TypeSize rounding, and non-strict for negative values TypeSize stores ceil(bit_len/8), so int_literal[1] covers 0-255. This means we can't distinguish edge cases like 127 (fits in int8) from 128 (doesn't fit), so we conservatively require int16+ for int_literal[1]. Note: Negative literal support requires additional work in the type checker to propagate negativity through unary negation. This is provided in a follow up. Supercedes #564 and closes #627 (closes #564) Stack: - #647 (this) - #648 - #649
d621ddf to
6860eb9
Compare
9ee451e to
44ebc93
Compare
Implement proper handling of negative integer literals in the type checker. Previously, negative literals like -42 were broken because: 1. The parser represents them as unary negation applied to a positive literal, so type_of_lit only sees the positive value 2. The negativity flag in IntLiteral was always false This commit fixes the issue by: - Allowing unary negation on IntLiteral types (they can always be negated since the result is just a negative literal) - Propagating the negativity flag when applying unary negation to an IntLiteral, flipping neg from false to true - Not propagating the expected type through negation when targeting signed types, to avoid premature type mismatch errors on the inner expression Also simplifies the coercion rule to use strict inequality for both positive and negative literals, since TypeSize rounding means we can't reliably distinguish edge cases in either direction. On top of #647 Supercedes #566 (will mark @mablr as a co-author to commend effort) and closes #560 (closes #566) Stack: - #647 - #648 (this) - #649 Co-Authored-By: Mablr <[email protected]>
Implement proper handling of negative integer literals in the type checker. Previously, negative literals like -42 were broken because: 1. The parser represents them as unary negation applied to a positive literal, so type_of_lit only sees the positive value 2. The negativity flag in IntLiteral was always false This commit fixes the issue by: - Allowing unary negation on IntLiteral types (they can always be negated since the result is just a negative literal) - Propagating the negativity flag when applying unary negation to an IntLiteral, flipping neg from false to true - Not propagating the expected type through negation when targeting signed types, to avoid premature type mismatch errors on the inner expression Also simplifies the coercion rule to use strict inequality for both positive and negative literals, since TypeSize rounding means we can't reliably distinguish edge cases in either direction.
…servation When both operands of a binary operation are IntLiteral, evaluate the expression at compile time to preserve literal type semantics. This allows expressions like `-(1 + 2)` to work correctly, since the result remains an IntLiteral that can be negated. Changes: - Extended IntScalar with explicit sign tracking and signed arithmetic - Added try_eval_int_literal_binop to evaluate literal binary expressions - Updated eval_array_len to reject negative array lengths
44ebc93 to
522c0bb
Compare
When both operands of a binary operation are IntLiteral, evaluate the expression at compile time to preserve literal type semantics. This allows expressions like
-(1 + 2)to work correctly, since the result remains an IntLiteral that can be negated.Changes:
On top of #648
Stack: