-
Notifications
You must be signed in to change notification settings - Fork 13
XML: LLVM + Typecheck (by Michael Gavrilenko, Danila Rudnev-Stepanyan and Daniel Vlasenko) #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
b0c444e
80f65fb
cb31cd8
8683b63
8e348d2
06625e3
74523e6
0ea7b05
e294d1a
2b3b228
b155c97
286e602
30411de
167f474
0b763bb
a447f33
990b036
d613e88
e14ef5f
f15595d
76b14fe
09122f3
5b7173c
6831a8d
1a86cf5
eaca60b
0489455
d9d21f2
42842b5
3f8b5e9
bd23da8
5ffceca
66e5f73
0a0e58a
bfff819
edc2623
28e60c7
ade1b8f
e142472
711b546
b9b6727
94f88b6
3c317cc
4eab432
ea6d35c
fde97ef
3ecc3e9
0421c39
d2f5aa4
dc019fa
90dd64f
2994f33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,3 +5,4 @@ | |
| *.o | ||
| *.out | ||
| *.exe | ||
| *.ll | ||
| 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 *) |
| 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 | ||
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable from_file_name : string option | ||
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable output_file_name : string option | ||
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable optimization_lvl : string option | ||
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable target : string | ||
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable show_ast : bool | ||
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable show_anf : bool | ||
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable show_cc : bool | ||
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable show_ll : bool | ||
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
spisladqo marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable check_types : bool | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| ; mutable show_types : bool | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| } | ||
|
|
||
| (* ------------------------------- *) | ||
| (* 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 | ||
| ;; | ||
| 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 *) |
Uh oh!
There was an error while loading. Please reload this page.