📄 arrays.hhf
字号:
#if( ! @defined( arrays_hhf ))?arrays_hhf := true;#includeOnce( "hla.hhf" )#includeOnce( "excepts.hhf" )namespace array;val boundsChk:boolean := @global:true;/*************************************************************************/ // Macro that returns true if its parameter is a // dynamic array variable. #macro isItDynamic( _SuspectName_ ); ( ( @class( _SuspectName_ ) = hla.cVar | @class( _SuspectName_ ) = hla.cStatic | @class( _SuspectName_ ) = hla.cParm ) & @defined( _SuspectName_.elementType ) & @defined( _SuspectName_.dataPtr ) & @defined( _SuspectName_.dopeVector ) ) #endmacro // Macro that returns true if its parameter is a variable #macro isItVar( _PossibleVarName_ ); ( @class( _PossibleVarName_ ) = hla.cVar | @class( _PossibleVarName_ ) = hla.cStatic | @class( _PossibleVarName_ ) = hla.cParm ) #endmacro /*************************************************************************/ // Dynamic array declaration // // e.g., // // static // // aDynArray: dArray( int32, 3 ); #macro dArray( _theType_, _NumDimensions_ ); #if( !@IsConst( _NumDimensions_ )) #error( "Number of dimensions must be a constant" ) #endif #if( @class( _theType_ ) <> hla.cType ) #error( "First parameter must be a data type" ) // Provide a fake type for the data declaration: uns32 #else record dataPtr: dword; dopeVector: uns32[ _NumDimensions_ ]; // elementType is only used to determine // the size of an element in daAlloc. elementType: _theType_; endrecord #endif #endmacro/*************************************************************************///// The following iterators return each element of the array passed as// a parameter. iterator __returnEachArrayElement1( var theArray:byte; Elements:uns32 ); @external( "array_ReturnEachArrayElement1" ); iterator __returnEachArrayElement2( var theArray:word; Elements:uns32 ); @external( "array_ReturnEachArrayElement2" ); iterator __returnEachArrayElement4( var theArray:dword; Elements:uns32 ); @external( "array_ReturnEachArrayElement4" ); iterator __returnEachArrayElement8( var theArray:qword; Elements:uns32 ); @external( "array_ReturnEachArrayElement8" ); iterator __returnEachArrayElement16 ( var theArray :lword; Elements :uns32 ); @external( "array_ReturnEachArrayElement16" ); iterator __returnEachArrayElementR32 ( var theArray:real32; Elements:uns32 ); @external( "array_ReturnEachArrayElementR32" ); iterator __returnEachArrayElementR64 ( var theArray:real64; Elements:uns32 ); @external( "array_ReturnEachArrayElementR64" ); iterator __returnEachArrayElementR80 ( var theArray:real80; Elements:uns32 ); @external( "array_ReturnEachArrayElementR80" ); // Here is the macro that provides procedure overloading for // each of the above procedures: #macro element( _theArray_ ):_dimIndex_; #if( array.isItDynamic( _theArray_ )) #if( @Size( _theArray_.elementType ) = 1 ) array.__returnEachArrayElement1 ( #{ push( _theArray_.dataPtr ); }#, #{ push( eax ); push( eax ); mov( _theArray_.dopeVector[0], eax ); ?_dimIndex_ := 1; #while ( _dimIndex_ < @Elements( _theArray_.dopeVector ) ) intmul ( _theArray_.dopeVector[ _dimIndex_ * 4], eax ); ?_dimIndex_ := _dimIndex_ + 1; #endwhile mov( eax, [esp+4] ); pop( eax ); }# ) #elseif( @Size( _theArray_.elementType ) = 2 ) array.__returnEachArrayElement2 ( #{ push( _theArray_.dataPtr ); }#, #{ push( eax ); push( eax ); mov( _theArray_.dopeVector[0], eax ); ?_dimIndex_ := 1; #while ( _dimIndex_ < @Elements( _theArray_.dopeVector ) ) intmul ( _theArray_.dopeVector[ _dimIndex_ * 4], eax ); ?_dimIndex_ := _dimIndex_ + 1; #endwhile mov( eax, [esp+4] ); pop( eax ); }# ) #elseif( @TypeName( _theArray_.elementType ) = "real32" ) array.__returnEachArrayElementR32 ( #{ push( _theArray_.dataPtr ); }#, #{ push( eax ); push( eax ); mov( _theArray_.dopeVector[0], eax ); ?_dimIndex_ := 1; #while ( _dimIndex_ < @Elements( _theArray_.dopeVector ) ) intmul ( _theArray_.dopeVector[ _dimIndex_ * 4], eax ); ?_dimIndex_ := _dimIndex_ + 1; #endwhile mov( eax, [esp+4] ); pop( eax ); }# ) #elseif( @Size( _theArray_.elementType ) = 4 ) array.__returnEachArrayElement4 ( #{ push( _theArray_.dataPtr ); }#, #{ push( eax ); push( eax ); mov( _theArray_.dopeVector[0], eax ); ?_dimIndex_ := 1; #while ( _dimIndex_ < @Elements( _theArray_.dopeVector ) ) intmul ( _theArray_.dopeVector[ _dimIndex_ * 4], eax ); ?_dimIndex_ := _dimIndex_ + 1; #endwhile mov( eax, [esp+4] ); pop( eax ); }# ) #elseif( @TypeName( _theArray_.elementType ) = "real64" ) array.__returnEachArrayElementR64 ( #{ push( _theArray_.dataPtr ); }#, #{ push( eax ); push( eax ); mov( _theArray_.dopeVector[0], eax ); ?_dimIndex_ := 1; #while ( _dimIndex_ < @Elements( _theArray_.dopeVector ) ) intmul ( _theArray_.dopeVector[ _dimIndex_ * 4], eax ); ?_dimIndex_ := _dimIndex_ + 1; #endwhile mov( eax, [esp+4] ); pop( eax ); }# ) #elseif( @Size( _theArray_.elementType ) = 8 ) array.__returnEachArrayElement8 ( #{ push( _theArray_.dataPtr ); }#, #{ push( eax ); push( eax ); mov( _theArray_.dopeVector[0], eax ); ?_dimIndex_ := 1; #while ( _dimIndex_ < @Elements( _theArray_.dopeVector ) ) intmul ( _theArray_.dopeVector[ _dimIndex_ * 4], eax ); ?_dimIndex_ := _dimIndex_ + 1; #endwhile mov( eax, [esp+4] ); pop( eax ); }# ) #elseif( @TypeName( _theArray_.elementType ) = "real80" ) array.__returnEachArrayElementR80 ( #{ push( _theArray_.dataPtr ); }#, #{ push( eax ); push( eax ); mov( _theArray_.dopeVector[0], eax ); ?_dimIndex_ := 1; #while ( _dimIndex_ < @Elements( _theArray_.dopeVector ) ) intmul ( _theArray_.dopeVector[ _dimIndex_ * 4], eax ); ?_dimIndex_ := _dimIndex_ + 1; #endwhile mov( eax, [esp+4] ); pop( eax ); }# ) #elseif( @Size( _theArray_.elementType ) = 16 ) array.__returnEachArrayElement16 ( #{ push( _theArray_.dataPtr ); }#, #{ push( eax ); push( eax ); mov( _theArray_.dopeVector[0], eax ); ?_dimIndex_ := 1; #while ( _dimIndex_ < @Elements( _theArray_.dopeVector ) ) intmul ( _theArray_.dopeVector[ _dimIndex_ * 4], eax ); ?_dimIndex_ := _dimIndex_ + 1; #endwhile mov( eax, [esp+4] ); pop( eax ); }# ) #else yyerror( "array.elements does not support this type" ); #endif #else // It's a static array. #if( @ElementSize( _theArray_ ) = 1 ) array.__returnEachArrayElement1 ( _theArray_, @Elements( _theArray_ ) ) #elseif( @ElementSize( _theArray_ ) = 2 ) array.__returnEachArrayElement2 ( _theArray_, @Elements( _theArray_ ) ) #elseif( @TypeName( _theArray_ ) = "real32" ) array.__returnEachArrayElementR32 ( _theArray_, @Elements( _theArray_ ) ) #elseif( @ElementSize( _theArray_ ) = 4 ) array.__returnEachArrayElement4 ( _theArray_, @Elements( _theArray_ ) ) #elseif( @TypeName( _theArray_ ) = "real64" ) array.__returnEachArrayElementR64 ( _theArray_, @Elements( _theArray_ ) ) #elseif( @ElementSize( _theArray_ ) = 8 ) array.__returnEachArrayElement8 ( _theArray_, @Elements( _theArray_ ) ) #elseif( @TypeName( _theArray_ ) = "real80" ) array.__returnEachArrayElementR80 ( _theArray_, @Elements( _theArray_ ) ) #elseif( @ElementSize( _theArray_ ) = 16 ) array.__returnEachArrayElement16 ( _theArray_, @Elements( _theArray_ ) ) #else yyerror( "array.elements does not support this type" ); #endif #endif #endmacro/*************************************************************************/ // daAlloc- // // Allocates storage for a dynamic array at run-time given // a list of array bounds. // // syntax: // // daAlloc( daArrayName, <<list of dimension bounds>> ); // // Notes: // // daArrayName must have been declared using "dArray" type. // // The number of comma separated dimension bounds must // match the number of dimensions specified in the dArray // declaration. // // Example: // // daAlloc( MyDA, 3, i, j ); // // This example assumes the variable declaration: MyDA:dArray( uns32, 3 ); // The "i" and "j" IDs in this example can be run-time variables. #macro daAlloc( _theDA_, _dimensions_[] ): _i_, _valid_, _size_, _curDim_, _hadVar_; #if( !array.isItDynamic( _theDA_ )) #error( "Expected a dynamic array variable" ) #elseif( @elements( _dimensions_ ) = 0 ) #error( "Must specify at least one dimension" ) #elseif( @elements( _dimensions_ ) <> @elements( _theDA_.dopeVector )) #error ( "Number of actual dimension bounds does not " nl "match number of declared dimensions" " (actual = " + string( @elements( _dimensions_ )) + " declared = " + string( @elements( _theDA_.dopeVector )) + ")" ) #else push( eax ); ?_i_ := 0; ?_valid_ := true; ?_hadVar_ := false; ?_size_ := 1; #while( _i_ < @elements( _dimensions_ )) ?_curDim_:text := _dimensions_[_i_]; #if( @IsConst( _curDim_ ) ) ?_valid_ := _valid_ & hla.isNumber( _curDim_ ); #elseif( array.isItVar( _curDim_ )) ?_valid_ := _valid_ & hla.isNumber( _curDim_ ); #else ?_valid_ := false; #endif #if( _valid_ ) #if( @IsConst( _curDim_ ) ) ?_size_ := _size_ * _curDim_; mov( _curDim_, _theDA_.dopeVector[ _i_*4 ] ); #else push( edx ); #if( !_hadVar_ ) mov( _curDim_, eax ); #else intmul( _curDim_, eax ); #endif #if ( @size( _curDim_ ) = 1 | @size( _curDim_ ) = 2 ) movzx( _curDim_, edx ); #elseif( @size( _curDim_ ) = 4 ) mov( _curDim_, edx ); #else #error( "Dimension object must be an integer" ); #endif mov( edx, _theDA_.dopeVector[ _i_*4 ]); ?_hadVar_ := true; pop( edx ); #endif #endif ?_i_ := _i_ + 1; ?@tostring:_curDim_ := 0; // Deallocate string. #endwhile #if( _valid_ ) #if( _size_ != 1 ) #if( _hadVar_ ) intmul( _size_, eax ); #else mov( _size_, eax ); #endif #endif #if( @size( _theDA_.elementType ) = 1 ) // do nothing #elseif( @size( _theDA_.elementType ) = 2 ) shl( 1, eax ); #elseif( @size( _theDA_.elementType ) = 4 ) shl( 2, eax ); #elseif( @size( _theDA_.elementType ) = 8 ) shl( 3, eax ); #elseif( @size( _theDA_.elementType ) = 16 ) shl( 4, eax ); #else intmul( @size( _theDA_.elementType ), eax ); #endif malloc( eax ); mov( eax, _theDA_.dataPtr ); #else #error( "Invalid dynamic array dimension list" ); #endif pop( eax ); #endif #endmacro/*************************************************************************/ // daFree: // // Frees a dynamic array allocated via daAlloc. #macro daFree( _theDA_ ); #if( !array.isItDynamic( _theDA_ )) #error( "Expected a dynamic array variable" ) #else if( _theDA_.dataPtr != 0 ) then free( _theDA_.dataPtr ); mov( 0, _theDA_.dataPtr ); else raise( ex.AttemptToDerefNULL ); endif; #endif #endmacro /*************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -