summaryrefslogtreecommitdiff
path: root/src/decomp/expr
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-01-27 00:43:59 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-01-27 00:43:59 (GMT)
commit7f35f8d2f211fdf087252ede7665e9c81f35cdc7 (patch)
treed1c88366bc73e51db38ef982897e95950405bf52 /src/decomp/expr
parent2050b07c42c15738662dd9b3c5841694b64ab2a3 (diff)
Implemented the first steps for visiting or replacing items in decompiled instructions.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@331 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/decomp/expr')
-rw-r--r--src/decomp/expr/access.c84
-rw-r--r--src/decomp/expr/arithm.c84
-rw-r--r--src/decomp/expr/array.c84
-rw-r--r--src/decomp/expr/assign.c84
-rw-r--r--src/decomp/expr/block.c80
-rw-r--r--src/decomp/expr/call.c80
-rw-r--r--src/decomp/expr/cond.c84
-rw-r--r--src/decomp/expr/return.c78
8 files changed, 658 insertions, 0 deletions
diff --git a/src/decomp/expr/access.c b/src/decomp/expr/access.c
index 277209a..f06c47b 100644
--- a/src/decomp/expr/access.c
+++ b/src/decomp/expr/access.c
@@ -54,6 +54,12 @@ static void g_access_expression_class_init(GAccessExpressionClass *);
/* Initialise une instance d'accessation quelconque. */
static void g_access_expression_init(GAccessExpression *);
+/* Visite un ensemble hiérarchique d'instructions décompilées. */
+static bool g_access_expression_visit(GAccessExpression *, dec_instr_visitor_cb, DecInstrVisitFlags, void *);
+
+/* Remplace une instruction décompilée par une autre. */
+static bool g_access_expression_replace(GAccessExpression *, GDecInstruction *, GDecInstruction *);
+
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_access_expression_print(const GAccessExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *);
@@ -99,6 +105,8 @@ static void g_access_expression_init(GAccessExpression *expr)
instr = G_DEC_INSTRUCTION(expr);
+ instr->visit = (dec_instr_visit_fc)g_access_expression_visit;
+ instr->replace = (dec_instr_replace_fc)g_access_expression_replace;
instr->print = (dec_instr_print_fc)g_access_expression_print;
}
@@ -133,6 +141,82 @@ GDecInstruction *g_access_expression_new(GDecExpression *owner, GDecExpression *
/******************************************************************************
* *
+* Paramètres : expr = première instruction à venir visiter. *
+* callback = procédure à appeler à chaque instruction visitée. *
+* flags = moments des appels à réaliser en retour. *
+* data = données quelconques associées au visiteur. *
+* *
+* Description : Visite un ensemble hiérarchique d'instructions décompilées. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_access_expression_visit(GAccessExpression *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->owner), callback, flags, data);
+
+ if (result)
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->target), callback, flags, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = première instruction à venir ausculter. *
+* old = instruction décompilée à venir remplacer. *
+* new = instruction décompilée à utiliser dorénavant. *
+* *
+* Description : Remplace une instruction décompilée par une autre. *
+* *
+* Retour : true si un remplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_access_expression_replace(GAccessExpression *expr, GDecInstruction *old, GDecInstruction *new)
+{
+ bool result; /* Bilan à retourner */
+
+ if (expr->owner == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->owner));
+ g_object_ref(G_OBJECT(new));
+ expr->owner = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->owner), old, new);
+
+ if (expr->target == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->target));
+ g_object_ref(G_OBJECT(new));
+ expr->target = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->target), old, new);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : expr = expression à transcrire en version humaine. *
* buffer = tampon où doit se réaliser l'insertion. *
* line = ligne d'impression prête à emploi ou NULL. *
diff --git a/src/decomp/expr/arithm.c b/src/decomp/expr/arithm.c
index d91e080..3811cf4 100644
--- a/src/decomp/expr/arithm.c
+++ b/src/decomp/expr/arithm.c
@@ -56,6 +56,12 @@ static void g_arithm_expression_class_init(GArithmExpressionClass *);
/* Initialise une instance d'opération arithmétique définie. */
static void g_arithm_expression_init(GArithmExpression *);
+/* Visite un ensemble hiérarchique d'instructions décompilées. */
+static bool g_arithm_expression_visit(GArithmExpression *, dec_instr_visitor_cb, DecInstrVisitFlags, void *);
+
+/* Remplace une instruction décompilée par une autre. */
+static bool g_arithm_expression_replace(GArithmExpression *, GDecInstruction *, GDecInstruction *);
+
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_arithm_expression_print(const GArithmExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *);
@@ -101,6 +107,8 @@ static void g_arithm_expression_init(GArithmExpression *expr)
instr = G_DEC_INSTRUCTION(expr);
+ instr->visit = (dec_instr_visit_fc)g_arithm_expression_visit;
+ instr->replace = (dec_instr_replace_fc)g_arithm_expression_replace;
instr->print = (dec_instr_print_fc)g_arithm_expression_print;
}
@@ -138,6 +146,82 @@ GDecInstruction *g_arithm_expression_new(GDecExpression *op1, ArithmOperationTyp
/******************************************************************************
* *
+* Paramètres : expr = première instruction à venir visiter. *
+* callback = procédure à appeler à chaque instruction visitée. *
+* flags = moments des appels à réaliser en retour. *
+* data = données quelconques associées au visiteur. *
+* *
+* Description : Visite un ensemble hiérarchique d'instructions décompilées. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arithm_expression_visit(GArithmExpression *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->op1), callback, flags, data);
+
+ if (result)
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->op2), callback, flags, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = première instruction à venir ausculter. *
+* old = instruction décompilée à venir remplacer. *
+* new = instruction décompilée à utiliser dorénavant. *
+* *
+* Description : Remplace une instruction décompilée par une autre. *
+* *
+* Retour : true si un remplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arithm_expression_replace(GArithmExpression *expr, GDecInstruction *old, GDecInstruction *new)
+{
+ bool result; /* Bilan à retourner */
+
+ if (expr->op1 == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->op1));
+ g_object_ref(G_OBJECT(new));
+ expr->op1 = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->op1), old, new);
+
+ if (expr->op2 == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->op2));
+ g_object_ref(G_OBJECT(new));
+ expr->op2 = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->op2), old, new);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : expr = expression à transcrire en version humaine. *
* buffer = tampon où doit se réaliser l'insertion. *
* line = ligne d'impression prête à emploi ou NULL. *
diff --git a/src/decomp/expr/array.c b/src/decomp/expr/array.c
index dc487ee..4053169 100644
--- a/src/decomp/expr/array.c
+++ b/src/decomp/expr/array.c
@@ -54,6 +54,12 @@ static void g_array_access_class_init(GArrayAccessClass *);
/* Initialise une instance d'accès à une cellule de tableau. */
static void g_array_access_init(GArrayAccess *);
+/* Visite un ensemble hiérarchique d'instructions décompilées. */
+static bool g_array_access_visit(GArrayAccess *, dec_instr_visitor_cb, DecInstrVisitFlags, void *);
+
+/* Remplace une instruction décompilée par une autre. */
+static bool g_array_access_replace(GArrayAccess *, GDecInstruction *, GDecInstruction *);
+
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_array_access_print(const GArrayAccess *, GCodeBuffer *, GBufferLine *, GLangOutput *);
@@ -99,6 +105,8 @@ static void g_array_access_init(GArrayAccess *expr)
instr = G_DEC_INSTRUCTION(expr);
+ instr->visit = (dec_instr_visit_fc)g_array_access_visit;
+ instr->replace = (dec_instr_replace_fc)g_array_access_replace;
instr->print = (dec_instr_print_fc)g_array_access_print;
}
@@ -133,6 +141,82 @@ GDecInstruction *g_array_access_new(GDecExpression *array, GDecExpression *index
/******************************************************************************
* *
+* Paramètres : expr = première instruction à venir visiter. *
+* callback = procédure à appeler à chaque instruction visitée. *
+* flags = moments des appels à réaliser en retour. *
+* data = données quelconques associées au visiteur. *
+* *
+* Description : Visite un ensemble hiérarchique d'instructions décompilées. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_array_access_visit(GArrayAccess *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->array), callback, flags, data);
+
+ if (result)
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->index), callback, flags, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = première instruction à venir ausculter. *
+* old = instruction décompilée à venir remplacer. *
+* new = instruction décompilée à utiliser dorénavant. *
+* *
+* Description : Remplace une instruction décompilée par une autre. *
+* *
+* Retour : true si un remplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_array_access_replace(GArrayAccess *expr, GDecInstruction *old, GDecInstruction *new)
+{
+ bool result; /* Bilan à retourner */
+
+ if (expr->array == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->array));
+ g_object_ref(G_OBJECT(new));
+ expr->array = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->array), old, new);
+
+ if (expr->index == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->index));
+ g_object_ref(G_OBJECT(new));
+ expr->index = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->index), old, new);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : expr = expression à transcrire en version humaine. *
* buffer = tampon où doit se réaliser l'insertion. *
* line = ligne d'impression prête à emploi ou NULL. *
diff --git a/src/decomp/expr/assign.c b/src/decomp/expr/assign.c
index fd86021..26d31f6 100644
--- a/src/decomp/expr/assign.c
+++ b/src/decomp/expr/assign.c
@@ -54,6 +54,12 @@ static void g_assign_expression_class_init(GAssignExpressionClass *);
/* Initialise une instance d'assignation quelconque. */
static void g_assign_expression_init(GAssignExpression *);
+/* Visite un ensemble hiérarchique d'instructions décompilées. */
+static bool g_assign_expression_visit(GAssignExpression *, dec_instr_visitor_cb, DecInstrVisitFlags, void *);
+
+/* Remplace une instruction décompilée par une autre. */
+static bool g_assign_expression_replace(GAssignExpression *, GDecInstruction *, GDecInstruction *);
+
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_assign_expression_print(const GAssignExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *);
@@ -99,6 +105,8 @@ static void g_assign_expression_init(GAssignExpression *expr)
instr = G_DEC_INSTRUCTION(expr);
+ instr->visit = (dec_instr_visit_fc)g_assign_expression_visit;
+ instr->replace = (dec_instr_replace_fc)g_assign_expression_replace;
instr->print = (dec_instr_print_fc)g_assign_expression_print;
}
@@ -133,6 +141,82 @@ GDecInstruction *g_assign_expression_new(GDecExpression *dest, GDecExpression *s
/******************************************************************************
* *
+* Paramètres : expr = première instruction à venir visiter. *
+* callback = procédure à appeler à chaque instruction visitée. *
+* flags = moments des appels à réaliser en retour. *
+* data = données quelconques associées au visiteur. *
+* *
+* Description : Visite un ensemble hiérarchique d'instructions décompilées. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_assign_expression_visit(GAssignExpression *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->dest), callback, flags, data);
+
+ if (result)
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->src), callback, flags, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = première instruction à venir ausculter. *
+* old = instruction décompilée à venir remplacer. *
+* new = instruction décompilée à utiliser dorénavant. *
+* *
+* Description : Remplace une instruction décompilée par une autre. *
+* *
+* Retour : true si un remplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_assign_expression_replace(GAssignExpression *expr, GDecInstruction *old, GDecInstruction *new)
+{
+ bool result; /* Bilan à retourner */
+
+ if (expr->dest == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->dest));
+ g_object_ref(G_OBJECT(new));
+ expr->dest = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->dest), old, new);
+
+ if (expr->src == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->src));
+ g_object_ref(G_OBJECT(new));
+ expr->src = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->src), old, new);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : expr = expression à transcrire en version humaine. *
* buffer = tampon où doit se réaliser l'insertion. *
* line = ligne d'impression prête à emploi ou NULL. *
diff --git a/src/decomp/expr/block.c b/src/decomp/expr/block.c
index 5124204..3c56ef6 100644
--- a/src/decomp/expr/block.c
+++ b/src/decomp/expr/block.c
@@ -57,6 +57,12 @@ static void g_expr_block_class_init(GExprBlockClass *);
/* Initialise une instance d'ensemble d'instructions. */
static void g_expr_block_init(GExprBlock *);
+/* Visite un ensemble hiérarchique d'instructions décompilées. */
+static bool g_expr_block_visit(GExprBlock *, dec_instr_visitor_cb, DecInstrVisitFlags, void *);
+
+/* Remplace une instruction décompilée par une autre. */
+static bool g_expr_block_replace(GExprBlock *, GDecInstruction *, GDecInstruction *);
+
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_expr_block_print(const GExprBlock *, GCodeBuffer *, GBufferLine *, GLangOutput *);
@@ -102,6 +108,8 @@ static void g_expr_block_init(GExprBlock *block)
instr = G_DEC_INSTRUCTION(block);
+ instr->visit = (dec_instr_visit_fc)g_expr_block_visit;
+ instr->replace = (dec_instr_replace_fc)g_expr_block_replace;
instr->print = (dec_instr_print_fc)g_expr_block_print;
}
@@ -134,6 +142,78 @@ GDecInstruction *g_expr_block_new(GDecInstruction *item)
/******************************************************************************
* *
+* Paramètres : block = première instruction à venir visiter. *
+* callback = procédure à appeler à chaque instruction visitée. *
+* flags = moments des appels à réaliser en retour. *
+* data = données quelconques associées au visiteur. *
+* *
+* Description : Visite un ensemble hiérarchique d'instructions décompilées. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_expr_block_visit(GExprBlock *block, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = true;
+
+ for (i = 0; i < block->count && result; i++)
+ result = g_dec_instruction_visit(block->list[i], callback, flags, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = première instruction à venir ausculter. *
+* old = instruction décompilée à venir remplacer. *
+* new = instruction décompilée à utiliser dorénavant. *
+* *
+* Description : Remplace une instruction décompilée par une autre. *
+* *
+* Retour : true si un remplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_expr_block_replace(GExprBlock *block, GDecInstruction *old, GDecInstruction *new)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = false;
+
+ for (i = 0; i < block->count; i++)
+ {
+ if (block->list[i] == old)
+ {
+ g_object_unref(G_OBJECT(block->list[i]));
+ g_object_ref(G_OBJECT(new));
+ block->list[i] = new;
+
+ result = true;
+
+ }
+ else
+ result |= g_dec_instruction_replace(block->list[i], old, new);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : block = expression à transcrire en version humaine. *
* buffer = tampon où doit se réaliser l'insertion. *
* line = ligne d'impression prête à emploi ou NULL. *
diff --git a/src/decomp/expr/call.c b/src/decomp/expr/call.c
index e518c6f..ed1c43a 100644
--- a/src/decomp/expr/call.c
+++ b/src/decomp/expr/call.c
@@ -60,6 +60,12 @@ static void g_routine_call_class_init(GRoutineCallClass *);
/* Initialise une instance d'appel à une routine quelconque. */
static void g_routine_call_init(GRoutineCall *);
+/* Visite un ensemble hiérarchique d'instructions décompilées. */
+static bool g_routine_call_visit(GRoutineCall *, dec_instr_visitor_cb, DecInstrVisitFlags, void *);
+
+/* Remplace une instruction décompilée par une autre. */
+static bool g_routine_call_replace(GRoutineCall *, GDecInstruction *, GDecInstruction *);
+
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_routine_call_print(const GRoutineCall *, GCodeBuffer *, GBufferLine *, GLangOutput *);
@@ -105,6 +111,8 @@ static void g_routine_call_init(GRoutineCall *expr)
instr = G_DEC_INSTRUCTION(expr);
+ instr->visit = (dec_instr_visit_fc)g_routine_call_visit;
+ instr->replace = (dec_instr_replace_fc)g_routine_call_replace;
instr->print = (dec_instr_print_fc)g_routine_call_print;
}
@@ -137,6 +145,78 @@ GDecInstruction *g_routine_call_new(GBinRoutine *routine)
/******************************************************************************
* *
+* Paramètres : call = première instruction à venir visiter. *
+* callback = procédure à appeler à chaque instruction visitée. *
+* flags = moments des appels à réaliser en retour. *
+* data = données quelconques associées au visiteur. *
+* *
+* Description : Visite un ensemble hiérarchique d'instructions décompilées. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_routine_call_visit(GRoutineCall *call, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = true;
+
+ for (i = 0; i < call->count && result; i++)
+ result = g_dec_instruction_visit(call->args[i], callback, flags, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : call = première instruction à venir ausculter. *
+* old = instruction décompilée à venir remplacer. *
+* new = instruction décompilée à utiliser dorénavant. *
+* *
+* Description : Remplace une instruction décompilée par une autre. *
+* *
+* Retour : true si un remplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_routine_call_replace(GRoutineCall *call, GDecInstruction *old, GDecInstruction *new)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = false;
+
+ for (i = 0; i < call->count; i++)
+ {
+ if (call->args[i] == old)
+ {
+ g_object_unref(G_OBJECT(call->args[i]));
+ g_object_ref(G_OBJECT(new));
+ call->args[i] = new;
+
+ result = true;
+
+ }
+ else
+ result |= g_dec_instruction_replace(call->args[i], old, new);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : call = expression à transcrire en version humaine. *
* buffer = tampon où doit se réaliser l'insertion. *
* line = ligne d'impression prête à emploi ou NULL. *
diff --git a/src/decomp/expr/cond.c b/src/decomp/expr/cond.c
index 4a9b63b..d96f483 100644
--- a/src/decomp/expr/cond.c
+++ b/src/decomp/expr/cond.c
@@ -55,6 +55,12 @@ static void g_cond_expression_class_init(GCondExpressionClass *);
/* Initialise une instance de condition binaire quelconque. */
static void g_cond_expression_init(GCondExpression *);
+/* Visite un ensemble hiérarchique d'instructions décompilées. */
+static bool g_cond_expression_visit(GCondExpression *, dec_instr_visitor_cb, DecInstrVisitFlags, void *);
+
+/* Remplace une instruction décompilée par une autre. */
+static bool g_cond_expression_replace(GCondExpression *, GDecInstruction *, GDecInstruction *);
+
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_cond_expression_print(const GCondExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *);
@@ -100,6 +106,8 @@ static void g_cond_expression_init(GCondExpression *expr)
instr = G_DEC_INSTRUCTION(expr);
+ instr->visit = (dec_instr_visit_fc)g_cond_expression_visit;
+ instr->replace = (dec_instr_replace_fc)g_cond_expression_replace;
instr->print = (dec_instr_print_fc)g_cond_expression_print;
}
@@ -136,6 +144,82 @@ GDecInstruction *g_cond_expression_new(GDecExpression *a, CompSignType sign, GDe
/******************************************************************************
* *
+* Paramètres : expr = première instruction à venir visiter. *
+* callback = procédure à appeler à chaque instruction visitée. *
+* flags = moments des appels à réaliser en retour. *
+* data = données quelconques associées au visiteur. *
+* *
+* Description : Visite un ensemble hiérarchique d'instructions décompilées. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_cond_expression_visit(GCondExpression *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->a), callback, flags, data);
+
+ if (result)
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->b), callback, flags, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = première instruction à venir ausculter. *
+* old = instruction décompilée à venir remplacer. *
+* new = instruction décompilée à utiliser dorénavant. *
+* *
+* Description : Remplace une instruction décompilée par une autre. *
+* *
+* Retour : true si un remplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_cond_expression_replace(GCondExpression *expr, GDecInstruction *old, GDecInstruction *new)
+{
+ bool result; /* Bilan à retourner */
+
+ if (expr->a == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->a));
+ g_object_ref(G_OBJECT(new));
+ expr->a = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->a), old, new);
+
+ if (expr->b == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->b));
+ g_object_ref(G_OBJECT(new));
+ expr->b = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->b), old, new);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : expr = expression à transcrire en version humaine. *
* buffer = tampon où doit se réaliser l'insertion. *
* line = ligne d'impression prête à emploi ou NULL. *
diff --git a/src/decomp/expr/return.c b/src/decomp/expr/return.c
index a9c10d9..d012893 100644
--- a/src/decomp/expr/return.c
+++ b/src/decomp/expr/return.c
@@ -53,6 +53,12 @@ static void g_return_expression_class_init(GReturnExpressionClass *);
/* Initialise une instance d'ordre de retour. */
static void g_return_expression_init(GReturnExpression *);
+/* Visite un ensemble hiérarchique d'instructions décompilées. */
+static bool g_return_expression_visit(GReturnExpression *, dec_instr_visitor_cb, DecInstrVisitFlags, void *);
+
+/* Remplace une instruction décompilée par une autre. */
+static bool g_return_expression_replace(GReturnExpression *, GDecInstruction *, GDecInstruction *);
+
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_return_expression_print(const GReturnExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *);
@@ -98,6 +104,8 @@ static void g_return_expression_init(GReturnExpression *expr)
instr = G_DEC_INSTRUCTION(expr);
+ instr->visit = (dec_instr_visit_fc)g_return_expression_visit;
+ instr->replace = (dec_instr_replace_fc)g_return_expression_replace;
instr->print = (dec_instr_print_fc)g_return_expression_print;
}
@@ -130,6 +138,76 @@ GDecInstruction *g_return_expression_new(GDecExpression *payload)
/******************************************************************************
* *
+* Paramètres : expr = première instruction à venir visiter. *
+* callback = procédure à appeler à chaque instruction visitée. *
+* flags = moments des appels à réaliser en retour. *
+* data = données quelconques associées au visiteur. *
+* *
+* Description : Visite un ensemble hiérarchique d'instructions décompilées. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_return_expression_visit(GReturnExpression *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
+{
+ bool result; /* Bilan à retourner */
+
+ if (expr->payload)
+ result = g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->payload), callback, flags, data);
+ else
+ result = false;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = première instruction à venir ausculter. *
+* old = instruction décompilée à venir remplacer. *
+* new = instruction décompilée à utiliser dorénavant. *
+* *
+* Description : Remplace une instruction décompilée par une autre. *
+* *
+* Retour : true si un remplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_return_expression_replace(GReturnExpression *expr, GDecInstruction *old, GDecInstruction *new)
+{
+ bool result; /* Bilan à retourner */
+
+ if (expr->payload)
+ {
+ if (expr->payload == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->payload));
+ g_object_ref(G_OBJECT(new));
+ expr->payload = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->payload), old, new);
+
+ }
+ else
+ result = false;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : expr = expression à transcrire en version humaine. *
* buffer = tampon où doit se réaliser l'insertion. *
* line = ligne d'impression prête à emploi ou NULL. *