/// <summary> /// set loop record info /// </summary> /// <param name="symbol"></param> /// <param name="startVal"></param> /// <param name="endVal"></param> /// <param name="stepVal"></param> public void SetLoopRecord(VarSymbol symbol, BaseData endVal, BaseData stepVal) { m_loopSymbol = symbol; m_endValue = endVal; m_stepValue = stepVal; }
/// <summary> /// set loop record info /// </summary> /// <param name="symbol"></param> /// <param name="startVal"></param> /// <param name="endVal"></param> /// <param name="stepVal"></param> public void SetLoopRecord( VarSymbol symbol, BaseData endVal, BaseData stepVal ) { m_loopSymbol = symbol; m_endValue = endVal; m_stepValue = stepVal; }
/// <summary> /// define a symbol /// </summary> /// <param name="sym"></param> public void Define( VarSymbol sym ) { if (m_varSymbolDic.ContainsKey(sym.NAME)) m_varSymbolDic[sym.NAME] = sym; else m_varSymbolDic.Add(sym.NAME, sym); }
protected void onInput(Statement s) { List <Expression> varList = s.m_expressList; string input = null; foreach (Expression exp in varList) { input = m_apiCall.Input(); BaseData dat = BaseData.Parser(input); // 转换为字符串 if (exp.m_symbolName.EndsWith("$")) { dat.Convert(BaseData.TYPE_STRING); } if (exp.m_type == Expression.EXP_SYMBOL) { VarSymbol symbol = m_symbolTable.ResolveVar(exp.m_symbolName); symbol.VALUE = dat; } else if (exp.m_type == Expression.EXP_ARRAY_SYMBOL) { List <int> indexs = expressListToIndexs(exp.m_funcParams); ArraySymbol arrSymbol = m_symbolTable.ResolveArray(exp.m_symbolName, indexs); arrSymbol.SetValue(indexs, dat); } else { throw new ErrorCode(ErrorCode.ERROR_CODE_02); } } }
/// <summary> /// return a symbol /// </summary> /// <param name="name"></param> /// <returns></returns> public VarSymbol ResolveVar(string name) { if (m_varSymbolDic.ContainsKey(name)) { return(m_varSymbolDic[name]); } // create a new VarSymbol symbol = null; if (name.EndsWith("%")) { symbol = new VarSymbol(name, new BaseData(0)); } else if (name.EndsWith("$")) { symbol = new VarSymbol(name, new BaseData("")); } else { symbol = new VarSymbol(name, new BaseData(0.0f)); } m_varSymbolDic.Add(name, symbol); return(symbol); }
/// <summary> /// read statement /// </summary> /// <param name="s"></param> protected void doRead(Statement s) { foreach (string symbolName in s.m_symbolList) { VarSymbol symbol = m_symbolTable.ResolveVar(symbolName); symbol.VALUE = m_dataRegion.GetData(); } }
/// <summary> /// define a symbol /// </summary> /// <param name="sym"></param> public void Define(VarSymbol sym) { if (m_varSymbolDic.ContainsKey(sym.NAME)) { m_varSymbolDic[sym.NAME] = sym; } else { m_varSymbolDic.Add(sym.NAME, sym); } }
/// <summary> /// assignment /// </summary> /// <param name="s"></param> protected void doAssign(Statement s) { // calculate the expression value BaseData dat = calculateExp(s.m_exp).m_value; if (s.m_expressList == null) { VarSymbol symbol = m_symbolTable.ResolveVar(s.m_symbol); symbol.VALUE = dat; } else { List <int> indexs = expressListToIndexs(s.m_expressList); ArraySymbol arrSymbol = m_symbolTable.ResolveArray(s.m_symbol, indexs); arrSymbol.SetValue(indexs, dat); } }
/// <summary> /// for statement /// </summary> /// <param name="s"></param> protected void doForBegin(Statement s) { string varName = s.m_symbol; VarSymbol symbol = m_symbolTable.ResolveVar(varName); ForRecord lr = null; // use the top of LoopRecord or push a new one ? if (m_forLoopStack.Count > 0) { lr = m_forLoopStack.Peek(); } if (lr == null || lr.LOOP_VAR_NAME != varName) { lr = new ForRecord(); m_forLoopStack.Push(lr); } BaseData startValue = calculateExp(s.m_expressList[0]).m_value; BaseData endValue = calculateExp(s.m_expressList[1]).m_value; BaseData stepValue = calculateExp(s.m_expressList[2]).m_value; // check the value type if (startValue.TYPE != BaseData.TYPE_INT && startValue.TYPE != BaseData.TYPE_FLOAT) { throw new ErrorCode(ErrorCode.ERROR_CODE_02); } if (endValue.TYPE != BaseData.TYPE_INT && endValue.TYPE != BaseData.TYPE_FLOAT) { throw new ErrorCode(ErrorCode.ERROR_CODE_02); } if (stepValue.TYPE != BaseData.TYPE_INT && stepValue.TYPE != BaseData.TYPE_FLOAT) { throw new ErrorCode(ErrorCode.ERROR_CODE_02); } // initital the loop var lr.SetLoopRecord(symbol, endValue, stepValue); lr.SetBeginIndex(s.m_lineIndex); // init the symbol value symbol.VALUE = startValue; }
/// <summary> /// return a symbol /// </summary> /// <param name="name"></param> /// <returns></returns> public VarSymbol ResolveVar( string name ) { if (m_varSymbolDic.ContainsKey(name)) return m_varSymbolDic[name]; // create a new VarSymbol symbol = null; if (name.EndsWith("%")) symbol = new VarSymbol( name, new BaseData(0)); else if (name.EndsWith("$")) symbol = new VarSymbol( name, new BaseData("")); else symbol = new VarSymbol( name, new BaseData(0.0f)); m_varSymbolDic.Add(name, symbol); return symbol; }
/// <summary> /// reduce the expession /// </summary> /// <param name="exp"></param> /// <returns></returns> protected Expression calculateExp(Expression exp) { Expression result = null; Expression midExp = null; Expression expLeft = null; Expression expRight = null; switch (exp.m_type) { case Expression.VALUE: result = exp; break; case Expression.TYPE_CLOSE_TO: result = exp; result.m_value = new BaseData(BaseData.TYPE_CLOSE_TO, 0); break; case Expression.TYPE_NEXT_LINE: result = exp; result.m_value = new BaseData(BaseData.TYPE_NEXT_LINE, 0); break; case Expression.EXP_SYMBOL: VarSymbol s = m_symbolTable.ResolveVar(exp.m_symbolName); result = new Expression(s.VALUE); break; case Expression.EXP_ARRAY_SYMBOL: List <int> indexs = expressListToIndexs(exp.m_funcParams); ArraySymbol arr = m_symbolTable.ResolveArray(exp.m_symbolName, indexs); result = new Expression(arr.GetValue(indexs)); break; // 内置函数 case Expression.EXP_FUNC: List <BaseData> param = new List <BaseData>(); // convert the parameters foreach (Expression e in exp.m_funcParams) { param.Add(calculateExp(e).m_value); } // call the function BaseData returnVal = m_innerFunc.CallFunc(exp.m_symbolName, param); result = new Expression(returnVal); break; // 用户自定义函数 case Expression.EXP_USER_FUNC: string funcName = exp.m_symbolName; FunSymbol func = m_symbolTable.ResolveFunc(funcName); Expression funcParam = exp.m_funcParams[0]; BaseData paramVal = calculateExp(funcParam).m_value; m_symbolTable.Define(new VarSymbol(CommonDef.FN_PARAM_SYMBOL, paramVal)); result = calculateExp(func.EXP); break; case Expression.OP_NOT: midExp = calculateExp(exp.m_leftExp); if (midExp.m_type == Expression.VALUE) { if (midExp.m_value != BaseData.ZERO) { result = new Expression(new BaseData(0)); } else { result = new Expression(new BaseData(1)); } } else { throw new ErrorCode(ErrorCode.ERROR_CODE_12); } break; case Expression.OP_NEG: midExp = calculateExp(exp.m_leftExp); if (midExp.m_type == Expression.VALUE) { result = midExp; result.m_value.NegValue(); } else { throw new ErrorCode(ErrorCode.ERROR_CODE_12); } break; case Expression.EXP_INKEY: result = new Expression(new BaseData(m_apiCall.Inkey())); break; // 二元运算符 case Expression.OP_ADD: case Expression.OP_MINUS: case Expression.OP_MUL: case Expression.OP_DIV: case Expression.OP_POWER: case Expression.OP_AND: case Expression.OP_OR: case Expression.OP_EQUAL: case Expression.OP_GREATER: case Expression.OP_GREATER_EQU: case Expression.OP_LESS: case Expression.OP_LESS_EQ: // check the value expLeft = calculateExp(exp.m_leftExp); expRight = calculateExp(exp.m_rightExp); if (expLeft.m_type != Expression.VALUE || expRight.m_type != Expression.VALUE) { throw new ErrorCode(ErrorCode.ERROR_CODE_12); } if (exp.m_type == Expression.OP_ADD) { result = new Expression(expLeft.m_value + expRight.m_value); } else if (exp.m_type == Expression.OP_MINUS) { result = new Expression(expLeft.m_value - expRight.m_value); } else if (exp.m_type == Expression.OP_MUL) { result = new Expression(expLeft.m_value * expRight.m_value); } else if (exp.m_type == Expression.OP_DIV) { result = new Expression(expLeft.m_value / expRight.m_value); } else if (exp.m_type == Expression.OP_POWER) { result = new Expression(expLeft.m_value ^ expRight.m_value); } else if (exp.m_type == Expression.OP_AND) { result = new Expression(expLeft.m_value & expRight.m_value); } else if (exp.m_type == Expression.OP_OR) { result = new Expression(expLeft.m_value | expRight.m_value); } else if (exp.m_type == Expression.OP_EQUAL) { result = new Expression(expLeft.m_value == expRight.m_value ? 1 : 0); } else if (exp.m_type == Expression.OP_GREATER) { result = new Expression(new BaseData(expLeft.m_value > expRight.m_value ? 1 : 0)); } else if (exp.m_type == Expression.OP_GREATER_EQU) { result = new Expression(new BaseData(expLeft.m_value >= expRight.m_value ? 1 : 0)); } else if (exp.m_type == Expression.OP_LESS) { result = new Expression(new BaseData(expLeft.m_value < expRight.m_value ? 1 : 0)); } else if (exp.m_type == Expression.OP_LESS_EQ) { result = new Expression(new BaseData(expLeft.m_value <= expRight.m_value ? 1 : 0)); } break; default: throw new ErrorCode(ErrorCode.ERROR_CODE_02); } return(result); }