feat: add tuple index access, multiline args, and effect unification fix
- Tuple index: `pair.0`, `pair.1` syntax across parser, typechecker, interpreter, C/JS backends, formatter, linter, and symbol table - Multi-line function args: allow newlines inside argument lists - Fix effect unification for callback parameters (empty expected effects means "no constraint", not "must be pure") Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -335,7 +335,7 @@ fn references_params(expr: &Expr, params: &[&str]) -> bool {
|
||||
Statement::Expr(e) => references_params(e, params),
|
||||
}) || references_params(result, params)
|
||||
}
|
||||
Expr::Field { object, .. } => references_params(object, params),
|
||||
Expr::Field { object, .. } | Expr::TupleIndex { object, .. } => references_params(object, params),
|
||||
Expr::Lambda { body, .. } => references_params(body, params),
|
||||
Expr::Tuple { elements, .. } => elements.iter().any(|e| references_params(e, params)),
|
||||
Expr::List { elements, .. } => elements.iter().any(|e| references_params(e, params)),
|
||||
@@ -519,7 +519,7 @@ fn has_recursive_calls(func_name: &str, body: &Expr) -> bool {
|
||||
Expr::Record { fields, .. } => {
|
||||
fields.iter().any(|(_, e)| has_recursive_calls(func_name, e))
|
||||
}
|
||||
Expr::Field { object, .. } => has_recursive_calls(func_name, object),
|
||||
Expr::Field { object, .. } | Expr::TupleIndex { object, .. } => has_recursive_calls(func_name, object),
|
||||
Expr::Let { value, body, .. } => {
|
||||
has_recursive_calls(func_name, value) || has_recursive_calls(func_name, body)
|
||||
}
|
||||
@@ -1673,6 +1673,42 @@ impl TypeChecker {
|
||||
span,
|
||||
} => self.infer_field(object, field, *span),
|
||||
|
||||
Expr::TupleIndex {
|
||||
object,
|
||||
index,
|
||||
span,
|
||||
} => {
|
||||
let object_type = self.infer_expr(object);
|
||||
match &object_type {
|
||||
Type::Tuple(types) => {
|
||||
if *index < types.len() {
|
||||
types[*index].clone()
|
||||
} else {
|
||||
self.errors.push(TypeError {
|
||||
message: format!(
|
||||
"Tuple index {} out of bounds for tuple with {} elements",
|
||||
index,
|
||||
types.len()
|
||||
),
|
||||
span: *span,
|
||||
});
|
||||
Type::Error
|
||||
}
|
||||
}
|
||||
Type::Var(_) => Type::var(),
|
||||
_ => {
|
||||
self.errors.push(TypeError {
|
||||
message: format!(
|
||||
"Cannot use tuple index on non-tuple type {}",
|
||||
object_type
|
||||
),
|
||||
span: *span,
|
||||
});
|
||||
Type::Error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expr::Lambda {
|
||||
params,
|
||||
return_type,
|
||||
|
||||
Reference in New Issue
Block a user