usability improvements to env and def
* env prints variables and functions in seperate columns * run/stl seperation of concerns significantly better * def doesnt store lists or lambdas in the environment
This commit is contained in:
parent
825854fd42
commit
6969ea63bc
7 changed files with 309 additions and 131 deletions
|
|
@ -16,7 +16,8 @@
|
|||
*/
|
||||
|
||||
use crate::eval::eval;
|
||||
use crate::segment::{Ctr, Seg};
|
||||
use crate::segment::{Ctr, Seg, Type};
|
||||
use crate::stdlib::{CONSOLE_XDIM_VNAME, RELISH_DEFAULT_CONS_WIDTH};
|
||||
use crate::sym::{SymTable, Symbol, UserFn, ValueType};
|
||||
use std::env;
|
||||
|
||||
|
|
@ -129,19 +130,76 @@ pub const ENV_DOCSTRING: &str = "takes no arguments
|
|||
prints out all available symbols and their associated values";
|
||||
|
||||
pub fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
// get width of current output
|
||||
let xdim: i128;
|
||||
if let Ctr::Integer(dim) = *syms
|
||||
.call_symbol(&CONSOLE_XDIM_VNAME.to_string(), &Seg::new(), true)
|
||||
.unwrap_or_else(|_: String| Box::new(Ctr::None)) {
|
||||
xdim = dim;
|
||||
} else {
|
||||
println!("{} contains non integer value, defaulting to {}",
|
||||
CONSOLE_XDIM_VNAME, RELISH_DEFAULT_CONS_WIDTH);
|
||||
xdim = RELISH_DEFAULT_CONS_WIDTH as i128;
|
||||
}
|
||||
|
||||
let mut v_col_len = 0;
|
||||
let mut f_col_len = 0;
|
||||
let mut functions = vec![];
|
||||
println!("VARIABLES:");
|
||||
let mut variables = vec![];
|
||||
for (name, val) in syms.iter() {
|
||||
match val.value {
|
||||
ValueType::VarForm(_) => {
|
||||
println!(" {}: {}", &name, val.value);
|
||||
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()),
|
||||
}
|
||||
_ => functions.push(name.clone()),
|
||||
|
||||
if token.len() > v_col_len && token.len() < xdim as usize {
|
||||
v_col_len = token.len();
|
||||
}
|
||||
|
||||
variables.push(token);
|
||||
} else {
|
||||
if f_col_len < name.len() && name.len() < xdim as usize {
|
||||
f_col_len = name.len();
|
||||
}
|
||||
functions.push(name.clone());
|
||||
}
|
||||
}
|
||||
println!("FUNCTIONS:");
|
||||
|
||||
let mut n_v_cols = xdim / v_col_len as i128;
|
||||
// now decrement to make sure theres room for two spaces of padding
|
||||
while n_v_cols > 1 && xdim % (v_col_len as i128) < (2 * n_v_cols) {
|
||||
n_v_cols -= 1;
|
||||
}
|
||||
// again for functions
|
||||
let mut n_f_cols = xdim / f_col_len as i128;
|
||||
while n_f_cols > 1 && xdim & (f_col_len as i128) < (2 * n_f_cols) {
|
||||
n_f_cols -= 1;
|
||||
}
|
||||
|
||||
let mut col_iter = 0;
|
||||
println!("VARIABLES:");
|
||||
for var in variables {
|
||||
print!("{:v_col_len$}", var);
|
||||
col_iter += 1;
|
||||
if col_iter % n_v_cols == 0 {
|
||||
print!("\n");
|
||||
} else {
|
||||
print!(" ");
|
||||
}
|
||||
}
|
||||
println!("\nFUNCTIONS:");
|
||||
col_iter = 0;
|
||||
for func in functions {
|
||||
println!(" {}", func);
|
||||
print!("{:f_col_len$}", func);
|
||||
col_iter += 1;
|
||||
if col_iter % n_f_cols == 0 {
|
||||
print!("\n");
|
||||
} else {
|
||||
print!(" ");
|
||||
}
|
||||
}
|
||||
Ok(Ctr::None)
|
||||
}
|
||||
|
|
@ -335,7 +393,7 @@ pub fn store_callback(ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result<C
|
|||
var_val_form = &outer_scope_val;
|
||||
},
|
||||
_ if !is_var => return Err("arg list must at least be a list".to_string()),
|
||||
_ => unimplemented!(), // rustc is haunted
|
||||
_ => unimplemented!(), // rustc is haunted and cursed
|
||||
}
|
||||
|
||||
if is_var {
|
||||
|
|
@ -353,11 +411,17 @@ pub fn store_callback(ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result<C
|
|||
Symbol::from_ast(&name, &docs, &outer_seg, None),
|
||||
);
|
||||
if env_cfg {
|
||||
let mut s = var_val.to_string();
|
||||
if let Ctr::String(tok) = var_val {
|
||||
s = tok;
|
||||
match var_val.to_type() {
|
||||
Type::Lambda => {},
|
||||
Type::Seg => {},
|
||||
_ => {
|
||||
let mut s = var_val.to_string();
|
||||
if let Ctr::String(tok) = var_val {
|
||||
s = tok;
|
||||
}
|
||||
env::set_var(name.clone(), s);
|
||||
}
|
||||
}
|
||||
env::set_var(name.clone(), s);
|
||||
}
|
||||
return Ok(Ctr::None)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue