mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -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.
|
//! The build stage of the ucg compiler.
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::{BTreeSet, HashMap};
|
||||||
use std::convert::TryInto;
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
@ -28,6 +27,7 @@ use rustyline::error::ReadlineError;
|
|||||||
use simple_error;
|
use simple_error;
|
||||||
|
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
|
#[macro_use]
|
||||||
use crate::build::opcode::pointer::OpPointer;
|
use crate::build::opcode::pointer::OpPointer;
|
||||||
use crate::build::opcode::translate;
|
use crate::build::opcode::translate;
|
||||||
use crate::build::opcode::translate::OpsMap;
|
use crate::build::opcode::translate::OpsMap;
|
||||||
@ -168,7 +168,34 @@ where
|
|||||||
self.validate_mode = true;
|
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 {
|
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);
|
let mut vm = VM::with_pointer(self.strict, ops, &self.working_dir);
|
||||||
if path.is_some() {
|
if path.is_some() {
|
||||||
vm.set_path(path.unwrap());
|
vm.set_path(path.unwrap());
|
||||||
@ -303,13 +330,12 @@ where
|
|||||||
pub fn eval_expr(&mut self, expr: Expression) -> Result<Rc<Val>, Box<dyn Error>> {
|
pub fn eval_expr(&mut self, expr: Expression) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
let ops_map =
|
let ops_map =
|
||||||
translate::AST::translate(vec![Statement::Expression(expr)], &self.working_dir);
|
translate::AST::translate(vec![Statement::Expression(expr)], &self.working_dir);
|
||||||
let mut vm = VM::new(self.strict, Rc::new(ops_map), &self.working_dir);
|
self.eval_ops(
|
||||||
if self.validate_mode {
|
OpPointer::new(Rc::new(ops_map)),
|
||||||
vm.enable_validate_mode();
|
Some(self.working_dir.clone()),
|
||||||
}
|
)?;
|
||||||
vm.run(self.environment)?;
|
if let Some(val) = &self.last {
|
||||||
if let Some((val, _)) = vm.last.clone() {
|
return Ok(val.clone());
|
||||||
return Ok(Rc::new(val.try_into()?));
|
|
||||||
}
|
}
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ mod debug;
|
|||||||
mod display;
|
mod display;
|
||||||
pub mod environment;
|
pub mod environment;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod error;
|
pub mod error;
|
||||||
mod convert;
|
mod convert;
|
||||||
pub mod pointer;
|
pub mod pointer;
|
||||||
mod runtime;
|
mod runtime;
|
||||||
|
@ -194,6 +194,8 @@ impl Builtins {
|
|||||||
let path = stack.pop();
|
let path = stack.pop();
|
||||||
if let Some((val, path_pos)) = path {
|
if let Some((val, path_pos)) = path {
|
||||||
if let &Value::P(Str(ref path)) = val.as_ref() {
|
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.
|
// TODO(jwall): A bit hacky we should probably change import stacks to be pathbufs.
|
||||||
let normalized =
|
let normalized =
|
||||||
decorate_error!(path_pos => self.normalize_path(base_path, false, path))?;
|
decorate_error!(path_pos => self.normalize_path(base_path, false, path))?;
|
||||||
|
@ -29,7 +29,7 @@ pub struct AST();
|
|||||||
pub struct OpsMap {
|
pub struct OpsMap {
|
||||||
pub ops: Vec<Op>,
|
pub ops: Vec<Op>,
|
||||||
pub pos: Vec<Position>,
|
pub pos: Vec<Position>,
|
||||||
pub links: BTreeMap<String, usize>,
|
pub links: BTreeMap<String, Position>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpsMap {
|
impl OpsMap {
|
||||||
@ -47,8 +47,8 @@ impl OpsMap {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_link(&mut self, path: String) {
|
pub fn add_link(&mut self, path: String, pos: Position) {
|
||||||
self.links.insert(path, self.len() - 1);
|
self.links.insert(path, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
@ -444,9 +444,9 @@ impl AST {
|
|||||||
}
|
}
|
||||||
Expression::Import(def) => {
|
Expression::Import(def) => {
|
||||||
let link_path = def.path.fragment.clone();
|
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::Val(Primitive::Str(def.path.fragment)), def.path.pos);
|
||||||
ops.push(Op::Runtime(Hook::Import), def.pos);
|
ops.push(Op::Runtime(Hook::Import), def.pos);
|
||||||
ops.add_link(link_path);
|
|
||||||
}
|
}
|
||||||
Expression::Include(def) => {
|
Expression::Include(def) => {
|
||||||
ops.push(Op::Val(Primitive::Str(def.typ.fragment)), def.typ.pos);
|
ops.push(Op::Val(Primitive::Str(def.typ.fragment)), def.typ.pos);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user