gdritter repos picoml / c4e5afe
Split apart modules Getty Ritter 5 years ago
3 changed file(s) with 204 addition(s) and 188 deletion(s). Collapse all Expand all
11 use std::collections::HashMap;
22
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;
307
318 impl Stmt {
329 fn eval(&self, env: &mut Env) -> Result<Value, String> {
3613 p.bind(e.eval(env)?, env);
3714 Ok(Value::Unit)
3815 },
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 }
6316 }
6417 }
6518 }
8639 }
8740 }
8841
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 }
19142 }
19243
19344 impl Expr {
23283 }
23384 }
23485
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
27086 }
27187
27288 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 }