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

📄 ejsparser.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		if (flags & EJS_FLAGS_EXE) {			/* FUTURE OPT -- can we optimize this. We are double accessing id 				with the Put below. Should we be using this or ejsSetProperty			 */			if (ejsCreatePropertyMethod(ep, obj, name) == 0) {				ejsMemoryError(ep);				goto err;			}		}		if (ejsParse(ep, EJS_STATE_RELEXP, flags) < 0) {			goto err;		}		if (flags & EJS_FLAGS_EXE) {			if (ejsSetPropertyMethod(ep, obj, name, ep->result) == 0) {				ejsMemoryError(ep);				goto err;			}		}		mprFree(name);		name = 0;		tid = getNextNonSpaceToken(ep, state);	} while (tid == EJS_TOK_COMMA);	if (tid != EJS_TOK_RBRACE) {		ejsSyntaxError(ep, 0);		goto err;	}	if (flags & EJS_FLAGS_EXE) {		ejsMakeObjLive(obj, 1);		ejsWriteVar(ep, ep->result, obj, EJS_SHALLOW_COPY);	}done:	ejsMakeObjPermanent(saveObj, saveObjPerm);	ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), savePropPerm);	ep->currentObj = saveObj;	ep->currentProperty = saveProperty;	if (obj) {		ejsFreeVar(ep, obj);	}	return state;err:	mprFree(name);	state = EJS_STATE_ERR;	goto done;}/******************************************************************************/static int parseArrayLiteral(Ejs *ep, int state, int flags, char *id){	EjsProperty		*saveProperty;	EjsVar			*saveObj;	EjsVar			*obj;	int				saveObjPerm, savePropPerm, tid;	saveObj = ep->currentObj;	saveProperty = ep->currentProperty;	saveObjPerm = ejsMakeObjPermanent(saveObj, 1);	savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), 1);	if (flags & EJS_FLAGS_EXE) {		obj = ejsCreateArray(ep, 0);		if (obj == 0) {			ejsMemoryError(ep);			goto err;		}		mprAssert(! ejsObjIsCollectable(obj));	} else {		obj = 0;	}	do {		if (ejsParse(ep, EJS_STATE_RELEXP, flags) < 0) {			goto err;		}		if (flags & EJS_FLAGS_EXE) {			/* MOB _- should this be put[array.length] */			if (ejsAddArrayElt(ep, obj, ep->result, EJS_SHALLOW_COPY) == 0) {				goto err;			}		}		tid = getNextNonSpaceToken(ep, state);	} while (tid == EJS_TOK_COMMA);	if (tid != EJS_TOK_RBRACKET) {		ejsSyntaxError(ep, "Missing right bracket");		goto err;	}	if (flags & EJS_FLAGS_EXE) {		ejsMakeObjLive(obj, 1);		ejsWriteVar(ep, ep->result, obj, EJS_SHALLOW_COPY);	}done:	ejsMakeObjPermanent(saveObj, saveObjPerm);	ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), savePropPerm);	ep->currentObj = saveObj;	ep->currentProperty = saveProperty;	ejsFreeVar(ep, obj);	return state;err:	state = EJS_STATE_ERR;	goto done;}/******************************************************************************//* *	Create a property.  *//*MOB -- simplify this. Enforce ep->currentObj to be always set.Then we can delete this and just call 	ejsCreatePropertyMethod(ep->currentObj, id);*///XXstatic int createProperty(Ejs *ep, EjsVar **objp, const char *id, int state){	EjsVar	*obj, *vp;	mprAssert(id && *id);	mprAssert(objp);	/*	 *	Determine the variable scope to use for the property.	 *	Standard says: "var x" means declare locally.	 *	"x = 2" means declare globally if x is undefined.	 */	if (ep->currentObj) {		if (ep->currentObj->type != EJS_TYPE_OBJECT) {			ejsSyntaxError(ep, "Reference is not an object");			return EJS_STATE_ERR;		}		obj = ep->currentObj;	} else {		/* MOB -- we should never be doing this here. ep->currentObj should			always be set already */		obj = (state == EJS_STATE_DEC) ? ep->local : ep->global;	}	mprAssert(obj);	vp = ejsCreatePropertyMethod(ep, obj, id);	if (vp == 0) {		if (!ep->gotException) {			ejsMemoryError(ep);		}		return EJS_STATE_ERR;	}	*objp = obj;	return state;}/******************************************************************************//* *	Update a property.  * *	Return with ep->currentProperty updated to point to the property. */static int updateProperty(Ejs *ep, EjsVar *obj, const char *id, int state,	EjsVar *value){	EjsVar	*vp;	/*  	 *	MOB -- do ready-only check here	 */	vp = ejsSetPropertyMethod(ep, obj, id, value);	if (vp == 0) {		ejsMemoryError(ep);		return EJS_STATE_ERR;	}	ep->currentProperty = ejsGetPropertyPtr(vp);	obj->objectState->dirty = 1;	return state;}/******************************************************************************//* *	Local vars  */typedef struct ParseCond {	EjsVar		lhs, rhs;	int			tid, operator;} ParseCond;/* *	Parse conditional expression (relational ops separated by ||, &&) */static int parseCond(Ejs *ep, int state, int flags){	ParseCond		*sp;	if ((sp = pushFrame(ep, sizeof(ParseCond))) == 0) {		return EJS_STATE_ERR;	}	mprAssert(ep);	if (flags & EJS_FLAGS_EXE) {		ejsClearVar(ep, ep->result);	}	sp->lhs.type = sp->rhs.type = EJS_TYPE_UNDEFINED;	sp->lhs.objectState = sp->rhs.objectState = 0;	sp->lhs.allocatedData = sp->rhs.allocatedData = 0;	ejsSetVarName(ep, &sp->lhs, "lhs");	ejsSetVarName(ep, &sp->rhs, "rhs");	sp->operator = 0;	do {		/*		 *	Recurse to handle one side of a conditional. Accumulate the		 *	left hand side and the final result in ep->result.		 */		state = ejsParse(ep, EJS_STATE_RELEXP, flags);		if (state < 0) {			break;		}		if (flags & EJS_FLAGS_EXE) {			if (sp->operator > 0) {				/*				 * 	FUTURE -- does not do precedence				 */ 				ejsWriteVar(ep, &sp->rhs, ep->result, EJS_SHALLOW_COPY);				if (evalCond(ep, &sp->lhs, sp->operator, &sp->rhs) < 0) {					state = EJS_STATE_ERR;					break;				}				/* Result left in ep->result */				/* MOB */				if (sp->lhs.type == EJS_TYPE_OBJECT) {					mprAssert(sp->lhs.objectState->alive == 0);				}				if (sp->rhs.type == EJS_TYPE_OBJECT) {					mprAssert(sp->rhs.objectState->alive == 0);				}			}		}		sp->tid = ejsLexGetToken(ep, state);		if (sp->tid == EJS_TOK_LOGICAL) {			sp->operator = (int) *ep->token;		} else if (sp->tid == EJS_TOK_RPAREN || sp->tid == EJS_TOK_SEMI) {			ejsLexPutbackToken(ep, sp->tid, ep->token);			state = EJS_STATE_COND_DONE;			break;		} else {			ejsLexPutbackToken(ep, sp->tid, ep->token);		}		if (flags & EJS_FLAGS_EXE) {			ejsWriteVar(ep, &sp->lhs, ep->result, EJS_SHALLOW_COPY);		}	} while (state == EJS_STATE_RELEXP_DONE);	ejsClearVar(ep, &sp->lhs);	ejsClearVar(ep, &sp->rhs);	popFrame(ep, sizeof(ParseCond));	return state;}/******************************************************************************//* *	Parse variable declaration list. Declarations can be of the following forms: *		var x; *		var x, y, z; *		var x = 1 + 2 / 3, y = 2 + 4; *		var x = { property: value, property: value ... }; *		var x = [ property: value, property: value ... ]; * *	We set the variable to NULL if there is no associated assignment. */static int parseDeclaration(Ejs *ep, int state, int flags){	int		tid;	mprAssert(ep);	do {		if ((tid = ejsLexGetToken(ep, state)) != EJS_TOK_ID) {			ejsSyntaxError(ep, 0);			return EJS_STATE_ERR;		}		ejsLexPutbackToken(ep, tid, ep->token);		/*		 *	Parse the entire assignment or simple identifier declaration		 */		if (ejsParse(ep, EJS_STATE_DEC, flags) != EJS_STATE_DEC_DONE) {			return EJS_STATE_ERR;		}		/*		 *	Peek at the next token, continue if comma seen		 *	Stop on ";" or "in" which is used in a "for (var x in ..."		 */		tid = ejsLexGetToken(ep, state);		if (tid == EJS_TOK_SEMI) {			return EJS_STATE_DEC_LIST_DONE;		} else if (tid == EJS_TOK_IN) {			ejsLexPutbackToken(ep, tid, ep->token);			return EJS_STATE_DEC_LIST_DONE;		} else if (flags & EJS_FLAGS_CLASS_DEC && 				(tid == EJS_TOK_LBRACE || tid == EJS_TOK_EXTENDS)) {			ejsLexPutbackToken(ep, tid, ep->token);			return EJS_STATE_DEC_LIST_DONE;		} else if (tid == EJS_TOK_RPAREN && flags & EJS_FLAGS_CATCH) {			ejsLexPutbackToken(ep, tid, ep->token);			return EJS_STATE_DEC_LIST_DONE;		} else if (tid != EJS_TOK_COMMA) {			ejsSyntaxError(ep, 0);			return EJS_STATE_ERR;		}	} while (tid == EJS_TOK_COMMA);	if (tid != EJS_TOK_SEMI) {		ejsSyntaxError(ep, 0);		return EJS_STATE_ERR;	}	return EJS_STATE_DEC_LIST_DONE;}/******************************************************************************//* *	Local vars  */typedef struct ParseExpr {	EjsVar		lhs, rhs;	int			rel, tid, unaryMinus;} ParseExpr;/* *	Parse expression (leftHandSide operator rightHandSide) */static int parseExpr(Ejs *ep, int state, int flags){	ParseExpr		*sp;	mprAssert(ep);	if ((sp = pushFrame(ep, sizeof(ParseExpr))) == 0) {		return EJS_STATE_ERR;	}	if (flags & EJS_FLAGS_EXE) {		ejsClearVar(ep, ep->result);	}	sp->lhs.type = sp->rhs.type = EJS_TYPE_UNDEFINED;	sp->lhs.objectState = sp->rhs.objectState = 0;	sp->lhs.allocatedData = sp->rhs.allocatedData = 0;	ejsSetVarName(ep, &sp->lhs, "lhs");	ejsSetVarName(ep, &sp->rhs, "rhs");	sp->rel = 0;	sp->tid = 0;	sp->unaryMinus = 0;	do {		/*		 *	This loop will handle an entire expression list. We call parse		 *	to evalutate each term which returns the result in ep->result.		 */		if (sp->tid == EJS_TOK_LOGICAL) {			state = ejsParse(ep, EJS_STATE_RELEXP, flags);			if (state < 0) {				break;			}		} else {			sp->tid = ejsLexGetToken(ep, state);			if (sp->tid == EJS_TOK_EXPR && (int) *ep->token == EJS_EXPR_MINUS) {				sp->unaryMinus = 1;			} else {				ejsLexPutbackToken(ep, sp->tid, ep->token);			}			state = ejsParse(ep, EJS_STATE_EXPR, flags);			if (state < 0) {				break;			}		}		if (flags & EJS_FLAGS_EXE) {			if (sp->unaryMinus) {				switch (ep->result->type) {				default:				case EJS_TYPE_UNDEFINED:				case EJS_TYPE_NULL:				case EJS_TYPE_STRING_CMETHOD:				case EJS_TYPE_CMETHOD:				case EJS_TYPE_METHOD:				case EJS_TYPE_PTR:				case EJS_TYPE_OBJECT:				case EJS_TYPE_STRING:				case EJS_TYPE_BOOL:					ejsError(ep, EJS_SYNTAX_ERROR, "Invalid unary minus");					state = EJS_STATE_ERR;					break;#if BLD_FEATURE_FLOATING_POINT				case EJS_TYPE_FLOAT:					ep->result->floating = - ep->result->floating;					break;#endif				case EJS_TYPE_INT:					ep->result->integer = - ep->result->integer;					break;#if BLD_FEATURE_INT64				case EJS_TYPE_INT64:					ep->result->integer64 = - ep->result->integer64;					break;#endif				}			}			sp->unaryMinus = 0;			if (sp->rel > 0) {				ejsWriteVar(ep, &sp->rhs, ep->result, EJS_SHALLOW_COPY);				if (sp->tid == EJS_TOK_LOGICAL) {					if (evalCond(ep, &sp->lhs, sp->rel, &sp->rhs) < 0) {						state = EJS_STATE_ERR;						break;					}				} else {					if (evalExpr(ep, &sp->lhs, sp->rel, &sp->rhs) < 0) {						state = EJS_STATE_ERR;						break;					}				}			}			/* MOB */			if (sp->lhs.type == EJS_TYPE_OBJECT) {				ejsMakeObjLive(&sp->lhs, 0);				mprAssert(sp->lhs.objectState->alive == 0);			}			if (sp->rhs.type == EJS_TYPE_OBJECT) {				ejsMakeObjLive(&sp->rhs, 0);				mprAssert(sp->rhs.objectState->alive == 0);			}		}		if ((sp->tid = ejsLexGetToken(ep, state)) == EJS_TOK_EXPR ||			 sp->tid == EJS_TOK_INC_DEC || sp->tid == EJS_TOK_LOGICAL) {			sp->rel = (int) *ep->token;			ejsWriteVar(ep, &sp->lhs, ep->result, EJS_SHALLOW_COPY);		} else {			ejsLexPutbackToken(ep, sp->tid, ep->token);			state = EJS_STATE_RELEXP_DONE;		}	} while (state == EJS_STATE_EXPR_DONE);	ejsClearVar(ep, &sp->lhs);	ejsClearVar(ep, &sp->rhs);	popFrame(ep, sizeof(ParseExpr));	return state;}/******************************************************************************//* *	Local vars */typedef struct ParseForIn {	EjsInput		*endScript, *bodyScript;	EjsProperty		*pp, *nextp;	EjsVar			*iteratorVar, *setVar, *vp;	int				forFlags, tid;} ParseForIn;/* *	Parse the "for ... in" statement. Format for the statement is: * *		for [each] (var varName in expression) { *			body; *		} */static int parseForIn(Ejs *ep, int state, int flags, int each){	ParseForIn		*sp;	mprAssert(ep);	if ((sp = pushFrame(ep, sizeof(ParseForIn))) == 0) {		return EJS_STATE_ERR;	}	sp->setVar = 0;	sp->iteratorVar = 0;	sp->bodyScript = 0;	sp->endScript = 0;	sp->tid = ejsLexGetToken(ep, state);	if (sp->tid != EJS_TOK_ID && sp->tid != EJS_TOK_VAR) {		ejsSyntaxError(ep, 0);		goto err;	}	ejsLexPutbackToken(ep, sp->tid, ep->token);	state = ejsParse(ep, EJS_STATE_EXPR, EJS_FLAGS_FORIN | flags);	if (state < 0) {		goto done;	}	if (flags & EJS_FLAGS_EXE) {		if (ep->currentProperty == 0) {			ejsSyntaxError(ep, 0);			goto err;		}		sp->iteratorVar = &ep->currentProperty->var;	} else {		sp->iteratorVar = 0;	}		if (ejsLexGetToken(ep, state) != EJS_TOK_IN) {		ejsSyntaxError(ep, 0);		goto err;	}	/*	 *	Get the set	 */

⌨️ 快捷键说明

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