enhanced the array literal reader to allow a comma if used after the first element

This commit is contained in:
hyunghwan.chung 2019-10-26 02:04:36 +00:00
parent 6a80f08bae
commit 3874483b23
4 changed files with 191 additions and 130 deletions

View File

@ -13,9 +13,15 @@ class FileAccessor(InputOutputStud) from "io.file"
{
//O_RDONLY := 0,
//O_WRONLY := 1
O_CLOEXEC from "O_CLOEXEC",
O_CREAT from "O_CREAT",
O_EXCL from "O_EXCL",
O_NOFOLLOW from "O_NOFOLLOW",
O_NONBLOCK from "O_NONBLOCK",
O_RDONLY from "O_RDONLY",
O_WRONLY from "O_WRONLY",
O_RDWR from "O_RDWR"
O_RDWR from "O_RDWR",
O_TRUNC from "O_TRUNC",
O_WRONLY from "O_WRONLY"
}
method(#primitive,#lenient) _open: path flags: flags.

View File

@ -7,132 +7,134 @@ class MyObject(Object)
| errmsgs synerrmsgs f |
errmsgs := #(
'no error'
'generic error'
"no error"
"generic error"
'not implemented'
'subsystem error'
'internal error that should never have happened'
'insufficient system memory'
'insufficient object memory'
'invalid class/type'
"not implemented"
"subsystem error"
"internal error that should never have happened"
"insufficient system memory"
"insufficient object memory"
"invalid class/type"
'invalid parameter or argument'
'data not found'
'existing/duplicate data'
'busy'
'access denied'
'operation not permitted'
'not directory'
'interrupted'
'pipe error'
'resource temporarily unavailable'
'bad system handle'
"invalid parameter or argument"
"data not found"
"existing/duplicate data"
"busy"
"access denied"
"operation not permitted"
"not directory"
"interrupted"
"pipe error"
"resource temporarily unavailable"
"bad system handle"
'*** undefined error ***'
'message receiver error'
'message sending error'
'wrong number of arguments'
'range error'
'byte-code full'
'dictionary full'
'processor full'
'too many semaphores'
'*** undefined error ***'
'divide by zero'
'I/O error'
'encoding conversion error'
'insufficient data for encoding conversion'
'buffer full'
"*** undefined error ***"
"message receiver error"
"message sending error"
"wrong number of arguments"
"range error"
"byte-code full"
"dictionary full"
"processor full"
"too many semaphores"
"*** undefined error ***"
"divide by zero"
"I/O error"
"encoding conversion error"
"insufficient data for encoding conversion"
"buffer full"
).
synerrmsgs := #(
'no error'
'illegal character'
'comment not closed'
'string not closed'
'no character after $'
'no valid character after #'
'no valid character after #\'
'wrong character literal'
'colon expected'
'string expected'
'invalid radix'
'invalid integer literal'
'invalid fixed-point decimal scale'
'invalid fixed-point decimal literal'
'byte too small or too large'
'wrong error literal'
'wrong smptr literal'
'{ expected'
'} expected'
'( expected'
') expected'
'] expected'
'. expected'
', expected'
'| expected'
'> expected'
':= expected'
'identifier expected'
'integer expected'
'primitive: expected'
'wrong directive'
'wrong name'
'duplicate name'
'undefined name'
'contradictory class definition'
'class not conforming to interface'
'invalid non-pointer instance size'
'prohibited inheritance'
'variable declaration not allowed'
'modifier expected'
'wrong modifier'
'disallowed modifier'
'duplicate modifier'
'method name expected'
'duplicate method name'
'invalid variadic method definition'
'variable name expected'
'duplicate argument name'
'duplicate temporary variable name'
'duplicate variable name'
'duplicate block argument name'
'undeclared variable'
'unusable variable in compiled code'
'inaccessible variable'
'ambiguous variable'
'too many instance/class variables'
'inaccessible super'
'wrong expression primary'
'too many temporaries'
'too many arguments'
'too many block temporaries'
'too many block arguments'
'array expression too large'
'instruction data too large'
'wrong primitive function number'
'wrong primitive function identifier'
'wrong primitive function argument definition'
'failed to import module'
'#include error'
'wrong pragma name'
'wrong namespace name'
'wrong pooldic import name'
'duplicate pooldic import name'
'literal expected'
'break or continue not within a loop'
'break or continue within a block'
'while expected'
'invalid goto target'
'label at end'
"no error"
"illegal character"
"comment not closed"
"string not closed"
"no character after $"
"no valid character after #"
"no valid character after #\\"
"wrong character literal"
"colon expected"
"string expected"
"invalid radix"
"invalid integer literal"
"invalid fixed-point decimal scale"
"invalid fixed-point decimal literal"
"byte too small or too large"
"wrong error literal"
"wrong smptr literal"
"{ expected"
"} expected"
"( expected"
") expected"
"] expected"
". expected"
", expected"
"| expected"
"> expected"
":= expected"
"identifier expected"
"integer expected"
"primitive: expected"
"wrong directive"
"wrong name"
"duplicate name"
"undefined name"
"contradictory class definition"
"class not conforming to interface"
"invalid non-pointer instance size"
"prohibited inheritance"
"variable declaration not allowed"
"modifier expected"
"wrong modifier"
"disallowed modifier"
"duplicate modifier"
"method name expected"
"duplicate method name"
"invalid variadic method definition"
"variable name expected"
"duplicate argument name"
"duplicate temporary variable name"
"duplicate variable name"
"duplicate block argument name"
"undeclared variable"
"unusable variable in compiled code"
"inaccessible variable"
"ambiguous variable"
"too many instance/class variables"
"inaccessible super"
"wrong expression primary"
"too many temporaries"
"too many arguments"
"too many block temporaries"
"too many block arguments"
"array expression too large"
"instruction data too large"
"wrong primitive function number"
"wrong primitive function identifier"
"wrong primitive function argument definition"
"wrong primitive value identifier"
"primitive value load from module not allowed"
"failed to import module"
"#include error"
"wrong pragma name"
"wrong namespace name"
"wrong pooldic import name"
"duplicate pooldic import name"
"literal expected"
"break or continue not within a loop"
"break or continue within a block"
"while expected"
"invalid goto target"
"label at end"
).
f := Stdio open: 'generr.out' for: 'w'.
[ f isError ] ifTrue: [ System logNl: 'Cannot open generr.out'. thisProcess terminate. ].
f := Stdio open: "generr.out" for: "w".
[ f isError ] ifTrue: [ System logNl: "Cannot open generr.out". thisProcess terminate. ].
self emitMessages: errmsgs named: 'errstr' on: f.
self emitMessages: synerrmsgs named: 'synerrstr' on: f.
self emitMessages: errmsgs named: "errstr" on: f.
self emitMessages: synerrmsgs named: "synerrstr" on: f.
f close.
}

View File

@ -5386,27 +5386,73 @@ static int read_array_literal (moo_t* moo, int rdonly, moo_oop_t* xlit)
{
moo_oop_t lit, a;
moo_oow_t i, j, saved_arlit_count;
int comma_used = -1; /* unknown */
saved_arlit_count = moo->c->arlit.count;
GET_TOKEN_GOTO (moo, oops); /* skip #( */
do
{
if (TOKEN_TYPE(moo) == MOO_IOTOK_EOF)
{
moo_setsynerr (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops;
}
else if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) break;
else if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN)
{
do
{
lit = token_to_literal(moo, rdonly);
if (!lit || add_to_array_literal_buffer(moo, lit) <= -1) goto oops;
GET_TOKEN_GOTO (moo, oops);
if (TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) break;
if (comma_used == -1)
{
/* check if a comma has been used after the first element */
if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA)
{
comma_used = 1;
goto literal_expected_after_comma;
}
else
{
comma_used = 0;
if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN || TOKEN_TYPE(moo) == MOO_IOTOK_EOF) break;
}
}
else if (comma_used == 0)
{
/* a comma is not expected. stop if EOF or ) is encountered */
if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN || TOKEN_TYPE(moo) == MOO_IOTOK_EOF) break;
}
else if (comma_used == 1)
{
/* a comma is expected */
if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA)
{
moo_setsynerr (moo, MOO_SYNERR_COMMA, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops;
}
literal_expected_after_comma:
GET_TOKEN_GOTO (moo, oops);
if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN || TOKEN_TYPE(moo) == MOO_IOTOK_EOF)
{
moo_setsynerr (moo, MOO_SYNERR_LITERAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops;
}
}
}
while (1);
if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN)
{
moo_setsynerr (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops;
}
}
a = moo_instantiate(moo, moo->_array, MOO_NULL, moo->c->arlit.count - saved_arlit_count);
if (!a) goto oops;

View File

@ -59,6 +59,8 @@ static moo_pfrc_t pf_open_file (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
flags = MOO_STACK_GETARG(moo, nargs, 1);
mode = (nargs < 3)? MOO_SMOOI_TO_OOP(0644): MOO_STACK_GETARG(moo, nargs, 2);
/* TODO: always set O_LARGEFILE on flags if necessary */
MOO_PF_CHECK_ARGS (moo, nargs, MOO_OBJ_IS_CHAR_POINTER(path) && MOO_OOP_IS_SMOOI(flags) && MOO_OOP_IS_SMOOI(mode));
MOO_PF_CHECK_ARGS (moo, nargs, moo_count_oocstr(MOO_OBJ_GET_CHAR_SLOT(path)) == MOO_OBJ_GET_SIZE(path));
@ -124,10 +126,15 @@ static moo_pfinfo_t pfinfos[] =
static moo_pvinfo_t pvinfos[] =
{
{ "O_CLOEXEC", { MOO_PV_INT, MOO_BQ(O_CLOEXEC) } },
{ "O_CREAT", { MOO_PV_INT, MOO_BQ(O_CREAT) } },
{ "O_EXCL", { MOO_PV_INT, MOO_BQ(O_EXCL) } },
{ "O_NOFOLLOW", { MOO_PV_INT, MOO_BQ(O_NOFOLLOW) } },
{ "O_NONBLOCK", { MOO_PV_INT, MOO_BQ(O_NONBLOCK) } },
{ "O_RDONLY", { MOO_PV_INT, MOO_BQ(O_RDONLY) } },
{ "O_RDWR", { MOO_PV_INT, MOO_BQ(O_RDWR) } },
{ "O_WRONLY", { MOO_PV_INT, MOO_BQ(O_WRONLY) } }
{ "O_TRUNC", { MOO_PV_INT, MOO_BQ(O_TRUNC) } },
{ "O_WRONLY", { MOO_PV_INT, MOO_BQ(O_WRONLY) } },
};
/* ------------------------------------------------------------------------ */