Personal tools
You are here: Home Projects LISP Le_Lisp Source code lelisp11 sm90 macros.c
Document Actions

macros.c

by Paul McJones last modified 2007-01-02 09:26

Click here to get the file

Size 5.3 kB - File type text/x-csrc

File contents


/* variables globales */

# define MAXMAC 2000
# define MAXMEM 20000
# define MAXPAR 20
# include <stdio.h>

struct stligne {
	char *etiquette;
	char *codop;
	char *paramv [MAXPAR];
		};

struct descripm {
	char *nom;
	char *corps;
		};

struct descripm pmac [MAXMAC];
struct descripm *entc = pmac;
char *ptc, *pts;
char *index();
char mem [MAXMEM];
char *memp = mem;
char *salloc ();

/* allocation dynamique de la mem. pour stocker le corps d'une macro */
putmacro (c)
{
	if (memp >= MAXMEM + mem)
		nonmem ();
		*memp++ = c;
}
/* fonction delimitant un champ */
char *champ ()
{
	char *ptd = pts;
	while (*ptc != '\n')
	{
		switch (*ptc) {
		case '<':
			while (*++ptc!='>' && *ptc!='')
				*pts++ = *ptc;
			++ptc;
			break;
		case '\t':
		case ' ':
			/* remplacer les blancs et les tabulation
			   par des 0 */
			*pts++ = '';
			while (*++ptc == ' ' || *ptc == '\t')
				;
			return (ptd);
		default:
			*pts++ = *ptc++;
		}
	}
	*pts++ = '';
	return (ptd);
}

/* decomposition dune ligne en champs */
decompligne(ligne, tchampp, copie)
char *ligne, *copie;
struct stligne *tchampp;
{	int i;
	char *pit;
	char *pat;
	ptc = ligne;
	pts = copie;
	tchampp->etiquette = champ ();
	tchampp->codop = champ ();
	pit = champ ();
	/* detecter les . argumens */
	if (pat = index(tchampp->codop, '.'))
	{
		tchampp->paramv[0] = pat + 1;
		*pat = '';
	} else
		tchampp->paramv[0] = "";
	for (i = 1; i < MAXPAR; i++) /* remplacer les , par des  */
	{
		tchampp->paramv[i] = pit;
		while (*pit != ',' && *pit != '')
			pit++;
		if (*pit == ',')  *pit++ = '';
	}
}

/* fonction recherchant le nom d'une macro dans le descrip. des macros */
struct descripm *ismacro (tchampp)
struct stligne *tchampp;
{
struct descripm *macp;
for (macp = pmac; macp < entc; macp++)
	{
		if (strcmp (tchampp->codop, macp->nom) == 0)
			return (macp);

	}
	return (NULL);
}


/* message d'erreur pour signaler des parametres de macro incorrects */
merr ()
{
	fprintf (stderr, "parametre incorrect \n");
	exit (1);
}

/* teste s'il y a au moins un \@, le remplace par l'etiq. courante */
getetiq (macp)
struct descripm *macp;
{
	static int etiqcount;
	char c;
	char *car;
	car = macp->corps;
	while ((c = *car) != '')
	{
		if ((c = *car++) == '\')
		{
			if ((c = *car++) == '@')
				return (++etiqcount);

		}
	}
	return (0);
}




expandmacro (macp, tchampp) /* remplace le nom d'une macro par son corps */
struct descripm *macp;
struct stligne *tchampp;
{
	char c, ligne[120], *chaine;
	int dansif;
	char *corps;
	int etiq;
	corps = macp->corps;
	etiq = getetiq (macp);
	chaine = ligne;
	dansif = 0;
	if (*tchampp->etiquette)
		printf("%s\t", tchampp->etiquette);
	while ((c = *corps) != '')
		{
		if ((c = *corps++) == '\')
			 /* remplacer le nom des parametres par leur valeur */
			{
			if ((c = *corps) >= '0' && c <= '9') {
				sprintf(chaine, "%s", tchampp->paramv[c-'0']);
				chaine += strlen(chaine);
			} else
				if ((c = *corps) == '@' )  {
			 /* remplacer les \@ par l'etiquette courante */
					sprintf(chaine, ".%d", etiq);
					chaine += strlen(chaine);
				}
				else
					merr (); /* message parametre incorrect */
			++corps;
			}
		else
			*chaine++ = c;
		if (c == '\n')
		{
			*chaine++ = '';
			dansif = recurmacro(ligne, dansif);
			chaine = ligne;
		}
	}
}

/* definition d'une macro */
defmacro(tchampp)
struct stligne *tchampp;
{
	struct stligne tchamp;
	char *p, c;
	char copie[120], ligne[120];
	strcpy (entc->nom = salloc(strlen(tchampp->etiquette) + 1),
		tchampp->etiquette);
	entc->corps = memp;
	/* memoriser le corps de la macro */
	while( fgets(ligne, sizeof ligne, stdin) )
	{
		decompligne(ligne, &tchamp, copie);
		if ( strcmp ( tchamp.codop, "ENDM" ) == 0 )
		break;
		p = ligne;
		while( c = *p++ )
		{
			putmacro (c);
		}
	}
	entc++;
}


/* allocation dynamique de la memoire */
char *salloc (N)
{
	char *p;
	p = memp;
	if ( (memp += N) <= mem + MAXMEM)
		return (p);
	nonmem ();
}


/* message de debordement memoire */
nonmem ()
{
	fprintf (stderr, " plus d'espace memoire disponible \n");
	exit (1);
}

/* programme principal */
recurmacro(chaine,dansif)
char *chaine;
{
	struct stligne tchamp;
	char copie[120];
	struct descripm *macp;
	if (*chaine =='*') {
		if (!dansif)
			fputs(chaine, stdout);
		return(dansif);
	}
	decompligne(chaine, &tchamp, copie);
	if (strcmp(tchamp.codop, "ENDC") == 0)
		return(0);
	if (strcmp(tchamp.codop, "IFEQ")==0 || strcmp(tchamp.codop, "IFNE")==0)
		return ( ifeqne(equal(tchamp.codop, "IFEQ"),
				 tchamp.paramv[1]) );
	if (strcmp(tchamp.codop, "IFC")==0 || strcmp(tchamp.codop, "IFNC")==0 )
		return (equal(tchamp.paramv[1], tchamp.paramv[2]) !=
			equal(tchamp.codop, "IFC") );
	if (dansif)
		return(dansif);
	if ( (macp = ismacro (&tchamp)) != NULL)
		expandmacro (macp, &tchamp);
	else
		if (strcmp (tchamp.codop, "MACRO") == 0)
			defmacro (&tchamp);
		else
			fputs (chaine, stdout);
	return(dansif);
}

/* programme principal */
main ()
{
	int dansif;
	char ligne[120];
	dansif = 0;
	while (fgets(ligne, sizeof ligne, stdin) != NULL)
		dansif = recurmacro(ligne, dansif);
}

equal(a,b)
{
	return (!strcmp(a,b));
}

ifeqne(iseqne, string)
{
	return( iseqne==0 );
}

« April 2024 »
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: