I think read will now read integers and symbols, but it's untested.

Everything compiles.
This commit is contained in:
Simon Brooke 2026-04-01 16:06:16 +01:00
parent cc8e96eda4
commit 9eb0d3c5a0
28 changed files with 594 additions and 293 deletions

View file

@ -23,16 +23,22 @@
#include <wctype.h>
#include "debug.h"
#include "memory/node.h"
#include "memory/pointer.h"
#include "memory/pso2.h"
#include "io/io.h"
#include "io/read.h"
#include "memory/node.h"
#include "memory/pointer.h"
#include "memory/pso2.h"
#include "memory/tags.h"
#include "payloads/integer.h"
#include "ops/stack_ops.h"
#include "payloads/read_stream.h"
#include "ops/assoc.h"
#include "ops/reverse.h"
#include "ops/stack_ops.h"
#include "ops/string_ops.h"
#include "ops/truth.h"
// TODO: what I've copied from 0.0.6 is *wierdly* over-complex for just now.
// I think I'm going to essentially delete all this and start again. We need
@ -57,29 +63,167 @@
/**
* An example wrapper function while I work out how I'm going to do this.
*
* For this and all other `read` functions unless documented otherwise, the
* arguments in the frame are expected to be:
*
* 0. The input stream to read from;
* 1. The read table currently in use;
* 2. The character most recently read from that stream.
*/
struct pso_pointer read_example( struct pso4 *frame,
struct pso_pointer frame_pointer,
struct pso_pointer read_example( struct pso_pointer frame_pointer,
struct pso_pointer env) {
struct pso_pointer character = fetch_arg( frame, 0);
struct pso_pointer stream = fetch_arg( frame, 1);
struct pso_pointer readtable = fetch_arg( frame, 2);
struct pso4 *frame = pointer_to_pso4( frame_pointer);
struct pso_pointer stream = fetch_arg( frame, 0);
struct pso_pointer readtable = fetch_arg( frame, 1);
struct pso_pointer character = fetch_arg( frame, 2);
struct pso_pointer result = nil;
return character;
return result;
}
/**
* Read the next object on this input stream and return a pso_pointer to it.
* @brief Read one integer from the stream and return it.
*
* For this and all other `read` functions unless documented otherwise, the
* arguments in the frame are expected to be:
*
* 0. The input stream to read from;
* 1. The read table currently in use;
* 2. The character most recently read from that stream.
*/
struct pso_pointer read( struct pso4 *frame,
struct pso_pointer frame_pointer,
struct pso_pointer read_number( struct pso_pointer frame_pointer,
struct pso_pointer env) {
struct pso4 *frame = pointer_to_pso4( frame_pointer);
struct pso_pointer stream = fetch_arg( frame, 0);
struct pso_pointer readtable = fetch_arg( frame, 1);
struct pso_pointer character = fetch_arg( frame, 2);
struct pso_pointer result = nil;
int base = 10;
// TODO: should check for *read-base* in the environment
int64_t value = 0;
if (readp(stream)) {
if (nilp( character)) {
character = get_character( stream);
}
wchar_t c = nilp(character) ? 0 :
pointer_to_object( character)->payload.character.character;
URL_FILE * input = pointer_to_object(stream)->payload.stream.stream;
for ( ; iswdigit( c );
c = url_fgetwc( input ) ){
value = (value * base) + ((int)c - (int)L'0');
}
url_ungetwc( c, input);
result = make_integer( value);
} // else exception?
return result;
}
struct pso_pointer read_symbol( struct pso_pointer frame_pointer,
struct pso_pointer env) {
struct pso4 *frame = pointer_to_pso4( frame_pointer);
struct pso_pointer stream = fetch_arg( frame, 0);
struct pso_pointer readtable = fetch_arg( frame, 1);
struct pso_pointer character = fetch_arg( frame, 2);
struct pso_pointer result = nil;
if (readp(stream)) {
if (nilp( character)) {
character = get_character( stream);
}
wchar_t c = nilp(character) ? 0 :
pointer_to_object( character)->payload.character.character;
URL_FILE * input = pointer_to_object(stream)->payload.stream.stream;
for ( ; iswalnum( c );
c = url_fgetwc( input ) ){
result = make_string_like_thing(c, result, SYMBOLTAG);
}
url_ungetwc( c, input);
result = reverse( result);
}
return result;
}
/**
* @brief Read the next object on the input stream indicated by this stack
* frame, and return a pso_pointer to the object read.
*
* For this and all other `read` functions unless documented otherwise, the
* arguments in the frame are expected to be:
*
* 0. The input stream to read from;
* 1. The read table currently in use;
* 2. The character most recently read from that stream.
*/
struct pso_pointer read( struct pso_pointer frame_pointer,
struct pso_pointer env ) {
struct pso_pointer* character = fetch_arg( frame, 0);
struct pso_pointer stream = fetch_arg( frame, 1);
struct pso_pointer readtable = fetch_arg( frame, 2);
struct pso4 *frame = pointer_to_pso4( frame_pointer);
struct pso_pointer stream = fetch_arg( frame, 0);
struct pso_pointer readtable = fetch_arg( frame, 1);
struct pso_pointer character = fetch_arg( frame, 2);
struct pso_pointer result = nil;
if (nilp(stream)) {
stream = make_read_stream( file_to_url_file(stdin), nil);
}
if (nilp( readtable)) {
// TODO: check for the value of `*read-table*` in the environment and
// use that.
}
if (nilp( character)) {
character = get_character( stream);
}
struct pso_pointer readmacro = assoc(character, readtable);
if (!nilp( readmacro)) {
// invoke the read macro on the stream
} else if (readp( stream) && characterp(character)) {
wchar_t c = pointer_to_object( character)->payload.character.character;
URL_FILE * input = pointer_to_object(stream)->payload.stream.stream;
switch ( c ) {
case ';':
for ( c = url_fgetwc( input ); c != '\n';
c = url_fgetwc( input ) );
/* skip all characters from semi-colon to the end of the line */
break;
case EOF:
// result = throw_exception( c_string_to_lisp_symbol( L"read" ),
// c_string_to_lisp_string
// ( L"End of input while reading" ),
// frame_pointer );
break;
default:
struct pso_pointer next = make_frame( frame_pointer, stream, readtable, make_character(c));
if ( iswdigit( c ) ) {
result =
read_number( next, env );
} else if ( iswalpha( c ) ) {
result = read_symbol( next, env );
} else {
// result =
// throw_exception( c_string_to_lisp_symbol( L"read" ),
// make_cons( c_string_to_lisp_string
// ( L"Unrecognised start of input character" ),
// make_string( c, NIL ) ),
// frame_pointer );
}
break;
}
}
return result;
}