After seeing C4[1], everything else doesn't seem tiny at all... and maybe it's just me, but this is another one of those projects where I found the directory layout rather confusing, especially for something that claims to be "small and easy to understand." bin/ is empty, there's only a single nearly-empty file in src/, lib/ is also empty, include/tvm is two levels but one is empty, and all the interesting stuff actually appears to be in libtvm/ .
More importantly, even after going through all the files in libtvm/ , I still haven't managed to find the main instruction execution loop nor the decoding switch. Sorry, but I don't think "small and easy to understand" applies, and I've had experience with VMs and interpreters and the like for many years. Compare with this, for example:
A rule-of-thumb when investigating the source code of a project for the first time: if I have to go more than 2 directories deep to get to the "meat" of the code, my desire to explore further drops significantly.
C library public headers are commonly two levels deep to so that projects using them can add the "include" directory to their header search path and in their code have #include "<libname>/header.h". It helps avoid filename clashes.
I dunno, I find it pretty easy to understand... seems like the main instruction loop is in tvm.c, in the function tvm_vm_run(), which is exactly the first place I looked and seems totally sensible to me.
for (; vm->prog->instr[*instr_idx] != -0x1; ++(*instr_idx))
tvm_step(vm, instr_idx);
Compare that to my 6809 emulator [1]. I have a mc6809_run() function that is pretty much the same, but mc6809_step() is in the same file and not hidden in a header file. There also seems to be a lack of memory operations (like reading or writing) other than PUSH/POP.
I find leaving them in the repo makes it pretty clear how your have to configure your build process. For GCC, I instantly know I need `-I ./tinyvm/include/` and can use `#include <tvm/tvm.h>` etc.
Being interested in wanting to write my own languages (though never finding the time with other pet projects) I always wanted to write something that would ultimately be usable with NekoVM as one of my side goals for a language. Neko also has a module for Apache.
rather recently I remembered [0], which I then rebuilt in C using the same memory layout and tried to approximate the functionality of the original thing [1]...
Scanning the syntax, is there an operation for addressing memory? I see an operation for moving one value to another and that's it. I don't see any method of addressing a variable position in memory (or a variable position in an array if one wants to be more managed about it).
I suppose you could handle all operations from the stack.
But I think a lot of things require memory reads and writes, at least to do efficiently.
Great work. After scanning the source tree with my eyes, I have yet to find the implementation of the instruction set. Therefore, I wouldn't say this is small.
More importantly, even after going through all the files in libtvm/ , I still haven't managed to find the main instruction execution loop nor the decoding switch. Sorry, but I don't think "small and easy to understand" applies, and I've had experience with VMs and interpreters and the like for many years. Compare with this, for example:
https://github.com/tjmerritt/z80
A rule-of-thumb when investigating the source code of a project for the first time: if I have to go more than 2 directories deep to get to the "meat" of the code, my desire to explore further drops significantly.
[1] https://news.ycombinator.com/item?id=8558822