diff --git a/src/arith/integer.c b/src/arith/integer.c index 5f47532..db486d2 100644 --- a/src/arith/integer.c +++ b/src/arith/integer.c @@ -218,18 +218,19 @@ struct cons_pointer base_partial( int depth ) { /** * destructively modify this `partial` by appending this `digit`. */ -struct cons_pointer append_digit( struct cons_pointer partial, struct cons_pointer digit) { +struct cons_pointer append_digit( struct cons_pointer partial, + struct cons_pointer digit ) { struct cons_pointer c = partial; struct cons_pointer result = partial; - if (nilp( partial)) { + if ( nilp( partial ) ) { result = digit; } else { - while ( !nilp( pointer2cell(c).payload.integer.more)) { - c = pointer2cell(c).payload.integer.more; + while ( !nilp( pointer2cell( c ).payload.integer.more ) ) { + c = pointer2cell( c ).payload.integer.more; } - (&pointer2cell(c))->payload.integer.more = digit; + ( &pointer2cell( c ) )->payload.integer.more = digit; } return result; } @@ -248,8 +249,8 @@ struct cons_pointer append_digit( struct cons_pointer partial, struct cons_point * @param b an integer. */ struct cons_pointer multiply_integers( struct cons_pointer a, - struct cons_pointer b ) { - struct cons_pointer result = make_integer( 0, NIL); + struct cons_pointer b ) { + struct cons_pointer result = make_integer( 0, NIL ); bool neg = is_negative( a ) != is_negative( b ); bool is_first_b = true; int i = 0; @@ -264,7 +265,7 @@ struct cons_pointer multiply_integers( struct cons_pointer a, /* for each digit in a, starting with the least significant (ai) */ for ( struct cons_pointer ai = a; !nilp( ai ); - ai = pointer2cell(ai).payload.integer.more) { + ai = pointer2cell( ai ).payload.integer.more ) { /* set carry to 0 */ __int128_t carry = 0; @@ -274,41 +275,41 @@ struct cons_pointer multiply_integers( struct cons_pointer a, /* for each digit in b, starting with the least significant (bj) */ for ( struct cons_pointer bj = b; !nilp( bj ); - bj = pointer2cell(bj).payload.integer.more) { + bj = pointer2cell( bj ).payload.integer.more ) { debug_printf( DEBUG_ARITH, - L"multiply_integers: a[i] = %Ld, b[j] = %Ld, i = %d\n", - pointer2cell(ai).payload.integer.value, - pointer2cell(bj).payload.integer.value, i); + L"multiply_integers: a[i] = %Ld, b[j] = %Ld, i = %d\n", + pointer2cell( ai ).payload.integer.value, + pointer2cell( bj ).payload.integer.value, i ); /* multiply ai with bj and add the carry, resulting in a * value xj which may exceed one digit */ - __int128_t xj = pointer2cell(ai).payload.integer.value * - pointer2cell(bj).payload.integer.value; + __int128_t xj = pointer2cell( ai ).payload.integer.value * + pointer2cell( bj ).payload.integer.value; xj += carry; /* if xj exceeds one digit, break it into the digit dj and * the carry */ carry = xj >> 60; - struct cons_pointer dj = make_integer( xj & MAX_INTEGER, NIL); + struct cons_pointer dj = make_integer( xj & MAX_INTEGER, NIL ); /* destructively modify ri by appending dj */ - ri = append_digit( ri, dj); - } /* end for bj */ + ri = append_digit( ri, dj ); + } /* end for bj */ /* if carry is not equal to zero, append it as a final digit * to ri */ - if (carry != 0) { - ri = append_digit( ri, make_integer( carry, NIL)); + if ( carry != 0 ) { + ri = append_digit( ri, make_integer( carry, NIL ) ); } /* add ri to result */ - result = add_integers( result, ri); + result = add_integers( result, ri ); debug_print( L"multiply_integers: result is ", DEBUG_ARITH ); debug_print_object( result, DEBUG_ARITH ); debug_println( DEBUG_ARITH ); - } /* end for ai */ + } /* end for ai */ } debug_print( L"multiply_integers returning: ", DEBUG_ARITH ); @@ -342,13 +343,16 @@ struct cons_pointer integer_to_string_add_digit( int digit, int digits, * to be looking to the next. H'mmmm. */ struct cons_pointer integer_to_string( struct cons_pointer int_pointer, - int base ) { + int base ) { struct cons_pointer result = NIL; if ( integerp( int_pointer ) ) { - struct cons_pointer next = pointer2cell( int_pointer ).payload.integer.more; - __int128_t accumulator = llabs( pointer2cell( int_pointer ).payload.integer.value ); - bool is_negative = pointer2cell( int_pointer ).payload.integer.value < 0; + struct cons_pointer next = + pointer2cell( int_pointer ).payload.integer.more; + __int128_t accumulator = + llabs( pointer2cell( int_pointer ).payload.integer.value ); + bool is_negative = + pointer2cell( int_pointer ).payload.integer.value < 0; int digits = 0; if ( accumulator == 0 && nilp( next ) ) { @@ -356,13 +360,14 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer, } else { while ( accumulator > 0 || !nilp( next ) ) { if ( accumulator < MAX_INTEGER && !nilp( next ) ) { - accumulator += (pointer2cell(next).payload.integer.value << 60); - next = pointer2cell(next).payload.integer.more; + accumulator += + ( pointer2cell( next ).payload.integer.value << 60 ); + next = pointer2cell( next ).payload.integer.more; } int offset = ( int ) ( accumulator % base ); debug_printf( DEBUG_IO, - L"integer_to_string: digit is %ld, hexadecimal is %c, accumulator is: ", - offset, hex_digits[offset] ); + L"integer_to_string: digit is %ld, hexadecimal is %c, accumulator is: ", + offset, hex_digits[offset] ); debug_print_128bit( accumulator, DEBUG_IO ); debug_print( L"; result is: ", DEBUG_IO ); debug_print_object( result, DEBUG_IO ); @@ -374,7 +379,7 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer, } if ( stringp( result ) - && pointer2cell( result ).payload.string.character == L',' ) { + && pointer2cell( result ).payload.string.character == L',' ) { /* if the number of digits in the string is divisible by 3, there will be * an unwanted comma on the front. */ result = pointer2cell( result ).payload.string.cdr; @@ -393,14 +398,15 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer, /** * true if a and be are both integers whose value is the same value. */ -bool equal_integer_integer(struct cons_pointer a, struct cons_pointer b) { +bool equal_integer_integer( struct cons_pointer a, struct cons_pointer b ) { bool result = false; - if (integerp(a) && integerp(b)){ + if ( integerp( a ) && integerp( b ) ) { struct cons_space_object *cell_a = &pointer2cell( a ); struct cons_space_object *cell_b = &pointer2cell( b ); - result = cell_a->payload.integer.value == cell_b->payload.integer.value; + result = + cell_a->payload.integer.value == cell_b->payload.integer.value; } return result; @@ -410,17 +416,16 @@ bool equal_integer_integer(struct cons_pointer a, struct cons_pointer b) { * true if `a` is an integer, and `b` is a real number whose value is the * value of that integer. */ -bool equal_integer_real(struct cons_pointer a, struct cons_pointer b) { +bool equal_integer_real( struct cons_pointer a, struct cons_pointer b ) { bool result = false; - if (integerp(a) && realp(b)) - { - long double bv = pointer2cell(b).payload.real.value; + if ( integerp( a ) && realp( b ) ) { + long double bv = pointer2cell( b ).payload.real.value; - if (floor(bv) == bv) { - result = pointer2cell(a).payload.integer.value == (int64_t)bv; + if ( floor( bv ) == bv ) { + result = pointer2cell( a ).payload.integer.value == ( int64_t ) bv; } } return result; -} \ No newline at end of file +} diff --git a/src/arith/integer.h b/src/arith/integer.h index 4ce58d5..09a7a83 100644 --- a/src/arith/integer.h +++ b/src/arith/integer.h @@ -14,19 +14,19 @@ #include #include -struct cons_pointer make_integer(int64_t value, struct cons_pointer more); +struct cons_pointer make_integer( int64_t value, struct cons_pointer more ); -struct cons_pointer add_integers(struct cons_pointer a, - struct cons_pointer b); +struct cons_pointer add_integers( struct cons_pointer a, + struct cons_pointer b ); -struct cons_pointer multiply_integers(struct cons_pointer a, - struct cons_pointer b); +struct cons_pointer multiply_integers( struct cons_pointer a, + struct cons_pointer b ); -struct cons_pointer integer_to_string(struct cons_pointer int_pointer, - int base); +struct cons_pointer integer_to_string( struct cons_pointer int_pointer, + int base ); -bool equal_integer_integer(struct cons_pointer a, struct cons_pointer b); +bool equal_integer_integer( struct cons_pointer a, struct cons_pointer b ); -bool equal_integer_real(struct cons_pointer a, struct cons_pointer b); +bool equal_integer_real( struct cons_pointer a, struct cons_pointer b ); #endif diff --git a/src/arith/peano.c b/src/arith/peano.c index 8fe63fb..5589f1f 100644 --- a/src/arith/peano.c +++ b/src/arith/peano.c @@ -247,8 +247,7 @@ struct cons_pointer add_2( struct stack_frame *frame, result = add_integers( arg1, arg2 ); break; case RATIOTV: - result = - add_integer_ratio( arg1, arg2 ); + result = add_integer_ratio( arg1, arg2 ); break; case REALTV: result = @@ -268,8 +267,7 @@ struct cons_pointer add_2( struct stack_frame *frame, result = arg2; break; case INTEGERTV: - result = - add_integer_ratio( arg2, arg1 ); + result = add_integer_ratio( arg2, arg1 ); break; case RATIOTV: result = add_ratio_ratio( arg1, arg2 ); @@ -380,9 +378,7 @@ struct cons_pointer multiply_2( struct stack_frame *frame, result = multiply_integers( arg1, arg2 ); break; case RATIOTV: - result = - multiply_integer_ratio( arg1, - arg2 ); + result = multiply_integer_ratio( arg1, arg2 ); break; case REALTV: result = @@ -405,13 +401,10 @@ struct cons_pointer multiply_2( struct stack_frame *frame, result = arg2; break; case INTEGERTV: - result = - multiply_integer_ratio( arg2, - arg1 ); + result = multiply_integer_ratio( arg2, arg1 ); break; case RATIOTV: - result = - multiply_ratio_ratio( arg1, arg2 ); + result = multiply_ratio_ratio( arg1, arg2 ); break; case REALTV: result = @@ -564,20 +557,18 @@ struct cons_pointer subtract_2( struct stack_frame *frame, result = arg2; break; case INTEGERTV:{ - struct cons_pointer i = - negative( arg2 ); + struct cons_pointer i = negative( arg2 ); inc_ref( i ); result = add_integers( arg1, i ); dec_ref( i ); } break; case RATIOTV:{ - struct cons_pointer tmp = - make_ratio( arg1, - make_integer( 1, NIL ) ); + struct cons_pointer tmp = make_ratio( arg1, + make_integer( 1, + NIL ) ); inc_ref( tmp ); - result = - subtract_ratio_ratio( tmp, arg2 ); + result = subtract_ratio_ratio( tmp, arg2 ); dec_ref( tmp ); } break; @@ -599,12 +590,11 @@ struct cons_pointer subtract_2( struct stack_frame *frame, result = arg2; break; case INTEGERTV:{ - struct cons_pointer tmp = - make_ratio( arg2, - make_integer( 1, NIL ) ); + struct cons_pointer tmp = make_ratio( arg2, + make_integer( 1, + NIL ) ); inc_ref( tmp ); - result = - subtract_ratio_ratio( arg1, tmp ); + result = subtract_ratio_ratio( arg1, tmp ); dec_ref( tmp ); } break; @@ -696,9 +686,7 @@ struct cons_pointer lisp_divide( struct struct cons_pointer ratio = make_ratio( frame->arg[0], one ); inc_ref( ratio ); - result = - divide_ratio_ratio( ratio, - frame->arg[1] ); + result = divide_ratio_ratio( ratio, frame->arg[1] ); dec_ref( ratio ); } break; @@ -725,17 +713,14 @@ struct cons_pointer lisp_divide( struct struct cons_pointer ratio = make_ratio( frame->arg[1], one ); inc_ref( ratio ); - result = - divide_ratio_ratio( frame->arg[0], - ratio ); + result = divide_ratio_ratio( frame->arg[0], ratio ); dec_ref( ratio ); dec_ref( one ); } break; case RATIOTV: result = - divide_ratio_ratio( frame->arg[0], - frame->arg[1] ); + divide_ratio_ratio( frame->arg[0], frame->arg[1] ); break; case REALTV: result = diff --git a/src/arith/peano.h b/src/arith/peano.h index 9bcd9e4..3076391 100644 --- a/src/arith/peano.h +++ b/src/arith/peano.h @@ -27,7 +27,7 @@ struct cons_pointer absolute( struct cons_pointer arg ); long double to_long_double( struct cons_pointer arg ); -int64_t to_long_int( struct cons_pointer arg ) ; +int64_t to_long_int( struct cons_pointer arg ); struct cons_pointer lisp_absolute( struct stack_frame *frame, struct cons_pointer frame_pointer, struct diff --git a/src/arith/ratio.c b/src/arith/ratio.c index f4c8056..8100ec2 100644 --- a/src/arith/ratio.c +++ b/src/arith/ratio.c @@ -43,42 +43,36 @@ int64_t least_common_multiple( int64_t m, int64_t n ) { return m / greatest_common_divisor( m, n ) * n; } -struct cons_pointer simplify_ratio( struct cons_pointer pointer) { +struct cons_pointer simplify_ratio( struct cons_pointer pointer ) { struct cons_pointer result = pointer; - struct cons_space_object cell = pointer2cell(pointer); - struct cons_space_object dividend = pointer2cell(cell.payload.ratio.dividend); - struct cons_space_object divisor = pointer2cell(cell.payload.ratio.divisor); + struct cons_space_object cell = pointer2cell( pointer ); + struct cons_space_object dividend = + pointer2cell( cell.payload.ratio.dividend ); + struct cons_space_object divisor = + pointer2cell( cell.payload.ratio.divisor ); - if (divisor.payload.integer.value == 1) - { - result = pointer2cell(pointer).payload.ratio.dividend; - } - else - { - if (ratiop(pointer)) - { + if ( divisor.payload.integer.value == 1 ) { + result = pointer2cell( pointer ).payload.ratio.dividend; + } else { + if ( ratiop( pointer ) ) { int64_t ddrv = dividend.payload.integer.value, - drrv = divisor.payload.integer.value, - gcd = greatest_common_divisor(ddrv, drrv); + drrv = divisor.payload.integer.value, + gcd = greatest_common_divisor( ddrv, drrv ); - if (gcd > 1) - { - if (drrv / gcd == 1) - { - result = make_integer(ddrv / gcd, NIL); - } - else - { + if ( gcd > 1 ) { + if ( drrv / gcd == 1 ) { + result = make_integer( ddrv / gcd, NIL ); + } else { result = - make_ratio(make_integer(ddrv / gcd, NIL), - make_integer(drrv / gcd, NIL)); + make_ratio( make_integer( ddrv / gcd, NIL ), + make_integer( drrv / gcd, NIL ) ); } } } } return result; - + } @@ -181,8 +175,7 @@ struct cons_pointer add_integer_ratio( struct cons_pointer intarg, ( L"Shouldn't happen: bad arg to add_integer_ratio" ), make_cons( intarg, make_cons( ratarg, - NIL ) ) ), - NIL ); + NIL ) ) ), NIL ); } return result; @@ -196,11 +189,10 @@ struct cons_pointer add_integer_ratio( struct cons_pointer intarg, */ struct cons_pointer divide_ratio_ratio( struct cons_pointer arg1, struct cons_pointer arg2 ) { - // TODO: this now has to work if `arg1` is an integer - struct cons_pointer i = make_ratio( pointer2cell( arg2 ).payload. - ratio.divisor, - pointer2cell( arg2 ).payload. - ratio.dividend ), result = + // TODO: this now has to work if `arg1` is an integer + struct cons_pointer i = + make_ratio( pointer2cell( arg2 ).payload.ratio.divisor, + pointer2cell( arg2 ).payload.ratio.dividend ), result = multiply_ratio_ratio( arg1, i ); dec_ref( i ); @@ -217,7 +209,7 @@ struct cons_pointer divide_ratio_ratio( struct cons_pointer arg1, struct cons_pointer multiply_ratio_ratio( struct cons_pointer arg1, struct cons_pointer arg2 ) { - // TODO: this now has to work if arg1 is an integer + // TODO: this now has to work if arg1 is an integer struct cons_pointer result; debug_print( L"multiply_ratio_ratio( arg1 = ", DEBUG_ARITH ); @@ -294,7 +286,7 @@ struct cons_pointer multiply_integer_ratio( struct cons_pointer intarg, */ struct cons_pointer subtract_ratio_ratio( struct cons_pointer arg1, struct cons_pointer arg2 ) { - struct cons_pointer i = negative( arg2), + struct cons_pointer i = negative( arg2 ), result = add_ratio_ratio( arg1, i ); dec_ref( i ); @@ -333,20 +325,18 @@ struct cons_pointer make_ratio( struct cons_pointer dividend, /** * True if a and be are identical ratios, else false. */ -bool equal_ratio_ratio(struct cons_pointer a, struct cons_pointer b) -{ +bool equal_ratio_ratio( struct cons_pointer a, struct cons_pointer b ) { bool result = false; - if (ratiop(a) && ratiop(b)) - { - struct cons_space_object *cell_a = &pointer2cell(a); - struct cons_space_object *cell_b = &pointer2cell(b); + if ( ratiop( a ) && ratiop( b ) ) { + struct cons_space_object *cell_a = &pointer2cell( a ); + struct cons_space_object *cell_b = &pointer2cell( b ); - result = equal_integer_integer(cell_a->payload.ratio.dividend, - cell_b->payload.ratio.dividend) && - equal_integer_integer(cell_a->payload.ratio.divisor, - cell_b->payload.ratio.divisor); + result = equal_integer_integer( cell_a->payload.ratio.dividend, + cell_b->payload.ratio.dividend ) && + equal_integer_integer( cell_a->payload.ratio.divisor, + cell_b->payload.ratio.divisor ); } return result; -} \ No newline at end of file +} diff --git a/src/arith/ratio.h b/src/arith/ratio.h index d440530..9068bfb 100644 --- a/src/arith/ratio.h +++ b/src/arith/ratio.h @@ -34,6 +34,6 @@ struct cons_pointer subtract_ratio_ratio( struct cons_pointer arg1, struct cons_pointer make_ratio( struct cons_pointer dividend, struct cons_pointer divisor ); -bool equal_ratio_ratio(struct cons_pointer a, struct cons_pointer b); +bool equal_ratio_ratio( struct cons_pointer a, struct cons_pointer b ); #endif diff --git a/src/authorise.c b/src/authorise.c index 5574db9..afd730d 100644 --- a/src/authorise.c +++ b/src/authorise.c @@ -15,10 +15,10 @@ * TODO: does nothing, yet. What it should do is access a magic value in the * runtime environment and check that it is identical to something on this `acl` */ -struct cons_pointer authorised(struct cons_pointer target, struct cons_pointer acl) { - if (nilp(acl)) { - acl = pointer2cell(target).access; +struct cons_pointer authorised( struct cons_pointer target, + struct cons_pointer acl ) { + if ( nilp( acl ) ) { + acl = pointer2cell( target ).access; } return TRUE; } - diff --git a/src/authorise.h b/src/authorise.h index c67977d..6c55b32 100644 --- a/src/authorise.h +++ b/src/authorise.h @@ -10,6 +10,7 @@ #ifndef __psse_authorise_h #define __psse_authorise_h -struct cons_pointer authorised(struct cons_pointer target, struct cons_pointer acl); +struct cons_pointer authorised( struct cons_pointer target, + struct cons_pointer acl ); -#endif \ No newline at end of file +#endif diff --git a/src/init.c b/src/init.c index 4126783..ca48b9d 100644 --- a/src/init.c +++ b/src/init.c @@ -84,8 +84,9 @@ void bind_value( wchar_t *name, struct cons_pointer value ) { dec_ref( n ); } -void print_banner() { - fwprintf(stdout, L"Post-Scarcity Software Environment version %s\n\n", VERSION); +void print_banner( ) { + fwprintf( stdout, L"Post-Scarcity Software Environment version %s\n\n", + VERSION ); } /** @@ -93,22 +94,24 @@ void print_banner() { * * @stream the stream to print to. */ -void print_options(FILE* stream) { - fwprintf(stream, L"Expected options are:\n"); - fwprintf(stream, L"\t-d\tDump memory to standard out at end of run (copious!);\n"); - fwprintf(stream, L"\t-h\tPrint this message and exit;\n"); - fwprintf(stream, L"\t-p\tShow a prompt (default is no prompt);\n"); - fwprintf(stream, L"\t-v LEVEL\n\t\tSet verbosity to the specified level (0...512)\n"); - fwprintf(stream, L"\t\tWhere bits are interpreted as follows:\n"); - fwprintf(stream, L"\t\t1\tALLOC;\n"); - fwprintf(stream, L"\t\t2\tARITH;\n"); - fwprintf(stream, L"\t\t4\tBIND;\n"); - fwprintf(stream, L"\t\t8\tBOOTSTRAP;\n"); - fwprintf(stream, L"\t\t16\tEVAL;\n"); - fwprintf(stream, L"\t\t32\tINPUT/OUTPUT;\n"); - fwprintf(stream, L"\t\t64\tLAMBDA;\n"); - fwprintf(stream, L"\t\t128\tREPL;\n"); - fwprintf(stream, L"\t\t256\tSTACK.\n"); +void print_options( FILE * stream ) { + fwprintf( stream, L"Expected options are:\n" ); + fwprintf( stream, + L"\t-d\tDump memory to standard out at end of run (copious!);\n" ); + fwprintf( stream, L"\t-h\tPrint this message and exit;\n" ); + fwprintf( stream, L"\t-p\tShow a prompt (default is no prompt);\n" ); + fwprintf( stream, + L"\t-v LEVEL\n\t\tSet verbosity to the specified level (0...512)\n" ); + fwprintf( stream, L"\t\tWhere bits are interpreted as follows:\n" ); + fwprintf( stream, L"\t\t1\tALLOC;\n" ); + fwprintf( stream, L"\t\t2\tARITH;\n" ); + fwprintf( stream, L"\t\t4\tBIND;\n" ); + fwprintf( stream, L"\t\t8\tBOOTSTRAP;\n" ); + fwprintf( stream, L"\t\t16\tEVAL;\n" ); + fwprintf( stream, L"\t\t32\tINPUT/OUTPUT;\n" ); + fwprintf( stream, L"\t\t64\tLAMBDA;\n" ); + fwprintf( stream, L"\t\t128\tREPL;\n" ); + fwprintf( stream, L"\t\t256\tSTACK.\n" ); } /** @@ -132,8 +135,8 @@ int main( int argc, char *argv[] ) { dump_at_end = true; break; case 'h': - print_banner(); - print_options(stdout); + print_banner( ); + print_options( stdout ); exit( 0 ); break; case 'p': @@ -144,14 +147,14 @@ int main( int argc, char *argv[] ) { break; default: fwprintf( stderr, L"Unexpected option %c\n", option ); - print_options(stderr); + print_options( stderr ); exit( 1 ); break; } } if ( show_prompt ) { - print_banner(); + print_banner( ); } debug_print( L"About to initialise cons pages\n", DEBUG_BOOTSTRAP ); @@ -225,10 +228,10 @@ int main( int argc, char *argv[] ) { bind_function( L"equal", &lisp_equal ); bind_function( L"eval", &lisp_eval ); bind_function( L"exception", &lisp_exception ); - bind_function( L"get-hash", &lisp_get_hash); - bind_function(L"hashmap", lisp_make_hashmap); + bind_function( L"get-hash", &lisp_get_hash ); + bind_function( L"hashmap", lisp_make_hashmap ); bind_function( L"inspect", &lisp_inspect ); - bind_function( L"keys", &lisp_keys); + bind_function( L"keys", &lisp_keys ); bind_function( L"meta", &lisp_metadata ); bind_function( L"metadata", &lisp_metadata ); bind_function( L"multiply", &lisp_multiply ); @@ -237,8 +240,8 @@ int main( int argc, char *argv[] ) { bind_function( L"open", &lisp_open ); bind_function( L"print", &lisp_print ); bind_function( L"progn", &lisp_progn ); - bind_function( L"put", lisp_hashmap_put); - bind_function( L"put-all", &lisp_hashmap_put_all); + bind_function( L"put", lisp_hashmap_put ); + bind_function( L"put-all", &lisp_hashmap_put_all ); bind_function( L"read", &lisp_read ); bind_function( L"read-char", &lisp_read_char ); bind_function( L"repl", &lisp_repl ); diff --git a/src/io/fopen.c b/src/io/fopen.c index d3ece5c..3a66806 100644 --- a/src/io/fopen.c +++ b/src/io/fopen.c @@ -213,7 +213,7 @@ URL_FILE *url_fopen( const char *url, const char *operation ) { file->handle.file = fopen( url, operation ); if ( file->handle.file ) { file->type = CFTYPE_FILE; /* marked as file */ - } else if ( index_of(':', url ) > -1 ) { + } else if ( index_of( ':', url ) > -1 ) { file->type = CFTYPE_CURL; /* marked as URL */ file->handle.curl = curl_easy_init( ); diff --git a/src/io/io.c b/src/io/io.c index 9976373..f621539 100644 --- a/src/io/io.c +++ b/src/io/io.c @@ -265,7 +265,7 @@ struct cons_pointer add_meta_integer( struct cons_pointer meta, wchar_t *key, struct cons_pointer add_meta_string( struct cons_pointer meta, wchar_t *key, char *value ) { - value = trim( value); + value = trim( value ); wchar_t buffer[strlen( value ) + 1]; mbstowcs( buffer, value, strlen( value ) + 1 ); @@ -280,9 +280,8 @@ struct cons_pointer add_meta_time( struct cons_pointer meta, wchar_t *key, char datestring[256]; strftime( datestring, - sizeof( datestring ), - nl_langinfo( D_T_FMT ), - localtime( value ) ); + sizeof( datestring ), + nl_langinfo( D_T_FMT ), localtime( value ) ); return add_meta_string( meta, key, datestring ); } @@ -391,7 +390,7 @@ void collect_meta( struct cons_pointer stream, char *url ) { } /* this is destructive change before the cell is released into the - * wild, and consequently permissible, just. */ + * wild, and consequently permissible, just. */ cell->payload.stream.meta = meta; } @@ -441,20 +440,23 @@ lisp_open( struct stack_frame *frame, struct cons_pointer frame_pointer, URL_FILE *stream = url_fopen( url, "r" ); debug_printf( DEBUG_IO, - L"lisp_open: stream @ %ld, stream type = %d, stream handle = %ld\n", - (long int) &stream, (int)stream->type, (long int)stream->handle.file); + L"lisp_open: stream @ %ld, stream type = %d, stream handle = %ld\n", + ( long int ) &stream, ( int ) stream->type, + ( long int ) stream->handle.file ); - switch (stream->type) { + switch ( stream->type ) { case CFTYPE_NONE: - return make_exception( - c_string_to_lisp_string( L"Could not open stream"), - frame_pointer); + return + make_exception( c_string_to_lisp_string + ( L"Could not open stream" ), + frame_pointer ); break; case CFTYPE_FILE: - if (stream->handle.file == NULL) { - return make_exception( - c_string_to_lisp_string( L"Could not open file"), - frame_pointer); + if ( stream->handle.file == NULL ) { + return + make_exception( c_string_to_lisp_string + ( L"Could not open file" ), + frame_pointer ); } break; case CFTYPE_CURL: @@ -501,8 +503,8 @@ lisp_read_char( struct stack_frame *frame, struct cons_pointer frame_pointer, if ( readp( frame->arg[0] ) ) { result = make_string( url_fgetwc - ( pointer2cell( frame->arg[0] ).payload. - stream.stream ), NIL ); + ( pointer2cell( frame->arg[0] ).payload.stream. + stream ), NIL ); } return result; diff --git a/src/io/print.c b/src/io/print.c index 3f33252..64d7b37 100644 --- a/src/io/print.c +++ b/src/io/print.c @@ -88,38 +88,38 @@ void print_list( URL_FILE * output, struct cons_pointer pointer ) { url_fputws( L")", output ); } -void print_map( URL_FILE *output, struct cons_pointer map ) { - if ( hashmapp( map ) ) { - struct vector_space_object *vso = pointer_to_vso( map ); +void print_map( URL_FILE * output, struct cons_pointer map ) { + if ( hashmapp( map ) ) { + struct vector_space_object *vso = pointer_to_vso( map ); - url_fputwc( btowc( '{' ), output ); + url_fputwc( btowc( '{' ), output ); - for ( struct cons_pointer ks = hashmap_keys( map ); !nilp( ks ); - ks = c_cdr( ks ) ) { - struct cons_pointer key = c_car( ks); - print( output, key ); - url_fputwc( btowc( ' ' ), output ); - print( output, hashmap_get( map, key ) ); + for ( struct cons_pointer ks = hashmap_keys( map ); !nilp( ks ); + ks = c_cdr( ks ) ) { + struct cons_pointer key = c_car( ks ); + print( output, key ); + url_fputwc( btowc( ' ' ), output ); + print( output, hashmap_get( map, key ) ); - if ( !nilp( c_cdr( ks ) ) ) { - url_fputws( L", ", output ); - } + if ( !nilp( c_cdr( ks ) ) ) { + url_fputws( L", ", output ); + } + } + + url_fputwc( btowc( '}' ), output ); } - - url_fputwc( btowc( '}' ), output ); - } } -void print_vso( URL_FILE * output, struct cons_pointer pointer) { - struct vector_space_object *vso = pointer_to_vso(pointer); - switch ( vso->header.tag.value) { +void print_vso( URL_FILE * output, struct cons_pointer pointer ) { + struct vector_space_object *vso = pointer_to_vso( pointer ); + switch ( vso->header.tag.value ) { case HASHTV: - print_map( output, pointer); + print_map( output, pointer ); break; - // \todo: others. + // \todo: others. default: - fwprintf( stderr, L"Unrecognised vector-space type '%d'\n", - vso->header.tag.value ); + fwprintf( stderr, L"Unrecognised vector-space type '%d'\n", + vso->header.tag.value ); } } @@ -130,14 +130,14 @@ void print_128bit( URL_FILE * output, __int128_t n ) { if ( n == 0 ) { fwprintf( stderr, L"0" ); } else { - char str[40] = { 0 }; // log10(1 << 128) + '\0' + char str[40] = { 0 }; // log10(1 << 128) + '\0' char *s = str + sizeof( str ) - 1; // start at the end while ( n != 0 ) { if ( s == str ) - return; // never happens + return; // never happens *--s = "0123456789"[n % 10]; // save last digit - n /= 10; // drop it + n /= 10; // drop it } url_fwprintf( output, L"%s", s ); } @@ -165,9 +165,9 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) { dump_stack_trace( output, pointer ); break; case FUNCTIONTV: - url_fputws( L"', output); + url_fputws( L"', output ); break; case INTEGERTV:{ struct cons_pointer s = integer_to_string( pointer, 10 ); @@ -181,7 +181,7 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) { print_string_contents( output, pointer ); break; case LAMBDATV:{ - url_fputws( L"', output); + url_fputwc( L'>', output ); } break; case NILTV: url_fwprintf( output, L"nil" ); break; case NLAMBDATV:{ - url_fputws( L"', output); + url_fputwc( L'>', output ); } break; case RATIOTV: @@ -218,8 +218,8 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) { break; case READTV: url_fwprintf( output, L"', output); + print( output, cell.payload.stream.meta ); + url_fputwc( L'>', output ); break; case REALTV: /* \todo using the C heap is a bad plan because it will fragment. @@ -245,26 +245,26 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) { break; case SPECIALTV: url_fwprintf( output, L"', output); + print( output, cell.payload.special.meta ); + url_fputwc( L'>', output ); break; case TIMETV: url_fwprintf( output, L"', output); + print_string( output, time_to_string( pointer ) ); + url_fputws( L"; ", output ); + print_128bit( output, pointer2cell( pointer ).payload.time.value ); + url_fputwc( L'>', output ); break; case TRUETV: url_fwprintf( output, L"t" ); break; case VECTORPOINTTV: - print_vso( output, pointer); + print_vso( output, pointer ); break; case WRITETV: url_fwprintf( output, L"', output); + print( output, cell.payload.stream.meta ); + url_fputwc( L'>', output ); break; default: fwprintf( stderr, diff --git a/src/io/read.c b/src/io/read.c index 2395cbc..9c87932 100644 --- a/src/io/read.c +++ b/src/io/read.c @@ -46,8 +46,8 @@ struct cons_pointer read_list( struct stack_frame *frame, struct cons_pointer frame_pointer, URL_FILE * input, wint_t initial ); struct cons_pointer read_map( struct stack_frame *frame, - struct cons_pointer frame_pointer, - URL_FILE * input, wint_t initial ); + struct cons_pointer frame_pointer, + URL_FILE * input, wint_t initial ); struct cons_pointer read_string( URL_FILE * input, wint_t initial ); struct cons_pointer read_symbol_or_key( URL_FILE * input, uint32_t tag, wint_t initial ); @@ -106,7 +106,7 @@ struct cons_pointer read_continuation( struct stack_frame *frame, break; case '{': result = read_map( frame, frame_pointer, input, - url_fgetwc( input ) ); + url_fgetwc( input ) ); break; case '"': result = read_string( input, url_fgetwc( input ) ); @@ -134,10 +134,12 @@ struct cons_pointer read_continuation( struct stack_frame *frame, } else if ( iswblank( next ) ) { /* dotted pair. \todo this isn't right, we * really need to backtrack up a level. */ - result = read_continuation( frame, frame_pointer, input, + result = + read_continuation( frame, frame_pointer, input, url_fgetwc( input ) ); - debug_print( L"read_continuation: dotted pair; read cdr ", - DEBUG_IO); + debug_print + ( L"read_continuation: dotted pair; read cdr ", + DEBUG_IO ); } else { read_symbol_or_key( input, SYMBOLTV, c ); } @@ -284,37 +286,34 @@ struct cons_pointer read_number( struct stack_frame *frame, * left parenthesis. */ struct cons_pointer read_list( struct stack_frame *frame, - struct cons_pointer frame_pointer, - URL_FILE * input, wint_t initial ) { + struct cons_pointer frame_pointer, + URL_FILE * input, wint_t initial ) { struct cons_pointer result = NIL; wint_t c; if ( initial != ')' ) { debug_printf( DEBUG_IO, - L"read_list starting '%C' (%d)\n", initial, initial ); + L"read_list starting '%C' (%d)\n", initial, initial ); struct cons_pointer car = read_continuation( frame, frame_pointer, input, - initial ); + initial ); /* skip whitespace */ - for (c = url_fgetwc( input ); - iswblank( c ) || iswcntrl( c ); - c = url_fgetwc( input )); + for ( c = url_fgetwc( input ); + iswblank( c ) || iswcntrl( c ); c = url_fgetwc( input ) ); - if ( c == L'.') { + if ( c == L'.' ) { /* might be a dotted pair; indeed, if we rule out numbers with * initial periods, it must be a dotted pair. \todo Ought to check, * howerver, that there's only one form after the period. */ result = make_cons( car, - c_car( read_list( frame, - frame_pointer, - input, - url_fgetwc( input ) ) ) ); + c_car( read_list( frame, + frame_pointer, + input, url_fgetwc( input ) ) ) ); } else { result = - make_cons( car, - read_list( frame, frame_pointer, input, c ) ); + make_cons( car, read_list( frame, frame_pointer, input, c ) ); } } else { debug_print( L"End of list detected\n", DEBUG_IO ); @@ -325,35 +324,35 @@ struct cons_pointer read_list( struct stack_frame *frame, struct cons_pointer read_map( struct stack_frame *frame, struct cons_pointer frame_pointer, - URL_FILE *input, wint_t initial ) { - // set write ACL to true whilst creating to prevent GC churn - struct cons_pointer result = make_hashmap( DFLT_HASHMAP_BUCKETS, NIL, TRUE ); - wint_t c = initial; + URL_FILE * input, wint_t initial ) { + // set write ACL to true whilst creating to prevent GC churn + struct cons_pointer result = + make_hashmap( DFLT_HASHMAP_BUCKETS, NIL, TRUE ); + wint_t c = initial; - while ( c != L'}' ) { - struct cons_pointer key = - read_continuation( frame, frame_pointer, input, c ); + while ( c != L'}' ) { + struct cons_pointer key = + read_continuation( frame, frame_pointer, input, c ); - /* skip whitespace */ - for ( c = url_fgetwc( input ); iswblank( c ) || iswcntrl( c ); - c = url_fgetwc( input ) ) - ; + /* skip whitespace */ + for ( c = url_fgetwc( input ); iswblank( c ) || iswcntrl( c ); + c = url_fgetwc( input ) ); - struct cons_pointer value = - read_continuation( frame, frame_pointer, input, c ); + struct cons_pointer value = + read_continuation( frame, frame_pointer, input, c ); - /* skip commaa and whitespace at this point. */ - for ( c = url_fgetwc( input ); c == L',' || iswblank( c ) || iswcntrl( c ); - c = url_fgetwc( input ) ) - ; + /* skip commaa and whitespace at this point. */ + for ( c = url_fgetwc( input ); + c == L',' || iswblank( c ) || iswcntrl( c ); + c = url_fgetwc( input ) ); - result = hashmap_put( result, key, value ); - } + result = hashmap_put( result, key, value ); + } - // default write ACL for maps should be NIL. - pointer_to_vso( result )->payload.hashmap.write_acl = NIL; + // default write ACL for maps should be NIL. + pointer_to_vso( result )->payload.hashmap.write_acl = NIL; - return result; + return result; } /** diff --git a/src/memory/conspage.c b/src/memory/conspage.c index 0b4bf7d..d8d54f9 100644 --- a/src/memory/conspage.c +++ b/src/memory/conspage.c @@ -179,7 +179,7 @@ void free_cell( struct cons_pointer pointer ) { dec_ref( cell->payload.string.cdr ); break; case VECTORPOINTTV: - free_vso( pointer); + free_vso( pointer ); break; } diff --git a/src/memory/consspaceobject.c b/src/memory/consspaceobject.c index 32c777f..5b04699 100644 --- a/src/memory/consspaceobject.c +++ b/src/memory/consspaceobject.c @@ -33,22 +33,22 @@ * vectorspace object indicated by the cell is this `value`, else false. */ bool check_tag( struct cons_pointer pointer, uint32_t value ) { - bool result = false; + bool result = false; - struct cons_space_object cell = pointer2cell( pointer ); - result = cell.tag.value == value; + struct cons_space_object cell = pointer2cell( pointer ); + result = cell.tag.value == value; - if ( result == false ) { - if ( cell.tag.value == VECTORPOINTTV ) { - struct vector_space_object *vec = pointer_to_vso( pointer ); + if ( result == false ) { + if ( cell.tag.value == VECTORPOINTTV ) { + struct vector_space_object *vec = pointer_to_vso( pointer ); - if ( vec != NULL ) { - result = vec->header.tag.value == value; - } + if ( vec != NULL ) { + result = vec->header.tag.value == value; + } + } } - } - return result; + return result; } /** @@ -99,22 +99,24 @@ struct cons_pointer dec_ref( struct cons_pointer pointer ) { * @return As a Lisp string, the tag of the object which is at that pointer. */ struct cons_pointer c_type( struct cons_pointer pointer ) { - struct cons_pointer result = NIL; - struct cons_space_object cell = pointer2cell( pointer ); + struct cons_pointer result = NIL; + struct cons_space_object cell = pointer2cell( pointer ); - if ( strncmp( (char *)&cell.tag.bytes, VECTORPOINTTAG, TAGLENGTH ) == 0 ) { - struct vector_space_object *vec = pointer_to_vso( pointer ); + if ( strncmp( ( char * ) &cell.tag.bytes, VECTORPOINTTAG, TAGLENGTH ) == + 0 ) { + struct vector_space_object *vec = pointer_to_vso( pointer ); - for ( int i = TAGLENGTH - 1; i >= 0; i-- ) { - result = make_string( (wchar_t)vec->header.tag.bytes[i], result ); + for ( int i = TAGLENGTH - 1; i >= 0; i-- ) { + result = + make_string( ( wchar_t ) vec->header.tag.bytes[i], result ); + } + } else { + for ( int i = TAGLENGTH - 1; i >= 0; i-- ) { + result = make_string( ( wchar_t ) cell.tag.bytes[i], result ); + } } - } else { - for ( int i = TAGLENGTH - 1; i >= 0; i-- ) { - result = make_string( (wchar_t)cell.tag.bytes[i], result ); - } - } - return result; + return result; } /** @@ -122,13 +124,13 @@ struct cons_pointer c_type( struct cons_pointer pointer ) { * authorised to read it, does not error but returns nil. */ struct cons_pointer c_car( struct cons_pointer arg ) { - struct cons_pointer result = NIL; + struct cons_pointer result = NIL; - if ( truep( authorised( arg, NIL ) ) && consp( arg ) ) { - result = pointer2cell( arg ).payload.cons.car; - } + if ( truep( authorised( arg, NIL ) ) && consp( arg ) ) { + result = pointer2cell( arg ).payload.cons.car; + } - return result; + return result; } /** @@ -136,34 +138,34 @@ struct cons_pointer c_car( struct cons_pointer arg ) { * not authorised to read it,does not error but returns nil. */ struct cons_pointer c_cdr( struct cons_pointer arg ) { - struct cons_pointer result = NIL; + struct cons_pointer result = NIL; - if ( truep( authorised( arg, NIL ) ) ) { - struct cons_space_object *cell = &pointer2cell( arg ); + if ( truep( authorised( arg, NIL ) ) ) { + struct cons_space_object *cell = &pointer2cell( arg ); - switch ( cell->tag.value ) { - case CONSTV: - result = cell->payload.cons.cdr; - break; - case KEYTV: - case STRINGTV: - case SYMBOLTV: - result = cell->payload.string.cdr; - break; + switch ( cell->tag.value ) { + case CONSTV: + result = cell->payload.cons.cdr; + break; + case KEYTV: + case STRINGTV: + case SYMBOLTV: + result = cell->payload.string.cdr; + break; + } } - } - return result; + return result; } /** * Implementation of `length` in C. If arg is not a cons, does not error but returns 0. */ -int c_length( struct cons_pointer arg) { +int c_length( struct cons_pointer arg ) { int result = 0; - for (struct cons_pointer c = arg; !nilp(c); c = c_cdr(c)) { - result ++; + for ( struct cons_pointer c = arg; !nilp( c ); c = c_cdr( c ) ) { + result++; } return result; @@ -276,27 +278,21 @@ struct cons_pointer make_nlambda( struct cons_pointer args, * * returns 0 for things which are not string like. */ -uint32_t calculate_hash(wint_t c, struct cons_pointer ptr) -{ - struct cons_space_object *cell = &pointer2cell(ptr); +uint32_t calculate_hash( wint_t c, struct cons_pointer ptr ) { + struct cons_space_object *cell = &pointer2cell( ptr ); uint32_t result = 0; - switch (cell->tag.value) - { - case KEYTV: - case STRINGTV: - case SYMBOLTV: - if (nilp(cell->payload.string.cdr)) - { - result = (uint32_t)c; - } - else - { - result = ((uint32_t)c * - cell->payload.string.hash) & - 0xffffffff; - } - break; + switch ( cell->tag.value ) { + case KEYTV: + case STRINGTV: + case SYMBOLTV: + if ( nilp( cell->payload.string.cdr ) ) { + result = ( uint32_t ) c; + } else { + result = ( ( uint32_t ) c * + cell->payload.string.hash ) & 0xffffffff; + } + break; } return result; @@ -324,7 +320,7 @@ make_string_like_thing( wint_t c, struct cons_pointer tail, uint32_t tag ) { * cell->payload.string.cdr = tail */ cell->payload.string.cdr.offset = tail.offset; - cell->payload.string.hash = calculate_hash(c, tail); + cell->payload.string.hash = calculate_hash( c, tail ); } else { // \todo should throw an exception! debug_printf( DEBUG_ALLOC, @@ -430,12 +426,12 @@ struct cons_pointer make_write_stream( URL_FILE * output, struct cons_pointer c_string_to_lisp_keyword( wchar_t *symbol ) { struct cons_pointer result = NIL; - for ( int i = wcslen( symbol ) -1; i >= 0; i-- ) { - wchar_t c = towlower(symbol[i]); + for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) { + wchar_t c = towlower( symbol[i] ); - if (iswalnum(c) || c == L'-') { - result = make_keyword( c, result ); - } + if ( iswalnum( c ) || c == L'-' ) { + result = make_keyword( c, result ); + } } return result; @@ -448,9 +444,9 @@ struct cons_pointer c_string_to_lisp_string( wchar_t *string ) { struct cons_pointer result = NIL; for ( int i = wcslen( string ) - 1; i >= 0; i-- ) { - if (iswprint(string[i]) && string[i] != '"') { - result = make_string( string[i], result ); - } + if ( iswprint( string[i] ) && string[i] != '"' ) { + result = make_string( string[i], result ); + } } return result; diff --git a/src/memory/consspaceobject.h b/src/memory/consspaceobject.h index 0efa0a6..2817e69 100644 --- a/src/memory/consspaceobject.h +++ b/src/memory/consspaceobject.h @@ -685,7 +685,7 @@ struct cons_pointer c_car( struct cons_pointer arg ); struct cons_pointer c_cdr( struct cons_pointer arg ); -int c_length( struct cons_pointer arg); +int c_length( struct cons_pointer arg ); struct cons_pointer make_cons( struct cons_pointer car, struct cons_pointer cdr ); diff --git a/src/memory/dump.c b/src/memory/dump.c index 2dc6658..086f8c8 100644 --- a/src/memory/dump.c +++ b/src/memory/dump.c @@ -46,8 +46,7 @@ void dump_string_cell( URL_FILE * output, wchar_t *prefix, cell.payload.string.character, cell.payload.string.hash, cell.payload.string.cdr.page, - cell.payload.string.cdr.offset, - cell.count ); + cell.payload.string.cdr.offset, cell.count ); url_fwprintf( output, L"\t\t value: " ); print( output, pointer ); url_fwprintf( output, L"\n" ); @@ -57,105 +56,111 @@ void dump_string_cell( URL_FILE * output, wchar_t *prefix, /** * dump the object at this cons_pointer to this output stream. */ -void dump_object( URL_FILE *output, struct cons_pointer pointer ) { - struct cons_space_object cell = pointer2cell( pointer ); - url_fwprintf( output, L"\t%4.4s (%d) at page %d, offset %d count %u\n", - cell.tag.bytes, cell.tag.value, pointer.page, pointer.offset, - cell.count ); +void dump_object( URL_FILE * output, struct cons_pointer pointer ) { + struct cons_space_object cell = pointer2cell( pointer ); + url_fwprintf( output, L"\t%4.4s (%d) at page %d, offset %d count %u\n", + cell.tag.bytes, cell.tag.value, pointer.page, pointer.offset, + cell.count ); - switch ( cell.tag.value ) { - case CONSTV: - url_fwprintf( output, - L"\t\tCons cell: car at page %d offset %d, cdr at page %d " - L"offset %d, count %u :", - cell.payload.cons.car.page, cell.payload.cons.car.offset, - cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset, - cell.count ); - print( output, pointer ); - url_fputws( L"\n", output ); - break; - case EXCEPTIONTV: - url_fwprintf( output, L"\t\tException cell: " ); - dump_stack_trace( output, pointer ); - break; - case FREETV: - url_fwprintf( output, L"\t\tFree cell: next at page %d offset %d\n", - cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset ); - break; - case INTEGERTV: - url_fwprintf( output, L"\t\tInteger cell: value %ld, count %u\n", - cell.payload.integer.value, cell.count ); - if ( !nilp( cell.payload.integer.more ) ) { - url_fputws( L"\t\tBIGNUM! More at:\n", output ); - dump_object( output, cell.payload.integer.more ); - } - break; - case KEYTV: - dump_string_cell( output, L"Keyword", pointer ); - break; - case LAMBDATV: - url_fwprintf( output, L"\t\t\u03bb cell;\n\t\t args: " ); - print( output, cell.payload.lambda.args ); - url_fwprintf( output, L";\n\t\t\tbody: " ); - print( output, cell.payload.lambda.body ); - url_fputws( L"\n", output ); - break; - case NILTV: - break; - case NLAMBDATV: - url_fwprintf( output, L"\t\tn\u03bb cell; \n\t\targs: " ); - print( output, cell.payload.lambda.args ); - url_fwprintf( output, L";\n\t\t\tbody: " ); - print( output, cell.payload.lambda.body ); - url_fputws( L"\n", output ); - break; - case RATIOTV: - url_fwprintf( - output, L"\t\tRational cell: value %ld/%ld, count %u\n", - pointer2cell( cell.payload.ratio.dividend ).payload.integer.value, - pointer2cell( cell.payload.ratio.divisor ).payload.integer.value, - cell.count ); - break; - case READTV: - url_fputws( L"\t\tInput stream; metadata: ", output ); - print( output, cell.payload.stream.meta ); - url_fputws( L"\n", output ); - break; - case REALTV: - url_fwprintf( output, L"\t\tReal cell: value %Lf, count %u\n", - cell.payload.real.value, cell.count ); - break; - case STRINGTV: - dump_string_cell( output, L"String", pointer ); - break; - case SYMBOLTV: - dump_string_cell( output, L"Symbol", pointer ); - break; - case TRUETV: - break; - case VECTORPOINTTV: { - url_fwprintf( output, L"\t\tPointer to vector-space object at %p\n", - cell.payload.vectorp.address ); - struct vector_space_object *vso = cell.payload.vectorp.address; - url_fwprintf( output, - L"\t\tVector space object of type %4.4s (%d), payload size " - L"%d bytes\n", - &vso->header.tag.bytes, vso->header.tag.value, - vso->header.size ); + switch ( cell.tag.value ) { + case CONSTV: + url_fwprintf( output, + L"\t\tCons cell: car at page %d offset %d, cdr at page %d " + L"offset %d, count %u :", + cell.payload.cons.car.page, + cell.payload.cons.car.offset, + cell.payload.cons.cdr.page, + cell.payload.cons.cdr.offset, cell.count ); + print( output, pointer ); + url_fputws( L"\n", output ); + break; + case EXCEPTIONTV: + url_fwprintf( output, L"\t\tException cell: " ); + dump_stack_trace( output, pointer ); + break; + case FREETV: + url_fwprintf( output, + L"\t\tFree cell: next at page %d offset %d\n", + cell.payload.cons.cdr.page, + cell.payload.cons.cdr.offset ); + break; + case INTEGERTV: + url_fwprintf( output, L"\t\tInteger cell: value %ld, count %u\n", + cell.payload.integer.value, cell.count ); + if ( !nilp( cell.payload.integer.more ) ) { + url_fputws( L"\t\tBIGNUM! More at:\n", output ); + dump_object( output, cell.payload.integer.more ); + } + break; + case KEYTV: + dump_string_cell( output, L"Keyword", pointer ); + break; + case LAMBDATV: + url_fwprintf( output, L"\t\t\u03bb cell;\n\t\t args: " ); + print( output, cell.payload.lambda.args ); + url_fwprintf( output, L";\n\t\t\tbody: " ); + print( output, cell.payload.lambda.body ); + url_fputws( L"\n", output ); + break; + case NILTV: + break; + case NLAMBDATV: + url_fwprintf( output, L"\t\tn\u03bb cell; \n\t\targs: " ); + print( output, cell.payload.lambda.args ); + url_fwprintf( output, L";\n\t\t\tbody: " ); + print( output, cell.payload.lambda.body ); + url_fputws( L"\n", output ); + break; + case RATIOTV: + url_fwprintf( output, + L"\t\tRational cell: value %ld/%ld, count %u\n", + pointer2cell( cell.payload.ratio.dividend ).payload. + integer.value, + pointer2cell( cell.payload.ratio.divisor ).payload. + integer.value, cell.count ); + break; + case READTV: + url_fputws( L"\t\tInput stream; metadata: ", output ); + print( output, cell.payload.stream.meta ); + url_fputws( L"\n", output ); + break; + case REALTV: + url_fwprintf( output, L"\t\tReal cell: value %Lf, count %u\n", + cell.payload.real.value, cell.count ); + break; + case STRINGTV: + dump_string_cell( output, L"String", pointer ); + break; + case SYMBOLTV: + dump_string_cell( output, L"Symbol", pointer ); + break; + case TRUETV: + break; + case VECTORPOINTTV:{ + url_fwprintf( output, + L"\t\tPointer to vector-space object at %p\n", + cell.payload.vectorp.address ); + struct vector_space_object *vso = cell.payload.vectorp.address; + url_fwprintf( output, + L"\t\tVector space object of type %4.4s (%d), payload size " + L"%d bytes\n", + &vso->header.tag.bytes, vso->header.tag.value, + vso->header.size ); - switch ( vso->header.tag.value ) { - case STACKFRAMETV: - dump_frame( output, pointer ); - break; - case HASHTV: - dump_map( output, pointer ); - break; - } - } break; - case WRITETV: - url_fputws( L"\t\tOutput stream; metadata: ", output ); - print( output, cell.payload.stream.meta ); - url_fputws( L"\n", output ); - break; - } + switch ( vso->header.tag.value ) { + case STACKFRAMETV: + dump_frame( output, pointer ); + break; + case HASHTV: + dump_map( output, pointer ); + break; + } + } + break; + case WRITETV: + url_fputws( L"\t\tOutput stream; metadata: ", output ); + print( output, cell.payload.stream.meta ); + url_fputws( L"\n", output ); + break; + } } diff --git a/src/memory/hashmap.c b/src/memory/hashmap.c index ae15461..2e68cda 100644 --- a/src/memory/hashmap.c +++ b/src/memory/hashmap.c @@ -24,47 +24,46 @@ * then `(sxhash x)` and `(sxhash y)` will always be equal. */ uint32_t sxhash( struct cons_pointer ptr ) { - // TODO: Not Yet Implemented - /* TODO: should look at the implementation of Common Lisp sxhash? - * My current implementation of `print` only addresses URL_FILE - * streams. It would be better if it also addressed strings but - * currently it doesn't. Creating a print string of the structure - * and taking the hash of that would be one simple (but not necessarily - * cheap) solution. - */ - /* TODO: sbcl's implementation of `sxhash` is in src/compiler/sxhash.lisp - * and is EXTREMELY complex, and essentially has a different dispatch for - * every type of object. It's likely we need to do the same. - */ - return 0; + // TODO: Not Yet Implemented + /* TODO: should look at the implementation of Common Lisp sxhash? + * My current implementation of `print` only addresses URL_FILE + * streams. It would be better if it also addressed strings but + * currently it doesn't. Creating a print string of the structure + * and taking the hash of that would be one simple (but not necessarily + * cheap) solution. + */ + /* TODO: sbcl's implementation of `sxhash` is in src/compiler/sxhash.lisp + * and is EXTREMELY complex, and essentially has a different dispatch for + * every type of object. It's likely we need to do the same. + */ + return 0; } /** * Get the hash value for the cell indicated by this `ptr`; currently only * implemented for string like things and integers. */ -uint32_t get_hash(struct cons_pointer ptr) -{ - struct cons_space_object *cell = &pointer2cell(ptr); +uint32_t get_hash( struct cons_pointer ptr ) { + struct cons_space_object *cell = &pointer2cell( ptr ); uint32_t result = 0; switch ( cell->tag.value ) { - case INTEGERTV: - /* Note that we're only hashing on the least significant word of an - * integer. */ - result = cell->payload.integer.value & 0xffffffff; - break; - case KEYTV: - case STRINGTV: - case SYMBOLTV: - result = cell->payload.string.hash; - break; - case TRUETV: - result = 1; // arbitrarily - break; - default: - result = sxhash( ptr ); - break; + case INTEGERTV: + /* Note that we're only hashing on the least significant word of an + * integer. */ + result = cell->payload.integer.value & 0xffffffff; + break; + case KEYTV: + case STRINGTV: + case SYMBOLTV: + result = cell->payload.string.hash; + break; + case TRUETV: + result = 1; // arbitrarily + break; + default: + result = sxhash( ptr ); + break; } return result; @@ -74,35 +73,34 @@ uint32_t get_hash(struct cons_pointer ptr) * Free the hashmap indicated by this `pointer`. */ void free_hashmap( struct cons_pointer pointer ) { - struct cons_space_object *cell = &pointer2cell( pointer ); + struct cons_space_object *cell = &pointer2cell( pointer ); - if ( hashmapp( pointer ) ) { - struct vector_space_object *vso = cell->payload.vectorp.address; + if ( hashmapp( pointer ) ) { + struct vector_space_object *vso = cell->payload.vectorp.address; - dec_ref( vso->payload.hashmap.hash_fn ); - dec_ref( vso->payload.hashmap.write_acl ); + dec_ref( vso->payload.hashmap.hash_fn ); + dec_ref( vso->payload.hashmap.write_acl ); - for ( int i = 0; i < vso->payload.hashmap.n_buckets; i++ ) { - if ( !nilp( vso->payload.hashmap.buckets[i] ) ) { - debug_printf( DEBUG_ALLOC, - L"Decrementing bucket [%d] of hashmap at 0x%lx\n", i, - cell->payload.vectorp.address ); - dec_ref( vso->payload.hashmap.buckets[i] ); - } + for ( int i = 0; i < vso->payload.hashmap.n_buckets; i++ ) { + if ( !nilp( vso->payload.hashmap.buckets[i] ) ) { + debug_printf( DEBUG_ALLOC, + L"Decrementing bucket [%d] of hashmap at 0x%lx\n", + i, cell->payload.vectorp.address ); + dec_ref( vso->payload.hashmap.buckets[i] ); + } + } + } else { + debug_printf( DEBUG_ALLOC, L"Non-hashmap passed to `free_hashmap`\n" ); } - } else { - debug_printf( DEBUG_ALLOC, L"Non-hashmap passed to `free_hashmap`\n" ); - } } /** * A lisp function signature conforming wrapper around get_hash, q.v.. */ -struct cons_pointer lisp_get_hash(struct stack_frame *frame, - struct cons_pointer frame_pointer, - struct cons_pointer env) -{ - return make_integer(get_hash(frame->arg[0]), NIL); +struct cons_pointer lisp_get_hash( struct stack_frame *frame, + struct cons_pointer frame_pointer, + struct cons_pointer env ) { + return make_integer( get_hash( frame->arg[0] ), NIL ); } /** @@ -112,22 +110,23 @@ struct cons_pointer lisp_get_hash(struct stack_frame *frame, struct cons_pointer make_hashmap( uint32_t n_buckets, struct cons_pointer hash_fn, struct cons_pointer write_acl ) { - struct cons_pointer result = - make_vso( HASHTV, ( sizeof( struct cons_pointer ) * ( n_buckets + 1 ) ) + - ( sizeof( uint32_t ) * 2 ) ); + struct cons_pointer result = + make_vso( HASHTV, + ( sizeof( struct cons_pointer ) * ( n_buckets + 1 ) ) + + ( sizeof( uint32_t ) * 2 ) ); - struct hashmap_payload *payload = - (struct hashmap_payload *)&pointer_to_vso( result )->payload; + struct hashmap_payload *payload = + ( struct hashmap_payload * ) &pointer_to_vso( result )->payload; - payload->hash_fn = inc_ref(hash_fn); - payload->write_acl = inc_ref(write_acl); + payload->hash_fn = inc_ref( hash_fn ); + payload->write_acl = inc_ref( write_acl ); - payload->n_buckets = n_buckets; - for ( int i = 0; i < n_buckets; i++ ) { - payload->buckets[i] = NIL; - } + payload->n_buckets = n_buckets; + for ( int i = 0; i < n_buckets; i++ ) { + payload->buckets[i] = NIL; + } - return result; + return result; } /** @@ -141,52 +140,54 @@ struct cons_pointer make_hashmap( uint32_t n_buckets, struct cons_pointer lisp_make_hashmap( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ) { - uint32_t n = DFLT_HASHMAP_BUCKETS; - struct cons_pointer hash_fn = NIL; - struct cons_pointer result = NIL; + uint32_t n = DFLT_HASHMAP_BUCKETS; + struct cons_pointer hash_fn = NIL; + struct cons_pointer result = NIL; - if ( frame->args > 0 ) { - if ( integerp( frame->arg[0] ) ) { - n = to_long_int( frame->arg[0] ) % UINT32_MAX; - } else if ( !nilp( frame->arg[0] ) ) { - result = make_exception( - c_string_to_lisp_string( L"First arg to `hashmap`, if passed, must " - L"be an integer or `nil`.`" ), - NIL ); + if ( frame->args > 0 ) { + if ( integerp( frame->arg[0] ) ) { + n = to_long_int( frame->arg[0] ) % UINT32_MAX; + } else if ( !nilp( frame->arg[0] ) ) { + result = + make_exception( c_string_to_lisp_string + ( L"First arg to `hashmap`, if passed, must " + L"be an integer or `nil`.`" ), NIL ); + } } - } - if ( frame->args > 1 ) { - hash_fn = frame->arg[1]; - } - - if ( nilp( result ) ) { - /* if there are fewer than 4 args, then arg[3] ought to be nil anyway, which - * is fine */ - result = make_hashmap( n, hash_fn, frame->arg[3] ); - struct vector_space_object *map = pointer_to_vso( result ); - - if ( frame->args > 2 && - truep( authorised( result, map->payload.hashmap.write_acl ) ) ) { - // then arg[2] ought to be an assoc list which we should iterate down - // populating the hashmap. - for ( struct cons_pointer cursor = frame->arg[2]; !nilp( cursor ); - cursor = c_cdr( cursor ) ) { - struct cons_pointer pair = c_car( cursor ); - struct cons_pointer key = c_car( pair ); - struct cons_pointer val = c_cdr( pair ); - - uint32_t bucket_no = - get_hash( key ) % - ( (struct hashmap_payload *)&( map->payload ) )->n_buckets; - - map->payload.hashmap.buckets[bucket_no] = - inc_ref( make_cons( make_cons( key, val ), - map->payload.hashmap.buckets[bucket_no] )); - } + if ( frame->args > 1 ) { + hash_fn = frame->arg[1]; } - } - return result; + if ( nilp( result ) ) { + /* if there are fewer than 4 args, then arg[3] ought to be nil anyway, which + * is fine */ + result = make_hashmap( n, hash_fn, frame->arg[3] ); + struct vector_space_object *map = pointer_to_vso( result ); + + if ( frame->args > 2 && + truep( authorised( result, map->payload.hashmap.write_acl ) ) ) { + // then arg[2] ought to be an assoc list which we should iterate down + // populating the hashmap. + for ( struct cons_pointer cursor = frame->arg[2]; !nilp( cursor ); + cursor = c_cdr( cursor ) ) { + struct cons_pointer pair = c_car( cursor ); + struct cons_pointer key = c_car( pair ); + struct cons_pointer val = c_cdr( pair ); + + uint32_t bucket_no = + get_hash( key ) % + ( ( struct hashmap_payload * ) &( map->payload ) )-> + n_buckets; + + map->payload.hashmap.buckets[bucket_no] = + inc_ref( make_cons( make_cons( key, val ), + map->payload.hashmap. + buckets[bucket_no] ) ); + } + } + } + + return result; } @@ -197,28 +198,30 @@ struct cons_pointer lisp_make_hashmap( struct stack_frame *frame, * readable hashmap. */ struct cons_pointer clone_hashmap( struct cons_pointer ptr ) { - struct cons_pointer result = NIL; + struct cons_pointer result = NIL; - if ( truep( authorised( ptr, NIL ) ) ) { - if ( hashmapp( ptr ) ) { - struct vector_space_object *from = pointer_to_vso( ptr ); + if ( truep( authorised( ptr, NIL ) ) ) { + if ( hashmapp( ptr ) ) { + struct vector_space_object *from = pointer_to_vso( ptr ); - if ( from != NULL ) { - struct hashmap_payload from_pl = from->payload.hashmap; - result = make_hashmap( from_pl.n_buckets, from_pl.hash_fn, from_pl.write_acl ); - struct vector_space_object *to = pointer_to_vso( result ); - struct hashmap_payload to_pl = to->payload.hashmap; + if ( from != NULL ) { + struct hashmap_payload from_pl = from->payload.hashmap; + result = + make_hashmap( from_pl.n_buckets, from_pl.hash_fn, + from_pl.write_acl ); + struct vector_space_object *to = pointer_to_vso( result ); + struct hashmap_payload to_pl = to->payload.hashmap; - for ( int i = 0; i < to_pl.n_buckets; i++ ) { - to_pl.buckets[i] = from_pl.buckets[i]; - inc_ref( to_pl.buckets[i] ); + for ( int i = 0; i < to_pl.n_buckets; i++ ) { + to_pl.buckets[i] = from_pl.buckets[i]; + inc_ref( to_pl.buckets[i] ); + } + } } - } } - } - // TODO: else exception? + // TODO: else exception? - return result; + return result; } /** @@ -229,37 +232,35 @@ struct cons_pointer clone_hashmap( struct cons_pointer ptr ) { struct cons_pointer hashmap_put( struct cons_pointer mapp, struct cons_pointer key, struct cons_pointer val ) { - // TODO: if current user has write access to this hashmap - if ( hashmapp( mapp ) && !nilp( key ) ) { - struct vector_space_object *map = pointer_to_vso( mapp ); + // TODO: if current user has write access to this hashmap + if ( hashmapp( mapp ) && !nilp( key ) ) { + struct vector_space_object *map = pointer_to_vso( mapp ); - if (nilp(authorised(mapp, map->payload.hashmap.write_acl))) { - mapp = clone_hashmap( mapp); - map = pointer_to_vso( mapp ); - } - uint32_t bucket_no = - get_hash( key ) % - map->payload.hashmap.n_buckets; + if ( nilp( authorised( mapp, map->payload.hashmap.write_acl ) ) ) { + mapp = clone_hashmap( mapp ); + map = pointer_to_vso( mapp ); + } + uint32_t bucket_no = get_hash( key ) % map->payload.hashmap.n_buckets; map->payload.hashmap.buckets[bucket_no] = inc_ref( make_cons( make_cons( key, val ), - map->payload.hashmap.buckets[bucket_no] )); - } + map->payload.hashmap.buckets[bucket_no] ) ); + } - return mapp; + return mapp; } struct cons_pointer hashmap_get( struct cons_pointer mapp, struct cons_pointer key ) { - struct cons_pointer result = NIL; - if ( hashmapp( mapp ) && truep( authorised( mapp, NIL ) ) && !nilp( key ) ) { - struct vector_space_object *map = pointer_to_vso( mapp ); - uint32_t bucket_no = get_hash( key ) % map->payload.hashmap.n_buckets; + struct cons_pointer result = NIL; + if ( hashmapp( mapp ) && truep( authorised( mapp, NIL ) ) && !nilp( key ) ) { + struct vector_space_object *map = pointer_to_vso( mapp ); + uint32_t bucket_no = get_hash( key ) % map->payload.hashmap.n_buckets; - result = c_assoc( key, map->payload.hashmap.buckets[bucket_no] ); - } + result = c_assoc( key, map->payload.hashmap.buckets[bucket_no] ); + } - return result; + return result; } /** @@ -272,11 +273,11 @@ struct cons_pointer hashmap_get( struct cons_pointer mapp, struct cons_pointer lisp_hashmap_put( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ) { - struct cons_pointer mapp = frame->arg[0]; - struct cons_pointer key = frame->arg[1]; - struct cons_pointer val = frame->arg[2]; + struct cons_pointer mapp = frame->arg[0]; + struct cons_pointer key = frame->arg[1]; + struct cons_pointer val = frame->arg[2]; - return hashmap_put(mapp, key, val); + return hashmap_put( mapp, key, val ); } /** @@ -286,21 +287,21 @@ struct cons_pointer lisp_hashmap_put( struct stack_frame *frame, */ struct cons_pointer hashmap_put_all( struct cons_pointer mapp, struct cons_pointer assoc ) { - // TODO: if current user has write access to this hashmap - if ( hashmapp( mapp ) && !nilp( assoc ) ) { - struct vector_space_object *map = pointer_to_vso( mapp ); + // TODO: if current user has write access to this hashmap + if ( hashmapp( mapp ) && !nilp( assoc ) ) { + struct vector_space_object *map = pointer_to_vso( mapp ); - if ( hashmapp( mapp ) && consp( assoc ) ) { - for ( struct cons_pointer pair = c_car( assoc ); !nilp( pair ); - pair = c_car( assoc ) ) { - /* TODO: this is really hammering the memory management system, because - * it will make a new lone for every key/value pair added. Fix. */ - mapp = hashmap_put( mapp, c_car( pair ), c_cdr( pair ) ); - } + if ( hashmapp( mapp ) && consp( assoc ) ) { + for ( struct cons_pointer pair = c_car( assoc ); !nilp( pair ); + pair = c_car( assoc ) ) { + /* TODO: this is really hammering the memory management system, because + * it will make a new lone for every key/value pair added. Fix. */ + mapp = hashmap_put( mapp, c_car( pair ), c_cdr( pair ) ); + } + } } - } - return mapp; + return mapp; } /** @@ -310,47 +311,47 @@ struct cons_pointer hashmap_put_all( struct cons_pointer mapp, struct cons_pointer lisp_hashmap_put_all( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ) { - return hashmap_put_all( frame->arg[0], frame->arg[1] ); + return hashmap_put_all( frame->arg[0], frame->arg[1] ); } /** * return a flat list of all the keys in the hashmap indicated by `map`. */ -struct cons_pointer hashmap_keys( struct cons_pointer mapp) { - struct cons_pointer result = NIL; - if ( hashmapp( mapp ) && truep( authorised( mapp, NIL ) )) { +struct cons_pointer hashmap_keys( struct cons_pointer mapp ) { + struct cons_pointer result = NIL; + if ( hashmapp( mapp ) && truep( authorised( mapp, NIL ) ) ) { struct vector_space_object *map = pointer_to_vso( mapp ); - for (int i = 0; i < map->payload.hashmap.n_buckets; i++) { - for (struct cons_pointer c = map->payload.hashmap.buckets[i]; - !nilp(c); - c = c_cdr(c)) { - result = make_cons(c_car( c_car(c)), result); - } + for ( int i = 0; i < map->payload.hashmap.n_buckets; i++ ) { + for ( struct cons_pointer c = map->payload.hashmap.buckets[i]; + !nilp( c ); c = c_cdr( c ) ) { + result = make_cons( c_car( c_car( c ) ), result ); + } + } } - } - return result; + return result; } struct cons_pointer lisp_hashmap_keys( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ) { - return hashmap_keys( frame->arg[0] ); + return hashmap_keys( frame->arg[0] ); } -void dump_map( URL_FILE *output, struct cons_pointer pointer ) { - struct hashmap_payload *payload = &pointer_to_vso( pointer )->payload.hashmap; - url_fwprintf( output, L"Hashmap with %d buckets:\n", payload->n_buckets ); - url_fwprintf( output, L"\tHash function: " ); - print( output, payload->hash_fn ); - url_fwprintf( output, L"\n\tWrite ACL: " ); - print( output, payload->write_acl ); - url_fwprintf( output, L"\n\tBuckets:" ); - for ( int i = 0; i < payload->n_buckets; i++ ) { - url_fwprintf( output, L"\n\t\t[%d]: ", i ); - print( output, payload->buckets[i] ); - } - url_fwprintf( output, L"\n" ); +void dump_map( URL_FILE * output, struct cons_pointer pointer ) { + struct hashmap_payload *payload = + &pointer_to_vso( pointer )->payload.hashmap; + url_fwprintf( output, L"Hashmap with %d buckets:\n", payload->n_buckets ); + url_fwprintf( output, L"\tHash function: " ); + print( output, payload->hash_fn ); + url_fwprintf( output, L"\n\tWrite ACL: " ); + print( output, payload->write_acl ); + url_fwprintf( output, L"\n\tBuckets:" ); + for ( int i = 0; i < payload->n_buckets; i++ ) { + url_fwprintf( output, L"\n\t\t[%d]: ", i ); + print( output, payload->buckets[i] ); + } + url_fwprintf( output, L"\n" ); } diff --git a/src/memory/hashmap.h b/src/memory/hashmap.h index 4602f3e..b6c4a74 100644 --- a/src/memory/hashmap.h +++ b/src/memory/hashmap.h @@ -15,13 +15,13 @@ #include "memory/consspaceobject.h" #include "memory/vectorspace.h" -#define DFLT_HASHMAP_BUCKETS 32 +#define DFLT_HASHMAP_BUCKETS 32 uint32_t get_hash( struct cons_pointer ptr ); void free_hashmap( struct cons_pointer ptr ); -void dump_map( URL_FILE *output, struct cons_pointer pointer ); +void dump_map( URL_FILE * output, struct cons_pointer pointer ); struct cons_pointer hashmap_get( struct cons_pointer mapp, struct cons_pointer key ); @@ -52,4 +52,4 @@ struct cons_pointer make_hashmap( uint32_t n_buckets, struct cons_pointer hash_fn, struct cons_pointer write_acl ); -#endif \ No newline at end of file +#endif diff --git a/src/memory/lookup3.c b/src/memory/lookup3.c index 006d513..359cff2 100644 --- a/src/memory/lookup3.c +++ b/src/memory/lookup3.c @@ -35,12 +35,12 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy. */ // #define SELF_TEST 1 -#include /* defines printf for tests */ -#include /* defines time_t for timings in the test */ -#include /* defines uint32_t etc */ -#include /* attempt to define endianness */ +#include /* defines printf for tests */ +#include /* defines time_t for timings in the test */ +#include /* defines uint32_t etc */ +#include /* attempt to define endianness */ #ifdef linux -# include /* attempt to define endianness */ +#include /* attempt to define endianness */ #endif /* @@ -51,16 +51,16 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy. __BYTE_ORDER == __LITTLE_ENDIAN) || \ (defined(i386) || defined(__i386__) || defined(__i486__) || \ defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) -# define HASH_LITTLE_ENDIAN 1 -# define HASH_BIG_ENDIAN 0 +#define HASH_LITTLE_ENDIAN 1 +#define HASH_BIG_ENDIAN 0 #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ __BYTE_ORDER == __BIG_ENDIAN) || \ (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 1 +#define HASH_LITTLE_ENDIAN 0 +#define HASH_BIG_ENDIAN 1 #else -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 0 +#define HASH_LITTLE_ENDIAN 0 +#define HASH_BIG_ENDIAN 0 #endif #define hashsize(n) ((uint32_t)1<<(n)) @@ -170,39 +170,38 @@ and these came close: hashlittle() has to dance around fitting the key bytes into registers. -------------------------------------------------------------------- */ -uint32_t hashword( -const uint32_t *k, /* the key, an array of uint32_t values */ -size_t length, /* the length of the key, in uint32_ts */ -uint32_t initval) /* the previous hash, or an arbitrary value */ -{ - uint32_t a,b,c; +uint32_t hashword( const uint32_t * k, /* the key, an array of uint32_t values */ + size_t length, /* the length of the key, in uint32_ts */ + uint32_t initval ) { /* the previous hash, or an arbitrary value */ + uint32_t a, b, c; - /* Set up the internal state */ - a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ( ( ( uint32_t ) length ) << 2 ) + initval; /*------------------------------------------------- handle most of the key */ - while (length > 3) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 3; - k += 3; - } + while ( length > 3 ) { + a += k[0]; + b += k[1]; + c += k[2]; + mix( a, b, c ); + length -= 3; + k += 3; + } /*------------------------------------------- handle the last 3 uint32_t's */ - switch(length) /* all the case statements fall through */ - { - case 3 : c+=k[2]; - case 2 : b+=k[1]; - case 1 : a+=k[0]; - final(a,b,c); - case 0: /* case 0: nothing left to add */ - break; - } + switch ( length ) { /* all the case statements fall through */ + case 3: + c += k[2]; + case 2: + b += k[1]; + case 1: + a += k[0]; + final( a, b, c ); + case 0: /* case 0: nothing left to add */ + break; + } /*------------------------------------------------------ report the result */ - return c; + return c; } @@ -214,41 +213,41 @@ both be initialized with seeds. If you pass in (*pb)==0, the output (*pc) will be the same as the return value from hashword(). -------------------------------------------------------------------- */ -void hashword2 ( -const uint32_t *k, /* the key, an array of uint32_t values */ -size_t length, /* the length of the key, in uint32_ts */ -uint32_t *pc, /* IN: seed OUT: primary hash value */ -uint32_t *pb) /* IN: more seed OUT: secondary hash value */ -{ - uint32_t a,b,c; +void hashword2( const uint32_t * k, /* the key, an array of uint32_t values */ + size_t length, /* the length of the key, in uint32_ts */ + uint32_t * pc, /* IN: seed OUT: primary hash value */ + uint32_t * pb ) { /* IN: more seed OUT: secondary hash value */ + uint32_t a, b, c; - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; - c += *pb; + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ( ( uint32_t ) ( length << 2 ) ) + *pc; + c += *pb; /*------------------------------------------------- handle most of the key */ - while (length > 3) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 3; - k += 3; - } + while ( length > 3 ) { + a += k[0]; + b += k[1]; + c += k[2]; + mix( a, b, c ); + length -= 3; + k += 3; + } /*------------------------------------------- handle the last 3 uint32_t's */ - switch(length) /* all the case statements fall through */ - { - case 3 : c+=k[2]; - case 2 : b+=k[1]; - case 1 : a+=k[0]; - final(a,b,c); - case 0: /* case 0: nothing left to add */ - break; - } + switch ( length ) { /* all the case statements fall through */ + case 3: + c += k[2]; + case 2: + b += k[1]; + case 1: + a += k[0]; + final( a, b, c ); + case 0: /* case 0: nothing left to add */ + break; + } /*------------------------------------------------------ report the result */ - *pc=c; *pb=b; + *pc = c; + *pb = b; } @@ -279,173 +278,251 @@ acceptable. Do NOT use for cryptographic purposes. ------------------------------------------------------------------------------- */ -uint32_t hashlittle( const void *key, size_t length, uint32_t initval) -{ - uint32_t a,b,c; /* internal state */ - union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ +uint32_t hashlittle( const void *key, size_t length, uint32_t initval ) { + uint32_t a, b, c; /* internal state */ + union { + const void *ptr; + size_t i; + } u; /* needed for Mac Powerbook G4 */ - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ( ( uint32_t ) length ) + initval; - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; + u.ptr = key; + if ( HASH_LITTLE_ENDIAN && ( ( u.i & 0x3 ) == 0 ) ) { + const uint32_t *k = ( const uint32_t * ) key; /* read 32-bit chunks */ + const uint8_t *k8; /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } + while ( length > 12 ) { + a += k[0]; + b += k[1]; + c += k[2]; + mix( a, b, c ); + length -= 12; + k += 3; + } /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ #ifndef VALGRIND - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : return c; /* zero length strings require no mixing */ - } + switch ( length ) { + case 12: + c += k[2]; + b += k[1]; + a += k[0]; + break; + case 11: + c += k[2] & 0xffffff; + b += k[1]; + a += k[0]; + break; + case 10: + c += k[2] & 0xffff; + b += k[1]; + a += k[0]; + break; + case 9: + c += k[2] & 0xff; + b += k[1]; + a += k[0]; + break; + case 8: + b += k[1]; + a += k[0]; + break; + case 7: + b += k[1] & 0xffffff; + a += k[0]; + break; + case 6: + b += k[1] & 0xffff; + a += k[0]; + break; + case 5: + b += k[1] & 0xff; + a += k[0]; + break; + case 4: + a += k[0]; + break; + case 3: + a += k[0] & 0xffffff; + break; + case 2: + a += k[0] & 0xffff; + break; + case 1: + a += k[0] & 0xff; + break; + case 0: + return c; /* zero length strings require no mixing */ + } #else /* make valgrind happy */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : return c; - } + k8 = ( const uint8_t * ) k; + switch ( length ) { + case 12: + c += k[2]; + b += k[1]; + a += k[0]; + break; + case 11: + c += ( ( uint32_t ) k8[10] ) << 16; /* fall through */ + case 10: + c += ( ( uint32_t ) k8[9] ) << 8; /* fall through */ + case 9: + c += k8[8]; /* fall through */ + case 8: + b += k[1]; + a += k[0]; + break; + case 7: + b += ( ( uint32_t ) k8[6] ) << 16; /* fall through */ + case 6: + b += ( ( uint32_t ) k8[5] ) << 8; /* fall through */ + case 5: + b += k8[4]; /* fall through */ + case 4: + a += k[0]; + break; + case 3: + a += ( ( uint32_t ) k8[2] ) << 16; /* fall through */ + case 2: + a += ( ( uint32_t ) k8[1] ) << 8; /* fall through */ + case 1: + a += k8[0]; + break; + case 0: + return c; + } #endif /* !valgrind */ - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; + } else if ( HASH_LITTLE_ENDIAN && ( ( u.i & 0x1 ) == 0 ) ) { + const uint16_t *k = ( const uint16_t * ) key; /* read 16-bit chunks */ + const uint8_t *k8; /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } + while ( length > 12 ) { + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + b += k[2] + ( ( ( uint32_t ) k[3] ) << 16 ); + c += k[4] + ( ( ( uint32_t ) k[5] ) << 16 ); + mix( a, b, c ); + length -= 12; + k += 6; + } /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : return c; /* zero length requires no mixing */ - } + k8 = ( const uint8_t * ) k; + switch ( length ) { + case 12: + c += k[4] + ( ( ( uint32_t ) k[5] ) << 16 ); + b += k[2] + ( ( ( uint32_t ) k[3] ) << 16 ); + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 11: + c += ( ( uint32_t ) k8[10] ) << 16; /* fall through */ + case 10: + c += k[4]; + b += k[2] + ( ( ( uint32_t ) k[3] ) << 16 ); + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 9: + c += k8[8]; /* fall through */ + case 8: + b += k[2] + ( ( ( uint32_t ) k[3] ) << 16 ); + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 7: + b += ( ( uint32_t ) k8[6] ) << 16; /* fall through */ + case 6: + b += k[2]; + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 5: + b += k8[4]; /* fall through */ + case 4: + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 3: + a += ( ( uint32_t ) k8[2] ) << 16; /* fall through */ + case 2: + a += k[0]; + break; + case 1: + a += k8[0]; + break; + case 0: + return c; /* zero length requires no mixing */ + } - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; + } else { /* need to read the key one byte at a time */ + const uint8_t *k = ( const uint8_t * ) key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } + while ( length > 12 ) { + a += k[0]; + a += ( ( uint32_t ) k[1] ) << 8; + a += ( ( uint32_t ) k[2] ) << 16; + a += ( ( uint32_t ) k[3] ) << 24; + b += k[4]; + b += ( ( uint32_t ) k[5] ) << 8; + b += ( ( uint32_t ) k[6] ) << 16; + b += ( ( uint32_t ) k[7] ) << 24; + c += k[8]; + c += ( ( uint32_t ) k[9] ) << 8; + c += ( ( uint32_t ) k[10] ) << 16; + c += ( ( uint32_t ) k[11] ) << 24; + mix( a, b, c ); + length -= 12; + k += 12; + } /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; - case 11: c+=((uint32_t)k[10])<<16; - case 10: c+=((uint32_t)k[9])<<8; - case 9 : c+=k[8]; - case 8 : b+=((uint32_t)k[7])<<24; - case 7 : b+=((uint32_t)k[6])<<16; - case 6 : b+=((uint32_t)k[5])<<8; - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3])<<24; - case 3 : a+=((uint32_t)k[2])<<16; - case 2 : a+=((uint32_t)k[1])<<8; - case 1 : a+=k[0]; - break; - case 0 : return c; + switch ( length ) { /* all the case statements fall through */ + case 12: + c += ( ( uint32_t ) k[11] ) << 24; + case 11: + c += ( ( uint32_t ) k[10] ) << 16; + case 10: + c += ( ( uint32_t ) k[9] ) << 8; + case 9: + c += k[8]; + case 8: + b += ( ( uint32_t ) k[7] ) << 24; + case 7: + b += ( ( uint32_t ) k[6] ) << 16; + case 6: + b += ( ( uint32_t ) k[5] ) << 8; + case 5: + b += k[4]; + case 4: + a += ( ( uint32_t ) k[3] ) << 24; + case 3: + a += ( ( uint32_t ) k[2] ) << 16; + case 2: + a += ( ( uint32_t ) k[1] ) << 8; + case 1: + a += k[0]; + break; + case 0: + return c; + } } - } - final(a,b,c); - return c; + final( a, b, c ); + return c; } @@ -459,178 +536,264 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval) * the key. *pc is better mixed than *pb, so use *pc first. If you want * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". */ -void hashlittle2( - const void *key, /* the key to hash */ - size_t length, /* length of the key */ - uint32_t *pc, /* IN: primary initval, OUT: primary hash */ - uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ -{ - uint32_t a,b,c; /* internal state */ - union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ +void hashlittle2( const void *key, /* the key to hash */ + size_t length, /* length of the key */ + uint32_t * pc, /* IN: primary initval, OUT: primary hash */ + uint32_t * pb ) { /* IN: secondary initval, OUT: secondary hash */ + uint32_t a, b, c; /* internal state */ + union { + const void *ptr; + size_t i; + } u; /* needed for Mac Powerbook G4 */ - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; - c += *pb; + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ( ( uint32_t ) length ) + *pc; + c += *pb; - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; + u.ptr = key; + if ( HASH_LITTLE_ENDIAN && ( ( u.i & 0x3 ) == 0 ) ) { + const uint32_t *k = ( const uint32_t * ) key; /* read 32-bit chunks */ + const uint8_t *k8; /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } + while ( length > 12 ) { + a += k[0]; + b += k[1]; + c += k[2]; + mix( a, b, c ); + length -= 12; + k += 3; + } /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ #ifndef VALGRIND - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } + switch ( length ) { + case 12: + c += k[2]; + b += k[1]; + a += k[0]; + break; + case 11: + c += k[2] & 0xffffff; + b += k[1]; + a += k[0]; + break; + case 10: + c += k[2] & 0xffff; + b += k[1]; + a += k[0]; + break; + case 9: + c += k[2] & 0xff; + b += k[1]; + a += k[0]; + break; + case 8: + b += k[1]; + a += k[0]; + break; + case 7: + b += k[1] & 0xffffff; + a += k[0]; + break; + case 6: + b += k[1] & 0xffff; + a += k[0]; + break; + case 5: + b += k[1] & 0xff; + a += k[0]; + break; + case 4: + a += k[0]; + break; + case 3: + a += k[0] & 0xffffff; + break; + case 2: + a += k[0] & 0xffff; + break; + case 1: + a += k[0] & 0xff; + break; + case 0: + *pc = c; + *pb = b; + return; /* zero length strings require no mixing */ + } #else /* make valgrind happy */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } + k8 = ( const uint8_t * ) k; + switch ( length ) { + case 12: + c += k[2]; + b += k[1]; + a += k[0]; + break; + case 11: + c += ( ( uint32_t ) k8[10] ) << 16; /* fall through */ + case 10: + c += ( ( uint32_t ) k8[9] ) << 8; /* fall through */ + case 9: + c += k8[8]; /* fall through */ + case 8: + b += k[1]; + a += k[0]; + break; + case 7: + b += ( ( uint32_t ) k8[6] ) << 16; /* fall through */ + case 6: + b += ( ( uint32_t ) k8[5] ) << 8; /* fall through */ + case 5: + b += k8[4]; /* fall through */ + case 4: + a += k[0]; + break; + case 3: + a += ( ( uint32_t ) k8[2] ) << 16; /* fall through */ + case 2: + a += ( ( uint32_t ) k8[1] ) << 8; /* fall through */ + case 1: + a += k8[0]; + break; + case 0: + *pc = c; + *pb = b; + return; /* zero length strings require no mixing */ + } #endif /* !valgrind */ - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; + } else if ( HASH_LITTLE_ENDIAN && ( ( u.i & 0x1 ) == 0 ) ) { + const uint16_t *k = ( const uint16_t * ) key; /* read 16-bit chunks */ + const uint8_t *k8; /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } + while ( length > 12 ) { + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + b += k[2] + ( ( ( uint32_t ) k[3] ) << 16 ); + c += k[4] + ( ( ( uint32_t ) k[5] ) << 16 ); + mix( a, b, c ); + length -= 12; + k += 6; + } /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } + k8 = ( const uint8_t * ) k; + switch ( length ) { + case 12: + c += k[4] + ( ( ( uint32_t ) k[5] ) << 16 ); + b += k[2] + ( ( ( uint32_t ) k[3] ) << 16 ); + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 11: + c += ( ( uint32_t ) k8[10] ) << 16; /* fall through */ + case 10: + c += k[4]; + b += k[2] + ( ( ( uint32_t ) k[3] ) << 16 ); + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 9: + c += k8[8]; /* fall through */ + case 8: + b += k[2] + ( ( ( uint32_t ) k[3] ) << 16 ); + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 7: + b += ( ( uint32_t ) k8[6] ) << 16; /* fall through */ + case 6: + b += k[2]; + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 5: + b += k8[4]; /* fall through */ + case 4: + a += k[0] + ( ( ( uint32_t ) k[1] ) << 16 ); + break; + case 3: + a += ( ( uint32_t ) k8[2] ) << 16; /* fall through */ + case 2: + a += k[0]; + break; + case 1: + a += k8[0]; + break; + case 0: + *pc = c; + *pb = b; + return; /* zero length strings require no mixing */ + } - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; + } else { /* need to read the key one byte at a time */ + const uint8_t *k = ( const uint8_t * ) key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } + while ( length > 12 ) { + a += k[0]; + a += ( ( uint32_t ) k[1] ) << 8; + a += ( ( uint32_t ) k[2] ) << 16; + a += ( ( uint32_t ) k[3] ) << 24; + b += k[4]; + b += ( ( uint32_t ) k[5] ) << 8; + b += ( ( uint32_t ) k[6] ) << 16; + b += ( ( uint32_t ) k[7] ) << 24; + c += k[8]; + c += ( ( uint32_t ) k[9] ) << 8; + c += ( ( uint32_t ) k[10] ) << 16; + c += ( ( uint32_t ) k[11] ) << 24; + mix( a, b, c ); + length -= 12; + k += 12; + } /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; - case 11: c+=((uint32_t)k[10])<<16; - case 10: c+=((uint32_t)k[9])<<8; - case 9 : c+=k[8]; - case 8 : b+=((uint32_t)k[7])<<24; - case 7 : b+=((uint32_t)k[6])<<16; - case 6 : b+=((uint32_t)k[5])<<8; - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3])<<24; - case 3 : a+=((uint32_t)k[2])<<16; - case 2 : a+=((uint32_t)k[1])<<8; - case 1 : a+=k[0]; - break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + switch ( length ) { /* all the case statements fall through */ + case 12: + c += ( ( uint32_t ) k[11] ) << 24; + case 11: + c += ( ( uint32_t ) k[10] ) << 16; + case 10: + c += ( ( uint32_t ) k[9] ) << 8; + case 9: + c += k[8]; + case 8: + b += ( ( uint32_t ) k[7] ) << 24; + case 7: + b += ( ( uint32_t ) k[6] ) << 16; + case 6: + b += ( ( uint32_t ) k[5] ) << 8; + case 5: + b += k[4]; + case 4: + a += ( ( uint32_t ) k[3] ) << 24; + case 3: + a += ( ( uint32_t ) k[2] ) << 16; + case 2: + a += ( ( uint32_t ) k[1] ) << 8; + case 1: + a += k[0]; + break; + case 0: + *pc = c; + *pb = b; + return; /* zero length strings require no mixing */ + } } - } - final(a,b,c); - *pc=c; *pb=b; + final( a, b, c ); + *pc = c; + *pb = b; } @@ -641,147 +804,214 @@ void hashlittle2( * from hashlittle() on all machines. hashbig() takes advantage of * big-endian byte ordering. */ -uint32_t hashbig( const void *key, size_t length, uint32_t initval) -{ - uint32_t a,b,c; - union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ +uint32_t hashbig( const void *key, size_t length, uint32_t initval ) { + uint32_t a, b, c; + union { + const void *ptr; + size_t i; + } u; /* to cast key to (size_t) happily */ - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ( ( uint32_t ) length ) + initval; - u.ptr = key; - if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; + u.ptr = key; + if ( HASH_BIG_ENDIAN && ( ( u.i & 0x3 ) == 0 ) ) { + const uint32_t *k = ( const uint32_t * ) key; /* read 32-bit chunks */ + const uint8_t *k8; /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } + while ( length > 12 ) { + a += k[0]; + b += k[1]; + c += k[2]; + mix( a, b, c ); + length -= 12; + k += 3; + } /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]<<8" actually reads beyond the end of the string, but - * then shifts out the part it's not allowed to read. Because the - * string is aligned, the illegal read is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ + /* + * "k[2]<<8" actually reads beyond the end of the string, but + * then shifts out the part it's not allowed to read. Because the + * string is aligned, the illegal read is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ #ifndef VALGRIND - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; - case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; - case 5 : b+=k[1]&0xff000000; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff00; break; - case 2 : a+=k[0]&0xffff0000; break; - case 1 : a+=k[0]&0xff000000; break; - case 0 : return c; /* zero length strings require no mixing */ - } + switch ( length ) { + case 12: + c += k[2]; + b += k[1]; + a += k[0]; + break; + case 11: + c += k[2] & 0xffffff00; + b += k[1]; + a += k[0]; + break; + case 10: + c += k[2] & 0xffff0000; + b += k[1]; + a += k[0]; + break; + case 9: + c += k[2] & 0xff000000; + b += k[1]; + a += k[0]; + break; + case 8: + b += k[1]; + a += k[0]; + break; + case 7: + b += k[1] & 0xffffff00; + a += k[0]; + break; + case 6: + b += k[1] & 0xffff0000; + a += k[0]; + break; + case 5: + b += k[1] & 0xff000000; + a += k[0]; + break; + case 4: + a += k[0]; + break; + case 3: + a += k[0] & 0xffffff00; + break; + case 2: + a += k[0] & 0xffff0000; + break; + case 1: + a += k[0] & 0xff000000; + break; + case 0: + return c; /* zero length strings require no mixing */ + } -#else /* make valgrind happy */ +#else /* make valgrind happy */ - k8 = (const uint8_t *)k; - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ - case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ - case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ - case 1 : a+=((uint32_t)k8[0])<<24; break; - case 0 : return c; - } + k8 = ( const uint8_t * ) k; + switch ( length ) { /* all the case statements fall through */ + case 12: + c += k[2]; + b += k[1]; + a += k[0]; + break; + case 11: + c += ( ( uint32_t ) k8[10] ) << 8; /* fall through */ + case 10: + c += ( ( uint32_t ) k8[9] ) << 16; /* fall through */ + case 9: + c += ( ( uint32_t ) k8[8] ) << 24; /* fall through */ + case 8: + b += k[1]; + a += k[0]; + break; + case 7: + b += ( ( uint32_t ) k8[6] ) << 8; /* fall through */ + case 6: + b += ( ( uint32_t ) k8[5] ) << 16; /* fall through */ + case 5: + b += ( ( uint32_t ) k8[4] ) << 24; /* fall through */ + case 4: + a += k[0]; + break; + case 3: + a += ( ( uint32_t ) k8[2] ) << 8; /* fall through */ + case 2: + a += ( ( uint32_t ) k8[1] ) << 16; /* fall through */ + case 1: + a += ( ( uint32_t ) k8[0] ) << 24; + break; + case 0: + return c; + } #endif /* !VALGRIND */ - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; + } else { /* need to read the key one byte at a time */ + const uint8_t *k = ( const uint8_t * ) key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += ((uint32_t)k[0])<<24; - a += ((uint32_t)k[1])<<16; - a += ((uint32_t)k[2])<<8; - a += ((uint32_t)k[3]); - b += ((uint32_t)k[4])<<24; - b += ((uint32_t)k[5])<<16; - b += ((uint32_t)k[6])<<8; - b += ((uint32_t)k[7]); - c += ((uint32_t)k[8])<<24; - c += ((uint32_t)k[9])<<16; - c += ((uint32_t)k[10])<<8; - c += ((uint32_t)k[11]); - mix(a,b,c); - length -= 12; - k += 12; - } + while ( length > 12 ) { + a += ( ( uint32_t ) k[0] ) << 24; + a += ( ( uint32_t ) k[1] ) << 16; + a += ( ( uint32_t ) k[2] ) << 8; + a += ( ( uint32_t ) k[3] ); + b += ( ( uint32_t ) k[4] ) << 24; + b += ( ( uint32_t ) k[5] ) << 16; + b += ( ( uint32_t ) k[6] ) << 8; + b += ( ( uint32_t ) k[7] ); + c += ( ( uint32_t ) k[8] ) << 24; + c += ( ( uint32_t ) k[9] ) << 16; + c += ( ( uint32_t ) k[10] ) << 8; + c += ( ( uint32_t ) k[11] ); + mix( a, b, c ); + length -= 12; + k += 12; + } /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[11]; - case 11: c+=((uint32_t)k[10])<<8; - case 10: c+=((uint32_t)k[9])<<16; - case 9 : c+=((uint32_t)k[8])<<24; - case 8 : b+=k[7]; - case 7 : b+=((uint32_t)k[6])<<8; - case 6 : b+=((uint32_t)k[5])<<16; - case 5 : b+=((uint32_t)k[4])<<24; - case 4 : a+=k[3]; - case 3 : a+=((uint32_t)k[2])<<8; - case 2 : a+=((uint32_t)k[1])<<16; - case 1 : a+=((uint32_t)k[0])<<24; - break; - case 0 : return c; + switch ( length ) { /* all the case statements fall through */ + case 12: + c += k[11]; + case 11: + c += ( ( uint32_t ) k[10] ) << 8; + case 10: + c += ( ( uint32_t ) k[9] ) << 16; + case 9: + c += ( ( uint32_t ) k[8] ) << 24; + case 8: + b += k[7]; + case 7: + b += ( ( uint32_t ) k[6] ) << 8; + case 6: + b += ( ( uint32_t ) k[5] ) << 16; + case 5: + b += ( ( uint32_t ) k[4] ) << 24; + case 4: + a += k[3]; + case 3: + a += ( ( uint32_t ) k[2] ) << 8; + case 2: + a += ( ( uint32_t ) k[1] ) << 16; + case 1: + a += ( ( uint32_t ) k[0] ) << 24; + break; + case 0: + return c; + } } - } - final(a,b,c); - return c; + final( a, b, c ); + return c; } #ifdef SELF_TEST /* used for timings */ -void driver1() -{ - uint8_t buf[256]; - uint32_t i; - uint32_t h=0; - time_t a,z; +void driver1( ) { + uint8_t buf[256]; + uint32_t i; + uint32_t h = 0; + time_t a, z; - time(&a); - for (i=0; i<256; ++i) buf[i] = 'x'; - for (i=0; i<1; ++i) - { - h = hashlittle(&buf[0],1,h); - } - time(&z); - if (z-a > 0) printf("time %d %.8x\n", z-a, h); + time( &a ); + for ( i = 0; i < 256; ++i ) + buf[i] = 'x'; + for ( i = 0; i < 1; ++i ) { + h = hashlittle( &buf[0], 1, h ); + } + time( &z ); + if ( z - a > 0 ) + printf( "time %d %.8x\n", z - a, h ); } /* check that every input bit changes every output bit half the time */ @@ -789,213 +1019,263 @@ void driver1() #define HASHLEN 1 #define MAXPAIR 60 #define MAXLEN 70 -void driver2() -{ - uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; - uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; - uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; - uint32_t x[HASHSTATE],y[HASHSTATE]; - uint32_t hlen; +void driver2( ) { + uint8_t qa[MAXLEN + 1], qb[MAXLEN + 2], *a = &qa[0], *b = &qb[1]; + uint32_t c[HASHSTATE], d[HASHSTATE], i = 0, j = 0, k, l, m = 0, z; + uint32_t e[HASHSTATE], f[HASHSTATE], g[HASHSTATE], h[HASHSTATE]; + uint32_t x[HASHSTATE], y[HASHSTATE]; + uint32_t hlen; - printf("No more than %d trials should ever be needed \n",MAXPAIR/2); - for (hlen=0; hlen < MAXLEN; ++hlen) - { - z=0; - for (i=0; i>(8-j)); - c[0] = hashlittle(a, hlen, m); - b[i] ^= ((k+1)<>(8-j)); - d[0] = hashlittle(b, hlen, m); - /* check every bit is 1, 0, set, and not set at least once */ - for (l=0; lz) z=k; - if (k==MAXPAIR) - { - printf("Some bit didn't change: "); - printf("%.8x %.8x %.8x %.8x %.8x %.8x ", - e[0],f[0],g[0],h[0],x[0],y[0]); - printf("i %d j %d m %d len %d\n", i, j, m, hlen); - } - if (z==MAXPAIR) goto done; - } - } + /*---- check that every output bit is affected by that input bit */ + for ( k = 0; k < MAXPAIR; k += 2 ) { + uint32_t finished = 1; + /* keys have one bit different */ + for ( l = 0; l < hlen + 1; ++l ) { + a[l] = b[l] = ( uint8_t ) 0; + } + /* have a and b be two keys differing in only one bit */ + a[i] ^= ( k << j ); + a[i] ^= ( k >> ( 8 - j ) ); + c[0] = hashlittle( a, hlen, m ); + b[i] ^= ( ( k + 1 ) << j ); + b[i] ^= ( ( k + 1 ) >> ( 8 - j ) ); + d[0] = hashlittle( b, hlen, m ); + /* check every bit is 1, 0, set, and not set at least once */ + for ( l = 0; l < HASHSTATE; ++l ) { + e[l] &= ( c[l] ^ d[l] ); + f[l] &= ~( c[l] ^ d[l] ); + g[l] &= c[l]; + h[l] &= ~c[l]; + x[l] &= d[l]; + y[l] &= ~d[l]; + if ( e[l] | f[l] | g[l] | h[l] | x[l] | y[l] ) + finished = 0; + } + if ( finished ) + break; + } + if ( k > z ) + z = k; + if ( k == MAXPAIR ) { + printf( "Some bit didn't change: " ); + printf( "%.8x %.8x %.8x %.8x %.8x %.8x ", + e[0], f[0], g[0], h[0], x[0], y[0] ); + printf( "i %d j %d m %d len %d\n", i, j, m, hlen ); + } + if ( z == MAXPAIR ) + goto done; + } + } + } + done: + if ( z < MAXPAIR ) { + printf( "Mix success %2d bytes %2d initvals ", i, m ); + printf( "required %d trials\n", z / 2 ); + } } - done: - if (z < MAXPAIR) - { - printf("Mix success %2d bytes %2d initvals ",i,m); - printf("required %d trials\n", z/2); - } - } - printf("\n"); + printf( "\n" ); } /* Check for reading beyond the end of the buffer and alignment problems */ -void driver3() -{ - uint8_t buf[MAXLEN+20], *b; - uint32_t len; - uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; - uint32_t h; - uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; - uint32_t i; - uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; - uint32_t j; - uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; - uint32_t ref,x,y; - uint8_t *p; +void driver3( ) { + uint8_t buf[MAXLEN + 20], *b; + uint32_t len; + uint8_t q[] = + "This is the time for all good men to come to the aid of their country..."; + uint32_t h; + uint8_t qq[] = + "xThis is the time for all good men to come to the aid of their country..."; + uint32_t i; + uint8_t qqq[] = + "xxThis is the time for all good men to come to the aid of their country..."; + uint32_t j; + uint8_t qqqq[] = + "xxxThis is the time for all good men to come to the aid of their country..."; + uint32_t ref, x, y; + uint8_t *p; - printf("Endianness. These lines should all be the same (for values filled in):\n"); - printf("%.8x %.8x %.8x\n", - hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13), - hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13), - hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13)); - p = q; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qq[1]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qqq[2]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qqqq[3]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - printf("\n"); + printf + ( "Endianness. These lines should all be the same (for values filled in):\n" ); + printf + ( "%.8x %.8x %.8x\n", + hashword( ( const uint32_t * ) q, ( sizeof( q ) - 1 ) / 4, 13 ), + hashword( ( const uint32_t * ) q, ( sizeof( q ) - 5 ) / 4, 13 ), + hashword( ( const uint32_t * ) q, ( sizeof( q ) - 9 ) / 4, 13 ) ); + p = q; + printf( "%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle( p, sizeof( q ) - 1, 13 ), hashlittle( p, + sizeof( q ) - 2, + 13 ), + hashlittle( p, sizeof( q ) - 3, 13 ), hashlittle( p, + sizeof( q ) - 4, + 13 ), + hashlittle( p, sizeof( q ) - 5, 13 ), hashlittle( p, + sizeof( q ) - 6, + 13 ), + hashlittle( p, sizeof( q ) - 7, 13 ), hashlittle( p, + sizeof( q ) - 8, + 13 ), + hashlittle( p, sizeof( q ) - 9, 13 ), hashlittle( p, + sizeof( q ) - 10, + 13 ), + hashlittle( p, sizeof( q ) - 11, 13 ), hashlittle( p, + sizeof( q ) - + 12, 13 ) ); + p = &qq[1]; + printf( "%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle( p, sizeof( q ) - 1, 13 ), hashlittle( p, + sizeof( q ) - 2, + 13 ), + hashlittle( p, sizeof( q ) - 3, 13 ), hashlittle( p, + sizeof( q ) - 4, + 13 ), + hashlittle( p, sizeof( q ) - 5, 13 ), hashlittle( p, + sizeof( q ) - 6, + 13 ), + hashlittle( p, sizeof( q ) - 7, 13 ), hashlittle( p, + sizeof( q ) - 8, + 13 ), + hashlittle( p, sizeof( q ) - 9, 13 ), hashlittle( p, + sizeof( q ) - 10, + 13 ), + hashlittle( p, sizeof( q ) - 11, 13 ), hashlittle( p, + sizeof( q ) - + 12, 13 ) ); + p = &qqq[2]; + printf( "%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle( p, sizeof( q ) - 1, 13 ), hashlittle( p, + sizeof( q ) - 2, + 13 ), + hashlittle( p, sizeof( q ) - 3, 13 ), hashlittle( p, + sizeof( q ) - 4, + 13 ), + hashlittle( p, sizeof( q ) - 5, 13 ), hashlittle( p, + sizeof( q ) - 6, + 13 ), + hashlittle( p, sizeof( q ) - 7, 13 ), hashlittle( p, + sizeof( q ) - 8, + 13 ), + hashlittle( p, sizeof( q ) - 9, 13 ), hashlittle( p, + sizeof( q ) - 10, + 13 ), + hashlittle( p, sizeof( q ) - 11, 13 ), hashlittle( p, + sizeof( q ) - + 12, 13 ) ); + p = &qqqq[3]; + printf( "%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle( p, sizeof( q ) - 1, 13 ), hashlittle( p, + sizeof( q ) - 2, + 13 ), + hashlittle( p, sizeof( q ) - 3, 13 ), hashlittle( p, + sizeof( q ) - 4, + 13 ), + hashlittle( p, sizeof( q ) - 5, 13 ), hashlittle( p, + sizeof( q ) - 6, + 13 ), + hashlittle( p, sizeof( q ) - 7, 13 ), hashlittle( p, + sizeof( q ) - 8, + 13 ), + hashlittle( p, sizeof( q ) - 9, 13 ), hashlittle( p, + sizeof( q ) - 10, + 13 ), + hashlittle( p, sizeof( q ) - 11, 13 ), hashlittle( p, + sizeof( q ) - + 12, 13 ) ); + printf( "\n" ); - /* check that hashlittle2 and hashlittle produce the same results */ - i=47; j=0; - hashlittle2(q, sizeof(q), &i, &j); - if (hashlittle(q, sizeof(q), 47) != i) - printf("hashlittle2 and hashlittle mismatch\n"); + /* check that hashlittle2 and hashlittle produce the same results */ + i = 47; + j = 0; + hashlittle2( q, sizeof( q ), &i, &j ); + if ( hashlittle( q, sizeof( q ), 47 ) != i ) + printf( "hashlittle2 and hashlittle mismatch\n" ); - /* check that hashword2 and hashword produce the same results */ - len = 0xdeadbeef; - i=47, j=0; - hashword2(&len, 1, &i, &j); - if (hashword(&len, 1, 47) != i) - printf("hashword2 and hashword mismatch %x %x\n", - i, hashword(&len, 1, 47)); + /* check that hashword2 and hashword produce the same results */ + len = 0xdeadbeef; + i = 47, j = 0; + hashword2( &len, 1, &i, &j ); + if ( hashword( &len, 1, 47 ) != i ) + printf( "hashword2 and hashword mismatch %x %x\n", + i, hashword( &len, 1, 47 ) ); - /* check hashlittle doesn't read before or after the ends of the string */ - for (h=0, b=buf+1; h<8; ++h, ++b) - { - for (i=0; iheader.tag.value ) { - case HASHTV: - free_hashmap( pointer ); - break; - case STACKFRAMETV: - free_stack_frame( get_stack_frame( pointer ) ); - break; - } + switch ( vso->header.tag.value ) { + case HASHTV: + free_hashmap( pointer ); + break; + case STACKFRAMETV: + free_stack_frame( get_stack_frame( pointer ) ); + break; + } // free( (void *)cell.payload.vectorp.address ); - debug_printf( DEBUG_ALLOC, L"Freed vector-space object at 0x%lx\n", - cell.payload.vectorp.address ); + debug_printf( DEBUG_ALLOC, L"Freed vector-space object at 0x%lx\n", + cell.payload.vectorp.address ); } // bool check_vso_tag( struct cons_pointer pointer, char * tag) { diff --git a/src/memory/vectorspace.h b/src/memory/vectorspace.h index 2eea84d..3265225 100644 --- a/src/memory/vectorspace.h +++ b/src/memory/vectorspace.h @@ -61,7 +61,7 @@ struct cons_pointer make_vso( uint32_t tag, uint64_t payload_size ); -void free_vso(struct cons_pointer pointer); +void free_vso( struct cons_pointer pointer ); /** * the header which forms the start of every vector space object. @@ -86,18 +86,16 @@ struct vector_space_header { * i.e. either an assoc list or a further hashmap. */ struct hashmap_payload { - struct cons_pointer - hash_fn; /* function for hashing values in this hashmap, or `NIL` to use - the default hashing function */ - struct cons_pointer write_acl; /* it seems to me that it is likely that the - * principal difference between a hashmap and a - * namespace is that a hashmap has a write ACL - * of `NIL`, meaning not writeable by anyone */ - uint32_t n_buckets; /* number of hash buckets */ - uint32_t unused; /* for word alignment and possible later expansion */ - struct cons_pointer - buckets[]; /* actual hash buckets, which should be `NIL` - * or assoc lists or (possibly) further hashmaps. */ + struct cons_pointer hash_fn; /* function for hashing values in this hashmap, or `NIL` to use + the default hashing function */ + struct cons_pointer write_acl; /* it seems to me that it is likely that the + * principal difference between a hashmap and a + * namespace is that a hashmap has a write ACL + * of `NIL`, meaning not writeable by anyone */ + uint32_t n_buckets; /* number of hash buckets */ + uint32_t unused; /* for word alignment and possible later expansion */ + struct cons_pointer buckets[]; /* actual hash buckets, which should be `NIL` + * or assoc lists or (possibly) further hashmaps. */ }; diff --git a/src/ops/equal.c b/src/ops/equal.c index feffb93..a02acc8 100644 --- a/src/ops/equal.c +++ b/src/ops/equal.c @@ -20,9 +20,8 @@ * Shallow, and thus cheap, equality: true if these two objects are * the same object, else false. */ -bool eq(struct cons_pointer a, struct cons_pointer b) -{ - return ((a.page == b.page) && (a.offset == b.offset)); +bool eq( struct cons_pointer a, struct cons_pointer b ) { + return ( ( a.page == b.page ) && ( a.offset == b.offset ) ); } /** @@ -32,10 +31,9 @@ bool eq(struct cons_pointer a, struct cons_pointer b) * @return true if the objects at these two cons pointers have the same tag, * else false. */ -bool same_type(struct cons_pointer a, struct cons_pointer b) -{ - struct cons_space_object *cell_a = &pointer2cell(a); - struct cons_space_object *cell_b = &pointer2cell(b); +bool same_type( struct cons_pointer a, struct cons_pointer b ) { + struct cons_space_object *cell_a = &pointer2cell( a ); + struct cons_space_object *cell_b = &pointer2cell( b ); return cell_a->tag.value == cell_b->tag.value; } @@ -45,104 +43,95 @@ bool same_type(struct cons_pointer a, struct cons_pointer b) * @param string the string to test * @return true if it's the end of a string. */ -bool end_of_string(struct cons_pointer string) -{ - return nilp(string) || - pointer2cell(string).payload.string.character == '\0'; +bool end_of_string( struct cons_pointer string ) { + return nilp( string ) || + pointer2cell( string ).payload.string.character == '\0'; } /** * Deep, and thus expensive, equality: true if these two objects have * identical structure, else false. */ -bool equal(struct cons_pointer a, struct cons_pointer b) -{ - bool result = eq(a, b); +bool equal( struct cons_pointer a, struct cons_pointer b ) { + bool result = eq( a, b ); - if (!result && same_type(a, b)) - { - struct cons_space_object *cell_a = &pointer2cell(a); - struct cons_space_object *cell_b = &pointer2cell(b); + if ( !result && same_type( a, b ) ) { + struct cons_space_object *cell_a = &pointer2cell( a ); + struct cons_space_object *cell_b = &pointer2cell( b ); - switch (cell_a->tag.value) - { - case CONSTV: - case LAMBDATV: - case NLAMBDATV: - /* TODO: it is not OK to do this on the stack since list-like - * structures can be of indefinite extent. It *must* be done by - * iteration (and even that is problematic) */ - result = - equal(cell_a->payload.cons.car, cell_b->payload.cons.car) && equal(cell_a->payload.cons.cdr, - cell_b->payload.cons.cdr); - break; - case KEYTV: - case STRINGTV: - case SYMBOLTV: - /* slightly complex because a string may or may not have a '\0' - * cell at the end, but I'll ignore that for now. I think in - * practice only the empty string will. - */ - /* TODO: it is not OK to do this on the stack since list-like - * structures can be of indefinite extent. It *must* be done by - * iteration (and even that is problematic) */ - result = - cell_a->payload.string.character == + switch ( cell_a->tag.value ) { + case CONSTV: + case LAMBDATV: + case NLAMBDATV: + /* TODO: it is not OK to do this on the stack since list-like + * structures can be of indefinite extent. It *must* be done by + * iteration (and even that is problematic) */ + result = + equal( cell_a->payload.cons.car, cell_b->payload.cons.car ) + && equal( cell_a->payload.cons.cdr, + cell_b->payload.cons.cdr ); + break; + case KEYTV: + case STRINGTV: + case SYMBOLTV: + /* slightly complex because a string may or may not have a '\0' + * cell at the end, but I'll ignore that for now. I think in + * practice only the empty string will. + */ + /* TODO: it is not OK to do this on the stack since list-like + * structures can be of indefinite extent. It *must* be done by + * iteration (and even that is problematic) */ + result = + cell_a->payload.string.character == cell_b->payload.string.character && - (equal(cell_a->payload.string.cdr, - cell_b->payload.string.cdr) || - (end_of_string(cell_a->payload.string.cdr) && end_of_string(cell_b->payload.string.cdr))); - break; - case INTEGERTV: - result = - (cell_a->payload.integer.value == - cell_b->payload.integer.value) && - equal(cell_a->payload.integer.more, - cell_b->payload.integer.more); - break; - case RATIOTV: - result = equal_ratio_ratio(a, b); - break; - case REALTV: - { - double num_a = to_long_double(a); - double num_b = to_long_double(b); - double max = - fabs(num_a) > - fabs(num_b) - ? fabs(num_a) - : fabs(num_b); + ( equal( cell_a->payload.string.cdr, + cell_b->payload.string.cdr ) || + ( end_of_string( cell_a->payload.string.cdr ) + && end_of_string( cell_b->payload.string.cdr ) ) ); + break; + case INTEGERTV: + result = + ( cell_a->payload.integer.value == + cell_b->payload.integer.value ) && + equal( cell_a->payload.integer.more, + cell_b->payload.integer.more ); + break; + case RATIOTV: + result = equal_ratio_ratio( a, b ); + break; + case REALTV: + { + double num_a = to_long_double( a ); + double num_b = to_long_double( b ); + double max = fabs( num_a ) > fabs( num_b ) + ? fabs( num_a ) + : fabs( num_b ); - /* - * not more different than one part in a million - close enough - */ - result = fabs(num_a - num_b) < (max / 1000000.0); + /* + * not more different than one part in a million - close enough + */ + result = fabs( num_a - num_b ) < ( max / 1000000.0 ); + } + break; + default: + result = false; + break; } - break; - default: - result = false; - break; - } - } - else if (numberp(a) && numberp(b)) - { - if (integerp(a)) - { - result = equal_integer_real(a, b); - } - else if (integerp(b)) - { - result = equal_integer_real(b, a); + } else if ( numberp( a ) && numberp( b ) ) { + if ( integerp( a ) ) { + result = equal_integer_real( a, b ); + } else if ( integerp( b ) ) { + result = equal_integer_real( b, a ); } } /* - * there's only supposed ever to be one T and one NIL cell, so each - * should be caught by eq; equality of vector-space objects is a whole - * other ball game so we won't deal with it now (and indeed may never). - * I'm not certain what equality means for read and write streams, so - * I'll ignore them, too, for now. - */ + * there's only supposed ever to be one T and one NIL cell, so each + * should be caught by eq; equality of vector-space objects is a whole + * other ball game so we won't deal with it now (and indeed may never). + * I'm not certain what equality means for read and write streams, so + * I'll ignore them, too, for now. + */ return result; } diff --git a/src/ops/intern.c b/src/ops/intern.c index 07b9693..d7b81c6 100644 --- a/src/ops/intern.c +++ b/src/ops/intern.c @@ -89,16 +89,16 @@ internedp( struct cons_pointer key, struct cons_pointer store ) { * of that key from the store; otherwise return NIL. */ struct cons_pointer c_assoc( struct cons_pointer key, - struct cons_pointer store ) { + struct cons_pointer store ) { struct cons_pointer result = NIL; - debug_print( L"c_assoc; key is `", DEBUG_BIND); - debug_print_object( key, DEBUG_BIND); - debug_print( L"`\n", DEBUG_BIND); + debug_print( L"c_assoc; key is `", DEBUG_BIND ); + debug_print_object( key, DEBUG_BIND ); + debug_print( L"`\n", DEBUG_BIND ); - if (consp(store)) { + if ( consp( store ) ) { for ( struct cons_pointer next = store; - consp( next ); next = pointer2cell( next ).payload.cons.cdr ) { + consp( next ); next = pointer2cell( next ).payload.cons.cdr ) { struct cons_space_object entry = pointer2cell( pointer2cell( next ).payload.cons.car ); @@ -107,15 +107,17 @@ struct cons_pointer c_assoc( struct cons_pointer key, break; } } - } else if (hashmapp( store)) { - result = hashmap_get( store, key); + } else if ( hashmapp( store ) ) { + result = hashmap_get( store, key ); } else { - result = throw_exception(c_string_to_lisp_string(L"Store is of unknown type"), NIL); + result = + throw_exception( c_string_to_lisp_string + ( L"Store is of unknown type" ), NIL ); } - debug_print( L"c_assoc returning ", DEBUG_BIND); - debug_print_object( result, DEBUG_BIND); - debug_println( DEBUG_BIND); + debug_print( L"c_assoc returning ", DEBUG_BIND ); + debug_print_object( result, DEBUG_BIND ); + debug_println( DEBUG_BIND ); return result; } @@ -125,8 +127,8 @@ struct cons_pointer c_assoc( struct cons_pointer key, * with this key/value pair added to the front. */ struct cons_pointer - set( struct cons_pointer key, struct cons_pointer value, - struct cons_pointer store ) { +set( struct cons_pointer key, struct cons_pointer value, + struct cons_pointer store ) { struct cons_pointer result = NIL; debug_print( L"set: binding `", DEBUG_BIND ); @@ -134,18 +136,18 @@ struct cons_pointer debug_print( L"` to `", DEBUG_BIND ); debug_print_object( value, DEBUG_BIND ); debug_print( L"` in store ", DEBUG_BIND ); - debug_dump_object( store, DEBUG_BIND); + debug_dump_object( store, DEBUG_BIND ); debug_println( DEBUG_BIND ); - if (nilp( store) || consp(store)) { + if ( nilp( store ) || consp( store ) ) { result = make_cons( make_cons( key, value ), store ); - } else if (hashmapp( store)) { - result = hashmap_put( store, key, value); + } else if ( hashmapp( store ) ) { + result = hashmap_put( store, key, value ); } - debug_print( L"set returning ", DEBUG_BIND); - debug_print_object( result, DEBUG_BIND); - debug_println( DEBUG_BIND); + debug_print( L"set returning ", DEBUG_BIND ); + debug_print_object( result, DEBUG_BIND ); + debug_println( DEBUG_BIND ); return result; } @@ -195,4 +197,3 @@ intern( struct cons_pointer key, struct cons_pointer environment ) { return result; } - diff --git a/src/ops/lispops.c b/src/ops/lispops.c index 474784d..454fb9a 100644 --- a/src/ops/lispops.c +++ b/src/ops/lispops.c @@ -106,7 +106,7 @@ struct cons_pointer eval_forms( struct stack_frame *frame, list = c_cdr( list ); } - return c_reverse( result); + return c_reverse( result ); } /** @@ -121,19 +121,18 @@ struct cons_pointer eval_forms( struct stack_frame *frame, * * This is experimental. It almost certainly WILL change. */ -struct cons_pointer lisp_try(struct stack_frame *frame, - struct cons_pointer frame_pointer, - struct cons_pointer env) { - struct cons_pointer result = c_progn(frame, frame_pointer, frame->arg[0], env); +struct cons_pointer lisp_try( struct stack_frame *frame, + struct cons_pointer frame_pointer, + struct cons_pointer env ) { + struct cons_pointer result = + c_progn( frame, frame_pointer, frame->arg[0], env ); - if (exceptionp(result)) - { + if ( exceptionp( result ) ) { // TODO: need to put the exception into the environment! - result = c_progn(frame, frame_pointer, frame->arg[1], - make_cons( - make_cons(c_string_to_lisp_keyword(L"*exception*"), - result), - env)); + result = c_progn( frame, frame_pointer, frame->arg[1], + make_cons( make_cons + ( c_string_to_lisp_keyword + ( L"*exception*" ), result ), env ) ); } return result; @@ -282,8 +281,7 @@ eval_lambda( struct cons_space_object cell, struct stack_frame *frame, result = eval_form( frame, frame_pointer, sexpr, new_env ); - if (exceptionp(result)) - { + if ( exceptionp( result ) ) { break; } } @@ -306,8 +304,8 @@ eval_lambda( struct cons_space_object cell, struct stack_frame *frame, * @return the result of evaluating the function with its arguments. */ struct cons_pointer - c_apply( struct stack_frame *frame, struct cons_pointer frame_pointer, - struct cons_pointer env ) { +c_apply( struct stack_frame *frame, struct cons_pointer frame_pointer, + struct cons_pointer env ) { debug_print( L"Entering c_apply\n", DEBUG_EVAL ); struct cons_pointer result = NIL; @@ -322,122 +320,124 @@ struct cons_pointer switch ( fn_cell.tag.value ) { case EXCEPTIONTV: - /* just pass exceptions straight back */ - result = fn_pointer; - break; + /* just pass exceptions straight back */ + result = fn_pointer; + break; case FUNCTIONTV: - { - struct cons_pointer exep = NIL; - struct cons_pointer next_pointer = - make_stack_frame( frame_pointer, args, env ); - inc_ref( next_pointer ); - if ( exceptionp( next_pointer ) ) { - result = next_pointer; - } else { - struct stack_frame *next = - get_stack_frame( next_pointer ); + { + struct cons_pointer exep = NIL; + struct cons_pointer next_pointer = + make_stack_frame( frame_pointer, args, env ); + inc_ref( next_pointer ); + if ( exceptionp( next_pointer ) ) { + result = next_pointer; + } else { + struct stack_frame *next = + get_stack_frame( next_pointer ); - result = - ( *fn_cell.payload.function.executable ) ( next, - next_pointer, - env ); - dec_ref( next_pointer ); - } - } - break; - - case KEYTV: - result = c_assoc( fn_pointer, - eval_form(frame, - frame_pointer, - c_car( c_cdr( frame->arg[0])), - env)); - break; - - case LAMBDATV: - { - struct cons_pointer exep = NIL; - struct cons_pointer next_pointer = - make_stack_frame( frame_pointer, args, env ); - inc_ref( next_pointer ); - if ( exceptionp( next_pointer ) ) { - result = next_pointer; - } else { - struct stack_frame *next = - get_stack_frame( next_pointer ); - result = - eval_lambda( fn_cell, next, next_pointer, env ); - if ( !exceptionp( result ) ) { + result = + ( *fn_cell.payload.function.executable ) ( next, + next_pointer, + env ); dec_ref( next_pointer ); } } - } - break; + break; + + case KEYTV: + result = c_assoc( fn_pointer, + eval_form( frame, + frame_pointer, + c_car( c_cdr( frame->arg[0] ) ), + env ) ); + break; + + case LAMBDATV: + { + struct cons_pointer exep = NIL; + struct cons_pointer next_pointer = + make_stack_frame( frame_pointer, args, env ); + inc_ref( next_pointer ); + if ( exceptionp( next_pointer ) ) { + result = next_pointer; + } else { + struct stack_frame *next = + get_stack_frame( next_pointer ); + result = + eval_lambda( fn_cell, next, next_pointer, env ); + if ( !exceptionp( result ) ) { + dec_ref( next_pointer ); + } + } + } + break; case VECTORPOINTTV: - switch ( pointer_to_vso(fn_pointer)->header.tag.value) { - case HASHTV: - /* \todo: if arg[0] is a CONS, treat it as a path */ - result = c_assoc( eval_form(frame, - frame_pointer, - c_car( c_cdr( frame->arg[0])), - env), - fn_pointer); + switch ( pointer_to_vso( fn_pointer )->header.tag.value ) { + case HASHTV: + /* \todo: if arg[0] is a CONS, treat it as a path */ + result = c_assoc( eval_form( frame, + frame_pointer, + c_car( c_cdr + ( frame-> + arg[0] ) ), + env ), fn_pointer ); + break; + } break; - } - break; case NLAMBDATV: - { - struct cons_pointer next_pointer = - make_special_frame( frame_pointer, args, env ); - inc_ref( next_pointer ); - if ( exceptionp( next_pointer ) ) { - result = next_pointer; - } else { - struct stack_frame *next = - get_stack_frame( next_pointer ); - result = - eval_lambda( fn_cell, next, next_pointer, env ); - dec_ref( next_pointer ); + { + struct cons_pointer next_pointer = + make_special_frame( frame_pointer, args, env ); + inc_ref( next_pointer ); + if ( exceptionp( next_pointer ) ) { + result = next_pointer; + } else { + struct stack_frame *next = + get_stack_frame( next_pointer ); + result = + eval_lambda( fn_cell, next, next_pointer, env ); + dec_ref( next_pointer ); + } } - } - break; + break; case SPECIALTV: - { - struct cons_pointer next_pointer = - make_special_frame( frame_pointer, args, env ); - inc_ref( next_pointer ); - if ( exceptionp( next_pointer ) ) { - result = next_pointer; - } else { - result = - ( *fn_cell.payload.special. - executable ) ( get_stack_frame( next_pointer ), - next_pointer, env ); - debug_print( L"Special form returning: ", DEBUG_EVAL ); - debug_print_object( result, DEBUG_EVAL ); - debug_println( DEBUG_EVAL ); - dec_ref( next_pointer ); + { + struct cons_pointer next_pointer = + make_special_frame( frame_pointer, args, env ); + inc_ref( next_pointer ); + if ( exceptionp( next_pointer ) ) { + result = next_pointer; + } else { + result = + ( *fn_cell.payload. + special.executable ) ( get_stack_frame + ( next_pointer ), + next_pointer, env ); + debug_print( L"Special form returning: ", DEBUG_EVAL ); + debug_print_object( result, DEBUG_EVAL ); + debug_println( DEBUG_EVAL ); + dec_ref( next_pointer ); + } } - } - break; + break; default: - { - int bs = sizeof( wchar_t ) * 1024; - wchar_t *buffer = malloc( bs ); - memset( buffer, '\0', bs ); - swprintf( buffer, bs, - L"Unexpected cell with tag %d (%4.4s) in function position", - fn_cell.tag.value, &fn_cell.tag.bytes[0] ); - struct cons_pointer message = - c_string_to_lisp_string( buffer ); - free( buffer ); - result = throw_exception( message, frame_pointer ); - } + { + int bs = sizeof( wchar_t ) * 1024; + wchar_t *buffer = malloc( bs ); + memset( buffer, '\0', bs ); + swprintf( buffer, bs, + L"Unexpected cell with tag %d (%4.4s) in function position", + fn_cell.tag.value, &fn_cell.tag.bytes[0] ); + struct cons_pointer message = + c_string_to_lisp_string( buffer ); + free( buffer ); + result = throw_exception( message, frame_pointer ); + } } } @@ -479,7 +479,7 @@ lisp_eval( struct stack_frame *frame, struct cons_pointer frame_pointer, switch ( cell.tag.value ) { case CONSTV: - result = c_apply( frame, frame_pointer, env ); + result = c_apply( frame, frame_pointer, env ); break; case SYMBOLTV: @@ -781,9 +781,10 @@ lisp_cdr( struct stack_frame *frame, struct cons_pointer frame_pointer, * @param env my environment (ignored). * @return the length of `any`, if it is a sequence, or zero otherwise. */ -struct cons_pointer lisp_length( struct stack_frame *frame, struct cons_pointer frame_pointer, - struct cons_pointer env ) { - return make_integer( c_length( frame->arg[0]), NIL); +struct cons_pointer lisp_length( struct stack_frame *frame, + struct cons_pointer frame_pointer, + struct cons_pointer env ) { + return make_integer( c_length( frame->arg[0] ), NIL ); } /** @@ -802,24 +803,24 @@ lisp_assoc( struct stack_frame *frame, struct cons_pointer frame_pointer, return c_assoc( frame->arg[0], frame->arg[1] ); } -struct cons_pointer c_keys(struct cons_pointer store) { - struct cons_pointer result = NIL; +struct cons_pointer c_keys( struct cons_pointer store ) { + struct cons_pointer result = NIL; - if ( hashmapp( store ) ) { - result = hashmap_keys( store ); - } else if ( consp( store ) ) { - for ( struct cons_pointer c = store; !nilp( c ); c = c_cdr( c ) ) { - result = make_cons( c_car( c ), result ); + if ( hashmapp( store ) ) { + result = hashmap_keys( store ); + } else if ( consp( store ) ) { + for ( struct cons_pointer c = store; !nilp( c ); c = c_cdr( c ) ) { + result = make_cons( c_car( c ), result ); + } } - } - return result; + return result; } struct cons_pointer lisp_keys( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ) { - return c_keys( frame->arg[0]); + return c_keys( frame->arg[0] ); } /** @@ -962,26 +963,26 @@ struct cons_pointer lisp_reverse( struct stack_frame *frame, struct cons_pointer lisp_inspect( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ) { - debug_print( L"Entering lisp_inspect\n", DEBUG_IO ); - struct cons_pointer result = NIL; - struct cons_pointer out_stream = writep( frame->arg[1] ) - ? frame->arg[1] - : get_default_stream( false, env ); - URL_FILE *output; + debug_print( L"Entering lisp_inspect\n", DEBUG_IO ); + struct cons_pointer result = NIL; + struct cons_pointer out_stream = writep( frame->arg[1] ) + ? frame->arg[1] + : get_default_stream( false, env ); + URL_FILE *output; - if ( writep( out_stream ) ) { - debug_print( L"lisp_inspect: setting output stream\n", DEBUG_IO ); - debug_dump_object( out_stream, DEBUG_IO ); - output = pointer2cell( out_stream ).payload.stream.stream; - } else { - output = file_to_url_file( stderr ); - } + if ( writep( out_stream ) ) { + debug_print( L"lisp_inspect: setting output stream\n", DEBUG_IO ); + debug_dump_object( out_stream, DEBUG_IO ); + output = pointer2cell( out_stream ).payload.stream.stream; + } else { + output = file_to_url_file( stderr ); + } - dump_object( output, frame->arg[0] ); + dump_object( output, frame->arg[0] ); - debug_print( L"Leaving lisp_inspect", DEBUG_IO ); + debug_print( L"Leaving lisp_inspect", DEBUG_IO ); - return result; + return result; } /** @@ -1064,7 +1065,7 @@ c_progn( struct stack_frame *frame, struct cons_pointer frame_pointer, result = eval_form( frame, frame_pointer, c_car( expressions ), env ); dec_ref( r ); - expressions = exceptionp(result) ? NIL : c_cdr( expressions ); + expressions = exceptionp( result ) ? NIL : c_cdr( expressions ); } return result; @@ -1332,7 +1333,7 @@ struct cons_pointer lisp_source( struct stack_frame *frame, case SPECIALTV: result = c_assoc( source_key, cell.payload.special.meta ); break; - case LAMBDATV: + case LAMBDATV: result = make_cons( c_string_to_lisp_symbol( L"lambda" ), make_cons( cell.payload.lambda.args, cell.payload.lambda.body ) ); diff --git a/src/ops/lispops.h b/src/ops/lispops.h index 014df2e..c1cc337 100644 --- a/src/ops/lispops.h +++ b/src/ops/lispops.h @@ -127,8 +127,8 @@ struct cons_pointer lisp_cdr( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ); struct cons_pointer lisp_inspect( struct stack_frame *frame, - struct cons_pointer frame_pointer, - struct cons_pointer env ); + struct cons_pointer frame_pointer, + struct cons_pointer env ); struct cons_pointer lisp_eq( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ); diff --git a/src/time/psse_time.c b/src/time/psse_time.c index e37e522..1f24b0e 100644 --- a/src/time/psse_time.c +++ b/src/time/psse_time.c @@ -28,42 +28,44 @@ * PSSE Lisp epoch is 14 Bn years, or 441,806,400,000,000,000 seconds, before * the UNIX epoch; the value in microseconds will break the C reader. */ -unsigned __int128 epoch_offset = ((__int128)(seconds_per_year * 1000000000L) * - (__int128)(14L * 1000000000L)); +unsigned __int128 epoch_offset = + ( ( __int128 ) ( seconds_per_year * 1000000000L ) * + ( __int128 ) ( 14L * 1000000000L ) ); /** * Return the UNIX time value which represents this time, if it falls within * the period representable in UNIX time, or zero otherwise. */ -long int lisp_time_to_unix_time(struct cons_pointer t) { +long int lisp_time_to_unix_time( struct cons_pointer t ) { long int result = 0; - if (timep( t)) { - unsigned __int128 value = pointer2cell(t).payload.time.value; + if ( timep( t ) ) { + unsigned __int128 value = pointer2cell( t ).payload.time.value; - if (value > epoch_offset) { // \todo && value < UNIX time rollover - result = ((value - epoch_offset) / 1000000000); + if ( value > epoch_offset ) { // \todo && value < UNIX time rollover + result = ( ( value - epoch_offset ) / 1000000000 ); } } return result; } -unsigned __int128 unix_time_to_lisp_time( time_t t) { - unsigned __int128 result = epoch_offset + (t * 1000000000); +unsigned __int128 unix_time_to_lisp_time( time_t t ) { + unsigned __int128 result = epoch_offset + ( t * 1000000000 ); return result; } -struct cons_pointer make_time( struct cons_pointer integer_or_nil) { +struct cons_pointer make_time( struct cons_pointer integer_or_nil ) { struct cons_pointer pointer = allocate_cell( TIMETV ); struct cons_space_object *cell = &pointer2cell( pointer ); - if (integerp(integer_or_nil)) { - cell->payload.time.value = pointer2cell(integer_or_nil).payload.integer.value; + if ( integerp( integer_or_nil ) ) { + cell->payload.time.value = + pointer2cell( integer_or_nil ).payload.integer.value; // \todo: if integer is a bignum, deal with it. } else { - cell->payload.time.value = unix_time_to_lisp_time( time(NULL)); + cell->payload.time.value = unix_time_to_lisp_time( time( NULL ) ); } return pointer; @@ -82,25 +84,26 @@ struct cons_pointer make_time( struct cons_pointer integer_or_nil) { * is that number of microseconds after the notional big bang; else the current * time. */ -struct cons_pointer lisp_time( struct stack_frame *frame, struct cons_pointer frame_pointer, - struct cons_pointer env ) { - return make_time( frame->arg[0]); +struct cons_pointer lisp_time( struct stack_frame *frame, + struct cons_pointer frame_pointer, + struct cons_pointer env ) { + return make_time( frame->arg[0] ); } /** * This is temporary, for bootstrapping. */ -struct cons_pointer time_to_string( struct cons_pointer pointer) { +struct cons_pointer time_to_string( struct cons_pointer pointer ) { struct cons_pointer result = NIL; - long int t = lisp_time_to_unix_time(pointer); + long int t = lisp_time_to_unix_time( pointer ); - if ( t != 0) { - char * bytes = ctime(&t); - int l = strlen(bytes) + 1; - wchar_t buffer[ l]; + if ( t != 0 ) { + char *bytes = ctime( &t ); + int l = strlen( bytes ) + 1; + wchar_t buffer[l]; - mbstowcs( buffer, bytes, l); - result = c_string_to_lisp_string( buffer); + mbstowcs( buffer, bytes, l ); + result = c_string_to_lisp_string( buffer ); } return result; diff --git a/src/time/psse_time.h b/src/time/psse_time.h index af70966..f2afdd2 100644 --- a/src/time/psse_time.h +++ b/src/time/psse_time.h @@ -13,8 +13,9 @@ #define _GNU_SOURCE #include "consspaceobject.h" -struct cons_pointer lisp_time( struct stack_frame *frame, struct cons_pointer frame_pointer, - struct cons_pointer env ); -struct cons_pointer time_to_string( struct cons_pointer pointer); +struct cons_pointer lisp_time( struct stack_frame *frame, + struct cons_pointer frame_pointer, + struct cons_pointer env ); +struct cons_pointer time_to_string( struct cons_pointer pointer ); #endif