diff --git a/calyx-frontend/src/ast.rs b/calyx-frontend/src/ast.rs index 728eae414..a857cfbd3 100644 --- a/calyx-frontend/src/ast.rs +++ b/calyx-frontend/src/ast.rs @@ -1,6 +1,6 @@ //! Abstract Syntax Tree for Calyx use super::parser; -use crate::{Attributes, PortDef, Primitive}; +use crate::{metadata::MetadataTable, Attributes, PortDef, Primitive}; use atty::Stream; use calyx_utils::{CalyxResult, Error, GPosIdx, Id, PosString}; use std::{num::NonZeroU64, path::PathBuf}; @@ -14,8 +14,10 @@ pub struct NamespaceDef { pub components: Vec, /// Extern statements and any primitive declarations in them. pub externs: Vec<(Option, Vec)>, - /// Optional opaque metadata + /// Optional legacy opaque metadata. Newer metadata is in [NamespaceDef::file_info_table] pub metadata: Option, + /// Optional metadata mapping table + pub file_info_table: Option, } impl NamespaceDef { diff --git a/calyx-frontend/src/parser.rs b/calyx-frontend/src/parser.rs index 0d24c06bc..7e6372666 100644 --- a/calyx-frontend/src/parser.rs +++ b/calyx-frontend/src/parser.rs @@ -1426,18 +1426,38 @@ impl CalyxParser { // end new metadata + fn extra_info( + input: Node, + ) -> ParseResult<(Option, Option)> { + Ok(match_nodes!(input.into_children(); + [metadata_legacy(l)] => (Some(l), None), + [metadata_table(t)] => (None, Some(t)), + [metadata_legacy(l), metadata_table(t)] => (Some(l), Some(t)), + [metadata_table(t), metadata_legacy(l)] => (Some(l), Some(t)) + )) + } + fn file(input: Node) -> ParseResult { Ok(match_nodes!( input.into_children(); // There really seems to be no straightforward way to resolve this // duplication - [imports(imports), externs_and_comps(mixed), metadata_legacy(m), EOI(_)] => { + [imports(imports), externs_and_comps(mixed), extra_info(info), EOI(_)] => { + let (mut legacy_metadata, metadata) = info; + // remove empty metadata strings + if let Some(m) = &legacy_metadata { + if m.is_empty() { + legacy_metadata = None; + } + } + let mut namespace = ast::NamespaceDef { imports, components: Vec::new(), externs: Vec::new(), - metadata: if m != *"" { Some(m) } else { None } + metadata: legacy_metadata, + file_info_table: metadata }; for m in mixed { match m { @@ -1461,7 +1481,8 @@ impl CalyxParser { imports, components: Vec::new(), externs: Vec::new(), - metadata: None + metadata: None, + file_info_table: None }; for m in mixed { match m { diff --git a/calyx-frontend/src/syntax.pest b/calyx-frontend/src/syntax.pest index 7b024baa1..831252f2a 100644 --- a/calyx-frontend/src/syntax.pest +++ b/calyx-frontend/src/syntax.pest @@ -58,7 +58,7 @@ file = { SOI ~ imports ~ externs_and_comps - ~ metadata_legacy? + ~ extra_info? ~ EOI } @@ -418,3 +418,11 @@ position_table = { metadata_table = { ^"fileinfo" ~ "#{" ~ file_table ~ position_table ~ "}#" } + + +extra_info = { + metadata_legacy + | metadata_table + | (metadata_legacy ~ metadata_table) + | (metadata_table ~ metadata_legacy) +} diff --git a/calyx-frontend/src/workspace.rs b/calyx-frontend/src/workspace.rs index 167f945d4..f022ddaf7 100644 --- a/calyx-frontend/src/workspace.rs +++ b/calyx-frontend/src/workspace.rs @@ -2,7 +2,7 @@ use super::{ ast::{ComponentDef, NamespaceDef}, parser, }; -use crate::LibrarySignatures; +use crate::{metadata::MetadataTable, LibrarySignatures}; use calyx_utils::{CalyxResult, Error, WithPos}; use std::{ collections::HashSet, @@ -48,8 +48,10 @@ pub struct Workspace { pub lib: LibrarySignatures, /// Original import statements present in the top-level file. pub original_imports: Vec, - /// Optional opaque metadata attached to the top-level file + /// Optional legacy opaque metadata attached to the top-level file. Newer metadata is stored in [Workspace::file_info_table] pub metadata: Option, + /// Optional metadata mapping table attached to the top-level file + pub file_info_table: Option, } impl Workspace { @@ -281,6 +283,7 @@ impl Workspace { // TODO (griffin): Probably not a great idea to clone the metadata // string but it works for now ws.metadata = ns.metadata.clone(); + ws.file_info_table = ns.file_info_table.clone(); // Merge the initial namespace let parent_canonical = parent_path.canonicalize().map_err(|err| { diff --git a/calyx-ir/src/context.rs b/calyx-ir/src/context.rs index cc00e1b86..69fe0c9cd 100644 --- a/calyx-ir/src/context.rs +++ b/calyx-ir/src/context.rs @@ -2,7 +2,7 @@ //! need to transform, lower, an emit a program. //! Passes usually have transform/analyze the components in the IR. use super::{Component, Id}; -use calyx_frontend::LibrarySignatures; +use calyx_frontend::{metadata::MetadataTable, LibrarySignatures}; /// Configuration information for the backends. #[derive(Default)] @@ -32,8 +32,10 @@ pub struct Context { /// Extra options provided to the command line. /// Interpreted by individual passes pub extra_opts: Vec, - /// An optional opaque metadata string which is used by Cider + /// An optional legacy opaque metadata string pub metadata: Option, + /// An optional metadata mapping table + pub file_info_table: Option, } impl Context { diff --git a/calyx-ir/src/from_ast.rs b/calyx-ir/src/from_ast.rs index cf912388b..9eca52523 100644 --- a/calyx-ir/src/from_ast.rs +++ b/calyx-ir/src/from_ast.rs @@ -245,6 +245,7 @@ pub fn ast_to_ir(mut workspace: Workspace) -> CalyxResult { entrypoint, extra_opts: vec![], metadata: workspace.metadata, + file_info_table: workspace.file_info_table, }) }