about summary refs log tree commit diff
path: root/src/parser/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/expr.rs')
-rw-r--r--src/parser/expr.rs34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/parser/expr.rs b/src/parser/expr.rs
index 73c873b5b3..2ec6d60cd0 100644
--- a/src/parser/expr.rs
+++ b/src/parser/expr.rs
@@ -1,11 +1,14 @@
+use std::borrow::Cow;
+
+use nom::alt;
 use nom::character::complete::{digit1, multispace0, multispace1};
 use nom::{
-    alt, call, char, complete, delimited, do_parse, flat_map, many0, map, named, opt, parse_to,
+    call, char, complete, delimited, do_parse, flat_map, many0, map, named, opt, parse_to,
     preceded, separated_list0, separated_list1, tag, tuple,
 };
 use pratt::{Affix, Associativity, PrattParser, Precedence};
 
-use crate::ast::{BinaryOperator, Binding, Expr, Fun, Ident, Literal, UnaryOperator};
+use crate::ast::{BinaryOperator, Binding, Expr, Fun, Literal, UnaryOperator};
 use crate::parser::{ident, type_};
 
 #[derive(Debug)]
@@ -161,7 +164,22 @@ named!(bool_(&str) -> Literal, alt!(
     tag!("false") => { |_| Literal::Bool(false) }
 ));
 
-named!(literal(&str) -> Literal, alt!(int | bool_));
+fn string_internal(i: &str) -> nom::IResult<&str, Cow<'_, str>, nom::error::Error<&str>> {
+    let (s, rem) = i
+        .split_once('"')
+        .ok_or_else(|| nom::Err::Error(nom::error::Error::new(i, nom::error::ErrorKind::Tag)))?;
+    Ok((rem, Cow::Borrowed(s)))
+}
+
+named!(string(&str) -> Literal, preceded!(
+    char!('"'),
+    map!(
+        string_internal,
+        |s| Literal::String(s)
+    )
+));
+
+named!(literal(&str) -> Literal, alt!(int | bool_ | string));
 
 named!(literal_expr(&str) -> Expr, map!(literal, Expr::Literal));
 
@@ -308,7 +326,7 @@ named!(pub expr(&str) -> Expr, alt!(
 #[cfg(test)]
 pub(crate) mod tests {
     use super::*;
-    use crate::ast::Type;
+    use crate::ast::{Ident, Type};
     use std::convert::TryFrom;
     use BinaryOperator::*;
     use Expr::{BinaryOp, If, Let, UnaryOp};
@@ -419,6 +437,14 @@ pub(crate) mod tests {
     }
 
     #[test]
+    fn simple_string_lit() {
+        assert_eq!(
+            test_parse!(expr, "\"foobar\""),
+            Expr::Literal(Literal::String(Cow::Borrowed("foobar")))
+        )
+    }
+
+    #[test]
     fn let_complex() {
         let res = test_parse!(expr, "let x = 1; y = x * 7 in (x + y) * 4");
         assert_eq!(