}
}
-pub fn parse(input: &str) -> Result<Sexp, ParseError> {
- match do_parse!(input, exp: sexp >> opt!(multispace) >> eof!() >> (exp)) {
+pub fn parse_one(input: &str) -> Result<Sexp, ParseError> {
+ match do_parse!(input,
+ exp: sexp >>
+ opt!(complete!(multispace)) >>
+ eof!() >>
+ (exp)) {
IResult::Done(_, res) => Ok(res),
_ => Err(ParseError::Unspecified),
}
}
+pub fn parse(input: &str) -> Result<Vec<Sexp>, ParseError> {
+ let parse_res: IResult<&str, Vec<Sexp>> =
+ do_parse!(input,
+ exps: many1!(complete!(sexp)) >>
+ opt!(complete!(multispace)) >>
+ eof!() >>
+ (exps));
+ match parse_res {
+ IResult::Done(_, res) => Ok(res),
+ e => {
+ println!("{:#?}", e);
+ Err(ParseError::Unspecified)
+ }
+ }
+}
+
named!(sexp<&str, Sexp>,
- alt!(
+ alt_complete!(
list => { |list| Sexp::List { list: list } }
| atom => { |atom| Sexp::Atom { atom: atom } }
)
)
);
-named!(atom<&str, Atom>, alt!(string | symbol | number | character));
+named!(atom<&str, Atom>, alt_complete!(string | symbol | number | character));
named!(string<&str, Atom>,
do_parse!(
opt!(multispace) >>
- tag_s!("\"") >>
- contents: take_until_s!("\"") >>
- tag_s!("\"") >>
+ tag_s!(r#"""#) >>
+ contents: take_until_s!(r#"""#) >>
+ tag_s!(r#"""#) >>
(Atom::Str(contents.into()))
)
);
named!(character<&str, Atom>,
do_parse!(
opt!(multispace) >>
- tag_s!("#\\") >>
+ tag_s!(r#"#\"#) >>
character: take_s!(1) >>
(Atom::Char(character.chars().next().unwrap()))
)
#[cfg(test)]
#[test]
fn test_parse_char() {
- assert_eq!(character("#\\\""), IResult::Done("", Atom::Char('"')));
- assert_eq!(character("#\\ "), IResult::Done("", Atom::Char(' ')));
- assert_eq!(character(" #\\\\"), IResult::Done("", Atom::Char('\\')));
+ assert_eq!(character(r#"#\""#), IResult::Done("", Atom::Char('"')));
+ assert_eq!(character(r#"#\ "#), IResult::Done("", Atom::Char(' ')));
+ assert_eq!(character(r#" #\\"#), IResult::Done("", Atom::Char('\\')));
assert!(character("#").is_incomplete());
assert!(character("a").is_err());
#[cfg(test)]
#[test]
-fn test_cant_parse() {
- assert!(parse("1 2").is_err());
+fn test_parse_only_one() {
+ assert!(parse_one("1 2").is_err());
}
#[cfg(test)]
#[test]
fn test_parse_expression() {
- assert_eq!(parse(r#"
+ assert_eq!(parse_one(r#"
(def (main)
(print (str "say " #\" "Hello, World" #\" " today!")))
"#),
]
}));
}
+
+#[cfg(test)]
+#[test]
+fn test_parse_multi() {
+ assert_eq!(parse(" 1 2 3 "),
+ Ok(vec![Sexp::Atom { atom: Atom::Int(1) },
+ Sexp::Atom { atom: Atom::Int(2) },
+ Sexp::Atom { atom: Atom::Int(3) }]));
+}