July Summary

Bold is a fast text editor. You can find details on the home page.

At the beginning of the month, I felt like writing debugger code, and it ended up being what I spent most of the month on.

The first week was spent writing a JSON parser (for use with DAPs and LSPs). I have written a few in the past in different languages, including one that uses SIMD. I never liked any of them for one reason or another (usually API issues), so I wrote one that had a nice API that used SIMD, and although the code isn't perfect, it's pretty close to what I'm looking for. Specifically, it has code for a fast skip (when you're not interested in a value), allows accessing objects by key, and has an iterator. In the past, I'd only implement two of these, and the code would be large (well over a thousand lines). In this version, I was able to anticipate the design and have all 3 while implementing it within 1k lines of code.

Week 2 I started working on DAPs. I reread the protocol and all my old DAP code and noticed a lot was missing. I picked a few DAPs I wanted to support and spent more than a day trying to figure out what they expect in the "launch" request. I'll quote the protocol. "the arguments for this request are not part of this specification". That's right, every adapter can require anything, and there's no standard way to specify args, working directory, env vars, etc. I had to use various techniques to figure them out, I looked at source code, watched TCP packets using wireshark, used a proxy executable to dump the stdin and stdout, and more. This was easily the most annoying part of supporting DAPs. A minor issue was adapter ID, some DAPs won't run if it doesn't see the AdapterID it expect. It would have been annoying to deal with that had I not need to research what DAPs expect for the launch request

Week 3, I took the debug DAP spec JSON and wrote code to generate structs, functions and parsing code. It wasn't as hard as I expected, and I spent more of the week writing test code than on the code generating the above.

Week 4, I thought I should do the same with LSPs specs JSON, since this code was fresh in my mind. That spec is a load of 💩. Looking through it I suspected I wouldn't use a significant amount of requests (I'll haven't looked at enough LSPs to know). There are places where an ID could either be an int or a string. I don't want to deal with both. Another issue is that some responses can have two or three types with overlapping member names. There's no way to know what you parsed until you reach the end of the object. It's extremely annoying, so I decided to generate whatever was easy to generate, and I'll have to write my own struct for various things because I don't want to deal with multiple types because the protocol specified multiple types.