added more builtins
This commit is contained in:
parent
cef5e1676e
commit
37306989fe
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user