added list len, front, and back
This commit is contained in:
parent
06d30ac263
commit
7fd47c1812
5 changed files with 215 additions and 12 deletions
33
src/stl.rs
33
src/stl.rs
|
|
@ -250,6 +250,39 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
|
|||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"len".to_string(),
|
||||
Symbol {
|
||||
name: String::from("len"),
|
||||
args: Args::Strict(vec![Type::Seg]),
|
||||
conditional_branches: false,
|
||||
docs: append::LEN_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(append::len_callback)),
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"car".to_string(),
|
||||
Symbol {
|
||||
name: String::from("car"),
|
||||
args: Args::Strict(vec![Type::Seg]),
|
||||
conditional_branches: false,
|
||||
docs: append::CAR_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(append::car_callback)),
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"cdr".to_string(),
|
||||
Symbol {
|
||||
name: String::from("cdr"),
|
||||
args: Args::Strict(vec![Type::Seg]),
|
||||
conditional_branches: false,
|
||||
docs: append::CDR_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(append::cdr_callback)),
|
||||
},
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,3 +49,57 @@ pub fn append_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
Ok(Ctr::Seg(temp))
|
||||
}
|
||||
}
|
||||
|
||||
pub const LEN_DOCSTRING: &str = "Takes a single argument, expected to be a list.
|
||||
Returns the length of said list.
|
||||
Interpreter will panic if the length of the list is greater than the max value of a signed 128 bit integer";
|
||||
|
||||
pub fn len_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
if let Ctr::Seg(ref s) = *ast.car {
|
||||
if let Ctr::None = *s.car {
|
||||
Ok(Ctr::Integer(0))
|
||||
} else {
|
||||
Ok(Ctr::Integer(s.len() as i128))
|
||||
}
|
||||
} else {
|
||||
Err("impossible condition: argument to len not a list".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub const CAR_DOCSTRING: &str = "Takes a single argument, expected to be a list.
|
||||
Returns a copy of the first value in that list.
|
||||
If the list is empty, returns an err to avoid passing back a null value.";
|
||||
|
||||
pub fn car_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
if let Ctr::Seg(ref s) = *ast.car {
|
||||
if let Ctr::None = *s.car {
|
||||
Err("argument is empty".to_string())
|
||||
} else {
|
||||
Ok(*s.car.clone())
|
||||
}
|
||||
} else {
|
||||
Err("impossible condition: argument to car not a list".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub const CDR_DOCSTRING: &str = "Takes a single argument, expected to be a list.
|
||||
Returns a copy of the last value in that list.
|
||||
If the list is empty, returns an err to avoid passing back a null value.";
|
||||
|
||||
pub fn cdr_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
if let Ctr::Seg(ref s) = *ast.car {
|
||||
let mut ret = &s.car;
|
||||
let mut iter = &s.cdr;
|
||||
while let Ctr::Seg(ref next) = **iter {
|
||||
ret = &next.car;
|
||||
iter = &next.cdr;
|
||||
}
|
||||
if let Ctr::None = **ret {
|
||||
Err("argument is empty".to_string())
|
||||
} else {
|
||||
Ok(*ret.clone())
|
||||
}
|
||||
} else {
|
||||
Err("impossible condition: argument to cdr not a list".to_string())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,14 +145,15 @@ impl Args {
|
|||
} else {
|
||||
return Err("expected no args".to_string());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Args::Infinite => {
|
||||
if !args.is_empty() {
|
||||
return Ok(());
|
||||
} else {
|
||||
return Err("expected args but none were provided".to_string());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Args::Lazy(ref num) => {
|
||||
let called_arg_count = args.len();
|
||||
|
|
@ -167,7 +168,7 @@ impl Args {
|
|||
} else if let Ctr::None = *args.car {
|
||||
return Err(format!("expected {} args. Got 0.", num,));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Args::Strict(ref arg_types) => {
|
||||
let mut idx: usize = 0;
|
||||
|
|
@ -202,7 +203,7 @@ impl Args {
|
|||
return Err("too few arguments".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue