mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-21 18:10:42 -04:00
DEV: Link all the packages upfront
This commit is contained in:
parent
159af40e7c
commit
7a8b8e46eb
@ -14,8 +14,7 @@
|
||||
|
||||
//! The build stage of the ucg compiler.
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::error::Error;
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
@ -28,6 +27,7 @@ use rustyline::error::ReadlineError;
|
||||
use simple_error;
|
||||
|
||||
use crate::ast::*;
|
||||
#[macro_use]
|
||||
use crate::build::opcode::pointer::OpPointer;
|
||||
use crate::build::opcode::translate;
|
||||
use crate::build::opcode::translate::OpsMap;
|
||||
@ -168,7 +168,34 @@ where
|
||||
self.validate_mode = true;
|
||||
}
|
||||
|
||||
fn link_ops(&self, ops: &OpPointer) -> BuildResult {
|
||||
let mut links = Vec::new();
|
||||
for (link, pos) in &ops.pos_map.links {
|
||||
links.push((link.clone(), pos.clone()));
|
||||
}
|
||||
let mut found = BTreeSet::new();
|
||||
loop {
|
||||
let (link, path_pos) = match links.pop() {
|
||||
Some(t) => t,
|
||||
None => break,
|
||||
};
|
||||
if found.contains(&link) {
|
||||
continue;
|
||||
}
|
||||
let ops = match self.environment.borrow_mut().get_ops_for_path(link.clone()) {
|
||||
Ok(ops) => ops,
|
||||
Err(e) => return Err(Box::new(e.with_pos(path_pos))),
|
||||
};
|
||||
found.insert(link);
|
||||
for (link, pos) in &ops.pos_map.links {
|
||||
links.push((link.clone(), pos.clone()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn eval_ops(&mut self, ops: OpPointer, path: Option<PathBuf>) -> BuildResult {
|
||||
self.link_ops(&ops)?;
|
||||
let mut vm = VM::with_pointer(self.strict, ops, &self.working_dir);
|
||||
if path.is_some() {
|
||||
vm.set_path(path.unwrap());
|
||||
@ -303,13 +330,12 @@ where
|
||||
pub fn eval_expr(&mut self, expr: Expression) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||
let ops_map =
|
||||
translate::AST::translate(vec![Statement::Expression(expr)], &self.working_dir);
|
||||
let mut vm = VM::new(self.strict, Rc::new(ops_map), &self.working_dir);
|
||||
if self.validate_mode {
|
||||
vm.enable_validate_mode();
|
||||
}
|
||||
vm.run(self.environment)?;
|
||||
if let Some((val, _)) = vm.last.clone() {
|
||||
return Ok(Rc::new(val.try_into()?));
|
||||
self.eval_ops(
|
||||
OpPointer::new(Rc::new(ops_map)),
|
||||
Some(self.working_dir.clone()),
|
||||
)?;
|
||||
if let Some(val) = &self.last {
|
||||
return Ok(val.clone());
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ mod debug;
|
||||
mod display;
|
||||
pub mod environment;
|
||||
#[macro_use]
|
||||
mod error;
|
||||
pub mod error;
|
||||
mod convert;
|
||||
pub mod pointer;
|
||||
mod runtime;
|
||||
|
@ -194,6 +194,8 @@ impl Builtins {
|
||||
let path = stack.pop();
|
||||
if let Some((val, path_pos)) = path {
|
||||
if let &Value::P(Str(ref path)) = val.as_ref() {
|
||||
// FIXME(jwall): Most of this is no longer necessary since
|
||||
// we do it before hand at the linker step.
|
||||
// TODO(jwall): A bit hacky we should probably change import stacks to be pathbufs.
|
||||
let normalized =
|
||||
decorate_error!(path_pos => self.normalize_path(base_path, false, path))?;
|
||||
|
@ -29,7 +29,7 @@ pub struct AST();
|
||||
pub struct OpsMap {
|
||||
pub ops: Vec<Op>,
|
||||
pub pos: Vec<Position>,
|
||||
pub links: BTreeMap<String, usize>,
|
||||
pub links: BTreeMap<String, Position>,
|
||||
}
|
||||
|
||||
impl OpsMap {
|
||||
@ -47,8 +47,8 @@ impl OpsMap {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_link(&mut self, path: String) {
|
||||
self.links.insert(path, self.len() - 1);
|
||||
pub fn add_link(&mut self, path: String, pos: Position) {
|
||||
self.links.insert(path, pos);
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
@ -444,9 +444,9 @@ impl AST {
|
||||
}
|
||||
Expression::Import(def) => {
|
||||
let link_path = def.path.fragment.clone();
|
||||
ops.add_link(link_path, def.path.pos.clone());
|
||||
ops.push(Op::Val(Primitive::Str(def.path.fragment)), def.path.pos);
|
||||
ops.push(Op::Runtime(Hook::Import), def.pos);
|
||||
ops.add_link(link_path);
|
||||
}
|
||||
Expression::Include(def) => {
|
||||
ops.push(Op::Val(Primitive::Str(def.typ.fragment)), def.typ.pos);
|
||||
|
Loading…
x
Reference in New Issue
Block a user