From 551e3af9d09a03aaa246cac46b98124bc10835ba Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 8 Jul 2021 21:16:16 +0200 Subject: [PATCH] Replace using with from --- src/parse/mod.rs | 48 +++++----- src/parse/parser.rs | 10 ++- src/parse/tokens.rs | 2 +- src/pretty.rs | 6 +- src/syntax/expr.rs | 4 +- src/syntax/token.rs | 6 +- tests/ref/code/import.png | Bin 4148 -> 4279 bytes tests/typ/code/block-scoping.typ | 2 +- tests/typ/code/import.typ | 129 ++++++++++++++------------- tests/typ/code/importable/cycle1.typ | 4 +- tests/typ/code/importable/cycle2.typ | 4 +- tools/support/typst.tmLanguage.json | 4 +- 12 files changed, 112 insertions(+), 107 deletions(-) diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 1d893ad9..c3d532a7 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -728,33 +728,29 @@ fn import_expr(p: &mut Parser) -> Option { let start = p.next_start(); p.assert(Token::Import); + let imports = if p.eat_if(Token::Star) { + // This is the wildcard scenario. + Imports::Wildcard + } else { + // This is the list of identifiers scenario. + p.start_group(Group::Imports, TokenMode::Code); + let items = collection(p).0; + if items.is_empty() { + p.expected_at("import items", p.prev_end()); + } + p.end_group(); + Imports::Idents(idents(p, items)) + }; + let mut import_expr = None; - if let Some(path) = expr(p) { - let imports = if p.expect(Token::Using) { - if p.eat_if(Token::Star) { - // This is the wildcard scenario. - Imports::Wildcard - } else { - // This is the list of identifier scenario. - p.start_group(Group::Expr, TokenMode::Code); - let items = collection(p).0; - if items.is_empty() { - p.expected_at("import items", p.prev_end()); - } - - let idents = idents(p, items); - p.end_group(); - Imports::Idents(idents) - } - } else { - Imports::Idents(vec![]) - }; - - import_expr = Some(Expr::Import(ImportExpr { - span: p.span(start), - imports, - path: Box::new(path), - })); + if p.expect(Token::From) { + if let Some(path) = expr(p) { + import_expr = Some(Expr::Import(ImportExpr { + span: p.span(start), + imports, + path: Box::new(path), + })); + } } import_expr diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 8ea80d68..1e0f2f5d 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -51,6 +51,8 @@ pub enum Group { Stmt, /// A group for a single expression, ended by a line break. Expr, + /// A group for import items, ended by a semicolon, line break or `from`. + Imports, } impl<'s> Parser<'s> { @@ -128,6 +130,7 @@ impl<'s> Parser<'s> { Group::Brace => self.assert(Token::LeftBrace), Group::Stmt => {} Group::Expr => {} + Group::Imports => {} } } @@ -149,6 +152,7 @@ impl<'s> Parser<'s> { Group::Brace => Some((Token::RightBrace, true)), Group::Stmt => Some((Token::Semicolon, false)), Group::Expr => None, + Group::Imports => None, } { if self.next == Some(end) { // Bump the delimeter and return. No need to rescan in this case. @@ -361,6 +365,7 @@ impl<'s> Parser<'s> { Token::RightBracket => self.inside(Group::Bracket), Token::RightBrace => self.inside(Group::Brace), Token::Semicolon => self.inside(Group::Stmt), + Token::From => self.inside(Group::Imports), Token::Space(n) => n >= 1 && self.stop_at_newline(), _ => false, } { @@ -371,7 +376,10 @@ impl<'s> Parser<'s> { /// Whether the active group ends at a newline. fn stop_at_newline(&self) -> bool { let active = self.groups.last().map(|group| group.kind); - matches!(active, Some(Group::Stmt) | Some(Group::Expr)) + matches!( + active, + Some(Group::Stmt) | Some(Group::Expr) | Some(Group::Imports) + ) } /// Whether we are inside the given group. diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index aebe7b70..d979d005 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -496,7 +496,7 @@ fn keyword(id: &str) -> Option> { "return" => Token::Return, "import" => Token::Import, "include" => Token::Include, - "using" => Token::Using, + "from" => Token::From, _ => return None, }) } diff --git a/src/pretty.rs b/src/pretty.rs index ff8841f3..46b82eb7 100644 --- a/src/pretty.rs +++ b/src/pretty.rs @@ -440,9 +440,9 @@ impl Pretty for ForPattern { impl Pretty for ImportExpr { fn pretty(&self, p: &mut Printer) { p.push_str("import "); - self.path.pretty(p); - p.push_str(" using "); self.imports.pretty(p); + p.push_str(" from "); + self.path.pretty(p); } } @@ -737,7 +737,7 @@ mod tests { roundtrip("#while x {y}"); roundtrip("#for x in y {z}"); roundtrip("#for k, x in y {z}"); - roundtrip("#import \"file.typ\" using *"); + roundtrip("#import * from \"file.typ\""); roundtrip("#include \"chapter1.typ\""); } diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index f5b79122..c4462ff8 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -59,7 +59,7 @@ pub enum Expr { While(WhileExpr), /// A for loop expression: `for x in y { z }`. For(ForExpr), - /// An import expression: `import "utils.typ" using a, b, c`. + /// An import expression: `import a, b, c from "utils.typ"`. Import(ImportExpr), /// An include expression: `include "chapter1.typ"`. Include(IncludeExpr), @@ -466,7 +466,7 @@ pub struct LetExpr { pub init: Option>, } -/// An import expression: `import "utils.typ" using a, b, c`. +/// An import expression: `import a, b, c from "utils.typ"`. #[derive(Debug, Clone, PartialEq)] pub struct ImportExpr { /// The source code location. diff --git a/src/syntax/token.rs b/src/syntax/token.rs index 425dac10..c14cf9f7 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -101,8 +101,8 @@ pub enum Token<'s> { Import, /// The `include` keyword. Include, - /// The `using` keyword. - Using, + /// The `from` keyword. + From, /// One or more whitespace characters. /// /// The contained `usize` denotes the number of newlines that were contained @@ -254,7 +254,7 @@ impl<'s> Token<'s> { Self::Return => "keyword `return`", Self::Import => "keyword `import`", Self::Include => "keyword `include`", - Self::Using => "keyword `using`", + Self::From => "keyword `from`", Self::Space(_) => "space", Self::Text(_) => "text", Self::UnicodeEscape(_) => "unicode escape sequence", diff --git a/tests/ref/code/import.png b/tests/ref/code/import.png index 0a811495529a1fef0e958a76b7d3d380b4c911da..75d4adce466752d86eda4a1156e495f57baaaa18 100644 GIT binary patch delta 4004 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 Bb^ibW delta 3910 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