(* Source compiler.ml *)
open S     (* Documentation de S *)
open Ast   (* Documentation de S.Ast *)
open Code  (* Documentation de Code *)
exception Error
(*  'slot xk [x0; ... ; xk ; ...]' renvoie k,
    c'est-a-dire la position de x dans l'env *)
let slot x env =
  
let rec slot_rec k = 
function
    | [] -> 
raise Error
    | 
y::
e ->
        
if x=
y then k
        else slot_rec (
k+1) 
e in
  slot_rec 0 
env
(***********************************************************)
(* Compilateur proprement dit, par rapport au cours        *)
(* Ma fonction 'comp e t k' renvoie Ce(t) @ k.             *)
(***********************************************************)
let rec comp e t k = 
match t with
(* Facile *)
| 
Num n -> 
Ldi n::
k
(* Plus géneral que les transparents, qui ne traitent que l'addition *)
| 
Op (
op,
t1,
t2) ->
   
comp e t1 (
Push::
comp e t2 (
IOp op::
k))
(* Attention aux arguments [] pour les compilations de t2 et t3 *)
| 
Ifz (
t1,
t2,
t3) ->
    
comp e t1 (
Test (
comp e t2 [],
comp e t3 [])::
k)
(* Cf. transparents *)
| 
Let (
x,
t1,
t2) ->
    
Pushenv::
comp e t1 (
Extend::
comp (
x::
e) 
t2 (
Popenv::
k))
(* Facile (une fois écrit slot) *)
| 
Var x -> 
Search (
slot x e)::
k
(* Cf. transparents *)
| 
App (
t1,
t2) ->
   
comp e t2 (
Push::
comp e t1 (
Apply::
k))
(* Une seule instruction MkClos, fermeture bouclées systématiques *)
| 
Fix (
f,
Fun (
x,
t)) ->
   
let c_fun = 
comp (
x::
f::
e) 
t [] 
in
   Mkclosrec c_fun::
k
| 
Fix (
_,
_) -> 
raise Error
| 
Fun (
x,
t) ->
   
let c_fun = 
comp (
x::
e) 
t [] 
in
   Mkclos c_fun::
k
(* Plus grand chose d'intéressant, quoique, noter
   la technique pour afficher le code compilé *)
let debug = 
false
let compile env t =
  
let r = 
comp env t [] 
in
  if debug then begin
    List.
iter
      (
fun i -> 
Printf.
eprintf "%a\n" print_instruction i)
      
r ;
    
flush stderr
  end ;
  
r 
This document was translated from LATEX by
HEVEA.