Skip to content

Commit

Permalink
readback_tup run.c
Browse files Browse the repository at this point in the history
  • Loading branch information
enricozb committed Jun 17, 2024
1 parent 1eaf5fe commit 4ee1bf4
Showing 1 changed file with 55 additions and 31 deletions.
86 changes: 55 additions & 31 deletions src/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ typedef struct Ctr {
Port args_buf[16];
} Ctr;

// Readback: Tuples
typedef struct Tup {
u32 elem_len;
Port elem_buf[8];
} Tup;

// Readback: λ-Encoded Str (UTF-32)
// FIXME: this is actually ASCII :|
// FIXME: remove len limit
Expand Down Expand Up @@ -72,6 +78,26 @@ Ctr readback_ctr(Net* net, Book* book, Port port) {
return ctr;
}

// Reads back a tuple of at most `size` elements. Tuples are
// (right-nested con nodes) (CON 1 (CON 2 (CON 3 (...))))
// The provided `port` should be `expanded` before calling.
Tup readback_tup(Net* net, Book* book, Port port, u32 size) {
Tup tup;
tup.elem_len = 0;

// Loads remaining arguments
while (get_tag(port) == CON && (tup.elem_len + 1 < size)) {
Pair node = node_load(net, get_val(port));
tup.elem_buf[tup.elem_len++] = expand(net, book, get_fst(node));

port = expand(net, book, get_snd(node));
}

tup.elem_buf[tup.elem_len++] = port;

return tup;
}

// Converts a Port into a UTF-32 (truncated to 24 bits) string.
// Since unicode scalars can fit in 21 bits, HVM's u24
// integers can contain any unicode scalar value.
Expand Down Expand Up @@ -256,16 +282,15 @@ FILE* readback_file(Port port) {
// Reads from a file a specified number of bytes.
// `argm` is a tuple of (file_descriptor, num_bytes).
Port io_read(Net* net, Book* book, Port argm) {
if (get_tag(argm) != CON) {
fprintf(stderr, "io_read: expected tuple, but got %u\n", get_tag(argm));
Tup tup = readback_tup(net, book, argm, 2);
if (tup.elem_len != 2) {
fprintf(stderr, "io_read: expected 2-tuple\n");
return new_port(ERA, 0);
}

Pair args = node_load(net, get_val(argm));
Port file = expand(net, book, get_fst(args));
u32 num_bytes = get_u24(get_val(expand(net, book, get_snd(args))));
FILE* fp = readback_file(tup.elem_buf[0]);
u32 num_bytes = get_u24(get_val(tup.elem_buf[1]));

FILE* fp = readback_file(file);
if (fp == NULL) {
fprintf(stderr, "io_read: invalid file descriptor\n");
return new_port(ERA, 0);
Expand All @@ -292,14 +317,14 @@ Port io_read(Net* net, Book* book, Port argm) {
// `argm` is a tuple (CON node) of the
// file name and mode as strings.
Port io_open(Net* net, Book* book, Port argm) {
if (get_tag(argm) != CON) {
fprintf(stderr, "io_open: expected tuple, but got %u\n", get_tag(argm));
Tup tup = readback_tup(net, book, argm, 2);
if (tup.elem_len != 2) {
fprintf(stderr, "io_open: expected 2-tuple\n");
return new_port(ERA, 0);
}

Pair args = node_load(net, get_val(argm));
Str name = readback_str(net, book, expand(net, book, get_fst(args)));
Str mode = readback_str(net, book, expand(net, book, get_snd(args)));
Str name = readback_str(net, book, tup.elem_buf[0]);
Str mode = readback_str(net, book, tup.elem_buf[1]);

for (u32 fd = 3; fd < sizeof(FILE_POINTERS); fd++) {
if (FILE_POINTERS[fd] == NULL) {
Expand Down Expand Up @@ -334,14 +359,14 @@ Port io_close(Net* net, Book* book, Port argm) {
// `argm` is a tuple (CON node) of the
// file descriptor and list of bytes to write.
Port io_write(Net* net, Book* book, Port argm) {
if (get_tag(argm) != CON) {
fprintf(stderr, "io_write: expected tuple, but got %u\n", get_tag(argm));
Tup tup = readback_tup(net, book, argm, 2);
if (tup.elem_len != 2) {
fprintf(stderr, "io_write: expected 2-tuple\n");
return new_port(ERA, 0);
}

Pair args = node_load(net, get_val(argm));
FILE* fp = readback_file(expand(net, book, get_fst(args)));
Bytes bytes = readback_bytes(net, book, get_snd(args));
FILE* fp = readback_file(expand(net, book, tup.elem_buf[0]));
Bytes bytes = readback_bytes(net, book, tup.elem_buf[1]);

if (fp == NULL) {
fprintf(stderr, "io_write: invalid file descriptor\n");
Expand All @@ -366,22 +391,15 @@ Port io_write(Net* net, Book* book, Port argm) {
// - 1 (SEEK_CUR): current position of the file pointer
// - 2 (SEEK_END): end of the file
Port io_seek(Net* net, Book* book, Port argm) {
if (get_tag(argm) != CON) {
fprintf(stderr, "io_seek: expected first tuple, but got %u\n", get_tag(argm));
return new_port(ERA, 0);
}

Pair args1 = node_load(net, get_val(argm));
Port argm2 = expand(net, book, get_snd(args1));
if (get_tag(argm2) != CON) {
fprintf(stderr, "io_seek: expected second tuple, but got %u\n", get_tag(argm2));
Tup tup = readback_tup(net, book, argm, 3);
if (tup.elem_len != 3) {
fprintf(stderr, "io_seek: expected 3-tuple\n");
return new_port(ERA, 0);
}
Pair args2 = node_load(net, get_val(argm2));

FILE* fp = readback_file(expand(net, book, get_fst(args1)));
i32 offset = get_i24(get_val(expand(net, book, get_fst(args2))));
u32 whence = get_i24(get_val(expand(net, book, get_snd(args2))));
FILE* fp = readback_file(tup.elem_buf[0]);
i32 offset = get_i24(get_val(tup.elem_buf[1]));
u32 whence = get_i24(get_val(tup.elem_buf[2]));

if (fp == NULL) {
fprintf(stderr, "io_write: invalid file descriptor\n");
Expand Down Expand Up @@ -425,11 +443,17 @@ Port io_get_time(Net* net, Book* book, Port argm) {
// `argm` is a tuple (CON node) of the high and low
// 24 bits for a 48-bit duration in nanoseconds.
Port io_sleep(Net* net, Book* book, Port argm) {
Tup tup = readback_tup(net, book, argm, 2);
if (tup.elem_len != 2) {
fprintf(stderr, "io_sleep: expected 3-tuple\n");
return new_port(ERA, 0);
}

// Get the sleep duration node
Pair dur_node = node_load(net, get_val(argm));
// Get the high and low 24-bit parts of the duration
u32 dur_hi = get_u24(get_val(expand(net, book, get_fst(dur_node))));
u32 dur_lo = get_u24(get_val(expand(net, book, get_snd(dur_node))));
u32 dur_hi = get_u24(get_val(tup.elem_buf[0]));
u32 dur_lo = get_u24(get_val(tup.elem_buf[1]));
// Combine into a 48-bit duration in nanoseconds
u64 dur_ns = (((u64)dur_hi) << 24) | dur_lo;
// Sleep for the specified duration
Expand Down

0 comments on commit 4ee1bf4

Please sign in to comment.