This isn't working, but I think it's progress.
This commit is contained in:
parent
5dee093e65
commit
9661ad339a
2
include/licence-header.txt
Normal file
2
include/licence-header.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
(c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||||
|
Licensed under GPL version 2.0, or, at your option, any later version.
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "conspage.h"
|
#include "conspage.h"
|
||||||
#include "consspaceobject.h"
|
#include "consspaceobject.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that the tag on the cell at this pointer is this tag
|
* Check that the tag on the cell at this pointer is this tag
|
||||||
|
@ -73,28 +74,47 @@ void dump_object( FILE * output, struct cons_pointer pointer ) {
|
||||||
cell.tag.bytes[3],
|
cell.tag.bytes[3],
|
||||||
cell.tag.value, pointer.page, pointer.offset, cell.count );
|
cell.tag.value, pointer.page, pointer.offset, cell.count );
|
||||||
|
|
||||||
if ( check_tag( pointer, CONSTAG ) ) {
|
switch ( cell.tag.value) {
|
||||||
|
case CONSTV:
|
||||||
fwprintf( output,
|
fwprintf( output,
|
||||||
L"\t\tCons cell: car at page %d offset %d, cdr at page %d offset %d\n",
|
L"\t\tCons cell: car at page %d offset %d, cdr at page %d offset %d\n",
|
||||||
cell.payload.cons.car.page,
|
cell.payload.cons.car.page,
|
||||||
cell.payload.cons.car.offset,
|
cell.payload.cons.car.offset,
|
||||||
cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset );
|
cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset );
|
||||||
} else if ( check_tag( pointer, INTEGERTAG ) ) {
|
break;
|
||||||
|
case INTEGERTV:
|
||||||
fwprintf( output,
|
fwprintf( output,
|
||||||
L"\t\tInteger cell: value %ld\n",
|
L"\t\tInteger cell: value %ld\n",
|
||||||
cell.payload.integer.value );
|
cell.payload.integer.value );
|
||||||
} else if ( check_tag( pointer, FREETAG ) ) {
|
break;
|
||||||
|
case FREETV:
|
||||||
fwprintf( output, L"\t\tFree cell: next at page %d offset %d\n",
|
fwprintf( output, L"\t\tFree cell: next at page %d offset %d\n",
|
||||||
cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset );
|
cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset );
|
||||||
} else if ( check_tag( pointer, REALTAG ) ) {
|
break;
|
||||||
|
case REALTV:
|
||||||
fwprintf( output, L"\t\tReal cell: value %Lf\n",
|
fwprintf( output, L"\t\tReal cell: value %Lf\n",
|
||||||
cell.payload.real.value );
|
cell.payload.real.value );
|
||||||
} else if ( check_tag( pointer, STRINGTAG ) ) {
|
break;
|
||||||
|
case STRINGTV:
|
||||||
fwprintf( output,
|
fwprintf( output,
|
||||||
L"\t\tString cell: character '%1c' (%1d) next at page %2d offset %3d\n",
|
L"\t\tString cell: character '%1c' (%1d) next at page %2d offset %3d\n",
|
||||||
cell.payload.string.character,
|
cell.payload.string.character,
|
||||||
cell.payload.string.cdr.page,
|
cell.payload.string.cdr.page,
|
||||||
cell.payload.string.cdr.offset );
|
cell.payload.string.cdr.offset );
|
||||||
|
fwprintf( output, L"\t\t value:");
|
||||||
|
print(output, pointer);
|
||||||
|
fwprintf( output, L"\n");
|
||||||
|
break;
|
||||||
|
case SYMBOLTV:
|
||||||
|
fwprintf( output,
|
||||||
|
L"\t\tSymbol cell: character '%1c' (%1d) next at page %2d offset %3d\n",
|
||||||
|
cell.payload.string.character,
|
||||||
|
cell.payload.string.cdr.page,
|
||||||
|
cell.payload.string.cdr.offset );
|
||||||
|
fwprintf( output, L"\t\t value:");
|
||||||
|
print(output, pointer);
|
||||||
|
fwprintf( output, L"\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@
|
||||||
#define stringp(conspoint) (check_tag(conspoint,STRINGTAG))
|
#define stringp(conspoint) (check_tag(conspoint,STRINGTAG))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* true if conspointer points to a string cell, else false
|
* true if conspointer points to a symbol cell, else false
|
||||||
*/
|
*/
|
||||||
#define symbolp(conspoint) (check_tag(conspoint,SYMBOLTAG))
|
#define symbolp(conspoint) (check_tag(conspoint,SYMBOLTAG))
|
||||||
|
|
||||||
|
|
38
src/equal.c
38
src/equal.c
|
@ -22,6 +22,21 @@ 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 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the objects at these two cons pointers have the same tag, else false.
|
||||||
|
* @param a a pointer to a cons-space object;
|
||||||
|
* @param b another pointer to a cons-space object.
|
||||||
|
* @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 );
|
||||||
|
|
||||||
|
return cell_a->tag.value == cell_b->tag.value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
@ -29,15 +44,18 @@ bool eq( struct cons_pointer a, struct cons_pointer b ) {
|
||||||
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 ) {
|
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 );
|
||||||
|
|
||||||
if ( consp( a ) && consp( b ) ) {
|
switch ( cell_a->tag.value ) {
|
||||||
|
case CONSTV:
|
||||||
result =
|
result =
|
||||||
equal( cell_a->payload.cons.car, cell_b->payload.cons.car )
|
equal( cell_a->payload.cons.car, cell_b->payload.cons.car )
|
||||||
&& equal( cell_a->payload.cons.cdr, cell_b->payload.cons.cdr );
|
&& equal( cell_a->payload.cons.cdr, cell_b->payload.cons.cdr );
|
||||||
} else if ( stringp( a ) && stringp( b ) ) {
|
break;
|
||||||
|
case STRINGTV:
|
||||||
|
case SYMBOLTV:
|
||||||
/*
|
/*
|
||||||
* slightly complex because a string may or may not have a '\0'
|
* 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
|
* cell at the end, but I'll ignore that for now. I think in
|
||||||
|
@ -48,17 +66,27 @@ bool equal( struct cons_pointer a, struct cons_pointer b ) {
|
||||||
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 );
|
||||||
} else if ( numberp( a ) && numberp( b ) ) {
|
break;
|
||||||
|
case INTEGERTV:
|
||||||
|
case REALTV:
|
||||||
|
{
|
||||||
double num_a = numeric_value( a );
|
double num_a = numeric_value( a );
|
||||||
double num_b = numeric_value( b );
|
double num_b = numeric_value( b );
|
||||||
double max =
|
double max =
|
||||||
fabs( num_a ) > fabs( num_b ) ? fabs( num_a ) : fabs( num_b );
|
fabs( num_a ) >
|
||||||
|
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;
|
||||||
|
default:
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* there's only supposed ever to be one T and one NIL cell, so each
|
* 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
|
* should be caught by eq; equality of vector-space objects is a whole
|
||||||
|
|
19
src/init.c
19
src/init.c
|
@ -54,14 +54,14 @@ int main( int argc, char *argv[] ) {
|
||||||
show_prompt = true;
|
show_prompt = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf( stderr, "Unexpected option %c\n", option );
|
fwprintf( stderr, L"Unexpected option %c\n", option );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( show_prompt ) {
|
if ( show_prompt ) {
|
||||||
fprintf( stdout,
|
fwprintf( stdout,
|
||||||
"Post scarcity software environment version %s\n\n",
|
L"Post scarcity software environment version %s\n\n",
|
||||||
VERSION );
|
VERSION );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,12 +70,17 @@ int main( int argc, char *argv[] ) {
|
||||||
/*
|
/*
|
||||||
* privileged variables (keywords)
|
* privileged variables (keywords)
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
deep_bind( intern( c_string_to_lisp_string( "nil" ), oblist ), NIL );
|
deep_bind( intern( c_string_to_lisp_string( "nil" ), oblist ), NIL );
|
||||||
deep_bind( intern( c_string_to_lisp_string( "t" ), oblist ), TRUE );
|
deep_bind( intern( c_string_to_lisp_string( "t" ), oblist ), TRUE );
|
||||||
|
*/
|
||||||
|
struct cons_pointer lisp_symbol = c_string_to_lisp_symbol( "oblist");
|
||||||
|
deep_bind( lisp_symbol, &oblist);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* primitive function operations
|
* primitive function operations
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
bind_function( "assoc", &lisp_assoc );
|
bind_function( "assoc", &lisp_assoc );
|
||||||
bind_function( "car", &lisp_car );
|
bind_function( "car", &lisp_car );
|
||||||
bind_function( "cdr", &lisp_cdr );
|
bind_function( "cdr", &lisp_cdr );
|
||||||
|
@ -84,13 +89,19 @@ int main( int argc, char *argv[] ) {
|
||||||
bind_function( "equal", &lisp_equal );
|
bind_function( "equal", &lisp_equal );
|
||||||
bind_function( "read", &lisp_read );
|
bind_function( "read", &lisp_read );
|
||||||
bind_function( "print", &lisp_print );
|
bind_function( "print", &lisp_print );
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
* primitive special forms
|
* primitive special forms
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
bind_special( "apply", &lisp_apply );
|
bind_special( "apply", &lisp_apply );
|
||||||
bind_special( "eval", &lisp_eval );
|
bind_special( "eval", &lisp_eval );
|
||||||
bind_special( "quote", &lisp_quote );
|
bind_special( "quote", &lisp_quote );
|
||||||
|
*/
|
||||||
|
if ( show_prompt) {
|
||||||
|
fwprintf( stderr, L"Oblist: ");
|
||||||
|
print(stderr, *oblist);
|
||||||
|
}
|
||||||
|
|
||||||
repl( stdin, stdout, stderr, show_prompt );
|
repl( stdin, stdout, stderr, show_prompt );
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct cons_pointer make_integer( long int value ) {
|
||||||
struct cons_space_object *cell = &pointer2cell( result );
|
struct cons_space_object *cell = &pointer2cell( result );
|
||||||
cell->payload.integer.value = value;
|
cell->payload.integer.value = value;
|
||||||
|
|
||||||
dump_object( stderr, result);
|
dump_object( stderr, result );
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
* they're visible to all users/threads, but again I don't yet have any idea how
|
* they're visible to all users/threads, but again I don't yet have any idea how
|
||||||
* that will work.
|
* that will work.
|
||||||
*/
|
*/
|
||||||
struct cons_pointer oblist = NIL;
|
struct cons_pointer oblist = & NIL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of interned? in C. The final implementation if interned? will
|
* Implementation of interned? in C. The final implementation if interned? will
|
||||||
|
@ -104,7 +104,7 @@ bind( struct cons_pointer key, struct cons_pointer value,
|
||||||
*/
|
*/
|
||||||
struct cons_pointer
|
struct cons_pointer
|
||||||
deep_bind( struct cons_pointer key, struct cons_pointer value ) {
|
deep_bind( struct cons_pointer key, struct cons_pointer value ) {
|
||||||
oblist = bind( key, value, oblist );
|
oblist = &bind( key, value, *oblist );
|
||||||
return oblist;
|
return oblist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef __intern_h
|
#ifndef __intern_h
|
||||||
#define __intern_h
|
#define __intern_h
|
||||||
|
|
||||||
extern struct cons_pointer oblist;
|
extern struct cons_pointer * oblist;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return the value associated with this key in this store. In the current
|
* return the value associated with this key in this store. In the current
|
||||||
|
|
|
@ -104,8 +104,7 @@ eval_cons( struct cons_pointer s_expr, struct cons_pointer env,
|
||||||
{
|
{
|
||||||
struct cons_space_object special = pointer2cell( fn_pointer );
|
struct cons_space_object special = pointer2cell( fn_pointer );
|
||||||
result =
|
result =
|
||||||
( *special.payload.special.executable ) ( args, env,
|
( *special.payload.special.executable ) ( args, env, my_frame );
|
||||||
my_frame );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -164,15 +163,15 @@ lisp_eval( struct cons_pointer s_expr, struct cons_pointer env,
|
||||||
struct cons_pointer result = s_expr;
|
struct cons_pointer result = s_expr;
|
||||||
struct cons_space_object cell = pointer2cell( s_expr );
|
struct cons_space_object cell = pointer2cell( s_expr );
|
||||||
|
|
||||||
fprintf( stderr, "In eval; about to make stack frame" );
|
|
||||||
|
|
||||||
struct stack_frame *frame = make_stack_frame( previous, s_expr, env );
|
|
||||||
|
|
||||||
fprintf( stderr, "In eval; stack frame made" );
|
|
||||||
|
|
||||||
switch ( cell.tag.value ) {
|
switch ( cell.tag.value ) {
|
||||||
case CONSTV:
|
case CONSTV:
|
||||||
|
fwprintf( stderr, L"In eval; about to make stack frame" );
|
||||||
|
struct stack_frame *frame = make_stack_frame( previous, s_expr, env );
|
||||||
|
fwprintf( stderr, L"In eval; stack frame made" );
|
||||||
|
|
||||||
result = eval_cons( s_expr, env, frame );
|
result = eval_cons( s_expr, env, frame );
|
||||||
|
|
||||||
|
free_stack_frame( frame );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYMBOLTV:
|
case SYMBOLTV:
|
||||||
|
@ -197,8 +196,6 @@ lisp_eval( struct cons_pointer s_expr, struct cons_pointer env,
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
free_stack_frame( frame );
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +209,7 @@ lisp_eval( struct cons_pointer s_expr, struct cons_pointer env,
|
||||||
struct cons_pointer
|
struct cons_pointer
|
||||||
lisp_quote( struct cons_pointer args, struct cons_pointer env,
|
lisp_quote( struct cons_pointer args, struct cons_pointer env,
|
||||||
struct stack_frame *frame ) {
|
struct stack_frame *frame ) {
|
||||||
return c_car( args );
|
return frame->arg[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -360,10 +357,10 @@ lisp_print( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
*/
|
*/
|
||||||
struct cons_pointer
|
struct cons_pointer
|
||||||
lisp_throw( struct cons_pointer message, struct stack_frame *frame ) {
|
lisp_throw( struct cons_pointer message, struct stack_frame *frame ) {
|
||||||
fprintf( stderr, "\nERROR: " );
|
fwprintf( stderr, L"\nERROR: " );
|
||||||
print( stderr, message );
|
print( stderr, message );
|
||||||
fprintf( stderr,
|
fwprintf( stderr,
|
||||||
"\n\nAn exception was thrown and I've no idea what to do now\n" );
|
L"\n\nAn exception was thrown and I've no idea what to do now\n" );
|
||||||
|
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
35
src/peano.c
Normal file
35
src/peano.c
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* peano.c
|
||||||
|
*
|
||||||
|
* Basic peano arithmetic
|
||||||
|
*
|
||||||
|
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||||
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "consspaceobject.h"
|
||||||
|
#include "conspage.h"
|
||||||
|
#include "equal.h"
|
||||||
|
#include "integer.h"
|
||||||
|
#include "intern.h"
|
||||||
|
#include "lispops.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "read.h"
|
||||||
|
#include "stack.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct cons_pointer
|
||||||
|
lisp_plus( struct cons_pointer s_expr, struct cons_pointer env,
|
||||||
|
struct stack_frame *frame ) {
|
||||||
|
struct cons_space_object cell = pointer2cell( s_expr );
|
||||||
|
struct cons_space_object result = NIL;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
|
@ -100,6 +100,12 @@ void print( FILE * output, struct cons_pointer pointer ) {
|
||||||
case TRUETV:
|
case TRUETV:
|
||||||
fwprintf( output, L"t" );
|
fwprintf( output, L"t" );
|
||||||
break;
|
break;
|
||||||
|
case FUNCTIONTV:
|
||||||
|
fwprintf( output, L"(Function)");
|
||||||
|
break;
|
||||||
|
case SPECIALTV:
|
||||||
|
fwprintf( output, L"(Special form)");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fwprintf( stderr,
|
fwprintf( stderr,
|
||||||
L"Error: Unrecognised tag value %d (%c%c%c%c)\n",
|
L"Error: Unrecognised tag value %d (%c%c%c%c)\n",
|
||||||
|
|
|
@ -96,7 +96,8 @@ struct cons_pointer read_number( FILE * input, wint_t initial ) {
|
||||||
} else {
|
} else {
|
||||||
accumulator = accumulator * 10 + ( ( int ) c - ( int ) '0' );
|
accumulator = accumulator * 10 + ( ( int ) c - ( int ) '0' );
|
||||||
|
|
||||||
fprintf( stderr, "Added character %c, accumulator now %ld\n", c, accumulator);
|
fprintf( stderr, "Added character %c, accumulator now %ld\n", c,
|
||||||
|
accumulator );
|
||||||
|
|
||||||
if ( seen_period ) {
|
if ( seen_period ) {
|
||||||
places_of_decimals++;
|
places_of_decimals++;
|
||||||
|
|
|
@ -40,8 +40,8 @@ repl( FILE * in_stream, FILE * out_stream, FILE * error_stream,
|
||||||
* I'm not certain about that, and as it will be a really
|
* I'm not certain about that, and as it will be a really
|
||||||
* major change I'm going to think some more before making
|
* major change I'm going to think some more before making
|
||||||
* in */
|
* in */
|
||||||
// print( out_stream, lisp_eval(input, oblist, NULL));
|
print( out_stream, lisp_eval( input, oblist, NULL ) );
|
||||||
print( out_stream, input );
|
// print( out_stream, input );
|
||||||
fwprintf( out_stream, L"\n" );
|
fwprintf( out_stream, L"\n" );
|
||||||
fwprintf( error_stream, L"\neval {%d,%d}=> ", input.page,
|
fwprintf( error_stream, L"\neval {%d,%d}=> ", input.page,
|
||||||
input.offset );
|
input.offset );
|
||||||
|
|
Loading…
Reference in a new issue