internal RightValueExpr CreateStringConst(string value, Location loc)
 {
     StringConst strConst = new StringConst();
     strConst.Value = value;
     RightValueExpr expr = new RightValueExpr();
     expr.RightValue = strConst;
     expr.Location = loc;
     return expr;
 }
        public override void Visit(FunctionCallStmt funcCallStmt, object[] args)
        {
            if (!root.FuncDefMap.ContainsKey(funcCallStmt.Name))
            {
                kernel.IssueError(ErrorType.FunctionNotExist, funcCallStmt.Location, funcCallStmt.Name);
                return;
            }

            FunctionDef def = root.FuncDefMap[funcCallStmt.Name];

            //解析ParaStr
            if (funcCallStmt.ParaStr != null)
            {
                int count = funcCallStmt.ParaStr.Length;
                if (def.ParaStrMap.ContainsKey(count))
                {
                    for (int i = 0; i < funcCallStmt.ParaStr.Length; i++)
                    {
                        string varName = def.ParaStrMap[count][i];
                        string content = funcCallStmt.ParaStr[i];
                        if (funcCallStmt.ParamMap.ContainsKey(varName))
                        {
                            kernel.IssueError(ErrorType.DuplicatedParaAndParaStr, funcCallStmt.Location, varName);
                        }
                        else
                        {
                            funcCallStmt.ParamMap.Add(varName, exprParser.CreateStringConst(content, funcCallStmt.Location));
                        }
                    }
                }
                else
                {
                    kernel.IssueError(ErrorType.NoMatchedParaStrDef, funcCallStmt.Location);
                }
            }

            //解析实参
            List<KeyValuePair<string, Expression>> toModify = new List<KeyValuePair<string, Expression>>();
            foreach (KeyValuePair<string, Expression> actual in funcCallStmt.ParamMap)
            {
                ParameterDef paramDef = def.ParaMap[actual.Key];
                string actualStr = ((actual.Value as RightValueExpr).RightValue as StringConst).Value;
                Location loc = actual.Value.Location;

                RightValue parsedValue = null;
                RightValueExpr rightValueExpr = new RightValueExpr();

                switch (paramDef.ParameterType)
                {
                    case ParameterDef.ParameterTypeEnum.Auto:
                        parsedValue = exprParser.ParseValue(actualStr, loc);
                        break;

                    case ParameterDef.ParameterTypeEnum.String:
                        continue;

                    case ParameterDef.ParameterTypeEnum.Expression:
                        toModify.Add(new KeyValuePair<string,Expression>(actual.Key, exprParser.ParseExpr(actualStr, loc)));
                        continue;

                    case ParameterDef.ParameterTypeEnum.Int:
                        parsedValue = exprParser.ParseValue(actualStr, DataType.Int, loc);
                        break;

                    case ParameterDef.ParameterTypeEnum.Float:
                        parsedValue = exprParser.ParseValue(actualStr, DataType.Float, loc);
                        break;

                    case ParameterDef.ParameterTypeEnum.Bool:
                        parsedValue = exprParser.ParseValue(actualStr, DataType.Bool, loc);
                        break;
                }

                rightValueExpr.RightValue = parsedValue;
                rightValueExpr.Location = loc;
                toModify.Add(new KeyValuePair<string,Expression>(actual.Key, rightValueExpr));
            }

            foreach(KeyValuePair<string,Expression> elem in toModify)
            {
                funcCallStmt.ParamMap[elem.Key] = elem.Value;
            }

            //添加默认值
            foreach (KeyValuePair<string, ParameterDef> pDef in def.ParaMap)
            {
                if (!funcCallStmt.ParamMap.ContainsKey(pDef.Key) && pDef.Value.Default != null)
                {
                    RightValueExpr expr = new RightValueExpr();
                    expr.RightValue = pDef.Value.Default;
                    funcCallStmt.ParamMap.Add(pDef.Key, expr);
                }
            }

            //参数完整性检查
            foreach (KeyValuePair<string, ParameterDef> pDef in def.ParaMap)
            {
                if (!funcCallStmt.ParamMap.ContainsKey(pDef.Key))
                {
                    kernel.IssueError(ErrorType.ParameterNotDefined, funcCallStmt.Location, pDef.Key);
                }
            }

            base.Visit(funcCallStmt, args);

            //TODO: 刷新Expression的DataType
        }
        /// <summary>
        /// end表示字符串最后一个字符的后一个位置
        /// </summary>
        /// <param name="begin"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private Expression parse(int begin, int end)
        {
            if (begin >= end)
            {
                kernel.IssueError(ErrorType.ExpressionSyntaxError, loc.Offset(begin));
                return null;
            }

            while (isWhiteSpace(expr[begin]))
                begin++;
            while (isWhiteSpace(expr[end - 1]))
                end--;

            int currentParenLevel;
            bool hasSideParren = true;
            while (expr[begin] == '(' && hasSideParren)
            {
                currentParenLevel = 0;
                int currentPos;
                for (currentPos = begin; currentPos < end; currentPos++)
                {
                    if (expr[currentPos] == '(') currentParenLevel++;
                    else if (expr[currentPos] == ')')
                    {
                        currentParenLevel--;
                        if (currentParenLevel == 0)
                        {
                            if (currentPos == end - 1)
                            {
                                begin++;
                                end--;
                            }
                            else
                                hasSideParren = false;
                            break;
                        }
                    }
                }

                if (currentPos == end && currentParenLevel > 0)
                {
                    kernel.IssueError(ErrorType.SingleParen, loc.Offset(begin));
                    return null;
                }
            }

            currentParenLevel = 0;
            OpLevel currentLevel = OpLevel.Null;
            OpLevel minLevel = OpLevel.Null;
            int minPos = -1;
            int minOpLength = 0;
            bool findOp = false;
            string op = null;
            MatchTokenResult matchTokenResult;

            //找到当前应处理的操作符
            for (int currentPos = begin; currentPos < end; currentPos = matchTokenResult.EndPos)
            {
                //if (expr[currentPos] == ' ' || expr[currentPos] == '\t' || expr[currentPos] == '\n'
                //    || Environment.NewLine.IndexOf(expr[currentPos]) != -1)
                //{
                //    op = null;
                //    continue;
                //}

                matchTokenResult = MatchToken(currentPos, end);
                if (matchTokenResult.TokenType == TokenType.Error)
                    return null;

                if (matchTokenResult.TokenType != TokenType.Operator)
                    continue;

                op = matchTokenResult.Matched;

                if (op != "(" && op != ")") findOp = true;
                if (op == "(")
                {
                    currentParenLevel++;
                    continue;
                }
                else if (op == ")")
                {
                    currentParenLevel--;
                    continue;
                }
                else if (currentParenLevel > 0)
                {
                    continue;
                }
                else if (currentParenLevel < 0)
                {
                    kernel.IssueError(ErrorType.SingleParen, loc.Offset(currentPos));
                    return null;
                }

                if (currentParenLevel == 0
                    &&(
                    (int)(currentLevel = getOpLevel(op)) < (int)minLevel)
                    || ((int)currentLevel == (int)minLevel && op != "=")    //=为右结合
                    )
                {
                    minLevel = currentLevel;
                    minPos = matchTokenResult.BeginPos;
                    minOpLength = op.Length;
                }
            }

            if (currentParenLevel != 0)
            {
                kernel.IssueError(ErrorType.SingleParen, loc.Offset(begin));
                return null;
            }

            if (!findOp)    //单个数据
            {
                string str = expr.Substring(begin, end - begin);
                int currentPos = begin;
                matchTokenResult = MatchToken(currentPos, end);

                switch (matchTokenResult.TokenType)
                {
                    case TokenType.Int:
                        RightValueExpr intResult = new RightValueExpr();
                        IntConst intConst = new IntConst();
                        intConst.Value = int.Parse(matchTokenResult.Matched);
                        intResult.DataType = DataType.Int;
                        intResult.RightValue = intConst;
                        intResult.Location = loc.Offset(begin);
                        return intResult;

                    case TokenType.Float:
                        RightValueExpr floatResult = new RightValueExpr();
                        FloatConst floatConst = new FloatConst();
                        floatConst.Value = float.Parse(matchTokenResult.Matched);
                        floatResult.DataType = DataType.Int;
                        floatResult.RightValue = floatConst;
                        floatResult.Location = loc.Offset(begin);
                        return floatResult;

                    case TokenType.String:
                        RightValueExpr strResult = new RightValueExpr();
                        StringConst strConst = new StringConst();
                        strConst.Value = matchTokenResult.Matched;
                        strResult.DataType = DataType.String;
                        strResult.RightValue = strConst;
                        strResult.Location = loc.Offset(begin);
                        return strResult;

                    case TokenType.Bool:
                        RightValueExpr boolResult = new RightValueExpr();
                        BoolConst boolConst = new BoolConst();
                        boolConst.Value = bool.Parse(matchTokenResult.Matched);
                        boolResult.DataType = DataType.Bool;
                        boolResult.RightValue = boolConst;
                        boolResult.Location = loc.Offset(begin);
                        return boolResult;

                    case TokenType.Variable:
                        VarRef varRef = new VarRef();
                        varRef.VarName = matchTokenResult.Matched;
                        LeftValueExpr leftValueResult = new LeftValueExpr();
                        leftValueResult.DataType = DataType.Unknown;
                        leftValueResult.Location = loc.Offset(begin);
                        leftValueResult.LeftValue = varRef;
                        return leftValueResult;

                    default:
                        kernel.IssueError(ErrorType.ExpressionSyntaxError, loc.Offset(begin));
                        return null;
                }
            }

            Expression left;
            Expression right;

            matchTokenResult = MatchToken(minPos, end);
            op = matchTokenResult.Matched;

            left = (begin != minPos) ? parse(begin, minPos) : null; //null表示单目运算符
            right = parse(matchTokenResult.EndPos, end);
            Location currentLoc = loc.Offset(begin);

            if (right == null)
                return null;

            switch (op)
            {
                case "=":
                    if (!(left is LeftValueExpr))
                    {
                        kernel.IssueError(ErrorType.NotLeftValue, currentLoc);
                        return null;
                    }
                    AssignExpr assignExpr = new AssignExpr();
                    assignExpr.LeftExpr = left as LeftValueExpr;
                    assignExpr.RightExpr = right;
                    assignExpr.DataType = right.DataType;
                    assignExpr.Location = currentLoc;
                    return assignExpr;

                case "&&":
                    return processBinaryLogicExpr(
                        new AndExpr(),
                        left, right, currentLoc);

                case "||":
                    return processBinaryLogicExpr(
                        new OrExpr(),
                        left, right, currentLoc);

                case "==":
                    return processBinaryCmpExpr(new EquExpr(), left, right, currentLoc);

                case "!=":
                    return processBinaryCmpExpr(new NeqExpr(), left, right, currentLoc);

                case ">":
                    return processBinaryCmpExpr(new GreatExpr(), left, right, currentLoc);

                case ">=":
                    return processBinaryCmpExpr(new GreatEquExpr(), left, right, currentLoc);

                case "<":
                    return processBinaryCmpExpr(new LessExpr(), left, right, currentLoc);

                case "<=":
                    return processBinaryCmpExpr(new LessEquExpr(), left, right, currentLoc);

                case "+":
                    return processBinaryAlgoExpr(new AddExpr(), left, right, currentLoc);

                case "-":
                    if (left == null)
                    {
                        NegativeExpr negExpr = new NegativeExpr();
                        if (right.DataType == DataType.Bool || right.DataType == DataType.String)
                        {
                            kernel.IssueError(ErrorType.OprandTypeError, currentLoc);
                            return null;
                        }
                        else if (right.DataType == DataType.Int)
                        {
                            negExpr.DataType = DataType.Int;
                        }
                        else if (right.DataType == DataType.Float)
                        {
                            negExpr.DataType = DataType.Float;
                        }
                        else
                        {
                            negExpr.DataType = DataType.Unknown;
                        }

                        negExpr.Op = right;
                        negExpr.Location = currentLoc;
                        return negExpr;
                    }
                    else
                    {
                        return processBinaryAlgoExpr(new SubExpr(), left, right, currentLoc);
                    }

                case "*":
                    return processBinaryAlgoExpr(new MulExpr(), left, right, currentLoc);

                case "/":
                    return processBinaryAlgoExpr(new DivExpr(), left, right, currentLoc);

                case "^":
                    return processBinaryAlgoExpr(new PowExpr(), left, right, currentLoc);

                case "!":
                    if (left != null)
                    {
                        kernel.IssueError(ErrorType.ExpressionSyntaxError, currentLoc);
                        return null;
                    }
                    else
                    {
                        NotExpr notExpr = new NotExpr();
                        notExpr.DataType = DataType.Bool;
                        notExpr.Op = right;
                        notExpr.Location = currentLoc;
                        return notExpr;
                    }
            }

            return null;
        }
 public void Visit(RightValueExpr rightValueExpr, object[] args)
 {
 }