Creating a .NET language
I am interested in creating a language that, when compiled, is interoperable with C#.
I understand the basics of lexing/parsing, but I don't know what would be necessary when compiling the syntax tree to IL in order for the language to be debuggable in something like visual studio or VSCode. I am comfortable approaching IL generation, but I don't know if I will need to generate a PDB or embed some other kind of debug labels in the IL or whatever else may be needed to allow debugging. I'm also not sure if there is anything else I should consider with this.
19 Replies
Draco might be of interest: https://github.com/Draco-lang
It's a language that targets the .NET environment
Gonna ping @Kuinox as well
I did take a look at draco after I saw it mentioned when searching
it seems like it might have its own debugger?
the debugger is optional
a .NET debugger will work for any .NET code
of course, if there is logic in the debugger which handles language-specific elements of the code generation, it will make the debugging experience better
(e.g. showing members of a closure as if they were local variables)
would that include breakpointing in the source code? That's sort of what I am hoping to achieve
you can use any .NET debugger to do breakpoints and stepping for any language
it'll work in the VS debugger, it'll work in any of the open-source .NET debuggers too
all you need really is the pdb
so if I put a breakpoint in a source file of this custom language, it would be hit when running the compiled program in VS?
sure, as long as the PDB is there
is
MetadataBuilder
something I could use for pdb/dll/exe generation? it looks like draco uses that for pdb generation at leastyes, building a portable PDB is done with MetadataBuilder
building the DLL is also done with MetadataBuilder
it is somewhat low-level API (compared to e.g. System.Reflection.Emit) but it gives you full control and the best performance
I can work with that
what about other debugger features like viewing variable values?
that will also mostly just work. though, the set of local variables in IL is not always what the user would 'think' the local variables are
e.g. inside of the delegate,
b
is not actually a local variable, it is a field. so, if you set a breakpoint inside of it, you wouldn't see b
as a "local" just going by the IL locals
the debugger needs special knowledge of how the language generates such constructs in IL to reverse-engineer what the locals 'should be' and create the correct display for the user
this is a purely cosmetic concern, though, since you can of course access fields through a debugger. just won't be as cleanhow would I be able to specify the information it needs to display cases like that correctly?
you can't, it's basically hard-coded into the debugger based on the language implementation
makes sense
I would probably just be happy enough to debug it at all
like, it will know that if it's inside of a class named
<>c__DisplayClassXXX
or whatever, and the document is C#, then it's inside of the method body of a lambdaso the minimum I need to do is generate a dll and a pdb and that should be enough for at least basic debugging?
yeah
thanks for all the help with this
👀