/// <summary> /// Visit a function expression /// </summary> /// <param name="expression">The expression</param> /// <exception cref="ArgumentNullException">Thrown when the input parameter is null</exception> public void Visit(FunctionExpression expression) { if (expression == null) { throw new ArgumentNullException("expression"); } expression.Expression.Accept(this); object param = result; if (expression.FunctionName == "sizeof") { string customTypeName; int symbolValue; if (param is string) { if ((context.TryResolveCustomType((string)param, out customTypeName) && !DatatypeInfoProvider.IsPredefinedDatatype(customTypeName)) || param.ToString().StartsWith("enum", StringComparison.OrdinalIgnoreCase) || param.ToString().StartsWith("struct", StringComparison.OrdinalIgnoreCase) || param.ToString().StartsWith("union", StringComparison.OrdinalIgnoreCase)) { result = "sizeof(" + param.ToString() + ")"; } else { result = DatatypeInfoProvider.GetRpcDatatypeLength((string)param); } } else if (context.TryResolveSymbol(expression.Text, out symbolValue)) { Type value = param.GetType(); string typeName = String.Empty; switch (value.ToString()) { case "System.Char": typeName = "char"; break; case "System.Byte": typeName = "byte"; break; case "System.Int16": typeName = "short"; break; case "System.Int32": typeName = "int"; break; case "System.Boolean": typeName = "boolean"; break; default: break; } result = DatatypeInfoProvider.GetRpcDatatypeLength(typeName); } if (result is int && (int)result <= 0) { throw new ExpressionEvaluatorException( string.Format(CultureInfo.InvariantCulture, "cannot get the datatype length for the datatype '{0}'", param)); } } }
/// <summary> /// The Literal operation /// </summary> /// <returns>An expression node created based on the operation</returns> protected ExpressionNode Literal() { if (currentToken.Text.Length > 0) { if (currentToken.Type == TokenType.Integer) { int res; if (TryConvertNumber(currentToken.Text, out res)) { ExpressionNode integer = new ExpressionNode( new Token(TokenType.Integer, res.ToString(CultureInfo.InvariantCulture))); GetNextToken(); return(integer); } else { throw new ExpressionEvaluatorException( string.Format(CultureInfo.InvariantCulture, "invalid number '{0}'", currentToken.Text)); } } else if (currentToken.Type == TokenType.String) { int x; if (!context.TryResolveSymbol(currentToken.Text, out x)) { string tokenText = currentToken.Text; while (true) { if (context.Variables != null && !context.Variables.ContainsKey(currentToken.Text) && !DatatypeInfoProvider.IsPredefinedDatatype(currentToken.Text) && !DatatypeInfoProvider.isPredefinedModifier(currentToken.Text)) { string typeInfo; if (context.TryResolveCustomType(currentToken.Text, out typeInfo)) { tokenText = typeInfo; break; } else { context.ReportError( string.Format(CultureInfo.InvariantCulture, "cannot resolve symbol '{0}'", currentToken.Text)); break; } } if (context.Variables != null && context.Variables.ContainsKey(currentToken.Text)) { tokenText = currentToken.Text; break; } // treat predefinedModifier as empty node if (DatatypeInfoProvider.isPredefinedModifier(currentToken.Text)) { GetNextToken(); } else if (DatatypeInfoProvider.IsPredefinedDatatype(currentToken.Text)) { tokenText = currentToken.Text; break; } } // in order to get pointer type size and avoid related issue bool isPointerType = false; GetNextToken(); if (isInSizeOf) { while (currentToken.Text == "*") { GetNextToken(); isPointerType = true; } } if (isPointerType) { ExpressionNode integer = new ExpressionNode( new Token(TokenType.Integer, "4")); return(integer); } ExpressionNode variable = new ExpressionNode( new Token(TokenType.Variable, tokenText)); return(variable); } else if (isInSizeOf) { string tokenText = currentToken.Text; GetNextToken(); //ignoring other expression while (currentToken.Text != ")") { GetNextToken(); } return(new ExpressionNode( new Token(TokenType.Variable, tokenText))); } else { GetNextToken(); return(new ExpressionNode( new Token(TokenType.Integer, x.ToString(CultureInfo.InvariantCulture)))); } } else { throw new ExpressionEvaluatorException( string.Format(CultureInfo.InvariantCulture, "unexpected token '{0}'", currentToken)); } } else { throw new ExpressionEvaluatorException("unexpected end of input"); } }