From 8bd701c03c3024e88f58f93935dbd9142d1481bb Mon Sep 17 00:00:00 2001 From: Ishan Jain Date: Tue, 28 May 2024 11:14:11 +0530 Subject: [PATCH] completed index op on hashtable, added puts builtin --- src/evaluator/builtins.rs | 13 +++++++++++++ src/evaluator/mod.rs | 1 + src/evaluator/tree_walker.rs | 12 ++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/evaluator/builtins.rs b/src/evaluator/builtins.rs index e0415a7..e4ed7dd 100644 --- a/src/evaluator/builtins.rs +++ b/src/evaluator/builtins.rs @@ -19,6 +19,7 @@ pub const BUILTINS: LazyCell> = LazyCell::new(|| { match &args[0] { Object::String(s) => Object::Integer(s.len() as i64), Object::Array(s) => Object::Integer(s.elements.len() as i64), + Object::Hash(h) => Object::Integer(h.pairs.len() as i64), v => Object::Error(format!("argument to `len` not supported, got {}", v)), } }), @@ -110,5 +111,17 @@ pub const BUILTINS: LazyCell> = LazyCell::new(|| { }), }), ); + + map.insert( + "puts", + Object::Builtin(BuiltinFunction { + func: Box::new(|args: Vec| { + for arg in args { + println!("{}", arg.inspect()); + } + Object::Null + }), + }), + ); map }); diff --git a/src/evaluator/mod.rs b/src/evaluator/mod.rs index 3ad277e..7572dd2 100644 --- a/src/evaluator/mod.rs +++ b/src/evaluator/mod.rs @@ -517,6 +517,7 @@ mod tests { elements: vec![Object::Integer(1), Object::Integer(5)], })), ), + ("len({\"foo\": \"bar\"})", Some(Object::Integer(1))), ]; run_test_cases(&test_cases); diff --git a/src/evaluator/tree_walker.rs b/src/evaluator/tree_walker.rs index beab588..d1cc680 100644 --- a/src/evaluator/tree_walker.rs +++ b/src/evaluator/tree_walker.rs @@ -318,10 +318,14 @@ impl TreeWalker { } fn eval_hash_index_expression(&self, left: &HashObject, index: Object) -> Option { - Some(Object::Error(format!( - "index operator not supported: {:?}", - left - ))) + if let Object::Function(_) = index { + return Some(Object::Error(format!("unusable as hash key: {}", index))); + } + + match left.pairs.get(&index) { + Some(v) => Some(v.clone()), + None => Some(Object::Null), + } } fn eval_array_index_expression(array: &Array, index: i64) -> Object { let max = array.elements.len() as i64;