Rappel :

graph TD
  Fopix --> ANF
  ANF --> Kontix
  Kontix --> Javix

Kontix

f(x_{1}, \dots, x_{n}) \underset{\text{Kontix}}{\implies} f(K, \text{Env}, x_{1,} \dots, x_{n})

main Kontix -> début du programme Javix

Au début

Compilation

En général

programme

\RA Permet d’estimer une taille précise de la taille de la pile

Le If

Le if basique

Comme dans Javix, rien de spécial, 2 étiquettes if_else et if_exit.

Le if(comp, TailExpr, TailExpr)

Si la condition est vraie, alors on continue avec l’expression récursive terminale, donc on ne revient jamais en arrière
Si la condition est fausse, on a une autre expression récursive terminale, alors on ne revient pas en arrière.

Donc vu qu’on ne revient jamais en arrière, pas besoin d’étiquette if_exit.

Exemple : if(b) call(f) else call(g).

if((comp_op, be1, be2), te1, te2)
compil(be1)
compil(be2)
ificmp_invop label_if_else
compil(te1)
label_if_else:
compile(te2)

Let/Blet : Let/BLet(id, e1, e2)

Compiler(e1)
; Générer une variable associée à l'id
; Mettre dans cette variable le résultat
Compiler(e2)

Appel de fonction : Call(be, [a0, ..., an]

be : basic expression
[a_{0}, \dots, a_{n}] un ensemble de variables

Appel direct be = Fun f

Exemple f(1, 3) : Call(Fun f, [Num(1), Num(3)]

; Il faut calculer les arguments a de 0 à n.
; Puis on AStore
AStore(n+2)
; ...
AStore(2)
Goto f_body ; étiquette qui traduit le K de la fonction f

Appel indirect be n’est pas un Fun, c’est une expression + compliquée

; Calcul de be
; Il faut calculer les arguments a de 0 à n.
; Puis on AStore
IStore(n+2)
; ...
AStore(2)
Goto dispatch

Appel à Kontinuation : Call(K, [be]) = Ret(be)

be est l’argument de la kontinuation.

ALoad(0) ; v0 = Kontinuation courante
Calcul(be)
AStore 2 ; résultat de be
Goto dispatch

dispatch

Push : PushCont(cont, ids, e)

let E = [K, E, eds] in
 let K = cont in e
Push taille len(ids) + 2 ; 2 : 1 pour k et 1 pour e
ANewArray ; création du tableau
; Maintenant on écrit dedans les nouvelles valeurs
E[0] <- v0
E[1] <- v1
E[2] <- les autres variables "ids"
AStore 1 ; on met l'adresse du tableau E sur la pile
; Il faut laisser au sommet de la pile l'adresse de la kontinuation correspondante
Push 'adresse'
IStore 0

Def : DefCont(cont, [x, y, z], res, expr)

def kont(e, res) =
     let [K, E, x, y, z] = e in
     expr
label_kont:
 ; extraire l'environnement e
 ; v1 = (kont, env, variables)
 v0 <- v1[0] ; on change de Kontinuation
 v3 <- v1[2] ; x
 v4 <- v1[3] ; y
 v5 <- v1[4] ; z
 v1 <- v1[1] ; env, qu'il faut faire à la fin pour pas perdre les variables, car on écrit dans v1