summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/assembler.c295
1 files changed, 267 insertions, 28 deletions
diff --git a/lib/assembler.c b/lib/assembler.c
index dec26e8..bc9d5d2 100644
--- a/lib/assembler.c
+++ b/lib/assembler.c
@@ -36,7 +36,7 @@ typedef struct bytestream_t {
struct bytestream_t *next;
- int line;
+ int line, relog;
char *filename;
} bytestream_t;
@@ -128,9 +128,11 @@ static bytestream_t *pushuninit(int size)
s->next = NULL;
s->Encoded = 0;
s->segment = segment;
- s->size = size;
+ s->size = 1;
s->Label = NULL;
s->Expr = NULL;
+
+ s->relog = 1;
s->line = line;
s->filename = filenames[nestedinc - 1];
@@ -169,6 +171,8 @@ static bytestream_t *pushdword(unsigned long int d, expression_t * e)
exception(1, _("You have to be into the .text or the .data segment to define a value."));
}
+ fprintf(stderr, "On pousse %i avec %p\n", d, e);
+
s = pushuninit(1);
s->Encoded = d;
if (e) {
@@ -185,6 +189,7 @@ static bytestream_t *pushlabel(char *label)
s = pushuninit(0);
s->Label = Estrdup(label);
+ s->size = 0;
NomVarToVar(label, labels, &trouve);
@@ -1121,6 +1126,7 @@ int assembler_init(void)
text->next = data->next = bss->next = NULL;
text->size = data->size = bss->size = 0;
+ text->Label = data->Label = bss->Label = NULL;
return 0;
}
@@ -1263,11 +1269,6 @@ static instruct_t *e_match_i(phon_t * phons, instruct_t * instructs, expression_
}
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;
@@ -1342,6 +1343,7 @@ static void evaluate_pattern(_TableauVariable * it, expression_t * e)
if (strcmp(m->name, "I")) {
exception(1, _("Unknow constant type in the meta language"));
}
+ fprintf(stderr, "On pousse une valeur (1)\n");
if (e->e_subtype == E_VALUE) {
pushdword(e->avalue, NULL);
} else {
@@ -1361,7 +1363,6 @@ static void evaluate_pattern(_TableauVariable * it, expression_t * e)
t->symbol = NULL;
t->pattern = NULL;
InsererVarDansTab(it, CreerElement(m->name, t));
- free(t);
}
}
}
@@ -1382,6 +1383,7 @@ static void evaluate_pattern(_TableauVariable * it, expression_t * e)
&& (e->child->next->child->e_subtype == E_VALUE)) {
tv = e->child->next->child->avalue;
}
+ fprintf(stderr, "On pousse une valeur (2)\n");
pushdword(tv, e->child);
} else {
exception(1, _("Logical error in meta language"));
@@ -1408,7 +1410,6 @@ static void evaluate_pattern(_TableauVariable * it, expression_t * e)
}
t->symbol = NULL;
InsererVarDansTab(it, CreerElement(m->name, t));
- free(t);
} else {
exception(1, _("Logical error in meta language"));
}
@@ -1432,7 +1433,6 @@ static void evaluate_pattern(_TableauVariable * it, expression_t * e)
t->symbol = NULL;
t->pattern = NULL;
InsererVarDansTab(it, CreerElement(m->name, t));
- free(t);
}
}
}
@@ -1546,6 +1546,7 @@ void asm_eol(void)
break;
switch (e_current->e_subtype) {
case E_VALUE:
+ fprintf(stderr, "On pousse une valeur (3)\n");
pushdword(e_current->avalue, NULL);
break;
case E_STRING:
@@ -1556,6 +1557,7 @@ void asm_eol(void)
break;
case E_LABEL:
case E_OPERATION:
+ fprintf(stderr, "On pousse une valeur (4)\n");
pushdword(0, e_current);
break;
default:
@@ -1613,13 +1615,13 @@ void asm_eol(void)
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")) {
+ fprintf(stderr, "On pousse une valeur (6)\n");
if (e_current->e_subtype == E_VALUE) {
pushdword(e_current->avalue, 0);
} else {
@@ -1636,6 +1638,7 @@ void asm_eol(void)
case 'O':
if (instr->etypes) {
if (!strcmp(instr->names[i], "I")) {
+ fprintf(stderr, "On pousse une valeur (7)\n");
if (e_current->e_subtype == E_VALUE) {
pushdword(e_current->avalue, 0);
} else {
@@ -1647,23 +1650,6 @@ void asm_eol(void)
("Unknow constant type in the meta language"));}
}
break;
- case 'o':
- if (instr->etypes) {
- if (!strcmp(instr->names[i], "I")) {
- if (e_current->e_subtype == E_VALUE) {
- exception(1,
- _
- ("Can't have a direct value for a relative offset"));}
- else {
- pi = pushdword(0, e_current);
- }
- pi->Encoded -= pi->offset;
- } else {
- exception(1,
- _
- ("Unknow constant type in the meta language"));}
- }
- break;
case 'P':
t = (expression_t *) Emalloc(sizeof(expression_t));
t->e_type = t->e_subtype = E_VALUE;
@@ -1730,6 +1716,7 @@ void asm_eol(void)
fprintf(stderr, "Variables\n");
AfficheTableau(it);
+ fprintf(stderr, "On pousse une valeur (8)\n");
pushdword(evaluate_field(it, "FI", fields), NULL);
DetruitTab(&it);
break;
@@ -1746,15 +1733,267 @@ void asm_eol(void)
e_current = e_line = NULL;
}
+/*
+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;
+
+bytestream_t *text, *data, *bss, *p_text, *p_data, *p_bss;
+int s_text = 0, s_data = 0, s_bss = 0;
+*/
+
+static void writeword(unsigned long int a, FILE * f, int n) {
+ int i;
+
+ fprintf(stderr, "On écrit le mot %i\n", a);
+ if (fwrite(&a, sizeof(unsigned long int), 1, f) != 1) {
+ if (ferror(f)) {
+ pushcontext(strerror(errno));
+ }
+ exception(1, _("Error writing file"));
+ }
+
+ for (i = 0; i < n - 1; i++) {
+ writeword(0, f, 1);
+ }
+}
+
+static void writestring(char * string, FILE * f) {
+ fprintf(stderr, "On écrit la chaîne %s\n", string);
+ for (; *string; string++) {
+ writeword(*string, f, 1);
+ }
+}
+
+/*
+ /\
+ / \
+ / ++ \
+ / ++ \
+ / \
+ |~~~~~~~~~~|
+ | +-+ +-+ |
+ | +-+ +-+ |
+ | |
+ | +--+ |
+ | | .| |
+ +---+--+---+
+
+*/
+
void asm_eof(FILE * f)
{
+ bytestream_t * t, * u;
+ FILE * f1, * f2;
+ int nbsymbols = 0, a;
+ char errctx[BUFSIZ], trouve;
+ bytestream_t * ttext = text, * tdata = data, * tbss = bss;
+
+ fprintf(stderr, "On a reçu une fin de fichier...\n");
+
+ pushcontext(_("Creating temporary files"));
+ if (!(f1 = fopen("__text__", "wb"))) {
+ pushcontext(strerror(errno));
+ exception(1, _("Error writing file __text__"));
+ }
+ if (!(f2 = fopen("__symbols__", "wb"))) {
+ pushcontext(strerror(errno));
+ exception(1, _("Error writing file __symbols__"));
+ }
+ popcontext();
+
+ pushcontext(_("Dumping memory into object file"));
+
+ pushcontext(_("Dumping text segment"));
+ for (ttext = ttext->next; ttext; ttext = ttext->next) {
+ sprintf(errctx, _("Processing word number %i coming from line %i of the file %s."), ttext->offset, ttext->line, ttext->filename);
+ fprintf(stderr, "%s\n", errctx);
+ pushcontext(errctx);
+
+ a = 0;
+
+ if (ttext->Expr) {
+ fprintf(stderr, "On a une sous-expression..\n");
+ switch(ttext->Expr->e_subtype) {
+ case E_VALUE:
+ fprintf(stderr, "Type valeur.\n");
+ a = ttext->Expr->avalue;
+ break;
+ case E_LABEL:
+ fprintf(stderr, "Type label.\n");
+ a = ttext->Expr->avalue;
+ nbsymbols++;
+ writeword(0, f2, 1);
+ writeword(ttext->offset, f2, 1);
+ writeword(strlen(ttext->Expr->symbol), f2, 1);
+ writestring(ttext->Expr->symbol, f2);
+ break;
+ case E_OPERATION:
+ fprintf(stderr, "Type operation.\n");
+ if (ttext->Expr->op != OP_FUNC_CALL) {
+ exception(1, _("Can't evaluate expression for a direct value"));
+ }
+ if (strcmp(ttext->Expr->symbol, "diff")) {
+ exception(1, _("Can't evaluate expression for a direct value"));
+ }
+ if ((ttext->Expr->child->e_subtype != E_LABEL) || (ttext->Expr->child->next->e_subtype != E_LABEL)) {
+ exception(1, _("Can only use the diff() function onto labels"));
+ }
+
+ t = (bytestream_t *) NomVarToVar(ttext->Expr->child->symbol, labels, &trouve);
+ if (!trouve) {
+ exception(1, _("Can only evaluate a diff on local symbols"));
+ }
+ u = (bytestream_t *) NomVarToVar(ttext->Expr->child->next->symbol, labels, &trouve);
+ if (!trouve) {
+ exception(1, _("Can only evaluate a diff on local symbols"));
+ }
+
+ if (t->segment != u->segment) {
+ exception(1, _("Can only evaluate a diff on symbols from the same segment"));
+ }
+
+ a = t->offset - u->offset;
+ break;
+ default:
+ exception(1, _("Can't evaluate expression"));
+
+ }
+ }
+
+ a += ttext->Encoded;
+
+ if (ttext->size) {
+ writeword(a, f1, text->size);
+ } else {
+ if (ttext->Label) {
+ nbsymbols++;
+ writeword(0, f2, 1);
+ writeword(ttext->offset, f2, 1);
+ writeword(strlen(ttext->Expr->symbol), f2, 1);
+ writestring(ttext->Expr->symbol, f2);
+ }
+ }
+ popcontext();
+ }
+ popcontext();
+
+ pushcontext(_("Dumping data segment"));
+ for (tdata = tdata->next; tdata; tdata = tdata->next) {
+ sprintf(errctx, _("Processing word number %i coming from line %i of the file %s."), tdata->offset, tdata->line, tdata->filename);
+ fprintf(stderr, "%s\n", errctx);
+ pushcontext(errctx);
+
+ a = 0;
+
+ if (tdata->Expr) {
+ fprintf(stderr, "On a une sous-expression..\n");
+ switch(tdata->Expr->e_subtype) {
+ case E_VALUE:
+ fprintf(stderr, "Type valeur.\n");
+ a = tdata->Expr->avalue;
+ break;
+ case E_LABEL:
+ fprintf(stderr, "Type label.\n");
+ a = tdata->Expr->avalue;
+ nbsymbols++;
+ writeword(0, f2, 1);
+ writeword(tdata->offset, f2, 1);
+ writeword(strlen(tdata->Expr->symbol), f2, 1);
+ writestring(tdata->Expr->symbol, f2);
+ break;
+ case E_OPERATION:
+ fprintf(stderr, "Type operation.\n");
+ if (tdata->Expr->op != OP_FUNC_CALL) {
+ exception(1, _("Can't evaluate expression for a direct value"));
+ }
+ if (strcmp(tdata->Expr->symbol, "diff")) {
+ exception(1, _("Can't evaluate expression for a direct value"));
+ }
+ if ((tdata->Expr->child->e_subtype != E_LABEL) || (tdata->Expr->child->next->e_subtype != E_LABEL)) {
+ exception(1, _("Can only use the diff() function onto labels"));
+ }
+
+ t = (bytestream_t *) NomVarToVar(tdata->Expr->child->symbol, labels, &trouve);
+ if (!trouve) {
+ exception(1, _("Can only evaluate a diff on local symbols"));
+ }
+ u = (bytestream_t *) NomVarToVar(tdata->Expr->child->next->symbol, labels, &trouve);
+ if (!trouve) {
+ exception(1, _("Can only evaluate a diff on local symbols"));
+ }
+
+ if (t->segment != u->segment) {
+ exception(1, _("Can only evaluate a diff on symbols from the same segment"));
+ }
+
+ a = t->offset - u->offset;
+ break;
+ default:
+ exception(1, _("Can't evaluate expression"));
+
+ }
+ }
+
+ a += tdata->Encoded;
+
+ if (tdata->size) {
+ writeword(a, f1, text->size);
+ } else {
+ if (tdata->Label) {
+ nbsymbols++;
+ writeword(0, f2, 1);
+ writeword(tdata->offset, f2, 1);
+ writeword(strlen(tdata->Expr->symbol), f2, 1);
+ writestring(tdata->Expr->symbol, f2);
+ }
+ }
+ popcontext();
+ }
+ popcontext();
+
+ fclose(f1);
+
+ pushcontext(_("Dumping bss segment"));
+ for (tbss = tbss->next; tbss; tbss = tbss->next) {
+ sprintf(errctx, _("Processing word number %i coming from line %i of the file %s."), tbss->offset, tbss->line, tbss->filename);
+ fprintf(stderr, "%s\n", errctx);
+ pushcontext(errctx);
+
+ if (!tbss->size) {
+ if (tbss->Label) {
+ nbsymbols++;
+ writeword(0, f2, 1);
+ writeword(tbss->offset, f2, 1);
+ writeword(strlen(tbss->Expr->symbol), f2, 1);
+ writestring(tbss->Expr->symbol, f2);
+ }
+ }
+ popcontext();
+ }
+ popcontext();
+
+
+ popcontext();
+ fclose(f1);
+ fclose(f2);
}
static void delete_bytestream(bytestream_t * s)
{
if (s->next)
delete_bytestream(s->next);
+ if (s->Label)
+ free(s->Label);
free(s);
}