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:
Ava Apples Affine 2023-05-21 23:53:00 +00:00
parent 825854fd42
commit 6969ea63bc
7 changed files with 309 additions and 131 deletions

View file

@ -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)
}