WIP lambda
* typesystem extended * docstrings and callback * tests defined, not implemented
This commit is contained in:
parent
7befdc869b
commit
b0bd369c1d
4 changed files with 88 additions and 24 deletions
|
|
@ -14,6 +14,7 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
use crate::sym::UserFn;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Add, Div, Index, Mul, Sub};
|
||||
|
|
@ -27,6 +28,7 @@ pub enum Ctr {
|
|||
Float(f64),
|
||||
Bool(bool),
|
||||
Seg(Seg),
|
||||
Lambda(UserFn),
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
|
@ -40,6 +42,7 @@ pub enum Type {
|
|||
Float,
|
||||
Bool,
|
||||
Seg,
|
||||
Lambda,
|
||||
None,
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +83,7 @@ impl Ctr {
|
|||
Ctr::Float(_s) => Type::Float,
|
||||
Ctr::Bool(_s) => Type::Bool,
|
||||
Ctr::Seg(_s) => Type::Seg,
|
||||
Ctr::Lambda(_s) => Type::Lambda,
|
||||
Ctr::None => Type::None,
|
||||
}
|
||||
}
|
||||
|
|
@ -240,6 +244,7 @@ impl Clone for Ctr {
|
|||
Ctr::Float(s) => Ctr::Float(*s),
|
||||
Ctr::Bool(s) => Ctr::Bool(*s),
|
||||
Ctr::Seg(s) => Ctr::Seg(s.clone()),
|
||||
Ctr::Lambda(s) => Ctr::Seg(s.clone()),
|
||||
Ctr::None => Ctr::None,
|
||||
}
|
||||
}
|
||||
|
|
@ -260,6 +265,7 @@ impl fmt::Display for Ctr {
|
|||
}
|
||||
}
|
||||
Ctr::Seg(s) => write!(f, "{}", s),
|
||||
Ctr::Lambda(l) => write!(f, "{}", l),
|
||||
Ctr::None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
|
@ -398,6 +404,7 @@ impl fmt::Display for Type {
|
|||
Type::Float => "float",
|
||||
Type::Bool => "bool",
|
||||
Type::Seg => "segment",
|
||||
Type::Lambda => "lambda",
|
||||
Type::None => "none",
|
||||
};
|
||||
|
||||
|
|
@ -414,6 +421,7 @@ impl std::convert::From<String> for Type {
|
|||
"float" => Type::Float,
|
||||
"bool" => Type::Bool,
|
||||
"segment" => Type::Seg,
|
||||
"lambda" => Type::Lambda,
|
||||
_ => Type::None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,3 +244,44 @@ pub fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
}
|
||||
Ok(Ctr::None)
|
||||
}
|
||||
|
||||
pub const LAMBDA_DOCSTRING: &str = "Takes two arguments of any type.
|
||||
No args are evaluated when lambda is called.
|
||||
Lambda makes sure the first argument is a list of symbols (or 'arguments') to the lambda function.
|
||||
The next arg is stored in a tree to evaluate on demand.
|
||||
|
||||
Example: (lambda (x y) (add x y))
|
||||
This can then be evaluated like so:
|
||||
((lambda (x y) (add x y)) 1 2)
|
||||
which is functionally equivalent to:
|
||||
(add 1 2)";
|
||||
|
||||
pub fn lambda_callback(
|
||||
ast: &Seg,
|
||||
_syms: &mut SymTable
|
||||
) -> Result<Ctr, String> {
|
||||
let mut args = vec![];
|
||||
if let Ctr::Seg(ref arg_head) = *ast.car {
|
||||
if !arg_head.circuit(&mut |arg: &Ctr| -> bool {
|
||||
if let Ctr::Symbol(ref s) = *arg {
|
||||
args.push(s.clone());
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}) {
|
||||
Err("all elements of first argumnets must be symbols".to_string())
|
||||
} else {
|
||||
if let Ctr::Seg(ref eval_head) = *ast.cdr {
|
||||
Ok(Ctr::Lambda(UserFn{
|
||||
ast: Box::new(eval_head.clone()),
|
||||
arg_syms: args,
|
||||
}))
|
||||
} else {
|
||||
Err("not enough args".to_string())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Err("first argument should be a list of symbols".to_string())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/sym.rs
12
src/sym.rs
|
|
@ -227,6 +227,18 @@ impl fmt::Display for Args {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for UserFn {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "(lambda: (");
|
||||
for i in self.arg_syms {
|
||||
write!(f, "{} ", i);
|
||||
}
|
||||
write!(f, ") {})", self.ast);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ValueType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue