Expr GetString(List<Token> tokens, ref int tokenIdx) { Expr result = null; if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.String)) { Token token = tokens[tokenIdx]; tokenIdx++; result = new Literal(ExprType.String, token.Value); } return result; }
Expr GetNumber(List<Token> tokens, ref int tokenIdx) { Expr result = null; if (tokens[tokenIdx].Type == TokenType.HexInt) { result = new Literal(ExprType.HexInt, tokens[tokenIdx++].Value); } else if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Number)) { Token token = tokens[tokenIdx]; tokenIdx++; if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Number)) { Token fp = tokens[tokenIdx]; tokenIdx++; result = new Literal(ExprType.Number, token.Value + fp.Value); } else { result = new Literal(ExprType.Number, token.Value); } } return result; }
Expr GetNull(List<Token> tokens, ref int tokenIdx) { Expr result = null; if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Name)) { Token token = tokens[tokenIdx]; if (token.Value.ToLowerInvariant() == "null") { tokenIdx++; result = new Literal(ExprType.Null, token.Value); } } return result; }
Expr GetName(List<Token> tokens, ref int tokenIdx) { Expr result = null; if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Name)) { Token token = tokens[tokenIdx]; tokenIdx++; result = new Literal(ExprType.Name, token.Value); result = GetIndexed(result, tokens, ref tokenIdx); result = GetChain(result, tokens, ref tokenIdx); } return result; }
Expr GetBytes(List<Token> tokens, ref int tokenIdx) { Expr result = null; if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.HexOrIndex)) { Token token = tokens[tokenIdx]; tokenIdx++; result = new Literal(ExprType.Bytes, token.Value); } return result; }
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) { try { result = Variables[literal.Value.ToLowerInvariant()]; } catch (KeyNotFoundException) { result = null; } } 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) { if (literal.Value.EndsWith("L", true, null)) { result = long.Parse(literal.Value.Substring(0, literal.Value.Length - 1), System.Globalization.NumberStyles.AllowHexSpecifier); } else { 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]); object indexArg = ExecuteExpr(cmd.Args[1]); int index = indexArg is Double ? (int)(Double)indexArg : (int)indexArg; 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)) { if (result != null) { Variables[name] = result; } else { Variables.Remove(name); } } else if (result != null) { 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); }