Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/adam-mcdaniel/dune into arg…
Browse files Browse the repository at this point in the history
…s-flatten
  • Loading branch information
adam-mcdaniel committed Oct 13, 2023
2 parents 4737e8e + 0d9025f commit ad3fb95
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dune"
version = "0.1.8"
version = "0.1.9"
authors = ["Adam McDaniel <[email protected]>"]
edition = "2021"
license = "Apache-2.0"
Expand Down
17 changes: 12 additions & 5 deletions src/binary/init/fn_module.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
use common_macros::b_tree_map;
use dune::{Environment, Error, Expression};

fn curry(f: Expression, args: usize, env: &mut Environment) -> Result<Expression, Error> {
pub(super) fn curry(
f: Expression,
args: usize,
env: &mut Environment,
) -> Result<Expression, Error> {
let mut result = Expression::Apply(
Box::new(f.clone()),
(0..args).map(|i| Expression::Symbol(format!("arg{}", i))).collect(),
(0..args)
.map(|i| Expression::Symbol(format!("arg{}", i)))
.collect(),
);
for i in (0..args).rev() {
result = Expression::Lambda(
format!("arg{}", i),
Box::new(result),
Environment::default()
).eval(env)?;
Environment::default(),
)
.eval(env)?;
}
Ok(result)
}

fn curry_builtin(args: Vec<Expression>, env: &mut Environment) -> Result<Expression, Error> {
if args.len() < 2 {
return Err(Error::CustomError(
"curry requires at least two arguments".to_string()
"curry requires at least two arguments".to_string(),
));
}
let f = args[0].eval(env)?;
Expand Down
6 changes: 2 additions & 4 deletions src/binary/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ mod os_module;
mod parse_module;
mod rand_module;
mod shell_module;
mod string_module;
mod time_module;
mod widget_module;


pub fn init(env: &mut Environment) {
let standard_module = b_tree_map! {
"math" => math_module::get(),
Expand All @@ -32,6 +32,7 @@ pub fn init(env: &mut Environment) {
"parse" => parse_module::get(),
"fs" => fs_module::get(env),
"ops" => operator_module::get(env),
"string" => string_module::get(),
};

env.define_module("std", standard_module.clone());
Expand All @@ -40,12 +41,10 @@ pub fn init(env: &mut Environment) {
env.define(name, module);
}


env.define("exit", env.get("os").unwrap()["exit"].clone());
env.define("cd", env.get("os").unwrap()["cd"].clone());
env.define("quit", env.get("exit").unwrap());


env.define_builtin(
"help",
|args, env| {
Expand Down Expand Up @@ -359,7 +358,6 @@ pub fn init(env: &mut Environment) {
"get the list of lines in a string",
);


env.define_builtin(
"eval",
|args, env| {
Expand Down
1 change: 0 additions & 1 deletion src/binary/init/operator_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ pub fn get(env: &mut Environment) -> Expression {
Expression::Map(tmp.bindings)
}


fn pipe_builtin(args: Vec<Expression>, env: &mut Environment) -> Result<Expression, Error> {
if args.len() <= 1 {
return Err(Error::CustomError(
Expand Down
88 changes: 88 additions & 0 deletions src/binary/init/string_module.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use super::fn_module::curry;
use common_macros::b_tree_map;
use dune::{Environment, Error, Expression};

fn split(args: Vec<Expression>, env: &mut Environment) -> Result<Expression, Error> {
if args.len() != 2 {
return Err(Error::CustomError(format!(
"expected 2 arguments, got {}",
args.len()
)));
}
match (args[0].eval(env)?, args[1].eval(env)?) {
(
Expression::Symbol(x) | Expression::String(x),
Expression::Symbol(y) | Expression::String(y),
) => {
let mut v = Vec::new();
for s in y.split(&x) {
v.push(Expression::String(s.to_string()));
}
Ok(Expression::List(v))
}
(a, b) => Err(Error::CustomError(format!(
"expected string, got values {} and {}",
a, b
))),
}
}

pub fn get() -> Expression {
(b_tree_map! {
String::from("isws") => Expression::builtin("isws", |args, env| {
match args[0].eval(env)? {
Expression::Symbol(x) | Expression::String(x) => {
Ok(Expression::Boolean(x.chars().all(|c| c.is_whitespace())))
}
otherwise => Err(Error::CustomError(format!(
"expected string, got value {}",
otherwise
))),
}
}, "is this string whitespace?"),

String::from("isalpha") => Expression::builtin("isalpha", |args, env| {
match args[0].eval(env)? {
Expression::Symbol(x) | Expression::String(x) => {
Ok(Expression::Boolean(x.chars().all(|c| c.is_alphabetic())))
}
otherwise => Err(Error::CustomError(format!(
"expected string, got value {}",
otherwise
))),
}
}, "is this string alphabetic?"),

String::from("isalphanumeric") => Expression::builtin("isalphanumeric", |args, env| {
match args[0].eval(env)? {
Expression::Symbol(x) | Expression::String(x) => {
Ok(Expression::Boolean(x.chars().all(|c| c.is_alphanumeric())))
}
otherwise => Err(Error::CustomError(format!(
"expected string, got value {}",
otherwise
))),
}
}, "is this string alphanumeric?"),

String::from("isnumeric") => Expression::builtin("isnumeric", |args, env| {
match args[0].eval(env)? {
Expression::Symbol(x) | Expression::String(x) => {
Ok(Expression::Boolean(x.chars().all(|c| c.is_numeric())))
}
otherwise => Err(Error::CustomError(format!(
"expected string, got value {}",
otherwise
))),
}
}, "is this string numeric?"),

String::from("split") => Expression::builtin("split", |args, env| {
curry(Expression::builtin("", split, ""), 2, env)?
.eval(env)?
.apply(args)
.eval(env)
}, "split a string on a given character"),
})
.into()
}
6 changes: 5 additions & 1 deletion src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ impl Environment {
}
}

pub fn define_module<A: ToString, B: ToString>(&mut self, name: A, module: impl Into<BTreeMap<B, Expression>>) {
pub fn define_module<A: ToString, B: ToString>(
&mut self,
name: A,
module: impl Into<BTreeMap<B, Expression>>,
) {
let mut result = BTreeMap::new();
for (key, value) in module.into() {
result.insert(key.to_string(), value);
Expand Down
4 changes: 4 additions & 0 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ impl Expression {
x.into()
}

pub fn apply(self, args: Vec<Self>) -> Self {
Self::Apply(Box::new(self), args)
}

pub fn is_truthy(&self) -> bool {
match self {
Self::Integer(i) => *i != 0,
Expand Down

0 comments on commit ad3fb95

Please sign in to comment.