mod cursor;
pub mod error;
mod expression;
mod function;
mod statement;
#[cfg(test)]
mod tests;
pub use self::error::{ParseError, ParseResult};
use crate::syntax::{ast::node::StatementList, lexer::TokenKind};
use cursor::Cursor;
use std::io::Read;
trait TokenParser<R>: Sized
where
R: Read,
{
type Output;
fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError>;
}
#[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<R> {
cursor: Cursor<R>,
}
impl<R> Parser<R> {
pub fn new(reader: R, strict_mode: bool) -> Self
where
R: Read,
{
let mut cursor = Cursor::new(reader);
cursor.set_strict_mode(strict_mode);
Self { cursor }
}
pub fn parse_all(&mut self) -> Result<StatementList, ParseError>
where
R: Read,
{
Script.parse(&mut self.cursor)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Script;
impl<R> TokenParser<R> for Script
where
R: Read,
{
type Output = StatementList;
fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError> {
match cursor.peek(0)? {
Some(tok) => {
let mut strict = false;
match tok.kind() {
TokenKind::StringLiteral(string) if string.as_ref() == "use strict" => {
cursor.set_strict_mode(true);
strict = true;
}
_ => {}
}
let mut statement_list = ScriptBody.parse(cursor)?;
statement_list.set_strict(strict);
Ok(statement_list)
}
None => Ok(StatementList::from(Vec::new())),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ScriptBody;
impl<R> TokenParser<R> for ScriptBody
where
R: Read,
{
type Output = StatementList;
fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError> {
self::statement::StatementList::new(false, false, false, false, &[]).parse(cursor)
}
}