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