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(self.error_with_stack(
878 "element requires at least 2 arguments (element-name and construction-expression)".to_string(),
879 ));
880 }
881
882 if args_vec.len() > 2 {
883 return Err(self.error_with_stack(
884 "element construction rule can only contain one sosofo expression\nTo combine multiple sosofos, use (sosofo-append ...)".to_string(),
885 ));
886 }
887
888 let element_name = if let Value::Symbol(ref name) = args_vec[0] {
890 name.clone()
891 } else {
892 return Err(self.error_with_stack(
893 "First argument to element must be a symbol".to_string(),
894 ));
895 };
896
897 self.processing_mode.add_rule(
901 element_name.to_string(),
902 args_vec[1].clone(),
903 self.current_source_file.clone(),
904 self.current_position.clone()
905 );
906
907 Ok(Value::Unspecified)
908 }
909
910 fn eval_default(&mut self, args: Value, _env: Gc<Environment>) -> EvalResult {
916 let args_vec = self.list_to_vec(args)?;
917
918 if args_vec.is_empty() {
919 return Err(self.error_with_stack(
920 "default requires at least 1 argument (construction-expression)".to_string(),
921 ));
922 }
923
924 if args_vec.len() > 1 {
925 return Err(self.error_with_stack(
926 "default construction rule can only contain one sosofo expression\nTo combine multiple sosofos, use (sosofo-append ...)".to_string(),
927 ));
928 }
929
930 self.processing_mode.add_default_rule(args_vec[0].clone());
932
933 Ok(Value::Unspecified)
934 }
935
936 fn eval_process_children(&mut self, env: Gc<Environment>) -> EvalResult {
942 let current_node = match &self.current_node {
944 Some(node) => node.clone(),
945 None => return Err(EvalError::new("No current node".to_string())),
946 };
947
948 let mut children = current_node.children();
950
951 let mut result = Value::Unspecified;
953 while !children.is_empty() {
954 if let Some(child_node) = children.first() {
956 let saved_node = self.current_node.clone();
958
959 self.current_node = Some(Rc::new(child_node));
961
962 result = self.process_node(env.clone())?;
964
965 self.current_node = saved_node;
967 }
968
969 children = children.rest();
971 }
972
973 Ok(result)
974 }
975
976 fn eval_make(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
982 let args_vec = self.list_to_vec(args)?;
983
984 if args_vec.is_empty() {
985 return Err(EvalError::new(
986 "make requires at least a flow object type".to_string(),
987 ));
988 }
989
990 let fo_type = match &args_vec[0] {
992 Value::Symbol(s) => s.as_ref(),
993 _ => return Err(EvalError::new(
994 "make: first argument must be a flow object type symbol".to_string(),
995 )),
996 };
997
998 let mut i = 1;
1000 let mut system_id = None;
1001 let mut data = None;
1002 let mut path = None;
1003 let mut body_exprs = Vec::new();
1004
1005 while i < args_vec.len() {
1006 match &args_vec[i] {
1007 Value::Keyword(kw) => {
1008 if i + 1 >= args_vec.len() {
1010 return Err(EvalError::new(
1011 format!("make: keyword {} requires a value", kw),
1012 ));
1013 }
1014 let value = self.eval(args_vec[i + 1].clone(), env.clone())?;
1015
1016 match kw.as_ref() {
1017 "system-id" => {
1018 if let Value::String(s) = value {
1019 system_id = Some(s);
1020 } else {
1021 return Err(EvalError::new(
1022 "make: system-id must be a string".to_string(),
1023 ));
1024 }
1025 }
1026 "data" => {
1027 if let Value::String(s) = value {
1028 data = Some(s);
1029 } else {
1030 return Err(EvalError::new(
1031 "make: data must be a string".to_string(),
1032 ));
1033 }
1034 }
1035 "path" => {
1036 if let Value::String(s) = value {
1037 path = Some(s);
1038 } else {
1039 return Err(EvalError::new(
1040 "make: path must be a string".to_string(),
1041 ));
1042 }
1043 }
1044 _ => {
1045 }
1047 }
1048 i += 2;
1049 }
1050 _ => {
1051 body_exprs.push(args_vec[i].clone());
1053 i += 1;
1054 }
1055 }
1056 }
1057
1058 let backend = self.backend.clone();
1060 match backend {
1061 Some(ref backend) => {
1062 match fo_type {
1063 "entity" => {
1064 if let Some(sid) = system_id {
1065 for expr in body_exprs {
1067 self.eval(expr, env.clone())?;
1068 }
1069
1070 let content = backend.borrow().current_output().to_string();
1072 backend.borrow_mut().entity(&sid, &content)
1073 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1074 backend.borrow_mut().clear_buffer();
1076 } else {
1077 return Err(EvalError::new(
1078 "make entity requires system-id: keyword".to_string(),
1079 ));
1080 }
1081 }
1082 "formatting-instruction" => {
1083 if let Some(d) = data {
1084 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 formatting-instruction requires data: keyword".to_string(),
1090 ));
1091 }
1092 }
1093 "literal" => {
1094 if let Some(d) = data {
1097 backend.borrow_mut().formatting_instruction(&d)
1098 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1099 } else {
1100 return Err(EvalError::new(
1101 "make literal requires data: keyword or a string body".to_string(),
1102 ));
1103 }
1104 }
1105 "directory" => {
1106 if let Some(p) = path {
1107 let prev_dir = backend.borrow().current_directory().map(|s| s.to_string());
1109
1110 backend.borrow_mut().directory(&p)
1112 .map_err(|e| EvalError::new(format!("Backend error: {}", e)))?;
1113
1114 for expr in body_exprs {
1117 self.eval(expr, env.clone())?;
1118 }
1119
1120 backend.borrow_mut().set_current_directory(prev_dir);
1122 } else {
1123 return Err(EvalError::new(
1124 "make directory requires path: keyword".to_string(),
1125 ));
1126 }
1127 }
1128 _ => {
1129 return Ok(Value::Unspecified);
1131 }
1132 }
1133 }
1134 None => {
1135 return Err(EvalError::new(
1136 "make: no backend available".to_string(),
1137 ));
1138 }
1139 }
1140
1141 Ok(Value::Unspecified)
1142 }
1143
1144 fn eval_set(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1146 let args_vec = self.list_to_vec(args)?;
1147 if args_vec.len() != 2 {
1148 return Err(EvalError::new(
1149 "set! requires exactly 2 arguments".to_string(),
1150 ));
1151 }
1152
1153 if let Value::Symbol(ref name) = args_vec[0] {
1154 let value = self.eval(args_vec[1].clone(), env.clone())?;
1155 env.set(name, value)
1156 .map_err(|e| EvalError::new(e))?;
1157 Ok(Value::Unspecified)
1158 } else {
1159 Err(EvalError::new(
1160 "First argument to set! must be a symbol".to_string(),
1161 ))
1162 }
1163 }
1164
1165 fn eval_lambda(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1167 let args_vec = self.list_to_vec(args)?;
1168 if args_vec.len() < 2 {
1169 return Err(EvalError::new(
1170 "lambda requires at least 2 arguments (params and body)".to_string(),
1171 ));
1172 }
1173
1174 let params_list = &args_vec[0];
1176 let params_vec = if params_list.is_nil() {
1177 Vec::new()
1179 } else {
1180 self.list_to_vec(params_list.clone())?
1181 };
1182
1183 let mut param_names = Vec::new();
1185 for param in params_vec {
1186 if let Value::Symbol(ref name) = param {
1187 param_names.push(name.to_string());
1188 } else {
1189 return Err(EvalError::new(format!(
1190 "Lambda parameter must be a symbol, got: {:?}",
1191 param
1192 )));
1193 }
1194 }
1195
1196 let body = if args_vec.len() == 2 {
1198 args_vec[1].clone()
1200 } else {
1201 let mut body_list = Value::Nil;
1203 for expr in args_vec[1..].iter().rev() {
1204 body_list = Value::cons(expr.clone(), body_list);
1205 }
1206 Value::cons(Value::symbol("begin"), body_list)
1207 };
1208
1209 let source_info = match (&self.current_source_file, &self.current_position) {
1212 (Some(file), Some(pos)) => {
1213 Some(SourceInfo::new(file.clone(), pos.clone()))
1215 }
1216 (Some(file), None) => {
1217 use crate::scheme::parser::Position;
1218 Some(SourceInfo::new(file.clone(), Position::new()))
1219 }
1220 _ => None,
1221 };
1222 Ok(Value::lambda_with_source(param_names, body, env, source_info, None))
1223 }
1224
1225 fn eval_let(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1227 let args_vec = self.list_to_vec(args)?;
1228 if args_vec.len() < 2 {
1229 return Err(EvalError::new(
1230 "let requires at least 2 arguments".to_string(),
1231 ));
1232 }
1233
1234 if let Value::Symbol(ref loop_name) = args_vec[0] {
1236 if args_vec.len() < 3 {
1237 return Err(EvalError::new(
1238 "named let requires at least 3 arguments".to_string(),
1239 ));
1240 }
1241
1242 let bindings_list = &args_vec[1];
1244 let bindings = self.list_to_vec(bindings_list.clone())?;
1245 let body = &args_vec[2..];
1246
1247 let mut var_names = Vec::new();
1249 let mut init_values = Vec::new();
1250 for binding in &bindings {
1251 let binding_vec = self.list_to_vec(binding.clone())?;
1252 if binding_vec.len() != 2 {
1253 return Err(EvalError::new(
1254 "named let binding must have exactly 2 elements".to_string(),
1255 ));
1256 }
1257 var_names.push(binding_vec[0].clone());
1258 init_values.push(binding_vec[1].clone());
1259 }
1260
1261 let lambda_params = self.vec_to_list(var_names);
1263 let mut lambda_body = vec![Value::symbol("lambda"), lambda_params];
1264 lambda_body.extend_from_slice(body);
1265 let lambda_expr = self.vec_to_list(lambda_body);
1266
1267 let letrec_binding = Value::cons(
1269 Value::symbol(loop_name),
1270 Value::cons(lambda_expr, Value::Nil),
1271 );
1272 let letrec_bindings = Value::cons(letrec_binding, Value::Nil);
1273
1274 let mut call_expr = vec![Value::symbol(loop_name)];
1276 call_expr.extend_from_slice(&init_values);
1277 let call = self.vec_to_list(call_expr);
1278
1279 return self.eval_letrec(self.vec_to_list(vec![letrec_bindings, call]), env);
1281 }
1282
1283 let bindings_list = &args_vec[0];
1285 let bindings = self.list_to_vec(bindings_list.clone())?;
1286
1287 let new_env = Environment::extend(env.clone());
1289
1290 for binding in bindings {
1292 let binding_vec = self.list_to_vec(binding)?;
1293 if binding_vec.len() != 2 {
1294 return Err(EvalError::new(
1295 "let binding must have exactly 2 elements".to_string(),
1296 ));
1297 }
1298
1299 if let Value::Symbol(ref name) = binding_vec[0] {
1300 let value = self.eval_inner(binding_vec[1].clone(), env.clone())?;
1301 new_env.define(name, value);
1302 } else {
1303 return Err(EvalError::new(
1304 "Binding variable must be a symbol".to_string(),
1305 ));
1306 }
1307 }
1308
1309 let body = &args_vec[1..];
1311 self.eval_sequence(body, new_env)
1312 }
1313
1314 fn eval_let_star(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1316 let args_vec = self.list_to_vec(args)?;
1317 if args_vec.len() < 2 {
1318 return Err(EvalError::new(
1319 "let* requires at least 2 arguments".to_string(),
1320 ));
1321 }
1322
1323 let bindings_list = &args_vec[0];
1325 let bindings = self.list_to_vec(bindings_list.clone())?;
1326
1327 let current_env = Environment::extend(env);
1329
1330 for binding in bindings {
1332 let binding_vec = self.list_to_vec(binding)?;
1333 if binding_vec.len() != 2 {
1334 return Err(EvalError::new(
1335 "let* binding must have exactly 2 elements".to_string(),
1336 ));
1337 }
1338
1339 if let Value::Symbol(ref name) = binding_vec[0] {
1340 let value = self.eval_inner(binding_vec[1].clone(), current_env.clone())?;
1341 current_env.define(name, value);
1342 } else {
1343 return Err(EvalError::new(
1344 "Binding variable must be a symbol".to_string(),
1345 ));
1346 }
1347 }
1348
1349 let body = &args_vec[1..];
1351 self.eval_sequence(body, current_env)
1352 }
1353
1354 fn eval_letrec(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1364 let args_vec = self.list_to_vec(args)?;
1365 if args_vec.len() < 2 {
1366 return Err(EvalError::new(
1367 "letrec requires at least 2 arguments".to_string(),
1368 ));
1369 }
1370
1371 let bindings_list = &args_vec[0];
1373 let bindings = self.list_to_vec(bindings_list.clone())?;
1374
1375 let new_env = Environment::extend(env);
1377
1378 let mut var_names = Vec::new();
1380 for binding in &bindings {
1381 let binding_vec = self.list_to_vec(binding.clone())?;
1382 if binding_vec.len() != 2 {
1383 return Err(EvalError::new(
1384 "letrec binding must have exactly 2 elements".to_string(),
1385 ));
1386 }
1387
1388 if let Value::Symbol(ref name) = binding_vec[0] {
1389 var_names.push(name.to_string());
1390 new_env.define(name, Value::Unspecified);
1391 } else {
1392 return Err(EvalError::new(
1393 "Binding variable must be a symbol".to_string(),
1394 ));
1395 }
1396 }
1397
1398 for (i, binding) in bindings.iter().enumerate() {
1400 let binding_vec = self.list_to_vec(binding.clone())?;
1401 let value = self.eval_inner(binding_vec[1].clone(), new_env.clone())?;
1402
1403 new_env.set(&var_names[i], value)
1405 .map_err(|e| EvalError::new(e))?;
1406 }
1407
1408 let body = &args_vec[1..];
1410 self.eval_sequence(body, new_env)
1411 }
1412
1413 fn eval_begin(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1415 let args_vec = self.list_to_vec(args)?;
1416 self.eval_sequence(&args_vec, env)
1417 }
1418
1419 fn eval_cond(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1421 let clauses = self.list_to_vec(args)?;
1422
1423 for clause in clauses {
1424 let clause_vec = self.list_to_vec(clause)?;
1425 if clause_vec.is_empty() {
1426 return Err(EvalError::new("Empty cond clause".to_string()));
1427 }
1428
1429 if let Value::Symbol(ref sym) = clause_vec[0] {
1431 if &**sym == "else" {
1432 return self.eval_sequence(&clause_vec[1..], env);
1433 }
1434 }
1435
1436 let test = self.eval_inner(clause_vec[0].clone(), env.clone())?;
1438 if test.is_true() {
1439 if clause_vec.len() == 1 {
1440 return Ok(test);
1441 } else {
1442 return self.eval_sequence(&clause_vec[1..], env);
1443 }
1444 }
1445 }
1446
1447 Ok(Value::Unspecified)
1448 }
1449
1450 fn eval_case(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1464 let case_position = self.current_position.clone();
1467 let case_file = self.current_source_file.clone();
1468
1469 let args_vec = self.list_to_vec(args)?;
1470 if args_vec.is_empty() {
1471 return Err(EvalError::new("case requires at least 1 argument".to_string()));
1472 }
1473
1474 let key = self.eval_inner(args_vec[0].clone(), env.clone())?;
1476
1477 for clause in &args_vec[1..] {
1479 let clause_vec = self.list_to_vec(clause.clone())?;
1480 if clause_vec.is_empty() {
1481 return Err(EvalError::new("Empty case clause".to_string()));
1482 }
1483
1484 if let Value::Symbol(ref sym) = clause_vec[0] {
1486 if &**sym == "else" {
1487 return self.eval_sequence(&clause_vec[1..], env);
1488 }
1489 }
1490
1491 let datums = self.list_to_vec(clause_vec[0].clone())?;
1493
1494 for datum in datums {
1498 if key.equal(&datum) {
1499 if clause_vec.len() == 1 {
1501 return Ok(Value::Unspecified);
1503 } else {
1504 return self.eval_sequence(&clause_vec[1..], env);
1505 }
1506 }
1507 }
1508 }
1509
1510 self.current_position = case_position.clone();
1512 self.current_source_file = case_file;
1513 Err(self.error_with_stack(format!(
1514 "no clause in case expression matched {:?}",
1515 key
1516 )))
1517 }
1518
1519 fn eval_and(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1521 let args_vec = self.list_to_vec(args)?;
1522
1523 if args_vec.is_empty() {
1524 return Ok(Value::bool(true));
1525 }
1526
1527 let mut result = Value::bool(true);
1528 for expr in args_vec {
1529 result = self.eval_inner(expr, env.clone())?;
1530 if !result.is_true() {
1531 return Ok(Value::bool(false));
1532 }
1533 }
1534
1535 Ok(result)
1536 }
1537
1538 fn eval_or(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1540 let args_vec = self.list_to_vec(args)?;
1541
1542 for expr in args_vec {
1543 let result = self.eval_inner(expr, env.clone())?;
1544 if result.is_true() {
1545 return Ok(result);
1546 }
1547 }
1548
1549 Ok(Value::bool(false))
1550 }
1551
1552 fn eval_sequence(&mut self, exprs: &[Value], env: Gc<Environment>) -> EvalResult {
1554 if exprs.is_empty() {
1555 return Ok(Value::Unspecified);
1556 }
1557
1558 let mut result = Value::Unspecified;
1559 for expr in exprs {
1560 result = self.eval_inner(expr.clone(), env.clone())?;
1561 }
1562
1563 Ok(result)
1564 }
1565
1566 fn eval_apply(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1571 let args_vec = self.list_to_vec(args)?;
1572 if args_vec.len() != 2 {
1573 return Err(EvalError::new(
1574 "apply requires exactly 2 arguments".to_string(),
1575 ));
1576 }
1577
1578 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1580
1581 let arg_list = self.eval_inner(args_vec[1].clone(), env)?;
1583
1584 let arg_values = self.list_to_vec(arg_list)?;
1586
1587 self.apply(proc, arg_values)
1589 }
1590
1591 fn eval_map(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1605 let args_vec = self.list_to_vec(args)?;
1606 if args_vec.len() < 2 {
1607 return Err(EvalError::new("map requires at least 2 arguments".to_string()));
1608 }
1609
1610 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1612
1613 let mut lists = Vec::new();
1615 for i in 1..args_vec.len() {
1616 let list = self.eval_inner(args_vec[i].clone(), env.clone())?;
1617 let list_vec = self.list_to_vec(list)?;
1618 lists.push(list_vec);
1619 }
1620
1621 if lists.is_empty() {
1623 return Ok(Value::Nil);
1624 }
1625
1626 let length = lists[0].len();
1627 for list in &lists[1..] {
1628 if list.len() != length {
1629 return Err(EvalError::new(
1630 "map: all lists must have the same length".to_string(),
1631 ));
1632 }
1633 }
1634
1635 let mut result_vec = Vec::new();
1637 for i in 0..length {
1638 let mut proc_args = Vec::new();
1640 for list in &lists {
1641 proc_args.push(list[i].clone());
1642 }
1643
1644 let result = self.apply(proc.clone(), proc_args)?;
1646 result_vec.push(result);
1647 }
1648
1649 let mut result_list = Value::Nil;
1651 for elem in result_vec.into_iter().rev() {
1652 result_list = Value::cons(elem, result_list);
1653 }
1654
1655 Ok(result_list)
1656 }
1657
1658 fn eval_for_each(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1666 let args_vec = self.list_to_vec(args)?;
1667 if args_vec.len() < 2 {
1668 return Err(EvalError::new(
1669 "for-each requires at least 2 arguments".to_string(),
1670 ));
1671 }
1672
1673 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1675
1676 let mut lists = Vec::new();
1678 for i in 1..args_vec.len() {
1679 let list = self.eval_inner(args_vec[i].clone(), env.clone())?;
1680 let list_vec = self.list_to_vec(list)?;
1681 lists.push(list_vec);
1682 }
1683
1684 if lists.is_empty() {
1686 return Ok(Value::Unspecified);
1687 }
1688
1689 let length = lists[0].len();
1690 for list in &lists[1..] {
1691 if list.len() != length {
1692 return Err(EvalError::new(
1693 "for-each: all lists must have the same length".to_string(),
1694 ));
1695 }
1696 }
1697
1698 for i in 0..length {
1700 let mut proc_args = Vec::new();
1702 for list in &lists {
1703 proc_args.push(list[i].clone());
1704 }
1705
1706 self.apply(proc.clone(), proc_args)?;
1708 }
1709
1710 Ok(Value::Unspecified)
1711 }
1712
1713 fn eval_node_list_filter(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1720 let args_vec = self.list_to_vec(args)?;
1721 if args_vec.len() != 2 {
1722 return Err(EvalError::new("node-list-filter requires exactly 2 arguments".to_string()));
1723 }
1724
1725 let pred = self.eval_inner(args_vec[0].clone(), env.clone())?;
1727
1728 let node_list_val = self.eval_inner(args_vec[1].clone(), env.clone())?;
1730
1731 match node_list_val {
1732 Value::NodeList(ref nl) => {
1733 let mut filtered_nodes = Vec::new();
1734
1735 let mut index = 0;
1737 loop {
1738 if let Some(node) = nl.get(index) {
1739 let node_val = Value::node(node);
1741 let result = self.apply(pred.clone(), vec![node_val.clone()])?;
1742
1743 if !matches!(result, Value::Bool(false)) {
1745 if let Value::Node(n) = node_val {
1747 filtered_nodes.push(n.as_ref().clone_node());
1748 }
1749 }
1750
1751 index += 1;
1752 } else {
1753 break;
1754 }
1755 }
1756
1757 Ok(Value::node_list(Box::new(crate::grove::VecNodeList::new(filtered_nodes))))
1758 }
1759 _ => Err(EvalError::new(format!("node-list-filter: second argument not a node-list: {:?}", node_list_val))),
1760 }
1761 }
1762
1763 fn eval_node_list_map(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1773 let args_vec = self.list_to_vec(args)?;
1774 if args_vec.len() != 2 {
1775 return Err(EvalError::new("node-list-map requires exactly 2 arguments".to_string()));
1776 }
1777
1778 let proc = self.eval_inner(args_vec[0].clone(), env.clone())?;
1780
1781 let node_list_val = self.eval_inner(args_vec[1].clone(), env.clone())?;
1783
1784 let mut result_nodes: Vec<Box<dyn crate::grove::Node>> = Vec::new();
1786
1787 match node_list_val {
1788 Value::Node(ref n) => {
1789 let node_val = Value::node(n.as_ref().clone_node());
1791 let result = self.apply(proc, vec![node_val])?;
1792
1793 match result {
1796 Value::Node(n) => {
1797 result_nodes.push(n.as_ref().clone_node());
1799 }
1800 Value::NodeList(nl) => {
1801 let mut index = 0;
1803 while let Some(node) = nl.get(index) {
1804 result_nodes.push(node);
1805 index += 1;
1806 }
1807 }
1808 _ => {
1809 }
1812 }
1813 }
1814 Value::NodeList(ref nl) => {
1815 let mut index = 0;
1817 loop {
1818 if let Some(node) = nl.get(index) {
1819 let node_val = Value::node(node);
1821 let result = self.apply(proc.clone(), vec![node_val])?;
1822
1823 match result {
1825 Value::Node(n) => {
1826 result_nodes.push(n.as_ref().clone_node());
1828 index += 1;
1829 }
1830 Value::NodeList(nl_result) => {
1831 let mut nl_index = 0;
1833 while let Some(node) = nl_result.get(nl_index) {
1834 result_nodes.push(node);
1835 nl_index += 1;
1836 }
1837 index += 1;
1838 }
1839 _ => {
1840 break;
1842 }
1843 }
1844 } else {
1845 break;
1846 }
1847 }
1848 }
1849 _ => return Err(EvalError::new(format!("node-list-map: second argument must be a node or node-list: {:?}", node_list_val))),
1850 }
1851
1852 Ok(Value::node_list(Box::new(crate::grove::VecNodeList::new(result_nodes))))
1854 }
1855
1856 fn eval_node_list_some(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1862 let args_vec = self.list_to_vec(args)?;
1863 if args_vec.len() != 2 {
1864 return Err(EvalError::new("node-list-some? requires exactly 2 arguments".to_string()));
1865 }
1866
1867 let pred = self.eval_inner(args_vec[0].clone(), env.clone())?;
1869
1870 let node_list_val = self.eval_inner(args_vec[1].clone(), env.clone())?;
1872
1873 match node_list_val {
1874 Value::NodeList(ref nl) => {
1875 let mut index = 0;
1877 loop {
1878 if let Some(node) = nl.get(index) {
1879 let node_val = Value::node(node);
1881 let result = self.apply(pred.clone(), vec![node_val])?;
1882
1883 if !matches!(result, Value::Bool(false)) {
1885 return Ok(Value::bool(true));
1886 }
1887
1888 index += 1;
1889 } else {
1890 break;
1891 }
1892 }
1893
1894 Ok(Value::bool(false))
1896 }
1897 _ => Err(EvalError::new(format!("node-list-some?: second argument not a node-list: {:?}", node_list_val))),
1898 }
1899 }
1900
1901 fn eval_load(&mut self, args: Value, env: Gc<Environment>) -> EvalResult {
1906 let args_vec = self.list_to_vec(args)?;
1907 if args_vec.len() != 1 {
1908 return Err(EvalError::new(
1909 "load requires exactly 1 argument".to_string(),
1910 ));
1911 }
1912
1913 let filename_val = self.eval_inner(args_vec[0].clone(), env.clone())?;
1915
1916 let filename = match filename_val {
1917 Value::String(s) => s.to_string(),
1918 _ => return Err(EvalError::new(
1919 format!("load: filename must be a string, got {:?}", filename_val)
1920 )),
1921 };
1922
1923 let contents = std::fs::read_to_string(&filename)
1925 .map_err(|e| EvalError::new(format!("load: cannot read file '{}': {}", filename, e)))?;
1926
1927 let mut parser = crate::scheme::parser::Parser::new_with_filename(&contents, filename.clone());
1929 let mut result = Value::Unspecified;
1930
1931 let prev_source_file = self.current_source_file.clone();
1933 let prev_position = self.current_position.clone();
1934 self.current_source_file = Some(filename.clone());
1935
1936 let eval_result = loop {
1938 let pos = parser.current_position();
1940
1941 match parser.parse() {
1942 Ok(expr) => {
1943 self.current_position = Some(pos);
1945
1946 match self.eval_inner(expr, env.clone()) {
1947 Ok(val) => result = val,
1948 Err(e) => break Err(e),
1949 }
1950 }
1951 Err(e) => {
1952 let error_msg = e.to_string();
1954 if error_msg.contains("Unexpected end of input")
1955 || error_msg.contains("Expected")
1956 || error_msg.contains("EOF") {
1957 break Ok(result);
1958 }
1959 break Err(EvalError::new(
1960 format!("load: parse error in '{}': {}", filename, e)
1961 ));
1962 }
1963 }
1964 };
1965
1966 self.current_source_file = prev_source_file;
1968 self.current_position = prev_position;
1969
1970 eval_result
1971 }
1972
1973 fn eval_application(
1979 &mut self,
1980 operator: Value,
1981 args: Value,
1982 env: Gc<Environment>,
1983 ) -> EvalResult {
1984 let application_pos = self.current_position.clone();
1986 let application_file = self.current_source_file.clone();
1987
1988 let proc = self.eval_inner(operator, env.clone())?;
1990
1991 let mut evaled_args = Vec::new();
1993 let mut current_args = args;
1994 loop {
1995 match current_args {
1996 Value::Nil => break,
1997 Value::Pair(ref p) => {
1998 let pair_borrow = p.borrow();
1999
2000 if let Some(ref pos) = pair_borrow.pos {
2003 if !self.line_mappings.is_empty() {
2005 if let Some(mapping) = self.line_mappings.iter().find(|m| m.output_line == pos.line) {
2006 self.current_source_file = Some(mapping.source_file.clone());
2007 self.current_position = Some(Position {
2008 line: mapping.source_line,
2009 column: pos.column,
2010 });
2011 } else {
2012 self.current_position = Some(pos.clone());
2013 }
2014 } else {
2015 self.current_position = Some(pos.clone());
2016 }
2017 }
2018
2019 let arg = pair_borrow.car.clone();
2020 let cdr = pair_borrow.cdr.clone();
2021 drop(pair_borrow); evaled_args.push(self.eval_inner(arg, env.clone())?);
2024 current_args = cdr;
2025 }
2026 _ => return Err(EvalError::new("Improper argument list".to_string())),
2027 }
2028 }
2029
2030 self.current_position = application_pos;
2033 self.current_source_file = application_file;
2034
2035 self.apply(proc, evaled_args)
2037 }
2038
2039 fn apply(&mut self, proc: Value, args: Vec<Value>) -> EvalResult {
2041 if let Value::Procedure(ref p) = proc {
2042 match &**p {
2043 Procedure::Primitive { name: _, func } => {
2044 func(&args).map_err(|e| self.error_with_stack(e))
2047 }
2048 Procedure::Lambda { params, body, env, source, name } => {
2049 if args.len() != params.len() {
2051 return Err(self.error_with_stack(format!(
2052 "Lambda expects {} arguments, got {}",
2053 params.len(),
2054 args.len()
2055 )));
2056 }
2057
2058 let saved_file = self.current_source_file.clone();
2060 let saved_pos = self.current_position.clone();
2061
2062 let pushed_frame = if let Some(func_name) = name.clone() {
2065 let call_site = match (&saved_file, &saved_pos) {
2066 (Some(file), Some(pos)) => Some(SourceInfo {
2067 file: file.clone(),
2068 pos: pos.clone(),
2069 }),
2070 _ => None,
2071 };
2072 self.push_call_frame(func_name, call_site);
2073 true
2074 } else {
2075 false
2076 };
2077
2078 if let Some(ref src) = source {
2080 self.current_source_file = Some(src.file.clone());
2081 self.current_position = Some(src.pos.clone());
2082 }
2083
2084 let lambda_env = Environment::extend(env.clone());
2086
2087 for (param_name, arg_value) in params.iter().zip(args.iter()) {
2089 lambda_env.define(param_name, arg_value.clone());
2090 }
2091
2092 let result = self.eval_inner((**body).clone(), lambda_env);
2094
2095 self.current_source_file = saved_file;
2097 self.current_position = saved_pos;
2098
2099 if pushed_frame {
2101 self.pop_call_frame();
2102 }
2103
2104 result
2105 }
2106 }
2107 } else {
2108 Err(self.error_with_stack(format!(
2109 "Not a procedure: {:?}",
2110 proc
2111 )))
2112 }
2113 }
2114}
2115
2116impl Default for Evaluator {
2117 fn default() -> Self {
2118 Self::new()
2119 }
2120}
2121
2122#[cfg(test)]
2127mod tests {
2128 use super::*;
2129
2130 fn make_env() -> Gc<Environment> {
2131 Environment::new_global()
2132 }
2133
2134 #[test]
2135 fn test_eval_self_evaluating() {
2136 let mut eval = Evaluator::new();
2137 let env = make_env();
2138
2139 assert!(eval.eval(Value::integer(42), env.clone()).unwrap().is_integer());
2140 assert!(eval.eval(Value::bool(true), env.clone()).unwrap().is_bool());
2141 assert!(eval.eval(Value::string("hello".to_string()), env).unwrap().is_string());
2142 }
2143
2144 #[test]
2145 fn test_eval_quote() {
2146 let mut eval = Evaluator::new();
2147 let env = make_env();
2148
2149 let expr = Value::cons(
2151 Value::symbol("quote"),
2152 Value::cons(
2153 Value::cons(
2154 Value::integer(1),
2155 Value::cons(Value::integer(2), Value::cons(Value::integer(3), Value::Nil)),
2156 ),
2157 Value::Nil,
2158 ),
2159 );
2160
2161 let result = eval.eval(expr, env).unwrap();
2162 assert!(result.is_list());
2163 }
2164
2165 #[test]
2166 fn test_eval_if_true() {
2167 let mut eval = Evaluator::new();
2168 let env = make_env();
2169
2170 let expr = Value::cons(
2172 Value::symbol("if"),
2173 Value::cons(
2174 Value::bool(true),
2175 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2176 ),
2177 );
2178
2179 let result = eval.eval(expr, env).unwrap();
2180 if let Value::Integer(n) = result {
2181 assert_eq!(n, 1);
2182 } else {
2183 panic!("Expected integer 1");
2184 }
2185 }
2186
2187 #[test]
2188 fn test_eval_if_false() {
2189 let mut eval = Evaluator::new();
2190 let env = make_env();
2191
2192 let expr = Value::cons(
2194 Value::symbol("if"),
2195 Value::cons(
2196 Value::bool(false),
2197 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2198 ),
2199 );
2200
2201 let result = eval.eval(expr, env).unwrap();
2202 if let Value::Integer(n) = result {
2203 assert_eq!(n, 2);
2204 } else {
2205 panic!("Expected integer 2");
2206 }
2207 }
2208
2209 #[test]
2210 fn test_eval_define() {
2211 let mut eval = Evaluator::new();
2212 let env = make_env();
2213
2214 let expr = Value::cons(
2216 Value::symbol("define"),
2217 Value::cons(Value::symbol("x"), Value::cons(Value::integer(42), Value::Nil)),
2218 );
2219
2220 eval.eval(expr, env.clone()).unwrap();
2221
2222 assert!(env.is_defined("x"));
2224 if let Value::Integer(n) = env.lookup("x").unwrap() {
2225 assert_eq!(n, 42);
2226 }
2227 }
2228
2229 #[test]
2230 fn test_eval_symbol_lookup() {
2231 let mut eval = Evaluator::new();
2232 let env = make_env();
2233
2234 env.define("x", Value::integer(99));
2235
2236 let result = eval.eval(Value::symbol("x"), env).unwrap();
2237 if let Value::Integer(n) = result {
2238 assert_eq!(n, 99);
2239 } else {
2240 panic!("Expected integer 99");
2241 }
2242 }
2243
2244 #[test]
2245 fn test_eval_and() {
2246 let mut eval = Evaluator::new();
2247 let env = make_env();
2248
2249 let expr = Value::cons(
2251 Value::symbol("and"),
2252 Value::cons(Value::bool(true), Value::cons(Value::bool(true), Value::Nil)),
2253 );
2254
2255 let result = eval.eval(expr, env.clone()).unwrap();
2256 assert!(result.is_true());
2257
2258 let expr = Value::cons(
2260 Value::symbol("and"),
2261 Value::cons(Value::bool(true), Value::cons(Value::bool(false), Value::Nil)),
2262 );
2263
2264 let result = eval.eval(expr, env).unwrap();
2265 assert!(!result.is_true());
2266 }
2267
2268 #[test]
2269 fn test_eval_or() {
2270 let mut eval = Evaluator::new();
2271 let env = make_env();
2272
2273 let expr = Value::cons(
2275 Value::symbol("or"),
2276 Value::cons(Value::bool(false), Value::cons(Value::bool(true), Value::Nil)),
2277 );
2278
2279 let result = eval.eval(expr, env.clone()).unwrap();
2280 assert!(result.is_true());
2281
2282 let expr = Value::cons(
2284 Value::symbol("or"),
2285 Value::cons(Value::bool(false), Value::cons(Value::bool(false), Value::Nil)),
2286 );
2287
2288 let result = eval.eval(expr, env).unwrap();
2289 assert!(!result.is_true());
2290 }
2291
2292 #[test]
2293 fn test_eval_lambda_creation() {
2294 let mut eval = Evaluator::new();
2295 let env = make_env();
2296
2297 let expr = Value::cons(
2299 Value::symbol("lambda"),
2300 Value::cons(
2301 Value::cons(Value::symbol("x"), Value::Nil),
2302 Value::cons(Value::symbol("x"), Value::Nil),
2303 ),
2304 );
2305
2306 let result = eval.eval(expr, env).unwrap();
2307 assert!(result.is_procedure());
2308 }
2309
2310 #[test]
2311 fn test_eval_lambda_application() {
2312 let mut eval = Evaluator::new();
2313 let env = make_env();
2314
2315 let lambda_expr = Value::cons(
2317 Value::symbol("lambda"),
2318 Value::cons(
2319 Value::cons(Value::symbol("x"), Value::Nil),
2320 Value::cons(Value::symbol("x"), Value::Nil),
2321 ),
2322 );
2323
2324 let app_expr = Value::cons(lambda_expr, Value::cons(Value::integer(42), Value::Nil));
2325
2326 let result = eval.eval(app_expr, env).unwrap();
2327 if let Value::Integer(n) = result {
2328 assert_eq!(n, 42);
2329 } else {
2330 panic!("Expected integer 42");
2331 }
2332 }
2333
2334 #[test]
2335 fn test_eval_lambda_multiple_params() {
2336 let mut eval = Evaluator::new();
2337 let env = make_env();
2338
2339 let params = Value::cons(Value::symbol("x"), Value::cons(Value::symbol("y"), Value::Nil));
2341 let body = Value::symbol("x");
2342
2343 let lambda_expr = Value::cons(Value::symbol("lambda"), Value::cons(params, Value::cons(body, Value::Nil)));
2344
2345 let app_expr = Value::cons(
2346 lambda_expr,
2347 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2348 );
2349
2350 let result = eval.eval(app_expr, env).unwrap();
2351 if let Value::Integer(n) = result {
2352 assert_eq!(n, 1);
2353 } else {
2354 panic!("Expected integer 1");
2355 }
2356 }
2357
2358 #[test]
2359 fn test_eval_lambda_wrong_arg_count() {
2360 let mut eval = Evaluator::new();
2361 let env = make_env();
2362
2363 let lambda_expr = Value::cons(
2365 Value::symbol("lambda"),
2366 Value::cons(
2367 Value::cons(Value::symbol("x"), Value::Nil),
2368 Value::cons(Value::symbol("x"), Value::Nil),
2369 ),
2370 );
2371
2372 let app_expr = Value::cons(
2373 lambda_expr,
2374 Value::cons(Value::integer(1), Value::cons(Value::integer(2), Value::Nil)),
2375 );
2376
2377 let result = eval.eval(app_expr, env);
2378 assert!(result.is_err());
2379 }
2380
2381 #[test]
2382 fn test_eval_lambda_closure() {
2383 let mut eval = Evaluator::new();
2384 let env = make_env();
2385
2386 env.define("x", Value::integer(10));
2388
2389 let lambda_expr = Value::cons(
2392 Value::symbol("lambda"),
2393 Value::cons(
2394 Value::cons(Value::symbol("y"), Value::Nil),
2395 Value::cons(Value::symbol("x"), Value::Nil),
2396 ),
2397 );
2398
2399 let app_expr = Value::cons(lambda_expr, Value::cons(Value::integer(20), Value::Nil));
2400
2401 let result = eval.eval(app_expr, env).unwrap();
2402 if let Value::Integer(n) = result {
2403 assert_eq!(n, 10); } else {
2405 panic!("Expected integer 10 from closure");
2406 }
2407 }
2408
2409 #[test]
2410 fn test_eval_lambda_no_params() {
2411 let mut eval = Evaluator::new();
2412 let env = make_env();
2413
2414 let lambda_expr = Value::cons(
2416 Value::symbol("lambda"),
2417 Value::cons(Value::Nil, Value::cons(Value::integer(42), Value::Nil)),
2418 );
2419
2420 let app_expr = Value::cons(lambda_expr, Value::Nil);
2421
2422 let result = eval.eval(app_expr, env).unwrap();
2423 if let Value::Integer(n) = result {
2424 assert_eq!(n, 42);
2425 } else {
2426 panic!("Expected integer 42");
2427 }
2428 }
2429
2430 #[test]
2431 fn test_eval_lambda_multiple_body_expressions() {
2432 let mut eval = Evaluator::new();
2433 let env = make_env();
2434
2435 let params = Value::cons(Value::symbol("x"), Value::Nil);
2438 let body1 = Value::integer(1);
2439 let body2 = Value::integer(2);
2440 let body3 = Value::symbol("x");
2441
2442 let lambda_expr = Value::cons(
2443 Value::symbol("lambda"),
2444 Value::cons(
2445 params,
2446 Value::cons(body1, Value::cons(body2, Value::cons(body3, Value::Nil))),
2447 ),
2448 );
2449
2450 let app_expr = Value::cons(lambda_expr, Value::cons(Value::integer(99), Value::Nil));
2451
2452 let result = eval.eval(app_expr, env).unwrap();
2453 if let Value::Integer(n) = result {
2454 assert_eq!(n, 99);
2455 } else {
2456 panic!("Expected integer 99");
2457 }
2458 }
2459
2460 #[test]
2461 fn test_element_rule_multiple_sosofos_error() {
2462 let mut eval = Evaluator::new();
2463 let env = make_env();
2464
2465 let expr = Value::cons(
2467 Value::symbol("element"),
2468 Value::cons(
2469 Value::symbol("foo"),
2470 Value::cons(
2471 Value::symbol("expr1"),
2472 Value::cons(Value::symbol("expr2"), Value::Nil),
2473 ),
2474 ),
2475 );
2476
2477 let result = eval.eval(expr, env);
2478 assert!(result.is_err());
2479 let err_msg = result.unwrap_err().to_string();
2480 assert!(err_msg.contains("can only contain one sosofo expression"));
2481 assert!(err_msg.contains("sosofo-append"));
2482 }
2483
2484 #[test]
2485 fn test_element_rule_single_sosofo_ok() {
2486 let mut eval = Evaluator::new();
2487 let env = make_env();
2488
2489 let expr = Value::cons(
2491 Value::symbol("element"),
2492 Value::cons(
2493 Value::symbol("foo"),
2494 Value::cons(Value::symbol("expr"), Value::Nil),
2495 ),
2496 );
2497
2498 let result = eval.eval(expr, env);
2499 assert!(result.is_ok());
2500 }
2501
2502 #[test]
2503 fn test_default_rule_multiple_sosofos_error() {
2504 let mut eval = Evaluator::new();
2505 let env = make_env();
2506
2507 let expr = Value::cons(
2509 Value::symbol("default"),
2510 Value::cons(
2511 Value::symbol("expr1"),
2512 Value::cons(Value::symbol("expr2"), Value::Nil),
2513 ),
2514 );
2515
2516 let result = eval.eval(expr, env);
2517 assert!(result.is_err());
2518 let err_msg = result.unwrap_err().to_string();
2519 assert!(err_msg.contains("can only contain one sosofo expression"));
2520 assert!(err_msg.contains("sosofo-append"));
2521 }
2522
2523 #[test]
2524 fn test_default_rule_single_sosofo_ok() {
2525 let mut eval = Evaluator::new();
2526 let env = make_env();
2527
2528 let expr = Value::cons(
2530 Value::symbol("default"),
2531 Value::cons(Value::symbol("expr"), Value::Nil),
2532 );
2533
2534 let result = eval.eval(expr, env);
2535 assert!(result.is_ok());
2536 }
2537}