3 //extern crate regex_macros;
8 use types::{MalVal,MalRet,
9 _nil,_true,_false,_int,symbol,string,list,vector,hash_mapv};
11 use super::printer::unescape_str;
13 #[deriving(Show, Clone)]
20 fn next(&mut self) -> Option<String> {
21 if self.position < self.tokens.len() {
23 Some(self.tokens[self.position-1].to_string())
28 fn peek(&self) -> Option<String> {
29 if self.position < self.tokens.len() {
30 Some(self.tokens[self.position].to_string())
37 fn tokenize(str :String) -> Vec<String> {
38 let mut results = vec![];
40 let re = match Pcre::compile(r###"[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)"###) {
41 Err(_) => { fail!("failed to compile regex") },
45 let mut it = re.matches(str.as_slice());
47 let opt_m = it.next();
48 if opt_m.is_none() { break; }
49 let m = opt_m.unwrap();
50 if m.group(1) == "" { break; }
51 if m.group(1).starts_with(";") { continue; }
53 results.push((*m.group(1)).to_string());
58 fn read_atom(rdr : &mut Reader) -> MalRet {
59 let otoken = rdr.next();
60 //println!("read_atom: {}", otoken);
61 if otoken.is_none() { return Err("read_atom underflow".to_string()); }
62 let stoken = otoken.unwrap();
63 let token = stoken.as_slice();
64 if regex!(r"^-?[0-9]+$").is_match(token) {
65 let num : Option<int> = from_str(token);
66 Ok(_int(num.unwrap()))
67 } else if regex!(r#"^".*"$"#).is_match(token) {
68 let new_str = token.slice(1,token.len()-1);
69 Ok(string(unescape_str(new_str)))
70 } else if token == "nil" {
72 } else if token == "true" {
74 } else if token == "false" {
81 fn read_seq(rdr : &mut Reader, start: &str, end: &str) -> Result<Vec<MalVal>,String> {
82 let otoken = rdr.next();
84 return Err("read_atom underflow".to_string());
86 let stoken = otoken.unwrap();
87 let token = stoken.as_slice();
89 return Err("expected '".to_string() + start.to_string() + "'".to_string());
92 let mut ast_vec : Vec<MalVal> = vec![];
94 let otoken = rdr.peek();
96 return Err("expected '".to_string() + end.to_string() + "', got EOF".to_string());
98 let stoken = otoken.unwrap();
99 let token = stoken.as_slice();
100 if token == end { break; }
102 match read_form(rdr) {
103 Ok(mv) => ast_vec.push(mv),
104 Err(e) => return Err(e),
112 fn read_list(rdr : &mut Reader) -> MalRet {
113 match read_seq(rdr, "(", ")") {
114 Ok(seq) => Ok(list(seq)),
119 fn read_vector(rdr : &mut Reader) -> MalRet {
120 match read_seq(rdr, "[", "]") {
121 Ok(seq) => Ok(vector(seq)),
126 fn read_hash_map(rdr : &mut Reader) -> MalRet {
127 match read_seq(rdr, "{", "}") {
128 Ok(seq) => hash_mapv(seq),
133 fn read_form(rdr : &mut Reader) -> MalRet {
134 let otoken = rdr.peek();
135 //println!("read_form: {}", otoken);
136 let stoken = otoken.unwrap();
137 let token = stoken.as_slice();
141 match read_form(rdr) {
142 Ok(f) => Ok(list(vec![symbol("quote"), f])),
148 match read_form(rdr) {
149 Ok(f) => Ok(list(vec![symbol("quasiquote"), f])),
155 match read_form(rdr) {
156 Ok(f) => Ok(list(vec![symbol("unquote"), f])),
162 match read_form(rdr) {
163 Ok(f) => Ok(list(vec![symbol("splice-unquote"), f])),
168 ")" => Err("unexected ')'".to_string()),
169 "(" => read_list(rdr),
171 "]" => Err("unexected ']'".to_string()),
172 "[" => read_vector(rdr),
174 "}" => Err("unexected '}'".to_string()),
175 "{" => read_hash_map(rdr),
181 pub fn read_str(str :String) -> MalRet {
182 let tokens = tokenize(str);
183 if tokens.len() == 0 {
184 return Err("<empty line>".to_string());
186 //println!("tokens: {}", tokens);
187 let rdr = &mut Reader{tokens: tokens, position: 0};