/**********************************************************************/
/*   This  file  is  the back end for the code generator and is used  */
/*   to  generate  an  ASCII version of the output, corresponding to  */
/*   the '.m' language.						      */
/**********************************************************************/
# include "crunch.h"

/**********************************************************************/
/*   Start a new line when we go over this column.		      */
/**********************************************************************/
# define	LINE_LENGTH	64

/**********************************************************************/
/*   How many columns to tab over when indenting.		      */
/**********************************************************************/
# define	TAB_SIZE	4

int	need_space;
int	list_level;
int	consec_opens;
int	col;
extern int flush_flag;

void
init_ascii()
{
	col = 0;
	consec_opens = 0;
	need_space = FALSE;
	list_level = 0;
}
void
gena_list()
{
	need_space = FALSE;
	if (consec_opens++ == 0 || list_level == 2)
		pr_string("\n(");
	else
		pr_string("(");
	list_level++;
}
void
gena_end_list()
{
	need_space = FALSE;
	consec_opens = 0;
	if (--list_level == 0)
		pr_string("\n)\n");
	else
		pr_string(")");
}
void
gena_int(n)
long	n;
{	char	buf[32];

	consec_opens = 0;
	sprintf(buf, "%ld", n);
	pr_string(buf);
	need_space = TRUE;
}
void
gena_float(v)
double	v;
{	char	buf[64];

	consec_opens = 0;
	sprintf(buf, "%g", v);
	pr_string(buf);
	need_space = TRUE;
}
void
gena_string(str)
char	*str;
{
	consec_opens = 0;
	pr_string("\"");
	while (*str) {
		switch (*str) {
		  case '\t': fputs("\\t", ofp); col++; break;
		  case '\r': fputs("\\r", ofp); col++; break;
		  case '\n': fputs("\\n", ofp); col++; break;
		  case '\f': fputs("\\f", ofp); col++; break;
		  default:
			fputc(*str, ofp);
			break;
		  }
		str++;
		col++;
		}
	fputc('"', ofp);
	col++;
	need_space = TRUE;
}
void
gena_token(val)
int	val;
{

	consec_opens = 0;
	pr_string(map(val));
	need_space = TRUE;
}
void
gena_id(str)
char *str;
{
	consec_opens = 0;
	pr_string(str);
	need_space = TRUE;
}
void
gena_lit(str)
char	*str;
{
	consec_opens = 0;
	pr_string(str);
	need_space = TRUE;
}
void
gena_macro()
{
}

/**********************************************************************/
/*   Compilation  finished.  This  is  a  tidy  up function, but for  */
/*   ascii mode there's nothing for us to do.			      */
/**********************************************************************/
void
gena_finish()
{
}

void
gena_null()
{
	pr_string(" NULL");
}
void
nl()
{	int	i;
	fputc('\n', ofp);
	col = list_level * TAB_SIZE;
	for (i = list_level * TAB_SIZE; i-- > 0;) {
		fputc(' ', ofp);
		}
}
void
pr_string(str)
register char	*str;
{

	if (col > LINE_LENGTH)
		nl();
	else if (need_space)
		fputc(' ', ofp);
	while (*str) {
		if (*str == '\n') {
			nl();
			str++;
			continue;
			}
		fputc(*str, ofp);
		str++;
		col++;
		}
	if (flush_flag)
		fflush(ofp);
}
