📄 patterns.hhf
字号:
mov( (type pat._actRec_ [ebx]).startPosn, ebx ); mov( pat.ar( FailToSave.jmpAdrs ), pat.FailTo.jmpAdrs ); mov( pat.ar( FailToSave.ebpSave ), ebp ); mov( ebp, pat.FailTo.ebpSave ); // The following forces the user to provide a semicolon after // the endmatch invocation. static ; endstatic #endmacro //////////////////////////////////////////////////////////////////////////// #macro match( _m_matchparms_[] ): _m_failAdrs_, _m_successAdrs_, _m_only1Fail_, _m_parm0_, _m_parm1_; // The following local is used to enforce the // presence of exactly one failure section. ?_m_only1Fail_ := false; // Because of alternation, we may need more that one // failure address (since, for each alternation section, // the previous sections must fail to that alternate). // Hence, _m_failAdrs_ is a string that we can set to // various labels under control of this macro. ?_m_failAdrs_ := hla.genLabel; #if( @elements( _m_matchparms_ ) = 1 ) // If there is only one parameter, // assume that it is a string. #if( @baseptype( @text( _m_matchparms_[0] ) ) <> hla.ptString ) #error( "Expected a string parameter" ); #endif #if( @IsConst( @text( _m_matchparms_[0] ) )) lea( esi, @text( _m_matchparms_[0] ) ); #else mov( @text( _m_matchparms_[0] ), esi ); #endif mov( (type str.strRec [esi]).length, edi ); add( esi, edi ); #elseif( @elements( _m_matchparms_ ) = 2 ) ?_m_parm0_ := @lowercase( _m_matchparms_[0], 0 ); ?_m_parm1_ := @lowercase( _m_matchparms_[1], 0 ); #if( _m_parm0_ = "edi" & _m_parm1_ = "esi" ) xchg( esi, edi ); #elseif( _m_parm0_ <> "esi" ) #if( _m_parm1_ = "esi" ) mov( esi, edi ); #elseif( _m_parm1_ <> "edi" ) mov( @text( _m_matchparms_[1]), edi ); #endif mov( @text( _m_matchparms_[0]), esi ); #elseif( _m_parm1_ <> "edi" ) // Note: at this point parm0 is ESI and // parm1 is not EDI. mov( @text( _m_matchparms_[1]), edi ); #endif #else #error( "match: Illegal number of parameters" ); #endif push( pat.CleanESP ); push( pat.FailTo.ebpSave ); push( pat.FailTo.jmpAdrs ); push( pat.StrStart ); mov( esp, pat.CleanESP ); mov( ebp, pat.FailTo.ebpSave ); mov( &@text( _m_failAdrs_ ), pat.FailTo.jmpAdrs ); mov( esi, pat.StrStart ); #keyword onePat; pat._onePat_; #keyword zeroOrOnePat; pat._zeroOrOnePat_; #keyword zeroOrMorePat; pat._zeroOrMorePat_; #keyword oneOrMorePat; pat._oneOrMorePat_; #keyword EOS( _EOS_accept_zero_parameters_[] ); #if( _m_only1Fail_ ) #error( "EOS may not appear in the if_failure section" ) #endif #if( @elements( _EOS_accept_zero_parameters_ ) <> 0 ) #error( "EOS does not accept any parameters" ) #endif if( esi <> edi ) then mov( pat.FailTo.ebpSave, ebp ); jmp( pat.FailTo.jmpAdrs ); endif; #keyword position( _m_pos_n_ ); #if( _m_only1Fail_ ) #error( "'position' may not appear in the if_failure section" ) #endif mov( pat.StrStart, esi ); add( _m_pos_n_, esi ); if( esi > edi ) then mov( pat.FailTo.ebpSave, ebp ); jmp( pat.FailTo.jmpAdrs ); endif; #keyword atPos( _m_AtPos_n_ ); #if( _m_only1Fail_ ) #error( "'AtPos' may not appear in the if_failure section" ) #endif mov( pat.StrStart, eax ); add( _m_AtPos_n_, eax ); if( eax <> esi ) then mov( pat.FailTo.ebpSave, ebp ); jmp( pat.FailTo.jmpAdrs ); endif; #keyword skip( _m_skip_n_ ); #if( _m_only1Fail_ ) #error( "'skip' may not appear in the if_failure section" ) #endif add( _m_skip_n_, esi ); if( esi >= edi ) then mov( pat.FailTo.ebpSave, ebp ); jmp( pat.FailTo.jmpAdrs ); endif; #keyword getPos( _m_getPos_dest_ ); #if( _m_only1Fail_ ) #error( "getPos may not appear in the if_failure section" ) #endif mov( esi, eax ); sub( pat.StrStart, eax ); mov( eax, _m_getPos_dest_ ); #keyword fail( _p_Fail_accept_zero_parameters_[] ); #if( @elements( _p_Fail_accept_zero_parameters_ ) <> 0 ) #error( "Fail does not accept any parameters" ); #endif mov( pat.FailTo.ebpSave, ebp ); jmp( pat.FailTo.jmpAdrs ); #keyword fence( _p_Fence_accept_zero_parameters_[] ); #if( _m_only1Fail_ ) #error( "'fence' may not appear in the if_failure section" ) #endif #if( @elements( _p_Fence_accept_zero_parameters_ ) <> 0 ) #error( "Fence does not accept any parameters" ); #endif mov( pat.CleanESP, esp ); mov( ebp, pat.FailTo.ebpSave ); mov( &@text( _m_failAdrs_ ), pat.FailTo.jmpAdrs ); #keyword alternate; jmp _m_successAdrs_; @text( _m_failAdrs_ ): ?_m_failAdrs_ := hla.genLabel; mov( pat.CleanESP, esp ); mov( pat.StrStart, esi ); mov( &@text( _m_failAdrs_ ), pat.FailTo.jmpAdrs ); #keyword if_failure; // The success code falls through to this point. // Skip over the failure code. jmp _m_successAdrs_; #if( _m_only1Fail_ ) #error( "Extra 'if_failure' section encountered" ) #endif ?_m_only1Fail_ := true; @text( _m_failAdrs_ ): mov( pat.CleanESP, esp ); pop( pat.StrStart ); pop( pat.FailTo.jmpAdrs ); pop( pat.FailTo.ebpSave ); pop( pat.CleanESP ); #terminator endmatch:_em_endofmatch_; // "if_failure" has already cleaned up the stack. Don't // do that twice. Since "if_failure" falls through to this // point, just jump over the clean up code. jmp _em_endofmatch_; #if( !_m_only1Fail_ ) #error( "Must have a 'if_failure' section" ) #endif _m_successAdrs_: mov( pat.CleanESP, esp ); mov( pat.StrStart, ebx ); pop( pat.StrStart ); pop( pat.FailTo.jmpAdrs ); pop( pat.FailTo.ebpSave ); pop( pat.CleanESP ); _em_endofmatch_: // The following forces a semicolon after // the endmatch invocation. static ; endstatic; #endmacro //////////////////////////////////////////////////////////////////////////// // // Accessor routines for the WordDelims and WhiteSpace character sets: procedure getWordDelims( var cst:cset ); @external( "pat_getWordDelims" ); procedure setWordDelims( cst:cset); @external( "pat_setWordDelims" ); procedure getWhiteSpace( var cst:cset ); @external( "pat_getWhiteSpace" ); procedure setWhiteSpace( cst:cset); @external( "pat_setWhiteSpace" ); // Pattern matching procedures: procedure peekCset( cst:cset ); @external( "pat_PeekCset" ); procedure oneCset( cst:cset ); @external( "pat_OneCset" ); procedure upToCset( cst:cset ); @external( "pat_UptoCset" ); procedure zeroOrOneCset( cst:cset ); @external( "pat_ZeroOrOneCset" ); procedure l_ZeroOrOneCset( cst:cset ); @external( "pat_lZeroOrOneCset" ); procedure zeroOrMoreCset( cst:cset ); @external( "pat_ZeroOrMoreCset" ); procedure l_ZeroOrMoreCset( cst:cset ); @external( "pat_lZeroOrMoreCset" ); procedure oneOrMoreCset( cst:cset ); @external( "pat_OneOrMoreCset" ); procedure l_OneOrMoreCset( cst:cset ); @external( "pat_lOneOrMoreCset" ); procedure exactlyNCset( cst:cset; n:uns32 ); @external( "pat_ExactlyNCset" ); procedure firstNCset( cst:cset; n:uns32 ); @external( "pat_FirstNCset" ); procedure norLessCset( cst:cset; n:uns32 ); @external( "pat_NorLessCset" ); procedure l_NorLessCset( cst:cset; n:uns32 ); @external( "pat_lNorLessCset" ); procedure norMoreCset( cst:cset; n:uns32 ); @external( "pat_NorMoreCset" ); procedure l_NorMoreCset( cst:cset; n:uns32 ); @external( "pat_lNorMoreCset" ); procedure ntoMCset( cst:cset; n:uns32; m:uns32 ); @external( "pat_NtoMCset" ); procedure l_NtoMCset( cst:cset; n:uns32; m:uns32 ); @external( "pat_lNtoMCset" ); procedure exactlyNtoMCset( cst:cset; n:uns32; m:uns32 ); @external( "pat_ExactlyNtoMCset" ); procedure l_ExactlyNtoMCset( cst:cset; n:uns32; m:uns32 ); @external( "pat_lExactlyNtoMCset" ); // Character matching routines. procedure peekChar( c:char ); @external( "pat_PeekChar" ); procedure oneChar( c:char ); @external( "pat_OneChar" ); procedure upToChar( c:char ); @external( "pat_UptoChar" ); procedure zeroOrOneChar( c:char ); @external( "pat_ZeroOrOneChar" ); procedure l_ZeroOrOneChar( c:char ); @external( "pat_lZeroOrOneChar" ); procedure zeroOrMoreChar( c:char ); @external( "pat_ZeroOrMoreChar" ); procedure l_ZeroOrMoreChar( c:char ); @external( "pat_LZeroOrMoreChar" ); procedure oneOrMoreChar( c:char ); @external( "pat_OneOrMoreChar" ); procedure l_OneOrMoreChar( c:char ); @external( "pat_lOneOrMoreChar" ); procedure exactlyNChar( c:char; n:uns32 ); @external( "pat_ExactlyNChar" ); procedure firstNChar( c:char; n:uns32 ); @external( "pat_FirstNChar" ); procedure norLessChar( c:char; n:uns32 ); @external( "pat_NorLessChar" ); procedure l_NorLessChar( c:char; n:uns32 ); @external( "pat_lNorLessChar" ); procedure norMoreChar( c:char; n:uns32 ); @external( "pat_NorMoreChar" ); procedure l_NorMoreChar( c:char; n:uns32 ); @external( "pat_lNorMoreChar" ); procedure ntoMChar( c:char; n:uns32; m:uns32 ); @external( "pat_NtoMChar" ); procedure l_NtoMChar( c:char; n:uns32; m:uns32 ); @external( "pat_lNtoMChar" ); procedure exactlyNtoMChar( c:char; n:uns32; m:uns32 ); @external( "pat_ExactlyNtoMChar" ); procedure l_ExactlyNtoMChar( c:char; n:uns32; m:uns32 ); @external( "pat_lExactlyNtoMChar" ); // Case insensitive Character matching routines. procedure peekiChar( c:char ); @external( "pat_PeekiChar" ); procedure oneiChar( c:char ); @external( "pat_OneiChar" ); procedure upToiChar( c:char ); @external( "pat_UptoiChar" ); procedure zeroOrOneiChar( c:char ); @external( "pat_ZeroOrOneiChar" ); procedure l_ZeroOrOneiChar( c:char ); @external( "pat_lZeroOrOneiChar" ); procedure zeroOrMoreiChar( c:char ); @external( "pat_ZeroOrMoreiChar" ); procedure l_ZeroOrMoreiChar( c:char ); @external( "pat_lZeroOrMoreiChar" ); procedure oneOrMoreiChar( c:char ); @external( "pat_OneOrMoreiChar" ); procedure l_OneOrMoreiChar( c:char ); @external( "pat_lOneOrMoreiChar" ); procedure exactlyNiChar( c:char; n:uns32 ); @external( "pat_ExactlyNiChar" ); procedure firstNiChar( c:char; n:uns32 ); @external( "pat_FirstNiChar" ); procedure norLessiChar( c:char; n:uns32 ); @external( "pat_NorLessiChar" ); procedure l_NorLessiChar( c:char; n:uns32 ); @external( "pat_lNorLessiChar" ); procedure norMoreiChar( c:char; n:uns32 ); @external( "pat_NorMoreiChar" ); procedure l_NorMoreiChar( c:char; n:uns32 ); @external( "pat_lNorMoreiChar" ); procedure ntoMiChar( c:char; n:uns32; m:uns32 ); @external( "pat_NtoMiChar" ); procedure l_NtoMiChar( c:char; n:uns32; m:uns32 ); @external( "pat_lNtoMiChar" ); procedure exactlyNtoMiChar( c:char; n:uns32; m:uns32 ); @external( "pat_ExactlyNtoMiChar" ); procedure l_ExactlyNtoMiChar( c:char; n:uns32; m:uns32 ); @external( "pat_lExactlyNtoMiChar" ); // String matching procedures: procedure matchStr( s:string ); @external( "pat_matchStr" ); procedure matchToStr( s:string ); @external( "pat_matchtoStr" ); procedure upToStr( s:string ); @external( "pat_uptoStr" ); procedure matchiStr( s:string ); @external( "pat_matchiStr" ); procedure matchToiStr( s:string ); @external( "pat_matchtoiStr" ); procedure upToiStr( s:string ); @external( "pat_uptoiStr" ); procedure matchWord( s:string ); @external( "pat_matchWord" ); procedure matchiWord( s:string ); @external( "pat_matchiWord" ); // String extraction procedures. procedure extract( s:string ); @external( "pat_extract" ); procedure a_extract( var s:string ); @external( "pat_aextract" ); // Whitespace and end of string matching procedures: procedure zeroOrMoreWS; @external( "pat_zeroOrMoreWS" ); procedure oneOrMoreWS; @external( "pat_oneOrMoreWS" ); procedure WSorEOS; @external( "pat_WSorEOS" ); procedure WSthenEOS; @external( "pat_WSthenEOS" ); procedure peekWS; @external( "pat_peekWS" ); procedure peekWSorEOS; @external( "pat_peekWSorEOS" ); // Match an arbitrary sequence of chars: procedure arb; @external( "pat_arb" ); procedure l_arb; @external( "pat_larb" );end pat;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -