fix: C backend string comparison, underscore patterns, and list memory

1. String == comparison now uses strcmp instead of pointer comparison
   - Added check in emit_expr() for BinaryOp::Eq/Ne on strings
   - Also fixed in emit_expr_with_env() for closures

2. Support `let _ = expr` pattern to discard values
   - Parser now accepts underscore in let bindings (both blocks and expressions)
   - C backend emits (void)expr; for underscore patterns

3. Fix list head/tail/get memory management
   - Added lux_incref() when extracting elements from lists
   - Prevents use-after-free when original list is freed

4. String.startsWith was already implemented (verified working)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 07:14:02 -05:00
parent fe985c96f5
commit 5a853702d1
2 changed files with 98 additions and 5 deletions

View File

@@ -532,7 +532,14 @@ impl Parser {
let start = self.current_span();
self.expect(TokenKind::Let)?;
let name = self.parse_ident()?;
// Allow underscore as wildcard pattern (discards the value)
let name = if self.check(TokenKind::Underscore) {
let span = self.current_span();
self.advance();
Ident::new("_".to_string(), span)
} else {
self.parse_ident()?
};
let typ = if self.check(TokenKind::Colon) {
self.advance();
@@ -1962,7 +1969,14 @@ impl Parser {
let start = self.current_span();
self.expect(TokenKind::Let)?;
let name = self.parse_ident()?;
// Allow underscore as wildcard pattern (discards the value)
let name = if self.check(TokenKind::Underscore) {
let span = self.current_span();
self.advance();
Ident::new("_".to_string(), span)
} else {
self.parse_ident()?
};
let typ = if self.check(TokenKind::Colon) {
self.advance();
@@ -2207,7 +2221,15 @@ impl Parser {
// Let statement
let let_start = self.current_span();
self.advance();
let name = self.parse_ident()?;
// Allow underscore as wildcard pattern (discards the value)
let name = if self.check(TokenKind::Underscore) {
let span = self.current_span();
self.advance();
Ident::new("_".to_string(), span)
} else {
self.parse_ident()?
};
let typ = if self.check(TokenKind::Colon) {
self.advance();