Génération de code
#Génération de code
La génération de code est l'étape où l'AST (Arbre Syntaxique Abstrait) est transformé en code exécutable. Cela peut être un bytecode, une IR (Intermediate Representation) comme LLVM IR, ou directement du code machine. Dans notre contexte, nous allons générer du bytecode WASM.
#À partir de l'AST
L'AST représente la structure du programme de manière hiérarchique. La génération de code consiste à parcourir cet arbre et à produire les instructions correspondantes dans le langage cible.
#Exemple d'AST
Considérons l'expression arithmétique 2 * (3 + 4)
. L'AST pourrait ressembler à :
1 *2 / \3 2 +4 / \5 3 4
#Génération de bytecode WASM
WebAssembly (WASM) est un format binaire exécutable dans les navigateurs. Nous allons générer un module WASM simple qui effectue une addition.
#Exemple (Python)
Nous allons créer un générateur de code qui produit un module WASM pour une fonction add(a, b)
.
1# Simulateur de génération de code WASM2# AST pour add(a, b) = a + b3ast = ('+', ('var', 'a'), ('var', 'b'))4 5# Génération de bytecode WASM (simplifiée)6def codegen_wasm(ast):7 code = []8 if ast[0] == '+':9 # Charger les variables 'a' et 'b' sur la pile10 code.append("local.get $a")11 code.append("local.get $b")12 # Additionner13 code.append("i32.add")14 elif ast[0] == 'var':
#Structure d'un module WASM
Un module WASM typique contient :
- Types : Signatures des fonctions.
- Fonctions : Définitions des fonctions.
- Exports : Fonctions accessibles depuis l'extérieur.
- Code : Instructions des fonctions.
#Exemple de module WASM (texte)
1(module2 (func $add (param $a i32) (param $b i32) (result i32)3 local.get $a4 local.get $b5 i32.add)6 (export "add" (func $add))7)
Ce module définit une fonction add
qui prend deux paramètres 32 bits et retourne leur somme.
#IR intermédiaire (LLVM IR)
Dans des compilateurs plus complexes, une IR comme LLVM IR est utilisée pour optimiser le code avant la génération finale.
#Exemple LLVM IR
1define i32 @add(i32 %a, i32 %b) {2 %result = add i32 %a, %b3 ret i32 %result4}
#Exercice : Générateur de code pour la multiplication
Implémentez un générateur de code qui produit un module WASM pour une fonction mul(a, b)
qui multiplie deux entiers.
#Instructions
- Définissez un AST pour l'expression
a * b
. - Implémentez une fonction
codegen_wasm
qui parcourt l'AST et génère les instructions WASM correspondantes. - Le module WASM doit exporter une fonction
mul
qui prend deux paramètresi32
et retourne leur produit.
#Exemple de code
1# Simulateur de génération de code WASM2# AST pour mul(a, b) = a * b3ast = ('*', ('var', 'a'), ('var', 'b'))4 5# Génération de bytecode WASM (simplifiée)6def codegen_wasm(ast):7 code = []8 if ast[0] == '*':9 # Charger les variables 'a' et 'b' sur la pile10 code.append("local.get $a")11 code.append("local.get $b")12 # Multiplier13 code.append("i32.mul")14 elif ast[0] == 'var':
- Constant Folding : Évaluer les expressions constantes à la compilation.
- Dead Code Elimination : Supprimer le code non utilisé.
- Register Allocation : Assigner les variables aux registres du processeur.