use std::str::FromStr;
use crate::{
error::Error,
lexer::{Lexer, Token, TokenIterator},
syntax::*,
};
use lalrpop_util::lalrpop_mod;
lalrpop_mod!(
#[allow(clippy::all, reason = "generated code")]
wgsl
);
lalrpop_mod!(
#[allow(clippy::all, reason = "generated code")]
wgsl_recognize
);
pub use crate::parser_support::ParseEntryPoint;
use wgsl::EntryPointParser;
macro_rules! parse {
($source:expr, $token:ident, $entrypoint:ident) => {{
match parse_tokens(Lexer::new($source), Token::$token) {
Ok(ParseEntryPoint::$entrypoint(res)) => Ok(res),
Ok(_) => unreachable!("parser parsed the wrong entrypoint"),
Err(e) => Err(e),
}
}};
}
pub fn parse_tokens(
lexer: impl TokenIterator,
entrypoint: Token,
) -> Result<ParseEntryPoint, Error> {
let lexer = std::iter::once(Ok((0, entrypoint, 0))).chain(lexer);
let parser = EntryPointParser::new();
parser.parse(lexer).map_err(Into::into)
}
pub fn parse_str(source: &str) -> Result<TranslationUnit, Error> {
parse!(source, EntryPointTranslationUnit, TranslationUnit)
}
pub fn recognize_str(source: &str) -> Result<(), Error> {
let lexer = Lexer::new(source);
let parser = wgsl_recognize::TranslationUnitParser::new();
parser.parse(lexer).map_err(Into::into)
}
pub fn recognize_template_list(lexer: impl TokenIterator) -> Result<(), Error> {
match parse_tokens(lexer, Token::EntryPointTryTemplateList) {
Ok(ParseEntryPoint::TryTemplateList(_)) => Ok(()),
Ok(_) => unreachable!("parser parsed the wrong entrypoint"),
Err(e) => Err(e),
}
}
impl FromStr for TranslationUnit {
type Err = Error;
fn from_str(source: &str) -> Result<Self, Self::Err> {
parse!(source, EntryPointTranslationUnit, TranslationUnit)
}
}
impl FromStr for GlobalDirective {
type Err = Error;
fn from_str(source: &str) -> Result<Self, Self::Err> {
parse!(source, EntryPointGlobalDirective, GlobalDirective)
}
}
impl FromStr for GlobalDeclaration {
type Err = Error;
fn from_str(source: &str) -> Result<Self, Self::Err> {
parse!(source, EntryPointGlobalDecl, GlobalDecl)
}
}
impl FromStr for Statement {
type Err = Error;
fn from_str(source: &str) -> Result<Self, Self::Err> {
parse!(source, EntryPointStatement, Statement)
}
}
impl FromStr for Expression {
type Err = Error;
fn from_str(source: &str) -> Result<Self, Self::Err> {
parse!(source, EntryPointExpression, Expression)
}
}
impl FromStr for LiteralExpression {
type Err = Error;
fn from_str(source: &str) -> Result<Self, Self::Err> {
parse!(source, EntryPointLiteral, Literal)
}
}
#[cfg(feature = "imports")]
impl FromStr for crate::syntax::ImportStatement {
type Err = Error;
fn from_str(source: &str) -> Result<Self, Self::Err> {
parse!(source, EntryPointImportStatement, ImportStatement)
}
}