summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPixel <>2001-04-13 12:03:09 +0000
committerPixel <>2001-04-13 12:03:09 +0000
commita984cf3f28d3a5935c84f96f6da3bc7bd39a9ff1 (patch)
treecf0157e6e7f9df0f6025b1191d5f6be17b9b057d /lib
parent905814760584d843409763d9f3c24b73b0780444 (diff)
Assembleur.
Diffstat (limited to 'lib')
-rw-r--r--lib/assembler.c1015
-rw-r--r--lib/exceptions.c61
-rw-r--r--lib/hash.c8
-rw-r--r--lib/instructions.txt2
-rw-r--r--lib/meta.c179
-rw-r--r--lib/numbers.c12
-rw-r--r--lib/parser.c151
7 files changed, 1256 insertions, 172 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;
}
diff --git a/lib/exceptions.c b/lib/exceptions.c
index 231ca63..0bacb32 100644
--- a/lib/exceptions.c
+++ b/lib/exceptions.c
@@ -4,42 +4,61 @@
#include "config.h"
#include "exceptions.h"
-char * contexts[128];
+char *contexts[128];
int clevel = 0;
-char * Estrdup(char * o) {
- char * r;
-
- if (!(r = strdup(o))) {
- exception(1, _("Out of memory."));
- }
- return r;
+/********************************\
+* *
+* Gestionnaire d'exceptions *
+* *
+\********************************/
+
+char *Estrdup(char *o)
+{
+ char *r;
+
+ if (o) {
+ if (!(r = strdup(o))) {
+ exception(1, _("Out of memory."));
+ }
+ } else {
+ return NULL;
+ }
+ return r;
}
-void * Emalloc(size_t s) {
- void * r;
-
- if (!(r = malloc(s))) {
- exception(1, _("Out of memory."));
- }
- return r;
+void *Emalloc(size_t s)
+{
+ void *r;
+
+ if (s) {
+ if (!(r = malloc(s))) {
+ exception(1, _("Out of memory."));
+ }
+ } else {
+ return NULL;
+ }
+ return r;
}
-void pushcontext(char * c) {
+void pushcontext(char *c)
+{
if (clevel == 128) {
exception(1, _("Too much error contexts during pushcontext()."));
}
contexts[clevel++] = Estrdup(c);
}
-void popcontext(void) {
+void popcontext(void)
+{
if (clevel == 0) {
exception(1, _("Error context empty, but popcontext() called."));
}
free(contexts[--clevel]);
}
-void flushcontext(void) {
+void flushcontext(void)
+{
while (clevel) {
popcontext();
}
@@ -48,11 +67,11 @@ void flushcontext(void) {
void exception(int level, char *msg)
{
int i;
-
+
fprintf(stderr, "Error detected. Showing context.\n");
for (i = 0; i < clevel; i++) {
fprintf(stderr, " (%i) - %s\n", i, contexts[i]);
}
- fprintf(stderr, " Error description: %s\n", msg);
- exit(level);
+ fprintf(stderr, " Error description: %s\n", msg);
+ exit(level);
}
diff --git a/lib/hash.c b/lib/hash.c
index 3736b80..58b6f9f 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -95,7 +95,8 @@ static void Supprimer(_ListeChaine * l, char *Nom)
}
}
-static void Detruit(_ListeChaine * l) {
+static void Detruit(_ListeChaine * l)
+{
_ListeChaine l_aux = NULL;
while (*l) {
@@ -180,13 +181,14 @@ int Initialise(_TableauVariable * t)
return (i);
}
-void DetruitTab(_TableauVariable * t){
+void DetruitTab(_TableauVariable * t)
+{
int i;
for (i = 0; i < strlen(CHAINEHACHAGE); i++) {
Detruit(&((*t)[i]));
}
-
+
free(*t);
*t = NULL;
}
diff --git a/lib/instructions.txt b/lib/instructions.txt
index ab8e387..6522ffe 100644
--- a/lib/instructions.txt
+++ b/lib/instructions.txt
@@ -1,5 +1,5 @@
FI:c3,6;c2,6;c1,6;e,6;op,8
-Fa:reserved,4;rm,2
+Fa:reserved,4;rm,
Pr:R0;R1;R2;R3;R4;R5;R6;R7;R8;R9;R10;R11;R12;R13;R14;R15;R16;R17;R18;R19;R20;R21;R22;R23;R24;R25;R26;R27;R28;R29;R30;R31;Rg;Rd;IP;Fl
Pm:regop=.Pr;.I=.O;[regop=.Pr;.I=.O[regop=.Pr
diff --git a/lib/meta.c b/lib/meta.c
index 275d60b..52e29ff 100644
--- a/lib/meta.c
+++ b/lib/meta.c
@@ -7,14 +7,17 @@
#include "config.h"
#else
#define _(x) x
-void exception(int, char *);
-char * Estrdup(char *);
-void * Emalloc(size_t);
#endif
#include "exceptions.h"
#include "numbers.h"
#include "meta.h"
+/*************************\
+* *
+* Meta Parser *
+* *
+\*************************/
+
static char meta_ops[] = ":.;(){}[=, ";
static char meta_firsts[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
static char meta_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789";
@@ -24,6 +27,8 @@ field_t *fields = NULL;
pattern_t *patterns = NULL;
instruct_t *instructs = NULL;
+/* Fonction interne pour déterminer si une chaîne forme un identifier correct. */
+
static int isident(char *word)
{
if (!strchr(meta_firsts, *word)) {
@@ -37,6 +42,8 @@ static int isident(char *word)
return 1;
}
+/* La fonction getword pour le meta parser. Beaucoup plus simple que le parser normal. */
+
static char *getword(char *line, char *p)
{
char o;
@@ -50,17 +57,21 @@ static char *getword(char *line, char *p)
return line;
}
+/* La terrible fonction meta_parse_line. Elle lit une chaîne correspondant à une ligne du fichier texte d'entrée.
+Le problème réside surtout dans le fait qu'il y a des variables globales et des effets de bords, ce qui empèche le
+découpage en sous routines. */
+
void meta_parse_line(char *line)
{
char buffer[BUFSIZ], *first = NULL, m = 0, *p1 = NULL, *p2 = NULL, *Fnames[MAXF], *Fimplicits[MAXF],
- *Snames[MAXF], *Sinames[MAXF], gotname = 0, goteoi = 0, errbuff[BUFSIZ];
+ *Snames[MAXF], *Sinames[MAXF], gotname = 0, goteoi = 0, errbuff[BUFSIZ];
phon_t *phon = NULL;
field_t *field = NULL;
pattern_t *pattern = NULL;
instruct_t *instruct = NULL;
metaexpr_t *metaexpr = NULL, *tmetaexpr, *tabmetaexpr[MAXM];
int Fsizes[MAXF], Fvalues[MAXF], Itypes[MAXF], Etypes[MAXF], nbfields = 0, valid, i, nbimplicit = 0;
-
+
if (*line == '#') {
return;
}
@@ -73,6 +84,7 @@ void meta_parse_line(char *line)
sprintf(errbuff, _("Analysing word '%s'"), buffer);
pushcontext(errbuff);
if (!m) {
+ /* Premier mot lut de la chaîne */
if (*line != ':') {
exception(1, _("Missing operator ':'"));
}
@@ -97,6 +109,7 @@ void meta_parse_line(char *line)
break;
}
} else {
+ /* Nous avons lut le premier mot, nous savons ce qu'il faut faire. */
switch (m) {
case 1: /* Champ */
if (gotname) {
@@ -117,6 +130,7 @@ void meta_parse_line(char *line)
field->name = first;
field->names = (char **) Emalloc(nbfields * sizeof(char *));
field->sizes = (int *) Emalloc(nbfields * sizeof(int));
+
for (i = 0; i < nbfields; i++) {
field->names[i] = Fnames[i];
field->sizes[i] = Fsizes[i];
@@ -169,7 +183,7 @@ void meta_parse_line(char *line)
} else {
tmetaexpr->string = NULL;
}
-
+
if (metaexpr) {
metaexpr->right = tmetaexpr;
} else {
@@ -177,7 +191,8 @@ void meta_parse_line(char *line)
}
if (*line == ';' || !*line) {
tabmetaexpr[nbfields++] = metaexpr;
- if (*line) line++;
+ if (*line)
+ line++;
metaexpr = NULL;
}
if (!*line) {
@@ -185,7 +200,8 @@ void meta_parse_line(char *line)
pattern->next = patterns->next;
patterns->next = pattern;
pattern->name = first;
- pattern->expr = (metaexpr_t **) Emalloc(nbfields * sizeof(metaexpr_t *));
+ pattern->expr =
+ (metaexpr_t **) Emalloc(nbfields * sizeof(metaexpr_t *));
for (i = 0; i < nbfields; i++) {
pattern->expr[i] = tabmetaexpr[i];
}
@@ -311,6 +327,7 @@ void meta_parse_line(char *line)
instruct->ivalues = (int *) Emalloc(nbimplicit * sizeof(int));
instruct->istrings = (char **) Emalloc(nbimplicit * sizeof(char *));
instruct->itypes = (int *) Emalloc(nbimplicit * sizeof(int));
+
for (i = 0; i < nbfields; i++) {
instruct->names[i] = Fnames[i];
instruct->strings[i] = Snames[i];
@@ -332,10 +349,12 @@ void meta_parse_line(char *line)
}
popcontext();
}
-
+
popcontext();
}
+/* Initialiseur et destructeur du meta parser */
+
int meta_init(void)
{
if (!(phons = (phon_t *) malloc(sizeof(phon_t)))) {
@@ -351,14 +370,14 @@ int meta_init(void)
fields->names = NULL;
fields->sizes = NULL;
fields->next = NULL;
-
+
if (!(patterns = (pattern_t *) malloc(sizeof(pattern_t)))) {
return -1;
}
patterns->name = NULL;
patterns->expr = NULL;
patterns->next = NULL;
-
+
if (!(instructs = (instruct_t *) malloc(sizeof(instruct_t)))) {
return -1;
}
@@ -373,23 +392,25 @@ int meta_init(void)
return 0;
}
-static void recurs_free_phon(phon_t * phon) {
+static void recurs_free_phon(phon_t * phon)
+{
if (phon->next) {
recurs_free_phon(phon->next);
}
-
+
free(phon->p1);
free(phon->p2);
free(phon);
}
-static void recurs_free_field(field_t * field) {
+static void recurs_free_field(field_t * field)
+{
int i;
-
+
if (field->next) {
recurs_free_field(field->next);
}
-
+
free(field->name);
for (i = 0; i < field->nbr; i++) {
free(field->names[i]);
@@ -399,11 +420,12 @@ static void recurs_free_field(field_t * field) {
free(field);
}
-static void recurs_free_metaexpr(metaexpr_t * metaexpr) {
+static void recurs_free_metaexpr(metaexpr_t * metaexpr)
+{
if (metaexpr->left) {
recurs_free_metaexpr(metaexpr->left);
}
-
+
if (metaexpr->right) {
recurs_free_metaexpr(metaexpr->right);
}
@@ -411,21 +433,22 @@ static void recurs_free_metaexpr(metaexpr_t * metaexpr) {
if (metaexpr->name) {
free(metaexpr->name);
}
-
+
if (metaexpr->string) {
free(metaexpr->string);
}
-
+
free(metaexpr);
}
-static void recurs_free_pattern(pattern_t * pattern) {
+static void recurs_free_pattern(pattern_t * pattern)
+{
int i;
if (pattern->next) {
recurs_free_pattern(pattern->next);
}
-
+
free(pattern->name);
for (i = 0; i < pattern->nbr; i++) {
recurs_free_metaexpr(pattern->expr[i]);
@@ -434,20 +457,21 @@ static void recurs_free_pattern(pattern_t * pattern) {
free(pattern);
}
-static void recurs_free_instruct(instruct_t * instruct) {
+static void recurs_free_instruct(instruct_t * instruct)
+{
int i;
-
+
if (instruct->next) {
recurs_free_instruct(instruct->next);
}
-
+
for (i = 0; i < instruct->nbexplicit; i++) {
free(instruct->names[i]);
if (instruct->strings[i]) {
free(instruct->strings[i]);
}
}
-
+
for (i = 0; i < instruct->nbimplicit; i++) {
free(instruct->implicits[i]);
free(instruct->istrings[i]);
@@ -462,11 +486,16 @@ static void recurs_free_instruct(instruct_t * instruct) {
free(instruct);
}
-void meta_flush(void) {
- if (phons->next) recurs_free_phon(phons->next);
- if (fields->next) recurs_free_field(fields->next);
- if (patterns->next) recurs_free_pattern(patterns->next);
- if (instructs->next) recurs_free_instruct(instructs->next);
+void meta_flush(void)
+{
+ if (phons->next)
+ recurs_free_phon(phons->next);
+ if (fields->next)
+ recurs_free_field(fields->next);
+ if (patterns->next)
+ recurs_free_pattern(patterns->next);
+ if (instructs->next)
+ recurs_free_instruct(instructs->next);
free(phons);
free(fields);
free(patterns);
@@ -477,14 +506,16 @@ void meta_flush(void) {
instructs = NULL;
}
-int meta_load(char * n) {
- FILE * f;
- char buf[BUFSIZ], *p;
-
+int meta_load(char *n)
+{
+ FILE *f;
+ char buf[BUFSIZ], errctx[BUFSIZ], *p;
+ int i = 0;
+
pushcontext("Loading meta file");
- sprintf(buf, "Opening file '%s'", n);
- pushcontext(buf);
-
+ sprintf(errctx, "Opening file '%s'", n);
+ pushcontext(errctx);
+
if (!(f = fopen(n, "r"))) {
pushcontext(strerror(errno));
return 1;
@@ -492,6 +523,8 @@ int meta_load(char * n) {
popcontext();
pushcontext("Reading file");
while (fgets(buf, BUFSIZ, f)) {
+ sprintf(errctx, "Reading line %i", ++i);
+ pushcontext(errctx);
if ((p = strchr(buf, '\r'))) {
*p = '\0';
}
@@ -499,39 +532,19 @@ int meta_load(char * n) {
*p = '\0';
}
meta_parse_line(buf);
+ popcontext();
}
popcontext();
popcontext();
-
-
+
+
fclose(f);
return 0;
}
#ifndef HAVE_CONFIG_H
-char * Estrdup(char * o) {
- char * r;
-
- if (!(r = strdup(o))) {
- exception(1, _("Out of memory."));
- }
- return r;
-}
-
-void * Emalloc(size_t s) {
- void * r;
-
- if (!(r = malloc(s))) {
- exception(1, _("Out of memory."));
- }
- return r;
-}
-void exception(int level, char *msg)
-{
- fprintf(stderr, "%s\n", msg);
- exit(level);
-}
+/* Programme de test si on compile le meta parser indépendament du reste du projet */
void main(void)
{
@@ -558,7 +571,7 @@ void main(void)
fprintf(stderr, " + %s (%i bits)\n", field->names[i], field->sizes[i]);
}
}
-
+
fprintf(stderr, "\nListe des patterns:\n");
for (pattern = patterns->next; pattern; pattern = pattern->next) {
fprintf(stderr, " o Pattern nommée %s, contenant %i metaexpressions:\n", pattern->name, pattern->nbr);
@@ -566,17 +579,20 @@ void main(void)
fprintf(stderr, " + %s (%s) type: %s\n",
pattern->expr[i]->name ? pattern->expr[i]->name : "Opérateur [",
pattern->expr[i]->string ? pattern->expr[i]->string : "Aucune chaîne associée",
- pattern->expr[i]->type ? "Constante prédéfinie" : pattern->expr[i]->left ? "Binaire" : pattern->expr[i]->right ? "Unaire" : "Feuille");
+ pattern->expr[i]->type ? "Constante prédéfinie" : pattern->expr[i]->
+ left ? "Binaire" : pattern->expr[i]->right ? "Unaire" : "Feuille");
if (pattern->expr[i]->left) {
fprintf(stderr, " - gauche: %s (%s) type: %s\n",
pattern->expr[i]->left->name ? pattern->expr[i]->left->name : "Opérateur [",
- pattern->expr[i]->left->string ? pattern->expr[i]->left->string : "Aucune chaîne associée",
+ pattern->expr[i]->left->string ? pattern->expr[i]->left->
+ string : "Aucune chaîne associée",
pattern->expr[i]->left->type ? "Constante prédéfinie" : "Feuille");
}
if (pattern->expr[i]->right) {
fprintf(stderr, " - droite: %s (%s) type: %s\n",
pattern->expr[i]->right->name ? pattern->expr[i]->right->name : "Opérateur [",
- pattern->expr[i]->right->string ? pattern->expr[i]->right->string : "Aucune chaîne associée",
+ pattern->expr[i]->right->string ? pattern->expr[i]->right->
+ string : "Aucune chaîne associée",
pattern->expr[i]->right->type ? "Constante prédéfinie" : "Feuille");
}
}
@@ -584,29 +600,32 @@ void main(void)
fprintf(stderr, "\nListe des instructions:\n");
for (instruct = instructs->next; instruct; instruct = instruct->next) {
- fprintf(stderr, " o Instruction contenant %i champs explicites et %i champs implicites.\n", instruct->nbexplicit, instruct->nbimplicit);
+ fprintf(stderr, " o Instruction contenant %i champs explicites et %i champs implicites.\n",
+ instruct->nbexplicit, instruct->nbimplicit);
fprintf(stderr, " => Champs explicites.\n");
for (i = 0; i < instruct->nbexplicit; i++) {
fprintf(stderr, " + %s <= %s (type %s)\n",
- instruct->names[i],
- instruct->strings[i] ? instruct->strings[i] : "Pas de chaîne associée",
- instruct->etypes[i] ? "prédéfinit" : "direct");
+ instruct->names[i],
+ instruct->strings[i] ? instruct->strings[i] : "Pas de chaîne associée",
+ instruct->etypes[i] ? "prédéfinit" : "direct");
}
fprintf(stderr, " => Champs implicites.\n");
for (i = 0; i < instruct->nbimplicit; i++) {
switch (instruct->itypes[i]) {
- case 0:
- fprintf(stderr, " + %s <= %s (type direct)\n", instruct->implicits[i], instruct->istrings[i]);
- break;
- case 1:
- fprintf(stderr, " + %s <= %i (type prédéfinit)\n", instruct->implicits[i], instruct->istrings[i]);
- break;
- case 2:
- fprintf(stderr, " + %s <= %i (type valeur)\n", instruct->implicits[i], instruct->ivalues[i]);
- break;
+ case 0:
+ fprintf(stderr, " + %s <= %s (type direct)\n", instruct->implicits[i],
+ instruct->istrings[i]);
+ break;
+ case 1:
+ fprintf(stderr, " + %s <= %i (type prédéfinit)\n", instruct->implicits[i],
+ instruct->istrings[i]);
+ break;
+ case 2:
+ fprintf(stderr, " + %s <= %i (type valeur)\n", instruct->implicits[i],
+ instruct->ivalues[i]);
+ break;
}
}
}
}
-
#endif
diff --git a/lib/numbers.c b/lib/numbers.c
index 8334dd4..9f032b5 100644
--- a/lib/numbers.c
+++ b/lib/numbers.c
@@ -1,11 +1,15 @@
#include "numbers.h"
+/* Cette fonction lit un nombre. Elle va chercher absolument à traduire la chaîne passée en argument en un nombre. Si
+ce nombre n'est pas valide, alors l'int valid est mis à faux. Cette fonction reconnais les nombres en décimaux, les nombres
+en octal préfixés avec 0 et les nombres en hexadécimal préfixés avec 0x. */
+
int char_to_number(char *st, int *valid)
{
int whattype = 0, result = 0;
-
+
*valid = 0;
-
+
if (*st == '0') {
st++;
if (*st == 'x') {
@@ -18,7 +22,7 @@ int char_to_number(char *st, int *valid)
return 0;
}
}
-
+
while (*st) {
switch (whattype) {
case 0:
@@ -52,7 +56,7 @@ int char_to_number(char *st, int *valid)
}
st++;
}
-
+
*valid = 1;
return result;
}
diff --git a/lib/parser.c b/lib/parser.c
index ee3e64c..2a9edd1 100644
--- a/lib/parser.c
+++ b/lib/parser.c
@@ -4,11 +4,16 @@
#include "config.h"
#else
#define _(x) x
-void exception(int, char *);
#endif
#include "exceptions.h"
#include "parser.h"
+#include "assembler.h"
+/*******************************\
+* *
+* Parser *
+* *
+\*******************************/
typedef unsigned char op_t;
@@ -22,8 +27,10 @@ static int pile_nestedcall[PILECALL_MAX];
static int pileop_pos = 0, pilecall_pos = 0;
+/* La liste des opérateurs reconnus par le parser */
+
static operator_t operators[] = {
- {',', 0, OP_NEST},
+ {',', 0, OP_NEST},
{'+', 2, OP_PLUS},
{'-', 2, OP_MOINS},
{'*', 3, OP_MUL},
@@ -37,6 +44,8 @@ static operator_t operators[] = {
{255, -1, -1}
};
+/* Fonction interne: convertit un operateur en sa structure */
+
static operator_t get_op(op_t op)
{
int i;
@@ -49,6 +58,8 @@ static operator_t get_op(op_t op)
return operators[i];
}
+/* Fonctions internes de lectures sur la structure */
+
static int get_pri(op_t op)
{
return get_op(op).pri;
@@ -59,6 +70,8 @@ static int get_func(op_t op)
return get_op(op).func;
}
+/* Focntions internes d'empilement / dépilement */
+
static op_t get_last_op(void)
{
if (pileop_pos)
@@ -87,20 +100,22 @@ static int pop_call(void)
{
if (pilecall_pos)
return pile_nestedcall[--pilecall_pos];
- return -1;
+ return -1;
}
-static void increment_call(void) {
- if (pilecall_pos) {
- if (pile_nestedcall[pilecall_pos - 1] != -1)
- pile_nestedcall[pilecall_pos - 1]++;
- }
-}
-
-static int get_last_call(void) {
- if (pilecall_pos)
- return pile_nestedcall[pilecall_pos - 1];
- return -1;
+static void increment_call(void)
+{
+ if (pilecall_pos) {
+ if (pile_nestedcall[pilecall_pos - 1] != -1)
+ pile_nestedcall[pilecall_pos - 1]++;
+ }
+}
+
+static int get_last_call(void)
+{
+ if (pilecall_pos)
+ return pile_nestedcall[pilecall_pos - 1];
+ return -1;
}
static void push_call(int call)
@@ -111,6 +126,8 @@ static void push_call(int call)
exception(-1, _("Too many nested functions calls in expression.\n"));
}
+/* Cette fonction lit un "mot" sur la chaine line et renvoit le nouveau pointeur */
+
static char *getword(char *line, char *p)
{
char o = 0, *d = line, instring = 0, gotbslash = 0;
@@ -120,18 +137,19 @@ static char *getword(char *line, char *p)
o = *(p++) = *line;
if (!gotbslash) {
switch (instring) {
- case 1:
- if (*line == '\'') {
- instring = 0;
- }
- break;
- case 2:
- if (*line == '"') {
- instring = 0;
- }
- break;
+ case 1:
+ if (*line == '\'') {
+ instring = 0;
+ }
+ break;
+ case 2:
+ if (*line == '"') {
+ instring = 0;
+ }
+ break;
}
- if (*line == '\\') gotbslash = 1;
+ if (*line == '\\')
+ gotbslash = 1;
} else {
gotbslash = 0;
}
@@ -143,7 +161,7 @@ static char *getword(char *line, char *p)
o = *(p++) = *line;
instring = 2;
} else {
- if (*(line) != ' ') {
+ if (*(line) != ' ' && *(line) != '\t') {
o = *(p++) = *line;
} else if (d != line) {
*p = '\0';
@@ -153,20 +171,28 @@ static char *getword(char *line, char *p)
}
line++;
} while (((*line) && (*line != ')') && (*line != ']') && (*line != ';') && (get_func(*line) == -1)
- && (get_func(o) == -1)) || (instring));
+ && (get_func(o) == -1)) || (instring));
*p = '\0';
return line;
}
+/* Cette fonction va parcourire une chaine afin d'appeler les fonction push_pule() et act_pile() */
+
void parse_line(char *line)
{
- char buffer[BUFSIZ], imm[BUFSIZ];
+ char buffer[BUFSIZ], imm[BUFSIZ], *d = line;
op_t op;
int got_unary = 128, nbrargs;
+ sprintf(buffer, "Read line '%s'", line);
+ pushcontext(buffer);
+
while (*line) {
line = getword(line, buffer);
+ sprintf(imm, "Analysing word '%s' at position %i", buffer, line - d);
+ pushcontext(imm);
if (get_func(buffer[0]) != -1) {
+ /* Le mot lut est un operateur, on agit sur la pile */
buffer[0] += got_unary;
if (got_unary) {
}
@@ -177,28 +203,35 @@ void parse_line(char *line)
exception(-1, _("Invalid binary operator"));
}
}
- while (get_pri(get_last_op()) >= get_pri(buffer[0]) && (((get_last_op() & 127) != '(') && ((get_last_op() & 127) != '['))) {
+ while (get_pri(get_last_op()) >= get_pri(buffer[0])
+ && (((get_last_op() & 127) != '(') && ((get_last_op() & 127) != '['))) {
act_pile(get_func(pop_op()));
got_unary = 0;
}
if (buffer[0] == '(') {
push_call(0);
- }
+ }
if (buffer[0] == ',') {
- increment_call();
- } else push_op(buffer[0]);
+ increment_call();
+ } else
+ push_op(buffer[0]);
got_unary = 128;
} else if ((buffer[0] == ';') || (buffer[0] == ')') || (buffer[0] == ']')) {
+ /* Le mot lut est un opérateur spécial, on vide la pile */
switch (buffer[0]) {
case ';':
+ /* Equivalent a fin de ligne */
while (pileop_pos) {
op = pop_op();
if (op == '(')
exception(-1, _("Parse error: too much left parenthesis"));
act_pile(get_func(op));
}
- break;
+ popcontext();
+ popcontext();
+ return;
case ')':
+ /* Fin de parenthese (Appel de fonction ou expression mathématique) */
while (1) {
if (!pileop_pos)
exception(-1, _("Parse error: too much right parenthesis"));
@@ -209,15 +242,16 @@ void parse_line(char *line)
exception(-1, _("Parse error: enclosure mismatch"));
act_pile(get_func(op));
}
- if (op == '(') {
- nbrargs = pop_call();
- sprintf(imm, "%i", nbrargs);
- push_pile(imm);
- act_pile(get_func(op));
- }
+ if (op == '(') {
+ nbrargs = pop_call();
+ sprintf(imm, "%i", nbrargs);
+ push_pile(imm);
+ act_pile(get_func(op));
+ }
got_unary = 0;
break;
case ']':
+ /* Fin d'opérateur de décalage */
while (1) {
if (!pileop_pos)
exception(-1, _("Parse error: too much right parenthesis"));
@@ -228,28 +262,30 @@ void parse_line(char *line)
exception(-1, _("Parse error: enclosure mismatch"));
act_pile(get_func(op));
}
- act_pile(get_func(op));
+ act_pile(get_func(op));
got_unary = 0;
break;
}
} else if (((buffer[0] >= 'A') && (buffer[0] <= 'Z')) || ((buffer[0] >= 'a') && (buffer[0] <= 'z'))
- || ((buffer[0] >= '0') && (buffer[0] <= '9')) || (buffer[0] == '_') || (buffer[0] == '"') || (buffer[0] == '\'')) {
+ || ((buffer[0] >= '0') && (buffer[0] <= '9')) || (buffer[0] == '_') || (buffer[0] == '"')
+ || (buffer[0] == '\'')) {
+ /* Dans tous les autres cas, on a reçu un symbole, on le pose sur la pile */
push_pile(buffer);
got_unary = 0;
- if (!get_last_call()) increment_call();
+ if (!get_last_call())
+ increment_call();
} else if (buffer[0]) {
exception(-1, _("Invalid character"));
}
+ popcontext();
}
+
+ popcontext();
}
#ifndef HAVE_CONFIG_H
-void exception(int level, char *msg)
-{
- fprintf(stderr, "%s\n", msg);
- exit(level);
-}
+/* Les quelques fonctions de test, lorsque le parser est compilé en dehors du projet. */
void push_pile(char *word)
{
@@ -279,9 +315,9 @@ void act_pile(int func)
case OP_MOINS_UNARY:
op = '|';
break;
- case OP_FUNC_CALL:
- op = '@';
- break;
+ case OP_FUNC_CALL:
+ op = '@';
+ break;
case OP_DECAL:
op = '[';
break;
@@ -295,15 +331,20 @@ void act_pile(int func)
void main(void)
{
parse_line("ADD R18, R20, 39;");
- printf("\n\n"); fflush(stdout);
+ printf("\n\n");
+ fflush(stdout);
parse_line("MOV R31, Bidule[48 + R12];");
- printf("\n\n"); fflush(stdout);
+ printf("\n\n");
+ fflush(stdout);
parse_line("MOV R12, [R3];");
- printf("\n\n"); fflush(stdout);
+ printf("\n\n");
+ fflush(stdout);
parse_line("MOV R22, Truc[(3+2)*8];");
- printf("\n\n"); fflush(stdout);
+ printf("\n\n");
+ fflush(stdout);
parse_line("Trucmuche DB \"Test de chaîne complète avec des opérateurs comme le + et le - ...\"");
- printf("\n\n"); fflush(stdout);
+ printf("\n\n");
+ fflush(stdout);
}
#endif