ref: a41bdff88f3a9315394fb3c4a39d0f4adf505492
dir: /src/asm/yaccprt1.y/
%{ #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