1use super::error::SyntaxError;
2use super::error::SyntaxErrorType;
3use super::error::SyntaxResult;
4use super::lex::lex_next;
5use super::lex::Lexer;
6use super::lex::LexerCheckpoint;
7use super::source::SourceRange;
8use super::token::Token;
9use super::token::TokenType;
10use crate::ast::Expression;
11use crate::ast::ModuleItem;
12use crate::ast::Node;
13use crate::ast::Statement;
14use crate::symbol::Scope;
15use crate::symbol::ScopeType;
16
17#[must_use]
18pub struct MaybeToken {
19 typ: TokenType,
20 range: SourceRange,
21 matched: bool,
22}
23
24impl MaybeToken {
25 pub fn is_match(&self) -> bool {
26 self.matched
27 }
28
29 pub fn match_loc(&self) -> Option<SourceRange> {
30 if self.matched {
31 Some(self.range)
32 } else {
33 None
34 }
35 }
36
37 pub fn error(&self, err: SyntaxErrorType) -> SyntaxError {
38 debug_assert!(!self.matched);
39 SyntaxError::from_loc(self.range, err, Some(self.typ))
40 }
41
42 pub fn and_then<R, F: FnOnce() -> SyntaxResult<R>>(self, f: F) -> SyntaxResult<Option<R>> {
43 Ok(if self.matched { Some(f()?) } else { None })
44 }
45}
46
47pub struct ParserCheckpoint {
48 checkpoint: LexerCheckpoint,
49}
50
51pub struct Parser<'a> {
52 lexer: Lexer<'a>,
53 pub(crate) scope: Scope, }
55
56impl<'a> Parser<'a> {
57 pub fn new(lexer: Lexer<'a>, root_scope: Scope) -> Parser<'a> {
58 Parser {
59 lexer,
60 scope: root_scope,
61 }
62 }
63
64 pub fn enter_new_scope(&mut self, typ: ScopeType) -> Scope {
66 let old = self.scope.clone();
67 let new = old.new_child(typ);
68 self.scope = new;
69 old
70 }
71
72 pub fn return_to_scope(&mut self, old: Scope) {
73 self.scope = old;
74 }
75
76 pub fn new_expression(&self, loc: SourceRange, expr: Expression) -> Node<Expression> {
77 Node {
78 loc,
79 stx: Box::new(expr),
80 scope: self.scope.clone(),
81 }
82 }
83
84 pub fn new_statement(&self, loc: SourceRange, stmt: Statement) -> Node<Statement> {
85 Node {
86 loc,
87 stx: Box::new(stmt),
88 scope: self.scope.clone(),
89 }
90 }
91
92 pub fn new_module_item(&self, loc: SourceRange, item: ModuleItem) -> Node<ModuleItem> {
93 Node {
94 loc,
95 stx: Box::new(item),
96 scope: self.scope.clone(),
97 }
98 }
99
100 pub fn lexer_mut(&mut self) -> &mut Lexer<'a> {
101 &mut self.lexer
102 }
103
104 pub fn source(&self, range: SourceRange) -> &[u8] {
105 &self.lexer[range]
106 }
107
108 pub fn source_as_string(&self, range: SourceRange) -> String {
109 unsafe { String::from_utf8_unchecked(self.source(range).to_vec()) }
110 }
111
112 pub fn source_range(&self) -> SourceRange {
113 self.lexer.source_range()
114 }
115
116 pub fn checkpoint(&self) -> ParserCheckpoint {
117 ParserCheckpoint {
118 checkpoint: self.lexer.checkpoint(),
119 }
120 }
121
122 pub fn since_checkpoint(&self, checkpoint: ParserCheckpoint) -> SourceRange {
123 self.lexer.since_checkpoint(checkpoint.checkpoint)
124 }
125
126 pub fn restore_checkpoint(&mut self, checkpoint: ParserCheckpoint) -> () {
127 self.lexer.apply_checkpoint(checkpoint.checkpoint);
128 }
129
130 fn forward<K: FnOnce(&Token) -> bool>(&mut self, keep: K) -> SyntaxResult<(bool, Token)> {
131 let cp = self.checkpoint();
132 let t = lex_next(&mut self.lexer)?;
133 let k = keep(&t);
134 if !k {
135 self.restore_checkpoint(cp);
136 };
137 Ok((k, t))
138 }
139
140 pub fn peek(&mut self) -> SyntaxResult<Token> {
141 self.forward(|_| false).map(|r| r.1)
142 }
143
144 pub fn consume(&mut self) -> SyntaxResult<Token> {
145 self.forward(|_| true).map(|r| r.1)
146 }
147
148 pub fn consume_if_pred<F: FnOnce(&Token) -> bool>(
149 &mut self,
150 pred: F,
151 ) -> SyntaxResult<MaybeToken> {
152 let (matched, t) = self.forward(pred)?;
153 Ok(MaybeToken {
154 typ: t.typ,
155 matched,
156 range: t.loc,
157 })
158 }
159
160 pub fn consume_if(&mut self, typ: TokenType) -> SyntaxResult<MaybeToken> {
161 self.consume_if_pred(|t| t.typ == typ)
162 }
163
164 pub fn require_predicate<P: FnOnce(TokenType) -> bool>(
165 &mut self,
166 pred: P,
167 expected: &'static str,
168 ) -> SyntaxResult<Token> {
169 let t = self.consume()?;
170 if !pred(t.typ) {
171 Err(t.error(SyntaxErrorType::ExpectedSyntax(expected)))
172 } else {
173 Ok(t)
174 }
175 }
176
177 pub fn require(&mut self, typ: TokenType) -> SyntaxResult<Token> {
178 let t = self.consume()?;
179 if t.typ != typ {
180 Err(t.error(SyntaxErrorType::RequiredTokenNotFound(typ)))
181 } else {
182 Ok(t)
183 }
184 }
185
186 pub fn require_identifier_as_string(&mut self) -> SyntaxResult<(SourceRange, String)> {
187 let loc = self.require(TokenType::Identifier)?.loc;
188 Ok((loc, self.source_as_string(loc)))
189 }
190}