cl-token: Merge token_type::Type and token_type::Keyword into a single enum
This commit is contained in:
parent
a213c7f70a
commit
902494e95a
@ -1,8 +1,8 @@
|
|||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
use crate::{env::Environment, temp_type_impl::ConValue, Interpret};
|
use crate::{env::Environment, temp_type_impl::ConValue, Interpret};
|
||||||
use cl_ast::*;
|
use cl_ast::*;
|
||||||
use cl_parser::Parser;
|
|
||||||
use cl_lexer::Lexer;
|
use cl_lexer::Lexer;
|
||||||
|
use cl_parser::Parser;
|
||||||
pub use macros::*;
|
pub use macros::*;
|
||||||
|
|
||||||
mod macros {
|
mod macros {
|
||||||
@ -187,7 +187,7 @@ mod fn_declarations {
|
|||||||
assert_eval!(env, fn empty_fn() {});
|
assert_eval!(env, fn empty_fn() {});
|
||||||
// TODO: true equality for functions
|
// TODO: true equality for functions
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"fn empty_fn",
|
"fn empty_fn () {\n \n}",
|
||||||
format!(
|
format!(
|
||||||
"{}",
|
"{}",
|
||||||
env.get("empty_fn")
|
env.get("empty_fn")
|
||||||
|
@ -51,7 +51,8 @@ pub mod lexer_iter {
|
|||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use conlang::lexer::Lexer;
|
/// # use cl_lexer::Lexer;
|
||||||
|
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
/// // Read in your code from somewhere
|
/// // Read in your code from somewhere
|
||||||
/// let some_code = "
|
/// let some_code = "
|
||||||
/// fn main () {
|
/// fn main () {
|
||||||
@ -61,16 +62,17 @@ pub mod lexer_iter {
|
|||||||
/// // Create a lexer over your code
|
/// // Create a lexer over your code
|
||||||
/// let mut lexer = Lexer::new(some_code);
|
/// let mut lexer = Lexer::new(some_code);
|
||||||
/// // Scan for a single token
|
/// // Scan for a single token
|
||||||
/// let first_token = lexer.scan().unwrap();
|
/// let first_token = lexer.scan()?;
|
||||||
/// println!("{first_token:?}");
|
/// println!("{first_token:?}");
|
||||||
/// // Loop over all the rest of the tokens
|
/// // Loop over all the rest of the tokens
|
||||||
/// for token in lexer {
|
/// for token in lexer {
|
||||||
/// # let token: Result<_,()> = Ok(token.unwrap());
|
/// # let token: Result<_,()> = Ok(token?);
|
||||||
/// match token {
|
/// match token {
|
||||||
/// Ok(token) => println!("{token:?}"),
|
/// Ok(token) => println!("{token:?}"),
|
||||||
/// Err(e) => eprintln!("{e:?}"),
|
/// Err(e) => eprintln!("{e:?}"),
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
|
/// # Ok(()) }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Lexer<'t> {
|
pub struct Lexer<'t> {
|
||||||
@ -331,8 +333,8 @@ impl<'t> Lexer<'t> {
|
|||||||
while let Ok(c) = self.xid_continue() {
|
while let Ok(c) = self.xid_continue() {
|
||||||
out.push(c)
|
out.push(c)
|
||||||
}
|
}
|
||||||
if let Ok(keyword) = Keyword::from_str(&out) {
|
if let Ok(keyword) = Type::from_str(&out) {
|
||||||
self.produce(Type::Keyword(keyword), ())
|
self.produce(keyword, ())
|
||||||
} else {
|
} else {
|
||||||
self.produce(Type::Identifier, Data::Identifier(out.into()))
|
self.produce(Type::Identifier, Data::Identifier(out.into()))
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ mod ident {
|
|||||||
mod keyword {
|
mod keyword {
|
||||||
use super::*;
|
use super::*;
|
||||||
macro kw($($k:ident),*) {
|
macro kw($($k:ident),*) {
|
||||||
[ $(Type::Keyword(Keyword::$k),)* ]
|
[ $(Type::$k,)* ]
|
||||||
}
|
}
|
||||||
test_lexer_output_type! {
|
test_lexer_output_type! {
|
||||||
kw_break { "break break" => kw![Break, Break] }
|
kw_break { "break break" => kw![Break, Break] }
|
||||||
|
@ -84,10 +84,6 @@ impl<'t> Parser<'t> {
|
|||||||
Err(self.error(Expected { want, got }, while_parsing))
|
Err(self.error(Expected { want, got }, while_parsing))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Consumes the next token if it matches the pattern [Keyword]
|
|
||||||
pub fn match_kw(&mut self, pat: Keyword, while_parsing: Parsing) -> PResult<Token> {
|
|
||||||
self.match_type(Type::Keyword(pat), while_parsing)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the three matched delimiter pairs
|
// the three matched delimiter pairs
|
||||||
@ -155,17 +151,15 @@ const fn rep<'t, T>(
|
|||||||
/// Expands to a pattern which matches item-like [Token] [Type]s
|
/// Expands to a pattern which matches item-like [Token] [Type]s
|
||||||
macro item_like() {
|
macro item_like() {
|
||||||
Type::Hash
|
Type::Hash
|
||||||
| Type::Keyword(
|
| Type::Pub
|
||||||
Keyword::Pub
|
| Type::Type
|
||||||
| Keyword::Type
|
| Type::Const
|
||||||
| Keyword::Const
|
| Type::Static
|
||||||
| Keyword::Static
|
| Type::Mod
|
||||||
| Keyword::Mod
|
| Type::Fn
|
||||||
| Keyword::Fn
|
| Type::Struct
|
||||||
| Keyword::Struct
|
| Type::Enum
|
||||||
| Keyword::Enum
|
| Type::Impl
|
||||||
| Keyword::Impl,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Top level parsing
|
/// Top level parsing
|
||||||
@ -291,21 +285,21 @@ 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(Parsing::Item)? {
|
Ok(match self.peek_type(Parsing::Item)? {
|
||||||
Type::Keyword(Keyword::Type) => self.parse_alias()?.into(),
|
Type::Type => self.parse_alias()?.into(),
|
||||||
Type::Keyword(Keyword::Const) => self.parse_const()?.into(),
|
Type::Const => self.parse_const()?.into(),
|
||||||
Type::Keyword(Keyword::Static) => self.parse_static()?.into(),
|
Type::Static => self.parse_static()?.into(),
|
||||||
Type::Keyword(Keyword::Mod) => self.parse_module()?.into(),
|
Type::Mod => self.parse_module()?.into(),
|
||||||
Type::Keyword(Keyword::Fn) => self.parse_function()?.into(),
|
Type::Fn => self.parse_function()?.into(),
|
||||||
Type::Keyword(Keyword::Struct) => self.parse_struct()?.into(),
|
Type::Struct => self.parse_struct()?.into(),
|
||||||
Type::Keyword(Keyword::Enum) => self.parse_enum()?.into(),
|
Type::Enum => self.parse_enum()?.into(),
|
||||||
Type::Keyword(Keyword::Impl) => self.parse_impl()?.into(),
|
Type::Impl => self.parse_impl()?.into(),
|
||||||
t => Err(self.error(Unexpected(t), Parsing::Item))?,
|
t => Err(self.error(Unexpected(t), Parsing::Item))?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_alias(&mut self) -> PResult<Alias> {
|
pub fn parse_alias(&mut self) -> PResult<Alias> {
|
||||||
const PARSING: Parsing = Parsing::Alias;
|
const PARSING: Parsing = Parsing::Alias;
|
||||||
self.match_kw(Keyword::Type, PARSING)?;
|
self.match_type(Type::Type, PARSING)?;
|
||||||
let out = Ok(Alias {
|
let out = Ok(Alias {
|
||||||
to: self.identifier()?,
|
to: self.identifier()?,
|
||||||
from: if self.match_type(Type::Eq, PARSING).is_ok() {
|
from: if self.match_type(Type::Eq, PARSING).is_ok() {
|
||||||
@ -320,7 +314,7 @@ impl<'t> Parser<'t> {
|
|||||||
|
|
||||||
pub fn parse_const(&mut self) -> PResult<Const> {
|
pub fn parse_const(&mut self) -> PResult<Const> {
|
||||||
const PARSING: Parsing = Parsing::Const;
|
const PARSING: Parsing = Parsing::Const;
|
||||||
self.match_kw(Keyword::Const, PARSING)?;
|
self.match_type(Type::Const, PARSING)?;
|
||||||
let out = Ok(Const {
|
let out = Ok(Const {
|
||||||
name: self.identifier()?,
|
name: self.identifier()?,
|
||||||
ty: {
|
ty: {
|
||||||
@ -337,7 +331,7 @@ impl<'t> Parser<'t> {
|
|||||||
}
|
}
|
||||||
pub fn parse_static(&mut self) -> PResult<Static> {
|
pub fn parse_static(&mut self) -> PResult<Static> {
|
||||||
const PARSING: Parsing = Parsing::Static;
|
const PARSING: Parsing = Parsing::Static;
|
||||||
self.match_kw(Keyword::Static, PARSING)?;
|
self.match_type(Type::Static, PARSING)?;
|
||||||
let out = Ok(Static {
|
let out = Ok(Static {
|
||||||
mutable: self.mutability()?,
|
mutable: self.mutability()?,
|
||||||
name: self.identifier()?,
|
name: self.identifier()?,
|
||||||
@ -355,7 +349,7 @@ impl<'t> Parser<'t> {
|
|||||||
}
|
}
|
||||||
pub fn parse_module(&mut self) -> PResult<Module> {
|
pub fn parse_module(&mut self) -> PResult<Module> {
|
||||||
const PARSING: Parsing = Parsing::Module;
|
const PARSING: Parsing = Parsing::Module;
|
||||||
self.match_kw(Keyword::Mod, PARSING)?;
|
self.match_type(Type::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> {
|
||||||
@ -373,7 +367,7 @@ impl<'t> Parser<'t> {
|
|||||||
}
|
}
|
||||||
pub fn parse_function(&mut self) -> PResult<Function> {
|
pub fn parse_function(&mut self) -> PResult<Function> {
|
||||||
const PARSING: Parsing = Parsing::Function;
|
const PARSING: Parsing = Parsing::Function;
|
||||||
self.match_kw(Keyword::Fn, PARSING)?;
|
self.match_type(Type::Fn, PARSING)?;
|
||||||
Ok(Function {
|
Ok(Function {
|
||||||
name: self.identifier()?,
|
name: self.identifier()?,
|
||||||
args: self.parse_params()?,
|
args: self.parse_params()?,
|
||||||
@ -415,7 +409,7 @@ impl<'t> Parser<'t> {
|
|||||||
}
|
}
|
||||||
pub fn parse_struct(&mut self) -> PResult<Struct> {
|
pub fn parse_struct(&mut self) -> PResult<Struct> {
|
||||||
const PARSING: Parsing = Parsing::Struct;
|
const PARSING: Parsing = Parsing::Struct;
|
||||||
self.match_kw(Keyword::Struct, PARSING)?;
|
self.match_type(Type::Struct, PARSING)?;
|
||||||
Ok(Struct {
|
Ok(Struct {
|
||||||
name: self.identifier()?,
|
name: self.identifier()?,
|
||||||
kind: match self.peek_type(PARSING)? {
|
kind: match self.peek_type(PARSING)? {
|
||||||
@ -460,7 +454,7 @@ impl<'t> Parser<'t> {
|
|||||||
pub fn parse_enum(&mut self) -> PResult<Enum> {
|
pub fn parse_enum(&mut self) -> PResult<Enum> {
|
||||||
// Enum = "enum" Identifier '{' (Variant ',')* Variant? '}' ;
|
// Enum = "enum" Identifier '{' (Variant ',')* Variant? '}' ;
|
||||||
const PARSING: Parsing = Parsing::Enum;
|
const PARSING: Parsing = Parsing::Enum;
|
||||||
self.match_kw(Keyword::Enum, PARSING)?;
|
self.match_type(Type::Enum, PARSING)?;
|
||||||
Ok(Enum {
|
Ok(Enum {
|
||||||
name: self.identifier()?,
|
name: self.identifier()?,
|
||||||
kind: match self.peek_type(PARSING)? {
|
kind: match self.peek_type(PARSING)? {
|
||||||
@ -518,19 +512,19 @@ impl<'t> Parser<'t> {
|
|||||||
|
|
||||||
pub fn parse_impl(&mut self) -> PResult<Impl> {
|
pub fn parse_impl(&mut self) -> PResult<Impl> {
|
||||||
const PARSING: Parsing = Parsing::Impl;
|
const PARSING: Parsing = Parsing::Impl;
|
||||||
self.match_kw(Keyword::Impl, PARSING)?;
|
self.match_type(Type::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(Parsing::Visibility)? {
|
if let Type::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(Parsing::Mutability)? {
|
if let Type::Mut = self.peek_type(Parsing::Mutability)? {
|
||||||
self.consume_peeked();
|
self.consume_peeked();
|
||||||
return Ok(Mutability::Mut);
|
return Ok(Mutability::Mut);
|
||||||
};
|
};
|
||||||
@ -550,13 +544,13 @@ impl<'t> Parser<'t> {
|
|||||||
self.consume_peeked();
|
self.consume_peeked();
|
||||||
TyKind::Never
|
TyKind::Never
|
||||||
}
|
}
|
||||||
Type::Keyword(Keyword::SelfTy) => {
|
Type::SelfTy => {
|
||||||
self.consume_peeked();
|
self.consume_peeked();
|
||||||
TyKind::SelfTy
|
TyKind::SelfTy
|
||||||
}
|
}
|
||||||
Type::Amp | Type::AmpAmp => self.tyref()?.into(),
|
Type::Amp | Type::AmpAmp => self.tyref()?.into(),
|
||||||
Type::LParen => self.tytuple()?.into(),
|
Type::LParen => self.tytuple()?.into(),
|
||||||
Type::Keyword(Keyword::Fn) => self.tyfn()?.into(),
|
Type::Fn => self.tyfn()?.into(),
|
||||||
path_like!() => self.path()?.into(),
|
path_like!() => self.path()?.into(),
|
||||||
t => Err(self.error(Unexpected(t), PARSING))?,
|
t => Err(self.error(Unexpected(t), PARSING))?,
|
||||||
};
|
};
|
||||||
@ -591,7 +585,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: Parsing = Parsing::TyFn;
|
const PARSING: Parsing = Parsing::TyFn;
|
||||||
self.match_type(Type::Keyword(Keyword::Fn), PARSING)?;
|
self.match_type(Type::Fn, PARSING)?;
|
||||||
Ok(TyFn {
|
Ok(TyFn {
|
||||||
args: self.tytuple()?,
|
args: self.tytuple()?,
|
||||||
rety: {
|
rety: {
|
||||||
@ -609,15 +603,11 @@ impl<'t> Parser<'t> {
|
|||||||
|
|
||||||
/// Expands to a pattern which matches literal-like [Type]s
|
/// Expands to a pattern which matches literal-like [Type]s
|
||||||
macro literal_like() {
|
macro literal_like() {
|
||||||
Type::Keyword(Keyword::True | Keyword::False)
|
Type::True | Type::False | Type::String | Type::Character | Type::Integer | Type::Float
|
||||||
| Type::String
|
|
||||||
| Type::Character
|
|
||||||
| Type::Integer
|
|
||||||
| Type::Float
|
|
||||||
}
|
}
|
||||||
/// Expands to a pattern which matches path-like [token Types](Type)
|
/// Expands to a pattern which matches path-like [token Types](Type)
|
||||||
macro path_like() {
|
macro path_like() {
|
||||||
Type::Keyword(Keyword::Super | Keyword::SelfKw) | Type::Identifier | Type::ColonColon
|
Type::Super | Type::SelfKw | Type::Identifier | Type::ColonColon
|
||||||
}
|
}
|
||||||
/// # Path parsing
|
/// # Path parsing
|
||||||
impl<'t> Parser<'t> {
|
impl<'t> Parser<'t> {
|
||||||
@ -625,8 +615,8 @@ impl<'t> Parser<'t> {
|
|||||||
pub fn path_part(&mut self) -> PResult<PathPart> {
|
pub fn path_part(&mut self) -> PResult<PathPart> {
|
||||||
const PARSING: Parsing = Parsing::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::Super => PathPart::SuperKw,
|
||||||
Type::Keyword(Keyword::SelfKw) => PathPart::SelfKw,
|
Type::SelfKw => PathPart::SelfKw,
|
||||||
Type::Identifier => PathPart::Ident(self.identifier()?),
|
Type::Identifier => PathPart::Ident(self.identifier()?),
|
||||||
t => return Err(self.error(Unexpected(t), PARSING)),
|
t => return Err(self.error(Unexpected(t), PARSING)),
|
||||||
};
|
};
|
||||||
@ -651,14 +641,14 @@ impl<'t> Parser<'t> {
|
|||||||
pub fn stmtkind(&mut self) -> PResult<StmtKind> {
|
pub fn stmtkind(&mut self) -> PResult<StmtKind> {
|
||||||
Ok(match self.peek_type(Parsing::StmtKind)? {
|
Ok(match self.peek_type(Parsing::StmtKind)? {
|
||||||
Type::Semi => StmtKind::Empty,
|
Type::Semi => StmtKind::Empty,
|
||||||
Type::Keyword(Keyword::Let) => self.parse_let()?.into(),
|
Type::Let => self.parse_let()?.into(),
|
||||||
item_like!() => self.item()?.into(),
|
item_like!() => self.item()?.into(),
|
||||||
_ => self.expr()?.into(),
|
_ => self.expr()?.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_let(&mut self) -> PResult<Let> {
|
pub fn parse_let(&mut self) -> PResult<Let> {
|
||||||
self.match_kw(Keyword::Let, Parsing::Let)?;
|
self.match_type(Type::Let, Parsing::Let)?;
|
||||||
Ok(Let {
|
Ok(Let {
|
||||||
mutable: self.mutability()?,
|
mutable: self.mutability()?,
|
||||||
name: self.identifier()?,
|
name: self.identifier()?,
|
||||||
@ -816,12 +806,12 @@ impl<'t> Parser<'t> {
|
|||||||
Type::LParen => self.exprkind_empty_group_or_tuple(),
|
Type::LParen => self.exprkind_empty_group_or_tuple(),
|
||||||
literal_like!() => Ok(self.literal()?.into()),
|
literal_like!() => Ok(self.literal()?.into()),
|
||||||
path_like!() => Ok(self.path()?.into()),
|
path_like!() => Ok(self.path()?.into()),
|
||||||
Type::Keyword(Keyword::If) => Ok(self.parse_if()?.into()),
|
Type::If => Ok(self.parse_if()?.into()),
|
||||||
Type::Keyword(Keyword::For) => Ok(self.parse_for()?.into()),
|
Type::For => Ok(self.parse_for()?.into()),
|
||||||
Type::Keyword(Keyword::While) => Ok(self.parse_while()?.into()),
|
Type::While => Ok(self.parse_while()?.into()),
|
||||||
Type::Keyword(Keyword::Break) => Ok(self.parse_break()?.into()),
|
Type::Break => Ok(self.parse_break()?.into()),
|
||||||
Type::Keyword(Keyword::Return) => Ok(self.parse_return()?.into()),
|
Type::Return => Ok(self.parse_return()?.into()),
|
||||||
Type::Keyword(Keyword::Continue) => Ok(self.parse_continue()?.into()),
|
Type::Continue => Ok(self.parse_continue()?.into()),
|
||||||
_ => Err(self.error(Nothing, Parsing::Expr)),
|
_ => Err(self.error(Nothing, Parsing::Expr)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -934,8 +924,8 @@ impl<'t> Parser<'t> {
|
|||||||
let tok = self.consume(Parsing::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::True => return Ok(Literal::Bool(true)),
|
||||||
Type::Keyword(Keyword::False) => return Ok(Literal::Bool(false)),
|
Type::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), Parsing::Literal)),
|
t => return Err(self.error(Unexpected(t), Parsing::Literal)),
|
||||||
}
|
}
|
||||||
@ -973,22 +963,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, Parsing::Break)?;
|
self.match_type(Type::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, Parsing::Return)?;
|
self.match_type(Type::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, Parsing::Continue)?;
|
self.match_type(Type::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, Parsing::While)?;
|
self.match_type(Type::While, Parsing::While)?;
|
||||||
Ok(While {
|
Ok(While {
|
||||||
cond: self.expr()?.into(),
|
cond: self.expr()?.into(),
|
||||||
pass: self.block()?.into(),
|
pass: self.block()?.into(),
|
||||||
@ -998,7 +988,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, Parsing::If)?;
|
self.match_type(Type::If, Parsing::If)?;
|
||||||
Ok(If {
|
Ok(If {
|
||||||
cond: self.expr()?.into(),
|
cond: self.expr()?.into(),
|
||||||
pass: self.block()?.into(),
|
pass: self.block()?.into(),
|
||||||
@ -1007,9 +997,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, Parsing::For)?;
|
self.match_type(Type::For, Parsing::For)?;
|
||||||
let bind = self.identifier()?;
|
let bind = self.identifier()?;
|
||||||
self.match_kw(Keyword::In, Parsing::For)?;
|
self.match_type(Type::In, Parsing::For)?;
|
||||||
Ok(For {
|
Ok(For {
|
||||||
bind,
|
bind,
|
||||||
cond: self.expr()?.into(),
|
cond: self.expr()?.into(),
|
||||||
@ -1020,7 +1010,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(Parsing::Else) {
|
match self.peek_type(Parsing::Else) {
|
||||||
Ok(Type::Keyword(Keyword::Else)) => {
|
Ok(Type::Else) => {
|
||||||
self.consume_peeked();
|
self.consume_peeked();
|
||||||
Ok(self.expr()?.into())
|
Ok(self.expr()?.into())
|
||||||
}
|
}
|
||||||
|
@ -10,4 +10,4 @@ pub mod token_type;
|
|||||||
|
|
||||||
pub use token::Token;
|
pub use token::Token;
|
||||||
pub use token_data::Data;
|
pub use token_data::Data;
|
||||||
pub use token_type::{Keyword, Type};
|
pub use token_type::Type;
|
||||||
|
@ -8,9 +8,34 @@ pub enum Type {
|
|||||||
Invalid,
|
Invalid,
|
||||||
// Any kind of comment
|
// Any kind of comment
|
||||||
Comment,
|
Comment,
|
||||||
// Any identifier
|
// A non-keyword identifier
|
||||||
Identifier,
|
Identifier,
|
||||||
Keyword(Keyword),
|
// A keyword
|
||||||
|
Break,
|
||||||
|
Cl,
|
||||||
|
Const,
|
||||||
|
Continue,
|
||||||
|
Else,
|
||||||
|
Enum,
|
||||||
|
False,
|
||||||
|
For,
|
||||||
|
Fn,
|
||||||
|
If,
|
||||||
|
Impl,
|
||||||
|
In,
|
||||||
|
Let,
|
||||||
|
Mod,
|
||||||
|
Mut,
|
||||||
|
Pub,
|
||||||
|
Return,
|
||||||
|
SelfKw,
|
||||||
|
SelfTy,
|
||||||
|
Static,
|
||||||
|
Struct,
|
||||||
|
Super,
|
||||||
|
True,
|
||||||
|
Type,
|
||||||
|
While,
|
||||||
// Literals
|
// Literals
|
||||||
Integer,
|
Integer,
|
||||||
Float,
|
Float,
|
||||||
@ -73,47 +98,44 @@ pub enum Type {
|
|||||||
XorXor, // ^^
|
XorXor, // ^^
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a reserved word.
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub enum Keyword {
|
|
||||||
Break,
|
|
||||||
Cl,
|
|
||||||
Const,
|
|
||||||
Continue,
|
|
||||||
Else,
|
|
||||||
Enum,
|
|
||||||
False,
|
|
||||||
For,
|
|
||||||
Fn,
|
|
||||||
If,
|
|
||||||
Impl,
|
|
||||||
In,
|
|
||||||
Let,
|
|
||||||
Mod,
|
|
||||||
Mut,
|
|
||||||
Pub,
|
|
||||||
Return,
|
|
||||||
SelfKw,
|
|
||||||
SelfTy,
|
|
||||||
Static,
|
|
||||||
Struct,
|
|
||||||
Super,
|
|
||||||
True,
|
|
||||||
Type,
|
|
||||||
While,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Type {
|
impl Display for Type {
|
||||||
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 {
|
||||||
Type::Invalid => "invalid".fmt(f),
|
Type::Invalid => "invalid".fmt(f),
|
||||||
Type::Comment => "comment".fmt(f),
|
Type::Comment => "comment".fmt(f),
|
||||||
Type::Identifier => "identifier".fmt(f),
|
Type::Identifier => "identifier".fmt(f),
|
||||||
Type::Keyword(k) => k.fmt(f),
|
|
||||||
|
Type::Break => "break".fmt(f),
|
||||||
|
Type::Cl => "cl".fmt(f),
|
||||||
|
Type::Const => "const".fmt(f),
|
||||||
|
Type::Continue => "continue".fmt(f),
|
||||||
|
Type::Else => "else".fmt(f),
|
||||||
|
Type::Enum => "enum".fmt(f),
|
||||||
|
Type::False => "false".fmt(f),
|
||||||
|
Type::For => "for".fmt(f),
|
||||||
|
Type::Fn => "fn".fmt(f),
|
||||||
|
Type::If => "if".fmt(f),
|
||||||
|
Type::Impl => "impl".fmt(f),
|
||||||
|
Type::In => "in".fmt(f),
|
||||||
|
Type::Let => "let".fmt(f),
|
||||||
|
Type::Mod => "mod".fmt(f),
|
||||||
|
Type::Mut => "mut".fmt(f),
|
||||||
|
Type::Pub => "pub".fmt(f),
|
||||||
|
Type::Return => "return".fmt(f),
|
||||||
|
Type::SelfKw => "self".fmt(f),
|
||||||
|
Type::SelfTy => "Self".fmt(f),
|
||||||
|
Type::Static => "static".fmt(f),
|
||||||
|
Type::Struct => "struct".fmt(f),
|
||||||
|
Type::Super => "super".fmt(f),
|
||||||
|
Type::True => "true".fmt(f),
|
||||||
|
Type::Type => "type".fmt(f),
|
||||||
|
Type::While => "while".fmt(f),
|
||||||
|
|
||||||
Type::Integer => "integer literal".fmt(f),
|
Type::Integer => "integer literal".fmt(f),
|
||||||
Type::Float => "float literal".fmt(f),
|
Type::Float => "float literal".fmt(f),
|
||||||
Type::String => "string literal".fmt(f),
|
Type::String => "string literal".fmt(f),
|
||||||
Type::Character => "char literal".fmt(f),
|
Type::Character => "char literal".fmt(f),
|
||||||
|
|
||||||
Type::LCurly => "left curly".fmt(f),
|
Type::LCurly => "left curly".fmt(f),
|
||||||
Type::RCurly => "right curly".fmt(f),
|
Type::RCurly => "right curly".fmt(f),
|
||||||
Type::LBrack => "left brack".fmt(f),
|
Type::LBrack => "left brack".fmt(f),
|
||||||
@ -171,41 +193,10 @@ impl Display for Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl FromStr for Type {
|
||||||
impl Display for Keyword {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::Break => "break".fmt(f),
|
|
||||||
Self::Cl => "cl".fmt(f),
|
|
||||||
Self::Const => "const".fmt(f),
|
|
||||||
Self::Continue => "continue".fmt(f),
|
|
||||||
Self::Else => "else".fmt(f),
|
|
||||||
Self::Enum => "enum".fmt(f),
|
|
||||||
Self::False => "false".fmt(f),
|
|
||||||
Self::For => "for".fmt(f),
|
|
||||||
Self::Fn => "fn".fmt(f),
|
|
||||||
Self::If => "if".fmt(f),
|
|
||||||
Self::Impl => "impl".fmt(f),
|
|
||||||
Self::In => "in".fmt(f),
|
|
||||||
Self::Let => "let".fmt(f),
|
|
||||||
Self::Mod => "mod".fmt(f),
|
|
||||||
Self::Mut => "mut".fmt(f),
|
|
||||||
Self::Pub => "pub".fmt(f),
|
|
||||||
Self::Return => "return".fmt(f),
|
|
||||||
Self::SelfKw => "self".fmt(f),
|
|
||||||
Self::SelfTy => "Self".fmt(f),
|
|
||||||
Self::Static => "static".fmt(f),
|
|
||||||
Self::Struct => "struct".fmt(f),
|
|
||||||
Self::Super => "super".fmt(f),
|
|
||||||
Self::True => "true".fmt(f),
|
|
||||||
Self::Type => "type".fmt(f),
|
|
||||||
Self::While => "while".fmt(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl FromStr for Keyword {
|
|
||||||
/// [FromStr] can only fail when an identifier isn't a keyword
|
/// [FromStr] can only fail when an identifier isn't a keyword
|
||||||
type Err = ();
|
type Err = ();
|
||||||
|
/// Parses a string s to return a Keyword
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
Ok(match s {
|
Ok(match s {
|
||||||
"break" => Self::Break,
|
"break" => Self::Break,
|
||||||
|
Loading…
Reference in New Issue
Block a user