diff --git a/src/append.rs b/src/append.rs
new file mode 100644
index 0000000..7a6c01d
--- /dev/null
+++ b/src/append.rs
@@ -0,0 +1,68 @@
+/* relish: versatile lisp shell
+ * Copyright (C) 2021 Aidan Hahn
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+use crate::func::{FTable, Function, Args, Operation};
+use crate::vars::{VTable};
+use crate::segment::{Ctr, Ast, circuit, list_idx, list_append, new_ast};
+use std::rc::Rc;
+use std::cell::RefCell;
+
+pub fn get_append() -> Function {
+ return Function{
+ name: String::from("append"),
+ loose_syms: false,
+ eval_lazy: false,
+ args: Args::Lazy(-1),
+ function: Operation::Internal(
+ |a: Ast, _b: Rc>, _c: Rc>| -> Ctr {
+ let ptr = list_idx(a.clone(), 0);
+ match ptr {
+ Ctr::Seg(ref c) => {
+ let acpy = a.clone();
+ match acpy.borrow().cdr.clone() {
+ Ctr::Seg(cn) => {
+ // append to list case
+ if !circuit(cn, &mut |arg: &Ctr| -> bool {
+ list_append(c.clone(), arg.clone());
+ return true;
+ }) {
+ eprintln!("get_append circuit loop should not have returned false");
+ }
+ },
+ _ => {
+ eprintln!("get_append args somehow not in standard form");
+ }
+ }
+
+ return ptr;
+ },
+ _ => {
+ let n = new_ast(Ctr::None, Ctr::None);
+ if !circuit(a, &mut |arg: &Ctr| -> bool {
+ list_append(n.clone(), arg.clone());
+ return true;
+ }) {
+ eprintln!("get_append circuit loop should not have returned false");
+ }
+
+ return Ctr::Seg(n);
+ }
+ }
+ }
+ )
+ };
+}
diff --git a/src/bin/main.rs b/src/bin/main.rs
index cea578f..1b180c1 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -98,7 +98,7 @@ fn main() {
return
},
Err(err) => {
- println!("Prompt error: {:?}", err);
+ eprintln!("Prompt error: {:?}", err);
break
}
}
diff --git a/src/lib.rs b/src/lib.rs
index c441a1e..23bac7b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -22,6 +22,7 @@ mod eval;
mod vars;
mod stl;
mod str;
+mod append;
pub mod ast {
pub use crate::segment::{Seg, Ctr, ast_to_string, Type, Ast, new_ast};
@@ -36,4 +37,5 @@ pub mod ast {
pub mod stdlib {
pub use crate::stl::{get_stdlib};
pub use crate::str::{get_echo};
+ pub use crate::append::{get_append};
}
diff --git a/src/stl.rs b/src/stl.rs
index 0ffeed6..6a4690b 100644
--- a/src/stl.rs
+++ b/src/stl.rs
@@ -14,7 +14,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+
use crate::str::get_echo;
+use crate::append::get_append;
use crate::func::{FTable, func_declare};
use std::rc::Rc;
use std::cell::RefCell;
@@ -24,6 +26,9 @@ pub fn get_stdlib() -> Result>, String> {
if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_echo()))) {
return Err(s)
}
+ if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_append()))) {
+ return Err(s)
+ }
return Ok(ft)
}
diff --git a/src/str.rs b/src/str.rs
index 6384ad3..d0dfe6f 100644
--- a/src/str.rs
+++ b/src/str.rs
@@ -21,6 +21,8 @@ use crate::segment::{Ctr, Ast, circuit, ast_as_string};
use std::rc::Rc;
use std::cell::RefCell;
+// Current primitive is to use a get_NNNNN function defined for each library function which returns a not-previously-owned
+// copy of the Function struct.
pub fn get_echo() -> Function {
return Function{
name: String::from("echo"),
@@ -44,8 +46,7 @@ pub fn get_echo() -> Function {
string.push_str("\n");
return true;
}) {
- // TODO: use custom logger
- println!("Echo failure!")
+ eprintln!("circuit loop in echo should not have returned false")
}
return Ctr::String(string);
}