diff --git a/oden-script/src/parser.rs b/oden-script/src/parser.rs index ce8c6bb7..bcbf0823 100644 --- a/oden-script/src/parser.rs +++ b/oden-script/src/parser.rs @@ -32,6 +32,7 @@ impl fmt::Display for SyntaxError { pub enum Literal { Float64(f64), + String(String), } pub enum UnaryOp { @@ -198,6 +199,7 @@ impl<'a> Parser<'a> { TokenKind::LeftParen => self.grouping(), TokenKind::Number => self.number(), TokenKind::Minus => self.unary(), + TokenKind::String => self.string(), _ => { self.error("expected an expression"); ExprRef::error() @@ -236,6 +238,30 @@ impl<'a> Parser<'a> { self.tree.add_expr(Expr::Literal(literal, token.clone())) } + fn string(&mut self) -> ExprRef { + let token = self.previous.as_ref().unwrap(); + + let mut result = String::new(); + let mut input = token.as_str().chars(); + + assert!(input.next().is_some()); // Delimiter + while let Some(ch) = input.next() { + match ch { + '\\' => match input.next().unwrap() { + 'n' => result.push('\n'), + 'r' => result.push('\r'), + 't' => result.push('\t'), + ch => result.push(ch), + }, + _ => result.push(ch), + } + } + result.pop(); // We pushed the other delimiter on, whoops. + + let literal = Literal::String(result); + self.tree.add_expr(Expr::Literal(literal, token.clone())) + } + fn grouping(&mut self) -> ExprRef { let result = self.expression(); self.consume( @@ -385,4 +411,9 @@ mod tests { test_expr!(add_expr, "1 + 2", "(+ 1 2)"); test_expr!(prec_expr, "1 + 2 * 3 - 7 * 7", "(- (+ 1 (* 2 3)) (* 7 7))"); test_expr!(unary, "-((23)) * 5", "(* (- 23) 5)"); + test_expr!( + strings, + r#" "Hello " + "world!" "#, + r#"(+ "Hello " "world!")"# + ); }