mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: Better file path handling through pointers.
This commit is contained in:
parent
7bc98514bf
commit
ceb98244c7
@ -13,8 +13,8 @@
|
||||
// limitations under the License.
|
||||
use std::collections::btree_map;
|
||||
use std::collections::BTreeMap;
|
||||
use std::rc::Rc;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::{Op, OpPointer};
|
||||
|
||||
@ -38,7 +38,11 @@ impl Ops {
|
||||
pub struct Entry<'a>(btree_map::Entry<'a, String, Rc<Vec<Op>>>);
|
||||
|
||||
impl<'a> Entry<'a> {
|
||||
pub fn get_pointer_or_else<F: FnOnce() -> Vec<Op>, P: Into<PathBuf>>(self, f: F, path: P) -> OpPointer {
|
||||
pub fn get_pointer_or_else<F: FnOnce() -> Vec<Op>, P: Into<PathBuf>>(
|
||||
self,
|
||||
f: F,
|
||||
path: P,
|
||||
) -> OpPointer {
|
||||
let cached = self.0.or_insert_with(|| Rc::new(f())).clone();
|
||||
OpPointer::new(cached).with_path(path.into())
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ impl Builtins {
|
||||
|
||||
pub fn handle<P: AsRef<Path>, O, E>(
|
||||
&mut self,
|
||||
path: P,
|
||||
path: Option<P>,
|
||||
h: Hook,
|
||||
stack: &mut Vec<Rc<Value>>,
|
||||
env: Rc<RefCell<Environment<O, E>>>,
|
||||
@ -77,9 +77,9 @@ impl Builtins {
|
||||
Hook::Assert => self.assert(stack),
|
||||
Hook::Convert => self.convert(stack, env),
|
||||
Hook::Out => self.out(path, stack, env),
|
||||
Hook::Map => self.map(path, stack, env),
|
||||
Hook::Filter => self.filter(path, stack, env),
|
||||
Hook::Reduce => self.reduce(path, stack, env),
|
||||
Hook::Map => self.map(stack, env),
|
||||
Hook::Filter => self.filter(stack, env),
|
||||
Hook::Reduce => self.reduce(stack, env),
|
||||
Hook::Regex => self.regex(stack),
|
||||
Hook::Range => self.range(stack),
|
||||
Hook::Trace(pos) => self.trace(stack, pos, env),
|
||||
@ -168,7 +168,7 @@ impl Builtins {
|
||||
},
|
||||
&path,
|
||||
);
|
||||
let mut vm = VM::with_pointer(path, op_pointer, env.clone());
|
||||
let mut vm = VM::with_pointer(op_pointer, env.clone());
|
||||
vm.run()?;
|
||||
let result = Rc::new(vm.symbols_to_tuple(true));
|
||||
val_cache.insert(path.clone(), result.clone());
|
||||
@ -269,7 +269,7 @@ impl Builtins {
|
||||
|
||||
fn out<P: AsRef<Path>, O, E>(
|
||||
&self,
|
||||
path: P,
|
||||
path: Option<P>,
|
||||
stack: &mut Vec<Rc<Value>>,
|
||||
env: Rc<RefCell<Environment<O, E>>>,
|
||||
) -> Result<(), Error>
|
||||
@ -277,6 +277,11 @@ impl Builtins {
|
||||
O: std::io::Write,
|
||||
E: std::io::Write,
|
||||
{
|
||||
let path = if let Some(path) = path {
|
||||
path
|
||||
} else {
|
||||
return Err(dbg!(Error {}));
|
||||
};
|
||||
let val = stack.pop();
|
||||
if let Some(val) = val {
|
||||
let val = val.try_into()?;
|
||||
@ -330,9 +335,8 @@ impl Builtins {
|
||||
return Err(dbg!(Error {}));
|
||||
}
|
||||
|
||||
fn map<P: AsRef<Path>, O, E>(
|
||||
fn map<O, E>(
|
||||
&self,
|
||||
path: P,
|
||||
stack: &mut Vec<Rc<Value>>,
|
||||
env: Rc<RefCell<Environment<O, E>>>,
|
||||
) -> Result<(), Error>
|
||||
@ -366,12 +370,7 @@ impl Builtins {
|
||||
// push function argument on the stack.
|
||||
stack.push(e.clone());
|
||||
// call function and push it's result on the stack.
|
||||
result_elems.push(VM::fcall_impl(
|
||||
path.as_ref().to_owned(),
|
||||
f,
|
||||
stack,
|
||||
env.clone(),
|
||||
)?);
|
||||
result_elems.push(VM::fcall_impl(f, stack, env.clone())?);
|
||||
}
|
||||
stack.push(Rc::new(C(List(result_elems))));
|
||||
}
|
||||
@ -380,7 +379,7 @@ impl Builtins {
|
||||
for (ref name, ref val) in _flds {
|
||||
stack.push(val.clone());
|
||||
stack.push(Rc::new(P(Str(name.clone()))));
|
||||
let result = VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||
let result = VM::fcall_impl(f, stack, env.clone())?;
|
||||
if let &C(List(ref fval)) = result.as_ref() {
|
||||
// we expect them to be a list of exactly 2 items.
|
||||
if fval.len() != 2 {
|
||||
@ -400,7 +399,7 @@ impl Builtins {
|
||||
for c in s.chars() {
|
||||
stack.push(Rc::new(P(Str(c.to_string()))));
|
||||
// call function and push it's result on the stack.
|
||||
let result = VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||
let result = VM::fcall_impl(f, stack, env.clone())?;
|
||||
if let &P(Str(ref s)) = result.as_ref() {
|
||||
buf.push_str(s);
|
||||
} else {
|
||||
@ -414,9 +413,8 @@ impl Builtins {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn filter<P: AsRef<Path>, O, E>(
|
||||
fn filter<O, E>(
|
||||
&self,
|
||||
path: P,
|
||||
stack: &mut Vec<Rc<Value>>,
|
||||
env: Rc<RefCell<Environment<O, E>>>,
|
||||
) -> Result<(), Error>
|
||||
@ -450,8 +448,7 @@ impl Builtins {
|
||||
// push function argument on the stack.
|
||||
stack.push(e.clone());
|
||||
// call function and push it's result on the stack.
|
||||
let condition =
|
||||
VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||
let condition = VM::fcall_impl(f, stack, env.clone())?;
|
||||
// Check for empty or boolean results and only push e back in
|
||||
// if they are non empty and true
|
||||
match condition.as_ref() {
|
||||
@ -468,8 +465,7 @@ impl Builtins {
|
||||
for (ref name, ref val) in _flds {
|
||||
stack.push(val.clone());
|
||||
stack.push(Rc::new(P(Str(name.clone()))));
|
||||
let condition =
|
||||
VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||
let condition = VM::fcall_impl(f, stack, env.clone())?;
|
||||
// Check for empty or boolean results and only push e back in
|
||||
// if they are non empty and true
|
||||
match condition.as_ref() {
|
||||
@ -486,8 +482,7 @@ impl Builtins {
|
||||
for c in s.chars() {
|
||||
stack.push(Rc::new(P(Str(c.to_string()))));
|
||||
// call function and push it's result on the stack.
|
||||
let condition =
|
||||
VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||
let condition = VM::fcall_impl(f, stack, env.clone())?;
|
||||
// Check for empty or boolean results and only push c back in
|
||||
// if they are non empty and true
|
||||
match condition.as_ref() {
|
||||
@ -533,9 +528,8 @@ impl Builtins {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reduce<P: AsRef<Path>, O, E>(
|
||||
fn reduce<O, E>(
|
||||
&self,
|
||||
path: P,
|
||||
stack: &mut Vec<Rc<Value>>,
|
||||
env: Rc<RefCell<Environment<O, E>>>,
|
||||
) -> Result<(), Error>
|
||||
@ -575,7 +569,7 @@ impl Builtins {
|
||||
stack.push(dbg!(e.clone()));
|
||||
stack.push(dbg!(acc.clone()));
|
||||
// call function and push it's result on the stack.
|
||||
acc = VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||
acc = VM::fcall_impl(f, stack, env.clone())?;
|
||||
}
|
||||
}
|
||||
&C(Tuple(ref _flds)) => {
|
||||
@ -585,7 +579,7 @@ impl Builtins {
|
||||
stack.push(Rc::new(P(Str(name.clone()))));
|
||||
stack.push(dbg!(acc.clone()));
|
||||
// call function and push it's result on the stack.
|
||||
acc = VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||
acc = VM::fcall_impl(f, stack, env.clone())?;
|
||||
}
|
||||
}
|
||||
&P(Str(ref _s)) => {
|
||||
@ -594,7 +588,7 @@ impl Builtins {
|
||||
stack.push(dbg!(Rc::new(P(Str(c.to_string())))));
|
||||
stack.push(dbg!(acc.clone()));
|
||||
// call function and push it's result on the stack.
|
||||
acc = VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||
acc = VM::fcall_impl(f, stack, env.clone())?;
|
||||
}
|
||||
}
|
||||
_ => return Err(dbg!(Error {})),
|
||||
|
@ -30,7 +30,7 @@ macro_rules! assert_cases {
|
||||
(__impl__ $cases:expr) => {
|
||||
for case in $cases.drain(0..) {
|
||||
let env = Rc::new(RefCell::new(Environment::new(Vec::new(), Vec::new())));
|
||||
let mut vm = VM::new("foo.ucg", Rc::new(case.0), env);
|
||||
let mut vm = VM::new(Rc::new(case.0), env);
|
||||
vm.run().unwrap();
|
||||
assert_eq!(dbg!(vm.pop()).unwrap(), Rc::new(case.1));
|
||||
}
|
||||
@ -120,7 +120,7 @@ fn bind_op() {
|
||||
|
||||
for case in cases.drain(0..) {
|
||||
let env = Rc::new(RefCell::new(Environment::new(Vec::new(), Vec::new())));
|
||||
let mut vm = VM::new("bar.ucg", Rc::new(case.0), env);
|
||||
let mut vm = VM::new(Rc::new(case.0), env);
|
||||
vm.run().unwrap();
|
||||
let (name, result) = case.1;
|
||||
let v = vm.get_binding(name).unwrap();
|
||||
@ -578,7 +578,7 @@ macro_rules! assert_parse_cases {
|
||||
let ops = Rc::new(translate::AST::translate(stmts, &root));
|
||||
assert!(ops.len() > 0);
|
||||
let env = Rc::new(RefCell::new(Environment::new(Vec::new(), Vec::new())));
|
||||
let mut vm = VM::new("foo.ucg", ops.clone(), env);
|
||||
let mut vm = VM::new(ops.clone(), env);
|
||||
vm.run().unwrap();
|
||||
assert_eq!(vm.pop().unwrap(), Rc::new(case.1));
|
||||
}
|
||||
@ -763,7 +763,7 @@ fn simple_trace() {
|
||||
let ops = Rc::new(translate::AST::translate(stmts, &root));
|
||||
assert!(ops.len() > 0);
|
||||
let env = Rc::new(RefCell::new(Environment::new(Vec::new(), Vec::new())));
|
||||
let mut vm = VM::new("foo.ucg", ops.clone(), env);
|
||||
let mut vm = VM::new(ops.clone(), env);
|
||||
vm.run().unwrap();
|
||||
assert_eq!(vm.pop().unwrap(), Rc::new(P(Int(2))));
|
||||
let err_out = &vm.env.borrow().stderr;
|
||||
|
@ -35,8 +35,6 @@ where
|
||||
symbols: Stack,
|
||||
runtime: runtime::Builtins,
|
||||
ops: OpPointer,
|
||||
// TODO(jwall): This should be optional
|
||||
path: PathBuf,
|
||||
pub env: Rc<RefCell<Environment<O, E>>>,
|
||||
}
|
||||
|
||||
@ -45,25 +43,16 @@ where
|
||||
O: std::io::Write,
|
||||
E: std::io::Write,
|
||||
{
|
||||
pub fn new<P: Into<PathBuf>>(
|
||||
path: P,
|
||||
ops: Rc<Vec<Op>>,
|
||||
env: Rc<RefCell<Environment<O, E>>>,
|
||||
) -> Self {
|
||||
Self::with_pointer(path, OpPointer::new(ops), env)
|
||||
pub fn new(ops: Rc<Vec<Op>>, env: Rc<RefCell<Environment<O, E>>>) -> Self {
|
||||
Self::with_pointer(OpPointer::new(ops), env)
|
||||
}
|
||||
|
||||
pub fn with_pointer<P: Into<PathBuf>>(
|
||||
path: P,
|
||||
ops: OpPointer,
|
||||
env: Rc<RefCell<Environment<O, E>>>,
|
||||
) -> Self {
|
||||
pub fn with_pointer(ops: OpPointer, env: Rc<RefCell<Environment<O, E>>>) -> Self {
|
||||
Self {
|
||||
stack: Vec::new(),
|
||||
symbols: Stack::new(),
|
||||
runtime: runtime::Builtins::new(),
|
||||
ops: ops,
|
||||
path: path.into(),
|
||||
env: env,
|
||||
}
|
||||
}
|
||||
@ -74,7 +63,6 @@ where
|
||||
symbols: symbols,
|
||||
runtime: self.runtime.clone(),
|
||||
ops: self.ops.clone(),
|
||||
path: self.path.clone(),
|
||||
env: self.env.clone(),
|
||||
}
|
||||
}
|
||||
@ -327,8 +315,7 @@ where
|
||||
self.op_jump(jptr)
|
||||
}
|
||||
|
||||
pub fn fcall_impl<P: Into<PathBuf>>(
|
||||
path: P,
|
||||
pub fn fcall_impl(
|
||||
f: &Func,
|
||||
stack: &mut Vec<Rc<Value>>,
|
||||
env: Rc<RefCell<Environment<O, E>>>,
|
||||
@ -339,7 +326,7 @@ where
|
||||
ref snapshot,
|
||||
} = f;
|
||||
// use the captured scope snapshot for the function.
|
||||
let mut vm = Self::with_pointer(path, ptr.clone(), env).to_scoped(snapshot.clone());
|
||||
let mut vm = Self::with_pointer(ptr.clone(), env).to_scoped(snapshot.clone());
|
||||
for nm in bindings.iter() {
|
||||
// now put each argument on our scope stack as a binding.
|
||||
// TODO(jwall): This should do a better error if there is
|
||||
@ -355,8 +342,7 @@ where
|
||||
fn op_new_scope(&mut self, jp: i32, ptr: OpPointer) -> Result<(), Error> {
|
||||
let scope_snapshot = self.symbols.snapshot();
|
||||
dbg!(&ptr);
|
||||
let mut vm =
|
||||
Self::with_pointer(&self.path, ptr, self.env.clone()).to_scoped(scope_snapshot);
|
||||
let mut vm = Self::with_pointer(ptr, self.env.clone()).to_scoped(scope_snapshot);
|
||||
dbg!(&vm.stack);
|
||||
vm.run()?;
|
||||
dbg!(&vm.stack);
|
||||
@ -368,7 +354,7 @@ where
|
||||
fn op_fcall(&mut self) -> Result<(), Error> {
|
||||
let f = dbg!(self.pop())?;
|
||||
if let &F(ref f) = f.as_ref() {
|
||||
let val = Self::fcall_impl(&self.path, f, &mut self.stack, self.env.clone())?;
|
||||
let val = Self::fcall_impl(f, &mut self.stack, self.env.clone())?;
|
||||
self.push(dbg!(val))?;
|
||||
}
|
||||
Ok(())
|
||||
@ -673,14 +659,13 @@ where
|
||||
}
|
||||
self.merge_field_into_tuple(&mut flds, "this".to_owned(), Rc::new(this))?;
|
||||
if let Some(ptr) = pkg_ptr {
|
||||
let mut pkg_vm =
|
||||
Self::with_pointer(self.path.clone(), ptr.clone(), self.env.clone());
|
||||
let mut pkg_vm = Self::with_pointer(ptr.clone(), self.env.clone());
|
||||
pkg_vm.run()?;
|
||||
let pkg_func = pkg_vm.pop()?;
|
||||
self.merge_field_into_tuple(&mut flds, "pkg".to_owned(), pkg_func)?;
|
||||
}
|
||||
|
||||
let mut vm = Self::with_pointer(self.path.clone(), ptr.clone(), self.env.clone());
|
||||
let mut vm = Self::with_pointer(ptr.clone(), self.env.clone());
|
||||
vm.push(Rc::new(S("mod".to_owned())))?;
|
||||
vm.push(Rc::new(C(Tuple(flds))))?;
|
||||
vm.run()?;
|
||||
@ -806,7 +791,7 @@ where
|
||||
|
||||
fn op_runtime(&mut self, h: Hook) -> Result<(), Error> {
|
||||
self.runtime
|
||||
.handle(&self.path, h, &mut self.stack, self.env.clone())
|
||||
.handle(self.ops.path.as_ref(), h, &mut self.stack, self.env.clone())
|
||||
}
|
||||
|
||||
fn op_render(&mut self) -> Result<(), Error> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user