nodom2-表达式(expression)类

原创
2019/01/16 23:46
阅读数 47

nodom2 主要完成了常见js表达式处理包括 操作符 ()!|*/+-><=&%,以及操作符组合如>=、===、!== 等,值null undefined true false。

代码结构有了很大优化,字符串处理变得更简单,分为字符串、变量和函数。

代码如下:

class Expression{
	/**
	 * @param exprStr	表达式串
	 */
	constructor(exprStr){
		this.inited = true;
		//旧值
		this.oldVal = undefined;
		//新值
		this.newVal = undefined;
		this.stack = this.init(exprStr);
	}

	/**
	 * 初始化,把表达式串转换成堆栈
	 */
	init(exprStr){
		//字符串开始
		let startStr = undefined;
		let type = 0; // 1字符串 2变量 3函数
		//字符串开始结束符
		let strings = "'`\"";
        //运算符
        let operand = "()!|*/+-><=&% 	";
        //
        let values = ['null','undefined','true','false'];
        //堆栈
        let stack = new Array();
        let sTmp = '';
        for(let i=0;i<exprStr.length;i++){
        	let c = exprStr[i];
        	switch(type){
        		case 1: //当前为字符串
        			//字符串标识
        			if(strings.indexOf(c) !== -1){
        				if(c === startStr){
        					this.addStr(sTmp + c,stack);
		        			startStr = undefined;
		        			sTmp = '';
		        			type = 0;
		        			continue;
		        		}
        			}
        			break;
        		case 2: //当前为变量
        			//操作符
        			if(operand.indexOf(c) !== -1){
        				//转为函数
        				if(c === '('){
        					type = 3;
        				}else{ //变量结束
        					this.addVar(sTmp,values,stack);
        					sTmp = '';
        					type = 0;
        				}
        			}
        			break;
        		case 3:
        			if(c === ')'){
        				let a = sTmp.trim().split('(');
        				//函数名
        				let fn = a[0];
        				//参数
        				let pa = a[1].split(',');
        				for(let j=0;j<pa.length;j++){
        					pa[j] = pa[j].trim();
        				}
        				
        				//函数入栈
        				stack.push({
        					val:fn,
        					params:pa,
        					type:'function'
        				});
        				sTmp = '';
        				type = 0;
        				continue;
        			}
        			break;
        		default:
        			//字符串开始
        			if(strings.indexOf(c) !== -1){
        				startStr = c;
        				type = 1;
        			}else if(operand.indexOf(c) === -1){ //变量开始
        				type = 2;
        				if(sTmp !== ''){
        					this.addStr(sTmp,stack);
	        				sTmp = '';
        				}
        			}
        	}
        	sTmp += c;
        }
		if(type === 2){ //变量处理
			this.addVar(sTmp,values,stack);
		}else if(type === 0 && sTmp !== ''){  //字符串
			this.addStr(sTmp,stack);
		}else{
			//抛出表达式错误
			throw DD.Error.handle('invoke','expression',0,'Node');
		}
        return stack;
    }    



	/**
	 * 表达式计算
	 * @param module 	模块
	 * @param model 	模型
	 */
	val(module,model){
		if(this.stack === null){
			return '';
		}
		let retStr = '';
		this.stack.forEach((item)=>{
			let value='';
			switch(item.type){
				case 'string'://字符串
					value = item.val;
					break;
				case 'field'://变量
					value = model.$get(item.val);
					break;
				case 'function'://函数
					let foo = module.methodFactory.get(item.val);
					if(DD.isFunction(foo)){
						let param = [];
						if(item.params.length>0){
							item.params.forEach((p)=>{
								param.push(model.$get(p));	
							});
						}
						value = foo.apply(module,param);
					}
			}
			retStr += value;
		});

		if(retStr !== ''){
			retStr = eval(retStr) + '';
		}
		//设置新值
		this.newVal = retStr;
		return retStr;
	}

	/**
	 * 添加变量
	 */
	 addVar(field,values,stack){
		let addFlag = false;
		//判断是否为值表达式 null undefined true false
		for(let j=0;j<values.length;j++){
			if(field === values[j]){
				addFlag = true;
				break;
			}
		}
		addFlag = addFlag || DD.isNumberString(field);
		//作为字符串处理   
		if(addFlag){
			this.addStr(field,stack);
		}else{
			stack.push({
				val:field.trim(),
				type:'field'
			});
		}
	}

	/**
     * 添加字符串
     */
	addStr(str,stack){
		//如果前一个类型为字符串,则追加到前一个
		if(stack.length > 0 && stack[stack.length-1].type === "string"){ 
			stack[stack.length-1].val += str;
		}else{
			stack.push({
				val:str,
				type:'string'
			});
		}
	}

	/**
	 * 提交,旧值换为新值,新值undefined
	 */
	commit(){
		this.oldVal = this.newVal;
		this.newVal = undefined;
	}


	/**
	 * 判断是否做了更改
	 */
	isChanged(){
		return this.oldVal === this.newVal;
	}


}

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部