Пример #1
0
        public object ExecuteExpr(Expr expr)
        {
            object result = null;
            if (expr is Literal)
            {
                Literal literal = (Literal)expr;
                if (literal.Type == ExprType.String)
                {
                    result = literal.Value;
                }
                else if (literal.Type == ExprType.Bytes)
                {
                    result = Utility.StringToBytes(literal.Value);
                }
                else if (literal.Type == ExprType.Name)
                {
                    result = Variables[literal.Value.ToLowerInvariant()];
                }
                else if (literal.Type == ExprType.Bool)
                {
                    result = Boolean.Parse(literal.Value);
                }
                else if (literal.Type == ExprType.Number)
                {
                    result = Double.Parse(literal.Value);
                }
                else if (literal.Type == ExprType.HexInt)
                {
                    result = Int32.Parse(literal.Value, System.Globalization.NumberStyles.AllowHexSpecifier);
                }
                else if (literal.Type == ExprType.Null)
                {
                }
                else
                {
                    throw new Exception("Unexpected literal: " + literal.Type);
                }
            }
            else if (expr is Command)
            {
                Command cmd = (Command)expr;
                if (cmd.Type == ExprType.Root)
                {
                    foreach (var arg in cmd.Args)
                    {
                        if (arg.Type == ExprType.Assign)
                        {
                            result = ExecuteExpr(arg);
                        }
                        else
                        {
                            result = ExecuteExpr(arg);
                            defaultVar = result;
                        }
                    }
                }
                else if ((cmd.Type == ExprType.DotInstanceDefault) || (cmd.Type == ExprType.DotInstanceDefaultChain))
                {
                    result = ExecuteFunction((Command)cmd.Args[1], ExecuteExpr(cmd.Args[0]), true);
                }
                else if ((cmd.Type == ExprType.DotInstance) || (cmd.Type == ExprType.DotInstanceChain))
                {
                    result = ExecuteFunction((Command)cmd.Args[1], ExecuteExpr(cmd.Args[0]), false);
                }
                else if (cmd.Type == ExprType.DotDefault)
                {
                    result = ExecuteFunction((Command)cmd.Args[0], null, true);
                }
                else if (cmd.Type == ExprType.Function)
                {
                    result = ExecuteFunction(cmd, null, false);
                }
                else if ((cmd.Type == ExprType.DotProperty) || (cmd.Type == ExprType.DotPropertyChain))
                {
                    object obj = ExecuteExpr(cmd.Args[0]);
                    string propertyName = ((Literal)cmd.Args[1]).Value;
                    result = obj.GetType().GetProperty(propertyName).GetValue(obj, null);
                }
                else if (cmd.Type == ExprType.Indexed)
                {
                    object obj = ExecuteExpr(cmd.Args[0]);
                    int index = Int32.Parse(((Literal)cmd.Args[1]).Value);

                    var type = obj.GetType();
                    if (type.IsArray)
                    {
                        result = ((Array)obj).GetValue(index);
                    }
                    else
                    {
                        var attributes = type.GetCustomAttributes(typeof(DefaultMemberAttribute), true);
                        if (attributes.Length > 0)
                        {
                            var indexerName = ((DefaultMemberAttribute)attributes[0]).MemberName;
                            result = type.GetProperty(indexerName).GetValue(obj, new object[] { index });
                        }
                        else
                        {
                            throw new Exception(obj.ToString() + " can't be indexed.");
                        }
                    }
                }
                else if (cmd.Type == ExprType.Array)
                {
                    object[] array = new object[cmd.Args.Count];
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = ExecuteExpr(cmd.Args[i]);
                    }
                    result = array;
                }
                else if (cmd.Type == ExprType.Assign)
                {
                    string name = ((Literal)cmd.Args[0]).Value.ToLowerInvariant();
                    result = ExecuteExpr(cmd.Args[1]);
                    if (Variables.ContainsKey(name))
                    {
                        Variables[name] = result;
                    }
                    else
                    {
                        Variables.Add(name, result);
                    }
                }
                else if (cmd.Type == ExprType.Negative)
                {
                    result = ((double)ExecuteExpr(cmd.Args[0])) * -1;
                }
                else if (cmd.Type == ExprType.Mod)
                {
                    result = ((double)ExecuteExpr(cmd.Args[0])) % ((double)ExecuteExpr(cmd.Args[1]));
                }
                else if (cmd.Type == ExprType.Div)
                {
                    result = ((double)ExecuteExpr(cmd.Args[0])) / ((double)ExecuteExpr(cmd.Args[1]));
                }
                else if (cmd.Type == ExprType.Mul)
                {
                    result = ((double)ExecuteExpr(cmd.Args[0])) * ((double)ExecuteExpr(cmd.Args[1]));
                }
                else if (cmd.Type == ExprType.Sub)
                {
                    result = ((double)ExecuteExpr(cmd.Args[0])) - ((double)ExecuteExpr(cmd.Args[1]));
                }
                else if (cmd.Type == ExprType.Add)
                {
                    object left = ExecuteExpr(cmd.Args[0]);
                    object right = ExecuteExpr(cmd.Args[1]);
                    if ((left is String) && (right is String))
                    {
                        result = ((string)left) + ((string)right);
                    }
                    else
                    {
                        result = ((double)left) + ((double)right);
                    }
                }
                else
                {
                    throw new Exception("Unexpected command: " + cmd.Type);
                }
            }
            return result;
        }
Пример #2
0
        Expr GetIndexed(Expr result, List<Token> tokens, ref int tokenIdx)
        {
            if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.HexOrIndex || tokens[tokenIdx].Type == TokenType.Name))
            {
                Command cmd = new Command(ExprType.Indexed);
                cmd.Args.Add(result);
                cmd.Args.Add(new Literal(tokens[tokenIdx].Type == TokenType.HexOrIndex ? ExprType.Number : ExprType.Name, tokens[tokenIdx].Value));
                tokenIdx++;

                result = cmd;
            }
            return result;
        }
Пример #3
0
        Expr GetDotPropertyChain(Expr result, List<Token> tokens, ref int tokenIdx)
        {
            Expr chain = null;
            if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Dot) &&
                ((tokenIdx + 1) < tokens.Count) && (tokens[tokenIdx + 1].Type == TokenType.Name))
            {
                Token property = tokens[tokenIdx + 1];
                tokenIdx += 2;

                Command cmd = new Command(ExprType.DotPropertyChain);
                cmd.Args.Add(result);
                cmd.Args.Add(new Literal(ExprType.Name, property.Value));
                chain = cmd;

                chain = GetIndexed(chain, tokens, ref tokenIdx);
                chain = GetChain(chain, tokens, ref tokenIdx);
            }
            return chain;
        }
Пример #4
0
 Expr GetDotInstanceDefaultChain(Expr result, List<Token> tokens, ref int tokenIdx)
 {
     Expr chain = null;
     if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Dot) &&
         ((tokenIdx + 1) < tokens.Count) && (tokens[tokenIdx + 1].Type == TokenType.Dot))
     {
         Token token = tokens[tokenIdx];
         tokenIdx += 2;
         Command cmd = new Command(ExprType.DotInstanceDefaultChain);
         chain = cmd;
         cmd.Args.Add(result);
         Expr expr = GetFunction(tokens, ref tokenIdx);
         if (expr == null)
         {
             throw new Exception("Expected a function" + token.Error(2));
         }
         cmd.Args.Add(expr);
     }
     return chain;
 }
Пример #5
0
 Expr GetChain(Expr result, List<Token> tokens, ref int tokenIdx)
 {
     Expr chain = null;
     if ((chain = GetDotInstanceDefaultChain(result, tokens, ref tokenIdx)) != null)
     {
         return chain;
     }
     else if ((chain = GetDotInstanceChain(result, tokens, ref tokenIdx)) != null)
     {
         return chain;
     }
     else if ((chain = GetDotPropertyChain(result, tokens, ref tokenIdx)) != null)
     {
         return chain;
     }
     return result;
 }
Пример #6
0
 Expr GetArithHelper(Expr result, ExprType exprType, List<Token> tokens, ref int tokenIdx)
 {
     Token token = tokens[tokenIdx];
     tokenIdx++;
     Command cmd = new Command(exprType);
     cmd.Args.Add(result);
     Expr expr = GetArith(tokens, ref tokenIdx);
     if (expr == null)
     {
         throw new Exception("Expected a numeric expression" + token.Error());
     }
     cmd.Args.Add(expr);
     return cmd;
 }