1use crate::Parser;
6
7pub const RESERVED: &[&str] = &[
9 "if", "then", "else", "case", "of", "let", "in", "type", "module", "where", "import",
10 "exposing", "as", "port",
11];
12
13#[inline]
15pub fn is_reserved(name: &str) -> bool {
16 RESERVED.contains(&name)
17}
18
19use crate::{Col, Row};
20
21impl<'a> Parser<'a> {
22 pub fn keyword_if<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
26 self.keyword(b"if", to_error)
27 }
28
29 pub fn keyword_then<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
33 self.keyword(b"then", to_error)
34 }
35
36 pub fn keyword_else<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
40 self.keyword(b"else", to_error)
41 }
42
43 pub fn keyword_case<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
47 self.keyword(b"case", to_error)
48 }
49
50 pub fn keyword_of<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
54 self.keyword(b"of", to_error)
55 }
56
57 pub fn keyword_let<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
61 self.keyword(b"let", to_error)
62 }
63
64 pub fn keyword_in<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
68 self.keyword(b"in", to_error)
69 }
70
71 pub fn keyword_type<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
75 self.keyword(b"type", to_error)
76 }
77
78 pub fn keyword_alias<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
82 self.keyword(b"alias", to_error)
83 }
84
85 pub fn keyword_infix<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
89 self.keyword(b"infix", to_error)
90 }
91
92 pub fn keyword_left<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
96 self.keyword(b"left", to_error)
97 }
98
99 pub fn keyword_right<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
103 self.keyword(b"right", to_error)
104 }
105
106 pub fn keyword_non<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
110 self.keyword(b"non", to_error)
111 }
112
113 pub fn keyword_import<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
117 self.keyword(b"import", to_error)
118 }
119
120 pub fn keyword_as<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
124 self.keyword(b"as", to_error)
125 }
126
127 pub fn keyword_exposing<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
131 self.keyword(b"exposing", to_error)
132 }
133
134 pub fn keyword_module<E>(&mut self, to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
138 self.keyword(b"module", to_error)
139 }
140
141 fn keyword<E>(&mut self, kw: &[u8], to_error: impl FnOnce(Row, Col) -> E) -> Result<(), E> {
145 if self.pos + kw.len() > self.src.len() {
147 let (row, col) = self.position();
148 return Err(to_error(row, col));
149 }
150
151 if &self.src[self.pos..self.pos + kw.len()] != kw {
153 let (row, col) = self.position();
154 return Err(to_error(row, col));
155 }
156
157 let next_pos = self.pos + kw.len();
159 if next_pos < self.src.len() {
160 let next_byte = self.src[next_pos];
161 if is_inner_char(next_byte) {
162 let (row, col) = self.position();
163 return Err(to_error(row, col));
164 }
165 }
166
167 for _ in 0..kw.len() {
169 self.advance();
170 }
171 Ok(())
172 }
173}
174
175#[inline]
179fn is_inner_char(b: u8) -> bool {
180 b.is_ascii_alphanumeric() || b == b'_'
181}