TAMER: Virtual symbol override

master
Mike Gerwitz 2020-01-15 11:24:56 -05:00
parent ab3aec980d
commit 7c60b53de8
7 changed files with 165 additions and 10 deletions

View File

@ -1,4 +1,4 @@
# This number is incremented for every linker change to force rebuilding
# of xmle files.
2
3

View File

@ -514,10 +514,18 @@
<!-- overridden; we're obsolete :( -->
</when>
<!-- if we've gotten this far, then the override is good; clear it -->
<!-- if we've gotten this far, then the override is good; clear it
so as not to trigger override errors -->
<when test="@override='true'">
<copy>
<sequence select="@*[ not( name()='override' ) ], *" />
<sequence select="@*[ not( name()='override' ) ]" />
<!-- mark this has having been overridden for the linker (see
TAMER; we'll hopefully be getting rid of overrides in the
future) -->
<attribute name="isoverride" select="'true'" />
<sequence select="*" />
</copy>
</when>

View File

@ -141,13 +141,29 @@ where
) -> AsgResult<ObjectRef<Ix>> {
// TODO: src check
if let Some(existing) = self.lookup(name) {
match self.graph.node_weight_mut(existing.0) {
Some(node @ Some(Object::Missing(_))) => {
let node = self.graph.node_weight_mut(existing.0).unwrap();
match node {
Some(Object::Missing(_)) => {
node.replace(Object::Ident(name, kind, src));
return Ok(existing);
}
Some(_) => return Ok(existing),
_ => (),
// TODO: no override-override
Some(Object::Ident(_, _, orig_src))
if orig_src.virtual_ && src.override_ =>
{
*orig_src = src;
return Ok(existing);
}
// TODO: no override-override
Some(Object::IdentFragment(_, _, orig_src, _))
if orig_src.virtual_ && src.override_ =>
{
// clears fragment, which is no longer applicable
node.replace(Object::Ident(name, kind, src));
return Ok(existing);
}
_ => return Ok(existing),
}
}
@ -414,6 +430,81 @@ mod test {
Ok(())
}
// TODO: incompatible
#[test]
fn declare_override_virtual_ident() -> AsgResult<()> {
let mut sut = Sut::with_capacity(0, 0);
let sym = Symbol::new_dummy(SymbolIndex::from_u32(1), "virtual");
let over_src = Symbol::new_dummy(SymbolIndex::from_u32(2), "src");
let virt_node = sut.declare(
&sym,
IdentKind::Meta,
Source {
virtual_: true,
..Default::default()
},
)?;
let over_src = Source {
override_: true,
src: Some(&over_src),
..Default::default()
};
let over_node = sut.declare(&sym, IdentKind::Meta, over_src.clone())?;
assert_eq!(virt_node, over_node);
assert_eq!(
sut.get(over_node),
Some(&Object::Ident(&sym, IdentKind::Meta, over_src,))
);
Ok(())
}
// TODO: incompatible
#[test]
fn declare_override_virtual_ident_fragment() -> AsgResult<()> {
let mut sut = Sut::with_capacity(0, 0);
let sym = Symbol::new_dummy(SymbolIndex::from_u32(1), "virtual");
let over_src = Symbol::new_dummy(SymbolIndex::from_u32(2), "src");
let virt_node = sut.declare(
&sym,
IdentKind::Meta,
Source {
virtual_: true,
..Default::default()
},
)?;
sut.set_fragment(virt_node, FragmentText::from("remove me"))?;
let over_src = Source {
override_: true,
src: Some(&over_src),
..Default::default()
};
let over_node = sut.declare(&sym, IdentKind::Meta, over_src.clone())?;
assert_eq!(virt_node, over_node);
// The act of overriding the node should have cleared any existing
// fragment, making way for a new fragment to take its place as soon
// as it is discovered. (So, back to an Object::Ident.)
assert_eq!(
sut.get(over_node),
Some(&Object::Ident(&sym, IdentKind::Meta, over_src,))
);
Ok(())
}
#[test]
fn add_fragment_to_ident() -> AsgResult<()> {
let mut sut = Sut::with_capacity(0, 0);

View File

@ -61,6 +61,12 @@ pub trait Asg<'i, Ix: IndexType> {
/// [`Object::Extern`] into a [`Object::Ident`].
/// When this happens,
/// the extern is said to be _resolved_.
///
/// If a virtual identifier of type [`Object::IdentFragment`] is
/// overridden,
/// then its fragment is cleared
/// (it returns to a [`Object::Ident`])
/// to make way for the fragment of the override.
fn declare(
&mut self,
name: &'i Symbol<'i>,

View File

@ -33,9 +33,9 @@ use crate::sym::Symbol;
/// / \ \
/// / v v
/// ((Empty)) -> (Extern) -> ((Ident)) -> ((IdentFragment)).
/// \ ^
/// \ /
/// `--------------------`
/// \ ^ /
/// \ / \ /
/// `--------------------` `-----------'
/// ```
///
/// The [`Empty`][Object::Empty] state is never directly accessable
@ -149,6 +149,22 @@ pub struct Source<'i> {
/// TODO: We have `parent`, `yields`, and `from`.
/// We should begin to consolodate.
pub from: Option<Vec<&'i Symbol<'i>>>,
/// Whether identifier is virtual (can be overridden).
///
/// This feature adds complexity and will ideally be removed in the
/// future.
///
/// See also [`override`][Source::override_].
pub virtual_: bool,
/// Whether identifier overrides a virtual identifier.
///
/// This feature adds complexity and will ideally be removed in the
/// future.
///
/// See also [`virtual_`][Source::virtual_].
pub override_: bool,
}
impl<'i> From<SymAttrs<'i>> for Source<'i> {
@ -164,6 +180,8 @@ impl<'i> From<SymAttrs<'i>> for Source<'i> {
yields: attrs.yields,
desc: attrs.desc,
from: attrs.from,
virtual_: attrs.virtual_,
override_: attrs.override_,
}
}
}
@ -189,6 +207,8 @@ mod test {
yields: Some(&ysym),
desc: Some("sym desc".to_string()),
from: Some(vec![&fsym]),
virtual_: true,
override_: true,
..Default::default()
};
@ -201,6 +221,8 @@ mod test {
yields: attrs.yields,
desc: Some("sym desc".to_string()),
from: Some(vec![&fsym]),
virtual_: true,
override_: true,
},
attrs.into(),
);

View File

@ -158,6 +158,16 @@ pub struct SymAttrs<'i> {
/// - [`SymType::Func`] lists params in order (so that the compiler
/// knows application order).
pub from: Option<Vec<&'i Symbol<'i>>>,
/// Whether symbol can be overridden.
///
/// See also [`override`][SymAttrs::override_].
pub virtual_: bool,
/// Whether symbol is an override of a virtual symbol.
///
/// See also [`virtual`][SymAttrs::virtual_].
pub override_: bool,
}
/// Legacy symbol types.

View File

@ -469,6 +469,14 @@ impl<'i, B: BufRead, I: Interner<'i>> XmloReader<'i, B, I> {
});
}
b"virtual" => {
sym_attrs.virtual_ = &*attr.value == b"true";
}
b"isoverride" => {
sym_attrs.override_ = &*attr.value == b"true";
}
// As this reader evolves, we may wish to provide an error
// for unknown attributes so that we can be sure that we've
// handled them all.
@ -1751,6 +1759,16 @@ mod test {
..Default::default()
}
r#virtual: [virtual="true"] => SymAttrs {
virtual_: true,
..Default::default()
}
r#override: [isoverride="true"] => SymAttrs {
override_: true,
..Default::default()
}
// Multiple attributes at once
multi: [src="foo", type="class", dim="1", dtype="float", extern="true"]
=> SymAttrs {