mod cursor;
pub mod error;
mod expression;
mod function;
mod statement;
#[cfg(test)]
mod tests;
use self::error::{ParseError, ParseResult};
use crate::syntax::ast::{node::StatementList, Token};
use cursor::Cursor;
trait TokenParser: Sized {
type Output;
fn parse(self, cursor: &mut Cursor<'_>) -> Result<Self::Output, ParseError>;
fn try_parse(self, cursor: &mut Cursor<'_>) -> Option<Self::Output> {
let initial_pos = cursor.pos();
if let Ok(node) = self.parse(cursor) {
Some(node)
} else {
cursor.seek(initial_pos);
None
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct AllowYield(bool);
impl From<bool> for AllowYield {
fn from(allow: bool) -> Self {
Self(allow)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct AllowAwait(bool);
impl From<bool> for AllowAwait {
fn from(allow: bool) -> Self {
Self(allow)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct AllowIn(bool);
impl From<bool> for AllowIn {
fn from(allow: bool) -> Self {
Self(allow)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct AllowReturn(bool);
impl From<bool> for AllowReturn {
fn from(allow: bool) -> Self {
Self(allow)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct AllowDefault(bool);
impl From<bool> for AllowDefault {
fn from(allow: bool) -> Self {
Self(allow)
}
}
#[derive(Debug)]
pub struct Parser<'a> {
cursor: Cursor<'a>,
}
impl<'a> Parser<'a> {
pub fn new(tokens: &'a [Token]) -> Self {
Self {
cursor: Cursor::new(tokens),
}
}
pub fn parse_all(&mut self) -> Result<StatementList, ParseError> {
Script.parse(&mut self.cursor)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Script;
impl TokenParser for Script {
type Output = StatementList;
fn parse(self, cursor: &mut Cursor<'_>) -> Result<Self::Output, ParseError> {
if cursor.peek(0).is_some() {
ScriptBody.parse(cursor)
} else {
Ok(StatementList::from(Vec::new()))
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ScriptBody;
impl TokenParser for ScriptBody {
type Output = StatementList;
fn parse(self, cursor: &mut Cursor<'_>) -> Result<Self::Output, ParseError> {
self::statement::StatementList::new(false, false, false, false).parse(cursor)
}
}