gdritter repos picoml / 56e8f76
Add tuples and pretty-printing Getty Ritter 6 years ago
1 changed file(s) with 171 addition(s) and 5 deletion(s). Collapse all Expand all
22
33 type Ident = String;
44 type Env = HashMap<Ident, Value>;
5
6 trait Show {
7 fn show(&self, buf: &mut String);
8 }
59
610 #[derive(Debug, Clone)]
711 pub enum Stmt {
812 Let(Pat, Option<Type>, Vec<Pat>, Expr),
913 Expr(Expr),
14 }
15
16 impl Show for Stmt {
17 fn show(&self, buf: &mut String) {
18 match *self {
19 Stmt::Let(ref p, _, _, ref e) => {
20 p.show(buf);
21 buf.push_str(" = ");
22 e.show(buf);
23 }
24 Stmt::Expr(ref e) =>
25 e.show(buf),
26 }
27 buf.push_str(";\n");
28 }
1029 }
1130
1231 impl Stmt {
2443 #[derive(Debug, Clone)]
2544 pub enum Pat {
2645 Var(Ident),
46 Tuple(Vec<Pat>),
47 }
48
49 impl Show for Pat {
50 fn show(&self, buf: &mut String) {
51 match *self {
52 Pat::Var(ref i) => buf.push_str(i),
53 Pat::Tuple(ref ps) => {
54 buf.push_str("(");
55 for (n, t) in ps.iter().enumerate() {
56 if n > 0 {
57 buf.push_str(", ");
58 }
59 t.show(buf);
60 }
61 buf.push_str(")");
62 }
63 }
64 }
2765 }
2866
2967 impl Pat {
3169 match *self {
3270 Pat::Var(ref n) => {
3371 let _ = env.insert(n.clone(), val);
72 },
73 Pat::Tuple(ref ps) => {
74 match val {
75 Value::Tuple(es) => {
76 if es.len() != ps.len() {
77 panic!("non-matching tuples!");
78 }
79 for (p, e) in ps.iter().zip(es.into_iter()) {
80 p.bind(e, env);
81 }
82 }
83 _ => panic!("not matching a tuple!"),
84 }
3485 }
3586 }
3687 }
3788
3889 fn mk_var<S: Into<String>>(s: S) -> Pat {
3990 Pat::Var(s.into())
91 }
92
93 fn mk_tuple(pats: Vec<Pat>) -> Pat {
94 Pat::Tuple(pats)
4095 }
4196 }
4297
59114 Fn(Box<Pat>, Box<Expr>),
60115 App(Box<Expr>, Box<Expr>),
61116 Do(Vec<Stmt>),
117 Tuple(Vec<Expr>),
118 }
119
120 impl Show for Expr {
121 fn show(&self, buf: &mut String) {
122 match *self {
123 Expr::Var(ref v) => buf.push_str(v),
124 Expr::Lit(ref l) => l.show(buf),
125 Expr::Fn(ref p, ref e) => {
126 buf.push_str("fn ");
127 p.show(buf);
128 buf.push_str(" => ");
129 e.show(buf);
130 }
131 Expr::App(ref e1, ref e2) => {
132 buf.push_str("(");
133 e1.show(buf);
134 buf.push_str(")(");
135 e2.show(buf);
136 buf.push_str(")");
137 }
138 Expr::Do(ref ss) => {
139 buf.push_str("do\n");
140 for s in ss.iter() {
141 s.show(buf);
142 }
143 buf.push_str("end\n");
144 }
145 Expr::Tuple(ref ts) => {
146 buf.push_str("(");
147 for (n, t) in ts.iter().enumerate() {
148 if n > 0 {
149 buf.push_str(", ");
150 }
151 t.show(buf);
152 }
153 buf.push_str(")");
154 }
155 }
156 }
62157 }
63158
64159 #[derive(Debug, Clone)]
65160 pub enum Value {
66161 Closure(Pat, Expr, Box<Env>),
67162 Lit(Literal),
163 Tuple(Vec<Value>),
68164 Unit,
165 }
166
167 impl Show for Value {
168 fn show(&self, buf: &mut String) {
169 match *self {
170 Value::Unit => buf.push_str("()"),
171 Value::Lit(ref l) => l.show(buf),
172 Value::Tuple(ref ts) => {
173 buf.push_str("(");
174 for (n, t) in ts.iter().enumerate() {
175 if n > 0 {
176 buf.push_str(", ");
177 }
178 t.show(buf);
179 }
180 buf.push_str(")");
181 }
182 Value::Closure(ref p, ref e, _) => {
183 buf.push_str("(\\");
184 p.show(buf);
185 buf.push_str(".");
186 e.show(buf);
187 buf.push_str(")");
188 }
189 }
190 }
69191 }
70192
71193 impl Expr {
101223 }
102224 Ok(result)
103225 },
226
227 Expr::Tuple(ref exprs) => {
228 let res: Result<Vec<Value>, String> =
229 exprs.iter().map(|e|e.eval(env)).collect();
230 Ok(Value::Tuple(res?))
231 },
104232 }
105233 }
106234
115243 fn mk_var<S: Into<String>>(s: S) -> Expr {
116244 Expr::Var(s.into())
117245 }
246
247 fn mk_tuple(es: Vec<Expr>) -> Expr {
248 Expr::Tuple(es)
249 }
118250 }
119251
120252 #[derive(Debug, Clone)]
122254 Int(i64),
123255 }
124256
257 impl Show for Literal {
258 fn show(&self, buf: &mut String) {
259 match *self {
260 Literal::Int(i) =>
261 buf.push_str(&format!("{}", i)),
262 }
263 }
264 }
265
266 fn show<S: Show>(s: &S) -> String {
267 let mut buf = String::new();
268 s.show(&mut buf);
269 buf
270 }
271
272 fn test(e: &Expr) {
273 let mut env = HashMap::new();
274 println!("> {}", show(e));
275 println!(" -> {}", show(&e.eval(&mut env).unwrap()));
276 }
125277
126278 fn main() {
127279 let sample = Expr::mk_app(
129281 Pat::mk_var("x"),
130282 Expr::mk_fn(
131283 Pat::mk_var("y"),
132 Expr::mk_var("y"),
284 Expr::mk_tuple(vec![
285 Expr::mk_var("x"),
286 Expr::mk_var("y"),
287 ]),
133288 ),
134289 ),
135290 Expr::Lit(Literal::Int(5)),
136291 );
137292
138 let mut env = HashMap::new();
139 println!("{:#?}", sample.eval(&mut env));
140 println!("{:#?}", Expr::mk_app(sample, Expr::Lit(Literal::Int(6))).eval(&mut env));
141 }
293 test(&sample);
294
295 let rs = Expr::mk_app(sample, Expr::Lit(Literal::Int(6)));
296 test(&rs);
297
298 let sample2 = Expr::mk_fn(
299 Pat::mk_tuple(vec![
300 Pat::mk_var("a"),
301 Pat::mk_var("b"),
302 ]),
303 Expr::mk_var("a"),
304 );
305
306 test(&Expr::mk_app(sample2, rs));
307 }