Sample implementation of expression evaluation
Applies to: Visual Studio Visual Studio for Mac
Note
This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here
Important
In Visual Studio 2015, this way of implementing expression evaluators is deprecated. For information about implementing CLR expression evaluators, see CLR expression evaluators and Managed expression evaluator Sample.
For a Watch window expression, Visual Studio calls ParseText to produce an IDebugExpression2 object. IDebugExpressionContext2::ParseText
instantiates an expression evaluator (EE) and calls Parse to get an IDebugParsedExpression object.
The IDebugExpressionEvaluator::Parse
performs the following tasks:
[C++ only] Parses the expression to look for errors.
Instantiates a class (called
CParsedExpression
in this example) that runs theIDebugParsedExpression
interface and stores in the class the expression to be parsed.Returns the
IDebugParsedExpression
interface from theCParsedExpression
object.
Note
In the examples that follow and in the MyCEE sample, the expression evaluator does not separate the parsing from the evaluation.
Managed code
The following code shows an implementation of IDebugExpressionEvaluator::Parse
in managed code. This version of the method defers the parsing to EvaluateSync as the code for parsing also evaluates at the same time (see Evaluate a Watch expression).
namespace EEMC
{
public class CParsedExpression : IDebugParsedExpression
{
public HRESULT Parse(
string expression,
uint parseFlags,
uint radix,
out string errorMessage,
out uint errorPosition,
out IDebugParsedExpression parsedExpression)
{
errorMessage = "";
errorPosition = 0;
parsedExpression =
new CParsedExpression(parseFlags, radix, expression);
return COM.S_OK;
}
}
}
Unmanaged code
The following code is an implementation of IDebugExpressionEvaluator::Parse
in unmanaged code. This method calls a helper function, Parse
, to parse the expression and check for errors, but this method ignores the resulting value. The formal evaluation is deferred to EvaluateSync where the expression is parsed while it is evaluated (see Evaluate a Watch expression).
STDMETHODIMP CExpressionEvaluator::Parse(
in LPCOLESTR pszExpression,
in PARSEFLAGS flags,
in UINT radix,
out BSTR *pbstrErrorMessages,
inout UINT *perrorCount,
out IDebugParsedExpression **ppparsedExpression
)
{
if (pbstrErrorMessages == NULL)
return E_INVALIDARG;
else
*pbstrErrormessages = 0;
if (pparsedExpression == NULL)
return E_INVALIDARG;
else
*pparsedExpression = 0;
if (perrorCount == NULL)
return E_INVALIDARG;
HRESULT hr;
// Look for errors in the expression but ignore results
hr = ::Parse( pszExpression, pbstrErrorMessages );
if (hr != S_OK)
return hr;
CParsedExpression* pparsedExpr = new CParsedExpression( radix, flags, pszExpression );
if (!pparsedExpr)
return E_OUTOFMEMORY;
hr = pparsedExpr->QueryInterface( IID_IDebugParsedExpression,
reinterpret_cast<void**>(ppparsedExpression) );
pparsedExpr->Release();
return hr;
}