==================================================
Kaleidoscope: Extending the Language: Control Flow
==================================================

.. contents::
   :local:

Written by `Chris Lattner <mailto:sabre@nondot.org>`_ and `Erick
Tryzelaar <mailto:idadesub@users.sourceforge.net>`_

Chapter 5 Introduction
======================

Welcome to Chapter 5 of the "`Implementing a language with
LLVM <index.html>`_" tutorial. Parts 1-4 described the implementation of
the simple Kaleidoscope language and included support for generating
LLVM IR, followed by optimizations and a JIT compiler. Unfortunately, as
presented, Kaleidoscope is mostly useless: it has no control flow other
than call and return. This means that you can't have conditional
branches in the code, significantly limiting its power. In this episode
of "build that compiler", we'll extend Kaleidoscope to have an
if/then/else expression plus a simple 'for' loop.

If/Then/Else
============

Extending Kaleidoscope to support if/then/else is quite straightforward.
It basically requires adding lexer support for this "new" concept to the
lexer, parser, AST, and LLVM code emitter. This example is nice, because
it shows how easy it is to "grow" a language over time, incrementally
extending it as new ideas are discovered.

Before we get going on "how" we add this extension, lets talk about
"what" we want. The basic idea is that we want to be able to write this
sort of thing:

::

    def fib(x)
      if x < 3 then
        1
      else
        fib(x-1)+fib(x-2);

In Kaleidoscope, every construct is an expression: there are no
statements. As such, the if/then/else expression needs to return a value
like any other. Since we're using a mostly functional form, we'll have
it evaluate its conditional, then return the 'then' or 'else' value
based on how the condition was resolved. This is very similar to the C
"?:" expression.

The semantics of the if/then/else expression is that it evaluates the
condition to a boolean equality value: 0.0 is considered to be false and
everything else is considered to be true. If the condition is true, the
first subexpression is evaluated and returned, if the condition is
false, the second subexpression is evaluated and returned. Since
Kaleidoscope allows side-effects, this behavior is important to nail
down.

Now that we know what we "want", lets break this down into its
constituent pieces.

Lexer Extensions for If/Then/Else
---------------------------------

The lexer extensions are straightforward. First we add new variants for
the relevant tokens:

.. code-block:: ocaml

      (* control *)
      | If | Then | Else | For | In

Once we have that, we recognize the new keywords in the lexer. This is
pretty simple stuff:

.. code-block:: ocaml

          ...
          match Buffer.contents buffer with
          | "def" -> [< 'Token.Def; stream >]
          | "extern" -> [< 'Token.Extern; stream >]
          | "if" -> [< 'Token.If; stream >]
          | "then" -> [< 'Token.Then; stream >]
          | "else" -> [< 'Token.Else; stream >]
          | "for" -> [< 'Token.For; stream >]
          | "in" -> [< 'Token.In; stream >]
          | id -> [< 'Token.Ident id; stream >]

AST Extensions for If/Then/Else
-------------------------------

To represent the new expression we add a new AST variant for it:

.. code-block:: ocaml

    type expr =
      ...
      (* variant for if/then/else. *)
      | If of expr * expr * expr

The AST variant just has pointers to the various subexpressions.

Parser Extensions for If/Then/Else
----------------------------------

Now that we have the relevant tokens coming from the lexer and we have
the AST node to build, our parsing logic is relatively straightforward.
First we define a new parsing function:

.. code-block:: ocaml

    let rec parse_primary = parser
      ...
      (* ifexpr ::= 'if' expr 'then' expr 'else' expr *)
      | [< 'Token.If; c=parse_expr;
           'Token.Then ?? "expected 'then'"; t=parse_expr;
           'Token.Else ?? "expected 'else'"; e=parse_expr >] ->
          Ast.If (c, t, e)

Next we hook it up as a primary expression:

.. code-block:: ocaml

    let rec parse_primary = parser
      ...
      (* ifexpr ::= 'if' expr 'then' expr 'else' expr *)
      | [< 'Token.If; c=parse_expr;
           'Token.Then ?? "expected 'then'"; t=parse_expr;
           'Token.Else ?? "expected 'else'"; e=parse_expr >] ->
          Ast.If (c, t, e)

LLVM IR for If/Then/Else
------------------------

Now that we have it parsing and building the AST, the final piece is
adding LLVM code generation support. This is the most interesting part
of the if/then/else example, because this is where it starts to
introduce new concepts. All of the code above has been thoroughly
described in previous chapters.

To motivate the code we want to produce, lets take a look at a simple
example. Consider:

::

    extern foo();
    extern bar();
    def baz(x) if x then foo() else bar();

If you disable optimizations, the code you'll (soon) get from
Kaleidoscope looks like this:

.. code-block:: llvm

    declare double @foo()

    declare double @bar()

    define double @baz(double %x) {
    entry:
      %ifcond = fcmp one double %x, 0.000000e+00
      br i1 %ifcond, label %then, label %else

    then:    ; preds = %entry
      %calltmp = call double @foo()
      br label %ifcont

    else:    ; preds = %entry
      %calltmp1 = call double @bar()
      br label %ifcont

    ifcont:    ; preds = %else, %then
      %iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ]
      ret double %iftmp
    }

To visualize the control flow graph, you can use a nifty feature of the
LLVM '`opt <http://llvm.org/cmds/opt.html>`_' tool. If you put this LLVM
IR into "t.ll" and run "``llvm-as < t.ll | opt -analyze -view-cfg``", `a
window will pop up <../ProgrammersManual.html#ViewGraph>`_ and you'll
see this graph:

.. figure:: LangImpl5-cfg.png
   :align: center
   :alt: Example CFG

   Example CFG

Another way to get this is to call
"``Llvm_analysis.view_function_cfg f``" or
"``Llvm_analysis.view_function_cfg_only f``" (where ``f`` is a
"``Function``") either by inserting actual calls into the code and
recompiling or by calling these in the debugger. LLVM has many nice
features for visualizing various graphs.

Getting back to the generated code, it is fairly simple: the entry block
evaluates the conditional expression ("x" in our case here) and compares
the result to 0.0 with the "``fcmp one``" instruction ('one' is "Ordered
and Not Equal"). Based on the result of this expression, the code jumps
to either the "then" or "else" blocks, which contain the expressions for
the true/false cases.

Once the then/else blocks are finished executing, they both branch back
to the 'ifcont' block to execute the code that happens after the
if/then/else. In this case the only thing left to do is to return to the
caller of the function. The question then becomes: how does the code
know which expression to return?

The answer to this question involves an important SSA operation: the
`Phi
operation <http://en.wikipedia.org/wiki/Static_single_assignment_form>`_.
If you're not familiar with SSA, `the wikipedia
article <http://en.wikipedia.org/wiki/Static_single_assignment_form>`_
is a good introduction and there are various other introductions to it
available on your favorite search engine. The short version is that
"execution" of the Phi operation requires "remembering" which block
control came from. The Phi operation takes on the value corresponding to
the input control block. In this case, if control comes in from the
"then" block, it gets the value of "calltmp". If control comes from the
"else" block, it gets the value of "calltmp1".

At this point, you are probably starting to think "Oh no! This means my
simple and elegant front-end will have to start generating SSA form in
order to use LLVM!". Fortunately, this is not the case, and we strongly
advise *not* implementing an SSA construction algorithm in your
front-end unless there is an amazingly good reason to do so. In
practice, there are two sorts of values that float around in code
written for your average imperative programming language that might need
Phi nodes:

#. Code that involves user variables: ``x = 1; x = x + 1;``
#. Values that are implicit in the structure of your AST, such as the
   Phi node in this case.

In `Chapter 7 <OCamlLangImpl7.html>`_ of this tutorial ("mutable
variables"), we'll talk about #1 in depth. For now, just believe me that
you don't need SSA construction to handle this case. For #2, you have
the choice of using the techniques that we will describe for #1, or you
can insert Phi nodes directly, if convenient. In this case, it is really
really easy to generate the Phi node, so we choose to do it directly.

Okay, enough of the motivation and overview, lets generate code!

Code Generation for If/Then/Else
--------------------------------

In order to generate code for this, we implement the ``Codegen`` method
for ``IfExprAST``:

.. code-block:: ocaml

    let rec codegen_expr = function
      ...
      | Ast.If (cond, then_, else_) ->
          let cond = codegen_expr cond in

          (* Convert condition to a bool by comparing equal to 0.0 *)
          let zero = const_float double_type 0.0 in
          let cond_val = build_fcmp Fcmp.One cond zero "ifcond" builder in

This code is straightforward and similar to what we saw before. We emit
the expression for the condition, then compare that value to zero to get
a truth value as a 1-bit (bool) value.

.. code-block:: ocaml

          (* Grab the first block so that we might later add the conditional branch
           * to it at the end of the function. *)
          let start_bb = insertion_block builder in
          let the_function = block_parent start_bb in

          let then_bb = append_block context "then" the_function in
          position_at_end then_bb builder;

As opposed to the `C++ tutorial <LangImpl5.html>`_, we have to build our
basic blocks bottom up since we can't have dangling BasicBlocks. We
start off by saving a pointer to the first block (which might not be the
entry block), which we'll need to build a conditional branch later. We
do this by asking the ``builder`` for the current BasicBlock. The fourth
line gets the current Function object that is being built. It gets this
by the ``start_bb`` for its "parent" (the function it is currently
embedded into).

Once it has that, it creates one block. It is automatically appended
into the function's list of blocks.

.. code-block:: ocaml

          (* Emit 'then' value. *)
          position_at_end then_bb builder;
          let then_val = codegen_expr then_ in

          (* Codegen of 'then' can change the current block, update then_bb for the
           * phi. We create a new name because one is used for the phi node, and the
           * other is used for the conditional branch. *)
          let new_then_bb = insertion_block builder in

We move the builder to start inserting into the "then" block. Strictly
speaking, this call moves the insertion point to be at the end of the
specified block. However, since the "then" block is empty, it also
starts out by inserting at the beginning of the block. :)

Once the insertion point is set, we recursively codegen the "then"
expression from the AST.

The final line here is quite subtle, but is very important. The basic
issue is that when we create the Phi node in the merge block, we need to
set up the block/value pairs that indicate how the Phi will work.
Importantly, the Phi node expects to have an entry for each predecessor
of the block in the CFG. Why then, are we getting the current block when
we just set it to ThenBB 5 lines above? The problem is that the "Then"
expression may actually itself change the block that the Builder is
emitting into if, for example, it contains a nested "if/then/else"
expression. Because calling Codegen recursively could arbitrarily change
the notion of the current block, we are required to get an up-to-date
value for code that will set up the Phi node.

.. code-block:: ocaml

          (* Emit 'else' value. *)
          let else_bb = append_block context "else" the_function in
          position_at_end else_bb builder;
          let else_val = codegen_expr else_ in

          (* Codegen of 'else' can change the current block, update else_bb for the
           * phi. *)
          let new_else_bb = insertion_block builder in

Code generation for the 'else' block is basically identical to codegen
for the 'then' block.

.. code-block:: ocaml

          (* Emit merge block. *)
          let merge_bb = append_block context "ifcont" the_function in
          position_at_end merge_bb builder;
          let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
          let phi = build_phi incoming "iftmp" builder in

The first two lines here are now familiar: the first adds the "merge"
block to the Function object. The second block changes the insertion
point so that newly created code will go into the "merge" block. Once
that is done, we need to create the PHI node and set up the block/value
pairs for the PHI.

.. code-block:: ocaml

          (* Return to the start block to add the conditional branch. *)
          position_at_end start_bb builder;
          ignore (build_cond_br cond_val then_bb else_bb builder);

Once the blocks are created, we can emit the conditional branch that
chooses between them. Note that creating new blocks does not implicitly
affect the IRBuilder, so it is still inserting into the block that the
condition went into. This is why we needed to save the "start" block.

.. code-block:: ocaml

          (* Set a unconditional branch at the end of the 'then' block and the
           * 'else' block to the 'merge' block. *)
          position_at_end new_then_bb builder; ignore (build_br merge_bb builder);
          position_at_end new_else_bb builder; ignore (build_br merge_bb builder);

          (* Finally, set the builder to the end of the merge block. *)
          position_at_end merge_bb builder;

          phi

To finish off the blocks, we create an unconditional branch to the merge
block. One interesting (and very important) aspect of the LLVM IR is
that it `requires all basic blocks to be
"terminated" <../LangRef.html#functionstructure>`_ with a `control flow
instruction <../LangRef.html#terminators>`_ such as return or branch.
This means that all control flow, *including fall throughs* must be made
explicit in the LLVM IR. If you violate this rule, the verifier will
emit an error.

Finally, the CodeGen function returns the phi node as the value computed
by the if/then/else expression. In our example above, this returned
value will feed into the code for the top-level function, which will
create the return instruction.

Overall, we now have the ability to execute conditional code in
Kaleidoscope. With this extension, Kaleidoscope is a fairly complete
language that can calculate a wide variety of numeric functions. Next up
we'll add another useful expression that is familiar from non-functional
languages...

'for' Loop Expression
=====================

Now that we know how to add basic control flow constructs to the
language, we have the tools to add more powerful things. Lets add
something more aggressive, a 'for' expression:

::

     extern putchard(char);
     def printstar(n)
       for i = 1, i < n, 1.0 in
         putchard(42);  # ascii 42 = '*'

     # print 100 '*' characters
     printstar(100);

This expression defines a new variable ("i" in this case) which iterates
from a starting value, while the condition ("i < n" in this case) is
true, incrementing by an optional step value ("1.0" in this case). If
the step value is omitted, it defaults to 1.0. While the loop is true,
it executes its body expression. Because we don't have anything better
to return, we'll just define the loop as always returning 0.0. In the
future when we have mutable variables, it will get more useful.

As before, lets talk about the changes that we need to Kaleidoscope to
support this.

Lexer Extensions for the 'for' Loop
-----------------------------------

The lexer extensions are the same sort of thing as for if/then/else:

.. code-block:: ocaml

      ... in Token.token ...
      (* control *)
      | If | Then | Else
      | For | In

      ... in Lexer.lex_ident...
          match Buffer.contents buffer with
          | "def" -> [< 'Token.Def; stream >]
          | "extern" -> [< 'Token.Extern; stream >]
          | "if" -> [< 'Token.If; stream >]
          | "then" -> [< 'Token.Then; stream >]
          | "else" -> [< 'Token.Else; stream >]
          | "for" -> [< 'Token.For; stream >]
          | "in" -> [< 'Token.In; stream >]
          | id -> [< 'Token.Ident id; stream >]

AST Extensions for the 'for' Loop
---------------------------------

The AST variant is just as simple. It basically boils down to capturing
the variable name and the constituent expressions in the node.

.. code-block:: ocaml

    type expr =
      ...
      (* variant for for/in. *)
      | For of string * expr * expr * expr option * expr

Parser Extensions for the 'for' Loop
------------------------------------

The parser code is also fairly standard. The only interesting thing here
is handling of the optional step value. The parser code handles it by
checking to see if the second comma is present. If not, it sets the step
value to null in the AST node:

.. code-block:: ocaml

    let rec parse_primary = parser
      ...
      (* forexpr
            ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)
      | [< 'Token.For;
           'Token.Ident id ?? "expected identifier after for";
           'Token.Kwd '=' ?? "expected '=' after for";
           stream >] ->
          begin parser
            | [<
                 start=parse_expr;
                 'Token.Kwd ',' ?? "expected ',' after for";
                 end_=parse_expr;
                 stream >] ->
                let step =
                  begin parser
                  | [< 'Token.Kwd ','; step=parse_expr >] -> Some step
                  | [< >] -> None
                  end stream
                in
                begin parser
                | [< 'Token.In; body=parse_expr >] ->
                    Ast.For (id, start, end_, step, body)
                | [< >] ->
                    raise (Stream.Error "expected 'in' after for")
                end stream
            | [< >] ->
                raise (Stream.Error "expected '=' after for")
          end stream

LLVM IR for the 'for' Loop
--------------------------

Now we get to the good part: the LLVM IR we want to generate for this
thing. With the simple example above, we get this LLVM IR (note that
this dump is generated with optimizations disabled for clarity):

.. code-block:: llvm

    declare double @putchard(double)

    define double @printstar(double %n) {
    entry:
            ; initial value = 1.0 (inlined into phi)
      br label %loop

    loop:    ; preds = %loop, %entry
      %i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ]
            ; body
      %calltmp = call double @putchard(double 4.200000e+01)
            ; increment
      %nextvar = fadd double %i, 1.000000e+00

            ; termination test
      %cmptmp = fcmp ult double %i, %n
      %booltmp = uitofp i1 %cmptmp to double
      %loopcond = fcmp one double %booltmp, 0.000000e+00
      br i1 %loopcond, label %loop, label %afterloop

    afterloop:    ; preds = %loop
            ; loop always returns 0.0
      ret double 0.000000e+00
    }

This loop contains all the same constructs we saw before: a phi node,
several expressions, and some basic blocks. Lets see how this fits
together.

Code Generation for the 'for' Loop
----------------------------------

The first part of Codegen is very simple: we just output the start
expression for the loop value:

.. code-block:: ocaml

    let rec codegen_expr = function
      ...
      | Ast.For (var_name, start, end_, step, body) ->
          (* Emit the start code first, without 'variable' in scope. *)
          let start_val = codegen_expr start in

With this out of the way, the next step is to set up the LLVM basic
block for the start of the loop body. In the case above, the whole loop
body is one block, but remember that the body code itself could consist
of multiple blocks (e.g. if it contains an if/then/else or a for/in
expression).

.. code-block:: ocaml

          (* Make the new basic block for the loop header, inserting after current
           * block. *)
          let preheader_bb = insertion_block builder in
          let the_function = block_parent preheader_bb in
          let loop_bb = append_block context "loop" the_function in

          (* Insert an explicit fall through from the current block to the
           * loop_bb. *)
          ignore (build_br loop_bb builder);

This code is similar to what we saw for if/then/else. Because we will
need it to create the Phi node, we remember the block that falls through
into the loop. Once we have that, we create the actual block that starts
the loop and create an unconditional branch for the fall-through between
the two blocks.

.. code-block:: ocaml

          (* Start insertion in loop_bb. *)
          position_at_end loop_bb builder;

          (* Start the PHI node with an entry for start. *)
          let variable = build_phi [(start_val, preheader_bb)] var_name builder in

Now that the "preheader" for the loop is set up, we switch to emitting
code for the loop body. To begin with, we move the insertion point and
create the PHI node for the loop induction variable. Since we already
know the incoming value for the starting value, we add it to the Phi
node. Note that the Phi will eventually get a second value for the
backedge, but we can't set it up yet (because it doesn't exist!).

.. code-block:: ocaml

          (* Within the loop, the variable is defined equal to the PHI node. If it
           * shadows an existing variable, we have to restore it, so save it
           * now. *)
          let old_val =
            try Some (Hashtbl.find named_values var_name) with Not_found -> None
          in
          Hashtbl.add named_values var_name variable;

          (* Emit the body of the loop.  This, like any other expr, can change the
           * current BB.  Note that we ignore the value computed by the body, but
           * don't allow an error *)
          ignore (codegen_expr body);

Now the code starts to get more interesting. Our 'for' loop introduces a
new variable to the symbol table. This means that our symbol table can
now contain either function arguments or loop variables. To handle this,
before we codegen the body of the loop, we add the loop variable as the
current value for its name. Note that it is possible that there is a
variable of the same name in the outer scope. It would be easy to make
this an error (emit an error and return null if there is already an
entry for VarName) but we choose to allow shadowing of variables. In
order to handle this correctly, we remember the Value that we are
potentially shadowing in ``old_val`` (which will be None if there is no
shadowed variable).

Once the loop variable is set into the symbol table, the code
recursively codegen's the body. This allows the body to use the loop
variable: any references to it will naturally find it in the symbol
table.

.. code-block:: ocaml

          (* Emit the step value. *)
          let step_val =
            match step with
            | Some step -> codegen_expr step
            (* If not specified, use 1.0. *)
            | None -> const_float double_type 1.0
          in

          let next_var = build_add variable step_val "nextvar" builder in

Now that the body is emitted, we compute the next value of the iteration
variable by adding the step value, or 1.0 if it isn't present.
'``next_var``' will be the value of the loop variable on the next
iteration of the loop.

.. code-block:: ocaml

          (* Compute the end condition. *)
          let end_cond = codegen_expr end_ in

          (* Convert condition to a bool by comparing equal to 0.0. *)
          let zero = const_float double_type 0.0 in
          let end_cond = build_fcmp Fcmp.One end_cond zero "loopcond" builder in

Finally, we evaluate the exit value of the loop, to determine whether
the loop should exit. This mirrors the condition evaluation for the
if/then/else statement.

.. code-block:: ocaml

          (* Create the "after loop" block and insert it. *)
          let loop_end_bb = insertion_block builder in
          let after_bb = append_block context "afterloop" the_function in

          (* Insert the conditional branch into the end of loop_end_bb. *)
          ignore (build_cond_br end_cond loop_bb after_bb builder);

          (* Any new code will be inserted in after_bb. *)
          position_at_end after_bb builder;

With the code for the body of the loop complete, we just need to finish
up the control flow for it. This code remembers the end block (for the
phi node), then creates the block for the loop exit ("afterloop"). Based
on the value of the exit condition, it creates a conditional branch that
chooses between executing the loop again and exiting the loop. Any
future code is emitted in the "afterloop" block, so it sets the
insertion position to it.

.. code-block:: ocaml

          (* Add a new entry to the PHI node for the backedge. *)
          add_incoming (next_var, loop_end_bb) variable;

          (* Restore the unshadowed variable. *)
          begin match old_val with
          | Some old_val -> Hashtbl.add named_values var_name old_val
          | None -> ()
          end;

          (* for expr always returns 0.0. *)
          const_null double_type

The final code handles various cleanups: now that we have the
"``next_var``" value, we can add the incoming value to the loop PHI
node. After that, we remove the loop variable from the symbol table, so
that it isn't in scope after the for loop. Finally, code generation of
the for loop always returns 0.0, so that is what we return from
``Codegen.codegen_expr``.

With this, we conclude the "adding control flow to Kaleidoscope" chapter
of the tutorial. In this chapter we added two control flow constructs,
and used them to motivate a couple of aspects of the LLVM IR that are
important for front-end implementors to know. In the next chapter of our
saga, we will get a bit crazier and add `user-defined
operators <OCamlLangImpl6.html>`_ to our poor innocent language.

Full Code Listing
=================

Here is the complete code listing for our running example, enhanced with
the if/then/else and for expressions.. To build this example, use:

.. code-block:: bash

    # Compile
    ocamlbuild toy.byte
    # Run
    ./toy.byte

Here is the code:

\_tags:
    ::

        <{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
        <*.{byte,native}>: g++, use_llvm, use_llvm_analysis
        <*.{byte,native}>: use_llvm_executionengine, use_llvm_target
        <*.{byte,native}>: use_llvm_scalar_opts, use_bindings

myocamlbuild.ml:
    .. code-block:: ocaml

        open Ocamlbuild_plugin;;

        ocaml_lib ~extern:true "llvm";;
        ocaml_lib ~extern:true "llvm_analysis";;
        ocaml_lib ~extern:true "llvm_executionengine";;
        ocaml_lib ~extern:true "llvm_target";;
        ocaml_lib ~extern:true "llvm_scalar_opts";;

        flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);;
        dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];;

token.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Lexer Tokens
         *===----------------------------------------------------------------------===*)

        (* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of
         * these others for known things. *)
        type token =
          (* commands *)
          | Def | Extern

          (* primary *)
          | Ident of string | Number of float

          (* unknown *)
          | Kwd of char

          (* control *)
          | If | Then | Else
          | For | In

lexer.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Lexer
         *===----------------------------------------------------------------------===*)

        let rec lex = parser
          (* Skip any whitespace. *)
          | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream

          (* identifier: [a-zA-Z][a-zA-Z0-9] *)
          | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] ->
              let buffer = Buffer.create 1 in
              Buffer.add_char buffer c;
              lex_ident buffer stream

          (* number: [0-9.]+ *)
          | [< ' ('0' .. '9' as c); stream >] ->
              let buffer = Buffer.create 1 in
              Buffer.add_char buffer c;
              lex_number buffer stream

          (* Comment until end of line. *)
          | [< ' ('#'); stream >] ->
              lex_comment stream

          (* Otherwise, just return the character as its ascii value. *)
          | [< 'c; stream >] ->
              [< 'Token.Kwd c; lex stream >]

          (* end of stream. *)
          | [< >] -> [< >]

        and lex_number buffer = parser
          | [< ' ('0' .. '9' | '.' as c); stream >] ->
              Buffer.add_char buffer c;
              lex_number buffer stream
          | [< stream=lex >] ->
              [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >]

        and lex_ident buffer = parser
          | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] ->
              Buffer.add_char buffer c;
              lex_ident buffer stream
          | [< stream=lex >] ->
              match Buffer.contents buffer with
              | "def" -> [< 'Token.Def; stream >]
              | "extern" -> [< 'Token.Extern; stream >]
              | "if" -> [< 'Token.If; stream >]
              | "then" -> [< 'Token.Then; stream >]
              | "else" -> [< 'Token.Else; stream >]
              | "for" -> [< 'Token.For; stream >]
              | "in" -> [< 'Token.In; stream >]
              | id -> [< 'Token.Ident id; stream >]

        and lex_comment = parser
          | [< ' ('\n'); stream=lex >] -> stream
          | [< 'c; e=lex_comment >] -> e
          | [< >] -> [< >]

ast.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Abstract Syntax Tree (aka Parse Tree)
         *===----------------------------------------------------------------------===*)

        (* expr - Base type for all expression nodes. *)
        type expr =
          (* variant for numeric literals like "1.0". *)
          | Number of float

          (* variant for referencing a variable, like "a". *)
          | Variable of string

          (* variant for a binary operator. *)
          | Binary of char * expr * expr

          (* variant for function calls. *)
          | Call of string * expr array

          (* variant for if/then/else. *)
          | If of expr * expr * expr

          (* variant for for/in. *)
          | For of string * expr * expr * expr option * expr

        (* proto - This type represents the "prototype" for a function, which captures
         * its name, and its argument names (thus implicitly the number of arguments the
         * function takes). *)
        type proto = Prototype of string * string array

        (* func - This type represents a function definition itself. *)
        type func = Function of proto * expr

parser.ml:
    .. code-block:: ocaml

        (*===---------------------------------------------------------------------===
         * Parser
         *===---------------------------------------------------------------------===*)

        (* binop_precedence - This holds the precedence for each binary operator that is
         * defined *)
        let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10

        (* precedence - Get the precedence of the pending binary operator token. *)
        let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1

        (* primary
         *   ::= identifier
         *   ::= numberexpr
         *   ::= parenexpr
         *   ::= ifexpr
         *   ::= forexpr *)
        let rec parse_primary = parser
          (* numberexpr ::= number *)
          | [< 'Token.Number n >] -> Ast.Number n

          (* parenexpr ::= '(' expression ')' *)
          | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e

          (* identifierexpr
           *   ::= identifier
           *   ::= identifier '(' argumentexpr ')' *)
          | [< 'Token.Ident id; stream >] ->
              let rec parse_args accumulator = parser
                | [< e=parse_expr; stream >] ->
                    begin parser
                      | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e
                      | [< >] -> e :: accumulator
                    end stream
                | [< >] -> accumulator
              in
              let rec parse_ident id = parser
                (* Call. *)
                | [< 'Token.Kwd '(';
                     args=parse_args [];
                     'Token.Kwd ')' ?? "expected ')'">] ->
                    Ast.Call (id, Array.of_list (List.rev args))

                (* Simple variable ref. *)
                | [< >] -> Ast.Variable id
              in
              parse_ident id stream

          (* ifexpr ::= 'if' expr 'then' expr 'else' expr *)
          | [< 'Token.If; c=parse_expr;
               'Token.Then ?? "expected 'then'"; t=parse_expr;
               'Token.Else ?? "expected 'else'"; e=parse_expr >] ->
              Ast.If (c, t, e)

          (* forexpr
                ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)
          | [< 'Token.For;
               'Token.Ident id ?? "expected identifier after for";
               'Token.Kwd '=' ?? "expected '=' after for";
               stream >] ->
              begin parser
                | [<
                     start=parse_expr;
                     'Token.Kwd ',' ?? "expected ',' after for";
                     end_=parse_expr;
                     stream >] ->
                    let step =
                      begin parser
                      | [< 'Token.Kwd ','; step=parse_expr >] -> Some step
                      | [< >] -> None
                      end stream
                    in
                    begin parser
                    | [< 'Token.In; body=parse_expr >] ->
                        Ast.For (id, start, end_, step, body)
                    | [< >] ->
                        raise (Stream.Error "expected 'in' after for")
                    end stream
                | [< >] ->
                    raise (Stream.Error "expected '=' after for")
              end stream

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

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

              (* If this is a binop that binds at least as tightly as the current binop,
               * consume it, otherwise we are done. *)
              if token_prec < expr_prec then lhs else begin
                (* Eat the binop. *)
                Stream.junk stream;

                (* Parse the primary expression after the binary operator. *)
                let rhs = parse_primary stream in

                (* Okay, we know this is a binop. *)
                let rhs =
                  match Stream.peek stream with
                  | Some (Token.Kwd c2) ->
                      (* If BinOp binds less tightly with rhs than the operator after
                       * rhs, let the pending operator take rhs as its lhs. *)
                      let next_prec = precedence c2 in
                      if token_prec < next_prec
                      then parse_bin_rhs (token_prec + 1) rhs stream
                      else rhs
                  | _ -> rhs
                in

                (* Merge lhs/rhs. *)
                let lhs = Ast.Binary (c, lhs, rhs) in
                parse_bin_rhs expr_prec lhs stream
              end
          | _ -> lhs

        (* expression
         *   ::= primary binoprhs *)
        and parse_expr = parser
          | [< lhs=parse_primary; stream >] -> parse_bin_rhs 0 lhs stream

        (* prototype
         *   ::= id '(' id* ')' *)
        let parse_prototype =
          let rec parse_args accumulator = parser
            | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
            | [< >] -> accumulator
          in

          parser
          | [< 'Token.Ident id;
               'Token.Kwd '(' ?? "expected '(' in prototype";
               args=parse_args [];
               'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
              (* success. *)
              Ast.Prototype (id, Array.of_list (List.rev args))

          | [< >] ->
              raise (Stream.Error "expected function name in prototype")

        (* definition ::= 'def' prototype expression *)
        let parse_definition = parser
          | [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
              Ast.Function (p, e)

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

        (*  external ::= 'extern' prototype *)
        let parse_extern = parser
          | [< 'Token.Extern; e=parse_prototype >] -> e

codegen.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Code Generation
         *===----------------------------------------------------------------------===*)

        open Llvm

        exception Error of string

        let context = global_context ()
        let the_module = create_module context "my cool jit"
        let builder = builder context
        let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
        let double_type = double_type context

        let rec codegen_expr = function
          | Ast.Number n -> const_float double_type n
          | Ast.Variable name ->
              (try Hashtbl.find named_values name with
                | Not_found -> raise (Error "unknown variable name"))
          | Ast.Binary (op, lhs, rhs) ->
              let lhs_val = codegen_expr lhs in
              let rhs_val = codegen_expr rhs in
              begin
                match op with
                | '+' -> build_add lhs_val rhs_val "addtmp" builder
                | '-' -> build_sub lhs_val rhs_val "subtmp" builder
                | '*' -> build_mul lhs_val rhs_val "multmp" builder
                | '<' ->
                    (* Convert bool 0/1 to double 0.0 or 1.0 *)
                    let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in
                    build_uitofp i double_type "booltmp" builder
                | _ -> raise (Error "invalid binary operator")
              end
          | Ast.Call (callee, args) ->
              (* Look up the name in the module table. *)
              let callee =
                match lookup_function callee the_module with
                | Some callee -> callee
                | None -> raise (Error "unknown function referenced")
              in
              let params = params callee in

              (* If argument mismatch error. *)
              if Array.length params == Array.length args then () else
                raise (Error "incorrect # arguments passed");
              let args = Array.map codegen_expr args in
              build_call callee args "calltmp" builder
          | Ast.If (cond, then_, else_) ->
              let cond = codegen_expr cond in

              (* Convert condition to a bool by comparing equal to 0.0 *)
              let zero = const_float double_type 0.0 in
              let cond_val = build_fcmp Fcmp.One cond zero "ifcond" builder in

              (* Grab the first block so that we might later add the conditional branch
               * to it at the end of the function. *)
              let start_bb = insertion_block builder in
              let the_function = block_parent start_bb in

              let then_bb = append_block context "then" the_function in

              (* Emit 'then' value. *)
              position_at_end then_bb builder;
              let then_val = codegen_expr then_ in

              (* Codegen of 'then' can change the current block, update then_bb for the
               * phi. We create a new name because one is used for the phi node, and the
               * other is used for the conditional branch. *)
              let new_then_bb = insertion_block builder in

              (* Emit 'else' value. *)
              let else_bb = append_block context "else" the_function in
              position_at_end else_bb builder;
              let else_val = codegen_expr else_ in

              (* Codegen of 'else' can change the current block, update else_bb for the
               * phi. *)
              let new_else_bb = insertion_block builder in

              (* Emit merge block. *)
              let merge_bb = append_block context "ifcont" the_function in
              position_at_end merge_bb builder;
              let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
              let phi = build_phi incoming "iftmp" builder in

              (* Return to the start block to add the conditional branch. *)
              position_at_end start_bb builder;
              ignore (build_cond_br cond_val then_bb else_bb builder);

              (* Set a unconditional branch at the end of the 'then' block and the
               * 'else' block to the 'merge' block. *)
              position_at_end new_then_bb builder; ignore (build_br merge_bb builder);
              position_at_end new_else_bb builder; ignore (build_br merge_bb builder);

              (* Finally, set the builder to the end of the merge block. *)
              position_at_end merge_bb builder;

              phi
          | Ast.For (var_name, start, end_, step, body) ->
              (* Emit the start code first, without 'variable' in scope. *)
              let start_val = codegen_expr start in

              (* Make the new basic block for the loop header, inserting after current
               * block. *)
              let preheader_bb = insertion_block builder in
              let the_function = block_parent preheader_bb in
              let loop_bb = append_block context "loop" the_function in

              (* Insert an explicit fall through from the current block to the
               * loop_bb. *)
              ignore (build_br loop_bb builder);

              (* Start insertion in loop_bb. *)
              position_at_end loop_bb builder;

              (* Start the PHI node with an entry for start. *)
              let variable = build_phi [(start_val, preheader_bb)] var_name builder in

              (* Within the loop, the variable is defined equal to the PHI node. If it
               * shadows an existing variable, we have to restore it, so save it
               * now. *)
              let old_val =
                try Some (Hashtbl.find named_values var_name) with Not_found -> None
              in
              Hashtbl.add named_values var_name variable;

              (* Emit the body of the loop.  This, like any other expr, can change the
               * current BB.  Note that we ignore the value computed by the body, but
               * don't allow an error *)
              ignore (codegen_expr body);

              (* Emit the step value. *)
              let step_val =
                match step with
                | Some step -> codegen_expr step
                (* If not specified, use 1.0. *)
                | None -> const_float double_type 1.0
              in

              let next_var = build_add variable step_val "nextvar" builder in

              (* Compute the end condition. *)
              let end_cond = codegen_expr end_ in

              (* Convert condition to a bool by comparing equal to 0.0. *)
              let zero = const_float double_type 0.0 in
              let end_cond = build_fcmp Fcmp.One end_cond zero "loopcond" builder in

              (* Create the "after loop" block and insert it. *)
              let loop_end_bb = insertion_block builder in
              let after_bb = append_block context "afterloop" the_function in

              (* Insert the conditional branch into the end of loop_end_bb. *)
              ignore (build_cond_br end_cond loop_bb after_bb builder);

              (* Any new code will be inserted in after_bb. *)
              position_at_end after_bb builder;

              (* Add a new entry to the PHI node for the backedge. *)
              add_incoming (next_var, loop_end_bb) variable;

              (* Restore the unshadowed variable. *)
              begin match old_val with
              | Some old_val -> Hashtbl.add named_values var_name old_val
              | None -> ()
              end;

              (* for expr always returns 0.0. *)
              const_null double_type

        let codegen_proto = function
          | Ast.Prototype (name, args) ->
              (* Make the function type: double(double,double) etc. *)
              let doubles = Array.make (Array.length args) double_type in
              let ft = function_type double_type doubles in
              let f =
                match lookup_function name the_module with
                | None -> declare_function name ft the_module

                (* If 'f' conflicted, there was already something named 'name'. If it
                 * has a body, don't allow redefinition or reextern. *)
                | Some f ->
                    (* If 'f' already has a body, reject this. *)
                    if block_begin f <> At_end f then
                      raise (Error "redefinition of function");

                    (* If 'f' took a different number of arguments, reject. *)
                    if element_type (type_of f) <> ft then
                      raise (Error "redefinition of function with different # args");
                    f
              in

              (* Set names for all arguments. *)
              Array.iteri (fun i a ->
                let n = args.(i) in
                set_value_name n a;
                Hashtbl.add named_values n a;
              ) (params f);
              f

        let codegen_func the_fpm = function
          | Ast.Function (proto, body) ->
              Hashtbl.clear named_values;
              let the_function = codegen_proto proto in

              (* Create a new basic block to start insertion into. *)
              let bb = append_block context "entry" the_function in
              position_at_end bb builder;

              try
                let ret_val = codegen_expr body in

                (* Finish off the function. *)
                let _ = build_ret ret_val builder in

                (* Validate the generated code, checking for consistency. *)
                Llvm_analysis.assert_valid_function the_function;

                (* Optimize the function. *)
                let _ = PassManager.run_function the_function the_fpm in

                the_function
              with e ->
                delete_function the_function;
                raise e

toplevel.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Top-Level parsing and JIT Driver
         *===----------------------------------------------------------------------===*)

        open Llvm
        open Llvm_executionengine

        (* top ::= definition | external | expression | ';' *)
        let rec main_loop the_fpm the_execution_engine stream =
          match Stream.peek stream with
          | None -> ()

          (* ignore top-level semicolons. *)
          | Some (Token.Kwd ';') ->
              Stream.junk stream;
              main_loop the_fpm the_execution_engine stream

          | Some token ->
              begin
                try match token with
                | Token.Def ->
                    let e = Parser.parse_definition stream in
                    print_endline "parsed a function definition.";
                    dump_value (Codegen.codegen_func the_fpm e);
                | Token.Extern ->
                    let e = Parser.parse_extern stream in
                    print_endline "parsed an extern.";
                    dump_value (Codegen.codegen_proto e);
                | _ ->
                    (* Evaluate a top-level expression into an anonymous function. *)
                    let e = Parser.parse_toplevel stream in
                    print_endline "parsed a top-level expr";
                    let the_function = Codegen.codegen_func the_fpm e in
                    dump_value the_function;

                    (* JIT the function, returning a function pointer. *)
                    let result = ExecutionEngine.run_function the_function [||]
                      the_execution_engine in

                    print_string "Evaluated to ";
                    print_float (GenericValue.as_float Codegen.double_type result);
                    print_newline ();
                with Stream.Error s | Codegen.Error s ->
                  (* Skip token for error recovery. *)
                  Stream.junk stream;
                  print_endline s;
              end;
              print_string "ready> "; flush stdout;
              main_loop the_fpm the_execution_engine stream

toy.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Main driver code.
         *===----------------------------------------------------------------------===*)

        open Llvm
        open Llvm_executionengine
        open Llvm_target
        open Llvm_scalar_opts

        let main () =
          ignore (initialize_native_target ());

          (* Install standard binary operators.
           * 1 is the lowest precedence. *)
          Hashtbl.add Parser.binop_precedence '<' 10;
          Hashtbl.add Parser.binop_precedence '+' 20;
          Hashtbl.add Parser.binop_precedence '-' 20;
          Hashtbl.add Parser.binop_precedence '*' 40;    (* highest. *)

          (* Prime the first token. *)
          print_string "ready> "; flush stdout;
          let stream = Lexer.lex (Stream.of_channel stdin) in

          (* Create the JIT. *)
          let the_execution_engine = ExecutionEngine.create Codegen.the_module in
          let the_fpm = PassManager.create_function Codegen.the_module in

          (* Set up the optimizer pipeline.  Start with registering info about how the
           * target lays out data structures. *)
          DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;

          (* Do simple "peephole" optimizations and bit-twiddling optzn. *)
          add_instruction_combination the_fpm;

          (* reassociate expressions. *)
          add_reassociation the_fpm;

          (* Eliminate Common SubExpressions. *)
          add_gvn the_fpm;

          (* Simplify the control flow graph (deleting unreachable blocks, etc). *)
          add_cfg_simplification the_fpm;

          ignore (PassManager.initialize the_fpm);

          (* Run the main "interpreter loop" now. *)
          Toplevel.main_loop the_fpm the_execution_engine stream;

          (* Print out all the generated code. *)
          dump_module Codegen.the_module
        ;;

        main ()

bindings.c
    .. code-block:: c

        #include <stdio.h>

        /* putchard - putchar that takes a double and returns 0. */
        extern double putchard(double X) {
          putchar((char)X);
          return 0;
        }

`Next: Extending the language: user-defined
operators <OCamlLangImpl6.html>`_

