// shell.hla // // 2012-07-31 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program shell;
#include( "stdlib.hhf" )
begin shell;
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end shell;
// more.hla // // 2012-09-03 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program more_demo;
#include( "stdlib.hhf" )
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
static
count: int32 := 0;
sum: int32 := 0;
avg: real32;
tmpStr: str.strvar( 32 );
begin more_demo;
repeat
try
stdout.puts( "Enter next integer to sum: " );
stdin.geti32();
stdin.flushInput();
add( eax, sum );
inc( count );
exception( ex.ConversionError )
stdout.puts( "Invalid input! Integers only please ..." nl );
exception( ex.ValueOutOfRange )
stdout.puts( "Invalid input! Value out of range ... " nl );
endtry;
until( !more() );
// The FINIT instruction initializes the FPU for proper operation.
// Your applications should execute this instruction before
// executing any other FPU instructions.
finit(); // initialize floating point (math) unit
// The FILD (integer load) instruction converts a 16, 32, or 64 bit two's
// complement integer to the 80 bit extended precision format and pushes the
// result onto the stack. This instruction always expects a single operand. This
// operand must be the address of a word, double word, or quad word integer
// variable.
fild( sum ); // float integer load
fild( count );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find totScores / totOutOf and leave result on top of FPU stack (in st0)
// The FSTP instruction POPS and copies the value on the top of the floating
// point register stack to another floating point register or to a 32, 64, or 80 bit
// memory variable. When copying data to a 32 or 64 bit memory variable, the
// 80 bit extended precision value on the top of stack is rounded to the smaller
// format as specified by the rounding control bits in the FPU control register.
fstp( avg ); // POP and store sto, the top of the FPU stack, into average
stdout.put
(
"The average of ", count, " numbers with sum ", sum, " is "
);
str.put( tmpStr, avg:20:2 );
str.delLeadingSpaces( tmpStr ); // to trim off any leading spaces ...
stdout.puts( tmpStr );
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end more_demo;
// getValidInt.hla // // 2012-09-03 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program getValidInt_demo;
#include( "stdlib.hhf" )
procedure getValidInt( prompt: string ); @nodisplay; @returns( "eax" );
begin getValidInt;
forever
try
stdout.puts( prompt );
stdin.geti32(); // returns 32 bit integer in eax
stdin.flushInput();
unprotected
break;
exception( ex.ConversionError )
stdout.puts( "Invalid input! Integers only please ..." nl );
stdin.flushInput();
exception( ex.ValueOutOfRange )
stdout.puts( "Invalid input! Value out of range ... " nl );
stdin.flushInput();
endtry;
endfor;
end getValidInt;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
static
count: int32 := 0;
sum: int32 := 0;
avg: real32;
tmpStr: str.strvar( 32 );
begin getValidInt_demo;
repeat
// note: need to preserve/restore any reg's used when using
// try..endtry as in getValidInt below ...
getValidInt( "Enter next value to sum: " ); // returns int32 in eax
add( eax, sum );
inc( count );
until( !more() );
finit(); // initialize floating point (math) unit
fild( sum ); // float integer load
fild( count );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find sum / count and ...
// leave result on top of FPU stack (in st0)
fstp( avg ); // POP and store sto, the top of the FPU stack, into avg
stdout.put
(
"The average of ", count, " numbers with sum ", sum, " is "
);
conv.r32ToStr( avg, 20, 2, ' ', tmpStr );
str.delLeadingSpaces( tmpStr );
stdout.puts( tmpStr );
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end getValidInt_demo;
// arrayInt.hla // // 2011-09-03 //
// enters integer data, finds sum, average, sorts, finds value, erase, shows
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program aryInt_demo;
#include( "stdlib.hhf" )
const
MAX_SIZE: uns32 := 4; // use small size here for simple testing purposes
type
//Aryi32: int32[MAX_SIZE];
pInt32: pointer to int32;
static
last: int32;
myAry: int32[MAX_SIZE]; // Aryi32;
pMyAry: pInt32 := &myAry;
count: uns32;
sum: int32 := 0;
avg: real32;
tmpStr: str.strvar( 32 );
procedure getValidInt( prompt: string ); @nodisplay; @returns( "eax" );
begin getValidInt;
forever
try
stdout.puts( prompt );
stdin.geti32(); // returns 32 bit integer in eax
stdin.flushInput();
unprotected
break;
exception( ex.ConversionError )
stdout.puts( "Invalid input! Integers only please ..." nl );
stdin.flushInput();
exception( ex.ValueOutOfRange )
stdout.puts( "Invalid input! Value out of range ... " nl );
stdin.flushInput();
endtry;
endfor;
end getValidInt;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
procedure sumAry( pAry: pInt32; size:uns32 ); @nodisplay; @returns( "eax" );
begin sumAry;
push( ebx ); push( ecx );
mov( 0, eax );
mov( pMyAry, ebx );
mov( size, ecx );
for( dec(ecx) ; (type int32 ecx) >= 0; dec( ecx ) ) do
add( (type int32 [ebx + ecx*4]), eax );
endfor;
pop( ecx ); pop( ebx );
end sumAry;
procedure showAry( pAry: pInt32; size:uns32 ); @nodisplay;
begin showAry;
push( ebx ); push( ecx );
mov( pAry, ebx );
for( mov( 0, ecx ); ecx < size; inc( ecx ) ) do
stdout.put( (type int32 [ebx + ecx*4]), " " );
endfor;
pop( ecx ); pop( ebx );
end showAry;
procedure isortAry( pAry: pInt32; size:uns32 ); @nodisplay;
begin isortAry;
push( eax ); push( ebx ); push( ecx ); push( edx ); push( esi );
// int i, j, cmp;
mov( pAry, ebx );
// start with an array of just the first 2 elements (if exists)
for( mov( 1, ecx ); ecx < size; inc( ecx ) ) do
// get copy of this new cmp element on each outer loop
mov( [ebx+ecx*4], edx );
// get index of element just to the left of the above 'cmp'
// to start comparisons
mov( ecx, esi );
dec( esi );
while( (type int32 esi) >= 0 && (type int32 edx) < [ebx + esi*4] ) do
//ary[j+1] = ary[j]; // copy element 'up'
//--j; // decrement j in preparation for next inner loop
mov( [ebx + esi*4], eax );
inc( esi );
mov( eax, [ebx + esi*4] );
sub( 2, esi );
endwhile;
//insert element at index j+1 (since j was decremented above)
//ary[j+1] = cmp;
inc( esi );
mov( edx, [ebx+esi*4] );
endfor;
pop( esi ); pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end isortAry;
procedure findAry( pAry: pInt32; size:uns32; value: int32 );
@nodisplay; @returns( "eax" );
begin findAry;
push( ebx ); push( edx );
mov( value, edx );
mov( pAry, ebx );
for( mov( 0, eax ); eax < size; inc( eax ) ) do
if( (type int32 [ebx+eax*4]) == edx ) then break; endif;
endfor;
// check end condition ...
if( eax == size ) then mov( -1, eax ); endif;
pop( edx ); pop( ebx );
end findAry;
// if valid index erase element, return new size in eax ...
procedure eraseAry( pAry: pInt32; size:uns32; index: uns32 );
@nodisplay; @returns( "eax" );
begin eraseAry;
push( ebx ); push( edx );
mov( pAry, ebx );
mov( index, edx );
if( (type int32 edx) >= 0 && edx < size ) then
dec( size );
for( mov( index, eax ); eax < size; inc( eax ) ) do
// copy each element above, down one index, so erased
//ary[i] = ary[i+1];
inc( eax );
mov( (type int32 [ebx+eax*4]), edx );
dec( eax );
mov( edx, (type int32 [ebx+eax*4]) );
endfor;
else
dec( size );
stdout.put( nl "ERROR! Index ", index, " out of range 0..",
size, nl );
inc( size );
endif;
mov( size, eax ); // now update size and return (new - if updated) size...
pop( edx ); pop( ebx );
end eraseAry;
begin aryInt_demo;
mov( 0, ecx ); // using ecx as counter ...
repeat
// note: need to preserve/restore any reg's used when using
// try..endtry as in getValidInt below ...
push( ecx ); // preserve ecx
getValidInt( "Enter next value to sum: " ); // returns int32 in eax
pop( ecx ); // restore ecx
mov( eax, myAry[ecx*4] );
inc( ecx );
if( ecx == MAX_SIZE ) then
stdout.put( "You have reached ", MAX_SIZE, ", the max size.", nl );
break;
endif;
until( !more() );
mov( ecx, count ); // count now holds size of entered array ...
sumAry( pMyAry, count );
mov( eax, sum );
finit(); // initialize floating point (math) unit
fild( sum ); // float integer load
fild( count );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find totScores / totOutOf and ...
// leave result on top of FPU stack (in st0)
fstp( avg ); // POP and store sto, the top of the FPU stack, into avg
stdout.put
(
"The average of ", count, " numbers with sum ", sum, " is "
);
conv.r32ToStr( avg, 20, 2, ' ', tmpStr );
str.delLeadingSpaces( tmpStr ); // to trim off any leading spaces ...
stdout.puts( tmpStr );
stdout.puts( nl "showAry: " );
showAry( pMyAry, count );
//last = my_ary[ i-1 ];
dec( ecx );
mov( mov( myAry[ecx*4], eax ), last );
stdout.puts( nl "After isort..." nl );
isortAry( pMyAry, count );
stdout.puts( "showAry: " );
showAry( pMyAry, count );
findAry( pMyAry, count, last ); // index returned in eax ...
if( (type int32 eax) != -1 ) then // i.e. if found ...
eraseAry( pMyAry, count, eax ); // count holds size, eax holds index
mov( eax, count ); // update count ...
stdout.put( nl "After erasing ", last, "..." nl );
stdout.put( "showAry: " );
showAry( pMyAry, count );
else stdout.put( nl, last, " NOT found in myAry." nl );
endif;
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end aryInt_demo;
// dynamicAryInt.hla // // 2011-08-11 //
// enters integer data, finds sum, average, sorts, finds value, erase, shows
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program dynamicAryInt;
#include( "stdlib.hhf" )
type
pInt32: pointer to int32;
static
last: int32;
pMyAry: pInt32;
maxSize:uns32;
count: uns32;
sum: int32 := 0;
avg: real32;
tmpStr: str.strvar( 32 );
procedure getValidInt( prompt: string ); @nodisplay; @returns( "eax" );
begin getValidInt;
forever
try
stdout.puts( prompt );
stdin.geti32(); // returns 32 bit integer in eax
stdin.flushInput();
unprotected
break;
exception( ex.ConversionError )
stdout.puts( "Invalid input! Integers only please ..." nl );
stdin.flushInput();
exception( ex.ValueOutOfRange )
stdout.puts( "Invalid input! Value out of range ... " nl );
stdin.flushInput();
endtry;
endfor;
end getValidInt;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
procedure sumAry( pAry: pInt32; size:uns32 ); @nodisplay; @returns( "eax" );
begin sumAry;
push( ebx ); push( ecx );
mov( 0, eax );
mov( pMyAry, ebx );
mov( size, ecx );
for( dec(ecx) ; (type int32 ecx) >= 0; dec( ecx ) ) do
add( (type int32 [ebx + ecx*4]), eax );
endfor;
pop( ecx ); pop( ebx );
end sumAry;
procedure showAry( pAry: pInt32; size:uns32 ); @nodisplay;
begin showAry;
push( ebx ); push( ecx );
mov( pAry, ebx );
for( mov( 0, ecx ); ecx < size; inc( ecx ) ) do
stdout.put( (type int32 [ebx + ecx*4]), " " );
endfor;
pop( ecx ); pop( ebx );
end showAry;
procedure isortAry( pAry: pInt32; size:uns32 ); @nodisplay;
begin isortAry;
push( eax ); push( ebx ); push( ecx ); push( edx ); push( esi );
// int i, j, cmp;
mov( pAry, ebx );
// start with an array of just the first 2 elements (if exists)
for( mov( 1, ecx ); ecx < size; inc( ecx ) ) do
// get copy of this new cmp element on each outer loop
mov( [ebx+ecx*4], edx );
// get index of element just to the left of the above 'cmp'
// to start comparisons
mov( ecx, esi );
dec( esi );
while( (type int32 esi) >= 0 && (type int32 edx) < [ebx + esi*4] ) do
//ary[j+1] = ary[j]; // copy element 'up'
//--j; // decrement j in preparation for next inner loop
mov( [ebx + esi*4], eax );
inc( esi );
mov( eax, [ebx + esi*4] );
sub( 2, esi );
endwhile;
//insert element at index j+1 (since j was decremented above)
//ary[j+1] = cmp;
inc( esi );
mov( edx, [ebx+esi*4] );
endfor;
pop( esi ); pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end isortAry;
procedure findAry( pAry: pInt32; size:uns32; value: int32 );
@nodisplay; @returns( "eax" );
begin findAry;
push( ebx ); push( edx );
mov( value, edx );
mov( pAry, ebx );
for( mov( 0, eax ); eax < size; inc( eax ) ) do
if( (type int32 [ebx+eax*4]) == edx ) then break; endif;
endfor;
// check end condition ...
if( eax == size ) then mov( -1, eax ); endif;
pop( edx ); pop( ebx );
end findAry;
// if valid index erase element, return new size in eax ...
procedure eraseAry( pAry: pInt32; size:uns32; index: uns32 );
@nodisplay; @returns( "eax" );
begin eraseAry;
push( ebx ); push( edx );
mov( pAry, ebx );
mov( index, edx );
if( (type int32 edx) >= 0 && edx < size ) then
dec( size );
for( mov( index, eax ); eax < size; inc( eax ) ) do
// copy each element above, down one index, so erased
//ary[i] = ary[i+1];
inc( eax );
mov( (type int32 [ebx+eax*4]), edx );
dec( eax );
mov( edx, (type int32 [ebx+eax*4]) );
endfor;
else
dec( size );
stdout.put( nl "ERROR! Index ", index, " out of range 0..",
size, nl );
inc( size );
endif;
mov( size, eax ); // now update size and return (new - if updated) size...
pop( edx ); pop( ebx );
end eraseAry;
begin dynamicAryInt;
getValidInt( "Max number of int's to input: " );
mov( eax, maxSize );
intmul( @size(int32), eax );
mem.alloc( eax );
mov( eax, pMyAry );
mov( pMyAry, ebx );
mov( 0, ecx ); // using ecx as counter ...
repeat
// note: need to preserve/restore any reg's used when using
// try..endtry as in getValidInt below ...
push( ecx );
getValidInt( "Enter next value to sum: " ); // returns int32 in eax
pop( ecx );
mov( pMyAry, ebx ); // restores ebx
mov( eax, [ebx+ecx*4] );
inc( ecx );
if( ecx == maxSize ) then
stdout.put( "You have reached ", maxSize, ", the max size.", nl );
break;
endif;
until( !more() );
mov( ecx, count ); // count now holds size of entered array ...
sumAry( pMyAry, count );
mov( eax, sum );
finit(); // initialize floating point (math) unit
fild( sum ); // float integer load
fild( count );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find totScores / totOutOf and ...
// leave result on top of FPU stack (in st0)
fstp( avg ); // POP and store sto, the top of the FPU stack, into avg
stdout.put
(
"The average of ", count, " numbers with sum ", sum, " is "
);
conv.r32ToStr( avg, 20, 2, ' ', tmpStr );
str.delLeadingSpaces( tmpStr ); // to trim off any leading spaces ...
stdout.puts( tmpStr );
stdout.puts( nl "showAry: " );
showAry( pMyAry, count );
//last = my_ary[ i-1 ];
dec( ecx );
mov( pMyAry, ebx );
mov( mov( (type int32 [ebx+ecx*4]), eax ), last );
stdout.puts( nl "After isort..." nl );
isortAry( pMyAry, count );
stdout.puts( "showAry: " );
showAry( pMyAry, count );
findAry( pMyAry, count, last ); // index returned in eax ...
if( (type int32 eax) >= 0 ) then // i.e. if found ...
eraseAry( pMyAry, count, eax ); // count holds size, eax holds index
mov( eax, count ); // update count ...
stdout.put( nl "After erasing ", last, "..." nl );
stdout.put( "showAry: " );
showAry( pMyAry, count );
else stdout.put( nl, last, " NOT found in myAry." nl );
endif;
free( pMyAry );
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end dynamicAryInt;
program VecInt; // 2012-09-03 //
const
FNAME: text := """testInt.dat""";
InitCap: uns32 := 2; // keeping it small here to test out Vec realloc
type
Rec: record
rval: int32;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @nodisplay; @noframe;
begin freeRec;
// no dynamic memory to free here in each Rec
ret();
end freeRec;
// NOTE! The two types above and the procedure freeRec
// MUST be defined before this next include...
#includeOnce( "vector_func's.hhf" ) // includes vector.hhf that includes stdlib.hhf
// Note that vector.hhf also has: ? @nodisplay:= true;
// So ... all procedures have @nodisplay 'as default' from here on ...
// for isort descending ...
procedure myCmpInt( a: pRec in esi; b: pRec in edi ); @returns("eax");
begin myCmpInt;
mov( (type Rec [esi]).rval, eax );
if( eax > (type Rec [edi]).rval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure myCmpIntEQ( a: pRec in esi; b: pRec in edi ); @returns("eax");
begin myCmpIntEQ;
mov( (type Rec [esi]).rval, eax );
if( eax == (type Rec [edi]).rval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpIntEQ;
// for msort ascending ...
procedure myCmp( a: pRec in esi; b: pRec in edi ); @returns("eax");
begin myCmp;
mov( (type Rec [esi]).rval, eax );
if( eax <= (type Rec [edi]).rval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
procedure showRec( pr: pRec in eax ); @noframe;
begin showRec;
stdout.put( (type Rec [eax]).rval );
ret();
end showRec;
procedure showVec( var v: Vec );
begin showVec;
push( eax ); push( ebx ); push( ecx );
mov( v, ebx );
for( mov( 0, ecx ); ecx < (type Vec[ebx]).size; inc( ecx ) ) do
intmul( @size(Rec), ecx, eax );
add( (type Vec[ebx]).ary, eax );
showRec( eax );
stdout.putc( ' ' );
endfor;
stdout.newln();
pop( ecx ); pop( ebx ); pop( eax );
end showVec;
procedure sumVec( var v: Vec ); @returns( "eax" );
begin sumVec;
push( ebx ); push( ecx ); push( edx );
mov( 0, eax );
mov( v, ebx );
mov( (type Vec [ebx]).size, ecx );
for( dec(ecx) ; (type int32 ecx) >= 0; dec( ecx ) ) do
intmul( @size(Rec), ecx, edx );
add( (type Vec[ebx]).ary, edx );
add( (type Rec [edx]).rval, eax );
endfor;
pop( edx ); pop( ecx ); pop( ebx );
end sumVec;
static
fin: dword;
myRec: Rec;
myVec: Vec;
sum: int32;
avg: real32;
tmpStr: str.strvar( 32 );
begin VecInt;
fileio.open( FNAME, fileio.r );
mov( eax, fin );
initVec( myVec );
while( !fileio.eof( fin ) ) do
fileio.getu32( fin );
mov( eax, myRec.rval );
push_backVec( myVec, myRec );
endwhile;
fileio.close( fin );
stdout.puts( "showVec: " );
showVec( myVec );
sumVec( myVec );
mov( eax, sum );
finit(); // initialize floating point (math) unit
fild( sum ); // float integer load
fild( myVec.size );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find totScores / totOutOf and ...
// leave result on top of FPU stack (in st0)
fstp( avg ); // POP and store sto, the top of the FPU stack, into avg
stdout.put
(
nl "The average of ", myVec.size, " numbers with sum ", sum, " is "
);
conv.r32ToStr( avg, 20, 2, ' ', tmpStr );
str.delLeadingSpaces( tmpStr ); // to trim off any leading spaces ...
stdout.puts( tmpStr );
mov( myVec.size, ecx );
//last = my_ary[ i-1 ];
dec( ecx );
mov( &myVec, ebx );
intmul( @size(Rec), ecx, eax );
add( (type Vec [ebx]).ary, eax );
mov( mov( (type Rec [eax]).rval, eax ), myRec.rval );
stdout.puts( nl nl "After isort...(descending)" nl );
mov( &myCmpInt, pMyCmp );
isortVec( myVec );
stdout.puts( "showVec: " );
showVec( myVec );
mov( &myCmpIntEQ, pMyCmp );
findVec( myVec, myRec ); // index returned in eax ...
if( (type int32 eax) >= 0 ) then // i.e. if found ...
eraseVec( myVec, eax ); // count eax holds index
stdout.put( nl "After erasing ", myRec.rval, "..." nl );
stdout.put( "showVec: " );
showVec( myVec );
else stdout.put( nl, myRec.rval, " NOT found in myVec." nl );
endif;
stdout.puts( nl "After msort... (ascending)" nl );
mov( &myCmp, pMyCmp );
msortVec( myVec );
stdout.puts( "showVec: " );
showVec( myVec );
clearVec( myVec );
stdout.puts( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end VecInt;
program SLListInt; // 2012-09-03 //
const
FNAME: text := """testInt.dat""";
type
NNode: record
nval: int32;
next: pointer to NNode;
endrecord;
pNNode: pointer to NNode;
procedure freeNNode( pn: pNNode in eax ); @nodisplay; @noframe;
begin freeNNode;
// no dynamic memory to free here in each NNode
ret();
end freeNNode;
// NOTE! The two types above and the procedure freeNNode
// MUST be defined before this next include...
#includeOnce( "sllist_func's.hhf" ) // includes sllist.hhf that includes stdlib.hhf
// Note that sllist.hhf also has: ? @nodisplay:= true;
// So ... all procedures have @nodisplay 'as default' from here on ...
// for isort descending ...
procedure myCmpInt( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpInt;
mov( (type NNode [esi]).nval, eax );
if( eax >= (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure myCmpIntEQ( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpIntEQ;
mov( (type NNode [esi]).nval, eax );
if( eax == (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpIntEQ;
// for msort ascending ...
procedure myCmp( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmp;
mov( (type NNode [esi]).nval, eax );
if( eax <= (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
procedure showNNode( pn: pNNode in eax ); @noframe;
begin showNNode;
stdout.put( (type NNode [eax]).nval );
ret();
end showNNode;
procedure showSLList( var v: SLList );
begin showSLList;
push( eax );
mov( v, eax );
mov( (type SLList[eax]).head, eax );
while( eax ) do
showNNode( eax );
stdout.putc( ' ' );
mov( (type NNode[eax]).next, eax );
endwhile;
stdout.newln();
pop( eax );
end showSLList;
procedure sumSLList( var v: SLList ); @returns( "eax" );
begin sumSLList;
push( ecx );
mov( 0, eax );
mov( v, ecx );
mov( (type SLList[ecx]).head, ecx );
while( ecx ) do
add( (type NNode [ecx]).nval, eax );
mov( (type NNode[ecx]).next, ecx );
endwhile;
pop( ecx );
end sumSLList;
static
fin: dword;
myNNode: NNode;
mySLList: SLList;
sum: int32;
avg: real32;
tmpStr: str.strvar( 32 );
begin SLListInt;
fileio.open( FNAME, fileio.r );
mov( eax, fin );
initSLList( mySLList );
while( !fileio.eof( fin ) ) do
fileio.getu32( fin );
mov( eax, myNNode.nval );
push_backSLList( mySLList, myNNode );
endwhile;
fileio.close( fin );
stdout.puts( "showSLList: " );
showSLList( mySLList );
sumSLList( mySLList );
mov( eax, sum );
finit(); // initialize floating point (math) unit
fild( sum ); // float integer load
fild( mySLList.size );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find totScores / totOutOf and ...
// leave result on top of FPU stack (in st0)
fstp( avg ); // POP and store sto, the top of the FPU stack, into avg
stdout.put
(
nl "The average of ", mySLList.size, " numbers with sum ", sum, " is "
);
conv.r32ToStr( avg, 20, 2, ' ', tmpStr );
str.delLeadingSpaces( tmpStr ); // to trim off any leading spaces ...
stdout.puts( tmpStr );
mov( mySLList.tail, eax );
mov( mov( (type NNode [eax]).nval, eax ), myNNode.nval );
stdout.puts( nl nl "After isort...(descending)" nl );
mov( &myCmpInt, pMyCmp );
isortSLList( mySLList );
stdout.puts( "showSLList: " );
showSLList( mySLList );
mov( &myCmpIntEQ, pMyCmp );
findSLList( mySLList, myNNode ); // index returned in eax ...
if( eax ) then // i.e. if found ...
eraseSLList( mySLList, eax ); // count eax holds index
stdout.put( nl "After erasing ", myNNode.nval, "..." nl );
stdout.put( "showSLList: " );
showSLList( mySLList );
else stdout.put( nl, myNNode.nval, " NOT found in mySLList." nl );
endif;
stdout.puts( nl "After msort... (ascending)" nl );
mov( &myCmp, pMyCmp );
msortSLList( mySLList );
stdout.puts( "showSLList: " );
showSLList( mySLList );
stdout.put( "mySLList.size = ", mySLList.size, nl );
clearSLList( mySLList );
stdout.puts( nl "After clear..." nl );
stdout.puts( "showSLList: " );
showSLList( mySLList );
stdout.put( "mySLList.size = ", mySLList.size, nl );
stdout.puts( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end SLListInt;
program SLList2Int; // 2012-09-03 //
#includeOnce( "readWord.hhf" )
#includeOnce( "sllist2_func's.hhf" ) // includes sllist2.hhf that includes stdlib.hhf
// Note that sllist2.hhf also has: ? @nodisplay:= true;
// So ... all procedures have @nodisplay 'as default' from here on ...
const
FNAME: text := """testInt.dat""";
/*
type
NNode: record
nval: int32;
next: pointer to NNode;
endrecord;
pNNode: pointer to NNode;
*/
procedure myFreeNNode( pn: pNNode in eax ); @noframe;
begin myFreeNNode;
// no dynamic memory to free here in each NNode
ret();
end myFreeNNode;
// for isort/msort descending ...
procedure myCmpInt( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpInt;
mov( (type NNode [esi]).nval, eax );
if( (type int32 eax) >= (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure myCmpIntEQ( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpIntEQ;
mov( (type NNode [esi]).nval, eax );
if( eax == (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpIntEQ;
// for isort/msort ascending ...
procedure myCmp( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmp;
mov( (type NNode [esi]).nval, eax );
if( (type int32 eax) <= (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
procedure showNNode( pn: pNNode in eax ); @noframe;
begin showNNode;
stdout.put( (type int32 (type NNode [eax]).nval) );
ret();
end showNNode;
procedure showSLList( var v: SLList );
begin showSLList;
push( eax );
mov( v, eax );
mov( (type SLList[eax]).head, eax );
while( eax ) do
showNNode( eax );
stdout.putc( ' ' );
mov( (type NNode[eax]).next, eax );
endwhile;
stdout.newln();
pop( eax );
end showSLList;
procedure sumSLList( var v: SLList ); @returns( "eax" );
begin sumSLList;
push( ecx );
mov( 0, eax );
mov( v, ecx );
mov( (type SLList[ecx]).head, ecx );
while( ecx ) do
add( (type NNode [ecx]).nval, eax );
mov( (type NNode[ecx]).next, ecx );
endwhile;
pop( ecx );
end sumSLList;
static
fin: dword;
myNNode: NNode;
mySLList: SLList;
sum: int32;
avg: real32;
tmpStr: str.strvar( 32 );
tmpStr2: string;
begin SLList2Int;
fileio.open( FNAME, fileio.r );
mov( eax, fin );
initSLList( mySLList );
while( readWord( fin, tmpStr2, " " nl stdio.tab ) ) do
conv.strToi32( tmpStr2, 0 ); // begin at index 0 ..
mov( eax, myNNode.nval );
push_backSLList( mySLList, myNNode );
str.free( tmpStr2 );
endwhile;
fileio.close( fin );
stdout.puts( "showSLList: " );
showSLList( mySLList );
sumSLList( mySLList );
mov( eax, sum );
finit(); // initialize floating point (math) unit
fild( sum ); // float integer load
fild( mySLList.size );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find totScores / totOutOf and ...
// leave result on top of FPU stack (in st0)
fstp( avg ); // POP and store sto, the top of the FPU stack, into avg
stdout.put
(
nl "The average of ", mySLList.size, " numbers with sum ", sum, " is "
);
conv.r32ToStr( avg, 20, 2, ' ', tmpStr );
str.delLeadingSpaces( tmpStr ); // to trim off any leading spaces ...
stdout.puts( tmpStr );
mov( mySLList.tail, eax );
mov( mov( (type NNode [eax]).nval, eax ), myNNode.nval );
stdout.puts( nl nl "After isort...(descending)" nl );
mov( &myCmpInt, pMyCmp );
isortSLList( mySLList );
stdout.puts( "showSLList: " );
showSLList( mySLList );
mov( &myCmpIntEQ, pMyCmp );
findSLList( mySLList, myNNode ); // index returned in eax ...
if( eax ) then // i.e. if found ...
mov( &myFreeNNode, pFreeNNode );
eraseSLList( mySLList, eax ); // eax holds pointer
stdout.put( nl "After erasing ", (type int32 myNNode.nval), "..." nl );
stdout.put( "showSLList: " );
showSLList( mySLList );
else stdout.put( nl, myNNode.nval, " NOT found in mySLList." nl );
endif;
stdout.puts( nl "After msort... (ascending)" nl );
mov( &myCmp, pMyCmp );
msortSLList( mySLList );
stdout.puts( "showSLList: " );
showSLList( mySLList );
stdout.put( "mySLList.size = ", mySLList.size, nl );
mov( &myFreeNNode, pFreeNNode );
clearSLList( mySLList );
stdout.puts( nl "After clear..." nl );
stdout.puts( "showSLList: " );
showSLList( mySLList );
stdout.put( "mySLList.size = ", mySLList.size, nl );
stdout.puts( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end SLList2Int;
// test_split.hla // // 2012-08-16 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program test_split;
#includeOnce( "memory.hhf" ) // so can use str.free in freeNNode below
type
NNode: record
nval: string;
next: pointer to NNode;
endrecord;
pNNode: pointer to NNode;
? @nodisplay:= true; // All procedures have @nodisplay 'as default' now.
procedure freeNNode( pn: pNNode in eax ); @noframe;
begin freeNNode;
str.free( (type NNode [eax]).nval );
ret();
end freeNNode;
// NOTE! The two types above and the procedure freeNNode
// MUST be defined before this next include...
#includeOnce( "sllist.hhf" ) // also has #include( "stdlib.hhf" )
procedure showNNode( pn: pNNode in eax ); @noframe;
begin showNNode;
stdout.put( (type NNode [eax]).nval );
ret();
end showNNode;
procedure showSLList( var sll: SLList );
begin showSLList;
push( eax );
mov( sll, eax );
mov( (type SLList [eax]).head, eax );
while( eax != 0 ) do
stdout.putc( ''' );
showNNode( eax );
stdout.putc( ''' );
mov( (type NNode [eax]).next, eax );
stdout.newln();
endwhile;
pop( eax );
end showSLList;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.flushInput();
stdin.getc();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
procedure chrIsInStr( c: char in al; s: string ); @returns( "eax" );
begin chrIsInStr;
str.chpos( s, al );
inc( eax );
end chrIsInStr;
procedure splitSLList( var sll: SLList; s: string; delims: string );
var
myNNode: NNode;
reg32: dword;
i: uns32;
begin splitSLList;
push( eax ); push( ebx ); push( ecx ); push( edx );
mov( sll, ebx );
mov( s, ecx ); // ecx holds start address ...
forever
while( chrIsInStr( (type char [ecx]), delims ) ) do
inc( ecx );
endwhile;
breakif( (type char [ecx]) == 0 ); // since 'empty' string
mov( ecx, edx );
inc( edx ); // edx holds address one past end of 'word' ...
mov( (type char [edx]), al );
while( al && !chrIsInStr( al, delims ) ) do
inc( edx );
mov( (type char [edx]), al );
endwhile;
mov( edx, reg32 ); // save a copy of 'end' in reg32 ...
sub( ecx, edx ); // edx holds 'len of next word'
mov( ecx, i );
mov( s, eax );
sub( eax, i ); // i is index to start
str.a_substr( s, i, edx ); // start, len
mov( eax, myNNode.nval );
push_backSLList( (type SLList [ebx]), myNNode );
mov( reg32, ecx ); // update (next) start pointer ecx ...
endfor;
pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end splitSLList;
static
s: string;
c: char;
myLst: SLList;
begin test_split;
initSLList( myLst );
repeat
stdout.puts( "Enter next string to split: " );
stdin.a_gets();
mov( eax, s );
stdout.put( "You entered: ", s, nl );
splitSLList( myLst, s, " " stdio.tab ); // compiler concates
// space&tab into one string
str.free( s );
stdout.put( "Before clear... myLst.size = ", myLst.size, nl );
showSLList( myLst );
clearSLList( myLst );
stdout.put( "After clear... myLst.size = ", myLst.size, nl );
until( !more() );
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end test_split;
program SLListIntInsert; // 2012-09-03 //
// using NNode to avoid conflict with Node
// using SLList to avoid conflict with List
#includeOnce( "readWord.hhf" ) // to read in file of int's as 'word-strings'
const
FNAME: text := """testInt.dat""";
type
NNode: record
nval: int32;
next: pointer to NNode;
endrecord;
pNNode: pointer to NNode;
procedure freeNNode( pn: pNNode in eax ); @nodisplay; @noframe;
begin freeNNode;
// no dynamic memory to free here in each Rec
ret();
end freeNNode;
// NOTE! The two types above and the procedure freeRec
// MUST be defined before this next include...
#includeOnce( "sllist_func's.hhf" ) // includes sllist.hhf that includes stdlib.hhf
// Note that sllist.hhf has ? @nodisplay:= true;
// So ... all procedures have @nodisplay 'as default' from here on ...
// for msort/isort ascending ...
procedure myCmp( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmp;
mov( (type NNode [esi]).nval, eax );
if( eax <= (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
// for find...
procedure myCmpEQ( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpEQ;
mov( (type NNode [esi]).nval, eax );
if( eax == (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpEQ;
procedure showNNode( pn: pNNode in eax ); @noframe;
begin showNNode;
stdout.put( (type NNode [eax]).nval );
ret();
end showNNode;
procedure showSLList( var sll: SLList );
begin showSLList;
push( eax ); push( ebx );
mov( sll, ebx );
mov( (type SLList [ebx]).head, eax );
while( eax != 0 ) do
showNNode( eax );
stdout.putc( ' ' );
mov( (type NNode [eax]).next, eax );
endwhile;
pop( ebx ); pop( eax );
end showSLList;
procedure sumSLList( var sll: SLList ); @returns( "eax" );
begin sumSLList;
push( ebx ); push( ecx );
mov( sll, ebx );
mov( (type SLList [ebx]).head, ecx );
mov( 0, eax );
while( ecx != 0 ) do
add( (type NNode [ecx]).nval, eax );
mov( (type NNode [ecx]).next, ecx );
endwhile;
pop( ecx ); pop( ebx );
end sumSLList;
procedure getValidInt( prompt: string ); @nodisplay; @returns( "eax" );
begin getValidInt;
forever
try
stdout.puts( prompt );
stdin.geti32(); // returns 32 bit integer in eax
stdin.flushInput();
unprotected
break;
exception( ex.ConversionError )
stdout.puts( "Invalid input! Integers only please ..." nl );
stdin.flushInput();
exception( ex.ValueOutOfRange )
stdout.puts( "Invalid input! Value out of range ... " nl );
stdin.flushInput();
endtry;
endfor;
end getValidInt;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
static
fin: dword;
myNNode: NNode;
mySLList: SLList;
sum: int32;
avg: real32;
tmpStr: str.strvar( 32 );
tmp2Str: string;
Sorted: boolean := false;
begin SLListIntInsert;
fileio.open( FNAME, fileio.r );
mov( eax, fin );
initSLList( mySLList );
// NOTE: " " nl stdio.tab all get concatenated below at assemble time
while( readWord( fin, tmp2Str, " " nl stdio.tab ) ) do
conv.strToi32( tmp2Str, 0 ); // begin at index 0 ...
mov( eax, myNNode.nval );
push_frontSLList( mySLList, myNNode );
str.free( tmp2Str );
endwhile;
fileio.close( fin );
stdout.puts( "After push_front... from file, SLList of int is ... " nl );
showSLList( mySLList );
stdout.newln();
sumSLList( mySLList );
mov( eax, sum );
finit(); // initialize floating point (math) unit
fild( sum ); // float integer load
fild( mySLList.size );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find totScores / totOutOf and ...
// leave result on top of FPU stack (in st0)
fstp( avg ); // POP and store sto, the top of the FPU stack, into avg
stdout.put
(
"The average of ", mySLList.size, " numbers with sum ", sum, " is "
);
str.put( tmpStr, avg:20:2 );
str.delLeadingSpaces( tmpStr ); // to trim off any/all leading spaces
stdout.puts( tmpStr );
mov( &myCmp, pMyCmp );
msortSLList( mySLList );
mov( true, Sorted );
stdout.puts( nl "After msortSLList( mySLList ); "
"mySLList of int is ... " nl );
showSLList( mySLList );
stdout.newln();
repeat
getValidInt( "Enter an integer to push_back... " );
mov( eax, myNNode.nval );
push_backSLList( mySLList, myNNode );
until( !more() );
stdout.puts( nl "After push_backSLList( mySLList, myNNode ); "
"SLList of int is ... " nl );
mov( false, Sorted );
showSLList( mySLList );
stdout.newln();
mov( mySLList.tail, ecx );
// get a copy of terminal nval into myNNode.nval
mov( (type NNode [ecx]).nval, myNNode.nval );
if( !Sorted ) then
isortSLList( mySLList );
stdout.puts( nl "After isortSLList( mySLList ); "
"SLList of int is ... " nl );
showSLList( mySLList );
stdout.newln();
endif;
mov( &myCmpEQ, pMyCmp );
// returns pointer (or 0 if not found) in eax ...
findSLList( mySLList, myNNode ); // eax now holds pointer to myNNode, or 0
if( eax ) then
eraseSLList( mySLList, eax );
stdout.puts( nl "After eraseSLList( mySLList, eax ); "
"SLList of int is ... " nl );
showSLList( mySLList );
stdout.newln();
else
stdout.put( myNNode.nval, " was not found in the SLList ..." nl );
endif;
mov( &myCmp, pMyCmp ); // remember to first set proper 'cmp' function
repeat
getValidInt( nl "Enter an integer to insert_sorted... " );
mov( eax, ebx ); // save copy in ebx ...
mem.alloc( @size(NNode) );
mov( ebx, (type NNode [eax]).nval );
insert_sortedSLList( mySLList, eax );
until( !more() );
stdout.puts( nl "After insert_sortedSLList( mySLList, eax ); "
"SLList of int is ... " nl );
showSLList( mySLList );
stdout.put( nl "Before clearSLList( mySLList ); mySLList.size = ",
mySLList.size, nl );
clearSLList( mySLList );
stdout.put( "After clearSLList( mySLList ); mySLList.size = ",
mySLList.size, nl );
stdout.puts( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end SLListIntInsert;
program test_readLineConsole; // 2012-08-23 //
#includeOnce( "readLineConsole.hhf" )
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.flushInput();
stdin.getc();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
static
s: string;
len: uns32;
maxlen: uns32;
begin test_readLineConsole;
repeat
stdout.put( "Enter a short line of text: " );
stdin.flushInput();
readLineConsole();
mov( eax, s );
mov( (type str.strRec [eax]).length, len );
mov( (type str.strRec [eax]).maxlen, maxlen );
stdout.put( "You entered: '", s, "'" nl );
stdout.put( "length = ", len, ", maxlen = ", maxlen, nl );
str.free( s );
until( !more() );
end test_readLineConsole;
program test_readWordConsole; // 2012-08-24 //
#includeOnce( "readWordConsole.hhf" )
static
s: string;
begin test_readWordConsole;
forever
stdout.puts( "Enter a line of 'words' (q to quit): " );
readWordConsole( s, " " stdio.tab );
if( (type char [eax]) == 'q' ) then
str.free( eax );
break;
endif;
stdout.put( "You entered: '", s, "'" nl );
stdout.put( "length = ", (type str.strRec [eax]).length,
", maxlen = ", (type str.strRec [eax]).maxlen, nl );
str.free( s );
endfor;
stdout.puts( nl "Press 'Enter' to exit/continue ... " );
stdin.flushInput();
stdin.readLn();
end test_readWordConsole;
program VecString; // 2012-09-03 //
#includeOnce( "readLine.hhf" );
const
FNAME: text := """testStr.dat""";
InitCap: uns32 := 2; // keeping it small here to test out Vec realloc
type
Rec: record
rval: string;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @nodisplay; @noframe;
begin freeRec;
str.free( (type Rec [eax]).rval );
ret();
end freeRec;
// NOTE! The two types above and the procedure freeRec
// MUST be defined before this next include...
#includeOnce( "vector_func's.hhf" ) // includes vector.hhf that includes stdlib.hhf
// Note that vector.hhf also has: ? @nodisplay:= true;
// So ... all procedures have @nodisplay 'as default' from here on ...
// for isort descending ...
procedure myCmpInt( a: pRec in esi; b: pRec in edi ); @returns("eax");
begin myCmpInt;
if( str.gt( (type Rec [esi]).rval, (type Rec [edi]).rval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure myCmpIntEQ( a: pRec in esi; b: pRec in edi ); @returns("eax");
begin myCmpIntEQ;
if( str.eq( (type Rec [esi]).rval, (type Rec [edi]).rval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpIntEQ;
// for msort ascending ...
procedure myCmp( a: pRec in esi; b: pRec in edi ); @returns("eax");
begin myCmp;
if( str.le( (type Rec [esi]).rval, (type Rec [edi]).rval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
procedure showRec( pr: pRec in eax ); @noframe;
begin showRec;
stdout.put( (type Rec [eax]).rval );
ret();
end showRec;
procedure showVec( var v: Vec );
begin showVec;
push( eax ); push( ebx ); push( ecx );
mov( v, ebx );
for( mov( 0, ecx ); ecx < (type Vec[ebx]).size; inc( ecx ) ) do
intmul( @size(Rec), ecx, eax );
add( (type Vec[ebx]).ary, eax );
showRec( eax );
stdout.putc( ' ' );
endfor;
stdout.newln();
pop( ecx ); pop( ebx ); pop( eax );
end showVec;
static
fin: dword;
myRec: Rec;
myVec: Vec;
tmpStr: str.strvar( 32 );
begin VecString;
fileio.open( FNAME, fileio.r );
mov( eax, fin );
initVec( myVec );
while( readLine( fin, myRec.rval ) ) do
push_backVec( myVec, myRec );
endwhile;
fileio.close( fin );
stdout.puts( "showVec: " );
showVec( myVec );
mov( myVec.size, ecx );
//last = my_ary[ i-1 ];
dec( ecx );
mov( &myVec, ebx );
intmul( @size(Rec), ecx, eax );
add( (type Vec [ebx]).ary, eax );
mov( mov( (type Rec [eax]).rval, eax ), myRec.rval );
stdout.puts( nl "After isort... (descending)" nl );
mov( &myCmpInt, pMyCmp );
isortVec( myVec );
stdout.puts( "showVec: " );
showVec( myVec );
mov( &myCmpIntEQ, pMyCmp );
findVec( myVec, myRec ); // index returned in eax ...
if( (type int32 eax) >= 0 ) then // i.e. if found ...
eraseVec( myVec, eax ); // count eax holds index
stdout.put( nl "After erasing ", myRec.rval, "..." nl );
stdout.put( "showVec: " );
showVec( myVec );
else stdout.put( nl, myRec.rval, " NOT found in myVec." nl );
endif;
stdout.puts( nl "After msort... (ascending)" nl );
mov( &myCmp, pMyCmp );
msortVec( myVec );
stdout.puts( "showVec: " );
showVec( myVec );
stdout.put( nl "Before clear, size = ", myVec.size,
", capacity = ", myVec.capacity, nl );
clearVec( myVec );
stdout.put( "After clear, size = ", myVec.size,
", capacity = ", myVec.capacity, nl );
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end VecString;
program test_vecStr; // 2012-07-19 //
#include( "stdlib.hhf" )
#includeOnce( "readLine.hhf" )
const
FNAME: text := """test.dat""" ;
InitCap: uns32 := 2;
type
Rec: record
str: string;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @nodisplay;
begin freeRec;
free( (type Rec [eax]).str );
end freeRec;
// NOTE! The two types above and the procedure freeRec
// MUST be defined before this next include...
#includeOnce( "vector.hhf" );
#includeOnce( "vector_func's.hhf" );
procedure showRec( pr: pRec in eax ); @nodisplay; @noframe;
begin showRec;
stdout.put( "'", (type Rec [eax]).str, "'" );
str.length( (type Rec [eax]).str );
stdout.put( ", len = ", (type uns32 eax) );
ret();
end showRec;
procedure showVec( var v: Vec ); @nodisplay;
begin showVec;
push( eax ); push( ebx ); push( ecx );
mov( v, ebx );
for( mov( 0, ecx ); ecx < (type Vec[ebx]).size; inc( ecx ) ) do
intmul( @size(Rec), ecx, eax );
add( (type Vec[ebx]).ary, eax );
showRec( eax );
stdout.newln();
endfor;
pop( ecx ); pop( ebx ); pop( eax );
end showVec;
static
fin: dword;
myRec: Rec;
myVec: Vec;
begin test_vecStr;
fileio.open( FNAME, fileio.r );
mov( eax, fin );
initVec( myVec );
while( readLine( fin, myRec.str ) ) do
push_backVec( myVec, myRec );
endwhile;
fileio.close( fin );
stdout.puts( "Showing vec of str ... " nl );
showVec( myVec );
stdout.put( "size = ", myVec.size, ", capacity = ", myVec.capacity, nl );
stdout.puts( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end test_vecStr;
z 3456789 123456789 123456789
2z
32z
444z
5555z
66666z
777z
88z
9z
z
program SLListString; // 2012-09-03 //
#includeOnce( "readLine.hhf" )
const
FNAME: text := """testStr.dat""";
type
NNode: record
nval: string;
next: pointer to NNode;
endrecord;
pNNode: pointer to NNode;
procedure freeNNode( pn: pNNode in eax ); @nodisplay; @noframe;
begin freeNNode;
str.free( (type NNode [eax]).nval );
ret();
end freeNNode;
// NOTE! The two types above and the procedure freeNNode
// MUST be defined before this next include...
#includeOnce( "sllist_func's.hhf" ) // includes sllist.hhf that includes stdlib.hhf
// Note that sllist.hhf also has: ? @nodisplay:= true;
// So ... all procedures have @nodisplay 'as default' from here on ...
// for isort descending ...
procedure myCmpInt( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpInt;
if( str.ge( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure myCmpIntEQ( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpIntEQ;
if( str.eq( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpIntEQ;
// for msort ascending ...
procedure myCmp( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmp;
if( str.le( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
procedure showNNode( pn: pNNode in eax ); @noframe;
begin showNNode;
stdout.put( (type NNode [eax]).nval );
ret();
end showNNode;
procedure showSLList( var v: SLList );
begin showSLList;
push( eax );
mov( v, eax );
mov( (type SLList[eax]).head, eax );
while( eax ) do
showNNode( eax );
stdout.putc( ' ' );
mov( (type NNode[eax]).next, eax );
endwhile;
stdout.newln();
pop( eax );
end showSLList;
static
fin: dword;
myNNode: NNode;
mySLList: SLList;
begin SLListString;
fileio.open( FNAME, fileio.r );
mov( eax, fin );
initSLList( mySLList );
while( readLine( fin, myNNode.nval ) ) do
push_backSLList( mySLList, myNNode );
endwhile;
fileio.close( fin );
stdout.puts( "showSLList: " );
showSLList( mySLList );
mov( mySLList.tail, eax );
mov( mov( (type NNode [eax]).nval, eax ), myNNode.nval );
stdout.puts( nl "After isort... (descending)" nl );
mov( &myCmpInt, pMyCmp );
isortSLList( mySLList );
stdout.puts( "showSLList: " );
showSLList( mySLList );
mov( &myCmpIntEQ, pMyCmp );
findSLList( mySLList, myNNode ); // index returned in eax ...
if( eax ) then // i.e. if found ...
eraseSLList( mySLList, eax ); // count eax holds index
stdout.put( nl "After erasing ", myNNode.nval, "..." nl );
stdout.put( "showSLList: " );
showSLList( mySLList );
else stdout.put( nl, myNNode.nval, " NOT found in mySLList." nl );
endif;
stdout.puts( nl "After msort... (ascending)" nl );
mov( &myCmp, pMyCmp );
msortSLList( mySLList );
stdout.puts( "showSLList: " );
showSLList( mySLList );
stdout.put( nl "Before clear, mySLList.size = ", mySLList.size, nl );
clearSLList( mySLList );
stdout.put( "After clear, mySLList.size = ", mySLList.size, nl );
stdout.puts( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end SLListString;
program SLList2Str; // 2012-09-03 //
#includeOnce( "readLine.hhf" )
#includeOnce( "sllist2_func's.hhf" ) // includes sllist2.hhf that includes stdlib.hhf
// Note that sllist2.hhf also has: ? @nodisplay:= true;
// So ... all procedures have @nodisplay 'as default' from here on ...
const
FNAME: text := """testStr.dat""";
/*
type
NNode: record
nval: int32;
next: pointer to NNode;
endrecord;
pNNode: pointer to NNode;
*/
procedure myFreeNNode( pn: pNNode in eax ); @noframe;
begin myFreeNNode;
str.free( (type NNode [eax]).nval );
ret();
end myFreeNNode;
// for isort descending ...
procedure myCmpInt( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpInt;
if( str.ge( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure myCmpIntEQ( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpIntEQ;
if( str.eq( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpIntEQ;
// for msort ascending ...
procedure myCmp( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmp;
if( str.le( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
procedure showNNode( pn: pNNode in eax ); @noframe;
begin showNNode;
stdout.put( (type string (type NNode [eax]).nval) );
ret();
end showNNode;
procedure showSLList( var v: SLList );
begin showSLList;
push( eax );
mov( v, eax );
mov( (type SLList[eax]).head, eax );
while( eax ) do
showNNode( eax );
stdout.putc( ' ' );
mov( (type NNode[eax]).next, eax );
endwhile;
stdout.newln();
pop( eax );
end showSLList;
static
fin: dword;
myNNode: NNode;
mySLList: SLList;
begin SLList2Str;
fileio.open( FNAME, fileio.r );
mov( eax, fin );
initSLList( mySLList );
while( readLine( fin, myNNode.nval ) ) do
push_backSLList( mySLList, myNNode );
endwhile;
fileio.close( fin );
stdout.puts( "showSLList: " );
showSLList( mySLList );
mov( mySLList.tail, eax );
mov( mov( (type NNode [eax]).nval, eax ), myNNode.nval );
stdout.puts( nl nl "After isort...(descending)" nl );
mov( &myCmpInt, pMyCmp );
isortSLList( mySLList );
stdout.puts( "showSLList: " );
showSLList( mySLList );
mov( &myCmpIntEQ, pMyCmp );
findSLList( mySLList, myNNode ); // index returned in eax ...
if( eax ) then // i.e. if found ...
mov( &myFreeNNode, pFreeNNode );
eraseSLList( mySLList, eax ); // eax holds pointer
stdout.put( nl "After erasing ", (type string myNNode.nval), "..." nl );
stdout.put( "showSLList: " );
showSLList( mySLList );
else stdout.put( nl, myNNode.nval, " NOT found in mySLList." nl );
endif;
stdout.puts( nl "After msort... (ascending)" nl );
mov( &myCmp, pMyCmp );
msortSLList( mySLList );
stdout.puts( "showSLList: " );
showSLList( mySLList );
stdout.put( "mySLList.size = ", mySLList.size, nl );
mov( &myFreeNNode, pFreeNNode );
clearSLList( mySLList );
stdout.puts( nl "After clear..." nl );
stdout.puts( "showSLList: " );
showSLList( mySLList );
stdout.put( "mySLList.size = ", mySLList.size, nl );
stdout.puts( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end SLList2Str;
“In the beginning God created the heaven and the earth. And the earth was without form, and void; and darkness [was] upon the face of the deep. And the Spirit of God moved upon the face of the waters. And God said, Let there be light: and there was light. And God saw the light, that [it was] good: and God divided the light from the darkness. And God called the light Day, and the darkness he called Night. And the evening and the morning were the first day. And God said, Let there be a firmament in the midst of the waters, and let it divide the waters from the waters. And God made the firmament, and divided the waters which [were] under the firmament from the waters which [were] above the firmament: and it was so. And God called the firmament Heaven. And the evening and the morning were the second day. And God said, Let the waters under the heaven be gathered together unto one place, and let the dry [land] appear: and it was so. And God called the dry [land] Earth; and the gathering together of the waters called he Seas: and God saw that [it was] good. And God said, Let the earth bring forth grass, the herb yielding seed, [and] the fruit tree yielding fruit after his kind, whose seed [is] in itself, upon the earth: and it was so. And the earth brought forth grass, [and] herb yielding seed after his kind, and the tree yielding fruit, whose seed [was] in itself, after his kind: and God saw that [it was] good. And the evening and the morning were the third day. And God said, Let there be lights in the firmament of the heaven to divide the day from the night; and let them be for signs, and for seasons, and for days, and years: And let them be for lights in the firmament of the heaven to give light upon the earth: and it was so. And God made two great lights; the greater light to rule the day, and the lesser light to rule the night: [he made] the stars also. And God set them in the firmament of the heaven to give light upon the earth, And to rule over the day and over the night, and to divide the light from the darkness: and God saw that [it was] good. And the evening and the morning were the fourth day. And God said, Let the waters bring forth abundantly the moving creature that hath life, and fowl [that] may fly above the earth in the open firmament of heaven. And God created great whales, and every living creature that moveth, which the waters brought forth abundantly, after their kind, and every winged fowl after his kind: and God saw that [it was] good. And God blessed them, saying, Be fruitful, and multiply, and fill the waters in the seas, and let fowl multiply in the earth. And the evening and the morning were the fifth day. And God said, Let the earth bring forth the living creature after his kind, cattle, and creeping thing, and beast of the earth after his kind: and it was so. And God made the beast of the earth after his kind, and cattle after their kind, and every thing that creepeth upon the earth after his kind: and God saw that [it was] good. And God said, Let us make man in our image, after our likeness: and let them have dominion over the fish of the sea, and over the fowl of the air, and over the cattle, and over all the earth, and over every creeping thing that creepeth upon the earth. So God created man in his [own] image, in the image of God created he him; male and female created he them. And God blessed them, and God said unto them, Be fruitful, and multiply, and replenish the earth, and subdue it: and have dominion over the fish of the sea, and over the fowl of the air, and over every living thing that moveth upon the earth. And God said, Behold, I have given you every herb bearing seed, which [is] upon the face of all the earth, and every tree, in the which [is] the fruit of a tree yielding seed; to you it shall be for meat. And to every beast of the earth, and to every fowl of the air, and to every thing that creepeth upon the earth, wherein [there is] life, [I have given] every green herb for meat: and it was so. And God saw every thing that he had made, and, behold, [it was] very good. And the evening and the morning were the sixth day.” (Ge 1:1-31 AV)
// uniqueCount.hla // // 2012-08-16 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program uniqueCount;
#include( "readLine.hhf" ) // also includes stdlib.hhf ...
//#includeOnce( "memory.hhf" ) // so can use str.free in freeNNode below
//#includeOnce( "stdio.hhf" ) // so can use stdio.tab below
const
FNAME: text := """genesis1.txt""";
MyDelimits: string := " .,;:?!()[]“”" stdio.tab;
type
NNode: record
nval: string;
next: pointer to NNode;
endrecord;
pNNode: pointer to NNode;
? @nodisplay:= true; // All procedures have @nodisplay 'as default' now.
procedure freeNNode( pn: pNNode in eax ); @noframe;
begin freeNNode;
str.free( (type NNode [eax]).nval );
ret();
end freeNNode;
// NOTE! The two types above and the procedure freeNNode
// MUST be defined before this next include...
#includeOnce( "sllist_func's.hhf" ) // also includes sllist.hhf/stdlib.hhf
// for msort/isort ascending ...
procedure myCmp( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmp;
if( str.le( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
/*
// for find...
procedure myCmpEQ( a: pNNode in esi; b: pNNode in edi ); @returns("eax");
begin myCmpEQ;
if( str.eq( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpEQ;
*/
procedure showNNode( pn: pNNode in eax ); @noframe;
begin showNNode;
stdout.put( (type NNode [eax]).nval );
ret();
end showNNode;
procedure showSLList( var sll: SLList );
begin showSLList;
push( eax );
mov( sll, eax );
mov( (type SLList [eax]).head, eax );
while( eax != 0 ) do
stdout.putc( ''' );
showNNode( eax );
stdout.puts( "'" nl );
mov( (type NNode [eax]).next, eax );
//stdin.readLn();
endwhile;
pop( eax );
end showSLList;
type
Rec: record
rval: string;
num: uns32;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @noframe;
begin freeRec;
str.free( (type Rec [eax]).rval );
ret();
end freeRec;
// OK ... can now ...
#include( "vector_func's.hhf" )
// for msort in descending frequency ...
procedure myCmpRec( a: pRec in esi; b: pRec in edi ); @returns("eax");
begin myCmpRec;
mov( (type Rec [esi]).num, eax );
if( eax > (type Rec [edi]).num ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpRec;
// and then ... define these next two ...
procedure showRec( pr: pRec in eax ); @nodisplay; @noframe;
begin showRec;
stdout.put( "'", (type Rec [eax]).rval, "', ", (type Rec [eax]).num );
ret();
end showRec;
procedure showVec( var v: Vec ); @nodisplay;
var
count: uns32;
begin showVec;
push( eax ); push( ebx ); push( ecx ); push( edx );
mov( 0, edx ); // sum set to zero ...
mov( edx, count ); // also zero initial count
mov( v, ebx );
for( mov( 0, ecx ); ecx < (type Vec[ebx]).size; inc( ecx ) ) do
intmul( @size(Rec), ecx, eax );
add( (type Vec[ebx]).ary, eax );
inc( count );
stdout.put( "<", count:3, "> : " );
showRec( eax );
add( (type Rec [eax]).num, edx );
stdout.newln();
endfor;
stdout.put( "The total number of original words was ",
(type uns32 edx), nl );
pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end showVec;
/*
procedure isortVec( var v: Vec ); // uses/needs pMyCmp(..)
static
rcmp: Rec;
tmpReg: dword;
begin isortVec;
push( eax ); push( ebx ); push( ecx ); push( edx ); push( esi ); push( edi );
//int i, j; // i in eax, j in edx
// start with an array of just the first 2 elements (if exists) ...
// for( i = 1; i < cv->size; ++i )
cld();
mov( v, ebx );
for( mov( 1, eax ); eax < (type Vec [ebx]).size; inc( eax ) ) do
// update this cmp Rec on each outer loop
//memcpy( &cmp, &cv->ary[i], sizeof(Rec) );
mov( &rcmp, edi );
intmul( @size(Rec), eax, esi );
add( (type Vec [ebx]).ary, esi );
mov( @size(Rec), ecx ); // get # bytes to copy in a Rec ... into ecx
rep.movsb(); // ok ... got copy into rcmp ...
// get index of element just to the left of the above 'cmp' to start comparisons
mov( eax, edx ); // j = i
dec( edx ); // --j // i.e. j = i-1; //
while( (type int32 edx) >= 0 ) do // while( j >= 0 && myCmp(&cmp, &cv->ary[j]) < 0 )
intmul( @size(Rec), edx, edi ); // get offset into edi ..
add( (type Vec [ebx]).ary, edi );
mov( &rcmp, esi );
//breakif( !pMyCmp(esi, edi) ); // 'copy up' // but first ...
mov( eax, tmpReg ); // get copy of loop counter in eax
pMyCmp( esi, edi );
if( eax ) then
mov( tmpReg, eax );
else
mov( tmpReg, eax );
break;
endif;
// Now ... 'copy up' ...
//memcpy( &cv->ary[j+1], &cv->ary[j], sizeof(Rec) );
intmul( @size(Rec), edx, esi );
add( (type Vec [ebx]).ary, esi );
mov( esi, edi );
add( @size(Rec), edi ); // to inc( j ) add size //
mov( @size(Rec), ecx ); // get # bytes to copy in a Rec into ecx
rep.movsb();
dec( edx ); //--j; // --j to prepare for next inner loop
endwhile;
// insert pointer at index j+1 (since j was decremented above ...
//memcpy( &cv->ary[j+1], &cmp, sizeof(Rec) );
inc( edx ); // ++j
mov( &rcmp, esi );
intmul( @size(Rec), edx, edi );
add( (type Vec [ebx]).ary, edi );
mov( @size(Rec), ecx ); // get # bytes to copy in a Rec into ecx
rep.movsb();
endfor;
pop( edi ); pop( esi ); pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end isortVec; // size hasn't changed ...
*/
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
static
fin: dword;
s: string;
mySLList: SLList;
t: timer_t;
myVec: Vec;
myRec: Rec;
begin uniqueCount;
initSLList( mySLList );
fileio.open( FNAME, fileio.r );
mov( eax, fin );
t.create();
t.start();
while( readLine( fin, s ) ) do
// passing in (by ref) the SLList to hold a list of words
splitSLList( mySLList, s, MyDelimits );
// free the original string since done with it here
str.free( s );
endwhile;
fileio.close( fin );
t.stop();
stdout.put( "Showing the list of words, "
"each word below inside single quotes ..." nl );
showSLList( mySLList );
stdout.put( "mySLList.size = ", mySLList.size, nl );
stdout.put( "Time to read into list was ", (type uns64 t.Accumulated ),
" millisecs" )
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
t.start(); // start timer ...
mov( &myCmp, pMyCmp );
msortSLList( mySLList );
initVec( myVec );
//mov( &myCmpEQ, pMyCmp );
//uniqueSLList( mySLList );
mov( mySLList.head, ecx );
while( ecx != 0 ) do // get vector of (Records of) unique words (with count) ...
mov( (type NNode [ecx]).nval, myRec.rval ); // get copy of pointer to string
mov( 1, myRec.num ); // set initial count ...
mov( (type NNode [ecx]).next, ecx );
while( ecx && str.eq( myRec.rval, (type NNode [ecx]).nval ) ) do
inc( myRec.num ); // while repeats inc count
mov( (type NNode [ecx]).next, ecx ); // 'inc' ecx pointer ...
endwhile;
push( ecx );
//push( ebx ); push( ecx ); push( esi ); push( edi ); // caller must preserve
push_backVec( myVec, myRec ); // ok done here ... push_back
pop( ecx );
endwhile;
t.stop(); // stop timer ...
stdout.put( nl "Showing list of UNIQUE words, word COUNT "
"(each word inside single quotes) ..." nl );
showVec( myVec );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
stdout.put( "Time to msort and get unique list was ", (type uns64 t.Accumulated ),
" millisecs" nl );
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
mov( &myCmpRec, pMyCmp );
isortVec( myVec );
stdout.put( nl "Showing list of UNIQUE words, word COUNT "
"(in descending COUNT frequency) ..." nl );
showVec( myVec );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
stdout.put( "Before clear... mySLList.size = ", mySLList.size, nl );
clearSLList( mySLList );
stdout.put( "After clear... mySLList.size = ", mySLList.size, nl );
mem.free( myVec.ary ); // ok ... JUST free ary mem as strings all freeded above
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end uniqueCount;
// uniqueCountIgnoreCase.hla // // 2012-08-16 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program uniqueCountIgnoreCase;
#include( "readLine.hhf" ) // also includes stdlib.hhf ...
//#includeOnce( "memory.hhf" ) // so can use str.free in freeNNode below
//#includeOnce( "stdio.hhf" ) // so can use stdio.tab below
const
FNAME: text := """genesis1.txt""";
MyDelimits: string := " .,;:?!()[]“”" stdio.tab;
type
NNode: record
nval: string;
next: pointer to NNode;
endrecord;
pNNode: pointer to NNode;
? @nodisplay:= true; // All procedures have @nodisplay 'as default' now.
procedure freeNNode( pn: pNNode in eax ); @noframe;
begin freeNNode;
str.free( (type NNode [eax]).nval );
ret();
end freeNNode;
// NOTE! The two types above and the procedure freeNNode
// MUST be defined before this next include...
#includeOnce( "sllist_func's.hhf" ) // also includes sllist.hhf/stdlib.hhf
// for msort/isort ascending ...
procedure myCmp( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmp;
if( str.ile( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
/*
// for find...
procedure myCmpEQ( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpEQ;
if( str.eq( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpEQ;
*/
procedure showNNode( pn: pNNode in eax ); @noframe;
begin showNNode;
stdout.put( (type NNode [eax]).nval );
ret();
end showNNode;
procedure showSLList( var sll: SLList );
begin showSLList;
push( eax );
mov( sll, eax );
mov( (type SLList [eax]).head, eax );
while( eax != 0 ) do
stdout.putc( ''' );
showNNode( eax );
stdout.puts( "'" nl );
mov( (type NNode [eax]).next, eax );
//stdin.readLn();
endwhile;
pop( eax );
end showSLList;
type
Rec: record
rval: string;
num: uns32;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @noframe;
begin freeRec;
str.free( (type Rec [eax]).rval );
ret();
end freeRec;
// OK ... can now ...
#include( "vector_func's.hhf" )
// for msort in descending frequency ...
procedure myCmpRec( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpRec;
mov( (type Rec [esi]).num, eax );
if( eax > (type Rec [edi]).num ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpRec;
// and then ... define these next two ...
procedure showRec( pr: pRec in eax ); @nodisplay; @noframe;
begin showRec;
stdout.put( "'", (type Rec [eax]).rval, "', ", (type Rec [eax]).num );
ret();
end showRec;
procedure showVec( var v: Vec ); @nodisplay;
var
count: uns32;
begin showVec;
push( eax ); push( ebx ); push( ecx ); push( edx );
mov( 0, edx ); // sum set to zero ...
mov( edx, count ); // also zero initial count
mov( v, ebx );
for( mov( 0, ecx ); ecx < (type Vec[ebx]).size; inc( ecx ) ) do
intmul( @size(Rec), ecx, eax );
add( (type Vec[ebx]).ary, eax );
inc( count );
stdout.put( "<", count:3, "> : " );
showRec( eax );
add( (type Rec [eax]).num, edx );
stdout.newln();
endfor;
stdout.put( "The total number of original words was ",
(type uns32 edx), nl );
pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end showVec;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
static
fin: dword;
s: string;
mySLList: SLList;
t: timer_t;
myVec: Vec;
myRec: Rec;
begin uniqueCountIgnoreCase;
initSLList( mySLList );
fileio.open( FNAME, fileio.r );
mov( eax, fin );
t.create();
t.start();
while( readLine( fin, s ) ) do
// passing in (by ref) the SLList to hold a list of words
splitSLList( mySLList, s, MyDelimits );
// free the original string since done with it here
str.free( s );
endwhile;
fileio.close( fin );
t.stop();
stdout.put( "Showing the list of words, "
"each word below inside single quotes ..." nl );
showSLList( mySLList );
stdout.put( "mySLList.size = ", mySLList.size, nl );
stdout.put( "Time to read into list was ", (type uns64 t.Accumulated ),
" millisecs" )
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
t.start(); // start timer ...
mov( &myCmp, pMyCmp );
msortSLList( mySLList );
initVec( myVec );
//mov( &myCmpEQ, pMyCmp );
//uniqueSLList( mySLList );
mov( mySLList.head, ecx );
while( ecx != 0 ) do // get vector of (Records of) unique words (with count) ...
mov( (type NNode [ecx]).nval, myRec.rval ); // get copy of pointer to string
mov( 1, myRec.num ); // set initial count ...
mov( (type NNode [ecx]).next, ecx );
while( ecx && str.ieq( myRec.rval, (type NNode [ecx]).nval ) ) do // ignore case
inc( myRec.num ); // while repeats inc count
mov( (type NNode [ecx]).next, ecx ); // 'inc' ecx pointer ...
endwhile;
push( ecx );
//push( ebx ); push( ecx ); push( esi ); push( edi ); // caller must preserve if needed
push_backVec( myVec, myRec ); // ok done here ... push_back
pop( ecx );
endwhile;
t.stop(); // stop timer ...
stdout.put( nl "Showing list of UNIQUE words, word COUNT "
"(each word inside single quotes) ..." nl );
showVec( myVec );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
stdout.put( "Time to msort and get unique list was ", (type uns64 t.Accumulated ),
" millisecs" nl );
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
mov( &myCmpRec, pMyCmp );
isortVec( myVec );
stdout.put( nl "Showing list of UNIQUE words, word COUNT "
"(in descending COUNT frequency) ..." nl );
showVec( myVec );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
stdout.put( "Before clear... mySLList.size = ", mySLList.size, nl );
clearSLList( mySLList );
stdout.put( "After clear... mySLList.size = ", mySLList.size, nl );
mem.free( myVec.ary ); // ok ... JUST free ary mem as strings all freeded above
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end uniqueCountIgnoreCase;
// uniqueCount_readWord.hla // // 2012-08-22 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program uniqueCount_readWord;
#includeOnce( "readWord.hhf" ) // also includes stdlib.hhf ...
#includeOnce( "vector2_func's.hhf" ) // includes vector2.hhf & stdlib.hhf
//? @nodisplay:= true; //
//All procedures have @nodisplay 'as default' now ... included above //
//#includeOnce( "memory.hhf" ) // so can use str.free in freeNNode below
//#includeOnce( "stdio.hhf" ) // so can use stdio.tab below
const
FNAME: text := """genesis1.txt""";
MyDelimits: string := " .,;:?!()[]“”" nl stdio.tab;
type
Rec: record
rval: string;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @noframe;
begin freeRec;
str.free( (type Rec [eax]).rval );
ret();
end freeRec;
// for msort/isort ascending ...
procedure myCmp( a: pRec in esi; b: pRec in edi ); @returns("eax");
begin myCmp;
if( str.le( (type Rec [esi]).rval, (type Rec [edi]).rval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
procedure showRec( pr: pRec in eax ); @noframe;
begin showRec;
stdout.put( (type Rec [eax]).rval );
ret();
end showRec;
procedure showVec( var vc: Vec );
begin showVec;
push( eax ); push( ebx ); push( ecx );
mov( vc, ebx );
for( mov( 0, ecx ); ecx < (type Vec [ebx]).size; inc( ecx ) ) do
stdout.putc( ''' );
intmul( @size( Rec ), ecx, eax );
add( (type Vec [ebx]).ary, eax );
showRec( eax );
stdout.puts( "'" nl );
endfor;
pop( ecx ); pop( ebx ); pop( eax );
end showVec;
type
Rec2: record
rval: string;
num: uns32;
endrecord;
pRec2: pointer to Rec2;
/*
procedure freeRec2( pr: pRec in eax ); @noframe;
begin freeRec2;
str.free( (type Rec2 [eax]).rval );
ret();
end freeRec2;
*/
// for msort in descending frequency ...
procedure myCmpRec2( a: pRec2 in esi; b: pRec2 in edi ); @returns("eax");
begin myCmpRec2;
mov( (type Rec2 [esi]).num, eax );
if( eax >= (type Rec2 [edi]).num ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpRec2;
// and then ... define these next two ...
procedure showRec2( pr: pRec2 in eax ); @nodisplay; @noframe;
begin showRec2;
stdout.put( "'", (type Rec2 [eax]).rval, "', ", (type Rec2 [eax]).num );
ret();
end showRec2;
procedure showVec2( var v: Vec ); @nodisplay;
var
count: uns32;
begin showVec2;
push( eax ); push( ebx ); push( ecx ); push( edx );
mov( 0, edx ); // sum set to zero ...
mov( edx, count ); // also zero initial count
mov( v, ebx );
for( mov( 0, ecx ); ecx < (type Vec[ebx]).size; inc( ecx ) ) do
intmul( @size(Rec2), ecx, eax );
add( (type Vec[ebx]).ary, eax );
inc( count );
stdout.put( "<", count:3, "> : " );
showRec2( eax );
add( (type Rec2 [eax]).num, edx );
stdout.newln();
endfor;
stdout.put( "The total number of original words was ",
(type uns32 edx), nl );
pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end showVec2;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
static
fin: dword;
reg32: dword;
s: string;
myVec: Vec;
myRec: Rec;
t: timer_t;
myVec2: Vec;
myRec2: Rec2;
begin uniqueCount_readWord;
initVec( myVec, @size( Rec ) );
fileio.open( FNAME, fileio.r );
mov( eax, fin );
t.create();
t.start();
while( readWord( fin, s, MyDelimits ) ) do
mov( eax, myRec.rval );
push_backVec( myVec, &myRec );
endwhile;
fileio.close( fin );
t.stop();
stdout.put( "Showing the Vec of words, "
"each word below inside single quotes ..." nl );
showVec( myVec );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
stdout.put( "Time to read into Vec was ", (type uns64 t.Accumulated ),
" millisecs" )
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
t.start(); // start timer ...
mov( &myCmp, pMyCmp );
msortVec( myVec );
initVec( myVec2, @size( Rec2 ) );
// get vector of (Records of) unique words (with count) ...
for( mov( 0, ecx ); ecx < myVec.size; nop() ) do // ecx is ++ in loop ...
intmul( @size( Rec ), ecx, eax );
add( myVec.ary, eax );
mov( (type Rec [eax]).rval, myRec2.rval ); // get copy of pointer to string
mov( 1, myRec2.num ); // set initial count ...
add( @size( Rec ), eax );
inc( ecx ); // ++ ecx in body of loop
mov( eax, reg32 ); // preserve eax ...
while( ecx < myVec.size && str.eq( myRec2.rval, (type Rec [eax]).rval ) ) do
inc( myRec2.num ); // while repeats inc count
inc( ecx ); // 'inc' ecx pointer ...
//mov( reg32, eax );
//add( @size( Rec ), eax );
//mov( eax, reg32 );
add( @size( Rec ), reg32 );
mov( reg32, eax );
endwhile;
push( ecx ); // preserve ecx
push_backVec( myVec2, &myRec2 ); // ok done here ... push_back
pop( ecx );
endfor;
t.stop(); // stop timer ...
stdout.put( nl "Showing Vec2 of UNIQUE words, word COUNT "
"(each word inside single quotes) ..." nl );
showVec2( myVec2 );
stdout.put( "myVec2.size = ", myVec2.size,
", myVec2.capacity = ", myVec2.capacity, nl );
stdout.put( "Time to msort and get unique Vec2 was ", (type uns64 t.Accumulated ),
" millisecs" nl );
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
mov( &myCmpRec2, pMyCmp );
msortVec( myVec2 );
stdout.put( nl "Showing list of UNIQUE words, word COUNT "
"(in descending COUNT frequency) ..." nl );
showVec2( myVec2 );
stdout.put( "myVec2.size = ", myVec2.size,
", myVec2.capacity = ", myVec2.capacity, nl );
stdout.put( "Before clear... myVec.size = ", myVec.size, nl );
mov( &freeRec, pFreeRec );
clearVec( myVec );
stdout.put( "After clear... myVec.size = ", myVec.size, nl );
mem.free( myVec2.ary ); // ok ... JUST free ary mem as strings all freeded above
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end uniqueCount_readWord;
// uniqueCountIC_readWord.hla // // 2012-08-22 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program uniqueCountIC_readWord;
#includeOnce( "readWord.hhf" ) // also includes stdlib.hhf ...
#includeOnce( "vector2_func's.hhf" ) // includes vector2.hhf & stdlib.hhf
//? @nodisplay:= true; //
//All procedures have @nodisplay 'as default' now ... included above //
//#includeOnce( "memory.hhf" ) // so can use str.free in freeNNode below
//#includeOnce( "stdio.hhf" ) // so can use stdio.tab below
const
FNAME: text := """genesis1.txt""";
MyDelimits: string := " .,;:?!()[]“”" nl stdio.tab;
type
Rec: record
rval: string;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @noframe;
begin freeRec;
str.free( (type Rec [eax]).rval );
ret();
end freeRec;
// for msort/isort ascending ...
procedure myCmp( a: pRec in esi; b: pRec in edi ); @returns("eax");
begin myCmp;
if( str.ile( (type Rec [esi]).rval, (type Rec [edi]).rval ) ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
procedure showRec( pr: pRec in eax ); @noframe;
begin showRec;
stdout.put( (type Rec [eax]).rval );
ret();
end showRec;
procedure showVec( var vc: Vec );
begin showVec;
push( eax ); push( ebx ); push( ecx );
mov( vc, ebx );
for( mov( 0, ecx ); ecx < (type Vec [ebx]).size; inc( ecx ) ) do
stdout.putc( ''' );
intmul( @size( Rec ), ecx, eax );
add( (type Vec [ebx]).ary, eax );
showRec( eax );
stdout.puts( "'" nl );
endfor;
pop( ecx ); pop( ebx ); pop( eax );
end showVec;
type
Rec2: record
rval: string;
num: uns32;
endrecord;
pRec2: pointer to Rec2;
/*
procedure freeRec2( pr: pRec in eax ); @noframe;
begin freeRec2;
str.free( (type Rec2 [eax]).rval );
ret();
end freeRec2;
*/
// for msort in descending frequency ...
procedure myCmpRec2( a: pRec2 in esi; b: pRec2 in edi ); @returns("eax");
begin myCmpRec2;
mov( (type Rec2 [esi]).num, eax );
if( eax >= (type Rec2 [edi]).num ) then
mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpRec2;
// and then ... define these next two ...
procedure showRec2( pr: pRec2 in eax ); @nodisplay; @noframe;
begin showRec2;
stdout.put( "'", (type Rec2 [eax]).rval, "', ", (type Rec2 [eax]).num );
ret();
end showRec2;
procedure showVec2( var v: Vec ); @nodisplay;
var
count: uns32;
begin showVec2;
push( eax ); push( ebx ); push( ecx ); push( edx );
mov( 0, edx ); // sum set to zero ...
mov( edx, count ); // also zero initial count
mov( v, ebx );
for( mov( 0, ecx ); ecx < (type Vec[ebx]).size; inc( ecx ) ) do
intmul( @size(Rec2), ecx, eax );
add( (type Vec[ebx]).ary, eax );
inc( count );
stdout.put( "<", count:3, "> : " );
showRec2( eax );
add( (type Rec2 [eax]).num, edx );
stdout.newln();
endfor;
stdout.put( "The total number of original words was ",
(type uns32 edx), nl );
pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end showVec2;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
static
fin: dword;
reg32: dword;
s: string;
myVec: Vec;
myRec: Rec;
t: timer_t;
myVec2: Vec;
myRec2: Rec2;
begin uniqueCountIC_readWord;
initVec( myVec, @size( Rec ) );
fileio.open( FNAME, fileio.r );
mov( eax, fin );
t.create();
t.start();
while( readWord( fin, s, MyDelimits ) ) do
mov( eax, myRec.rval );
push_backVec( myVec, &myRec );
endwhile;
fileio.close( fin );
t.stop();
stdout.put( "Showing the Vec of words, "
"each word below inside single quotes ..." nl );
showVec( myVec );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
stdout.put( "Time to read into Vec was ", (type uns64 t.Accumulated ),
" millisecs" )
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
t.start(); // start timer ...
mov( &myCmp, pMyCmp );
msortVec( myVec );
initVec( myVec2, @size( Rec2 ) );
// get vector of (Records of) unique words (with count) ...
for( mov( 0, ecx ); ecx < myVec.size; nop() ) do // ecx is ++ in loop ...
intmul( @size( Rec ), ecx, eax );
add( myVec.ary, eax );
mov( (type Rec [eax]).rval, myRec2.rval ); // get copy of pointer to string
mov( 1, myRec2.num ); // set initial count ...
add( @size( Rec ), eax );
inc( ecx ); // ++ ecx is done inside loop
mov( eax, reg32 ); // preserve eax ...
while( ecx < myVec.size && str.ieq( myRec2.rval, (type Rec [eax]).rval ) ) do
inc( myRec2.num ); // while repeats inc count
inc( ecx ); // 'inc' ecx pointer ...
//mov( reg32, eax );
//add( @size( Rec ), eax );
//mov( eax, reg32 );
add( @size( Rec ), reg32 );
mov( reg32, eax );
endwhile;
push( ecx ); // preserve ecx
push_backVec( myVec2, &myRec2 ); // ok done here ... push_back
pop( ecx );
endfor;
t.stop(); // stop timer ...
stdout.put( nl "Showing Vec2 of UNIQUE words, word COUNT "
"(each word inside single quotes) ..." nl );
showVec2( myVec2 );
stdout.put( "myVec2.size = ", myVec2.size,
", myVec2.capacity = ", myVec2.capacity, nl );
stdout.put( "Time to msort and get unique Vec2 was ", (type uns64 t.Accumulated ),
" millisecs" nl );
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
mov( &myCmpRec2, pMyCmp );
msortVec( myVec2 );
stdout.put( nl "Showing list of UNIQUE words, word COUNT "
"(in descending COUNT frequency) ..." nl );
showVec2( myVec2 );
stdout.put( "myVec2.size = ", myVec2.size,
", myVec2.capacity = ", myVec2.capacity, nl );
stdout.put( "Before clear... myVec.size = ", myVec.size, nl );
mov( &freeRec, pFreeRec );
clearVec( myVec );
stdout.put( "After clear... myVec.size = ", myVec.size, nl );
mem.free( myVec2.ary ); // ok ... JUST free ary mem as strings all freeded above
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end uniqueCountIC_readWord;
program ContactsVector2; // 2012-09-03 // testing vector2.hhf & vector2_func's.hhf
#includeOnce( "readLine.hhf" )
#includeOnce( "vector2_func's.hhf" ) // also has includes vector2.hhf
// NOTE that ALSO set by above include vector2.hhf ... ? @nodisplay:= true;
// So ... all procedures have @nodisplay 'as default' from here on ...
const
FNAME: text := """contacts.dat"""; // each """ includes one " in output
static
// global variables utilized in program (to keep it simple here)
Sorted: boolean := false;
Done: boolean := false;
Update: boolean := false;
type
MyContact: record
theName: string;
thePhone: string;
endrecord;
static
myBook: Vec; // Vec type was defined above in included file "vector2.hhf"
myC: MyContact;
procedure destroyRec( p: dword in eax ); @noframe;
begin destroyRec;
str.free( (type MyContact [eax]).theName );
str.free( (type MyContact [eax]).thePhone );
ret();
end destroyRec;
// for msort... by names ...
procedure myCmp( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmp;
if( str.le( (type MyContact [esi]).theName,
(type MyContact [edi]).theName ) ) then
mov( 1, eax );
else
mov( 0, eax );
endif;
end myCmp;
// for isort... by names ...
procedure myCmp2( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmp2;
if( str.lt( (type MyContact [esi]).theName,
(type MyContact [edi]).theName ) ) then
mov( 1, eax );
else
mov( 0, eax );
endif;
end myCmp2;
// for find by name ...
procedure myCmpEQ( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpEQ;
if( str.eq( (type MyContact [esi]).theName,
(type MyContact [edi]).theName ) ) then
mov( 1, eax );
else
mov( 0, eax );
endif;
end myCmpEQ;
procedure takeIn( message:string; value:string ); @returns("eax");
begin takeIn;
push( edi );
forever;
stdout.puts( message );
if( str.length( value ) > 0 ) then
stdout.put( "(", value, "): " );
else
stdout.puts( ": " );
endif;
stdin.flushInput();
stdin.a_gets();
mov( eax, edi );
// ensure first letter is Upper Case ...
mov( chars.toUpper( [edi] ), (type char [edi]) );
stdout.put("You input '", (type string edi), "' Ok (y/n) ? " );
stdin.getc();
chars.toLower( al );
if( al == 'y' ) then
mov( edi, eax );
break;
else
str.free( edi );
endif;
endfor;
pop( edi );
end takeIn;
procedure fileBook( var v: Vec );
var
fout: dword;
rsize: uns32;
begin fileBook;
push( eax ); push( ebx ); push( ecx ); push( edx );
try
fileio.openNew( FNAME ); // overwrites any existing file
mov( eax, fout );
mov( v, ebx );
mov( (type Vec [ebx]).elen, rsize );
for( mov( 0, ecx ); ecx < (type Vec [ebx]).size; inc( ecx ) ) do
mov( rsize, edx );
intmul( ecx, edx );
add( (type Vec [ebx]).ary, edx );
fileio.put( fout, (type MyContact[edx]).theName, nl );
fileio.put( fout, (type MyContact[edx]).thePhone, nl );
endfor;
fileio.close( fout );
exception( ex.FileOpenFailure )
stdout.put( "There was a problem opening file ", FNAME,
" for output." nl );
endtry;
pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end fileBook;
// Total number of contacts is stored in global variable RecCount
procedure addContacts( var v: Vec );
var
oldSize:uns32;
rsize: uns32;
static
newC: MyContact;
begin addContacts;
push( eax ); push( ebx ); push( ecx );
mov( v, ebx );
mov( (type Vec [ebx]).size, oldSize );
mov( (type Vec [ebx]).elen, rsize );
stdout.puts( "To abort/exit, just enter/accept an empty line "
"for 'name' or 'phone' ... " nl );
forever
mov( takeIn( "Enter name ", "" ), newC.theName );
mov( takeIn( "Enter phone ", "" ), newC.thePhone );
if( str.length(newC.theName) && str.length(newC.thePhone) ) then
push_backVec( (type Vec [ebx]), &newC );
else
str.free( newC.thePhone );
str.free( newC.theName );
stdout.puts( "Ok ... aborted ... " );
endif;
stdout.puts( nl "More y/n ? " );
stdin.flushInput();
stdin.getc();
chars.toLower( al );
breakif( al == 'n' );
endfor;
mov( (type Vec [ebx]).size, ecx );
if( ecx > oldSize ) then // Contacts were added ...
mov( &myCmp2, pMyCmp ); // so can isort... ok, when called ...
isortVec( (type Vec [ebx]) ); // also updates Update
mov( true, Sorted );
mov( true, Update );
endif;
pop( ecx ); pop( ebx); pop( eax );
end addContacts;
// returns count of records in file in Vec size parameter
procedure inputBook_fromFile( var v: Vec );
var
fin: dword;
static
myC: MyContact;
begin inputBook_fromFile;
push( eax ); push( ebx );
try
fileio.open( FNAME, fileio.r ); // open file for reading
mov( eax, fin );
mov( v, ebx );
while( !fileio.eof( fin) ) do
// allocate space for new string and
// mov pointer into array (of pointers)
fileio.a_gets( fin ); // returns new string in eax
mov( eax, myC.theName ); // get Contact
fileio.a_gets( fin);
mov( eax, myC.thePhone );
push_backVec( (type Vec [ebx]), &myC );
endwhile;
fileio.close( fin );
exception( ex.FileOpenFailure )
stdout.puts
(
nl "There was some problem reading your file. "
"Perhaps it dosen't exist?"
nl "Do want to start a new contact book (y/n) ? "
);
stdin.getc();
chars.toLower( al );
if( al == 'y' ) then
mov( v, ebx );
addContacts( (type Vec [ebx]) );
endif;
endtry;
pop( ebx ); pop( eax );
end inputBook_fromFile;
procedure editContact( var v: Vec; i: int32 in eax );
var
s: string;
begin editContact;
push( ebx );
mov( v, ebx );
if( (type Vec [ebx]).size > 0 ) then // need at least 1 record to edit
push( eax ); push( ecx ); push( edx );
mov( (type Vec [ebx]).elen, edx );
intmul( eax, edx );
add( (type Vec [ebx]).ary, edx );
// free old allocated strings and overwite with new ... (if updated )
mov( (type MyContact [edx]).theName, eax );
mov( eax, s ); // get copy of pointer into s ...
stdout.puts( "To abort/exit, just enter/accept an empty "
"line for a name ... " nl );
mov( takeIn( "Enter name ", s ), (type MyContact [edx]).theName );
if( str.length( (type MyContact [edx]).theName ) ) then // if NOT empty ...
str.free( s );
mov( (type MyContact [edx]).thePhone, eax );
mov( eax, s ); // get copy into s ...
mov( takeIn( "Enter phone ", s ), (type MyContact [edx]).thePhone );
str.free( s );
mov( &myCmp, pMyCmp ); // so can msort ok, when called ...
msortVec( (type Vec [ebx]) ); // also updates Update ...
mov( true, Sorted );
mov( true, Update );
else
str.free( (type MyContact [edx]).theName ); // free rejected entry ...
mov( mov( s, eax ), (type MyContact [edx]).theName ); // restore original
stdout.puts( "Ok ... edit aborted ... " nl );
endif;
pop( edx ); pop( ecx ); pop( eax );
endif;
pop( ebx );
end editContact;
/*
procedure deleteContact( var v: Vec );
var
index: uns32;
begin deleteContact;
push( ebx );
mov( v, ebx );
if( (type Vec [ebx]).size > 0 ) then // can't delete 0 records
push( eax ); push (ecx ); push( esi ); push( edi );
takeInValidNum( (type Vec [ebx]).size );
// returns valid num 1..RecCount in eax
dec( eax ); // to get to proper record index to delete
mov( eax, index );
mov( (type Vec [ebx]).elen, eax );
intmul( index, eax );
add( (type Vec [ebx]).ary, eax );
pFreeRec( eax );
// need at least 2 rec's to be able to move some down over one ...
mov( (type Vec [ebx]).size, ecx );
if( ecx > 1 ) then
cld();
mov( ecx, esi ); // if ecx-1 - eax > 1
dec( esi );
sub( index, esi );
if( esi > 0 ) then // copy last chunk down one record size
//inc( esi );
mov( esi, ecx );
intmul( (type Vec [ebx]).elen, ecx ); // bytes to mov in ecx
mov( (type Vec [ebx]).elen, edi );
intmul( index, edi );
add( (type Vec [ebx]).ary, edi );
mov( edi, esi );
add( (type Vec [ebx]).elen, esi );
rep.movsb();
endif;
endif;
dec( (type Vec [ebx]).size );
pop( edi ); pop( esi ); pop( ecx ); pop( eax );
endif;
pop( ebx );
end deleteContact;
*/
procedure showBook( var v: Vec );
var
lineCount: int32;
begin showBook;
push( eax ); push( ebx ); push( ecx );
// a little different formatting ...
console.cls();
stdout.puts
(
nl "Your 'book' : __________________________________________________" nl
);
mov( 2, lineCount );
mov( v, ebx );
for( mov( 0, ecx ); ecx < (type Vec [ebx]).size; inc( ecx ) ) do
inc( lineCount );
mov( (type Vec [ebx]).elen, eax );
intmul( ecx, eax );
add( (type Vec [ebx]).ary, eax );
stdout.puts( nl stdio.tab stdio.tab );
inc( ecx ); // to show 1,2,3 ... and not 0,1,2 ...
stdout.putu32Size( ecx, 3, '0' );
dec( ecx ); // now restore to 0,1,2 ...
stdout.put( ": ", (type MyContact [eax]).theName : -24 );
stdout.puts( " ---> " );
stdout.put( (type MyContact [eax]).thePhone : 15 )
endfor;
pop( ecx ); pop( ebx ); pop( eax );
end showBook;
procedure showMenu( var v: Vec );
var
s: string;
oldSize: uns32;
begin showMenu;
push( eax ); push( ebx );
mov( v, ebx );
showBook( (type Vec [ebx]) );
stdout.put
(
nl nl "Total contacts now in memory = ", (type Vec [ebx]).size,
", capacity = ", (type Vec [ebx]).capacity, "."
nl nl "Add, Delete, Edit, Sort, XDuplicates or Quit (a, d, e, s, x, q) ? "
);
stdin.flushInput();
stdin.getc();
chars.toLower( al );
if( al == 'a' ) then
addContacts( (type Vec [ebx]) );
elseif( al == 'd' ) then
//mov( &destroyRec, pFreeRec );
//deleteContact( (type Vec [ebx]) );
stdout.puts( "To abort/exit, just enter/accept an empty "
"line for a name ... " nl );
mov( takeIn( "Enter name to find", "" ),
myC.theName ); // returns in eax then copies pointer to myC.string
if( str.length( myC.theName ) ) then
mov( &myCmpEQ, pMyCmp ); // so can use findVec (EQ)
findVec( (type Vec [ebx]), &myC ); // returns index in eax (-1 if not found)
if( eax != -1 ) then
inc( eax ); // convert index to position ...
stdout.put( "Found at position ", (type uns32 eax), " so erasing ... " nl );
dec( eax ); // now restore as index ...
mov( &destroyRec, pFreeRec );
eraseVec( (type Vec [ebx]), eax ); // a library proc
else
stdout.put( myC.theName, " was NOT found ... " nl );
str.free( myC.theName );
endif;
else
str.free( myC.theName );
stdout.puts( "Ok ... aborting delete ... " nl );
endif;
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
elseif( al == 'e' ) then
stdout.puts( "To abort/exit, just enter/accept an empty "
"line for a name ... " nl );
mov( takeIn( "Enter name to find", "" ),
myC.theName ); // returns in eax then copies pointer to myC.string
if( str.length( myC.theName ) ) then
mov( &myCmpEQ, pMyCmp ); // so can use findVec (EQ)
findVec( (type Vec [ebx]), &myC ); // returns indwx in eax (-1 if not found)
if( eax != -1 ) then
stdout.put( "Found at index ", (type uns32 eax), nl );
editContact( (type Vec [ebx]), eax );
else
stdout.put( myC.theName, " was NOT found ... " nl );
str.free( myC.theName );
endif;
else
str.free( myC.theName );
stdout.puts( "Ok ... aborting edit ... " nl );
endif;
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
elseif( al == 's' ) then
mov( &myCmp, pMyCmp ); // so can msort... ok, when called
msortVec( (type Vec [ebx]) );
mov( true, Sorted );
mov( true, Update );
elseif( al == 'x' ) then
if( !Sorted ) then
mov( &myCmp, pMyCmp ); // so can msort... ok, when called
msortVec( (type Vec [ebx]) );
mov( true, Sorted );
mov( true, Update );
endif;
mov( &myCmpEQ, pMyCmp ); // so can cmp (EQ)... ok, when called
mov( &destroyRec, pFreeRec );
mov( v, ebx );
mov( (type Vec [ebx]).size, oldSize );
xDuplicates( (type Vec [ebx]) ); // pre-sort array to 'chop' duplicates
mov( (type Vec [ebx]).size, eax );
if( eax < oldSize ) then
mov( true, Update ); // and ... will update 'contacts.dat' file
endif;
elseif( al == 'q' ) then
mov( true, Done ); // 'Done' is also a global variable
endif;
pop( ebx ); pop( eax );
end showMenu;
begin ContactsVector2;
initVec( myBook, @size(MyContact) );
reserveVec( myBook, 3 );
mov( &destroyRec, pFreeRec );
inputBook_fromFile( myBook ); // returns the record count in size parameter
repeat
showMenu( myBook );
until( Done );
if( Update ) then
fileBook( myBook );
stdout.put( nl "Ok ... your BOOK should NOW be filed in file '",
FNAME, "' ... " nl );
endif; // update file with changes ...
stdout.put( nl "Before clear... myBook.size = ", myBook.size,
", myBook.capacity = ", myBook.capacity, nl );
clearVec( myBook );
stdout.put( "After clear... myBook.size = ", myBook.size,
", myBook.capacity = ", myBook.capacity, nl );
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end ContactsVector2;
program ContactsSLList2; // 2012-09-03 // testing sllist2.hhf & sllist2_func's.hhf
#includeOnce( "readLine.hhf" )
#includeOnce( "sllist2_func's.hhf" ) // also has includes sllist2.hhf
// NOTE that ALSO set by above include sslist2.hhf ... ? @nodisplay:= true;
// So ... all procedures have @nodisplay 'as default' from here on ...
const
FNAME: text := """contacts.dat"""; // each """ includes one " in output
static
// global variables utilized in program (to keep it simple here)
Sorted: boolean := false;
Done: boolean := false;
Update: boolean := false;
type
MyContact: record
theName: string;
thePhone: string;
endrecord;
static
myBook: SLList; // SLList type was defined above in included file "sllist2.hhf"
procedure destroyMyC( p: dword in eax ); @noframe;
begin destroyMyC;
push( ebx );
mov( [eax], ebx );
str.free( (type MyContact [ebx]).theName );
str.free( (type MyContact [ebx]).thePhone );
mem.free( ebx );
pop( ebx );
ret();
end destroyMyC;
// for isort/msort... by names ...
procedure myCmp( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmp;
push( ebx );
mov( [esi], eax );
mov( [edi], ebx );
if( str.le( (type MyContact [eax]).theName,
(type MyContact [ebx]).theName ) ) then
mov( 1, eax );
else
mov( 0, eax );
endif;
pop( ebx );
end myCmp;
// for find by name ...
procedure myCmpEQ( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpEQ;
push( ebx );
mov( [esi], eax );
mov( [edi], ebx );
if( str.eq( (type MyContact [eax]).theName,
(type MyContact [ebx]).theName ) ) then
mov( 1, eax );
else
mov( 0, eax );
endif;
pop( ebx );
end myCmpEQ;
// returns string 'taken in' in eax ...
procedure takeIn( message:string; value:string ); @returns("eax");
begin takeIn;
push( edi );
forever;
stdout.puts( message );
if( str.length( value ) > 0 ) then
stdout.put( "(", value, "): " );
else
stdout.puts( ": " );
endif;
stdin.flushInput();
stdin.a_gets();
mov( eax, edi );
// ensure first letter is Upper Case ...
mov( mov( chars.toUpper( [edi] ), al), (type char [edi]) );
stdout.put("You input '", (type string edi), "' Ok (y/n) ? " );
stdin.getc();
chars.toLower( al );
if( al == 'y' ) then
mov( edi, eax );
break;
else
str.free( edi );
endif;
endfor;
pop( edi );
end takeIn;
procedure fileBook( var sll: SLList );
var
fout: dword;
begin fileBook;
push( eax ); push( ebx );
try
fileio.openNew( FNAME ); // overwrites any existing file
mov( eax, fout );
mov( sll, eax );
mov( (type SLList [eax]).head, eax );
while( eax ) do
mov( [eax], ebx );
fileio.put( fout, (type MyContact [ebx]).theName, nl );
fileio.put( fout, (type MyContact [ebx]).thePhone, nl );
mov( (type NNode[eax]).next, eax );
endwhile;
fileio.close( fout );
exception( ex.FileOpenFailure )
stdout.put( "There was a problem opening file ", FNAME,
" for output." nl );
endtry;
pop( ebx ); pop( eax );
end fileBook;
// Total number of contacts is stored in global variable RecCount
procedure addContacts( var sll: SLList );
var
newNNode: NNode;
oldSize: uns32;
begin addContacts;
push( eax ); push( ebx ); push( ecx );
mov( sll, ebx );
mov( (type SLList [ebx]).size, eax );
mov( eax, oldSize );
mov( (type SLList [ebx]).head, eax );
stdout.puts( "To abort/exit, just enter/accept an empty line "
"for 'name' or 'phone' ... " nl );
forever
mem.alloc( @size( MyContact ) );
mov( eax, ecx );
mov( takeIn( "Enter name ", "" ), (type MyContact [ecx]).theName );
mov( takeIn( "Enter phone ", "" ), (type MyContact [ecx]).thePhone );
if( str.length( (type MyContact [ecx]).theName ) &&
str.length( (type MyContact [ecx]).thePhone ) ) then
mov( ecx, newNNode.nval );
push_backSLList( (type SLList [ebx]), newNNode );
else
str.free( (type MyContact [ecx]).thePhone );
str.free( (type MyContact [ecx]).theName );
stdout.puts( "Ok ... aborted ... " );
endif;
stdout.puts( nl "More y/n ? " );
stdin.flushInput();
stdin.getc();
chars.toLower( al );
breakif( al == 'n' );
endfor;
mov( (type SLList [ebx]).size, ecx );
if( ecx > oldSize ) then // Contacts were added ...
mov( &myCmp, pMyCmp ); // so can msort... ok, when called ...
msortSLList( (type SLList [ebx]) ); // also updates Update
mov( true, Sorted );
mov( true, Update );
endif;
pop( ecx ); pop( ebx); pop( eax );
end addContacts;
// returns count of records in file in SLList size parameter
procedure inputBook_fromFile( var sll: SLList );
var
fin: dword;
newNNode: NNode;
begin inputBook_fromFile;
push( eax ); push( ebx ); push( ecx );
try
fileio.open( FNAME, fileio.r ); // open file for reading
mov( eax, fin );
mov( sll, ebx );
while( !fileio.eof( fin) ) do
mem.alloc( @size( MyContact ) );
mov( eax, ecx );
// allocate space for new string and
// mov pointer into array (of pointers)
fileio.a_gets( fin ); // returns new string in eax
mov( eax, (type MyContact [ecx]).theName ); // get Contact
fileio.a_gets( fin);
mov( eax, (type MyContact [ecx]).thePhone );
mov( ecx, newNNode.nval );
push_backSLList( (type SLList [ebx]), newNNode );
endwhile;
fileio.close( fin );
exception( ex.FileOpenFailure )
stdout.puts
(
nl "There was some problem reading your file. "
"Perhaps it dosen't exist?"
nl "Do want to start a new contact book (y/n) ? "
);
stdin.getc();
chars.toLower( al );
if( al == 'y' ) then
mov( sll, ebx );
addContacts( (type SLList [ebx]) );
endif;
endtry;
pop( ecx ); pop( ebx ); pop( eax );
end inputBook_fromFile;
procedure editContact( var sll: SLList; pn: dword in eax );
var
s: string;
begin editContact;
push( ebx ); push( ecx ); push( edx );
mov( sll, ebx );
if( (type SLList [ebx]).size > 0 ) then // need at least 1 record to edit
// free old allocated strings and overwite with new ... (if updated )
mov( [eax], ecx ); // derefence pointer
mov( (type MyContact [ecx]).theName, edx );
mov( edx, s ); // get copy of pointer into s ...
stdout.puts( "To abort/exit, just enter/accept an empty "
"line for a name ... " nl );
mov( takeIn( "Enter name ", s ), (type MyContact [ecx]).theName );
if( str.length( (type MyContact [ecx]).theName ) ) then // if NOT empty ...
str.free( s );
mov( (type MyContact [ecx]).thePhone, edx );
mov( edx, s ); // get copy into s ...
mov( takeIn( "Enter phone ", s ), (type MyContact [ecx]).thePhone );
str.free( s );
mov( &myCmp, pMyCmp ); // so can msort ok, when called ...
msortSLList( (type SLList [ebx]) ); // also updates Update ...
mov( true, Sorted );
mov( true, Update );
else
str.free( (type MyContact [ecx]).theName ); // free rejected entry ...
mov( mov( s, edx ), (type MyContact [ecx]).theName ); // restore original
stdout.puts( "Ok ... edit aborted ... " nl );
endif;
endif;
pop( edx ); pop( ecx ); pop( ebx );
end editContact;
procedure showBook( var sll: SLList );
var
lineCount: int32;
begin showBook;
push( eax ); push( ebx ); push( ecx ); push( edx );
// a little different formatting ...
console.cls();
stdout.puts
(
nl "Your 'book' : __________________________________________________" nl
);
mov( 2, lineCount );
mov( sll, ebx );
mov( (type SLList [ebx]).head, eax );
mov( 0, ecx );
while( eax ) do
inc( lineCount );
stdout.puts( nl stdio.tab stdio.tab );
inc( ecx ); // to show 1,2,3 ... and not 0,1,2 ...
stdout.putu32Size( ecx, 3, '0' );
mov( [eax], edx );
stdout.put( ": ", (type MyContact [edx]).theName : -24 );
stdout.puts( " ---> " );
stdout.put( (type MyContact [edx]).thePhone : 15 );
mov( (type NNode [eax]).next, eax );
endwhile;
pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end showBook;
procedure showMenu( var sll: SLList );
var
s: string;
oldSize: uns32;
myC: MyContact;
myNNode: NNode;
begin showMenu;
push( eax ); push( ebx );
mov( sll, ebx );
showBook( (type SLList [ebx]) );
stdout.put
(
nl nl "Total contacts now in memory = ", (type SLList [ebx]).size,
nl nl "Add, Delete, Edit, Sort, XDuplicates or Quit (a, d, e, s, x, q) ? "
);
stdin.flushInput();
stdin.getc();
chars.toLower( al );
if( al == 'a' ) then
addContacts( (type SLList [ebx]) );
elseif( al == 'd' ) then
stdout.puts( "To abort/exit, just enter/accept an empty "
"line for a name ... " nl );
mov( takeIn( "Enter name to find", "" ),
myC.theName ); // returns in eax then copies pointer to myC.string
if( str.length( myC.theName ) ) then
mov( &myCmpEQ, pMyCmp ); // so can use findVec (EQ)
findSLList( (type SLList [ebx]), myC ); // returns pointer or 0
if( eax ) then
stdout.put( "Found ... so erasing ... " nl );
mov( &destroyMyC, pFreeNNode );
eraseSLList( (type SLList [ebx]), eax ); // a library proc
else
stdout.put( myC.theName, " was NOT found ... " nl );
str.free( myC.theName );
endif;
else
str.free( myC.theName );
stdout.puts( "Ok ... aborting delete ... " nl );
endif;
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
elseif( al == 'e' ) then
mem.alloc( @size( MyContact ) );
mov( eax, ecx );
stdout.puts( "To abort/exit, just enter/accept an empty "
"line for a name ... " nl );
mov( takeIn( "Enter name to find", "" ), // returns in eax then copies pointer ...
(type MyContact [ecx]).theName );
if( str.length( (type MyContact [ecx]).theName ) ) then
mov( &myCmpEQ, pMyCmp ); // so can use findSLList (EQ)
mov( ecx, myNNode.nval );
findSLList( (type SLList [ebx]), myNNode ); // returns pointer or 0
if( eax ) then
stdout.put( "Found ... ", nl );
editContact( (type SLList [ebx]), eax );
else
stdout.put( myC.theName, " was NOT found ... " nl );
str.free( myC.theName );
endif;
else
str.free( myC.theName );
stdout.puts( "Ok ... aborting edit ... " nl );
endif;
mem.free( ecx );
stdout.put( nl "Press 'Enter' to continue ... " );
stdin.readLn();
elseif( al == 's' ) then
mov( &myCmp, pMyCmp ); // so can msort... ok, when called
msortSLList( (type SLList [ebx]) );
mov( true, Sorted );
mov( true, Update );
elseif( al == 'x' ) then
if( !Sorted ) then
mov( &myCmp, pMyCmp ); // so can msort... ok, when called
msortSLList( (type SLList [ebx]) );
mov( true, Sorted );
mov( true, Update );
endif;
mov( &myCmpEQ, pMyCmp ); // so can cmp (EQ)... ok, when called
mov( &destroyMyC, pFreeNNode );
mov( sll, ebx );
mov( (type SLList [ebx]).size, oldSize );
uniqueSLList( (type SLList [ebx]) ); // pre-sort array to 'chop' duplicates
mov( (type SLList [ebx]).size, eax );
if( eax < oldSize ) then
mov( true, Update ); // and ... will update 'contacts.dat' file
endif;
elseif( al == 'q' ) then
mov( true, Done ); // 'Done' is also a global variable
endif;
pop( ebx ); pop( eax );
end showMenu;
begin ContactsSLList2;
initSLList( myBook );
mov( &destroyMyC, pFreeNNode );
inputBook_fromFile( myBook ); // returns the record count in size parameter
repeat
showMenu( myBook );
until( Done );
if( Update ) then
fileBook( myBook );
stdout.put( nl "Ok ... your BOOK should NOW be filed in file '",
FNAME, "' ... " nl );
endif; // update file if changes ...
stdout.put( nl "Before clear... myBook.size = ", myBook.size, nl );
clearSLList( myBook );
stdout.put( "After clear... myBook.size = ", myBook.size, nl );
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end ContactsSLList2;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
z 3456789 123456789 123456789
2z
32z
444z
5555z
66666z
777z
88z
9z
z
program testVec2StrInt; // 2012-09-03 //
#includeOnce( "readWord.hhf" )
const
Fname: text := """testStr.dat""" ;
Fname2: text := """testInt.dat""" ;
InitCap: uns32 := 2; // Note: if NOT defined here defaults to 8
// kept small for testing of Vec memory reallocates
#includeOnce( "vector2_func's.hhf" ); // Note: has #includeOnce("vector2.hhf");
// and "vector2.hhf" has ? @nodisplay:= true;
// so all procedures have @nodisplay 'as default'
// Ok ... now we need to define our records ...
// and free rec procedures (to handle potential case of dynamic memory)
type
Rec: record
str: string;
endrecord;
procedure freeRec( pr: dword in eax ); @noframe;
begin freeRec;
str.free( (type Rec [eax]).str );
ret();
end freeRec;
type
Rec2: record
i32: int32;
endrecord;
procedure freeRec2( pr: dword in eax ); @noframe;
begin freeRec2;
// no dynamic memory to free here ...
ret();
end freeRec2;
// Now ... we can define our compare functions to be used by find and sort ...
// re. isort...
procedure myCmp( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmp;
if( str.lt( (type Rec [esi]).str, (type Rec [edi]).str ) ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmp;
// re. msort...
procedure myCmpLE( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpLE;
if( str.le( (type Rec [esi]).str, (type Rec [edi]).str ) ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpLE;
// re. isort...
procedure myCmpRev( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpRev;
if( str.gt( (type Rec [esi]).str, (type Rec [edi]).str ) ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpRev;
// re. find...
procedure myCmpEQ( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpEQ;
if( str.eq( (type Rec [esi]).str, (type Rec [edi]).str ) ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpEQ;
// re. comparing int32 ... for msort reverse order... recall >= is used
procedure myCmpIntRev( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpIntRev;
mov( (type Rec2 [esi]).i32, esi );
mov( (type Rec2 [edi]).i32, eax );
if( (type int32 esi) >= eax ) then mov( 1, eax ); // i.e. descending sort
else mov( 0, eax );
endif;
end myCmpIntRev;
// re. find int32...
procedure myCmpEQRec2( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpEQRec2;
mov( (type Rec2 [esi]).i32, esi );
mov( (type Rec2 [edi]).i32, eax );
if( (type int32 esi) == eax ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpEQRec2;
// so can reuse showVec with different showRec's ...
static
pShowRec: procedure( pr: dword in eax ); // get a proc pointer
// Now .. define show record ... for each different record ...
procedure showRec( pr: dword in eax ); @noframe;
begin showRec;
stdout.puts( (type Rec [eax]).str );
ret();
end showRec;
procedure showRec2( pr: dword in eax ); @noframe;
begin showRec2;
stdout.puti32( [eax] );
ret();
end showRec2;
// using above procedure pointer pShowRec ... can define showVec
procedure showVec( var v: Vec );
begin showVec;
push( eax ); push( ebx ); push( ecx );
mov( v, ebx );
for( mov( 0, ecx ); ecx < (type Vec[ebx]).size; inc( ecx ) ) do
mov( ecx, eax );
intmul( (type Vec [ebx]).elen, eax );
add( (type Vec[ebx]).ary, eax );
pShowRec( eax );
stdout.putc( ' ' );
endfor;
pop( ecx ); pop( ebx ); pop( eax );
end showVec;
static
fin: dword; // file handle
myRec: Rec; // get some objects with memory ...
myRec2: Rec2;
myVec: Vec;
myVec2: Vec;
tmpStr: string;
begin testVec2StrInt;
// get some strings from file into a Vec using push_backVec...
fileio.open( Fname, fileio.r );
mov( eax, fin );
initVec( myVec, @size(Rec) ); // Note: must initial for Vec to work
while( readWord( fin, myRec.str, " " nl stdio.tab ) ) do
push_backVec( myVec, &myRec ); // Note here, passing Vec by ref and Rec by pointer
endwhile;
fileio.close( fin );
stdout.puts( "Showing vec of str ... " nl );
mov( &showRec, pShowRec );
showVec( myVec );
stdout.put( "size = ", myVec.size, ", capacity = ", myVec.capacity, nl );
mov( &myCmp, pMyCmp );
isortVec( myVec );
stdout.puts( nl "Showing insert sorted vec of str ... " nl );
showVec( myVec );
stdout.put( "size = ", myVec.size, ", capacity = ", myVec.capacity, nl )
mov( &myCmpRev, pMyCmp );
isortVec( myVec );
stdout.puts( nl "Showing insert sorted REVERSE vec of str ... " nl );
showVec( myVec );
stdout.put( "size = ", myVec.size, ", capacity = ", myVec.capacity, nl );
mov( &myCmpLE, pMyCmp );
msortVec( myVec );
stdout.puts( nl "Showing merge sorted vec of str ... " nl );
showVec( myVec );
stdout.put( "size = ", myVec.size, ", capacity = ", myVec.capacity, nl nl );
str.a_cpy( "777z" );
mov( eax, myRec.str );
mov( &myCmpEQ, pMyCmp );
findVec( myVec, &myRec );
mov( &freeRec, pFreeRec );
if( (type int32 eax) != -1 ) then
stdout.put( "'", myRec.str, "' WAS FOUND at index ", (type int32 eax), nl );
stdout.puts( "So after erasing ... vec is ... " nl );
eraseVec( myVec, eax );
showVec( myVec );
else
stdout.put( "'", myRec.str, "' was NOT found in the vector ... ", nl );
endif;
// ok ... clean up all dynamic memory when 'done'
str.free( myRec.str );
//mov( &freeRec, pFreeRec ); // done above before erase ...
clearVec( myVec );
stdout.puts( nl "Press 'Enter' to continue to Vec of integers from file ... " );
stdin.readLn();
// get some int's from an int file into a different Vec (using push_backVec...)
fileio.open( Fname2, fileio.r );
mov( eax, fin );
initVec( myVec2, @size(Rec2) );
while( readWord( fin, tmpStr, " " nl stdio.tab ) ) do
conv.strToi32( tmpStr, 0 ); // begin at index 0 ...
mov( eax, myRec2.i32 );
push_backVec( myVec2, &myRec2 );
endwhile;
fileio.close( fin );
stdout.puts( "Showing vec of int32 ... " nl );
mov( &showRec2, pShowRec );
showVec( myVec2 );
stdout.put( "size = ", myVec2.size, ", capacity = ", myVec2.capacity, nl );
mov( &myCmpIntRev, pMyCmp );
msortVec( myVec2 );
stdout.puts( nl "Showing merge sorted (reverse) vec of int32 ... " nl );
showVec( myVec2 );
stdout.put( "size = ", myVec2.size, ", capacity = ", myVec2.capacity, nl );
mov( 11, myRec2.i32 );
mov( &myCmpEQRec2, pMyCmp );
findVec( myVec2, &myRec2 );
mov( &freeRec2, pFreeRec );
if( (type int32 eax) != -1 ) then
stdout.put( nl "'", myRec2.i32, "' WAS FOUND at index ", (type int32 eax), nl );
stdout.puts( nl "So after erasing ... vec is ... " nl );
eraseVec( myVec2, eax );
showVec( myVec2 );
else
stdout.put( "'", myRec2.i32, "' was NOT found in the vector ... ", nl );
endif;
stdout.put( "size = ", myVec2.size, ", capacity = ", myVec2.capacity, nl nl );
// mov( &freeRec2, pFreeRec ); // done above before erase ...
clearVec( myVec2 );
stdout.put( "After clear... size = ", myVec2.size, ", capacity = ",
myVec2.capacity, nl nl );
stdout.puts( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end testVec2StrInt;
program testSLList2StrInt; // 2012-09-03 //
#includeOnce( "readWord.hhf" ) // Note: has ? @nodisplay:= true; ... so all
// procedures have @nodisplay 'as default'
#includeOnce( "sllist2_func's.hhf" ); // Note: has #includeOnce("sllist2.hhf");
const
Fname: text := """testStr.dat""" ;
Fname2: text := """testInt.dat""" ;
// Ok ... now we need to define our records ...
// and free NNode procedures (to handle potential case of dynamic memory)
procedure freeStrNNode( pr: dword in eax ); @noframe;
begin freeStrNNode;
str.free( (type NNode [eax]).nval );
ret();
end freeStrNNode;
procedure freeIntNNode( pr: dword in eax ); @noframe;
begin freeIntNNode;
// no dynamic memory to free here ...
ret();
end freeIntNNode;
// Now ... we can define our compare functions to be used by find and sort ...
// re. msort/isort...
procedure myCmpLE( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpLE;
if( str.le( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpLE;
// re. msort/isort...
procedure myCmpRev( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpRev;
if( str.ge( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpRev;
// re. find...
procedure myCmpEQ( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpEQ;
if( str.eq( (type NNode [esi]).nval, (type NNode [edi]).nval ) ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpEQ;
// re. comparing int32 ... for isort/msort reverse order... recall >= used
procedure myCmpIntRev( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpIntRev;
mov( (type NNode [esi]).nval, eax );
if( (type int32 eax) >= (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpIntRev;
// for isort/msort ascending ...
procedure myCmpInt( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpInt;
mov( (type NNode [esi]).nval, eax );
if( (type int32 eax) <= (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
// re. find int32...
procedure myCmpEQInt( a: dword in esi; b: dword in edi ); @returns("eax");
begin myCmpEQInt;
mov( (type NNode [esi]).nval, eax );
if( eax == (type NNode [edi]).nval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpEQInt;
// so can reuse showSLList with different showRec's ...
static
pShowNNode: procedure( pr: dword in eax ); // get a proc pointer
// Now .. define show record ... for each different record ...
procedure showNNodeStr( pr: dword in eax ); @noframe;
begin showNNodeStr;
stdout.puts( (type NNode [eax]).nval );
ret();
end showNNodeStr;
procedure showNNodeInt( pr: dword in eax ); @noframe;
begin showNNodeInt;
stdout.puti32( (type NNode [eax]).nval );
ret();
end showNNodeInt;
// using above procedure pointer pShowNNode ... can define showSLList
procedure showSLList( var v: SLList );
begin showSLList;
push( eax );
mov( v, eax );
mov( (type SLList[eax]).head, eax );
while( eax ) do
pShowNNode( eax );
mov( (type NNode[eax]).next, eax );
stdout.putc( ' ' );
endwhile;
pop( eax );
end showSLList;
static
fin: dword; // file handle
myNNode: NNode;
mySLList: SLList;
mySLList2: SLList;
tmpStr: string;
begin testSLList2StrInt;
// get some strings from file into a SLList using push_backSLList...
fileio.open( Fname, fileio.r );
mov( eax, fin );
initSLList( mySLList ); // Note: must initial for SLList to work
while( readWord( fin, myNNode.nval, " " nl stdio.tab ) ) do
push_backSLList( mySLList, myNNode ); // Note here, passing SLList and myNNode by ref
endwhile;
fileio.close( fin );
stdout.puts( "Showing SLList of string ... " nl );
mov( &showNNodeStr, pShowNNode );
showSLList( mySLList );
stdout.put( "size = ", mySLList.size, nl );
mov( &myCmpLE, pMyCmp );
isortSLList( mySLList );
stdout.puts( nl "Showing insert sorted SLList of str ... " nl );
showSLList( mySLList );
stdout.put( "size = ", mySLList.size, nl )
mov( &myCmpRev, pMyCmp );
isortSLList( mySLList );
stdout.puts( nl "Showing insert sorted REVERSE SLList of str ... " nl );
showSLList( mySLList );
stdout.put( "size = ", mySLList.size, nl );
mov( &myCmpLE, pMyCmp );
msortSLList( mySLList );
stdout.puts( nl "Showing merge sorted SLList of str ... " nl );
showSLList( mySLList );
stdout.put( "size = ", mySLList.size, nl nl );
str.a_cpy( "777z" );
mov( eax, myNNode.nval );
mov( &myCmpEQ, pMyCmp );
findSLList( mySLList, myNNode );
mov( &freeStrNNode, pFreeNNode );
if( eax ) then
stdout.puts( "Found ... So erasing ... and SLList now is ... " nl );
eraseSLList( mySLList, eax );
showSLList( mySLList );
else
stdout.put( "'", (type string myNNode.nval), "' was NOT found in the SLList ... ", nl );
endif;
// ok ... clean up all dynamic memory when 'done'
str.free( myNNode.nval );
//mov( &freeStrNNode, pFreeNNode ); // done above ...(before erase)
clearSLList( mySLList );
stdout.puts( nl "Press 'Enter' to continue to SLList of integers from file ... " );
stdin.readLn();
// get some int's from an int file into a different SLList (using push_backSLList...)
fileio.open( Fname2, fileio.r );
mov( eax, fin );
initSLList( mySLList2 );
while( readWord( fin, tmpStr, " " nl stdio.tab ) ) do
conv.strToi32( tmpStr, 0 ); // begin at index 0 ...
mov( eax, myNNode.nval );
push_backSLList( mySLList2, myNNode );
str.free( tmpStr );
endwhile;
fileio.close( fin );
stdout.puts( "Showing SLList of int32 ... " nl );
mov( &showNNodeInt, pShowNNode );
showSLList( mySLList2 );
stdout.put( "size = ", mySLList2.size, nl );
mov( &myCmpIntRev, pMyCmp );
msortSLList( mySLList2 );
stdout.puts( nl "Showing merge sorted (reverse) SLList of int32 ... " nl );
showSLList( mySLList2 );
stdout.put( "size = ", mySLList2.size, nl );
mov( 11, myNNode.nval );
mov( &myCmpEQInt, pMyCmp );
findSLList( mySLList2, myNNode );
mov( &freeIntNNode, pFreeNNode );
if( eax ) then
stdout.put( nl "Found ", (type int32 myNNode.nval),
" so after erasing SLList is ... " nl );
eraseSLList( mySLList2, eax );
showSLList( mySLList2 );
else
stdout.put( "'", (type int32 myNNode.nval), "' was NOT found in the SLList ... ", nl );
endif;
stdout.puts( nl "Showing insert sorted SLList of int32 ... " nl );
mov( &myCmpInt, pMyCmp );
isortSLList( mySLList2 );
showSLList( mySLList2 );
stdout.put( "size = ", mySLList2.size, nl );;
// mov( &freeIntNNode, pFreeNNode ); // done above before erase ...
clearSLList( mySLList2 );
stdout.put( "After clear... size = ", mySLList2.size, nl nl );
stdout.puts( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn();
end testSLList2StrInt;
/* msortVecInt.hla */ /* this version 2012-08-22 */
/*
NOTE!
FILE READ ERROR if NL char at end of file of integers ...
SO ... first MUST ensure all non-numeric char's, are trimmed from
the end of the file of integers ... can use a text editor !
*/
/*
http://developers-heaven.net/forum/index.php/topic,46.0.html
*/
program msortVecIntLarge;
const
InitCap: uns32 := 3000000; // to hold 3 Million random int's
HEADER: string := "HLA program to sort 3 Million random int's from file"
#13 #10 "stored in an HLA user defined type Vec...";
//#includeOnce( "readWord.hhf" )
type
Rec: record
rval: int32;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @noframe;
begin freeRec;
// NO dynamic memory here to free ...
ret();
end freeRec;
// ok ... after above two types defined ... now can ...
#includeOnce( "vector_func's.hhf" )
procedure myCmpInt( a: pRec in esi; b: pRec in edi ); @returns( "eax" );
begin myCmpInt;
mov( (type Rec [esi]).rval, eax );
if( eax <= (type Rec [edi]).rval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure isSorted( var v: Vec ); @returns( "eax" );
begin isSorted;
mov( v, ebx );
mov( (type Vec [ebx]).size, ecx );
dec( ecx );
intmul( @size( Rec ), ecx, eax );
add( (type Vec [ebx]).ary, eax );
mov( (type Rec [eax]).rval, edi );
while( (type int32 ecx) > 0 ) do
dec( ecx );
sub( @size( Rec ), eax );
mov( (type Rec [eax]).rval, esi );
if( (type int32 esi) > edi ) then
mov( 0, eax );
break;
endif;
mov( esi, edi );
endwhile;
mov( 1, eax );
end isSorted;
static
myVec: Vec;
myRec: Rec;
fin: dword;
tmpStr: string;
clock: timer_t;
begin msortVecIntLarge;
stdout.put( HEADER, nl nl );
initVec( myVec );
clock.create();
clock.start();
fileio.open( "randInt3M.txt", fileio.r );
mov( eax, fin );
while( !fileio.eof( fin ) ) do
fileio.geti32( fin );
mov( eax, myRec.rval );
// push( ebx ); push( ecx ); push( esi ); push( edi ); // if needed //
push_backVec( myVec, myRec );
endwhile;
clock.stop();
stdout.put( nl "To fill Vec from file ... ms = ", (type uns64 clock.Accumulated), nl );
clock.start();
mov( &myCmpInt, pMyCmp );
msortVec( myVec );
clock.stop();
stdout.put( nl "To msort ... ms = ", (type uns64 clock.Accumulated), nl );
isSorted( myVec );
stdout.put( "isSorted( myVec ) = ", (type boolean al) );
stdout.puts( nl nl "Press 'Enter' to exit/continue ... " );
stdin.readLn();
end msortVecIntLarge;
#if( false )
int main( void ) /* ***************************************************** */
{
FILE* fp;
double ti, tp;
int i, valToFind;
Rec r;
Cvec cv;
initCvec( &cv ); /* Note: MUST initial Cvec v ... for Cvec to work */
puts( HEADER );
ti = clock();
fp = fopen( "randInt3M.txt", "r" );
while( 1 == fscanf( fp, "%d", &r.val ) )
{
push_backCvec( &cv, &r ); /* since good Rec was obtained */
/*if( cv.size == 32768*3 ) break; // 32768*11 */
}
tp = clock() - ti;
printf( "%d int's were read from file in %.2f sec's ... ",
cv.size, tp/CLOCKS_PER_SEC );
ti = clock();
msort( &cv );
tp = clock() - ti;
printf( "merge sorted in %.2f sec's", tp/CLOCKS_PER_SEC );
printf( "\nand isSorted( &v ) = %d\n", isSorted( &cv ) );
ti = clock();
uniqueCvec( &cv );
tp = clock() - ti;
printf( "\nuniqueCvec in %.2f sec's", tp/CLOCKS_PER_SEC );
printf( " ... and isSorted( &cv ) = %d ", isSorted( &cv ) );
printf( "\n... and isUniqueCvec( &cv ) = %d\n",
isUniqueCvec( &cv ) & cv.isSorted );
printf( "\nAfter uniqueCvec: cv.size = %d, cv.cap = %d\n\n", cv.size, cv.cap );
valToFind = cv.ary[cv.size-1].val;
ti = clock();
i = findCvec( &cv, valToFind );
if( i != -1 )
{
eraseCvec( &cv, i );
tp = clock() - ti;
printf( "%d was erased ...", valToFind);
printf( "%d is new end val...\n", cv.ary[cv.size-1].val);
printf( "find/ereaseCvec in %.2f sec's\n\n", tp/CLOCKS_PER_SEC );
}
else printf( "%d was NOT-found/NOT-erased ...\n\n", valToFind );
myShowAll( &cv );
printf( "Before clearCvec: cv.size = %d, cv.cap = %d\n", cv.size, cv.cap );
clearCvec( &cv );
printf( "After clearCvec: cv.size = %d, cv.cap = %d\n", cv.size, cv.cap );
fclose( fp );
fputs( "\nPress 'Enter' to continue ... ", stdout );
getchar();
return 0;
} /* ******************************************************************** */
#endif
/* msortVecInt2.hla */ /* this version 2012-08-22 */
/*
http://developers-heaven.net/forum/index.php/topic,46.0.html
*/
program msortVecIntLarge;
const
InitCap: uns32 := 3_000_000; // to hold 3 Million random int's
HEADER: string := "HLA program to sort 3 Million random int's from file"
#13 #10 "stored in an HLA user defined type Vec...";
type
Rec: record
rval: int32;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @noframe;
begin freeRec;
// NO dynamic memory here to free ...
ret();
end freeRec;
// ok ... after above two types defined ... now can ...
#includeOnce( "vector_func's.hhf" )
procedure myCmpInt( a: pRec in esi; b: pRec in edi ); @returns( "eax" );
begin myCmpInt;
mov( (type Rec [esi]).rval, eax );
if( eax <= (type Rec [edi]).rval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure isSorted( var v: Vec ); @returns( "eax" );
begin isSorted;
mov( v, ebx );
mov( (type Vec [ebx]).size, ecx );
dec( ecx );
intmul( @size( Rec ), ecx, eax );
add( (type Vec [ebx]).ary, eax );
mov( (type Rec [eax]).rval, edi );
while( (type int32 ecx) > 0 ) do
dec( ecx );
sub( @size( Rec ), eax );
mov( (type Rec [eax]).rval, esi );
if( (type int32 esi) > edi ) then
mov( 0, eax );
break;
endif;
mov( esi, edi );
endwhile;
mov( 1, eax );
end isSorted;
static
myVec: Vec;
myRec: Rec;
fin: dword;
tmpStr: string;
clock: timer_t;
line: str.strvar( 256 ); // lines here are less than 100 char's
begin msortVecIntLarge;
stdout.put( HEADER, nl nl );
initVec( myVec );
clock.create();
clock.start();
fileio.open( "randInt3M.txt", fileio.r );
mov( eax, fin );
while( !fileio.eof( fin ) ) do
fileio.gets( fin, line ); // max size fixed above to 256 char's
mov( line, esi );
mov( (type str.strRec [esi]).length, edx );
if( edx ) then // i.e. if line NOT empty ... trim any spaces from end
dec( edx );
while( (type char [esi+edx]) == ' ' ) do dec( edx ); endwhile;
inc( edx );
mov( 0, (type char [esi+edx]) ); // ensure 0 terminated
//mov( edx, (type str.strRec [esi]).length ); // update with new length
while( (type char [esi]) != 0 ) do
conv.atoi32( [esi] );
mov( eax, myRec.rval );
// push( ebx ); push( ecx ); push( esi ); push( edi ); // if needed //
push( esi );
push_backVec( myVec, myRec );
pop( esi );
endwhile;
endif;
endwhile;
clock.stop();
stdout.put( nl "To fill Vec from file ... ms = ", (type uns64 clock.Accumulated), nl );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
clock.start();
mov( &myCmpInt, pMyCmp );
msortVec( myVec );
clock.stop();
stdout.put( nl "To msort ... ms = ", (type uns64 clock.Accumulated), nl );
isSorted( myVec );
stdout.put( "isSorted( myVec ) = ", (type boolean al), nl );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
clearVec( myVec );
stdout.puts( nl "Press 'Enter' to exit/continue ... " );
stdin.readLn();
end msortVecIntLarge;
/* msortVecInt3.hla */ /* this version 2012-08-22 */
/*
http://developers-heaven.net/forum/index.php/topic,46.0.html
*/
program msortVecIntLarge;
const
InitCap: uns32 := 3_000_000; // to hold 3 Million random int's
FNAME: string := "randInt3M.txt";
HEADER: string := "HLA program to sort 3 Million random int's from file"
#13 #10 "stored in an HLA user defined type Vec...";
type
Rec: record
rval: int32;
endrecord;
pRec: pointer to Rec;
procedure freeRec( pr: pRec in eax ); @noframe;
begin freeRec;
// NO dynamic memory here to free ...
ret();
end freeRec;
// ok ... after above two types defined ... now can ...
#includeOnce( "vector_func's.hhf" )
procedure myCmpInt( a: pRec in esi; b: pRec in edi ); @returns( "eax" );
begin myCmpInt;
mov( (type Rec [esi]).rval, eax );
if( eax <= (type Rec [edi]).rval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure isSorted( var v: Vec ); @returns( "eax" );
begin isSorted;
mov( v, ebx );
mov( (type Vec [ebx]).size, ecx );
dec( ecx );
intmul( @size( Rec ), ecx, eax );
add( (type Vec [ebx]).ary, eax );
mov( (type Rec [eax]).rval, edi );
while( (type int32 ecx) > 0 ) do
dec( ecx );
sub( @size( Rec ), eax );
mov( (type Rec [eax]).rval, esi );
if( (type int32 esi) > edi ) then
mov( 0, eax );
break;
endif;
mov( esi, edi );
endwhile;
mov( 1, eax );
end isSorted;
static
myVec: Vec;
myRec: Rec;
fin: dword;
tmpStr: string;
clock: timer_t;
buf: pointer to char;
begin msortVecIntLarge;
stdout.put( HEADER, nl nl );
initVec( myVec );
clock.create();
clock.start();
fileio.open( FNAME, fileio.r );
mov( eax, fin );
filesys.size( fin );
mov( eax, ecx );
inc( eax ); // leave room for terminal 0
mem.alloc( eax );
mov( eax, buf );
fileio.read( fin, [eax], ecx );
if( eax != -1 ) then
if( ecx ) then
dec( ecx );
mov( buf, esi );
while( (type int32 ecx) >= 0 && (type char [esi+ecx]) < '0' ||
(type char [esi+ecx]) > '9' ) do dec( ecx );
endwhile;
inc( ecx );
mov( 0, (type char [esi+ecx]) ); // ensure 0 terminated
while( (type char [esi]) != 0 ) do
conv.atoi32( [esi] );
mov( eax, myRec.rval );
// push( ebx ); push( ecx ); push( esi ); push( edi ); // if needed //
push( esi );
push_backVec( myVec, myRec );
pop( esi );
endwhile;
endif;
else
stdout.put( "There was a problem reading file ", FNAME, nl );
endif;
mem.free( buf );
clock.stop();
stdout.put( nl "To fill Vec from file ... ms = ", (type uns64 clock.Accumulated), nl );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
clock.start();
mov( &myCmpInt, pMyCmp );
msortVec( myVec );
clock.stop();
stdout.put( nl "To msort ... ms = ", (type uns64 clock.Accumulated), nl );
isSorted( myVec );
stdout.put( "isSorted( myVec ) = ", (type boolean al), nl );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
clearVec( myVec );
stdout.puts( nl "Press 'Enter' to exit/continue ... " );
stdin.readLn();
end msortVecIntLarge;
program fileSizeReadDemo_atoi32; // 2012-08-16 //
const
InitCap: uns32 := 3_000_000;
#includeOnce( "vector2_func's.hhf" )
type
Rec: record
rval: int32;
endrecord;
pRec: pointer to Rec;
procedure myFreeRec( pr: pRec in eax ); @noframe;
begin myFreeRec;
// no dynamic memory to free ...
ret();
end myFreeRec;
// re. msort...
procedure myCmpInt( a: pRec in esi; b: pRec in edi ); @returns( "eax" );
begin myCmpInt;
mov( (type Rec [esi]).rval, eax );
if( eax <= (type Rec [edi]).rval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure isSorted( var v: Vec ); @returns( "eax" );
begin isSorted;
mov( v, ebx );
mov( (type Vec [ebx]).size, ecx );
if( ecx > 2 ) then
dec( ecx );
intmul( @size( Rec ), ecx, eax );
add( (type Vec [ebx]).ary, eax );
mov( (type Rec [eax]).rval, edi );
while( (type int32 ecx) > 0 ) do
dec( ecx );
sub( @size( Rec ), eax );
mov( (type Rec [eax]).rval, esi );
if( (type int32 esi) > edi ) then
mov( 0, eax );
break;
endif;
mov( esi, edi );
endwhile;
endif;
mov( 1, eax );
end isSorted;
static
fin: dword;
line: string;
myVec: Vec;
myRec: Rec;
clock: timer_t;
begin fileSizeReadDemo_atoi32;
clock.create();
clock.start();
fileio.open( "randInt3M.txt", fileio.r );
mov( eax, fin );
filesys.size( fin );
mov( eax, ecx );
if( ecx != -1 ) then
stdout.put( nl "Size of file = ", (type uns32 ecx), " bytes", nl );
str.alloc( ecx );
mov( eax, line );
fileio.read( fin, [eax], ecx ); // get whole file into string
mov( line, eax ); // now ensure 'end' is 'trimmed'
dec( ecx );
while( (type char [eax+ecx]) < '0' || (type char [eax+ecx]) > '9' ) do
dec( ecx );
endwhile;
inc( ecx );
mov( ecx, (type str.strRec [eax]).length );
mov( 0, (type char [eax+ecx]) ); // ensure 0 terminated ...
initVec( myVec, @size(Rec) ); // now get 'words' into a Vec of int32
mov( &myFreeRec, pFreeRec ); // so can clearVec ... ok
mov( line, esi );
while( (type char [esi]) != 0 ) do
conv.atoi32( [esi] );
mov( eax, myRec.rval );
push( esi );
//push( ebx ); push( ecx ); push( esi ); push( edi );
push_backVec( myVec, &myRec );
pop( esi );
endwhile;
str.free( line );
clock.stop();
stdout.put( nl "To fill Vec with int32 from file ... ms = ",
(type uns64 clock.Accumulated), nl
"myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
clock.start();
mov( &myCmpInt, pMyCmp );
msortVec( myVec );
clock.stop();
stdout.put( nl "To msort Vec ... ms = ",
(type uns64 clock.Accumulated) );
isSorted( myVec );
stdout.put( ", isSorted( myVec ) = ", (type boolean al), nl );
mov( myVec.size, ecx );
dec( ecx );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
intmul( @size( Rec ), ecx, ecx );
add( myVec.ary, ecx );
stdout.put( "last 'sorted' value = '",
(type Rec [ecx]).rval, "'" nl );
clearVec( myVec );
else
stdout.put( "Error calculating file size" nl );
endif;
fileio.close( fin );
stdout.puts( nl "Press 'Enter' to exit/continue ... " );
stdin.readLn();
end fileSizeReadDemo_atoi32;
program blobDemo; // 2012-08-21 //
const
InitCap: uns32 := 3_000_000;
FNAME: string := "randInt3M.txt";
#includeOnce( "vector2_func's.hhf" )
type
Rec: record
rval: int32;
endrecord;
pRec: pointer to Rec;
procedure myFreeRec( pr: pRec in eax ); @noframe;
begin myFreeRec;
// no dynamic memory to free ...
ret();
end myFreeRec;
// re. msort...
procedure myCmpInt( a: pRec in esi; b: pRec in edi ); @returns( "eax" );
begin myCmpInt;
mov( (type Rec [esi]).rval, eax );
if( eax <= (type Rec [edi]).rval ) then mov( 1, eax );
else mov( 0, eax );
endif;
end myCmpInt;
procedure isSorted( var v: Vec ); @returns( "eax" );
begin isSorted;
mov( v, ebx );
mov( (type Vec [ebx]).size, ecx );
if( ecx > 2 ) then
dec( ecx );
intmul( @size( Rec ), ecx, eax );
add( (type Vec [ebx]).ary, eax );
mov( (type Rec [eax]).rval, edi );
while( (type int32 ecx) > 0 ) do
dec( ecx );
sub( @size( Rec ), eax );
mov( (type Rec [eax]).rval, esi );
if( (type int32 esi) > edi ) then
mov( 0, eax );
break;
endif;
mov( esi, edi );
endwhile;
endif;
mov( 1, eax );
end isSorted;
static
fin: dword;
tmpReg: dword;
line: string;
myVec: Vec;
myRec: Rec;
clock: timer_t;
blb: blob.blob;
c: char[4];
loops: uns32 := 5; // so can check load/sort run times ... x5
sum1: uns32[2] := [ 0, 0 ];
sum2: uns32[2] := [ 0, 0 ];
ratio: real32;
begin blobDemo;
clock.create();
beginLoops:
clock.start();
fileio.open( FNAME, fileio.r );
mov( eax, fin );
filesys.size( fin );
mov( eax, ecx );
if( ecx != -1 ) then
stdout.put( nl "Size of file = ", (type uns32 ecx), " bytes", nl );
str.alloc( ecx );
mov( eax, line );
fileio.read( fin, [eax], ecx ); // get whole file into string
mov( line, eax ); // now ensure 'end' is 'trimmed'
dec( ecx );
while( (type char [eax+ecx]) < '0' || (type char [eax+ecx]) > '9' ) do
dec( ecx );
endwhile;
inc( ecx );
mov( ecx, (type str.strRec [eax]).length );
mov( 0, (type char [eax+ecx]) ); // ensure 0 terminated ...
initVec( myVec, @size(Rec) ); // now get 'words' into a Vec of int32
mov( &myFreeRec, pFreeRec ); // so can clearVec ... ok
mov( line, esi );
while( (type char [esi]) != 0 ) do
conv.atoi32( [esi] );
mov( eax, myRec.rval );
mov( esi, tmpReg ); // preserve esi ...
//push( ebx ); push( ecx ); push( esi ); push( edi );
push_backVec( myVec, &myRec );
mov( tmpReg, esi ); // retore esi ...
endwhile;
str.free( line );
clock.stop();
add( eax, sum1 );
stdout.put( nl "To fill Vec with int32 from file/string_buf ... ms = ",
(type uns64 clock.Accumulated), nl
"myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
clock.start();
mov( &myCmpInt, pMyCmp );
msortVec( myVec );
clock.stop();
add( eax, sum1[4] );
stdout.put( nl "To msort Vec ... ms = ",
(type uns64 clock.Accumulated) );
isSorted( myVec );
stdout.put( ", isSorted( myVec ) = ", (type boolean al), nl );
mov( myVec.size, ecx );
dec( ecx );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
intmul( @size( Rec ), ecx, ecx );
add( myVec.ary, ecx );
stdout.put( "last 'sorted' value = '",
(type Rec [ecx]).rval, "'" nl );
clearVec( myVec );
else
stdout.put( "Error calculating file size" nl );
endif;
fileio.close( fin );
stdout.puts( nl nl "Ok ... now demo of almost as super fast "
"fileio ... using an HLA blob ..." nl nl );
initVec( myVec, @size( Rec ) ); // DON'T FORGET to init... @size( Rec )
clock.start();
blob.a_load( FNAME );
mov( eax, blb );
// now trim off any/all NON 0..9 char's from end of blob ...
// and reset length ...
//blob.maxlen( blb );
//stdout.put( "blob.maxlen = ", (type uns32 eax), nl );
blob.length( blb );
//stdout.put( "blob.length = ", (type uns32 eax), nl );
mov( eax, ecx ); // mov (present) blob length into ecx ...
dec( ecx ); // so can 'test' content of last char's in blob
while( (type int32 ecx) >= 0 ) do
//get at last char per either of the 2 lines below ...
//blob.readAt( blobPointer, buffer, index, count );
//blob.readAt( blobPointer, [eax], 2999999, 1 );
blob.readAt( blb, &c, ecx, 1 );
mov( c, al );
if( al < '0' || al > '9' ) then
dec( ecx );
else
break;
endif;
endwhile;
inc( ecx ); // get 'new' length
blob.setLength( blb, ecx ); // Ok ... update with 'new' blob length
// Now can get each int32 from blob without worrying about 'crash' ...
// if there were any non 0..9 char's, after n'th 0..9 char, before eof
while( !blob.eof( blb ) ) do
blob.geti32( blb );
mov( eax, myRec.rval );
push_backVec( myVec, &myRec );
endwhile;
blob.free( blb ); // free (not destroy) since used alloc via blob.a_load
clock.stop();
add( eax, sum2 );
stdout.put( nl "To fill Vec with int32 from file/blob ... ms = ",
(type uns64 clock.Accumulated), nl
"myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
clock.start();
mov( &myCmpInt, pMyCmp ); // done above alraedy
msortVec( myVec );
clock.stop();
add( eax, sum2[4] );
stdout.put( nl "To msort Vec ... ms = ",
(type uns64 clock.Accumulated) );
isSorted( myVec );
stdout.put( ", isSorted( myVec ) = ", (type boolean al), nl );
mov( myVec.size, ecx );
dec( ecx );
stdout.put( "myVec.size = ", myVec.size,
", myVec.capacity = ", myVec.capacity, nl );
intmul( @size( Rec ), ecx, ecx );
add( myVec.ary, ecx );
stdout.put( "last 'sorted' value = '",
(type Rec [ecx]).rval, "'" nl );
clearVec( myVec );
dec( loops );
jnz( beginLoops );
stdout.put( nl nl
"Summery of times ..." nl nl
"Load 1st method sum:", sum1:6, nl
"Sort sum:", sum1[4]:6, nl
"Load 2nd method sum:", sum2:6, nl
"Sort sum:", sum2[4]:6, nl nl );
finit();
fild( sum2[0] );
fild( sum1[0] );
fdivp();
fstp( ratio ); // POP and store sto int ...
stdout.put( "Ratio of load times method2/method1 =", ratio:5:2, nl );
stdout.puts( nl "Press 'Enter' to exit/continue ... " );
stdin.readLn();
end blobDemo;