1use std::vec;
2
3use crate::types::List;
4
5use super::types::Type;
6static VEC_PREFIX: &'static str = "#(";
7static QUOTE_PREFIX: &'static str = "'(";
8static U8VEC_PREFIX: &'static str = "#u8(";
9static PREFIX: &'static str = "(";
10static SUFFIX: &'static str = ")";
11
12pub fn parser(expr: String) -> Result<Type, String> {
13 let e = parse0(expr.trim());
14 println!("parser:{}", e);
15 Ok(e)
16}
17
18fn parse0(expr: &str) -> Type {
19 let is_vec = expr.starts_with(VEC_PREFIX);
20 let is_quote = expr.starts_with(QUOTE_PREFIX);
21 let is_u8_vec = expr.starts_with(U8VEC_PREFIX);
22 let is_push = expr.starts_with(PREFIX) || is_vec || is_u8_vec || is_quote;
23 if is_push {
24 parse_expr(expr)
25 } else {
26 parse_atom(expr).unwrap()
27 }
28}
29
30fn parse_expr(expr: &str) -> Type {
31 let mut stack = Vec::new();
32 let mut next = true;
33 let mut exp = expr;
34 while next {
35 exp = exp.trim();
36 let is_vec = exp.starts_with(VEC_PREFIX);
37 let is_quote = exp.starts_with(QUOTE_PREFIX);
38 let is_u8_vec = exp.starts_with(U8VEC_PREFIX);
39 let is_push = exp.starts_with(PREFIX) || is_vec || is_u8_vec || is_quote;
40 let index = if is_u8_vec {
41 4
42 } else if is_vec || is_quote {
43 2
44 } else {
45 1
46 };
47 let next_exp = &exp[index..];
48 let to_index = get_to_index(next_exp);
49 next = next_exp.find(SUFFIX) != None;
50 let sub_exp = &next_exp[..to_index];
51 if is_push {
53 if is_u8_vec {
54 let v = parse_vec(sub_exp)
55 .iter()
56 .map(|x| as_u8(x))
57 .collect::<Vec<u8>>();
58 stack.push(Type::u8vector_of(v));
59 } else if is_vec {
60 stack.push(Type::vector_of(parse_vec(sub_exp)));
61 } else if is_quote {
62 let v = parse_vec(sub_exp);
63 let mut vec = vec![Type::symbol("quote")];
64 vec.push(Type::expr_of(v));
65 stack.push(Type::Lists(List::of_quote(vec)));
66 } else {
67 stack.push(Type::expr_of(parse_vec(sub_exp)));
68 }
69 } else {
70 let brother = stack.pop().unwrap();
71 if stack.is_empty() {
72 stack.push(brother);
73 } else {
74 let mut parent = stack.pop().unwrap();
75 match &mut parent {
76 Type::Lists(p) => {
77 if p.is_quote() {
78 if let Type::Lists(d) = p.get_data().get_mut(1).unwrap() {
79 d.push(brother);
80 d.push_vec(parse_vec(sub_exp));
81 }else{
82 }
84 } else {
85 p.push(brother);
86 p.push_vec(parse_vec(sub_exp));
87 }
88 }
89 Type::Vectors(p) => {
90 p.push(brother);
91 p.push_vec(parse_vec(sub_exp));
92 }
93 Type::ByteVectors(p) => {
94 p.push(as_u8(&brother));
95 let v = parse_vec(sub_exp)
96 .iter()
97 .map(|x| as_u8(x))
98 .collect::<Vec<u8>>();
99 p.push_vec(v);
100 }
101 _ => {}
102 }
103 stack.push(parent);
104 }
105 }
106
107 exp = exp[to_index + index..].trim();
111 }
113 stack.pop().unwrap()
114}
115
116fn get_to_index(next_exp: &str) -> usize {
117 let pre0 = next_exp.find(PREFIX);
119 let pre1 = next_exp.find(VEC_PREFIX);
120 let pre2 = next_exp.find(U8VEC_PREFIX);
121 let pre3 = next_exp.find(QUOTE_PREFIX);
122 let mut t = vec![pre0, pre1, pre2, pre3]
124 .iter()
125 .filter(|x| x.is_some())
126 .map(|x| x.unwrap())
127 .collect::<Vec<usize>>();
128 t.sort();
129 let pre = t.get(0);
130 let suf = next_exp.find(SUFFIX);
131 if suf != None {
132 let suf_index = suf.unwrap();
133 if pre != None {
134 let pre_index = pre.unwrap();
135 if *pre_index < suf_index {
136 *pre_index
137 } else {
138 suf_index
139 }
140 } else {
141 suf_index
142 }
143 } else {
144 0
145 }
146}
147
148fn parse_vec(exp: &str) -> Vec<Type> {
149 rep_str(exp.to_string())
150 .trim()
151 .split_whitespace()
152 .map(|s| parse_atom(s).unwrap())
153 .collect()
154}
155
156fn rep_str(str: String) -> String {
161 if let Some(i) = str.find("'") {
162 let sub = &str[i + 1..];
163 if let Some(j) = sub.find("'") {
164 let s = &sub[..j].replace(" ", "\\u0009");
165 let mut all_str = String::new();
166 let right_str = &str[..i + 1];
167 let left_str = &sub[j..];
168 all_str.push_str(right_str);
169 all_str.push_str(s);
170 all_str.push_str(rep_str(left_str.to_string()).as_str());
171 return all_str;
172 }
173 return str;
174 } else {
175 return str;
176 }
177}
178
179fn parse_atom(s: &str) -> Result<Type, String> {
180 let t: Type = match s {
181 "nil" => Type::Nil,
182 "#t" => Type::Booleans(true),
183 "#f" => Type::Booleans(false),
184 _ => {
185 if s.starts_with("'") {
186 Type::expr_of(vec![Type::symbol("quote"), parse0(&s.replace("'", ""))])
187 } else if s.starts_with("\"") && s.ends_with("\"") && s.len() > 2 {
188 Type::string_of(
189 s[1..s.len() - 1]
190 .replace("\\u0009", " ")
191 .replace("\\r", "\r")
192 .replace("\\n", "\n")
193 .to_string(),
194 )
195 } else if s.starts_with("#\\") && s.len() == 2 {
196 Type::character_of(s.chars().nth(2).unwrap())
197 } else if s.starts_with(U8VEC_PREFIX) && s.len() > 4 {
198 let v = parse0(&s.replace(U8VEC_PREFIX, "("));
199 let r = match v {
200 Type::Lists(v) => v.data(),
201 _ => vec![v],
202 };
203 Type::u8vector_of(r.iter().map(|x| as_u8(x)).collect::<Vec<u8>>())
204 } else if s.starts_with(VEC_PREFIX) && s.len() > 2 {
205 let v = parse0(&s.replace(VEC_PREFIX, "("));
206 let r = match v {
207 Type::Lists(v) => v.data(),
208 _ => vec![v],
209 };
210 Type::vector_of(r)
211 } else if s.parse::<isize>().is_ok() {
212 Type::integer_of(s.parse::<isize>().unwrap())
213 } else if s.parse::<f64>().is_ok() {
214 Type::float_of(s.parse::<f64>().unwrap())
215 } else if s.starts_with(",@") {
216 if s.len() > 2 {
217 Type::expr_of(vec![
218 Type::symbol_of(",@".to_string()),
219 Type::symbol_of(s[2..].to_string()),
220 ])
221 } else {
222 Type::symbol_of(s.to_string())
223 }
224 } else {
225 peel_onions(s, vec![",", "'"])
226 }
227 }
228 };
229 Ok(t)
230}
231
232fn peel_onions(s: &str, keys: Vec<&str>) -> Type {
233 for key in keys {
234 if s.starts_with(key) && s.len() > key.len() {
235 return Type::expr_of(vec![
236 Type::Symbols(key.to_string()),
237 Type::Symbols(s[key.len()..].to_string()),
238 ]);
239 }
240 }
241 Type::Symbols(s.to_string())
242}
243
244fn as_u8(v: &Type) -> u8 {
245 match v {
246 Type::Numbers(v) => *v as u8,
247 Type::Characters(v) => *v as u8,
248 _ => 0,
249 }
250}