summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <>2001-04-15 01:15:02 +0000
committerPixel <>2001-04-15 01:15:02 +0000
commit1d2c4bd4e380395c68151d40239d1539d39fdd91 (patch)
tree5d257d14007c3a67ac716c01c8334878483c3697
parenta984cf3f28d3a5935c84f96f6da3bc7bd39a9ff1 (diff)
Assembleur
-rw-r--r--lib/assembler.c705
-rw-r--r--lib/hash.c36
-rw-r--r--lib/instructions.txt16
-rw-r--r--lib/meta.c8
-rw-r--r--lib/parser.c3
5 files changed, 684 insertions, 84 deletions
diff --git a/lib/assembler.c b/lib/assembler.c
index 2a3bb86..60fe86f 100644
--- a/lib/assembler.c
+++ b/lib/assembler.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include "config.h"
#include "meta.h"
@@ -30,13 +31,13 @@ typedef struct expression_t {
typedef struct bytestream_t {
unsigned long int Encoded;
int offset, segment, size;
- char * Label;
- expression_t * Expr;
+ char *Label;
+ expression_t *Expr;
- struct bytestream_t * next;
+ struct bytestream_t *next;
int line;
- char * filename;
+ char *filename;
} bytestream_t;
enum {
@@ -61,26 +62,75 @@ int segment = -1;
int special = 0;
_TableauVariable defines, labels;
int line = -1;
-char * filename = NULL, * filenames[32];
+char *filename = NULL, *filenames[32], *defined;
int nestedinc = 0;
-bytestream_t * text, * data, * bss, * p_text, * p_data, * p_bss;
+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 void debug_print_expression(expression_t * e)
+{
+ switch (e->e_subtype) {
+ case E_OPERATION:
+ switch (e->op) {
+ case OP_PLUS:
+ fprintf(stderr, "Operation plus\n");
+ break;
+ case OP_MOINS:
+ fprintf(stderr, "Operation moins\n");
+ break;
+ case OP_DECAL:
+ fprintf(stderr, "Operation decal\n");
+ break;
+ case OP_DIRECT:
+ fprintf(stderr, "Operation direct\n");
+ break;
+ default:
+ fprintf(stderr, "Operation diverse...\n");
+ break;
+ }
+ debug_print_expression(e->child);
+ fprintf(stderr, "--\n");
+ break;
+ case E_VALUE:
+ fprintf(stderr, "Valeur: %li\n", e->avalue);
+ break;
+ case E_LABEL:
+ fprintf(stderr, "Label: %s\n", e->symbol);
+ break;
+ case E_STRING:
+ fprintf(stderr, "String: %s\n", e->symbol);
+ break;
+ case E_PATTERN:
+ fprintf(stderr, "Pattern: %s, index %i\n", e->pattern->name, e->index);
+ break;
+ case E_INTERNAL:
+ fprintf(stderr, "Instruction interne: %s\n", e->symbol);
+ break;
+ case E_INSTRUCT:
+ fprintf(stderr, "Instruction: %s\n", e->symbol);
+ break;
+ }
+ if (e->next) {
+ debug_print_expression(e->next);
+ }
+}
+
+static expression_t *copy_expression(expression_t * e);
+
+static bytestream_t *pushuninit(int size)
+{
+ bytestream_t *s;
-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->segment = segment;
s->size = size;
s->Label = NULL;
s->Expr = NULL;
- s->line = line
+ s->line = line;
s->filename = filenames[nestedinc];
@@ -103,51 +153,57 @@ static bytestream_t * pushuninit(int size) {
p_bss = s;
s_bss += size;
break;
-
+
}
-
+
return s;
}
-static bytestream_t * pushdword(unsigned long int d, expression_t * e) {
- bytestream_t * s;
+static bytestream_t *pushdword(unsigned long int d, expression_t * e)
+{
+ bytestream_t *s;
- if ((segment <= 0) || (segment >= 1)) {
+ 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);
+ s->Expr = copy_expression(e);
}
-
+
return s;
}
-static bytestream_t * pushlabel(char * label) {
- bytestream_t * 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"));
}
+ InsererVarDansTab(&labels, CreerElement(label, s));
+
return s;
}
-static void pushstring(char * s) {
- char marker = *s, valid, tstring[6];
-
+static void pushstring(char *s)
+{
+ char marker = *s, tstring[6];
+ int valid;
+
while ((*s) && (marker != *s)) {
if (*s == '\\') {
s++;
- switch(*s) {
+ switch (*s) {
case '0':
pushdword('\0', NULL);
break;
@@ -184,11 +240,11 @@ static void pushstring(char * s) {
break;
}
} else {
- pushdword(s, NULL);
+ pushdword(*s, NULL);
}
s++;
}
-
+
}
static void pushstart(void)
@@ -246,6 +302,10 @@ static void free_expr(expression_t * e)
free_expr(e->next);
}
+ if (e->symbol) {
+ free(e->symbol);
+ }
+
free(e);
}
@@ -372,6 +432,7 @@ void push_pile(char *a)
break;
case 2: /* Cas de #define */
if (wc == 1) {
+ defined = Estrdup(a);
break;
}
case 0: /* Cas normal */
@@ -416,7 +477,7 @@ void push_pile(char *a)
/* Cas des pseudos instructions {DB, DW, DD, DS} */
- if (wc == 1) {
+ if (wc <= 1) {
trouve = 0;
switch (downcase(*a)) {
case 'd':
@@ -424,9 +485,13 @@ void push_pile(char *a)
trouve = 1;
switch (downcase(*(a + 1))) {
case 'b':
+ e->op = 1;
case 'w':
+ e->op = 2;
case 'd':
+ e->op = 3;
case 's':
+ e->op = 4;
break;
default:
trouve = 0;
@@ -435,7 +500,9 @@ void push_pile(char *a)
}
if (trouve) {
e->e_subtype = E_INTERNAL;
- e->prev->e_subtype = E_LABEL;
+ if (e->prev) {
+ e->prev->e_subtype = E_LABEL;
+ }
}
}
@@ -455,7 +522,9 @@ void push_pile(char *a)
/* 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;
+ if ((e->symbol[0] != '\"') && (e->symbol[0] != '\'')) {
+ e->e_subtype = E_LABEL;
+ }
}
e_current = e;
@@ -491,6 +560,7 @@ void push_pile(char *a)
{'-', 2, OP_MOINS},
{'*', 3, OP_MUL},
{'/', 3, OP_DIV},
+ {'%', 3, OP_MOD},
{'+' + 128, 4, OP_PLUS_UNARY},
{'-' + 128, 4, OP_MOINS_UNARY},
{'(', 5, OP_FUNC_CALL},
@@ -512,6 +582,7 @@ static void evaluate(expression_t * e)
case OP_MOINS:
case OP_MUL:
case OP_DIV:
+ case OP_MOD:
if ((e->child->e_subtype == E_VALUE) && (e->child->next->e_subtype == E_VALUE)) {
switch (e->op) {
case OP_PLUS:
@@ -529,6 +600,12 @@ static void evaluate(expression_t * e)
}
e->avalue = e->child->avalue / e->child->next->avalue;
break;
+ case OP_MOD:
+ 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);
@@ -581,6 +658,15 @@ static void evaluate(expression_t * e)
if (e->child->next->child->e_subtype == e->child->next->child->next->e_subtype) {
exception(1, _("Expression too complex or invalid"));
}
+ /* On veut obtenir quelque chose sous la forme LABEL[VALUE + PATTERN] */
+ if (e->child->next->child->e_subtype == E_PATTERN) {
+ t = e->child->next->child;
+ e->child->next->child = t->next;
+ t->next->prev = NULL;
+ t->next->next = t;
+ t->prev = t->next;
+ t->next = NULL;
+ }
}
break;
case OP_DIRECT:
@@ -592,7 +678,8 @@ static void evaluate(expression_t * e)
| 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) {
+ switch (e->child->e_subtype) {
+ case E_OPERATION:
if (!((e->child->op == OP_PLUS) || (e->child->op == OP_MOINS))) {
exception(1, _("Address operation invalid"));
}
@@ -850,10 +937,16 @@ static void evaluate(expression_t * e)
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 l'on est ici, c'est que l'on est dans le cas [PATTERN + VALUE]
+ ou [VALUE + PATTERN]. On se met sur la forme [VALUE + PATTERN] */
+ if (e->child->child->e_subtype == E_PATTERN) {
+ t = e->child->child;
+ e->child->child = t->next;
+ t->next->prev = NULL;
+ t->next->next = t;
+ t->prev = t->next;
+ t->next = NULL;
+ }
}
}
/* Bon si on arrive ici sain et sauf, c'est que l'expression est sous la forme
@@ -870,11 +963,21 @@ static void evaluate(expression_t * e)
}
free(t);
e->op = OP_DECAL;
-
- } /* if operation */
+ break; /* case OPERATION */
+ case E_LABEL:
+ /* On est sous la forme [LABEL], on va mettre sous la forme LABEL[0] */
+ t = (expression_t *) Emalloc(sizeof(expression_t));
+ t->e_type = t->e_subtype = E_VALUE;
+ t->avalue = 0;
+ t->next = t->child = NULL;
+ t->prev = e->child;
+ e->child->next = t;
+ t->father = e;
+ e->op = OP_DECAL;
+ break;
+ }
break;
}
-
}
void act_pile(int o)
@@ -897,15 +1000,18 @@ void act_pile(int o)
case OP_MOINS:
case OP_MUL:
case OP_DIV:
+ case OP_MOD:
case OP_DECAL:
- e2 = e_current;
e1 = e_current->prev;
+ e2 = e_current;
if (e_current->prev->prev) {
e_current->prev->prev->next = NULL;
+ e_current = e1->prev;
} else {
e_current = NULL;
}
e1->prev = NULL;
+ e2->next = NULL;
e->child = e1;
e1->father = e2->father = e;
break;
@@ -983,29 +1089,495 @@ int assembler_init(void)
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;
-
+ 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;
}
+static void super_pattern(pattern_t * patterns, expression_t * e)
+{
+ int i;
+
+ if (!(e->e_subtype == E_OPERATION))
+ return;
+ if (!((e->op == OP_DECAL) || (e->op == OP_DIRECT)))
+ return;
+
+ for (patterns = patterns->next; patterns; patterns = patterns->next) {
+ for (i = 0; i < patterns->nbr; i++) {
+ if (!patterns->expr[i]->name) {
+ if (e->e_subtype == E_OPERATION) {
+ if (e->op == OP_DIRECT) {
+ if (!patterns->expr[i]->left) {
+ e->pattern = patterns;
+ e->index = i;
+ }
+ } else {
+ if (patterns->expr[i]->left) {
+ e->pattern = patterns;
+ e->index = i;
+ }
+ }
+ }
+ } else {
+ if (patterns->expr[i]->string) {
+ if (patterns->expr[i]->string[0] == 'O') {
+ if (e->e_subtype == E_OPERATION) {
+ if (((e->op == OP_DIRECT) && (e->child->e_subtype == E_VALUE))
+ || ((e->op == OP_DECAL)
+ && (e->child->next->e_subtype = E_VALUE))) {
+ e->pattern = patterns;
+ e->index = i;
+ }
+ } else {
+ if (e->e_subtype == E_LABEL) {
+ e->pattern = patterns;
+ e->index = i;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static int islabel(expression_t *);
+
+static int islabel2(expression_t * e)
+{
+ if (islabel(e))
+ return 1;
+ if (e->next) {
+ return islabel2(e->next);
+ }
+ return 0;
+}
+
+static int islabel(expression_t * e)
+{
+ if (e->e_subtype == E_LABEL)
+ return 1;
+ if (e->child) {
+ return islabel2(e->child);
+ }
+ return 0;
+}
+
+static instruct_t *e_match_i(phon_t * phons, instruct_t * instructs, expression_t * e)
+{
+ char *stringtolook = e->symbol;
+ expression_t *t;
+ int i, go_out;
+
+ for (t = e->next; t; t = t->next) {
+ if (!t->pattern)
+ super_pattern(patterns, t);
+ }
+
+ 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) {
+ t = e;
+ go_out = 0;
+ for (i = 0; (!go_out) && (i < instructs->nbexplicit); i++) {
+ if (!instructs->strings[i]) {
+ if (strcasecmp(instructs->names[i], i ? t->symbol : stringtolook)) {
+ go_out = 1;
+ } else
+ fprintf(stderr, "On a reconnu le mot %s au %i eme mot\n", t->symbol, i);
+ } else {
+ switch (instructs->strings[i][0]) {
+ case 'P':
+ if (!t->pattern) {
+ fprintf(stderr,
+ "On a une pattern sur le mot %i, mais pas dans l'instruction...\n",
+ i);
+ go_out = 1;
+ } else {
+ fprintf(stderr,
+ "On a la pattern %s sur le mot %i, on la compare avec %s\n",
+ instructs->strings[i] + 1, i, t->pattern->name);
+ if (strcasecmp(instructs->strings[i] + 1, t->pattern->name))
+ go_out = 1;
+ else
+ fprintf(stderr, "Ok, on ne sort pas.\n");
+ }
+ break;
+ case 'C':
+ if (t->e_subtype != E_VALUE) {
+ go_out = 1;
+ if (t->e_subtype == E_OPERATION) {
+ if (t->op == OP_FUNC_CALL)
+ go_out = 0;
+ }
+ }
+ break;
+ case 'o':
+ /* Pour que quelque chose soit absolu, il nous suffit d'avoir un label dans l'expression */
+ if (!islabel(t))
+ go_out = 1;
+ break;
+ case 'O':
+ /* C'est le cas le plus simple ou presque, il suffit de tout prendre */
+ break;
+ default:
+ exception(1, _("Unknow predefined string into the meta language"));
+ }
+ }
+
+ if (!(t = t->next) && ((i + 1) < instructs->nbexplicit)) {
+ go_out = 1;
+ fprintf(stderr, "On sort quand même... (t = %p et i = %i)\n", t, i);
+ }
+ }
+
+ if (!go_out) {
+ break;
+ }
+ }
+
+ if (instructs) {
+ fprintf(stderr, "Nous avons reconnu une instruction:\n");
+ fprintf(stderr, " o Instruction contenant %i champs explicites et %i champs implicites.\n",
+ instructs->nbexplicit, instructs->nbimplicit);
+ fprintf(stderr, " => Champs explicites.\n");
+ for (i = 0; i < instructs->nbexplicit; i++) {
+ fprintf(stderr, " + %s <= %s (type %s)\n",
+ instructs->names[i],
+ instructs->strings[i] ? instructs->strings[i] : "Pas de chaîne associée",
+ instructs->etypes[i] ? "prédéfinit" : "direct");
+ }
+ fprintf(stderr, " => Champs implicites.\n");
+ for (i = 0; i < instructs->nbimplicit; i++) {
+ switch (instructs->itypes[i]) {
+ case 0:
+ fprintf(stderr, " + %s <= %s (type direct)\n", instructs->implicits[i],
+ instructs->istrings[i]);
+ break;
+ case 1:
+ fprintf(stderr, " + %s <= %s (type prédéfinit)\n", instructs->implicits[i],
+ instructs->istrings[i]);
+ break;
+ case 2:
+ fprintf(stderr, " + %s <= %i (type valeur)\n", instructs->implicits[i],
+ instructs->ivalues[i]);
+ break;
+ }
+ }
+ } else {
+ fprintf(stderr, "Nous n'avons pas reconnu l'instruction.\n");
+ }
+
+ return instructs;
+}
+
+static void evaluate_pattern(_TableauVariable * it, expression_t * e)
+{
+ metaexpr_t *m;
+ expression_t *t;
+
+ if (!e->pattern) {
+ exception(1, _("Pattern not matching..."));
+ }
+
+ m = e->pattern->expr[e->index];
+
+ switch (e->e_subtype) {
+ case E_OPERATION:
+ switch (e->op) {
+ case OP_DECAL:
+ /* On est sous la forme LABEL[VALEUR + PATTERN] au pire */
+ switch (e->child->next->e_subtype) {
+ case E_OPERATION:
+ /* Et voila on y est... */
+ t = (expression_t *) Emalloc(sizeof(expression_t));
+ t->e_type = t->e_subtype = E_VALUE;
+ t->avalue = e->child->next->child->next->index;
+ t->next = t->child = NULL;
+
+ InsererVarDansTab(it, CreerElement(m->string, t));
+ free(t);
+
+ t = (expression_t *) Emalloc(sizeof(expression_t));
+ t->e_type = t->e_subtype = E_LABEL;
+ t->avalue = 0;
+ t->next = t->child = NULL;
+ t->symbol = Estrdup(e->child->symbol);
+
+ pushdword(e->child->next->child->avalue, t);
+ free(t);
+ break;
+ case E_VALUE:
+ /* Sous la forme LABEL[VALEUR] */
+ t = (expression_t *) Emalloc(sizeof(expression_t));
+ t->e_type = t->e_subtype = E_LABEL;
+ t->avalue = 0;
+ t->next = t->child = NULL;
+ t->symbol = Estrdup(e->child->symbol);
+
+ pushdword(e->child->next->avalue, t);
+ free(t);
+ break;
+ case E_PATTERN:
+ /* Sous la forme LABEL[PATTERN] */
+ t = (expression_t *) Emalloc(sizeof(expression_t));
+ t->e_type = t->e_subtype = E_VALUE;
+ t->avalue = e->child->next->index;
+ t->next = t->child = NULL;
+
+ InsererVarDansTab(it, CreerElement(m->string, t));
+ free(t);
+
+ t = (expression_t *) Emalloc(sizeof(expression_t));
+ t->e_type = t->e_subtype = E_LABEL;
+ t->avalue = 0;
+ t->next = t->child = NULL;
+ t->symbol = Estrdup(e->child->symbol);
+
+ pushdword(0, t);
+ free(t);
+ break;
+ default:
+ exception(1, _("Pattern not matching..."));
+ break;
+ }
+ break;
+ case OP_DIRECT:
+ switch (e->child->e_subtype) {
+ case E_OPERATION:
+ /* Sous la forme [VALUE + PATTERN] */
+ t = (expression_t *) Emalloc(sizeof(expression_t));
+ t->e_type = t->e_subtype = E_VALUE;
+ t->avalue = e->child->child->next->index;
+ t->next = t->child = NULL;
+
+ InsererVarDansTab(it, CreerElement(m->string, t));
+ free(t);
+
+ pushdword(e->child->child->avalue, NULL);
+ break;
+ case E_VALUE:
+ /* Sous la forme [VALUE] */
+ pushdword(e->child->avalue, NULL);
+ break;
+ case E_PATTERN:
+ /* Sous la forme [PATTERN] */
+ t = (expression_t *) Emalloc(sizeof(expression_t));
+ t->e_type = t->e_subtype = E_VALUE;
+ t->avalue = e->child->child->next->index;
+ t->next = t->child = NULL;
+
+ InsererVarDansTab(it, CreerElement(m->string, t));
+ free(t);
+
+ pushdword(e->child->child->avalue, NULL);
+ break;
+ default:
+ exception(1, _("Pattern not matching..."));
+ break;
+ }
+ break;
+ default:
+ exception(1, _("Pattern not matching..."));
+ break;
+ }
+ break;
+ case E_PATTERN:
+ break;
+ default:
+ exception(1, _("Pattern not matching..."));
+ break;
+ }
+}
+
void asm_eol(void)
{
- /* Gros morceau encore ici... */
+ instruct_t *instr;
+ expression_t *t;
+ int i;
+ bytestream_t *pi;
+ _TableauVariable it;
+
+ switch (special) {
+ case 2: /* Cas de #define */
+ InsererVarDansTab(&defines, CreerElement(defined, e_line));
+ free(defined);
+ break;
+ case 1: /* Cas des directives . */
+ case 3: /* Cas de #undef */
+ case 4: /* Cas de #include */
+ /* Rien à faire ici... tout est déjà fait dans la routine push_pile() */
+ break;
+ case 0: /* Cas normal */
+ /* C'est ici la bonne histoire... Il faut reconnaitre l'instruction */
+
+ fprintf(stderr, "Fin de ligne sur:\n");
+ debug_print_expression(e_line);
+
+ e_current = e_line;
+ /* Est-ce que le premier mot est un label terminant par ':' ? */
+ if (e_current->e_subtype == E_LABEL) {
+ if (e_current->symbol[strlen(e_current->symbol) - 1] == ':') {
+ pushlabel(e_current->symbol);
+ e_line = e_current->next;
+ e_current->next = NULL;
+ free_expr(e_current);
+ e_current = e_line;
+ } else {
+ /* C'est peut-être une instruction spéciale */
+ if ((e_current->next) && (e_current->next->e_subtype == E_INTERNAL)) {
+ pushlabel(e_current->symbol);
+ e_line = e_current->next;
+ e_current->next = NULL;
+ free_expr(e_current);
+ e_current = e_line;
+ } else {
+ exception(1, _("Unknow instruction"));
+ }
+ }
+ }
+
+ switch (e_current->e_subtype) {
+ case E_INTERNAL:
+ switch (e_current->op) {
+ case 1:
+ case 2:
+ case 3:
+ do {
+ e_line = e_current->next;
+ e_current->next = NULL;
+ free_expr(e_current);
+ e_current = e_line;
+ if (!e_current)
+ break;
+ switch (e_current->e_subtype) {
+ case E_VALUE:
+ pushdword(e_current->avalue, NULL);
+ break;
+ case E_LABEL:
+ case E_OPERATION:
+ pushdword(0, e_current);
+ break;
+ default:
+ exception(1, _("Bad constant for an immediate value"));
+ }
+ } while (1);
+ break;
+ case 4:
+ do {
+ e_line = e_current->next;
+ e_current->next = NULL;
+ free_expr(e_current);
+ e_current = e_line;
+ if (!e_current)
+ break;
+ switch (e_current->e_subtype) {
+ case E_STRING:
+ pushstring(e_current->symbol);
+ break;
+ default:
+ exception(1, _("Bad constant for a string"));
+ }
+ } while (1);
+ break;
+ }
+ break;
+ case E_INSTRUCT:
+ if (segment != SEG_TEXT) {
+ exception(1, _("You can only have an instruction into a .text segment"));
+ }
+ if (!(instr = e_match_i(phons, instructs, e_current))) {
+ exception(1, _("Unmatched instruction"));
+ }
+
+ /* Operation crutiale: nous avons l'instruction qui correspond le mieux à notre
+ expression, on va tenter de l'évaluer */
+
+ Initialise(&it);
+ pi = pushdword(0, NULL);
+
+ for (i = 0; i < instr->nbexplicit; i++) {
+ if (instr->strings[i]) {
+ switch (instr->strings[i][0]) {
+ case 'C':
+ if (instr->etypes) {
+ if (!strcmp(instr->names[i], "I")) {
+ if (e_current->e_subtype == E_VALUE) {
+ pushdword(e_current->avalue, 0);
+ } else {
+ pushdword(0, e_current);
+ }
+ } else {
+ exception(1,
+ _
+ ("Unknow constant type in the meta language"));
+ }
+ } else {
+ InsererVarDansTab(&it,
+ CreerElement(instr->names[i], e_current));
+ }
+ break;
+ case 'P':
+ t = (expression_t *) Emalloc(sizeof(expression_t));
+ t->e_type = t->e_subtype = E_VALUE;
+ t->avalue = e_current->index;
+ t->child = t->next = NULL;
+ InsererVarDansTab(&it, CreerElement(instr->names[i], t));
+ free(t);
+ evaluate_pattern(&it, e_current);
+
+
+
+ break;
+ default:
+ exception(1, _("Unknow constant type in the meta language"));
+ }
+ }
+
+ e_line = e_current->next;
+ e_current->next = NULL;
+ free_expr(e_current);
+ e_current = e_line;
+ }
+
+
+
+ break;
+ default:
+ exception(1, _("Unknow instruction"));
+ break;
+ }
+
+ break;
+ }
+
wc = 0;
special = 0;
+ e_current = e_line = NULL;
}
void asm_eof(void)
{
}
-static void delete_bytestream(bytestream_t * s) {
- if (s->next) delete_bytestream(s->next);
+static void delete_bytestream(bytestream_t * s)
+{
+ if (s->next)
+ delete_bytestream(s->next);
free(s);
}
@@ -1020,6 +1592,39 @@ void assembler_flush(void)
int process_file(char *name)
{
- /* Petite chose à faire ici et cela sera bon */
+ FILE *f;
+ char buf[BUFSIZ], errctx[BUFSIZ], *p;
+ int i = 0;
+
+ pushcontext(_("Loading file"));
+ sprintf(errctx, _("Opening file '%s'"), name);
+ pushcontext(errctx);
+ filenames[nestedinc++] = Estrdup(name);
+ if (!(f = fopen(name, "r"))) {
+ pushcontext(strerror(errno));
+ return 1;
+ }
+ popcontext();
+ pushcontext(_("Reading file"));
+ while (fgets(buf, BUFSIZ, f)) {
+ sprintf(errctx, _("Reading line %i"), line = ++i);
+ pushcontext(errctx);
+ if ((p = strchr(buf, '\r'))) {
+ *p = '\0';
+ }
+ if ((p = strchr(buf, '\n'))) {
+ *p = '\0';
+ }
+ parse_line(buf);
+ sprintf(errctx, _("Summering line %s"), buf);
+ pushcontext(errctx);
+ asm_eol();
+ popcontext();
+ popcontext();
+ }
+ nestedinc--;
+ popcontext();
+ popcontext();
+ fclose(f);
return 0;
}
diff --git a/lib/hash.c b/lib/hash.c
index 58b6f9f..bd406c8 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -2,20 +2,17 @@
#include <stdlib.h>
#include <string.h>
#include "hash.h"
+#include "exceptions.h"
+#include "config.h"
static char *CHAINEHACHAGE = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
-static void TraitementDesErreurs(int codeerreur)
-{
- if (codeerreur == 1) {
- printf("\tErreur d'allocation\n");
- } else {
- printf("\tUne autre erreur...\n");
- }
-}
-
static int FonctionHachage(char *clef)
{
unsigned int i;
+
+ if (!clef) {
+ exception(1, _("Internal error into hashing"));
+ }
for (i = 0; i < strlen(CHAINEHACHAGE); i++) {
if (clef[0] == CHAINEHACHAGE[i]) {
@@ -29,11 +26,8 @@ _Element CreerElement(char *Nom, _TypeVariable Var)
{
_Element e;
- e.NomVar = strdup(Nom);
+ e.NomVar = Estrdup(Nom);
- if (e.NomVar == NULL) {
- TraitementDesErreurs(1);
- }
e.Variable = Var;
return (e);
}
@@ -43,18 +37,8 @@ static _ListeChaine InserTete(_ListeChaine l, _Element e)
_ListeChaine aux;
unsigned int i;
- aux = (_ListeChaine) malloc(sizeof(struct _LstChn));
-
- if (aux == NULL) {
- TraitementDesErreurs(1);
- return (NULL);
- }
- aux->Elem.NomVar = (char *) malloc(sizeof(char) * (strlen(e.NomVar) + 1));
-
- if (aux->Elem.NomVar == NULL) {
- TraitementDesErreurs(1);
- return (NULL);
- }
+ aux = (_ListeChaine) Emalloc(sizeof(struct _LstChn));
+ aux->Elem.NomVar = (char *) Emalloc(sizeof(char) * (strlen(e.NomVar) + 1));
for (i = 0; i <= strlen(e.NomVar); i++) {
aux->Elem.NomVar[i] = e.NomVar[i];
}
@@ -174,7 +158,7 @@ int Initialise(_TableauVariable * t)
{
unsigned int i;
- (*t) = (_TableauVariable) malloc(sizeof(_ListeChaine) * strlen(CHAINEHACHAGE));
+ (*t) = (_TableauVariable) Emalloc(sizeof(_ListeChaine) * strlen(CHAINEHACHAGE));
for (i = 0; i < strlen(CHAINEHACHAGE); i++) {
(*t)[i] = NULL;
}
diff --git a/lib/instructions.txt b/lib/instructions.txt
index 6522ffe..494ca47 100644
--- a/lib/instructions.txt
+++ b/lib/instructions.txt
@@ -1,6 +1,15 @@
+# Champ d'instructions général
FI:c3,6;c2,6;c1,6;e,6;op,8
-Fa:reserved,4;rm,
+
+# Champ d'adressage
+Fa:reserved,4;rm,2
+
+# Pattern des registres
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
+
+# Pattern des adressages
+# .O = Adresse absolue (relogée)
+# .o = Adresse relative à l'instruction en cours (ex: Label, Label + 2, __current__ + 4)
Pm:regop=.Pr;.I=.O;[regop=.Pr;.I=.O[regop=.Pr
# bits 3 - 2
@@ -56,9 +65,10 @@ I:SHR c1=.Pr,c2=.Pr,.I=.C;op=0x7;e=0x1
# Transferts
I:MOV c1=.Pr,rm=.Pm;op=8;e=0;c2=.Fa;c3=regop
+I:MOV c1=.Pr,c3=.Pr;op=8;e=0;c2=0
I:MOV c1=.Pr,.I=.C;op=8;e=1
-I:MOV c2=.Pm,rm=.Pr;op=8;e=2;c2=.Fa;c3=regop
-I:MOV c2=.Pm,.I=.C;op=8;e=3;c2=.Fa;c3=regop
+I:MOV c2=.Pm,rm=.Pr;op=8;e=2;c1=.Fa;c3=regop
+I:MOV c2=.Pm,.I=.C;op=8;e=3;c1=.Fa;c3=regop
p:MV=MOV
diff --git a/lib/meta.c b/lib/meta.c
index 52e29ff..0bc6f48 100644
--- a/lib/meta.c
+++ b/lib/meta.c
@@ -512,8 +512,8 @@ int meta_load(char *n)
char buf[BUFSIZ], errctx[BUFSIZ], *p;
int i = 0;
- pushcontext("Loading meta file");
- sprintf(errctx, "Opening file '%s'", n);
+ pushcontext(_("Loading meta file"));
+ sprintf(errctx, _("Opening file '%s'"), n);
pushcontext(errctx);
if (!(f = fopen(n, "r"))) {
@@ -521,9 +521,9 @@ int meta_load(char *n)
return 1;
}
popcontext();
- pushcontext("Reading file");
+ pushcontext(_("Reading file"));
while (fgets(buf, BUFSIZ, f)) {
- sprintf(errctx, "Reading line %i", ++i);
+ sprintf(errctx, _("Reading line %i"), ++i);
pushcontext(errctx);
if ((p = strchr(buf, '\r'))) {
*p = '\0';
diff --git a/lib/parser.c b/lib/parser.c
index 2a9edd1..47cae8d 100644
--- a/lib/parser.c
+++ b/lib/parser.c
@@ -35,6 +35,7 @@ static operator_t operators[] = {
{'-', 2, OP_MOINS},
{'*', 3, OP_MUL},
{'/', 3, OP_DIV},
+ {'%', 3, OP_MOD},
{'+' + 128, 4, OP_PLUS_UNARY},
{'-' + 128, 4, OP_MOINS_UNARY},
{'(', 5, OP_FUNC_CALL},
@@ -268,7 +269,7 @@ void parse_line(char *line)
}
} 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] == '\'') || (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;