diff options
| -rw-r--r-- | lib/assembler.c | 705 | ||||
| -rw-r--r-- | lib/hash.c | 36 | ||||
| -rw-r--r-- | lib/instructions.txt | 16 | ||||
| -rw-r--r-- | lib/meta.c | 8 | ||||
| -rw-r--r-- | lib/parser.c | 3 | 
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;  } @@ -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 @@ -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; | 
