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
289impl Evaluator {
290 pub fn new() -> Self {
292 Evaluator {
293 grove: None,
294 current_node: None,
295 processing_mode: ProcessingMode::new(),
296 backend: None,
297 call_stack: Vec::new(),
298 current_source_file: None,
299 current_position: None,
300 }
301 }
302
303 pub fn with_grove(grove: Rc<dyn Grove>) -> Self {
305 Evaluator {
306 grove: Some(grove),
307 current_node: None,
308 processing_mode: ProcessingMode::new(),
309 backend: None,
310 call_stack: Vec::new(),
311 current_source_file: None,
312 current_position: None,
313 }
314 }
315
316 pub fn set_source_file(&mut self, file: String) {
318 self.current_source_file = Some(file);
319 }
320
321 pub fn source_file(&self) -> Option<&str> {
323 self.current_source_file.as_deref()
324 }
325
326 pub fn set_position(&mut self, position: Position) {
328 self.current_position = Some(position);
329 }
330
331 fn push_call_frame(&mut self, function_name: String, source: Option<SourceInfo>) {
333 self.call_stack.push(CallFrame::new(function_name, source));
334 }
335
336 fn pop_call_frame(&mut self) {
338 self.call_stack.pop();
339 }
340
341 fn error_with_stack(&self, message: String) -> EvalError {
343 let full_message = match (&self.current_source_file, &self.current_position) {
345 (Some(file), Some(pos)) => {
346 format!("{}:{}:{}:E: {}", file, pos.line, pos.column, message)
347 }
348 (Some(file), None) => {
349 format!("{}:E: {}", file, message)
350 }
351 _ => message,
352 };
353 EvalError::with_stack(full_message, self.call_stack.clone())
354 }
355
356 pub fn set_backend(&mut self, backend: Rc<RefCell<dyn FotBuilder>>) {
358 self.backend = Some(backend);
359 }
360
361 pub fn set_grove(&mut self, grove: Rc<dyn Grove>) {
363 self.grove = Some(grove);
364 }
365
366 pub fn grove(&self) -> Option<&Rc<dyn Grove>> {
368 self.grove.as_ref()
369 }
370
371 pub fn set_current_node(&mut self, node: Box<dyn Node>) {
373 self.current_node = Some(Rc::new(node));
374 }
375
376 pub fn current_node(&self) -> Option<Rc<Box<dyn Node>>> {
378 self.current_node.clone()
379 }
380
381 pub fn clear_current_node(&mut self) {
383 self.current_node = None;
384 }
385
386 pub fn process_root(&mut self, env: Gc<Environment>) -> EvalResult {
395 let root_node = match &self.grove {
397 Some(grove) => grove.root(),
398 None => return Err(EvalError::new("No grove set".to_string())),
399 };
400
401 self.current_node = Some(Rc::new(root_node));
403 self.process_node(env)
404 }
405
406 pub fn process_node(&mut self, env: Gc<Environment>) -> EvalResult {
417 let node = match &self.current_node {
418 Some(n) => n.clone(),
419 None => return Err(EvalError::new("No current node".to_string())),
420 };
421
422 let gi = match node.gi() {
424 Some(gi) => gi,
425 None => {
426 return Ok(Value::Unspecified);
429 }
430 };
431
432 let rule = self.processing_mode.find_match(&gi);
434
435 if let Some(rule) = rule {
436 let saved_file = self.current_source_file.clone();
439 let saved_pos = self.current_position.clone();
440
441 if let Some(ref rule_file) = rule.source_file {
444 self.current_source_file = Some(rule_file.clone());
445 }
446 if let Some(ref rule_pos) = rule.source_pos {
447 self.current_position = Some(rule_pos.clone());
448 }
449
450 let result = self.eval(rule.expr.clone(), env);
452
453 self.current_source_file = saved_file;
455 self.current_position = saved_pos;
456
457 result
458 } else if let Some(ref default_expr) = self.processing_mode.default_rule {
459 self.eval(default_expr.clone(), env)
461 } else {
462 self.eval_process_children(env)
465 }
466 }
467
468 pub fn eval(&mut self, expr: Value, env: Gc<Environment>) -> EvalResult {
478 let context_was_set = has_evaluator_context();
480 let previous_context = get_evaluator_context();
481
482 set_evaluator_context(EvaluatorContext {
485 grove: self.grove.clone(),
486 current_node: self.current_node.clone(),
487 backend: self.backend.clone(),
488 });
489
490 let result = self.eval_inner(expr, env);
492
493 if context_was_set {
495 if let Some(prev_ctx) = previous_context {
496 set_evaluator_context(prev_ctx);
497 }
498 } else {
499 clear_evaluator_context();
500 }
501
502 result
503 }
504
505 fn eval_inner(&mut self, expr: Value, env: Gc<Environment>) -> EvalResult {
507 match expr {
508 Value::Nil => Ok(Value::Nil),
510 Value::Bool(_) => Ok(expr),
511 Value::Integer(_) => Ok(expr),
512 Value::Real(_) => Ok(expr),
513 Value::Char(_) => Ok(expr),
514 Value::String(_) => Ok(expr),
515 Value::Procedure(_) => Ok(expr),
516 Value::Vector(_) => Ok(expr), Value::Unspecified => Ok(expr),
518 Value::Error => Ok(expr),
519
520 Value::Node(_) => Ok(expr),
522 Value::NodeList(_) => Ok(expr),
523 Value::Sosofo => Ok(expr),
524
525 Value::Symbol(ref name) => env
527 .lookup(name)
528 .ok_or_else(|| self.error_with_stack(format!("Undefined variable: {}", name))),
529
530 Value::Keyword(_) => Ok(expr),
532
533 Value::Pair(_) => self.eval_list(expr, env),
535 }
536 }
537
538 fn eval_list(&mut self, expr: Value, env: Gc<Environment>) -> EvalResult {
540 if let Value::Pair(ref p) = expr {
542 let pair_data = p.borrow();
543 if let Some(ref pos) = pair_data.pos {
544 self.current_position = Some(pos.clone());
545 }
546 }
547
548 let (operator, args) = self.list_car_cdr(&expr)?;
550
551 if let Value::Symbol(ref sym) = operator {
553 match &**sym {
554 "quote" => self.eval_quote(args),
555 "if" => self.eval_if(args, env),
556 "define" => self.eval_define(args, env),
557 "set!" => self.eval_set(args, env),
558 "lambda" => self.eval_lambda(args, env),
559 "let" => self.eval_let(args, env),
560 "let*" => self.eval_let_star(args, env),
561 "letrec" => self.eval_letrec(args, env),
562 "begin" => self.eval_begin(args, env),
563 "cond" => self.eval_cond(args, env),
564 "case" => self.eval_case(args, env),
565 "and" => self.eval_and(args, env),
566 "or" => self.eval_or(args, env),
567 "apply" => self.eval_apply(args, env),
568 "map" => self.eval_map(args, env),
569 "for-each" => self.eval_for_each(args, env),
570 "node-list-filter" => self.eval_node_list_filter(args, env),
571 "node-list-map" => self.eval_node_list_map(args, env),
572 "node-list-some?" => self.eval_node_list_some(args, env),
573 "load" => self.eval_load(args, env),
574
575 "define-language" => self.eval_define_language(args, env),
577 "declare-flow-object-class" => self.eval_declare_flow_object_class(args, env),
578 "declare-characteristic" => self.eval_declare_characteristic(args, env),
579 "element" => self.eval_element(args, env),
580 "default" => self.eval_default(args, env),
581 "process-children" => self.eval_process_children(env),
582 "make" => self.eval_make(args, env),
583
584 _ => self.eval_application(operator, args, env),
586 }
587 } else {
588 self.eval_application(operator, args, env)
590 }
591 }
592
593 fn list_car_cdr(&self, list: &Value) -> Result<(Value, Value), EvalError> {
595 if let Value::Pair(ref p) = list {
596 let pair = p.borrow();
597 Ok((pair.car.clone(), pair.cdr.clone()))
598 } else {
599 Err(EvalError::new("Expected list".to_string()))
600 }
601 }
602
603 fn vec_to_list(&self, vec: Vec<Value>) -> Value {
605 let mut result = Value::Nil;
606 for val in vec.iter().rev() {
607 result = Value::cons(val.clone(), result);
608 }
609 result
610 }
611
612 fn list_to_vec(&self, list: Value) -> Result<Vec<Value>, EvalError> {
614 let mut result = Vec::new();
615 let mut current = list;
616
617 loop {
618 match current {
619 Value::Nil => break,
620 Value::Pair(ref p) => {
621 let pair = p.borrow();
622 result.push(pair.car.clone());
623 let cdr = pair.cdr.clone();
624 drop(pair); current = cdr;
626 }
627 _ => return Err(EvalError::new("Improper list".to_string())),
628 }
629 }
630
631 Ok(result)
632 }
633
634 fn eval_quote(&mut self, args: Value) -> EvalResult {
640 let args_vec = self.list_to_vec(args)?;
641 if args_vec.len() != 1 {
642 return Err(EvalError::new("quote requires exactly 1 argument".to_string()));
643 }
644 Ok(args_vec[0].clone())
645 }
646
647 fn eval_if(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
649 let args_vec = self.list_to_vec(args)?;
650 if args_vec.len() < 2 || args_vec.len() > 3 {
651 return Err(EvalError::new(
652 "if requires 2 or 3 arguments".to_string(),
653 ));
654 }
655
656 let test = self.eval_inner(args_vec[0].clone(), env.clone())?;
657
658 if test.is_true() {
659 self.eval_inner(args_vec[1].clone(), env)
660 } else if args_vec.len() == 3 {
661 self.eval_inner(args_vec[2].clone(), env)
662 } else {
663 Ok(Value::Unspecified)
664 }
665 }
666
667 fn eval_define(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
669 let args_vec = self.list_to_vec(args)?;
670 if args_vec.len() < 2 {
671 return Err(EvalError::new(
672 "define requires at least 2 arguments".to_string(),
673 ));
674 }
675
676 match &args_vec[0] {
678 Value::Symbol(ref name) => {
679 if args_vec.len() != 2 {
681 return Err(EvalError::new(
682 "define with symbol requires exactly 2 arguments".to_string(),
683 ));
684 }
685 let value = self.eval_inner(args_vec[1].clone(), env.clone())?;
686 env.define(name, value);
687 Ok(Value::Unspecified)
688 }
689
690 Value::Pair(_) => {
691 let (name_val, params) = self.list_car_cdr(&args_vec[0])?;
694
695 if let Value::Symbol(ref name) = name_val {
696 let params_vec = if params.is_nil() {
698 Vec::new()
699 } else {
700 self.list_to_vec(params)?
701 };
702
703 let mut param_names = Vec::new();
704 for param in params_vec {
705 if let Value::Symbol(ref pname) = param {
706 param_names.push(pname.to_string());
707 } else {
708 return Err(EvalError::new(format!(
709 "Parameter must be a symbol, got: {:?}",
710 param
711 )));
712 }
713 }
714
715 let body = if args_vec.len() == 2 {
717 args_vec[1].clone()
718 } else {
719 let mut body_list = Value::Nil;
720 for expr in args_vec[1..].iter().rev() {
721 body_list = Value::cons(expr.clone(), body_list);
722 }
723 Value::cons(Value::symbol("begin"), body_list)
724 };
725
726 let source_info = self.current_source_file.as_ref().map(|file| {
728 use crate::scheme::parser::Position;
729 SourceInfo::new(file.clone(), Position::new())
730 });
731 let lambda_value = Value::lambda_with_source(
732 param_names,
733 body,
734 env.clone(),
735 source_info,
736 Some(name.to_string()),
737 );
738
739 env.define(name, lambda_value);
740 Ok(Value::Unspecified)
741 } else {
742 Err(EvalError::new(
743 "First element of define must be a symbol".to_string(),
744 ))
745 }
746 }
747
748 _ => Err(EvalError::new(
749 "First argument to define must be symbol or list".to_string(),
750 )),
751 }
752 }
753
754 fn eval_define_language(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
757 let args_vec = self.list_to_vec(args)?;
758
759 if args_vec.is_empty() {
760 return Err(EvalError::new(
761 "define-language requires at least 1 argument".to_string(),
762 ));
763 }
764
765 if let Value::Symbol(ref name) = args_vec[0] {
767 env.define(name, args_vec[0].clone());
770 Ok(Value::Unspecified)
771 } else {
772 Err(EvalError::new(
773 "First argument to define-language must be a symbol".to_string(),
774 ))
775 }
776 }
777
778 fn eval_declare_flow_object_class(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
781 let args_vec = self.list_to_vec(args)?;
782
783 if args_vec.is_empty() {
784 return Err(EvalError::new(
785 "declare-flow-object-class requires at least 1 argument".to_string(),
786 ));
787 }
788
789 if let Value::Symbol(ref name) = args_vec[0] {
791 env.define(name, args_vec[0].clone());
794 Ok(Value::Unspecified)
795 } else {
796 Err(EvalError::new(
797 "First argument to declare-flow-object-class must be a symbol".to_string(),
798 ))
799 }
800 }
801
802 fn eval_declare_characteristic(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
805 let args_vec = self.list_to_vec(args)?;
806
807 if args_vec.len() < 3 {
808 return Err(EvalError::new(
809 "declare-characteristic requires at least 3 arguments (name, public-id, default-value)".to_string(),
810 ));
811 }
812
813 if let Value::Symbol(ref name) = args_vec[0] {
815 let default_value = self.eval(args_vec[2].clone(), env.clone())?;
817
818 env.define(name, default_value);
820 Ok(Value::Unspecified)
821 } else {
822 Err(EvalError::new(
823 "First argument to declare-characteristic must be a symbol".to_string(),
824 ))
825 }
826 }
827
828 fn eval_element(&mut self, args: Value, _env: Gc<Environment>) -> EvalResult {
834 let args_vec = self.list_to_vec(args)?;
835
836 if args_vec.len() < 2 {
837 return Err(EvalError::new(
838 "element requires at least 2 arguments (element-name and construction-expression)".to_string(),
839 ));
840 }
841
842 let element_name = if let Value::Symbol(ref name) = args_vec[0] {
844 name.clone()
845 } else {
846 return Err(EvalError::new(
847 "First argument to element must be a symbol".to_string(),
848 ));
849 };
850
851 self.processing_mode.add_rule(
855 element_name.to_string(),
856 args_vec[1].clone(),
857 self.current_source_file.clone(),
858 self.current_position.clone()
859 );
860
861 Ok(Value::Unspecified)
862 }
863
864 fn eval_default(&mut self, args: Value, _env: Gc<Environment>) -> EvalResult {
870 let args_vec = self.list_to_vec(args)?;
871
872 if args_vec.is_empty() {
873 return Err(EvalError::new(
874 "default requires at least 1 argument (construction-expression)".to_string(),
875 ));
876 }
877
878 self.processing_mode.add_default_rule(args_vec[0].clone());
880
881 Ok(Value::Unspecified)
882 }
883
884 fn eval_process_children(&mut self, env: Gc<Environment>) -> EvalResult {
890 let current_node = match &self.current_node {
892 Some(node) => node.clone(),
893 None => return Err(EvalError::new("No current node".to_string())),
894 };
895
896 let mut children = current_node.children();
898
899 let mut result = Value::Unspecified;
901 while !children.is_empty() {
902 if let Some(child_node) = children.first() {
904 let saved_node = self.current_node.clone();
906
907 self.current_node = Some(Rc::new(child_node));
909
910 result = self.process_node(env.clone())?;
912
913 self.current_node = saved_node;
915 }
916
917 children = children.rest();
919 }
920
921 Ok(result)
922 }
923
924 fn eval_make(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
930 let args_vec = self.list_to_vec(args)?;
931
932 if args_vec.is_empty() {
933 return Err(EvalError::new(
934 "make requires at least a flow object type".to_string(),
935 ));
936 }
937
938 let fo_type = match &args_vec[0] {
940 Value::Symbol(s) => s.as_ref(),
941 _ => return Err(EvalError::new(
942 "make: first argument must be a flow object type symbol".to_string(),
943 )),
944 };
945
946 let mut i = 1;
948 let mut system_id = None;
949 let mut data = None;
950 let mut path = None;
951 let mut body_exprs = Vec::new();
952
953 while i < args_vec.len() {
954 match &args_vec[i] {
955 Value::Keyword(kw) => {
956 if i + 1 >= args_vec.len() {
958 return Err(EvalError::new(
959 format!("make: keyword {} requires a value", kw),
960 ));
961 }
962 let value = self.eval(args_vec[i + 1].clone(), env.clone())?;
963
964 match kw.as_ref() {
965 "system-id" => {
966 if let Value::String(s) = value {
967 system_id = Some(s);
968 } else {
969 return Err(EvalError::new(
970 "make: system-id must be a string".to_string(),
971 ));
972 }
973 }
974 "data" => {
975 if let Value::String(s) = value {
976 data = Some(s);
977 } else {
978 return Err(EvalError::new(
979 "make: data must be a string".to_string(),
980 ));
981 }
982 }
983 "path" => {
984 if let Value::String(s) = value {
985 path = Some(s);
986 } else {
987 return Err(EvalError::new(
988 "make: path must be a string".to_string(),
989 ));
990 }
991 }
992 _ => {
993 }
995 }
996 i += 2;
997 }
998 _ => {
999 body_exprs.push(args_vec[i].clone());
1001 i += 1;
1002 }
1003 }
1004 }
1005
1006 let backend = self.backend.clone();
1008 match backend {
1009 Some(ref backend) => {
1010 match fo_type {
1011 "entity" => {
1012 if let Some(sid) = system_id {
1013 for expr in body_exprs {
1015 self.eval(expr, env.clone())?;
1016 }
1017
1018 let content = backend.borrow().current_output().to_string();
1020 backend.borrow_mut().entity(&sid, &content)
1021 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1022 backend.borrow_mut().clear_buffer();
1024 } else {
1025 return Err(EvalError::new(
1026 "make entity requires system-id: keyword".to_string(),
1027 ));
1028 }
1029 }
1030 "formatting-instruction" => {
1031 if let Some(d) = data {
1032 backend.borrow_mut().formatting_instruction(&d)
1034 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1035 } else {
1036 return Err(EvalError::new(
1037 "make formatting-instruction requires data: keyword".to_string(),
1038 ));
1039 }
1040 }
1041 "literal" => {
1042 if let Some(d) = data {
1045 backend.borrow_mut().formatting_instruction(&d)
1046 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1047 } else {
1048 return Err(EvalError::new(
1049 "make literal requires data: keyword or a string body".to_string(),
1050 ));
1051 }
1052 }
1053 "directory" => {
1054 if let Some(p) = path {
1055 let prev_dir = backend.borrow().current_directory().map(|s| s.to_string());
1057
1058 backend.borrow_mut().directory(&p)
1060 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1061
1062 for expr in body_exprs {
1065 self.eval(expr, env.clone())?;
1066 }
1067
1068 backend.borrow_mut().set_current_directory(prev_dir);
1070 } else {
1071 return Err(EvalError::new(
1072 "make directory requires path: keyword".to_string(),
1073 ));
1074 }
1075 }
1076 _ => {
1077 return Ok(Value::Unspecified);
1079 }
1080 }
1081 }
1082 None => {
1083 return Err(EvalError::new(
1084 "make: no backend available".to_string(),
1085 ));
1086 }
1087 }
1088
1089 Ok(Value::Unspecified)
1090 }
1091
1092 fn eval_set(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1094 let args_vec = self.list_to_vec(args)?;
1095 if args_vec.len() != 2 {
1096 return Err(EvalError::new(
1097 "set! requires exactly 2 arguments".to_string(),
1098 ));
1099 }
1100
1101 if let Value::Symbol(ref name) = args_vec[0] {
1102 let value = self.eval(args_vec[1].clone(), env.clone())?;
1103 env.set(name, value)
1104 .map_err(|e| EvalError::new(e))?;
1105 Ok(Value::Unspecified)
1106 } else {
1107 Err(EvalError::new(
1108 "First argument to set! must be a symbol".to_string(),
1109 ))
1110 }
1111 }
1112
1113 fn eval_lambda(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1115 let args_vec = self.list_to_vec(args)?;
1116 if args_vec.len() < 2 {
1117 return Err(EvalError::new(
1118 "lambda requires at least 2 arguments (params and body)".to_string(),
1119 ));
1120 }
1121
1122 let params_list = &args_vec[0];
1124 let params_vec = if params_list.is_nil() {
1125 Vec::new()
1127 } else {
1128 self.list_to_vec(params_list.clone())?
1129 };
1130
1131 let mut param_names = Vec::new();
1133 for param in params_vec {
1134 if let Value::Symbol(ref name) = param {
1135 param_names.push(name.to_string());
1136 } else {
1137 return Err(EvalError::new(format!(
1138 "Lambda parameter must be a symbol, got: {:?}",
1139 param
1140 )));
1141 }
1142 }
1143
1144 let body = if args_vec.len() == 2 {
1146 args_vec[1].clone()
1148 } else {
1149 let mut body_list = Value::Nil;
1151 for expr in args_vec[1..].iter().rev() {
1152 body_list = Value::cons(expr.clone(), body_list);
1153 }
1154 Value::cons(Value::symbol("begin"), body_list)
1155 };
1156
1157 let source_info = match (&self.current_source_file, &self.current_position) {
1160 (Some(file), Some(pos)) => {
1161 Some(SourceInfo::new(file.clone(), pos.clone()))
1163 }
1164 (Some(file), None) => {
1165 use crate::scheme::parser::Position;
1166 Some(SourceInfo::new(file.clone(), Position::new()))
1167 }
1168 _ => None,
1169 };
1170 Ok(Value::lambda_with_source(param_names, body, env, source_info, None))
1171 }
1172
1173 fn eval_let(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1175 let args_vec = self.list_to_vec(args)?;
1176 if args_vec.len() < 2 {
1177 return Err(EvalError::new(
1178 "let requires at least 2 arguments".to_string(),
1179 ));
1180 }
1181
1182 if let Value::Symbol(ref loop_name) = args_vec[0] {
1184 if args_vec.len() < 3 {
1185 return Err(EvalError::new(
1186 "named let requires at least 3 arguments".to_string(),
1187 ));
1188 }
1189
1190 let bindings_list = &args_vec[1];
1192 let bindings = self.list_to_vec(bindings_list.clone())?;
1193 let body = &args_vec[2..];
1194
1195 let mut var_names = Vec::new();
1197 let mut init_values = Vec::new();
1198 for binding in &bindings {
1199 let binding_vec = self.list_to_vec(binding.clone())?;
1200 if binding_vec.len() != 2 {
1201 return Err(EvalError::new(
1202 "named let binding must have exactly 2 elements".to_string(),
1203 ));
1204 }
1205 var_names.push(binding_vec[0].clone());
1206 init_values.push(binding_vec[1].clone());
1207 }
1208
1209 let lambda_params = self.vec_to_list(var_names);
1211 let mut lambda_body = vec![Value::symbol("lambda"), lambda_params];
1212 lambda_body.extend_from_slice(body);
1213 let lambda_expr = self.vec_to_list(lambda_body);
1214
1215 let letrec_binding = Value::cons(
1217 Value::symbol(loop_name),
1218 Value::cons(lambda_expr, Value::Nil),
1219 );
1220 let letrec_bindings = Value::cons(letrec_binding, Value::Nil);
1221
1222 let mut call_expr = vec![Value::symbol(loop_name)];
1224 call_expr.extend_from_slice(&init_values);
1225 let call = self.vec_to_list(call_expr);
1226
1227 return self.eval_letrec(self.vec_to_list(vec![letrec_bindings, call]), env);
1229 }
1230
1231 let bindings_list = &args_vec[0];
1233 let bindings = self.list_to_vec(bindings_list.clone())?;
1234
1235 let new_env = Environment::extend(env.clone());
1237
1238 for binding in bindings {
1240 let binding_vec = self.list_to_vec(binding)?;
1241 if binding_vec.len() != 2 {
1242 return Err(EvalError::new(
1243 "let binding must have exactly 2 elements".to_string(),
1244 ));
1245 }
1246
1247 if let Value::Symbol(ref name) = binding_vec[0] {
1248 let value = self.eval_inner(binding_vec[1].clone(), env.clone())?;
1249 new_env.define(name, value);
1250 } else {
1251 return Err(EvalError::new(
1252 "Binding variable must be a symbol".to_string(),
1253 ));
1254 }
1255 }
1256
1257 let body = &args_vec[1..];
1259 self.eval_sequence(body, new_env)
1260 }
1261
1262 fn eval_let_star(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1264 let args_vec = self.list_to_vec(args)?;
1265 if args_vec.len() < 2 {
1266 return Err(EvalError::new(
1267 "let* requires at least 2 arguments".to_string(),
1268 ));
1269 }
1270
1271 let bindings_list = &args_vec[0];
1273 let bindings = self.list_to_vec(bindings_list.clone())?;
1274
1275 let current_env = Environment::extend(env);
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(), current_env.clone())?;
1289 current_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, current_env)
1300 }
1301
1302 fn eval_letrec(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1312 let args_vec = self.list_to_vec(args)?;
1313 if args_vec.len() < 2 {
1314 return Err(EvalError::new(
1315 "letrec requires at least 2 arguments".to_string(),
1316 ));
1317 }
1318
1319 let bindings_list = &args_vec[0];
1321 let bindings = self.list_to_vec(bindings_list.clone())?;
1322
1323 let new_env = Environment::extend(env);
1325
1326 let mut var_names = Vec::new();
1328 for binding in &bindings {
1329 let binding_vec = self.list_to_vec(binding.clone())?;
1330 if binding_vec.len() != 2 {
1331 return Err(EvalError::new(
1332 "letrec binding must have exactly 2 elements".to_string(),
1333 ));
1334 }
1335
1336 if let Value::Symbol(ref name) = binding_vec[0] {
1337 var_names.push(name.to_string());
1338 new_env.define(name, Value::Unspecified);
1339 } else {
1340 return Err(EvalError::new(
1341 "Binding variable must be a symbol".to_string(),
1342 ));
1343 }
1344 }
1345
1346 for (i, binding) in bindings.iter().enumerate() {
1348 let binding_vec = self.list_to_vec(binding.clone())?;
1349 let value = self.eval_inner(binding_vec[1].clone(), new_env.clone())?;
1350
1351 new_env.set(&var_names[i], value)
1353 .map_err(|e| EvalError::new(e))?;
1354 }
1355
1356 let body = &args_vec[1..];
1358 self.eval_sequence(body, new_env)
1359 }
1360
1361 fn eval_begin(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1363 let args_vec = self.list_to_vec(args)?;
1364 self.eval_sequence(&args_vec, env)
1365 }
1366
1367 fn eval_cond(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1369 let clauses = self.list_to_vec(args)?;
1370
1371 for clause in clauses {
1372 let clause_vec = self.list_to_vec(clause)?;
1373 if clause_vec.is_empty() {
1374 return Err(EvalError::new("Empty cond clause".to_string()));
1375 }
1376
1377 if let Value::Symbol(ref sym) = clause_vec[0] {
1379 if &**sym == "else" {
1380 return self.eval_sequence(&clause_vec[1..], env);
1381 }
1382 }
1383
1384 let test = self.eval_inner(clause_vec[0].clone(), env.clone())?;
1386 if test.is_true() {
1387 if clause_vec.len() == 1 {
1388 return Ok(test);
1389 } else {
1390 return self.eval_sequence(&clause_vec[1..], env);
1391 }
1392 }
1393 }
1394
1395 Ok(Value::Unspecified)
1396 }
1397
1398 fn eval_case(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1412 let case_position = self.current_position.clone();
1415 let case_file = self.current_source_file.clone();
1416
1417 let args_vec = self.list_to_vec(args)?;
1418 if args_vec.is_empty() {
1419 return Err(EvalError::new("case requires at least 1 argument".to_string()));
1420 }
1421
1422 let key = self.eval_inner(args_vec[0].clone(), env.clone())?;
1424
1425 for clause in &args_vec[1..] {
1427 let clause_vec = self.list_to_vec(clause.clone())?;
1428 if clause_vec.is_empty() {
1429 return Err(EvalError::new("Empty case clause".to_string()));
1430 }
1431
1432 if let Value::Symbol(ref sym) = clause_vec[0] {
1434 if &**sym == "else" {
1435 return self.eval_sequence(&clause_vec[1..], env);
1436 }
1437 }
1438
1439 let datums = self.list_to_vec(clause_vec[0].clone())?;
1441
1442 for datum in datums {
1446 if key.equal(&datum) {
1447 if clause_vec.len() == 1 {
1449 return Ok(Value::Unspecified);
1451 } else {
1452 return self.eval_sequence(&clause_vec[1..], env);
1453 }
1454 }
1455 }
1456 }
1457
1458 self.current_position = case_position.clone();
1460 self.current_source_file = case_file;
1461 Err(self.error_with_stack(format!(
1462 "no clause in case expression matched {:?}",
1463 key
1464 )))
1465 }
1466
1467 fn eval_and(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1469 let args_vec = self.list_to_vec(args)?;
1470
1471 if args_vec.is_empty() {
1472 return Ok(Value::bool(true));
1473 }
1474
1475 let mut result = Value::bool(true);
1476 for expr in args_vec {
1477 result = self.eval_inner(expr, env.clone())?;
1478 if !result.is_true() {
1479 return Ok(Value::bool(false));
1480 }
1481 }
1482
1483 Ok(result)
1484 }
1485
1486 fn eval_or(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1488 let args_vec = self.list_to_vec(args)?;
1489
1490 for expr in args_vec {
1491 let result = self.eval_inner(expr, env.clone())?;
1492 if result.is_true() {
1493 return Ok(result);
1494 }
1495 }
1496
1497 Ok(Value::bool(false))
1498 }
1499
1500 fn eval_sequence(&mut self, exprs: &[Value], env: Gc<Environment>) -> EvalResult {
1502 if exprs.is_empty() {
1503 return Ok(Value::Unspecified);
1504 }
1505
1506 let mut result = Value::Unspecified;
1507 for expr in exprs {
1508 result = self.eval_inner(expr.clone(), env.clone())?;
1509 }
1510
1511 Ok(result)
1512 }
1513
1514 fn eval_apply(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1519 let args_vec = self.list_to_vec(args)?;
1520 if args_vec.len() != 2 {
1521 return Err(EvalError::new(
1522 "apply requires exactly 2 arguments".to_string(),
1523 ));
1524 }
1525
1526 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1528
1529 let arg_list = self.eval_inner(args_vec[1].clone(), env)?;
1531
1532 let arg_values = self.list_to_vec(arg_list)?;
1534
1535 self.apply(proc, arg_values)
1537 }
1538
1539 fn eval_map(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1553 let args_vec = self.list_to_vec(args)?;
1554 if args_vec.len() < 2 {
1555 return Err(EvalError::new("map requires at least 2 arguments".to_string()));
1556 }
1557
1558 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1560
1561 let mut lists = Vec::new();
1563 for i in 1..args_vec.len() {
1564 let list = self.eval_inner(args_vec[i].clone(), env.clone())?;
1565 let list_vec = self.list_to_vec(list)?;
1566 lists.push(list_vec);
1567 }
1568
1569 if lists.is_empty() {
1571 return Ok(Value::Nil);
1572 }
1573
1574 let length = lists[0].len();
1575 for list in &lists[1..] {
1576 if list.len() != length {
1577 return Err(EvalError::new(
1578 "map: all lists must have the same length".to_string(),
1579 ));
1580 }
1581 }
1582
1583 let mut result_vec = Vec::new();
1585 for i in 0..length {
1586 let mut proc_args = Vec::new();
1588 for list in &lists {
1589 proc_args.push(list[i].clone());
1590 }
1591
1592 let result = self.apply(proc.clone(), proc_args)?;
1594 result_vec.push(result);
1595 }
1596
1597 let mut result_list = Value::Nil;
1599 for elem in result_vec.into_iter().rev() {
1600 result_list = Value::cons(elem, result_list);
1601 }
1602
1603 Ok(result_list)
1604 }
1605
1606 fn eval_for_each(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1614 let args_vec = self.list_to_vec(args)?;
1615 if args_vec.len() < 2 {
1616 return Err(EvalError::new(
1617 "for-each requires at least 2 arguments".to_string(),
1618 ));
1619 }
1620
1621 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1623
1624 let mut lists = Vec::new();
1626 for i in 1..args_vec.len() {
1627 let list = self.eval_inner(args_vec[i].clone(), env.clone())?;
1628 let list_vec = self.list_to_vec(list)?;
1629 lists.push(list_vec);
1630 }
1631
1632 if lists.is_empty() {
1634 return Ok(Value::Unspecified);
1635 }
1636
1637 let length = lists[0].len();
1638 for list in &lists[1..] {
1639 if list.len() != length {
1640 return Err(EvalError::new(
1641 "for-each: all lists must have the same length".to_string(),
1642 ));
1643 }
1644 }
1645
1646 for i in 0..length {
1648 let mut proc_args = Vec::new();
1650 for list in &lists {
1651 proc_args.push(list[i].clone());
1652 }
1653
1654 self.apply(proc.clone(), proc_args)?;
1656 }
1657
1658 Ok(Value::Unspecified)
1659 }
1660
1661 fn eval_node_list_filter(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1668 let args_vec = self.list_to_vec(args)?;
1669 if args_vec.len() != 2 {
1670 return Err(EvalError::new("node-list-filter requires exactly 2 arguments".to_string()));
1671 }
1672
1673 let pred = self.eval_inner(args_vec[0].clone(), env.clone())?;
1675
1676 let node_list_val = self.eval_inner(args_vec[1].clone(), env.clone())?;
1678
1679 match node_list_val {
1680 Value::NodeList(ref nl) => {
1681 let mut filtered_nodes = Vec::new();
1682
1683 let mut index = 0;
1685 loop {
1686 if let Some(node) = nl.get(index) {
1687 let node_val = Value::node(node);
1689 let result = self.apply(pred.clone(), vec![node_val.clone()])?;
1690
1691 if !matches!(result, Value::Bool(false)) {
1693 if let Value::Node(n) = node_val {
1695 filtered_nodes.push(n.as_ref().clone_node());
1696 }
1697 }
1698
1699 index += 1;
1700 } else {
1701 break;
1702 }
1703 }
1704
1705 Ok(Value::node_list(Box::new(crate::grove::VecNodeList::new(filtered_nodes))))
1706 }
1707 _ => Err(EvalError::new(format!("node-list-filter: second argument not a node-list: {:?}", node_list_val))),
1708 }
1709 }
1710
1711 fn eval_node_list_map(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1721 let args_vec = self.list_to_vec(args)?;
1722 if args_vec.len() != 2 {
1723 return Err(EvalError::new("node-list-map requires exactly 2 arguments".to_string()));
1724 }
1725
1726 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1728
1729 let node_list_val = self.eval_inner(args_vec[1].clone(), env.clone())?;
1731
1732 let mut result_nodes: Vec<Box<dyn crate::grove::Node>> = Vec::new();
1734
1735 match node_list_val {
1736 Value::Node(ref n) => {
1737 let node_val = Value::node(n.as_ref().clone_node());
1739 let result = self.apply(proc, vec![node_val])?;
1740
1741 match result {
1744 Value::Node(n) => {
1745 result_nodes.push(n.as_ref().clone_node());
1747 }
1748 Value::NodeList(nl) => {
1749 let mut index = 0;
1751 while let Some(node) = nl.get(index) {
1752 result_nodes.push(node);
1753 index += 1;
1754 }
1755 }
1756 _ => {
1757 }
1760 }
1761 }
1762 Value::NodeList(ref nl) => {
1763 let mut index = 0;
1765 loop {
1766 if let Some(node) = nl.get(index) {
1767 let node_val = Value::node(node);
1769 let result = self.apply(proc.clone(), vec![node_val])?;
1770
1771 match result {
1773 Value::Node(n) => {
1774 result_nodes.push(n.as_ref().clone_node());
1776 index += 1;
1777 }
1778 Value::NodeList(nl_result) => {
1779 let mut nl_index = 0;
1781 while let Some(node) = nl_result.get(nl_index) {
1782 result_nodes.push(node);
1783 nl_index += 1;
1784 }
1785 index += 1;
1786 }
1787 _ => {
1788 break;
1790 }
1791 }
1792 } else {
1793 break;
1794 }
1795 }
1796 }
1797 _ => return Err(EvalError::new(format!("node-list-map: second argument must be a node or node-list: {:?}", node_list_val))),
1798 }
1799
1800 Ok(Value::node_list(Box::new(crate::grove::VecNodeList::new(result_nodes))))
1802 }
1803
1804 fn eval_node_list_some(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1810 let args_vec = self.list_to_vec(args)?;
1811 if args_vec.len() != 2 {
1812 return Err(EvalError::new("node-list-some? requires exactly 2 arguments".to_string()));
1813 }
1814
1815 let pred = self.eval_inner(args_vec[0].clone(), env.clone())?;
1817
1818 let node_list_val = self.eval_inner(args_vec[1].clone(), env.clone())?;
1820
1821 match node_list_val {
1822 Value::NodeList(ref nl) => {
1823 let mut index = 0;
1825 loop {
1826 if let Some(node) = nl.get(index) {
1827 let node_val = Value::node(node);
1829 let result = self.apply(pred.clone(), vec![node_val])?;
1830
1831 if !matches!(result, Value::Bool(false)) {
1833 return Ok(Value::bool(true));
1834 }
1835
1836 index += 1;
1837 } else {
1838 break;
1839 }
1840 }
1841
1842 Ok(Value::bool(false))
1844 }
1845 _ => Err(EvalError::new(format!("node-list-some?: second argument not a node-list: {:?}", node_list_val))),
1846 }
1847 }
1848
1849 fn eval_load(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1854 let args_vec = self.list_to_vec(args)?;
1855 if args_vec.len() != 1 {
1856 return Err(EvalError::new(
1857 "load requires exactly 1 argument".to_string(),
1858 ));
1859 }
1860
1861 let filename_val = self.eval_inner(args_vec[0].clone(), env.clone())?;
1863
1864 let filename = match filename_val {
1865 Value::String(s) => s.to_string(),
1866 _ => return Err(EvalError::new(
1867 format!("load: filename must be a string, got {:?}", filename_val)
1868 )),
1869 };
1870
1871 let contents = std::fs::read_to_string(&filename)
1873 .map_err(|e| EvalError::new(format!("load: cannot read file '{}': {}", filename, e)))?;
1874
1875 let mut parser = crate::scheme::parser::Parser::new(&contents);
1877 let mut result = Value::Unspecified;
1878
1879 let prev_source_file = self.current_source_file.clone();
1881 let prev_position = self.current_position.clone();
1882 self.current_source_file = Some(filename.clone());
1883
1884 let eval_result = loop {
1886 let pos = parser.current_position();
1888
1889 match parser.parse() {
1890 Ok(expr) => {
1891 self.current_position = Some(pos);
1893
1894 match self.eval_inner(expr, env.clone()) {
1895 Ok(val) => result = val,
1896 Err(e) => break Err(e),
1897 }
1898 }
1899 Err(e) => {
1900 let error_msg = e.to_string();
1902 if error_msg.contains("Unexpected end of input")
1903 || error_msg.contains("Expected")
1904 || error_msg.contains("EOF") {
1905 break Ok(result);
1906 }
1907 break Err(EvalError::new(
1908 format!("load: parse error in '{}': {}", filename, e)
1909 ));
1910 }
1911 }
1912 };
1913
1914 self.current_source_file = prev_source_file;
1916 self.current_position = prev_position;
1917
1918 eval_result
1919 }
1920
1921 fn eval_application(
1927 &mut self,
1928 operator: Value,
1929 args: Value,
1930 env: Gc<Environment>,
1931 ) -> EvalResult {
1932 let application_pos = self.current_position.clone();
1934 let application_file = self.current_source_file.clone();
1935
1936 let proc = self.eval_inner(operator, env.clone())?;
1938
1939 let args_vec = self.list_to_vec(args)?;
1941 let mut evaled_args = Vec::new();
1942 for arg in args_vec {
1943 if let Value::Pair(ref p) = arg {
1945 if let Some(ref pos) = p.borrow().pos {
1946 self.current_position = Some(pos.clone());
1947 }
1948 }
1949 evaled_args.push(self.eval_inner(arg, env.clone())?);
1950 }
1951
1952 self.current_position = application_pos;
1955 self.current_source_file = application_file;
1956
1957 self.apply(proc, evaled_args)
1959 }
1960
1961 fn apply(&mut self, proc: Value, args: Vec<Value>) -> EvalResult {
1963 if let Value::Procedure(ref p) = proc {
1964 match &**p {
1965 Procedure::Primitive { name, func } => {
1966 func(&args).map_err(|e| self.error_with_stack(e))
1969 }
1970 Procedure::Lambda { params, body, env, source, name } => {
1971 if args.len() != params.len() {
1973 return Err(self.error_with_stack(format!(
1974 "Lambda expects {} arguments, got {}",
1975 params.len(),
1976 args.len()
1977 )));
1978 }
1979
1980 let saved_file = self.current_source_file.clone();
1982 let saved_pos = self.current_position.clone();
1983
1984 let pushed_frame = if let Some(func_name) = name.clone() {
1987 let call_site = match (&saved_file, &saved_pos) {
1988 (Some(file), Some(pos)) => Some(SourceInfo {
1989 file: file.clone(),
1990 pos: pos.clone(),
1991 }),
1992 _ => None,
1993 };
1994 self.push_call_frame(func_name, call_site);
1995 true
1996 } else {
1997 false
1998 };
1999
2000 if let Some(ref src) = source {
2002 self.current_source_file = Some(src.file.clone());
2003 self.current_position = Some(src.pos.clone());
2004 }
2005
2006 let lambda_env = Environment::extend(env.clone());
2008
2009 for (param_name, arg_value) in params.iter().zip(args.iter()) {
2011 lambda_env.define(param_name, arg_value.clone());
2012 }
2013
2014 let result = self.eval_inner((**body).clone(), lambda_env);
2016
2017 self.current_source_file = saved_file;
2019 self.current_position = saved_pos;
2020
2021 if pushed_frame {
2023 self.pop_call_frame();
2024 }
2025
2026 result
2027 }
2028 }
2029 } else {
2030 Err(self.error_with_stack(format!(
2031 "Not a procedure: {:?}",
2032 proc
2033 )))
2034 }
2035 }
2036}
2037
2038impl Default for Evaluator {
2039 fn default() -> Self {
2040 Self::new()
2041 }
2042}
2043
2044#[cfg(test)]
2049mod tests {
2050 use super::*;
2051
2052 fn make_env() -> Gc<Environment> {
2053 Environment::new_global()
2054 }
2055
2056 #[test]
2057 fn test_eval_self_evaluating() {
2058 let mut eval = Evaluator::new();
2059 let env = make_env();
2060
2061 assert!(eval.eval(Value::integer(42), env.clone()).unwrap().is_integer());
2062 assert!(eval.eval(Value::bool(true), env.clone()).unwrap().is_bool());
2063 assert!(eval.eval(Value::string("hello".to_string()), env).unwrap().is_string());
2064 }
2065
2066 #[test]
2067 fn test_eval_quote() {
2068 let mut eval = Evaluator::new();
2069 let env = make_env();
2070
2071 let expr = Value::cons(
2073 Value::symbol("quote"),
2074 Value::cons(
2075 Value::cons(
2076 Value::integer(1),
2077 Value::cons(Value::integer(2), Value::cons(Value::integer(3), Value::Nil)),
2078 ),
2079 Value::Nil,
2080 ),
2081 );
2082
2083 let result = eval.eval(expr, env).unwrap();
2084 assert!(result.is_list());
2085 }
2086
2087 #[test]
2088 fn test_eval_if_true() {
2089 let mut eval = Evaluator::new();
2090 let env = make_env();
2091
2092 let expr = Value::cons(
2094 Value::symbol("if"),
2095 Value::cons(
2096 Value::bool(true),
2097 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2098 ),
2099 );
2100
2101 let result = eval.eval(expr, env).unwrap();
2102 if let Value::Integer(n) = result {
2103 assert_eq!(n, 1);
2104 } else {
2105 panic!("Expected integer 1");
2106 }
2107 }
2108
2109 #[test]
2110 fn test_eval_if_false() {
2111 let mut eval = Evaluator::new();
2112 let env = make_env();
2113
2114 let expr = Value::cons(
2116 Value::symbol("if"),
2117 Value::cons(
2118 Value::bool(false),
2119 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2120 ),
2121 );
2122
2123 let result = eval.eval(expr, env).unwrap();
2124 if let Value::Integer(n) = result {
2125 assert_eq!(n, 2);
2126 } else {
2127 panic!("Expected integer 2");
2128 }
2129 }
2130
2131 #[test]
2132 fn test_eval_define() {
2133 let mut eval = Evaluator::new();
2134 let env = make_env();
2135
2136 let expr = Value::cons(
2138 Value::symbol("define"),
2139 Value::cons(Value::symbol("x"), Value::cons(Value::integer(42), Value::Nil)),
2140 );
2141
2142 eval.eval(expr, env.clone()).unwrap();
2143
2144 assert!(env.is_defined("x"));
2146 if let Value::Integer(n) = env.lookup("x").unwrap() {
2147 assert_eq!(n, 42);
2148 }
2149 }
2150
2151 #[test]
2152 fn test_eval_symbol_lookup() {
2153 let mut eval = Evaluator::new();
2154 let env = make_env();
2155
2156 env.define("x", Value::integer(99));
2157
2158 let result = eval.eval(Value::symbol("x"), env).unwrap();
2159 if let Value::Integer(n) = result {
2160 assert_eq!(n, 99);
2161 } else {
2162 panic!("Expected integer 99");
2163 }
2164 }
2165
2166 #[test]
2167 fn test_eval_and() {
2168 let mut eval = Evaluator::new();
2169 let env = make_env();
2170
2171 let expr = Value::cons(
2173 Value::symbol("and"),
2174 Value::cons(Value::bool(true), Value::cons(Value::bool(true), Value::Nil)),
2175 );
2176
2177 let result = eval.eval(expr, env.clone()).unwrap();
2178 assert!(result.is_true());
2179
2180 let expr = Value::cons(
2182 Value::symbol("and"),
2183 Value::cons(Value::bool(true), Value::cons(Value::bool(false), Value::Nil)),
2184 );
2185
2186 let result = eval.eval(expr, env).unwrap();
2187 assert!(!result.is_true());
2188 }
2189
2190 #[test]
2191 fn test_eval_or() {
2192 let mut eval = Evaluator::new();
2193 let env = make_env();
2194
2195 let expr = Value::cons(
2197 Value::symbol("or"),
2198 Value::cons(Value::bool(false), Value::cons(Value::bool(true), Value::Nil)),
2199 );
2200
2201 let result = eval.eval(expr, env.clone()).unwrap();
2202 assert!(result.is_true());
2203
2204 let expr = Value::cons(
2206 Value::symbol("or"),
2207 Value::cons(Value::bool(false), Value::cons(Value::bool(false), Value::Nil)),
2208 );
2209
2210 let result = eval.eval(expr, env).unwrap();
2211 assert!(!result.is_true());
2212 }
2213
2214 #[test]
2215 fn test_eval_lambda_creation() {
2216 let mut eval = Evaluator::new();
2217 let env = make_env();
2218
2219 let expr = Value::cons(
2221 Value::symbol("lambda"),
2222 Value::cons(
2223 Value::cons(Value::symbol("x"), Value::Nil),
2224 Value::cons(Value::symbol("x"), Value::Nil),
2225 ),
2226 );
2227
2228 let result = eval.eval(expr, env).unwrap();
2229 assert!(result.is_procedure());
2230 }
2231
2232 #[test]
2233 fn test_eval_lambda_application() {
2234 let mut eval = Evaluator::new();
2235 let env = make_env();
2236
2237 let lambda_expr = Value::cons(
2239 Value::symbol("lambda"),
2240 Value::cons(
2241 Value::cons(Value::symbol("x"), Value::Nil),
2242 Value::cons(Value::symbol("x"), Value::Nil),
2243 ),
2244 );
2245
2246 let app_expr = Value::cons(lambda_expr, Value::cons(Value::integer(42), Value::Nil));
2247
2248 let result = eval.eval(app_expr, env).unwrap();
2249 if let Value::Integer(n) = result {
2250 assert_eq!(n, 42);
2251 } else {
2252 panic!("Expected integer 42");
2253 }
2254 }
2255
2256 #[test]
2257 fn test_eval_lambda_multiple_params() {
2258 let mut eval = Evaluator::new();
2259 let env = make_env();
2260
2261 let params = Value::cons(Value::symbol("x"), Value::cons(Value::symbol("y"), Value::Nil));
2263 let body = Value::symbol("x");
2264
2265 let lambda_expr = Value::cons(Value::symbol("lambda"), Value::cons(params, Value::cons(body, Value::Nil)));
2266
2267 let app_expr = Value::cons(
2268 lambda_expr,
2269 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2270 );
2271
2272 let result = eval.eval(app_expr, env).unwrap();
2273 if let Value::Integer(n) = result {
2274 assert_eq!(n, 1);
2275 } else {
2276 panic!("Expected integer 1");
2277 }
2278 }
2279
2280 #[test]
2281 fn test_eval_lambda_wrong_arg_count() {
2282 let mut eval = Evaluator::new();
2283 let env = make_env();
2284
2285 let lambda_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 app_expr = Value::cons(
2295 lambda_expr,
2296 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2297 );
2298
2299 let result = eval.eval(app_expr, env);
2300 assert!(result.is_err());
2301 }
2302
2303 #[test]
2304 fn test_eval_lambda_closure() {
2305 let mut eval = Evaluator::new();
2306 let env = make_env();
2307
2308 env.define("x", Value::integer(10));
2310
2311 let lambda_expr = Value::cons(
2314 Value::symbol("lambda"),
2315 Value::cons(
2316 Value::cons(Value::symbol("y"), Value::Nil),
2317 Value::cons(Value::symbol("x"), Value::Nil),
2318 ),
2319 );
2320
2321 let app_expr = Value::cons(lambda_expr, Value::cons(Value::integer(20), Value::Nil));
2322
2323 let result = eval.eval(app_expr, env).unwrap();
2324 if let Value::Integer(n) = result {
2325 assert_eq!(n, 10); } else {
2327 panic!("Expected integer 10 from closure");
2328 }
2329 }
2330
2331 #[test]
2332 fn test_eval_lambda_no_params() {
2333 let mut eval = Evaluator::new();
2334 let env = make_env();
2335
2336 let lambda_expr = Value::cons(
2338 Value::symbol("lambda"),
2339 Value::cons(Value::Nil, Value::cons(Value::integer(42), Value::Nil)),
2340 );
2341
2342 let app_expr = Value::cons(lambda_expr, Value::Nil);
2343
2344 let result = eval.eval(app_expr, env).unwrap();
2345 if let Value::Integer(n) = result {
2346 assert_eq!(n, 42);
2347 } else {
2348 panic!("Expected integer 42");
2349 }
2350 }
2351
2352 #[test]
2353 fn test_eval_lambda_multiple_body_expressions() {
2354 let mut eval = Evaluator::new();
2355 let env = make_env();
2356
2357 let params = Value::cons(Value::symbol("x"), Value::Nil);
2360 let body1 = Value::integer(1);
2361 let body2 = Value::integer(2);
2362 let body3 = Value::symbol("x");
2363
2364 let lambda_expr = Value::cons(
2365 Value::symbol("lambda"),
2366 Value::cons(
2367 params,
2368 Value::cons(body1, Value::cons(body2, Value::cons(body3, Value::Nil))),
2369 ),
2370 );
2371
2372 let app_expr = Value::cons(lambda_expr, Value::cons(Value::integer(99), Value::Nil));
2373
2374 let result = eval.eval(app_expr, env).unwrap();
2375 if let Value::Integer(n) = result {
2376 assert_eq!(n, 99);
2377 } else {
2378 panic!("Expected integer 99");
2379 }
2380 }
2381}