/* lex.c */
#include "codegen.h"
#include "driver.h"
#include "lex.h"
#include "preprocess.h"
#include "stdlib.h"
#include "vars.h"

/**
	Note: the line[] and lptr are statics for the following tokenizing functions,
	in which line[] is for line buffered input was chr(), -> inspect_chr()
**/

/** inspect current chr, doesn't advance pointer **/
char inspect_chr()
{
	return (line[lptr] & 127);
}

/** lookahead, but doesn't advance ptr **/
char lookahead()
{
	if (inspect_chr() == 0)
		return 0;
	else
		return (line[lptr+1] & 127);
}

/** ret chr from linebuffer and advance ptr unless null chr **/
char g_nxtchr()
{
	if (inspect_chr() == 0)
		return 0;
	else
		return (line[lptr++] & 127);
}

/** reindex & null terminate input line **/
void kill()
{
	lptr = 0;
	line[lptr] = 0;
}

/** ck chr at line[lptr], if null & !eof_flg, get next line[] fill **/
/** bridges line breaks, & preprocess stuff **/
char scan_nxt()
{
	while (inspect_chr() == 0)
	{
		if (eof_flg)
			return 0;
		input_line();
		preprocess();
	}
	return g_nxtchr();
}

/** ck line[] for null (EOL), if so, get next line, ret chr or null **/
/** called only by preprocess() **/
char inchar()
{
	if (inspect_chr() == 0)
		input_line();
	if (eof_flg)
		return 0;
	return (g_nxtchr());
}

/**
	Main input function, chars accumulate into static line[],
	also echoes to file commentary tokens, if desired by user.
	a byte value > 7Fh (sign set) is read as eof in this function
	On return, line[] holds string of k's, where k is of the set
	of bytes {1..7Fh} with a null termination, 0.
**/
void input_line()
{
	FILE *unit;
	int k;
	
	while(1)
	{
		if (fp_input == 0)
			openin();
			
		if (eof_flg)
			return;
			
		if ((unit = fp_input2) == 0)
			unit = fp_input;
		
		kill();	 				/** clear line index **/

		while ((k = fgetc(unit)) > 0)  		/** main fetch fn **/
		{
			if ((k == EOL) | (lptr >= LINEMAX))
				break;			/** chg >= to > **/
			
			/** store input in static char array **/
			line[lptr++] = k;
		}	/** a null in stream will abort while **/

		line[lptr] = 0;				/* append null */
		lineno++;				/* read one more line */

		if (k <= 0)				/** eof is - flag **/
		{
			fclose(unit);
			if (fp_input2)
				endinclude();
			else
				fp_input = 0;
		}
		
		/** indicates something was read to process **/
		if (lptr)
		{
			/** if flgs, echo to FILE as comment **/
			if ((ctext) & (cmode))
			{
				sa_comment();
				outstr(line);		/** FILE output **/
				nl();
			}
			lptr = 0;			/** reindex for next time **/
			return;				/** with line[] filled to process **/
		}
	}
}