Handmade Network»Duikelaar

Recent Activity

Didn't have a lot of time so I didn't finish or get much done for my jam project, but at least I have something...
It modifies .obj's and inserting tracing code. When you run your program, it records where branches and calls are going, and saves that to a file. Then, the user can use another program to view the data which deduces the full execution path and you can look at what your program did, zoom into function calls, etc..
I also wanted to make it work for indirect calls & jmps and in general for bigger programs, and add searching capabilities and recording function args and return values, but alas, no time. That would allow you to do things like search for where in your program you allocated memory, match malloc's to free's, investigate use-after-free's, etc.. &rainman
Also fun fact: a recursive function actually exhibits a Droste effect

Capturing all the instructions executed by a program &rainman

Got started on 'C+ Dev', a C/C+/C++ IDE! &cpdev https://handmade.network/p/236/c-dev/ I can't not make tools please help

Added a nice and easy to use API for my C+ compiler so you can use it as a library. Some random things you can do with it:

  • Setting compiler options dynamically
  • Custom checks: enforce a maximum level of indirection, enforce naming conventions
  • Automatically generating serialization functions for structures
  • Scripting
  • Custom language features: basic RAII, member functions

The video shows an example application that uses this library. I first enter a source file and cmdline options and compile the source file. Then, I can search this compiled file using a filter script (e.g. 'IsFunction(node) MATCH;'). Some boilerplate code gets inserted above and below to make it a valid C function and then it gets compiled, codegen'd, linked against the compiler library and finally launched, all at runtime, nothing gets written to disk. The application then calls into the native code that was generated and uses it to filter the AST, by checking whether 'IsFunction' returns true for a given node, displaying a list of all the matches, which you can then browse around in. The application uses the source information that every AST node has to locate the node in source files. When you click on a 'Token' button, the text editor goes to the corresponding location, and when you ctrl-click on an identifier, the text editor goes to the location of the corresponding definition.

Added operator overloading to my C+ compiler. Most binary and unary operators as well as assignment operators can be overloaded. And a funky feature: '.' and '->' can also be overloaded, so 'int a = b.c;' can be converted to a call like 'int a = operator.(b, "c");'. Probably not very useful, but interesting enough to try.

I also implemented some missing C features, so it will now compile most of C. In order to see how it performs on code I didn't write myself, I tried compiling an open source C project, Zydis (https://zydis.re/), an assembly/disassembly library with a size of about 25kLOC, and I was able to compile the whole project succesfully! I had to write a build script by hand, but after some messing around it was also possible to let CMake generate makefiles that use my compiler, so it is getting closer to be used as a drop-in replacement.

Got around to do some programming on my C (plus) compiler again, so I implemented an x64 backend. Instead of feeding LLVM some IR and letting it generate an .obj, the compiler now first generates its own SSA IR which is very much like LLVM's, which then gets converted to unoptimized x64 machinecode. It also generates debug info (globals, functions, locals, types and line info), so it is now almost functionally equivalent to the LLVM backend. LLVM took about 500ms to just generate an .obj without optimizations, the x64 backend takes more like 25ms (though the resulting code is much slower).

It's very fun for the first time stepping through your program which your compiler compiled all by itself and looking at all the variables 🙂 And to see that even absolutely terrible machinecode is still fast enough for a lot of things on a modern computer...

I just saw some people in #general talking about a hypothetical 'C+' language. Well, let me showcase what I have been working on for the past year or so, coincidentally called CPlus/C+ 🙂 It's mainly C with some QoL extensions:

  • Function overloading;
  • Out-of-order-ness, no forward declarations needed for anything;
  • C++'s auto;
  • Jai's using - still experimental;
  • Defining functions within functions;
  • No separate scopes for structs, unions, globals and types; just one scope for everything; no int promotion; some more lax typecasts;
  • A #define_block+#define_end multiline version of #define meaning no backslashes for multiline #define's;
  • Modules, which are a kind of non-nestable namespaces with some added features - kinda experimental;
  • Most of C11.

The module system and the out-of-order-ness are the most important ones, because they allow easy unity builds, without any header files/forward declarations, and It Just Works.

It's nearing completion featurewise, I am currently working on a X64 backend to go along with LLVM. It is decently stable but it's still completely unoptimized. To test the compiler/language I am building tools and libraries (e.g. GUI lib, profiler, debugger, editor) for it which will eventually form an IDE. It currently compiles ~30K lines of C+.

Images showing some example code and a profiler written from scratch in C+: