diff --git a/content/posts/code_generation_for_simple_arithmetic/note.md b/content/posts/code_generation_for_simple_arithmetic/note.md new file mode 100644 index 0000000..f5cd503 --- /dev/null +++ b/content/posts/code_generation_for_simple_arithmetic/note.md @@ -0,0 +1,66 @@ +X-Date: 2024-08-11T22:05:08Z +X-Note-Id: feb302ea-ad13-4727-befa-83b7d4cc4333 +Subject: First working code generation for simple arithmetic +X-Slug: code_generation_for_simple_arithmetic + +I've got my first bytecode output by the compiler. The runtime now takes a string, parses it into S-expressions, +and passes them to the compilation phase. The compilation phase is more or less one-pass and emits an unoptimized +bytecode for a "register machine". At the moment, the register machine is not there, so no execution yet. But I +already know how to make it because the previous version of Valeri had it. + +This is what the entry point in Valeri looks like now: + +``` +auto code_str = TRY(String::create("(* (+ 1 2 3) 4)")); +auto reader = Reader(code_str); + +auto parsed = TRY(reader.read_one()); +auto code_str_written = TRY(write_one(parsed)); + +// Print the s-expression back, to make sure that +// we've parsed it correctly +TRY(debug_print(code_str_written)); + +auto compiled = TRY(compile(parsed)); +Function& fun = *compiled.to(); + +TRY(debug_print(TRY(fun.constants()))); +TRY(debug_print(TRY(fun.code()))); +``` + +And this is what it outputs to the console: + +``` +(* (+ 1 2 3) 4) + +[1 2 3 4] + +[ + # + # + # + # + # + # + # + # +] +``` + +- The first line here is the expression we are compiling. It is exactly the same as what we've been parsing. +- The second line is an array of constants. They are later referred to as `c` where `` is position +in this array. +- And the rest is text representation of the bytecode. It should be quite obvious what it does, the only thing that +you need to know is that the accumulator is usually the first argument to the instruction. + +In this example, a few things can potentially be eliminated. If I were writing the bytecode by hand, I could've removed +the pointless assignments of constants to registers and instead referred to constants directly in subsequent instructions. +But at this point it will make the compiler a lot more complex than needed for the prototype. + +Next steps will be: + +- Writing a simple virtual machine +- Adding lambda functions, conditionals and such +- Writing a REPL + +Stay tuned.