enhanced the array literal reader to allow a comma if used after the first element
This commit is contained in:
		| @ -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. | ||||
|  | ||||
| @ -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. | ||||
| 	} | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
|  | ||||
| @ -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) } }, | ||||
| }; | ||||
| /* ------------------------------------------------------------------------ */ | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user