⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ejsparser.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
		case EJS_TOK_COMMA:			ejsLexPutbackToken(ep, sp->tid, ep->token);			goto done;		case EJS_TOK_LPAREN:			if (state == EJS_STATE_EXPR) {				if ((sp->rs = ejsParse(ep, EJS_STATE_RELEXP, flags)) < 0) {					state = sp->rs;					goto done;				}				if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {					ejsSyntaxError(ep, 0);					goto err;				}				goto done;			} else if (state == EJS_STATE_STMT) {				ejsLexPutbackToken(ep, EJS_TOK_METHOD_NAME, ep->token);			}			break;		case EJS_TOK_RPAREN:			ejsLexPutbackToken(ep, sp->tid, ep->token);			goto done;		case EJS_TOK_EXTENDS:			if (! (flags & EJS_FLAGS_CLASS_DEC)) {				ejsSyntaxError(ep, 0);				goto err;			}			sp->saveObj = ep->currentObj;			sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1);						sp->rs = ejsParse(ep, EJS_STATE_STMT, flags);			ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm);			if (sp->rs < 0) {				state = sp->rs;				goto done;			}			if (flags & EJS_FLAGS_EXE) {				if (createClass(ep, sp->saveObj, sp->id, 						ejsGetVarPtr(ep->currentProperty)) < 0) {					goto err;				}			}			if (ejsLexGetToken(ep, state) != EJS_TOK_LBRACE) {				ejsSyntaxError(ep, 0);				goto err;			}			ejsLexPutbackToken(ep, ep->tid, ep->token);			goto done;		case EJS_TOK_LBRACE:			if (flags & EJS_FLAGS_CLASS_DEC) {				if (state == EJS_STATE_DEC) {					if (flags & EJS_FLAGS_EXE) {						if (createClass(ep, ep->currentObj, sp->id, 0) < 0) {							goto err;						}					}					ejsLexPutbackToken(ep, sp->tid, ep->token);				} else if (state == EJS_STATE_STMT) {					ejsLexPutbackToken(ep, sp->tid, ep->token);				}				goto done;			}			/*			 *	This handles any code in braces except "if () {} else {}"			 */			if (state != EJS_STATE_STMT) {				ejsSyntaxError(ep, 0);				goto err;			}			/*			 *	Parse will return EJS_STATE_STMT_BLOCK_DONE when the RBRACE 			 *	is seen.			 */			sp->exception = 0;			do {				state = ejsParse(ep, EJS_STATE_STMT, flags);				if (state == EJS_STATE_ERR) {					/*					 *	We need to keep parsing to get to the end of the block					 */					if (sp->exception == 0) {						sp->exception = ejsDupVar(ep, ep->result, 								EJS_SHALLOW_COPY);						if (sp->exception == 0) {							ejsMemoryError(ep);							goto err;						}						if (sp->exception->type == EJS_TYPE_OBJECT) {							ejsMakeObjLive(sp->exception, 0);							mprAssert(sp->exception->objectState->alive == 0);						}						/*						 *	If we're in a try block, we need to keep parsing						 *	so we can find the end of the block and the start						 *	of the catch block. Otherwise, we are done.						 */						if (!(flags & EJS_FLAGS_TRY)) {							break;						}					}					flags &= ~EJS_FLAGS_EXE;					if (ep->recurseCount > 20) {						break;					}					state = EJS_STATE_STMT_DONE;					ep->gotException = 0;				}			} while (state == EJS_STATE_STMT_DONE);			if (sp->exception) {				ep->gotException = 1;				ejsWriteVar(ep, ep->result, sp->exception, EJS_SHALLOW_COPY);				/* Eat the closing brace */				ejsLexGetToken(ep, state);				ejsFreeVar(ep, sp->exception);				goto err;			}			ejsFreeVar(ep, sp->exception);			if (state < 0) {				goto done;			}			if (ejsLexGetToken(ep, state) != EJS_TOK_RBRACE) {				ejsSyntaxError(ep, 0);				goto err;			}			state = EJS_STATE_STMT_DONE;			goto done;		case EJS_TOK_RBRACE:			if (state == EJS_STATE_STMT) {				ejsLexPutbackToken(ep, sp->tid, ep->token);				state = EJS_STATE_STMT_BLOCK_DONE;							} else if (state == EJS_STATE_EXPR) {				ejsLexPutbackToken(ep, sp->tid, ep->token);				state = EJS_STATE_EXPR;			} else {				ejsSyntaxError(ep, 0);				state = EJS_STATE_ERR;			}			goto done;		case EJS_TOK_RETURN:			if ((sp->rs = ejsParse(ep, EJS_STATE_RELEXP, flags)) < 0) {				state = sp->rs;				goto done;			}			if (flags & EJS_FLAGS_EXE) {				state = EJS_STATE_RET;				goto done;			}			break;		}	}done:	mprFree(sp->id);	if (sp->expectEndOfStmt && state >= 0) {		sp->tid = ejsLexGetToken(ep, state);		if (sp->tid == EJS_TOK_RBRACE) {			ejsLexPutbackToken(ep, EJS_TOK_RBRACE, ep->token);		} else if (sp->tid != EJS_TOK_SEMI && sp->tid != EJS_TOK_NEWLINE && 				sp->tid != EJS_TOK_EOF) {			ejsSyntaxError(ep, 0);			state = EJS_STATE_ERR;		} else {			/*			 *	Skip newlines after semi-colon			 */			removeNewlines(ep, state);		}	}	/*	 *	Advance the state	 */	switch (state) {	case EJS_STATE_STMT:	case EJS_STATE_STMT_DONE:		state = EJS_STATE_STMT_DONE;		break;	case EJS_STATE_DEC:	case EJS_STATE_DEC_DONE:		state = EJS_STATE_DEC_DONE;		break;	case EJS_STATE_EXPR:	case EJS_STATE_EXPR_DONE:		state = EJS_STATE_EXPR_DONE;		break;	case EJS_STATE_STMT_BLOCK_DONE:	case EJS_STATE_EOF:	case EJS_STATE_RET:		break;	default:		if (state != EJS_STATE_ERR) {			ejsSyntaxError(ep, 0);		}		state = EJS_STATE_ERR;	}	popFrame(ep, sizeof(ParseStmt));	return state;err:	state = EJS_STATE_ERR;	goto done;}/******************************************************************************//* *	Local vars  */typedef struct ParseFor {	char		*initToken;	int 		tid, foundVar, initId, each;} ParseFor;/* *	Parse method arguments */static int parseFor(Ejs *ep, int state, int flags){	ParseFor		*sp;	if ((sp = pushFrame(ep, sizeof(ParseFor))) == 0) {		return EJS_STATE_ERR;	}	mprAssert(ep);	if (state != EJS_STATE_STMT) {		ejsSyntaxError(ep, 0);		goto err;	}	if ((sp->tid = ejsLexGetToken(ep, state)) == EJS_TOK_EACH) {		sp->each = 1;		sp->tid = ejsLexGetToken(ep, state);	} else {		sp->each = 0;	}	if (sp->tid != EJS_TOK_LPAREN) {		ejsSyntaxError(ep, 0);		goto err;	}	/*	 *	Need to peek 2-3 tokens ahead and see if this is a 	 *		for [each] ([var] x in set) 	 *	or	 *		for (init ; whileCond; incr)	 */	sp->initId = ejsLexGetToken(ep, EJS_STATE_EXPR);	sp->foundVar = 0;	if (sp->initId == EJS_TOK_ID && strcmp(ep->token, "var") == 0) {		sp->foundVar = 1;		sp->initId = ejsLexGetToken(ep, EJS_STATE_EXPR);	}	sp->initToken = mprStrdup(ep, ep->token);	sp->tid = ejsLexGetToken(ep, EJS_STATE_EXPR);	ejsLexPutbackToken(ep, sp->tid, ep->token);	ejsLexPutbackToken(ep, sp->initId, sp->initToken);	mprFree(sp->initToken);	if (sp->foundVar) {		ejsLexPutbackToken(ep, EJS_TOK_ID, "var");	}	if (sp->tid == EJS_TOK_IN) {		state = parseForIn(ep, state, flags, sp->each);	} else {		state = parseRegFor(ep, state, flags);	}done:	popFrame(ep, sizeof(ParseFor));	return state;err:	state = EJS_STATE_ERR;	goto done;}/******************************************************************************//* *	Parse method arguments */static int parseArgs(Ejs *ep, int state, int flags){	EjsVar		*vp;	int			tid;	mprAssert(ep);	do {		/*		 *	Peek and see if there are no args		 */		tid = ejsLexGetToken(ep, state);		ejsLexPutbackToken(ep, tid, ep->token);		if (tid == EJS_TOK_RPAREN) {			break;		}		/*		 *	If this is part of a constructor, must run methods in args normally  		 */		flags &= ~EJS_FLAGS_NEW;		state = ejsParse(ep, EJS_STATE_RELEXP, flags);		if (state < 0) {			return state;		}		if (flags & EJS_FLAGS_EXE) {			mprAssert(ep->proc->args);			vp = ejsDupVar(ep, ep->result, EJS_SHALLOW_COPY);			if (vp == 0) {				ejsMemoryError(ep);				return EJS_STATE_ERR;			}			/* MOB */			if (vp->type == EJS_TYPE_OBJECT) {				ejsMakeObjLive(vp, 0);				mprAssert(vp->objectState->alive == 0);			}			/*			 *	Propagate the name			 */			ejsSetVarName(ep, vp, ep->result->propertyName);			mprAddItem(ep->proc->args, vp);		}		/*		 *	Peek at the next token, continue if more args (ie. comma seen)		 */		tid = ejsLexGetToken(ep, state);		if (tid != EJS_TOK_COMMA) {			ejsLexPutbackToken(ep, tid, ep->token);		}	} while (tid == EJS_TOK_COMMA);	if (tid != EJS_TOK_RPAREN && state != EJS_STATE_RELEXP_DONE) {		ejsSyntaxError(ep, 0);		return EJS_STATE_ERR;	}	return EJS_STATE_ARG_LIST_DONE;}/******************************************************************************//* *	Local vars  */typedef struct ParseAssign {	EjsProperty		*saveProperty;	EjsVar			*saveObj;	int				saveObjPerm, savePropPerm, rc;} ParseAssign;/* *	Parse an assignment statement */static int parseAssignment(Ejs *ep, int state, int flags, char *id){	ParseAssign		*sp;	if (id == 0) {		if (!ep->gotException) {			ejsSyntaxError(ep, 0);		}		return EJS_STATE_ERR;	}	if ((sp = pushFrame(ep, sizeof(ParseAssign))) == 0) {		return EJS_STATE_ERR;	}	mprAssert(ep->currentObj);	/*	 *	Parse the right hand side of the "="	 */	sp->saveObj = ep->currentObj;	sp->saveProperty = ep->currentProperty;	sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1);	sp->savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(sp->saveProperty), 1);	sp->rc = ejsParse(ep, EJS_STATE_RELEXP, flags | EJS_FLAGS_ASSIGNMENT);		ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm);	ejsMakeObjPermanent(ejsGetVarPtr(sp->saveProperty), sp->savePropPerm);	if (sp->rc < 0) {		state = EJS_STATE_ERR;	}	ep->currentObj = sp->saveObj;	ep->currentProperty = sp->saveProperty;	popFrame(ep, sizeof(ParseAssign));	if (! (flags & EJS_FLAGS_EXE)) {		return state;	}	return state;}/******************************************************************************/static int assignPropertyValue(Ejs *ep, char *id, int state, EjsVar *value, 	int flags){	EjsProperty		*saveProperty;	EjsVar			*saveObj, *obj, *vp;	char			*procName;	int				saveObjPerm, savePropPerm, rc;	mprAssert(flags & EJS_FLAGS_EXE);	if (ep->currentProperty && 			!ep->currentProperty->var.flags & EJS_GET_ACCESSOR) {		obj = ep->currentObj;	} else {		/*		 *	Handle any set accessors.		 *	FUTURE OPT -- could be faster		 * 	FUTURE OPT -- coming here even when doing just a set "x = value";		 */		procName = 0;		if (mprAllocStrcat(MPR_LOC_ARGS(ep), &procName, EJS_MAX_ID + 5, 0, 				"-set-", id, 0) > 0) {			MprArray	*args;			ep->currentProperty = searchSpacesForProperty(ep, state, 				ep->currentObj, procName, flags);			if (ep->currentProperty) {				args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS);				vp = ejsDupVar(ep, value, EJS_SHALLOW_COPY);				mprAddItem(args, vp);				mprAssert(! ejsObjIsCollectable(vp));				saveObj = ep->currentObj;				saveProperty = ep->currentProperty;				saveObjPerm = ejsMakeObjPermanent(saveObj, 1);				savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), 					1);				/*				 *	Invoke the set accessor			 	 */				rc = ejsRunMethod(ep, ep->currentObj, procName, args);				mprFree(procName);				ejsFreeMethodArgs(ep, args);				ejsMakeObjPermanent(saveObj, saveObjPerm);				ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), savePropPerm);				ep->currentObj = saveObj;				ep->currentProperty = saveProperty;				if (rc < 0) {					return EJS_STATE_ERR;				}				return state;			}			mprFree(procName);		}		if (ep->currentProperty == 0) {			/*			 *	MOB -- can we omit this as updateProperty below will create			 */			if (createProperty(ep, &obj, id, state) < 0) {				return EJS_STATE_ERR;			}		}	}	if (updateProperty(ep, obj, id, state, value) < 0) {		return EJS_STATE_ERR;	}	vp = ejsGetVarPtr(ep->currentProperty);	if (vp->type == EJS_TYPE_OBJECT) {		ejsMakeObjLive(vp, 1);	}	return state;}/******************************************************************************/static int parseObjectLiteral(Ejs *ep, int state, int flags, char *id){	EjsProperty		*saveProperty;	EjsVar			*saveObj;	EjsVar			*obj;	char			*name;	int				saveObjPerm, savePropPerm, tid;	name = 0;	saveObj = ep->currentObj;	saveProperty = ep->currentProperty;	saveObjPerm = ejsMakeObjPermanent(saveObj, 1);	savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), 1);	if (flags & EJS_FLAGS_EXE) {		obj = ejsCreateSimpleObj(ep, "Object");		if (obj == 0) {			ejsMemoryError(ep);			goto err;		}		mprAssert(! ejsObjIsCollectable(obj));	} else {		obj = 0;	}	do {		tid = getNextNonSpaceToken(ep, state);		if (tid != EJS_TOK_ID) {			ejsSyntaxError(ep, 0);			goto err;		}		name = mprStrdup(ep, ep->token);		tid = getNextNonSpaceToken(ep, state);		if (tid != EJS_TOK_COLON) {			ejsSyntaxError(ep, 0);			goto err;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -