From 80fdb0714b75cb240d8b8068d718b915f1904110 Mon Sep 17 00:00:00 2001 From: Pixel <> Date: Thu, 29 Mar 2001 23:40:57 +0000 Subject: First. --- lib/Makefile.am | 11 + lib/assembler.c | 0 lib/hash.c | 215 ++++++++++++++++++++ lib/instructions.txt | 102 ++++++++++ lib/meta.c | 560 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/numbers.c | 59 ++++++ lib/parser.c | 309 ++++++++++++++++++++++++++++ 7 files changed, 1256 insertions(+) create mode 100644 lib/Makefile.am create mode 100644 lib/assembler.c create mode 100644 lib/hash.c create mode 100644 lib/instructions.txt create mode 100644 lib/meta.c create mode 100644 lib/numbers.c create mode 100644 lib/parser.c (limited to 'lib') diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..4d66b47 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,11 @@ +localedir = $(datadir)/locale +DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ +AM_CFLAGS = -O3 -Wall -Wstrict-prototypes $(CFLAGS) +INCLUDES = -I. -I.. -I$(includedir) -I../include +lib_LTLIBRARIES = libCompilo.la + +libCompilo_la_SOURCES = assembler.c parser.c meta.c numbers.c hash.h + +libCompilo_la_LDFLAGS = -version-info $(ProjetArchi_VERSION_INFO) + +EXTRA_DIST = instructions.txt \ No newline at end of file diff --git a/lib/assembler.c b/lib/assembler.c new file mode 100644 index 0000000..e69de29 diff --git a/lib/hash.c b/lib/hash.c new file mode 100644 index 0000000..9f45885 --- /dev/null +++ b/lib/hash.c @@ -0,0 +1,215 @@ +#include +#include +#include +#include "hash.h" +#include "global.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; + + for (i = 0; i < strlen(CHAINEHACHAGE); i++) { + if (clef[0] == CHAINEHACHAGE[i]) { + return (i); + } + } + return (-1); +} + +_Element CreerElement(char *Nom, _TypeVariable Var) +{ + _Element e; + + e.NomVar = strdup(Nom); + + if (e.NomVar == NULL) { + TraitementDesErreurs(1); + } + e.Variable = Var; + return (e); +} + +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); + } + for (i = 0; i <= strlen(e.NomVar); i++) { + aux->Elem.NomVar[i] = e.NomVar[i]; + } + aux->Elem.Variable = e.Variable; + aux->Suivant = l; + return (aux); +} + +static int EgaliteChaine(char *ch1, char *ch2) +{ + unsigned int i; + + if (strlen(ch1) != strlen(ch2)) { + return (0); + } + for (i = 0; i < strlen(ch1); i++) { + if (ch1[i] != ch2[i]) { + return (0); + } + } + return (1); + /* return (1-strcmp(ch1,ch2)); */ +} + +static void Supprimer(_ListeChaine * l, char *Nom) +{ + _ListeChaine l_aux = NULL; + + if ((*l) != NULL) { + if (EgaliteChaine((*l)->Elem.NomVar, Nom)) { + l_aux = *l; + *l = (*l)->Suivant; + free(l_aux->Elem.NomVar); + free(l_aux); + } else { + Supprimer(&((*l)->Suivant), Nom); + } + } +} + +static void Detruit(_ListeChaine * l) { + _ListeChaine l_aux = NULL; + + while (*l) { + l_aux = l->Suivant; + free((*l)->Elem.NomVar); + free(*l); + *l = l_aux; + } +} + +char SupprimerDansTab(_TableauVariable * t, char *Nom) +{ + int index = FonctionHachage(Nom); + + if (0 <= index && index < strlen(CHAINEHACHAGE)) { + Supprimer(&((*t)[index]), Nom); + } else { + return (0); + } + return (1); +} + +char InsererVarDansTab(_TableauVariable * t, _Element e) +{ + int index = FonctionHachage(e.NomVar); + + if (0 <= index && index < strlen(CHAINEHACHAGE)) { + (*t)[index] = InserTete((*t)[index], e); + } else { + return (0); + } + return (1); +} + +static _TypeVariable NomVarToVarListe(char *Nom, _ListeChaine l, char *trouve) +{ + *trouve = 0; + while (l != NULL) { + if (EgaliteChaine(Nom, (l->Elem).NomVar)) { + *trouve = 1; + return (l->Elem.Variable); + } + l = l->Suivant; + } +#ifdef HAVE_CONFIG_H + return (NULL); +#else + return 0; +#endif +} + +_TypeVariable NomVarToVar(char *Nom, _TableauVariable t, char *trouve) +{ + return (NomVarToVarListe(Nom, t[FonctionHachage(Nom)], trouve)); +} + +void AfficheListe(_ListeChaine l) +{ + while (l != NULL) { + printf("%s\n", l->Elem.NomVar); + l = l->Suivant; + } +} + +void AfficheTableau(_TableauVariable t) +{ + unsigned int i; + + for (i = 0; i < TAILLECHAINEHACHAGE; i++) { + AfficheListe(t[i]); + } +} + +int Initialise(_TableauVariable * t) +{ + unsigned int i; + + (*t) = (_TableauVariable) malloc(sizeof(_ListeChaine) * strlen(CHAINEHACHAGE)); + for (i = 0; i < strlen(CHAINEHACHAGE); i++) { + (*t)[i] = NULL; + } + return (i); +} + +void DetruitTab(_TableauVariable * t){ + for (i = 0; i < strlen(CHAINEHACHAGE); i++) { + Detruit(&((*t)[i])); + } + + free(*t); + *t = NULL; +} + +#ifndef HAVE_CONFIG_H +int main(void) +{ + int c; + _TableauVariable t; + + Initialise(&t); + InsererVarDansTab(&t, CreerElement("yves", 14)); + InsererVarDansTab(&t, CreerElement("vomitif", 8)); + InsererVarDansTab(&t, CreerElement("vomi", 2)); + InsererVarDansTab(&t, CreerElement("Vomi", 25)); + InsererVarDansTab(&t, CreerElement("_vomi", 20)); + AfficheTableau(t); + printf("\n"); + SupprimerDansTab(&t, "Vomi"); + AfficheTableau(t); + + /* c'est a cause du ouindause qui ferme tout de suite l'exec, + mais moi je veux ce qu'il se passe */ + c = getc(stdin); + return (c); +} +#endif diff --git a/lib/instructions.txt b/lib/instructions.txt new file mode 100644 index 0000000..ab8e387 --- /dev/null +++ b/lib/instructions.txt @@ -0,0 +1,102 @@ +FI:c3,6;c2,6;c1,6;e,6;op,8 +Fa:reserved,4;rm,2 +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 + +# bits 3 - 2 +# ~~~~~~~~~~ +# 00 overflow +# 01 zero +# 10 sign +# 11 parity + +# bits 5 - 4 +# ~~~~~~~~~~ +# 00 test1 +# 01 test1 || test2 +# 10 test1 && !test2 +# 11 test1 || !test2 + + +# Arithmetique + +I:ADD c1=.Pr,c2=.Pr,c3=.Pr;op=0x0;e=0x0 +I:ADD c1=.Pr,c2=.Pr,.I=.C;op=0x0;e=0x1 +I:ADU c1=.Pr,c2=.Pr,c3=.Pr;op=0x0;e=0x2 +I:ADU c1=.Pr,c2=.Pr,.I=.C;op=0x0;e=0x3 + +p:ADS=ADD + +I:SUB c1=.Pr,c2=.Pr,c3=.Pr;op=0x1;e=0x0 +I:SUB c1=.Pr,c2=.Pr,.I=.C;op=0x1;e=0x1 +I:SBU c1=.Pr,c2=.Pr,c3=.Pr;op=0x1;e=0x2 +I:SBU c1=.Pr,c2=.Pr,.I=.C;op=0x1;e=0x3 + +p:SBS=SUB + +I:MUL c2=.Pr,c3=.Pr;op=0x2;e=0x0 +I:MUL c2=.Pr,.I=.C;op=0x2;e=0x1 + +I:DIV c2=.Pr,c3=.Pr;op=0x3;e=0x0 +I:DIV c2=.Pr,.I=.C;op=0x3;e=0x1 + +I:AND c1=.Pr,c2=.Pr,c3=.Pr;op=0x4;e=0x0 +I:AND c1=.Pr,c2=.Pr,.I=.C;op=0x4;e=0x1 + +I:OR c1=.Pr,c2=.Pr,c3=.Pr;op=0x5;e=0x0 +I:OR c1=.Pr,c2=.Pr,.I=.C;op=0x5;e=0x1 + +I:SHL c1=.Pr,c2=.Pr,c3=.Pr;op=0x6;e=0x0 +I:SHL c1=.Pr,c2=.Pr,I=.C;op=0x6;e=0x1 + +I:SHR c1=.Pr,c2=.Pr,c3=.Pr;op=0x7;e=0x0 +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,.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 + +p:MV=MOV + + +# Misc1 + +I:NOP;op=9 + + +# Branchements + +# bits 3 - 2 +# ~~~~~~~~~~ +# 00 overflow +# 01 zero +# 10 sign +# 11 parity + +# bits 5 - 4 +# ~~~~~~~~~~ +# 00 test1 +# 01 test1 || test2 == !(!test1 && !test2) +# 10 test1 && !test2 == !(!test1 || test2) +# 11 test1 || !test2 == !(!test1 && test2) + +I:JE c1=.Pr,c2=.Pr,.I=.o;op=0xb;e=0x0 +I:JNE c1=.Pr,c2=.Pr,.I=.o;op=0xb;e=0x1 +I:JL c1=.Pr,c2=.Pr,.I=.o;op=0xb;e=0x2 +I:JLE c1=.Pr,c2=.Pr,.I=.o;op=0xb;e=0x3 +I:JG c2=.Pr,c1=.Pr,.I=.o;op=0xb;e=0x2 +I:JGE c2=.Pr,c1=.Pr,.I=.o;op=0xb;e=0x3 + +I:JO .I=.o;op=0xb;e=0x10 +I:JZ .I=.o;op=0xb;e=0x14 +I:JS .I=.o;op=0xb;e=0x18 +I:JP .I=.o;op=0xb;e=0x1c + +I:JNO .I=.o;op=0xb;e=0x30 +I:JNZ .I=.o;op=0xb;e=0x34 +I:JNS .I=.o;op=0xb;e=0x38 +I:JNP .I=.o;op=0xb;e=0x3c diff --git a/lib/meta.c b/lib/meta.c new file mode 100644 index 0000000..7aa5add --- /dev/null +++ b/lib/meta.c @@ -0,0 +1,560 @@ +#include +#include +#include +#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define _(x) x +void exception(int, char *); +char * Estrdup(char *); +void * Emalloc(size_t); +#endif +#include "global.h" +#include "numbers.h" +#include "meta.h" + +static char meta_ops[] = ":.;(){}[=, "; +static char meta_firsts[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"; +static char meta_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"; + +phon_t *phons = NULL; +field_t *fields = NULL; +pattern_t *patterns = NULL; +instruct_t *instructs = NULL; + +static int isident(char *word) +{ + if (!strchr(meta_firsts, *word)) { + return 0; + } + while (*word) { + if (!strchr(meta_chars, *(word++))) { + return 0; + } + } + return 1; +} + +static char *getword(char *line, char *p) +{ + char o; + + do { + o = *(p++) = *line; + line++; + } while ((*line) && (!strchr(meta_ops, o)) && (!strchr(meta_ops, *line))); + *p = '\0'; + return line; +} + +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; + 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; + } + while (*line) { + line = getword(line, buffer); + if (!m) { + if (*line != ':') { + exception(1, _("Missing operator ':'")); + } + line++; + switch (buffer[0]) { + case 'F': + first = Estrdup(&buffer[1]); + m = 1; + break; + case 'P': + first = Estrdup(&buffer[1]); + pattern = (pattern_t *) Emalloc(sizeof(pattern_t)); + pattern->name = first; + pattern->next = NULL; + m = 2; + break; + case 'p': + m = 3; + break; + case 'I': + m = 4; + break; + } + } else { + switch (m) { + case 1: /* Champ */ + if (gotname) { + Fsizes[nbfields++] = char_to_number(buffer, &valid); + if (!valid) { + exception(1, _("Invalid number.")); + } + if (*line) { + if (*line != ';') { + exception(1, _("Expecting ';' for field separator.")); + } + line++; + gotname = 0; + } else { + field = (field_t *) Emalloc(sizeof(field_t)); + field->next = fields->next; + fields->next = field; + 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]; + } + field->nbr = nbfields; + } + } else { + if (*line != ',') { + exception(1, _("Expecting ',' for field separator.")); + } + line++; + Fnames[nbfields] = Estrdup(buffer); + gotname = 1; + } + break; + case 2: /* Pattern */ + if (*buffer == '[') { + tmetaexpr = (metaexpr_t *) Emalloc(sizeof(metaexpr_t)); + tmetaexpr->name = NULL; + tmetaexpr->string = NULL; + tmetaexpr->left = metaexpr; + metaexpr = tmetaexpr; + } else { + tmetaexpr = (metaexpr_t *) Emalloc(sizeof(metaexpr_t)); + tmetaexpr->left = tmetaexpr->right = NULL; + tmetaexpr->type = 0; + if (*buffer == '.') { + tmetaexpr->type = 1; + line = getword(line, buffer); + } + if (!isident(buffer)) { + exception(1, _("Identifier incorrect.")); + } + tmetaexpr->name = Estrdup(buffer); + if (*line == '=') { + if (*(++line) != '.') { + exception(1, _("Error: Expecting a . after a =")); + } + line = getword(++line, buffer); + if (!isident(buffer)) { + exception(1, _("Identifier incorrect.")); + } + tmetaexpr->string = Estrdup(buffer); + } else { + tmetaexpr->string = NULL; + } + + if (metaexpr) { + metaexpr->right = tmetaexpr; + } else { + metaexpr = tmetaexpr; + } + if (*line == ';' || !*line) { + tabmetaexpr[nbfields++] = metaexpr; + if (*line) line++; + metaexpr = NULL; + } + if (!*line) { + pattern = (pattern_t *) Emalloc(sizeof(pattern_t)); + pattern->next = patterns->next; + patterns->next = pattern; + pattern->name = first; + pattern->expr = (metaexpr_t **) Emalloc(nbfields * sizeof(metaexpr_t *)); + for (i = 0; i < nbfields; i++) { + pattern->expr[i] = tabmetaexpr[i]; + } + pattern->nbr = nbfields; + } + } + break; + case 3: /* Phonème */ + if (p1) { + if (p2) { + exception(1, _("Extra parameters for field 'p'.")); + } else { + if (isident(buffer)) { + p2 = Estrdup(buffer); + } else { + exception(1, _("Identifier incorrect.")); + } + if (*line) { + exception(1, _("Unexpected char at end of line.")); + } + + phon = (phon_t *) Emalloc(sizeof(phon_t)); + phon->next = phons->next; + phons->next = phon; + phon->p1 = p1; + phon->p2 = p2; + } + } else { + if (isident(buffer)) { + p1 = Estrdup(buffer); + if (*line != '=') { + exception(1, _("Expecting operator '=' for field 'p'.")); + } + line++; + } else { + exception(1, _("Identifier incorrect.")); + } + } + break; + case 4: /* Instruction */ + if (!goteoi) { + if (isident(buffer) || (*buffer == '.')) { + Etypes[nbfields] = 0; + if (*buffer == '.') { + Etypes[nbfields] = 1; + line = getword(line, buffer); + } + Fnames[nbfields] = Estrdup(buffer); + if (*line == '=') { + if (*(++line) != '.') { + exception(1, _("Error: character . expected.")); + } + line = getword(++line, buffer); + if (!isident(buffer)) { + exception(1, _("Identifier incorrect.")); + } + Snames[nbfields] = Estrdup(buffer); + } else { + Snames[nbfields] = NULL; + } + nbfields++; + if (*line == ';') { + goteoi = 1; + line++; + } + } + } else { + if (!isident(buffer)) { + exception(1, _("Identifier incorrect.")); + } + Fimplicits[nbimplicit] = Estrdup(buffer); + if (*line != '=') { + exception(1, _("= expected after an implicit name")); + } + line = getword(++line, buffer); + + if (*buffer == '.') { + Itypes[nbimplicit] = 1; + line = getword(line, buffer); + if (!isident(buffer)) { + exception(1, _("Identifier incorrect")); + } + Sinames[nbimplicit] = Estrdup(buffer); + } else { + Sinames[nbimplicit] = NULL; + Itypes[nbimplicit] = 2; + Fvalues[nbimplicit] = char_to_number(buffer, &valid); + if (!valid) { + if (!isident(buffer)) { + exception(1, _("Identifier incorrect")); + } + Sinames[nbimplicit] = Estrdup(buffer); + Itypes[nbimplicit] = 0; + } + } + nbimplicit++; + + if (*line) { + if (*line != ';') { + exception(1, _("expecting ; as field separator")); + } + line++; + } else { + instruct = (instruct_t *) Emalloc(sizeof(instruct_t)); + instruct->next = instructs->next; + instructs->next = instruct; + instruct->names = (char **) Emalloc(nbfields * sizeof(char *)); + instruct->strings = (char **) Emalloc(nbfields * sizeof(char *)); + instruct->etypes = (int *) Emalloc(nbfields * sizeof(int)); + instruct->implicits = (char **) Emalloc(nbimplicit * sizeof(char *)); + 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]; + instruct->etypes[i] = Etypes[i]; + } + instruct->nbexplicit = nbfields; + for (i = 0; i < nbimplicit; i++) { + instruct->implicits[i] = Fimplicits[i]; + instruct->ivalues[i] = Fvalues[i]; + instruct->istrings[i] = Sinames[i]; + instruct->itypes[i] = Itypes[i]; + } + instruct->nbimplicit = nbimplicit; + goteoi = 0; + } + } + break; + } + } + } +} + +int meta_init(void) +{ + if (!(phons = (phon_t *) malloc(sizeof(phon_t)))) { + return -1; + } + phons->p1 = phons->p2 = NULL; + phons->next = NULL; + + if (!(fields = (field_t *) malloc(sizeof(field_t)))) { + return -1; + } + fields->name = NULL; + 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; + } + instructs->names = NULL; + instructs->strings = NULL; + instructs->etypes = NULL; + instructs->implicits = NULL; + instructs->ivalues = NULL; + instructs->istrings = NULL; + instructs->itypes = NULL; + + return 0; +} + +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) { + int i; + + if (field->next) { + recurs_free_field(field->next); + } + + free(field->name); + for (i = 0; i < field->nbr; i++) { + free(field->names[i]); + } + free(field->names); + free(field->sizes); + free(field); +} + +static void recurs_free_metaexpr(metaexpr_t * metaexpr) { + if (metaexpr->left) { + recurs_free_metaexpr(metaexpr->left); + } + + if (metaexpr->right) { + recurs_free_metaexpr(metaexpr->right); + } + + if (metaexpr->name) { + free(metaexpr->name); + } + + if (metaexpr->string) { + free(metaexpr->string); + } + + free(metaexpr); +} + +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]); + } + free(pattern->expr); + free(pattern); +} + +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]); + } + + free(instruct->names); + free(instruct->strings); + free(instruct->etypes); + free(instruct->implicits); + free(instruct->istrings); + free(instruct->itypes); + 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); + free(phons); + free(fields); + free(patterns); + free(instructs); + phons = NULL; + fields = NULL; + patterns = NULL; + instructs = NULL; +} + +#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); +} + +void main(void) +{ + FILE *f; + char buf[BUFSIZ], *p; + phon_t *phon; + field_t *field; + pattern_t *pattern; + instruct_t *instruct; + int i; + + if (meta_init()) + exception(1, _("Meta parser init failed.")); + + f = fopen("instructions.txt", "r"); + while (fgets(buf, BUFSIZ, f)) { + if ((p = strchr(buf, '\n'))) { + *p = '\0'; + } + meta_parse_line(buf); + } + + fprintf(stderr, "\nListe des phonèmes:\n"); + for (phon = phons->next; phon; phon = phon->next) { + fprintf(stderr, " o %s <===> %s\n", phon->p1, phon->p2); + } + + fprintf(stderr, "\nListe des champs:\n"); + for (field = fields->next; field; field = field->next) { + fprintf(stderr, " o Champ nommé %s, contenant %i parties:\n", field->name, field->nbr); + for (i = 0; i < field->nbr; i++) { + 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); + for (i = 0; i < pattern->nbr; i++) { + 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"); + 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->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->type ? "Constante prédéfinie" : "Feuille"); + } + } + } + + 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, " => 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"); + } + 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; + } + } + } +} + +#endif diff --git a/lib/numbers.c b/lib/numbers.c new file mode 100644 index 0000000..ba45f29 --- /dev/null +++ b/lib/numbers.c @@ -0,0 +1,59 @@ +#include "global.h" +#include "numbers.h" + +int char_to_number(char *st, int *valid) +{ + int whattype = 0, result = 0; + + *valid = 0; + + if (*st == '0') { + st++; + if (*st == 'x') { + whattype = 1; + st++; + } else if (*st) { + whattype = 2; + } else { + *valid = 1; + return 0; + } + } + + while (*st) { + switch (whattype) { + case 0: + if ((*st < '0') || (*st > '9')) { + return 0; + } + result *= 10; + result += *st - '0'; + break; + case 1: + if (((*st < '0') || (*st > '9')) && ((*st < 'A') || (*st > 'F')) + && ((*st < 'a') || (*st > 'f'))) { + return 0; + } + result *= 16; + if ((*st >= '0') && (*st <= '9')) { + result += *st - '0'; + } else if ((*st >= 'A') && (*st <= 'F')) { + result += *st - 'A' + 10; + } else { + result += *st - 'a' + 10; + } + break; + case 2: + if ((*st < '0') || (*st > '7')) { + return 0; + } + result *= 8; + result += *st - '0'; + break; + } + st++; + } + + *valid = 1; + return result; +} diff --git a/lib/parser.c b/lib/parser.c new file mode 100644 index 0000000..a2947e6 --- /dev/null +++ b/lib/parser.c @@ -0,0 +1,309 @@ +#include +#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define _(x) x +void exception(int, char *); +#endif +#include "global.h" +#include "parser.h" + + +typedef unsigned char op_t; + +typedef struct operator_t { + op_t op; + int pri, func; +} operator_t; + +static op_t pile_operators[PILEOP_MAX]; +static int pile_nestedcall[PILECALL_MAX]; + +static int pileop_pos = 0, pilecall_pos = 0; + +static operator_t operators[] = { + {',', 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 operator_t get_op(op_t op) +{ + int i; + + for (i = 0; operators[i].op != 255; i++) { + if (operators[i].op == op) + return operators[i]; + } + + return operators[i]; +} + +static int get_pri(op_t op) +{ + return get_op(op).pri; +} + +static int get_func(op_t op) +{ + return get_op(op).func; +} + +static op_t get_last_op(void) +{ + if (pileop_pos) + return pile_operators[pileop_pos - 1]; + else + return -1; +} + +static op_t pop_op(void) +{ + if (pileop_pos) + return pile_operators[--pileop_pos]; + return -1; +} + +static void push_op(op_t op) +{ + if (pileop_pos != PILEOP_MAX) + pile_operators[pileop_pos++] = op; + else + exception(-1, _("Too many nested operators in expression.\n")); + +} + +static int pop_call(void) +{ + if (pilecall_pos) + return pile_nestedcall[--pilecall_pos]; + 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) +{ + if (pilecall_pos != PILECALL_MAX) + pile_nestedcall[pilecall_pos++] = call; + else + exception(-1, _("Too many nested functions calls in expression.\n")); +} + +static char *getword(char *line, char *p) +{ + char o = 0, *d = line, instring = 0, gotbslash = 0; + + do { + if (instring) { + o = *(p++) = *line; + if (!gotbslash) { + switch (instring) { + case 1: + if (*line == '\'') { + instring = 0; + } + break; + case 2: + if (*line == '"') { + instring = 0; + } + break; + } + if (*line == '\\') gotbslash = 1; + } else { + gotbslash = 0; + } + } else { + if (*(line) == '\'') { + o = *(p++) = *line; + instring = 1; + } else if (*(line) == '"') { + o = *(p++) = *line; + instring = 2; + } else { + if (*(line) != ' ') { + o = *(p++) = *line; + } else if (d != line) { + *p = '\0'; + return line; + } + } + } + line++; + } while (((*line) && (*line != ')') && (*line != ']') && (*line != ';') && (get_func(*line) == -1) + && (get_func(o) == -1)) || (instring)); + *p = '\0'; + return line; +} + +void parse_line(char *line) +{ + char buffer[BUFSIZ], imm[BUFSIZ]; + op_t op; + int got_unary = 128, nbrargs; + + while (*line) { + line = getword(line, buffer); + if (get_func(buffer[0]) != -1) { + buffer[0] += got_unary; + if (got_unary) { + } + if (get_pri(buffer[0]) == -1) { + if (got_unary) { + exception(-1, _("Invalid unary operator")); + } else { + exception(-1, _("Invalid binary operator")); + } + } + 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]); + got_unary = 128; + } else if ((buffer[0] == ';') || (buffer[0] == ')') || (buffer[0] == ']')) { + switch (buffer[0]) { + case ';': + while (pileop_pos) { + op = pop_op(); + if (op == '(') + exception(-1, _("Parse error: too much left parenthesis")); + act_pile(get_func(op)); + } + break; + case ')': + while (1) { + if (!pileop_pos) + exception(-1, _("Parse error: too much right parenthesis")); + op = pop_op(); + if (((op & 127) == '(')) + break; + if (((op & 127) == '[')) + 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)); + } + got_unary = 0; + break; + case ']': + while (1) { + if (!pileop_pos) + exception(-1, _("Parse error: too much right parenthesis")); + op = pop_op(); + if (((op & 127) == '[')) + break; + if (((op & 127) == '(')) + exception(-1, _("Parse error: enclosure mismatch")); + 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] == '\'')) { + push_pile(buffer); + got_unary = 0; + if (!get_last_call()) increment_call(); + } else if (buffer[0]) { + exception(-1, _("Invalid character")); + } + } +} + +#ifndef HAVE_CONFIG_H + +void exception(int level, char *msg) +{ + fprintf(stderr, "%s\n", msg); + exit(level); +} + +void push_pile(char *word) +{ + printf("%s ", word); +} + +void act_pile(int func) +{ + char op; + + switch (func) { + case OP_PLUS: + op = '+'; + break; + case OP_MOINS: + op = '-'; + break; + case OP_DIV: + op = '/'; + break; + case OP_MUL: + op = '*'; + break; + case OP_PLUS_UNARY: + op = '\0'; + break; + case OP_MOINS_UNARY: + op = '|'; + break; + case OP_FUNC_CALL: + op = '@'; + break; + case OP_DECAL: + op = '['; + break; + case OP_DIRECT: + op = '{'; + break; + } + printf("%c ", op); +} + +void main(void) +{ + parse_line("ADD R18, R20, 39;"); + printf("\n\n"); fflush(stdout); + parse_line("MOV R31, Bidule[48 + R12];"); + printf("\n\n"); fflush(stdout); + parse_line("MOV R12, [R3];"); + printf("\n\n"); fflush(stdout); + parse_line("MOV R22, Truc[(3+2)*8];"); + 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); +} + +#endif -- cgit v1.2.3