1mod cursor;
4pub mod error;
5mod expression;
6mod function;
7mod statement;
8#[cfg(test)]
9mod tests;
10
11pub use self::error::{ParseError, ParseResult};
12use crate::syntax::{ast::node::StatementList, lexer::TokenKind};
13
14use cursor::Cursor;
15
16use std::io::Read;
17
18trait TokenParser<R>: Sized
22where
23 R: Read,
24{
25 type Output; fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError>;
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36struct AllowYield(bool);
37
38impl From<bool> for AllowYield {
39 fn from(allow: bool) -> Self {
40 Self(allow)
41 }
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46struct AllowAwait(bool);
47
48impl From<bool> for AllowAwait {
49 fn from(allow: bool) -> Self {
50 Self(allow)
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56struct AllowIn(bool);
57
58impl From<bool> for AllowIn {
59 fn from(allow: bool) -> Self {
60 Self(allow)
61 }
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66struct AllowReturn(bool);
67
68impl From<bool> for AllowReturn {
69 fn from(allow: bool) -> Self {
70 Self(allow)
71 }
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq)]
76struct AllowDefault(bool);
77
78impl From<bool> for AllowDefault {
79 fn from(allow: bool) -> Self {
80 Self(allow)
81 }
82}
83
84#[derive(Debug)]
85pub struct Parser<R> {
86 cursor: Cursor<R>,
88}
89
90impl<R> Parser<R> {
91 pub fn new(reader: R, strict_mode: bool) -> Self
92 where
93 R: Read,
94 {
95 let mut cursor = Cursor::new(reader);
96 cursor.set_strict_mode(strict_mode);
97
98 Self { cursor }
99 }
100
101 pub fn parse_all(&mut self) -> Result<StatementList, ParseError>
102 where
103 R: Read,
104 {
105 Script.parse(&mut self.cursor)
106 }
107}
108
109#[derive(Debug, Clone, Copy)]
116pub struct Script;
117
118impl<R> TokenParser<R> for Script
119where
120 R: Read,
121{
122 type Output = StatementList;
123
124 fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError> {
125 match cursor.peek(0)? {
126 Some(tok) => {
127 let mut strict = false;
128 match tok.kind() {
129 TokenKind::StringLiteral(string) if string.as_ref() == "use strict" => {
130 cursor.set_strict_mode(true);
131 strict = true;
132 }
133 _ => {}
134 }
135 let mut statement_list = ScriptBody.parse(cursor)?;
136 statement_list.set_strict(strict);
137 Ok(statement_list)
138 }
139 None => Ok(StatementList::from(Vec::new())),
140 }
141 }
142}
143
144#[derive(Debug, Clone, Copy)]
151pub struct ScriptBody;
152
153impl<R> TokenParser<R> for ScriptBody
154where
155 R: Read,
156{
157 type Output = StatementList;
158
159 fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError> {
160 self::statement::StatementList::new(false, false, false, false, &[]).parse(cursor)
161 }
162}