Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add list facilities #9

Merged
merged 25 commits into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions schemius-native/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clap::Parser;
use schemius::Interpreter;
use std::error::Error;

/// Simple Scheme interpreter born as a personal learning project
#[derive(Parser, Debug)]
Expand All @@ -18,25 +19,22 @@ struct Args {
source: Option<String>,
}

fn main() {
fn main() -> Result<(), Box<dyn Error>> {
let args = Args::parse();
let mut interpreter = Interpreter::default();

match args.eval {
Some(expr) => {
interpreter.eval_expression_no_print(expr);
return;
}
Some(expr) => interpreter.eval_expression_no_print(expr)?,
_ => (),
}

match args.print {
Some(expr) => return interpreter.eval_expression_and_print(expr),
Some(expr) => interpreter.eval_expression_and_print(expr)?,
_ => (),
}

match args.source {
Some(path) => return interpreter.execute_file(path),
Some(path) => interpreter.execute_file(path)?,
_ => (),
}

Expand All @@ -54,5 +52,6 @@ fn main() {
println!("\t(environment-bindings) -> Show bindings in current env");
println!("\t(exit) -> Exit program");
println!();
interpreter.run_repl()

Ok(interpreter.run_repl()?)
}
5 changes: 4 additions & 1 deletion schemius-web/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ lazy_static! {

#[wasm_bindgen]
pub fn evaluate(expression: &str) -> String {
INTERPRETER.try_lock().unwrap().eval_expression_and_format(expression.to_string())
match INTERPRETER.try_lock().unwrap().eval_expression_and_format(expression.to_string()) {
Ok(result) => result,
Err(err) => err,
}
}

#[cfg(test)]
Expand Down
41 changes: 16 additions & 25 deletions schemius/src/core/builtins/base_procs.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,43 @@
use super::{
eval,
s_list::SList,
s_procedure::{ProcedureArgs, ProcedureEnv, ProcedureOutput},
Accessor, SExpr, SchemeEnvironment, SchemeList,
};

pub fn r_apply(args: ProcedureArgs, env: ProcedureEnv) -> ProcedureOutput {
pub fn r_apply(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {
if args.s_len() != 2 {
return Err(format!("Exception in apply: expected 2 arguments, found {}", args.s_len()));
}

let symbol = &args[0];
let arg_list = &args[1];
let proc = args.s_car().unwrap();
let args = args.s_cadr().unwrap();
let mut to_be_evaluated = vec![];
to_be_evaluated.push(proc.clone());

match eval(arg_list, env.clone()) {
Ok(list) => match list {
SExpr::List(args) => {
let iterator = [symbol.clone()];
let mut args = args.borrow().clone();
args.splice(0..0, iterator);

Ok(SExpr::List(SchemeList::new(args.clone())))
}
_ => Err(String::from("Exception in apply: must provide a quoted list of arguments")),
},
Err(e) => Err(e),
match args {
SExpr::List(list) => list.borrow().iter().for_each(|arg| to_be_evaluated.push(arg.clone())),
other => return Err(format!("Exception in #<apply>: {} is not a list", other)),
}

Ok(SExpr::List(SchemeList::new(to_be_evaluated)))
}

pub fn r_eval(args: ProcedureArgs, env: ProcedureEnv) -> ProcedureOutput {
pub fn r_eval(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {
if args.s_len() != 1 {
return Err(format!("Exception in eval: expected 1 argument, found {}", args.s_len()));
}

eval(&args[0], env.clone())
Ok(args.s_car().unwrap().clone())
}

pub fn r_display(args: ProcedureArgs, env: ProcedureEnv) -> ProcedureOutput {
pub fn r_display(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {
if args.s_len() != 1 {
return Err(format!("Exception in display: expected 1 argument, found {}", args.s_len()));
}

match eval(&args[0], env.clone()) {
Ok(val) => match val {
SExpr::String(string) => Ok(SExpr::Symbol(string.borrow().to_string())), // Avoids double quotes
expr => Ok(SExpr::Symbol(format!("{}", expr))),
},
Err(e) => Err(e),
match args.s_car().unwrap() {
SExpr::String(string) => Ok(SExpr::Symbol(string.borrow().to_string())), // Avoids double quotes
expr => Ok(SExpr::Symbol(format!("{}", expr))),
}
}

Expand Down
3 changes: 2 additions & 1 deletion schemius/src/core/builtins/boolean_procs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{
s_list::SList,
s_procedure::{ProcedureArgs, ProcedureEnv, ProcedureOutput},
SExpr,
};
Expand All @@ -11,7 +12,7 @@ macro_rules! fn_is {
return Err(format!("Exception in {}: expected 1 argument, found {}", $name, args.len()));
}

match args[0].$source_fn() {
match args.s_car().unwrap().$source_fn() {
Ok(res) => Ok(SExpr::Boolean(res)),
Err(e) => Err(e)
}
Expand Down
Loading