shithub: rgbds

ref: a41bdff88f3a9315394fb3c4a39d0f4adf505492
dir: /src/asm/yaccprt1.y/

View raw version
%{
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "asm/symbol.h"
#include "asm/asm.h"
#include "asm/output.h"
#include "asm/mylink.h"
#include "asm/fstack.h"
#include "asm/mymath.h"
#include "asm/rpn.h"
#include "asm/main.h"
#include "asm/lexer.h"

extern bool haltnop;

char	*tzNewMacro;
ULONG	ulNewMacroSize;

size_t symvaluetostring(char *dest, size_t maxLength, char *sym)
{
	size_t length;

	if (sym_isString(sym)) {
		char *src = sym_GetStringValue(sym);
		size_t i;

		for (i = 0; src[i] != 0; i++) {
			if (i >= maxLength) {
				fatalerror("Symbol value too long to fit buffer");
			}
			dest[i] = src[i];
		}

		length = i;
	} else {
		ULONG value = sym_GetConstantValue(sym);
		int fullLength = snprintf(dest, maxLength + 1, "$%lX", value);

		if (fullLength < 0) {
			fatalerror("snprintf encoding error");
		} else {
			length = (size_t)fullLength;

			if (length > maxLength) {
				fatalerror("Symbol value too long to fit buffer");
			}
		}
	}

	return length;
}

ULONG	str2int( char *s )
{
	ULONG r=0;
	while( *s )
	{
		r<<=8;
		r|=(UBYTE)(*s++);
	}
	return( r );
}

ULONG	isWhiteSpace( char s )
{
	return( s==' ' || s=='\t' || s=='\0' || s=='\n' );
}

ULONG	isRept( char *s )
{
	return( (strncasecmp(s,"REPT",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}

ULONG	isEndr( char *s )
{
	return( (strncasecmp(s,"Endr",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}

void	copyrept( void )
{
	SLONG	level=1, len, instring=0;
	char	*src=pCurrentBuffer->pBuffer;

	while( *src && level )
	{
		if( instring==0 )
		{
			if( isRept(src) )
			{
				level+=1;
				src+=4;
			}
			else if( isEndr(src) )
			{
				level-=1;
				src+=4;
			}
			else
			{
				if( *src=='\"' )
					instring=1;
				src+=1;
			}
		}
		else
		{
			if( *src=='\\' )
			{
				src+=2;
			}
			else if( *src=='\"' )
			{
				src+=1;
				instring=0;
			}
			else
			{
				src+=1;
			}
		}
	}

	len=src-pCurrentBuffer->pBuffer-4;

	src=pCurrentBuffer->pBuffer;
	ulNewMacroSize=len;

	if( (tzNewMacro=(char *)malloc(ulNewMacroSize+1))!=NULL )
	{
		ULONG i;

		tzNewMacro[ulNewMacroSize]=0;
		for( i=0; i<ulNewMacroSize; i+=1 )
		{
			if( (tzNewMacro[i]=src[i])=='\n' )
				nLineNo+=1;
		}
	}
	else
		fatalerror( "No mem for REPT block" );

	yyskipbytes( ulNewMacroSize+4 );

}

ULONG	isMacro( char *s )
{
	return( (strncasecmp(s,"MACRO",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[5]) );
}

ULONG	isEndm( char *s )
{
	return( (strncasecmp(s,"Endm",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}

void	copymacro( void )
{
	SLONG	level=1, len, instring=0;
	char	*src=pCurrentBuffer->pBuffer;

	while( *src && level )
	{
		if( instring==0 )
		{
			if( isMacro(src) )
			{
				level+=1;
				src+=4;
			}
			else if( isEndm(src) )
			{
				level-=1;
				src+=4;
			}
			else
			{
				if( *src=='\"' )
					instring=1;
				src+=1;
			}
		}
		else
		{
			if( *src=='\\' )
			{
				src+=2;
			}
			else if( *src=='\"' )
			{
				src+=1;
				instring=0;
			}
			else
			{
				src+=1;
			}
		}
	}

	len=src-pCurrentBuffer->pBuffer-4;

	src=pCurrentBuffer->pBuffer;
	ulNewMacroSize=len;

	if( (tzNewMacro=(char *)malloc(ulNewMacroSize+2))!=NULL )
	{
		ULONG i;

		tzNewMacro[ulNewMacroSize]='\n';
		tzNewMacro[ulNewMacroSize+1]=0;
		for( i=0; i<ulNewMacroSize; i+=1 )
		{
			if( (tzNewMacro[i]=src[i])=='\n' )
				nLineNo+=1;
		}
	}
	else
		fatalerror( "No mem for MACRO definition" );

	yyskipbytes( ulNewMacroSize+4 );
}

ULONG	isIf( char *s )
{
	return( (strncasecmp(s,"If",2)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[2]) );
}

ULONG	isElse( char *s )
{
	return( (strncasecmp(s,"Else",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}

ULONG	isEndc( char *s )
{
	return( (strncasecmp(s,"Endc",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}

void	if_skip_to_else( void )
{
	SLONG	level=1, len, instring=0;
	char	*src=pCurrentBuffer->pBuffer;

	while( *src && level )
	{
		if( *src=='\n' )
			nLineNo+=1;

		if( instring==0 )
		{
			if( isIf(src) )
			{
				level+=1;
				src+=2;
			}
			else if( level==1 && isElse(src) )
			{
				level-=1;
				src+=4;
			}
			else if( isEndc(src) )
			{
				level-=1;
				if( level!=0 )
					src+=4;
			}
			else
			{
				if( *src=='\"' )
					instring=1;
				src+=1;
			}
		}
		else
		{
			if( *src=='\\' )
			{
				src+=2;
			}
			else if( *src=='\"' )
			{
				src+=1;
				instring=0;
			}
			else
			{
				src+=1;
			}
		}
	}

	len=src-pCurrentBuffer->pBuffer;

	yyskipbytes( len );
	yyunput( '\n' );
	nLineNo-=1;
}

void	if_skip_to_endc( void )
{
	SLONG	level=1, len, instring=0;
	char	*src=pCurrentBuffer->pBuffer;

	while( *src && level )
	{
		if( *src=='\n' )
			nLineNo+=1;

		if( instring==0 )
		{
			if( isIf(src) )
			{
				level+=1;
				src+=2;
			}
			else if( isEndc(src) )
			{
				level-=1;
				if( level!=0 )
					src+=4;
			}
			else
			{
				if( *src=='\"' )
					instring=1;
				src+=1;
			}
		}
		else
		{
			if( *src=='\\' )
			{
				src+=2;
			}
			else if( *src=='\"' )
			{
				src+=1;
				instring=0;
			}
			else
			{
				src+=1;
			}
		}
	}

	len=src-pCurrentBuffer->pBuffer;

	yyskipbytes( len );
	yyunput( '\n' );
	nLineNo-=1;
}

%}

%union
{
    char tzSym[MAXSYMLEN + 1];
    char tzString[MAXSTRLEN + 1];
    struct Expression sVal;
    SLONG nConstValue;
}

%type	<sVal>	relocconst
%type	<nConstValue>	const
%type	<nConstValue>	const_3bit
%type	<sVal>	const_8bit
%type	<sVal>	const_16bit
%type	<sVal>	const_PCrel
%type	<nConstValue>	sectiontype

%type	<tzString>	string

%token	<nConstValue>		T_NUMBER
%token	<tzString>	T_STRING

%left	T_OP_LOGICNOT
%left	T_OP_LOGICOR T_OP_LOGICAND T_OP_LOGICEQU
%left	T_OP_LOGICGT T_OP_LOGICLT T_OP_LOGICGE T_OP_LOGICLE T_OP_LOGICNE
%left	T_OP_ADD T_OP_SUB
%left	T_OP_OR T_OP_XOR T_OP_AND
%left	T_OP_SHL T_OP_SHR
%left	T_OP_MUL T_OP_DIV T_OP_MOD
%left	T_OP_NOT
%left	T_OP_DEF
%left	T_OP_BANK
%left	T_OP_SIN
%left	T_OP_COS
%left	T_OP_TAN
%left	T_OP_ASIN
%left	T_OP_ACOS
%left	T_OP_ATAN
%left	T_OP_ATAN2
%left	T_OP_FDIV
%left	T_OP_FMUL

%left	T_OP_STRCMP
%left	T_OP_STRIN
%left	T_OP_STRSUB
%left	T_OP_STRLEN
%left	T_OP_STRCAT
%left	T_OP_STRUPR
%left	T_OP_STRLWR

%left	NEG     /* negation--unary minus */

%token	<tzSym> T_LABEL
%token	<tzSym> T_ID
%token	<tzSym> T_POP_EQU
%token	<tzSym> T_POP_SET
%token	<tzSym> T_POP_EQUS

%token	T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_IF T_POP_ELSE T_POP_ENDC
%token	T_POP_IMPORT T_POP_EXPORT T_POP_GLOBAL
%token	T_POP_DB T_POP_DS T_POP_DW T_POP_DL
%token	T_POP_SECTION
%token	T_POP_RB
%token	T_POP_RW
%token	T_POP_RL
%token	T_POP_MACRO
%token	T_POP_ENDM
%token	T_POP_RSRESET T_POP_RSSET
%token	T_POP_INCBIN T_POP_REPT
%token	T_POP_SHIFT
%token	T_POP_ENDR
%token	T_POP_FAIL
%token	T_POP_WARN
%token	T_POP_PURGE
%token	T_POP_POPS
%token	T_POP_PUSHS
%token	T_POP_POPO
%token	T_POP_PUSHO
%token	T_POP_OPT