-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathast.ml
More file actions
133 lines (110 loc) · 3.81 KB
/
ast.ml
File metadata and controls
133 lines (110 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
(* AST for Philosopher's Code *)
type op = Add | Subtract | Multiply | Divide | And | Or | Greater | Lesser;;
type uop = Not;;
type primitive = Int_Decl;;
type expr =
| Literal of literal
| Id of string
| Call of string * expr list
| Binop of expr * op * expr
| Uniop of uop * expr
| Expr of expr
| Noexpr
and literal =
| Int_Lit of int
| Float_Lit of float
| Char_Lit of int
| String_Lit of string
| Bool_Lit of bool;;
type formal =
| Formal of string;;
type fun_decl =
{
func_name: string;
formals: formal list;
};;
type stmt =
| Expr of expr
| Block of stmt list
| SimpleStmt of simple_stmt
| CompoundStmt of compound_stmt
and simple_stmt =
| Reassign of string * expr
| Assign of string * expr
| Return of expr
| No_Print
and compound_stmt =
| If of expr * stmt * stmt
| DoWhile of stmt * expr;;
(* function definitions must be defined separately from statements because they must be generated outside the "main" method *)
type fun_def_stmt =
| Fun_Def_Stmt of fun_def
and fun_def =
| Fun_Def of fun_decl * stmt;;
type program = Program of fun_def_stmt list * stmt list;;
(*pretty-printing functions*)
let string_of_op = function
| Add -> "+"
| Subtract -> "-"
| Divide -> "/"
| Multiply -> "*"
| And -> "&&"
| Or -> "||"
| Greater -> ">"
| Lesser -> "<";;
let string_of_uop = function
| Not -> "!" ;;
let rec string_of_expr = function
(*| Expr(e) -> "(" ^ string_of_expr e ^ ")"*)
| Literal(e) -> (string_of_literal e)
| Binop(a, o, b) -> (string_of_expr a)^(string_of_op o)^(string_of_expr b)
| Uniop(uo, a) -> (string_of_uop uo) ^ (string_of_expr a)
| Id(s) -> s
| Call(f, el) -> (match f with
"aparecium" ->
"printf(\"%d\\n\", " ^ String.concat ", " (List.map string_of_expr el) ^")"
| "avis" -> "printf(\"%s\\n\", \"bird bird bird bird\")"
| _ -> f ^ "(" ^ String.concat ", " (List.map string_of_expr el) ^ ")")
| Noexpr -> ""
| _ -> "did not match"
and string_of_literal = function
| Int_Lit(i) -> string_of_int i
| Float_Lit(f) -> string_of_float f
| Char_Lit(c) -> string_of_int c
| String_Lit(s) -> s
| Bool_Lit(true) -> "1"
| Bool_Lit(false) -> "0" ;;
let rec string_of_stmt = function
| Expr(e) -> (string_of_expr e)^";"
| SimpleStmt(s) -> (string_of_simple_stmt s)
| CompoundStmt(s) -> (string_of_compound_stmt s)
| Block(sl) -> "{ "^(String.concat " " (List.map string_of_stmt sl)) ^" }\n"
and string_of_simple_stmt = function
| Assign(v, e) -> "int "^v^ " = " ^ string_of_expr e ^ ";"
| Reassign(v, e) -> v^" = " ^string_of_expr e ^ ";"
| Return(e) -> "return "^string_of_expr e ^";"
| No_Print -> "int noPrint;"
and string_of_compound_stmt = function
| If(e, s1, s2) ->
"if("^(string_of_expr e)^")\n "^(string_of_stmt s1)^" else "^(string_of_stmt s2)
| DoWhile(b, c) -> "do\n" ^string_of_stmt b ^ "while (" ^ string_of_expr c ^");\n"
let rec string_of_fun_def_stmt = function
| Fun_Def_Stmt(f) -> string_of_fun f
and string_of_fun = function
| Fun_Def(f, s) -> (string_of_fun_decl f) ^ (string_of_stmt s)
and string_of_fun_decl fd =
"int "^fd.func_name^"("^(string_of_formals_list fd.formals)^")\n"
and string_of_formals_list fl = String.concat ", " (List.map string_of_formal fl)
and string_of_formal = function
| Formal(f) -> "int "^ f;;
let rec string_of_program = function
| Program(fun_def_stmt_list, stmt_list) -> let result =
(String.concat "" (List.map string_of_fun_def_stmt fun_def_stmt_list) ^ "\n",
String.concat "" (List.map string_of_stmt stmt_list) ^ "\n")
in result;;
(*
let string_of_program ((fun_def_stmt_list: fun_def_stmt list), (stmt_list: stmt list)) = match Program(fun_def_stmt_list, stmt_list) with
| Program(fun_def_stmt_list, stmt_list) -> let result =
(String.concat "" (List.map string_of_fun_def_stmt fun_def_stmt_list) ^ "\n",
String.concat "" (List.map string_of_stmt stmt_list) ^ "\n")
in result;;*)