summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am11
-rw-r--r--lib/assembler.c0
-rw-r--r--lib/hash.c215
-rw-r--r--lib/instructions.txt102
-rw-r--r--lib/meta.c560
-rw-r--r--lib/numbers.c59
-rw-r--r--lib/parser.c309
7 files changed, 1256 insertions, 0 deletions
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
--- /dev/null
+++ b/lib/assembler.c
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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 <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <string.h>
+#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 <stdio.h>
+#include <limits.h>
+#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