README.md (3584B) - raw
1 bf interpreter. 2 3 following: https://eli.thegreenplace.net/2017/adventures-in-jit-compilation-part-1-an-interpreter/ 4 5 using: zig nightly (0.11.0-dev.48+678f3f6e6), download zig at https://ziglang.org/download/ . Other versions may work, no guarantees. 6 7 Note: to run `fixtures/factor.bf`, overflow must be allowed, so build w/ `-Drelease-fast`. 8 9 ## usage 10 11 stages: 12 - og (original) 13 - opt1 (optimized 1) 14 - ... 15 16 ``` 17 zig build <stage> -Drelease-fast -- <bf-source-file> 18 ``` 19 20 There's also a flag to enable tracing of instructions `-Dtrace`, and some fixtures to try in `./fixtures`. So one example run would be: 21 22 ``` 23 zig build opt1 -Drelease-fast -Dtrace -- fixtures/mandelbrot.bf 24 ``` 25 26 ## Notes 27 28 ### Tracing 29 30 Tracing is enabled/disabled at compile time. 31 32 In `build.zig`: 33 34 ```zig 35 // Build option for tracing instructions 36 const trace_value = b.option(bool, "trace", "enable tracing instructions for interpreter") orelse false; 37 const trace_step = b.addOptions(); 38 trace_step.addOption(bool, "TRACE", trace_value); 39 ``` 40 41 creates an option with the flag `-Dtrace`, then assigns it to the variable `TRACE`. 42 43 Then, for each executable generated, the option is assigned to a package which can be imported. 44 45 `build.zig`: 46 ```zig 47 exe.addOptions("build_with_trace", trace_step); 48 ``` 49 50 `main.zig`: 51 ```zig 52 const TRACE = @import("build_with_trace").TRACE; 53 54 pub fn main() anyerror!void { 55 if (TRACE) { 56 std.debug.print("Building with TRACE enabled\n", .{}); 57 } 58 ``` 59 Branches will be automatically eliminated if trace.TRACE is false. 60 61 A comment on discord: 62 https://discord.com/channels/605571803288698900/605572581046747136/950032936399429662 63 64 >there is also aggressive dead-code elimination on comptime-chosen paths. That is to say, if the condition of an if statement/expression is known at comptime (even if the resulting expression is a runtime one), the code of the expression on false will be eliminated, and the contents of the expression of the else clause will be eliminated on true. 65 66 There's probably doc for it, will link if found. 67 68 ## Porting zig to c3 69 70 ``` 71 brainz lynt| ❯ c3c --version 72 C3 Compiler Version: 0.6.7 (Pre-release, Feb 13 2025 09:30:57) 73 Installed directory: /home/hwchen/c3dev/c3c/build/ 74 Git Hash: 27f09ca8884f852fa331c94c9d326c23e3597128 75 Backends: LLVM 76 LLVM version: 18.1.8 77 LLVM default target: x86_64-pc-linux-gnu 78 ``` 79 80 Currently ported just the unoptimized version, but already have some notes 81 . 82 83 - using turnt for snapshot testing, this is already simpler for setting up tests (you don't have to set up writers and readers in unit test framework, or worry about setting up stubs to try to get almost-e2e-testing), but it's also better because you can use the same test suit across different implementations easily. 84 - `anytype` in Zig is really unhelpful, it requires more descriptive arg names to have any idea what kind of type it is at all. 85 - I guess I do find `const` and `var` to be line-noise. I'm uncertain how important having these are, but definitely doesn't matter for small hobby projects. 86 - Zig tendency to chain is actually pretty annoying. I guess this happens in Rust too. Plus the tendency to use a full module prefix, starting from std (probably in part because importing names is such a pain. And I remember shadowing from module names being a pain too). 87 - I guess that this means that recursive imports in c3 are pretty convenient, but I still have a lot of mixed feelings about them, not sure how it'd work out in a larger project. 88 - named params with defaults in c3 feel much better.