Restandardised formatting.

This commit is contained in:
Simon Brooke 2021-08-17 16:37:04 +01:00
parent 93d4bd14a0
commit b0a49fb71d
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
29 changed files with 1861 additions and 1604 deletions

View file

@ -218,18 +218,19 @@ struct cons_pointer base_partial( int depth ) {
/** /**
* destructively modify this `partial` by appending this `digit`. * 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 c = partial;
struct cons_pointer result = partial; struct cons_pointer result = partial;
if (nilp( partial)) { if ( nilp( partial ) ) {
result = digit; result = digit;
} else { } else {
while ( !nilp( pointer2cell(c).payload.integer.more)) { while ( !nilp( pointer2cell( c ).payload.integer.more ) ) {
c = 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; return result;
} }
@ -249,7 +250,7 @@ struct cons_pointer append_digit( struct cons_pointer partial, struct cons_point
*/ */
struct cons_pointer multiply_integers( struct cons_pointer a, struct cons_pointer multiply_integers( struct cons_pointer a,
struct cons_pointer b ) { struct cons_pointer b ) {
struct cons_pointer result = make_integer( 0, NIL); struct cons_pointer result = make_integer( 0, NIL );
bool neg = is_negative( a ) != is_negative( b ); bool neg = is_negative( a ) != is_negative( b );
bool is_first_b = true; bool is_first_b = true;
int i = 0; 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 each digit in a, starting with the least significant (ai) */
for ( struct cons_pointer ai = a; !nilp( 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 */ /* set carry to 0 */
__int128_t carry = 0; __int128_t carry = 0;
@ -274,36 +275,36 @@ struct cons_pointer multiply_integers( struct cons_pointer a,
/* for each digit in b, starting with the least significant (bj) */ /* for each digit in b, starting with the least significant (bj) */
for ( struct cons_pointer bj = b; !nilp( 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, debug_printf( DEBUG_ARITH,
L"multiply_integers: a[i] = %Ld, b[j] = %Ld, i = %d\n", L"multiply_integers: a[i] = %Ld, b[j] = %Ld, i = %d\n",
pointer2cell(ai).payload.integer.value, pointer2cell( ai ).payload.integer.value,
pointer2cell(bj).payload.integer.value, i); pointer2cell( bj ).payload.integer.value, i );
/* multiply ai with bj and add the carry, resulting in a /* multiply ai with bj and add the carry, resulting in a
* value xj which may exceed one digit */ * value xj which may exceed one digit */
__int128_t xj = pointer2cell(ai).payload.integer.value * __int128_t xj = pointer2cell( ai ).payload.integer.value *
pointer2cell(bj).payload.integer.value; pointer2cell( bj ).payload.integer.value;
xj += carry; xj += carry;
/* if xj exceeds one digit, break it into the digit dj and /* if xj exceeds one digit, break it into the digit dj and
* the carry */ * the carry */
carry = xj >> 60; 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 */ /* destructively modify ri by appending dj */
ri = append_digit( ri, dj); ri = append_digit( ri, dj );
} /* end for bj */ } /* end for bj */
/* if carry is not equal to zero, append it as a final digit /* if carry is not equal to zero, append it as a final digit
* to ri */ * to ri */
if (carry != 0) { if ( carry != 0 ) {
ri = append_digit( ri, make_integer( carry, NIL)); ri = append_digit( ri, make_integer( carry, NIL ) );
} }
/* add ri to result */ /* 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( L"multiply_integers: result is ", DEBUG_ARITH );
debug_print_object( result, DEBUG_ARITH ); debug_print_object( result, DEBUG_ARITH );
@ -346,9 +347,12 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
if ( integerp( int_pointer ) ) { if ( integerp( int_pointer ) ) {
struct cons_pointer next = pointer2cell( int_pointer ).payload.integer.more; struct cons_pointer next =
__int128_t accumulator = llabs( pointer2cell( int_pointer ).payload.integer.value ); pointer2cell( int_pointer ).payload.integer.more;
bool is_negative = pointer2cell( int_pointer ).payload.integer.value < 0; __int128_t accumulator =
llabs( pointer2cell( int_pointer ).payload.integer.value );
bool is_negative =
pointer2cell( int_pointer ).payload.integer.value < 0;
int digits = 0; int digits = 0;
if ( accumulator == 0 && nilp( next ) ) { if ( accumulator == 0 && nilp( next ) ) {
@ -356,8 +360,9 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
} else { } else {
while ( accumulator > 0 || !nilp( next ) ) { while ( accumulator > 0 || !nilp( next ) ) {
if ( accumulator < MAX_INTEGER && !nilp( next ) ) { if ( accumulator < MAX_INTEGER && !nilp( next ) ) {
accumulator += (pointer2cell(next).payload.integer.value << 60); accumulator +=
next = pointer2cell(next).payload.integer.more; ( pointer2cell( next ).payload.integer.value << 60 );
next = pointer2cell( next ).payload.integer.more;
} }
int offset = ( int ) ( accumulator % base ); int offset = ( int ) ( accumulator % base );
debug_printf( DEBUG_IO, debug_printf( DEBUG_IO,
@ -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. * 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; 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_a = &pointer2cell( a );
struct cons_space_object *cell_b = &pointer2cell( b ); 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; return result;
@ -410,15 +416,14 @@ 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 * true if `a` is an integer, and `b` is a real number whose value is the
* value of that integer. * 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; bool result = false;
if (integerp(a) && realp(b)) if ( integerp( a ) && realp( b ) ) {
{ long double bv = pointer2cell( b ).payload.real.value;
long double bv = pointer2cell(b).payload.real.value;
if (floor(bv) == bv) { if ( floor( bv ) == bv ) {
result = pointer2cell(a).payload.integer.value == (int64_t)bv; result = pointer2cell( a ).payload.integer.value == ( int64_t ) bv;
} }
} }

View file

@ -14,19 +14,19 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
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 add_integers( struct cons_pointer a,
struct cons_pointer b); struct cons_pointer b );
struct cons_pointer multiply_integers(struct cons_pointer a, struct cons_pointer multiply_integers( struct cons_pointer a,
struct cons_pointer b); struct cons_pointer b );
struct cons_pointer integer_to_string(struct cons_pointer int_pointer, struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
int base); 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 #endif

View file

@ -247,8 +247,7 @@ struct cons_pointer add_2( struct stack_frame *frame,
result = add_integers( arg1, arg2 ); result = add_integers( arg1, arg2 );
break; break;
case RATIOTV: case RATIOTV:
result = result = add_integer_ratio( arg1, arg2 );
add_integer_ratio( arg1, arg2 );
break; break;
case REALTV: case REALTV:
result = result =
@ -268,8 +267,7 @@ struct cons_pointer add_2( struct stack_frame *frame,
result = arg2; result = arg2;
break; break;
case INTEGERTV: case INTEGERTV:
result = result = add_integer_ratio( arg2, arg1 );
add_integer_ratio( arg2, arg1 );
break; break;
case RATIOTV: case RATIOTV:
result = add_ratio_ratio( arg1, arg2 ); result = add_ratio_ratio( arg1, arg2 );
@ -380,9 +378,7 @@ struct cons_pointer multiply_2( struct stack_frame *frame,
result = multiply_integers( arg1, arg2 ); result = multiply_integers( arg1, arg2 );
break; break;
case RATIOTV: case RATIOTV:
result = result = multiply_integer_ratio( arg1, arg2 );
multiply_integer_ratio( arg1,
arg2 );
break; break;
case REALTV: case REALTV:
result = result =
@ -405,13 +401,10 @@ struct cons_pointer multiply_2( struct stack_frame *frame,
result = arg2; result = arg2;
break; break;
case INTEGERTV: case INTEGERTV:
result = result = multiply_integer_ratio( arg2, arg1 );
multiply_integer_ratio( arg2,
arg1 );
break; break;
case RATIOTV: case RATIOTV:
result = result = multiply_ratio_ratio( arg1, arg2 );
multiply_ratio_ratio( arg1, arg2 );
break; break;
case REALTV: case REALTV:
result = result =
@ -564,20 +557,18 @@ struct cons_pointer subtract_2( struct stack_frame *frame,
result = arg2; result = arg2;
break; break;
case INTEGERTV:{ case INTEGERTV:{
struct cons_pointer i = struct cons_pointer i = negative( arg2 );
negative( arg2 );
inc_ref( i ); inc_ref( i );
result = add_integers( arg1, i ); result = add_integers( arg1, i );
dec_ref( i ); dec_ref( i );
} }
break; break;
case RATIOTV:{ case RATIOTV:{
struct cons_pointer tmp = struct cons_pointer tmp = make_ratio( arg1,
make_ratio( arg1, make_integer( 1,
make_integer( 1, NIL ) ); NIL ) );
inc_ref( tmp ); inc_ref( tmp );
result = result = subtract_ratio_ratio( tmp, arg2 );
subtract_ratio_ratio( tmp, arg2 );
dec_ref( tmp ); dec_ref( tmp );
} }
break; break;
@ -599,12 +590,11 @@ struct cons_pointer subtract_2( struct stack_frame *frame,
result = arg2; result = arg2;
break; break;
case INTEGERTV:{ case INTEGERTV:{
struct cons_pointer tmp = struct cons_pointer tmp = make_ratio( arg2,
make_ratio( arg2, make_integer( 1,
make_integer( 1, NIL ) ); NIL ) );
inc_ref( tmp ); inc_ref( tmp );
result = result = subtract_ratio_ratio( arg1, tmp );
subtract_ratio_ratio( arg1, tmp );
dec_ref( tmp ); dec_ref( tmp );
} }
break; break;
@ -696,9 +686,7 @@ struct cons_pointer lisp_divide( struct
struct cons_pointer ratio = struct cons_pointer ratio =
make_ratio( frame->arg[0], one ); make_ratio( frame->arg[0], one );
inc_ref( ratio ); inc_ref( ratio );
result = result = divide_ratio_ratio( ratio, frame->arg[1] );
divide_ratio_ratio( ratio,
frame->arg[1] );
dec_ref( ratio ); dec_ref( ratio );
} }
break; break;
@ -725,17 +713,14 @@ struct cons_pointer lisp_divide( struct
struct cons_pointer ratio = struct cons_pointer ratio =
make_ratio( frame->arg[1], one ); make_ratio( frame->arg[1], one );
inc_ref( ratio ); inc_ref( ratio );
result = result = divide_ratio_ratio( frame->arg[0], ratio );
divide_ratio_ratio( frame->arg[0],
ratio );
dec_ref( ratio ); dec_ref( ratio );
dec_ref( one ); dec_ref( one );
} }
break; break;
case RATIOTV: case RATIOTV:
result = result =
divide_ratio_ratio( frame->arg[0], divide_ratio_ratio( frame->arg[0], frame->arg[1] );
frame->arg[1] );
break; break;
case REALTV: case REALTV:
result = result =

View file

@ -27,7 +27,7 @@ struct cons_pointer absolute( struct cons_pointer arg );
long double to_long_double( 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 struct cons_pointer lisp_absolute( struct stack_frame
*frame, struct cons_pointer frame_pointer, struct *frame, struct cons_pointer frame_pointer, struct

View file

@ -43,35 +43,29 @@ int64_t least_common_multiple( int64_t m, int64_t n ) {
return m / greatest_common_divisor( m, n ) * 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_pointer result = pointer;
struct cons_space_object cell = pointer2cell(pointer); struct cons_space_object cell = pointer2cell( pointer );
struct cons_space_object dividend = pointer2cell(cell.payload.ratio.dividend); struct cons_space_object dividend =
struct cons_space_object divisor = pointer2cell(cell.payload.ratio.divisor); pointer2cell( cell.payload.ratio.dividend );
struct cons_space_object divisor =
pointer2cell( cell.payload.ratio.divisor );
if (divisor.payload.integer.value == 1) if ( divisor.payload.integer.value == 1 ) {
{ result = pointer2cell( pointer ).payload.ratio.dividend;
result = pointer2cell(pointer).payload.ratio.dividend; } else {
} if ( ratiop( pointer ) ) {
else
{
if (ratiop(pointer))
{
int64_t ddrv = dividend.payload.integer.value, int64_t ddrv = dividend.payload.integer.value,
drrv = divisor.payload.integer.value, drrv = divisor.payload.integer.value,
gcd = greatest_common_divisor(ddrv, drrv); gcd = greatest_common_divisor( ddrv, drrv );
if (gcd > 1) if ( gcd > 1 ) {
{ if ( drrv / gcd == 1 ) {
if (drrv / gcd == 1) result = make_integer( ddrv / gcd, NIL );
{ } else {
result = make_integer(ddrv / gcd, NIL);
}
else
{
result = result =
make_ratio(make_integer(ddrv / gcd, NIL), make_ratio( make_integer( ddrv / gcd, NIL ),
make_integer(drrv / gcd, NIL)); make_integer( drrv / gcd, NIL ) );
} }
} }
} }
@ -181,8 +175,7 @@ struct cons_pointer add_integer_ratio( struct cons_pointer intarg,
( L"Shouldn't happen: bad arg to add_integer_ratio" ), ( L"Shouldn't happen: bad arg to add_integer_ratio" ),
make_cons( intarg, make_cons( intarg,
make_cons( ratarg, make_cons( ratarg,
NIL ) ) ), NIL ) ) ), NIL );
NIL );
} }
return result; return result;
@ -197,10 +190,9 @@ struct cons_pointer add_integer_ratio( struct cons_pointer intarg,
struct cons_pointer divide_ratio_ratio( struct cons_pointer arg1, struct cons_pointer divide_ratio_ratio( struct cons_pointer arg1,
struct cons_pointer arg2 ) { 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 i = make_ratio( pointer2cell( arg2 ).payload. struct cons_pointer i =
ratio.divisor, make_ratio( pointer2cell( arg2 ).payload.ratio.divisor,
pointer2cell( arg2 ).payload. pointer2cell( arg2 ).payload.ratio.dividend ), result =
ratio.dividend ), result =
multiply_ratio_ratio( arg1, i ); multiply_ratio_ratio( arg1, i );
dec_ref( i ); dec_ref( i );
@ -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 subtract_ratio_ratio( struct cons_pointer arg1,
struct cons_pointer arg2 ) { struct cons_pointer arg2 ) {
struct cons_pointer i = negative( arg2), struct cons_pointer i = negative( arg2 ),
result = add_ratio_ratio( arg1, i ); result = add_ratio_ratio( arg1, i );
dec_ref( i ); dec_ref( i );
@ -333,19 +325,17 @@ struct cons_pointer make_ratio( struct cons_pointer dividend,
/** /**
* True if a and be are identical ratios, else false. * 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; bool result = false;
if (ratiop(a) && ratiop(b)) if ( ratiop( a ) && ratiop( b ) ) {
{ struct cons_space_object *cell_a = &pointer2cell( a );
struct cons_space_object *cell_a = &pointer2cell(a); struct cons_space_object *cell_b = &pointer2cell( b );
struct cons_space_object *cell_b = &pointer2cell(b);
result = equal_integer_integer(cell_a->payload.ratio.dividend, result = equal_integer_integer( cell_a->payload.ratio.dividend,
cell_b->payload.ratio.dividend) && cell_b->payload.ratio.dividend ) &&
equal_integer_integer(cell_a->payload.ratio.divisor, equal_integer_integer( cell_a->payload.ratio.divisor,
cell_b->payload.ratio.divisor); cell_b->payload.ratio.divisor );
} }
return result; return result;

View file

@ -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 make_ratio( struct cons_pointer dividend,
struct cons_pointer divisor ); 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 #endif

View file

@ -15,10 +15,10 @@
* TODO: does nothing, yet. What it should do is access a magic value in the * 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` * 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) { struct cons_pointer authorised( struct cons_pointer target,
if (nilp(acl)) { struct cons_pointer acl ) {
acl = pointer2cell(target).access; if ( nilp( acl ) ) {
acl = pointer2cell( target ).access;
} }
return TRUE; return TRUE;
} }

View file

@ -10,6 +10,7 @@
#ifndef __psse_authorise_h #ifndef __psse_authorise_h
#define __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 #endif

View file

@ -84,8 +84,9 @@ void bind_value( wchar_t *name, struct cons_pointer value ) {
dec_ref( n ); dec_ref( n );
} }
void print_banner() { void print_banner( ) {
fwprintf(stdout, L"Post-Scarcity Software Environment version %s\n\n", VERSION); 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. * @stream the stream to print to.
*/ */
void print_options(FILE* stream) { void print_options( FILE * stream ) {
fwprintf(stream, L"Expected options are:\n"); 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,
fwprintf(stream, L"\t-h\tPrint this message and exit;\n"); L"\t-d\tDump memory to standard out at end of run (copious!);\n" );
fwprintf(stream, L"\t-p\tShow a prompt (default is no prompt);\n"); fwprintf( stream, L"\t-h\tPrint this message and exit;\n" );
fwprintf(stream, L"\t-v LEVEL\n\t\tSet verbosity to the specified level (0...512)\n"); fwprintf( stream, L"\t-p\tShow a prompt (default is no prompt);\n" );
fwprintf(stream, L"\t\tWhere bits are interpreted as follows:\n"); fwprintf( stream,
fwprintf(stream, L"\t\t1\tALLOC;\n"); L"\t-v LEVEL\n\t\tSet verbosity to the specified level (0...512)\n" );
fwprintf(stream, L"\t\t2\tARITH;\n"); fwprintf( stream, L"\t\tWhere bits are interpreted as follows:\n" );
fwprintf(stream, L"\t\t4\tBIND;\n"); fwprintf( stream, L"\t\t1\tALLOC;\n" );
fwprintf(stream, L"\t\t8\tBOOTSTRAP;\n"); fwprintf( stream, L"\t\t2\tARITH;\n" );
fwprintf(stream, L"\t\t16\tEVAL;\n"); fwprintf( stream, L"\t\t4\tBIND;\n" );
fwprintf(stream, L"\t\t32\tINPUT/OUTPUT;\n"); fwprintf( stream, L"\t\t8\tBOOTSTRAP;\n" );
fwprintf(stream, L"\t\t64\tLAMBDA;\n"); fwprintf( stream, L"\t\t16\tEVAL;\n" );
fwprintf(stream, L"\t\t128\tREPL;\n"); fwprintf( stream, L"\t\t32\tINPUT/OUTPUT;\n" );
fwprintf(stream, L"\t\t256\tSTACK.\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; dump_at_end = true;
break; break;
case 'h': case 'h':
print_banner(); print_banner( );
print_options(stdout); print_options( stdout );
exit( 0 ); exit( 0 );
break; break;
case 'p': case 'p':
@ -144,14 +147,14 @@ int main( int argc, char *argv[] ) {
break; break;
default: default:
fwprintf( stderr, L"Unexpected option %c\n", option ); fwprintf( stderr, L"Unexpected option %c\n", option );
print_options(stderr); print_options( stderr );
exit( 1 ); exit( 1 );
break; break;
} }
} }
if ( show_prompt ) { if ( show_prompt ) {
print_banner(); print_banner( );
} }
debug_print( L"About to initialise cons pages\n", DEBUG_BOOTSTRAP ); 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"equal", &lisp_equal );
bind_function( L"eval", &lisp_eval ); bind_function( L"eval", &lisp_eval );
bind_function( L"exception", &lisp_exception ); bind_function( L"exception", &lisp_exception );
bind_function( L"get-hash", &lisp_get_hash); bind_function( L"get-hash", &lisp_get_hash );
bind_function(L"hashmap", lisp_make_hashmap); bind_function( L"hashmap", lisp_make_hashmap );
bind_function( L"inspect", &lisp_inspect ); 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"meta", &lisp_metadata );
bind_function( L"metadata", &lisp_metadata ); bind_function( L"metadata", &lisp_metadata );
bind_function( L"multiply", &lisp_multiply ); 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"open", &lisp_open );
bind_function( L"print", &lisp_print ); bind_function( L"print", &lisp_print );
bind_function( L"progn", &lisp_progn ); bind_function( L"progn", &lisp_progn );
bind_function( L"put", lisp_hashmap_put); bind_function( L"put", lisp_hashmap_put );
bind_function( L"put-all", &lisp_hashmap_put_all); bind_function( L"put-all", &lisp_hashmap_put_all );
bind_function( L"read", &lisp_read ); bind_function( L"read", &lisp_read );
bind_function( L"read-char", &lisp_read_char ); bind_function( L"read-char", &lisp_read_char );
bind_function( L"repl", &lisp_repl ); bind_function( L"repl", &lisp_repl );

View file

@ -213,7 +213,7 @@ URL_FILE *url_fopen( const char *url, const char *operation ) {
file->handle.file = fopen( url, operation ); file->handle.file = fopen( url, operation );
if ( file->handle.file ) { if ( file->handle.file ) {
file->type = CFTYPE_FILE; /* marked as 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->type = CFTYPE_CURL; /* marked as URL */
file->handle.curl = curl_easy_init( ); file->handle.curl = curl_easy_init( );

View file

@ -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, struct cons_pointer add_meta_string( struct cons_pointer meta, wchar_t *key,
char *value ) { char *value ) {
value = trim( value); value = trim( value );
wchar_t buffer[strlen( value ) + 1]; wchar_t buffer[strlen( value ) + 1];
mbstowcs( buffer, value, strlen( value ) + 1 ); mbstowcs( buffer, value, strlen( value ) + 1 );
@ -281,8 +281,7 @@ struct cons_pointer add_meta_time( struct cons_pointer meta, wchar_t *key,
strftime( datestring, strftime( datestring,
sizeof( datestring ), sizeof( datestring ),
nl_langinfo( D_T_FMT ), nl_langinfo( D_T_FMT ), localtime( value ) );
localtime( value ) );
return add_meta_string( meta, key, datestring ); return add_meta_string( meta, key, datestring );
} }
@ -442,19 +441,22 @@ lisp_open( struct stack_frame *frame, struct cons_pointer frame_pointer,
debug_printf( DEBUG_IO, debug_printf( DEBUG_IO,
L"lisp_open: stream @ %ld, stream type = %d, stream handle = %ld\n", L"lisp_open: stream @ %ld, stream type = %d, stream handle = %ld\n",
(long int) &stream, (int)stream->type, (long int)stream->handle.file); ( long int ) &stream, ( int ) stream->type,
( long int ) stream->handle.file );
switch (stream->type) { switch ( stream->type ) {
case CFTYPE_NONE: case CFTYPE_NONE:
return make_exception( return
c_string_to_lisp_string( L"Could not open stream"), make_exception( c_string_to_lisp_string
frame_pointer); ( L"Could not open stream" ),
frame_pointer );
break; break;
case CFTYPE_FILE: case CFTYPE_FILE:
if (stream->handle.file == NULL) { if ( stream->handle.file == NULL ) {
return make_exception( return
c_string_to_lisp_string( L"Could not open file"), make_exception( c_string_to_lisp_string
frame_pointer); ( L"Could not open file" ),
frame_pointer );
} }
break; break;
case CFTYPE_CURL: case CFTYPE_CURL:
@ -501,8 +503,8 @@ lisp_read_char( struct stack_frame *frame, struct cons_pointer frame_pointer,
if ( readp( frame->arg[0] ) ) { if ( readp( frame->arg[0] ) ) {
result = result =
make_string( url_fgetwc make_string( url_fgetwc
( pointer2cell( frame->arg[0] ).payload. ( pointer2cell( frame->arg[0] ).payload.stream.
stream.stream ), NIL ); stream ), NIL );
} }
return result; return result;

View file

@ -88,7 +88,7 @@ void print_list( URL_FILE * output, struct cons_pointer pointer ) {
url_fputws( L")", output ); url_fputws( L")", output );
} }
void print_map( URL_FILE *output, struct cons_pointer map ) { void print_map( URL_FILE * output, struct cons_pointer map ) {
if ( hashmapp( map ) ) { if ( hashmapp( map ) ) {
struct vector_space_object *vso = pointer_to_vso( map ); struct vector_space_object *vso = pointer_to_vso( map );
@ -96,7 +96,7 @@ void print_map( URL_FILE *output, struct cons_pointer map ) {
for ( struct cons_pointer ks = hashmap_keys( map ); !nilp( ks ); for ( struct cons_pointer ks = hashmap_keys( map ); !nilp( ks );
ks = c_cdr( ks ) ) { ks = c_cdr( ks ) ) {
struct cons_pointer key = c_car( ks); struct cons_pointer key = c_car( ks );
print( output, key ); print( output, key );
url_fputwc( btowc( ' ' ), output ); url_fputwc( btowc( ' ' ), output );
print( output, hashmap_get( map, key ) ); print( output, hashmap_get( map, key ) );
@ -110,11 +110,11 @@ void print_map( URL_FILE *output, struct cons_pointer map ) {
} }
} }
void print_vso( URL_FILE * output, struct cons_pointer pointer) { void print_vso( URL_FILE * output, struct cons_pointer pointer ) {
struct vector_space_object *vso = pointer_to_vso(pointer); struct vector_space_object *vso = pointer_to_vso( pointer );
switch ( vso->header.tag.value) { switch ( vso->header.tag.value ) {
case HASHTV: case HASHTV:
print_map( output, pointer); print_map( output, pointer );
break; break;
// \todo: others. // \todo: others.
default: default:
@ -165,9 +165,9 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) {
dump_stack_trace( output, pointer ); dump_stack_trace( output, pointer );
break; break;
case FUNCTIONTV: case FUNCTIONTV:
url_fputws( L"<Function: ", output); url_fputws( L"<Function: ", output );
print( output, cell.payload.function.meta); print( output, cell.payload.function.meta );
url_fputwc( L'>', output); url_fputwc( L'>', output );
break; break;
case INTEGERTV:{ case INTEGERTV:{
struct cons_pointer s = integer_to_string( pointer, 10 ); 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 ); print_string_contents( output, pointer );
break; break;
case LAMBDATV:{ case LAMBDATV:{
url_fputws( L"<Anonymous Function: ", output); url_fputws( L"<Anonymous Function: ", output );
struct cons_pointer to_print = struct cons_pointer to_print =
make_cons( c_string_to_lisp_symbol( L"\u03bb" ), make_cons( c_string_to_lisp_symbol( L"\u03bb" ),
make_cons( cell.payload.lambda.args, make_cons( cell.payload.lambda.args,
@ -191,14 +191,14 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) {
print( output, to_print ); print( output, to_print );
dec_ref( to_print ); dec_ref( to_print );
url_fputwc( L'>', output); url_fputwc( L'>', output );
} }
break; break;
case NILTV: case NILTV:
url_fwprintf( output, L"nil" ); url_fwprintf( output, L"nil" );
break; break;
case NLAMBDATV:{ case NLAMBDATV:{
url_fputws( L"<Anonymous Special Form: ", output); url_fputws( L"<Anonymous Special Form: ", output );
struct cons_pointer to_print = struct cons_pointer to_print =
make_cons( c_string_to_lisp_symbol( L"n\u03bb" ), make_cons( c_string_to_lisp_symbol( L"n\u03bb" ),
make_cons( cell.payload.lambda.args, make_cons( cell.payload.lambda.args,
@ -208,7 +208,7 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) {
print( output, to_print ); print( output, to_print );
dec_ref( to_print ); dec_ref( to_print );
url_fputwc( L'>', output); url_fputwc( L'>', output );
} }
break; break;
case RATIOTV: case RATIOTV:
@ -218,8 +218,8 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) {
break; break;
case READTV: case READTV:
url_fwprintf( output, L"<Input stream: " ); url_fwprintf( output, L"<Input stream: " );
print( output, cell.payload.stream.meta); print( output, cell.payload.stream.meta );
url_fputwc( L'>', output); url_fputwc( L'>', output );
break; break;
case REALTV: case REALTV:
/* \todo using the C heap is a bad plan because it will fragment. /* \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; break;
case SPECIALTV: case SPECIALTV:
url_fwprintf( output, L"<Special form: " ); url_fwprintf( output, L"<Special form: " );
print( output, cell.payload.special.meta); print( output, cell.payload.special.meta );
url_fputwc( L'>', output); url_fputwc( L'>', output );
break; break;
case TIMETV: case TIMETV:
url_fwprintf( output, L"<Time: " ); url_fwprintf( output, L"<Time: " );
print_string( output, time_to_string( pointer)); print_string( output, time_to_string( pointer ) );
url_fputws( L"; ", output); url_fputws( L"; ", output );
print_128bit( output, pointer2cell(pointer).payload.time.value); print_128bit( output, pointer2cell( pointer ).payload.time.value );
url_fputwc( L'>', output); url_fputwc( L'>', output );
break; break;
case TRUETV: case TRUETV:
url_fwprintf( output, L"t" ); url_fwprintf( output, L"t" );
break; break;
case VECTORPOINTTV: case VECTORPOINTTV:
print_vso( output, pointer); print_vso( output, pointer );
break; break;
case WRITETV: case WRITETV:
url_fwprintf( output, L"<Output stream: " ); url_fwprintf( output, L"<Output stream: " );
print( output, cell.payload.stream.meta); print( output, cell.payload.stream.meta );
url_fputwc( L'>', output); url_fputwc( L'>', output );
break; break;
default: default:
fwprintf( stderr, fwprintf( stderr,

View file

@ -134,10 +134,12 @@ struct cons_pointer read_continuation( struct stack_frame *frame,
} else if ( iswblank( next ) ) { } else if ( iswblank( next ) ) {
/* dotted pair. \todo this isn't right, we /* dotted pair. \todo this isn't right, we
* really need to backtrack up a level. */ * really need to backtrack up a level. */
result = read_continuation( frame, frame_pointer, input, result =
read_continuation( frame, frame_pointer, input,
url_fgetwc( input ) ); url_fgetwc( input ) );
debug_print( L"read_continuation: dotted pair; read cdr ", debug_print
DEBUG_IO); ( L"read_continuation: dotted pair; read cdr ",
DEBUG_IO );
} else { } else {
read_symbol_or_key( input, SYMBOLTV, c ); read_symbol_or_key( input, SYMBOLTV, c );
} }
@ -297,11 +299,10 @@ struct cons_pointer read_list( struct stack_frame *frame,
initial ); initial );
/* skip whitespace */ /* skip whitespace */
for (c = url_fgetwc( input ); for ( c = url_fgetwc( input );
iswblank( c ) || iswcntrl( c ); iswblank( c ) || iswcntrl( c ); c = url_fgetwc( input ) );
c = url_fgetwc( input ));
if ( c == L'.') { if ( c == L'.' ) {
/* might be a dotted pair; indeed, if we rule out numbers with /* might be a dotted pair; indeed, if we rule out numbers with
* initial periods, it must be a dotted pair. \todo Ought to check, * initial periods, it must be a dotted pair. \todo Ought to check,
* howerver, that there's only one form after the period. */ * howerver, that there's only one form after the period. */
@ -309,12 +310,10 @@ struct cons_pointer read_list( struct stack_frame *frame,
make_cons( car, make_cons( car,
c_car( read_list( frame, c_car( read_list( frame,
frame_pointer, frame_pointer,
input, input, url_fgetwc( input ) ) ) );
url_fgetwc( input ) ) ) );
} else { } else {
result = result =
make_cons( car, make_cons( car, read_list( frame, frame_pointer, input, c ) );
read_list( frame, frame_pointer, input, c ) );
} }
} else { } else {
debug_print( L"End of list detected\n", DEBUG_IO ); debug_print( L"End of list detected\n", DEBUG_IO );
@ -325,9 +324,10 @@ struct cons_pointer read_list( struct stack_frame *frame,
struct cons_pointer read_map( struct stack_frame *frame, struct cons_pointer read_map( struct stack_frame *frame,
struct cons_pointer frame_pointer, struct cons_pointer frame_pointer,
URL_FILE *input, wint_t initial ) { URL_FILE * input, wint_t initial ) {
// set write ACL to true whilst creating to prevent GC churn // set write ACL to true whilst creating to prevent GC churn
struct cons_pointer result = make_hashmap( DFLT_HASHMAP_BUCKETS, NIL, TRUE ); struct cons_pointer result =
make_hashmap( DFLT_HASHMAP_BUCKETS, NIL, TRUE );
wint_t c = initial; wint_t c = initial;
while ( c != L'}' ) { while ( c != L'}' ) {
@ -336,16 +336,15 @@ struct cons_pointer read_map( struct stack_frame *frame,
/* skip whitespace */ /* skip whitespace */
for ( c = url_fgetwc( input ); iswblank( c ) || iswcntrl( c ); for ( c = url_fgetwc( input ); iswblank( c ) || iswcntrl( c );
c = url_fgetwc( input ) ) c = url_fgetwc( input ) );
;
struct cons_pointer value = struct cons_pointer value =
read_continuation( frame, frame_pointer, input, c ); read_continuation( frame, frame_pointer, input, c );
/* skip commaa and whitespace at this point. */ /* skip commaa and whitespace at this point. */
for ( c = url_fgetwc( input ); c == L',' || iswblank( c ) || iswcntrl( c ); for ( c = url_fgetwc( input );
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 );
} }

View file

@ -179,7 +179,7 @@ void free_cell( struct cons_pointer pointer ) {
dec_ref( cell->payload.string.cdr ); dec_ref( cell->payload.string.cdr );
break; break;
case VECTORPOINTTV: case VECTORPOINTTV:
free_vso( pointer); free_vso( pointer );
break; break;
} }

View file

@ -102,15 +102,17 @@ struct cons_pointer c_type( struct cons_pointer pointer ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
struct cons_space_object cell = pointer2cell( pointer ); struct cons_space_object cell = pointer2cell( pointer );
if ( strncmp( (char *)&cell.tag.bytes, VECTORPOINTTAG, TAGLENGTH ) == 0 ) { if ( strncmp( ( char * ) &cell.tag.bytes, VECTORPOINTTAG, TAGLENGTH ) ==
0 ) {
struct vector_space_object *vec = pointer_to_vso( pointer ); struct vector_space_object *vec = pointer_to_vso( pointer );
for ( int i = TAGLENGTH - 1; i >= 0; i-- ) { for ( int i = TAGLENGTH - 1; i >= 0; i-- ) {
result = make_string( (wchar_t)vec->header.tag.bytes[i], result ); result =
make_string( ( wchar_t ) vec->header.tag.bytes[i], result );
} }
} else { } else {
for ( int i = TAGLENGTH - 1; i >= 0; i-- ) { for ( int i = TAGLENGTH - 1; i >= 0; i-- ) {
result = make_string( (wchar_t)cell.tag.bytes[i], result ); result = make_string( ( wchar_t ) cell.tag.bytes[i], result );
} }
} }
@ -159,11 +161,11 @@ struct cons_pointer c_cdr( struct cons_pointer arg ) {
/** /**
* Implementation of `length` in C. If arg is not a cons, does not error but returns 0. * 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; int result = 0;
for (struct cons_pointer c = arg; !nilp(c); c = c_cdr(c)) { for ( struct cons_pointer c = arg; !nilp( c ); c = c_cdr( c ) ) {
result ++; result++;
} }
return result; return result;
@ -276,25 +278,19 @@ struct cons_pointer make_nlambda( struct cons_pointer args,
* *
* returns 0 for things which are not string like. * returns 0 for things which are not string like.
*/ */
uint32_t calculate_hash(wint_t c, struct cons_pointer ptr) uint32_t calculate_hash( wint_t c, struct cons_pointer ptr ) {
{ struct cons_space_object *cell = &pointer2cell( ptr );
struct cons_space_object *cell = &pointer2cell(ptr);
uint32_t result = 0; uint32_t result = 0;
switch (cell->tag.value) switch ( cell->tag.value ) {
{
case KEYTV: case KEYTV:
case STRINGTV: case STRINGTV:
case SYMBOLTV: case SYMBOLTV:
if (nilp(cell->payload.string.cdr)) if ( nilp( cell->payload.string.cdr ) ) {
{ result = ( uint32_t ) c;
result = (uint32_t)c; } else {
} result = ( ( uint32_t ) c *
else cell->payload.string.hash ) & 0xffffffff;
{
result = ((uint32_t)c *
cell->payload.string.hash) &
0xffffffff;
} }
break; break;
} }
@ -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 = tail */
cell->payload.string.cdr.offset = tail.offset; cell->payload.string.cdr.offset = tail.offset;
cell->payload.string.hash = calculate_hash(c, tail); cell->payload.string.hash = calculate_hash( c, tail );
} else { } else {
// \todo should throw an exception! // \todo should throw an exception!
debug_printf( DEBUG_ALLOC, debug_printf( DEBUG_ALLOC,
@ -430,10 +426,10 @@ struct cons_pointer make_write_stream( URL_FILE * output,
struct cons_pointer c_string_to_lisp_keyword( wchar_t *symbol ) { struct cons_pointer c_string_to_lisp_keyword( wchar_t *symbol ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
for ( int i = wcslen( symbol ) -1; i >= 0; i-- ) { for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) {
wchar_t c = towlower(symbol[i]); wchar_t c = towlower( symbol[i] );
if (iswalnum(c) || c == L'-') { if ( iswalnum( c ) || c == L'-' ) {
result = make_keyword( c, result ); result = make_keyword( c, result );
} }
} }
@ -448,7 +444,7 @@ struct cons_pointer c_string_to_lisp_string( wchar_t *string ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
for ( int i = wcslen( string ) - 1; i >= 0; i-- ) { for ( int i = wcslen( string ) - 1; i >= 0; i-- ) {
if (iswprint(string[i]) && string[i] != '"') { if ( iswprint( string[i] ) && string[i] != '"' ) {
result = make_string( string[i], result ); result = make_string( string[i], result );
} }
} }

View file

@ -685,7 +685,7 @@ struct cons_pointer c_car( struct cons_pointer arg );
struct cons_pointer c_cdr( 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 make_cons( struct cons_pointer car,
struct cons_pointer cdr ); struct cons_pointer cdr );

View file

@ -46,8 +46,7 @@ void dump_string_cell( URL_FILE * output, wchar_t *prefix,
cell.payload.string.character, cell.payload.string.character,
cell.payload.string.hash, cell.payload.string.hash,
cell.payload.string.cdr.page, cell.payload.string.cdr.page,
cell.payload.string.cdr.offset, cell.payload.string.cdr.offset, cell.count );
cell.count );
url_fwprintf( output, L"\t\t value: " ); url_fwprintf( output, L"\t\t value: " );
print( output, pointer ); print( output, pointer );
url_fwprintf( output, L"\n" ); url_fwprintf( output, L"\n" );
@ -57,7 +56,7 @@ void dump_string_cell( URL_FILE * output, wchar_t *prefix,
/** /**
* dump the object at this cons_pointer to this output stream. * dump the object at this cons_pointer to this output stream.
*/ */
void dump_object( URL_FILE *output, struct cons_pointer pointer ) { void dump_object( URL_FILE * output, struct cons_pointer pointer ) {
struct cons_space_object cell = pointer2cell( pointer ); struct cons_space_object cell = pointer2cell( pointer );
url_fwprintf( output, L"\t%4.4s (%d) at page %d, offset %d count %u\n", 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.tag.bytes, cell.tag.value, pointer.page, pointer.offset,
@ -68,9 +67,10 @@ void dump_object( URL_FILE *output, struct cons_pointer pointer ) {
url_fwprintf( output, url_fwprintf( output,
L"\t\tCons cell: car at page %d offset %d, cdr at page %d " L"\t\tCons cell: car at page %d offset %d, cdr at page %d "
L"offset %d, count %u :", L"offset %d, count %u :",
cell.payload.cons.car.page, cell.payload.cons.car.offset, cell.payload.cons.car.page,
cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset, cell.payload.cons.car.offset,
cell.count ); cell.payload.cons.cdr.page,
cell.payload.cons.cdr.offset, cell.count );
print( output, pointer ); print( output, pointer );
url_fputws( L"\n", output ); url_fputws( L"\n", output );
break; break;
@ -79,8 +79,10 @@ void dump_object( URL_FILE *output, struct cons_pointer pointer ) {
dump_stack_trace( output, pointer ); dump_stack_trace( output, pointer );
break; break;
case FREETV: case FREETV:
url_fwprintf( output, L"\t\tFree cell: next at page %d offset %d\n", url_fwprintf( output,
cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset ); L"\t\tFree cell: next at page %d offset %d\n",
cell.payload.cons.cdr.page,
cell.payload.cons.cdr.offset );
break; break;
case INTEGERTV: case INTEGERTV:
url_fwprintf( output, L"\t\tInteger cell: value %ld, count %u\n", url_fwprintf( output, L"\t\tInteger cell: value %ld, count %u\n",
@ -110,11 +112,12 @@ void dump_object( URL_FILE *output, struct cons_pointer pointer ) {
url_fputws( L"\n", output ); url_fputws( L"\n", output );
break; break;
case RATIOTV: case RATIOTV:
url_fwprintf( url_fwprintf( output,
output, L"\t\tRational cell: value %ld/%ld, count %u\n", L"\t\tRational cell: value %ld/%ld, count %u\n",
pointer2cell( cell.payload.ratio.dividend ).payload.integer.value, pointer2cell( cell.payload.ratio.dividend ).payload.
pointer2cell( cell.payload.ratio.divisor ).payload.integer.value, integer.value,
cell.count ); pointer2cell( cell.payload.ratio.divisor ).payload.
integer.value, cell.count );
break; break;
case READTV: case READTV:
url_fputws( L"\t\tInput stream; metadata: ", output ); url_fputws( L"\t\tInput stream; metadata: ", output );
@ -133,8 +136,9 @@ void dump_object( URL_FILE *output, struct cons_pointer pointer ) {
break; break;
case TRUETV: case TRUETV:
break; break;
case VECTORPOINTTV: { case VECTORPOINTTV:{
url_fwprintf( output, L"\t\tPointer to vector-space object at %p\n", url_fwprintf( output,
L"\t\tPointer to vector-space object at %p\n",
cell.payload.vectorp.address ); cell.payload.vectorp.address );
struct vector_space_object *vso = cell.payload.vectorp.address; struct vector_space_object *vso = cell.payload.vectorp.address;
url_fwprintf( output, url_fwprintf( output,
@ -151,7 +155,8 @@ void dump_object( URL_FILE *output, struct cons_pointer pointer ) {
dump_map( output, pointer ); dump_map( output, pointer );
break; break;
} }
} break; }
break;
case WRITETV: case WRITETV:
url_fputws( L"\t\tOutput stream; metadata: ", output ); url_fputws( L"\t\tOutput stream; metadata: ", output );
print( output, cell.payload.stream.meta ); print( output, cell.payload.stream.meta );

View file

@ -43,9 +43,8 @@ uint32_t sxhash( struct cons_pointer ptr ) {
* Get the hash value for the cell indicated by this `ptr`; currently only * Get the hash value for the cell indicated by this `ptr`; currently only
* implemented for string like things and integers. * implemented for string like things and integers.
*/ */
uint32_t get_hash(struct cons_pointer ptr) uint32_t get_hash( struct cons_pointer ptr ) {
{ struct cons_space_object *cell = &pointer2cell( ptr );
struct cons_space_object *cell = &pointer2cell(ptr);
uint32_t result = 0; uint32_t result = 0;
switch ( cell->tag.value ) { switch ( cell->tag.value ) {
@ -85,8 +84,8 @@ void free_hashmap( struct cons_pointer pointer ) {
for ( int i = 0; i < vso->payload.hashmap.n_buckets; i++ ) { for ( int i = 0; i < vso->payload.hashmap.n_buckets; i++ ) {
if ( !nilp( vso->payload.hashmap.buckets[i] ) ) { if ( !nilp( vso->payload.hashmap.buckets[i] ) ) {
debug_printf( DEBUG_ALLOC, debug_printf( DEBUG_ALLOC,
L"Decrementing bucket [%d] of hashmap at 0x%lx\n", i, L"Decrementing bucket [%d] of hashmap at 0x%lx\n",
cell->payload.vectorp.address ); i, cell->payload.vectorp.address );
dec_ref( vso->payload.hashmap.buckets[i] ); dec_ref( vso->payload.hashmap.buckets[i] );
} }
} }
@ -98,11 +97,10 @@ void free_hashmap( struct cons_pointer pointer ) {
/** /**
* A lisp function signature conforming wrapper around get_hash, q.v.. * A lisp function signature conforming wrapper around get_hash, q.v..
*/ */
struct cons_pointer lisp_get_hash(struct stack_frame *frame, struct cons_pointer lisp_get_hash( struct stack_frame *frame,
struct cons_pointer frame_pointer, struct cons_pointer frame_pointer,
struct cons_pointer env) struct cons_pointer env ) {
{ return make_integer( get_hash( frame->arg[0] ), NIL );
return make_integer(get_hash(frame->arg[0]), NIL);
} }
/** /**
@ -113,14 +111,15 @@ struct cons_pointer make_hashmap( uint32_t n_buckets,
struct cons_pointer hash_fn, struct cons_pointer hash_fn,
struct cons_pointer write_acl ) { struct cons_pointer write_acl ) {
struct cons_pointer result = struct cons_pointer result =
make_vso( HASHTV, ( sizeof( struct cons_pointer ) * ( n_buckets + 1 ) ) + make_vso( HASHTV,
( sizeof( struct cons_pointer ) * ( n_buckets + 1 ) ) +
( sizeof( uint32_t ) * 2 ) ); ( sizeof( uint32_t ) * 2 ) );
struct hashmap_payload *payload = struct hashmap_payload *payload =
(struct hashmap_payload *)&pointer_to_vso( result )->payload; ( struct hashmap_payload * ) &pointer_to_vso( result )->payload;
payload->hash_fn = inc_ref(hash_fn); payload->hash_fn = inc_ref( hash_fn );
payload->write_acl = inc_ref(write_acl); payload->write_acl = inc_ref( write_acl );
payload->n_buckets = n_buckets; payload->n_buckets = n_buckets;
for ( int i = 0; i < n_buckets; i++ ) { for ( int i = 0; i < n_buckets; i++ ) {
@ -149,10 +148,10 @@ struct cons_pointer lisp_make_hashmap( struct stack_frame *frame,
if ( integerp( frame->arg[0] ) ) { if ( integerp( frame->arg[0] ) ) {
n = to_long_int( frame->arg[0] ) % UINT32_MAX; n = to_long_int( frame->arg[0] ) % UINT32_MAX;
} else if ( !nilp( frame->arg[0] ) ) { } else if ( !nilp( frame->arg[0] ) ) {
result = make_exception( result =
c_string_to_lisp_string( L"First arg to `hashmap`, if passed, must " make_exception( c_string_to_lisp_string
L"be an integer or `nil`.`" ), ( L"First arg to `hashmap`, if passed, must "
NIL ); L"be an integer or `nil`.`" ), NIL );
} }
} }
if ( frame->args > 1 ) { if ( frame->args > 1 ) {
@ -177,11 +176,13 @@ struct cons_pointer lisp_make_hashmap( struct stack_frame *frame,
uint32_t bucket_no = uint32_t bucket_no =
get_hash( key ) % get_hash( key ) %
( (struct hashmap_payload *)&( map->payload ) )->n_buckets; ( ( struct hashmap_payload * ) &( map->payload ) )->
n_buckets;
map->payload.hashmap.buckets[bucket_no] = map->payload.hashmap.buckets[bucket_no] =
inc_ref( make_cons( make_cons( key, val ), inc_ref( make_cons( make_cons( key, val ),
map->payload.hashmap.buckets[bucket_no] )); map->payload.hashmap.
buckets[bucket_no] ) );
} }
} }
} }
@ -205,7 +206,9 @@ struct cons_pointer clone_hashmap( struct cons_pointer ptr ) {
if ( from != NULL ) { if ( from != NULL ) {
struct hashmap_payload from_pl = from->payload.hashmap; struct hashmap_payload from_pl = from->payload.hashmap;
result = make_hashmap( from_pl.n_buckets, from_pl.hash_fn, from_pl.write_acl ); 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 vector_space_object *to = pointer_to_vso( result );
struct hashmap_payload to_pl = to->payload.hashmap; struct hashmap_payload to_pl = to->payload.hashmap;
@ -233,17 +236,15 @@ struct cons_pointer hashmap_put( struct cons_pointer mapp,
if ( hashmapp( mapp ) && !nilp( key ) ) { if ( hashmapp( mapp ) && !nilp( key ) ) {
struct vector_space_object *map = pointer_to_vso( mapp ); struct vector_space_object *map = pointer_to_vso( mapp );
if (nilp(authorised(mapp, map->payload.hashmap.write_acl))) { if ( nilp( authorised( mapp, map->payload.hashmap.write_acl ) ) ) {
mapp = clone_hashmap( mapp); mapp = clone_hashmap( mapp );
map = pointer_to_vso( mapp ); map = pointer_to_vso( mapp );
} }
uint32_t bucket_no = uint32_t bucket_no = get_hash( key ) % map->payload.hashmap.n_buckets;
get_hash( key ) %
map->payload.hashmap.n_buckets;
map->payload.hashmap.buckets[bucket_no] = map->payload.hashmap.buckets[bucket_no] =
inc_ref( make_cons( make_cons( key, val ), inc_ref( make_cons( make_cons( key, val ),
map->payload.hashmap.buckets[bucket_no] )); map->payload.hashmap.buckets[bucket_no] ) );
} }
return mapp; return mapp;
@ -276,7 +277,7 @@ struct cons_pointer lisp_hashmap_put( struct stack_frame *frame,
struct cons_pointer key = frame->arg[1]; struct cons_pointer key = frame->arg[1];
struct cons_pointer val = frame->arg[2]; struct cons_pointer val = frame->arg[2];
return hashmap_put(mapp, key, val); return hashmap_put( mapp, key, val );
} }
/** /**
@ -316,16 +317,15 @@ struct cons_pointer lisp_hashmap_put_all( struct stack_frame *frame,
/** /**
* return a flat list of all the keys in the hashmap indicated by `map`. * 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 hashmap_keys( struct cons_pointer mapp ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
if ( hashmapp( mapp ) && truep( authorised( mapp, NIL ) )) { if ( hashmapp( mapp ) && truep( authorised( mapp, NIL ) ) ) {
struct vector_space_object *map = pointer_to_vso( mapp ); struct vector_space_object *map = pointer_to_vso( mapp );
for (int i = 0; i < map->payload.hashmap.n_buckets; i++) { for ( int i = 0; i < map->payload.hashmap.n_buckets; i++ ) {
for (struct cons_pointer c = map->payload.hashmap.buckets[i]; for ( struct cons_pointer c = map->payload.hashmap.buckets[i];
!nilp(c); !nilp( c ); c = c_cdr( c ) ) {
c = c_cdr(c)) { result = make_cons( c_car( c_car( c ) ), result );
result = make_cons(c_car( c_car(c)), result);
} }
} }
@ -340,8 +340,9 @@ struct cons_pointer lisp_hashmap_keys( struct stack_frame *frame,
return hashmap_keys( frame->arg[0] ); return hashmap_keys( frame->arg[0] );
} }
void dump_map( URL_FILE *output, struct cons_pointer pointer ) { void dump_map( URL_FILE * output, struct cons_pointer pointer ) {
struct hashmap_payload *payload = &pointer_to_vso( pointer )->payload.hashmap; 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"Hashmap with %d buckets:\n", payload->n_buckets );
url_fwprintf( output, L"\tHash function: " ); url_fwprintf( output, L"\tHash function: " );
print( output, payload->hash_fn ); print( output, payload->hash_fn );

View file

@ -21,7 +21,7 @@ uint32_t get_hash( struct cons_pointer ptr );
void free_hashmap( 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 hashmap_get( struct cons_pointer mapp,
struct cons_pointer key ); struct cons_pointer key );

File diff suppressed because it is too large Load diff

View file

@ -11,9 +11,6 @@
#ifndef __lookup3_h #ifndef __lookup3_h
#define __lookup3_h #define __lookup3_h
uint32_t hashword( uint32_t hashword( const uint32_t * k, size_t length, uint32_t initval );
const uint32_t *k,
size_t length,
uint32_t initval);
#endif #endif

View file

@ -61,7 +61,7 @@
struct cons_pointer make_vso( uint32_t tag, uint64_t payload_size ); 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. * the header which forms the start of every vector space object.
@ -86,8 +86,7 @@ struct vector_space_header {
* i.e. either an assoc list or a further hashmap. * i.e. either an assoc list or a further hashmap.
*/ */
struct hashmap_payload { struct hashmap_payload {
struct cons_pointer struct cons_pointer hash_fn; /* function for hashing values in this hashmap, or `NIL` to use
hash_fn; /* function for hashing values in this hashmap, or `NIL` to use
the default hashing function */ the default hashing function */
struct cons_pointer write_acl; /* it seems to me that it is likely that the struct cons_pointer write_acl; /* it seems to me that it is likely that the
* principal difference between a hashmap and a * principal difference between a hashmap and a
@ -95,8 +94,7 @@ struct hashmap_payload {
* of `NIL`, meaning not writeable by anyone */ * of `NIL`, meaning not writeable by anyone */
uint32_t n_buckets; /* number of hash buckets */ uint32_t n_buckets; /* number of hash buckets */
uint32_t unused; /* for word alignment and possible later expansion */ uint32_t unused; /* for word alignment and possible later expansion */
struct cons_pointer struct cons_pointer buckets[]; /* actual hash buckets, which should be `NIL`
buckets[]; /* actual hash buckets, which should be `NIL`
* or assoc lists or (possibly) further hashmaps. */ * or assoc lists or (possibly) further hashmaps. */
}; };

View file

@ -20,9 +20,8 @@
* Shallow, and thus cheap, equality: true if these two objects are * Shallow, and thus cheap, equality: true if these two objects are
* the same object, else false. * the same object, else false.
*/ */
bool eq(struct cons_pointer a, struct cons_pointer b) bool eq( struct cons_pointer a, struct cons_pointer b ) {
{ return ( ( a.page == b.page ) && ( a.offset == b.offset ) );
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, * @return true if the objects at these two cons pointers have the same tag,
* else false. * else false.
*/ */
bool same_type(struct cons_pointer a, struct cons_pointer 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_a = &pointer2cell(a); struct cons_space_object *cell_b = &pointer2cell( b );
struct cons_space_object *cell_b = &pointer2cell(b);
return cell_a->tag.value == cell_b->tag.value; return cell_a->tag.value == cell_b->tag.value;
} }
@ -45,27 +43,23 @@ bool same_type(struct cons_pointer a, struct cons_pointer b)
* @param string the string to test * @param string the string to test
* @return true if it's the end of a string. * @return true if it's the end of a string.
*/ */
bool end_of_string(struct cons_pointer string) bool end_of_string( struct cons_pointer string ) {
{ return nilp( string ) ||
return nilp(string) || pointer2cell( string ).payload.string.character == '\0';
pointer2cell(string).payload.string.character == '\0';
} }
/** /**
* Deep, and thus expensive, equality: true if these two objects have * Deep, and thus expensive, equality: true if these two objects have
* identical structure, else false. * identical structure, else false.
*/ */
bool equal(struct cons_pointer a, struct cons_pointer b) bool equal( struct cons_pointer a, struct cons_pointer b ) {
{ bool result = eq( a, b );
bool result = eq(a, b);
if (!result && same_type(a, b)) if ( !result && same_type( a, b ) ) {
{ struct cons_space_object *cell_a = &pointer2cell( a );
struct cons_space_object *cell_a = &pointer2cell(a); struct cons_space_object *cell_b = &pointer2cell( b );
struct cons_space_object *cell_b = &pointer2cell(b);
switch (cell_a->tag.value) switch ( cell_a->tag.value ) {
{
case CONSTV: case CONSTV:
case LAMBDATV: case LAMBDATV:
case NLAMBDATV: case NLAMBDATV:
@ -73,8 +67,9 @@ bool equal(struct cons_pointer a, struct cons_pointer b)
* structures can be of indefinite extent. It *must* be done by * structures can be of indefinite extent. It *must* be done by
* iteration (and even that is problematic) */ * iteration (and even that is problematic) */
result = result =
equal(cell_a->payload.cons.car, cell_b->payload.cons.car) && equal(cell_a->payload.cons.cdr, equal( cell_a->payload.cons.car, cell_b->payload.cons.car )
cell_b->payload.cons.cdr); && equal( cell_a->payload.cons.cdr,
cell_b->payload.cons.cdr );
break; break;
case KEYTV: case KEYTV:
case STRINGTV: case STRINGTV:
@ -89,50 +84,44 @@ bool equal(struct cons_pointer a, struct cons_pointer b)
result = result =
cell_a->payload.string.character == cell_a->payload.string.character ==
cell_b->payload.string.character && cell_b->payload.string.character &&
(equal(cell_a->payload.string.cdr, ( equal( cell_a->payload.string.cdr,
cell_b->payload.string.cdr) || cell_b->payload.string.cdr ) ||
(end_of_string(cell_a->payload.string.cdr) && end_of_string(cell_b->payload.string.cdr))); ( end_of_string( cell_a->payload.string.cdr )
&& end_of_string( cell_b->payload.string.cdr ) ) );
break; break;
case INTEGERTV: case INTEGERTV:
result = result =
(cell_a->payload.integer.value == ( cell_a->payload.integer.value ==
cell_b->payload.integer.value) && cell_b->payload.integer.value ) &&
equal(cell_a->payload.integer.more, equal( cell_a->payload.integer.more,
cell_b->payload.integer.more); cell_b->payload.integer.more );
break; break;
case RATIOTV: case RATIOTV:
result = equal_ratio_ratio(a, b); result = equal_ratio_ratio( a, b );
break; break;
case REALTV: case REALTV:
{ {
double num_a = to_long_double(a); double num_a = to_long_double( a );
double num_b = to_long_double(b); double num_b = to_long_double( b );
double max = double max = fabs( num_a ) > fabs( num_b )
fabs(num_a) > ? fabs( num_a )
fabs(num_b) : fabs( num_b );
? fabs(num_a)
: fabs(num_b);
/* /*
* not more different than one part in a million - close enough * not more different than one part in a million - close enough
*/ */
result = fabs(num_a - num_b) < (max / 1000000.0); result = fabs( num_a - num_b ) < ( max / 1000000.0 );
} }
break; break;
default: default:
result = false; result = false;
break; break;
} }
} } else if ( numberp( a ) && numberp( b ) ) {
else if (numberp(a) && numberp(b)) if ( integerp( a ) ) {
{ result = equal_integer_real( a, b );
if (integerp(a)) } else if ( integerp( b ) ) {
{ result = equal_integer_real( b, a );
result = equal_integer_real(a, b);
}
else if (integerp(b))
{
result = equal_integer_real(b, a);
} }
} }

View file

@ -92,11 +92,11 @@ struct cons_pointer c_assoc( struct cons_pointer key,
struct cons_pointer store ) { struct cons_pointer store ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
debug_print( L"c_assoc; key is `", DEBUG_BIND); debug_print( L"c_assoc; key is `", DEBUG_BIND );
debug_print_object( key, DEBUG_BIND); debug_print_object( key, DEBUG_BIND );
debug_print( L"`\n", DEBUG_BIND); debug_print( L"`\n", DEBUG_BIND );
if (consp(store)) { if ( consp( store ) ) {
for ( struct cons_pointer next = 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 = struct cons_space_object entry =
@ -107,15 +107,17 @@ struct cons_pointer c_assoc( struct cons_pointer key,
break; break;
} }
} }
} else if (hashmapp( store)) { } else if ( hashmapp( store ) ) {
result = hashmap_get( store, key); result = hashmap_get( store, key );
} else { } 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( L"c_assoc returning ", DEBUG_BIND );
debug_print_object( result, DEBUG_BIND); debug_print_object( result, DEBUG_BIND );
debug_println( DEBUG_BIND); debug_println( DEBUG_BIND );
return result; return result;
} }
@ -125,7 +127,7 @@ struct cons_pointer c_assoc( struct cons_pointer key,
* with this key/value pair added to the front. * with this key/value pair added to the front.
*/ */
struct cons_pointer struct cons_pointer
set( struct cons_pointer key, struct cons_pointer value, set( struct cons_pointer key, struct cons_pointer value,
struct cons_pointer store ) { struct cons_pointer store ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
@ -134,18 +136,18 @@ struct cons_pointer
debug_print( L"` to `", DEBUG_BIND ); debug_print( L"` to `", DEBUG_BIND );
debug_print_object( value, DEBUG_BIND ); debug_print_object( value, DEBUG_BIND );
debug_print( L"` in store ", 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 ); debug_println( DEBUG_BIND );
if (nilp( store) || consp(store)) { if ( nilp( store ) || consp( store ) ) {
result = make_cons( make_cons( key, value ), store ); result = make_cons( make_cons( key, value ), store );
} else if (hashmapp( store)) { } else if ( hashmapp( store ) ) {
result = hashmap_put( store, key, value); result = hashmap_put( store, key, value );
} }
debug_print( L"set returning ", DEBUG_BIND); debug_print( L"set returning ", DEBUG_BIND );
debug_print_object( result, DEBUG_BIND); debug_print_object( result, DEBUG_BIND );
debug_println( DEBUG_BIND); debug_println( DEBUG_BIND );
return result; return result;
} }
@ -195,4 +197,3 @@ intern( struct cons_pointer key, struct cons_pointer environment ) {
return result; return result;
} }

View file

@ -106,7 +106,7 @@ struct cons_pointer eval_forms( struct stack_frame *frame,
list = c_cdr( list ); 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. * This is experimental. It almost certainly WILL change.
*/ */
struct cons_pointer lisp_try(struct stack_frame *frame, struct cons_pointer lisp_try( struct stack_frame *frame,
struct cons_pointer frame_pointer, struct cons_pointer frame_pointer,
struct cons_pointer env) { struct cons_pointer env ) {
struct cons_pointer result = c_progn(frame, frame_pointer, frame->arg[0], 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! // TODO: need to put the exception into the environment!
result = c_progn(frame, frame_pointer, frame->arg[1], result = c_progn( frame, frame_pointer, frame->arg[1],
make_cons( make_cons( make_cons
make_cons(c_string_to_lisp_keyword(L"*exception*"), ( c_string_to_lisp_keyword
result), ( L"*exception*" ), result ), env ) );
env));
} }
return result; 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 ); result = eval_form( frame, frame_pointer, sexpr, new_env );
if (exceptionp(result)) if ( exceptionp( result ) ) {
{
break; break;
} }
} }
@ -306,7 +304,7 @@ eval_lambda( struct cons_space_object cell, struct stack_frame *frame,
* @return the result of evaluating the function with its arguments. * @return the result of evaluating the function with its arguments.
*/ */
struct cons_pointer struct cons_pointer
c_apply( struct stack_frame *frame, struct cons_pointer frame_pointer, c_apply( struct stack_frame *frame, struct cons_pointer frame_pointer,
struct cons_pointer env ) { struct cons_pointer env ) {
debug_print( L"Entering c_apply\n", DEBUG_EVAL ); debug_print( L"Entering c_apply\n", DEBUG_EVAL );
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
@ -349,10 +347,10 @@ struct cons_pointer
case KEYTV: case KEYTV:
result = c_assoc( fn_pointer, result = c_assoc( fn_pointer,
eval_form(frame, eval_form( frame,
frame_pointer, frame_pointer,
c_car( c_cdr( frame->arg[0])), c_car( c_cdr( frame->arg[0] ) ),
env)); env ) );
break; break;
case LAMBDATV: case LAMBDATV:
@ -376,14 +374,15 @@ struct cons_pointer
break; break;
case VECTORPOINTTV: case VECTORPOINTTV:
switch ( pointer_to_vso(fn_pointer)->header.tag.value) { switch ( pointer_to_vso( fn_pointer )->header.tag.value ) {
case HASHTV: case HASHTV:
/* \todo: if arg[0] is a CONS, treat it as a path */ /* \todo: if arg[0] is a CONS, treat it as a path */
result = c_assoc( eval_form(frame, result = c_assoc( eval_form( frame,
frame_pointer, frame_pointer,
c_car( c_cdr( frame->arg[0])), c_car( c_cdr
env), ( frame->
fn_pointer); arg[0] ) ),
env ), fn_pointer );
break; break;
} }
break; break;
@ -414,8 +413,9 @@ struct cons_pointer
result = next_pointer; result = next_pointer;
} else { } else {
result = result =
( *fn_cell.payload.special. ( *fn_cell.payload.
executable ) ( get_stack_frame( next_pointer ), special.executable ) ( get_stack_frame
( next_pointer ),
next_pointer, env ); next_pointer, env );
debug_print( L"Special form returning: ", DEBUG_EVAL ); debug_print( L"Special form returning: ", DEBUG_EVAL );
debug_print_object( result, DEBUG_EVAL ); debug_print_object( result, DEBUG_EVAL );
@ -781,9 +781,10 @@ lisp_cdr( struct stack_frame *frame, struct cons_pointer frame_pointer,
* @param env my environment (ignored). * @param env my environment (ignored).
* @return the length of `any`, if it is a sequence, or zero otherwise. * @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 lisp_length( struct stack_frame *frame,
struct cons_pointer frame_pointer,
struct cons_pointer env ) { struct cons_pointer env ) {
return make_integer( c_length( frame->arg[0]), NIL); return make_integer( c_length( frame->arg[0] ), NIL );
} }
/** /**
@ -802,7 +803,7 @@ lisp_assoc( struct stack_frame *frame, struct cons_pointer frame_pointer,
return c_assoc( frame->arg[0], frame->arg[1] ); return c_assoc( frame->arg[0], frame->arg[1] );
} }
struct cons_pointer c_keys(struct cons_pointer store) { struct cons_pointer c_keys( struct cons_pointer store ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
if ( hashmapp( store ) ) { if ( hashmapp( store ) ) {
@ -819,7 +820,7 @@ struct cons_pointer c_keys(struct cons_pointer store) {
struct cons_pointer lisp_keys( struct stack_frame *frame, struct cons_pointer lisp_keys( struct stack_frame *frame,
struct cons_pointer frame_pointer, struct cons_pointer frame_pointer,
struct cons_pointer env ) { struct cons_pointer env ) {
return c_keys( frame->arg[0]); return c_keys( frame->arg[0] );
} }
/** /**
@ -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 ); result = eval_form( frame, frame_pointer, c_car( expressions ), env );
dec_ref( r ); dec_ref( r );
expressions = exceptionp(result) ? NIL : c_cdr( expressions ); expressions = exceptionp( result ) ? NIL : c_cdr( expressions );
} }
return result; return result;

View file

@ -28,42 +28,44 @@
* PSSE Lisp epoch is 14 Bn years, or 441,806,400,000,000,000 seconds, before * 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. * the UNIX epoch; the value in microseconds will break the C reader.
*/ */
unsigned __int128 epoch_offset = ((__int128)(seconds_per_year * 1000000000L) * unsigned __int128 epoch_offset =
(__int128)(14L * 1000000000L)); ( ( __int128 ) ( seconds_per_year * 1000000000L ) *
( __int128 ) ( 14L * 1000000000L ) );
/** /**
* Return the UNIX time value which represents this time, if it falls within * Return the UNIX time value which represents this time, if it falls within
* the period representable in UNIX time, or zero otherwise. * 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; long int result = 0;
if (timep( t)) { if ( timep( t ) ) {
unsigned __int128 value = pointer2cell(t).payload.time.value; unsigned __int128 value = pointer2cell( t ).payload.time.value;
if (value > epoch_offset) { // \todo && value < UNIX time rollover if ( value > epoch_offset ) { // \todo && value < UNIX time rollover
result = ((value - epoch_offset) / 1000000000); result = ( ( value - epoch_offset ) / 1000000000 );
} }
} }
return result; return result;
} }
unsigned __int128 unix_time_to_lisp_time( time_t t) { unsigned __int128 unix_time_to_lisp_time( time_t t ) {
unsigned __int128 result = epoch_offset + (t * 1000000000); unsigned __int128 result = epoch_offset + ( t * 1000000000 );
return result; 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_pointer pointer = allocate_cell( TIMETV );
struct cons_space_object *cell = &pointer2cell( pointer ); struct cons_space_object *cell = &pointer2cell( pointer );
if (integerp(integer_or_nil)) { if ( integerp( integer_or_nil ) ) {
cell->payload.time.value = pointer2cell(integer_or_nil).payload.integer.value; cell->payload.time.value =
pointer2cell( integer_or_nil ).payload.integer.value;
// \todo: if integer is a bignum, deal with it. // \todo: if integer is a bignum, deal with it.
} else { } 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; 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 * is that number of microseconds after the notional big bang; else the current
* time. * time.
*/ */
struct cons_pointer lisp_time( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer lisp_time( struct stack_frame *frame,
struct cons_pointer frame_pointer,
struct cons_pointer env ) { struct cons_pointer env ) {
return make_time( frame->arg[0]); return make_time( frame->arg[0] );
} }
/** /**
* This is temporary, for bootstrapping. * 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; 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) { if ( t != 0 ) {
char * bytes = ctime(&t); char *bytes = ctime( &t );
int l = strlen(bytes) + 1; int l = strlen( bytes ) + 1;
wchar_t buffer[ l]; wchar_t buffer[l];
mbstowcs( buffer, bytes, l); mbstowcs( buffer, bytes, l );
result = c_string_to_lisp_string( buffer); result = c_string_to_lisp_string( buffer );
} }
return result; return result;

View file

@ -13,8 +13,9 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include "consspaceobject.h" #include "consspaceobject.h"
struct cons_pointer lisp_time( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer lisp_time( struct stack_frame *frame,
struct cons_pointer frame_pointer,
struct cons_pointer env ); struct cons_pointer env );
struct cons_pointer time_to_string( struct cons_pointer pointer); struct cons_pointer time_to_string( struct cons_pointer pointer );
#endif #endif