enhanced the compiler to handle a string as a series of bytes in a byte array literal.

added FileAccessor>>seek:whence:
This commit is contained in:
hyunghwan.chung 2019-10-29 14:21:14 +00:00
parent 044177fa61
commit b5b72c626c
6 changed files with 107 additions and 26 deletions

View File

@ -38,9 +38,10 @@
* #\pB8000000 SmallPointer(smptr) literal * #\pB8000000 SmallPointer(smptr) literal
* #() Array. Comma as element delimiter is optional * #() Array. Comma as element delimiter is optional
* #[] ByteArray. Comma as element delimiter is optional * #[] ByteArray. Comma as element delimiter is optional #[ 16r10, 16r20, 16r30 ] #[ "\x10\x20", "\x30" ]
* #{} Dictionary - not supported yet * #{} Dictionary - not supported yet
The followings are not literals. The followings forms expressions. The followings are not literals. The followings forms expressions.
* ##() Array expression. Comma required to delimit elements * ##() Array expression. Comma required to delimit elements

View File

@ -539,9 +539,7 @@ extend Apex
// TODO: implement this properly // TODO: implement this properly
| class_name ctx | | class_name ctx |
class_name := if (self class == Class) { self name } else { self class name }. class_name := if (self class == Class) { self name } else { self class name }.
//System backtrace.
System backtrace.
NoSuchMessageException signal: (message_name & " not understood by " & class_name). NoSuchMessageException signal: (message_name & " not understood by " & class_name).
} }

View File

@ -3,7 +3,9 @@ class(#limited) InputOutputStud(Object) from "io"
var(#get) handle. // you must keep handle as the first field for consitency with the io module. var(#get) handle. // you must keep handle as the first field for consitency with the io module.
method(#primitive,#lenient) _close. method(#primitive,#lenient) _close.
method(#primitive) _readBytesInto: buffer.
method(#primitive) _readBytesInto: buffer startingAt: offset for: count. method(#primitive) _readBytesInto: buffer startingAt: offset for: count.
method(#primitive) _writeBytesFrom: buffer.
method(#primitive) _writeBytesFrom: buffer startingAt: offset for: count. method(#primitive) _writeBytesFrom: buffer startingAt: offset for: count.
} }
@ -21,10 +23,15 @@ class FileAccessor(InputOutputStud) from "io.file"
O_RDONLY from "O_RDONLY", O_RDONLY from "O_RDONLY",
O_RDWR from "O_RDWR", O_RDWR from "O_RDWR",
O_TRUNC from "O_TRUNC", O_TRUNC from "O_TRUNC",
O_WRONLY from "O_WRONLY" O_WRONLY from "O_WRONLY",
SEEK_CUR from "SEEK_CUR",
SEEK_END from "SEEK_END",
SEEK_SET from "SEEK_SET"
} }
method(#primitive,#lenient) _open: path flags: flags. method(#primitive,#lenient) _open: path flags: flags.
method(#primitive) _seek: offset whence: whence.
method(#class) on: path for: flags method(#class) on: path for: flags
{ {

View File

@ -5288,34 +5288,53 @@ static int read_byte_array_literal (moo_t* moo, int rdonly, moo_oop_t* xlit)
GET_TOKEN_GOTO (moo, oops); /* skip #[ and read the next token */ GET_TOKEN_GOTO (moo, oops); /* skip #[ and read the next token */
while (TOKEN_TYPE(moo) == MOO_IOTOK_INTLIT || TOKEN_TYPE(moo) == MOO_IOTOK_RADINTLIT || TOKEN_TYPE(moo) == MOO_IOTOK_CHARLIT) while (TOKEN_TYPE(moo) == MOO_IOTOK_INTLIT || TOKEN_TYPE(moo) == MOO_IOTOK_RADINTLIT || TOKEN_TYPE(moo) == MOO_IOTOK_CHARLIT || TOKEN_TYPE(moo) == MOO_IOTOK_STRLIT)
{ {
/* TODO: check if the number is an integer */ /* TODO: check if the number is an integer */
if (TOKEN_TYPE(moo) == MOO_IOTOK_CHARLIT) if (TOKEN_TYPE(moo) == MOO_IOTOK_STRLIT)
{ {
/* accept a character literal inside a byte array literal */ moo_oow_t i;
tmp = TOKEN_NAME_PTR(moo)[0]; for (i = 0; i < TOKEN_NAME_LEN(moo); i++)
{
tmp = TOKEN_NAME_PTR(moo)[i];
if (tmp < 0 || tmp > 0xFF)
{
moo_setsynerr (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops;
}
if (add_to_byte_array_literal_buffer(moo, tmp) <= -1) goto oops;
}
} }
else if (string_to_smooi(moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADINTLIT, &tmp) <= -1) else
{ {
/* the token reader reads a valid token. no other errors if (TOKEN_TYPE(moo) == MOO_IOTOK_CHARLIT)
* than the range error must not occur */ {
MOO_ASSERT (moo, moo->errnum == MOO_ERANGE); /* accept a character literal inside a byte array literal */
tmp = TOKEN_NAME_PTR(moo)[0];
}
else if (string_to_smooi(moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADINTLIT, &tmp) <= -1)
{
/* the token reader reads a valid token. no other errors
* than the range error must not occur */
MOO_ASSERT (moo, moo->errnum == MOO_ERANGE);
/* if the token is out of the SMOOI range, it's too big or /* if the token is out of the SMOOI range, it's too big or
* to small to be a byte */ * to small to be a byte */
moo_setsynerr (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo)); moo_setsynerr (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops; goto oops;
}
if (tmp < 0 || tmp > 0xFF)
{
moo_setsynerr (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops;
}
if (add_to_byte_array_literal_buffer(moo, tmp) <= -1) goto oops;
} }
if (tmp < 0 || tmp > 0xFF)
{
moo_setsynerr (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops;
}
if (add_to_byte_array_literal_buffer(moo, tmp) <= -1) goto oops;
GET_TOKEN_GOTO (moo, oops); GET_TOKEN_GOTO (moo, oops);
if (comma_used == -1) if (comma_used == -1)

View File

@ -111,6 +111,57 @@ oops:
} }
static moo_pfrc_t pf_seek_file (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
{
oop_io_t io;
moo_oop_t tmp;
moo_oow_t offset, whence;
int fd;
ssize_t n;
io = (oop_io_t)MOO_STACK_GETRCV(moo, nargs);
MOO_PF_CHECK_RCV (moo,
MOO_OOP_IS_POINTER(io) &&
MOO_OBJ_BYTESOF(io) >= (MOO_SIZEOF(*io) - MOO_SIZEOF(moo_obj_t)) &&
MOO_OOP_IS_SMOOI(io->handle)
);
fd = MOO_OOP_TO_SMOOI(io->handle);
if (fd <= -1)
{
moo_seterrbfmt (moo, MOO_EINVAL, "bad IO handle - %d", fd);
return MOO_PF_FAILURE;
}
tmp = MOO_STACK_GETARG(moo, nargs, 0);
if (moo_inttooow(moo, tmp, &offset) <= 0)
{
moo_seterrbfmt (moo, MOO_EINVAL, "invalid offset - %O", tmp);
return MOO_PF_FAILURE;
}
tmp = MOO_STACK_GETARG(moo, nargs, 1);
if (moo_inttooow(moo, tmp, &whence) <= 0)
{
moo_seterrbfmt (moo, MOO_EINVAL, "invalid whence - %O", tmp);
return MOO_PF_FAILURE;
}
n = lseek(fd, offset, whence);
if (n <= -1)
{
moo_seterrwithsyserr (moo, 0, errno);
return MOO_PF_FAILURE;
}
/* [NOTE] on EWOULDBLOCK or EGAIN, -1 is returned */
MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(n));
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(n));
return MOO_PF_SUCCESS;
}
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
#define C MOO_METHOD_CLASS #define C MOO_METHOD_CLASS
@ -122,6 +173,7 @@ static moo_pfinfo_t pfinfos[] =
{ {
{ I, "open:flags:", { pf_open_file, 2, 2 } }, { I, "open:flags:", { pf_open_file, 2, 2 } },
{ I, "open:flags:mode:", { pf_open_file, 3, 3 } }, { I, "open:flags:mode:", { pf_open_file, 3, 3 } },
{ I, "seek:whence:", { pf_seek_file, 2, 2 } }
}; };
static moo_pvinfo_t pvinfos[] = static moo_pvinfo_t pvinfos[] =
@ -134,7 +186,11 @@ static moo_pvinfo_t pvinfos[] =
{ "O_RDONLY", { MOO_PV_OOI, (const void*)O_RDONLY } }, { "O_RDONLY", { MOO_PV_OOI, (const void*)O_RDONLY } },
{ "O_RDWR", { MOO_PV_OOI, (const void*)O_RDWR } }, { "O_RDWR", { MOO_PV_OOI, (const void*)O_RDWR } },
{ "O_TRUNC", { MOO_PV_OOI, (const void*)O_TRUNC } }, { "O_TRUNC", { MOO_PV_OOI, (const void*)O_TRUNC } },
{ "O_WRONLY", { MOO_PV_OOI, (const void*)O_WRONLY } } { "O_WRONLY", { MOO_PV_OOI, (const void*)O_WRONLY } },
{ "SEEK_CUR", { MOO_PV_OOI, (const void*)SEEK_CUR } },
{ "SEEK_END", { MOO_PV_OOI, (const void*)SEEK_SET } },
{ "SEEK_SET", { MOO_PV_OOI, (const void*)SEEK_SET } }
}; };
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */

View File

@ -176,7 +176,7 @@ static moo_pfrc_t pf_write_bytes (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
moo_oop_t tmp; moo_oop_t tmp;
tmp = MOO_STACK_GETARG(moo, nargs, 1); tmp = MOO_STACK_GETARG(moo, nargs, 1);
if (moo_inttooow (moo, tmp, &offset) <= 0) if (moo_inttooow(moo, tmp, &offset) <= 0)
{ {
moo_seterrbfmt (moo, MOO_EINVAL, "invalid offset - %O", tmp); moo_seterrbfmt (moo, MOO_EINVAL, "invalid offset - %O", tmp);
return MOO_PF_FAILURE; return MOO_PF_FAILURE;