diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/assembler.c | 295 |
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); } |