ref: eb4f790a827c7758182a3750eb717332b30d475f
dir: /src/asm/yaccprt3.y/
%start asmfile %% asmfile : lines lastline ; lastline : /* empty */ | line { nLineNo+=1; nTotalLines+=1; } ; lines : /* empty */ | lines line '\n' { nLineNo+=1; nTotalLines+=1; } ; line : /* empty */ | label | label cpu_command | label macro | label simple_pseudoop | pseudoop ; label : /* empty */ | T_LABEL { if( $1[0]=='.' ) sym_AddLocalReloc($1); else sym_AddReloc($1); } | T_LABEL ':' { if( $1[0]=='.' ) sym_AddLocalReloc($1); else sym_AddReloc($1); } | T_LABEL ':' ':' { sym_AddReloc($1); sym_Export($1); } ; macro : T_ID { yy_set_state( LEX_STATE_MACROARGS ); } macroargs { yy_set_state( LEX_STATE_NORMAL ); if( !fstk_RunMacro($1) ) { fprintf(stderr, "Macro '%s' not defined", $1); yyerror( "No such macro" ); } } ; macroargs : /* empty */ | macroarg | macroarg ',' macroargs ; macroarg : T_STRING { sym_AddNewMacroArg( $1 ); } ; pseudoop : equ | set | rb | rw | rl | equs | macrodef ; simple_pseudoop : include | printf | printt | printv | if | else | endc | import | export | global | db | dw | dl | ds | section | rsreset | rsset | incbin | rept | shift | fail | warn | purge | pops | pushs | popo | pusho | opt ; opt : T_POP_OPT { yy_set_state( LEX_STATE_MACROARGS ); } opt_list { yy_set_state( LEX_STATE_NORMAL ); } ; opt_list : opt_list_entry | opt_list_entry ',' opt_list ; opt_list_entry : T_STRING { opt_Parse($1); } ; popo : T_POP_POPO { opt_Pop(); } ; pusho : T_POP_PUSHO { opt_Push(); } ; pops : T_POP_POPS { out_PopSection(); } ; pushs : T_POP_PUSHS { out_PushSection(); } ; fail : T_POP_FAIL string { fatalerror($2); } ; warn : T_POP_WARN string { yyerror($2); } ; shift : T_POP_SHIFT { sym_ShiftCurrentMacroArgs(); } ; rept : T_POP_REPT const { copyrept(); fstk_RunRept( $2 ); } ; macrodef : T_LABEL ':' T_POP_MACRO { copymacro(); sym_AddMacro($1); } ; equs : T_LABEL T_POP_EQUS string { sym_AddString( $1, $3 ); } ; rsset : T_POP_RSSET const { sym_AddSet( "_RS", $2 ); } ; rsreset : T_POP_RSRESET { sym_AddSet( "_RS", 0 ); } ; rl : T_LABEL T_POP_RL const { sym_AddEqu( $1, sym_GetConstantValue("_RS") ); sym_AddSet( "_RS", sym_GetConstantValue("_RS")+4*$3 ); } ; rw : T_LABEL T_POP_RW const { sym_AddEqu( $1, sym_GetConstantValue("_RS") ); sym_AddSet( "_RS", sym_GetConstantValue("_RS")+2*$3 ); } ; rb : T_LABEL T_POP_RB const { sym_AddEqu( $1, sym_GetConstantValue("_RS") ); sym_AddSet( "_RS", sym_GetConstantValue("_RS")+$3 ); } ; ds : T_POP_DS const { out_Skip( $2 ); } ; db : T_POP_DB constlist_8bit ; dw : T_POP_DW constlist_16bit ; dl : T_POP_DL constlist_32bit ; purge : T_POP_PURGE { oDontExpandStrings=1; } purge_list { oDontExpandStrings=0; } ; purge_list : purge_list_entry | purge_list_entry ',' purge_list ; purge_list_entry : T_ID { sym_Purge($1); } ; import : T_POP_IMPORT import_list ; import_list : import_list_entry | import_list_entry ',' import_list ; import_list_entry : T_ID { sym_Import($1); } ; export : T_POP_EXPORT export_list ; export_list : export_list_entry | export_list_entry ',' export_list ; export_list_entry : T_ID { sym_Export($1); } ; global : T_POP_GLOBAL global_list ; global_list : global_list_entry | global_list_entry ',' global_list ; global_list_entry : T_ID { sym_Global($1); } ; equ : T_LABEL T_POP_EQU const { sym_AddEqu( $1, $3 ); } ; set : T_LABEL T_POP_SET const { sym_AddSet( $1, $3 ); } ; include : T_POP_INCLUDE string { if( !fstk_RunInclude($2) ) { fprintf(stderr, "Could not open file '%s' : %s\n", $2, strerror(errno)); yyerror( "File not found" ); } } ; incbin : T_POP_INCBIN string { out_BinaryFile( $2 ); } | T_POP_INCBIN string ',' const ',' const { out_BinaryFileSlice( $2, $4, $6 ); } ; printt : T_POP_PRINTT string { if( nPass==1 ) printf( "%s", $2 ); } ; printv : T_POP_PRINTV const { if( nPass==1 ) printf( "$%lX", $2 ); } ; printf : T_POP_PRINTF const { if( nPass==1 ) math_Print( $2 ); } ; if : T_POP_IF const { nIFDepth+=1; if( !$2 ) { if_skip_to_else(); /* will continue parsing just after ELSE or just at ENDC keyword */ } } else : T_POP_ELSE { if_skip_to_endc(); /* will continue parsing just at ENDC keyword */ } ; endc : T_POP_ENDC { nIFDepth-=1; } ; const_3bit : const { if( ($1<0) || ($1>7) ) { yyerror( "Immediate value must be 3-bit" ); } else $$=$1&0x7; } ; constlist_8bit : constlist_8bit_entry | constlist_8bit_entry ',' constlist_8bit ; constlist_8bit_entry : { out_Skip( 1 ); } | const_8bit { out_RelByte( &$1 ); } | string { out_String( $1 ); } ; constlist_16bit : constlist_16bit_entry | constlist_16bit_entry ',' constlist_16bit ; constlist_16bit_entry : { out_Skip( 2 ); } | const_16bit { out_RelWord( &$1 ); } ; constlist_32bit : constlist_32bit_entry | constlist_32bit_entry ',' constlist_32bit ; constlist_32bit_entry : { out_Skip( 4 ); } | relocconst { out_RelLong( &$1 ); } ; const_PCrel : relocconst { $$ = $1; if( !rpn_isPCRelative(&$1) ) yyerror( "Expression must be PC-relative" ); } ; const_8bit : relocconst { if( (!rpn_isReloc(&$1)) && (($1.nVal<-128) || ($1.nVal>255)) ) { yyerror( "Expression must be 8-bit" ); } $$=$1; } ; const_16bit : relocconst { if( (!rpn_isReloc(&$1)) && (($1.nVal<-32768) || ($1.nVal>65535)) ) { yyerror( "Expression must be 16-bit" ); } $$=$1; } ; relocconst : T_ID { rpn_Symbol(&$$,$1); $$.nVal = sym_GetValue($1); } | T_NUMBER { rpn_Number(&$$,$1); $$.nVal = $1; } | string { ULONG r; r=str2int($1); rpn_Number(&$$,r); $$.nVal=r; } | T_OP_LOGICNOT relocconst %prec NEG { rpn_LOGNOT(&$$,&$2); } | relocconst T_OP_LOGICOR relocconst { rpn_LOGOR(&$$,&$1,&$3); } | relocconst T_OP_LOGICAND relocconst { rpn_LOGAND(&$$,&$1,&$3); } | relocconst T_OP_LOGICEQU relocconst { rpn_LOGEQU(&$$,&$1,&$3); } | relocconst T_OP_LOGICGT relocconst { rpn_LOGGT(&$$,&$1,&$3); } | relocconst T_OP_LOGICLT relocconst { rpn_LOGLT(&$$,&$1,&$3); } | relocconst T_OP_LOGICGE relocconst { rpn_LOGGE(&$$,&$1,&$3); } | relocconst T_OP_LOGICLE relocconst { rpn_LOGLE(&$$,&$1,&$3); } | relocconst T_OP_LOGICNE relocconst { rpn_LOGNE(&$$,&$1,&$3); } | relocconst T_OP_ADD relocconst { rpn_ADD(&$$,&$1,&$3); } | relocconst T_OP_SUB relocconst { rpn_SUB(&$$,&$1,&$3); } | relocconst T_OP_XOR relocconst { rpn_XOR(&$$,&$1,&$3); } | relocconst T_OP_OR relocconst { rpn_OR(&$$,&$1,&$3); } | relocconst T_OP_AND relocconst { rpn_AND(&$$,&$1,&$3); } | relocconst T_OP_SHL relocconst { rpn_SHL(&$$,&$1,&$3); } | relocconst T_OP_SHR relocconst { rpn_SHR(&$$,&$1,&$3); } | relocconst T_OP_MUL relocconst { rpn_MUL(&$$,&$1,&$3); } | relocconst T_OP_DIV relocconst { rpn_DIV(&$$,&$1,&$3); } | relocconst T_OP_MOD relocconst { rpn_MOD(&$$,&$1,&$3); } | T_OP_ADD relocconst %prec NEG { $$ = $2; } | T_OP_SUB relocconst %prec NEG { rpn_UNNEG(&$$,&$2); } | T_OP_NOT relocconst %prec NEG { rpn_UNNOT(&$$,&$2); } | T_OP_BANK '(' T_ID ')' { rpn_Bank(&$$,$3); $$.nVal = 0; } | T_OP_DEF '(' T_ID ')' { rpn_Number(&$$,sym_isConstDefined($3)); } | T_OP_FDIV '(' const ',' const ')' { rpn_Number(&$$,math_Div($3,$5)); } | T_OP_FMUL '(' const ',' const ')' { rpn_Number(&$$,math_Mul($3,$5)); } | T_OP_SIN '(' const ')' { rpn_Number(&$$,math_Sin($3)); } | T_OP_COS '(' const ')' { rpn_Number(&$$,math_Cos($3)); } | T_OP_TAN '(' const ')' { rpn_Number(&$$,math_Tan($3)); } | T_OP_ASIN '(' const ')' { rpn_Number(&$$,math_ASin($3)); } | T_OP_ACOS '(' const ')' { rpn_Number(&$$,math_ACos($3)); } | T_OP_ATAN '(' const ')' { rpn_Number(&$$,math_ATan($3)); } | T_OP_ATAN2 '(' const ',' const ')' { rpn_Number(&$$,math_ATan2($3,$5)); } | T_OP_STRCMP '(' string ',' string ')' { rpn_Number(&$$,strcmp($3,$5)); } | T_OP_STRIN '(' string ',' string ')' { char *p; if( (p=strstr($3,$5))!=NULL ) { rpn_Number(&$$,p-$3+1); } else { rpn_Number(&$$,0); } } | T_OP_STRLEN '(' string ')' { rpn_Number(&$$,strlen($3)); } | '(' relocconst ')' { $$ = $2; } ; const : T_ID { $$ = sym_GetConstantValue($1); } | T_NUMBER { $$ = $1; } | string { $$ = str2int($1); } | T_OP_LOGICNOT const %prec NEG { $$ = !$2; } | const T_OP_LOGICOR const { $$ = $1 || $3; } | const T_OP_LOGICAND const { $$ = $1 && $3; } | const T_OP_LOGICEQU const { $$ = $1 == $3; } | const T_OP_LOGICGT const { $$ = $1 > $3; } | const T_OP_LOGICLT const { $$ = $1 < $3; } | const T_OP_LOGICGE const { $$ = $1 >= $3; } | const T_OP_LOGICLE const { $$ = $1 <= $3; } | const T_OP_LOGICNE const { $$ = $1 != $3; } | const T_OP_ADD const { $$ = $1 + $3; } | const T_OP_SUB const { $$ = $1 - $3; } | T_ID T_OP_SUB T_ID { $$ = sym_GetDefinedValue($1) - sym_GetDefinedValue($3); } | const T_OP_XOR const { $$ = $1 ^ $3; } | const T_OP_OR const { $$ = $1 | $3; } | const T_OP_AND const { $$ = $1 & $3; } | const T_OP_SHL const { $$ = $1 << $3; } | const T_OP_SHR const { $$ = $1 >> $3; } | const T_OP_MUL const { $$ = $1 * $3; } | const T_OP_DIV const { $$ = $1 / $3; } | const T_OP_MOD const { $$ = $1 % $3; } | T_OP_ADD const %prec NEG { $$ = +$2; } | T_OP_SUB const %prec NEG { $$ = -$2; } | T_OP_NOT const %prec NEG { $$ = 0xFFFFFFFF^$2; } | T_OP_FDIV '(' const ',' const ')' { $$ = math_Div($3,$5); } | T_OP_FMUL '(' const ',' const ')' { $$ = math_Mul($3,$5); } | T_OP_SIN '(' const ')' { $$ = math_Sin($3); } | T_OP_COS '(' const ')' { $$ = math_Cos($3); } | T_OP_TAN '(' const ')' { $$ = math_Tan($3); } | T_OP_ASIN '(' const ')' { $$ = math_ASin($3); } | T_OP_ACOS '(' const ')' { $$ = math_ACos($3); } | T_OP_ATAN '(' const ')' { $$ = math_ATan($3); } | T_OP_ATAN2 '(' const ',' const ')' { $$ = math_ATan2($3,$5); } | T_OP_DEF '(' T_ID ')' { $$ = sym_isConstDefined($3); } | T_OP_STRCMP '(' string ',' string ')' { $$ = strcmp( $3, $5 ); } | T_OP_STRIN '(' string ',' string ')' { char *p; if( (p=strstr($3,$5))!=NULL ) { $$ = p-$3+1; } else { $$ = 0; } } | T_OP_STRLEN '(' string ')' { $$ = strlen($3); } | '(' const ')' { $$ = $2; } ; string : T_STRING { strcpy($$,$1); } | T_OP_STRSUB '(' string ',' const ',' const ')' { strncpy($$,$3+$5-1,$7); $$[$7]=0; } | T_OP_STRCAT '(' string ',' string ')' { strcpy($$,$3); strcat($$,$5); } | T_OP_STRUPR '(' string ')' { strcpy($$,$3); strupr($$); } | T_OP_STRLWR '(' string ')' { strcpy($$,$3); strlwr($$); } ;