Skip to content

Commit

Permalink
Add OCaml tutorial to the examples.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97966 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Erick Tryzelaar committed Mar 8, 2010
1 parent 9ef76b9 commit 49457b8
Show file tree
Hide file tree
Showing 65 changed files with 3,508 additions and 29 deletions.
123 changes: 95 additions & 28 deletions bindings/ocaml/Makefile.ocaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,35 +66,64 @@ Archive.CMA := $(strip $(OCAMLC) -a -custom $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \
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))

OcamlSources2 := $(filter-out $(ExcludeSources),$(OcamlSources1))
OcamlHeaders2 := $(filter-out $(ExcludeHeaders),$(OcamlHeaders1))

OcamlSources := $(OcamlSources1:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
OcamlHeaders := $(OcamlHeaders1:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
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
Expand All @@ -106,18 +135,27 @@ $(ObjDir)/%.mli: $(PROJ_SRC_DIR)/%.mli $(ObjDir)/.dir
$(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
Expand Down Expand Up @@ -160,7 +198,7 @@ $(OcamlDir)/%.o: $(LibDir)/%.o
$(Verb) ln -sf $< $@

clean-deplibs:
$(Verb) rm -f $(OutputLibs)
$(Verb) $(RM) -f $(OutputLibs)

install-deplibs:
$(Verb) $(MKDIR) $(PROJ_libocamldir)
Expand All @@ -169,11 +207,12 @@ install-deplibs:
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
Expand Down Expand Up @@ -212,10 +251,16 @@ uninstall-cmis::
$(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
Expand All @@ -228,10 +273,6 @@ $(LibraryCMA): $(ObjectsCMO) $(OcamlDir)/.dir
$(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)/%)

Expand All @@ -243,14 +284,22 @@ install-cma:: $(OutputCMA)
uninstall-cma::
$(Echo) "Uninstalling $(DestCMA)"
-$(Verb) $(RM) -f $(DestCMA)

endif

##===- Build optimized ocaml archive (.ml's -> .cmx's -> .cmxa, .a) -------===##

# The ocamlopt compiler is supported on a set of targets disjoint from LLVM's.
# 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
Expand All @@ -260,18 +309,11 @@ $(OutputCMXA): $(LibraryCMXA)
$(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)

Expand All @@ -295,7 +337,27 @@ uninstall-cmxa::
$(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 ---------------------------------------------===##
Expand Down Expand Up @@ -325,7 +387,10 @@ printcamlvars::
$(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)'
Expand All @@ -340,4 +405,6 @@ printcamlvars::
.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
3 changes: 2 additions & 1 deletion examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ LEVEL=..

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
Expand Down
22 changes: 22 additions & 0 deletions examples/OCaml-Kaleidoscope/Chapter2/Makefile
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions examples/OCaml-Kaleidoscope/Chapter2/_tags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
25 changes: 25 additions & 0 deletions examples/OCaml-Kaleidoscope/Chapter2/ast.ml
Original file line number Diff line number Diff line change
@@ -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
52 changes: 52 additions & 0 deletions examples/OCaml-Kaleidoscope/Chapter2/lexer.ml
Original file line number Diff line number Diff line change
@@ -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
| [< >] -> [< >]
Loading

0 comments on commit 49457b8

Please sign in to comment.