Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use statements #547

Merged
merged 5 commits into from
Oct 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/analyzer/src/namespace/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ impl ModuleId {
sink.push(&diag)
}
}
ast::ModuleStmt::Import(inner) => {
sink.push(&errors::not_yet_implemented("import", inner.span));
ast::ModuleStmt::Use(inner) => {
sink.push(&errors::not_yet_implemented("use", inner.span));
}
_ => {} // everything else is a type def, handled below.
}
Expand Down
2 changes: 1 addition & 1 deletion crates/lowering/src/mappers/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn module(db: &dyn AnalyzerDb, module: ModuleId) -> ast::Module {
.iter()
.filter_map(|stmt| match stmt {
ast::ModuleStmt::Pragma(_) => Some(stmt.clone()),
ast::ModuleStmt::Import(_) => Some(stmt.clone()),
ast::ModuleStmt::Use(_) => Some(stmt.clone()),
_ => None,
})
.collect::<Vec<_>>();
Expand Down
128 changes: 63 additions & 65 deletions crates/parser/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct Module {
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub enum ModuleStmt {
Pragma(Node<Pragma>),
Import(Node<Import>),
Use(Node<Use>),
TypeAlias(Node<TypeAlias>),
Contract(Node<Contract>),
Struct(Node<Struct>),
Expand All @@ -27,13 +27,28 @@ pub struct Pragma {
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub enum Import {
Simple {
names: Vec<Node<SimpleImportName>>,
pub struct Path {
pub names: Vec<Node<String>>,
pub trailing_delim: bool,
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct Use {
pub tree: Node<UseTree>,
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub enum UseTree {
Glob {
prefix: Node<Path>,
},
From {
path: Node<FromImportPath>,
names: Node<FromImportNames>,
Nested {
prefix: Node<Path>,
children: Vec<Node<UseTree>>,
},
Simple {
path: Node<Path>,
rename: Option<Node<String>>,
},
}

Expand Down Expand Up @@ -90,35 +105,6 @@ impl Spanned for GenericArg {
}
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct SimpleImportName {
pub path: Vec<Node<String>>,
pub alias: Option<Node<String>>,
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub enum FromImportPath {
Absolute {
path: Vec<Node<String>>,
},
Relative {
parent_level: usize,
path: Vec<Node<String>>,
},
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub enum FromImportNames {
Star,
List(Vec<Node<FromImportName>>),
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct FromImportName {
pub name: Node<String>,
pub alias: Option<Node<String>>,
}

/// struct or contract field, with optional 'pub' and 'const' qualifiers
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct Field {
Expand Down Expand Up @@ -373,7 +359,7 @@ impl Spanned for ModuleStmt {
fn span(&self) -> Span {
match self {
ModuleStmt::Pragma(inner) => inner.span,
ModuleStmt::Import(inner) => inner.span,
ModuleStmt::Use(inner) => inner.span,
ModuleStmt::TypeAlias(inner) => inner.span,
ModuleStmt::Contract(inner) => inner.span,
ModuleStmt::Struct(inner) => inner.span,
Expand All @@ -400,7 +386,7 @@ impl fmt::Display for ModuleStmt {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
ModuleStmt::Pragma(node) => write!(f, "{}", node.kind),
ModuleStmt::Import(node) => write!(f, "{}", node.kind),
ModuleStmt::Use(node) => write!(f, "{}", node.kind),
ModuleStmt::TypeAlias(node) => write!(f, "{}", node.kind),
ModuleStmt::Contract(node) => write!(f, "{}", node.kind),
ModuleStmt::Struct(node) => write!(f, "{}", node.kind),
Expand All @@ -414,9 +400,45 @@ impl fmt::Display for Pragma {
}
}

impl fmt::Display for Import {
fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
todo!()
impl fmt::Display for Use {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "use {}", self.tree.kind)
}
}

impl fmt::Display for UseTree {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
UseTree::Glob { prefix } => write!(f, "{}*", prefix.kind),
UseTree::Simple { path, rename } => {
if let Some(rename) = rename {
write!(f, "{} as {}", path.kind, rename.kind)
} else {
write!(f, "{}", path.kind)
}
}
UseTree::Nested { prefix, children } => {
write!(f, "{}{{{}}}", prefix.kind, node_comma_joined(children))
}
}
}
}

impl fmt::Display for Path {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let joined_names = self
.names
.iter()
.map(|name| name.kind.to_string())
.collect::<Vec<_>>()
.join("::");
write!(f, "{}", joined_names)?;

if self.trailing_delim {
write!(f, "::")?;
}

Ok(())
}
}

Expand Down Expand Up @@ -474,30 +496,6 @@ impl fmt::Display for GenericArg {
}
}

impl fmt::Display for SimpleImportName {
fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
todo!()
}
}

impl fmt::Display for FromImportPath {
fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
todo!()
}
}

impl fmt::Display for FromImportNames {
fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
todo!()
}
}

impl fmt::Display for FromImportName {
fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
todo!()
}
}

impl fmt::Display for Field {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if self.is_pub {
Expand Down
21 changes: 9 additions & 12 deletions crates/parser/src/grammar/Fe.grammar
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,21 @@ file_input: NEWLINE ENDMARKER | module_stmt+ ENDMARKER

module_stmt: import_stmt | type_def | contract_def

########################### import_stmt ##############################
########################### path ######################################

import_stmt: (simple_import | from_import) NEWLINE
path: NAME ('::' NAME)*

simple_import: 'import' (simple_import_name (',' simple_import_name)*)
simple_import_name: dotted_name ['as' NAME]
trailing_delim_path: path '::'

from_import: from_import_parent_alt | from_import_sub_alt
########################### use_stmt ##################################

from_import_parent_alt: 'from' '.'+ 'import' from_import_names
from_import_sub_alt: 'from' from_import_sub_path 'import' from_import_names
use_stmt: 'use' use_tree NEWLINE

from_import_sub_path: '.'* dotted_name
from_import_names: '*' | '(' from_import_names_list ')' | from_import_names_list
from_import_names_list: from_import_name (',' from_import_name)* [',']
from_import_name: NAME ['as' NAME]
use_tree: (simple_use_tree | glob_use_tree | nested_use_tree)

dotted_name: NAME ('.' NAME)*
simple_use_tree: path ['as' NAME]
glob_use_tree: trailing_delim_path '*'
nested_use_tree: trailing_delim_path '{' [use_tree (',' use_tree)* [',']] '}'

########################### type_def #################################

Expand Down
Loading