Skip to content

Managed Expression Evaluator Sample

Gregg Miskelly edited this page Jul 27, 2023 · 14 revisions

To demonstrate integration of a .NET language with the debugger, this repo contains a sample compiler named Iris as well as a .NET Expression Evaluator (EE).

Browsing the Sample

The sample compiler and EE are in the "Iris" directory at the root of the repo. This folder contains several subdirectories:

Directory Description
FrontEndTest Contains unit tests focused on the front end parts of the Iris compiler. These tests can be run from within Visual Studio using "Test Explorer" or outside of Visual Studio by using MSTest.
ic This project is a command line driver for the Iris compiler.
IrisCompiler This project builds a .dll containing the code for the compiler itself. This .dll is referenced by the command line driver as well as the EE component.
IrisExtension This project containing all of the EE components as well as some registration information for the Iris language and EE. We'll go into more detail of IrisExtension below....
IrisRuntime This is the runtime .dll referenced by Iris programs. It currently only contains two methods. One method is used by the compiler to initialize string arrays. The other is the implementation of rand.
vsix This project packages up IrisExtension and IrisCompiler into an extension for Visual Studio.
xplat-package This project is used to produce a folder containing the files needed to run IrisExtension in various cross-platform .NET scenarios (Linux debugging in any VS IDE, VS Code C# debugging on Windows, etc).
Programs This folder contains sample programs written in the Iris language as well as a .cmd file for building them

Building the Sample

  1. Ensure you have the Visual Studio Extension Development workload installed.
  2. First clone the repository (or a fork of the repo) to your local machine.
  3. Open and build Iris.sln in Visual Studio

This project pulls in some NuGet packages so Visual Studio will need to be able to download packages during build. If downloading packages fails, make sure 'Allow NuGet to download missing packages during build.' from Tools -> Options -> NuGet Package Manager, is checked.

Running the Sample

First you'll want an Iris program to debug. The Iris/Programs directory contains a sample program named TicTacToe.iris. We'll use that program to try out the debugger.

To build TicTacToe.iris:

  1. Open a command prompt
  2. cd to /Iris/Programs
  3. Run "build.cmd"

Following these steps should have created TicTacToe.dll and TicTacToe.pdb. We can now try debugging TicTacToe.dll. To do that follow these steps:

  1. Open Iris.sln in Visual Studio (if you don't already have it loaded)
  2. Set 'vsix' as the Startup Project
  3. Run Visual Studio with the Extension using F5 (or Ctrl-F5 if you don't want to debug).
  4. This should cause a new "Experimental" instance of Visual Studio to start, and for it to open ConcordExtensibilitySamples\Iris\Programs\TicTacToe.csproj. This is a dummy project file that has been configured to launch TicTacToe under the debugger. It is also configured to automatically build it.
  5. Push F10 (step)
  6. This should automatically open TicTacToe.iris and you'll be stopped at the "begin" of the main block.

Some things to try with the sample:

  1. Notice that you can set breakpoints, step, and the variable inspection windows are working (Autos window and DataTips require a language service so they will not do anything).
  2. Also notice that advanced features of the debugger such as Set Next Statement, Step into Specific, and Conditional Breakpoints are all available and are flavored in the Iris language.
  3. It's also possible to modify values in the Watch and Locals windows when it's allowed by the compiler.

Implementation of IrisExtension

IrisExtension references both the Iris Compiler .dll as well as the Concord API assemblies (Microsoft.VisualStudio.Debugger.Engine.dll and Microsoft.VisualStudio.Debugger.Metadata.dll).

IrisExtension contains several Concord components as well as some shared code and registration information. Below is a list of the files in IrisExtension and their purpose. Good files to start with are ExpressionCompiler/IrisExpressionCompiler.cs, Formatter/IrisFormatter.cs, and FrameDecoder/IrisFrameDecoder.cs.

File Purpose
AddressComparer.cs This is an IEqualityComparer that allows us to use DkmClrInstructionAddress as a dictionary key in some of the other classes.
InspectionScope.cs Represents the "Scope" of a code location. Its job is translation from the debug engine and CLR's understanding of the current scope into scope information that's understood by the Iris compiler.
InspectionSession.cs This class is used to manage the lifetime of instances of other IrisExtension classes.
Iris.pkgdef This is a .pkgdef file containing the registration for the Iris language. It consists of "compiler ID" and "vendor" GUIDs that match the GUIDS emitted in the symbol (.pdb) files generated by the compiler.
LocalVariable.cs This is a pairing of a Variable and the slot number containing the value. It's used as part of the scope information.
source.extension.vsixmanifest This is the vsix manifest file. The interesting part of this file is the "Assets" section. The asset to take note of is "DebuggerEngineExtension". This is how Concord discovers IrisExtension and loads its components when debugging in the Iris language.
Utility.cs Contains utility functions needed by other classes in IrisExtension

ExpressionCompiler Subdirectory:

File Purpose
AssignmentTranslator.cs This file contains a subclass of the "Translator" class responsible for compiling expressions being assigned to values as well as generating the code for doing the assignment itself. It is the core of the implementation for IDkmClrExpressionCompiler.CompileAssignment
ContextFactory.cs This is a factory for generating instances of the DebugCompilerContext class.
DebugCompilerContext.cs This is a subclass of the "CompilerContext" class. This class contains the context information needed by the compiler and is specific to debugging.
ExpressionCompiler.vsdconfigxml This is the configuration file containing registration information for the Expression Compiler. See the section on component registration files for more information.
ExpressionTranslator.cs This file contains a subclass of the "Translator" class for compiling expressions. It is the core of the implementation for IDkmClrExpressionCompiler.CompileExpression
IrisExpressionCompiler.cs This file is the entry point for the Expression Compiler. It integrates with Concord by implementing IDkmClrExpressionCompiler.
LocalVariablesTranslator.cs This file contains a subclass of the "Translator" class for generating the local variables query. It doesn't do any parsing. Instead it looks through the symbol table and generates methods and local variable entries for all of the symbols that should be shown in the Locals window. It is the core of the implementation for IDkmClrExpressionCompiler.GetClrLocalVariableQuery

Formatter Subdirectory:

File Purpose
Formatter.vsdconfigxml This is the configuration file containing registration information for the Formatter.
IrisFormatter.cs This file is the entry point for the Formatter. It integrates with Concord by implementing IDkmClrFormatter.

FrameDecoder Subdirectory:

File Purpose
FrameDecoder.vsdconfigxml This is the configuration file containing registration information for the FrameDecoder.
IrisFrameDecoder.cs This file is the entry point for the FrameDecoder. It integrates with Concord by implementing IDkmLanguageFrameDecoder.
Clone this wiki locally