Skip to content

Commit

Permalink
svlog: rst: Add resolution for subroutine port ambiguity
Browse files Browse the repository at this point in the history
Add a resolution query for the type/name ambiguity in subroutine ports.
This currently needs to be called manually for visitors, which is a bit
annoying. This should be improved in #211 later.

Contributes towards function calls in #168.
  • Loading branch information
fabianschuiki committed Jan 9, 2021
1 parent 2215d63 commit 73f0654
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/svlog/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,18 @@ where
_ => true,
}
}

/// Override for `SubroutinePort`s in order to resolve ambiguity.
// TODO(fschuik): This functionality should go into a `rst::Visitor`.
fn pre_visit_subroutine_port(&mut self, node: &'a ast::SubroutinePort<'a>) -> bool {
use ast::WalkVisitor;
node.dir.walk(self);
node.var.walk(self);
self.cx
.resolve_subroutine_port_ty_name(Ref(node))
.walk(self);
false
}
}

/// Any AST node that can be instantiated.
Expand Down
47 changes: 47 additions & 0 deletions src/svlog/rst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,50 @@ pub(crate) fn disamb_type_or_expr<'a>(
ast::TypeOrExpr::Type(_ty) => Ok(ast),
}
}

/// Resolve the type/name ambiguity in a subroutine port.
#[moore_derive::query]
pub(crate) fn resolve_subroutine_port_ty_name<'a>(
cx: &impl Context<'a>,
Ref(node): Ref<'a, ast::SubroutinePort<'a>>,
) -> &'a (ast::Type<'a>, Option<ast::SubroutinePortName<'a>>) {
let xs = match &node.ty_name {
ast::Ambiguous::Unique(x) => return x,
ast::Ambiguous::Ambiguous(xs) => xs,
};
debug!("Resolving ambiguity in {:1?}", node);

// Let's first try to resolve type names.
for x in xs {
let name = match x.0.kind.data {
ast::NamedType(x) => x,
_ => continue,
};
trace!(" - Trying type name {}", name);
let binding = match cx
.resolve_local(name.value, cx.scope_location(node), false)
.unwrap_or(None)
{
Some(x) => x,
None => continue,
};
trace!(" - Resolved to {:?}", binding);
match cx.disamb_kind(Ref(&binding.node)) {
Kind::Type => {
trace!(" - Resolved as {:?}", x);
return x;
}
_ => continue,
}
}

// If we arrive here, named types did not match. Return whatever is left.
for x in xs {
if x.1.is_some() {
trace!(" - Resolved as {:?}", x);
return x;
}
}

bug_span!(node.span, cx, "unable to resolve ambiguity");
}
7 changes: 7 additions & 0 deletions src/svlog/syntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1748,6 +1748,13 @@ pub enum SubroutineKind {
}

/// A function or task port.
///
/// Since the grammar allows for both omitting the type and omitting the port
/// name (the latter only if the subroutine has no body, i.e. is a prototype),
/// there is an ambiguity when just a name is provided: `foo` may be a port with
/// implicit type, if `foo` is not a defined type or the subroutine is not a
/// prototype, or `foo` may be a port of type `foo` without a name, if `foo` is
/// a defined type.
#[moore_derive::node]
#[indefinite("subroutine port")]
#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down

0 comments on commit 73f0654

Please sign in to comment.