feat(prelude): add more std functions
This commit is contained in:
parent
efe1a7877b
commit
eb2cda854f
@ -97,7 +97,7 @@ pub fn prelude_lambda(_env: &Environment, expr: Expression) -> Result<Expression
|
|||||||
pub fn prelude_let(env: &Environment, expr: Expression) -> Result<Expression, EvalError> {
|
pub fn prelude_let(env: &Environment, expr: Expression) -> Result<Expression, EvalError> {
|
||||||
let [bindings, body] = expr.try_into()?;
|
let [bindings, body] = expr.try_into()?;
|
||||||
|
|
||||||
let bindings = CellIterator::new(bindings)
|
let bindings = CellIterator::new(eval(env, bindings)?)
|
||||||
.map(|e| {
|
.map(|e| {
|
||||||
let (s, e) = e?.try_into()?;
|
let (s, e) = e?.try_into()?;
|
||||||
if let Expression::Symbol(s) = s {
|
if let Expression::Symbol(s) = s {
|
||||||
@ -158,6 +158,14 @@ pub fn prelude_gt(env: &Environment, expr: Expression) -> Result<Expression, Eva
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prelude_not(env: &Environment, expr: Expression) -> Result<Expression, EvalError> {
|
||||||
|
let [a] = expr.try_into()?;
|
||||||
|
match a {
|
||||||
|
Expression::Nil => Ok(Expression::True),
|
||||||
|
_ => Ok(Expression::Nil),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn prelude_set(env: &Environment, expr: Expression) -> Result<Expression, EvalError> {
|
pub fn prelude_set(env: &Environment, expr: Expression) -> Result<Expression, EvalError> {
|
||||||
let [s, e] = expr.try_into()?;
|
let [s, e] = expr.try_into()?;
|
||||||
|
|
||||||
@ -178,6 +186,31 @@ pub fn prelude_print(env: &Environment, expr: Expression) -> Result<Expression,
|
|||||||
Ok(e)
|
Ok(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prelude_cons(env: &Environment, expr: Expression) -> Result<Expression, EvalError> {
|
||||||
|
let [a, b] = expr.try_into()?;
|
||||||
|
Ok(Expression::Cell(
|
||||||
|
Box::new(eval(env, a)?),
|
||||||
|
Box::new(eval(env, b)?),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prelude_car(env: &Environment, expr: Expression) -> Result<Expression, EvalError> {
|
||||||
|
let [arg] = expr.try_into()?;
|
||||||
|
let (a, _) = eval(env, arg)?.try_into()?;
|
||||||
|
Ok(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prelude_cdr(env: &Environment, expr: Expression) -> Result<Expression, EvalError> {
|
||||||
|
let [arg] = expr.try_into()?;
|
||||||
|
let (_, b) = eval(env, arg)?.try_into()?;
|
||||||
|
Ok(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prelude_eval(env: &Environment, expr: Expression) -> Result<Expression, EvalError> {
|
||||||
|
let [e] = expr.try_into()?;
|
||||||
|
eval(env, eval(env, e)?)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mk_prelude(layer: &mut EnvironmentLayer) {
|
pub fn mk_prelude(layer: &mut EnvironmentLayer) {
|
||||||
layer.set("+".to_string(), Expression::Function(prelude_add));
|
layer.set("+".to_string(), Expression::Function(prelude_add));
|
||||||
layer.set("-".to_string(), Expression::Function(prelude_sub));
|
layer.set("-".to_string(), Expression::Function(prelude_sub));
|
||||||
@ -185,10 +218,15 @@ pub fn mk_prelude(layer: &mut EnvironmentLayer) {
|
|||||||
layer.set("/".to_string(), Expression::Function(prelude_div));
|
layer.set("/".to_string(), Expression::Function(prelude_div));
|
||||||
layer.set("lambda".to_string(), Expression::Function(prelude_lambda));
|
layer.set("lambda".to_string(), Expression::Function(prelude_lambda));
|
||||||
layer.set("if".to_string(), Expression::Function(prelude_if));
|
layer.set("if".to_string(), Expression::Function(prelude_if));
|
||||||
layer.set("==".to_string(), Expression::Function(prelude_eq));
|
layer.set("=".to_string(), Expression::Function(prelude_eq));
|
||||||
layer.set("<".to_string(), Expression::Function(prelude_lt));
|
layer.set("<".to_string(), Expression::Function(prelude_lt));
|
||||||
layer.set(">".to_string(), Expression::Function(prelude_gt));
|
layer.set(">".to_string(), Expression::Function(prelude_gt));
|
||||||
|
layer.set("not".to_string(), Expression::Function(prelude_not));
|
||||||
layer.set("let".to_string(), Expression::Function(prelude_let));
|
layer.set("let".to_string(), Expression::Function(prelude_let));
|
||||||
layer.set("set".to_string(), Expression::Function(prelude_set));
|
layer.set("set".to_string(), Expression::Function(prelude_set));
|
||||||
layer.set("print".to_string(), Expression::Function(prelude_print));
|
layer.set("print".to_string(), Expression::Function(prelude_print));
|
||||||
|
layer.set("cons".to_string(), Expression::Function(prelude_cons));
|
||||||
|
layer.set("car".to_string(), Expression::Function(prelude_car));
|
||||||
|
layer.set("cdr".to_string(), Expression::Function(prelude_cdr));
|
||||||
|
layer.set("eval".to_string(), Expression::Function(prelude_eval));
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/main.rs
27
src/main.rs
@ -5,20 +5,26 @@ use parser::ExpressionStream;
|
|||||||
use crate::lisp::{eval, Environment};
|
use crate::lisp::{eval, Environment};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let program1 = "((lambda (x y) (+ (if (< x 10) (* x 11) x) y)) 2 20)";
|
let programs = [
|
||||||
let program2 = "(set 'myvar \"hello world!\")";
|
"((lambda (x y) (+ (if (< x 10) (* x 11) x) y)) 2 20)",
|
||||||
let program3 = "(print myvar) (print 'myvar)";
|
"(set 'myvar \"hello world!\")",
|
||||||
|
"(print myvar) (print 'myvar)",
|
||||||
|
"(car (cons 'a 'b)) (cdr (cons 'c 'd)) (cons 'a 'b)",
|
||||||
|
"(eval (car (cons 'myvar 'b)))",
|
||||||
|
"(set 'pow (lambda (a b) (if (= b 0) 1 (* a (pow a (- b 1))))))",
|
||||||
|
"pow",
|
||||||
|
"(pow 2 10)",
|
||||||
|
"(let '((fib . (lambda (n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))))) (fib 10))",
|
||||||
|
];
|
||||||
|
|
||||||
let environment = Environment::default();
|
let environment = Environment::default();
|
||||||
|
|
||||||
for r in ExpressionStream::from_char_stream(
|
for r in ExpressionStream::from_char_stream(programs.iter().map(|p| p.chars()).flatten()) {
|
||||||
program1
|
|
||||||
.chars()
|
|
||||||
.chain(program2.chars())
|
|
||||||
.chain(program3.chars()),
|
|
||||||
) {
|
|
||||||
match r {
|
match r {
|
||||||
Err(err) => println!("ParserError: {:?}", err),
|
Err(err) => {
|
||||||
|
println!("ParserError: {:?}", err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
Ok(expr) => {
|
Ok(expr) => {
|
||||||
println!("Evaluating: {}", expr.clone());
|
println!("Evaluating: {}", expr.clone());
|
||||||
match eval(&environment, expr) {
|
match eval(&environment, expr) {
|
||||||
@ -30,5 +36,4 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
println!("Interpreter Done!");
|
println!("Interpreter Done!");
|
||||||
println!("Environment: {:?}", environment);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user