(2023-04-22) LVTL is out
------------------------
Yes, I did it. An interpreter of VTL-2 in less than 300 SLOC of pure C89. And
you can get it from my downloads section at hoi.st, a shar.gz with the C
file itself, the shell wrapper unbuf.sh to turn off input buffering for the
programs that use $ for single-character input, and a bunch of example VTL-2
programs taken from the official manual and Rosetta Code.
Note that I labeled this version LVTL-A to stress both on the fact that it's
the very first published revision and the fact it's made as portable as
possible as it only uses the standard ANSI C library. As you may have
guessed, some other, more environment-specific versions **may** appear soon
enough. I won't reveal which versions in particular for now, because I
honestly don't know for sure myself yet, but I do know it is going to be an
interesting journey.
This particular version is also not very speed-optimized and mainly uses the
most naive approach possible to navigate through the loaded code: since
lines might not be entered in order, every iteration finds the next valid
line throughout the entire allocated block of memory. It has no garbage
collector whatsoever either: if the line gets overwritten by its number, it
gets invalidated by labeling it as the line 65535 which is never read. This
is why, in addition to 0, 65535 is also not a valid line number in LVTL.
Because zeroes in the line number positions are used to find the free space
to place the new statement to. I'm not sure how the original VTL-2
implementations did all this but I'm pretty sure no sort of GC could be
implemented in 768 bytes of machine code.
Speaking of which, I wonder if there are any specifications or example code
left for the previous VTL version, VTL-1. If we search "Very Tiny Language"
on teh webz, we either get info on VTL-2 or some Japanese resources
(although some of them have example code which clearly is VTL-2) or Arduino
ports. The only things we know about VTL-1 for sure are the ones we can
deduce from the VTL-2 manual:
* it had less characters allowed per line (not sure how many exactly);
* it had 11 less variables available;
* expressions were not allowed as inputs, only numbers;
* looks like it didn't allow parentheses at all, because...
* ...looks like it supported a single operation per line only;
* it had no array manipulation (*) syntax);
* it had no sysvars for last byte (&) and EOM (*);
* it had no PRNG access (' sysvar);
* it had no single-character input/output ($ sysvar);
* it had no > and < sysvars (well, LVTL doesn't have them either);
* the # sysvar meant "current line number + 1", not just current line number;
Note that I've only listed anything regarding the language features
themselves. Things like "it displayed "OK" after entering numbered lines" or
"it required setting line number to 0 on init" or "it allowed to enter
control characters into lines" are more like particular implementation
details that can easily be altered. Still, there ain't much info on what
this language actually was. Yet, some Japanese guy had produced this wonder
of C coding called vtl7.c (a bit sanitized and reformatted by me):
#include <stdio.h>
#include <stdlib.h>
char c[80];
int v['Z'-'A'] = {0};
int getval(char* p) {
char* q = p;
int a = (int) strtol(p, &p, 0);
if(q == p) {
p++;
return v[*q-'A'];
}
return a;
}
int expr(char* p) {
int a = getval(p);
for(;*p;) {
char op = *p++;
int b = getval(p);
if(op == '+') a += b;
if(op == '-') a -= b;
if(op == '*') a *= b;
if(op == '/') a /= b;
if(op == '=') a = a==b;
if(op == '>') a = a >= b;
if(op == '<') a = a <= b;
}
return a;
}
Now, this is zen. Of course, it's missing a whole lot of features even
compared to the VTL-1 and can't be used for anything beyond a simple
calculator with variables, but it showcases the basic ideas of REPL and
strict LTR expression parsing in less than 40 SLOC of C. To be honest,
adding parentheses to this particular evaluator is not that hard, one just
needs to recursively pass the rest of expression to the same function and
note the amount of parsed characters to further skip on return. Anyway, if
you want to start creating your own VTL flavor, this particular piece of
code is a great starting point.