| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | #pragma once
 | 
					
						
							|  |  |  | #include <memory>
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2019-05-27 21:51:39 -07:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | typedef std::vector<std::string> dot; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | enum class binop { | 
					
						
							|  |  |  |     plus, | 
					
						
							|  |  |  |     minus, | 
					
						
							|  |  |  |     times, | 
					
						
							|  |  |  |     divide, | 
					
						
							|  |  |  |     land, | 
					
						
							|  |  |  |     lor, | 
					
						
							|  |  |  |     eq, | 
					
						
							|  |  |  |     neq, | 
					
						
							|  |  |  |     lt, | 
					
						
							|  |  |  |     lte, | 
					
						
							|  |  |  |     gt, | 
					
						
							|  |  |  |     gte | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum class unop { | 
					
						
							|  |  |  |     lnot | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct expr { | 
					
						
							|  |  |  |     virtual ~expr() = default; | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  |      | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix) = 0; | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 11:12:53 -07:00
										 |  |  | typedef expr* expr_ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct expr_id : expr { | 
					
						
							|  |  |  |     std::string id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expr_id(std::string i) : | 
					
						
							|  |  |  |         id(std::move(i)) {} | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:12:53 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct expr_int : expr { | 
					
						
							|  |  |  |     int val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expr_int(int i) : val(i) {} | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:12:53 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct expr_float : expr { | 
					
						
							|  |  |  |     double val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expr_float(double f) : val(f) {} | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:12:53 -07:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct expr_binop : expr { | 
					
						
							|  |  |  |     binop op; | 
					
						
							|  |  |  |     expr_ptr left; | 
					
						
							|  |  |  |     expr_ptr right; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expr_binop(binop nop, expr_ptr l, expr_ptr r) : | 
					
						
							|  |  |  |         op(nop), left(std::move(l)), right(std::move(r)) {} | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct expr_unop : expr { | 
					
						
							|  |  |  |     unop op; | 
					
						
							|  |  |  |     expr_ptr child; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expr_unop(unop nop, expr_ptr c) : | 
					
						
							|  |  |  |         op(nop), child(std::move(c)) {} | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct expr_assign : expr { | 
					
						
							|  |  |  |     std::string var; | 
					
						
							|  |  |  |     expr_ptr child; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expr_assign(std::string v, expr_ptr c) : | 
					
						
							|  |  |  |         var(std::move(v)), child(std::move(c)) {} | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename T, typename ... Ts> | 
					
						
							|  |  |  | expr_ptr make_expr(Ts&& ... ts) { | 
					
						
							|  |  |  |     return expr_ptr(new T(std::move(ts)...)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct stmt { | 
					
						
							|  |  |  |     virtual ~stmt() = default; | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix) = 0; | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 11:12:53 -07:00
										 |  |  | typedef stmt* stmt_ptr; | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct stmt_block : stmt { | 
					
						
							|  |  |  |     std::vector<stmt_ptr> children; | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct stmt_if : stmt { | 
					
						
							|  |  |  |     expr_ptr cond; | 
					
						
							|  |  |  |     stmt_ptr then; | 
					
						
							|  |  |  |     stmt_ptr els; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     stmt_if(expr_ptr c, stmt_ptr t, stmt_ptr e = nullptr) : | 
					
						
							|  |  |  |         cond(std::move(c)), then(std::move(t)), els(std::move(e)) {} | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct stmt_while : stmt { | 
					
						
							|  |  |  |     expr_ptr cond; | 
					
						
							|  |  |  |     stmt_ptr body; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 11:12:53 -07:00
										 |  |  |     stmt_while(expr_ptr c, stmt_ptr b) : | 
					
						
							|  |  |  |         cond(std::move(c)), body(std::move(b)) {} | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct stmt_break : stmt { | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 11:12:53 -07:00
										 |  |  | struct stmt_expr : stmt { | 
					
						
							|  |  |  |     expr_ptr child; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     stmt_expr(expr_ptr c) : | 
					
						
							|  |  |  |         child(std::move(c)) {} | 
					
						
							| 
									
										
										
										
											2019-05-20 13:28:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual void print_dot(dot& into, std::string prefix); | 
					
						
							| 
									
										
										
										
											2019-05-20 11:12:53 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-20 09:48:37 -07:00
										 |  |  | template <typename T, typename ... Ts> | 
					
						
							|  |  |  | stmt_ptr make_stmt(Ts&& ... ts) { | 
					
						
							|  |  |  |     return stmt_ptr(new T(std::move(ts)...)); | 
					
						
							|  |  |  | } |