diff --git a/build.soft b/soft/build.lsp similarity index 74% rename from build.soft rename to soft/build.lsp index d76521c..92680f5 100644 --- a/build.soft +++ b/soft/build.lsp @@ -1,4 +1,4 @@ -(require '[stdlib.soft]) +(require 'stdlib) (println (-> stdlib/args (map (fun [x] (str "Hello " x))))) diff --git a/soft/stdlib.lsp b/soft/stdlib.lsp new file mode 100644 index 0000000..056b05e --- /dev/null +++ b/soft/stdlib.lsp @@ -0,0 +1,25 @@ +(declare defmacro* fun*) + +(defmacro* map* (fun* [f coll] + (if (cons? coll) + (cons (f (car coll)) (map* f (cdr coll))) + coll))) + +(defmacro* quasi-quote (fun* [form] + (if (cons? form) + (if (= 'unquote (car form)) + (cdr form) + (cons 'list (map* quasi-quote form))) + (list 'quote form)))) + +(defmacro* defmacro (fun* [name args & body] + (let [body `(begin ~body)] + `(defmacro* ~name (fun* ~name ~args ~body))))) + +(defmacro fun [args & body] + (let [body `(begin ~body)] + `(fun* local ~args ~body))) + +(defmacro defun [name args & body] + (let [body `(begin ~body)] + `(def* ~name (fun* ~name ~args ~body)))) diff --git a/src/eval.rs b/src/eval.rs index e259a49..b9b70df 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -64,18 +64,10 @@ pub enum Value { name: Keyword, value: Box, }, - Set { - target: Box, - value: Box, - }, - Deref { - value: Box, - }, Recur { arguments: Vec, }, Quote(Expr), - Atomic(Arc>), Ptr(*mut ()), Nil, } @@ -247,18 +239,6 @@ impl Expr { .map(|expr| expr.expand(environment)) .collect::, _>>()?, }), - Expr::Deref(deref) => Ok(Value::Deref { - value: deref.value()?.expand(environment)?.into(), - }), - Expr::Atomic(atomic) => { - let value = atomic.value()?.expand(environment)?; - let atomic = Arc::new(RwLock::new(value)); - Ok(Value::Atomic(atomic)) - } - Expr::Set(set) => Ok(Value::Set { - target: set.target()?.expand(environment)?.into(), - value: set.value()?.expand(environment)?.into(), - }), Expr::DefMacro(def_macro) => Ok(Value::DefMacro { name: def_macro.name()?.expand(environment)?.try_into()?, value: def_macro.value()?.expand(environment)?.into(), @@ -316,22 +296,6 @@ impl Value { /// Evaluate the expression into a value. pub fn eval(self, environment: &Environment) -> Trampoline { match self { - Value::Deref { box value, .. } => { - let Value::Atomic(atomic) = value else { - bail!(EvalError::ExpectedAtomic) - }; - let guard = atomic.read().expect("poisoned atomic"); - - Done(guard.clone()) - } - Value::Set { box target, value } => { - let Value::Atomic(atomic) = target else { - bail!(EvalError::ExpectedAtomic) - }; - let mut guard = atomic.write().expect("poisoned atomic"); - *guard = value.eval(environment)?.clone(); - Done(guard.clone()) - } Value::Keyword(keyword) if !keyword.is_atom => { match environment.find_definition(keyword.clone()) { Some(Definition { value, .. }) => Done(value), diff --git a/src/semantic.rs b/src/semantic.rs index c44c4ac..1ed421c 100644 --- a/src/semantic.rs +++ b/src/semantic.rs @@ -1,14 +1,11 @@ use crate::Term; define_ast!(Expr, { - Fun, // (fun* (a b) (+ a b)) + Fun, // (fun* [a b] (+ a b)) List, // [a b c] or (list a b c) Apply, // (a b c) or (apply a b c) - Def, // (def a 123) + Def, // (def* a 123) Recur, // (recur a) - Deref, // (deref* 123) - Atomic, // (atomic* 123) - Set, // (set* a 123) DefMacro, // (defmacro* a (fun (a b) (+ a b)) Quote, // '(fun* (a b) (+ a b)) Literal // 123 | "bla" | :bla | bla @@ -17,9 +14,6 @@ define_ast!(Expr, { define_builtin!(DefMacro, "defmacro*", 2); define_builtin!(Def, "def*", 2); define_builtin!(Recur, "recur"); -define_builtin!(Atomic, "atomic*", 1); -define_builtin!(Deref, "deref*", 1); -define_builtin!(Set, "set*", 2); define_builtin!(Fun, "fun*", 2); define_builtin!(Quote, "'", 2); define_builtin!(Apply, "apply"); @@ -123,58 +117,6 @@ pub mod recur { } } -/// Set expression construct, it's a definition of a value. -pub mod set { - pub use super::*; - - impl Set { - /// Returns the name of the definition. - pub fn target(&self) -> Result { - self.0 - .at(1) - .ok_or(SemanticError::InvalidExpression)? - .try_into() - } - - /// Returns the value of the definition. - pub fn value(&self) -> Result { - self.0 - .at(2) - .ok_or(SemanticError::InvalidExpression)? - .try_into() - } - } -} - -/// Deref expression construct, it's a mutable value. -pub mod deref { - pub use super::*; - - impl Deref { - /// Returns the value of the definition. - pub fn value(&self) -> Result { - self.0 - .at(1) - .ok_or(SemanticError::InvalidExpression)? - .try_into() - } - } -} - -/// Atomic expression construct, it's a mutable value. -pub mod atomic { - pub use super::*; - - impl Atomic { - /// Returns the value of the definition. - pub fn value(&self) -> Result { - self.0 - .at(1) - .ok_or(SemanticError::InvalidExpression)? - .try_into() - } - } -} /// Define expression construct, it's a definition of a value. pub mod def { @@ -343,11 +285,8 @@ impl TryFrom for Expr { fn try_from(value: Term) -> Result { DefMacro::try_new(value.clone()) - .or_else(|_| Atomic::try_new(value.clone())) - .or_else(|_| Deref::try_new(value.clone())) .or_else(|_| Recur::try_new(value.clone())) .or_else(|_| Def::try_new(value.clone())) - .or_else(|_| Set::try_new(value.clone())) .or_else(|_| Fun::try_new(value.clone())) .or_else(|_| Quote::try_new(value.clone())) .or_else(|_| Apply::try_new(value.clone())) diff --git a/stdlib.soft b/stdlib.soft deleted file mode 100644 index 7ebcf7a..0000000 --- a/stdlib.soft +++ /dev/null @@ -1,15 +0,0 @@ -(defmacro* map* (fun* [f coll] - (if (cons? coll) - (cons (f (car coll)) (map* f (cdr coll))) - coll))) - -(defmacro* quasi-quote (fun* [form] - (if (cons? form) - (if (= 'unquote (car form)) - (cdr form) - (cons 'list (map* quasi-quote form))) - (list 'quote form)))) - -(defmacro* defmacro [name args & body] - (let [body (cons 'block body)] - `(defmacro* ,name (fun* ,args ,body))))