Exemplo n.º 1
0
        /// <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);
        }