Investigating why symbols created by read are not equal to those created in C.
This commit is contained in:
parent
1cfd333e26
commit
cf655e8020
6 changed files with 67 additions and 123 deletions
|
|
@ -177,13 +177,13 @@ struct function_data function_initialisers[] = {
|
||||||
U"return that expression unevaluated.",
|
U"return that expression unevaluated.",
|
||||||
&read},
|
&read},
|
||||||
{U"read-character",
|
{U"read-character",
|
||||||
U"(read_character stream): read a single character from `stream` and "
|
U"(read-character stream): read a single character from `stream` and "
|
||||||
U"return it.",
|
U"return it.",
|
||||||
&read_character},
|
&read_character},
|
||||||
{U"read_number",
|
{U"read-number",
|
||||||
U"(read-number stream): read a number from `stream` and return it.",
|
U"(read-number stream): read a number from `stream` and return it.",
|
||||||
&read_number},
|
&read_number},
|
||||||
{U"read_symbol",
|
{U"read-symbol",
|
||||||
U"(read-symbol stream): read a symbol from `stream` and return it.",
|
U"(read-symbol stream): read a symbol from `stream` and return it.",
|
||||||
&read_symbol},
|
&read_symbol},
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -318,16 +318,18 @@ initialise_function_bindings(struct pso_pointer frame_pointer) {
|
||||||
struct pso_pointer result = fetch_env(frame_pointer);
|
struct pso_pointer result = fetch_env(frame_pointer);
|
||||||
|
|
||||||
for (int i = 0; function_initialisers[i].executable != NULL; i++) {
|
for (int i = 0; function_initialisers[i].executable != NULL; i++) {
|
||||||
result = bind_function(push_local(frame_pointer, make_frame_with_env(0, frame_pointer, result)),
|
struct pso_pointer b = c_car( bind_function( frame_pointer,
|
||||||
function_initialisers[i].name,
|
function_initialisers[i].name,
|
||||||
function_initialisers[i].documentation,
|
function_initialisers[i].documentation,
|
||||||
function_initialisers[i].executable);
|
function_initialisers[i].executable));
|
||||||
|
result = make_cons( frame_pointer, b, result);
|
||||||
}
|
}
|
||||||
for (int i = 0; special_initialisers[i].executable != NULL; i++) {
|
for (int i = 0; special_initialisers[i].executable != NULL; i++) {
|
||||||
result = bind_function(push_local( frame_pointer, make_frame_with_env(0, frame_pointer, result)),
|
struct pso_pointer b = c_car( bind_special( frame_pointer,
|
||||||
special_initialisers[i].name,
|
special_initialisers[i].name,
|
||||||
special_initialisers[i].documentation,
|
special_initialisers[i].documentation,
|
||||||
special_initialisers[i].executable);
|
special_initialisers[i].executable));
|
||||||
|
result = make_cons( frame_pointer, b, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,12 @@
|
||||||
#include "memory/tags.h"
|
#include "memory/tags.h"
|
||||||
|
|
||||||
#include "payloads/character.h"
|
#include "payloads/character.h"
|
||||||
|
#include "payloads/cons.h"
|
||||||
#include "payloads/exception.h"
|
#include "payloads/exception.h"
|
||||||
#include "payloads/function.h"
|
#include "payloads/function.h"
|
||||||
#include "payloads/integer.h"
|
#include "payloads/integer.h"
|
||||||
#include "payloads/read_stream.h"
|
#include "payloads/read_stream.h"
|
||||||
|
#include "payloads/symbol.h"
|
||||||
|
|
||||||
#include "ops/assoc.h"
|
#include "ops/assoc.h"
|
||||||
#include "ops/reverse.h"
|
#include "ops/reverse.h"
|
||||||
|
|
@ -150,6 +152,9 @@ struct pso_pointer read_number( struct pso_pointer frame_pointer ) {
|
||||||
url_ungetwc( c, input );
|
url_ungetwc( c, input );
|
||||||
result = make_integer( frame_pointer, value );
|
result = make_integer( frame_pointer, value );
|
||||||
} // else exception?
|
} // else exception?
|
||||||
|
#ifdef DEBUG
|
||||||
|
debug_printf( DEBUG_IO, 0, L"\nRead number %ld\n", value );
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -171,7 +176,7 @@ struct pso_pointer read_symbol( struct pso_pointer frame_pointer ) {
|
||||||
? 0 : pointer_to_object( character )->payload.character.character;
|
? 0 : pointer_to_object( character )->payload.character.character;
|
||||||
|
|
||||||
URL_FILE *input = pointer_to_object( stream )->payload.stream.stream;
|
URL_FILE *input = pointer_to_object( stream )->payload.stream.stream;
|
||||||
for ( ; iswalnum( c ); c = url_fgetwc( input ) ) {
|
for ( ; symbol_char_p( c ); c = url_fgetwc( input ) ) {
|
||||||
result =
|
result =
|
||||||
make_string_like_thing( frame_pointer, c, result, SYMBOLTAG );
|
make_string_like_thing( frame_pointer, c, result, SYMBOLTAG );
|
||||||
}
|
}
|
||||||
|
|
@ -180,6 +185,17 @@ struct pso_pointer read_symbol( struct pso_pointer frame_pointer ) {
|
||||||
result = c_reverse( frame_pointer, result );
|
result = c_reverse( frame_pointer, result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
debug_print( L"\nRead symbol `", DEBUG_IO, 0 );
|
||||||
|
debug_print_object( result, DEBUG_IO, 0);
|
||||||
|
debug_print( L"`\n\t", DEBUG_IO, 0);
|
||||||
|
for ( struct pso_pointer cursor = result; !c_nilp(cursor); cursor = c_cdr(cursor)) {
|
||||||
|
wint_t c = pointer_to_object(cursor)->payload.string.character;
|
||||||
|
debug_printf( DEBUG_IO, 0, L"[Character %lc (%d)]", c, c);
|
||||||
|
}
|
||||||
|
debug_println(DEBUG_IO);
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,7 +260,7 @@ struct pso_pointer read( struct pso_pointer frame_pointer ) {
|
||||||
inc_ref( next );
|
inc_ref( next );
|
||||||
if ( iswdigit( c ) ) {
|
if ( iswdigit( c ) ) {
|
||||||
result = push_local( frame_pointer, read_number( next ) );
|
result = push_local( frame_pointer, read_number( next ) );
|
||||||
} else if ( iswalpha( c ) ) {
|
} else if ( symbol_char_p( c ) ) {
|
||||||
result = push_local( frame_pointer, read_symbol( next ) );
|
result = push_local( frame_pointer, read_symbol( next ) );
|
||||||
} else {
|
} else {
|
||||||
// result =
|
// result =
|
||||||
|
|
@ -268,9 +284,9 @@ struct pso_pointer read( struct pso_pointer frame_pointer ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
debug_print( L"Read object: ", DEBUG_IO, 0 );
|
debug_print( L"Read expression: `", DEBUG_IO, 0 );
|
||||||
debug_print_object( result, DEBUG_IO, 0 );
|
debug_print_object( result, DEBUG_IO, 0 );
|
||||||
debug_println( DEBUG_IO );
|
debug_print( L"`\n", DEBUG_IO, 0 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,16 @@ struct pso_pointer search( struct pso_pointer key,
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
debug_print( L"In search; key is: ", DEBUG_BIND, 0 );
|
debug_print( L"In search; key is: `", DEBUG_BIND, 0 );
|
||||||
debug_print_object( key, DEBUG_BIND, 0 );
|
debug_print_object( key, DEBUG_BIND, 0 );
|
||||||
debug_println( DEBUG_BIND );
|
debug_print( L"`\n", DEBUG_BIND, 0 );
|
||||||
|
debug_print(L"", DEBUG_BIND, 2);
|
||||||
|
if (symbolp(key)) {
|
||||||
|
for ( struct pso_pointer cursor = key; !c_nilp(cursor); cursor = c_cdr(cursor)) {
|
||||||
|
wint_t c = pointer_to_object(cursor)->payload.string.character;
|
||||||
|
debug_printf( DEBUG_BIND, 0, L"[Character %lc (%d)]", c, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( consp( store ) ) {
|
if ( consp( store ) ) {
|
||||||
|
|
@ -53,7 +60,17 @@ struct pso_pointer search( struct pso_pointer key,
|
||||||
struct pso_pointer pair = c_car( cursor );
|
struct pso_pointer pair = c_car( cursor );
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
debug_print( L"Checking ", DEBUG_BIND, 2 );
|
debug_print( L"Checking ", DEBUG_BIND, 2 );
|
||||||
debug_print_object( pair, DEBUG_BIND, 0 );
|
debug_print_object( c_car( pair), DEBUG_BIND, 0 );
|
||||||
|
debug_println( DEBUG_BIND);
|
||||||
|
debug_print(L"", DEBUG_BIND, 4);
|
||||||
|
if (symbolp(c_car( pair))) {
|
||||||
|
for ( struct pso_pointer cursor = c_car(pair); !c_nilp(cursor); cursor = c_cdr(cursor)) {
|
||||||
|
wint_t c = pointer_to_object(cursor)->payload.string.character;
|
||||||
|
debug_printf( DEBUG_BIND, 0, L"[Character %lc (%d)]", c, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug_println(DEBUG_BIND);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( consp( pair ) && c_equal( c_car( pair ), key ) ) {
|
if ( consp( pair ) && c_equal( c_car( pair ), key ) ) {
|
||||||
|
|
|
||||||
|
|
@ -45,112 +45,6 @@
|
||||||
#include "payloads/stack.h"
|
#include "payloads/stack.h"
|
||||||
#include "payloads/symbol.h"
|
#include "payloads/symbol.h"
|
||||||
|
|
||||||
///**
|
|
||||||
// * @brief Apply a function to arguments in an environment.
|
|
||||||
// *
|
|
||||||
// * * (apply fn args)
|
|
||||||
// */
|
|
||||||
//struct pso_pointer apply( struct pso_pointer frame_pointer ) {
|
|
||||||
//
|
|
||||||
//// TODO.
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
///**
|
|
||||||
// * @brief Evaluate a form, in an environment
|
|
||||||
// *
|
|
||||||
// * * (eval form)
|
|
||||||
// */
|
|
||||||
//struct pso_pointer eval( struct pso_pointer frame_pointer ) {
|
|
||||||
// struct pso4 *frame = pointer_to_pso4( frame_pointer );
|
|
||||||
//
|
|
||||||
// struct pso_pointer arg = fetch_arg( frame, 0 );
|
|
||||||
// struct pso_pointer result = nil;
|
|
||||||
//
|
|
||||||
// if ( !c_c_nilp( arg ) ) {
|
|
||||||
// switch ( get_tag_value( arg ) ) {
|
|
||||||
// // case CONSTV:
|
|
||||||
// // result = eval_cons( frame, frame_pointer, env);
|
|
||||||
// // break;
|
|
||||||
// case INTEGERTV:
|
|
||||||
// case KEYTV:
|
|
||||||
// case NILTV:
|
|
||||||
// case STRINGTV:
|
|
||||||
// // self evaluating
|
|
||||||
// result = nil;
|
|
||||||
// break;
|
|
||||||
// case SYMBOLTV:
|
|
||||||
// result = c_assoc( arg, fetch_env( frame_pointer ) );
|
|
||||||
// break;
|
|
||||||
// // case LAMBDATV:
|
|
||||||
// // result = eval_lambda( frame, frame_pointer, env);
|
|
||||||
// // break;
|
|
||||||
// // case NLAMBDATV:
|
|
||||||
// // result = eval_nlambda( frame, frame_pointer, env);
|
|
||||||
// // break;
|
|
||||||
// // case SPECIALTV:
|
|
||||||
// // result = eval_special( frame, frame_pointer, env);
|
|
||||||
// // break;
|
|
||||||
// default:
|
|
||||||
//#ifdef DEBUG
|
|
||||||
// struct pso2 *object = pointer_to_object( arg );
|
|
||||||
// debug_printf( DEBUG_EVAL, 0,
|
|
||||||
// L"Can't yet evaluate objects of type %3.3s\n",
|
|
||||||
// object->header.tag.bytes.mnemonic[0] );
|
|
||||||
// debug_print_object( arg, DEBUG_EVAL, 2 );
|
|
||||||
// debug_println( DEBUG_EVAL, 0 );
|
|
||||||
//#endif
|
|
||||||
// result = make_exception( make_frame( 1, frame_pointer,
|
|
||||||
// make_cons( frame_pointer,
|
|
||||||
// c_string_to_lisp_string
|
|
||||||
// ( frame_pointer,
|
|
||||||
// L"Can't yet evaluate things of this type: " ),
|
|
||||||
// arg ),
|
|
||||||
// make_cons( frame_pointer,
|
|
||||||
// make_cons
|
|
||||||
// ( frame_pointer,
|
|
||||||
// c_string_to_lisp_keyword
|
|
||||||
// ( frame_pointer,
|
|
||||||
// L"tag" ),
|
|
||||||
// get_tag_string
|
|
||||||
// ( frame_pointer,
|
|
||||||
// arg ) ),
|
|
||||||
// nil ), nil ) );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if ( exceptionp( result ) ) {
|
|
||||||
// struct pso3 *x =
|
|
||||||
// ( struct pso3 * ) pointer_to_object_with_tag_value( result,
|
|
||||||
// EXCEPTIONTV );
|
|
||||||
//
|
|
||||||
// if ( c_c_nilp( x->payload.exception.stack ) ) {
|
|
||||||
// x->payload.exception.stack = frame_pointer;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return result;
|
|
||||||
//}
|
|
||||||
/*
|
|
||||||
* lispops.c
|
|
||||||
*
|
|
||||||
* List processing operations.
|
|
||||||
*
|
|
||||||
* The general idea here is that a list processing operation is a
|
|
||||||
* function which takes two arguments, both pso_pointers:
|
|
||||||
*
|
|
||||||
* 1. args, the argument list to this function;
|
|
||||||
* 2. env, the environment in which this function should be evaluated;
|
|
||||||
*
|
|
||||||
* and returns a pso_pointer, the result.
|
|
||||||
*
|
|
||||||
* They must all have the same signature so that I can call them as
|
|
||||||
* function pointers.
|
|
||||||
*
|
|
||||||
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
|
||||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Useful building block; evaluate this single form in the context of this
|
* Useful building block; evaluate this single form in the context of this
|
||||||
* parent stack frame and this environment.
|
* parent stack frame and this environment.
|
||||||
|
|
@ -779,6 +673,12 @@ lisp_eval( struct pso_pointer frame_pointer ) {
|
||||||
|
|
||||||
case SYMBOLTV:
|
case SYMBOLTV:
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
debug_print( L"\nEvaluating symbol `", DEBUG_EVAL, 0);
|
||||||
|
debug_print_object( fetch_arg( frame, 0), DEBUG_EVAL, 0);
|
||||||
|
debug_print( L"`\n\tEnvironment is: ", DEBUG_EVAL, 0);
|
||||||
|
debug_dump_object( fetch_env(frame_pointer), DEBUG_EVAL, 0);
|
||||||
|
#endif
|
||||||
struct pso_pointer canonical =
|
struct pso_pointer canonical =
|
||||||
c_interned( frame->payload.stack_frame.arg[0], fetch_env(frame_pointer) );
|
c_interned( frame->payload.stack_frame.arg[0], fetch_env(frame_pointer) );
|
||||||
if ( c_nilp( canonical ) ) {
|
if ( c_nilp( canonical ) ) {
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,6 @@ char *lisp_string_to_c_string( struct pso_pointer s ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a lisp symbol representation of this wide character string. In
|
* Return a lisp symbol representation of this wide character string. In
|
||||||
* symbols, I am accepting only lower case characters and certain punctuation.
|
* symbols, I am accepting only lower case characters and certain punctuation.
|
||||||
|
|
@ -182,9 +181,9 @@ struct pso_pointer c_string_to_lisp_symbol( struct pso_pointer frame_pointer,
|
||||||
struct pso_pointer result = nil;
|
struct pso_pointer result = nil;
|
||||||
|
|
||||||
for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) {
|
for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) {
|
||||||
char32_t c = towlower( symbol[i] );
|
char32_t c = symbol[i];
|
||||||
|
|
||||||
if ( iswalpha( c ) || wcschr(L"-*|!?", c)) {
|
if ( symbol_char_p(c)) {
|
||||||
result = make_symbol( frame_pointer, c, result );
|
result = make_symbol( frame_pointer, c, result );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,16 @@
|
||||||
|
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief true if the argument `wc`, a wide character, is suitable for
|
||||||
|
* inclusion in a symbol.
|
||||||
|
*
|
||||||
|
* Note that Common Lisp is *much* less restrictive
|
||||||
|
* than this currently is, so rethinking may be necessary.
|
||||||
|
*/
|
||||||
|
#define symbol_char_p(wc)(iswalpha( wc ) || wcschr(L"-*|!?", wc))
|
||||||
|
|
||||||
|
|
||||||
/* TODO: for now, Symbol shares a payload with String, but this may change.
|
/* TODO: for now, Symbol shares a payload with String, but this may change.
|
||||||
* Strings are of indefinite length, but symbols are really not, and might
|
* Strings are of indefinite length, but symbols are really not, and might
|
||||||
* fit into any size class. */
|
* fit into any size class. */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue