mirror of
https://github.com/tweag/nickel.git
synced 2024-09-20 16:08:14 +03:00
Attach meta data to linearized terms
This commit is contained in:
parent
4cd865fe7a
commit
3646ede403
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
||||
use nickel::{
|
||||
identifier::Ident,
|
||||
position::TermPos,
|
||||
term::Term,
|
||||
term::{MetaValue, Term},
|
||||
typecheck::{
|
||||
linearization::{
|
||||
Building, Completed, Environment, Linearization, LinearizationItem, Linearizer,
|
||||
@ -67,6 +67,7 @@ impl BuildingExt for Linearization<Building<BuildingResource>> {
|
||||
pub struct AnalysisHost {
|
||||
env: Environment,
|
||||
scope: Vec<ScopeId>,
|
||||
meta: Option<MetaValue>,
|
||||
}
|
||||
|
||||
impl AnalysisHost {
|
||||
@ -74,6 +75,7 @@ impl AnalysisHost {
|
||||
AnalysisHost {
|
||||
env: Environment::new(),
|
||||
scope: Vec::new(),
|
||||
meta: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -101,6 +103,7 @@ impl Linearizer<BuildingResource, (UnifTable, HashMap<usize, Ident>)> for Analys
|
||||
pos,
|
||||
scope: self.scope.clone(),
|
||||
kind: TermKind::Declaration(ident.to_string(), Vec::new()),
|
||||
meta: self.meta.take(),
|
||||
});
|
||||
}
|
||||
Term::Var(ident) => {
|
||||
@ -113,6 +116,7 @@ impl Linearizer<BuildingResource, (UnifTable, HashMap<usize, Ident>)> for Analys
|
||||
// id = parent: full let binding including the body
|
||||
// id = parent + 1: actual delcaration scope, i.e. _ = < definition >
|
||||
kind: TermKind::Usage(parent.map(|id| id + 1)),
|
||||
meta: self.meta.take(),
|
||||
});
|
||||
if let Some(parent) = parent {
|
||||
lin.add_usage(parent, id);
|
||||
@ -124,14 +128,29 @@ impl Linearizer<BuildingResource, (UnifTable, HashMap<usize, Ident>)> for Analys
|
||||
ty,
|
||||
kind: TermKind::Record(attrs.clone()),
|
||||
scope: self.scope.clone(),
|
||||
meta: self.meta.take(),
|
||||
}),
|
||||
|
||||
Term::MetaValue(meta) => {
|
||||
// Notice 1: No push to lin
|
||||
// Notice 2: we discard the encoded value as anything we
|
||||
// would do with the value will be handled in the following
|
||||
// call to [Self::add_term]
|
||||
let meta = MetaValue {
|
||||
value: None,
|
||||
..meta.to_owned()
|
||||
};
|
||||
|
||||
self.meta.insert(meta);
|
||||
}
|
||||
|
||||
_ => lin.push(LinearizationItem {
|
||||
id,
|
||||
pos,
|
||||
ty,
|
||||
scope: self.scope.clone(),
|
||||
kind: TermKind::Structure,
|
||||
meta: self.meta.take(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@ -175,12 +194,14 @@ impl Linearizer<BuildingResource, (UnifTable, HashMap<usize, Ident>)> for Analys
|
||||
ty,
|
||||
kind,
|
||||
scope,
|
||||
meta,
|
||||
}| LinearizationItem {
|
||||
ty: to_type(&table, &reported_names, &mut NameReg::new(), ty),
|
||||
id,
|
||||
pos,
|
||||
kind,
|
||||
scope,
|
||||
meta,
|
||||
},
|
||||
)
|
||||
.collect();
|
||||
@ -201,6 +222,9 @@ impl Linearizer<BuildingResource, (UnifTable, HashMap<usize, Ident>)> for Analys
|
||||
AnalysisHost {
|
||||
scope,
|
||||
env: self.env.clone(),
|
||||
/// when opening a new scope `meta` is assumed to be `None` as meta data
|
||||
/// is immediately followed by a term without opening a scope
|
||||
meta: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ use std::{collections::HashMap, marker::PhantomData};
|
||||
|
||||
use super::TypeWrapper;
|
||||
use crate::environment::Environment as GenericEnvironment;
|
||||
use crate::term::RecordAttrs;
|
||||
use crate::types::Types;
|
||||
use crate::types::{AbsType, Types};
|
||||
use crate::term::{MetaValue, RecordAttrs};
|
||||
use crate::{identifier::Ident, position::TermPos, term::Term};
|
||||
|
||||
/// Holds the state of a linearization, either in progress or finalized
|
||||
@ -103,6 +103,7 @@ pub struct LinearizationItem<S: ResolutionState> {
|
||||
pub ty: S,
|
||||
pub kind: TermKind,
|
||||
pub scope: Vec<ScopeId>,
|
||||
pub meta: Option<MetaValue>,
|
||||
}
|
||||
|
||||
/// Abstact term kinds.
|
||||
@ -187,53 +188,12 @@ pub enum ScopeId {
|
||||
|
||||
impl ScopeIdElem for ScopeId {}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct BuildingResource {
|
||||
pub linearization: Vec<LinearizationItem<Unresolved>>,
|
||||
pub scope: HashMap<Vec<ScopeId>, Vec<usize>>,
|
||||
}
|
||||
|
||||
impl Into<Completed> for Linearization<Completed> {
|
||||
fn into(self) -> Completed {
|
||||
self.state
|
||||
}
|
||||
}
|
||||
|
||||
impl Linearization<Building<BuildingResource>> {
|
||||
pub fn push(&mut self, item: LinearizationItem<Unresolved>) {
|
||||
self.state
|
||||
.resource
|
||||
.scope
|
||||
.remove(&item.scope)
|
||||
.map(|mut s| {
|
||||
s.push(item.id);
|
||||
s
|
||||
})
|
||||
.or_else(|| Some(vec![item.id]))
|
||||
.into_iter()
|
||||
.for_each(|l| {
|
||||
self.state.resource.scope.insert(item.scope.clone(), l);
|
||||
});
|
||||
self.state.resource.linearization.push(item);
|
||||
}
|
||||
|
||||
pub fn add_usage(&mut self, decl: usize, usage: usize) {
|
||||
match self
|
||||
.state
|
||||
.resource
|
||||
.linearization
|
||||
.get_mut(decl)
|
||||
.expect("Coundt find parent")
|
||||
.kind
|
||||
{
|
||||
TermKind::Structure => unreachable!(),
|
||||
TermKind::Usage(_) => unreachable!(),
|
||||
TermKind::Record(_) => unreachable!(),
|
||||
TermKind::Declaration(_, ref mut usages) => usages.push(usage),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl Completed {
|
||||
pub fn get_item(&self, id: usize) -> Option<&LinearizationItem<Resolved>> {
|
||||
self.id_mapping
|
||||
|
Loading…
Reference in New Issue
Block a user