mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: pkg() functions *should* work now.
This commit is contained in:
parent
d09bd13f42
commit
7bc98514bf
@ -14,6 +14,7 @@
|
|||||||
use std::collections::btree_map;
|
use std::collections::btree_map;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use super::{Op, OpPointer};
|
use super::{Op, OpPointer};
|
||||||
|
|
||||||
@ -37,8 +38,8 @@ impl Ops {
|
|||||||
pub struct Entry<'a>(btree_map::Entry<'a, String, Rc<Vec<Op>>>);
|
pub struct Entry<'a>(btree_map::Entry<'a, String, Rc<Vec<Op>>>);
|
||||||
|
|
||||||
impl<'a> Entry<'a> {
|
impl<'a> Entry<'a> {
|
||||||
pub fn get_pointer_or_else<F: FnOnce() -> Vec<Op>>(self, f: F) -> 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();
|
let cached = self.0.or_insert_with(|| Rc::new(f())).clone();
|
||||||
OpPointer::new(cached)
|
OpPointer::new(cached).with_path(path.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,7 @@ pub struct Module {
|
|||||||
ptr: OpPointer,
|
ptr: OpPointer,
|
||||||
result_ptr: Option<usize>,
|
result_ptr: Option<usize>,
|
||||||
flds: Vec<(String, Rc<Value>)>,
|
flds: Vec<(String, Rc<Value>)>,
|
||||||
|
pkg_ptr: Option<OpPointer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::{Error, Op};
|
use super::{Error, Op};
|
||||||
@ -19,6 +20,7 @@ use super::{Error, Op};
|
|||||||
pub struct OpPointer {
|
pub struct OpPointer {
|
||||||
pub ops: Rc<Vec<Op>>,
|
pub ops: Rc<Vec<Op>>,
|
||||||
pub ptr: Option<usize>,
|
pub ptr: Option<usize>,
|
||||||
|
pub path: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpPointer {
|
impl OpPointer {
|
||||||
@ -27,9 +29,15 @@ impl OpPointer {
|
|||||||
Self {
|
Self {
|
||||||
ops: ops,
|
ops: ops,
|
||||||
ptr: None,
|
ptr: None,
|
||||||
|
path: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_path(mut self, path: PathBuf) -> Self {
|
||||||
|
self.path = Some(path);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn next(&mut self) -> Option<&Op> {
|
pub fn next(&mut self) -> Option<&Op> {
|
||||||
if let Some(i) = self.ptr {
|
if let Some(i) = self.ptr {
|
||||||
let nxt = i + 1;
|
let nxt = i + 1;
|
||||||
@ -70,6 +78,7 @@ impl OpPointer {
|
|||||||
Self {
|
Self {
|
||||||
ops: self.ops.clone(),
|
ops: self.ops.clone(),
|
||||||
ptr: None,
|
ptr: None,
|
||||||
|
path: self.path.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,15 @@ use std::rc::Rc;
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use super::environment::Environment;
|
use super::environment::Environment;
|
||||||
|
use super::pointer::OpPointer;
|
||||||
use super::Value::{C, F, P, S};
|
use super::Value::{C, F, P, S};
|
||||||
use super::VM;
|
use super::VM;
|
||||||
use super::{Composite, Error, Hook, Primitive, Value};
|
use super::{Composite, Error, Hook, Primitive, Value};
|
||||||
use crate::ast::Position;
|
use crate::ast::Position;
|
||||||
use crate::build::ir::Val;
|
use crate::build::ir::Val;
|
||||||
use crate::build::AssertCollector;
|
use crate::build::AssertCollector;
|
||||||
|
use crate::iter::OffsetStrIter;
|
||||||
|
use crate::parse::parse;
|
||||||
use Composite::{List, Tuple};
|
use Composite::{List, Tuple};
|
||||||
use Primitive::{Bool, Empty, Int, Str};
|
use Primitive::{Bool, Empty, Int, Str};
|
||||||
|
|
||||||
@ -147,14 +150,24 @@ impl Builtins {
|
|||||||
if val_cache.contains_key(path) {
|
if val_cache.contains_key(path) {
|
||||||
stack.push(val_cache[path].clone());
|
stack.push(val_cache[path].clone());
|
||||||
} else {
|
} else {
|
||||||
let op_pointer =
|
let op_pointer = env.borrow_mut().op_cache.entry(path).get_pointer_or_else(
|
||||||
env.borrow_mut()
|
|| {
|
||||||
.op_cache
|
// FIXME(jwall): We need to do proper error handling here.
|
||||||
.entry(path)
|
let p = PathBuf::from(&path);
|
||||||
.get_pointer_or_else(|| {
|
let root = p.parent().unwrap();
|
||||||
// FIXME(jwall): import
|
// first we read in the file
|
||||||
unimplemented!("Compiling paths are not implemented yet");
|
let mut f = File::open(&path).unwrap();
|
||||||
});
|
// then we parse it
|
||||||
|
let mut contents = String::new();
|
||||||
|
f.read_to_string(&mut contents).unwrap();
|
||||||
|
let iter = OffsetStrIter::new(&contents).with_src_file(&p);
|
||||||
|
let stmts = parse(iter, None).unwrap();
|
||||||
|
// then we create an ops from it
|
||||||
|
let ops = super::translate::AST::translate(stmts, &root);
|
||||||
|
ops
|
||||||
|
},
|
||||||
|
&path,
|
||||||
|
);
|
||||||
let mut vm = VM::with_pointer(path, op_pointer, env.clone());
|
let mut vm = VM::with_pointer(path, op_pointer, env.clone());
|
||||||
vm.run()?;
|
vm.run()?;
|
||||||
let result = Rc::new(vm.symbols_to_tuple(true));
|
let result = Rc::new(vm.symbols_to_tuple(true));
|
||||||
@ -176,7 +189,6 @@ impl Builtins {
|
|||||||
O: std::io::Write,
|
O: std::io::Write,
|
||||||
E: std::io::Write,
|
E: std::io::Write,
|
||||||
{
|
{
|
||||||
// TODO(jwall): include
|
|
||||||
let path = stack.pop();
|
let path = stack.pop();
|
||||||
let typ = stack.pop();
|
let typ = stack.pop();
|
||||||
let path = if let Some(val) = path {
|
let path = if let Some(val) = path {
|
||||||
@ -347,7 +359,6 @@ impl Builtins {
|
|||||||
return Err(dbg!(Error {}));
|
return Err(dbg!(Error {}));
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(jwall): This can also be tuples or strings.
|
|
||||||
match list.as_ref() {
|
match list.as_ref() {
|
||||||
&C(List(ref elems)) => {
|
&C(List(ref elems)) => {
|
||||||
let mut result_elems = Vec::new();
|
let mut result_elems = Vec::new();
|
||||||
@ -432,7 +443,6 @@ impl Builtins {
|
|||||||
return dbg!(Err(Error {}));
|
return dbg!(Err(Error {}));
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(jwall): This can also be tuples or strings.
|
|
||||||
let elems = match list.as_ref() {
|
let elems = match list.as_ref() {
|
||||||
&C(List(ref elems)) => {
|
&C(List(ref elems)) => {
|
||||||
let mut result_elems = Vec::new();
|
let mut result_elems = Vec::new();
|
||||||
@ -558,7 +568,6 @@ impl Builtins {
|
|||||||
return dbg!(Err(Error {}));
|
return dbg!(Err(Error {}));
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(jwall): This can also be tuples or strings.
|
|
||||||
match list.as_ref() {
|
match list.as_ref() {
|
||||||
&C(List(ref elems)) => {
|
&C(List(ref elems)) => {
|
||||||
for e in dbg!(elems).iter() {
|
for e in dbg!(elems).iter() {
|
||||||
|
@ -384,34 +384,30 @@ fn module_call() {
|
|||||||
assert_cases![
|
assert_cases![
|
||||||
vec![
|
vec![
|
||||||
InitTuple, // 0 // override tuple
|
InitTuple, // 0 // override tuple
|
||||||
Sym("one".to_owned()), // 1
|
Sym("one".to_owned()), // 1
|
||||||
Val(Int(11)), // 2
|
Val(Int(11)), // 2
|
||||||
Field, // 3
|
Field, // 3
|
||||||
Sym("m".to_owned()), // 4 // binding name for module
|
Sym("m".to_owned()), // 4 // binding name for module
|
||||||
InitTuple, // 5 // Module tuple bindings
|
InitTuple, // 5 // Module tuple bindings
|
||||||
Sym("one".to_owned()), // 6
|
Sym("one".to_owned()), // 6
|
||||||
Val(Int(1)), // 7
|
Val(Int(1)), // 7
|
||||||
Field, // 8
|
Field, // 8
|
||||||
Sym("two".to_owned()), // 9
|
Sym("two".to_owned()), // 9
|
||||||
Val(Int(2)), // 10
|
Val(Int(2)), // 10
|
||||||
Field, // 11
|
Field, // 11
|
||||||
Module(5), // 12 // Module body definition
|
Module(7), // 12 // Module body definition
|
||||||
Bind, // 13 // bind the mod tuple
|
Bind, // 13 // bind the mod tuple
|
||||||
Sym("foo".to_owned()), // 14
|
Sym("foo".to_owned()), // 14
|
||||||
DeRef("mod".to_owned()), // 15
|
DeRef("mod".to_owned()), // 15
|
||||||
Bind, // 16 // bind mod tuple to foo
|
Val(Str("one".to_owned())), // 16
|
||||||
Return, // 17 // end the module
|
Index, // 17
|
||||||
Bind, // 18 // bind module to the binding name
|
Bind, // 18 // bind mod tuple to foo
|
||||||
DeRef("m".to_owned()), // 19
|
Return, // 19 // end the module
|
||||||
Cp, // 20 // Call the module
|
Bind, // 20 // bind module to the binding name
|
||||||
|
DeRef("m".to_owned()), // 21
|
||||||
|
Cp, // 22 // Call the module
|
||||||
] => C(Tuple(vec![
|
] => C(Tuple(vec![
|
||||||
(
|
("foo".to_owned(), Rc::new(P(Int(11)))),
|
||||||
"foo".to_owned(),
|
|
||||||
Rc::new(C(Tuple(vec![
|
|
||||||
("one".to_owned(), Rc::new(P(Int(11)))),
|
|
||||||
("two".to_owned(), Rc::new(P(Int(2)))),
|
|
||||||
])))
|
|
||||||
),
|
|
||||||
])),
|
])),
|
||||||
vec![
|
vec![
|
||||||
InitTuple, // 0 // override tuple
|
InitTuple, // 0 // override tuple
|
||||||
@ -429,7 +425,7 @@ fn module_call() {
|
|||||||
InitThunk(2), // 12 // Module Return expression
|
InitThunk(2), // 12 // Module Return expression
|
||||||
Val(Int(1)), // 13
|
Val(Int(1)), // 13
|
||||||
Return, // 14
|
Return, // 14
|
||||||
Module(5), // 15 // Module definition
|
Module(5), // 15 // Module definition
|
||||||
Bind, // 16
|
Bind, // 16
|
||||||
Sym("foo".to_owned()), // 17
|
Sym("foo".to_owned()), // 17
|
||||||
DeRef("mod".to_owned()), // 18
|
DeRef("mod".to_owned()), // 18
|
||||||
@ -577,8 +573,9 @@ macro_rules! assert_parse_cases {
|
|||||||
(__impl__ $cases:expr) => {
|
(__impl__ $cases:expr) => {
|
||||||
for case in $cases.drain(0..) {
|
for case in $cases.drain(0..) {
|
||||||
let stmts = parse(OffsetStrIter::from(dbg!(case.0)), None).unwrap();
|
let stmts = parse(OffsetStrIter::from(dbg!(case.0)), None).unwrap();
|
||||||
|
let root = std::env::current_dir().unwrap();
|
||||||
// TODO(jwall): preprocessor
|
// TODO(jwall): preprocessor
|
||||||
let ops = Rc::new(translate::AST::translate(stmts));
|
let ops = Rc::new(translate::AST::translate(stmts, &root));
|
||||||
assert!(ops.len() > 0);
|
assert!(ops.len() > 0);
|
||||||
let env = Rc::new(RefCell::new(Environment::new(Vec::new(), Vec::new())));
|
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("foo.ucg", ops.clone(), env);
|
||||||
@ -762,7 +759,8 @@ fn simple_selects() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn simple_trace() {
|
fn simple_trace() {
|
||||||
let stmts = parse(OffsetStrIter::from(dbg!("TRACE 1+1;")), None).unwrap();
|
let stmts = parse(OffsetStrIter::from(dbg!("TRACE 1+1;")), None).unwrap();
|
||||||
let ops = Rc::new(translate::AST::translate(stmts));
|
let root = std::env::current_dir().unwrap();
|
||||||
|
let ops = Rc::new(translate::AST::translate(stmts, &root));
|
||||||
assert!(ops.len() > 0);
|
assert!(ops.len() > 0);
|
||||||
let env = Rc::new(RefCell::new(Environment::new(Vec::new(), Vec::new())));
|
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("foo.ucg", ops.clone(), env);
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::ast::{BinaryExprType, Expression, FormatArgs, Statement, Value};
|
use crate::ast::{BinaryExprType, Expression, FormatArgs, Statement, Value};
|
||||||
use crate::ast::{FuncOpDef, TemplatePart};
|
use crate::ast::{FuncOpDef, TemplatePart};
|
||||||
use crate::build::format::{ExpressionTemplate, SimpleTemplate, TemplateParser};
|
use crate::build::format::{ExpressionTemplate, SimpleTemplate, TemplateParser};
|
||||||
@ -20,23 +22,23 @@ use crate::build::opcode::{Hook, Op};
|
|||||||
pub struct AST();
|
pub struct AST();
|
||||||
|
|
||||||
impl AST {
|
impl AST {
|
||||||
pub fn translate(stmts: Vec<Statement>) -> Vec<Op> {
|
pub fn translate<P: AsRef<Path>>(stmts: Vec<Statement>, root: &P) -> Vec<Op> {
|
||||||
let mut ops = Vec::new();
|
let mut ops = Vec::new();
|
||||||
Self::translate_stmts(stmts, &mut ops);
|
Self::translate_stmts(stmts, &mut ops, root.as_ref());
|
||||||
return ops;
|
return ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_stmts(stmts: Vec<Statement>, mut ops: &mut Vec<Op>) {
|
fn translate_stmts(stmts: Vec<Statement>, mut ops: &mut Vec<Op>, root: &Path) {
|
||||||
for stmt in stmts {
|
for stmt in stmts {
|
||||||
match stmt {
|
match stmt {
|
||||||
Statement::Expression(expr) => Self::translate_expr(expr, &mut ops),
|
Statement::Expression(expr) => Self::translate_expr(expr, &mut ops, root),
|
||||||
Statement::Assert(_, _) => {
|
Statement::Assert(_, _) => {
|
||||||
unimplemented!("Assert statements are not implmented yet")
|
unimplemented!("Assert statements are not implmented yet")
|
||||||
}
|
}
|
||||||
Statement::Let(def) => {
|
Statement::Let(def) => {
|
||||||
let binding = def.name.fragment;
|
let binding = def.name.fragment;
|
||||||
ops.push(Op::Sym(binding));
|
ops.push(Op::Sym(binding));
|
||||||
Self::translate_expr(def.value, &mut ops);
|
Self::translate_expr(def.value, &mut ops, root);
|
||||||
ops.push(Op::Bind);
|
ops.push(Op::Bind);
|
||||||
}
|
}
|
||||||
Statement::Output(_, _, _) => {
|
Statement::Output(_, _, _) => {
|
||||||
@ -49,107 +51,106 @@ impl AST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_expr(expr: Expression, mut ops: &mut Vec<Op>) {
|
fn translate_expr(expr: Expression, mut ops: &mut Vec<Op>, root: &Path) {
|
||||||
match expr {
|
match expr {
|
||||||
Expression::Simple(v) => {
|
Expression::Simple(v) => {
|
||||||
Self::translate_value(v, &mut ops);
|
Self::translate_value(v, &mut ops, root);
|
||||||
}
|
}
|
||||||
Expression::Binary(def) => {
|
Expression::Binary(def) => {
|
||||||
match def.kind {
|
match def.kind {
|
||||||
BinaryExprType::Add => {
|
BinaryExprType::Add => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Add);
|
ops.push(Op::Add);
|
||||||
}
|
}
|
||||||
BinaryExprType::Sub => {
|
BinaryExprType::Sub => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Sub);
|
ops.push(Op::Sub);
|
||||||
}
|
}
|
||||||
BinaryExprType::Div => {
|
BinaryExprType::Div => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Div);
|
ops.push(Op::Div);
|
||||||
}
|
}
|
||||||
BinaryExprType::Mul => {
|
BinaryExprType::Mul => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Mul);
|
ops.push(Op::Mul);
|
||||||
}
|
}
|
||||||
BinaryExprType::Equal => {
|
BinaryExprType::Equal => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Equal);
|
ops.push(Op::Equal);
|
||||||
}
|
}
|
||||||
BinaryExprType::GT => {
|
BinaryExprType::GT => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Gt);
|
ops.push(Op::Gt);
|
||||||
}
|
}
|
||||||
BinaryExprType::LT => {
|
BinaryExprType::LT => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Lt);
|
ops.push(Op::Lt);
|
||||||
}
|
}
|
||||||
BinaryExprType::GTEqual => {
|
BinaryExprType::GTEqual => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::GtEq);
|
ops.push(Op::GtEq);
|
||||||
}
|
}
|
||||||
BinaryExprType::LTEqual => {
|
BinaryExprType::LTEqual => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::LtEq);
|
ops.push(Op::LtEq);
|
||||||
}
|
}
|
||||||
BinaryExprType::NotEqual => {
|
BinaryExprType::NotEqual => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Equal);
|
ops.push(Op::Equal);
|
||||||
ops.push(Op::Not);
|
ops.push(Op::Not);
|
||||||
}
|
}
|
||||||
BinaryExprType::REMatch => {
|
BinaryExprType::REMatch => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Runtime(Hook::Regex));
|
ops.push(Op::Runtime(Hook::Regex));
|
||||||
}
|
}
|
||||||
BinaryExprType::NotREMatch => {
|
BinaryExprType::NotREMatch => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Runtime(Hook::Regex));
|
ops.push(Op::Runtime(Hook::Regex));
|
||||||
ops.push(Op::Not);
|
ops.push(Op::Not);
|
||||||
}
|
}
|
||||||
BinaryExprType::IS => {
|
BinaryExprType::IS => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Typ);
|
ops.push(Op::Typ);
|
||||||
ops.push(Op::Equal);
|
ops.push(Op::Equal);
|
||||||
}
|
}
|
||||||
BinaryExprType::AND => {
|
BinaryExprType::AND => {
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Noop);
|
ops.push(Op::Noop);
|
||||||
let idx = ops.len() - 1;
|
let idx = ops.len() - 1;
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
let jptr = (ops.len() - 1 - idx) as i32;
|
let jptr = (ops.len() - 1 - idx) as i32;
|
||||||
ops[idx] = Op::And(dbg!(jptr));
|
ops[idx] = Op::And(dbg!(jptr));
|
||||||
dbg!(ops);
|
dbg!(ops);
|
||||||
}
|
}
|
||||||
BinaryExprType::OR => {
|
BinaryExprType::OR => {
|
||||||
// FIXME(jwall): This needs to be handled very differently
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
ops.push(Op::Noop); // Placeholder
|
||||||
ops.push(Op::Noop); // Placeholder used for
|
|
||||||
let idx = ops.len() - 1;
|
let idx = ops.len() - 1;
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
let jptr = (ops.len() - 1 - idx) as i32;
|
let jptr = (ops.len() - 1 - idx) as i32;
|
||||||
ops[idx] = Op::Or(jptr);
|
ops[idx] = Op::Or(jptr);
|
||||||
}
|
}
|
||||||
BinaryExprType::Mod => {
|
BinaryExprType::Mod => {
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
ops.push(Op::Mod);
|
ops.push(Op::Mod);
|
||||||
}
|
}
|
||||||
BinaryExprType::IN => {
|
BinaryExprType::IN => {
|
||||||
// Dot expressions expect the left side to be pushed first
|
// Dot expressions expect the left side to be pushed first
|
||||||
Self::translate_expr(*def.right, &mut ops);
|
Self::translate_expr(*def.right, &mut ops, root);
|
||||||
// Symbols on the right side should be converted to strings to satisfy
|
// Symbols on the right side should be converted to strings to satisfy
|
||||||
// the Index operation contract.
|
// the Index operation contract.
|
||||||
match *def.left {
|
match *def.left {
|
||||||
@ -157,10 +158,11 @@ impl AST {
|
|||||||
Self::translate_expr(
|
Self::translate_expr(
|
||||||
Expression::Simple(Value::Str(name)),
|
Expression::Simple(Value::Str(name)),
|
||||||
&mut ops,
|
&mut ops,
|
||||||
|
root,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expr => {
|
expr => {
|
||||||
Self::translate_expr(expr, &mut ops);
|
Self::translate_expr(expr, &mut ops, root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ops.push(Op::SafeIndex);
|
ops.push(Op::SafeIndex);
|
||||||
@ -170,7 +172,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
BinaryExprType::DOT => {
|
BinaryExprType::DOT => {
|
||||||
// Dot expressions expect the left side to be pushed first
|
// Dot expressions expect the left side to be pushed first
|
||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops, root);
|
||||||
// Symbols on the right side should be converted to strings to satisfy
|
// Symbols on the right side should be converted to strings to satisfy
|
||||||
// the Index operation contract.
|
// the Index operation contract.
|
||||||
match *def.right {
|
match *def.right {
|
||||||
@ -178,10 +180,11 @@ impl AST {
|
|||||||
Self::translate_expr(
|
Self::translate_expr(
|
||||||
Expression::Simple(Value::Str(name)),
|
Expression::Simple(Value::Str(name)),
|
||||||
&mut ops,
|
&mut ops,
|
||||||
|
root,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expr => {
|
expr => {
|
||||||
Self::translate_expr(expr, &mut ops);
|
Self::translate_expr(expr, &mut ops, root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ops.push(Op::Index);
|
ops.push(Op::Index);
|
||||||
@ -189,15 +192,13 @@ impl AST {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
Expression::Grouped(expr, _) => {
|
Expression::Grouped(expr, _) => {
|
||||||
Self::translate_expr(*expr, &mut ops);
|
Self::translate_expr(*expr, &mut ops, root);
|
||||||
}
|
}
|
||||||
Expression::Fail(def) => {
|
Expression::Fail(def) => {
|
||||||
Self::translate_expr(*def.message, &mut ops);
|
Self::translate_expr(*def.message, &mut ops, root);
|
||||||
ops.push(Op::Bang);
|
ops.push(Op::Bang);
|
||||||
}
|
}
|
||||||
Expression::Format(def) => {
|
Expression::Format(def) => {
|
||||||
// TODO(jwall): It would actually be safer if this was happening
|
|
||||||
// when we create the format def instead of here.
|
|
||||||
match def.args {
|
match def.args {
|
||||||
FormatArgs::List(mut elems) => {
|
FormatArgs::List(mut elems) => {
|
||||||
let formatter = SimpleTemplate::new();
|
let formatter = SimpleTemplate::new();
|
||||||
@ -215,9 +216,10 @@ impl AST {
|
|||||||
&mut elems_iter,
|
&mut elems_iter,
|
||||||
&mut ops,
|
&mut ops,
|
||||||
true,
|
true,
|
||||||
|
root,
|
||||||
);
|
);
|
||||||
for p in parts_iter {
|
for p in parts_iter {
|
||||||
Self::translate_template_part(p, &mut elems_iter, &mut ops, true);
|
Self::translate_template_part(p, &mut elems_iter, &mut ops, true, root);
|
||||||
ops.push(Op::Add);
|
ops.push(Op::Add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,14 +230,13 @@ impl AST {
|
|||||||
let mut parts = formatter.parse(&def.template).unwrap();
|
let mut parts = formatter.parse(&def.template).unwrap();
|
||||||
parts.reverse();
|
parts.reverse();
|
||||||
let mut parts_iter = parts.drain(0..);
|
let mut parts_iter = parts.drain(0..);
|
||||||
// TODO(jwall): We need to assume there is a new scope introduced now
|
|
||||||
ops.push(Op::Noop);
|
ops.push(Op::Noop);
|
||||||
let scope_idx = ops.len() - 1;
|
let scope_idx = ops.len() - 1;
|
||||||
|
|
||||||
// Add our item binding shadowing any binding that already
|
// Add our item binding shadowing any binding that already
|
||||||
// existed.
|
// existed.
|
||||||
ops.push(Op::Sym("item".to_owned()));
|
ops.push(Op::Sym("item".to_owned()));
|
||||||
Self::translate_expr(*expr, &mut ops);
|
Self::translate_expr(*expr, &mut ops, root);
|
||||||
ops.push(Op::BindOver);
|
ops.push(Op::BindOver);
|
||||||
let mut elems = Vec::new();
|
let mut elems = Vec::new();
|
||||||
let mut elems_iter = elems.drain(0..);
|
let mut elems_iter = elems.drain(0..);
|
||||||
@ -244,9 +245,16 @@ impl AST {
|
|||||||
&mut elems_iter,
|
&mut elems_iter,
|
||||||
&mut ops,
|
&mut ops,
|
||||||
false,
|
false,
|
||||||
|
root,
|
||||||
);
|
);
|
||||||
for p in parts_iter {
|
for p in parts_iter {
|
||||||
Self::translate_template_part(p, &mut elems_iter, &mut ops, false);
|
Self::translate_template_part(
|
||||||
|
p,
|
||||||
|
&mut elems_iter,
|
||||||
|
&mut ops,
|
||||||
|
false,
|
||||||
|
root,
|
||||||
|
);
|
||||||
ops.push(Op::Add);
|
ops.push(Op::Add);
|
||||||
}
|
}
|
||||||
ops.push(Op::Return);
|
ops.push(Op::Return);
|
||||||
@ -263,7 +271,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
ops.push(Op::Noop);
|
ops.push(Op::Noop);
|
||||||
let idx = ops.len() - 1;
|
let idx = ops.len() - 1;
|
||||||
Self::translate_expr(*def.fields, &mut ops);
|
Self::translate_expr(*def.fields, &mut ops, root);
|
||||||
ops.push(Op::Return);
|
ops.push(Op::Return);
|
||||||
let jptr = ops.len() - 1 - idx;
|
let jptr = ops.len() - 1 - idx;
|
||||||
ops[idx] = Op::Func(jptr as i32);
|
ops[idx] = Op::Func(jptr as i32);
|
||||||
@ -272,27 +280,27 @@ impl AST {
|
|||||||
match def {
|
match def {
|
||||||
FuncOpDef::Map(def) => {
|
FuncOpDef::Map(def) => {
|
||||||
// push the function on the stack first.
|
// push the function on the stack first.
|
||||||
Self::translate_expr(*def.func, &mut ops);
|
Self::translate_expr(*def.func, &mut ops, root);
|
||||||
// push the target on the stack third
|
// push the target on the stack third
|
||||||
Self::translate_expr(*def.target, &mut ops);
|
Self::translate_expr(*def.target, &mut ops, root);
|
||||||
// finally push the Hook::Map opcode
|
// finally push the Hook::Map opcode
|
||||||
ops.push(Op::Runtime(Hook::Map));
|
ops.push(Op::Runtime(Hook::Map));
|
||||||
}
|
}
|
||||||
FuncOpDef::Filter(def) => {
|
FuncOpDef::Filter(def) => {
|
||||||
// push the function on the stack first.
|
// push the function on the stack first.
|
||||||
Self::translate_expr(*def.func, &mut ops);
|
Self::translate_expr(*def.func, &mut ops, root);
|
||||||
// push the target on the stack third
|
// push the target on the stack third
|
||||||
Self::translate_expr(*def.target, &mut ops);
|
Self::translate_expr(*def.target, &mut ops, root);
|
||||||
// finally push the Hook::Map opcode
|
// finally push the Hook::Map opcode
|
||||||
ops.push(Op::Runtime(Hook::Filter));
|
ops.push(Op::Runtime(Hook::Filter));
|
||||||
}
|
}
|
||||||
FuncOpDef::Reduce(def) => {
|
FuncOpDef::Reduce(def) => {
|
||||||
// push the function on the stack first.
|
// push the function on the stack first.
|
||||||
Self::translate_expr(*def.func, &mut ops);
|
Self::translate_expr(*def.func, &mut ops, root);
|
||||||
// push the accumulator on the stack third
|
// push the accumulator on the stack third
|
||||||
Self::translate_expr(*def.acc, &mut ops);
|
Self::translate_expr(*def.acc, &mut ops, root);
|
||||||
// push the target on the stack third
|
// push the target on the stack third
|
||||||
Self::translate_expr(*def.target, &mut ops);
|
Self::translate_expr(*def.target, &mut ops, root);
|
||||||
// finally push the Hook::Map opcode
|
// finally push the Hook::Map opcode
|
||||||
ops.push(Op::Runtime(Hook::Reduce));
|
ops.push(Op::Runtime(Hook::Reduce));
|
||||||
}
|
}
|
||||||
@ -307,7 +315,8 @@ impl AST {
|
|||||||
ops.push(Op::Val(Primitive::Str(def.path.fragment)));
|
ops.push(Op::Val(Primitive::Str(def.path.fragment)));
|
||||||
ops.push(Op::Runtime(Hook::Include));
|
ops.push(Op::Runtime(Hook::Include));
|
||||||
}
|
}
|
||||||
Expression::Module(def) => {
|
Expression::Module(mut def) => {
|
||||||
|
def.imports_to_absolute(root.to_path_buf());
|
||||||
let argset = def.arg_set;
|
let argset = def.arg_set;
|
||||||
let out_expr = def.out_expr;
|
let out_expr = def.out_expr;
|
||||||
let stmts = def.statements;
|
let stmts = def.statements;
|
||||||
@ -315,7 +324,7 @@ impl AST {
|
|||||||
ops.push(Op::InitTuple);
|
ops.push(Op::InitTuple);
|
||||||
for (t, e) in argset {
|
for (t, e) in argset {
|
||||||
ops.push(Op::Sym(t.fragment));
|
ops.push(Op::Sym(t.fragment));
|
||||||
Self::translate_expr(e, &mut ops);
|
Self::translate_expr(e, &mut ops, root);
|
||||||
ops.push(Op::Field);
|
ops.push(Op::Field);
|
||||||
}
|
}
|
||||||
// If there is one then emit our return expression
|
// If there is one then emit our return expression
|
||||||
@ -323,7 +332,7 @@ impl AST {
|
|||||||
// Insert placeholder until we know jptr for this thunk
|
// Insert placeholder until we know jptr for this thunk
|
||||||
ops.push(Op::Noop);
|
ops.push(Op::Noop);
|
||||||
let idx = ops.len() - 1;
|
let idx = ops.len() - 1;
|
||||||
Self::translate_expr(*expr, &mut ops);
|
Self::translate_expr(*expr, &mut ops, root);
|
||||||
ops.push(Op::Return);
|
ops.push(Op::Return);
|
||||||
let jptr = ops.len() - idx - 1;
|
let jptr = ops.len() - idx - 1;
|
||||||
ops[idx] = Op::InitThunk(jptr as i32);
|
ops[idx] = Op::InitThunk(jptr as i32);
|
||||||
@ -335,34 +344,34 @@ impl AST {
|
|||||||
// Bind our mod tuple.
|
// Bind our mod tuple.
|
||||||
ops.push(Op::Bind);
|
ops.push(Op::Bind);
|
||||||
// emit all of our statements;
|
// emit all of our statements;
|
||||||
Self::translate_stmts(stmts, &mut ops);
|
Self::translate_stmts(stmts, &mut ops, root);
|
||||||
// Return from the module
|
// Return from the module
|
||||||
ops.push(Op::Return);
|
ops.push(Op::Return);
|
||||||
let jptr = ops.len() - idx - 1;
|
let jptr = ops.len() - idx - 1;
|
||||||
ops[idx] = Op::Module(jptr as i32);
|
ops[idx] = Op::Module(jptr as i32);
|
||||||
}
|
}
|
||||||
Expression::Not(def) => {
|
Expression::Not(def) => {
|
||||||
Self::translate_expr(*def.expr, &mut ops);
|
Self::translate_expr(*def.expr, &mut ops, root);
|
||||||
ops.push(Op::Not);
|
ops.push(Op::Not);
|
||||||
}
|
}
|
||||||
Expression::Range(def) => {
|
Expression::Range(def) => {
|
||||||
Self::translate_expr(*def.end, &mut ops);
|
Self::translate_expr(*def.end, &mut ops, root);
|
||||||
if let Some(expr) = def.step {
|
if let Some(expr) = def.step {
|
||||||
Self::translate_expr(*expr, &mut ops);
|
Self::translate_expr(*expr, &mut ops, root);
|
||||||
} else {
|
} else {
|
||||||
ops.push(Op::Val(Primitive::Empty));
|
ops.push(Op::Val(Primitive::Empty));
|
||||||
}
|
}
|
||||||
Self::translate_expr(*def.start, &mut ops);
|
Self::translate_expr(*def.start, &mut ops, root);
|
||||||
ops.push(Op::Runtime(Hook::Range));
|
ops.push(Op::Runtime(Hook::Range));
|
||||||
}
|
}
|
||||||
Expression::Select(def) => {
|
Expression::Select(def) => {
|
||||||
Self::translate_expr(*def.val, &mut ops);
|
Self::translate_expr(*def.val, &mut ops, root);
|
||||||
let mut jumps = Vec::new();
|
let mut jumps = Vec::new();
|
||||||
for (key, val) in def.tuple {
|
for (key, val) in def.tuple {
|
||||||
ops.push(Op::Sym(key.fragment));
|
ops.push(Op::Sym(key.fragment));
|
||||||
ops.push(Op::Noop);
|
ops.push(Op::Noop);
|
||||||
let idx = ops.len() - 1;
|
let idx = ops.len() - 1;
|
||||||
Self::translate_expr(val, &mut ops);
|
Self::translate_expr(val, &mut ops, root);
|
||||||
ops.push(Op::Noop);
|
ops.push(Op::Noop);
|
||||||
jumps.push(ops.len() - 1);
|
jumps.push(ops.len() - 1);
|
||||||
let jptr = ops.len() - idx - 1;
|
let jptr = ops.len() - idx - 1;
|
||||||
@ -375,7 +384,7 @@ impl AST {
|
|||||||
ops[i] = Op::Jump(idx as i32);
|
ops[i] = Op::Jump(idx as i32);
|
||||||
}
|
}
|
||||||
if let Some(default) = def.default {
|
if let Some(default) = def.default {
|
||||||
Self::translate_expr(*default, &mut ops);
|
Self::translate_expr(*default, &mut ops, root);
|
||||||
} else {
|
} else {
|
||||||
ops.push(Op::Bang);
|
ops.push(Op::Bang);
|
||||||
}
|
}
|
||||||
@ -384,10 +393,10 @@ impl AST {
|
|||||||
Expression::Call(def) => {
|
Expression::Call(def) => {
|
||||||
// first push our arguments.
|
// first push our arguments.
|
||||||
for e in def.arglist {
|
for e in def.arglist {
|
||||||
Self::translate_expr(e, &mut ops);
|
Self::translate_expr(e, &mut ops, root);
|
||||||
}
|
}
|
||||||
// then push the func reference
|
// then push the func reference
|
||||||
Self::translate_value(def.funcref, &mut ops);
|
Self::translate_value(def.funcref, &mut ops, root);
|
||||||
ops.push(Op::FCall);
|
ops.push(Op::FCall);
|
||||||
dbg!(ops);
|
dbg!(ops);
|
||||||
}
|
}
|
||||||
@ -395,10 +404,10 @@ impl AST {
|
|||||||
ops.push(Op::InitTuple);
|
ops.push(Op::InitTuple);
|
||||||
for (t, e) in def.fields {
|
for (t, e) in def.fields {
|
||||||
ops.push(Op::Sym(t.fragment));
|
ops.push(Op::Sym(t.fragment));
|
||||||
Self::translate_expr(e, &mut ops);
|
Self::translate_expr(e, &mut ops, root);
|
||||||
ops.push(Op::Field);
|
ops.push(Op::Field);
|
||||||
}
|
}
|
||||||
Self::translate_value(def.selector, &mut ops);
|
Self::translate_value(def.selector, &mut ops, root);
|
||||||
ops.push(Op::Cp);
|
ops.push(Op::Cp);
|
||||||
}
|
}
|
||||||
Expression::Debug(def) => {
|
Expression::Debug(def) => {
|
||||||
@ -409,7 +418,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
let expr_pretty = String::from_utf8(buffer).unwrap();
|
let expr_pretty = String::from_utf8(buffer).unwrap();
|
||||||
ops.push(Op::Val(Primitive::Str(expr_pretty)));
|
ops.push(Op::Val(Primitive::Str(expr_pretty)));
|
||||||
Self::translate_expr(*def.expr, &mut ops);
|
Self::translate_expr(*def.expr, &mut ops, root);
|
||||||
ops.push(Op::Runtime(Hook::Trace(def.pos)));
|
ops.push(Op::Runtime(Hook::Trace(def.pos)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,6 +429,7 @@ impl AST {
|
|||||||
elems: &mut EI,
|
elems: &mut EI,
|
||||||
mut ops: &mut Vec<Op>,
|
mut ops: &mut Vec<Op>,
|
||||||
place_holder: bool,
|
place_holder: bool,
|
||||||
|
root: &Path,
|
||||||
) {
|
) {
|
||||||
match part {
|
match part {
|
||||||
TemplatePart::Str(s) => {
|
TemplatePart::Str(s) => {
|
||||||
@ -430,7 +440,7 @@ impl AST {
|
|||||||
// In theory this should never be reachable
|
// In theory this should never be reachable
|
||||||
unreachable!();
|
unreachable!();
|
||||||
} else {
|
} else {
|
||||||
Self::translate_expr(elems.next().unwrap(), &mut ops);
|
Self::translate_expr(elems.next().unwrap(), &mut ops, root);
|
||||||
ops.push(Op::Render);
|
ops.push(Op::Render);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -438,14 +448,14 @@ impl AST {
|
|||||||
if place_holder {
|
if place_holder {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
} else {
|
} else {
|
||||||
Self::translate_expr(expr, &mut ops);
|
Self::translate_expr(expr, &mut ops, root);
|
||||||
ops.push(Op::Render);
|
ops.push(Op::Render);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_value(value: Value, mut ops: &mut Vec<Op>) {
|
fn translate_value(value: Value, mut ops: &mut Vec<Op>, root: &Path) {
|
||||||
match value {
|
match value {
|
||||||
Value::Int(i) => ops.push(Op::Val(Primitive::Int(i.val))),
|
Value::Int(i) => ops.push(Op::Val(Primitive::Int(i.val))),
|
||||||
Value::Float(f) => ops.push(Op::Val(Primitive::Float(f.val))),
|
Value::Float(f) => ops.push(Op::Val(Primitive::Float(f.val))),
|
||||||
@ -459,14 +469,14 @@ impl AST {
|
|||||||
ops.push(Op::InitTuple);
|
ops.push(Op::InitTuple);
|
||||||
for (k, v) in flds.val {
|
for (k, v) in flds.val {
|
||||||
ops.push(Op::Sym(k.fragment));
|
ops.push(Op::Sym(k.fragment));
|
||||||
Self::translate_expr(v, &mut ops);
|
Self::translate_expr(v, &mut ops, root);
|
||||||
ops.push(Op::Field);
|
ops.push(Op::Field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::List(els) => {
|
Value::List(els) => {
|
||||||
ops.push(Op::InitList);
|
ops.push(Op::InitList);
|
||||||
for el in els.elems {
|
for el in els.elems {
|
||||||
Self::translate_expr(el, &mut ops);
|
Self::translate_expr(el, &mut ops, root);
|
||||||
ops.push(Op::Element);
|
ops.push(Op::Element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,10 +274,23 @@ where
|
|||||||
};
|
};
|
||||||
let mut ops = self.ops.clone();
|
let mut ops = self.ops.clone();
|
||||||
ops.jump(idx)?;
|
ops.jump(idx)?;
|
||||||
|
let pkg_ptr = if let Some(ref path) = self.ops.path {
|
||||||
|
let pkg_ops = vec![
|
||||||
|
Op::InitList,
|
||||||
|
Op::Func(3),
|
||||||
|
Op::Val(Str(path.to_string_lossy().to_string())),
|
||||||
|
Op::Runtime(Hook::Import),
|
||||||
|
Op::Return,
|
||||||
|
];
|
||||||
|
Some(OpPointer::new(Rc::new(pkg_ops)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
self.push(Rc::new(M(Module {
|
self.push(Rc::new(M(Module {
|
||||||
ptr: ops,
|
ptr: ops,
|
||||||
result_ptr: result_ptr,
|
result_ptr: result_ptr,
|
||||||
flds: flds,
|
flds: flds,
|
||||||
|
pkg_ptr: pkg_ptr,
|
||||||
})))?;
|
})))?;
|
||||||
self.op_jump(jptr)
|
self.op_jump(jptr)
|
||||||
}
|
}
|
||||||
@ -589,8 +602,8 @@ where
|
|||||||
|
|
||||||
fn op_index(&mut self, safe: bool) -> Result<(), Error> {
|
fn op_index(&mut self, safe: bool) -> Result<(), Error> {
|
||||||
// left and then right
|
// left and then right
|
||||||
let right = self.pop()?;
|
let right = dbg!(self.pop()?);
|
||||||
let left = self.pop()?;
|
let left = dbg!(self.pop()?);
|
||||||
match right.as_ref() {
|
match right.as_ref() {
|
||||||
&P(Int(i)) => {
|
&P(Int(i)) => {
|
||||||
if let &C(List(ref elems)) = left.as_ref() {
|
if let &C(List(ref elems)) = left.as_ref() {
|
||||||
@ -645,18 +658,28 @@ where
|
|||||||
ref ptr,
|
ref ptr,
|
||||||
ref result_ptr,
|
ref result_ptr,
|
||||||
ref flds,
|
ref flds,
|
||||||
|
ref pkg_ptr,
|
||||||
}) => {
|
}) => {
|
||||||
//let this = M(Module {
|
let this = M(Module {
|
||||||
// ptr: ptr.clone(),
|
ptr: ptr.clone(),
|
||||||
// result_ptr: result_ptr.clone(),
|
result_ptr: result_ptr.clone(),
|
||||||
// flds: flds.clone(),
|
flds: flds.clone(),
|
||||||
//});
|
pkg_ptr: pkg_ptr.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
let mut flds = flds.clone();
|
let mut flds = flds.clone();
|
||||||
for (name, val) in overrides {
|
for (name, val) in overrides {
|
||||||
self.merge_field_into_tuple(&mut flds, name, val)?;
|
self.merge_field_into_tuple(&mut flds, name, val)?;
|
||||||
}
|
}
|
||||||
// FIXME(jwall): We need to populate the pkg key for modules.
|
self.merge_field_into_tuple(&mut flds, "this".to_owned(), Rc::new(this))?;
|
||||||
//self.merge_field_into_tuple(&mut flds, "this".to_owned(), this)?;
|
if let Some(ptr) = pkg_ptr {
|
||||||
|
let mut pkg_vm =
|
||||||
|
Self::with_pointer(self.path.clone(), 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(self.path.clone(), ptr.clone(), self.env.clone());
|
||||||
vm.push(Rc::new(S("mod".to_owned())))?;
|
vm.push(Rc::new(S("mod".to_owned())))?;
|
||||||
vm.push(Rc::new(C(Tuple(flds))))?;
|
vm.push(Rc::new(C(Tuple(flds))))?;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user