fix: add Char pattern matching and Char comparison operators

- Parser: support Char literals in match patterns (e.g., 'x' => ...)
- Interpreter: add Char comparison for <, <=, >, >= operators
  Previously only Int, Float, and String supported ordering comparisons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 08:25:15 -05:00
parent d26fd975d1
commit e3b6f4322a
2 changed files with 12 additions and 0 deletions

View File

@@ -1610,6 +1610,7 @@ impl Interpreter {
(Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a < b)), (Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a < b)),
(Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a < b)), (Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a < b)),
(Value::String(a), Value::String(b)) => Ok(Value::Bool(a < b)), (Value::String(a), Value::String(b)) => Ok(Value::Bool(a < b)),
(Value::Char(a), Value::Char(b)) => Ok(Value::Bool(a < b)),
(l, r) => Err(RuntimeError { (l, r) => Err(RuntimeError {
message: format!("Cannot compare {} and {}", l.type_name(), r.type_name()), message: format!("Cannot compare {} and {}", l.type_name(), r.type_name()),
span: Some(span), span: Some(span),
@@ -1619,6 +1620,7 @@ impl Interpreter {
(Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a <= b)), (Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a <= b)),
(Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a <= b)), (Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a <= b)),
(Value::String(a), Value::String(b)) => Ok(Value::Bool(a <= b)), (Value::String(a), Value::String(b)) => Ok(Value::Bool(a <= b)),
(Value::Char(a), Value::Char(b)) => Ok(Value::Bool(a <= b)),
(l, r) => Err(RuntimeError { (l, r) => Err(RuntimeError {
message: format!("Cannot compare {} and {}", l.type_name(), r.type_name()), message: format!("Cannot compare {} and {}", l.type_name(), r.type_name()),
span: Some(span), span: Some(span),
@@ -1628,6 +1630,7 @@ impl Interpreter {
(Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a > b)), (Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a > b)),
(Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a > b)), (Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a > b)),
(Value::String(a), Value::String(b)) => Ok(Value::Bool(a > b)), (Value::String(a), Value::String(b)) => Ok(Value::Bool(a > b)),
(Value::Char(a), Value::Char(b)) => Ok(Value::Bool(a > b)),
(l, r) => Err(RuntimeError { (l, r) => Err(RuntimeError {
message: format!("Cannot compare {} and {}", l.type_name(), r.type_name()), message: format!("Cannot compare {} and {}", l.type_name(), r.type_name()),
span: Some(span), span: Some(span),
@@ -1637,6 +1640,7 @@ impl Interpreter {
(Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a >= b)), (Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a >= b)),
(Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a >= b)), (Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a >= b)),
(Value::String(a), Value::String(b)) => Ok(Value::Bool(a >= b)), (Value::String(a), Value::String(b)) => Ok(Value::Bool(a >= b)),
(Value::Char(a), Value::Char(b)) => Ok(Value::Bool(a >= b)),
(l, r) => Err(RuntimeError { (l, r) => Err(RuntimeError {
message: format!("Cannot compare {} and {}", l.type_name(), r.type_name()), message: format!("Cannot compare {} and {}", l.type_name(), r.type_name()),
span: Some(span), span: Some(span),

View File

@@ -1887,6 +1887,14 @@ impl Parser {
span: token.span, span: token.span,
})) }))
} }
TokenKind::Char(c) => {
let c = *c;
self.advance();
Ok(Pattern::Literal(Literal {
kind: LiteralKind::Char(c),
span: token.span,
}))
}
TokenKind::Ident(name) => { TokenKind::Ident(name) => {
// Check if it starts with uppercase (constructor) or lowercase (variable) // Check if it starts with uppercase (constructor) or lowercase (variable)
if name.chars().next().map_or(false, |c| c.is_uppercase()) { if name.chars().next().map_or(false, |c| c.is_uppercase()) {