Readme and clippy cleanups
This commit is contained in:
parent
cbd52de91b
commit
8cc0202a7b
13 changed files with 159 additions and 197 deletions
|
|
@ -25,8 +25,7 @@ The purpose of Relish is to create a highly portable, easy to integrate language
|
|||
* Contact
|
||||
[[https://matrix.to/#/#relish:matrix.sunnypup.io][Matrix chat: #relish:matrix.sunnypup.io]]
|
||||
|
||||
If you like Relish and want to support me in working on it consider donating:
|
||||
https://ko-fi.com/avaaffine
|
||||
If you like Relish and want to support me in working on it consider donating: [[https://ko-fi.com/avaaffine][Ava's Ko-Fi]].
|
||||
|
||||
* Documentation
|
||||
** Writing in Relish
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ Readers should be able to run the Relish repl to follow along with this guide an
|
|||
* Syntax
|
||||
** Data types
|
||||
Relish leverages the following data types:
|
||||
- Strings: delimited by ~'~, ~"~, or ~`~
|
||||
- Strings: delimited by one of the following: ~' " `~
|
||||
- Integers: up to 128 bit signed integers
|
||||
- Floats: all floats are stored as 64 bit floats
|
||||
- Booleans: ~true~ or ~false~
|
||||
- Symbols: an un-delimited chunk of text containing alphanumerics, ~-~, ~_~, or ~?~
|
||||
- Symbols: an un-delimited chunk of text containing alphanumerics or one of the following: ~- _ ?~
|
||||
|
||||
Symbols and Functions can contain data of any type. there is no immediate restriction on what can be set/passed to what..... However, internally Relish is typed, and many builtin functions will get picky about what types are passed to them.
|
||||
** S-Expressions
|
||||
|
|
|
|||
|
|
@ -56,9 +56,10 @@ impl fmt::Display for Traceback {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::convert::Into<String> for Traceback {
|
||||
fn into(self) -> String {
|
||||
format!("{}", self)
|
||||
|
||||
impl std::convert::From<Traceback> for String {
|
||||
fn from(arg: Traceback) -> Self {
|
||||
format!("{}", arg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ pub fn eval(ast: &Seg, syms: &mut SymTable) -> Result<Box<Ctr>, Traceback> {
|
|||
}
|
||||
},
|
||||
|
||||
Ctr::Lambda(ref l) => return Ok(call_lambda(l, arg_cdr, syms)?.clone()),
|
||||
Ctr::Lambda(ref l) => return Ok(call_lambda(l, arg_cdr, syms)?),
|
||||
|
||||
Ctr::Symbol(ref tok) => {
|
||||
let outer_scope_seg_holder: Seg;
|
||||
|
|
|
|||
|
|
@ -43,14 +43,12 @@ pub fn lex(document: &String) -> Result<Box<Seg>, Traceback> {
|
|||
let document_normal = document.clone() + " ";
|
||||
let tree = process(&document_normal);
|
||||
|
||||
// TODO: Make multiple forms of Ok()
|
||||
// To represent the multiple passable outcomes
|
||||
return match tree {
|
||||
match tree {
|
||||
Err(e) => Err(start_trace(
|
||||
("<lex>", format!("Problem lexing document: {:?}", e))
|
||||
.into())),
|
||||
Ok(t) => Ok(t),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/* The logic used in lex
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use std::env::{var, current_dir};
|
|||
|
||||
fn get_paths() -> Vec<String> {
|
||||
Vec::from_iter(var("PATH")
|
||||
.unwrap_or("".to_string().into())
|
||||
.unwrap_or("".to_string())
|
||||
.split(':')
|
||||
.map(String::from))
|
||||
}
|
||||
|
|
@ -69,7 +69,7 @@ pub fn run_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
if let Ctr::String(ref filename) = *ast.car {
|
||||
if filename.ends_with(".rls") {
|
||||
if let Some(filepath) = find_on_path(filename.to_string()) {
|
||||
return run(filepath, syms)
|
||||
run(filepath, syms)
|
||||
.and(Ok(Ctr::None))
|
||||
} else {
|
||||
let canonical_path_res = fs::canonicalize(filename);
|
||||
|
|
@ -90,7 +90,7 @@ pub fn run_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
).and(Ok(Ctr::None))
|
||||
}
|
||||
} else {
|
||||
return Err(start_trace(
|
||||
Err(start_trace(
|
||||
("<call script>", "binary called, unimplemented!")
|
||||
.into()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ Example: (pop (1 2 3)) -> (1 (2 3)).
|
|||
The head can then be accessed by car and the rest can be accessed by cdr.";
|
||||
fn pop_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
if let Ctr::Seg(ref s) = *ast.car {
|
||||
if s.len() < 1 {
|
||||
if s.is_empty() {
|
||||
return Err(start_trace(("pop", "input is empty").into()));
|
||||
}
|
||||
let mut ret = Seg::new();
|
||||
|
|
@ -134,7 +134,7 @@ Example: (dq (1 2 3)) -> (3 (1 2)).
|
|||
The last element can then be accessed by car and the rest can be accessed by cdr.";
|
||||
fn dequeue_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
if let Ctr::Seg(ref s) = *ast.car {
|
||||
if s.len() < 1 {
|
||||
if s.is_empty() {
|
||||
return Err(start_trace(("dequeue", "expected an input").into()));
|
||||
}
|
||||
let mut rest = Seg::new();
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
name.clone(),
|
||||
Symbol::from_ast(
|
||||
name, &"variable used in let form".to_string(),
|
||||
&Seg::from_mono(Box::new(*var_val_res.unwrap().clone())),
|
||||
&Seg::from_mono(Box::new(*var_val_res.unwrap())),
|
||||
None),
|
||||
);
|
||||
locals.push(name.clone());
|
||||
|
|
@ -214,7 +214,7 @@ fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
if !eval_forms.circuit(&mut |eval_form: &Ctr| -> bool {
|
||||
let res: Result<Box<Ctr>, Traceback>;
|
||||
if let Ctr::Seg(ref eval_tree) = eval_form {
|
||||
res = eval(&eval_tree, &mut localsyms);
|
||||
res = eval(eval_tree, &mut localsyms);
|
||||
} else {
|
||||
let eval_tree = Seg::from_mono(Box::new(eval_form.clone()));
|
||||
let intermediate = eval(&eval_tree, &mut localsyms);
|
||||
|
|
@ -234,7 +234,7 @@ fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
return false;
|
||||
}
|
||||
|
||||
result = res.unwrap().clone();
|
||||
result = res.unwrap();
|
||||
true
|
||||
}) {
|
||||
assert!(err_trace.depth() > 0);
|
||||
|
|
@ -314,7 +314,7 @@ fn while_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(*(result.unwrap()).clone())
|
||||
Ok(*(result.unwrap()))
|
||||
}
|
||||
|
||||
const CIRCUIT_DOCSTRING: &str = "traverses a list of N un-evaluated forms.
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ fn eval_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
Err(e) => Err(e.with_trace(
|
||||
("eval", "evaluation failure")
|
||||
.into())),
|
||||
Ok(s) => Ok(*s.clone()),
|
||||
Ok(s) => Ok(*s),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ fn eval_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
Err(e) => Err(e.with_trace(
|
||||
("eval", "evaluation failure")
|
||||
.into())),
|
||||
Ok(s) => Ok(*s.clone()),
|
||||
Ok(s) => Ok(*s),
|
||||
}
|
||||
} else {
|
||||
Ok(res)
|
||||
|
|
@ -101,7 +101,7 @@ fn help_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
return Err(start_trace(("help", "expected one input").into()));
|
||||
}
|
||||
if let Ctr::Symbol(ref symbol) = *ast.car {
|
||||
if let Some(ref sym) = syms.get(symbol) {
|
||||
if let Some(sym) = syms.get(symbol) {
|
||||
let args_str: String;
|
||||
if let ValueType::VarForm(_) = sym.value {
|
||||
args_str = "(its a variable)".to_string();
|
||||
|
|
@ -132,18 +132,12 @@ returns true or false according to whether or not the symbol is found in the sym
|
|||
fn isset_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
if ast.len() != 1 {
|
||||
Err(start_trace(("set?", "expcted one input").into()))
|
||||
} else {
|
||||
if let Ctr::Symbol(ref symbol) = *ast.car {
|
||||
if let Some(_) = syms.get(symbol) {
|
||||
Ok(Ctr::Bool(true))
|
||||
} else {
|
||||
Ok(Ctr::Bool(false))
|
||||
}
|
||||
} else if let Ctr::Symbol(ref symbol) = *ast.car {
|
||||
Ok(Ctr::Bool(syms.get(symbol).is_some()))
|
||||
} else {
|
||||
Err(start_trace(("set?", "expected argument to be a input").into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ENV_DOCSTRING: &str = "takes no arguments
|
||||
prints out all available symbols and their associated values";
|
||||
|
|
@ -166,12 +160,11 @@ fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
let mut variables = vec![];
|
||||
for (name, val) in syms.iter() {
|
||||
if let ValueType::VarForm(l) = &val.value {
|
||||
let token: String;
|
||||
match l.to_type() {
|
||||
Type::Lambda => token = format!("{}: <lambda>", name),
|
||||
Type::Seg => token = format!("{}: <form>", name),
|
||||
_ => token = format!("{}: {}", name, val.value.to_string()),
|
||||
}
|
||||
let token: String = match l.to_type() {
|
||||
Type::Lambda => format!("{}: <lambda>", name),
|
||||
Type::Seg => format!("{}: <form>", name),
|
||||
_ => format!("{}: {}", name, val.value),
|
||||
};
|
||||
|
||||
if token.len() > v_col_len && token.len() < xdim as usize {
|
||||
v_col_len = token.len();
|
||||
|
|
@ -203,7 +196,7 @@ fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
print!("{:v_col_len$}", var);
|
||||
col_iter += 1;
|
||||
if col_iter % n_v_cols == 0 {
|
||||
print!("\n");
|
||||
println!();
|
||||
} else {
|
||||
print!(" ");
|
||||
}
|
||||
|
|
@ -214,7 +207,7 @@ fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
print!("{:f_col_len$}", func);
|
||||
col_iter += 1;
|
||||
if col_iter % n_f_cols == 0 {
|
||||
print!("\n");
|
||||
println!();
|
||||
} else {
|
||||
print!(" ");
|
||||
}
|
||||
|
|
@ -250,8 +243,7 @@ fn lambda_callback(
|
|||
}
|
||||
}) {
|
||||
Err(start_trace(("lambda", "lambda inputs should all be symbols").into()))
|
||||
} else {
|
||||
if let Ctr::Seg(ref eval_head) = *ast.cdr {
|
||||
} else if let Ctr::Seg(ref eval_head) = *ast.cdr {
|
||||
if let Ctr::Seg(_) = *eval_head.car {
|
||||
Ok(Ctr::Lambda(UserFn{
|
||||
ast: Box::new(eval_head.clone()),
|
||||
|
|
@ -263,7 +255,6 @@ fn lambda_callback(
|
|||
} else {
|
||||
Err(start_trace(("lambda", "not enough args").into()))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Err(start_trace(("lambda", "expected list of lambda inputs").into()))
|
||||
}
|
||||
|
|
@ -296,8 +287,7 @@ fn setdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
Err(start_trace(
|
||||
("set-doc", "expected two inputs")
|
||||
.into()))
|
||||
} else {
|
||||
if let Ctr::Symbol(ref symbol) = *ast.car {
|
||||
} else if let Ctr::Symbol(ref symbol) = *ast.car {
|
||||
if let Some(mut sym) = syms.remove(symbol) {
|
||||
if let Ctr::Seg(ref doc_node) = *ast.cdr {
|
||||
if let Ctr::String(ref doc) = *doc_node.car {
|
||||
|
|
@ -320,14 +310,12 @@ fn setdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
("set-doc", format!("{symbol} is undefined"))
|
||||
.into()))
|
||||
}
|
||||
|
||||
} else {
|
||||
Err(start_trace(
|
||||
("set-doc", "first input must be a symbol")
|
||||
.into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const STORE_DOCSTRING: &str = "allows user to define functions and variables.
|
||||
A call may take one of three forms:
|
||||
|
|
@ -377,11 +365,9 @@ fn store_callback(ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result<Ctr,
|
|||
}
|
||||
|
||||
return Ok(Ctr::None)
|
||||
} else {
|
||||
if ast.len() < 3 || ast.len() > 4 {
|
||||
} else if ast.len() < 3 || ast.len() > 4 {
|
||||
return Err(start_trace(("def", "expected 3 or 4 inputs").into()))
|
||||
}
|
||||
}
|
||||
|
||||
let mut iter: &Seg;
|
||||
if let Ctr::Seg(ref s) = *ast.cdr {
|
||||
|
|
@ -394,7 +380,7 @@ fn store_callback(ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result<Ctr,
|
|||
Ctr::String(ref s) => docs = s.clone(),
|
||||
Ctr::Symbol(ref s) => match syms.call_symbol(s, &Seg::new(), true) {
|
||||
Ok(d) => if let Ctr::String(doc) = *d {
|
||||
docs = doc.clone();
|
||||
docs = doc;
|
||||
} else {
|
||||
return Err(start_trace(("def", "expected docs input to evaluate to a string").into()))
|
||||
},
|
||||
|
|
@ -432,7 +418,6 @@ fn store_callback(ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result<Ctr,
|
|||
}
|
||||
|
||||
if is_var {
|
||||
let var_val: Ctr;
|
||||
let var_eval_result = eval(var_val_form, syms);
|
||||
if let Err(e) = var_eval_result {
|
||||
return Err(e.with_trace(
|
||||
|
|
@ -440,11 +425,11 @@ fn store_callback(ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result<Ctr,
|
|||
.into()))
|
||||
}
|
||||
let var_eval_final = *var_eval_result?;
|
||||
match var_eval_final {
|
||||
Ctr::Seg(ref s) if expand => var_val = *s.car.clone(),
|
||||
Ctr::Seg(ref s) if !expand => var_val = Ctr::Seg(s.clone()),
|
||||
_ => var_val = var_eval_final,
|
||||
}
|
||||
let var_val: Ctr = match var_eval_final {
|
||||
Ctr::Seg(ref s) if expand => *s.car.clone(),
|
||||
Ctr::Seg(ref s) if !expand => Ctr::Seg(s.clone()),
|
||||
_ => var_eval_final,
|
||||
};
|
||||
|
||||
let outer_seg = Seg::from_mono(Box::new(var_val.clone()));
|
||||
syms.insert(
|
||||
|
|
|
|||
|
|
@ -20,11 +20,7 @@ use crate::error::{Traceback, start_trace};
|
|||
use std::rc::Rc;
|
||||
|
||||
fn isnumeric(arg: &Ctr) -> bool {
|
||||
match arg {
|
||||
Ctr::Integer(_) => true,
|
||||
Ctr::Float(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(arg, Ctr::Integer(_) | Ctr::Float(_))
|
||||
}
|
||||
|
||||
const ADD_DOCSTRING: &str =
|
||||
|
|
@ -175,7 +171,7 @@ fn floatcast_callback(ast: &Seg, _: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
if let Ctr::Integer(i) = *ast.car {
|
||||
Ok(Ctr::Float(i as f64))
|
||||
} else if let Ctr::String(ref s) = *ast.car {
|
||||
let flt = str::parse::<f64>(&s);
|
||||
let flt = str::parse::<f64>(s);
|
||||
if flt.is_err() {
|
||||
Err(start_trace(
|
||||
("float", flt.err().unwrap().to_string())
|
||||
|
|
@ -452,7 +448,7 @@ fn inc_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
|
||||
let sym_ret = syms
|
||||
.remove(&var_name);
|
||||
if let None = sym_ret {
|
||||
if sym_ret.is_none() {
|
||||
return Err(start_trace(
|
||||
("inc", format!("input ({var_name}) is not defined"))
|
||||
.into()))
|
||||
|
|
@ -499,7 +495,7 @@ fn dec_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
|
||||
let sym_ret = syms
|
||||
.remove(&var_name);
|
||||
if let None = sym_ret {
|
||||
if sym_ret.is_none() {
|
||||
return Err(start_trace(
|
||||
("dec", format!("input ({var_name}) is not defined"))
|
||||
.into()))
|
||||
|
|
|
|||
|
|
@ -37,10 +37,7 @@ use {
|
|||
},
|
||||
std::{
|
||||
collections::VecDeque,
|
||||
cell::{
|
||||
RefCell, RefMut,
|
||||
BorrowMutError,
|
||||
},
|
||||
cell::RefCell,
|
||||
io::Result as IOResult,
|
||||
rc::Rc,
|
||||
fs::{
|
||||
|
|
@ -109,9 +106,9 @@ pub fn unign_sigs() {
|
|||
|
||||
// TODO: trigger this on SIGCHLD instead of traditional shell once per input
|
||||
pub fn check_jobs(state: &mut ShellState) {
|
||||
let mut idx = 0 as usize;
|
||||
let mut idx = 0usize;
|
||||
while idx < state.children.len() {
|
||||
if let Ok(_) = state.children[idx].try_wait() {
|
||||
if state.children[idx].try_wait().is_ok() {
|
||||
state.children.remove(idx);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -134,7 +131,7 @@ pub fn args_from_ast(ast: &Seg, syms: &mut SymTable) -> Vec<String> {
|
|||
match *res_ctr {
|
||||
Ctr::Lambda(_) => false,
|
||||
Ctr::Seg(_) => false,
|
||||
Ctr::String(s) => args.push(s.clone()) == (),
|
||||
Ctr::String(s) => args.push(s) == (),
|
||||
_ => args.push(res_ctr.to_string()) == (),
|
||||
}
|
||||
} else {
|
||||
|
|
@ -178,15 +175,13 @@ fn launch_command(
|
|||
newchld = Command::new(path)
|
||||
.pre_exec(move || -> IOResult<()> {
|
||||
let pid = unistd::getpid();
|
||||
if let Err(_) = unistd::setpgid(pid, pid) {
|
||||
if unistd::setpgid(pid, pid).is_err() {
|
||||
// crying would be nice... if you had eyes
|
||||
}
|
||||
|
||||
if !background {
|
||||
if let Err(_) = unistd::tcsetpgrp(0, pid) {
|
||||
if !background &&unistd::tcsetpgrp(0, pid).is_err() {
|
||||
// you wish to scream, but fork() has taken from you your throat
|
||||
}
|
||||
}
|
||||
|
||||
unign_sigs();
|
||||
Ok(())
|
||||
|
|
@ -255,8 +250,7 @@ fn make_foreground(pid: u32, state: &mut ShellState) -> Result<(), String>{
|
|||
|
||||
state.last_exit_code = exit
|
||||
.code()
|
||||
.or(Some(-1))
|
||||
.unwrap();
|
||||
.unwrap_or(-1);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -298,8 +292,7 @@ fn load_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Resu
|
|||
Err(start_trace(
|
||||
("load", "empty command")
|
||||
.into()))
|
||||
} else {
|
||||
if let Some(filepath) = run::find_on_path(args.pop_front().unwrap()) {
|
||||
} else if let Some(filepath) = run::find_on_path(args.pop_front().unwrap()) {
|
||||
if let Err(e) = launch_command(
|
||||
filepath,
|
||||
&Vec::from(args.make_contiguous()),
|
||||
|
|
@ -322,7 +315,6 @@ fn load_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Resu
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const PIPE_DOCSTRING: &str = "Calls a sequence of shell commands.
|
||||
Each one has their output redirected to the input of the next one.
|
||||
|
|
@ -385,8 +377,7 @@ fn pipe_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Resu
|
|||
Err(start_trace(
|
||||
("pipe", err)
|
||||
.into()))
|
||||
} else {
|
||||
if lastpid > 0 {
|
||||
} else if lastpid > 0 {
|
||||
if let Some(pos) = state.children
|
||||
.iter()
|
||||
.position(|x| x.id() == lastpid)
|
||||
|
|
@ -396,7 +387,7 @@ fn pipe_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Resu
|
|||
.expect("failed to wait on last child");
|
||||
state.last_exit_code = exit.status
|
||||
.code()
|
||||
.or_else(|| {Some(-1)})
|
||||
.or(Some(-1))
|
||||
.unwrap();
|
||||
|
||||
println!("{}", String::from_utf8_lossy(&exit.stdout));
|
||||
|
|
@ -412,7 +403,6 @@ fn pipe_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Resu
|
|||
.into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LOAD_TO_STRING_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.
|
||||
|
|
@ -437,8 +427,7 @@ fn load_to_string_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellStat
|
|||
Err(start_trace(
|
||||
("load-to-string", "command is empty")
|
||||
.into()))
|
||||
} else {
|
||||
if let Some(filepath) = run::find_on_path(args.pop_front().unwrap()) {
|
||||
} else if let Some(filepath) = run::find_on_path(args.pop_front().unwrap()) {
|
||||
let res = Command::new(filepath).args(args).output();
|
||||
if let Ok(output) = res {
|
||||
if let Some(code) = output.status.code() {
|
||||
|
|
@ -448,7 +437,7 @@ fn load_to_string_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellStat
|
|||
Ok(Ctr::String(string.trim_end().to_string()))
|
||||
} else {
|
||||
Err(start_trace(
|
||||
("load-to-string", format!("couldn't marshall utf-8 command output into a string"))
|
||||
("load-to-string", "couldn't marshall utf-8 command output into a string")
|
||||
.into()))
|
||||
}
|
||||
} else {
|
||||
|
|
@ -463,7 +452,6 @@ fn load_to_string_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellStat
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: rework this callback to reduce spaghett
|
||||
const LOAD_WITH_DOCSTRING: &str = "Takes two arguments.
|
||||
|
|
@ -514,7 +502,7 @@ fn load_with_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) ->
|
|||
return false
|
||||
}
|
||||
stdin = Some(Stdio::from(input.ok().unwrap()));
|
||||
return true
|
||||
true
|
||||
},
|
||||
"stdout" => {
|
||||
if !stdout.is_none() {
|
||||
|
|
@ -531,7 +519,7 @@ fn load_with_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) ->
|
|||
return false
|
||||
}
|
||||
stdout = Some(Stdio::from(out.ok().unwrap()));
|
||||
return true
|
||||
true
|
||||
},
|
||||
"stderr" => {
|
||||
if !stderr.is_none() {
|
||||
|
|
@ -548,7 +536,7 @@ fn load_with_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) ->
|
|||
return false
|
||||
}
|
||||
stderr = Some(Stdio::from(err.ok().unwrap()));
|
||||
return true
|
||||
true
|
||||
},
|
||||
_ => {
|
||||
e = Some(format!("can only override stdin, stdout, or stderr"));
|
||||
|
|
@ -668,8 +656,7 @@ fn bg_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Result
|
|||
Err(start_trace(
|
||||
("bg", "empty command")
|
||||
.into()))
|
||||
} else {
|
||||
if let Some(filepath) = run::find_on_path(args.pop_front().unwrap()) {
|
||||
} else if let Some(filepath) = run::find_on_path(args.pop_front().unwrap()) {
|
||||
if let Err(e) = launch_command(
|
||||
filepath,
|
||||
&Vec::from(args.make_contiguous()),
|
||||
|
|
@ -692,7 +679,6 @@ fn bg_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Result
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const FG_DOCSTRING: &str = "takes one argument (an integer).
|
||||
Integer is presumed to be a PID of a running background job.
|
||||
|
|
@ -727,7 +713,7 @@ const CD_DOCSTRING: &str =
|
|||
fn cd_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
if let Ctr::String(ref dir) = *ast.car {
|
||||
let dirp = Path::new(dir);
|
||||
if let Err(s) = set_current_dir(&dirp) {
|
||||
if let Err(s) = set_current_dir(dirp) {
|
||||
Err(start_trace(
|
||||
("cd", s.to_string())
|
||||
.into()))
|
||||
|
|
@ -746,7 +732,7 @@ pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>
|
|||
let pgid_res = unistd::getpgid(Some(pid));
|
||||
let sid_res = unistd::getsid(Some(pid));
|
||||
|
||||
if !pgid_res.is_ok() || !sid_res.is_ok() {
|
||||
if pgid_res.is_err() || sid_res.is_err() {
|
||||
panic!("couldn't get pgid")
|
||||
}
|
||||
let pgid = pgid_res.ok().unwrap();
|
||||
|
|
@ -760,14 +746,14 @@ pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>
|
|||
state.parent_sid = sid;
|
||||
if let Ok(attr) = tcgetattr(0) {
|
||||
state.attr = Some(attr.clone());
|
||||
shattr = attr.clone();
|
||||
shattr = attr;
|
||||
} else {
|
||||
panic!("couldn't get term attrs");
|
||||
}
|
||||
}
|
||||
|
||||
let term_pgrp_res = unistd::tcgetpgrp(0);
|
||||
if !term_pgrp_res.is_ok() {
|
||||
if term_pgrp_res.is_err() {
|
||||
panic!("couldn't get terminal's pgrp: {:?}", term_pgrp_res)
|
||||
}
|
||||
|
||||
|
|
@ -898,16 +884,13 @@ pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>
|
|||
symtable,
|
||||
&mut lts_ss
|
||||
.try_borrow_mut()
|
||||
.or(Ok::<RefMut<'_, ShellState>, BorrowMutError>(
|
||||
RefCell::from(ShellState{
|
||||
.unwrap_or(RefCell::from(ShellState{
|
||||
parent_pid: pid,
|
||||
parent_sid: pgid,
|
||||
children: vec![],
|
||||
last_exit_code: 0,
|
||||
attr: Some(shattr.clone()),
|
||||
}).borrow_mut()))
|
||||
.unwrap()
|
||||
)
|
||||
})),
|
||||
..Default::default()
|
||||
},
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ fn concat_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
match arg {
|
||||
// should be a thing here
|
||||
Ctr::Symbol(_) => return false,
|
||||
Ctr::String(s) => string.push_str(&s),
|
||||
Ctr::String(s) => string.push_str(s),
|
||||
Ctr::Integer(i) => string.push_str(&i.to_string()),
|
||||
Ctr::Float(f) => string.push_str(&f.to_string()),
|
||||
Ctr::Bool(b) => string.push_str(&b.to_string()),
|
||||
|
|
@ -56,7 +56,7 @@ fn concat_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
("concat", "highly suspicious that an input was an unevaluated symbol")
|
||||
.into()))
|
||||
}
|
||||
return Ok(Ctr::String(string));
|
||||
Ok(Ctr::String(string))
|
||||
}
|
||||
|
||||
const STRLEN_DOCSTRING: &str = "Takes a single arg of any type.
|
||||
|
|
@ -147,7 +147,7 @@ fn split_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
.into()))
|
||||
}
|
||||
|
||||
if let Ctr::String(ref s) = &*second_arg_obj {
|
||||
if let Ctr::String(ref s) = second_arg_obj {
|
||||
delim_str = s.clone();
|
||||
} else {
|
||||
return Err(start_trace(
|
||||
|
|
@ -174,7 +174,7 @@ fn input_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
io::stdin().read_line(&mut input).expect("couldnt read user input");
|
||||
Ok(Ctr::String(input.trim().to_string()))
|
||||
} else {
|
||||
return Err(start_trace(
|
||||
Err(start_trace(
|
||||
("input", "expected a string input to prompt user with")
|
||||
.into()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,13 +143,13 @@ impl SymTable {
|
|||
if let ValueType::VarForm(ref val) = symbol.value {
|
||||
match **val {
|
||||
Ctr::Lambda(ref l) if call_func => {
|
||||
return call_lambda(
|
||||
call_lambda(
|
||||
l,
|
||||
&Box::new(Ctr::Seg(args.clone())),
|
||||
self
|
||||
)
|
||||
},
|
||||
_ => return Ok(val.clone()),
|
||||
_ => Ok(val.clone()),
|
||||
}
|
||||
} else if call_func {
|
||||
symbol.call(args, self)
|
||||
|
|
@ -343,7 +343,7 @@ impl Symbol {
|
|||
errcon = eval_res.err().unwrap();
|
||||
return false
|
||||
}
|
||||
outer_scope_seg_storage.append(eval_res.unwrap().clone());
|
||||
outer_scope_seg_storage.append(eval_res.unwrap());
|
||||
} else if let Ctr::Symbol(ref s) = arg {
|
||||
let eval_res = syms.call_symbol(
|
||||
s,
|
||||
|
|
@ -354,7 +354,7 @@ impl Symbol {
|
|||
errcon = eval_res.err().unwrap();
|
||||
return false
|
||||
}
|
||||
outer_scope_seg_storage.append(eval_res.unwrap().clone());
|
||||
outer_scope_seg_storage.append(eval_res.unwrap());
|
||||
} else {
|
||||
outer_scope_seg_storage.append(Box::new(arg.clone()));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue