📄 lists.hhf
字号:
#if( ! @defined( lists_hhf ))?lists_hhf := 1;#includeOnce( "hla.hhf" )const nodePtr :text := "nodePtr_t"; // Deprecated type node :text := "node_t"; // Deprecated type list :text := "list_t"; // Deprecated type virtualList :text := "virtualList_t"; // Deprecated type type nodePtr_t :pointer to node_t; node_t: class var Prev: pointer to node_t; Next: pointer to node_t; procedure create; @returns( "esi" ); @external; // Whoever derives a class from node must // supply the "destroy" method. This function // must free any storage associated with a given // node. method destroy; @abstract; // Whoever derives a class from node must // supply the "cmpNodes" method. This must // compare the current node against the // node passed as a parameter and return // the flags just as an unsigned CMP instruction // would set them. // // Note: cmpNodes must not modify any register // values or any field values other than // the flags. method cmpNodes( n:nodePtr_t ); @abstract; endclass; namespace _hla; // make_listClass - // // This macro is used to create a base list class. // The first parameter is the name of the class to create. // The second parameter is a string listing the 'function' // names that you want converted to a class method (if not // present, it will be a class procedure). #macro make_listClass( className, methods ); className: class var Head: nodePtr_t; Tail: nodePtr_t; Cnt: uns32; // Make sure this class is an even multiple // of four bytes long. This must be the // last field in this data structure. // Note: Doesn't align work in classes now? (3/06/2001) #if( @CurOffset mod 4 <> 0 ) Padding: byte[ 4 - (@CurOffset mod 4) ]; #endif procedure create; @returns( "esi" ); @external( @uppercase( @string( className ), 0 ) + "_CREATE" ); _hla.function( destroy ); @external( "LIST_DESTROY" ); _hla.function( numNodes ); @returns("eax" ); @external( "LIST_NUMNODES" ); /*****************/ _hla.function( appendIndex ) ( var n: node_t; posn: dword ); @returns( "esi" ); @external( "LIST_APPENDINDEX" ); _hla.function( appendNode ) ( var n: node_t; var after: node_t ); @returns( "esi" ); @external( "LIST_APPENDNODE" ); _hla.function( appendLast ) ( var n:node_t ); @returns( "esi" ); @external( "LIST_APPENDLAST" ); // append- // // This macro provide simulated "procedure overloading" // for the previous three procedures. // // If there is only one parameter present, this macro // calls the list.append_last method. // // If there are two parameters present, this macro // checks the type of the second parameter. If that // parameter is a pointer or a class object, then // this macro calls the list.append_node method, otherwise // it calls the list.append_index method (and assumes that // the second parameter is an integer constant). #macro append( args[] ): funcName; // Save the name of the class object (this gets wiped // out quickly, so we need to save it now). ?funcName:string := @curObject; // If there is only one parameter, call the // list.append_last method. #if( @elements( args ) = 1 ) @text( funcName + ".appendLast" )( @text( args[0] )) // If there are two parameters, check the type of // the second parameter and call list.append_node // if it's a class object (or pointer), otherwise // call the list.append_index method. #elseif ( @elements( args ) = 2 & ( @pType( @text( args[1] )) = hla.ptClass | @pType( @text( args[1] )) = hla.ptPointer ) ) @text( funcName + ".appendNode" ) ( @text( args[0] ), @text( args[1] ) ) #elseif( @elements( args ) = 2 ) @text( funcName + ".appendIndex" ) ( @text( args[0] ), @text( args[1] ) ) // If it's none of the above, emit an error message. #else #error( "Illegal call to list.append" ) #endif #endmacro /*****************/ _hla.function( insertIndex ) ( var n: node_t; posn: dword ); @returns( "esi" ); @external( "LIST_INSERTINDEX" ); _hla.function( insertNode ) ( var n: node_t; var before: node_t ); @returns( "esi" ); @external( "LIST_INSERTNODE" ); _hla.function( insertFirst ) ( var n:node_t ); @returns( "esi" ); @external( "LIST_INSERTFIRST" ); // insert- // // This macro provide simulated "procedure overloading" // for the previous three procedures. // // If there is only one parameter present, this macro // calls the list.insert_first method. // // If there are two parameters present, this macro // checks the type of the second parameter. If that // parameter is a pointer or a class object, then // this macro calls the list.insert_node method, otherwise // it calls the list.insert_index method (and assumes that // the second parameter is an integer constant). #macro insert( args[] ): funcName; // Save the name of the class object (this gets wiped // out quickly, so we need to save it now). ?funcName:string := @curObject; // If there is only one parameter, call the // list.insert_first method. #if( @elements( args ) = 1 ) @text( funcName + ".insertFirst" )( @text( args[0] )) // If there are two parameters, check the type of // the second parameter and call list.insert_node // if it's a class object (or pointer), otherwise // call the list.insert_index method. #elseif ( @elements( args ) = 2 & ( @pType( @text( args[1] )) = hla.ptClass | @pType( @text( args[1] )) = hla.ptPointer ) ) @text( funcName + ".insertNode" ) ( @text( args[0] ), @text( args[1] ) ) #elseif( @elements( args ) = 2 ) @text( funcName + ".insertIndex" ) ( @text( args[0] ), @text( args[1] ) ) // If it's none of the above, emit an error message. #else #error( "Illegal call to list.insert" ) #endif #endmacro /*****************/ _hla.function( deleteIndex )( posn:dword ); @returns( "esi" ); @external( "LIST_DELETEINDEX" ); _hla.function( deleteNode )( var n:node_t ); @returns( "esi" ); @external( "LIST_DELETENODE" ); _hla.function( deleteFirst ); @returns( "esi" ); @external( "LIST_DELETEFIRST" ); _hla.function( deleteLast ); @returns( "esi" ); @external( "LIST_DELETELAST" ); // delete- // // This macro provide simulated "procedure overloading" // for delete_index, delete_node, and delete_first. // // If this macro has no parameters, it calls the // list.delete_first method. // // If there is one parameter present, this macro // checks the type of that parameter. If it is a // pointer or a class object, then this macro calls // the list.delete_node method, otherwise // it calls the list.delete_index method. #macro delete( args[] ): funcName; // Save the name of the class object (this gets wiped // out quickly, so we need to save it now). ?funcName:string := @curObject; // If there is only one parameter, call the // list.insert_first method. #if( @elements( args ) = 0 ) @text( funcName + ".deleteFirst" )() // If there are two parameters, check the type of // the second parameter and call list.insert_node // if it's a class object (or pointer), otherwise // call the list.insert_index method. #elseif ( @elements( args ) = 1 & ( @pType( @text( args[0] )) = hla.ptClass | @pType( @text( args[0] )) = hla.ptPointer ) ) @text( funcName + ".deleteNode" ) ( @text( args[0] ) ) #elseif( @elements( args ) = 1 ) @text( funcName + ".deleteIndex" ) ( @text( args[0] ) ) // If it's none of the above, emit an error message. #else #error( "Illegal call to list.delete" ) #endif #endmacro /*****************/ _hla.function( xchgNodes )( n1:nodePtr_t; n2:nodePtr_t ); @external( "LIST_XCHGNODES" ); _hla.function( index )( posn:dword ); @external( "LIST_INDEX" ); _hla.function( sort ); @external( "LIST_SORT" ); _hla.function( reverse ); @external( "LIST_REVERSE" ); _hla.function( search )( cmpthunk:thunk ); @external( "LIST_SEARCH" ); iterator nodeInList; @external( "LIST_NODEINLIST" ); iterator nodeInListReversed; @external( "LIST_NODEINLISTREVERSED" ); iterator filteredNodeInList( t:thunk ); @external( "LIST_FILTEREDNODEINLIST" ); iterator filteredNodeInListReversed( t:thunk ); @external( "LIST_FILTEREDNODEINLISTREVERSED" ); endclass; #endmacro end _hla; type // Create the standard list class with all // functions being procedures: _hla.make_listClass( list_t, " " ); // Create a listClass with all the functions // being methods: _hla.make_listClass ( virtualList_t, "destroy" "numNodes" "appendIndex" "appendNode" "appendLast" "insertIndex" "insertNode" "insertFirst" "deleteIndex" "deleteNode" "deleteFirst" "deleteFast" "index" ); #endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -