[nucl] add a mock stream

This commit is contained in:
Daniel Kochmański 2025-05-21 09:31:07 +02:00
parent 0058af914f
commit da7ff0e8bf
3 changed files with 164 additions and 1 deletions

View file

@ -55,7 +55,8 @@ NUCL_CFLG = -DECL_NUCL -DECL_BUILD -DGC_NO_THREAD_REDIRECTS \
-I$(builddir) -I$(srcdir) -g3 -rdynamic -I$(builddir) -I$(srcdir) -g3 -rdynamic
NUCL_SRCS = boot.c escape.c module.c stacks.c eql.c \ NUCL_SRCS = boot.c escape.c module.c stacks.c eql.c \
memory.c atomic.c process.c apply.c interpreter.c stream.c memory.c atomic.c process.c apply.c interpreter.c stream.c \
streams/strm_nucl.c
BOOT_OBJS = boot.o escape.o module.o stacks.o eql.o BOOT_OBJS = boot.o escape.o module.o stacks.o eql.o

View file

@ -80,6 +80,18 @@ void smoke_bytecodes (void)
ecl_stack_frame_close(f); ecl_stack_frame_close(f);
} }
cl_object ecl_make_stub_stream(void);
cl_object ecl_make_nucl_stream(void);
void
smoke_stream (void)
{
cl_object strm = ecl_make_nucl_stream();
printf(">>> smoke_stream: stream is %p\n", strm);
si_read_char(strm, ECL_NIL, ECL_NIL);
si_write_char(ECL_CODE_CHAR('c'), strm);
}
int main() { int main() {
cl_env_ptr the_env = ecl_core.first_env; cl_env_ptr the_env = ecl_core.first_env;
ecl_boot(); ecl_boot();
@ -102,10 +114,19 @@ int main() {
nucl_flamethrower(0); nucl_flamethrower(0);
printf("-----------------------------------------------\n\n"); printf("-----------------------------------------------\n\n");
/* Just install the handler. */
cl_object handlers = ecl_cons_stack(_nucl_extinguisher, ECL_NIL);
ECL_SETQ(the_env, ECL_SIGNAL_HANDLERS, handlers);
printf("\n[:bytecodes t] --------------------------------\n"); printf("\n[:bytecodes t] --------------------------------\n");
smoke_bytecodes(); smoke_bytecodes();
printf("-----------------------------------------------\n\n"); printf("-----------------------------------------------\n\n");
printf("\n[:stream t] --------------------------------\n");
smoke_stream();
printf("-----------------------------------------------\n\n");
printf("Good bye ECL! %p\n", the_env); printf("Good bye ECL! %p\n", the_env);
ecl_halt(); ecl_halt();

141
src/c/streams/strm_nucl.c Normal file
View file

@ -0,0 +1,141 @@
/* -- imports ------------------------------------------------------- */
#include <ecl/ecl.h>
#include <ecl/ecl-inl.h>
#include <ecl/internal.h>
#include <ecl/external.h>
#include <ecl/bytecodes.h>
cl_index
not_implemented_byte8(cl_object strm, unsigned char *c, cl_index n)
{
ecl_ferror(ECL_EX_NIY, ECL_NIL, ECL_NIL);
return 0;
}
static cl_index
not_implemented_vector(cl_object strm, cl_object data, cl_index start, cl_index end)
{
ecl_ferror(ECL_EX_NIY, ECL_NIL, ECL_NIL);
return 0;
}
static void
not_implemented_writer(cl_object strm, cl_object c)
{
ecl_ferror(ECL_EX_NIY, ECL_NIL, ECL_NIL);
}
static void
not_implemented_option(cl_object strm)
{
ecl_ferror(ECL_EX_NIY, ECL_NIL, ECL_NIL);
}
static cl_object
not_implemented_setter(cl_object strm, cl_object val)
{
ecl_ferror(ECL_EX_NIY, ECL_NIL, ECL_NIL);
}
static cl_object
not_implemented_reader(cl_object strm)
{
ecl_ferror(ECL_EX_NIY, ECL_NIL, ECL_NIL);
return ECL_NIL;
}
static int
not_implemented_reader_raw(cl_object strm)
{
ecl_ferror(ECL_EX_NIY, ECL_NIL, ECL_NIL);
return 0;
}
static int
not_implemented_writer_raw(cl_object strm, int c)
{
ecl_ferror(ECL_EX_NIY, ECL_NIL, ECL_NIL);
return 0;
}
static void
not_implemented_unread_raw(cl_object strm, int c)
{
ecl_ferror(ECL_EX_NIY, ECL_NIL, ECL_NIL);
}
struct ecl_file_ops stub_io_ops = {
/* Used to implement encodings */
.write_byte8 = not_implemented_byte8,
.read_byte8 = not_implemented_byte8,
/* Binary I/O */
.write_byte = not_implemented_writer,
.read_byte = not_implemented_reader,
/* String I/O */
.read_char = not_implemented_reader_raw,
.write_char = not_implemented_writer_raw,
.unread_char = not_implemented_unread_raw,
.peek_char = not_implemented_reader_raw,
/* Used to implement r/w sequence */
.read_vector = not_implemented_vector,
.write_vector = not_implemented_vector,
/* Stream operations */
.listen = not_implemented_reader_raw,
.clear_input = not_implemented_option,
.clear_output = not_implemented_option,
.finish_output = not_implemented_option,
.force_output = not_implemented_option,
/* Stream appraisal */
.input_p = not_implemented_reader_raw,
.output_p = not_implemented_reader_raw,
.interactive_p = not_implemented_reader_raw,
.element_type = not_implemented_reader,
/* Cursor operations */
.length = not_implemented_reader,
.get_position = not_implemented_reader,
.set_position = not_implemented_setter,
.string_length = not_implemented_setter,
.column = not_implemented_reader_raw,
/* File stream readers */
.pathname = not_implemented_reader,
.truename = not_implemented_reader,
/* Closing the stream (generic_close replaces the dispatch table) */
.close = not_implemented_reader,
};
cl_object
ecl_make_stub_stream(void)
{
cl_object strm = ecl_alloc_stream();
strm->stream.ops = &stub_io_ops;
strm->stream.mode = ecl_smm_other;
return strm;
}
static int
nucl_read_char(cl_object strm)
{
return 'X';
}
static int
nucl_write_char(cl_object strm, ecl_character c)
{
printf("Character: %c\n", c);
return c;
}
cl_object
ecl_make_nucl_stream(void)
{
cl_object strm = ecl_alloc_stream();
strm->d.t = t_stream; /* hum */
struct ecl_file_ops *ops = ecl_duplicate_dispatch_table(&stub_io_ops);
ops->read_char = nucl_read_char;
ops->write_char = nucl_write_char;
strm->stream.ops = ops;
strm->stream.mode = ecl_smm_other;
return strm;
}