-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoProlog.ml
189 lines (173 loc) · 5.2 KB
/
toProlog.ml
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
open Ast
let rec print_prolog e =
match e with
| ASTNum(n) -> Printf.printf "%d" n
| ASTBool(b) -> Printf.printf "%b" b
| ASTId(id) -> Printf.printf "\"%s\"" id
| ASTNot(e) -> print_string "not("; print_prolog e; print_string ")"
| ASTAlloc(e) -> print_string "alloc("; print_prolog e; print_char ')'
| ASTNth(e1, e2) -> print_string "nth("; print_prolog e1; print_string ", ";
print_prolog e2; print_char ')'
| ASTLen(e) -> print_string "len("; print_prolog e; print_char ')'
| ASTIf(cond, cons, alt) -> print_if cond cons alt
| ASTPrim(op, e1, e2) -> print_prim op e1 e2
| ASTApplication(first, next) -> print_application first next;
| ASTAbs(args, expr) -> print_abs args expr
and print_prim op e1 e2 =
Printf.printf "%s(" (string_of_op op);
print_prolog e1;
Printf.printf ", ";
print_prolog e2;
Printf.printf ")"
and print_if cond cons alt =
Printf.printf "if(";
print_prolog cond;
Printf.printf ", ";
print_prolog cons;
Printf.printf ", ";
print_prolog alt;
Printf.printf ")"
and print_exprs e =
let rec print_exprs_rec exprs =
match exprs with
[h] -> print_prolog h
| h::t -> print_prolog h; print_string ", "; print_exprs t;
| _ -> ()
in
print_char '[';
print_exprs_rec e;
print_char ']'
and print_application func args =
let rec print_args args =
match args with
[h] -> print_prolog h
| h::t -> print_prolog h; print_string ", "; print_args t;
| _ -> ()
in
print_string "app(";
print_prolog func;
print_string ", [";
print_args args;
print_string "])"
and print_type t =
match t with
| Int -> print_string "int"
| Bool -> print_string "bool"
| Void -> print_string "void"
| ArrowType(h, t) ->
print_string "arrow(";
print_types h;
print_string ", ";
print_type t;
print_string ")"
| Vec(t) -> print_string "vec("; print_type t; print_char ')'
and print_types t =
let rec print_types_rec types =
match types with
[h] -> print_type h
| h::t -> print_type h; print_string ", "; print_types_rec t
| [] -> ()
in
print_string "[";
print_types_rec t;
print_string "]"
and print_arg a =
let Arg(ident, t) = a in
print_string "(\"";
print_string ident;
print_string "\", ";
print_type t;
print_string ")"
and print_args args =
print_char '[';
let rec print_args_rec args =
match args with
| [h] -> print_arg h;
| h::t -> print_arg h; print_string ", "; print_args_rec t
| _ -> ()
in
print_args_rec args;
print_char ']'
and print_abs a e =
print_string "abs(";
print_args a;
print_string ", ";
print_prolog e;
print_string ")"
and print_dec d =
match d with
| Const(id, t, e) -> Printf.printf "const(\"%s\", " id;
print_type t;
print_string ", ";
print_prolog e;
print_char ')'
| Fun(id, t, a, e) -> Printf.printf "fun(\"%s\", " id;
print_type (fun_type t a);
print_string ", ";
print_args a;
print_string ", ";
print_prolog e;
print_string ")"
| FunRec(id, t, a, e) -> Printf.printf "funRec(\"%s\", " id;
print_type (fun_type t a);
print_string ", ";
print_args a;
print_string ", ";
print_prolog e;
print_string ")"
| Var(id, t) -> Printf.printf "var(\"%s\", " id;
print_type t;
print_char ')'
| Proc(id, a, cmds) -> print_proc false id a cmds
| ProcRec(id, a, cmds) -> print_proc true id a cmds
and print_proc r id args cmds =
if r then print_string "procRec" else print_string "proc";
Printf.printf "(\"%s\", " id;
print_args args;
print_string ", ";
print_commands cmds;
print_char ')'
and print_stat s =
match s with
Echo(e) -> print_string "echo("; print_prolog e; print_char ')'
| Set(e1, e2) -> Printf.printf "set(";
print_prolog e1;
print_string ", ";
print_prolog e2;
print_char ')'
| IfStat(expr, cons, alt) -> print_string "if(";
print_prolog expr;
print_string ", ";
print_commands cons;
print_string ", ";
print_commands alt;
print_char ')'
| While(expr, cmds) -> print_string "while(";
print_prolog expr;
print_string ", ";
print_commands cmds;
print_char ')'
| Call(id, exprs) -> Printf.printf "call(\"%s\", " id;
print_exprs exprs;
print_char ')'
and print_command c =
match c with
| StatCmd(s) -> print_stat s
| DecCmd(d) -> print_dec d
and print_commands c =
let rec print_commands_rec (c: Ast.cmd list) =
match c with
| [h] -> print_command h
| h::t -> print_command h; print_string ", "; print_commands_rec t
| _ -> ()
in
print_string "[";
print_commands_rec c;
print_string "]"
let () =
try
let lexbuf = Lexing.from_channel stdin in
let e = Parser.prog Lexer.token lexbuf in
print_commands e;
print_string ".\n"
with Lexer.Eof -> exit 0