From b8d70d33933de3c9d1efeecb562539de3486f947 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 23 Jan 2024 01:51:00 -0600 Subject: [PATCH] Cleanup: Break Loc out into a common module, rename WhileParsing => Parsing --- cl-frontend/examples/identify_tokens.rs | 2 +- libconlang/src/ast.rs | 37 +--- libconlang/src/ast/ast_impl.rs | 13 -- libconlang/src/common.rs | 46 +++++ libconlang/src/interpreter.rs | 2 +- libconlang/src/lib.rs | 2 + libconlang/src/parser.rs | 258 ++++++++++++------------ libconlang/src/token.rs | 2 +- 8 files changed, 182 insertions(+), 180 deletions(-) create mode 100644 libconlang/src/common.rs diff --git a/cl-frontend/examples/identify_tokens.rs b/cl-frontend/examples/identify_tokens.rs index 6799df0..cbd0b61 100644 --- a/cl-frontend/examples/identify_tokens.rs +++ b/cl-frontend/examples/identify_tokens.rs @@ -47,7 +47,7 @@ fn lex_tokens(file: &str, path: Option<&Path>) -> Result<(), Box> { Err(e) => { println!("{e:?}"); continue; - }, + } }; if let Some(path) = path { print!("{path:?}:") diff --git a/libconlang/src/ast.rs b/libconlang/src/ast.rs index 2873578..0320aeb 100644 --- a/libconlang/src/ast.rs +++ b/libconlang/src/ast.rs @@ -9,44 +9,9 @@ //! - [AssignKind], [BinaryKind], and [UnaryKind] operators //! - [Ty] and [TyKind]: Type qualifiers //! - [Path]: Path expressions -//! -//! # Notable structures -//! - [struct@Span]: Stores the start and end [struct@Loc] of a notable AST node -//! - [struct@Loc]: Stores the line/column of a notable AST node -#![allow(non_snake_case)] - +use crate::common::*; pub mod ast_impl; -// Universal data types - -/// Stores the start and end [locations](struct@Loc) within the token stream -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Span { - pub head: Loc, - pub tail: Loc, -} -pub fn Span(head: Loc, tail: Loc) -> Span { - Span { head, tail } -} - -/// Stores a read-only (line, column) location in a token stream -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Loc { - line: u32, - col: u32, -} -pub fn Loc(line: u32, col: u32) -> Loc { - Loc { line, col } -} -impl Loc { - pub fn line(self) -> u32 { - self.line - } - pub fn col(self) -> u32 { - self.col - } -} - #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] pub enum Mutability { #[default] diff --git a/libconlang/src/ast/ast_impl.rs b/libconlang/src/ast/ast_impl.rs index d952549..e4e5ce6 100644 --- a/libconlang/src/ast/ast_impl.rs +++ b/libconlang/src/ast/ast_impl.rs @@ -54,12 +54,6 @@ mod display { } } - impl Display for Loc { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let Loc { line, col } = self; - write!(f, "{line}:{col}:") - } - } impl Display for Mutability { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -630,7 +624,6 @@ pub mod format { mod convert { //! Converts between major enums and enum variants use super::*; - use crate::lexer::Lexer; impl> From for Identifier { fn from(value: T) -> Self { @@ -735,10 +728,4 @@ mod convert { Self { body: Some(value.into()) } } } - - impl<'t> From<&Lexer<'t>> for Loc { - fn from(value: &Lexer<'t>) -> Self { - Self { line: value.line(), col: value.col() } - } - } } diff --git a/libconlang/src/common.rs b/libconlang/src/common.rs new file mode 100644 index 0000000..6382f3f --- /dev/null +++ b/libconlang/src/common.rs @@ -0,0 +1,46 @@ +//! # Universally useful structures +//! - [struct@Span]: Stores the start and end [struct@Loc] of a notable AST node +//! - [struct@Loc]: Stores the line/column of a notable AST node +#![allow(non_snake_case)] +use crate::lexer::Lexer; + +/// Stores the start and end [locations](struct@Loc) within the token stream +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Span { + pub head: Loc, + pub tail: Loc, +} +pub fn Span(head: Loc, tail: Loc) -> Span { + Span { head, tail } +} + +/// Stores a read-only (line, column) location in a token stream +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Loc { + line: u32, + col: u32, +} +pub fn Loc(line: u32, col: u32) -> Loc { + Loc { line, col } +} +impl Loc { + pub fn line(self) -> u32 { + self.line + } + pub fn col(self) -> u32 { + self.col + } +} + +impl std::fmt::Display for Loc { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Loc { line, col } = self; + write!(f, "{line}:{col}:") + } +} + +impl<'t> From<&Lexer<'t>> for Loc { + fn from(value: &Lexer<'t>) -> Self { + Loc(value.line(), value.col()) + } +} diff --git a/libconlang/src/interpreter.rs b/libconlang/src/interpreter.rs index 4ec09a6..8598aea 100644 --- a/libconlang/src/interpreter.rs +++ b/libconlang/src/interpreter.rs @@ -1043,7 +1043,7 @@ pub mod error { //! The [Error] type represents any error thrown by the [Environment](super::Environment) use super::temp_type_impl::ConValue; - use crate::ast::Loc; + use crate::common::Loc; pub type IResult = Result; diff --git a/libconlang/src/lib.rs b/libconlang/src/lib.rs index fbbbad4..73cbe7e 100644 --- a/libconlang/src/lib.rs +++ b/libconlang/src/lib.rs @@ -2,6 +2,8 @@ #![warn(clippy::all)] #![feature(decl_macro)] +pub mod common; + pub mod token; pub mod ast; diff --git a/libconlang/src/parser.rs b/libconlang/src/parser.rs index 76784a7..2df8abe 100644 --- a/libconlang/src/parser.rs +++ b/libconlang/src/parser.rs @@ -1,16 +1,17 @@ //! Parses [tokens](super::token) into an [AST](super::ast) -//! +//! //! For the full grammar, see [grammar.ebnf][1] -//! +//! //! [1]: https://git.soft.fish/j/Conlang/src/branch/main/grammar.ebnf use self::error::{ Error, ErrorKind::{self, *}, - PResult, WhileParsing, + PResult, Parsing, }; use crate::{ ast::*, + common::*, lexer::{error::Error as LexError, Lexer}, token::{ token_data::Data, @@ -29,7 +30,7 @@ pub mod error { #[derive(Clone, Debug, PartialEq, Eq)] pub struct Error { pub reason: ErrorKind, - pub while_parsing: WhileParsing, + pub while_parsing: Parsing, pub loc: Loc, } impl std::error::Error for Error {} @@ -64,7 +65,7 @@ pub mod error { /// Compactly represents the stage of parsing an [Error] originated in #[derive(Clone, Copy, Debug, PartialEq, Eq)] - pub enum WhileParsing { + pub enum Parsing { File, Item, @@ -155,67 +156,67 @@ pub mod error { } } } - impl Display for WhileParsing { + impl Display for Parsing { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - WhileParsing::File => "a file", - WhileParsing::Item => "an item", - WhileParsing::Visibility => "a visibility qualifier", - WhileParsing::Mutability => "a mutability qualifier", - WhileParsing::ItemKind => "an item", - WhileParsing::Const => "a const item", - WhileParsing::Static => "a static variable", - WhileParsing::Module => "a module", - WhileParsing::ModuleKind => "a module", - WhileParsing::Function => "a function", - WhileParsing::Param => "a function parameter", - WhileParsing::Struct => "a struct", - WhileParsing::StructKind => "a struct", - WhileParsing::StructMember => "a struct member", - WhileParsing::Enum => "an enum", - WhileParsing::EnumKind => "an enum", - WhileParsing::Variant => "an enum variant", - WhileParsing::VariantKind => "an enum variant", - WhileParsing::Impl => "an impl block", + Parsing::File => "a file", + Parsing::Item => "an item", + Parsing::Visibility => "a visibility qualifier", + Parsing::Mutability => "a mutability qualifier", + Parsing::ItemKind => "an item", + Parsing::Const => "a const item", + Parsing::Static => "a static variable", + Parsing::Module => "a module", + Parsing::ModuleKind => "a module", + Parsing::Function => "a function", + Parsing::Param => "a function parameter", + Parsing::Struct => "a struct", + Parsing::StructKind => "a struct", + Parsing::StructMember => "a struct member", + Parsing::Enum => "an enum", + Parsing::EnumKind => "an enum", + Parsing::Variant => "an enum variant", + Parsing::VariantKind => "an enum variant", + Parsing::Impl => "an impl block", - WhileParsing::Ty => "a type", - WhileParsing::TyKind => "a type", - WhileParsing::TyTuple => "a tuple of types", - WhileParsing::TyRef => "a reference type", - WhileParsing::TyFn => "a function pointer type", + Parsing::Ty => "a type", + Parsing::TyKind => "a type", + Parsing::TyTuple => "a tuple of types", + Parsing::TyRef => "a reference type", + Parsing::TyFn => "a function pointer type", - WhileParsing::Stmt => "a statement", - WhileParsing::StmtKind => "a statement", - WhileParsing::Let => "a local variable declaration", + Parsing::Stmt => "a statement", + Parsing::StmtKind => "a statement", + Parsing::Let => "a local variable declaration", - WhileParsing::Expr => "an expression", - WhileParsing::ExprKind => "an expression", - WhileParsing::Assign => "an assignment", - WhileParsing::AssignKind => "an assignment", - WhileParsing::Binary => "a binary expression", - WhileParsing::BinaryKind => "a binary expression", - WhileParsing::Unary => "a unary expression", - WhileParsing::UnaryKind => "a unary expression", - WhileParsing::Index => "an indexing expression", - WhileParsing::Call => "a call expression", - WhileParsing::Member => "a member access expression", - WhileParsing::PathExpr => "a path", - WhileParsing::PathPart => "a path component", - WhileParsing::Identifier => "an identifier", - WhileParsing::Literal => "a literal", - WhileParsing::Array => "an array", - WhileParsing::ArrayRep => "an array of form [k;N]", - WhileParsing::AddrOf => "a borrow op", - WhileParsing::Block => "a block", - WhileParsing::Group => "a grouped expression", - WhileParsing::Tuple => "a tuple", - WhileParsing::While => "a while expression", - WhileParsing::If => "an if expression", - WhileParsing::For => "a for expression", - WhileParsing::Else => "an else block", - WhileParsing::Break => "a break expression", - WhileParsing::Return => "a return expression", - WhileParsing::Continue => "a continue expression", + Parsing::Expr => "an expression", + Parsing::ExprKind => "an expression", + Parsing::Assign => "an assignment", + Parsing::AssignKind => "an assignment", + Parsing::Binary => "a binary expression", + Parsing::BinaryKind => "a binary expression", + Parsing::Unary => "a unary expression", + Parsing::UnaryKind => "a unary expression", + Parsing::Index => "an indexing expression", + Parsing::Call => "a call expression", + Parsing::Member => "a member access expression", + Parsing::PathExpr => "a path", + Parsing::PathPart => "a path component", + Parsing::Identifier => "an identifier", + Parsing::Literal => "a literal", + Parsing::Array => "an array", + Parsing::ArrayRep => "an array of form [k;N]", + Parsing::AddrOf => "a borrow op", + Parsing::Block => "a block", + Parsing::Group => "a grouped expression", + Parsing::Tuple => "a tuple", + Parsing::While => "a while expression", + Parsing::If => "an if expression", + Parsing::For => "a for expression", + Parsing::Else => "an else block", + Parsing::Break => "a break expression", + Parsing::Return => "a return expression", + Parsing::Continue => "a continue expression", } .fmt(f) } @@ -241,17 +242,18 @@ impl<'t> Parser<'t> { } /// Constructs an [Error] - fn error(&self, reason: ErrorKind, while_parsing: WhileParsing) -> Error { + fn error(&self, reason: ErrorKind, while_parsing: Parsing) -> Error { Error { reason, while_parsing, loc: self.loc } } /// Internal impl of peek and consume - fn consume_from_lexer(&mut self, while_parsing: WhileParsing) -> PResult { + fn consume_from_lexer(&mut self, while_parsing: Parsing) -> PResult { loop { match self .lexer .scan() .map_err(|e| self.error(e.into(), while_parsing))? { + t if t.ty() == Type::Invalid => continue, t if t.ty() == Type::Comment => continue, t => break Ok(t), } @@ -260,7 +262,7 @@ impl<'t> Parser<'t> { /// Looks ahead one token /// /// Stores the token in an internal lookahead buffer - pub fn peek(&mut self, while_parsing: WhileParsing) -> PResult<&Token> { + pub fn peek(&mut self, while_parsing: Parsing) -> PResult<&Token> { if self.next.is_none() { self.next = Some(self.consume_from_lexer(while_parsing)?); } @@ -276,11 +278,11 @@ impl<'t> Parser<'t> { self.next.take() } /// Looks ahead at the next [Token]'s [Type] - pub fn peek_type(&mut self, while_parsing: WhileParsing) -> PResult { + pub fn peek_type(&mut self, while_parsing: Parsing) -> PResult { self.peek(while_parsing).map(|t| t.ty()) } /// Consumes one [Token] - pub fn consume(&mut self, while_parsing: WhileParsing) -> PResult { + pub fn consume(&mut self, while_parsing: Parsing) -> PResult { self.loc = Loc::from(&self.lexer); match self.next.take() { Some(token) => Ok(token), @@ -288,7 +290,7 @@ impl<'t> Parser<'t> { } } /// Consumes the next [Token] if it matches the pattern [Type] - pub fn match_type(&mut self, want: Type, while_parsing: WhileParsing) -> PResult { + pub fn match_type(&mut self, want: Type, while_parsing: Parsing) -> PResult { let got = self.peek_type(while_parsing)?; if got == want { Ok(self.consume_peeked().expect("should not fail after peek")) @@ -297,7 +299,7 @@ impl<'t> Parser<'t> { } } /// Consumes the next token if it matches the pattern [Keyword] - pub fn match_kw(&mut self, pat: Keyword, while_parsing: WhileParsing) -> PResult { + pub fn match_kw(&mut self, pat: Keyword, while_parsing: Parsing) -> PResult { self.match_type(Type::Keyword(pat), while_parsing) } } @@ -310,7 +312,7 @@ impl<'t> Parser<'t> { open: Type, f: F, close: Type, - while_parsing: WhileParsing, + while_parsing: Parsing, ) -> PResult where F: Fn(&mut Self) -> PResult, @@ -328,7 +330,7 @@ impl<'t> Parser<'t> { separator: Type, f: F, terminator: Type, - while_parsing: WhileParsing, + while_parsing: Parsing, ) -> PResult> where F: Fn(&mut Self) -> PResult, @@ -350,7 +352,7 @@ impl<'t> Parser<'t> { &mut self, f: F, terminator: Type, - while_parsing: WhileParsing, + while_parsing: Parsing, ) -> PResult> where F: Fn(&mut Self) -> PResult, @@ -382,7 +384,7 @@ impl<'t> Parser<'t> { /// Parses a [File] pub fn file(&mut self) -> PResult { let mut items = vec![]; - while match self.peek_type(WhileParsing::File) { + while match self.peek_type(Parsing::File) { Ok(Type::RCurly) | Err(Error { reason: EndOfInput, .. }) => false, Ok(_) => true, Err(e) => Err(e)?, @@ -416,7 +418,7 @@ impl<'t> Parser<'t> { /// /// See also: [Parser::path_part], [Parser::identifier] pub fn path(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::PathExpr; + const PARSING: Parsing = Parsing::PathExpr; let absolute = matches!(self.peek_type(PARSING)?, Type::ColonColon); if absolute { self.consume_peeked(); @@ -434,7 +436,7 @@ impl<'t> Parser<'t> { /// /// See also: [Parser::stmtkind] pub fn stmt(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Stmt; + const PARSING: Parsing = Parsing::Stmt; let start = self.loc(); Ok(Stmt { kind: match self.peek_type(PARSING)? { @@ -468,7 +470,7 @@ impl<'t> Parser<'t> { /// /// See also: [Parser::item] pub fn itemkind(&mut self) -> PResult { - Ok(match self.peek_type(WhileParsing::Item)? { + Ok(match self.peek_type(Parsing::Item)? { Type::Keyword(Keyword::Const) => self.parse_const()?.into(), Type::Keyword(Keyword::Static) => self.parse_static()?.into(), Type::Keyword(Keyword::Mod) => self.parse_module()?.into(), @@ -476,12 +478,12 @@ impl<'t> Parser<'t> { Type::Keyword(Keyword::Struct) => self.parse_struct()?.into(), Type::Keyword(Keyword::Enum) => self.parse_enum()?.into(), Type::Keyword(Keyword::Impl) => self.parse_impl()?.into(), - t => Err(self.error(Unexpected(t), WhileParsing::Item))?, + t => Err(self.error(Unexpected(t), Parsing::Item))?, }) } pub fn parse_const(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Const; + const PARSING: Parsing = Parsing::Const; self.match_kw(Keyword::Const, PARSING)?; let out = Ok(Const { name: self.identifier()?, @@ -498,7 +500,7 @@ impl<'t> Parser<'t> { out } pub fn parse_static(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Static; + const PARSING: Parsing = Parsing::Static; self.match_kw(Keyword::Static, PARSING)?; let out = Ok(Static { mutable: self.mutability()?, @@ -516,12 +518,12 @@ impl<'t> Parser<'t> { out } pub fn parse_module(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Module; + const PARSING: Parsing = Parsing::Module; self.match_kw(Keyword::Mod, PARSING)?; Ok(Module { name: self.identifier()?, kind: self.modulekind()? }) } pub fn modulekind(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::ModuleKind; + const PARSING: Parsing = Parsing::ModuleKind; match self.peek_type(PARSING)? { Type::LCurly => Ok(ModuleKind::Inline(self.delimited( Type::LCurly, @@ -537,7 +539,7 @@ impl<'t> Parser<'t> { } } pub fn parse_function(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Function; + const PARSING: Parsing = Parsing::Function; self.match_kw(Keyword::Fn, PARSING)?; Ok(Function { name: self.identifier()?, @@ -561,7 +563,7 @@ impl<'t> Parser<'t> { }) } pub fn parse_params(&mut self) -> PResult> { - const PARSING: WhileParsing = WhileParsing::Function; + const PARSING: Parsing = Parsing::Function; self.delimited( Type::LParen, |this| this.separated(Type::Comma, Self::parse_param, Type::RParen, PARSING), @@ -574,13 +576,13 @@ impl<'t> Parser<'t> { mutability: self.mutability()?, name: self.identifier()?, ty: { - self.match_type(Type::Colon, WhileParsing::Param)?; + self.match_type(Type::Colon, Parsing::Param)?; self.ty()?.into() }, }) } pub fn parse_struct(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Struct; + const PARSING: Parsing = Parsing::Struct; self.match_kw(Keyword::Struct, PARSING)?; Ok(Struct { name: self.identifier()?, @@ -596,7 +598,7 @@ impl<'t> Parser<'t> { }) } pub fn structkind_tuple(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::StructKind; + const PARSING: Parsing = Parsing::StructKind; Ok(StructKind::Tuple(self.delimited( Type::LParen, @@ -606,7 +608,7 @@ impl<'t> Parser<'t> { )?)) } pub fn structkind_struct(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::StructKind; + const PARSING: Parsing = Parsing::StructKind; Ok(StructKind::Struct(self.delimited( Type::LCurly, @@ -616,7 +618,7 @@ impl<'t> Parser<'t> { )?)) } pub fn struct_member(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::StructMember; + const PARSING: Parsing = Parsing::StructMember; Ok(StructMember { vis: self.visibility()?, name: self.identifier()?, @@ -627,25 +629,25 @@ impl<'t> Parser<'t> { }) } pub fn parse_enum(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Enum; + const PARSING: Parsing = Parsing::Enum; self.match_kw(Keyword::Enum, PARSING)?; Err(self.error(Todo, PARSING)) } pub fn parse_impl(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Impl; + const PARSING: Parsing = Parsing::Impl; self.match_kw(Keyword::Impl, PARSING)?; Err(self.error(Todo, PARSING)) } pub fn visibility(&mut self) -> PResult { - if let Type::Keyword(Keyword::Pub) = self.peek_type(WhileParsing::Visibility)? { + if let Type::Keyword(Keyword::Pub) = self.peek_type(Parsing::Visibility)? { self.consume_peeked(); return Ok(Visibility::Public); }; Ok(Visibility::Private) } pub fn mutability(&mut self) -> PResult { - if let Type::Keyword(Keyword::Mut) = self.peek_type(WhileParsing::Mutability)? { + if let Type::Keyword(Keyword::Mut) = self.peek_type(Parsing::Mutability)? { self.consume_peeked(); return Ok(Mutability::Mut); }; @@ -659,7 +661,7 @@ impl<'t> Parser<'t> { /// /// See also: [Parser::ty] pub fn tykind(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::TyKind; + const PARSING: Parsing = Parsing::TyKind; let out = match self.peek_type(PARSING)? { Type::Bang => { self.consume_peeked(); @@ -676,7 +678,7 @@ impl<'t> Parser<'t> { } /// [TyTuple] = `(` ([Ty] `,`)* [Ty]? `)` pub fn tytuple(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::TyTuple; + const PARSING: Parsing = Parsing::TyTuple; Ok(TyTuple { types: self.delimited( Type::LParen, @@ -688,7 +690,7 @@ impl<'t> Parser<'t> { } /// [TyRef] = (`&`|`&&`)* [Path] pub fn tyref(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::TyRef; + const PARSING: Parsing = Parsing::TyRef; let mut count = 0; loop { match self.peek_type(PARSING)? { @@ -702,7 +704,7 @@ impl<'t> Parser<'t> { } /// [TyFn] = `fn` [TyTuple] (-> [Ty])? pub fn tyfn(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::TyFn; + const PARSING: Parsing = Parsing::TyFn; self.match_type(Type::Keyword(Keyword::Fn), PARSING)?; Ok(TyFn { args: self.tytuple()?, @@ -735,7 +737,7 @@ macro path_like() { impl<'t> Parser<'t> { /// [PathPart] = `super` | `self` | [Identifier] pub fn path_part(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::PathPart; + const PARSING: Parsing = Parsing::PathPart; let out = match self.peek_type(PARSING)? { Type::Keyword(Keyword::Super) => PathPart::SuperKw, Type::Keyword(Keyword::SelfKw) => PathPart::SelfKw, @@ -747,7 +749,7 @@ impl<'t> Parser<'t> { } /// [Identifier] = [`Identifier`](Type::Identifier) pub fn identifier(&mut self) -> PResult { - let tok = self.match_type(Type::Identifier, WhileParsing::Identifier)?; + let tok = self.match_type(Type::Identifier, Parsing::Identifier)?; match tok.data() { Data::Identifier(ident) => Ok(ident.into()), _ => panic!("Expected token data for {tok:?}"), @@ -761,7 +763,7 @@ impl<'t> Parser<'t> { /// /// See also: [Parser::stmt] pub fn stmtkind(&mut self) -> PResult { - match self.peek_type(WhileParsing::StmtKind)? { + match self.peek_type(Parsing::StmtKind)? { Type::Semi => Ok(StmtKind::Empty), Type::Keyword(Keyword::Let) => self.stmtkind_local(), item_like!() => self.stmtkind_item(), @@ -779,11 +781,11 @@ impl<'t> Parser<'t> { } pub fn parse_let(&mut self) -> PResult { - self.match_kw(Keyword::Let, WhileParsing::Let)?; + self.match_kw(Keyword::Let, Parsing::Let)?; Ok(Let { mutable: self.mutability()?, name: self.identifier()?, - init: if Type::Eq == self.peek_type(WhileParsing::Let)? { + init: if Type::Eq == self.peek_type(Parsing::Let)? { self.consume_peeked(); Some(self.expr()?.into()) } else { @@ -882,7 +884,7 @@ impl<'t> Parser<'t> { } /// Call = [Index] (`(` [Tuple]? `)`)* pub fn exprkind_call(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Call; + const PARSING: Parsing = Parsing::Call; let callee = self.expr_from(Self::exprkind_index)?; let mut args = vec![]; while Ok(Type::LParen) == self.peek_type(PARSING) { @@ -898,7 +900,7 @@ impl<'t> Parser<'t> { } /// [Index] = [Primary](Parser::exprkind_primary) (`[` [Indices] `]`)* pub fn exprkind_index(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Index; + const PARSING: Parsing = Parsing::Index; let head = self.expr_from(Self::exprkind_primary)?; if Type::LBrack != self.peek_type(PARSING)? { return Ok(head.kind); @@ -914,7 +916,7 @@ impl<'t> Parser<'t> { } /// Delegates to the set of highest-priority rules based on unambiguous pattern matching pub fn exprkind_primary(&mut self) -> PResult { - match self.peek_type(WhileParsing::Expr)? { + match self.peek_type(Parsing::Expr)? { Type::Amp | Type::AmpAmp => self.exprkind_addrof(), Type::LCurly => self.exprkind_block(), Type::LBrack => self.exprkind_array(), @@ -927,7 +929,7 @@ impl<'t> Parser<'t> { Type::Keyword(Keyword::Break) => Ok(self.parse_break()?.into()), Type::Keyword(Keyword::Return) => Ok(self.parse_return()?.into()), Type::Keyword(Keyword::Continue) => Ok(self.parse_continue()?.into()), - _ => Err(self.error(Nothing, WhileParsing::Expr)), + _ => Err(self.error(Nothing, Parsing::Expr)), } } /// [Array] = '[' ([Expr] ',')* [Expr]? ']' @@ -935,7 +937,7 @@ impl<'t> Parser<'t> { /// Array and ArrayRef are ambiguous until the second token, /// so they can't be independent subexpressions pub fn exprkind_array(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Array; + const PARSING: Parsing = Parsing::Array; const START: Type = Type::LBrack; const END: Type = Type::RBrack; self.match_type(START, PARSING)?; @@ -949,7 +951,7 @@ impl<'t> Parser<'t> { } /// [ArrayRep] = `[` [Expr] `;` [Expr] `]` pub fn exprkind_array_rep(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Array; + const PARSING: Parsing = Parsing::Array; const END: Type = Type::RBrack; let first = self.expr()?; let out: ExprKind = match self.peek_type(PARSING)? { @@ -979,7 +981,7 @@ impl<'t> Parser<'t> { /// [AddrOf] = (`&`|`&&`)* [Expr] pub fn exprkind_addrof(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::AddrOf; + const PARSING: Parsing = Parsing::AddrOf; let mut count = 0; loop { match self.peek_type(PARSING)? { @@ -999,27 +1001,27 @@ impl<'t> Parser<'t> { /// /// [ExprKind::Empty] and [Group] are special cases of [Tuple] pub fn exprkind_empty_group_or_tuple(&mut self) -> PResult { - self.match_type(Type::LParen, WhileParsing::Group)?; - let out = match self.peek_type(WhileParsing::Group)? { + self.match_type(Type::LParen, Parsing::Group)?; + let out = match self.peek_type(Parsing::Group)? { Type::RParen => Ok(ExprKind::Empty), _ => self.exprkind_group(), }; - match self.peek_type(WhileParsing::Group) { + match self.peek_type(Parsing::Group) { Ok(Type::RParen) => self.consume_peeked(), - _ => Err(self.error(UnmatchedParentheses, WhileParsing::Group))?, + _ => Err(self.error(UnmatchedParentheses, Parsing::Group))?, }; out } /// [Group] = `(`([Empty](ExprKind::Empty)|[Expr]|[Tuple])`)` pub fn exprkind_group(&mut self) -> PResult { let first = self.expr()?; - match self.peek_type(WhileParsing::Group)? { + match self.peek_type(Parsing::Group)? { Type::Comma => { let mut exprs = vec![first]; self.consume_peeked(); - while Type::RParen != self.peek_type(WhileParsing::Tuple)? { + while Type::RParen != self.peek_type(Parsing::Tuple)? { exprs.push(self.expr()?); - match self.peek_type(WhileParsing::Tuple)? { + match self.peek_type(Parsing::Tuple)? { Type::Comma => self.consume_peeked(), _ => break, }; @@ -1036,13 +1038,13 @@ impl<'t> Parser<'t> { /// [Literal] = [String](Type::String) | [Character](Type::Character) /// | [Float](Type::Float) (TODO) | [Integer](Type::Integer) | `true` | `false` pub fn literal(&mut self) -> PResult { - let tok = self.consume(WhileParsing::Literal)?; + let tok = self.consume(Parsing::Literal)?; // keyword literals true and false match tok.ty() { Type::Keyword(Keyword::True) => return Ok(Literal::Bool(true)), Type::Keyword(Keyword::False) => return Ok(Literal::Bool(false)), Type::String | Type::Character | Type::Integer | Type::Float => (), - t => return Err(self.error(Unexpected(t), WhileParsing::Literal)), + t => return Err(self.error(Unexpected(t), Parsing::Literal)), } Ok(match tok.data() { Data::String(v) => Literal::from(v.as_str()), @@ -1061,7 +1063,7 @@ impl<'t> Parser<'t> { Err(e) => return Err(e), } { exprs.push(expr); - match self.peek_type(WhileParsing::Tuple)? { + match self.peek_type(Parsing::Tuple)? { Type::Comma => self.consume_peeked(), _ => break, }; @@ -1070,7 +1072,7 @@ impl<'t> Parser<'t> { } /// [Block] = `{` [Stmt]* `}` pub fn block(&mut self) -> PResult { - const PARSING: WhileParsing = WhileParsing::Block; + const PARSING: Parsing = Parsing::Block; const START: Type = Type::LCurly; const END: Type = Type::RCurly; Ok(Block { @@ -1087,22 +1089,22 @@ impl<'t> Parser<'t> { impl<'t> Parser<'t> { /// [Break] = `break` [Expr]? pub fn parse_break(&mut self) -> PResult { - self.match_kw(Keyword::Break, WhileParsing::Break)?; + self.match_kw(Keyword::Break, Parsing::Break)?; Ok(Break { body: self.optional_expr()?.map(Into::into) }) } /// [Return] = `return` [Expr]? pub fn parse_return(&mut self) -> PResult { - self.match_kw(Keyword::Return, WhileParsing::Return)?; + self.match_kw(Keyword::Return, Parsing::Return)?; Ok(Return { body: self.optional_expr()?.map(Into::into) }) } /// [Continue] = `continue` pub fn parse_continue(&mut self) -> PResult { - self.match_kw(Keyword::Continue, WhileParsing::Continue)?; + self.match_kw(Keyword::Continue, Parsing::Continue)?; Ok(Continue) } /// [While] = `while` [Expr] [Block] [Else]? pub fn parse_while(&mut self) -> PResult { - self.match_kw(Keyword::While, WhileParsing::While)?; + self.match_kw(Keyword::While, Parsing::While)?; Ok(While { cond: self.expr()?.into(), pass: self.block()?.into(), @@ -1112,7 +1114,7 @@ impl<'t> Parser<'t> { /// [If] = `if` [Expr] [Block] [Else]? #[rustfmt::skip] // second line is barely not long enough pub fn parse_if(&mut self) -> PResult { - self.match_kw(Keyword::If, WhileParsing::If)?; + self.match_kw(Keyword::If, Parsing::If)?; Ok(If { cond: self.expr()?.into(), pass: self.block()?.into(), @@ -1121,9 +1123,9 @@ impl<'t> Parser<'t> { } /// [For]: `for` Pattern (TODO) `in` [Expr] [Block] [Else]? pub fn parse_for(&mut self) -> PResult { - self.match_kw(Keyword::For, WhileParsing::For)?; + self.match_kw(Keyword::For, Parsing::For)?; let bind = self.identifier()?; - self.match_kw(Keyword::In, WhileParsing::For)?; + self.match_kw(Keyword::In, Parsing::For)?; Ok(For { bind, cond: self.expr()?.into(), @@ -1133,7 +1135,7 @@ impl<'t> Parser<'t> { } /// [Else]: (`else` [Block])? pub fn parse_else(&mut self) -> PResult { - match self.peek_type(WhileParsing::Else) { + match self.peek_type(Parsing::Else) { Ok(Type::Keyword(Keyword::Else)) => { self.consume_peeked(); Ok(self.expr()?.into()) @@ -1146,7 +1148,7 @@ impl<'t> Parser<'t> { macro operator($($name:ident ($returns:ident) {$($t:ident => $p:ident),*$(,)?};)*) {$( pub fn $name (&mut self) -> PResult<$returns> { - const PARSING: WhileParsing = WhileParsing::$returns; + const PARSING: Parsing = Parsing::$returns; let out = Ok(match self.peek_type(PARSING) { $(Ok(Type::$t) => $returns::$p,)* Err(e) => Err(e)?, @@ -1218,7 +1220,7 @@ impl<'t> Parser<'t> { }; } pub fn member_op(&mut self) -> PResult<()> { - const PARSING: WhileParsing = WhileParsing::Member; + const PARSING: Parsing = Parsing::Member; match self.peek(PARSING)?.ty() { Type::Dot => {} t => Err(self.error(Unexpected(t), PARSING))?, diff --git a/libconlang/src/token.rs b/libconlang/src/token.rs index 9389962..6335e51 100644 --- a/libconlang/src/token.rs +++ b/libconlang/src/token.rs @@ -1,5 +1,5 @@ //! # Token -//! +//! //! Stores a component of a file as a [Type], some [Data], and a line and column number pub mod token_data;