added more builtins

This commit is contained in:
Ishan Jain 2024-05-26 20:12:42 +05:30
parent cef5e1676e
commit 37306989fe
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27
2 changed files with 106 additions and 1 deletions

View File

@ -1,6 +1,6 @@
use std::{cell::LazyCell, collections::HashMap}; use std::{cell::LazyCell, collections::HashMap};
use super::{BuiltinFunction, Object}; use super::{Array, BuiltinFunction, Object};
pub const BUILTINS: LazyCell<HashMap<&'static str, Object>> = LazyCell::new(|| { pub const BUILTINS: LazyCell<HashMap<&'static str, Object>> = LazyCell::new(|| {
let mut map = HashMap::new(); let mut map = HashMap::new();
@ -25,5 +25,90 @@ pub const BUILTINS: LazyCell<HashMap<&'static str, Object>> = LazyCell::new(|| {
}), }),
); );
map.insert(
"first",
Object::Builtin(BuiltinFunction {
func: Box::new(|args: Vec<Object>| {
if args.len() != 1 {
return Object::Error(format!(
"wrong number of arguments. got={}, want=1",
args.len()
));
}
match &args[0] {
Object::Array(s) => s.elements[0].clone(),
v => Object::Error(format!("argument to `len` not supported, got {}", v)),
}
}),
}),
);
map.insert(
"last",
Object::Builtin(BuiltinFunction {
func: Box::new(|args: Vec<Object>| {
if args.len() != 1 {
return Object::Error(format!(
"wrong number of arguments. got={}, want=1",
args.len()
));
}
match &args[0] {
Object::Array(s) => {
let last = s.elements.len();
s.elements[last - 1].clone()
}
v => Object::Error(format!("argument to `len` not supported, got {}", v)),
}
}),
}),
);
map.insert(
"rest",
Object::Builtin(BuiltinFunction {
func: Box::new(|args: Vec<Object>| {
if args.len() != 1 {
return Object::Error(format!(
"wrong number of arguments. got={}, want=1",
args.len()
));
}
match &args[0] {
Object::Array(s) => Object::Array(Array {
elements: s.elements.iter().skip(1).cloned().collect(),
}),
v => Object::Error(format!("argument to `len` not supported, got {}", v)),
}
}),
}),
);
map.insert(
"push",
Object::Builtin(BuiltinFunction {
func: Box::new(|args: Vec<Object>| {
if args.len() != 2 {
return Object::Error(format!(
"wrong number of arguments. got={}, want=2",
args.len()
));
}
match &args[0] {
Object::Array(s) => {
let mut elements = s.elements.clone();
elements.push(args[1].clone());
Object::Array(Array { elements })
}
v => Object::Error(format!("argument to `len` not supported, got {}", v)),
}
}),
}),
);
map map
}); });

View File

@ -467,6 +467,26 @@ mod tests {
"wrong number of arguments. got=2, want=1".to_string(), "wrong number of arguments. got=2, want=1".to_string(),
)), )),
), ),
("first([1,2,3,4])", Some(Object::Integer(1))),
("last([1,2,3,4])", Some(Object::Integer(4))),
(
"rest([1,2,3,4])",
Some(Object::Array(Array {
elements: vec![Object::Integer(2), Object::Integer(3), Object::Integer(4)],
})),
),
(
"push([1,2,3,4])",
Some(Object::Error(
"wrong number of arguments. got=1, want=2".to_string(),
)),
),
(
"push([1],5)",
Some(Object::Array(Array {
elements: vec![Object::Integer(1), Object::Integer(5)],
})),
),
]; ];
run_test_cases(&test_cases); run_test_cases(&test_cases);