Substantial work on read-list, not yet fully working.
This commit is contained in:
parent
80049f2272
commit
6b89779bab
5 changed files with 127 additions and 11 deletions
|
|
@ -87,6 +87,13 @@ struct pso_pointer read_example( struct pso_pointer frame_pointer ) {
|
|||
return result;
|
||||
}
|
||||
|
||||
struct pso_pointer make_eof_exception( struct pso_pointer frame_pointer) {
|
||||
return make_exception( make_frame( 1, frame_pointer,
|
||||
c_string_to_lisp_string
|
||||
( frame_pointer,
|
||||
L"Read: end of input while reading" ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: return the next character from the stream indicated by arg 0;
|
||||
* further arguments are ignored.
|
||||
|
|
@ -115,6 +122,71 @@ struct pso_pointer read_character( struct pso_pointer frame_pointer ) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief advance the `stream` indicated in arg[0] of this stack frame over any
|
||||
* whitespace characters. The character indicated by arg[2] will be treated as
|
||||
* potentially the first such character. Returns the first non-space character
|
||||
* encountered, or an exception.
|
||||
*/
|
||||
struct pso_pointer skip_whitespace( struct pso_pointer frame_pointer ) {
|
||||
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 (characterp(character)) {
|
||||
wchar_t wc = pointer_to_object(character)->payload.character.character;
|
||||
if (!iswspace( wc) && wc != L',') {
|
||||
result = character;
|
||||
}
|
||||
}
|
||||
|
||||
if (c_nilp( result) && readp( stream)) {
|
||||
URL_FILE* input = pointer_to_object(stream)->payload.stream.stream;
|
||||
|
||||
wint_t wc = url_fgetwc( input);
|
||||
while ( iswspace(wc) || wc==L',') { wc = url_fgetwc( input); }
|
||||
result = (wc == WEOF) ? make_eof_exception(frame_pointer) : make_character(frame_pointer, wc);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct pso_pointer read_list( struct pso_pointer frame_pointer ) {
|
||||
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 (!c_nilp(character) && characterp(character) &&
|
||||
pointer_to_object(character)->payload.character.character == SYNTAX_LPAR) {
|
||||
// it's OK if an LPAR is passed in, but we don't want it now.
|
||||
character = nil;
|
||||
}
|
||||
if (!c_nilp( character)) {
|
||||
// if anything other than LPAR is passed in as character, TODO: throw exception.
|
||||
}
|
||||
|
||||
while ( c_nilp(character) || (characterp(character) &&
|
||||
pointer_to_object(character)->payload.character.character != SYNTAX_RPAR)) {
|
||||
character = skip_whitespace( make_frame(3, frame_pointer, stream, readtable, character));
|
||||
struct pso_pointer r = read( make_frame(3, frame_pointer, stream, readtable, character));
|
||||
|
||||
if (exceptionp(r)) {
|
||||
result = r;
|
||||
break;
|
||||
} else {
|
||||
result = make_cons( frame_pointer, r, result);
|
||||
character = skip_whitespace( make_frame(3, frame_pointer, stream, readtable, character));
|
||||
}
|
||||
}
|
||||
|
||||
return consp(result) ? c_reverse( frame_pointer, result) : result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read one integer from the stream and return it.
|
||||
*
|
||||
|
|
@ -226,7 +298,7 @@ struct pso_pointer read( struct pso_pointer frame_pointer ) {
|
|||
}
|
||||
|
||||
if ( c_nilp( character ) ) {
|
||||
character = read_character( make_frame( 1, frame_pointer, stream ) );
|
||||
character = skip_whitespace( make_frame( 1, frame_pointer, stream ) );
|
||||
}
|
||||
|
||||
struct pso_pointer readmacro = c_assoc( character, readtable );
|
||||
|
|
@ -239,16 +311,16 @@ struct pso_pointer read( struct pso_pointer frame_pointer ) {
|
|||
URL_FILE *input = pointer_to_object( stream )->payload.stream.stream;
|
||||
|
||||
switch ( c ) {
|
||||
case ';':
|
||||
case SYNTAX_SEMICOLON:
|
||||
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 SYNTAX_LPAR:
|
||||
result = read_list( make_frame(3, stream, readtable, character));
|
||||
break;
|
||||
case EOF:
|
||||
result = make_exception( make_frame( 1, frame_pointer,
|
||||
c_string_to_lisp_string
|
||||
( frame_pointer,
|
||||
L"Read: end of input while reading" ) ) );
|
||||
result = make_eof_exception(frame_pointer);
|
||||
break;
|
||||
default:
|
||||
struct pso_pointer next = make_frame( 3, frame_pointer, stream,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue