Skip to content

Commit 0390e4b

Browse files
DmitryPilyukRozhkovAleksandrKakadu
authored
[D] (E) FML: Middleend + LLVM (#105)
* make beta-ast in pattern_elim * Add Pe Ast * fix * fix pe * fix pe (unit pattern) * add monade for pe * fix again * Add new manytests * Fix problem with PNill * pe fix(ast trouble) * add monade * add alpha converter * Closure converdion * add ll beta version * fix bugs * oops * fix bug with fack * Fix lint problem * Add mli files * Fix format * Update tests * WIP ANF * anf barely * Anf runner * fix ll let * Some fixes * Fix alpha convertion * Improve anf runner * Fix LL * Init llvm module * add llvm dune and binops * WIP compiler of cexpr * Add compilation of if then else * fix maybe * Add runner * fixes * Add exec tests * fix type * Fix exception * Fix apply * fix all bugs * add some tests * clean code * Improve not partial apply * Fix double ret in main * fix identifiers * fix anf inference * Typechecker fails Signed-off-by: Kakadu <Kakadu@pm.me> * Fix type of tuple_element func * Rework alpha_conv * add a little for me * feat: semi-live version match elimination * fix: tuple conv * fix match (add check bindinings for cons, clever comb and more * fix middle ast * Format me_elim and add tests * Add tests * fix hard patterns decl * fix bug in tuple * fix * feat: add somes in lambda lift * add handle for LL. feat for efun and elet ll * delete old * clean code (monade add in common) * Closure conversion fix * rename fail and fix ll (bultins problem) * fix case with _ in match * fix handle for func first class in LL * fix bugs * wip anf * fix ast * anf done * fix based value * Improve LL * Update tests * Add type inference to anf tests * Format * better * fix bug with getting tuple in efun * Fix order of args * fix list pattern in me * Fix linter warnings * Fixes * New runtime * Codegen * Codegen in work * fixes * Add mli * Why compiler crashes? Signed-off-by: Kakadu <Kakadu@pm.me> * Add apply_args and new_closure names in builtins * Fixes CI issue due to manytests directory change * Rename x013.ml --------- Signed-off-by: Kakadu <Kakadu@pm.me> Co-authored-by: RozhkovAleksandr <rozhkov_a@outlook.com> Co-authored-by: Kakadu <Kakadu@pm.me>
1 parent 61f0faa commit 0390e4b

44 files changed

Lines changed: 6087 additions & 24 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

FML/bin/bitecode.t

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
$ ./compiler.exe < manytests/typed/001fac.ml
2+
$ cat < out.ll
3+
; ModuleID = 'FML'
4+
source_filename = "FML"
5+
target triple = "x86_64-pc-linux-gnu"
6+
7+
declare i64 @new_closure(i64, i64)
8+
9+
declare i64 @apply_args(i64, i64, i64, ...)
10+
11+
declare i64 @print_int(i64)
12+
13+
declare i64 @rt_add(i64, i64)
14+
15+
declare i64 @rt_sub(i64, i64)
16+
17+
declare i64 @rt_mul(i64, i64)
18+
19+
declare i64 @rt_div(i64, i64)
20+
21+
declare i64 @rt_leq(i64, i64)
22+
23+
declare i64 @rt_less(i64, i64)
24+
25+
declare i64 @rt_geq(i64, i64)
26+
27+
declare i64 @rt_gre(i64, i64)
28+
29+
declare i64 @rt_eq(i64, i64)
30+
31+
declare i64 @rt_neq(i64, i64)
32+
33+
declare i64 @rt_and(i64, i64)
34+
35+
declare i64 @rt_or(i64, i64)
36+
37+
declare i64 @fail_match(i64)
38+
39+
define i64 @fac(i64 %n) {
40+
entry:
41+
%sle = icmp sle i64 %n, 1
42+
%sle_i64t = zext i1 %sle to i64
43+
%cond_v = icmp ne i64 %sle_i64t, 0
44+
br i1 %cond_v, label %then, label %else
45+
46+
then: ; preds = %entry
47+
br label %merge
48+
49+
else: ; preds = %entry
50+
%sub = sub i64 %n, 1
51+
%call = call i64 @fac(i64 %sub)
52+
%mul = mul i64 %n, %call
53+
br label %merge
54+
55+
merge: ; preds = %else, %then
56+
%phi = phi i64 [ 1, %then ], [ %mul, %else ]
57+
ret i64 %phi
58+
}
59+
60+
define i64 @main() {
61+
entry:
62+
%call = call i64 @fac(i64 4)
63+
%call1 = call i64 @print_int(i64 %call)
64+
ret i64 0
65+
}
66+
67+
$ ./compiler.exe < manytests/typed/002fac.ml
68+
$ cat < out.ll
69+
; ModuleID = 'FML'
70+
source_filename = "FML"
71+
target triple = "x86_64-pc-linux-gnu"
72+
73+
declare i64 @new_closure(i64, i64)
74+
75+
declare i64 @apply_args(i64, i64, i64, ...)
76+
77+
declare i64 @print_int(i64)
78+
79+
declare i64 @rt_add(i64, i64)
80+
81+
declare i64 @rt_sub(i64, i64)
82+
83+
declare i64 @rt_mul(i64, i64)
84+
85+
declare i64 @rt_div(i64, i64)
86+
87+
declare i64 @rt_leq(i64, i64)
88+
89+
declare i64 @rt_less(i64, i64)
90+
91+
declare i64 @rt_geq(i64, i64)
92+
93+
declare i64 @rt_gre(i64, i64)
94+
95+
declare i64 @rt_eq(i64, i64)
96+
97+
declare i64 @rt_neq(i64, i64)
98+
99+
declare i64 @rt_and(i64, i64)
100+
101+
declare i64 @rt_or(i64, i64)
102+
103+
declare i64 @fail_match(i64)
104+
105+
define i64 @lam_ll0(i64 %k, i64 %n, i64 %p) {
106+
entry:
107+
%mul = mul i64 %p, %n
108+
%applied_closure = call i64 (i64, i64, ...) @apply_args(i64 %k, i64 1, i64 %mul)
109+
ret i64 %applied_closure
110+
}
111+
112+
define i64 @fac_cps(i64 %n, i64 %k) {
113+
entry:
114+
%eq = icmp eq i64 %n, 1
115+
%eq_i64t = zext i1 %eq to i64
116+
%cond_v = icmp ne i64 %eq_i64t, 0
117+
br i1 %cond_v, label %then, label %else
118+
119+
then: ; preds = %entry
120+
%applied_closure = call i64 (i64, i64, ...) @apply_args(i64 %k, i64 1, i64 1)
121+
br label %merge
122+
123+
else: ; preds = %entry
124+
%empty_closure = call i64 @new_closure(i64 ptrtoint (ptr @lam_ll0 to i64), i64 3)
125+
%applied_closure1 = call i64 (i64, i64, ...) @apply_args(i64 %empty_closure, i64 2, i64 %k, i64 %n)
126+
%sub = sub i64 %n, 1
127+
%call = call i64 @fac_cps(i64 %sub, i64 %applied_closure1)
128+
br label %merge
129+
130+
merge: ; preds = %else, %then
131+
%phi = phi i64 [ %applied_closure, %then ], [ %call, %else ]
132+
ret i64 %phi
133+
}
134+
135+
define i64 @lam_ll1(i64 %print_int_ac0) {
136+
entry:
137+
ret i64 %print_int_ac0
138+
}
139+
140+
define i64 @main() {
141+
entry:
142+
%empty_closure = call i64 @new_closure(i64 ptrtoint (ptr @lam_ll1 to i64), i64 1)
143+
%call = call i64 @fac_cps(i64 4, i64 %empty_closure)
144+
%call1 = call i64 @print_int(i64 %call)
145+
ret i64 0
146+
}

FML/bin/compiler.ml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
(** Copyright 2024-2025, Dmitry Pilyuk, Aleksandr Rozhkov *)
2+
3+
(** SPDX-License-Identifier: LGPL-2.1 *)
4+
5+
open Fml_lib
6+
7+
let () =
8+
let input = Stdio.In_channel.input_all Stdlib.stdin in
9+
let parse_and_infer input =
10+
match Parser.parse input with
11+
| Ok parsed ->
12+
(match Inferencer.run_program_inferencer parsed with
13+
| Ok types -> Ok (parsed, types)
14+
| Error _ -> Error (Format.asprintf "Infer error:"))
15+
| Error e -> Error (Format.sprintf "Parsing error: %s" e)
16+
in
17+
match parse_and_infer input with
18+
| Ok (ast, _) ->
19+
let ast = A_conv.ac_program ast in
20+
let ast_me = Match_elimination.match_elimination ast in
21+
let ast_cc = C_conv.cc_program ast_me in
22+
let ast_ll = Lambda_lift.lambda_lift ast_cc in
23+
let ast_anf = Anf.anf ast_ll in
24+
Codegen.compile_program ast_anf
25+
| Error message -> Format.printf "%s" message
26+
;;

FML/bin/dune

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
(executable
2+
(name compiler)
3+
(public_name compliler)
4+
(modules compiler)
5+
(libraries fml_lib stdio))
6+
7+
(cram
8+
(deps ./x013.ml_test.txt))
9+
10+
(cram
11+
(applies_to bitecode)
12+
(deps
13+
./compiler.exe
14+
manytests/do_not_type/001.ml
15+
manytests/do_not_type/002if.ml
16+
manytests/do_not_type/003occurs.ml
17+
manytests/do_not_type/004let_poly.ml
18+
manytests/do_not_type/015tuples.ml
19+
manytests/typed/001fac.ml
20+
manytests/typed/002fac.ml
21+
manytests/typed/003fib.ml
22+
manytests/typed/004manyargs.ml
23+
manytests/typed/005fix.ml
24+
manytests/typed/006partial.ml
25+
manytests/typed/006partial2.ml
26+
manytests/typed/006partial3.ml
27+
manytests/typed/007order.ml
28+
manytests/typed/008ascription.ml
29+
manytests/typed/009let_poly.ml
30+
manytests/typed/011mapcps.ml
31+
manytests/typed/012fibcps.ml
32+
manytests/typed/013foldfoldr.ml
33+
manytests/typed/015tuples.ml
34+
manytests/typed/016lists.ml))
35+
36+
(cram
37+
(applies_to llvm_exec)
38+
(deps
39+
./compiler.exe
40+
../lib/llvm/runtime.o
41+
manytests/do_not_type/001.ml
42+
manytests/do_not_type/002if.ml
43+
manytests/do_not_type/003occurs.ml
44+
manytests/do_not_type/004let_poly.ml
45+
manytests/do_not_type/015tuples.ml
46+
manytests/typed/001fac.ml
47+
manytests/typed/002fac.ml
48+
manytests/typed/003fib.ml
49+
manytests/typed/004manyargs.ml
50+
manytests/typed/005fix.ml
51+
manytests/typed/006partial.ml
52+
manytests/typed/006partial2.ml
53+
manytests/typed/006partial3.ml
54+
manytests/typed/007order.ml
55+
manytests/typed/008ascription.ml
56+
manytests/typed/009let_poly.ml
57+
manytests/typed/011mapcps.ml
58+
manytests/typed/012fibcps.ml
59+
; manytests/typed/x013.ml
60+
manytests/typed/013foldfoldr.ml
61+
manytests/typed/015tuples.ml
62+
manytests/typed/016lists.ml))

FML/bin/llvm_exec.t

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
$ ./compiler.exe < manytests/typed/001fac.ml
2+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 001fac
3+
$ ./001fac
4+
24
5+
6+
$ ./compiler.exe < manytests/typed/002fac.ml
7+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 002fac
8+
$ ./002fac
9+
24
10+
11+
$ ./compiler.exe < manytests/typed/003fib.ml
12+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 003fib
13+
$ ./003fib
14+
33
15+
16+
$ ./compiler.exe < manytests/typed/004manyargs.ml
17+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 004manyargs
18+
$ ./004manyargs
19+
1111111111110100
20+
21+
$ ./compiler.exe < manytests/typed/005fix.ml
22+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 005fix
23+
$ ./005fix
24+
720
25+
26+
$ ./compiler.exe < manytests/typed/006partial.ml
27+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 006partial
28+
$ ./006partial
29+
1122
30+
31+
$ ./compiler.exe < manytests/typed/006partial2.ml
32+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 006partial2
33+
$ ./006partial2
34+
1237
35+
36+
$ ./compiler.exe < manytests/typed/006partial3.ml
37+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 006partial3
38+
$ ./006partial3
39+
489
40+
41+
$ ./compiler.exe < manytests/typed/007order.ml
42+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 007order
43+
$ ./007order
44+
-1421103-55555510000
45+
46+
$ ./compiler.exe < manytests/typed/008ascription.ml
47+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 008ascription
48+
$ ./008ascription
49+
8
50+
51+
$ ./compiler.exe < manytests/typed/012fibcps.ml
52+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 012fibcps && rm out.ll
53+
$ ./012fibcps && rm -f out.ll
54+
8
55+
56+
$ ls manytests/typed
57+
$ ocaml -w -26 ./x013.ml_test.txt
58+
1111111111
59+
60+
$ ./compiler.exe < ./x013.ml_test.txt
61+
$ clang-16 out.ll ../lib/llvm/runtime.o -lffi -o 013
62+
$ ./013
63+
1111111111
64+
65+

FML/bin/manytests

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../manytests

FML/bin/x013.ml_test.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
let wrap f = if 1 = 1 then f else f
2+
3+
let test3 a b c =
4+
let a = print_int a in
5+
let b = print_int b in
6+
let c = print_int c in
7+
0
8+
9+
let apply_args a b c d e f g h i j = a + b + c + d + e + f + g + h + i + j
10+
11+
let main =
12+
let rez =
13+
(wrap apply_args 1 10 100 1000 10000 100000 1000000 10000000 100000000
14+
1000000000)
15+
in
16+
let () = print_int rez in
17+
0
18+

0 commit comments

Comments
 (0)