|
|
@ -112,12 +112,12 @@ fn dbg(msg: &str, pos: &usize) { |
|
|
|
fn atom_of_string(s: String) -> Atom { |
|
|
|
fn atom_of_string(s: String) -> Atom { |
|
|
|
match FromStr::from_str(&s) { |
|
|
|
match FromStr::from_str(&s) { |
|
|
|
Ok(i) => return Atom::I(i), |
|
|
|
Ok(i) => return Atom::I(i), |
|
|
|
Err(_) => {}, |
|
|
|
Err(_) => {} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
match FromStr::from_str(&s) { |
|
|
|
match FromStr::from_str(&s) { |
|
|
|
Ok(f) => return Atom::F(f), |
|
|
|
Ok(f) => return Atom::F(f), |
|
|
|
Err(_) => {}, |
|
|
|
Err(_) => {} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Atom::S(s) |
|
|
|
Atom::S(s) |
|
|
@ -126,7 +126,7 @@ fn atom_of_string(s: String) -> Atom { |
|
|
|
// returns the char it found, and the new size if you wish to consume that char
|
|
|
|
// returns the char it found, and the new size if you wish to consume that char
|
|
|
|
fn peek(s: &str, pos: &usize) -> ERes<(char, usize)> { |
|
|
|
fn peek(s: &str, pos: &usize) -> ERes<(char, usize)> { |
|
|
|
dbg("peek", pos); |
|
|
|
dbg("peek", pos); |
|
|
|
if *pos == s.len() { return err("unexpected eof", s, pos) } |
|
|
|
if *pos == s.len() { return err("unexpected eof", s, pos); } |
|
|
|
if s.is_char_boundary(*pos) { |
|
|
|
if s.is_char_boundary(*pos) { |
|
|
|
let ch = s[*pos..].chars().next().unwrap(); |
|
|
|
let ch = s[*pos..].chars().next().unwrap(); |
|
|
|
let next = *pos + ch.len_utf8(); |
|
|
|
let next = *pos + ch.len_utf8(); |
|
|
@ -146,10 +146,10 @@ fn expect(s: &str, pos: &mut usize, c: char) -> ERes<()> { |
|
|
|
|
|
|
|
|
|
|
|
fn consume_until_newline(s: &str, pos: &mut usize) -> ERes<()> { |
|
|
|
fn consume_until_newline(s: &str, pos: &mut usize) -> ERes<()> { |
|
|
|
loop { |
|
|
|
loop { |
|
|
|
if *pos == s.len() { return Ok(()) } |
|
|
|
if *pos == s.len() { return Ok(()); } |
|
|
|
let (ch, next) = peek(s, pos)?; |
|
|
|
let (ch, next) = peek(s, pos)?; |
|
|
|
*pos = next; |
|
|
|
*pos = next; |
|
|
|
if ch == '\n' { return Ok(()) } |
|
|
|
if ch == '\n' { return Ok(()); } |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -157,12 +157,10 @@ fn consume_until_newline(s: &str, pos: &mut usize) -> ERes<()> { |
|
|
|
fn zspace(s: &str, pos: &mut usize) -> ERes<()> { |
|
|
|
fn zspace(s: &str, pos: &mut usize) -> ERes<()> { |
|
|
|
dbg("zspace", pos); |
|
|
|
dbg("zspace", pos); |
|
|
|
loop { |
|
|
|
loop { |
|
|
|
if *pos == s.len() { return Ok(()) } |
|
|
|
if *pos == s.len() { return Ok(()); } |
|
|
|
let (ch, next) = peek(s, pos)?; |
|
|
|
let (ch, next) = peek(s, pos)?; |
|
|
|
|
|
|
|
|
|
|
|
if ch == ';' { consume_until_newline(s, pos)? } |
|
|
|
if ch == ';' { consume_until_newline(s, pos)? } else if ch.is_whitespace() { *pos = next; } else { return Ok(()); } |
|
|
|
else if ch.is_whitespace() { *pos = next; } |
|
|
|
|
|
|
|
else { return Ok(()) } |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -201,11 +199,14 @@ fn parse_unquoted_atom(s: &str, pos: &mut usize) -> ERes<Atom> { |
|
|
|
let mut cs: String = String::new(); |
|
|
|
let mut cs: String = String::new(); |
|
|
|
|
|
|
|
|
|
|
|
loop { |
|
|
|
loop { |
|
|
|
if *pos == s.len() { break } |
|
|
|
if *pos == s.len() { break; } |
|
|
|
let (c, next) = peek(s, pos)?; |
|
|
|
let (c, next) = peek(s, pos)?; |
|
|
|
|
|
|
|
|
|
|
|
if c == ';' { consume_until_newline(s, pos)?; break } |
|
|
|
if c == ';' { |
|
|
|
if c.is_whitespace() || c == '(' || c == ')' { break } |
|
|
|
consume_until_newline(s, pos)?; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if c.is_whitespace() || c == '(' || c == ')' { break; } |
|
|
|
cs.push(c); |
|
|
|
cs.push(c); |
|
|
|
*pos = next; |
|
|
|
*pos = next; |
|
|
|
} |
|
|
|
} |
|
|
@ -217,8 +218,7 @@ fn parse_atom(s: &str, pos: &mut usize) -> ERes<Atom> { |
|
|
|
dbg("parse_atom", pos); |
|
|
|
dbg("parse_atom", pos); |
|
|
|
let (ch, _) = peek(s, pos)?; |
|
|
|
let (ch, _) = peek(s, pos)?; |
|
|
|
|
|
|
|
|
|
|
|
if ch == '"' { parse_quoted_atom (s, pos) } |
|
|
|
if ch == '"' { parse_quoted_atom(s, pos) } else { parse_unquoted_atom(s, pos) } |
|
|
|
else { parse_unquoted_atom(s, pos) } |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn parse_list(s: &str, pos: &mut usize) -> ERes<Vec<Sexp>> { |
|
|
|
fn parse_list(s: &str, pos: &mut usize) -> ERes<Vec<Sexp>> { |
|
|
@ -248,8 +248,7 @@ fn parse_sexp(s: &str, pos: &mut usize) -> ERes<Sexp> { |
|
|
|
zspace(s, pos)?; |
|
|
|
zspace(s, pos)?; |
|
|
|
let (c, _) = peek(s, pos)?; |
|
|
|
let (c, _) = peek(s, pos)?; |
|
|
|
let r = |
|
|
|
let r = |
|
|
|
if c == '(' { Ok(Sexp::List(parse_list(s, pos)?)) } |
|
|
|
if c == '(' { Ok(Sexp::List(parse_list(s, pos)?)) } else { Ok(Sexp::Atom(parse_atom(s, pos)?)) }; |
|
|
|
else { Ok(Sexp::Atom(parse_atom(s, pos)?)) }; |
|
|
|
|
|
|
|
zspace(s, pos)?; |
|
|
|
zspace(s, pos)?; |
|
|
|
r |
|
|
|
r |
|
|
|
} |
|
|
|
} |
|
|
@ -293,7 +292,7 @@ fn is_num_string(s: &str) -> bool { |
|
|
|
|
|
|
|
|
|
|
|
fn string_contains_whitespace(s: &str) -> bool { |
|
|
|
fn string_contains_whitespace(s: &str) -> bool { |
|
|
|
for c in s.chars() { |
|
|
|
for c in s.chars() { |
|
|
|
if c.is_whitespace() { return true } |
|
|
|
if c.is_whitespace() { return true; } |
|
|
|
} |
|
|
|
} |
|
|
|
false |
|
|
|
false |
|
|
|
} |
|
|
|
} |
|
|
@ -332,7 +331,7 @@ impl fmt::Display for Sexp { |
|
|
|
write!(f, "{}{}", s, x)?; |
|
|
|
write!(f, "{}{}", s, x)?; |
|
|
|
} |
|
|
|
} |
|
|
|
write!(f, ")") |
|
|
|
write!(f, ")") |
|
|
|
}, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|