[llvm-commits] [llvm] r97966 - in /llvm/trunk: bindings/ocaml/ examples/ examples/OCaml-Kaleidoscope/ examples/OCaml-Kaleidoscope/Chapter2/ examples/OCaml-Kaleidoscope/Chapter3/ examples/OCaml-Kaleidoscope/Chapter4/ examples/OCaml-Kaleidoscope/Chapter5/ examples/OCaml-Kaleidoscope/Chapter6/ examples/OCaml-Kaleidoscope/Chapter7/

Erick Tryzelaar idadesub at users.sourceforge.net
Mon Mar 8 11:32:28 PST 2010


Author: erickt
Date: Mon Mar  8 13:32:27 2010
New Revision: 97966

URL: http://llvm.org/viewvc/llvm-project?rev=97966&view=rev
Log:
Add OCaml tutorial to the examples.

Added:
    llvm/trunk/examples/OCaml-Kaleidoscope/
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml
    llvm/trunk/examples/OCaml-Kaleidoscope/Makefile
Modified:
    llvm/trunk/bindings/ocaml/Makefile.ocaml
    llvm/trunk/examples/Makefile

Modified: llvm/trunk/bindings/ocaml/Makefile.ocaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/Makefile.ocaml?rev=97966&r1=97965&r2=97966&view=diff
==============================================================================
--- llvm/trunk/bindings/ocaml/Makefile.ocaml (original)
+++ llvm/trunk/bindings/ocaml/Makefile.ocaml Mon Mar  8 13:32:27 2010
@@ -66,35 +66,64 @@
 Compile.CMX  := $(strip $(OCAMLOPT) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
 Archive.CMXA := $(strip $(OCAMLOPT) -a $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) -o)
 
+ifdef OCAMLOPT
+Archive.EXE := $(strip $(OCAMLOPT) -cc $(CXX) $(OCAMLCFLAGS) $(UsedOcamLibs:%=%.cmxa) $(OCAMLDEBUGFLAG) -o)
+else
+Archive.EXE := $(strip $(OCAMLC) -cc $(CXX) $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG:%=%.cma) -o)
+endif
+
 # Source files
 OcamlSources1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.ml))
-OcamlHeaders1 := $(OcamlSources1:.ml=.mli)
+OcamlHeaders1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.mli))
 
-OcamlSources := $(OcamlSources1:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
-OcamlHeaders := $(OcamlHeaders1:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
+OcamlSources2 := $(filter-out $(ExcludeSources),$(OcamlSources1))
+OcamlHeaders2 := $(filter-out $(ExcludeHeaders),$(OcamlHeaders1))
+
+OcamlSources := $(OcamlSources2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
+OcamlHeaders := $(OcamlHeaders2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
 
 # Intermediate files
-LibraryCMA   := $(ObjDir)/$(LIBRARYNAME).cma
-LibraryCMXA  := $(ObjDir)/$(LIBRARYNAME).cmxa
 ObjectsCMI   := $(OcamlSources:%.ml=%.cmi)
 ObjectsCMO   := $(OcamlSources:%.ml=%.cmo)
 ObjectsCMX   := $(OcamlSources:%.ml=%.cmx)
 
+ifdef LIBRARYNAME
+LibraryCMA   := $(ObjDir)/$(LIBRARYNAME).cma
+LibraryCMXA  := $(ObjDir)/$(LIBRARYNAME).cmxa
+endif
+
+ifdef TOOLNAME
+ToolEXE      := $(ObjDir)/$(TOOLNAME)$(EXEEXT)
+endif
+
 # Output files
 #   The .cmo files are the only intermediates; all others are to be installed.
-LibraryA   := $(OcamlDir)/lib$(LIBRARYNAME).a
-OutputCMA  := $(LibraryCMA:$(ObjDir)/%.cma=$(OcamlDir)/%.cma)
-OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa)
 OutputsCMI := $(ObjectsCMI:$(ObjDir)/%.cmi=$(OcamlDir)/%.cmi)
 OutputsCMX := $(ObjectsCMX:$(ObjDir)/%.cmx=$(OcamlDir)/%.cmx)
 OutputLibs := $(UsedLibNames:%=$(OcamlDir)/%)
 
+ifdef LIBRARYNAME
+LibraryA   := $(OcamlDir)/lib$(LIBRARYNAME).a
+OutputCMA  := $(LibraryCMA:$(ObjDir)/%.cma=$(OcamlDir)/%.cma)
+OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa)
+endif
+
+ifdef TOOLNAME
+ifdef EXAMPLE_TOOL
+OutputEXE := $(ExmplDir)/$(strip $(TOOLNAME))$(EXEEXT)
+else
+OutputEXE := $(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT)
+endif
+endif
+
 # Installation targets
+DestLibs := $(UsedLibNames:%=$(PROJ_libocamldir)/%)
+
+ifdef LIBRARYNAME
 DestA    := $(PROJ_libocamldir)/lib$(LIBRARYNAME).a
 DestCMA  := $(PROJ_libocamldir)/$(LIBRARYNAME).cma
 DestCMXA := $(PROJ_libocamldir)/$(LIBRARYNAME).cmxa
-DestLibs := $(UsedLibNames:%=$(PROJ_libocamldir)/%)
-
+endif
 
 ##===- Dependencies -------------------------------------------------------===##
 # Copy the sources into the intermediate directory because older ocamlc doesn't
@@ -106,18 +135,27 @@
 $(ObjDir)/%.ml: $(PROJ_SRC_DIR)/%.ml $(ObjDir)/.dir
 	$(Verb) $(CP) -f $< $@
 
+$(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi)
+
+ifdef LIBRARYNAME
 $(ObjDir)/$(LIBRARYNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
                                    $(OcamlDir)/.dir $(ObjDir)/.dir
 	$(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
 
-$(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi)
-
 -include $(ObjDir)/$(LIBRARYNAME).ocamldep
+endif
+
+ifdef TOOLNAME
+$(ObjDir)/$(TOOLNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
+                                $(OcamlDir)/.dir $(ObjDir)/.dir
+	$(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
 
+-include $(ObjDir)/$(TOOLNAME).ocamldep
+endif
 
 ##===- Build static library from C sources --------------------------------===##
 
-ifneq ($(ObjectsO),)
+ifdef LibraryA
 all-local:: $(LibraryA)
 clean-local:: clean-a
 install-local:: install-a
@@ -160,7 +198,7 @@
 	$(Verb) ln -sf $< $@
 
 clean-deplibs:
-	$(Verb) rm -f $(OutputLibs)
+	$(Verb) $(RM) -f $(OutputLibs)
 
 install-deplibs:
 	$(Verb) $(MKDIR) $(PROJ_libocamldir)
@@ -169,11 +207,12 @@
 	done
 
 uninstall-deplibs:
-	$(Verb) rm -f $(DestLibs)
+	$(Verb) $(RM) -f $(DestLibs)
 
 
 ##===- Build ocaml interfaces (.mli's -> .cmi's) --------------------------===##
 
+ifneq ($(OcamlHeaders),)
 all-local:: build-cmis
 clean-local:: clean-cmis
 install-local:: install-cmis
@@ -212,10 +251,16 @@
 	  $(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \
 	  $(RM) -f "$(PROJ_libocamldir)/$$i"; \
 	done
+endif
 
 
 ##===- Build ocaml bytecode archive (.ml's -> .cmo's -> .cma) -------------===##
 
+$(ObjDir)/%.cmo: $(ObjDir)/%.ml
+	$(Echo) "Compiling $(notdir $<) for $(BuildMode) build"
+	$(Verb) $(Compile.CMO) $@ $<
+
+ifdef LIBRARYNAME
 all-local:: $(OutputCMA)
 clean-local:: clean-cma
 install-local:: install-cma
@@ -228,10 +273,6 @@
 	$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
 	$(Verb) $(Archive.CMA) $@ $(ObjectsCMO)
 
-$(ObjDir)/%.cmo: $(ObjDir)/%.ml
-	$(Echo) "Compiling $(notdir $<) for $(BuildMode) build"
-	$(Verb) $(Compile.CMO) $@ $<
-
 clean-cma::
 	$(Verb) $(RM) -f $(OutputCMA) $(UsedLibNames:%=$(OcamlDir)/%)
 
@@ -243,7 +284,7 @@
 uninstall-cma::
 	$(Echo) "Uninstalling $(DestCMA)"
 	-$(Verb) $(RM) -f $(DestCMA)
-
+endif
 
 ##===- Build optimized ocaml archive (.ml's -> .cmx's -> .cmxa, .a) -------===##
 
@@ -251,6 +292,14 @@
 # If unavailable, 'configure' will not define OCAMLOPT in Makefile.config.
 ifdef OCAMLOPT
 
+$(OcamlDir)/%.cmx: $(ObjDir)/%.cmx
+	$(Verb) $(CP) -f $< $@
+
+$(ObjDir)/%.cmx: $(ObjDir)/%.ml
+	$(Echo) "Compiling optimized $(notdir $<) for $(BuildMode) build"
+	$(Verb) $(Compile.CMX) $@ $<
+
+ifdef LIBRARYNAME
 all-local:: $(OutputCMXA) $(OutputsCMX)
 clean-local:: clean-cmxa
 install-local:: install-cmxa
@@ -260,18 +309,11 @@
 	$(Verb) $(CP) -f $< $@
 	$(Verb) $(CP) -f $(<:.cmxa=.a) $(@:.cmxa=.a)
 
-$(OcamlDir)/%.cmx: $(ObjDir)/%.cmx
-	$(Verb) $(CP) -f $< $@
-
 $(LibraryCMXA): $(ObjectsCMX)
 	$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
 	$(Verb) $(Archive.CMXA) $@ $(ObjectsCMX)
 	$(Verb) $(RM) -f $(@:.cmxa=.o)
 
-$(ObjDir)/%.cmx: $(ObjDir)/%.ml
-	$(Echo) "Compiling optimized $(notdir $<) for $(BuildMode) build"
-	$(Verb) $(Compile.CMX) $@ $<
-
 clean-cmxa::
 	$(Verb) $(RM) -f $(OutputCMXA) $(OutputCMXA:.cmxa=.a) $(OutputsCMX)
 
@@ -295,7 +337,27 @@
 	  $(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \
 	  $(RM) -f $(PROJ_libocamldir)/$$i; \
 	done
+endif
+endif
+
+##===- Build executables --------------------------------------------------===##
+
+ifdef TOOLNAME
+all-local:: $(OutputEXE)
+clean-local:: clean-exe
+
+$(OutputEXE): $(ToolEXE) $(OcamlDir)/.dir
+	$(Verb) $(CP) -f $< $@
 
+ifndef OCAMLOPT
+$(ToolEXE): $(ObjectsCMO) $(OcamlDir)/.dir
+	$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
+	$(Verb) $(Archive.EXE) $@ $<
+else
+$(ToolEXE): $(ObjectsCMX) $(OcamlDir)/.dir
+	$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
+	$(Verb) $(Archive.EXE) $@ $<
+endif
 endif
 
 ##===- Generate documentation ---------------------------------------------===##
@@ -325,7 +387,10 @@
 	$(Echo) "LibraryCMA   : " '$(LibraryCMA)'
 	$(Echo) "LibraryCMXA  : " '$(LibraryCMXA)'
 	$(Echo) "OcamlSources1: " '$(OcamlSources1)'
+	$(Echo) "OcamlSources2: " '$(OcamlSources2)'
 	$(Echo) "OcamlSources : " '$(OcamlSources)'
+	$(Echo) "OcamlHeaders1: " '$(OcamlHeaders1)'
+	$(Echo) "OcamlHeaders2: " '$(OcamlHeaders2)'
 	$(Echo) "OcamlHeaders : " '$(OcamlHeaders)'
 	$(Echo) "ObjectsCMI   : " '$(ObjectsCMI)'
 	$(Echo) "ObjectsCMO   : " '$(ObjectsCMO)'
@@ -340,4 +405,6 @@
 .PHONY: printcamlvars   build-cmis \
             clean-a     clean-cmis     clean-cma     clean-cmxa \
           install-a   install-cmis   install-cma   install-cmxa \
-		uninstall-a uninstall-cmis uninstall-cma uninstall-cmxa
+          install-exe \
+		uninstall-a uninstall-cmis uninstall-cma uninstall-cmxa \
+		uninstall-exe

Modified: llvm/trunk/examples/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Makefile?rev=97966&r1=97965&r2=97966&view=diff
==============================================================================
--- llvm/trunk/examples/Makefile (original)
+++ llvm/trunk/examples/Makefile Mon Mar  8 13:32:27 2010
@@ -10,7 +10,8 @@
 
 include $(LEVEL)/Makefile.config
 
-PARALLEL_DIRS:= BrainF Fibonacci HowToUseJIT Kaleidoscope ModuleMaker
+PARALLEL_DIRS:= BrainF Fibonacci HowToUseJIT Kaleidoscope ModuleMaker \
+	OCaml-Kaleidoscope
 
 ifeq ($(HAVE_PTHREAD),1)
 PARALLEL_DIRS += ParallelJIT 

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile Mon Mar  8 13:32:27 2010
@@ -0,0 +1,22 @@
+##===- examples/OCaml-Kaleidoscope/Chapter2/Makefile -------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+# 
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 2.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch2
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm
+
+OCAMLCFLAGS += -pp camlp4of
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags Mon Mar  8 13:32:27 2010
@@ -0,0 +1 @@
+<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,25 @@
+(*===----------------------------------------------------------------------===
+ * 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
+
+(* 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,52 @@
+(*===----------------------------------------------------------------------===
+ * 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 >]
+      | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+  | [< ' ('\n'); stream=lex >] -> stream
+  | [< 'c; e=lex_comment >] -> e
+  | [< >] -> [< >]

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,122 @@
+(*===---------------------------------------------------------------------===
+ * 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 *)
+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
+
+  | [< >] -> 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,15 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,34 @@
+(*===----------------------------------------------------------------------===
+ * Top-Level parsing and JIT Driver
+ *===----------------------------------------------------------------------===*)
+
+(* top ::= definition | external | expression | ';' *)
+let rec main_loop stream =
+  match Stream.peek stream with
+  | None -> ()
+
+  (* ignore top-level semicolons. *)
+  | Some (Token.Kwd ';') ->
+      Stream.junk stream;
+      main_loop stream
+
+  | Some token ->
+      begin
+        try match token with
+        | Token.Def ->
+            ignore(Parser.parse_definition stream);
+            print_endline "parsed a function definition.";
+        | Token.Extern ->
+            ignore(Parser.parse_extern stream);
+            print_endline "parsed an extern.";
+        | _ ->
+            (* Evaluate a top-level expression into an anonymous function. *)
+            ignore(Parser.parse_toplevel stream);
+            print_endline "parsed a top-level expr";
+        with Stream.Error s ->
+          (* Skip token for error recovery. *)
+          Stream.junk stream;
+          print_endline s;
+      end;
+      print_string "ready> "; flush stdout;
+      main_loop stream

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,21 @@
+(*===----------------------------------------------------------------------===
+ * Main driver code.
+ *===----------------------------------------------------------------------===*)
+
+let main () =
+  (* 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
+
+  (* Run the main "interpreter loop" now. *)
+  Toplevel.main_loop stream;
+;;
+
+main ()

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile Mon Mar  8 13:32:27 2010
@@ -0,0 +1,24 @@
+##===- examples/OCaml-Kaleidoscope/Chapter3/Makefile -------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+# 
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 3.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch3
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags Mon Mar  8 13:32:27 2010
@@ -0,0 +1,2 @@
+<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
+<*.{byte,native}>: g++, use_llvm, use_llvm_analysis

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,25 @@
+(*===----------------------------------------------------------------------===
+ * 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
+
+(* 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,100 @@
+(*===----------------------------------------------------------------------===
+ * 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
+
+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 = 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;
+
+        the_function
+      with e ->
+        delete_function the_function;
+        raise e

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,52 @@
+(*===----------------------------------------------------------------------===
+ * 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 >]
+      | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+  | [< ' ('\n'); stream=lex >] -> stream
+  | [< 'c; e=lex_comment >] -> e
+  | [< >] -> [< >]

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,6 @@
+open Ocamlbuild_plugin;;
+
+ocaml_lib ~extern:true "llvm";;
+ocaml_lib ~extern:true "llvm_analysis";;
+
+flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);;

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,122 @@
+(*===---------------------------------------------------------------------===
+ * 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 *)
+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
+
+  | [< >] -> 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,15 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,39 @@
+(*===----------------------------------------------------------------------===
+ * Top-Level parsing and JIT Driver
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+
+(* top ::= definition | external | expression | ';' *)
+let rec main_loop stream =
+  match Stream.peek stream with
+  | None -> ()
+
+  (* ignore top-level semicolons. *)
+  | Some (Token.Kwd ';') ->
+      Stream.junk stream;
+      main_loop 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 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";
+            dump_value (Codegen.codegen_func e);
+        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 stream

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,26 @@
+(*===----------------------------------------------------------------------===
+ * Main driver code.
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+
+let main () =
+  (* 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
+
+  (* Run the main "interpreter loop" now. *)
+  Toplevel.main_loop stream;
+
+  (* Print out all the generated code. *)
+  dump_module Codegen.the_module
+;;
+
+main ()

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile Mon Mar  8 13:32:27 2010
@@ -0,0 +1,25 @@
+##===- examples/OCaml-Kaleidoscope/Chapter4/Makefile -------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+# 
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 4.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch4
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
+	llvm_scalar_opts
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags Mon Mar  8 13:32:27 2010
@@ -0,0 +1,4 @@
+<{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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,25 @@
+(*===----------------------------------------------------------------------===
+ * 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
+
+(* 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c Mon Mar  8 13:32:27 2010
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+/* putchard - putchar that takes a double and returns 0. */
+extern double putchard(double X) {
+  putchar((char)X);
+  return 0;
+}

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,103 @@
+(*===----------------------------------------------------------------------===
+ * 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
+
+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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,52 @@
+(*===----------------------------------------------------------------------===
+ * 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 >]
+      | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+  | [< ' ('\n'); stream=lex >] -> stream
+  | [< 'c; e=lex_comment >] -> e
+  | [< >] -> [< >]

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,10 @@
+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"];;

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,122 @@
+(*===---------------------------------------------------------------------===
+ * 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 *)
+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
+
+  | [< >] -> 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,15 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,49 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,53 @@
+(*===----------------------------------------------------------------------===
+ * 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. *)
+  TargetData.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 ()

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile Mon Mar  8 13:32:27 2010
@@ -0,0 +1,25 @@
+##===- examples/OCaml-Kaleidoscope/Chapter5/Makefile -------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+# 
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 5.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch5
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
+	llvm_scalar_opts
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags Mon Mar  8 13:32:27 2010
@@ -0,0 +1,4 @@
+<{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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,31 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c Mon Mar  8 13:32:27 2010
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+/* putchard - putchar that takes a double and returns 0. */
+extern double putchard(double X) {
+  putchar((char)X);
+  return 0;
+}

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,225 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,57 @@
+(*===----------------------------------------------------------------------===
+ * 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
+  | [< >] -> [< >]

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,10 @@
+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"];;

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,158 @@
+(*===---------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,19 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,49 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,53 @@
+(*===----------------------------------------------------------------------===
+ * 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. *)
+  TargetData.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 ()

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile Mon Mar  8 13:32:27 2010
@@ -0,0 +1,25 @@
+##===- examples/OCaml-Kaleidoscope/Chapter6/Makefile -------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+# 
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 6.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch6
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
+	llvm_scalar_opts
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags Mon Mar  8 13:32:27 2010
@@ -0,0 +1,4 @@
+<{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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,36 @@
+(*===----------------------------------------------------------------------===
+ * 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 unary operator. *)
+  | Unary of char * expr
+
+  (* 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
+  | BinOpPrototype of string * string array * int
+
+(* func - This type represents a function definition itself. *)
+type func = Function of proto * expr

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c Mon Mar  8 13:32:27 2010
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+/* putchard - putchar that takes a double and returns 0. */
+extern double putchard(double X) {
+  putchar((char)X);
+  return 0;
+}
+
+/* printd - printf that takes a double prints it as "%f\n", returning 0. */
+extern double printd(double X) {
+  printf("%f\n", X);
+  return 0;
+}

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,251 @@
+(*===----------------------------------------------------------------------===
+ * 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.Unary (op, operand) ->
+      let operand = codegen_expr operand in
+      let callee = "unary" ^ (String.make 1 op) in
+      let callee =
+        match lookup_function callee the_module with
+        | Some callee -> callee
+        | None -> raise (Error "unknown unary operator")
+      in
+      build_call callee [|operand|] "unop" builder
+  | 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
+        | _ ->
+            (* If it wasn't a builtin binary operator, it must be a user defined
+             * one. Emit a call to it. *)
+            let callee = "binary" ^ (String.make 1 op) in
+            let callee =
+              match lookup_function callee the_module with
+              | Some callee -> callee
+              | None -> raise (Error "binary operator not found!")
+            in
+            build_call callee [|lhs_val; rhs_val|] "binop" builder
+      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) | Ast.BinOpPrototype (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
+
+      (* If this is an operator, install it. *)
+      begin match proto with
+      | Ast.BinOpPrototype (name, args, prec) ->
+          let op = name.[String.length name - 1] in
+          Hashtbl.add Parser.binop_precedence op prec;
+      | _ -> ()
+      end;
+
+      (* 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,59 @@
+(*===----------------------------------------------------------------------===
+ * 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 >]
+      | "binary" -> [< 'Token.Binary; stream >]
+      | "unary" -> [< 'Token.Unary; stream >]
+      | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+  | [< ' ('\n'); stream=lex >] -> stream
+  | [< 'c; e=lex_comment >] -> e
+  | [< >] -> [< >]

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,10 @@
+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"];;

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,195 @@
+(*===---------------------------------------------------------------------===
+ * 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.")
+
+(* unary
+ *   ::= primary
+ *   ::= '!' unary *)
+and parse_unary = parser
+  (* If this is a unary operator, read it. *)
+  | [< 'Token.Kwd op when op != '(' && op != ')'; operand=parse_expr >] ->
+      Ast.Unary (op, operand)
+
+  (* If the current token is not an operator, it must be a primary expr. *)
+  | [< stream >] -> parse_primary stream
+
+(* 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 unary expression after the binary operator. *)
+        let rhs = parse_unary 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_unary; stream >] -> parse_bin_rhs 0 lhs stream
+
+(* prototype
+ *   ::= id '(' id* ')'
+ *   ::= binary LETTER number? (id, id)
+ *   ::= unary LETTER number? (id) *)
+let parse_prototype =
+  let rec parse_args accumulator = parser
+    | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
+    | [< >] -> accumulator
+  in
+  let parse_operator = parser
+    | [< 'Token.Unary >] -> "unary", 1
+    | [< 'Token.Binary >] -> "binary", 2
+  in
+  let parse_binary_precedence = parser
+    | [< 'Token.Number n >] -> int_of_float n
+    | [< >] -> 30
+  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))
+  | [< (prefix, kind)=parse_operator;
+       'Token.Kwd op ?? "expected an operator";
+       (* Read the precedence if present. *)
+       binary_precedence=parse_binary_precedence;
+       'Token.Kwd '(' ?? "expected '(' in prototype";
+        args=parse_args [];
+       'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+      let name = prefix ^ (String.make 1 op) in
+      let args = Array.of_list (List.rev args) in
+
+      (* Verify right number of arguments for operator. *)
+      if Array.length args != kind
+      then raise (Stream.Error "invalid number of operands for operator")
+      else
+        if kind == 1 then
+          Ast.Prototype (name, args)
+        else
+          Ast.BinOpPrototype (name, args, binary_precedence)
+  | [< >] ->
+      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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,22 @@
+(*===----------------------------------------------------------------------===
+ * 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
+
+  (* operators *)
+  | Binary | Unary

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,49 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,53 @@
+(*===----------------------------------------------------------------------===
+ * 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. *)
+  TargetData.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 ()

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile Mon Mar  8 13:32:27 2010
@@ -0,0 +1,25 @@
+##===- examples/OCaml-Kaleidoscope/Chapter7/Makefile -------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+# 
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 7.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch7
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
+	llvm_scalar_opts
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags Mon Mar  8 13:32:27 2010
@@ -0,0 +1,4 @@
+<{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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,39 @@
+(*===----------------------------------------------------------------------===
+ * 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 unary operator. *)
+  | Unary of char * expr
+
+  (* 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
+
+  (* variant for var/in. *)
+  | Var of (string * expr option) array * 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
+  | BinOpPrototype of string * string array * int
+
+(* func - This type represents a function definition itself. *)
+type func = Function of proto * expr

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c Mon Mar  8 13:32:27 2010
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+/* putchard - putchar that takes a double and returns 0. */
+extern double putchard(double X) {
+  putchar((char)X);
+  return 0;
+}
+
+/* printd - printf that takes a double prints it as "%f\n", returning 0. */
+extern double printd(double X) {
+  printf("%f\n", X);
+  return 0;
+}

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,370 @@
+(*===----------------------------------------------------------------------===
+ * 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
+
+(* Create an alloca instruction in the entry block of the function. This
+ * is used for mutable variables etc. *)
+let create_entry_block_alloca the_function var_name =
+  let builder = builder_at context (instr_begin (entry_block the_function)) in
+  build_alloca double_type var_name builder
+
+let rec codegen_expr = function
+  | Ast.Number n -> const_float double_type n
+  | Ast.Variable name ->
+      let v = try Hashtbl.find named_values name with
+        | Not_found -> raise (Error "unknown variable name")
+      in
+      (* Load the value. *)
+      build_load v name builder
+  | Ast.Unary (op, operand) ->
+      let operand = codegen_expr operand in
+      let callee = "unary" ^ (String.make 1 op) in
+      let callee =
+        match lookup_function callee the_module with
+        | Some callee -> callee
+        | None -> raise (Error "unknown unary operator")
+      in
+      build_call callee [|operand|] "unop" builder
+  | Ast.Binary (op, lhs, rhs) ->
+      begin match op with
+      | '=' ->
+          (* Special case '=' because we don't want to emit the LHS as an
+           * expression. *)
+          let name =
+            match lhs with
+            | Ast.Variable name -> name
+            | _ -> raise (Error "destination of '=' must be a variable")
+          in
+
+          (* Codegen the rhs. *)
+          let val_ = codegen_expr rhs in
+
+          (* Lookup the name. *)
+          let variable = try Hashtbl.find named_values name with
+          | Not_found -> raise (Error "unknown variable name")
+          in
+          ignore(build_store val_ variable builder);
+          val_
+      | _ ->
+          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
+            | _ ->
+                (* If it wasn't a builtin binary operator, it must be a user defined
+                 * one. Emit a call to it. *)
+                let callee = "binary" ^ (String.make 1 op) in
+                let callee =
+                  match lookup_function callee the_module with
+                  | Some callee -> callee
+                  | None -> raise (Error "binary operator not found!")
+                in
+                build_call callee [|lhs_val; rhs_val|] "binop" builder
+          end
+      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) ->
+      (* Output this as:
+       *   var = alloca double
+       *   ...
+       *   start = startexpr
+       *   store start -> var
+       *   goto loop
+       * loop:
+       *   ...
+       *   bodyexpr
+       *   ...
+       * loopend:
+       *   step = stepexpr
+       *   endcond = endexpr
+       *
+       *   curvar = load var
+       *   nextvar = curvar + step
+       *   store nextvar -> var
+       *   br endcond, loop, endloop
+       * outloop: *)
+
+      let the_function = block_parent (insertion_block builder) in
+
+      (* Create an alloca for the variable in the entry block. *)
+      let alloca = create_entry_block_alloca the_function var_name in
+
+      (* Emit the start code first, without 'variable' in scope. *)
+      let start_val = codegen_expr start in
+
+      (* Store the value into the alloca. *)
+      ignore(build_store start_val alloca builder);
+
+      (* Make the new basic block for the loop header, inserting after current
+       * block. *)
+      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;
+
+      (* 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 alloca;
+
+      (* 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
+
+      (* Compute the end condition. *)
+      let end_cond = codegen_expr end_ in
+
+      (* Reload, increment, and restore the alloca. This handles the case where
+       * the body of the loop mutates the variable. *)
+      let cur_var = build_load alloca var_name builder in
+      let next_var = build_add cur_var step_val "nextvar" builder in
+      ignore(build_store next_var alloca builder);
+
+      (* 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 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;
+
+      (* 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
+  | Ast.Var (var_names, body) ->
+      let old_bindings = ref [] in
+
+      let the_function = block_parent (insertion_block builder) in
+
+      (* Register all variables and emit their initializer. *)
+      Array.iter (fun (var_name, init) ->
+        (* Emit the initializer before adding the variable to scope, this
+         * prevents the initializer from referencing the variable itself, and
+         * permits stuff like this:
+         *   var a = 1 in
+         *     var a = a in ...   # refers to outer 'a'. *)
+        let init_val =
+          match init with
+          | Some init -> codegen_expr init
+          (* If not specified, use 0.0. *)
+          | None -> const_float double_type 0.0
+        in
+
+        let alloca = create_entry_block_alloca the_function var_name in
+        ignore(build_store init_val alloca builder);
+
+        (* Remember the old variable binding so that we can restore the binding
+         * when we unrecurse. *)
+        begin
+          try
+            let old_value = Hashtbl.find named_values var_name in
+            old_bindings := (var_name, old_value) :: !old_bindings;
+          with Not_found -> ()
+        end;
+
+        (* Remember this binding. *)
+        Hashtbl.add named_values var_name alloca;
+      ) var_names;
+
+      (* Codegen the body, now that all vars are in scope. *)
+      let body_val = codegen_expr body in
+
+      (* Pop all our variables from scope. *)
+      List.iter (fun (var_name, old_value) ->
+        Hashtbl.add named_values var_name old_value
+      ) !old_bindings;
+
+      (* Return the body computation. *)
+      body_val
+
+let codegen_proto = function
+  | Ast.Prototype (name, args) | Ast.BinOpPrototype (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
+
+(* Create an alloca for each argument and register the argument in the symbol
+ * table so that references to it will succeed. *)
+let create_argument_allocas the_function proto =
+  let args = match proto with
+    | Ast.Prototype (_, args) | Ast.BinOpPrototype (_, args, _) -> args
+  in
+  Array.iteri (fun i ai ->
+    let var_name = args.(i) in
+    (* Create an alloca for this variable. *)
+    let alloca = create_entry_block_alloca the_function var_name in
+
+    (* Store the initial value into the alloca. *)
+    ignore(build_store ai alloca builder);
+
+    (* Add arguments to variable symbol table. *)
+    Hashtbl.add named_values var_name alloca;
+  ) (params the_function)
+
+let codegen_func the_fpm = function
+  | Ast.Function (proto, body) ->
+      Hashtbl.clear named_values;
+      let the_function = codegen_proto proto in
+
+      (* If this is an operator, install it. *)
+      begin match proto with
+      | Ast.BinOpPrototype (name, args, prec) ->
+          let op = name.[String.length name - 1] in
+          Hashtbl.add Parser.binop_precedence op prec;
+      | _ -> ()
+      end;
+
+      (* Create a new basic block to start insertion into. *)
+      let bb = append_block context "entry" the_function in
+      position_at_end bb builder;
+
+      try
+        (* Add all arguments to the symbol table and create their allocas. *)
+        create_argument_allocas the_function proto;
+
+        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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,60 @@
+(*===----------------------------------------------------------------------===
+ * 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 >]
+      | "binary" -> [< 'Token.Binary; stream >]
+      | "unary" -> [< 'Token.Unary; stream >]
+      | "var" -> [< 'Token.Var; stream >]
+      | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+  | [< ' ('\n'); stream=lex >] -> stream
+  | [< 'c; e=lex_comment >] -> e
+  | [< >] -> [< >]

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,10 @@
+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"];;

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,221 @@
+(*===---------------------------------------------------------------------===
+ * 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
+ *   ::= varexpr *)
+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
+
+  (* varexpr
+   *   ::= 'var' identifier ('=' expression?
+   *             (',' identifier ('=' expression)?)* 'in' expression *)
+  | [< 'Token.Var;
+       (* At least one variable name is required. *)
+       'Token.Ident id ?? "expected identifier after var";
+       init=parse_var_init;
+       var_names=parse_var_names [(id, init)];
+       (* At this point, we have to have 'in'. *)
+       'Token.In ?? "expected 'in' keyword after 'var'";
+       body=parse_expr >] ->
+      Ast.Var (Array.of_list (List.rev var_names), body)
+
+  | [< >] -> raise (Stream.Error "unknown token when expecting an expression.")
+
+(* unary
+ *   ::= primary
+ *   ::= '!' unary *)
+and parse_unary = parser
+  (* If this is a unary operator, read it. *)
+  | [< 'Token.Kwd op when op != '(' && op != ')'; operand=parse_expr >] ->
+      Ast.Unary (op, operand)
+
+  (* If the current token is not an operator, it must be a primary expr. *)
+  | [< stream >] -> parse_primary stream
+
+(* 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_unary 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
+
+and parse_var_init = parser
+  (* read in the optional initializer. *)
+  | [< 'Token.Kwd '='; e=parse_expr >] -> Some e
+  | [< >] -> None
+
+and parse_var_names accumulator = parser
+  | [< 'Token.Kwd ',';
+       'Token.Ident id ?? "expected identifier list after var";
+       init=parse_var_init;
+       e=parse_var_names ((id, init) :: accumulator) >] -> e
+  | [< >] -> accumulator
+
+(* expression
+ *   ::= primary binoprhs *)
+and parse_expr = parser
+  | [< lhs=parse_unary; stream >] -> parse_bin_rhs 0 lhs stream
+
+(* prototype
+ *   ::= id '(' id* ')'
+ *   ::= binary LETTER number? (id, id)
+ *   ::= unary LETTER number? (id) *)
+let parse_prototype =
+  let rec parse_args accumulator = parser
+    | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
+    | [< >] -> accumulator
+  in
+  let parse_operator = parser
+    | [< 'Token.Unary >] -> "unary", 1
+    | [< 'Token.Binary >] -> "binary", 2
+  in
+  let parse_binary_precedence = parser
+    | [< 'Token.Number n >] -> int_of_float n
+    | [< >] -> 30
+  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))
+  | [< (prefix, kind)=parse_operator;
+       'Token.Kwd op ?? "expected an operator";
+       (* Read the precedence if present. *)
+       binary_precedence=parse_binary_precedence;
+       'Token.Kwd '(' ?? "expected '(' in prototype";
+        args=parse_args [];
+       'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+      let name = prefix ^ (String.make 1 op) in
+      let args = Array.of_list (List.rev args) in
+
+      (* Verify right number of arguments for operator. *)
+      if Array.length args != kind
+      then raise (Stream.Error "invalid number of operands for operator")
+      else
+        if kind == 1 then
+          Ast.Prototype (name, args)
+        else
+          Ast.BinOpPrototype (name, args, binary_precedence)
+  | [< >] ->
+      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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,25 @@
+(*===----------------------------------------------------------------------===
+ * 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
+
+  (* operators *)
+  | Binary | Unary
+
+  (* var definition *)
+  | Var

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,49 @@
+(*===----------------------------------------------------------------------===
+ * 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

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml Mon Mar  8 13:32:27 2010
@@ -0,0 +1,57 @@
+(*===----------------------------------------------------------------------===
+ * 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 '=' 2;
+  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. *)
+  TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+
+  (* Promote allocas to registers. *)
+  add_memory_to_register_promotion 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 ()

Added: llvm/trunk/examples/OCaml-Kaleidoscope/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Makefile Mon Mar  8 13:32:27 2010
@@ -0,0 +1,15 @@
+##===- examples/OCaml-Kaleidoscope/Makefile ----------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+LEVEL=../..
+
+include $(LEVEL)/Makefile.config
+
+PARALLEL_DIRS:= Chapter2 Chapter3 Chapter4 Chapter5 Chapter6 Chapter7
+
+include $(LEVEL)/Makefile.common





More information about the llvm-commits mailing list