diff options
Diffstat (limited to 'tools/d2c/conv/manager.c')
-rw-r--r-- | tools/d2c/conv/manager.c | 420 |
1 files changed, 216 insertions, 204 deletions
diff --git a/tools/d2c/conv/manager.c b/tools/d2c/conv/manager.c index 555ea38..33518db 100644 --- a/tools/d2c/conv/manager.c +++ b/tools/d2c/conv/manager.c @@ -29,6 +29,7 @@ #include <malloc.h> #include <stdbool.h> #include <string.h> +#include <unistd.h> #include "../helpers.h" @@ -42,11 +43,6 @@ /* Fonction de conversion */ struct _conv_func { - bool used; /* Conversion utilisée ? */ - bool intermediate; /* Variable intermédiaire ? */ - bool declared; /* Expression déjà déclarée ? */ - bool defined; /* Expression déjà définie ? */ - char *dest; /* Variable de destination */ bool is_expr; /* Choix du contenu réel */ @@ -64,9 +60,18 @@ struct _conv_func }; + bool used_as_inter; /* Variable intermédiaire ? */ + bool used_as_op; /* Opérande finale d'instruct° */ + bool declared; /* Expression déjà déclarée ? */ + bool defined; /* Expression déjà définie ? */ + }; +/* Indique si l'utilisation en intermédiaire est brute ou non. */ +static bool is_conv_func_raw_as_inter(const conv_func *); + + /* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */ @@ -196,25 +201,6 @@ const char *get_conv_dest_name(const conv_func *func) /****************************************************************************** * * * Paramètres : func = fonction de conversion à consulter. * -* * -* Description : Indique la nature d'une conversion : fonction ou expression ?* -* * -* Retour : Indication sur la constitution interne de la conversion. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool is_conv_func_expression(const conv_func *func) -{ - return func->is_expr; - -} - - -/****************************************************************************** -* * -* Paramètres : func = fonction de conversion à consulter. * * bits = gestionnaire des bits d'encodage. * * list = liste de l'ensemble des fonctions de conversion. * * size = taille déterminée avec précision. [OUT] * @@ -260,8 +246,13 @@ bool mark_conv_func(conv_func *func, bool inter, const coding_bits *bits, const { bool result; /* Bilan à remonter */ - func->used = true; - func->intermediate |= inter; + if (inter) + func->used_as_inter = true; + else + { + assert(!func->is_expr); + func->used_as_op = true; + } if (func->is_expr) result = ensure_arg_expr_content_fully_marked(func->expr, bits, list); @@ -275,69 +266,160 @@ bool mark_conv_func(conv_func *func, bool inter, const coding_bits *bits, const /****************************************************************************** * * -* Paramètres : func = fonction de conversion à manipuler. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* pp = pré-processeur pour les échanges de chaînes. * -* wide = taille des mots décodés. * +* Paramètres : func = fonction de conversion à consulter. * * * -* Description : Déclare les variables associées à une fonction de conversion.* +* Description : Indique si l'utilisation en intermédiaire est brute ou non. * * * -* Retour : Bilan de l'opération. * +* Retour : true si une variable brute est à manipuler, false sinon. * * * * Remarques : - * * * ******************************************************************************/ -bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, const pre_processor *pp, unsigned int wide) +static bool is_conv_func_raw_as_inter(const conv_func *func) { - bool result; /* Bilan à remonter */ + bool result; /* Résultat à faire remonter */ - printf(" -> declaration for '%s': declared ? %d - expr ? %d\n", - func->dest, func->declared, func->is_expr); + if (func->is_expr) + result = true; + else + result = (strcmp(func->name, "UInt") == 0); - assert(func->used); + return result; - /* Si la fonction a déjà été définie lors d'un précédent besoin... */ - if (func->declared) return true; +} - if (func->is_expr) - result = ensure_arg_expr_content_fully_declared(func->expr, fd, bits, list, pp, wide); - else - result = ensure_arg_list_content_fully_declared(func->args, fd, bits, list, pp, wide); - if (result && func->intermediate) - { - if (!func->is_expr && is_operand_producer(pp, func->name)) - dprintf(fd, "\t\tGArchOperand *val_%s;\n", func->dest); - else - dprintf(fd, "\t\tuint%u_t val_%s;\n", wide, func->dest); - } - func->declared = result; +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à manipuler. * +* fd = descripteur d'un flux ouvert en écriture. * +* inter = note un résultat de conversion comme intermédiaire. * +* * +* Description : Imprime la désignation de la destination d'une conversion. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - return result; +void write_conv_func(conv_func *func, int fd, bool inter) +{ + bool as_raw; /* Choix logique du format */ + + if (inter) + as_raw = is_conv_func_raw_as_inter(func); + else + as_raw = false; + + if (as_raw) + dprintf(fd, "val_%s", func->dest); + else + dprintf(fd, "op_%s", func->dest); } /****************************************************************************** * * -* Paramètres : func = fonction de conversion à consulter. * +* Paramètres : func = fonction de conversion à manipuler. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* tab = décalage éventuel selon l'inclusion. * * * -* Description : Indique si une conversion a déjà été définie. * +* Description : Déclare les variables associées à une fonction de conversion.* * * -* Retour : Etat de la définition. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -bool is_conv_func_already_defined(const conv_func *func) +bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, const char *tab) { - return func->defined; + bool result; /* Bilan à remonter */ + bool as_raw; /* Choix logique du format */ + unsigned int wide; /* Taille des mots */ + off_t start; /* Point de départ dans le code*/ + off_t end; /* Point d'arrivée dans le code*/ + + assert(func->used_as_inter || func->used_as_op); + + /** + * Si la fonction a déjà été définie lors d'un précédent besoin... + */ + if (func->declared) return true; + + if (func->is_expr) + result = ensure_arg_expr_content_fully_declared(func->expr, fd, bits, list, tab); + + else + result = ensure_arg_list_content_fully_declared(func->args, fd, bits, list, tab); + + if (result) + { + if (func->used_as_inter) + { + as_raw = is_conv_func_raw_as_inter(func); + + /** + * Si la variable intermédiaire n'est pas brute, deux cas de figure + * sont possibles : + * + * - la variable est un objet purement intermédiaire. + * - la variable est un object qui sera également utilisé en opérande. + * + * Dans les deux cas, on laisse la déclaration en tant qu'opérande + * rédiger la déclaration car il s'agit de déclarations identiques. + */ + + if (as_raw) + { + wide = count_coded_bits(bits); + + start = lseek(fd, 0, SEEK_CUR); + + dprintf(fd, "\t%suint%u_t ", tab, wide); + + write_conv_func(func, fd, true); + + dprintf(fd, ";"); + + end = lseek(fd, 0, SEEK_CUR); + + dprintf(fd, "%*s", (tab[0] == '\0' ? 42 : 39) - (int)(end - start), "/"); + dprintf(fd, "* Champ brut à décoder */\n"); + + } + + } + + if (func->used_as_op || (func->used_as_inter && !as_raw)) + { + start = lseek(fd, 0, SEEK_CUR); + + dprintf(fd, "\t%sGArchOperand *", tab); + + write_conv_func(func, fd, false); + + dprintf(fd, ";"); + + end = lseek(fd, 0, SEEK_CUR); + + dprintf(fd, "%*s", (tab[0] == '\0' ? 42 : 39) - (int)(end - start), "/"); + dprintf(fd, "* Opérande à intégrer */\n"); + + } + + } + + func->declared = result; + + return result; } @@ -345,13 +427,11 @@ bool is_conv_func_already_defined(const conv_func *func) /****************************************************************************** * * * Paramètres : func = fonction de conversion à manipuler. * -* last = précise si la conversion est la dernière. * -* internal = indique le type de manipulation finale. * * fd = descripteur d'un flux ouvert en écriture. * -* arch = architecture visée par l'opération globale. * * bits = gestionnaire des bits d'encodage. * * list = liste de l'ensemble des fonctions de conversion. * -* pp = pré-processeur pour les échanges de chaînes. * +* tab = décalage éventuel selon l'inclusion. * +* optional = indique si l'opérande finale est optionnelle. * * exit = exprime le besoin d'une voie de sortie. [OUT] * * * * Description : Définit les variables associées à une fonction de conversion.* @@ -362,89 +442,109 @@ bool is_conv_func_already_defined(const conv_func *func) * * ******************************************************************************/ -bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp, bool *exit) +bool define_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, const char *tab, bool optional, bool *exit) { bool result; /* Bilan à remonter */ - const char *callable; /* Fonction à appeler */ + bool as_raw; /* Choix logique du format */ - /* Si la fonction a déjà été définie lors d'un précédent besoin... */ - if (func->defined) return true; + /** + * Si la fonction a déjà été définie lors d'un précédent besoin... + */ + if (func->defined) + { + // TODO : faire un object_ref() si c'est un objet + //assert(0); + + return true; + + } if (func->is_expr) - result = ensure_arg_expr_content_fully_defined(func->expr, fd, arch, bits, list, pp, exit); + result = ensure_arg_expr_content_fully_defined(func->expr, fd, bits, list, tab, exit); else - result = ensure_arg_list_content_fully_defined(func->args, fd, arch, bits, list, pp, exit); - - /* Nom de la fonction effectivement appelée */ + result = ensure_arg_list_content_fully_defined(func->args, fd, bits, list, tab, exit); - if (!func->is_expr) + if (result) { - callable = find_macro(pp, func->name); + if (func->used_as_inter) + { + as_raw = is_conv_func_raw_as_inter(func); - if (callable == NULL) - callable = func->name; + /** + * Se référer au besoin aux commentaires de declare_conv_func(). + */ - } - else callable = NULL; + if (as_raw) + { + dprintf(fd, "\t%s", tab); - if (last && callable == NULL) - { - fprintf(stderr, "Error: expected function to store '%s'.\n", func->dest); - return false; - } + write_conv_func(func, fd, true); - /* Dernier niveau : la variable de destination est imposée ! */ - if (last) - { - /* Si l'on doit manipuler une propriété d'instructon... */ - if (internal) - result = checked_call_instr_func(false, callable, func->args, fd, bits, list, pp); + dprintf(fd, " = "); - /* Si on doit constituer un opérande à ajouter... */ - else - { - if (strchr(callable, '(') == NULL) - dprintf(fd, "\t\top = %s(", callable); - else - dprintf(fd, "\t\top = %s", callable); + if (func->is_expr) + result = define_arg_expr(func->expr, fd, bits, list); - result &= define_arg_list(func->args, fd, bits, list); + else + { + assert(strcmp(func->name, "UInt") == 0); + assert(get_arg_list_size(func->args) == 1); - dprintf(fd, ");\n"); + result = define_arg_list(func->args, fd, bits, list); - } + } - } + dprintf(fd, ";\n"); + dprintf(fd, "\n"); - /* On constitue une variable intermédiaire, dont on peut conserver le nom ! */ - else - { - dprintf(fd, "\t\tval_%s = ", func->dest); + } - if (func->is_expr) - result &= define_arg_expr(func->expr, fd, bits, list); + } - else + if (func->used_as_op || (func->used_as_inter && !as_raw)) { - dprintf(fd, "%s(", callable); + dprintf(fd, "\t%s", tab); + + write_conv_func(func, fd, false); + + dprintf(fd, " = %s(", func->name); result = define_arg_list(func->args, fd, bits, list); - dprintf(fd, ")"); + dprintf(fd, ");\n"); - } + if (optional) + { + if (as_raw) + { + fprintf(stderr, "%s can not be optional and used as intermediate value as the same time!\n", + func->dest); - dprintf(fd, ";\n"); + result = false; + + } + + } + + else + { + dprintf(fd, "\t%sif (", tab); + + write_conv_func(func, fd, false); + + dprintf(fd, " == NULL) goto bad_exit;\n"); + + *exit = true; + + } + + dprintf(fd, "\n"); - if (!func->is_expr && is_operand_producer(pp, func->name)) - { - dprintf(fd, "\t\tif (val_%s == NULL) goto bad_exit;\n", func->dest); - *exit = true; } - } + func->defined = result; - func->defined = result; + } return result; @@ -562,91 +662,3 @@ conv_func *find_named_conv_in_list(const conv_list *list, const char *name) return result; } - - -/****************************************************************************** -* * -* Paramètres : list = liste de fonctions de conversion à consulter. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* pp = pré-processeur pour les échanges de chaînes. * -* wide = taille des mots décodés. * -* * -* Description : Déclare l'ensemble des variables intermédiaires. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool declare_used_intermediate_conversions(const conv_list *list, int fd, const coding_bits *bits, const pre_processor *pp, unsigned int wide) -{ - bool result; /* Bilan à remonter */ - size_t i; /* Boucle de parcours */ - conv_func *func; /* Conversion à traiter */ - - result = true; - - for (i = 0; i < list->func_count && result; i++) - { - func = list->functions[i]; - - if (func->used && func->intermediate) - result = declare_conv_func(func, fd, bits, list, pp, wide); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = liste de fonctions de conversion à consulter. * -* fd = descripteur d'un flux ouvert en écriture. * -* arch = architecture visée par l'opération globale. * -* bits = gestionnaire des bits d'encodage. * -* pp = pré-processeur pour les échanges de chaînes. * -* exit = exprime le besoin d'une voie de sortie. [OUT] * -* * -* Description : Définit l'ensemble des variables intermédiaires. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool define_used_intermediate_conversions(const conv_list *list, int fd, const char *arch, const coding_bits *bits, const pre_processor *pp, bool *exit) -{ - bool result; /* Bilan à remonter */ - bool got_one; /* Suit le nombre d'impressions*/ - size_t i; /* Boucle de parcours */ - conv_func *func; /* Conversion à traiter */ - - result = true; - - got_one = false; - - for (i = 0; i < list->func_count && result; i++) - { - func = list->functions[i]; - - if (func->used && func->intermediate) - { - result = define_conv_func(func, false, false, fd, arch, bits, list, pp, exit); - - got_one = true; - - } - - } - - if (got_one) - dprintf(fd, "\n"); - - return result; - -} |