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

@ -46,6 +46,7 @@
#include "ops/string_ops.h"
#include "ops/truth.h"
#include "payloads/character.h"
#include "payloads/cons.h"
#include "payloads/exception.h"
#include "payloads/integer.h"
@ -81,7 +82,7 @@ wint_t ungotten = 0;
*
* @return 0 on success; any other value means failure.
*/
int io_init( ) {
int initialise_io( ) {
int result = curl_global_init( CURL_GLOBAL_SSL );
io_share = curl_share_init( );
@ -252,6 +253,43 @@ wint_t url_ungetwc( wint_t wc, URL_FILE *input ) {
return result;
}
/**
* @brief Read one character object from this `read_stream`.
*
* @param read_stream a pointer to an object which should be a read stream
* object,
*
* @return a pointer to a character object on success, or `nil` on failure.
*/
struct pso_pointer get_character( struct pso_pointer read_stream ) {
struct pso_pointer result = nil;
if (readp( read_stream)) {
result = make_character( url_fgetwc( pointer_to_object_of_size_class(read_stream, 2)->payload.stream.stream));
}
return result;
}
/**
* @brief Push back this character `c` onto this read stream `r`.
*
* @param c a pointer to an object which should be a character object;
* @param r a pointer to an object which should be a read stream object,
*
* @return `t` on success, else `nil`.
*/
struct pso_pointer push_back_character( struct pso_pointer c, struct pso_pointer r) {
struct pso_pointer result = nil;
if (characterp(c) && readp(r)) {
if (url_ungetwc( (wint_t)(pointer_to_object(c)->payload.character.character),
pointer_to_object(r)->payload.stream.stream) >= 0) {
result = t;
}
}
return result;
}
/**
* Function, sort-of: close the file indicated by my first arg, and return

View file

@ -18,7 +18,7 @@
extern CURLSH *io_share;
int io_init( );
int initialise_io( );
#define C_IO_IN L"*in*"
#define C_IO_OUT L"*out*"
@ -30,6 +30,10 @@ URL_FILE *file_to_url_file( FILE * f );
wint_t url_fgetwc( URL_FILE * input );
wint_t url_ungetwc( wint_t wc, URL_FILE * input );
struct pso_pointer get_character( struct pso_pointer read_stream );
struct pso_pointer push_back_character( struct pso_pointer c, struct pso_pointer r);
struct pso_pointer get_default_stream( bool inputp, struct pso_pointer env );
struct pso_pointer

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;
}