A very trivial scripting language implemented in C11. Only for educational purposes.
- Requires CMake 4.2 (Actually, 3.16+ is fine!)
- Make, Ninja, or another build tool
- Clang is preferred
- Usage:
./project.sh help- Statically-linked binary:
./project.sh br - Dynamically-linked demo binary (uses shared lib):
./project.sh sr
- Statically-linked binary:
- Run
./build/tbasic -ifor the debuggable binary. - Run
./tbasic -ifor the release binary. This is to keep a working release binary separate from the debug build.
- BASIC inspired but:
- No line numbers or GOTO.
- And even more QoL extras!
- Add logical operator (&&, ||) support. OK
- Add assignment operator.
- Add variable assignment. OK
- Add loops support. OK
- Add object base. OK
- Add object heap. OK
- Add simple, fixed size list objects. OK
- Add mark & sweep GC. OK
- Add native function library for: OK
- I/O: print(...args)
- Math: powf(), sqrtf(), clamp(), floorf(), and ceilf()
- Add for-loop variation with
BREAK;andCONTINUE;OK - Add negative number literals. OK
- Add object display methods. OK
- Add immutable strings as separate, interned values. OK
- Create string type. OK
- Add more library functions:
stoi,stofOK
- Add "dict objects": OK
- Add
foo["bar"]syntax for accessing any keys of objects vs.::. OK - Add compiler support for not duplicating string constants. OK
- Add compiler support for dict literals. OK
- Add
make_dict_dudopcode to VM & generation. OK
- Make unified API to register native functions & manipulate VM state. OK
- Support shared object library builds, exposing a header API to the shared lib. OK
- Fix IF-ELSE syntax to allow ELSE IF or premature END. OK
- Add null handling operators: OK
- Prefix
?for compact null checks. - Binary Infix
??for null coalescing.
- Prefix
- Fix var hoisting. OK
- Add
RESERVEopcode. - Change variable generations to set a local offset in the RESERVE-d stack slots upon assignment or initialization.
- Implement
RESERVEopcode.
- Add
- Add try-catch & exceptions. OK
- Add bytecode optimization pass with super-instructions. OK
- Refactor compiler to use cleaner tracking of flag changes, passing bitflags per callee. OK
- Refactor VM to trampoline into native calls vs. doing a branch each time. OK
- Fix exceptions to not naively unwind out of the nearest
RET. What if aRETis in aTRYand makes that exception falsely uncaught? OK
- Add
ASSERT <expr>, <simple-expr, call or literal>;OK - Add lambdas: OK
LET foo : FUN (a, b):
RET a + b;
END;
- Add destructuring of lists into a finite set of names. OK
BIND nums : [a, b, c];
- Fix the atrocious compiler errors to be more specific with column numbers per line. OK
- Add debug info per bytecode chunk e.g line & col per statement. OK
- Add closures. OK
FUN makeCounter(x, y):
RET FUN() USES x, y:
x := x + y;
RET x;
END
END
- Add bitwise NOT, AND, OR, XOR, SHL, SHR... Remove RESERVE opcode in favor of a chunk's non-parameter local count. OK
- Add binary / hexadecimal literals. OK
- Add ASCII escapes in strings. OK
- Add iterators. OK
tb_iterator_t: Semantics of a cursor through an object, allowing checking, peeking, and advancing.- NO
chkiterfunction- iterators are testable to a boolean. mkiter(obj): creates iterator.mviter(obj): advances iterator, returns false on end.pkiter(obj): peeks current value of iterator.
- Expand builtin library: OK
- Add
thawfunction:- Args: an object reference
- Sets the object's mutable flag to
TRUE. - Returns
FALSEon non-objects.
- Add
freezefunction:- Args: an object reference
- Sets the object's mutable flag to
FALSE, disallowing mutation of any kind. - Returns
FALSEfor non-objects.
- Add list functions:
lsrev(list): returns true if a list is fed.lscat(dest, src): returnsdestor NIL on success / failure.lsclr(list): returns true if a list is fed.lscut(list, begin, len): returns a new sliced list with given bounds.
- Add file stream functions:
- An
fsobject has the semantics of a tuple with(hidden-filename, 0 => pos, 1 => hasErr, 2 => isEOF). fopen(path, mode: int): returns anfson success butNILon failure.- Modes:
- 0: "r"
- 1: "rb"
- 2: "w"
- 3: "wb"
- Modes:
fclose(fs): returnsTRUEon success.fgetc(fs): returns ASCII code as a 0-255 integer value butNILon failure.fputc(fs, ascii): returnsTRUEon success.fread(fs, buf, n): returnsnfor bytes successfully read but-1on failure.fwrite(fs, buf, n): returnnfor bytes successfully written but-1on failure.
- An
- Add
- Make top-level declarations global by default. OK
- Add diagnostic annotations:
@DOC "This function sorts all items using a predicate."@WARN "This function is too error prone.")
- Add the ability to generate standalone C files which bundle TBasic bytecode & the interpreter as an executable.
- Add macro system.