___ ___ ___ ___ ___
/\ \ /\ \ /\__\ ___ /\__\ /\ \
/::\ \ /::\ \ /:/ / /\ \ /::| | /::\ \
/:/\:\ \ /:/\:\ \ /:/ / \:\ \ /:|:| | /:/\:\ \
/::\~\:\ \ /:/ \:\ \ /:/ / ___ /::\__\ /:/|:| |__ /::\~\:\ \
/:/\:\ \:\__\ /:/__/ \:\__\ /:/__/ /\__\ __/:/\/__/ /:/ |:| /\__\ /:/\:\ \:\__\
\/__\:\ \/__/ \:\ \ /:/ / \:\ \ /:/ / /\/:/ / \/__|:|/:/ / \:\~\:\ \/__/
\:\__\ \:\ /:/ / \:\ /:/ / \::/__/ |:/:/ / \:\ \:\__\
\/__/ \:\/:/ / \:\/:/ / \:\__\ |::/ / \:\ \/__/
\::/ / \::/ / \/__/ /:/ / \:\__\
\/__/ \/__/ \/__/ \/__/
Make sure ocamlbuild is installed. Then just type make
By default ./fouine
is an interpretor.
To use it type ./fouine
. Several options are available:
-debug
to pretty print the instructions after they are inputted, or complementary informations when compiling.-nocoloration
to deactivate the syntax coloration. It is activated by default.-noinference
to deactivate type inference (activated by default)-interm FILE
to save the compiled code in the fileFILE
-o FILE
to save transformed code in a file-R
to activate the transformation suppressing references-E
to activate the cps transformation (expressions are made by continuations)ER
to activate both transformations-nobuildins
to deactivate the buildins-noinference
to deactivate the inference-machine (Z|S|J)
if you want to compile your fouine file.Z|S|J
determines for which machine it will be compiled. It is important to note that the different machines don't support pattern matching and constructors !Z
is a ZINC machineS
is a secd machineJ
is a joint interpretation / secd machine. It will interpret the program until "pure" expressions (only made of arithmetical expressions) is found. It then switch to a secd machine for this expression.
- a file can be passed to
./fouine
. In that case, this file will be executed. Otherwise./fouine
will be launched under the repl mode
The script test.sh
will test Fouine with the files found in the folder tests/
The syntax - and the functionnalities - are similar with Caml. Here is a summary:
-
Basic mathematical operators :
+,-, /, *, =, <>, <, >, <=, >=, and, or, not
.- Operators
+,-, /, *
have typesint -> int-> int
. and, or, not
have typesbool-> bool-> bool
andbool->bool
=, <>, <, >, <=, >=
have types'a->'a->int
Depending on how the interpreter / compiler is launch, these operators are either buildins or not. With the option-nobuildins
, or if it is compiled for aZINC
machine, then they aren't buildins. Otherwise they are : we can therefore change their behaviour by redefining+
,*
, ...
- Operators
-
Branching:
if condition then foo else bar
.foo
andbar
must have the same type. Expressions likeif cond then expr
works only ifexpr
is of typeunit
-
Functions:
fun a-> fun b -> expr
is a two variables anonymous fonction -
Affectation and variables:
let ident = exp in expression
will affect to the identifierident
the valueexpr
.let ident a b c = expr in expression
is a shortcut forlet ident = fun a-> fun b-> fun c->expr in expression
. Expressions of the formlet ident = expr
are only accepted on the top level.let rec ident = expr
will behave almost identically aslet ident = expr
:expr
is assigned toident
, butident
can be present inexpr
, thus allowing recursive functions.
-
References. References are almost likes pointer. They are mutable. We can access to the value of a reference with the operator
!
, and modify the value of a reference with:=
(typeref 'a -> 'a -> unit
).let a = ref 6 in let _ = a := 8 in !a (* <- it is 8 *)
-
Underscore (
_
). It matches everything. These instructions are valid:let _ = expr
let f x _ = x in f
-
Exceptions:
- An exception can be emitted with the instruction
raise n
where n is an integer. - An exception can be caught with a bloc of the form
try foo with E x -> bar
. Ifx
is a constant, thenbar
is executed only iffoo
raised an exception havingx
has value. Otherwise,bar
is executed iffoo
raised an exception
- An exception can be emitted with the instruction
-
array: integer fixed-length arrays can be created with the syntax
makeArray n
wheren
is the length. An element can be accessed with the syntaxarray.(index)
, and affected witharray.(index) <- value
-
prInt:
prInt expr
will printexpr
and return the valueexpr
. It has typeint -> int
-
Files. The command
open "file"
will open a fouine file and will load its code as a module (functions declared in this file will be accessible with the syntaxfile.function
. If the file doesn't exists, or if it contains a parsing error, the loaded code will be()
. Beware: paths are relatives to the interpreter files -
Tuples:
(a, b, c)
will create a three dimensionnal tuple. You can match on the elements:let x, y = 1, 2
-
Types and constructors
- Declarations are like in Caml with the syntax:
type ('a, ..., 'b) type_name = | Constr1 of (type_arguments1) .... | Constrn of (type_argumentsn)
- Types are recursives:
let 'a test = None of 'a test
- Constructors aren't force to have arguments
- Declarations are like in Caml with the syntax:
-
Pattern matching: expression like
let 0, (), (x, _), Constr y = ....
orfun (x, Constr (a, b)) -> ...
are valid. You can explicitely match a value with the syntaxmatch expr with | pattern_1 -> expr1 | ... -> ... | pattern_n -> exprn
. Ifexpr
matches withpatterni
, thenexpri
will be executed -
;;
are required at the end of an expression -
We can redefined a number of operators (infix or prefix). The syntax is the same than in caml:
let (@@) a b = ....
-
List: An empty list can be build with
[]
, two list can be concatenated with@
and an element can be inserted to the front with::
. They are compatible with pattern matching (their definition is simplytype 'a list = None | Elem of ('a * 'a list)
). They are not working with compilation. -
modules. A module can be defined as follow:
module Test : sig ... end = struct .. end;;
. Signatures can be also providedmodule type TestSig = sig type t;; type t2 = int;; val f : int -> int -> int end;; module Test : TestSig = struct type t = int;; let f a b = a + b;; end;;
It is important to note that signatures only checks for the presence of the elements. They are not as powerfull as in OCaml. -
Type constraints. Type constraints are working if no
ref
are presents.let f x : int = x;; int -> int
let f (x : bool) = x;; bool -> bool
((fun x -> x) : int -> int)
-
Base types:
'a -> 'b
,'a ref
,int array
,int
,bool
The constructors of our types have only an argument which is a tuple. From there, certains expressions which are not working in Caml are working in Fouine:
>>> type 'a ok = Machin of 'a;;
>>> let a = Machin 3;;
val a : int ok = Machin (3)
>>> let Machin b = a;;
val b : int = 3
Two types transformations can be applied. The first one will remove the references and simulate them using an array (transformation R) The second one do a cps transformation of the code (transformation E). Recursive functions are transformed using an Y-combinator. The two transformations can be applied at the same time (transformation ER). Typing errors can then appear because our fouine langage is converted into a subset of fouine very similar to lambda calculus. Therefore our typing system isn't powerfull enough to type these expressions. (but the same problem arise in Caml)
inference.ml
: type inferencebuildins.ml
: buildins functions definition (apport from basic mathematical operators)inference_old.ml
: old type inference. Kept for archeleogical purposestransformations.ml
: code transformationsprettyprint.ml
: fouine pretty printerbinop.ml
: binary operators functionsshared.ml
: buildins declarations and variables environmentstypes.ml
: type definitions and utilities around typescommons.ml
: file containing elements usefull everywhere in the codeerrors.ml
: errors les erreursfile.ml
: everything to deal with filesmain.ml
: repl, main and loading filesinterpret.ml
: interpretercompilB.ml
: fouine to SECD machine bytecode compilationsecdB.ml
: to execute SECD bytecodeutils.ml
: display, debug and utilities functions for the SECD simulatorbruijn.ml
: De bruijn indicesdream.ml
: environment used for the secd and the bruijn indicesexpr.ml
: declaration of the types used to define our astparser.mly
,lexer.mll
: parsing and lexingbruijnZ.ml
,compilZ.ml
,secdZ.ml
: de bruijn indices, compilation and simulation for a ZINC machinejit.ml
: mixed machine