1use crate::stdlib::register_stdlib;
2use crate::ast::*;
3use crate::env::Environment;
4use crate::value::Value;
5use crate::lexer::Lexer;
6use crate::parser::Parser;
7use std::collections::HashMap;
8
9#[derive(Debug, Clone)]
10pub struct RuntimeError {
11 pub message: String,
12}
13
14impl RuntimeError {
15 pub fn new(message: impl Into<String>) -> Self {
16 RuntimeError { message: message.into() }
17 }
18}
19
20impl std::fmt::Display for RuntimeError {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 write!(f, "runtime error: {}", self.message)
23 }
24}
25
26impl std::error::Error for RuntimeError {}
27
28pub struct Interpreter {
29 env: Environment,
30}
31
32impl Interpreter {
33 pub fn new() -> Self {
34 let mut interp = Interpreter {
35 env: Environment::new(),
36 };
37 register_stdlib(&mut interp.env);
38 interp
39 }
40
41 pub fn env(&self) -> &Environment {
42 &self.env
43 }
44
45 pub fn env_mut(&mut self) -> &mut Environment {
46 &mut self.env
47 }
48
49 pub fn run_source(&mut self, source: &str) -> Result<Value, RuntimeError> {
50 let tokens = Lexer::tokenize(source).map_err(|e| RuntimeError::new(e.message))?;
51 let stmts = Parser::parse(tokens).map_err(|e| RuntimeError::new(e.message))?;
52 let mut last = Value::Unit;
53 for stmt in &stmts {
54 last = self.exec_stmt(stmt)?;
55 }
56 Ok(last)
57 }
58
59 pub fn exec_stmt(&mut self, stmt: &Stmt) -> Result<Value, RuntimeError> {
60 match stmt {
61 Stmt::Expr(expr) => self.eval_expr(expr),
62 Stmt::ValDecl { pattern, value, .. } => {
63 let val = self.eval_expr(value)?;
64 self.bind_pattern(pattern, &val)?;
65 Ok(Value::Unit)
66 }
67 Stmt::VarDecl { pattern, value, .. } => {
68 let val = self.eval_expr(value)?;
69 self.bind_pattern_mut(pattern, &val)?;
70 Ok(Value::Unit)
71 }
72 Stmt::DefDecl(def_decl) => {
73 let closure = self.env.capture();
74 let fn_val = Value::Function {
75 name: Some(def_decl.name.clone()),
76 params: def_decl.params.iter().map(|p| p.name.clone()).collect(),
77 body: def_decl.body.clone(),
78 closure,
79 };
80 self.env.define(&def_decl.name, fn_val, false);
81 Ok(Value::Unit)
82 }
83 Stmt::ClassDecl(class) => {
84 let ctor_name = class.name.clone();
85 let ctor_params = class.ctor_params.clone();
86 let is_case = class.is_case;
87 let class_body = class.body.clone();
88
89 let class_val = Value::Object {
90 class_name: format!("${}$class", ctor_name),
91 fields: {
92 let mut f = HashMap::new();
93 f.insert("__ctor_params__".into(), Value::List(
94 ctor_params.iter().map(|p| Value::String(p.name.clone())).collect()
95 ));
96 f.insert("__is_case__".into(), Value::Bool(is_case));
97 f
98 },
99 methods: {
100 let mut m = HashMap::new();
101 for stmt in &class_body {
102 if let Stmt::DefDecl(d) = stmt {
103 m.insert(d.name.clone(), Value::Function {
104 name: Some(d.name.clone()),
105 params: d.params.iter().map(|p| p.name.clone()).collect(),
106 body: d.body.clone(),
107 closure: vec![],
108 });
109 }
110 }
111 m
112 },
113 };
114 self.env.define(&ctor_name, class_val, false);
115 Ok(Value::Unit)
116 }
117 Stmt::TraitDecl(_) => Ok(Value::Unit),
118 Stmt::ObjectDecl(obj) => {
119 let mut fields = HashMap::new();
120 let mut methods = HashMap::new();
121 self.env.push();
122 for stmt in &obj.body {
123 match stmt {
124 Stmt::ValDecl { pattern, value, .. } => {
125 let val = self.eval_expr(value)?;
126 if let Pattern::Variable { name, .. } = pattern {
127 fields.insert(name.clone(), val.clone());
128 self.env.define(name, val, false);
129 }
130 }
131 Stmt::VarDecl { pattern, value, .. } => {
132 let val = self.eval_expr(value)?;
133 if let Pattern::Variable { name, .. } = pattern {
134 fields.insert(name.clone(), val.clone());
135 self.env.define(name, val, true);
136 }
137 }
138 Stmt::DefDecl(d) => {
139 let closure = self.env.capture();
140 let fn_val = Value::Function {
141 name: Some(d.name.clone()),
142 params: d.params.iter().map(|p| p.name.clone()).collect(),
143 body: d.body.clone(),
144 closure,
145 };
146 methods.insert(d.name.clone(), fn_val.clone());
147 self.env.define(&d.name, fn_val, false);
148 }
149 _ => { let _ = self.exec_stmt(stmt); }
150 }
151 }
152 self.env.pop();
153 let obj_val = Value::Object {
154 class_name: obj.name.clone(),
155 fields,
156 methods,
157 };
158 self.env.define(&obj.name, obj_val, false);
159 Ok(Value::Unit)
160 }
161 Stmt::ImportDecl { .. } => Ok(Value::Unit),
162 Stmt::TypeDecl { .. } => Ok(Value::Unit),
163 }
164 }
165
166 pub fn eval_expr(&mut self, expr: &Expr) -> Result<Value, RuntimeError> {
167 match expr {
168 Expr::Literal { value, .. } => Ok(literal_to_value(value)),
169
170 Expr::Binary { left, op, right, .. } => {
171 let lv = self.eval_expr(left)?;
172 match op {
173 BinOp::And => {
174 if !lv.is_truthy() { return Ok(Value::Bool(false)); }
175 let rv = self.eval_expr(right)?;
176 Ok(Value::Bool(rv.is_truthy()))
177 }
178 BinOp::Or => {
179 if lv.is_truthy() { return Ok(Value::Bool(true)); }
180 let rv = self.eval_expr(right)?;
181 Ok(Value::Bool(rv.is_truthy()))
182 }
183 _ => {
184 let rv = self.eval_expr(right)?;
185 self.eval_binary(&lv, op, &rv)
186 }
187 }
188 }
189
190 Expr::Unary { op, operand, .. } => {
191 let v = self.eval_expr(operand)?;
192 match op {
193 UnaryOp::Negate => v.to_int().map(|n| Value::Int(-n))
194 .or_else(|| v.to_double().map(|n| Value::Double(-n)))
195 .ok_or_else(|| RuntimeError::new(format!("cannot negate {}", v.type_name()))),
196 UnaryOp::Not => Ok(Value::Bool(!v.is_truthy())),
197 UnaryOp::BitNot => v.to_int().map(|n| Value::Int(!n))
198 .ok_or_else(|| RuntimeError::new(format!("cannot bitwise negate {}", v.type_name()))),
199 UnaryOp::Positive => Ok(v),
200 }
201 }
202
203 Expr::If { cond, then_branch, else_branch, .. } => {
204 let cv = self.eval_expr(cond)?;
205 if cv.is_truthy() {
206 self.eval_expr(then_branch)
207 } else if let Some(els) = else_branch {
208 self.eval_expr(els)
209 } else {
210 Ok(Value::Unit)
211 }
212 }
213
214 Expr::Block { stmts, .. } => {
215 self.env.push();
216 let mut last = Value::Unit;
217 for stmt in stmts {
218 last = self.exec_stmt(stmt)?;
219 }
220 self.env.pop();
221 Ok(last)
222 }
223
224 Expr::Lambda { params, body, .. } => {
225 let closure = self.env.capture();
226 Ok(Value::Function {
227 name: None,
228 params: params.iter().map(|p| p.name.clone()).collect(),
229 body: (**body).clone(),
230 closure,
231 })
232 }
233
234 Expr::Identifier { name, .. } => {
235 self.env.lookup(name).cloned().ok_or_else(|| {
236 RuntimeError::new(format!("not found: value {}", name))
237 })
238 }
239
240 Expr::Apply { func, args, .. } => {
241 let fv = self.eval_expr(func)?;
242 let arg_vals: Vec<Value> = args.iter().map(|a| self.eval_expr(a)).collect::<Result<Vec<_>, _>>()?;
243 self.call_value(fv, arg_vals)
244 }
245
246 Expr::MethodCall { receiver, method, args, .. } => {
247 let rv = self.eval_expr(receiver)?;
248 let arg_vals: Vec<Value> = args.iter().map(|a| self.eval_expr(a)).collect::<Result<Vec<_>, _>>()?;
249 self.eval_method_call(rv, method, arg_vals)
250 }
251
252 Expr::FieldAccess { receiver, field, .. } => {
253 let rv = self.eval_expr(receiver)?;
254 match self.eval_field_access(&rv, field) {
255 ok @ Ok(_) => ok,
256 Err(_) => self.eval_method_call(rv, field, vec![]),
257 }
258 }
259
260 Expr::Match { scrutinee, cases, .. } => {
261 let sv = self.eval_expr(scrutinee)?;
262 self.eval_match(&sv, cases)
263 }
264
265 Expr::Tuple { elements, .. } => {
266 let vals: Vec<Value> = elements.iter().map(|e| self.eval_expr(e)).collect::<Result<Vec<_>, _>>()?;
267 Ok(Value::Tuple(vals))
268 }
269
270 Expr::Assign { target, value, .. } => {
271 let vv = self.eval_expr(value)?;
272 match &**target {
273 Expr::Identifier { name, .. } => {
274 if !self.env.assign(name, vv) {
275 return Err(RuntimeError::new(format!("cannot assign to {}", name)));
276 }
277 Ok(Value::Unit)
278 }
279 _ => Err(RuntimeError::new("invalid assignment target")),
280 }
281 }
282
283 Expr::Return { value, .. } => {
284 if let Some(v) = value {
285 let val = self.eval_expr(v)?;
286 Err(RuntimeError::new(format!("__return__{}", val)))
287 } else {
288 Err(RuntimeError::new("__return__()"))
289 }
290 }
291
292 Expr::Throw { value, .. } => {
293 let v = self.eval_expr(value)?;
294 Err(RuntimeError::new(format!("__exception__{}", v)))
295 }
296
297 Expr::Try { body, catches, finally_block, .. } => {
298 match self.eval_expr(body) {
299 Ok(v) => {
300 if let Some(fin) = finally_block {
301 self.eval_expr(fin)?;
302 }
303 Ok(v)
304 }
305 Err(e) => {
306 let err_str = e.message.clone();
307 let matched = self.try_catch(&err_str, catches);
308 if let Some(r) = matched {
309 if let Some(fin) = finally_block {
310 let _ = self.eval_expr(fin);
311 }
312 r
313 } else {
314 if let Some(fin) = finally_block {
315 let _ = self.eval_expr(fin);
316 }
317 Err(e)
318 }
319 }
320 }
321 }
322
323 Expr::New { class_name, args, .. } => {
324 let arg_vals: Vec<Value> = args.iter().map(|a| self.eval_expr(a)).collect::<Result<Vec<_>, _>>()?;
325 let class_val = self.env.lookup(class_name).cloned();
326 match class_val {
327 Some(Value::Object { fields, methods, .. }) => {
328 let ctor_params = fields.get("__ctor_params__")
329 .and_then(|v| if let Value::List(names) = v {
330 Some(names.iter().map(|n| {
331 if let Value::String(s) = n { s.clone() } else { format!("{}", n) }
332 }).collect::<Vec<_>>())
333 } else { None })
334 .unwrap_or_default();
335 let mut obj_fields = HashMap::new();
336 for (i, param_name) in ctor_params.iter().enumerate() {
337 if i < arg_vals.len() {
338 obj_fields.insert(param_name.clone(), arg_vals[i].clone());
339 }
340 }
341 Ok(Value::Object {
342 class_name: class_name.clone(),
343 fields: obj_fields,
344 methods: methods.clone(),
345 })
346 }
347 Some(v) => self.call_value(v, arg_vals),
348 None => Err(RuntimeError::new(format!("not found: type {}", class_name))),
349 }
350 }
351
352 Expr::For { enumerators, body, is_yield, .. } => {
353 if *is_yield {
354 let mut results = Vec::new();
355 self.eval_for_enumerators(enumerators, &mut |env| {
356 let val = env.eval_expr(body)?;
357 results.push(val);
358 Ok(())
359 })?;
360 Ok(Value::List(results))
361 } else {
362 self.eval_for_enumerators(enumerators, &mut |env| {
363 env.eval_expr(body)?;
364 Ok(())
365 })?;
366 Ok(Value::Unit)
367 }
368 }
369
370 Expr::While { cond, body, .. } => {
371 loop {
372 let cv = self.eval_expr(cond)?;
373 if !cv.is_truthy() { break; }
374 self.eval_expr(body)?;
375 }
376 Ok(Value::Unit)
377 }
378
379 Expr::DoWhile { body, cond, .. } => {
380 loop {
381 self.eval_expr(body)?;
382 let cv = self.eval_expr(cond)?;
383 if !cv.is_truthy() { break; }
384 }
385 Ok(Value::Unit)
386 }
387
388 Expr::StringInterpolation { parts, .. } => {
389 let mut result = String::new();
390 for part in parts {
391 match part {
392 InterpPart::Literal(s) => result.push_str(s),
393 InterpPart::Expression(expr) => {
394 let v = self.eval_expr(expr)?;
395 result.push_str(&format!("{}", v));
396 }
397 }
398 }
399 Ok(Value::String(result))
400 }
401
402 Expr::This(_) => {
403 self.env.lookup("this").cloned()
404 .ok_or_else(|| RuntimeError::new("'this' used outside of class"))
405 }
406 Expr::Super(_) => {
407 self.env.lookup("super").cloned()
408 .ok_or_else(|| RuntimeError::new("'super' used outside of class"))
409 }
410 Expr::Paren { expr, .. } => self.eval_expr(expr),
411 Expr::TypeApply { expr, .. } => self.eval_expr(expr),
412 Expr::UnaryMethodCall { receiver, method, .. } => {
413 let rv = self.eval_expr(receiver)?;
414 self.eval_method_call(rv, method, vec![])
415 }
416 }
417 }
418
419 fn eval_binary(&self, left: &Value, op: &BinOp, right: &Value) -> Result<Value, RuntimeError> {
420 match op {
421 BinOp::Add => match (left, right) {
422 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a + b)),
423 (Value::Long(a), Value::Long(b)) => Ok(Value::Long(a + b)),
424 (Value::Int(a), Value::Long(b)) => Ok(Value::Long(a + b)),
425 (Value::Long(a), Value::Int(b)) => Ok(Value::Long(a + b)),
426 (Value::Double(a), Value::Double(b)) => Ok(Value::Double(a + b)),
427 (Value::Int(a), Value::Double(b)) => Ok(Value::Double(*a as f64 + b)),
428 (Value::Double(a), Value::Int(b)) => Ok(Value::Double(a + *b as f64)),
429 (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a + b)),
430 (Value::String(a), _) => Ok(Value::String(format!("{}{}", a, right))),
431 (_, Value::String(b)) => Ok(Value::String(format!("{}{}", left, b))),
432 _ => Err(RuntimeError::new(format!("cannot add {} and {}", left.type_name(), right.type_name()))),
433 },
434 BinOp::Sub => match (left, right) {
435 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a - b)),
436 (Value::Long(a), Value::Long(b)) => Ok(Value::Long(a - b)),
437 (Value::Double(a), Value::Double(b)) => Ok(Value::Double(a - b)),
438 (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a - b)),
439 (Value::Int(a), Value::Double(b)) => Ok(Value::Double(*a as f64 - b)),
440 (Value::Double(a), Value::Int(b)) => Ok(Value::Double(a - *b as f64)),
441 _ => Err(RuntimeError::new(format!("cannot subtract {} and {}", left.type_name(), right.type_name()))),
442 },
443 BinOp::Mul => match (left, right) {
444 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a * b)),
445 (Value::Long(a), Value::Long(b)) => Ok(Value::Long(a * b)),
446 (Value::Double(a), Value::Double(b)) => Ok(Value::Double(a * b)),
447 (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a * b)),
448 (Value::Int(a), Value::Double(b)) => Ok(Value::Double(*a as f64 * b)),
449 (Value::Double(a), Value::Int(b)) => Ok(Value::Double(a * *b as f64)),
450 _ => Err(RuntimeError::new(format!("cannot multiply {} and {}", left.type_name(), right.type_name()))),
451 },
452 BinOp::Div => match (left, right) {
453 (Value::Int(a), Value::Int(b)) => {
454 if *b == 0 { return Err(RuntimeError::new("division by zero")); }
455 Ok(Value::Int(a / b))
456 }
457 (Value::Double(a), Value::Double(b)) => Ok(Value::Double(a / b)),
458 (Value::Int(a), Value::Double(b)) => Ok(Value::Double(*a as f64 / b)),
459 (Value::Double(a), Value::Int(b)) => Ok(Value::Double(a / *b as f64)),
460 _ => Err(RuntimeError::new("cannot divide")),
461 },
462 BinOp::Mod => match (left, right) {
463 (Value::Int(a), Value::Int(b)) => {
464 if *b == 0 { return Err(RuntimeError::new("division by zero")); }
465 Ok(Value::Int(a % b))
466 }
467 (Value::Double(a), Value::Double(b)) => Ok(Value::Double(a % b)),
468 _ => Err(RuntimeError::new("cannot modulo")),
469 },
470 BinOp::Eq => Ok(Value::Bool(left == right)),
471 BinOp::Neq => Ok(Value::Bool(left != right)),
472 BinOp::Lt => self.compare_values(left, right, std::cmp::Ordering::is_lt),
473 BinOp::Gt => self.compare_values(left, right, std::cmp::Ordering::is_gt),
474 BinOp::Leq => self.compare_values(left, right, std::cmp::Ordering::is_le),
475 BinOp::Geq => self.compare_values(left, right, std::cmp::Ordering::is_ge),
476 BinOp::BitAnd => match (left, right) {
477 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a & b)),
478 (Value::Long(a), Value::Long(b)) => Ok(Value::Long(a & b)),
479 (Value::Bool(a), Value::Bool(b)) => Ok(Value::Bool(*a && *b)),
480 _ => Err(RuntimeError::new("cannot bitwise and")),
481 },
482 BinOp::BitOr => match (left, right) {
483 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a | b)),
484 (Value::Long(a), Value::Long(b)) => Ok(Value::Long(a | b)),
485 (Value::Bool(a), Value::Bool(b)) => Ok(Value::Bool(*a || *b)),
486 _ => Err(RuntimeError::new("cannot bitwise or")),
487 },
488 BinOp::BitXor => match (left, right) {
489 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a ^ b)),
490 (Value::Long(a), Value::Long(b)) => Ok(Value::Long(a ^ b)),
491 _ => Err(RuntimeError::new("cannot bitwise xor")),
492 },
493 BinOp::LeftShift => match (left, right) {
494 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a << b)),
495 (Value::Long(a), Value::Int(b)) => Ok(Value::Long(a << b)),
496 _ => Err(RuntimeError::new("cannot shift left")),
497 },
498 BinOp::RightShift => match (left, right) {
499 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a >> b)),
500 (Value::Long(a), Value::Int(b)) => Ok(Value::Long(a >> b)),
501 _ => Err(RuntimeError::new("cannot shift right")),
502 },
503 BinOp::UnsignedRightShift => match (left, right) {
504 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(((*a as u64) >> b) as i64)),
505 (Value::Long(a), Value::Int(b)) => Ok(Value::Long(((*a as u64) >> b) as i64)),
506 _ => Err(RuntimeError::new("cannot unsigned shift right")),
507 },
508 BinOp::And | BinOp::Or => unreachable!(),
509 }
510 }
511
512 fn compare_values(&self, left: &Value, right: &Value, check: fn(std::cmp::Ordering) -> bool) -> Result<Value, RuntimeError> {
513 let ord = match (left, right) {
514 (Value::Int(a), Value::Int(b)) => a.cmp(b),
515 (Value::Long(a), Value::Long(b)) => a.cmp(b),
516 (Value::Double(a), Value::Double(b)) => a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal),
517 (Value::Int(a), Value::Double(b)) => (*a as f64).partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal),
518 (Value::Double(a), Value::Int(b)) => a.partial_cmp(&(*b as f64)).unwrap_or(std::cmp::Ordering::Equal),
519 (Value::String(a), Value::String(b)) => a.cmp(b),
520 (Value::Char(a), Value::Char(b)) => a.cmp(b),
521 _ => return Err(RuntimeError::new(format!("cannot compare {} and {}", left.type_name(), right.type_name()))),
522 };
523 Ok(Value::Bool(check(ord)))
524 }
525
526 fn call_value(&mut self, func: Value, args: Vec<Value>) -> Result<Value, RuntimeError> {
527 match func {
528 Value::Function { params, body, closure, .. } => {
529 if params.len() != args.len() {
530 return Err(RuntimeError::new(
531 format!("wrong number of arguments: expected {}, got {}", params.len(), args.len())
532 ));
533 }
534 self.env.push();
535 self.env.restore(&closure);
536 for (name, val) in params.iter().zip(args.iter()) {
537 self.env.define(name, val.deep_clone(), false);
538 }
539 let result = match self.eval_expr(&body) {
540 Ok(v) => v,
541 Err(e) if e.message.starts_with("__return__") => {
542 let val_str = &e.message["__return__".len()..];
543 self.env.pop();
544 if val_str == "()" { return Ok(Value::Unit); }
545 return Err(e);
546 }
547 Err(e) => { self.env.pop(); return Err(e); }
548 };
549 self.env.pop();
550 Ok(result)
551 }
552 Value::BuiltinFunction { name, .. } => self.call_builtin(&name, args),
553 Value::Object { class_name, fields, methods } => {
554 let ctor_params = fields.get("__ctor_params__")
555 .and_then(|v| if let Value::List(names) = v {
556 Some(names.iter().map(|n| {
557 if let Value::String(s) = n { s.clone() } else { format!("{}", n) }
558 }).collect::<Vec<_>>())
559 } else { None })
560 .unwrap_or_default();
561 let mut obj_fields = HashMap::new();
562 for (i, param_name) in ctor_params.iter().enumerate() {
563 if i < args.len() {
564 obj_fields.insert(param_name.clone(), args[i].clone());
565 }
566 }
567 Ok(Value::Object { class_name, fields: obj_fields, methods })
568 }
569 _ => Err(RuntimeError::new(format!("cannot call {}", func.type_name()))),
570 }
571 }
572
573 fn call_builtin(&mut self, name: &str, args: Vec<Value>) -> Result<Value, RuntimeError> {
574 match name {
575 "__println__" => {
576 match args.first() {
577 Some(v) => println!("{}", v),
578 None => println!(),
579 }
580 Ok(Value::Unit)
581 }
582 "__print__" => {
583 if let Some(v) = args.first() { print!("{}", v); }
584 Ok(Value::Unit)
585 }
586 "__assert__" => {
587 if let Some(Value::Bool(false)) = args.first() {
588 Err(RuntimeError::new("assertion failed"))
589 } else { Ok(Value::Unit) }
590 }
591 "__require__" => {
592 if let Some(Value::Bool(false)) = args.first() {
593 Err(RuntimeError::new("requirement failed"))
594 } else { Ok(Value::Unit) }
595 }
596 "__identity__" => Ok(args.first().cloned().unwrap_or(Value::Unit)),
597 "__List_apply__" => Ok(Value::List(args)),
598 "__Map_apply__" => {
599 let mut entries = Vec::new();
600 for arg in &args {
601 if let Value::Tuple(pair) = arg {
602 if pair.len() == 2 { entries.push((pair[0].clone(), pair[1].clone())); }
603 }
604 }
605 Ok(Value::Map(entries))
606 }
607 "__Some__" => Ok(args.first().cloned().unwrap_or(Value::Null)),
608 "__abs__" => match args.first() {
609 Some(Value::Int(n)) => Ok(Value::Int(n.abs())),
610 Some(Value::Double(n)) => Ok(Value::Double(n.abs())),
611 Some(Value::Long(n)) => Ok(Value::Long(n.abs())),
612 _ => Err(RuntimeError::new("abs requires numeric")),
613 },
614 "__max__" => match (args.first(), args.get(1)) {
615 (Some(Value::Int(a)), Some(Value::Int(b))) => Ok(Value::Int((*a).max(*b))),
616 (Some(Value::Double(a)), Some(Value::Double(b))) => Ok(Value::Double(a.max(*b))),
617 _ => Err(RuntimeError::new("max requires two numbers")),
618 },
619 "__min__" => match (args.first(), args.get(1)) {
620 (Some(Value::Int(a)), Some(Value::Int(b))) => Ok(Value::Int((*a).min(*b))),
621 (Some(Value::Double(a)), Some(Value::Double(b))) => Ok(Value::Double(a.min(*b))),
622 _ => Err(RuntimeError::new("min requires two numbers")),
623 },
624 "__pow__" => match (args.first(), args.get(1)) {
625 (Some(Value::Double(a)), Some(Value::Double(b))) => Ok(Value::Double(a.powf(*b))),
626 (Some(Value::Int(a)), Some(Value::Int(b))) => Ok(Value::Double((*a as f64).powf(*b as f64))),
627 _ => Err(RuntimeError::new("pow requires two numbers")),
628 },
629 "__sqrt__" => match args.first() {
630 Some(Value::Double(n)) => Ok(Value::Double(n.sqrt())),
631 Some(Value::Int(n)) => Ok(Value::Double((*n as f64).sqrt())),
632 _ => Err(RuntimeError::new("sqrt requires numeric")),
633 },
634 "__range_to__" => match (args.first(), args.get(1)) {
635 (Some(Value::Int(a)), Some(Value::Int(b))) => {
636 Ok(Value::List((*a..=*b).map(Value::Int).collect()))
637 }
638 _ => Err(RuntimeError::new("range requires two ints")),
639 },
640 "__range_until__" => match (args.first(), args.get(1)) {
641 (Some(Value::Int(a)), Some(Value::Int(b))) => {
642 Ok(Value::List((*a..*b).map(Value::Int).collect()))
643 }
644 _ => Err(RuntimeError::new("range until requires two ints")),
645 },
646 other => Err(RuntimeError::new(format!("unknown builtin: {}", other))),
647 }
648 }
649
650 #[allow(clippy::cognitive_complexity)]
651 fn eval_method_call(&mut self, receiver: Value, method: &str, args: Vec<Value>) -> Result<Value, RuntimeError> {
652 match (&receiver, method) {
653 (Value::String(s), "length") => Ok(Value::Int(s.len() as i64)),
654 (Value::String(s), "substring") => match (args.first(), args.get(1)) {
655 (Some(Value::Int(start)), Some(Value::Int(end))) => Ok(Value::String(s[*start as usize..*end as usize].to_string())),
656 (Some(Value::Int(start)), None) => Ok(Value::String(s[*start as usize..].to_string())),
657 _ => Err(RuntimeError::new("substring requires int args")),
658 },
659 (Value::String(s), "split") => match args.first() {
660 Some(Value::String(sep)) => Ok(Value::List(s.split(sep).map(|p| Value::String(p.to_string())).collect())),
661 _ => Err(RuntimeError::new("split requires string arg")),
662 },
663 (Value::String(s), "trim") => Ok(Value::String(s.trim().to_string())),
664 (Value::String(s), "toUpperCase") => Ok(Value::String(s.to_uppercase())),
665 (Value::String(s), "toLowerCase") => Ok(Value::String(s.to_lowercase())),
666 (Value::String(s), "replace") => match (args.first(), args.get(1)) {
667 (Some(Value::String(from)), Some(Value::String(to))) => Ok(Value::String(s.replace(from.as_str(), to.as_str()))),
668 _ => Err(RuntimeError::new("replace requires two strings")),
669 },
670 (Value::String(s), "contains") => match args.first() {
671 Some(Value::String(sub)) => Ok(Value::Bool(s.contains(sub.as_str()))),
672 _ => Err(RuntimeError::new("contains requires string")),
673 },
674 (Value::String(s), "startsWith") => match args.first() {
675 Some(Value::String(prefix)) => Ok(Value::Bool(s.starts_with(prefix.as_str()))),
676 _ => Err(RuntimeError::new("startsWith requires string")),
677 },
678 (Value::String(s), "endsWith") => match args.first() {
679 Some(Value::String(suffix)) => Ok(Value::Bool(s.ends_with(suffix.as_str()))),
680 _ => Err(RuntimeError::new("endsWith requires string")),
681 },
682 (Value::String(s), "isEmpty") => Ok(Value::Bool(s.is_empty())),
683 (Value::String(s), "nonEmpty") => Ok(Value::Bool(!s.is_empty())),
684 (Value::String(s), "reverse") => Ok(Value::String(s.chars().rev().collect())),
685 (Value::String(s), "indexOf") => match args.first() {
686 Some(Value::String(sub)) => Ok(Value::Int(s.find(sub.as_str()).map_or(-1, |i| i as i64))),
687 _ => Err(RuntimeError::new("indexOf requires string")),
688 },
689 (Value::String(s), "charAt") => match args.first() {
690 Some(Value::Int(idx)) => s.chars().nth(*idx as usize).map(Value::Char).ok_or_else(|| RuntimeError::new("index out of bounds")),
691 _ => Err(RuntimeError::new("charAt requires int")),
692 },
693 (Value::String(s), "toInt") => s.parse::<i64>().map(Value::Int).map_err(|_| RuntimeError::new(format!("cannot parse '{}' as Int", s))),
694 (Value::String(s), "toDouble") => s.parse::<f64>().map(Value::Double).map_err(|_| RuntimeError::new(format!("cannot parse '{}' as Double", s))),
695 (Value::String(s), "strip") => Ok(Value::String(s.trim().to_string())),
696 (Value::Int(n), "toString") => Ok(Value::String(n.to_string())),
697 (Value::Int(n), "toLong") => Ok(Value::Long(*n)),
698 (Value::Int(n), "toDouble") => Ok(Value::Double(*n as f64)),
699 (Value::Int(n), "toFloat") => Ok(Value::Float(*n as f64)),
700 (Value::Int(n), "toChar") => Ok(Value::Char(char::from_u32(*n as u32).unwrap_or('\0'))),
701 (Value::Long(n), "toInt") => Ok(Value::Int(*n)),
702 (Value::Long(n), "toDouble") => Ok(Value::Double(*n as f64)),
703 (Value::Double(n), "toInt") => Ok(Value::Int(*n as i64)),
704 (Value::Double(n), "toFloat") => Ok(Value::Float(*n)),
705 (Value::Double(n), "toLong") => Ok(Value::Long(*n as i64)),
706 (Value::Float(n), "toDouble") => Ok(Value::Double(*n)),
707 (Value::Float(n), "toInt") => Ok(Value::Int(*n as i64)),
708 (Value::Char(c), "toInt") => Ok(Value::Int(*c as i64)),
709 (Value::Bool(b), "toString") => Ok(Value::String(b.to_string())),
710
711 (Value::List(elements), "length") | (Value::List(elements), "size") => Ok(Value::Int(elements.len() as i64)),
712 (Value::List(elements), "isEmpty") => Ok(Value::Bool(elements.is_empty())),
713 (Value::List(elements), "nonEmpty") => Ok(Value::Bool(!elements.is_empty())),
714 (Value::List(elements), "head") => elements.first().cloned().ok_or_else(|| RuntimeError::new("head of empty list")),
715 (Value::List(elements), "last") => elements.last().cloned().ok_or_else(|| RuntimeError::new("last of empty list")),
716 (Value::List(elements), "tail") => {
717 if elements.is_empty() { return Err(RuntimeError::new("tail of empty list")); }
718 Ok(Value::List(elements[1..].to_vec()))
719 }
720 (Value::List(elements), "init") => {
721 if elements.is_empty() { return Err(RuntimeError::new("init of empty list")); }
722 Ok(Value::List(elements[..elements.len()-1].to_vec()))
723 }
724 (Value::List(elements), "reverse") => Ok(Value::List(elements.iter().rev().cloned().collect())),
725 (Value::List(elements), "distinct") => {
726 let mut seen = Vec::new();
727 for e in elements { if !seen.contains(e) { seen.push(e.clone()); } }
728 Ok(Value::List(seen))
729 }
730 (Value::List(elements), "map") => {
731 if let Some(func) = args.first().cloned() {
732 let mut results = Vec::new();
733 for elem in elements { results.push(self.call_value(func.clone(), vec![elem.clone()])?); }
734 Ok(Value::List(results))
735 } else { Err(RuntimeError::new("map requires a function")) }
736 }
737 (Value::List(elements), "flatMap") => {
738 if let Some(func) = args.first().cloned() {
739 let mut results = Vec::new();
740 for elem in elements {
741 match self.call_value(func.clone(), vec![elem.clone()])? {
742 Value::List(inner) => results.extend(inner),
743 other => results.push(other),
744 }
745 }
746 Ok(Value::List(results))
747 } else { Err(RuntimeError::new("flatMap requires a function")) }
748 }
749 (Value::List(elements), "filter") | (Value::List(elements), "withFilter") => {
750 if let Some(func) = args.first().cloned() {
751 let mut results = Vec::new();
752 for elem in elements {
753 if let Value::Bool(true) = self.call_value(func.clone(), vec![elem.clone()])? {
754 results.push(elem.clone());
755 }
756 }
757 Ok(Value::List(results))
758 } else { Err(RuntimeError::new("filter requires a function")) }
759 }
760 (Value::List(elements), "foreach") => {
761 if let Some(func) = args.first().cloned() {
762 for elem in elements { self.call_value(func.clone(), vec![elem.clone()])?; }
763 }
764 Ok(Value::Unit)
765 }
766 (Value::List(elements), "foldLeft") => {
767 if args.len() >= 2 {
768 let mut acc = args[0].clone();
769 let func = args[1].clone();
770 for elem in elements { acc = self.call_value(func.clone(), vec![acc, elem.clone()])?; }
771 Ok(acc)
772 } else { Err(RuntimeError::new("foldLeft requires initial value and function")) }
773 }
774 (Value::List(elements), "foldRight") => {
775 if args.len() >= 2 {
776 let mut acc = args[0].clone();
777 let func = args[1].clone();
778 for elem in elements.iter().rev() { acc = self.call_value(func.clone(), vec![elem.clone(), acc])?; }
779 Ok(acc)
780 } else { Err(RuntimeError::new("foldRight requires initial value and function")) }
781 }
782 (Value::List(elements), "reduce") | (Value::List(elements), "reduceLeft") => {
783 if elements.is_empty() { return Err(RuntimeError::new("reduce on empty list")); }
784 if let Some(func) = args.first().cloned() {
785 let mut acc = elements[0].clone();
786 for elem in &elements[1..] { acc = self.call_value(func.clone(), vec![acc, elem.clone()])?; }
787 Ok(acc)
788 } else { Err(RuntimeError::new("reduce requires a function")) }
789 }
790 (Value::List(elements), "find") => {
791 if let Some(func) = args.first().cloned() {
792 for elem in elements {
793 if let Value::Bool(true) = self.call_value(func.clone(), vec![elem.clone()])? { return Ok(elem.clone()); }
794 }
795 Ok(Value::String("None".into()))
796 } else { Err(RuntimeError::new("find requires a function")) }
797 }
798 (Value::List(elements), "exists") => {
799 if let Some(func) = args.first().cloned() {
800 for elem in elements {
801 if let Value::Bool(true) = self.call_value(func.clone(), vec![elem.clone()])? { return Ok(Value::Bool(true)); }
802 }
803 Ok(Value::Bool(false))
804 } else { Err(RuntimeError::new("exists requires a function")) }
805 }
806 (Value::List(elements), "forall") => {
807 if let Some(func) = args.first().cloned() {
808 for elem in elements {
809 if let Value::Bool(false) = self.call_value(func.clone(), vec![elem.clone()])? { return Ok(Value::Bool(false)); }
810 }
811 Ok(Value::Bool(true))
812 } else { Err(RuntimeError::new("forall requires a function")) }
813 }
814 (Value::List(elements), "count") => {
815 if let Some(func) = args.first().cloned() {
816 let mut count = 0i64;
817 for elem in elements {
818 if let Value::Bool(true) = self.call_value(func.clone(), vec![elem.clone()])? { count += 1; }
819 }
820 Ok(Value::Int(count))
821 } else { Err(RuntimeError::new("count requires a function")) }
822 }
823 (Value::List(elements), "take") => match args.first() {
824 Some(Value::Int(n)) => Ok(Value::List(elements.iter().take(*n as usize).cloned().collect())),
825 _ => Err(RuntimeError::new("take requires int")),
826 },
827 (Value::List(elements), "drop") => match args.first() {
828 Some(Value::Int(n)) => Ok(Value::List(elements.iter().skip(*n as usize).cloned().collect())),
829 _ => Err(RuntimeError::new("drop requires int")),
830 },
831 (Value::List(elements), "zip") => match args.first() {
832 Some(Value::List(other)) => Ok(Value::List(elements.iter().zip(other.iter()).map(|(a, b)| Value::Tuple(vec![a.clone(), b.clone()])).collect())),
833 _ => Err(RuntimeError::new("zip requires a list")),
834 },
835 (Value::List(elements), "zipWithIndex") => {
836 Ok(Value::List(elements.iter().enumerate().map(|(i, v)| Value::Tuple(vec![v.clone(), Value::Int(i as i64)])).collect()))
837 }
838 (Value::List(elements), "sorted") => {
839 let mut sorted = elements.clone();
840 sorted.sort_by(|a, b| match (a, b) {
841 (Value::Int(x), Value::Int(y)) => x.cmp(y),
842 (Value::Double(x), Value::Double(y)) => x.partial_cmp(y).unwrap_or(std::cmp::Ordering::Equal),
843 (Value::String(x), Value::String(y)) => x.cmp(y),
844 _ => std::cmp::Ordering::Equal,
845 });
846 Ok(Value::List(sorted))
847 }
848 (Value::List(elements), "sum") => {
849 let mut total = 0i64;
850 for e in elements { if let Some(n) = e.to_int() { total += n; } }
851 Ok(Value::Int(total))
852 }
853 (Value::List(elements), "product") => {
854 let mut total = 1i64;
855 for e in elements { if let Some(n) = e.to_int() { total *= n; } }
856 Ok(Value::Int(total))
857 }
858 (Value::List(elements), "min") => elements.iter().filter_map(|e| e.to_int()).min().map(Value::Int).ok_or_else(|| RuntimeError::new("min of empty list")),
859 (Value::List(elements), "max") => elements.iter().filter_map(|e| e.to_int()).max().map(Value::Int).ok_or_else(|| RuntimeError::new("max of empty list")),
860 (Value::List(elements), "mkString") => {
861 let sep = match args.first() { Some(Value::String(s)) => s.clone(), _ => String::new() };
862 Ok(Value::String(elements.iter().map(|e| format!("{}", e)).collect::<Vec<_>>().join(&sep)))
863 }
864 (Value::List(elements), "flatten") => {
865 let mut result = Vec::new();
866 for e in elements { match e { Value::List(inner) => result.extend(inner.clone()), other => result.push(other.clone()) } }
867 Ok(Value::List(result))
868 }
869 (Value::List(elements), "contains") => match args.first() {
870 Some(target) => Ok(Value::Bool(elements.contains(target))),
871 None => Err(RuntimeError::new("contains requires an argument")),
872 },
873 (Value::List(elements), "indexOf") => match args.first() {
874 Some(target) => Ok(Value::Int(elements.iter().position(|e| e == target).map_or(-1, |i| i as i64))),
875 None => Err(RuntimeError::new("indexOf requires an argument")),
876 },
877 (Value::List(_), "toList") => Ok(receiver.clone()),
878 (Value::List(elements), "toArray") => Ok(Value::Array(elements.clone())),
879
880 (Value::Map(entries), "get") => match args.first() {
881 Some(key) => match entries.iter().find(|(k, _)| *k == *key) {
882 Some((_, v)) => Ok(v.clone()),
883 None => Ok(Value::String("None".into())),
884 },
885 None => Err(RuntimeError::new("get requires a key")),
886 },
887 (Value::Map(entries), "contains") => match args.first() {
888 Some(key) => Ok(Value::Bool(entries.iter().any(|(k, _)| *k == *key))),
889 None => Err(RuntimeError::new("contains requires a key")),
890 },
891 (Value::Map(entries), "keys") => Ok(Value::List(entries.iter().map(|(k, _)| k.clone()).collect())),
892 (Value::Map(entries), "values") => Ok(Value::List(entries.iter().map(|(_, v)| v.clone()).collect())),
893 (Value::Map(entries), "size") | (Value::Map(entries), "length") => Ok(Value::Int(entries.len() as i64)),
894 (Value::Map(entries), "isEmpty") => Ok(Value::Bool(entries.is_empty())),
895 (Value::Map(entries), "foreach") | (Value::Map(entries), "foreachEntry") => {
896 if let Some(func) = args.first().cloned() {
897 for (k, v) in entries { self.call_value(func.clone(), vec![k.clone(), v.clone()])?; }
898 }
899 Ok(Value::Unit)
900 }
901 (Value::Map(entries), "map") => {
902 if let Some(func) = args.first().cloned() {
903 let mut results = Vec::new();
904 for (k, v) in entries { results.push(self.call_value(func.clone(), vec![k.clone(), v.clone()])?); }
905 Ok(Value::List(results))
906 } else { Err(RuntimeError::new("map requires a function")) }
907 }
908 (Value::Map(entries), "updated") => {
909 if args.len() >= 2 {
910 let mut new_entries = entries.clone();
911 if let Some(pos) = new_entries.iter().position(|(k, _)| *k == args[0]) {
912 new_entries[pos].1 = args[1].clone();
913 } else {
914 new_entries.push((args[0].clone(), args[1].clone()));
915 }
916 Ok(Value::Map(new_entries))
917 } else { Err(RuntimeError::new("updated requires key and value")) }
918 }
919
920 (Value::Tuple(elements), "_1") if !elements.is_empty() => Ok(elements[0].clone()),
921 (Value::Tuple(elements), "_2") if elements.len() > 1 => Ok(elements[1].clone()),
922 (Value::Tuple(elements), "_3") if elements.len() > 2 => Ok(elements[2].clone()),
923 (Value::Tuple(elements), "_4") if elements.len() > 3 => Ok(elements[3].clone()),
924 (Value::Tuple(elements), "_5") if elements.len() > 4 => Ok(elements[4].clone()),
925 (Value::Tuple(elements), "toList") => Ok(Value::List(elements.clone())),
926
927 (Value::Object { class_name, fields, methods }, method_name) => {
928 if let Some(method_val) = methods.get(method_name) {
929 self.call_value(method_val.clone(), args)
930 } else if method_name == "toString" {
931 Ok(Value::String(format!("{}", receiver)))
932 } else if method_name == "equals" {
933 Ok(Value::Bool(receiver == args.first().cloned().unwrap_or(Value::Null)))
934 } else if method_name == "hashCode" {
935 Ok(Value::Int(0))
936 } else if method_name == "copy" {
937 Ok(receiver.clone())
938 } else if method_name == "canEqual" {
939 Ok(Value::Bool(true))
940 } else if method_name == "productPrefix" {
941 Ok(Value::String(class_name.clone()))
942 } else if method_name == "_1" || method_name == "_2" || method_name == "_3" || method_name == "_4" || method_name == "_5" {
943 let idx = method_name[1..].parse::<usize>().unwrap_or(1) - 1;
944 let mut keys: Vec<&String> = fields.keys().collect();
945 keys.sort();
946 if idx < keys.len() {
947 fields.get(keys[idx]).cloned().ok_or_else(|| RuntimeError::new("field not found"))
948 } else { Err(RuntimeError::new("tuple index out of bounds")) }
949 } else {
950 Err(RuntimeError::new(format!("{} has no method '{}'", class_name, method_name)))
951 }
952 }
953 _ => Err(RuntimeError::new(format!("cannot call method '{}' on {}", method, receiver.type_name()))),
954 }
955 }
956
957 fn eval_field_access(&mut self, receiver: &Value, field: &str) -> Result<Value, RuntimeError> {
958 match receiver {
959 Value::Object { fields, .. } => {
960 if let Some(val) = fields.get(field) { Ok(val.clone()) }
961 else if field == "toString" { Ok(Value::String(format!("{}", receiver))) }
962 else if field == "Pi" { Ok(Value::Double(std::f64::consts::PI)) }
963 else if field == "E" { Ok(Value::Double(std::f64::consts::E)) }
964 else { Err(RuntimeError::new(format!("field '{}' not found", field))) }
965 }
966 Value::Tuple(elements) => {
967 if field.starts_with('_') && field.len() >= 2 {
968 if let Ok(idx) = field[1..].parse::<usize>() {
969 if idx >= 1 && idx <= elements.len() { Ok(elements[idx - 1].clone()) }
970 else { Err(RuntimeError::new("tuple index out of bounds")) }
971 } else { Err(RuntimeError::new(format!("invalid tuple accessor: {}", field))) }
972 } else { Err(RuntimeError::new(format!("tuple has no field '{}'", field))) }
973 }
974 Value::List(elements) => {
975 match field {
976 "length" | "size" => Ok(Value::Int(elements.len() as i64)),
977 "head" => elements.first().cloned().ok_or_else(|| RuntimeError::new("head of empty list")),
978 "isEmpty" => Ok(Value::Bool(elements.is_empty())),
979 _ => Err(RuntimeError::new(format!("List has no field '{}'", field))),
980 }
981 }
982 Value::String(s) => {
983 if field == "length" { Ok(Value::Int(s.len() as i64)) }
984 else { Err(RuntimeError::new(format!("String has no field '{}'", field))) }
985 }
986 _ => Err(RuntimeError::new(format!("cannot access field '{}' on {}", field, receiver.type_name()))),
987 }
988 }
989
990 fn eval_match(&mut self, scrutinee: &Value, cases: &[MatchCase]) -> Result<Value, RuntimeError> {
991 for case in cases {
992 self.env.push();
993 if self.match_pattern(&case.pattern, scrutinee)? {
994 if let Some(guard) = &case.guard {
995 let guard_val = self.eval_expr(guard)?;
996 if !guard_val.is_truthy() {
997 self.env.pop();
998 continue;
999 }
1000 }
1001 let result = self.eval_expr(&case.body);
1002 self.env.pop();
1003 return result;
1004 }
1005 self.env.pop();
1006 }
1007 Err(RuntimeError::new(format!("match error: no case matched for {}", scrutinee)))
1008 }
1009
1010 fn try_catch(&mut self, err_str: &str, catches: &[MatchCase]) -> Option<Result<Value, RuntimeError>> {
1011 let exc_value = if err_str.starts_with("__exception__") {
1012 Value::String(err_str["__exception__".len()..].to_string())
1013 } else {
1014 Value::String(err_str.to_string())
1015 };
1016 self.env.push();
1017 for case in catches {
1018 if let Ok(true) = self.match_pattern(&case.pattern, &exc_value) {
1019 if let Some(guard) = &case.guard {
1020 if let Ok(guard_val) = self.eval_expr(guard) {
1021 if !guard_val.is_truthy() { continue; }
1022 }
1023 }
1024 let result = self.eval_expr(&case.body);
1025 self.env.pop();
1026 return Some(result);
1027 }
1028 }
1029 self.env.pop();
1030 None
1031 }
1032
1033 fn eval_for_enumerators(&mut self, enumerators: &[Enumerator], body: &mut dyn FnMut(&mut Interpreter) -> Result<(), RuntimeError>) -> Result<(), RuntimeError> {
1034 self.eval_for_enumerators_rec(enumerators, 0, body)
1035 }
1036
1037 fn eval_for_enumerators_rec(&mut self, enumerators: &[Enumerator], idx: usize, body: &mut dyn FnMut(&mut Interpreter) -> Result<(), RuntimeError>) -> Result<(), RuntimeError> {
1038 if idx >= enumerators.len() { body(self)?; return Ok(()); }
1039 match &enumerators[idx] {
1040 Enumerator::Generator { pattern, expr, .. } => {
1041 let collection = self.eval_expr(expr)?;
1042 match collection {
1043 Value::List(elements) => {
1044 for elem in &elements {
1045 self.env.push();
1046 self.bind_pattern(pattern, elem)?;
1047 self.eval_for_enumerators_rec(enumerators, idx + 1, body)?;
1048 self.env.pop();
1049 }
1050 }
1051 Value::Tuple(elements) => {
1052 for elem in &elements {
1053 self.env.push();
1054 self.bind_pattern(pattern, elem)?;
1055 self.eval_for_enumerators_rec(enumerators, idx + 1, body)?;
1056 self.env.pop();
1057 }
1058 }
1059 _ => {
1060 self.env.push();
1061 self.bind_pattern(pattern, &collection)?;
1062 self.eval_for_enumerators_rec(enumerators, idx + 1, body)?;
1063 self.env.pop();
1064 }
1065 }
1066 }
1067 Enumerator::Filter { cond, .. } => {
1068 let cv = self.eval_expr(cond)?;
1069 if cv.is_truthy() { self.eval_for_enumerators_rec(enumerators, idx + 1, body)?; }
1070 }
1071 Enumerator::Val { pattern, expr, .. } => {
1072 let val = self.eval_expr(expr)?;
1073 self.bind_pattern(pattern, &val)?;
1074 self.eval_for_enumerators_rec(enumerators, idx + 1, body)?;
1075 }
1076 }
1077 Ok(())
1078 }
1079
1080 fn match_pattern(&mut self, pattern: &Pattern, value: &Value) -> Result<bool, RuntimeError> {
1081 match pattern {
1082 Pattern::Wildcard(_) => Ok(true),
1083 Pattern::Variable { name, .. } => {
1084 if name != "_" { self.env.define(name, value.clone(), false); }
1085 Ok(true)
1086 }
1087 Pattern::Literal { value: lit, .. } => Ok(*value == literal_to_value(lit)),
1088 Pattern::Constructor { name, args, .. } => match value {
1089 Value::Object { class_name, fields, .. } => {
1090 if class_name != name { return Ok(false); }
1091 let mut field_keys: Vec<&String> = fields.keys().filter(|k| !k.starts_with("__")).collect();
1092 field_keys.sort();
1093 if args.len() != field_keys.len() { return Ok(false); }
1094 for (pat, key) in args.iter().zip(field_keys.iter()) {
1095 let field_val = fields.get(*key).cloned().unwrap_or(Value::Unit);
1096 if !self.match_pattern(pat, &field_val)? { return Ok(false); }
1097 }
1098 Ok(true)
1099 }
1100 _ => Ok(false),
1101 },
1102 Pattern::Tuple { elements, .. } => {
1103 if let Value::Tuple(vals) = value {
1104 if elements.len() != vals.len() { return Ok(false); }
1105 for (pat, val) in elements.iter().zip(vals.iter()) {
1106 if !self.match_pattern(pat, val)? { return Ok(false); }
1107 }
1108 Ok(true)
1109 } else { Ok(false) }
1110 }
1111 Pattern::Typed { pattern, .. } => self.match_pattern(pattern, value),
1112 Pattern::Alternative { left, right, .. } => {
1113 if self.match_pattern(left, value)? { Ok(true) } else { self.match_pattern(right, value) }
1114 }
1115 Pattern::SequenceWildcard(_) => Ok(true),
1116 }
1117 }
1118
1119 fn bind_pattern(&mut self, pattern: &Pattern, value: &Value) -> Result<(), RuntimeError> {
1120 match pattern {
1121 Pattern::Wildcard(_) => Ok(()),
1122 Pattern::Variable { name, .. } => {
1123 if name != "_" { self.env.define(name, value.clone(), false); }
1124 Ok(())
1125 }
1126 Pattern::Literal { .. } => Ok(()),
1127 Pattern::Constructor { args, .. } => match value {
1128 Value::Object { fields, .. } => {
1129 let mut keys: Vec<&String> = fields.keys().filter(|k| !k.starts_with("__")).collect();
1130 keys.sort();
1131 for (pat, key) in args.iter().zip(keys.iter()) {
1132 let field_val = fields.get(*key).cloned().unwrap_or(Value::Unit);
1133 self.bind_pattern(pat, &field_val)?;
1134 }
1135 Ok(())
1136 }
1137 _ => Ok(()),
1138 },
1139 Pattern::Tuple { elements, .. } => {
1140 if let Value::Tuple(vals) = value {
1141 for (pat, val) in elements.iter().zip(vals.iter()) { self.bind_pattern(pat, val)?; }
1142 }
1143 Ok(())
1144 }
1145 Pattern::Typed { pattern, .. } => self.bind_pattern(pattern, value),
1146 _ => Ok(()),
1147 }
1148 }
1149
1150 fn bind_pattern_mut(&mut self, pattern: &Pattern, value: &Value) -> Result<(), RuntimeError> {
1151 match pattern {
1152 Pattern::Variable { name, .. } => {
1153 if name != "_" { self.env.define(name, value.clone(), true); }
1154 Ok(())
1155 }
1156 _ => self.bind_pattern(pattern, value),
1157 }
1158 }
1159}
1160
1161fn literal_to_value(lit: &Literal) -> Value {
1162 match lit {
1163 Literal::Int(v) => Value::Int(*v),
1164 Literal::Long(v) => Value::Long(*v),
1165 Literal::Double(v) => Value::Double(*v),
1166 Literal::Float(v) => Value::Float(*v),
1167 Literal::Bool(v) => Value::Bool(*v),
1168 Literal::String(v) => Value::String(v.clone()),
1169 Literal::Char(v) => Value::Char(*v),
1170 Literal::Null => Value::Null,
1171 Literal::Unit => Value::Unit,
1172 }
1173}
1174
1175#[cfg(test)]
1176mod tests {
1177 use super::*;
1178
1179 fn eval(source: &str) -> Value {
1180 let mut interp = Interpreter::new();
1181 interp.run_source(source).unwrap()
1182 }
1183
1184 fn eval_err(source: &str) -> RuntimeError {
1185 let mut interp = Interpreter::new();
1186 interp.run_source(source).unwrap_err()
1187 }
1188
1189 #[test]
1190 fn test_int_literal() { assert_eq!(eval("42"), Value::Int(42)); }
1191 #[test]
1192 fn test_string_literal() { assert_eq!(eval("\"hello\""), Value::String("hello".into())); }
1193 #[test]
1194 fn test_bool_literal() { assert_eq!(eval("true"), Value::Bool(true)); }
1195 #[test]
1196 fn test_null() { assert_eq!(eval("null"), Value::Null); }
1197 #[test]
1198 fn test_unit() { assert_eq!(eval("()"), Value::Unit); }
1199 #[test]
1200 fn test_negation() { assert_eq!(eval("-42"), Value::Int(-42)); }
1201
1202 #[test]
1203 fn test_arithmetic() {
1204 assert_eq!(eval("1 + 2"), Value::Int(3));
1205 assert_eq!(eval("10 - 3"), Value::Int(7));
1206 assert_eq!(eval("4 * 5"), Value::Int(20));
1207 assert_eq!(eval("10 / 3"), Value::Int(3));
1208 assert_eq!(eval("10 % 3"), Value::Int(1));
1209 }
1210
1211 #[test]
1212 fn test_string_concat() {
1213 assert_eq!(eval("\"hello\" + \" \" + \"world\""), Value::String("hello world".into()));
1214 }
1215
1216 #[test]
1217 fn test_comparison() {
1218 assert_eq!(eval("1 == 1"), Value::Bool(true));
1219 assert_eq!(eval("1 != 2"), Value::Bool(true));
1220 assert_eq!(eval("1 < 2"), Value::Bool(true));
1221 assert_eq!(eval("2 > 1"), Value::Bool(true));
1222 assert_eq!(eval("1 >= 1"), Value::Bool(true));
1223 assert_eq!(eval("1 <= 1"), Value::Bool(true));
1224 }
1225
1226 #[test]
1227 fn test_boolean_logic() {
1228 assert_eq!(eval("true && false"), Value::Bool(false));
1229 assert_eq!(eval("true || false"), Value::Bool(true));
1230 assert_eq!(eval("!true"), Value::Bool(false));
1231 assert_eq!(eval("!false"), Value::Bool(true));
1232 }
1233
1234 #[test]
1235 fn test_if_else() {
1236 assert_eq!(eval("if (true) 1 else 2"), Value::Int(1));
1237 assert_eq!(eval("if (false) 1 else 2"), Value::Int(2));
1238 assert_eq!(eval("if (true) 42"), Value::Int(42));
1239 }
1240
1241 #[test]
1242 fn test_block() {
1243 assert_eq!(eval("{ val x = 10; val y = 20; x + y }"), Value::Int(30));
1244 }
1245
1246 #[test]
1247 fn test_lambda() {
1248 assert_eq!(eval("{ val f = (x) => x + 1; f(41) }"), Value::Int(42));
1249 }
1250
1251 #[test]
1252 fn test_def() {
1253 assert_eq!(eval("def add(a: Int, b: Int): Int = a + b; add(3, 4)"), Value::Int(7));
1254 }
1255
1256 #[test]
1257 fn test_val() { assert_eq!(eval("val x = 42; x"), Value::Int(42)); }
1258
1259 #[test]
1260 fn test_var() { assert_eq!(eval("var x = 1; x = 2; x"), Value::Int(2)); }
1261
1262 #[test]
1263 fn test_tuple() {
1264 match eval("(1, 2, 3)") {
1265 Value::Tuple(v) => assert_eq!(v, vec![Value::Int(1), Value::Int(2), Value::Int(3)]),
1266 _ => panic!("expected tuple"),
1267 }
1268 }
1269
1270 #[test]
1271 fn test_list() {
1272 match eval("List(1, 2, 3)") {
1273 Value::List(v) => assert_eq!(v.len(), 3),
1274 _ => panic!("expected list"),
1275 }
1276 }
1277
1278 #[test]
1279 fn test_list_map() {
1280 match eval("List(1, 2, 3).map((x) => x * 2)") {
1281 Value::List(v) => assert_eq!(v, vec![Value::Int(2), Value::Int(4), Value::Int(6)]),
1282 _ => panic!("expected list"),
1283 }
1284 }
1285
1286 #[test]
1287 fn test_list_filter() {
1288 match eval("List(1, 2, 3, 4, 5).filter((x) => x > 3)") {
1289 Value::List(v) => assert_eq!(v, vec![Value::Int(4), Value::Int(5)]),
1290 _ => panic!("expected list"),
1291 }
1292 }
1293
1294 #[test]
1295 fn test_list_fold_left() {
1296 assert_eq!(eval("List(1, 2, 3).reduce((a, b) => a + b)"), Value::Int(6));
1298 }
1299
1300 #[test]
1301 fn test_recursion() {
1302 assert_eq!(eval("def fact(n: Int): Int = if (n <= 1) 1 else n * fact(n - 1); fact(5)"), Value::Int(120));
1303 }
1304
1305 #[test]
1306 fn test_class() {
1307 let result = eval("class Point(val x: Int, val y: Int); val p = new Point(1, 2); p");
1308 match result {
1309 Value::Object { class_name, fields, .. } => {
1310 assert_eq!(class_name, "Point");
1311 assert_eq!(fields.get("x"), Some(&Value::Int(1)));
1312 assert_eq!(fields.get("y"), Some(&Value::Int(2)));
1313 }
1314 _ => panic!("expected object"),
1315 }
1316 }
1317
1318 #[test]
1319 fn test_match() {
1320 assert_eq!(eval("3 match { case 1 => 10 case 2 => 20 case _ => 30 }"), Value::Int(30));
1321 }
1322
1323 #[test]
1324 fn test_for_yield() {
1325 match eval("for (x <- List(1, 2, 3)) yield x * 2") {
1326 Value::List(v) => assert_eq!(v, vec![Value::Int(2), Value::Int(4), Value::Int(6)]),
1327 _ => panic!("expected list"),
1328 }
1329 }
1330
1331 #[test]
1332 fn test_string_methods() {
1333 assert_eq!(eval("\"hello\".length"), Value::Int(5));
1334 assert_eq!(eval("\"hello\".toUpperCase"), Value::String("HELLO".into()));
1335 assert_eq!(eval("\" hi \".trim"), Value::String("hi".into()));
1336 }
1337
1338 #[test]
1339 fn test_while_loop() {
1340 assert_eq!(eval("var x = 0; var i = 0; while (i < 5) { x = x + i; i = i + 1 }; x"), Value::Int(10));
1341 }
1342
1343 #[test]
1344 fn test_precedence() {
1345 assert_eq!(eval("2 + 3 * 4"), Value::Int(14));
1346 assert_eq!(eval("(2 + 3) * 4"), Value::Int(20));
1347 }
1348
1349 #[test]
1350 fn test_higher_order() {
1351 assert_eq!(eval("{ def apply(f: Int => Int, x: Int): Int = f(x); apply((x) => x * x, 5) }"), Value::Int(25));
1352 }
1353
1354 #[test]
1355 fn test_closures() {
1356 assert_eq!(eval("{ val x = 10; val f = () => x + 1; f() }"), Value::Int(11));
1357 assert_eq!(eval("{ def makeAdder(n: Int): Int => Int = (x) => x + n; val add5 = makeAdder(5); add5(10) }"), Value::Int(15));
1358 }
1359
1360 #[test]
1361 fn test_curried_application() {
1362 assert_eq!(eval("{ def add(a: Int, b: Int): Int = a + b; add(3, 4) }"), Value::Int(7));
1363 }
1364
1365 #[test]
1366 fn test_division_by_zero() {
1367 match eval_err("1 / 0") {
1368 e => assert!(e.message.contains("division by zero")),
1369 }
1370 }
1371
1372 #[test]
1373 fn test_list_head_tail() {
1374 match eval("List(10, 20, 30).head") { Value::Int(10) => {} _ => panic!("expected 10") }
1375 match eval("List(10, 20, 30).tail") {
1376 Value::List(v) => assert_eq!(v, vec![Value::Int(20), Value::Int(30)]),
1377 _ => panic!("expected list"),
1378 }
1379 }
1380
1381 #[test]
1382 fn test_list_reduce() {
1383 assert_eq!(eval("List(1, 2, 3, 4).reduce((a, b) => a + b)"), Value::Int(10));
1384 }
1385
1386 #[test]
1387 fn test_list_sorted() {
1388 match eval("List(3, 1, 2).sorted") {
1389 Value::List(v) => assert_eq!(v, vec![Value::Int(1), Value::Int(2), Value::Int(3)]),
1390 _ => panic!("expected list"),
1391 }
1392 }
1393
1394 #[test]
1395 fn test_list_reverse() {
1396 match eval("List(1, 2, 3).reverse") {
1397 Value::List(v) => assert_eq!(v, vec![Value::Int(3), Value::Int(2), Value::Int(1)]),
1398 _ => panic!("expected list"),
1399 }
1400 }
1401
1402 #[test]
1403 fn test_list_mkstring() {
1404 assert_eq!(eval("List(1, 2, 3).mkString(\", \")"), Value::String("1, 2, 3".into()));
1405 }
1406
1407 #[test]
1408 fn test_object_decl() {
1409 let result = eval("object Math { val pi = 3 }; Math");
1410 match result {
1411 Value::Object { class_name, fields, .. } => {
1412 assert_eq!(class_name, "Math");
1413 assert_eq!(fields.get("pi"), Some(&Value::Int(3)));
1414 }
1415 _ => panic!("expected object"),
1416 }
1417 }
1418
1419 #[test]
1420 fn test_object_methods() {
1421 let result = eval("object Calc { def double(x: Int): Int = x * 2 }; Calc.double(21)");
1422 assert_eq!(result, Value::Int(42));
1423 }
1424
1425 #[test]
1426 fn test_for_with_filter() {
1427 match eval("for (x <- List(1, 2, 3, 4, 5); if x % 2 == 0) yield x") {
1428 Value::List(v) => assert_eq!(v, vec![Value::Int(2), Value::Int(4)]),
1429 _ => panic!("expected list"),
1430 }
1431 }
1432
1433 #[test]
1434 fn test_nested_for() {
1435 match eval("for (x <- List(1, 2); y <- List(3, 4)) yield x + y") {
1436 Value::List(v) => assert_eq!(v, vec![Value::Int(4), Value::Int(5), Value::Int(5), Value::Int(6)]),
1437 _ => panic!("expected list"),
1438 }
1439 }
1440
1441 #[test]
1442 fn test_string_contains() {
1443 assert_eq!(eval("\"hello world\".contains(\"world\")"), Value::Bool(true));
1444 assert_eq!(eval("\"hello world\".contains(\"foo\")"), Value::Bool(false));
1445 }
1446
1447 #[test]
1448 fn test_fibonacci() {
1449 assert_eq!(eval("def fib(n: Int): Int = if (n <= 1) n else fib(n - 1) + fib(n - 2); fib(10)"), Value::Int(55));
1450 }
1451
1452 #[test]
1453 fn test_type_annotations() {
1454 assert_eq!(eval("val x: Int = 42; x"), Value::Int(42));
1455 assert_eq!(eval("val s: String = \"hi\"; s"), Value::String("hi".into()));
1456 }
1457
1458 #[test]
1459 fn test_multi_statement_program() {
1460 let src = r#"
1461 val x = 10
1462 val y = 20
1463 val z = x + y
1464 z
1465 "#;
1466 assert_eq!(eval(src), Value::Int(30));
1467 }
1468
1469 #[test]
1470 fn test_list_sum_product() {
1471 assert_eq!(eval("List(1, 2, 3, 4, 5).sum"), Value::Int(15));
1472 assert_eq!(eval("List(1, 2, 3, 4, 5).product"), Value::Int(120));
1473 }
1474
1475 #[test]
1476 fn test_list_exists_forall() {
1477 assert_eq!(eval("List(1, 2, 3).exists((x) => x > 2)"), Value::Bool(true));
1478 assert_eq!(eval("List(1, 2, 3).forall((x) => x > 0)"), Value::Bool(true));
1479 assert_eq!(eval("List(1, 2, 3).forall((x) => x > 1)"), Value::Bool(false));
1480 }
1481}