1use super::*;
14
15fn is_name_char(c: Chr) -> bool {
17 false
18 || (c >= b'A' && c <= b'Z')
19 || (c >= b'a' && c <= b'z')
20 || (c >= b'0' && c <= b'9')
21 || (c == b'_')
22 || (c == b'.')
23}
24
25fn parse_name(code: &Str) -> (&Str, &Str) {
26 let code = skip_whitespace(code);
27 let mut i: usize = 0;
28 while i < code.len() && is_name_char(code[i]) {
29 i += 1;
30 }
31 (&code[i..], &code[0..i])
32}
33
34fn skip_whitespace(code: &Str) -> &Str {
35 let mut i: usize = 0;
36 while i < code.len() && (code[i] == b' ' || code[i] == b'\n') {
37 i += 1;
38 }
39 &code[i..]
40}
41
42fn parse_text<'a>(code: &'a Str, text: &Str) -> Result<&'a Str, String> {
43 let code = skip_whitespace(code);
44 if code.starts_with(text) {
45 Ok(&code[text.len()..])
46 } else {
47 Err(format!("Expected '{}', found '{}'", String::from_utf8_lossy(text), String::from_utf8_lossy(code)))
48 }
49}
50
51pub fn parse_term<'a>(code: &'a Str, ctx: &mut Context<'a>, idx: &mut u32) -> (&'a Str, Term) {
53 let code = skip_whitespace(code);
54 match code[0] {
55 b'/' if code[1] == b'/' => {
57 let end = code.iter().position(|&c| c == b'\n').unwrap_or(code.len());
58 parse_term(&code[end..], ctx, idx)
59 }
60 b'\xce' if code[1] == b'\xbb' && code[2] == b'(' => {
62 let (code, nam) = parse_name(&code[3..]);
63 let code = parse_text(code, b":").unwrap();
64 let (code, typ) = parse_term(code, ctx, idx);
65 let code = parse_text(code, b")").unwrap();
66 extend(nam, None, ctx);
67 let (code, bod) = parse_term(code, ctx, idx);
68 narrow(ctx);
69 let nam = nam.to_vec();
70 let typ = Some(Box::new(typ));
71 let bod = Box::new(bod);
72 (code, Lam { nam, typ, bod })
73 },
74 b'\xce' if code[1] == b'\xbb' => {
76 let (code, nam) = parse_name(&code[2..]);
77 extend(nam, None, ctx);
78 let (code, bod) = parse_term(code, ctx, idx);
79 narrow(ctx);
80 let nam = nam.to_vec();
81 let typ = None;
82 let bod = Box::new(bod);
83 (code, Lam { nam, typ, bod })
84 }
85 b'(' => {
87 let (mut code, mut fun) = parse_term(&code[1..], ctx, idx);
88 while code[0] != b')' {
89 let (new_code, arg) = parse_term(code, ctx, idx);
90 code = new_code;
91 let arg = Box::new(arg);
92 fun = App { fun: Box::new(fun), arg };
93 }
94 let code = parse_text(code, b")").unwrap();
95 (code, fun)
96 }
97 b'<' => {
99 let (code, val) = parse_term(&code[1..], ctx, idx);
100 let code = parse_text(code, b":").unwrap();
101 let (code, typ) = parse_term(code, ctx, idx);
102 let code = parse_text(code, b">").unwrap();
103 (code, Ann { val: Box::new(val), typ: Box::new(typ) })
104 },
105 b'{' => {
107 let (code, fst) = parse_term(&code[1..], ctx, idx);
108 let (code, snd) = parse_term(code, ctx, idx);
109 let code = parse_text(code, b"}").unwrap();
110 let (code, tag) = if code[0] == b'#' { parse_name(&code[1..]) } else { (code, &b""[..]) };
111 let tag = name_to_index(&tag.to_vec());
112 let fst = Box::new(fst);
113 let snd = Box::new(snd);
114 (code, Sup { tag, fst, snd })
115 }
116 b'd' if code.starts_with(b"dup ") => {
118 let code = &code[4..];
119 let (code, tag) = if code[0] == b'#' { parse_name(&code[1..]) } else { (code, &b""[..]) };
120 let (code, fst) = parse_name(code);
121 let (code, snd) = parse_name(code);
122 let code = parse_text(code, b"=").unwrap();
123 extend(snd, None, ctx);
124 extend(fst, None, ctx);
125 let (code, val) = parse_term(code, ctx, idx);
126 let code = if code[0] == b';' { &code[1..] } else { code };
127 let (code, nxt) = parse_term(code, ctx, idx);
128 narrow(ctx);
129 narrow(ctx);
130 let tag = name_to_index(&tag.to_vec());
131 let fst = fst.to_vec();
132 let snd = snd.to_vec();
133 let val = Box::new(val);
134 let nxt = Box::new(nxt);
135 (code, Dup { tag, fst, snd, val, nxt })
136 }
137 b'd' if code.starts_with(b"def ") => {
139 let (code, nam) = parse_name(&code[4..]);
140 let code = parse_text(code, b"=").unwrap();
141 let (code, val) = parse_term(code, ctx, idx);
142 let code = if code[0] == b';' { &code[1..] } else { code };
143 extend(nam, Some(val), ctx);
144 let (code, bod) = parse_term(code, ctx, idx);
145 narrow(ctx);
146 (code, bod)
147 }
148 b'*' => {
150 (&code[1..], Set)
151 },
152 _ => {
154 let (code, nam) = parse_name(code);
155 let mut val: Option<Term> = None;
156 for i in (0..ctx.len()).rev() {
157 if ctx[i].0 == nam {
158 match ctx[i].1 {
159 Some(ref term) => {
160 let mut name = nam.clone().to_vec();
161 val = Some(copy(&name, *idx, term));
162 *idx += 1;
163 break;
164 }
165 None => {
166 break;
167 }
168 }
169 }
170 }
171 let nam = nam.to_vec();
172 (code, match val { Some(term) => term, None => Var { nam } })
173 }
174 }
175}
176
177pub fn from_string<'a>(code : &'a Str) -> Term {
179 let mut ctx = Vec::new();
180 let mut idx = 0;
181 parse_term(code, &mut ctx, &mut idx).1
182}
183
184pub fn to_string(term : &Term) -> Vec<Chr> {
186 fn stringify_term(code : &mut Vec<u8>, term : &Term) {
187 match term {
188 &Lam{ref nam, ref typ, ref bod} => {
189 code.extend_from_slice("λ".as_bytes());
190 if let Some(ref t) = typ {
191 code.extend_from_slice(b"(");
192 code.append(&mut nam.clone());
193 code.extend_from_slice(b": ");
194 stringify_term(code, &t);
195 code.extend_from_slice(b")");
196 } else {
197 code.append(&mut nam.clone());
198 }
199 code.extend_from_slice(b" ");
200 stringify_term(code, &bod);
201 },
202 &App{ref fun, ref arg} => {
203 code.extend_from_slice(b"(");
204 stringify_term(code, &fun);
205 code.extend_from_slice(b" ");
206 stringify_term(code, &arg);
207 code.extend_from_slice(b")");
208 },
209 &Ann{ref val, ref typ} => {
210 code.extend_from_slice(b"<");
211 stringify_term(code, &val);
212 code.extend_from_slice(b": ");
213 stringify_term(code, &typ);
214 code.extend_from_slice(b">");
215 },
216 &Sup{tag, ref fst, ref snd} => {
217 code.extend_from_slice(b"[");
218 stringify_term(code, &fst);
219 code.extend_from_slice(b" ");
220 stringify_term(code, &snd);
221 if tag != 0 {
222 code.extend_from_slice(b"#");
223 code.append(&mut index_to_name(tag));
224 }
225 code.extend_from_slice(b"]");
226 },
227 &Dup{tag, ref fst, ref snd, ref val, ref nxt} => {
228 code.extend_from_slice(b"dup ");
229 if tag != 0 {
230 code.extend_from_slice(b"#");
231 code.append(&mut index_to_name(tag));
232 code.extend_from_slice(b" ");
233 }
234 code.append(&mut fst.clone());
235 code.extend_from_slice(b" ");
236 code.append(&mut snd.clone());
237 code.extend_from_slice(b" = ");
238 stringify_term(code, &val);
239 code.extend_from_slice(b"; ");
240 stringify_term(code, &nxt);
241 },
242 &Set => {
243 code.extend_from_slice(b"*");
244 },
245 &Var{ref nam} => {
246 code.append(&mut nam.clone());
247 },
248 }
249 }
250 let mut code = Vec::new();
251 stringify_term(&mut code, &term);
252 return code;
253}
254