mirror of
https://github.com/SpaceManiac/SpacemanDMM.git
synced 2025-12-23 05:36:47 +00:00
Add more traversal options to the object tree
This commit is contained in:
parent
2e6948c182
commit
14154fd272
2 changed files with 68 additions and 2 deletions
|
|
@ -29,7 +29,7 @@ pub mod constants;
|
|||
///
|
||||
/// Errors are automatically pretty-printed to stdout before they are returned.
|
||||
pub fn parse_environment(dme: &Path) -> Result<objtree::ObjectTree, DMError> {
|
||||
let mut preprocessor = preprocessor::Preprocessor::new(dme.to_owned()).unwrap();
|
||||
let mut preprocessor = preprocessor::Preprocessor::new(dme.to_owned())?;
|
||||
parser::parse(indents::IndentProcessor::new(&mut preprocessor)).map_err(|e| {
|
||||
pretty_print_error(&mut io::stdout(), &preprocessor, &e).unwrap();
|
||||
e
|
||||
|
|
|
|||
|
|
@ -6,12 +6,16 @@ use std::cell::Cell;
|
|||
pub use petgraph::graph::NodeIndex;
|
||||
use petgraph::graph::Graph;
|
||||
use petgraph::visit::EdgeRef;
|
||||
use petgraph::Direction;
|
||||
use linked_hash_map::LinkedHashMap;
|
||||
|
||||
use super::ast::{Expression, TypePath, PathOp, Prefab};
|
||||
use super::constants::Constant;
|
||||
use super::{DMError, Location};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Variables
|
||||
|
||||
pub type Vars = LinkedHashMap<String, Constant>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -46,9 +50,12 @@ pub struct TypeVar {
|
|||
pub declaration: Option<VarDeclaration>,
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Types
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Type {
|
||||
name: String,
|
||||
pub name: String,
|
||||
pub path: String,
|
||||
pub vars: LinkedHashMap<String, TypeVar>,
|
||||
parent_type: Cell<NodeIndex>,
|
||||
|
|
@ -132,6 +139,61 @@ pub fn subpath(path: &str, parent: &str) -> bool {
|
|||
path == &parent[..parent.len() - 1] || path.starts_with(parent)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Type references
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TypeRef<'a> {
|
||||
idx: NodeIndex,
|
||||
ty: &'a Type,
|
||||
}
|
||||
|
||||
impl<'a> TypeRef<'a> {
|
||||
fn new(tree: &'a ObjectTree, idx: NodeIndex) -> TypeRef<'a> {
|
||||
TypeRef {
|
||||
idx,
|
||||
ty: tree.graph.node_weight(idx).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parent(&self, objtree: &'a ObjectTree) -> Option<TypeRef<'a>> {
|
||||
objtree.graph.neighbors_directed(self.idx, Direction::Incoming).next().map(|i| TypeRef::new(objtree, i))
|
||||
}
|
||||
|
||||
pub fn parent_type(&self, objtree: &'a ObjectTree) -> Option<TypeRef<'a>> {
|
||||
let idx = self.ty.parent_type.get();
|
||||
objtree.graph.node_weight(idx).map(|ty| TypeRef { idx, ty })
|
||||
}
|
||||
|
||||
pub fn child(&self, name: &str, objtree: &'a ObjectTree) -> Option<TypeRef<'a>> {
|
||||
for idx in objtree.graph.neighbors(self.idx) {
|
||||
let ty = objtree.graph.node_weight(idx).unwrap();
|
||||
if ty.name == name {
|
||||
return Some(TypeRef { idx, ty });
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn children(&self, objtree: &'a ObjectTree) -> Vec<TypeRef<'a>> {
|
||||
let mut output = Vec::new();
|
||||
for idx in objtree.graph.neighbors(self.idx) {
|
||||
output.push(TypeRef::new(objtree, idx));
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::std::ops::Deref for TypeRef<'a> {
|
||||
type Target = Type;
|
||||
fn deref(&self) -> &Type {
|
||||
self.ty
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// The object tree itself
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectTree {
|
||||
pub graph: Graph<Type, ()>,
|
||||
|
|
@ -164,6 +226,10 @@ impl ObjectTree {
|
|||
// ------------------------------------------------------------------------
|
||||
// Access
|
||||
|
||||
pub fn root(&self) -> TypeRef {
|
||||
TypeRef::new(self, NodeIndex::new(0))
|
||||
}
|
||||
|
||||
pub fn find(&self, path: &str) -> Option<&Type> {
|
||||
self.types.get(path).and_then(|&ix| self.graph.node_weight(ix))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue