From 3874483b23dae715d9e43aea5d81640726fdc10c Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Sat, 26 Oct 2019 02:04:36 +0000 Subject: [PATCH] enhanced the array literal reader to allow a comma if used after the first element --- moo/kernel/IO.moo | 12 ++- moo/kernel/generr.moo | 236 +++++++++++++++++++++--------------------- moo/lib/comp.c | 64 ++++++++++-- moo/mod/io-file.c | 9 +- 4 files changed, 191 insertions(+), 130 deletions(-) diff --git a/moo/kernel/IO.moo b/moo/kernel/IO.moo index a74e4d5..4f4fbfa 100644 --- a/moo/kernel/IO.moo +++ b/moo/kernel/IO.moo @@ -13,9 +13,15 @@ class FileAccessor(InputOutputStud) from "io.file" { //O_RDONLY := 0, //O_WRONLY := 1 - O_RDONLY from "O_RDONLY", - O_WRONLY from "O_WRONLY", - O_RDWR from "O_RDWR" + 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_RDWR from "O_RDWR", + O_TRUNC from "O_TRUNC", + O_WRONLY from "O_WRONLY" } method(#primitive,#lenient) _open: path flags: flags. diff --git a/moo/kernel/generr.moo b/moo/kernel/generr.moo index 9efe469..5dfd2b2 100644 --- a/moo/kernel/generr.moo +++ b/moo/kernel/generr.moo @@ -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. } diff --git a/moo/lib/comp.c b/moo/lib/comp.c index f091714..f6227e4 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -5386,26 +5386,72 @@ 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) { - 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) + { + 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; } - else if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) break; - - lit = token_to_literal(moo, rdonly); - if (!lit || add_to_array_literal_buffer(moo, lit) <= -1) goto oops; - - GET_TOKEN_GOTO (moo, oops); } - while (1); a = moo_instantiate(moo, moo->_array, MOO_NULL, moo->c->arlit.count - saved_arlit_count); if (!a) goto oops; diff --git a/moo/mod/io-file.c b/moo/mod/io-file.c index 44c99a2..6677771 100644 --- a/moo/mod/io-file.c +++ b/moo/mod/io-file.c @@ -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) } }, }; /* ------------------------------------------------------------------------ */