Split apart modules
Getty Ritter
6 years ago
1 | 1 | use std::collections::HashMap; |
2 | 2 | |
3 | type Ident = String; | |
4 | type Env = HashMap<Ident, Value>; | |
5 | ||
6 | trait Show { | |
7 | fn show(&self, buf: &mut String); | |
8 | } | |
9 | ||
10 | #[derive(Debug, Clone)] | |
11 | pub enum Stmt { | |
12 | Let(Pat, Option<Type>, Vec<Pat>, Expr), | |
13 | 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 | } | |
29 | } | |
3 | mod types; | |
4 | mod pretty; | |
5 | use types::*; | |
6 | use pretty::show; | |
30 | 7 | |
31 | 8 | impl Stmt { |
32 | 9 | fn eval(&self, env: &mut Env) -> Result<Value, String> { |
36 | 13 | p.bind(e.eval(env)?, env); |
37 | 14 | Ok(Value::Unit) |
38 | 15 | }, |
39 | } | |
40 | } | |
41 | } | |
42 | ||
43 | #[derive(Debug, Clone)] | |
44 | pub enum Pat { | |
45 | 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 | 16 | } |
64 | 17 | } |
65 | 18 | } |
86 | 39 | } |
87 | 40 | } |
88 | 41 | |
89 | fn mk_var<S: Into<String>>(s: S) -> Pat { | |
90 | Pat::Var(s.into()) | |
91 | } | |
92 | ||
93 | fn mk_tuple(pats: Vec<Pat>) -> Pat { | |
94 | Pat::Tuple(pats) | |
95 | } | |
96 | } | |
97 | ||
98 | #[derive(Debug, Clone)] | |
99 | pub enum Type { | |
100 | Prim(PrimType), | |
101 | Arr(Box<Type>, Box<Type>), | |
102 | } | |
103 | ||
104 | #[derive(Debug, Clone)] | |
105 | pub enum PrimType { | |
106 | Unit, | |
107 | Nat, | |
108 | } | |
109 | ||
110 | #[derive(Debug, Clone)] | |
111 | pub enum Expr { | |
112 | Var(Ident), | |
113 | Lit(Literal), | |
114 | Fn(Box<Pat>, Box<Expr>), | |
115 | App(Box<Expr>, Box<Expr>), | |
116 | 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 | } | |
157 | } | |
158 | ||
159 | #[derive(Debug, Clone)] | |
160 | pub enum Value { | |
161 | Closure(Pat, Expr, Box<Env>), | |
162 | Lit(Literal), | |
163 | Tuple(Vec<Value>), | |
164 | 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 | } | |
191 | 42 | } |
192 | 43 | |
193 | 44 | impl Expr { |
232 | 83 | } |
233 | 84 | } |
234 | 85 | |
235 | fn mk_fn(p: Pat, e: Expr) -> Expr { | |
236 | Expr::Fn(Box::new(p), Box::new(e)) | |
237 | } | |
238 | ||
239 | fn mk_app(e1: Expr, e2: Expr) -> Expr { | |
240 | Expr::App(Box::new(e1), Box::new(e2)) | |
241 | } | |
242 | ||
243 | fn mk_var<S: Into<String>>(s: S) -> Expr { | |
244 | Expr::Var(s.into()) | |
245 | } | |
246 | ||
247 | fn mk_tuple(es: Vec<Expr>) -> Expr { | |
248 | Expr::Tuple(es) | |
249 | } | |
250 | } | |
251 | ||
252 | #[derive(Debug, Clone)] | |
253 | pub enum Literal { | |
254 | Int(i64), | |
255 | } | |
256 | ||
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 | 86 | } |
271 | 87 | |
272 | 88 | fn test(e: &Expr) { |
1 | use types::*; | |
2 | ||
3 | pub trait Show { | |
4 | fn show(&self, buf: &mut String); | |
5 | } | |
6 | ||
7 | impl Show for Stmt { | |
8 | fn show(&self, buf: &mut String) { | |
9 | match *self { | |
10 | Stmt::Let(ref p, _, _, ref e) => { | |
11 | p.show(buf); | |
12 | buf.push_str(" = "); | |
13 | e.show(buf); | |
14 | } | |
15 | Stmt::Expr(ref e) => | |
16 | e.show(buf), | |
17 | } | |
18 | buf.push_str(";\n"); | |
19 | } | |
20 | } | |
21 | ||
22 | ||
23 | impl Show for Pat { | |
24 | fn show(&self, buf: &mut String) { | |
25 | match *self { | |
26 | Pat::Var(ref i) => buf.push_str(i), | |
27 | Pat::Tuple(ref ps) => { | |
28 | buf.push_str("("); | |
29 | for (n, t) in ps.iter().enumerate() { | |
30 | if n > 0 { | |
31 | buf.push_str(", "); | |
32 | } | |
33 | t.show(buf); | |
34 | } | |
35 | buf.push_str(")"); | |
36 | } | |
37 | } | |
38 | } | |
39 | } | |
40 | ||
41 | ||
42 | impl Show for Value { | |
43 | fn show(&self, buf: &mut String) { | |
44 | match *self { | |
45 | Value::Unit => buf.push_str("()"), | |
46 | Value::Lit(ref l) => l.show(buf), | |
47 | Value::Tuple(ref ts) => { | |
48 | buf.push_str("("); | |
49 | for (n, t) in ts.iter().enumerate() { | |
50 | if n > 0 { | |
51 | buf.push_str(", "); | |
52 | } | |
53 | t.show(buf); | |
54 | } | |
55 | buf.push_str(")"); | |
56 | } | |
57 | Value::Closure(ref p, ref e, _) => { | |
58 | buf.push_str("(\\"); | |
59 | p.show(buf); | |
60 | buf.push_str("."); | |
61 | e.show(buf); | |
62 | buf.push_str(")"); | |
63 | } | |
64 | } | |
65 | } | |
66 | } | |
67 | ||
68 | impl Show for Literal { | |
69 | fn show(&self, buf: &mut String) { | |
70 | match *self { | |
71 | Literal::Int(i) => | |
72 | buf.push_str(&format!("{}", i)), | |
73 | } | |
74 | } | |
75 | } | |
76 | ||
77 | impl Show for Expr { | |
78 | fn show(&self, buf: &mut String) { | |
79 | match *self { | |
80 | Expr::Var(ref v) => buf.push_str(v), | |
81 | Expr::Lit(ref l) => l.show(buf), | |
82 | Expr::Fn(ref p, ref e) => { | |
83 | buf.push_str("fn "); | |
84 | p.show(buf); | |
85 | buf.push_str(" => "); | |
86 | e.show(buf); | |
87 | } | |
88 | Expr::App(ref e1, ref e2) => { | |
89 | buf.push_str("("); | |
90 | e1.show(buf); | |
91 | buf.push_str(")("); | |
92 | e2.show(buf); | |
93 | buf.push_str(")"); | |
94 | } | |
95 | Expr::Do(ref ss) => { | |
96 | buf.push_str("do\n"); | |
97 | for s in ss.iter() { | |
98 | s.show(buf); | |
99 | } | |
100 | buf.push_str("end\n"); | |
101 | } | |
102 | Expr::Tuple(ref ts) => { | |
103 | buf.push_str("("); | |
104 | for (n, t) in ts.iter().enumerate() { | |
105 | if n > 0 { | |
106 | buf.push_str(", "); | |
107 | } | |
108 | t.show(buf); | |
109 | } | |
110 | buf.push_str(")"); | |
111 | } | |
112 | } | |
113 | } | |
114 | } | |
115 | ||
116 | pub fn show<S: Show>(s: &S) -> String { | |
117 | let mut buf = String::new(); | |
118 | s.show(&mut buf); | |
119 | buf | |
120 | } |
1 | use std::collections::HashMap; | |
2 | ||
3 | pub type Ident = String; | |
4 | pub type Env = HashMap<Ident, Value>; | |
5 | ||
6 | ||
7 | #[derive(Debug, Clone)] | |
8 | pub enum Stmt { | |
9 | Let(Pat, Option<Type>, Vec<Pat>, Expr), | |
10 | Expr(Expr), | |
11 | } | |
12 | ||
13 | #[derive(Debug, Clone)] | |
14 | pub enum Pat { | |
15 | Var(Ident), | |
16 | Tuple(Vec<Pat>), | |
17 | } | |
18 | ||
19 | impl Pat { | |
20 | pub fn mk_var<S: Into<String>>(s: S) -> Pat { | |
21 | Pat::Var(s.into()) | |
22 | } | |
23 | ||
24 | pub fn mk_tuple(pats: Vec<Pat>) -> Pat { | |
25 | Pat::Tuple(pats) | |
26 | } | |
27 | } | |
28 | ||
29 | #[derive(Debug, Clone)] | |
30 | pub enum Type { | |
31 | Prim(PrimType), | |
32 | Arr(Box<Type>, Box<Type>), | |
33 | } | |
34 | ||
35 | #[derive(Debug, Clone)] | |
36 | pub enum PrimType { | |
37 | Unit, | |
38 | Nat, | |
39 | } | |
40 | ||
41 | #[derive(Debug, Clone)] | |
42 | pub enum Expr { | |
43 | Var(Ident), | |
44 | Lit(Literal), | |
45 | Fn(Box<Pat>, Box<Expr>), | |
46 | App(Box<Expr>, Box<Expr>), | |
47 | Do(Vec<Stmt>), | |
48 | Tuple(Vec<Expr>), | |
49 | } | |
50 | ||
51 | #[derive(Debug, Clone)] | |
52 | pub enum Value { | |
53 | Closure(Pat, Expr, Box<Env>), | |
54 | Lit(Literal), | |
55 | Tuple(Vec<Value>), | |
56 | Unit, | |
57 | } | |
58 | ||
59 | #[derive(Debug, Clone)] | |
60 | pub enum Literal { | |
61 | Int(i64), | |
62 | } | |
63 | ||
64 | impl Expr { | |
65 | pub fn mk_fn(p: Pat, e: Expr) -> Expr { | |
66 | Expr::Fn(Box::new(p), Box::new(e)) | |
67 | } | |
68 | ||
69 | pub fn mk_app(e1: Expr, e2: Expr) -> Expr { | |
70 | Expr::App(Box::new(e1), Box::new(e2)) | |
71 | } | |
72 | ||
73 | pub fn mk_var<S: Into<String>>(s: S) -> Expr { | |
74 | Expr::Var(s.into()) | |
75 | } | |
76 | ||
77 | pub fn mk_tuple(es: Vec<Expr>) -> Expr { | |
78 | Expr::Tuple(es) | |
79 | } | |
80 | } |