Skip to content

Commit 870b1a8

Browse files
committed
Chapter 3: Code generation to LLVM IR.
Note: had to replace build_add with build_fadd, build_mul with build_fmul, etc. to get their example to work because the base versions expect ints, but we convert all our inputs to doubles
1 parent d23ead5 commit 870b1a8

File tree

4 files changed

+28
-16
lines changed

4 files changed

+28
-16
lines changed

_tags

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
"+llvm-2.8": include
12
<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
3+
<*.{byte,native}>: g++, use_llvm, use_llvm_analysis

parser.ml

+12-12
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,24 @@ let rec parse_primary = parser
3333
| [< >] -> accumulator
3434
in
3535
let rec parse_ident id = parser
36-
(* Call. *)
36+
(* Call. *)
3737
| [< 'Token.Kwd '(';
38-
args=parse_args [];
39-
'Token.Kwd ')' ?? "expected ')'">] ->
40-
Ast.Call (id, Array.of_list (List.rev args))
38+
args=parse_args [];
39+
'Token.Kwd ')' ?? "expected ')'">] ->
40+
Ast.Call (id, Array.of_list (List.rev args))
4141

42-
(* Simple variable ref. *)
42+
(* Simple variable ref. *)
4343
| [< >] -> Ast.Variable id
4444
in
45-
parse_ident id stream
45+
parse_ident id stream
4646

4747
| [< >] -> raise (Stream.Error "unknown token when expecting an expression.")
4848

4949
(* binoprhs
5050
* ::= ('+' primary)* *)
5151
and parse_bin_rhs expr_prec lhs stream =
5252
match Stream.peek stream with
53-
(* If this is a binop, find its precedence. *)
53+
(* If this is a binop, find its precedence. *)
5454
| Some (Token.Kwd c) when Hashtbl.mem binop_precedence c ->
5555
let token_prec = precedence c in
5656

@@ -97,9 +97,9 @@ let parse_prototype =
9797

9898
parser
9999
| [< 'Token.Ident id;
100-
'Token.Kwd '(' ?? "expected '(' in prototype";
101-
args=parse_args [];
102-
'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
100+
'Token.Kwd '(' ?? "expected '(' in prototype";
101+
args=parse_args [];
102+
'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
103103
(* success. *)
104104
Ast.Prototype (id, Array.of_list (List.rev args))
105105

@@ -109,13 +109,13 @@ let parse_prototype =
109109
(* definition ::= 'def' prototype expression *)
110110
let parse_definition = parser
111111
| [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
112-
Ast.Function (p, e)
112+
Ast.Function (p, e)
113113

114114
(* toplevelexpr ::= expression *)
115115
let parse_toplevel = parser
116116
| [< e=parse_expr >] ->
117117
(* Make an anonymous proto. *)
118-
Ast.Function (Ast.Prototype ("", [||]), e)
118+
Ast.Function (Ast.Prototype ("", [||]), e)
119119

120120
(* external ::= 'extern' prototype *)
121121
let parse_extern = parser

toplevel.ml

+9-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* Top-Level parsing and JIT Driver
33
*===----------------------------------------------------------------------===*)
44

5+
open Llvm
6+
57
(* top ::= definition | external | expression | ';' *)
68
let rec main_loop stream =
79
match Stream.peek stream with
@@ -16,16 +18,19 @@ let rec main_loop stream =
1618
begin
1719
try match token with
1820
| Token.Def ->
19-
ignore(Parser.parse_definition stream);
21+
let e = Parser.parse_definition stream in
2022
print_endline "parsed a function definition.";
23+
dump_value (Codegen.codegen_func e);
2124
| Token.Extern ->
22-
ignore(Parser.parse_extern stream);
25+
let e = Parser.parse_extern stream in
2326
print_endline "parsed an extern.";
27+
dump_value (Codegen.codegen_proto e);
2428
| _ ->
2529
(* Evaluate a top-level expression into an anonymous function. *)
26-
ignore(Parser.parse_toplevel stream);
30+
let e = Parser.parse_toplevel stream in
2731
print_endline "parsed a top-level expr";
28-
with Stream.Error s ->
32+
dump_value (Codegen.codegen_func e);
33+
with Stream.Error s | Codegen.Error s ->
2934
(* Skip token for error recovery. *)
3035
Stream.junk stream;
3136
print_endline s;

toy.ml

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Main driver code.
44
*===----------------------------------------------------------------------===*)
55

6+
open Llvm
7+
68
let main () =
79
(* Install standard binary operators.
810
* 1 is the lowest precedence. *)
@@ -17,6 +19,9 @@ let main () =
1719

1820
(* Run the main "interpreter loop" now. *)
1921
Toplevel.main_loop stream;
22+
23+
(* Print out all the generated code. *)
24+
dump_module Codegen.the_module
2025
;;
2126

2227
main ()

0 commit comments

Comments
 (0)