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

📄 ejsparser.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
	sp->tid = ejsLexGetToken(ep, state);	if (sp->tid != EJS_TOK_ID) {		ejsSyntaxError(ep, 0);		goto err;	}	ejsLexPutbackToken(ep, sp->tid, ep->token);	state = ejsParse(ep, EJS_STATE_EXPR, flags);	if (state < 0) {		goto done;	}	if ((flags & EJS_FLAGS_EXE) && 			(ep->result == 0 || ep->result->type == EJS_TYPE_UNDEFINED)) {		ejsError(ep, EJS_REFERENCE_ERROR, "Can't access array or object");		goto err;	}		if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {		ejsSyntaxError(ep, 0);		goto err;	}	sp->setVar = ejsDupVar(ep, ep->result, EJS_SHALLOW_COPY);	sp->bodyScript = getInputStruct(ep);	/*	 *	Parse the body and remember the end of the body script	 */	sp->forFlags = flags & ~EJS_FLAGS_EXE;	ejsLexSaveInputState(ep, sp->bodyScript);	state = ejsParse(ep, EJS_STATE_STMT, sp->forFlags);	if (state < 0) {		goto done;	}	sp->endScript = getInputStruct(ep);	ejsInitInputState(sp->endScript);	ejsLexSaveInputState(ep, sp->endScript);	/*	 *	Enumerate the properties	 */	if (flags & EJS_FLAGS_EXE) {		if (sp->setVar->type == EJS_TYPE_OBJECT) {			sp->setVar->objectState->preventDeleteProp = 1;			sp->pp = ejsGetFirstProperty(sp->setVar, 0);			while (sp->pp) {				sp->nextp = ejsGetNextProperty(sp->pp, 0);				if (! sp->pp->dontEnumerate && !sp->pp->delayedDelete) {					if (each) {						sp->vp = ejsWriteVar(ep, sp->iteratorVar,							ejsGetVarPtr(sp->pp), EJS_SHALLOW_COPY);					} else {						sp->vp = ejsWriteVarAsString(ep, sp->iteratorVar, 							sp->pp->name);					}					if (sp->vp == 0) {						ejsError(ep, EJS_MEMORY_ERROR, 							"Can't write to variable");						goto err;					}					ejsLexRestoreInputState(ep, sp->bodyScript);					state = ejsParse(ep, EJS_STATE_STMT, flags);					if (state < 0) {						if (sp->setVar->objectState) {							sp->setVar->objectState->preventDeleteProp = 0;						}						goto done;					}				}				sp->pp = sp->nextp;			}			/*		     *	Process delayed deletes			 */			if (sp->setVar->objectState) {				sp->setVar->objectState->preventDeleteProp = 0;				if (sp->setVar->objectState->delayedDeleteProp) {					sp->pp = ejsGetFirstProperty(sp->setVar, 0);					while (sp->pp) {						sp->nextp = ejsGetNextProperty(sp->pp, 0);						if (sp->pp->delayedDelete) {							ejsDeleteProperty(ep, sp->setVar, sp->pp->name);						}						sp->pp = sp->nextp;					}					sp->setVar->objectState->delayedDeleteProp = 0;				}			}		} else {			ejsError(ep, EJS_REFERENCE_ERROR,				"Variable to iterate over is not an array or object");			goto err;		}	}	ejsLexRestoreInputState(ep, sp->endScript);done:	if (sp->endScript) {		ejsLexFreeInputState(ep, sp->endScript);		ejsLexFreeInputState(ep, sp->bodyScript);	}	if (sp->bodyScript) {		freeInputStruct(ep, sp->bodyScript);	}	if (sp->endScript) {		freeInputStruct(ep, sp->endScript);	}	if (sp->setVar) {		ejsFreeVar(ep, sp->setVar);	}	popFrame(ep, sizeof(ParseForIn));	return state;err:	state = EJS_STATE_ERR;	goto done;}/******************************************************************************//* *	Parse the for statement. Format for the expression is: * *		for (initial; condition; incr) { *			body; *		} */static int parseRegFor(Ejs *ep, int state, int flags){	EjsInput	*condScript, *endScript, *bodyScript, *incrScript;	endScript = getInputStruct(ep);	bodyScript = getInputStruct(ep);	incrScript = getInputStruct(ep);	condScript = getInputStruct(ep);	ejsInitInputState(endScript);	ejsInitInputState(bodyScript);	ejsInitInputState(incrScript);	ejsInitInputState(condScript);	state = parseForInner(ep, state, flags, 		condScript, incrScript, bodyScript, endScript);	ejsLexFreeInputState(ep, condScript);	ejsLexFreeInputState(ep, incrScript);	ejsLexFreeInputState(ep, endScript);	ejsLexFreeInputState(ep, bodyScript);	freeInputStruct(ep, condScript);	freeInputStruct(ep, incrScript);	freeInputStruct(ep, endScript);	freeInputStruct(ep, bodyScript);	return state;}/******************************************************************************/static int parseForInner(Ejs *ep, int state, int flags, EjsInput *condScript,	EjsInput *incrScript, EjsInput *bodyScript, EjsInput *endScript){	int			forFlags, cond, rs;	mprAssert(ep);	/*	 *	Evaluate the for loop initialization statement	 */	if ((state = ejsParse(ep, EJS_STATE_STMT, flags)) < 0) {		return state;	}	/*	 *	The first time through, we save the current input context just prior	 *	to each step: prior to the conditional, the loop increment and  	 *	the loop body.	 */	ejsLexSaveInputState(ep, condScript);	if ((rs = ejsParse(ep, EJS_STATE_COND, flags)) < 0) {		return rs;	}	cond = (ep->result->boolean != 0);	if (ejsLexGetToken(ep, state) != EJS_TOK_SEMI) {		ejsSyntaxError(ep, 0);		return EJS_STATE_ERR;	}	/*	 *	Don't execute the loop increment statement or the body 	 *	first time.	 */	forFlags = flags & ~EJS_FLAGS_EXE;	ejsLexSaveInputState(ep, incrScript);	if ((rs = ejsParse(ep, EJS_STATE_EXPR, forFlags)) < 0) {		return rs;	}	if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {		ejsSyntaxError(ep, 0);		return EJS_STATE_ERR;	}	/*	 *	Parse the body and remember the end of the body script	 */	ejsLexSaveInputState(ep, bodyScript);	if ((rs = ejsParse(ep, EJS_STATE_STMT, forFlags)) < 0) {		return rs;	}	ejsLexSaveInputState(ep, endScript);	/*	 *	Now actually do the for loop. Note loop has been rotated	 */	while (cond && (flags & EJS_FLAGS_EXE)) {		/*		 *	Evaluate the body		 */		ejsLexRestoreInputState(ep, bodyScript);		if ((rs = ejsParse(ep, EJS_STATE_STMT, flags)) < 0) {			return rs;		}		/*		 *	Evaluate the increment script		 */		ejsLexRestoreInputState(ep, incrScript);		if ((rs = ejsParse(ep, EJS_STATE_EXPR, flags)) < 0) {			return rs;		}		/*		 *	Evaluate the condition		 */		ejsLexRestoreInputState(ep, condScript);		if ((rs = ejsParse(ep, EJS_STATE_COND, flags)) < 0) {			return 0;		}		mprAssert(ep->result->type == EJS_TYPE_BOOL);		cond = (ep->result->boolean != 0);	}	ejsLexRestoreInputState(ep, endScript);	return state;}/******************************************************************************//* *	Create the bare class object */static int createClass(Ejs *ep, EjsVar *obj, const char *className, 	EjsVar *baseClass){	EjsVar	*classObj, *existingClass;	existingClass = ejsGetClass(ep, obj, className);	if (existingClass) {		/*		 *	We allow partial clases and method redefinition		 *	FUTURE -- should prevent this if the class is sealed.		 *	DISABLED Error message and return OK.		 */		/* ejsError(ep, EJS_EVAL_ERROR, "Can't create class %s", className); */		return 0;	}	if (baseClass == 0) {		baseClass = ejsGetClass(ep, ep->service->globalClass, "Object");		mprAssert(baseClass);	}	classObj = ejsCreateSimpleClass(ep, baseClass, className);	if (classObj == 0) {		ejsMemoryError(ep);		return -1;	}	mprAssert(! ejsObjIsCollectable(classObj));	ep->currentProperty = ejsSetPropertyAndFree(ep, obj, className, classObj);	mprAssert(ep->currentProperty);	if (ep->currentProperty == 0) {		return -1;	}	return 0;}/******************************************************************************//* *	Local vars for parseTry */typedef struct ParseTry {	EjsVar		*exception;	int			tid, caught, rs, catchFlags;} ParseTry;/* *	Parse try block * *		try {} */static int parseTry(Ejs *ep, int state, int flags){	ParseTry		*sp;	if ((sp = pushFrame(ep, sizeof(ParseTry))) == 0) {		return EJS_STATE_ERR;	}	mprAssert(ep);	sp->caught = 0;	sp->exception = 0;	sp->catchFlags = flags;	/*	 *	Execute the code in the try block	 */	sp->rs = ejsParse(ep, EJS_STATE_STMT, flags | EJS_FLAGS_TRY);	if (sp->rs < 0) {		if (sp->rs == EJS_STATE_ERR) {			sp->exception = ejsDupVar(ep, ep->result, EJS_SHALLOW_COPY);			if (sp->exception == 0) {				ejsMemoryError(ep);				goto err;			}		} else {			state = sp->rs;			goto done;		}	} else {		sp->catchFlags = flags & ~EJS_FLAGS_EXE;	}	/*	 *	On success path or when an exception is caught, we must parse all	 *	catch and finally blocks.	 */	sp->tid = getNextNonSpaceToken(ep, state);	if (sp->tid == EJS_TOK_CATCH) {		ep->gotException = 0;		sp->tid = getNextNonSpaceToken(ep, state);		if (sp->tid == EJS_TOK_LBRACE) {			/*			 *	Unqualified "catch "			 */			ejsLexPutbackToken(ep, sp->tid, ep->token);			if (ejsParse(ep, EJS_STATE_STMT, sp->catchFlags) >= 0) {				sp->caught++;			}		} else if (sp->tid == EJS_TOK_LPAREN) {			/*			 *	Qualified "catch (variable) "			 */			if ((sp->rs = ejsParse(ep, EJS_STATE_DEC_LIST, 					sp->catchFlags | EJS_FLAGS_CATCH)) < 0) {				ejsSyntaxError(ep, "Bad catch statement");				state = sp->rs;				goto done;			}			sp->tid = getNextNonSpaceToken(ep, state);			if (sp->tid != EJS_TOK_RPAREN) {				ejsSyntaxError(ep, 0);				goto err;			}			if (sp->catchFlags & EJS_FLAGS_EXE) {				if (ep->currentProperty == 0) {					ejsError(ep, EJS_EVAL_ERROR, "Can't define catch variable");					goto err;				}				/*				 *	Set the catch variable				 */				if (ejsWriteVar(ep, 						ejsGetVarPtr(ep->currentProperty), sp->exception, 						EJS_SHALLOW_COPY) == 0) {					ejsError(ep, EJS_EVAL_ERROR, "Can't update catch variable");					goto err;				}			}			/*			 * 	Parse the catch block			 */			if ((sp->rs = ejsParse(ep, EJS_STATE_STMT, sp->catchFlags)) < 0) {				state = sp->rs;				goto done;			}			sp->caught++;			ep->gotException = 0;		}		sp->tid = getNextNonSpaceToken(ep, state);	}	/*	 *	Parse the finally block	 */	if (sp->tid == EJS_TOK_FINALLY) {		if (ejsParse(ep, EJS_STATE_STMT, flags) < 0) {			goto err;		}	} else {		ejsLexPutbackToken(ep, sp->tid, ep->token);	}	/*	 *	Set the exception value	 */	if (sp->exception && !sp->caught) {		ejsWriteVar(ep, ep->result, sp->exception, EJS_SHALLOW_COPY);		goto err;	}		state = EJS_STATE_STMT_DONE;done:	if (sp->exception) {		ejsFreeVar(ep, sp->exception);	}	popFrame(ep, sizeof(ParseTry));	return state;err:	state = EJS_STATE_ERR;	goto done;}/******************************************************************************//* *	Parse throw statement * *		throw expression */static int parseThrow(Ejs *ep, int state, int flags){	int		rc;	mprAssert(ep);	if ((rc = ejsParse(ep, EJS_STATE_EXPR, flags)) < 0) {		return rc;	}	if (flags & EJS_FLAGS_EXE) {		/*		 *	We have thrown the exception so set the state to ERR 		 */		ep->gotException = 1;		return EJS_STATE_ERR;	}	return state;}/******************************************************************************//* *	Parse a class and module declaration * *		class <name> [extends baseClass] { *			[public | private | ... ] var declarations ... *			[constructor] function declarations ... *		} * *		Modules are identical except declared with a "module" instead of *		"class". Modules cannot be instantiated and are used for mixins. *	 */static int parseClass(Ejs *ep, int state, int flags){	int			originalToken, tid, fid;	mprAssert(ep);	originalToken = ep->tid;	/*	 *	Parse "class Name [extends BaseClass]"	 */	if (ejsParse(ep, EJS_STATE_DEC_LIST, flags | EJS_FLAGS_CLASS_DEC) < 0) {		return EJS_STATE_ERR;	}	tid = getNextNonSpaceToken(ep, state);	if (tid != EJS_TOK_LBRACE) {		return EJS_STATE_ERR;	}	/* 	 *	After parsing the class body, ep->local will contain the actual 	 *	class/module object. So, we save ep->local by creating a new block.	 */	if (flags & EJS_FLAGS_EXE) {		fid = ejsSetBlock(ep, ejsGetVarPtr(ep->currentProperty));		ejsSetVarName(ep, ep->local, ep->currentProperty->name);	} else {		fid = -1;	}	/* FUTURE -- should prevent modules from being instantiated */	/*	 *	Parse class body	 */	do {		state = ejsParse(ep, EJS_STATE_STMT, flags);		if (state < 0) {			if (fid >= 0) {				ejsCloseBlock(ep, fid);			}			return state;		}		tid = getNextNonSpaceToken(ep, state);		if (tid == EJS_TOK_RBRACE) {			break;		}		ejsLexPutbackToken(ep, tid, ep->token);	} while (state >= 0);	if (fid >= 0) {		ejsCloseBlock(ep, fid);	}	if (tid != EJS_TOK_RBRACE) {		ejsSyntaxError(ep, 0);		state = EJS_STATE_ERR;	}	return state;}/******************************************************************************/

⌨️ 快捷键说明

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