Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
b0c444e
feat: add skeleton for llvm codegen
spisladqo Jan 27, 2026
80f65fb
feat: add driver code for llvm, basic codegen
spisladqo Jan 28, 2026
cb31cd8
feat: can compile function decls with args and a little more
spisladqo Jan 31, 2026
8683b63
feat: allow nested let ... in, draft of gen_variable
spisladqo Jan 31, 2026
8e348d2
feat: support if then else
spisladqo Jan 31, 2026
06625e3
feat: add map to store types of declared functions
spisladqo Feb 2, 2026
74523e6
feat: now map also stores fvalues, made declarations easier
spisladqo Feb 2, 2026
0ea7b05
feat: add support for closures, draft of tuples
spisladqo Feb 2, 2026
e294d1a
feat: add partial application
spisladqo Feb 2, 2026
2b3b228
feat: add create_tuple_init fun, codegen tuples with it, fix types
spisladqo Feb 10, 2026
b155c97
fix: authors in dune-project
spisladqo Feb 10, 2026
286e602
feat: gen main, now all vars are inside main
spisladqo Feb 10, 2026
30411de
fix: capture free vars in cc
spisladqo Feb 10, 2026
167f474
fix: closure application
spisladqo Feb 10, 2026
0b763bb
fix: calls to void returning functions don't segfault anymore
spisladqo Feb 10, 2026
a447f33
feat: now can load tuple elements
spisladqo Feb 12, 2026
990b036
test: add cram tests for llvm codegen, fix cc and compiler warnings
spisladqo Feb 12, 2026
d613e88
fix: cast ptr to i64 when calling builtin, put return 0 in the END of…
spisladqo Feb 13, 2026
e14ef5f
fix: now ll lifts everything, it works!
spisladqo Feb 15, 2026
f15595d
fix: change error message
spisladqo Feb 15, 2026
76b14fe
feat: add ability to optimize llvm ir
spisladqo Feb 15, 2026
09122f3
feat: user can choose llvm target, rv64 by default
spisladqo Feb 15, 2026
5b7173c
chore: add *.ll to gitignore
spisladqo Feb 15, 2026
6831a8d
fix: tag ints in llvm
spisladqo Feb 15, 2026
1a86cf5
fix: alignment and wrong size in stores
spisladqo Feb 15, 2026
eaca60b
fix: rv_call in rt and panic msgs
spisladqo Feb 16, 2026
0489455
fix: many bugs in codegen_llvm, add gc_llvm tests, now all passes
spisladqo Feb 16, 2026
d9d21f2
Merge branch 'Kakadu:master' into feat/llvm
spisladqo Feb 16, 2026
42842b5
fix: remove unneeded module
spisladqo Feb 16, 2026
3f8b5e9
feat: added cram test showing llvm codegen options
spisladqo Feb 16, 2026
bd23da8
feat: remove trash
spisladqo Feb 16, 2026
5ffceca
fix: warnings
spisladqo Feb 16, 2026
66e5f73
fix: add clang-18 and llc-18 to deps
spisladqo Feb 16, 2026
0a0e58a
fix: error message
spisladqo Feb 16, 2026
bfff819
fix: zanuda warnings
spisladqo Feb 16, 2026
edc2623
feat: add naive typechecking
spisladqo Feb 24, 2026
28e60c7
feat: add skeleton for remy-based infer
spisladqo Feb 27, 2026
ade1b8f
feat: add more to infer_expr, add infer_pat and pp for types
spisladqo Feb 27, 2026
e142472
test: add some unit tests for infer_expr
spisladqo Feb 27, 2026
711b546
test: add tests for patterns, tests for exp_fun and exp_apply
spisladqo Feb 28, 2026
b9b6727
fix: recursion, very naughty typo
spisladqo Feb 28, 2026
94f88b6
feat: add infer for let nonrec with tests, improve fail messages
spisladqo Feb 28, 2026
3c317cc
feat: add fun to make test writing easier
spisladqo Feb 28, 2026
4eab432
feat: add support for let rec .. (and), bin operators, and add more t…
spisladqo Feb 28, 2026
ea6d35c
feat: add infer for match and function match exprs, and tests
spisladqo Mar 1, 2026
fde97ef
feat: add infer for str items and prog, fix generalization
spisladqo Mar 1, 2026
3ecc3e9
feat: add cram tests for infer, enhance pretty-print, fix numerous bugs
spisladqo Mar 2, 2026
0421c39
feat: move new types to ast, add infer for typed pats/exprs, delete p…
spisladqo Mar 2, 2026
d2f5aa4
feat: add levels, generalization is sound now
spisladqo Mar 2, 2026
dc019fa
feat: monadic errors in infer, finally no failwith
spisladqo Mar 3, 2026
90dd64f
feat: update call to infer from driver code
spisladqo Mar 3, 2026
2994f33
test: add some tests
spisladqo Mar 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions XML/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
*.o
*.out
*.exe
*.ll
10 changes: 6 additions & 4 deletions XML/XML.opam
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "A short LLVM demo"
maintainer: ["Mikhail Gavrilenko" "Danila Rudnev-Stepanyan"]
authors: ["Mikhail Gavrilenko" "Danila Rudnev-Stepanyan"]
synopsis: "A small ML compiler"
maintainer: [
"Mikhail Gavrilenko" "Danila Rudnev-Stepanyan" "Daniel Vlasenko"
]
authors: ["Mikhail Gavrilenko" "Danila Rudnev-Stepanyan" "Daniel Vlasenko"]
license: "LGPL-3.0-or-later WITH OCaml-LGPL-linking-exception"
homepage: "https://github.com/Kakadu/comp24"
bug-reports: "https://github.com/Kakadu/comp24/issues"
Expand Down Expand Up @@ -33,7 +35,7 @@ build: [
]
dev-repo: "git+https://github.com/Kakadu/comp24.git"
depexts: [
[ "llvm-18-dev" "clang-18" "gcc-riscv64-linux-gnu" "g++-riscv64-linux-gnu" "qemu-user"] {os-distribution = "ubuntu"}
[ "llvm-18-dev" "clang-18" "llc-18" "gcc-riscv64-linux-gnu" "g++-riscv64-linux-gnu" "qemu-user"] {os-distribution = "ubuntu"}
]
pin-depends: [
["ppx_deriving_qcheck.0.6" "git+https://github.com/c-cube/qcheck.git#42429bf06ba12373cad02b1404f50d0ad6238af5"]
Expand Down
2 changes: 1 addition & 1 deletion XML/XML.opam.template
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
depexts: [
[ "llvm-18-dev" "clang-18" "gcc-riscv64-linux-gnu" "g++-riscv64-linux-gnu" "qemu-user"] {os-distribution = "ubuntu"}
[ "llvm-18-dev" "clang-18" "llc-18" "gcc-riscv64-linux-gnu" "g++-riscv64-linux-gnu" "qemu-user"] {os-distribution = "ubuntu"}
]
pin-depends: [
["ppx_deriving_qcheck.0.6" "git+https://github.com/c-cube/qcheck.git#42429bf06ba12373cad02b1404f50d0ad6238af5"]
Expand Down
24 changes: 23 additions & 1 deletion XML/bin/XML.ml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
(** Copyright 2024-2025, Mikhail Gavrilenko,Danila Rudnev-Stepanyan, Daniel Vlasenko *)
(** Copyright 2025-2026, Mikhail Gavrilenko,Danila Rudnev-Stepanyan, Daniel Vlasenko *)

(** SPDX-License-Identifier: LGPL-3.0-or-later *)

open Format
open Common.Pprinter

(* ------------------------------- *)
(* Command-line Options *)
Expand All @@ -17,6 +18,8 @@ type options =
; mutable show_cc : bool
; mutable show_ll : bool
; mutable gc_stats : bool
; mutable check_types : bool
; mutable show_types : bool
}

(* ------------------------------- *)
Expand All @@ -36,6 +39,17 @@ let to_asm ~gc_stats ast : string =

let compile_and_write options source_code =
let ast = Common.Parser.parse_str source_code in
(if options.check_types
then
let open Middleend.Infer in
match infer_program env_with_things ast with
| Ok (env, names) ->
if options.show_types
then (
pprint_env env names;
exit 0)
else ()
| Error err -> Format.printf "Type error: %a\n" Middleend.Infer.pprint_err err);
if options.show_ast
then (
printf "%a\n" Common.Pprinter.pprint_program ast;
Expand Down Expand Up @@ -106,6 +120,8 @@ let () =
; show_cc = false
; show_ll = false
; gc_stats = false
; check_types = true
; show_types = false
}
in
let usage_msg =
Expand Down Expand Up @@ -136,6 +152,12 @@ let () =
; ( "--gc-stats"
, Arg.Unit (fun () -> options.gc_stats <- true)
, " Enable GC statistics and force a collection at program start/end" )
; ( "-notypes"
, Arg.Unit (fun () -> options.check_types <- false)
, " Do not typecheck the program before compilation" )
; ( "-typedtree"
, Arg.Unit (fun () -> options.show_types <- true)
, " Show all names with their types and exit" )
]
in
let handle_anon_arg filename =
Expand Down
3 changes: 3 additions & 0 deletions XML/bin/XML.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(** Copyright 2025-2026, Mikhail Gavrilenko,Danila Rudnev-Stepanyan, Daniel Vlasenko *)

(** SPDX-License-Identifier: LGPL-3.0-or-later *)
187 changes: 187 additions & 0 deletions XML/bin/XML_llvm.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
(** Copyright 2025-2026, Mikhail Gavrilenko,Danila Rudnev-Stepanyan, Daniel Vlasenko *)

(** SPDX-License-Identifier: LGPL-3.0-or-later *)

open Format
open Common.Pprinter

(* ------------------------------- *)
(* Command-line Options *)
(* ------------------------------- *)

type options =
{ mutable input_file_name : string option
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable from_file_name : string option
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable output_file_name : string option
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable optimization_lvl : string option
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable target : string
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable show_ast : bool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable show_anf : bool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable show_cc : bool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable show_ll : bool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable check_types : bool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

; mutable show_types : bool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mutable data structures for teaching purposes is usually discouraged. Replace Hashtables by standard tree-like maps or consider Hash-Array Mapped Tries (HAMT). Use mutable references and mutable structure fields only if it is really required. In all places where it is needed indeed, describe in a comment why it is needed there.

}

(* ------------------------------- *)
(* Compiler Entry Points *)
(* ------------------------------- *)

let to_llvm_ir ast options =
let cc_program = Middleend.Cc.cc_program ast in
let anf_ast = Middleend.Anf.anf_program cc_program in
let ll_anf = Middleend.Ll.lambda_lift_program anf_ast in
(* let buf = Buffer.create 1024 in
let ppf = formatter_of_buffer buf in *)
(* let triple = "x86_64-pc-linux-gnu" in *)
let target = options.target in
let opt = options.optimization_lvl in
Backend.Codegen_llvm.gen_program_ir ll_anf target opt
;;

let compile_and_write options source_code =
let ast = Common.Parser.parse_str source_code in
(if options.check_types
then
let open Middleend.Infer in
match infer_program env_with_things ast with
| Ok (env, names) ->
if options.show_types
then (
pprint_env env names;
exit 0)
else ()
| Error err -> Format.printf "Type error: %a\n" Middleend.Infer.pprint_err err);
if options.show_ast
then (
(* printf "%a\n" Common.Pprinter.pprint_program ast; *)
printf "%s\n" (Common.Ast.show_program ast);
exit 0);
let cc_ast = Middleend.Cc.cc_program ast in
if options.show_cc
then (
printf "%a\n" Common.Pprinter.pprint_program cc_ast;
exit 0);
let anf_ast = Middleend.Anf.anf_program cc_ast in
if options.show_anf
then (
Middleend.Pprinter.print_anf_program std_formatter anf_ast;
exit 0);
let anf_after_ll = Middleend.Ll.lambda_lift_program anf_ast in
if options.show_ll
then (
(* Middleend.Pprinter.print_anf_program std_formatter anf_after_ll; *)
printf "%s\n" (Middleend.Anf.show_aprogram anf_after_ll);
exit 0);
let llvm_ir_code = to_llvm_ir ast options in
match options.output_file_name with
| Some out_file ->
(try
let oc = open_out out_file in
output_string oc llvm_ir_code;
close_out oc
with
| Sys_error msg ->
eprintf "Error: Could not write to output file '%s': %s\n" out_file msg;
exit 1)
| None -> print_string llvm_ir_code
;;

let read_channel_to_string ic =
let buf = Buffer.create 1024 in
try
while true do
Buffer.add_string buf (input_line ic ^ "\n")
done;
"" (* Недостижимо *)
with
| End_of_file -> Buffer.contents buf
;;

let read_file path =
try
let ch = open_in path in
let s = really_input_string ch (in_channel_length ch) in
close_in ch;
s
with
| Sys_error msg ->
eprintf "Error: Could not read input file '%s': %s\n" path msg;
exit 1
;;

(* ------------------------------- *)
(* Main Driver *)
(* ------------------------------- *)

let () =
let options =
{ input_file_name = None
; from_file_name = None
; output_file_name = None
; show_ast = false
; show_anf = false
; show_cc = false
; show_ll = false
; optimization_lvl = None
; target = "riscv64-unknown-linux-gnu"
; check_types = true
; show_types = false
}
in
let usage_msg =
"MiniML Compiler\n\n"
^ "Usage: dune exec ./bin/compile.exe -- <options> [input_file.ml]\n"
^ "If no input file is provided, reads from standard input.\n\n"
^ "Options:"
in
let arg_specs =
[ ( "-o"
, Arg.String (fun fname -> options.output_file_name <- Some fname)
, " <file> Set the output file name for the llvm ir code" )
; ( "--ast"
, Arg.Unit (fun () -> options.show_ast <- true)
, " Show the parsed Abstract Syntax Tree and exit" )
; ( "--anf"
, Arg.Unit (fun () -> options.show_anf <- true)
, " Show the ANF representation and exit" )
; ( "--cc"
, Arg.Unit (fun () -> options.show_cc <- true)
, " Show the representation after applying CC and exit" )
; ( "-fromfile"
, Arg.String (fun fname -> options.from_file_name <- Some fname)
, " <file> Read source from file (preferred over positional arg)" )
; ( "--ll"
, Arg.Unit (fun () -> options.show_ll <- true)
, " Show ANF after lambda lifting and exit" )
; ( "-O"
, Arg.String (fun opt -> options.optimization_lvl <- Some opt)
, " Set IR optimization level, \"O0\" by default" )
; ( "-t"
, Arg.String (fun targ -> options.target <- targ)
, " Set target platform, \"riscv64-unknown-linux-gnu\" by default" )
; ( "-notypes"
, Arg.Unit (fun () -> options.check_types <- false)
, " Do not typecheck the program before compilation" )
; ( "-typedtree"
, Arg.Unit (fun () -> options.show_types <- true)
, " Show all names with their types and exit" )
]
in
let handle_anon_arg filename =
match options.input_file_name with
| None -> options.input_file_name <- Some filename
| Some _ ->
eprintf "Error: Only one input file is allowed.\n";
Arg.usage arg_specs usage_msg;
exit 1
in
Arg.parse arg_specs handle_anon_arg usage_msg;
let source_code =
match options.from_file_name, options.input_file_name with
| Some path, _ -> read_file path
| None, Some path -> read_file path
| None, None -> read_channel_to_string stdin
in
compile_and_write options source_code
;;
3 changes: 3 additions & 0 deletions XML/bin/XML_llvm.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(** Copyright 2025-2026, Mikhail Gavrilenko,Danila Rudnev-Stepanyan, Daniel Vlasenko *)

(** SPDX-License-Identifier: LGPL-3.0-or-later *)
5 changes: 5 additions & 0 deletions XML/bin/dune
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
(public_name XML)
(name XML)
(libraries XML.Backend XML.Common XML.Middleend))

(executable
(public_name XML_llvm)
(name XML_llvm)
(libraries XML.Backend XML.Common XML.Middleend))
Loading
Loading