diff options
Diffstat (limited to 'lib/assembler.c')
-rw-r--r-- | lib/assembler.c | 1015 |
1 files changed, 1007 insertions, 8 deletions
diff --git a/lib/assembler.c b/lib/assembler.c index 28bd714..2a3bb86 100644 --- a/lib/assembler.c +++ b/lib/assembler.c @@ -1,26 +1,1025 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> +#include "config.h" #include "meta.h" #include "hash.h" #include "parser.h" +#include "assembler.h" +#include "exceptions.h" +#include "types.h" +#include "numbers.h" +#define downcase(x) ((((x)>='A')&&((x)<='Z'))?((x)-'A'+'a'):(x)) +#define upcase(x) ((((x)>='a')&&((x)<='z'))?((x)-'a'+'A'):(x)) -void push_pile(char * a) { - fprintf(stderr, "Push_pile(\"%s\")\n", a); +int process_file(char *); + +typedef struct expression_t { + int e_type; + int e_subtype; + Uint32 avalue; + char *symbol; + pattern_t *pattern; + int index; + int op; + struct expression_t *next, *prev, *child, *father; +} expression_t; + +typedef struct bytestream_t { + unsigned long int Encoded; + int offset, segment, size; + char * Label; + expression_t * Expr; + + struct bytestream_t * next; + + int line; + char * filename; +} bytestream_t; + +enum { + SEG_TEXT, + SEG_DATA, + SEG_BSS +}; + +enum { + E_STRING, + E_VALUE, + E_OPERATION, + E_LABEL, + E_INTERNAL, + E_PATTERN, + E_INSTRUCT +}; + +int wc = 0; +expression_t *e_current = NULL, *e_line = NULL; +int segment = -1; +int special = 0; +_TableauVariable defines, labels; +int line = -1; +char * filename = NULL, * filenames[32]; +int nestedinc = 0; + +bytestream_t * text, * data, * bss, * p_text, * p_data, * p_bss; +int s_text = 0, s_data = 0, s_bss = 0; + +expression_t *copy_expression(expression_t * e); + +static bytestream_t * pushuninit(int size) { + bytestream_t * s; + + s = (bytestream_t *) Emalloc(sizeof(bytestream_t)); + s->next = NULL; + s->Encoded = 0; + s->segment = segment + s->size = size; + s->Label = NULL; + s->Expr = NULL; + + s->line = line + s->filename = filenames[nestedinc]; + + + switch (segment) { + case SEG_TEXT: + s->offset = s_text; + p_text->next = s; + p_text = s; + s_text += size; + break; + case SEG_DATA: + s->offset = s_data; + p_data->next = s; + p_data = s; + s_data += size; + break; + case SEG_BSS: + s->offset = s_bss; + p_bss->next = s; + p_bss = s; + s_bss += size; + break; + + } + + return s; +} + +static bytestream_t * pushdword(unsigned long int d, expression_t * e) { + bytestream_t * s; + + if ((segment <= 0) || (segment >= 1)) { + exception(1, _("You have to be into the .text or the .data segment to define a value.")); + } + + s = pushuninit(1); + s->Encoded = d; + if (e) { + s->Expr = copyexpression(e); + } + + return s; +} + +static bytestream_t * pushlabel(char * label) { + bytestream_t * s; + char trouve; + + s = pushuninit(0); + s->Label = Estrdup(label); + + NomVarToVar(label, labels, &trouve); + + if (trouve) { + exception(1, _("Label already defined")); + } + + return s; +} + +static void pushstring(char * s) { + char marker = *s, valid, tstring[6]; + + while ((*s) && (marker != *s)) { + if (*s == '\\') { + s++; + switch(*s) { + case '0': + pushdword('\0', NULL); + break; + case 'a': + pushdword('\a', NULL); + break; + case 'b': + pushdword('\b', NULL); + break; + case 'f': + pushdword('\f', NULL); + break; + case 'n': + pushdword('\n', NULL); + break; + case 'r': + pushdword('\r', NULL); + break; + case 't': + pushdword('\t', NULL); + break; + case 'v': + pushdword('\v', NULL); + break; + case '\'': + case '\"': + case '\\': + pushdword(*s, NULL); + break; + case 'x': + tstring[0] = '0'; + strncpy(tstring + 1, s, 4); + pushdword(char_to_number(tstring, &valid), NULL); + break; + } + } else { + pushdword(s, NULL); + } + s++; + } + +} + +static void pushstart(void) +{ + if (segment != SEG_TEXT) { + exception(1, _("You can't have the startpoint elsewhere than the .text segment")); + } + pushlabel("__start__"); +} + +static void look4pattern(pattern_t * patterns, expression_t * expression) +{ + int i; + + for (patterns = patterns->next; patterns; patterns = patterns->next) { + for (i = 0; i < patterns->nbr; i++) { + if (!(patterns->expr[i]->type || patterns->expr[i]->string || !patterns->expr[i]->name)) { + if (!strcasecmp(patterns->expr[i]->name, expression->symbol)) { + expression->e_subtype = E_PATTERN; + expression->pattern = patterns; + expression->index = i; + return; + } + } + } + } +} + +static void look4instr(phon_t * phons, instruct_t * instructs, expression_t * e) +{ + char *stringtolook = e->symbol; + + for (phons = phons->next; phons; phons = phons->next) { + if (!strcasecmp(phons->p1, stringtolook)) { + stringtolook = phons->p2; + break; + } + } + + for (instructs = instructs->next; instructs; instructs = instructs->next) { + if (!strcasecmp(instructs->names[0], stringtolook)) { + e->e_subtype = E_INSTRUCT; + return; + } + } +} + +static void free_expr(expression_t * e) +{ + if (e->child) { + free_expr(e->child); + } + + if (e->next) { + free_expr(e->next); + } + + free(e); +} + +static expression_t *copy_expression(expression_t * e) +{ + expression_t *t, *e_t; + char trouve; + + t = Emalloc(sizeof(expression_t)); + *t = *e; + + if (t->symbol) { + e_t = (expression_t *) NomVarToVar(e->symbol, defines, &trouve); + if ((trouve) && (t->e_subtype = E_STRING)) { + free(t); + t = copy_expression(e_t); + return t; + } else { + t->symbol = Estrdup(t->symbol); + } + } + + if (t->child) { + t->child = copy_expression(t->child); + } + + if (t->next) { + t->next = copy_expression(t->next); + } + + if (t->next) { + t->next->prev = t; + } + + return t; +} + +void push_pile(char *a) +{ + int valid, number; + expression_t *e, *e_t; + char trouve; + static char err[BUFSIZ]; + + if (!wc) { + special = 0; + switch (downcase(*a)) { + case '.': + valid = 0; + special = 1; + switch (downcase(*(a + 1))) { + case 'd': + if (!(strcasecmp(a + 2, "ata"))) { + segment = SEG_DATA; + valid = 1; + wc++; + return; + } + break; + case 't': + if (!(strcasecmp(a + 2, "ext"))) { + segment = SEG_TEXT; + valid = 1; + wc++; + return; + } + break; + case 'b': + if (!(strcasecmp(a + 2, "ss"))) { + segment = SEG_BSS; + valid = 1; + wc++; + return; + } + break; + case 's': + if (!(strcasecmp(a + 2, "tart"))) { + pushstart(); + valid = 1; + wc++; + return; + } + break; + } + if (!valid) { + exception(1, _("Not a valid . directive")); + } + break; + case '#': + valid = 0; + switch (downcase(*(a + 1))) { + case 'd': + if (!(strcasecmp(a + 2, "efine"))) { + special = 2; + valid = 1; + } + wc++; + return; + case 'u': + if (!(strcasecmp(a + 2, "ndef"))) { + special = 3; + valid = 1; + } + wc++; + return; + case 'i': + if (!(strcasecmp(a + 2, "nclude"))) { + special = 4; + valid = 1; + } + wc++; + return; + } + if (!valid) { + exception(1, _("Not a valid # directive")); + } + break; + } + } + + switch (special) { + case 1: /* Cas des directives . */ + exception(1, _("Error: extra parameters to a . directive.")); + break; + case 2: /* Cas de #define */ + if (wc == 1) { + break; + } + case 0: /* Cas normal */ + e = (expression_t *) Emalloc(sizeof(expression_t)); + if (!e_line) { + e_line = e_current = e; + } + e->pattern = NULL; + number = char_to_number(a, &valid); + if (valid) { + e->e_type = E_VALUE; + e->e_subtype = E_VALUE; + e->avalue = number; + e->symbol = NULL; + } else { + e_t = (expression_t *) NomVarToVar(a, defines, &trouve); + if (trouve) { + e = copy_expression(e_t); + } else { + e->e_type = E_STRING; + e->e_subtype = E_STRING; + e->avalue = 0; + e->symbol = Estrdup(a); + } + } + e->op = -1; + e->prev = e_current; + e->next = NULL; + if (e_current) { + e_current->next = e; + } + e->father = NULL; + e->child = NULL; + + /* On prédevine le subtype sur quelques cas */ + + /* Cas des labels (en nom:) */ + + if ((wc == 0) && (a[strlen(a) - 1] == ':')) { + e->e_subtype = E_LABEL; + } + + /* Cas des pseudos instructions {DB, DW, DD, DS} */ + + if (wc == 1) { + trouve = 0; + switch (downcase(*a)) { + case 'd': + if (!*(a + 2)) { + trouve = 1; + switch (downcase(*(a + 1))) { + case 'b': + case 'w': + case 'd': + case 's': + break; + default: + trouve = 0; + } + } + } + if (trouve) { + e->e_subtype = E_INTERNAL; + e->prev->e_subtype = E_LABEL; + } + } + + /* Cas des patterns */ + + if (e->e_subtype == E_STRING) { + look4pattern(patterns, e); + } + + /* On regarde si cela n'est pas une instruction connue dans le meta langage */ + + if (((wc == 0) && (e->e_subtype == E_STRING)) + || ((wc == 1) && (e->prev->e_subtype == E_LABEL))) { + look4instr(phons, instructs, e); + } + + /* Dans tous les autres cas, nous considerons qu'il s'agit d'une référence à un label... */ + + if (e->e_subtype == E_STRING) { + e->e_subtype = E_LABEL; + } + + e_current = e; + break; + case 3: /* Cas de #undef */ + if (wc != 1) { + exception(1, _("Too much arguments to #undef")); + } + NomVarToVar(a, defines, &trouve); + if (!trouve) { + exception(1, _("Defined symbol not found.")); + } + SupprimerDansTab(&defines, a); + break; + case 4: /* Cas de #include */ + if (wc != 1) { + exception(1, _("Too much arguments to #include")); + } + sprintf(err, _("Including file at line %i"), line); + pushcontext(err); + process_file(a); + popcontext(); + break; + } + + wc++; } -void act_pile(int o) { - fprintf(stderr, "Act_pile(%i)\n", o); + +/* + {',', 0, OP_NEST}, + {'+', 2, OP_PLUS}, + {'-', 2, OP_MOINS}, + {'*', 3, OP_MUL}, + {'/', 3, OP_DIV}, + {'+' + 128, 4, OP_PLUS_UNARY}, + {'-' + 128, 4, OP_MOINS_UNARY}, + {'(', 5, OP_FUNC_CALL}, + {'(' + 128, 5, OP_LPAREN}, + {'[', 5, OP_DECAL}, + {'[' + 128, 5, OP_DIRECT}, + {255, -1, -1} +*/ + +static void evaluate(expression_t * e) +{ + expression_t *t, *u; + + if (e->e_subtype != E_OPERATION) + return; + + switch (e->op) { + case OP_PLUS: + case OP_MOINS: + case OP_MUL: + case OP_DIV: + if ((e->child->e_subtype == E_VALUE) && (e->child->next->e_subtype == E_VALUE)) { + switch (e->op) { + case OP_PLUS: + e->avalue = e->child->avalue + e->child->next->avalue; + break; + case OP_MOINS: + e->avalue = e->child->avalue - e->child->next->avalue; + break; + case OP_MUL: + e->avalue = e->child->avalue * e->child->next->avalue; + break; + case OP_DIV: + if (!e->child->next->avalue) { + exception(1, _("Zero divide.")); + } + e->avalue = e->child->avalue / e->child->next->avalue; + break; + } + free(e->child->next); + free(e->child); + e->child = NULL; + e->e_type = e->e_subtype = E_VALUE; + } else { + /* un seul cas particulier supporté... */ + if (!((e->op == OP_PLUS) + || ((e->op == OP_MOINS) && (e->child->next->e_subtype = E_VALUE)))) { + exception(1, _("Error: unable to compute the immediate value")); + } + } + break; + case OP_PLUS_UNARY: + case OP_MOINS_UNARY: + if (!e->child->e_subtype == E_VALUE) { + exception(1, _("Error: unable to compute the immediate value")); + } + e->avalue = (e->op == OP_MOINS_UNARY) ? -e->child->avalue : e->child->avalue; + free(e->child); + e->child = NULL; + e->e_type = e->e_subtype = E_VALUE; + break; + case OP_FUNC_CALL: + if (strcasecmp(e->symbol, "diff")) { + exception(1, _("Function unknow")); + } + break; + /* Jusqu'ici les évaluations étaient faciles. Nous allons attaquer la partie la plus ardue + de l'évaluation, celle de l'évaluation (disons plutôt de la simplification) des adresses */ + case OP_DECAL: + if ((e->child->e_subtype == E_LABEL) && (e->child->next->e_subtype == E_LABEL)) { + exception(1, _("Addresses addition not allowed")); + } + + if (e->child->e_subtype != E_LABEL) { + exception(1, _("You can only use the decal operator on labels")); + } + + if (e->child->next->e_subtype == E_OPERATION) { + if ((e->child->next->op != OP_MOINS) && (e->child->next->op != OP_PLUS)) { + exception(1, _("Address operation invalid")); + } + if ((e->child->next->op == OP_MOINS) && (e->child->next->child->next->e_subtype != E_VALUE)) { + exception(1, _("Address operation invalid")); + } + if (e->child->next->child->e_subtype == E_LABEL) { + exception(1, _("Addresses operations not allowed")); + } + if (e->child->next->child->e_subtype == e->child->next->child->next->e_subtype) { + exception(1, _("Expression too complex or invalid")); + } + } + break; + case OP_DIRECT: + /*******************************************************************\ + | Le code qui suit est sans doute immonde mais il est nécessaire... | + | Attention à la foret d'ifs, ça fait mal quand on s'y pert... | + | Le truc c'est que l'on va tenter d'éliminer l'expression avec une | + | batterie de tests pour vérifier si elle est correcte ou pas. | + | Nous la modifierons au fur et a mesure de sorte à lui donner une | + | forme canonique afin de pouvoir la traiter correctement plus tard | + \*******************************************************************/ + if (e->child->e_subtype == E_OPERATION) { + if (!((e->child->op == OP_PLUS) || (e->child->op == OP_MOINS))) { + exception(1, _("Address operation invalid")); + } + if ((e->child->child->e_subtype == E_LABEL) + && (e->child->child->next->e_subtype == E_LABEL)) { + exception(1, _("Addresses operations not allowed")); + } + if (e->child->child->next->e_subtype == E_LABEL) { + if (e->child->op == OP_MOINS) { + exception(1, _("Address type not supported")); + } + /* Sous la forme [A + LABEL], on inverse... */ + t = e->child->child; + e->child->child = t->next; + t->next->prev = NULL; + t->next->next = t; + t->prev = t->next; + t->next = NULL; + } + if (e->child->child->e_subtype == E_LABEL) { + if ((e->child->op != OP_PLUS) + && (e->child->child->next->e_subtype != E_VALUE)) { + exception(1, _("Address type not supported")); + } + } else { + if ((e->child->child->e_subtype == E_OPERATION) + && ((e->child->child->op == OP_PLUS) + || (e->child->child->op == OP_MOINS))) { + /* On est sous la forme [(A +- B) +- C], on inverse... */ + + /***********************************************\ + | | + | L'arbre des expressions est sous la forme: | + | | + | Direct | + | | | + | Operation1 | + | / \ | + |Operation2 C | + | / \ | + | A B | + | | + | et l'on veut: | + | | + | Direct | + | | | + | Operation2 | + | / \ | + | A Operation1 | + | / \ | + | B C | + | | + \***********************************************/ + + t = e->child->child->child->next; /* t pointe sur B */ + + e->child->child->child->next = e->child; /* Op1 devient fils droit de Op2 */ + e->child->father = e->child->child; + e->child->prev = e->child->child->child; + + e->child = e->child->child; /* Fils de Direct devient Op2 */ + e->child->father = e; + + e->child->child->next->child = t; /* B devient fils gauche de Op1 */ + t->next = e->child->next; + t->next->prev = t; + t->father = t->next->father; + t->prev = NULL; + + } + if ((t = e->child->child->next)->e_subtype == E_OPERATION) { + /* On est sous la forme [A +- (B +- C)], on vérifie l'intégrité de la sous opération. + Cela ne peut pas être [A - (B +- C)] car il faut que (B +- C) soit une valeur + immediate et donc aurait été calculé avant. */ + if (e->child->op == OP_MOINS) { + exception(1, _("Address type not supported")); + } + switch (e->child->child->e_subtype) { + /* quoique similiares, les trois cas suivant nécessitent trois traitements + différents */ + case E_LABEL: + /* On a donc [LABEL + (B +- C)], on va vérifier si C n'est pas une PATTERN, + et si c'est le cas, il ne faut pas que ce soit - C. Sinon nous ne devons + pas avoir de labels pour B ou C */ + + if ((e->child->child->next->child->next->e_subtype == E_PATTERN) && + (e->child->child->next->op == OP_MOINS)) { + exception(1, _("Address type not supported")); + } + + if (e->child->child->next->child->e_subtype == E_LABEL) { + exception(1, _("Address addition not supported")); + } + + /* Si B et C sont du même type, on jette l'éponge... */ + + if (e->child->child->next->child->e_subtype == + e->child->child->next->child->next->e_subtype) { + exception(1, _("Expression too complex or invalid")); + } + + /* Ok, si notre expression a réussi à franchir toutes ses étapes, c'est qu'elle + est correcte.... Enfin j'espère :) Je vais modifier l'expression de sorte a ce + qu'elle ait la forme [LABEL + (VALEUR +- PATTERN)] */ + + if ((t = e->child->child->next->child)->e_subtype == E_PATTERN) { + t->prev = t->next; + t->next = NULL; + t->prev->next = t; + t->prev->prev = NULL; + t->father->child = t->prev; + if (t->father->op == OP_MOINS) { + t->father->op = OP_PLUS; + t->prev->avalue = -t->prev->avalue; + } + } + break; + case E_PATTERN: + /* On a donc [PATTERN + (B +- C)], on va vérifier si C n'est pas un LABEL, + et si c'est le cas, il ne faut pas que ce soit - C. Sinon nous ne devons + pas avoir de patterns pour B ou C. */ + + if ((e->child->child->next->child->next->e_subtype == E_LABEL) && + (e->child->child->next->op == OP_MOINS)) { + exception(1, _("Address type not supported")); + } + + if (e->child->child->next->child->e_subtype == E_PATTERN) { + exception(1, _("Expression invalid")); + } + + /* Si B et C sont du même type, on jette l'éponge... */ + + if (e->child->child->next->child->e_subtype == + e->child->child->next->child->next->e_subtype) { + exception(1, _("Expression too complex or invalid")); + } + + /* Ok, si notre expression a réussi à franchir toutes ses étapes, c'est qu'elle + est correcte.... Enfin j'espère :) Je vais modifier l'expression de sorte a ce + qu'elle ait la forme [LABEL + (VALEUR +- PATTERN)] */ + + /* Pas mal de boulot ici... */ + if ((t = e->child->child->next->child)->e_subtype == E_LABEL) { + /* Nous avons [PATTERN + (LABEL +- VALEUR)], on inverse LABEL et VALEUR */ + t->prev = t->next; + t->next = NULL; + t->prev->next = t; + t->prev->prev = NULL; + t->father->child = t->prev; + if (t->father->op == OP_MOINS) { + t->father->op = OP_PLUS; + t->prev->avalue = -t->prev->avalue; + } + } + + /* Nous avons [PATTERN + (VALEUR + LABEL)] */ + + /* On bouge le LABEL */ + t = e->child->child->next->child->next; + t->father = e->child; + t->prev = NULL; + t->next = e->child->child->next; + + /* On bouge le PATTERN */ + t = e->child->child; + t->father = t->next; + t->prev = t->next->child; + t->next = NULL; + + /* On rétablit l'arbre correct */ + e->child->child = t->prev->next; + e->child->child->next->prev = e->child->child; + t->prev->next = t; + break; + case E_VALUE: + /* On a donc [VALUE + (B +- C)], si B ou C sont des valeurs, on intervient. */ + + if (e->child->child->next->child->e_subtype == E_VALUE) { + if (e->child->child->next->op == OP_MOINS) { + exception(1, _("Expression invalid")); + } + e->child->child->avalue += e->child->child->next->child->avalue; + t = e->child->child->next; + e->child->child->next = t->child->next; + free_expr(t); + /* Magie, on a attérit sur le cas [VALUE + qquechose] ... + On va pas s'embeter, on va réévaluer la chose :) */ + evaluate(e); + return; + } else if (e->child->child->next->child->next->e_subtype == E_VALUE) { + /* Quasiment la même chose qu'au dessus... */ + if (e->child->child->next->op == OP_MOINS) { + e->child->child->avalue -= + e->child->child->next->child->avalue; + } else { + e->child->child->avalue += + e->child->child->next->child->avalue; + } + t = e->child->child->next; + e->child->child->next = t->child; + free_expr(t); + evaluate(e); + return; + } else { + /* Si B et C sont du même type, on jette l'éponge... */ + + if (e->child->child->next->child->e_subtype == + e->child->child->next->child->next->e_subtype) { + exception(1, _("Expression too complex or invalid")); + } + + /* Ok, si notre expression a réussi à franchir toutes ses étapes, c'est qu'elle + est correcte.... Enfin j'espère :) Je vais modifier l'expression de sorte a ce + qu'elle ait la forme [LABEL + (VALEUR +- PATTERN)] */ + + /* Pas mal de boulot ici... */ + if ((t = e->child->child->next->child)->e_subtype == E_PATTERN) { + /* Nous avons [VALEUR + (PATTERN + LABEL)], on inverse LABEL et PATTERN */ + t->prev = t->next; + t->next = NULL; + t->prev->next = t; + t->prev->prev = NULL; + t->father->child = t->prev; + if (t->father->op == OP_MOINS) { + t->father->op = OP_PLUS; + t->prev->avalue = -t->prev->avalue; + } + } + + /* Nous avons [VALEUR + (LABEL + PATTERN)] */ + + /* On bouge le LABEL */ + t = e->child->child->next->child; + t->father = e->child; + t->prev = NULL; + u = t->next; + t->next = e->child->child->next; + + /* On bouge la VALEUR */ + t = e->child->child; + t->father = t->next; + t->next = u; + t->prev = NULL; + + /* On rétablit l'arbre correct */ + e->child->child = u->prev; + e->child->child->next->prev = e->child->child; + e->child->child->next->child = t; + u->prev = t; + } + default: + /* Bon si l'on est ici, c'est pas bon signe non plus... */ + exception(1, _("Expression too complex")); + break; + } + } else { + /* Le pire, c'est que je vois même pas comment on peut atterir ici... + J'ai beau me creuser les méninges, je vois pas :) + On va donc dire que c'est invalide */ + exception(1, _("Expression too complex")); + } + } + /* Bon si on arrive ici sain et sauf, c'est que l'expression est sous la forme + canonique: [LABEL + A] avec A quelque chose de valide. On va donc transformer + l'expression en LABEL[A] */ + + t = e->child; + e->child = t->child; + e->child->father = e; + e->child->next->father = e; + if (t->op == OP_MOINS) { + /* On est sous la forme [LABEL - IMM], on met LABEL[-A] */ + e->child->next->avalue = -e->child->next->avalue; + } + free(t); + e->op = OP_DECAL; + + } /* if operation */ + break; + } + +} + +void act_pile(int o) +{ + expression_t *e, *e1, *e2; + int i, nbargs; + + e = Emalloc(sizeof(expression_t)); + e->op = o; + e->avalue = 0; + e->symbol = NULL; + e->e_type = E_OPERATION; + e->e_subtype = E_OPERATION; + e->next = e->prev = e->father = e->child = NULL; + switch (o) { + case OP_NEST: + exception(1, _("Something wrong, nested operator called...")); + break; + case OP_PLUS: + case OP_MOINS: + case OP_MUL: + case OP_DIV: + case OP_DECAL: + e2 = e_current; + e1 = e_current->prev; + if (e_current->prev->prev) { + e_current->prev->prev->next = NULL; + } else { + e_current = NULL; + } + e1->prev = NULL; + e->child = e1; + e1->father = e2->father = e; + break; + case OP_PLUS_UNARY: + case OP_MOINS_UNARY: + case OP_DIRECT: + e1 = e_current; + if (e1->prev) { + e_current->prev->next = NULL; + e_current = e1->prev; + } else { + e_current = NULL; + } + + e1->prev = NULL; + e->child = e1; + e1->father = e; + break; + case OP_FUNC_CALL: + e1 = e_current; + e_current->prev->next = NULL; + e_current = e1->prev; + nbargs = e1->avalue; + free(e1); + e1 = e2 = NULL; + for (i = 0; i < nbargs; i++) { + e1 = e_current; + e_current->prev->next = NULL; + e_current = e1->prev; + if (e2) { + e2->next = e1; + e2->prev = NULL; + e1->prev = e2; + } else { + e1->prev = NULL; + } + e2 = e1; + } + + e2 = e_current; + if (e2->prev) { + e_current->prev->next = NULL; + e_current = e1->prev; + } + e->symbol = e2->symbol; + free(e2); + e->avalue = nbargs; + for (e2 = e1; e2; e2 = e2->next) { + e2->father = e; + } + e->child = e1; + break; + case OP_LPAREN: + exception(1, _("Something wrong, lparenthesis operator called...")); + break; + default: + exception(1, _("Something wrong, should never got here...")); + break; + } + + if (e_current) { + e_current->next = e; + e->prev = e_current; + } + + e_current = e; + evaluate(e_current); } -int assembler_init(void) { +int assembler_init(void) +{ + Initialise(&defines); + if (!defines) + return 1; + Initialise(&labels); + if (!defines) + return 1; + if (!(p_text = text = (bytestream_t *) malloc(sizeof(bytestream_t)))) return 1; + if (!(p_data = data = (bytestream_t *) malloc(sizeof(bytestream_t)))) return 1; + if (!(p_bss = bss = (bytestream_t *) malloc(sizeof(bytestream_t)))) return 1; + + text->next = data->next = bss->next = NULL; + text->size = data->size = bss->size = 0; + return 0; } -void asm_eol(void) { - fprintf(stderr, "End of line\n"); +void asm_eol(void) +{ + /* Gros morceau encore ici... */ + wc = 0; + special = 0; } -void assembler_flush(void) { +void asm_eof(void) +{ +} + +static void delete_bytestream(bytestream_t * s) { + if (s->next) delete_bytestream(s->next); + free(s); +} + +void assembler_flush(void) +{ + DetruitTab(&defines); + DetruitTab(&labels); + delete_bytestream(text); + delete_bytestream(data); + delete_bytestream(bss); +} + +int process_file(char *name) +{ + /* Petite chose à faire ici et cela sera bon */ + return 0; } |