summaryrefslogtreecommitdiff
path: root/lib/assembler.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/assembler.c')
-rw-r--r--lib/assembler.c1015
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;
}