1use super::{lexer, word, bracket, Tree, Location, Loc, Stream, Context, Parse};
4use lexer::{Comment, CharacterLiteral, StringLiteral};
5use word::{Whitespace, Alphanumeric};
6use bracket::{Round, Brace};
7
8mod op;
9pub use op::{Precedence, Op};
10
11mod atom;
12pub use atom::{Operator};
13
14mod precedence;
15use precedence::{Stack};
16
17pub const MISSING_FIELD: &'static str = "Missing field name";
18pub const MISSING_ARGS: &'static str = "Missing function arguments";
19pub const MISSING_RETURN_TYPE: &'static str = "Missing function return type";
20
21#[derive(Debug, Copy, Clone, PartialEq)]
26pub enum Keyword { Fn, Dot }
27
28impl Tree for Keyword {
29 fn declare_keywords(mut declare: impl FnMut(&'static str, Self)) {
30 declare("fn", Self::Fn);
31 declare(".", Self::Dot);
32 }
33}
34
35pub type MaybeExpr = Option<Box<Expr>>;
39
40#[derive(Debug)]
54pub enum Expr {
55 Char(Loc<char>),
57
58 String(Loc<String>),
60
61 Name(Loc<String>),
63
64 Round(Round),
66
67 Function(Option<Loc<String>>, Loc<Round>, MaybeExpr, Option<Brace>),
69
70 Op(MaybeExpr, Loc<Op>, MaybeExpr),
72
73 Field(MaybeExpr, Loc<String>),
75
76 Call(MaybeExpr, Loc<Round>),
78}
79
80impl Tree for Expr {}
81
82fn skip(input: &mut Context<impl Stream>) -> Result<(), String> {
86 while input.read::<Whitespace>()?.is_some() || input.read::<Comment>()?.is_some() {
87 input.pop();
88 }
89 Ok(())
90}
91
92#[derive(Default, Debug)]
99pub struct Parser;
100
101impl Parser {
102 fn parse_field(
104 &self,
105 input: &mut Context<impl Stream>,
106 ) -> Result<Box<Alphanumeric>, String> {
107 input.read::<Alphanumeric>()?.ok_or_else(|| MISSING_FIELD.into())
108 }
109
110 fn parse_function(
112 &self,
113 input: &mut Context<impl Stream>,
114 ) -> Result<Expr, String> {
115 skip(input)?;
116 let name = input.read::<Alphanumeric>()?;
117 let name = name.map(|name| input.locate(name.0));
118 let args = input.read::<Round>()?.ok_or_else(|| MISSING_ARGS)?;
119 let args = input.locate(*args);
120 skip(input)?;
121 let return_type = if let Some(c) = input.read::<char>()? {
122 if *c == ':' {
123 skip(input)?;
124 if let Some(type_name) = input.read::<Alphanumeric>()? {
125 Some(Box::new(Expr::Name(input.locate(type_name.0))))
126 } else if let Some(round) = input.read::<Round>()? {
127 Some(Box::new(Expr::Round(*round)))
128 } else {
129 Err(MISSING_RETURN_TYPE)?
130 }
131 } else {
132 input.unread(c);
133 None
134 }
135 } else {
136 None
137 };
138 skip(input)?;
139 let body = input.read::<Brace>()?.map(|body| *body);
140 Ok(Expr::Function(name, args, return_type, body))
141 }
142}
143
144impl Parse for Parser {
145 fn parse(
146 &self,
147 input: &mut Context<impl Stream>,
148 ) -> Result<Box<dyn Tree>, String> {
149 let mut stack = Stack::default();
150 loop {
151 skip(input)?;
152 if let Some(tree) = input.read::<Alphanumeric>()? {
153 stack.nonfix(Expr::Name(input.locate(tree.0)), input.last());
154 } else if let Some(tree) = input.read::<Round>()? {
155 if stack.has_expr() {
156 let tree = input.locate(*tree);
157 stack.postfix(Precedence::MAX, |expr| Expr::Call(expr, tree));
158 } else {
159 stack.nonfix(Expr::Round(*tree), input.last());
160 }
161 } else if let Some(tree) = input.read::<Operator>()? {
162 stack.op(input.locate(
163 if stack.has_expr() { tree.with_left } else { tree.without_left }
164 ));
165 } else if let Some(keyword) = input.read::<Keyword>()? {
166 match *keyword {
167 Keyword::Fn => {
168 let loc = input.last();
169 stack.nonfix(self.parse_function(input)?, loc);
170 },
171 Keyword::Dot => {
172 let field = self.parse_field(input)?;
173 let field = input.locate(field.0);
174 stack.postfix(Precedence::MAX, |expr| Expr::Field(expr, field));
175 },
176 }
177 } else if let Some(tree) = input.read::<CharacterLiteral>()? {
178 stack.nonfix(Expr::Char(input.locate(tree.0)), input.last());
179 } else if let Some(tree) = input.read::<StringLiteral>()? {
180 stack.nonfix(Expr::String(input.locate(tree.0)), input.last());
181 } else {
182 break;
183 }
184 }
185 Ok(if let Some(expr) = stack.flush() { expr } else { input.read_any()? })
186 }
187}
188
189#[cfg(test)]
192mod tests {
193 use super::*;
194 use crate::{parsers, EndOfFile, Characters};
195 use parsers::{Brackets};
196
197 fn expr(input: impl Stream) -> impl Stream {
199 Parser.parse_stream(input)
200 }
201
202 fn round(input: impl Stream) -> impl Stream {
204 expr(Brackets::new('(', ')', |contents| {
205 let contents = expr(contents.into_iter()).read_all();
206 Round::new(contents)
207 }, input))
208 }
209
210 fn brace(input: impl Stream) -> impl Stream {
212 round(Brackets::new('{', '}', |contents| {
213 let contents = round(contents.into_iter()).read_all();
214 Brace::new(contents)
215 }, input))
216 }
217
218 fn parse(source: &'static str) -> impl Stream {
220 let stream = Characters::new(source, true);
221 let stream = parsers::LEXER.parse_stream(stream);
222 let mut word_parser = parsers::Word::default();
223 word_parser.add_keywords::<Operator>();
224 word_parser.add_keywords::<Keyword>();
225 let stream = word_parser.parse_stream(stream);
226 brace(stream)
227 }
228
229 fn parse_one(source: &'static str) -> Box<Expr> {
231 let mut stream = parse(source);
232 let result = match stream.read().result() {
233 Ok(tree) => match tree.downcast::<Expr>() {
234 Ok(tree) => tree,
235 Err(tree) => panic!("Got a non-Expr: {:?}", tree),
236 },
237 Err(e) => panic!("Got error: {:?}", e),
238 };
239 assert_eq!(stream.read(), EndOfFile);
240 result
241 }
242
243 fn check_op(e: impl Into<MaybeExpr>, expected: Op) -> (MaybeExpr, MaybeExpr) {
246 match *e.into().expect("Missing Expr::Op") {
247 Expr::Op(left, observed, right) => {
248 assert_eq!(observed, expected);
249 (left, right)
250 },
251 e => panic!("Expected an Expr::Op but got {:?}", e),
252 }
253 }
254
255 fn check_name(e: impl Into<MaybeExpr>, expected: &'static str) {
257 match *e.into().expect("Missing Expr::Name") {
258 Expr::Name(observed) => assert_eq!(observed, expected),
259 e => panic!("Expected an Expr::Name but got {:?}", e),
260 }
261 }
262
263 fn check_field(e: impl Into<MaybeExpr>, expected: &'static str) -> MaybeExpr {
266 match *e.into().expect("Missing Expr::Field") {
267 Expr::Field(object, observed) => {
268 assert_eq!(observed, expected);
269 object
270 },
271 e => panic!("Expected an Expr::Name but got {:?}", e),
272 }
273 }
274
275 #[test]
276 fn missing() {
277 let tree = parse_one("a b");
278 let (a, b) = check_op(tree, Op::Missing);
279 check_name(a, "a");
280 check_name(b, "b");
281 }
282
283 #[test]
284 fn ergonomics1() {
285 let tree = parse_one("item in low .. high and condition");
286 let (tree, condition) = check_op(tree, Op::BoolAnd);
287 check_name(condition, "condition");
288 let (item, tree) = check_op(tree, Op::In);
289 check_name(item, "item");
290 let (low, high) = check_op(tree, Op::Exclusive);
291 check_name(low, "low");
292 check_name(high, "high");
293 }
294
295 #[test]
296 fn ergonomics2() {
297 let tree = parse_one("0 == x & 1 << 4");
298 let (zero, tree) = check_op(tree, Op::EQ);
299 check_name(zero, "0");
300 let (x, tree) = check_op(tree, Op::BitAnd);
301 check_name(x, "x");
302 let (one, four) = check_op(tree, Op::SL);
303 check_name(one, "1");
304 check_name(four, "4");
305 }
306
307 #[test]
308 fn ergonomics3() {
309 let tree = parse_one("-x ** 2");
310 let (none, tree) = check_op(tree, Op::Minus);
311 assert!(none.is_none());
312 let (x, two) = check_op(tree, Op::Pow);
313 check_name(x, "x");
314 check_name(two, "2");
315 }
316
317 #[test]
318 fn ergonomics4() {
319 let tree = parse_one("x == 1 + y.z");
320 let (x, tree) = check_op(tree, Op::EQ);
321 check_name(x, "x");
322 let (one, tree) = check_op(tree, Op::Add);
323 check_name(one, "1");
324 let y = check_field(tree, "z");
325 check_name(y, "y");
326 }
327
328 #[test]
329 fn ergonomics5() {
330 let tree = parse_one("1 + 2 * 3");
331 let (one, tree) = check_op(tree, Op::Add);
332 check_name(one, "1");
333 let (two, three) = check_op(tree, Op::Mul);
334 check_name(two, "2");
335 check_name(three, "3");
336 }
337
338 #[test]
339 fn ergonomics6() {
340 let tree = parse_one("x + 1 << 4 * y");
341 let (left, right) = check_op(tree, Op::SL);
342 let (x, one) = check_op(left, Op::Add);
343 check_name(x, "x");
344 check_name(one, "1");
345 let (four, y) = check_op(right, Op::Mul);
346 check_name(four, "4");
347 check_name(y, "y");
348 }
349
350 #[test]
351 fn ergonomics7() {
352 let tree = parse_one("low ... high : type");
353 let (low, tree) = check_op(tree, Op::Inclusive);
354 check_name(low, "low");
355 let (high, type_) = check_op(tree, Op::Cast);
356 check_name(high, "high");
357 check_name(type_, "type");
358 }
359
360 #[test]
361 fn ergonomics8() {
362 let tree = parse_one("x: type >= 0");
363 let (tree, zero) = check_op(tree, Op::GE);
364 check_name(zero, "0");
365 let (x, type_) = check_op(tree, Op::Cast);
366 check_name(x, "x");
367 check_name(type_, "type");
368 }
369}