mark core as nostd

* implement custom hashmap to back symtable
* pass in print and read callbacks to keep stdlib pure
* use core / alloc versions of Box, Rc, Vec, etc
* replace pow func with libm

Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2024-07-26 22:16:21 -07:00
parent 0c2aad2cb6
commit d6a0e68460
26 changed files with 493 additions and 288 deletions

View file

@ -184,7 +184,7 @@ mod tests {
let document = "(exists? \"/tmp\")";
let result = "true";
let mut syms = SymTable::new();
static_stdlib(&mut syms);
static_stdlib(&mut syms, |_: &String| (), || String::new());
static_stdlib_overwrites(&mut syms);
assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -199,7 +199,7 @@ mod tests {
let document = "(exists? \"cargo.timtam\")";
let result = "false";
let mut syms = SymTable::new();
static_stdlib(&mut syms);
static_stdlib(&mut syms, |_: &String| (), || String::new());
static_stdlib_overwrites(&mut syms);
assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -219,7 +219,7 @@ mod tests {
(eq? (read-file t) s))";
let result = "true";
let mut syms = SymTable::new();
static_stdlib(&mut syms);
static_stdlib(&mut syms, |_: &String| (), || String::new());
static_stdlib_overwrites(&mut syms);
assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -240,7 +240,7 @@ mod tests {
(concat s s)))";
let result = "true";
let mut syms = SymTable::new();
static_stdlib(&mut syms);
static_stdlib(&mut syms, |_: &String| (), || String::new());
static_stdlib_overwrites(&mut syms);
assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms)

View file

@ -466,11 +466,9 @@ fn make_prompt(syms: &mut SymTable) -> CustomPrompt {
}
fn make_completer(syms: &mut SymTable) -> CustomCompleter {
let mut toks = vec![];
for i in syms.keys(){
toks.push(i.clone());
}
CustomCompleter(toks)
CustomCompleter(syms.iter()
.map(|i| i.0.clone())
.collect())
}
fn get_token_to_complete(line: &str, pos: usize) -> (String, bool, usize) {

View file

@ -23,7 +23,7 @@ use {
},
crate::run,
libc::{
sigaddset, sigemptyset, sigprocmask, exit,
sigaddset, sigemptyset, sigprocmask,
SIGINT, SIGCHLD, SIGTTOU, SIGTTIN, SIGQUIT, SIGTSTP,
SIG_BLOCK, SIG_UNBLOCK
},
@ -43,6 +43,7 @@ use {
os::unix::process::CommandExt,
mem,
thread,
process,
time::Duration,
},
nix::{
@ -619,19 +620,6 @@ fn q_callback(_ast: &Seg, _syms: &SymTable, state: &mut ShellState) -> Result<Ct
Ok(Ctr::Integer(state.last_exit_code.into()))
}
const EXIT_DOCSTRING: &str = "Takes on integer input. calls libc exit() with given argument.";
fn exit_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
let mut ret = -1;
if let Ctr::Integer(i) = *ast.car {
ret = i;
} else {
eprintln!("WARNING: input was not an integer. Exiting -1.")
}
unsafe {
exit(ret as i32);
}
}
const BG_DOCSTRING: &str = "Calls a binary off disk with given arguments.
Arguments may be of any type except lambda. If a symbol is not defined it will be passed as a string.
first argument (command name) will be found on path (or an error returned).
@ -780,7 +768,34 @@ fn cd_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
}
}
const EXIT_DOCSTRING: &str = "Takes on input: an integer used as an exit code.
Entire REPL process quits with exit code.";
fn exit_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
if let Ctr::Integer(i) = *ast.car {
if i > 2 ^ 32 {
panic!("argument to exit too large!")
} else {
process::exit(i as i32);
}
} else {
panic!("impossible argument to exit")
}
}
pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>>) {
syms.insert(
"exit".to_string(),
Symbol {
name: String::from("exit"),
args: Args::Strict(vec![Type::Integer]),
conditional_branches: false,
docs: EXIT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(exit_callback)),
..Default::default()
},
);
let pid = unistd::getpid();
let pgid_res = unistd::getpgid(Some(pid));
let sid_res = unistd::getsid(Some(pid));
@ -986,7 +1001,7 @@ mod tests {
let result = vec!["binary"];
let mut syms = SymTable::new();
static_stdlib(&mut syms);
static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ok(ref s) = lex(&document.to_string()) {
assert_eq!(
@ -1004,7 +1019,7 @@ mod tests {
let result = vec!["binary", "--flag=1", "122", "yeet", "true"];
let mut syms = SymTable::new();
static_stdlib(&mut syms);
static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ok(ref s) = lex(&document.to_string()) {
assert_eq!(
@ -1022,7 +1037,7 @@ mod tests {
let result = vec!["binary", "--flag=1", "122", "yeet", "true", "syms"];
let mut syms = SymTable::new();
static_stdlib(&mut syms);
static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ok(ref s) = lex(&document.to_string()) {
assert_eq!(
@ -1041,7 +1056,7 @@ mod tests {
let result = vec!["binary", "--flag=1", "122", "yeet", "true", "1"];
let mut syms = SymTable::new();
static_stdlib(&mut syms);
static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&decl.to_string()).unwrap(), &mut syms).unwrap();
@ -1061,7 +1076,7 @@ mod tests {
let result = vec!["binary", "--flag=1", "122", "yeet", "true", "3"];
let mut syms = SymTable::new();
static_stdlib(&mut syms);
static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ok(ref s) = lex(&document.to_string()) {
assert_eq!(

View file

@ -25,6 +25,7 @@ use crate::run::{run_callback, RUN_DOCSTRING};
use std::rc::Rc;
use std::cell::RefCell;
use std::env::vars;
use std::io;
#[cfg(feature = "posix")]
use crate::posix;
@ -63,7 +64,16 @@ fn prompt_delimiter_default_callback(_: &Seg, _: &mut SymTable) -> Result<Ctr, T
/// inserts all stdlib functions that can be inserted without
/// any kind of further configuration data into a symtable
pub fn static_stdlib_overwrites(syms: &mut SymTable) {
static_stdlib(syms);
static_stdlib(
syms,
|arg: &String| print!("{}", arg),
|| -> String {
let _= io::stdout();
let mut input = String::new();
io::stdin().read_line(&mut input).expect("couldnt read user input");
input.trim().to_string()
},
);
window::add_window_lib_funcs(syms);
file::add_file_lib(syms);