1use crate::scheme::environment::Environment;
30use crate::scheme::parser::Position;
31use crate::scheme::value::{Procedure, Value};
32use crate::grove::{Grove, Node};
33use crate::fot::FotBuilder;
34use gc::Gc;
35use std::rc::Rc;
36use std::cell::RefCell;
37
38thread_local! {
49 static EVALUATOR_CONTEXT: RefCell<Option<EvaluatorContext>> = RefCell::new(None);
50}
51
52#[derive(Clone)]
54pub struct EvaluatorContext {
55 pub grove: Option<Rc<dyn Grove>>,
56 pub current_node: Option<Rc<Box<dyn Node>>>,
57 pub backend: Option<Rc<RefCell<dyn FotBuilder>>>,
58}
59
60pub fn get_evaluator_context() -> Option<EvaluatorContext> {
62 EVALUATOR_CONTEXT.with(|ctx| ctx.borrow().clone())
63}
64
65fn has_evaluator_context() -> bool {
67 EVALUATOR_CONTEXT.with(|ctx| ctx.borrow().is_some())
68}
69
70fn set_evaluator_context(ctx: EvaluatorContext) {
72 EVALUATOR_CONTEXT.with(|c| *c.borrow_mut() = Some(ctx));
73}
74
75fn clear_evaluator_context() {
77 EVALUATOR_CONTEXT.with(|c| *c.borrow_mut() = None);
78}
79
80use crate::scheme::value::SourceInfo;
85
86#[derive(Debug, Clone)]
90pub struct CallFrame {
91 pub function_name: String,
93 pub source: Option<SourceInfo>,
95}
96
97impl CallFrame {
98 pub fn new(function_name: String, source: Option<SourceInfo>) -> Self {
99 CallFrame {
100 function_name,
101 source,
102 }
103 }
104}
105
106#[derive(Debug, Clone)]
112pub struct EvalError {
113 pub message: String,
114 pub call_stack: Vec<CallFrame>,
115}
116
117impl EvalError {
118 pub fn new(message: String) -> Self {
119 EvalError {
120 message,
121 call_stack: Vec::new(),
122 }
123 }
124
125 pub fn with_stack(message: String, call_stack: Vec<CallFrame>) -> Self {
127 EvalError {
128 message,
129 call_stack,
130 }
131 }
132}
133
134impl std::fmt::Display for EvalError {
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 write!(f, "{}", self.message)?;
138
139 for (i, frame) in self.call_stack.iter().rev().enumerate() {
141 if let Some(ref source) = frame.source {
142 if i == 0 {
144 writeln!(f, "\n{}:{}:{}:I: called from here",
145 source.file, source.pos.line, source.pos.column)?;
146 } else {
147 writeln!(f, "{}:{}:{}:I: called from here",
148 source.file, source.pos.line, source.pos.column)?;
149 }
150 } else {
151 if i == 0 {
152 writeln!(f, "\n{}:I: called from here", frame.function_name)?;
153 } else {
154 writeln!(f, "{}:I: called from here", frame.function_name)?;
155 }
156 }
157 }
158
159 Ok(())
160 }
161}
162
163impl std::error::Error for EvalError {}
164
165pub type EvalResult = Result<Value, EvalError>;
166
167#[derive(Clone)]
176pub struct ConstructionRule {
177 pub element_name: String,
179
180 pub expr: Value,
182
183 pub source_file: Option<String>,
185 pub source_pos: Option<Position>,
186}
187
188pub struct ProcessingMode {
193 pub rules: Vec<ConstructionRule>,
197
198 pub default_rule: Option<Value>,
200}
201
202impl ProcessingMode {
203 pub fn new() -> Self {
205 ProcessingMode {
206 rules: Vec::new(),
207 default_rule: None,
208 }
209 }
210
211 pub fn add_rule(&mut self, element_name: String, expr: Value, source_file: Option<String>, source_pos: Option<Position>) {
213 self.rules.push(ConstructionRule {
214 element_name,
215 expr,
216 source_file,
217 source_pos
218 });
219 }
220
221 pub fn add_default_rule(&mut self, expr: Value) {
223 self.default_rule = Some(expr);
224 }
225
226 pub fn find_match(&self, gi: &str) -> Option<&ConstructionRule> {
231 self.rules.iter().find(|rule| rule.element_name == gi)
232 }
233}
234
235pub struct Evaluator {
250 grove: Option<Rc<dyn Grove>>,
252
253 current_node: Option<Rc<Box<dyn Node>>>,
259
260 processing_mode: ProcessingMode,
265
266 backend: Option<Rc<RefCell<dyn FotBuilder>>>,
271
272 call_stack: Vec<CallFrame>,
277
278 current_source_file: Option<String>,
282
283 current_position: Option<Position>,
287
288 line_mappings: Vec<LineMapping>,
294}
295
296#[derive(Debug, Clone)]
298pub struct LineMapping {
299 pub output_line: usize,
301 pub source_file: String,
303 pub source_line: usize,
305}
306
307impl Evaluator {
308 pub fn new() -> Self {
310 Evaluator {
311 grove: None,
312 current_node: None,
313 processing_mode: ProcessingMode::new(),
314 backend: None,
315 call_stack: Vec::new(),
316 current_source_file: None,
317 current_position: None,
318 line_mappings: Vec::new(),
319 }
320 }
321
322 pub fn with_grove(grove: Rc<dyn Grove>) -> Self {
324 Evaluator {
325 grove: Some(grove),
326 current_node: None,
327 processing_mode: ProcessingMode::new(),
328 backend: None,
329 call_stack: Vec::new(),
330 current_source_file: None,
331 current_position: None,
332 line_mappings: Vec::new(),
333 }
334 }
335
336 pub fn set_line_mappings(&mut self, mappings: Vec<LineMapping>) {
338 self.line_mappings = mappings;
339 }
340
341 pub fn set_source_file(&mut self, file: String) {
343 self.current_source_file = Some(file);
344 }
345
346 pub fn source_file(&self) -> Option<&str> {
348 self.current_source_file.as_deref()
349 }
350
351 pub fn set_position(&mut self, position: Position) {
353 self.current_position = Some(position);
354 }
355
356 fn push_call_frame(&mut self, function_name: String, source: Option<SourceInfo>) {
358 self.call_stack.push(CallFrame::new(function_name, source));
359 }
360
361 fn pop_call_frame(&mut self) {
363 self.call_stack.pop();
364 }
365
366 fn error_with_stack(&self, message: String) -> EvalError {
368 let full_message = match (&self.current_source_file, &self.current_position) {
370 (Some(file), Some(pos)) => {
371 format!("{}:{}:{}:E: {}", file, pos.line, pos.column, message)
372 }
373 (Some(file), None) => {
374 format!("{}:E: {}", file, message)
375 }
376 _ => message,
377 };
378 EvalError::with_stack(full_message, self.call_stack.clone())
379 }
380
381 pub fn set_backend(&mut self, backend: Rc<RefCell<dyn FotBuilder>>) {
383 self.backend = Some(backend);
384 }
385
386 pub fn set_grove(&mut self, grove: Rc<dyn Grove>) {
388 self.grove = Some(grove);
389 }
390
391 pub fn grove(&self) -> Option<&Rc<dyn Grove>> {
393 self.grove.as_ref()
394 }
395
396 pub fn set_current_node(&mut self, node: Box<dyn Node>) {
398 self.current_node = Some(Rc::new(node));
399 }
400
401 pub fn current_node(&self) -> Option<Rc<Box<dyn Node>>> {
403 self.current_node.clone()
404 }
405
406 pub fn clear_current_node(&mut self) {
408 self.current_node = None;
409 }
410
411 pub fn process_root(&mut self, env: Gc<Environment>) -> EvalResult {
420 let root_node = match &self.grove {
422 Some(grove) => grove.root(),
423 None => return Err(EvalError::new("No grove set".to_string())),
424 };
425
426 self.current_node = Some(Rc::new(root_node));
428 self.process_node(env)
429 }
430
431 pub fn process_node(&mut self, env: Gc<Environment>) -> EvalResult {
442 let node = match &self.current_node {
443 Some(n) => n.clone(),
444 None => return Err(EvalError::new("No current node".to_string())),
445 };
446
447 let gi = match node.gi() {
449 Some(gi) => gi,
450 None => {
451 return Ok(Value::Unspecified);
454 }
455 };
456
457 let rule = self.processing_mode.find_match(&gi);
459
460 if let Some(rule) = rule {
461 let saved_file = self.current_source_file.clone();
464 let saved_pos = self.current_position.clone();
465
466 if let Some(ref rule_file) = rule.source_file {
469 self.current_source_file = Some(rule_file.clone());
470 }
471 if let Some(ref rule_pos) = rule.source_pos {
472 self.current_position = Some(rule_pos.clone());
473 }
474
475 let result = self.eval(rule.expr.clone(), env);
477
478 self.current_source_file = saved_file;
480 self.current_position = saved_pos;
481
482 result
483 } else if let Some(ref default_expr) = self.processing_mode.default_rule {
484 self.eval(default_expr.clone(), env)
486 } else {
487 self.eval_process_children(env)
490 }
491 }
492
493 pub fn eval(&mut self, expr: Value, env: Gc<Environment>) -> EvalResult {
503 let context_was_set = has_evaluator_context();
505 let previous_context = get_evaluator_context();
506
507 set_evaluator_context(EvaluatorContext {
510 grove: self.grove.clone(),
511 current_node: self.current_node.clone(),
512 backend: self.backend.clone(),
513 });
514
515 let result = self.eval_inner(expr, env);
517
518 if context_was_set {
520 if let Some(prev_ctx) = previous_context {
521 set_evaluator_context(prev_ctx);
522 }
523 } else {
524 clear_evaluator_context();
525 }
526
527 result
528 }
529
530 fn eval_inner(&mut self, expr: Value, env: Gc<Environment>) -> EvalResult {
532 match expr {
533 Value::Nil => Ok(Value::Nil),
535 Value::Bool(_) => Ok(expr),
536 Value::Integer(_) => Ok(expr),
537 Value::Real(_) => Ok(expr),
538 Value::Char(_) => Ok(expr),
539 Value::String(_) => Ok(expr),
540 Value::Procedure(_) => Ok(expr),
541 Value::Vector(_) => Ok(expr), Value::Unspecified => Ok(expr),
543 Value::Error => Ok(expr),
544
545 Value::Node(_) => Ok(expr),
547 Value::NodeList(_) => Ok(expr),
548 Value::Sosofo => Ok(expr),
549
550 Value::Symbol(ref name) => env
552 .lookup(name)
553 .ok_or_else(|| self.error_with_stack(format!("Undefined variable: {}", name))),
554
555 Value::Keyword(_) => Ok(expr),
557
558 Value::Pair(_) => self.eval_list(expr, env),
560 }
561 }
562
563 fn eval_list(&mut self, expr: Value, env: Gc<Environment>) -> EvalResult {
565 if let Value::Pair(ref p) = expr {
567 let pair_data = p.borrow();
568 if let Some(ref pos) = pair_data.pos {
569 if !self.line_mappings.is_empty() {
571 if let Some(mapping) = self.line_mappings.iter().find(|m| m.output_line == pos.line) {
572 self.current_source_file = Some(mapping.source_file.clone());
573 self.current_position = Some(Position {
574 line: mapping.source_line,
575 column: pos.column,
576 });
577 } else {
578 self.current_position = Some(pos.clone());
580 }
581 } else {
582 self.current_position = Some(pos.clone());
584 }
585 }
586 }
587
588 let (operator, args) = self.list_car_cdr(&expr)?;
590
591 if let Value::Symbol(ref sym) = operator {
593 match &**sym {
594 "quote" => self.eval_quote(args),
595 "if" => self.eval_if(args, env),
596 "define" => self.eval_define(args, env),
597 "set!" => self.eval_set(args, env),
598 "lambda" => self.eval_lambda(args, env),
599 "let" => self.eval_let(args, env),
600 "let*" => self.eval_let_star(args, env),
601 "letrec" => self.eval_letrec(args, env),
602 "begin" => self.eval_begin(args, env),
603 "cond" => self.eval_cond(args, env),
604 "case" => self.eval_case(args, env),
605 "and" => self.eval_and(args, env),
606 "or" => self.eval_or(args, env),
607 "apply" => self.eval_apply(args, env),
608 "map" => self.eval_map(args, env),
609 "for-each" => self.eval_for_each(args, env),
610 "node-list-filter" => self.eval_node_list_filter(args, env),
611 "node-list-map" => self.eval_node_list_map(args, env),
612 "node-list-some?" => self.eval_node_list_some(args, env),
613 "load" => self.eval_load(args, env),
614
615 "define-language" => self.eval_define_language(args, env),
617 "declare-flow-object-class" => self.eval_declare_flow_object_class(args, env),
618 "declare-characteristic" => self.eval_declare_characteristic(args, env),
619 "element" => self.eval_element(args, env),
620 "default" => self.eval_default(args, env),
621 "process-children" => self.eval_process_children(env),
622 "make" => self.eval_make(args, env),
623
624 _ => self.eval_application(operator, args, env),
626 }
627 } else {
628 self.eval_application(operator, args, env)
630 }
631 }
632
633 fn list_car_cdr(&self, list: &Value) -> Result<(Value, Value), EvalError> {
635 if let Value::Pair(ref p) = list {
636 let pair = p.borrow();
637 Ok((pair.car.clone(), pair.cdr.clone()))
638 } else {
639 Err(EvalError::new("Expected list".to_string()))
640 }
641 }
642
643 fn vec_to_list(&self, vec: Vec<Value>) -> Value {
645 let mut result = Value::Nil;
646 for val in vec.iter().rev() {
647 result = Value::cons(val.clone(), result);
648 }
649 result
650 }
651
652 fn list_to_vec(&self, list: Value) -> Result<Vec<Value>, EvalError> {
654 let mut result = Vec::new();
655 let mut current = list;
656
657 loop {
658 match current {
659 Value::Nil => break,
660 Value::Pair(ref p) => {
661 let pair = p.borrow();
662 result.push(pair.car.clone());
663 let cdr = pair.cdr.clone();
664 drop(pair); current = cdr;
666 }
667 _ => return Err(EvalError::new("Improper list".to_string())),
668 }
669 }
670
671 Ok(result)
672 }
673
674 fn eval_quote(&mut self, args: Value) -> EvalResult {
680 let args_vec = self.list_to_vec(args)?;
681 if args_vec.len() != 1 {
682 return Err(EvalError::new("quote requires exactly 1 argument".to_string()));
683 }
684 Ok(args_vec[0].clone())
685 }
686
687 fn eval_if(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
689 let args_vec = self.list_to_vec(args)?;
690 if args_vec.len() < 2 || args_vec.len() > 3 {
691 return Err(EvalError::new(
692 "if requires 2 or 3 arguments".to_string(),
693 ));
694 }
695
696 let test = self.eval_inner(args_vec[0].clone(), env.clone())?;
697
698 if test.is_true() {
699 self.eval_inner(args_vec[1].clone(), env)
700 } else if args_vec.len() == 3 {
701 self.eval_inner(args_vec[2].clone(), env)
702 } else {
703 Ok(Value::Unspecified)
704 }
705 }
706
707 fn eval_define(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
709 let args_vec = self.list_to_vec(args)?;
710 if args_vec.len() < 2 {
711 return Err(EvalError::new(
712 "define requires at least 2 arguments".to_string(),
713 ));
714 }
715
716 match &args_vec[0] {
718 Value::Symbol(ref name) => {
719 if args_vec.len() != 2 {
721 return Err(EvalError::new(
722 "define with symbol requires exactly 2 arguments".to_string(),
723 ));
724 }
725 let value = self.eval_inner(args_vec[1].clone(), env.clone())?;
726 env.define(name, value);
727 Ok(Value::Unspecified)
728 }
729
730 Value::Pair(_) => {
731 let (name_val, params) = self.list_car_cdr(&args_vec[0])?;
734
735 if let Value::Symbol(ref name) = name_val {
736 let params_vec = if params.is_nil() {
738 Vec::new()
739 } else {
740 self.list_to_vec(params)?
741 };
742
743 let mut param_names = Vec::new();
744 for param in params_vec {
745 if let Value::Symbol(ref pname) = param {
746 param_names.push(pname.to_string());
747 } else {
748 return Err(EvalError::new(format!(
749 "Parameter must be a symbol, got: {:?}",
750 param
751 )));
752 }
753 }
754
755 let body = if args_vec.len() == 2 {
757 args_vec[1].clone()
758 } else {
759 let mut body_list = Value::Nil;
760 for expr in args_vec[1..].iter().rev() {
761 body_list = Value::cons(expr.clone(), body_list);
762 }
763 Value::cons(Value::symbol("begin"), body_list)
764 };
765
766 let source_info = self.current_source_file.as_ref().map(|file| {
768 use crate::scheme::parser::Position;
769 SourceInfo::new(file.clone(), Position::new())
770 });
771 let lambda_value = Value::lambda_with_source(
772 param_names,
773 body,
774 env.clone(),
775 source_info,
776 Some(name.to_string()),
777 );
778
779 env.define(name, lambda_value);
780 Ok(Value::Unspecified)
781 } else {
782 Err(EvalError::new(
783 "First element of define must be a symbol".to_string(),
784 ))
785 }
786 }
787
788 _ => Err(EvalError::new(
789 "First argument to define must be symbol or list".to_string(),
790 )),
791 }
792 }
793
794 fn eval_define_language(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
797 let args_vec = self.list_to_vec(args)?;
798
799 if args_vec.is_empty() {
800 return Err(EvalError::new(
801 "define-language requires at least 1 argument".to_string(),
802 ));
803 }
804
805 if let Value::Symbol(ref name) = args_vec[0] {
807 env.define(name, args_vec[0].clone());
810 Ok(Value::Unspecified)
811 } else {
812 Err(EvalError::new(
813 "First argument to define-language must be a symbol".to_string(),
814 ))
815 }
816 }
817
818 fn eval_declare_flow_object_class(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
821 let args_vec = self.list_to_vec(args)?;
822
823 if args_vec.is_empty() {
824 return Err(EvalError::new(
825 "declare-flow-object-class requires at least 1 argument".to_string(),
826 ));
827 }
828
829 if let Value::Symbol(ref name) = args_vec[0] {
831 env.define(name, args_vec[0].clone());
834 Ok(Value::Unspecified)
835 } else {
836 Err(EvalError::new(
837 "First argument to declare-flow-object-class must be a symbol".to_string(),
838 ))
839 }
840 }
841
842 fn eval_declare_characteristic(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
845 let args_vec = self.list_to_vec(args)?;
846
847 if args_vec.len() < 3 {
848 return Err(EvalError::new(
849 "declare-characteristic requires at least 3 arguments (name, public-id, default-value)".to_string(),
850 ));
851 }
852
853 if let Value::Symbol(ref name) = args_vec[0] {
855 let default_value = self.eval(args_vec[2].clone(), env.clone())?;
857
858 env.define(name, default_value);
860 Ok(Value::Unspecified)
861 } else {
862 Err(EvalError::new(
863 "First argument to declare-characteristic must be a symbol".to_string(),
864 ))
865 }
866 }
867
868 fn eval_element(&mut self, args: Value, _env: Gc<Environment>) -> EvalResult {
874 let args_vec = self.list_to_vec(args)?;
875
876 if args_vec.len() < 2 {
877 return Err(EvalError::new(
878 "element requires at least 2 arguments (element-name and construction-expression)".to_string(),
879 ));
880 }
881
882 let element_name = if let Value::Symbol(ref name) = args_vec[0] {
884 name.clone()
885 } else {
886 return Err(EvalError::new(
887 "First argument to element must be a symbol".to_string(),
888 ));
889 };
890
891 self.processing_mode.add_rule(
895 element_name.to_string(),
896 args_vec[1].clone(),
897 self.current_source_file.clone(),
898 self.current_position.clone()
899 );
900
901 Ok(Value::Unspecified)
902 }
903
904 fn eval_default(&mut self, args: Value, _env: Gc<Environment>) -> EvalResult {
910 let args_vec = self.list_to_vec(args)?;
911
912 if args_vec.is_empty() {
913 return Err(EvalError::new(
914 "default requires at least 1 argument (construction-expression)".to_string(),
915 ));
916 }
917
918 self.processing_mode.add_default_rule(args_vec[0].clone());
920
921 Ok(Value::Unspecified)
922 }
923
924 fn eval_process_children(&mut self, env: Gc<Environment>) -> EvalResult {
930 let current_node = match &self.current_node {
932 Some(node) => node.clone(),
933 None => return Err(EvalError::new("No current node".to_string())),
934 };
935
936 let mut children = current_node.children();
938
939 let mut result = Value::Unspecified;
941 while !children.is_empty() {
942 if let Some(child_node) = children.first() {
944 let saved_node = self.current_node.clone();
946
947 self.current_node = Some(Rc::new(child_node));
949
950 result = self.process_node(env.clone())?;
952
953 self.current_node = saved_node;
955 }
956
957 children = children.rest();
959 }
960
961 Ok(result)
962 }
963
964 fn eval_make(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
970 let args_vec = self.list_to_vec(args)?;
971
972 if args_vec.is_empty() {
973 return Err(EvalError::new(
974 "make requires at least a flow object type".to_string(),
975 ));
976 }
977
978 let fo_type = match &args_vec[0] {
980 Value::Symbol(s) => s.as_ref(),
981 _ => return Err(EvalError::new(
982 "make: first argument must be a flow object type symbol".to_string(),
983 )),
984 };
985
986 let mut i = 1;
988 let mut system_id = None;
989 let mut data = None;
990 let mut path = None;
991 let mut body_exprs = Vec::new();
992
993 while i < args_vec.len() {
994 match &args_vec[i] {
995 Value::Keyword(kw) => {
996 if i + 1 >= args_vec.len() {
998 return Err(EvalError::new(
999 format!("make: keyword {} requires a value", kw),
1000 ));
1001 }
1002 let value = self.eval(args_vec[i + 1].clone(), env.clone())?;
1003
1004 match kw.as_ref() {
1005 "system-id" => {
1006 if let Value::String(s) = value {
1007 system_id = Some(s);
1008 } else {
1009 return Err(EvalError::new(
1010 "make: system-id must be a string".to_string(),
1011 ));
1012 }
1013 }
1014 "data" => {
1015 if let Value::String(s) = value {
1016 data = Some(s);
1017 } else {
1018 return Err(EvalError::new(
1019 "make: data must be a string".to_string(),
1020 ));
1021 }
1022 }
1023 "path" => {
1024 if let Value::String(s) = value {
1025 path = Some(s);
1026 } else {
1027 return Err(EvalError::new(
1028 "make: path must be a string".to_string(),
1029 ));
1030 }
1031 }
1032 _ => {
1033 }
1035 }
1036 i += 2;
1037 }
1038 _ => {
1039 body_exprs.push(args_vec[i].clone());
1041 i += 1;
1042 }
1043 }
1044 }
1045
1046 let backend = self.backend.clone();
1048 match backend {
1049 Some(ref backend) => {
1050 match fo_type {
1051 "entity" => {
1052 if let Some(sid) = system_id {
1053 for expr in body_exprs {
1055 self.eval(expr, env.clone())?;
1056 }
1057
1058 let content = backend.borrow().current_output().to_string();
1060 backend.borrow_mut().entity(&sid, &content)
1061 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1062 backend.borrow_mut().clear_buffer();
1064 } else {
1065 return Err(EvalError::new(
1066 "make entity requires system-id: keyword".to_string(),
1067 ));
1068 }
1069 }
1070 "formatting-instruction" => {
1071 if let Some(d) = data {
1072 backend.borrow_mut().formatting_instruction(&d)
1074 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1075 } else {
1076 return Err(EvalError::new(
1077 "make formatting-instruction requires data: keyword".to_string(),
1078 ));
1079 }
1080 }
1081 "literal" => {
1082 if let Some(d) = data {
1085 backend.borrow_mut().formatting_instruction(&d)
1086 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1087 } else {
1088 return Err(EvalError::new(
1089 "make literal requires data: keyword or a string body".to_string(),
1090 ));
1091 }
1092 }
1093 "directory" => {
1094 if let Some(p) = path {
1095 let prev_dir = backend.borrow().current_directory().map(|s| s.to_string());
1097
1098 backend.borrow_mut().directory(&p)
1100 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1101
1102 for expr in body_exprs {
1105 self.eval(expr, env.clone())?;
1106 }
1107
1108 backend.borrow_mut().set_current_directory(prev_dir);
1110 } else {
1111 return Err(EvalError::new(
1112 "make directory requires path: keyword".to_string(),
1113 ));
1114 }
1115 }
1116 _ => {
1117 return Ok(Value::Unspecified);
1119 }
1120 }
1121 }
1122 None => {
1123 return Err(EvalError::new(
1124 "make: no backend available".to_string(),
1125 ));
1126 }
1127 }
1128
1129 Ok(Value::Unspecified)
1130 }
1131
1132 fn eval_set(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1134 let args_vec = self.list_to_vec(args)?;
1135 if args_vec.len() != 2 {
1136 return Err(EvalError::new(
1137 "set! requires exactly 2 arguments".to_string(),
1138 ));
1139 }
1140
1141 if let Value::Symbol(ref name) = args_vec[0] {
1142 let value = self.eval(args_vec[1].clone(), env.clone())?;
1143 env.set(name, value)
1144 .map_err(|e| EvalError::new(e))?;
1145 Ok(Value::Unspecified)
1146 } else {
1147 Err(EvalError::new(
1148 "First argument to set! must be a symbol".to_string(),
1149 ))
1150 }
1151 }
1152
1153 fn eval_lambda(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1155 let args_vec = self.list_to_vec(args)?;
1156 if args_vec.len() < 2 {
1157 return Err(EvalError::new(
1158 "lambda requires at least 2 arguments (params and body)".to_string(),
1159 ));
1160 }
1161
1162 let params_list = &args_vec[0];
1164 let params_vec = if params_list.is_nil() {
1165 Vec::new()
1167 } else {
1168 self.list_to_vec(params_list.clone())?
1169 };
1170
1171 let mut param_names = Vec::new();
1173 for param in params_vec {
1174 if let Value::Symbol(ref name) = param {
1175 param_names.push(name.to_string());
1176 } else {
1177 return Err(EvalError::new(format!(
1178 "Lambda parameter must be a symbol, got: {:?}",
1179 param
1180 )));
1181 }
1182 }
1183
1184 let body = if args_vec.len() == 2 {
1186 args_vec[1].clone()
1188 } else {
1189 let mut body_list = Value::Nil;
1191 for expr in args_vec[1..].iter().rev() {
1192 body_list = Value::cons(expr.clone(), body_list);
1193 }
1194 Value::cons(Value::symbol("begin"), body_list)
1195 };
1196
1197 let source_info = match (&self.current_source_file, &self.current_position) {
1200 (Some(file), Some(pos)) => {
1201 Some(SourceInfo::new(file.clone(), pos.clone()))
1203 }
1204 (Some(file), None) => {
1205 use crate::scheme::parser::Position;
1206 Some(SourceInfo::new(file.clone(), Position::new()))
1207 }
1208 _ => None,
1209 };
1210 Ok(Value::lambda_with_source(param_names, body, env, source_info, None))
1211 }
1212
1213 fn eval_let(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1215 let args_vec = self.list_to_vec(args)?;
1216 if args_vec.len() < 2 {
1217 return Err(EvalError::new(
1218 "let requires at least 2 arguments".to_string(),
1219 ));
1220 }
1221
1222 if let Value::Symbol(ref loop_name) = args_vec[0] {
1224 if args_vec.len() < 3 {
1225 return Err(EvalError::new(
1226 "named let requires at least 3 arguments".to_string(),
1227 ));
1228 }
1229
1230 let bindings_list = &args_vec[1];
1232 let bindings = self.list_to_vec(bindings_list.clone())?;
1233 let body = &args_vec[2..];
1234
1235 let mut var_names = Vec::new();
1237 let mut init_values = Vec::new();
1238 for binding in &bindings {
1239 let binding_vec = self.list_to_vec(binding.clone())?;
1240 if binding_vec.len() != 2 {
1241 return Err(EvalError::new(
1242 "named let binding must have exactly 2 elements".to_string(),
1243 ));
1244 }
1245 var_names.push(binding_vec[0].clone());
1246 init_values.push(binding_vec[1].clone());
1247 }
1248
1249 let lambda_params = self.vec_to_list(var_names);
1251 let mut lambda_body = vec![Value::symbol("lambda"), lambda_params];
1252 lambda_body.extend_from_slice(body);
1253 let lambda_expr = self.vec_to_list(lambda_body);
1254
1255 let letrec_binding = Value::cons(
1257 Value::symbol(loop_name),
1258 Value::cons(lambda_expr, Value::Nil),
1259 );
1260 let letrec_bindings = Value::cons(letrec_binding, Value::Nil);
1261
1262 let mut call_expr = vec![Value::symbol(loop_name)];
1264 call_expr.extend_from_slice(&init_values);
1265 let call = self.vec_to_list(call_expr);
1266
1267 return self.eval_letrec(self.vec_to_list(vec![letrec_bindings, call]), env);
1269 }
1270
1271 let bindings_list = &args_vec[0];
1273 let bindings = self.list_to_vec(bindings_list.clone())?;
1274
1275 let new_env = Environment::extend(env.clone());
1277
1278 for binding in bindings {
1280 let binding_vec = self.list_to_vec(binding)?;
1281 if binding_vec.len() != 2 {
1282 return Err(EvalError::new(
1283 "let binding must have exactly 2 elements".to_string(),
1284 ));
1285 }
1286
1287 if let Value::Symbol(ref name) = binding_vec[0] {
1288 let value = self.eval_inner(binding_vec[1].clone(), env.clone())?;
1289 new_env.define(name, value);
1290 } else {
1291 return Err(EvalError::new(
1292 "Binding variable must be a symbol".to_string(),
1293 ));
1294 }
1295 }
1296
1297 let body = &args_vec[1..];
1299 self.eval_sequence(body, new_env)
1300 }
1301
1302 fn eval_let_star(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1304 let args_vec = self.list_to_vec(args)?;
1305 if args_vec.len() < 2 {
1306 return Err(EvalError::new(
1307 "let* requires at least 2 arguments".to_string(),
1308 ));
1309 }
1310
1311 let bindings_list = &args_vec[0];
1313 let bindings = self.list_to_vec(bindings_list.clone())?;
1314
1315 let current_env = Environment::extend(env);
1317
1318 for binding in bindings {
1320 let binding_vec = self.list_to_vec(binding)?;
1321 if binding_vec.len() != 2 {
1322 return Err(EvalError::new(
1323 "let* binding must have exactly 2 elements".to_string(),
1324 ));
1325 }
1326
1327 if let Value::Symbol(ref name) = binding_vec[0] {
1328 let value = self.eval_inner(binding_vec[1].clone(), current_env.clone())?;
1329 current_env.define(name, value);
1330 } else {
1331 return Err(EvalError::new(
1332 "Binding variable must be a symbol".to_string(),
1333 ));
1334 }
1335 }
1336
1337 let body = &args_vec[1..];
1339 self.eval_sequence(body, current_env)
1340 }
1341
1342 fn eval_letrec(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1352 let args_vec = self.list_to_vec(args)?;
1353 if args_vec.len() < 2 {
1354 return Err(EvalError::new(
1355 "letrec requires at least 2 arguments".to_string(),
1356 ));
1357 }
1358
1359 let bindings_list = &args_vec[0];
1361 let bindings = self.list_to_vec(bindings_list.clone())?;
1362
1363 let new_env = Environment::extend(env);
1365
1366 let mut var_names = Vec::new();
1368 for binding in &bindings {
1369 let binding_vec = self.list_to_vec(binding.clone())?;
1370 if binding_vec.len() != 2 {
1371 return Err(EvalError::new(
1372 "letrec binding must have exactly 2 elements".to_string(),
1373 ));
1374 }
1375
1376 if let Value::Symbol(ref name) = binding_vec[0] {
1377 var_names.push(name.to_string());
1378 new_env.define(name, Value::Unspecified);
1379 } else {
1380 return Err(EvalError::new(
1381 "Binding variable must be a symbol".to_string(),
1382 ));
1383 }
1384 }
1385
1386 for (i, binding) in bindings.iter().enumerate() {
1388 let binding_vec = self.list_to_vec(binding.clone())?;
1389 let value = self.eval_inner(binding_vec[1].clone(), new_env.clone())?;
1390
1391 new_env.set(&var_names[i], value)
1393 .map_err(|e| EvalError::new(e))?;
1394 }
1395
1396 let body = &args_vec[1..];
1398 self.eval_sequence(body, new_env)
1399 }
1400
1401 fn eval_begin(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1403 let args_vec = self.list_to_vec(args)?;
1404 self.eval_sequence(&args_vec, env)
1405 }
1406
1407 fn eval_cond(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1409 let clauses = self.list_to_vec(args)?;
1410
1411 for clause in clauses {
1412 let clause_vec = self.list_to_vec(clause)?;
1413 if clause_vec.is_empty() {
1414 return Err(EvalError::new("Empty cond clause".to_string()));
1415 }
1416
1417 if let Value::Symbol(ref sym) = clause_vec[0] {
1419 if &**sym == "else" {
1420 return self.eval_sequence(&clause_vec[1..], env);
1421 }
1422 }
1423
1424 let test = self.eval_inner(clause_vec[0].clone(), env.clone())?;
1426 if test.is_true() {
1427 if clause_vec.len() == 1 {
1428 return Ok(test);
1429 } else {
1430 return self.eval_sequence(&clause_vec[1..], env);
1431 }
1432 }
1433 }
1434
1435 Ok(Value::Unspecified)
1436 }
1437
1438 fn eval_case(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1452 let case_position = self.current_position.clone();
1455 let case_file = self.current_source_file.clone();
1456
1457 let args_vec = self.list_to_vec(args)?;
1458 if args_vec.is_empty() {
1459 return Err(EvalError::new("case requires at least 1 argument".to_string()));
1460 }
1461
1462 let key = self.eval_inner(args_vec[0].clone(), env.clone())?;
1464
1465 for clause in &args_vec[1..] {
1467 let clause_vec = self.list_to_vec(clause.clone())?;
1468 if clause_vec.is_empty() {
1469 return Err(EvalError::new("Empty case clause".to_string()));
1470 }
1471
1472 if let Value::Symbol(ref sym) = clause_vec[0] {
1474 if &**sym == "else" {
1475 return self.eval_sequence(&clause_vec[1..], env);
1476 }
1477 }
1478
1479 let datums = self.list_to_vec(clause_vec[0].clone())?;
1481
1482 for datum in datums {
1486 if key.equal(&datum) {
1487 if clause_vec.len() == 1 {
1489 return Ok(Value::Unspecified);
1491 } else {
1492 return self.eval_sequence(&clause_vec[1..], env);
1493 }
1494 }
1495 }
1496 }
1497
1498 self.current_position = case_position.clone();
1500 self.current_source_file = case_file;
1501 Err(self.error_with_stack(format!(
1502 "no clause in case expression matched {:?}",
1503 key
1504 )))
1505 }
1506
1507 fn eval_and(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1509 let args_vec = self.list_to_vec(args)?;
1510
1511 if args_vec.is_empty() {
1512 return Ok(Value::bool(true));
1513 }
1514
1515 let mut result = Value::bool(true);
1516 for expr in args_vec {
1517 result = self.eval_inner(expr, env.clone())?;
1518 if !result.is_true() {
1519 return Ok(Value::bool(false));
1520 }
1521 }
1522
1523 Ok(result)
1524 }
1525
1526 fn eval_or(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1528 let args_vec = self.list_to_vec(args)?;
1529
1530 for expr in args_vec {
1531 let result = self.eval_inner(expr, env.clone())?;
1532 if result.is_true() {
1533 return Ok(result);
1534 }
1535 }
1536
1537 Ok(Value::bool(false))
1538 }
1539
1540 fn eval_sequence(&mut self, exprs: &[Value], env: Gc<Environment>) -> EvalResult {
1542 if exprs.is_empty() {
1543 return Ok(Value::Unspecified);
1544 }
1545
1546 let mut result = Value::Unspecified;
1547 for expr in exprs {
1548 result = self.eval_inner(expr.clone(), env.clone())?;
1549 }
1550
1551 Ok(result)
1552 }
1553
1554 fn eval_apply(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1559 let args_vec = self.list_to_vec(args)?;
1560 if args_vec.len() != 2 {
1561 return Err(EvalError::new(
1562 "apply requires exactly 2 arguments".to_string(),
1563 ));
1564 }
1565
1566 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1568
1569 let arg_list = self.eval_inner(args_vec[1].clone(), env)?;
1571
1572 let arg_values = self.list_to_vec(arg_list)?;
1574
1575 self.apply(proc, arg_values)
1577 }
1578
1579 fn eval_map(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1593 let args_vec = self.list_to_vec(args)?;
1594 if args_vec.len() < 2 {
1595 return Err(EvalError::new("map requires at least 2 arguments".to_string()));
1596 }
1597
1598 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1600
1601 let mut lists = Vec::new();
1603 for i in 1..args_vec.len() {
1604 let list = self.eval_inner(args_vec[i].clone(), env.clone())?;
1605 let list_vec = self.list_to_vec(list)?;
1606 lists.push(list_vec);
1607 }
1608
1609 if lists.is_empty() {
1611 return Ok(Value::Nil);
1612 }
1613
1614 let length = lists[0].len();
1615 for list in &lists[1..] {
1616 if list.len() != length {
1617 return Err(EvalError::new(
1618 "map: all lists must have the same length".to_string(),
1619 ));
1620 }
1621 }
1622
1623 let mut result_vec = Vec::new();
1625 for i in 0..length {
1626 let mut proc_args = Vec::new();
1628 for list in &lists {
1629 proc_args.push(list[i].clone());
1630 }
1631
1632 let result = self.apply(proc.clone(), proc_args)?;
1634 result_vec.push(result);
1635 }
1636
1637 let mut result_list = Value::Nil;
1639 for elem in result_vec.into_iter().rev() {
1640 result_list = Value::cons(elem, result_list);
1641 }
1642
1643 Ok(result_list)
1644 }
1645
1646 fn eval_for_each(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1654 let args_vec = self.list_to_vec(args)?;
1655 if args_vec.len() < 2 {
1656 return Err(EvalError::new(
1657 "for-each requires at least 2 arguments".to_string(),
1658 ));
1659 }
1660
1661 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1663
1664 let mut lists = Vec::new();
1666 for i in 1..args_vec.len() {
1667 let list = self.eval_inner(args_vec[i].clone(), env.clone())?;
1668 let list_vec = self.list_to_vec(list)?;
1669 lists.push(list_vec);
1670 }
1671
1672 if lists.is_empty() {
1674 return Ok(Value::Unspecified);
1675 }
1676
1677 let length = lists[0].len();
1678 for list in &lists[1..] {
1679 if list.len() != length {
1680 return Err(EvalError::new(
1681 "for-each: all lists must have the same length".to_string(),
1682 ));
1683 }
1684 }
1685
1686 for i in 0..length {
1688 let mut proc_args = Vec::new();
1690 for list in &lists {
1691 proc_args.push(list[i].clone());
1692 }
1693
1694 self.apply(proc.clone(), proc_args)?;
1696 }
1697
1698 Ok(Value::Unspecified)
1699 }
1700
1701 fn eval_node_list_filter(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1708 let args_vec = self.list_to_vec(args)?;
1709 if args_vec.len() != 2 {
1710 return Err(EvalError::new("node-list-filter requires exactly 2 arguments".to_string()));
1711 }
1712
1713 let pred = self.eval_inner(args_vec[0].clone(), env.clone())?;
1715
1716 let node_list_val = self.eval_inner(args_vec[1].clone(), env.clone())?;
1718
1719 match node_list_val {
1720 Value::NodeList(ref nl) => {
1721 let mut filtered_nodes = Vec::new();
1722
1723 let mut index = 0;
1725 loop {
1726 if let Some(node) = nl.get(index) {
1727 let node_val = Value::node(node);
1729 let result = self.apply(pred.clone(), vec![node_val.clone()])?;
1730
1731 if !matches!(result, Value::Bool(false)) {
1733 if let Value::Node(n) = node_val {
1735 filtered_nodes.push(n.as_ref().clone_node());
1736 }
1737 }
1738
1739 index += 1;
1740 } else {
1741 break;
1742 }
1743 }
1744
1745 Ok(Value::node_list(Box::new(crate::grove::VecNodeList::new(filtered_nodes))))
1746 }
1747 _ => Err(EvalError::new(format!("node-list-filter: second argument not a node-list: {:?}", node_list_val))),
1748 }
1749 }
1750
1751 fn eval_node_list_map(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1761 let args_vec = self.list_to_vec(args)?;
1762 if args_vec.len() != 2 {
1763 return Err(EvalError::new("node-list-map requires exactly 2 arguments".to_string()));
1764 }
1765
1766 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1768
1769 let node_list_val = self.eval_inner(args_vec[1].clone(), env.clone())?;
1771
1772 let mut result_nodes: Vec<Box<dyn crate::grove::Node>> = Vec::new();
1774
1775 match node_list_val {
1776 Value::Node(ref n) => {
1777 let node_val = Value::node(n.as_ref().clone_node());
1779 let result = self.apply(proc, vec![node_val])?;
1780
1781 match result {
1784 Value::Node(n) => {
1785 result_nodes.push(n.as_ref().clone_node());
1787 }
1788 Value::NodeList(nl) => {
1789 let mut index = 0;
1791 while let Some(node) = nl.get(index) {
1792 result_nodes.push(node);
1793 index += 1;
1794 }
1795 }
1796 _ => {
1797 }
1800 }
1801 }
1802 Value::NodeList(ref nl) => {
1803 let mut index = 0;
1805 loop {
1806 if let Some(node) = nl.get(index) {
1807 let node_val = Value::node(node);
1809 let result = self.apply(proc.clone(), vec![node_val])?;
1810
1811 match result {
1813 Value::Node(n) => {
1814 result_nodes.push(n.as_ref().clone_node());
1816 index += 1;
1817 }
1818 Value::NodeList(nl_result) => {
1819 let mut nl_index = 0;
1821 while let Some(node) = nl_result.get(nl_index) {
1822 result_nodes.push(node);
1823 nl_index += 1;
1824 }
1825 index += 1;
1826 }
1827 _ => {
1828 break;
1830 }
1831 }
1832 } else {
1833 break;
1834 }
1835 }
1836 }
1837 _ => return Err(EvalError::new(format!("node-list-map: second argument must be a node or node-list: {:?}", node_list_val))),
1838 }
1839
1840 Ok(Value::node_list(Box::new(crate::grove::VecNodeList::new(result_nodes))))
1842 }
1843
1844 fn eval_node_list_some(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1850 let args_vec = self.list_to_vec(args)?;
1851 if args_vec.len() != 2 {
1852 return Err(EvalError::new("node-list-some? requires exactly 2 arguments".to_string()));
1853 }
1854
1855 let pred = self.eval_inner(args_vec[0].clone(), env.clone())?;
1857
1858 let node_list_val = self.eval_inner(args_vec[1].clone(), env.clone())?;
1860
1861 match node_list_val {
1862 Value::NodeList(ref nl) => {
1863 let mut index = 0;
1865 loop {
1866 if let Some(node) = nl.get(index) {
1867 let node_val = Value::node(node);
1869 let result = self.apply(pred.clone(), vec![node_val])?;
1870
1871 if !matches!(result, Value::Bool(false)) {
1873 return Ok(Value::bool(true));
1874 }
1875
1876 index += 1;
1877 } else {
1878 break;
1879 }
1880 }
1881
1882 Ok(Value::bool(false))
1884 }
1885 _ => Err(EvalError::new(format!("node-list-some?: second argument not a node-list: {:?}", node_list_val))),
1886 }
1887 }
1888
1889 fn eval_load(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1894 let args_vec = self.list_to_vec(args)?;
1895 if args_vec.len() != 1 {
1896 return Err(EvalError::new(
1897 "load requires exactly 1 argument".to_string(),
1898 ));
1899 }
1900
1901 let filename_val = self.eval_inner(args_vec[0].clone(), env.clone())?;
1903
1904 let filename = match filename_val {
1905 Value::String(s) => s.to_string(),
1906 _ => return Err(EvalError::new(
1907 format!("load: filename must be a string, got {:?}", filename_val)
1908 )),
1909 };
1910
1911 let contents = std::fs::read_to_string(&filename)
1913 .map_err(|e| EvalError::new(format!("load: cannot read file '{}': {}", filename, e)))?;
1914
1915 let mut parser = crate::scheme::parser::Parser::new_with_filename(&contents, filename.clone());
1917 let mut result = Value::Unspecified;
1918
1919 let prev_source_file = self.current_source_file.clone();
1921 let prev_position = self.current_position.clone();
1922 self.current_source_file = Some(filename.clone());
1923
1924 let eval_result = loop {
1926 let pos = parser.current_position();
1928
1929 match parser.parse() {
1930 Ok(expr) => {
1931 self.current_position = Some(pos);
1933
1934 match self.eval_inner(expr, env.clone()) {
1935 Ok(val) => result = val,
1936 Err(e) => break Err(e),
1937 }
1938 }
1939 Err(e) => {
1940 let error_msg = e.to_string();
1942 if error_msg.contains("Unexpected end of input")
1943 || error_msg.contains("Expected")
1944 || error_msg.contains("EOF") {
1945 break Ok(result);
1946 }
1947 break Err(EvalError::new(
1948 format!("load: parse error in '{}': {}", filename, e)
1949 ));
1950 }
1951 }
1952 };
1953
1954 self.current_source_file = prev_source_file;
1956 self.current_position = prev_position;
1957
1958 eval_result
1959 }
1960
1961 fn eval_application(
1967 &mut self,
1968 operator: Value,
1969 args: Value,
1970 env: Gc<Environment>,
1971 ) -> EvalResult {
1972 let application_pos = self.current_position.clone();
1974 let application_file = self.current_source_file.clone();
1975
1976 let proc = self.eval_inner(operator, env.clone())?;
1978
1979 let mut evaled_args = Vec::new();
1981 let mut current_args = args;
1982 loop {
1983 match current_args {
1984 Value::Nil => break,
1985 Value::Pair(ref p) => {
1986 let pair_borrow = p.borrow();
1987
1988 if let Some(ref pos) = pair_borrow.pos {
1991 if !self.line_mappings.is_empty() {
1993 if let Some(mapping) = self.line_mappings.iter().find(|m| m.output_line == pos.line) {
1994 self.current_source_file = Some(mapping.source_file.clone());
1995 self.current_position = Some(Position {
1996 line: mapping.source_line,
1997 column: pos.column,
1998 });
1999 } else {
2000 self.current_position = Some(pos.clone());
2001 }
2002 } else {
2003 self.current_position = Some(pos.clone());
2004 }
2005 }
2006
2007 let arg = pair_borrow.car.clone();
2008 let cdr = pair_borrow.cdr.clone();
2009 drop(pair_borrow); evaled_args.push(self.eval_inner(arg, env.clone())?);
2012 current_args = cdr;
2013 }
2014 _ => return Err(EvalError::new("Improper argument list".to_string())),
2015 }
2016 }
2017
2018 self.current_position = application_pos;
2021 self.current_source_file = application_file;
2022
2023 self.apply(proc, evaled_args)
2025 }
2026
2027 fn apply(&mut self, proc: Value, args: Vec<Value>) -> EvalResult {
2029 if let Value::Procedure(ref p) = proc {
2030 match &**p {
2031 Procedure::Primitive { name, func } => {
2032 func(&args).map_err(|e| self.error_with_stack(e))
2035 }
2036 Procedure::Lambda { params, body, env, source, name } => {
2037 if args.len() != params.len() {
2039 return Err(self.error_with_stack(format!(
2040 "Lambda expects {} arguments, got {}",
2041 params.len(),
2042 args.len()
2043 )));
2044 }
2045
2046 let saved_file = self.current_source_file.clone();
2048 let saved_pos = self.current_position.clone();
2049
2050 let pushed_frame = if let Some(func_name) = name.clone() {
2053 let call_site = match (&saved_file, &saved_pos) {
2054 (Some(file), Some(pos)) => Some(SourceInfo {
2055 file: file.clone(),
2056 pos: pos.clone(),
2057 }),
2058 _ => None,
2059 };
2060 self.push_call_frame(func_name, call_site);
2061 true
2062 } else {
2063 false
2064 };
2065
2066 if let Some(ref src) = source {
2068 self.current_source_file = Some(src.file.clone());
2069 self.current_position = Some(src.pos.clone());
2070 }
2071
2072 let lambda_env = Environment::extend(env.clone());
2074
2075 for (param_name, arg_value) in params.iter().zip(args.iter()) {
2077 lambda_env.define(param_name, arg_value.clone());
2078 }
2079
2080 let result = self.eval_inner((**body).clone(), lambda_env);
2082
2083 self.current_source_file = saved_file;
2085 self.current_position = saved_pos;
2086
2087 if pushed_frame {
2089 self.pop_call_frame();
2090 }
2091
2092 result
2093 }
2094 }
2095 } else {
2096 Err(self.error_with_stack(format!(
2097 "Not a procedure: {:?}",
2098 proc
2099 )))
2100 }
2101 }
2102}
2103
2104impl Default for Evaluator {
2105 fn default() -> Self {
2106 Self::new()
2107 }
2108}
2109
2110#[cfg(test)]
2115mod tests {
2116 use super::*;
2117
2118 fn make_env() -> Gc<Environment> {
2119 Environment::new_global()
2120 }
2121
2122 #[test]
2123 fn test_eval_self_evaluating() {
2124 let mut eval = Evaluator::new();
2125 let env = make_env();
2126
2127 assert!(eval.eval(Value::integer(42), env.clone()).unwrap().is_integer());
2128 assert!(eval.eval(Value::bool(true), env.clone()).unwrap().is_bool());
2129 assert!(eval.eval(Value::string("hello".to_string()), env).unwrap().is_string());
2130 }
2131
2132 #[test]
2133 fn test_eval_quote() {
2134 let mut eval = Evaluator::new();
2135 let env = make_env();
2136
2137 let expr = Value::cons(
2139 Value::symbol("quote"),
2140 Value::cons(
2141 Value::cons(
2142 Value::integer(1),
2143 Value::cons(Value::integer(2), Value::cons(Value::integer(3), Value::Nil)),
2144 ),
2145 Value::Nil,
2146 ),
2147 );
2148
2149 let result = eval.eval(expr, env).unwrap();
2150 assert!(result.is_list());
2151 }
2152
2153 #[test]
2154 fn test_eval_if_true() {
2155 let mut eval = Evaluator::new();
2156 let env = make_env();
2157
2158 let expr = Value::cons(
2160 Value::symbol("if"),
2161 Value::cons(
2162 Value::bool(true),
2163 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2164 ),
2165 );
2166
2167 let result = eval.eval(expr, env).unwrap();
2168 if let Value::Integer(n) = result {
2169 assert_eq!(n, 1);
2170 } else {
2171 panic!("Expected integer 1");
2172 }
2173 }
2174
2175 #[test]
2176 fn test_eval_if_false() {
2177 let mut eval = Evaluator::new();
2178 let env = make_env();
2179
2180 let expr = Value::cons(
2182 Value::symbol("if"),
2183 Value::cons(
2184 Value::bool(false),
2185 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2186 ),
2187 );
2188
2189 let result = eval.eval(expr, env).unwrap();
2190 if let Value::Integer(n) = result {
2191 assert_eq!(n, 2);
2192 } else {
2193 panic!("Expected integer 2");
2194 }
2195 }
2196
2197 #[test]
2198 fn test_eval_define() {
2199 let mut eval = Evaluator::new();
2200 let env = make_env();
2201
2202 let expr = Value::cons(
2204 Value::symbol("define"),
2205 Value::cons(Value::symbol("x"), Value::cons(Value::integer(42), Value::Nil)),
2206 );
2207
2208 eval.eval(expr, env.clone()).unwrap();
2209
2210 assert!(env.is_defined("x"));
2212 if let Value::Integer(n) = env.lookup("x").unwrap() {
2213 assert_eq!(n, 42);
2214 }
2215 }
2216
2217 #[test]
2218 fn test_eval_symbol_lookup() {
2219 let mut eval = Evaluator::new();
2220 let env = make_env();
2221
2222 env.define("x", Value::integer(99));
2223
2224 let result = eval.eval(Value::symbol("x"), env).unwrap();
2225 if let Value::Integer(n) = result {
2226 assert_eq!(n, 99);
2227 } else {
2228 panic!("Expected integer 99");
2229 }
2230 }
2231
2232 #[test]
2233 fn test_eval_and() {
2234 let mut eval = Evaluator::new();
2235 let env = make_env();
2236
2237 let expr = Value::cons(
2239 Value::symbol("and"),
2240 Value::cons(Value::bool(true), Value::cons(Value::bool(true), Value::Nil)),
2241 );
2242
2243 let result = eval.eval(expr, env.clone()).unwrap();
2244 assert!(result.is_true());
2245
2246 let expr = Value::cons(
2248 Value::symbol("and"),
2249 Value::cons(Value::bool(true), Value::cons(Value::bool(false), Value::Nil)),
2250 );
2251
2252 let result = eval.eval(expr, env).unwrap();
2253 assert!(!result.is_true());
2254 }
2255
2256 #[test]
2257 fn test_eval_or() {
2258 let mut eval = Evaluator::new();
2259 let env = make_env();
2260
2261 let expr = Value::cons(
2263 Value::symbol("or"),
2264 Value::cons(Value::bool(false), Value::cons(Value::bool(true), Value::Nil)),
2265 );
2266
2267 let result = eval.eval(expr, env.clone()).unwrap();
2268 assert!(result.is_true());
2269
2270 let expr = Value::cons(
2272 Value::symbol("or"),
2273 Value::cons(Value::bool(false), Value::cons(Value::bool(false), Value::Nil)),
2274 );
2275
2276 let result = eval.eval(expr, env).unwrap();
2277 assert!(!result.is_true());
2278 }
2279
2280 #[test]
2281 fn test_eval_lambda_creation() {
2282 let mut eval = Evaluator::new();
2283 let env = make_env();
2284
2285 let expr = Value::cons(
2287 Value::symbol("lambda"),
2288 Value::cons(
2289 Value::cons(Value::symbol("x"), Value::Nil),
2290 Value::cons(Value::symbol("x"), Value::Nil),
2291 ),
2292 );
2293
2294 let result = eval.eval(expr, env).unwrap();
2295 assert!(result.is_procedure());
2296 }
2297
2298 #[test]
2299 fn test_eval_lambda_application() {
2300 let mut eval = Evaluator::new();
2301 let env = make_env();
2302
2303 let lambda_expr = Value::cons(
2305 Value::symbol("lambda"),
2306 Value::cons(
2307 Value::cons(Value::symbol("x"), Value::Nil),
2308 Value::cons(Value::symbol("x"), Value::Nil),
2309 ),
2310 );
2311
2312 let app_expr = Value::cons(lambda_expr, Value::cons(Value::integer(42), Value::Nil));
2313
2314 let result = eval.eval(app_expr, env).unwrap();
2315 if let Value::Integer(n) = result {
2316 assert_eq!(n, 42);
2317 } else {
2318 panic!("Expected integer 42");
2319 }
2320 }
2321
2322 #[test]
2323 fn test_eval_lambda_multiple_params() {
2324 let mut eval = Evaluator::new();
2325 let env = make_env();
2326
2327 let params = Value::cons(Value::symbol("x"), Value::cons(Value::symbol("y"), Value::Nil));
2329 let body = Value::symbol("x");
2330
2331 let lambda_expr = Value::cons(Value::symbol("lambda"), Value::cons(params, Value::cons(body, Value::Nil)));
2332
2333 let app_expr = Value::cons(
2334 lambda_expr,
2335 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2336 );
2337
2338 let result = eval.eval(app_expr, env).unwrap();
2339 if let Value::Integer(n) = result {
2340 assert_eq!(n, 1);
2341 } else {
2342 panic!("Expected integer 1");
2343 }
2344 }
2345
2346 #[test]
2347 fn test_eval_lambda_wrong_arg_count() {
2348 let mut eval = Evaluator::new();
2349 let env = make_env();
2350
2351 let lambda_expr = Value::cons(
2353 Value::symbol("lambda"),
2354 Value::cons(
2355 Value::cons(Value::symbol("x"), Value::Nil),
2356 Value::cons(Value::symbol("x"), Value::Nil),
2357 ),
2358 );
2359
2360 let app_expr = Value::cons(
2361 lambda_expr,
2362 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2363 );
2364
2365 let result = eval.eval(app_expr, env);
2366 assert!(result.is_err());
2367 }
2368
2369 #[test]
2370 fn test_eval_lambda_closure() {
2371 let mut eval = Evaluator::new();
2372 let env = make_env();
2373
2374 env.define("x", Value::integer(10));
2376
2377 let lambda_expr = Value::cons(
2380 Value::symbol("lambda"),
2381 Value::cons(
2382 Value::cons(Value::symbol("y"), Value::Nil),
2383 Value::cons(Value::symbol("x"), Value::Nil),
2384 ),
2385 );
2386
2387 let app_expr = Value::cons(lambda_expr, Value::cons(Value::integer(20), Value::Nil));
2388
2389 let result = eval.eval(app_expr, env).unwrap();
2390 if let Value::Integer(n) = result {
2391 assert_eq!(n, 10); } else {
2393 panic!("Expected integer 10 from closure");
2394 }
2395 }
2396
2397 #[test]
2398 fn test_eval_lambda_no_params() {
2399 let mut eval = Evaluator::new();
2400 let env = make_env();
2401
2402 let lambda_expr = Value::cons(
2404 Value::symbol("lambda"),
2405 Value::cons(Value::Nil, Value::cons(Value::integer(42), Value::Nil)),
2406 );
2407
2408 let app_expr = Value::cons(lambda_expr, Value::Nil);
2409
2410 let result = eval.eval(app_expr, env).unwrap();
2411 if let Value::Integer(n) = result {
2412 assert_eq!(n, 42);
2413 } else {
2414 panic!("Expected integer 42");
2415 }
2416 }
2417
2418 #[test]
2419 fn test_eval_lambda_multiple_body_expressions() {
2420 let mut eval = Evaluator::new();
2421 let env = make_env();
2422
2423 let params = Value::cons(Value::symbol("x"), Value::Nil);
2426 let body1 = Value::integer(1);
2427 let body2 = Value::integer(2);
2428 let body3 = Value::symbol("x");
2429
2430 let lambda_expr = Value::cons(
2431 Value::symbol("lambda"),
2432 Value::cons(
2433 params,
2434 Value::cons(body1, Value::cons(body2, Value::cons(body3, Value::Nil))),
2435 ),
2436 );
2437
2438 let app_expr = Value::cons(lambda_expr, Value::cons(Value::integer(99), Value::Nil));
2439
2440 let result = eval.eval(app_expr, env).unwrap();
2441 if let Value::Integer(n) = result {
2442 assert_eq!(n, 99);
2443 } else {
2444 panic!("Expected integer 99");
2445 }
2446 }
2447}