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:
parent
044177fa61
commit
b5b72c626c
@ -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
|
||||||
|
@ -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).
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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];
|
||||||
|
}
|
||||||
|
|
||||||
/* if the token is out of the SMOOI range, it's too big or
|
else if (string_to_smooi(moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADINTLIT, &tmp) <= -1)
|
||||||
* to small to be a byte */
|
{
|
||||||
moo_setsynerr (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
/* the token reader reads a valid token. no other errors
|
||||||
goto oops;
|
* 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
|
||||||
|
* to small to be a byte */
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
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)
|
||||||
|
@ -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 } }
|
||||||
};
|
};
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user