fall back on shell command behaviour for undefined variables
Signed-off-by: Ava Hahn <ava@sunnypup.io>
This commit is contained in:
parent
0babc1986a
commit
c05b94e92a
5 changed files with 84 additions and 15 deletions
60
src/sym.rs
60
src/sym.rs
|
|
@ -18,6 +18,7 @@
|
|||
use crate::eval::eval;
|
||||
use crate::error::{Traceback, start_trace};
|
||||
use crate::segment::{Ctr, Seg, Type};
|
||||
use crate::stl::posix::POSIX_LOAD_NAME;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
|
@ -129,8 +130,42 @@ impl SymTable {
|
|||
args: &Seg,
|
||||
call_func: bool,
|
||||
) -> Result<Box<Ctr>, Traceback> {
|
||||
let outer_scope_seg: Seg;
|
||||
let mut call_args = args;
|
||||
let mut name_token = name.to_string();
|
||||
let mut symbol = match self.remove(name) {
|
||||
Some(s) => s,
|
||||
|
||||
/* implicit load:
|
||||
* on a call to an undefined function
|
||||
* assume a shell command is being run
|
||||
*/
|
||||
None if cfg!(feature="implicit-load")
|
||||
&& call_func => match self.remove(&POSIX_LOAD_NAME.to_string()) {
|
||||
Some(s) => {
|
||||
name_token = String::from(POSIX_LOAD_NAME);
|
||||
/* highly unfortunate circumstance
|
||||
* we must now rebuild the original ast
|
||||
* costs a whole clone of the args
|
||||
* this feature is non-standard
|
||||
*/
|
||||
outer_scope_seg = Seg::from(
|
||||
Box::from(Ctr::Symbol(name.to_string())),
|
||||
if let Ctr::None = *args.car {
|
||||
Box::from(Ctr::None)
|
||||
} else {
|
||||
Box::from(Ctr::Seg(args.clone()))
|
||||
},
|
||||
);
|
||||
call_args = &outer_scope_seg;
|
||||
s
|
||||
},
|
||||
None => return Err(
|
||||
Traceback::new()
|
||||
.with_trace(("(implicit load)", "(load function not found)").into())
|
||||
)
|
||||
},
|
||||
|
||||
None => return Err(
|
||||
Traceback::new()
|
||||
.with_trace((name, "(is an undefined symbol)").into())
|
||||
|
|
@ -139,7 +174,7 @@ impl SymTable {
|
|||
// will re-increment when inserted
|
||||
// but we dont want to increment it
|
||||
symbol.__generation -= 1;
|
||||
self.insert(name.to_string(), symbol.clone());
|
||||
self.insert(name_token, symbol.clone());
|
||||
if let ValueType::VarForm(ref val) = symbol.value {
|
||||
match **val {
|
||||
Ctr::Lambda(ref l) if call_func => {
|
||||
|
|
@ -165,7 +200,7 @@ impl SymTable {
|
|||
}
|
||||
}
|
||||
if call_func {
|
||||
symbol.call(args, self)
|
||||
symbol.call(call_args, self)
|
||||
} else {
|
||||
// its a function but call_func is off
|
||||
Ok(Box::new(Ctr::Symbol(name.to_string())))
|
||||
|
|
@ -173,14 +208,19 @@ impl SymTable {
|
|||
}
|
||||
|
||||
pub fn is_function_type(&self, name: &String) -> Option<bool> {
|
||||
if let ValueType::VarForm(ref val) = self.get(name)?.value {
|
||||
match **val {
|
||||
Ctr::Lambda(_) => Some(true),
|
||||
Ctr::Symbol(ref n) => self.is_function_type(n),
|
||||
_ => Some(false),
|
||||
}
|
||||
} else {
|
||||
Some(true)
|
||||
match self.get(name) {
|
||||
/* implicit-load: assume you just drew load function */
|
||||
None if cfg!(feature="implicit-load") => Some(true),
|
||||
Some(value) => if let ValueType::VarForm(ref val) = value.value {
|
||||
match **val {
|
||||
Ctr::Lambda(_) => Some(true),
|
||||
Ctr::Symbol(ref n) => self.is_function_type(n),
|
||||
_ => Some(false),
|
||||
}
|
||||
} else {
|
||||
Some(true)
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue