Flower is a programming language

January 2023 status update

What's going on?

I thought I wouldn't get much done in January since I've been extremely swamped with other things. But maybe taking a break in December helped, since some progress did happen. Both in the source code and the design space.

Running the test suite

Last (real) update I talked about language test suite. Like usually, writing a test suite revealed some glaring flaws in the implementation.

I got around to write a lot of simple tests cases like

def func main() -> s32 as {
    return 0;
}

and

def func main() -> s32 as {
    return -(-(2 * 2) - 2;
}

and

def func test_call() -> s32 as {
    def answer = -42;
    return answer;
}

def func main() -> s32 as {
    return -test_call();
}

...and so on. Nothing too complicated yet, but simple things like this end up being very informative and effective at making everything roll smoothly.

The good part is that most of these tests passed straight through the compiler and the virtual machine running them. There was only one bigger error that took more time to fix, and I still am not sure what caused it in the first place. It was a memory error regarding variable-sized-int negation that took couple of days to get straight.

But yey, all the tests passed and I had successfully built a glorified calculator.

Bytecode generation

Since the bytecode needed to be redesigned a bit, and am still quite sure it still requires multiple iterations, I did something a sane man would've done from the get go and split bytecode generation into separate library.

This ended up being a large-ish refactoring, but it really clarified how things work better and I'm decently happy with the current way of doing things (for now at least).

Now I don't directly write the bytecode in the compiler, but call the library functions to write it for me. This also made assembly/disassembly a lot simpler, and probably will speed up the iterations later on.

Pessimising the compiler

There was one annoying thing I noticed. My compiler was too eager to just write many of the tests I used into bytecode that just read return <number>.

Which is working exactly as expected, since pure functions that evaluate into a value can be treated as just that value. This is by design. The problem is that all of these tests really didn't tell me too much about how the virtual machine worked at all, since all it would run is return <value>.

I would need to pessimise the compiler to be able to test the VM properly.

I realised I had to implement basically "write everything verbatim to the bytecode" -switch to the compiler. So, that's the first thing I want to finish in February. When that's done and all the basic examples run with the VM, I can finally go on to a bit more complex basics.

Bit more complex basics?

The compiler now handles most of the "basic basics". It doesn't handle "complex basics". This means, it can handle local variables, arithmetics, (some) type casts, simple branching and function calls (and kinda-handle C function calls as well, but that's going to be burnt in the flames of rebirth).

What it doesn't handle is things like for- or while -loops, user-defined types or global variables. All loops are if + goto at the moment. There is some basic groundwork done for all of these, but I'd say those are still missing for most intents and purposes. Getting started on these is the secondary goal for February.

Also, this codebase officially turns one-year-old next month. Let's see how far we get by that point.

Stats!

Return of the git stats!

 include/fir/bytecode.hpp                                          |  71 +++++
 include/fir/disassembler.hpp                                      |  12 +
 include/{flvm => fir}/type.hpp                                    |  24 +-
 include/fir/value.hpp                                             | 150 +++++++++
 include/fir/varint.hpp                                            | 865 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/flowc/codegen/flir.hpp                                    |  12 +-
 include/flvm/bytecode.hpp                                         | 158 ---------
 include/flvm/common.hpp                                           |   4 -
 include/flvm/disassembler.hpp                                     |  13 -
 include/flvm/flvm.hpp                                             |  16 +-
 include/flvm/function.hpp                                         |  17 +-
 include/flvm/program.hpp                                          |   6 +-
 include/flvm/value.hpp                                            |  34 --
 include/flvm/varint.hpp                                           | 388 ----------------------
 include/{flvm/utility.hpp => util/buffer.hpp}                     |   6 +-
 include/{common => util}/cli.hpp                                  |   0
 include/{flvm => util}/smallvec.hpp                               |  41 +--
 meson.build                                                       |  14 +
 src/codegen/flir.cpp                                              | 636 ++++++++++++++++++++++++++-----------
 src/fir/bytecode.cpp                                              |  87 +++++
 src/{flvm => fir}/disassembler.cpp                                |   8 +-
 src/fir/meson.build                                               |  19 ++
 src/fir/value.cpp                                                 | 241 ++++++++++++++
 src/flvm/bytecode.cpp                                             |   3 -
 src/flvm/flvm_cli.cpp                                             |   8 +-
 src/flvm/function.cpp                                             |  11 +-
 src/flvm/meson.build                                              |   6 +-
 src/flvm/program.cpp                                              |  18 +-
 src/flvm/type.cpp                                                 |   9 -
 src/flvm/value.cpp                                                | 130 --------
 src/flvm/vm.cpp                                                   |  22 +-
 src/meson.build                                                   |   4 +-
 tests/flvm/buffer.cpp                                             |  16 +-
 tests/flvm/meson.build                                            |  31 +-
 tests/flvm/smallvec.cpp                                           |  74 ++---
 tests/flvm/type.cpp                                               | 113 +++++++
 tests/flvm/value.cpp                                              | 261 +++++++++++++++
 tests/flvm/varint.cpp                                             | 236 +++++++++-----
 tests/internal/flir/conversions.cpp                               |  10 +-
 tests/internal/meson.build                                        |   3 +-
 tests/suite/00-simple/tests.py                                    |   5 +-
 tests/suite/01-arithmetics/tests.py                               |  11 -
 tests/suite/01a-integer-arithmetics/div0.flow                     |   3 +
 tests/suite/01a-integer-arithmetics/mul0.flow                     |   3 +
 tests/suite/01a-integer-arithmetics/sub0.flow                     |   3 +
 tests/suite/{01-arithmetics => 01a-integer-arithmetics}/sum0.flow |   0
 tests/suite/01a-integer-arithmetics/tests.py                      |  23 ++
 tests/test_runner.cpp                                             |   5 +
 tools/flc/flc.cpp                                                 |  10 +-
 tools/meson.build                                                 |   4 +-
 update_3rdparty_deps.sh                                           |   3 +
 51 files changed, 2685 insertions(+), 1162 deletions(-)

Posted 2023-01-27 in status