]>
Witch of Git - ess/blob - src/lib.rs
1 //! A lightweight S-expression parser intended for language implementation.
9 use nom
::{digit
, multispace
, IResult
};
11 #[derive(Debug, PartialEq, Clone, PartialOrd)]
13 /// A value representing a symbol. A symbol is an atomic unit
15 /// A value representing a string literal.
17 /// A value representing an integer. Any number containing no decimal point
18 /// will be parsed as an `Int`.
20 /// A value representing a float. Any number containing a decimal point will
21 /// be parsed as a `Float`.
25 #[derive(Debug, PartialEq, Clone, PartialOrd)]
27 /// A wrapper around the atom type
31 /// A list of subexpressions
37 pub fn parse(input
: &str) -> Result
<Sexp
, ()> {
39 IResult
::Done(_
, res
) => Ok(res
),
44 named
!(sexp
<&str, Sexp
>,
46 list
=> { |list
| Sexp
::List
{ list
: list
} }
47 | atom
=> { |atom
| Sexp
::Atom
{ atom
: atom
} }
51 named
!(list
<&str, Vec
<Sexp
> >,
55 entries
: many0
!(sexp
) >>
62 named
!(atom
<&str, Atom
>, alt
!(string
| symbol
| number
));
64 named
!(string
<&str, Atom
>,
68 contents: take_until_s!("\"") >>
71 (Atom::Str(contents.into()))
75 named!(symbol<&str, Atom>,
78 name: take_while1_s!(valid_ident_char) >>
79 (Atom::Sym(name.into()))
83 fn valid_ident_char(c: char) -> bool {
84 !c.is_whitespace() && c != '"'
&& c
!= '
('
&& c
!= '
)'
87 named
!(number
<&str, Atom
>,
91 (Atom
::Int(integral
.chars().fold
(0, |i
, c
| i
* 10 + c
as i64 - '
0'
as i64)))