xref: /aosp_15_r20/external/llvm/docs/tutorial/OCamlLangImpl3.rst (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker========================================
2*9880d681SAndroid Build Coastguard WorkerKaleidoscope: Code generation to LLVM IR
3*9880d681SAndroid Build Coastguard Worker========================================
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker.. contents::
6*9880d681SAndroid Build Coastguard Worker   :local:
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard WorkerChapter 3 Introduction
9*9880d681SAndroid Build Coastguard Worker======================
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard WorkerWelcome to Chapter 3 of the "`Implementing a language with
12*9880d681SAndroid Build Coastguard WorkerLLVM <index.html>`_" tutorial. This chapter shows you how to transform
13*9880d681SAndroid Build Coastguard Workerthe `Abstract Syntax Tree <OCamlLangImpl2.html>`_, built in Chapter 2,
14*9880d681SAndroid Build Coastguard Workerinto LLVM IR. This will teach you a little bit about how LLVM does
15*9880d681SAndroid Build Coastguard Workerthings, as well as demonstrate how easy it is to use. It's much more
16*9880d681SAndroid Build Coastguard Workerwork to build a lexer and parser than it is to generate LLVM IR code. :)
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker**Please note**: the code in this chapter and later require LLVM 2.3 or
19*9880d681SAndroid Build Coastguard WorkerLLVM SVN to work. LLVM 2.2 and before will not work with it.
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard WorkerCode Generation Setup
22*9880d681SAndroid Build Coastguard Worker=====================
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard WorkerIn order to generate LLVM IR, we want some simple setup to get started.
25*9880d681SAndroid Build Coastguard WorkerFirst we define virtual code generation (codegen) methods in each AST
26*9880d681SAndroid Build Coastguard Workerclass:
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker    let rec codegen_expr = function
31*9880d681SAndroid Build Coastguard Worker      | Ast.Number n -> ...
32*9880d681SAndroid Build Coastguard Worker      | Ast.Variable name -> ...
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard WorkerThe ``Codegen.codegen_expr`` function says to emit IR for that AST node
35*9880d681SAndroid Build Coastguard Workeralong with all the things it depends on, and they all return an LLVM
36*9880d681SAndroid Build Coastguard WorkerValue object. "Value" is the class used to represent a "`Static Single
37*9880d681SAndroid Build Coastguard WorkerAssignment
38*9880d681SAndroid Build Coastguard Worker(SSA) <http://en.wikipedia.org/wiki/Static_single_assignment_form>`_
39*9880d681SAndroid Build Coastguard Workerregister" or "SSA value" in LLVM. The most distinct aspect of SSA values
40*9880d681SAndroid Build Coastguard Workeris that their value is computed as the related instruction executes, and
41*9880d681SAndroid Build Coastguard Workerit does not get a new value until (and if) the instruction re-executes.
42*9880d681SAndroid Build Coastguard WorkerIn other words, there is no way to "change" an SSA value. For more
43*9880d681SAndroid Build Coastguard Workerinformation, please read up on `Static Single
44*9880d681SAndroid Build Coastguard WorkerAssignment <http://en.wikipedia.org/wiki/Static_single_assignment_form>`_
45*9880d681SAndroid Build Coastguard Worker- the concepts are really quite natural once you grok them.
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard WorkerThe second thing we want is an "Error" exception like we used for the
48*9880d681SAndroid Build Coastguard Workerparser, which will be used to report errors found during code generation
49*9880d681SAndroid Build Coastguard Worker(for example, use of an undeclared parameter):
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker    exception Error of string
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker    let context = global_context ()
56*9880d681SAndroid Build Coastguard Worker    let the_module = create_module context "my cool jit"
57*9880d681SAndroid Build Coastguard Worker    let builder = builder context
58*9880d681SAndroid Build Coastguard Worker    let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
59*9880d681SAndroid Build Coastguard Worker    let double_type = double_type context
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard WorkerThe static variables will be used during code generation.
62*9880d681SAndroid Build Coastguard Worker``Codgen.the_module`` is the LLVM construct that contains all of the
63*9880d681SAndroid Build Coastguard Workerfunctions and global variables in a chunk of code. In many ways, it is
64*9880d681SAndroid Build Coastguard Workerthe top-level structure that the LLVM IR uses to contain code.
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard WorkerThe ``Codegen.builder`` object is a helper object that makes it easy to
67*9880d681SAndroid Build Coastguard Workergenerate LLVM instructions. Instances of the
68*9880d681SAndroid Build Coastguard Worker`IRBuilder <http://llvm.org/doxygen/IRBuilder_8h-source.html>`_
69*9880d681SAndroid Build Coastguard Workerclass keep track of the current place to insert instructions and has
70*9880d681SAndroid Build Coastguard Workermethods to create new instructions.
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard WorkerThe ``Codegen.named_values`` map keeps track of which values are defined
73*9880d681SAndroid Build Coastguard Workerin the current scope and what their LLVM representation is. (In other
74*9880d681SAndroid Build Coastguard Workerwords, it is a symbol table for the code). In this form of Kaleidoscope,
75*9880d681SAndroid Build Coastguard Workerthe only things that can be referenced are function parameters. As such,
76*9880d681SAndroid Build Coastguard Workerfunction parameters will be in this map when generating code for their
77*9880d681SAndroid Build Coastguard Workerfunction body.
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard WorkerWith these basics in place, we can start talking about how to generate
80*9880d681SAndroid Build Coastguard Workercode for each expression. Note that this assumes that the
81*9880d681SAndroid Build Coastguard Worker``Codgen.builder`` has been set up to generate code *into* something.
82*9880d681SAndroid Build Coastguard WorkerFor now, we'll assume that this has already been done, and we'll just
83*9880d681SAndroid Build Coastguard Workeruse it to emit code.
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard WorkerExpression Code Generation
86*9880d681SAndroid Build Coastguard Worker==========================
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard WorkerGenerating LLVM code for expression nodes is very straightforward: less
89*9880d681SAndroid Build Coastguard Workerthan 30 lines of commented code for all four of our expression nodes.
90*9880d681SAndroid Build Coastguard WorkerFirst we'll do numeric literals:
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker      | Ast.Number n -> const_float double_type n
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard WorkerIn the LLVM IR, numeric constants are represented with the
97*9880d681SAndroid Build Coastguard Worker``ConstantFP`` class, which holds the numeric value in an ``APFloat``
98*9880d681SAndroid Build Coastguard Workerinternally (``APFloat`` has the capability of holding floating point
99*9880d681SAndroid Build Coastguard Workerconstants of Arbitrary Precision). This code basically just creates
100*9880d681SAndroid Build Coastguard Workerand returns a ``ConstantFP``. Note that in the LLVM IR that constants
101*9880d681SAndroid Build Coastguard Workerare all uniqued together and shared. For this reason, the API uses "the
102*9880d681SAndroid Build Coastguard Workerfoo::get(..)" idiom instead of "new foo(..)" or "foo::Create(..)".
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker      | Ast.Variable name ->
107*9880d681SAndroid Build Coastguard Worker          (try Hashtbl.find named_values name with
108*9880d681SAndroid Build Coastguard Worker            | Not_found -> raise (Error "unknown variable name"))
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard WorkerReferences to variables are also quite simple using LLVM. In the simple
111*9880d681SAndroid Build Coastguard Workerversion of Kaleidoscope, we assume that the variable has already been
112*9880d681SAndroid Build Coastguard Workeremitted somewhere and its value is available. In practice, the only
113*9880d681SAndroid Build Coastguard Workervalues that can be in the ``Codegen.named_values`` map are function
114*9880d681SAndroid Build Coastguard Workerarguments. This code simply checks to see that the specified name is in
115*9880d681SAndroid Build Coastguard Workerthe map (if not, an unknown variable is being referenced) and returns
116*9880d681SAndroid Build Coastguard Workerthe value for it. In future chapters, we'll add support for `loop
117*9880d681SAndroid Build Coastguard Workerinduction variables <LangImpl5.html#for-loop-expression>`_ in the symbol table, and for
118*9880d681SAndroid Build Coastguard Worker`local variables <LangImpl7.html#user-defined-local-variables>`_.
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker      | Ast.Binary (op, lhs, rhs) ->
123*9880d681SAndroid Build Coastguard Worker          let lhs_val = codegen_expr lhs in
124*9880d681SAndroid Build Coastguard Worker          let rhs_val = codegen_expr rhs in
125*9880d681SAndroid Build Coastguard Worker          begin
126*9880d681SAndroid Build Coastguard Worker            match op with
127*9880d681SAndroid Build Coastguard Worker            | '+' -> build_fadd lhs_val rhs_val "addtmp" builder
128*9880d681SAndroid Build Coastguard Worker            | '-' -> build_fsub lhs_val rhs_val "subtmp" builder
129*9880d681SAndroid Build Coastguard Worker            | '*' -> build_fmul lhs_val rhs_val "multmp" builder
130*9880d681SAndroid Build Coastguard Worker            | '<' ->
131*9880d681SAndroid Build Coastguard Worker                (* Convert bool 0/1 to double 0.0 or 1.0 *)
132*9880d681SAndroid Build Coastguard Worker                let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in
133*9880d681SAndroid Build Coastguard Worker                build_uitofp i double_type "booltmp" builder
134*9880d681SAndroid Build Coastguard Worker            | _ -> raise (Error "invalid binary operator")
135*9880d681SAndroid Build Coastguard Worker          end
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard WorkerBinary operators start to get more interesting. The basic idea here is
138*9880d681SAndroid Build Coastguard Workerthat we recursively emit code for the left-hand side of the expression,
139*9880d681SAndroid Build Coastguard Workerthen the right-hand side, then we compute the result of the binary
140*9880d681SAndroid Build Coastguard Workerexpression. In this code, we do a simple switch on the opcode to create
141*9880d681SAndroid Build Coastguard Workerthe right LLVM instruction.
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard WorkerIn the example above, the LLVM builder class is starting to show its
144*9880d681SAndroid Build Coastguard Workervalue. IRBuilder knows where to insert the newly created instruction,
145*9880d681SAndroid Build Coastguard Workerall you have to do is specify what instruction to create (e.g. with
146*9880d681SAndroid Build Coastguard Worker``Llvm.create_add``), which operands to use (``lhs`` and ``rhs`` here)
147*9880d681SAndroid Build Coastguard Workerand optionally provide a name for the generated instruction.
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard WorkerOne nice thing about LLVM is that the name is just a hint. For instance,
150*9880d681SAndroid Build Coastguard Workerif the code above emits multiple "addtmp" variables, LLVM will
151*9880d681SAndroid Build Coastguard Workerautomatically provide each one with an increasing, unique numeric
152*9880d681SAndroid Build Coastguard Workersuffix. Local value names for instructions are purely optional, but it
153*9880d681SAndroid Build Coastguard Workermakes it much easier to read the IR dumps.
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker`LLVM instructions <../LangRef.html#instruction-reference>`_ are constrained by strict
156*9880d681SAndroid Build Coastguard Workerrules: for example, the Left and Right operators of an `add
157*9880d681SAndroid Build Coastguard Workerinstruction <../LangRef.html#add-instruction>`_ must have the same type, and the
158*9880d681SAndroid Build Coastguard Workerresult type of the add must match the operand types. Because all values
159*9880d681SAndroid Build Coastguard Workerin Kaleidoscope are doubles, this makes for very simple code for add,
160*9880d681SAndroid Build Coastguard Workersub and mul.
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard WorkerOn the other hand, LLVM specifies that the `fcmp
163*9880d681SAndroid Build Coastguard Workerinstruction <../LangRef.html#fcmp-instruction>`_ always returns an 'i1' value (a
164*9880d681SAndroid Build Coastguard Workerone bit integer). The problem with this is that Kaleidoscope wants the
165*9880d681SAndroid Build Coastguard Workervalue to be a 0.0 or 1.0 value. In order to get these semantics, we
166*9880d681SAndroid Build Coastguard Workercombine the fcmp instruction with a `uitofp
167*9880d681SAndroid Build Coastguard Workerinstruction <../LangRef.html#uitofp-to-instruction>`_. This instruction converts its
168*9880d681SAndroid Build Coastguard Workerinput integer into a floating point value by treating the input as an
169*9880d681SAndroid Build Coastguard Workerunsigned value. In contrast, if we used the `sitofp
170*9880d681SAndroid Build Coastguard Workerinstruction <../LangRef.html#sitofp-to-instruction>`_, the Kaleidoscope '<' operator
171*9880d681SAndroid Build Coastguard Workerwould return 0.0 and -1.0, depending on the input value.
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker      | Ast.Call (callee, args) ->
176*9880d681SAndroid Build Coastguard Worker          (* Look up the name in the module table. *)
177*9880d681SAndroid Build Coastguard Worker          let callee =
178*9880d681SAndroid Build Coastguard Worker            match lookup_function callee the_module with
179*9880d681SAndroid Build Coastguard Worker            | Some callee -> callee
180*9880d681SAndroid Build Coastguard Worker            | None -> raise (Error "unknown function referenced")
181*9880d681SAndroid Build Coastguard Worker          in
182*9880d681SAndroid Build Coastguard Worker          let params = params callee in
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker          (* If argument mismatch error. *)
185*9880d681SAndroid Build Coastguard Worker          if Array.length params == Array.length args then () else
186*9880d681SAndroid Build Coastguard Worker            raise (Error "incorrect # arguments passed");
187*9880d681SAndroid Build Coastguard Worker          let args = Array.map codegen_expr args in
188*9880d681SAndroid Build Coastguard Worker          build_call callee args "calltmp" builder
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard WorkerCode generation for function calls is quite straightforward with LLVM.
191*9880d681SAndroid Build Coastguard WorkerThe code above initially does a function name lookup in the LLVM
192*9880d681SAndroid Build Coastguard WorkerModule's symbol table. Recall that the LLVM Module is the container that
193*9880d681SAndroid Build Coastguard Workerholds all of the functions we are JIT'ing. By giving each function the
194*9880d681SAndroid Build Coastguard Workersame name as what the user specifies, we can use the LLVM symbol table
195*9880d681SAndroid Build Coastguard Workerto resolve function names for us.
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard WorkerOnce we have the function to call, we recursively codegen each argument
198*9880d681SAndroid Build Coastguard Workerthat is to be passed in, and create an LLVM `call
199*9880d681SAndroid Build Coastguard Workerinstruction <../LangRef.html#call-instruction>`_. Note that LLVM uses the native C
200*9880d681SAndroid Build Coastguard Workercalling conventions by default, allowing these calls to also call into
201*9880d681SAndroid Build Coastguard Workerstandard library functions like "sin" and "cos", with no additional
202*9880d681SAndroid Build Coastguard Workereffort.
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard WorkerThis wraps up our handling of the four basic expressions that we have so
205*9880d681SAndroid Build Coastguard Workerfar in Kaleidoscope. Feel free to go in and add some more. For example,
206*9880d681SAndroid Build Coastguard Workerby browsing the `LLVM language reference <../LangRef.html>`_ you'll find
207*9880d681SAndroid Build Coastguard Workerseveral other interesting instructions that are really easy to plug into
208*9880d681SAndroid Build Coastguard Workerour basic framework.
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard WorkerFunction Code Generation
211*9880d681SAndroid Build Coastguard Worker========================
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard WorkerCode generation for prototypes and functions must handle a number of
214*9880d681SAndroid Build Coastguard Workerdetails, which make their code less beautiful than expression code
215*9880d681SAndroid Build Coastguard Workergeneration, but allows us to illustrate some important points. First,
216*9880d681SAndroid Build Coastguard Workerlets talk about code generation for prototypes: they are used both for
217*9880d681SAndroid Build Coastguard Workerfunction bodies and external function declarations. The code starts
218*9880d681SAndroid Build Coastguard Workerwith:
219*9880d681SAndroid Build Coastguard Worker
220*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker    let codegen_proto = function
223*9880d681SAndroid Build Coastguard Worker      | Ast.Prototype (name, args) ->
224*9880d681SAndroid Build Coastguard Worker          (* Make the function type: double(double,double) etc. *)
225*9880d681SAndroid Build Coastguard Worker          let doubles = Array.make (Array.length args) double_type in
226*9880d681SAndroid Build Coastguard Worker          let ft = function_type double_type doubles in
227*9880d681SAndroid Build Coastguard Worker          let f =
228*9880d681SAndroid Build Coastguard Worker            match lookup_function name the_module with
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard WorkerThis code packs a lot of power into a few lines. Note first that this
231*9880d681SAndroid Build Coastguard Workerfunction returns a "Function\*" instead of a "Value\*" (although at the
232*9880d681SAndroid Build Coastguard Workermoment they both are modeled by ``llvalue`` in ocaml). Because a
233*9880d681SAndroid Build Coastguard Worker"prototype" really talks about the external interface for a function
234*9880d681SAndroid Build Coastguard Worker(not the value computed by an expression), it makes sense for it to
235*9880d681SAndroid Build Coastguard Workerreturn the LLVM Function it corresponds to when codegen'd.
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard WorkerThe call to ``Llvm.function_type`` creates the ``Llvm.llvalue`` that
238*9880d681SAndroid Build Coastguard Workershould be used for a given Prototype. Since all function arguments in
239*9880d681SAndroid Build Coastguard WorkerKaleidoscope are of type double, the first line creates a vector of "N"
240*9880d681SAndroid Build Coastguard WorkerLLVM double types. It then uses the ``Llvm.function_type`` method to
241*9880d681SAndroid Build Coastguard Workercreate a function type that takes "N" doubles as arguments, returns one
242*9880d681SAndroid Build Coastguard Workerdouble as a result, and that is not vararg (that uses the function
243*9880d681SAndroid Build Coastguard Worker``Llvm.var_arg_function_type``). Note that Types in LLVM are uniqued
244*9880d681SAndroid Build Coastguard Workerjust like ``Constant``'s are, so you don't "new" a type, you "get" it.
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard WorkerThe final line above checks if the function has already been defined in
247*9880d681SAndroid Build Coastguard Worker``Codegen.the_module``. If not, we will create it.
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker            | None -> declare_function name ft the_module
252*9880d681SAndroid Build Coastguard Worker
253*9880d681SAndroid Build Coastguard WorkerThis indicates the type and name to use, as well as which module to
254*9880d681SAndroid Build Coastguard Workerinsert into. By default we assume a function has
255*9880d681SAndroid Build Coastguard Worker``Llvm.Linkage.ExternalLinkage``. "`external
256*9880d681SAndroid Build Coastguard Workerlinkage <../LangRef.html#linkage>`_" means that the function may be defined
257*9880d681SAndroid Build Coastguard Workeroutside the current module and/or that it is callable by functions
258*9880d681SAndroid Build Coastguard Workeroutside the module. The "``name``" passed in is the name the user
259*9880d681SAndroid Build Coastguard Workerspecified: this name is registered in "``Codegen.the_module``"s symbol
260*9880d681SAndroid Build Coastguard Workertable, which is used by the function call code above.
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard WorkerIn Kaleidoscope, I choose to allow redefinitions of functions in two
263*9880d681SAndroid Build Coastguard Workercases: first, we want to allow 'extern'ing a function more than once, as
264*9880d681SAndroid Build Coastguard Workerlong as the prototypes for the externs match (since all arguments have
265*9880d681SAndroid Build Coastguard Workerthe same type, we just have to check that the number of arguments
266*9880d681SAndroid Build Coastguard Workermatch). Second, we want to allow 'extern'ing a function and then
267*9880d681SAndroid Build Coastguard Workerdefining a body for it. This is useful when defining mutually recursive
268*9880d681SAndroid Build Coastguard Workerfunctions.
269*9880d681SAndroid Build Coastguard Worker
270*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker            (* If 'f' conflicted, there was already something named 'name'. If it
273*9880d681SAndroid Build Coastguard Worker             * has a body, don't allow redefinition or reextern. *)
274*9880d681SAndroid Build Coastguard Worker            | Some f ->
275*9880d681SAndroid Build Coastguard Worker                (* If 'f' already has a body, reject this. *)
276*9880d681SAndroid Build Coastguard Worker                if Array.length (basic_blocks f) == 0 then () else
277*9880d681SAndroid Build Coastguard Worker                  raise (Error "redefinition of function");
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Worker                (* If 'f' took a different number of arguments, reject. *)
280*9880d681SAndroid Build Coastguard Worker                if Array.length (params f) == Array.length args then () else
281*9880d681SAndroid Build Coastguard Worker                  raise (Error "redefinition of function with different # args");
282*9880d681SAndroid Build Coastguard Worker                f
283*9880d681SAndroid Build Coastguard Worker          in
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard WorkerIn order to verify the logic above, we first check to see if the
286*9880d681SAndroid Build Coastguard Workerpre-existing function is "empty". In this case, empty means that it has
287*9880d681SAndroid Build Coastguard Workerno basic blocks in it, which means it has no body. If it has no body, it
288*9880d681SAndroid Build Coastguard Workeris a forward declaration. Since we don't allow anything after a full
289*9880d681SAndroid Build Coastguard Workerdefinition of the function, the code rejects this case. If the previous
290*9880d681SAndroid Build Coastguard Workerreference to a function was an 'extern', we simply verify that the
291*9880d681SAndroid Build Coastguard Workernumber of arguments for that definition and this one match up. If not,
292*9880d681SAndroid Build Coastguard Workerwe emit an error.
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker          (* Set names for all arguments. *)
297*9880d681SAndroid Build Coastguard Worker          Array.iteri (fun i a ->
298*9880d681SAndroid Build Coastguard Worker            let n = args.(i) in
299*9880d681SAndroid Build Coastguard Worker            set_value_name n a;
300*9880d681SAndroid Build Coastguard Worker            Hashtbl.add named_values n a;
301*9880d681SAndroid Build Coastguard Worker          ) (params f);
302*9880d681SAndroid Build Coastguard Worker          f
303*9880d681SAndroid Build Coastguard Worker
304*9880d681SAndroid Build Coastguard WorkerThe last bit of code for prototypes loops over all of the arguments in
305*9880d681SAndroid Build Coastguard Workerthe function, setting the name of the LLVM Argument objects to match,
306*9880d681SAndroid Build Coastguard Workerand registering the arguments in the ``Codegen.named_values`` map for
307*9880d681SAndroid Build Coastguard Workerfuture use by the ``Ast.Variable`` variant. Once this is set up, it
308*9880d681SAndroid Build Coastguard Workerreturns the Function object to the caller. Note that we don't check for
309*9880d681SAndroid Build Coastguard Workerconflicting argument names here (e.g. "extern foo(a b a)"). Doing so
310*9880d681SAndroid Build Coastguard Workerwould be very straight-forward with the mechanics we have already used
311*9880d681SAndroid Build Coastguard Workerabove.
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker    let codegen_func = function
316*9880d681SAndroid Build Coastguard Worker      | Ast.Function (proto, body) ->
317*9880d681SAndroid Build Coastguard Worker          Hashtbl.clear named_values;
318*9880d681SAndroid Build Coastguard Worker          let the_function = codegen_proto proto in
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard WorkerCode generation for function definitions starts out simply enough: we
321*9880d681SAndroid Build Coastguard Workerjust codegen the prototype (Proto) and verify that it is ok. We then
322*9880d681SAndroid Build Coastguard Workerclear out the ``Codegen.named_values`` map to make sure that there isn't
323*9880d681SAndroid Build Coastguard Workeranything in it from the last function we compiled. Code generation of
324*9880d681SAndroid Build Coastguard Workerthe prototype ensures that there is an LLVM Function object that is
325*9880d681SAndroid Build Coastguard Workerready to go for us.
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker          (* Create a new basic block to start insertion into. *)
330*9880d681SAndroid Build Coastguard Worker          let bb = append_block context "entry" the_function in
331*9880d681SAndroid Build Coastguard Worker          position_at_end bb builder;
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker          try
334*9880d681SAndroid Build Coastguard Worker            let ret_val = codegen_expr body in
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard WorkerNow we get to the point where the ``Codegen.builder`` is set up. The
337*9880d681SAndroid Build Coastguard Workerfirst line creates a new `basic
338*9880d681SAndroid Build Coastguard Workerblock <http://en.wikipedia.org/wiki/Basic_block>`_ (named "entry"),
339*9880d681SAndroid Build Coastguard Workerwhich is inserted into ``the_function``. The second line then tells the
340*9880d681SAndroid Build Coastguard Workerbuilder that new instructions should be inserted into the end of the new
341*9880d681SAndroid Build Coastguard Workerbasic block. Basic blocks in LLVM are an important part of functions
342*9880d681SAndroid Build Coastguard Workerthat define the `Control Flow
343*9880d681SAndroid Build Coastguard WorkerGraph <http://en.wikipedia.org/wiki/Control_flow_graph>`_. Since we
344*9880d681SAndroid Build Coastguard Workerdon't have any control flow, our functions will only contain one block
345*9880d681SAndroid Build Coastguard Workerat this point. We'll fix this in `Chapter 5 <OCamlLangImpl5.html>`_ :).
346*9880d681SAndroid Build Coastguard Worker
347*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker            let ret_val = codegen_expr body in
350*9880d681SAndroid Build Coastguard Worker
351*9880d681SAndroid Build Coastguard Worker            (* Finish off the function. *)
352*9880d681SAndroid Build Coastguard Worker            let _ = build_ret ret_val builder in
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker            (* Validate the generated code, checking for consistency. *)
355*9880d681SAndroid Build Coastguard Worker            Llvm_analysis.assert_valid_function the_function;
356*9880d681SAndroid Build Coastguard Worker
357*9880d681SAndroid Build Coastguard Worker            the_function
358*9880d681SAndroid Build Coastguard Worker
359*9880d681SAndroid Build Coastguard WorkerOnce the insertion point is set up, we call the ``Codegen.codegen_func``
360*9880d681SAndroid Build Coastguard Workermethod for the root expression of the function. If no error happens,
361*9880d681SAndroid Build Coastguard Workerthis emits code to compute the expression into the entry block and
362*9880d681SAndroid Build Coastguard Workerreturns the value that was computed. Assuming no error, we then create
363*9880d681SAndroid Build Coastguard Workeran LLVM `ret instruction <../LangRef.html#ret-instruction>`_, which completes the
364*9880d681SAndroid Build Coastguard Workerfunction. Once the function is built, we call
365*9880d681SAndroid Build Coastguard Worker``Llvm_analysis.assert_valid_function``, which is provided by LLVM. This
366*9880d681SAndroid Build Coastguard Workerfunction does a variety of consistency checks on the generated code, to
367*9880d681SAndroid Build Coastguard Workerdetermine if our compiler is doing everything right. Using this is
368*9880d681SAndroid Build Coastguard Workerimportant: it can catch a lot of bugs. Once the function is finished and
369*9880d681SAndroid Build Coastguard Workervalidated, we return it.
370*9880d681SAndroid Build Coastguard Worker
371*9880d681SAndroid Build Coastguard Worker.. code-block:: ocaml
372*9880d681SAndroid Build Coastguard Worker
373*9880d681SAndroid Build Coastguard Worker          with e ->
374*9880d681SAndroid Build Coastguard Worker            delete_function the_function;
375*9880d681SAndroid Build Coastguard Worker            raise e
376*9880d681SAndroid Build Coastguard Worker
377*9880d681SAndroid Build Coastguard WorkerThe only piece left here is handling of the error case. For simplicity,
378*9880d681SAndroid Build Coastguard Workerwe handle this by merely deleting the function we produced with the
379*9880d681SAndroid Build Coastguard Worker``Llvm.delete_function`` method. This allows the user to redefine a
380*9880d681SAndroid Build Coastguard Workerfunction that they incorrectly typed in before: if we didn't delete it,
381*9880d681SAndroid Build Coastguard Workerit would live in the symbol table, with a body, preventing future
382*9880d681SAndroid Build Coastguard Workerredefinition.
383*9880d681SAndroid Build Coastguard Worker
384*9880d681SAndroid Build Coastguard WorkerThis code does have a bug, though. Since the ``Codegen.codegen_proto``
385*9880d681SAndroid Build Coastguard Workercan return a previously defined forward declaration, our code can
386*9880d681SAndroid Build Coastguard Workeractually delete a forward declaration. There are a number of ways to fix
387*9880d681SAndroid Build Coastguard Workerthis bug, see what you can come up with! Here is a testcase:
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker::
390*9880d681SAndroid Build Coastguard Worker
391*9880d681SAndroid Build Coastguard Worker    extern foo(a b);     # ok, defines foo.
392*9880d681SAndroid Build Coastguard Worker    def foo(a b) c;      # error, 'c' is invalid.
393*9880d681SAndroid Build Coastguard Worker    def bar() foo(1, 2); # error, unknown function "foo"
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard WorkerDriver Changes and Closing Thoughts
396*9880d681SAndroid Build Coastguard Worker===================================
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard WorkerFor now, code generation to LLVM doesn't really get us much, except that
399*9880d681SAndroid Build Coastguard Workerwe can look at the pretty IR calls. The sample code inserts calls to
400*9880d681SAndroid Build Coastguard WorkerCodegen into the "``Toplevel.main_loop``", and then dumps out the LLVM
401*9880d681SAndroid Build Coastguard WorkerIR. This gives a nice way to look at the LLVM IR for simple functions.
402*9880d681SAndroid Build Coastguard WorkerFor example:
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Worker::
405*9880d681SAndroid Build Coastguard Worker
406*9880d681SAndroid Build Coastguard Worker    ready> 4+5;
407*9880d681SAndroid Build Coastguard Worker    Read top-level expression:
408*9880d681SAndroid Build Coastguard Worker    define double @""() {
409*9880d681SAndroid Build Coastguard Worker    entry:
410*9880d681SAndroid Build Coastguard Worker            %addtmp = fadd double 4.000000e+00, 5.000000e+00
411*9880d681SAndroid Build Coastguard Worker            ret double %addtmp
412*9880d681SAndroid Build Coastguard Worker    }
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard WorkerNote how the parser turns the top-level expression into anonymous
415*9880d681SAndroid Build Coastguard Workerfunctions for us. This will be handy when we add `JIT
416*9880d681SAndroid Build Coastguard Workersupport <OCamlLangImpl4.html#adding-a-jit-compiler>`_ in the next chapter. Also note that
417*9880d681SAndroid Build Coastguard Workerthe code is very literally transcribed, no optimizations are being
418*9880d681SAndroid Build Coastguard Workerperformed. We will `add
419*9880d681SAndroid Build Coastguard Workeroptimizations <OCamlLangImpl4.html#trivial-constant-folding>`_ explicitly in the
420*9880d681SAndroid Build Coastguard Workernext chapter.
421*9880d681SAndroid Build Coastguard Worker
422*9880d681SAndroid Build Coastguard Worker::
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Worker    ready> def foo(a b) a*a + 2*a*b + b*b;
425*9880d681SAndroid Build Coastguard Worker    Read function definition:
426*9880d681SAndroid Build Coastguard Worker    define double @foo(double %a, double %b) {
427*9880d681SAndroid Build Coastguard Worker    entry:
428*9880d681SAndroid Build Coastguard Worker            %multmp = fmul double %a, %a
429*9880d681SAndroid Build Coastguard Worker            %multmp1 = fmul double 2.000000e+00, %a
430*9880d681SAndroid Build Coastguard Worker            %multmp2 = fmul double %multmp1, %b
431*9880d681SAndroid Build Coastguard Worker            %addtmp = fadd double %multmp, %multmp2
432*9880d681SAndroid Build Coastguard Worker            %multmp3 = fmul double %b, %b
433*9880d681SAndroid Build Coastguard Worker            %addtmp4 = fadd double %addtmp, %multmp3
434*9880d681SAndroid Build Coastguard Worker            ret double %addtmp4
435*9880d681SAndroid Build Coastguard Worker    }
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard WorkerThis shows some simple arithmetic. Notice the striking similarity to the
438*9880d681SAndroid Build Coastguard WorkerLLVM builder calls that we use to create the instructions.
439*9880d681SAndroid Build Coastguard Worker
440*9880d681SAndroid Build Coastguard Worker::
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Worker    ready> def bar(a) foo(a, 4.0) + bar(31337);
443*9880d681SAndroid Build Coastguard Worker    Read function definition:
444*9880d681SAndroid Build Coastguard Worker    define double @bar(double %a) {
445*9880d681SAndroid Build Coastguard Worker    entry:
446*9880d681SAndroid Build Coastguard Worker            %calltmp = call double @foo(double %a, double 4.000000e+00)
447*9880d681SAndroid Build Coastguard Worker            %calltmp1 = call double @bar(double 3.133700e+04)
448*9880d681SAndroid Build Coastguard Worker            %addtmp = fadd double %calltmp, %calltmp1
449*9880d681SAndroid Build Coastguard Worker            ret double %addtmp
450*9880d681SAndroid Build Coastguard Worker    }
451*9880d681SAndroid Build Coastguard Worker
452*9880d681SAndroid Build Coastguard WorkerThis shows some function calls. Note that this function will take a long
453*9880d681SAndroid Build Coastguard Workertime to execute if you call it. In the future we'll add conditional
454*9880d681SAndroid Build Coastguard Workercontrol flow to actually make recursion useful :).
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker::
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker    ready> extern cos(x);
459*9880d681SAndroid Build Coastguard Worker    Read extern:
460*9880d681SAndroid Build Coastguard Worker    declare double @cos(double)
461*9880d681SAndroid Build Coastguard Worker
462*9880d681SAndroid Build Coastguard Worker    ready> cos(1.234);
463*9880d681SAndroid Build Coastguard Worker    Read top-level expression:
464*9880d681SAndroid Build Coastguard Worker    define double @""() {
465*9880d681SAndroid Build Coastguard Worker    entry:
466*9880d681SAndroid Build Coastguard Worker            %calltmp = call double @cos(double 1.234000e+00)
467*9880d681SAndroid Build Coastguard Worker            ret double %calltmp
468*9880d681SAndroid Build Coastguard Worker    }
469*9880d681SAndroid Build Coastguard Worker
470*9880d681SAndroid Build Coastguard WorkerThis shows an extern for the libm "cos" function, and a call to it.
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Worker::
473*9880d681SAndroid Build Coastguard Worker
474*9880d681SAndroid Build Coastguard Worker    ready> ^D
475*9880d681SAndroid Build Coastguard Worker    ; ModuleID = 'my cool jit'
476*9880d681SAndroid Build Coastguard Worker
477*9880d681SAndroid Build Coastguard Worker    define double @""() {
478*9880d681SAndroid Build Coastguard Worker    entry:
479*9880d681SAndroid Build Coastguard Worker            %addtmp = fadd double 4.000000e+00, 5.000000e+00
480*9880d681SAndroid Build Coastguard Worker            ret double %addtmp
481*9880d681SAndroid Build Coastguard Worker    }
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Worker    define double @foo(double %a, double %b) {
484*9880d681SAndroid Build Coastguard Worker    entry:
485*9880d681SAndroid Build Coastguard Worker            %multmp = fmul double %a, %a
486*9880d681SAndroid Build Coastguard Worker            %multmp1 = fmul double 2.000000e+00, %a
487*9880d681SAndroid Build Coastguard Worker            %multmp2 = fmul double %multmp1, %b
488*9880d681SAndroid Build Coastguard Worker            %addtmp = fadd double %multmp, %multmp2
489*9880d681SAndroid Build Coastguard Worker            %multmp3 = fmul double %b, %b
490*9880d681SAndroid Build Coastguard Worker            %addtmp4 = fadd double %addtmp, %multmp3
491*9880d681SAndroid Build Coastguard Worker            ret double %addtmp4
492*9880d681SAndroid Build Coastguard Worker    }
493*9880d681SAndroid Build Coastguard Worker
494*9880d681SAndroid Build Coastguard Worker    define double @bar(double %a) {
495*9880d681SAndroid Build Coastguard Worker    entry:
496*9880d681SAndroid Build Coastguard Worker            %calltmp = call double @foo(double %a, double 4.000000e+00)
497*9880d681SAndroid Build Coastguard Worker            %calltmp1 = call double @bar(double 3.133700e+04)
498*9880d681SAndroid Build Coastguard Worker            %addtmp = fadd double %calltmp, %calltmp1
499*9880d681SAndroid Build Coastguard Worker            ret double %addtmp
500*9880d681SAndroid Build Coastguard Worker    }
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker    declare double @cos(double)
503*9880d681SAndroid Build Coastguard Worker
504*9880d681SAndroid Build Coastguard Worker    define double @""() {
505*9880d681SAndroid Build Coastguard Worker    entry:
506*9880d681SAndroid Build Coastguard Worker            %calltmp = call double @cos(double 1.234000e+00)
507*9880d681SAndroid Build Coastguard Worker            ret double %calltmp
508*9880d681SAndroid Build Coastguard Worker    }
509*9880d681SAndroid Build Coastguard Worker
510*9880d681SAndroid Build Coastguard WorkerWhen you quit the current demo, it dumps out the IR for the entire
511*9880d681SAndroid Build Coastguard Workermodule generated. Here you can see the big picture with all the
512*9880d681SAndroid Build Coastguard Workerfunctions referencing each other.
513*9880d681SAndroid Build Coastguard Worker
514*9880d681SAndroid Build Coastguard WorkerThis wraps up the third chapter of the Kaleidoscope tutorial. Up next,
515*9880d681SAndroid Build Coastguard Workerwe'll describe how to `add JIT codegen and optimizer
516*9880d681SAndroid Build Coastguard Workersupport <OCamlLangImpl4.html>`_ to this so we can actually start running
517*9880d681SAndroid Build Coastguard Workercode!
518*9880d681SAndroid Build Coastguard Worker
519*9880d681SAndroid Build Coastguard WorkerFull Code Listing
520*9880d681SAndroid Build Coastguard Worker=================
521*9880d681SAndroid Build Coastguard Worker
522*9880d681SAndroid Build Coastguard WorkerHere is the complete code listing for our running example, enhanced with
523*9880d681SAndroid Build Coastguard Workerthe LLVM code generator. Because this uses the LLVM libraries, we need
524*9880d681SAndroid Build Coastguard Workerto link them in. To do this, we use the
525*9880d681SAndroid Build Coastguard Worker`llvm-config <http://llvm.org/cmds/llvm-config.html>`_ tool to inform
526*9880d681SAndroid Build Coastguard Workerour makefile/command line about which options to use:
527*9880d681SAndroid Build Coastguard Worker
528*9880d681SAndroid Build Coastguard Worker.. code-block:: bash
529*9880d681SAndroid Build Coastguard Worker
530*9880d681SAndroid Build Coastguard Worker    # Compile
531*9880d681SAndroid Build Coastguard Worker    ocamlbuild toy.byte
532*9880d681SAndroid Build Coastguard Worker    # Run
533*9880d681SAndroid Build Coastguard Worker    ./toy.byte
534*9880d681SAndroid Build Coastguard Worker
535*9880d681SAndroid Build Coastguard WorkerHere is the code:
536*9880d681SAndroid Build Coastguard Worker
537*9880d681SAndroid Build Coastguard Worker\_tags:
538*9880d681SAndroid Build Coastguard Worker    ::
539*9880d681SAndroid Build Coastguard Worker
540*9880d681SAndroid Build Coastguard Worker        <{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
541*9880d681SAndroid Build Coastguard Worker        <*.{byte,native}>: g++, use_llvm, use_llvm_analysis
542*9880d681SAndroid Build Coastguard Worker
543*9880d681SAndroid Build Coastguard Workermyocamlbuild.ml:
544*9880d681SAndroid Build Coastguard Worker    .. code-block:: ocaml
545*9880d681SAndroid Build Coastguard Worker
546*9880d681SAndroid Build Coastguard Worker        open Ocamlbuild_plugin;;
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker        ocaml_lib ~extern:true "llvm";;
549*9880d681SAndroid Build Coastguard Worker        ocaml_lib ~extern:true "llvm_analysis";;
550*9880d681SAndroid Build Coastguard Worker
551*9880d681SAndroid Build Coastguard Worker        flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);;
552*9880d681SAndroid Build Coastguard Worker
553*9880d681SAndroid Build Coastguard Workertoken.ml:
554*9880d681SAndroid Build Coastguard Worker    .. code-block:: ocaml
555*9880d681SAndroid Build Coastguard Worker
556*9880d681SAndroid Build Coastguard Worker        (*===----------------------------------------------------------------------===
557*9880d681SAndroid Build Coastguard Worker         * Lexer Tokens
558*9880d681SAndroid Build Coastguard Worker         *===----------------------------------------------------------------------===*)
559*9880d681SAndroid Build Coastguard Worker
560*9880d681SAndroid Build Coastguard Worker        (* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of
561*9880d681SAndroid Build Coastguard Worker         * these others for known things. *)
562*9880d681SAndroid Build Coastguard Worker        type token =
563*9880d681SAndroid Build Coastguard Worker          (* commands *)
564*9880d681SAndroid Build Coastguard Worker          | Def | Extern
565*9880d681SAndroid Build Coastguard Worker
566*9880d681SAndroid Build Coastguard Worker          (* primary *)
567*9880d681SAndroid Build Coastguard Worker          | Ident of string | Number of float
568*9880d681SAndroid Build Coastguard Worker
569*9880d681SAndroid Build Coastguard Worker          (* unknown *)
570*9880d681SAndroid Build Coastguard Worker          | Kwd of char
571*9880d681SAndroid Build Coastguard Worker
572*9880d681SAndroid Build Coastguard Workerlexer.ml:
573*9880d681SAndroid Build Coastguard Worker    .. code-block:: ocaml
574*9880d681SAndroid Build Coastguard Worker
575*9880d681SAndroid Build Coastguard Worker        (*===----------------------------------------------------------------------===
576*9880d681SAndroid Build Coastguard Worker         * Lexer
577*9880d681SAndroid Build Coastguard Worker         *===----------------------------------------------------------------------===*)
578*9880d681SAndroid Build Coastguard Worker
579*9880d681SAndroid Build Coastguard Worker        let rec lex = parser
580*9880d681SAndroid Build Coastguard Worker          (* Skip any whitespace. *)
581*9880d681SAndroid Build Coastguard Worker          | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream
582*9880d681SAndroid Build Coastguard Worker
583*9880d681SAndroid Build Coastguard Worker          (* identifier: [a-zA-Z][a-zA-Z0-9] *)
584*9880d681SAndroid Build Coastguard Worker          | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] ->
585*9880d681SAndroid Build Coastguard Worker              let buffer = Buffer.create 1 in
586*9880d681SAndroid Build Coastguard Worker              Buffer.add_char buffer c;
587*9880d681SAndroid Build Coastguard Worker              lex_ident buffer stream
588*9880d681SAndroid Build Coastguard Worker
589*9880d681SAndroid Build Coastguard Worker          (* number: [0-9.]+ *)
590*9880d681SAndroid Build Coastguard Worker          | [< ' ('0' .. '9' as c); stream >] ->
591*9880d681SAndroid Build Coastguard Worker              let buffer = Buffer.create 1 in
592*9880d681SAndroid Build Coastguard Worker              Buffer.add_char buffer c;
593*9880d681SAndroid Build Coastguard Worker              lex_number buffer stream
594*9880d681SAndroid Build Coastguard Worker
595*9880d681SAndroid Build Coastguard Worker          (* Comment until end of line. *)
596*9880d681SAndroid Build Coastguard Worker          | [< ' ('#'); stream >] ->
597*9880d681SAndroid Build Coastguard Worker              lex_comment stream
598*9880d681SAndroid Build Coastguard Worker
599*9880d681SAndroid Build Coastguard Worker          (* Otherwise, just return the character as its ascii value. *)
600*9880d681SAndroid Build Coastguard Worker          | [< 'c; stream >] ->
601*9880d681SAndroid Build Coastguard Worker              [< 'Token.Kwd c; lex stream >]
602*9880d681SAndroid Build Coastguard Worker
603*9880d681SAndroid Build Coastguard Worker          (* end of stream. *)
604*9880d681SAndroid Build Coastguard Worker          | [< >] -> [< >]
605*9880d681SAndroid Build Coastguard Worker
606*9880d681SAndroid Build Coastguard Worker        and lex_number buffer = parser
607*9880d681SAndroid Build Coastguard Worker          | [< ' ('0' .. '9' | '.' as c); stream >] ->
608*9880d681SAndroid Build Coastguard Worker              Buffer.add_char buffer c;
609*9880d681SAndroid Build Coastguard Worker              lex_number buffer stream
610*9880d681SAndroid Build Coastguard Worker          | [< stream=lex >] ->
611*9880d681SAndroid Build Coastguard Worker              [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >]
612*9880d681SAndroid Build Coastguard Worker
613*9880d681SAndroid Build Coastguard Worker        and lex_ident buffer = parser
614*9880d681SAndroid Build Coastguard Worker          | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] ->
615*9880d681SAndroid Build Coastguard Worker              Buffer.add_char buffer c;
616*9880d681SAndroid Build Coastguard Worker              lex_ident buffer stream
617*9880d681SAndroid Build Coastguard Worker          | [< stream=lex >] ->
618*9880d681SAndroid Build Coastguard Worker              match Buffer.contents buffer with
619*9880d681SAndroid Build Coastguard Worker              | "def" -> [< 'Token.Def; stream >]
620*9880d681SAndroid Build Coastguard Worker              | "extern" -> [< 'Token.Extern; stream >]
621*9880d681SAndroid Build Coastguard Worker              | id -> [< 'Token.Ident id; stream >]
622*9880d681SAndroid Build Coastguard Worker
623*9880d681SAndroid Build Coastguard Worker        and lex_comment = parser
624*9880d681SAndroid Build Coastguard Worker          | [< ' ('\n'); stream=lex >] -> stream
625*9880d681SAndroid Build Coastguard Worker          | [< 'c; e=lex_comment >] -> e
626*9880d681SAndroid Build Coastguard Worker          | [< >] -> [< >]
627*9880d681SAndroid Build Coastguard Worker
628*9880d681SAndroid Build Coastguard Workerast.ml:
629*9880d681SAndroid Build Coastguard Worker    .. code-block:: ocaml
630*9880d681SAndroid Build Coastguard Worker
631*9880d681SAndroid Build Coastguard Worker        (*===----------------------------------------------------------------------===
632*9880d681SAndroid Build Coastguard Worker         * Abstract Syntax Tree (aka Parse Tree)
633*9880d681SAndroid Build Coastguard Worker         *===----------------------------------------------------------------------===*)
634*9880d681SAndroid Build Coastguard Worker
635*9880d681SAndroid Build Coastguard Worker        (* expr - Base type for all expression nodes. *)
636*9880d681SAndroid Build Coastguard Worker        type expr =
637*9880d681SAndroid Build Coastguard Worker          (* variant for numeric literals like "1.0". *)
638*9880d681SAndroid Build Coastguard Worker          | Number of float
639*9880d681SAndroid Build Coastguard Worker
640*9880d681SAndroid Build Coastguard Worker          (* variant for referencing a variable, like "a". *)
641*9880d681SAndroid Build Coastguard Worker          | Variable of string
642*9880d681SAndroid Build Coastguard Worker
643*9880d681SAndroid Build Coastguard Worker          (* variant for a binary operator. *)
644*9880d681SAndroid Build Coastguard Worker          | Binary of char * expr * expr
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker          (* variant for function calls. *)
647*9880d681SAndroid Build Coastguard Worker          | Call of string * expr array
648*9880d681SAndroid Build Coastguard Worker
649*9880d681SAndroid Build Coastguard Worker        (* proto - This type represents the "prototype" for a function, which captures
650*9880d681SAndroid Build Coastguard Worker         * its name, and its argument names (thus implicitly the number of arguments the
651*9880d681SAndroid Build Coastguard Worker         * function takes). *)
652*9880d681SAndroid Build Coastguard Worker        type proto = Prototype of string * string array
653*9880d681SAndroid Build Coastguard Worker
654*9880d681SAndroid Build Coastguard Worker        (* func - This type represents a function definition itself. *)
655*9880d681SAndroid Build Coastguard Worker        type func = Function of proto * expr
656*9880d681SAndroid Build Coastguard Worker
657*9880d681SAndroid Build Coastguard Workerparser.ml:
658*9880d681SAndroid Build Coastguard Worker    .. code-block:: ocaml
659*9880d681SAndroid Build Coastguard Worker
660*9880d681SAndroid Build Coastguard Worker        (*===---------------------------------------------------------------------===
661*9880d681SAndroid Build Coastguard Worker         * Parser
662*9880d681SAndroid Build Coastguard Worker         *===---------------------------------------------------------------------===*)
663*9880d681SAndroid Build Coastguard Worker
664*9880d681SAndroid Build Coastguard Worker        (* binop_precedence - This holds the precedence for each binary operator that is
665*9880d681SAndroid Build Coastguard Worker         * defined *)
666*9880d681SAndroid Build Coastguard Worker        let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10
667*9880d681SAndroid Build Coastguard Worker
668*9880d681SAndroid Build Coastguard Worker        (* precedence - Get the precedence of the pending binary operator token. *)
669*9880d681SAndroid Build Coastguard Worker        let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1
670*9880d681SAndroid Build Coastguard Worker
671*9880d681SAndroid Build Coastguard Worker        (* primary
672*9880d681SAndroid Build Coastguard Worker         *   ::= identifier
673*9880d681SAndroid Build Coastguard Worker         *   ::= numberexpr
674*9880d681SAndroid Build Coastguard Worker         *   ::= parenexpr *)
675*9880d681SAndroid Build Coastguard Worker        let rec parse_primary = parser
676*9880d681SAndroid Build Coastguard Worker          (* numberexpr ::= number *)
677*9880d681SAndroid Build Coastguard Worker          | [< 'Token.Number n >] -> Ast.Number n
678*9880d681SAndroid Build Coastguard Worker
679*9880d681SAndroid Build Coastguard Worker          (* parenexpr ::= '(' expression ')' *)
680*9880d681SAndroid Build Coastguard Worker          | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e
681*9880d681SAndroid Build Coastguard Worker
682*9880d681SAndroid Build Coastguard Worker          (* identifierexpr
683*9880d681SAndroid Build Coastguard Worker           *   ::= identifier
684*9880d681SAndroid Build Coastguard Worker           *   ::= identifier '(' argumentexpr ')' *)
685*9880d681SAndroid Build Coastguard Worker          | [< 'Token.Ident id; stream >] ->
686*9880d681SAndroid Build Coastguard Worker              let rec parse_args accumulator = parser
687*9880d681SAndroid Build Coastguard Worker                | [< e=parse_expr; stream >] ->
688*9880d681SAndroid Build Coastguard Worker                    begin parser
689*9880d681SAndroid Build Coastguard Worker                      | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e
690*9880d681SAndroid Build Coastguard Worker                      | [< >] -> e :: accumulator
691*9880d681SAndroid Build Coastguard Worker                    end stream
692*9880d681SAndroid Build Coastguard Worker                | [< >] -> accumulator
693*9880d681SAndroid Build Coastguard Worker              in
694*9880d681SAndroid Build Coastguard Worker              let rec parse_ident id = parser
695*9880d681SAndroid Build Coastguard Worker                (* Call. *)
696*9880d681SAndroid Build Coastguard Worker                | [< 'Token.Kwd '(';
697*9880d681SAndroid Build Coastguard Worker                     args=parse_args [];
698*9880d681SAndroid Build Coastguard Worker                     'Token.Kwd ')' ?? "expected ')'">] ->
699*9880d681SAndroid Build Coastguard Worker                    Ast.Call (id, Array.of_list (List.rev args))
700*9880d681SAndroid Build Coastguard Worker
701*9880d681SAndroid Build Coastguard Worker                (* Simple variable ref. *)
702*9880d681SAndroid Build Coastguard Worker                | [< >] -> Ast.Variable id
703*9880d681SAndroid Build Coastguard Worker              in
704*9880d681SAndroid Build Coastguard Worker              parse_ident id stream
705*9880d681SAndroid Build Coastguard Worker
706*9880d681SAndroid Build Coastguard Worker          | [< >] -> raise (Stream.Error "unknown token when expecting an expression.")
707*9880d681SAndroid Build Coastguard Worker
708*9880d681SAndroid Build Coastguard Worker        (* binoprhs
709*9880d681SAndroid Build Coastguard Worker         *   ::= ('+' primary)* *)
710*9880d681SAndroid Build Coastguard Worker        and parse_bin_rhs expr_prec lhs stream =
711*9880d681SAndroid Build Coastguard Worker          match Stream.peek stream with
712*9880d681SAndroid Build Coastguard Worker          (* If this is a binop, find its precedence. *)
713*9880d681SAndroid Build Coastguard Worker          | Some (Token.Kwd c) when Hashtbl.mem binop_precedence c ->
714*9880d681SAndroid Build Coastguard Worker              let token_prec = precedence c in
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker              (* If this is a binop that binds at least as tightly as the current binop,
717*9880d681SAndroid Build Coastguard Worker               * consume it, otherwise we are done. *)
718*9880d681SAndroid Build Coastguard Worker              if token_prec < expr_prec then lhs else begin
719*9880d681SAndroid Build Coastguard Worker                (* Eat the binop. *)
720*9880d681SAndroid Build Coastguard Worker                Stream.junk stream;
721*9880d681SAndroid Build Coastguard Worker
722*9880d681SAndroid Build Coastguard Worker                (* Parse the primary expression after the binary operator. *)
723*9880d681SAndroid Build Coastguard Worker                let rhs = parse_primary stream in
724*9880d681SAndroid Build Coastguard Worker
725*9880d681SAndroid Build Coastguard Worker                (* Okay, we know this is a binop. *)
726*9880d681SAndroid Build Coastguard Worker                let rhs =
727*9880d681SAndroid Build Coastguard Worker                  match Stream.peek stream with
728*9880d681SAndroid Build Coastguard Worker                  | Some (Token.Kwd c2) ->
729*9880d681SAndroid Build Coastguard Worker                      (* If BinOp binds less tightly with rhs than the operator after
730*9880d681SAndroid Build Coastguard Worker                       * rhs, let the pending operator take rhs as its lhs. *)
731*9880d681SAndroid Build Coastguard Worker                      let next_prec = precedence c2 in
732*9880d681SAndroid Build Coastguard Worker                      if token_prec < next_prec
733*9880d681SAndroid Build Coastguard Worker                      then parse_bin_rhs (token_prec + 1) rhs stream
734*9880d681SAndroid Build Coastguard Worker                      else rhs
735*9880d681SAndroid Build Coastguard Worker                  | _ -> rhs
736*9880d681SAndroid Build Coastguard Worker                in
737*9880d681SAndroid Build Coastguard Worker
738*9880d681SAndroid Build Coastguard Worker                (* Merge lhs/rhs. *)
739*9880d681SAndroid Build Coastguard Worker                let lhs = Ast.Binary (c, lhs, rhs) in
740*9880d681SAndroid Build Coastguard Worker                parse_bin_rhs expr_prec lhs stream
741*9880d681SAndroid Build Coastguard Worker              end
742*9880d681SAndroid Build Coastguard Worker          | _ -> lhs
743*9880d681SAndroid Build Coastguard Worker
744*9880d681SAndroid Build Coastguard Worker        (* expression
745*9880d681SAndroid Build Coastguard Worker         *   ::= primary binoprhs *)
746*9880d681SAndroid Build Coastguard Worker        and parse_expr = parser
747*9880d681SAndroid Build Coastguard Worker          | [< lhs=parse_primary; stream >] -> parse_bin_rhs 0 lhs stream
748*9880d681SAndroid Build Coastguard Worker
749*9880d681SAndroid Build Coastguard Worker        (* prototype
750*9880d681SAndroid Build Coastguard Worker         *   ::= id '(' id* ')' *)
751*9880d681SAndroid Build Coastguard Worker        let parse_prototype =
752*9880d681SAndroid Build Coastguard Worker          let rec parse_args accumulator = parser
753*9880d681SAndroid Build Coastguard Worker            | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
754*9880d681SAndroid Build Coastguard Worker            | [< >] -> accumulator
755*9880d681SAndroid Build Coastguard Worker          in
756*9880d681SAndroid Build Coastguard Worker
757*9880d681SAndroid Build Coastguard Worker          parser
758*9880d681SAndroid Build Coastguard Worker          | [< 'Token.Ident id;
759*9880d681SAndroid Build Coastguard Worker               'Token.Kwd '(' ?? "expected '(' in prototype";
760*9880d681SAndroid Build Coastguard Worker               args=parse_args [];
761*9880d681SAndroid Build Coastguard Worker               'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
762*9880d681SAndroid Build Coastguard Worker              (* success. *)
763*9880d681SAndroid Build Coastguard Worker              Ast.Prototype (id, Array.of_list (List.rev args))
764*9880d681SAndroid Build Coastguard Worker
765*9880d681SAndroid Build Coastguard Worker          | [< >] ->
766*9880d681SAndroid Build Coastguard Worker              raise (Stream.Error "expected function name in prototype")
767*9880d681SAndroid Build Coastguard Worker
768*9880d681SAndroid Build Coastguard Worker        (* definition ::= 'def' prototype expression *)
769*9880d681SAndroid Build Coastguard Worker        let parse_definition = parser
770*9880d681SAndroid Build Coastguard Worker          | [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
771*9880d681SAndroid Build Coastguard Worker              Ast.Function (p, e)
772*9880d681SAndroid Build Coastguard Worker
773*9880d681SAndroid Build Coastguard Worker        (* toplevelexpr ::= expression *)
774*9880d681SAndroid Build Coastguard Worker        let parse_toplevel = parser
775*9880d681SAndroid Build Coastguard Worker          | [< e=parse_expr >] ->
776*9880d681SAndroid Build Coastguard Worker              (* Make an anonymous proto. *)
777*9880d681SAndroid Build Coastguard Worker              Ast.Function (Ast.Prototype ("", [||]), e)
778*9880d681SAndroid Build Coastguard Worker
779*9880d681SAndroid Build Coastguard Worker        (*  external ::= 'extern' prototype *)
780*9880d681SAndroid Build Coastguard Worker        let parse_extern = parser
781*9880d681SAndroid Build Coastguard Worker          | [< 'Token.Extern; e=parse_prototype >] -> e
782*9880d681SAndroid Build Coastguard Worker
783*9880d681SAndroid Build Coastguard Workercodegen.ml:
784*9880d681SAndroid Build Coastguard Worker    .. code-block:: ocaml
785*9880d681SAndroid Build Coastguard Worker
786*9880d681SAndroid Build Coastguard Worker        (*===----------------------------------------------------------------------===
787*9880d681SAndroid Build Coastguard Worker         * Code Generation
788*9880d681SAndroid Build Coastguard Worker         *===----------------------------------------------------------------------===*)
789*9880d681SAndroid Build Coastguard Worker
790*9880d681SAndroid Build Coastguard Worker        open Llvm
791*9880d681SAndroid Build Coastguard Worker
792*9880d681SAndroid Build Coastguard Worker        exception Error of string
793*9880d681SAndroid Build Coastguard Worker
794*9880d681SAndroid Build Coastguard Worker        let context = global_context ()
795*9880d681SAndroid Build Coastguard Worker        let the_module = create_module context "my cool jit"
796*9880d681SAndroid Build Coastguard Worker        let builder = builder context
797*9880d681SAndroid Build Coastguard Worker        let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
798*9880d681SAndroid Build Coastguard Worker        let double_type = double_type context
799*9880d681SAndroid Build Coastguard Worker
800*9880d681SAndroid Build Coastguard Worker        let rec codegen_expr = function
801*9880d681SAndroid Build Coastguard Worker          | Ast.Number n -> const_float double_type n
802*9880d681SAndroid Build Coastguard Worker          | Ast.Variable name ->
803*9880d681SAndroid Build Coastguard Worker              (try Hashtbl.find named_values name with
804*9880d681SAndroid Build Coastguard Worker                | Not_found -> raise (Error "unknown variable name"))
805*9880d681SAndroid Build Coastguard Worker          | Ast.Binary (op, lhs, rhs) ->
806*9880d681SAndroid Build Coastguard Worker              let lhs_val = codegen_expr lhs in
807*9880d681SAndroid Build Coastguard Worker              let rhs_val = codegen_expr rhs in
808*9880d681SAndroid Build Coastguard Worker              begin
809*9880d681SAndroid Build Coastguard Worker                match op with
810*9880d681SAndroid Build Coastguard Worker                | '+' -> build_add lhs_val rhs_val "addtmp" builder
811*9880d681SAndroid Build Coastguard Worker                | '-' -> build_sub lhs_val rhs_val "subtmp" builder
812*9880d681SAndroid Build Coastguard Worker                | '*' -> build_mul lhs_val rhs_val "multmp" builder
813*9880d681SAndroid Build Coastguard Worker                | '<' ->
814*9880d681SAndroid Build Coastguard Worker                    (* Convert bool 0/1 to double 0.0 or 1.0 *)
815*9880d681SAndroid Build Coastguard Worker                    let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in
816*9880d681SAndroid Build Coastguard Worker                    build_uitofp i double_type "booltmp" builder
817*9880d681SAndroid Build Coastguard Worker                | _ -> raise (Error "invalid binary operator")
818*9880d681SAndroid Build Coastguard Worker              end
819*9880d681SAndroid Build Coastguard Worker          | Ast.Call (callee, args) ->
820*9880d681SAndroid Build Coastguard Worker              (* Look up the name in the module table. *)
821*9880d681SAndroid Build Coastguard Worker              let callee =
822*9880d681SAndroid Build Coastguard Worker                match lookup_function callee the_module with
823*9880d681SAndroid Build Coastguard Worker                | Some callee -> callee
824*9880d681SAndroid Build Coastguard Worker                | None -> raise (Error "unknown function referenced")
825*9880d681SAndroid Build Coastguard Worker              in
826*9880d681SAndroid Build Coastguard Worker              let params = params callee in
827*9880d681SAndroid Build Coastguard Worker
828*9880d681SAndroid Build Coastguard Worker              (* If argument mismatch error. *)
829*9880d681SAndroid Build Coastguard Worker              if Array.length params == Array.length args then () else
830*9880d681SAndroid Build Coastguard Worker                raise (Error "incorrect # arguments passed");
831*9880d681SAndroid Build Coastguard Worker              let args = Array.map codegen_expr args in
832*9880d681SAndroid Build Coastguard Worker              build_call callee args "calltmp" builder
833*9880d681SAndroid Build Coastguard Worker
834*9880d681SAndroid Build Coastguard Worker        let codegen_proto = function
835*9880d681SAndroid Build Coastguard Worker          | Ast.Prototype (name, args) ->
836*9880d681SAndroid Build Coastguard Worker              (* Make the function type: double(double,double) etc. *)
837*9880d681SAndroid Build Coastguard Worker              let doubles = Array.make (Array.length args) double_type in
838*9880d681SAndroid Build Coastguard Worker              let ft = function_type double_type doubles in
839*9880d681SAndroid Build Coastguard Worker              let f =
840*9880d681SAndroid Build Coastguard Worker                match lookup_function name the_module with
841*9880d681SAndroid Build Coastguard Worker                | None -> declare_function name ft the_module
842*9880d681SAndroid Build Coastguard Worker
843*9880d681SAndroid Build Coastguard Worker                (* If 'f' conflicted, there was already something named 'name'. If it
844*9880d681SAndroid Build Coastguard Worker                 * has a body, don't allow redefinition or reextern. *)
845*9880d681SAndroid Build Coastguard Worker                | Some f ->
846*9880d681SAndroid Build Coastguard Worker                    (* If 'f' already has a body, reject this. *)
847*9880d681SAndroid Build Coastguard Worker                    if block_begin f <> At_end f then
848*9880d681SAndroid Build Coastguard Worker                      raise (Error "redefinition of function");
849*9880d681SAndroid Build Coastguard Worker
850*9880d681SAndroid Build Coastguard Worker                    (* If 'f' took a different number of arguments, reject. *)
851*9880d681SAndroid Build Coastguard Worker                    if element_type (type_of f) <> ft then
852*9880d681SAndroid Build Coastguard Worker                      raise (Error "redefinition of function with different # args");
853*9880d681SAndroid Build Coastguard Worker                    f
854*9880d681SAndroid Build Coastguard Worker              in
855*9880d681SAndroid Build Coastguard Worker
856*9880d681SAndroid Build Coastguard Worker              (* Set names for all arguments. *)
857*9880d681SAndroid Build Coastguard Worker              Array.iteri (fun i a ->
858*9880d681SAndroid Build Coastguard Worker                let n = args.(i) in
859*9880d681SAndroid Build Coastguard Worker                set_value_name n a;
860*9880d681SAndroid Build Coastguard Worker                Hashtbl.add named_values n a;
861*9880d681SAndroid Build Coastguard Worker              ) (params f);
862*9880d681SAndroid Build Coastguard Worker              f
863*9880d681SAndroid Build Coastguard Worker
864*9880d681SAndroid Build Coastguard Worker        let codegen_func = function
865*9880d681SAndroid Build Coastguard Worker          | Ast.Function (proto, body) ->
866*9880d681SAndroid Build Coastguard Worker              Hashtbl.clear named_values;
867*9880d681SAndroid Build Coastguard Worker              let the_function = codegen_proto proto in
868*9880d681SAndroid Build Coastguard Worker
869*9880d681SAndroid Build Coastguard Worker              (* Create a new basic block to start insertion into. *)
870*9880d681SAndroid Build Coastguard Worker              let bb = append_block context "entry" the_function in
871*9880d681SAndroid Build Coastguard Worker              position_at_end bb builder;
872*9880d681SAndroid Build Coastguard Worker
873*9880d681SAndroid Build Coastguard Worker              try
874*9880d681SAndroid Build Coastguard Worker                let ret_val = codegen_expr body in
875*9880d681SAndroid Build Coastguard Worker
876*9880d681SAndroid Build Coastguard Worker                (* Finish off the function. *)
877*9880d681SAndroid Build Coastguard Worker                let _ = build_ret ret_val builder in
878*9880d681SAndroid Build Coastguard Worker
879*9880d681SAndroid Build Coastguard Worker                (* Validate the generated code, checking for consistency. *)
880*9880d681SAndroid Build Coastguard Worker                Llvm_analysis.assert_valid_function the_function;
881*9880d681SAndroid Build Coastguard Worker
882*9880d681SAndroid Build Coastguard Worker                the_function
883*9880d681SAndroid Build Coastguard Worker              with e ->
884*9880d681SAndroid Build Coastguard Worker                delete_function the_function;
885*9880d681SAndroid Build Coastguard Worker                raise e
886*9880d681SAndroid Build Coastguard Worker
887*9880d681SAndroid Build Coastguard Workertoplevel.ml:
888*9880d681SAndroid Build Coastguard Worker    .. code-block:: ocaml
889*9880d681SAndroid Build Coastguard Worker
890*9880d681SAndroid Build Coastguard Worker        (*===----------------------------------------------------------------------===
891*9880d681SAndroid Build Coastguard Worker         * Top-Level parsing and JIT Driver
892*9880d681SAndroid Build Coastguard Worker         *===----------------------------------------------------------------------===*)
893*9880d681SAndroid Build Coastguard Worker
894*9880d681SAndroid Build Coastguard Worker        open Llvm
895*9880d681SAndroid Build Coastguard Worker
896*9880d681SAndroid Build Coastguard Worker        (* top ::= definition | external | expression | ';' *)
897*9880d681SAndroid Build Coastguard Worker        let rec main_loop stream =
898*9880d681SAndroid Build Coastguard Worker          match Stream.peek stream with
899*9880d681SAndroid Build Coastguard Worker          | None -> ()
900*9880d681SAndroid Build Coastguard Worker
901*9880d681SAndroid Build Coastguard Worker          (* ignore top-level semicolons. *)
902*9880d681SAndroid Build Coastguard Worker          | Some (Token.Kwd ';') ->
903*9880d681SAndroid Build Coastguard Worker              Stream.junk stream;
904*9880d681SAndroid Build Coastguard Worker              main_loop stream
905*9880d681SAndroid Build Coastguard Worker
906*9880d681SAndroid Build Coastguard Worker          | Some token ->
907*9880d681SAndroid Build Coastguard Worker              begin
908*9880d681SAndroid Build Coastguard Worker                try match token with
909*9880d681SAndroid Build Coastguard Worker                | Token.Def ->
910*9880d681SAndroid Build Coastguard Worker                    let e = Parser.parse_definition stream in
911*9880d681SAndroid Build Coastguard Worker                    print_endline "parsed a function definition.";
912*9880d681SAndroid Build Coastguard Worker                    dump_value (Codegen.codegen_func e);
913*9880d681SAndroid Build Coastguard Worker                | Token.Extern ->
914*9880d681SAndroid Build Coastguard Worker                    let e = Parser.parse_extern stream in
915*9880d681SAndroid Build Coastguard Worker                    print_endline "parsed an extern.";
916*9880d681SAndroid Build Coastguard Worker                    dump_value (Codegen.codegen_proto e);
917*9880d681SAndroid Build Coastguard Worker                | _ ->
918*9880d681SAndroid Build Coastguard Worker                    (* Evaluate a top-level expression into an anonymous function. *)
919*9880d681SAndroid Build Coastguard Worker                    let e = Parser.parse_toplevel stream in
920*9880d681SAndroid Build Coastguard Worker                    print_endline "parsed a top-level expr";
921*9880d681SAndroid Build Coastguard Worker                    dump_value (Codegen.codegen_func e);
922*9880d681SAndroid Build Coastguard Worker                with Stream.Error s | Codegen.Error s ->
923*9880d681SAndroid Build Coastguard Worker                  (* Skip token for error recovery. *)
924*9880d681SAndroid Build Coastguard Worker                  Stream.junk stream;
925*9880d681SAndroid Build Coastguard Worker                  print_endline s;
926*9880d681SAndroid Build Coastguard Worker              end;
927*9880d681SAndroid Build Coastguard Worker              print_string "ready> "; flush stdout;
928*9880d681SAndroid Build Coastguard Worker              main_loop stream
929*9880d681SAndroid Build Coastguard Worker
930*9880d681SAndroid Build Coastguard Workertoy.ml:
931*9880d681SAndroid Build Coastguard Worker    .. code-block:: ocaml
932*9880d681SAndroid Build Coastguard Worker
933*9880d681SAndroid Build Coastguard Worker        (*===----------------------------------------------------------------------===
934*9880d681SAndroid Build Coastguard Worker         * Main driver code.
935*9880d681SAndroid Build Coastguard Worker         *===----------------------------------------------------------------------===*)
936*9880d681SAndroid Build Coastguard Worker
937*9880d681SAndroid Build Coastguard Worker        open Llvm
938*9880d681SAndroid Build Coastguard Worker
939*9880d681SAndroid Build Coastguard Worker        let main () =
940*9880d681SAndroid Build Coastguard Worker          (* Install standard binary operators.
941*9880d681SAndroid Build Coastguard Worker           * 1 is the lowest precedence. *)
942*9880d681SAndroid Build Coastguard Worker          Hashtbl.add Parser.binop_precedence '<' 10;
943*9880d681SAndroid Build Coastguard Worker          Hashtbl.add Parser.binop_precedence '+' 20;
944*9880d681SAndroid Build Coastguard Worker          Hashtbl.add Parser.binop_precedence '-' 20;
945*9880d681SAndroid Build Coastguard Worker          Hashtbl.add Parser.binop_precedence '*' 40;    (* highest. *)
946*9880d681SAndroid Build Coastguard Worker
947*9880d681SAndroid Build Coastguard Worker          (* Prime the first token. *)
948*9880d681SAndroid Build Coastguard Worker          print_string "ready> "; flush stdout;
949*9880d681SAndroid Build Coastguard Worker          let stream = Lexer.lex (Stream.of_channel stdin) in
950*9880d681SAndroid Build Coastguard Worker
951*9880d681SAndroid Build Coastguard Worker          (* Run the main "interpreter loop" now. *)
952*9880d681SAndroid Build Coastguard Worker          Toplevel.main_loop stream;
953*9880d681SAndroid Build Coastguard Worker
954*9880d681SAndroid Build Coastguard Worker          (* Print out all the generated code. *)
955*9880d681SAndroid Build Coastguard Worker          dump_module Codegen.the_module
956*9880d681SAndroid Build Coastguard Worker        ;;
957*9880d681SAndroid Build Coastguard Worker
958*9880d681SAndroid Build Coastguard Worker        main ()
959*9880d681SAndroid Build Coastguard Worker
960*9880d681SAndroid Build Coastguard Worker`Next: Adding JIT and Optimizer Support <OCamlLangImpl4.html>`_
961*9880d681SAndroid Build Coastguard Worker
962