Tbdlang Documentation
Alpha Version 2, Zig 0.15.2 implementation

Tbdlang is designed as a lightweight, small, 
simple and safe virtual machine language. This
means all code written in tbdlang is executed
inside of a virtual machine and does not perform
host operations unless explicitly allowed.

Tbdlang puts the priority of size and simplicity
first. It is definitely not the fastest language, 
but it is incredibly compact and simplistic for 
what it can do.

Tbdlang has no types. The type of data is implied
and guessed at runtime based on the operation being
performed on the data.

This document can either be viewed from the source
code tree at docs.txt, or via the version embedded
into the vm, viewable by simply typing

	> ./vm docs

after you compile a release.

The vm also has commands to view version information
and run a testing program written in tbdlang embedded
into the vm as simple commands. Said commands are
simply version and test, respectively.

Tbdlang uses a few keywords to represent operations.
These keywords include
	New - define or modify a variable
	Escape - execute pre-compiled Zig code embedded into the vm
	Func - define a function
	End - end a function definition
	Return - return from a function
	If - execute a function on a conditional
	Call - call a function

New uses the syntax of
New (varname) (data payload)
where varname is the name of the variable to manipulate.
The data payload can either be quoted data (" ") to
represent a literal value or a mathematical operation
or unquoted data to represent another variable.
If the data in unquoted, the data in the variable
referenced will be copied into the variable being mutated.
Data quoted using single quotes (' ') will be treated as a
true literal, as in no operation will be performed on it
besides a store, unlike double quoted data (" "), marking
a literal, which is checked for mathematical expressions.
Data placed inside of curly braces ({ }) will be evaluated
as an indirect, as in the value will be pulled from a variable,
evaluated, and then the result of that will be stored.
Literals and True Literals are the same in most cases, except 
for when the data is a math operation or the name of a variable.
It is generally better to use True Literals instead of Literals
to hold raw data payloads, but they are interchangeable in
most cases.

Math operations also support variable referencing.

Escape is used to execute functions not available to standard
tbdlang, such as system-level operations. This is done by
compiling Zig programs that work with the virtual machine
directly into the main binary of the virtual machine.
This allows for safe, controlled host execution.
Escape uses the syntax of simply the escape operation's name
placed after the keyword. 
Most of the standard library is written in Zig using Escape.

Func is used to define a function for later execution.
This is done with the Func keyword followed by the name of the
function to define. Then the instructions to execute when
the function is called should come after the keyword on a 
newline and should be ended by a newline followed by the End
keyword.

Return is used to return from a function early. It simply
returns to the caller of the function.

If is used to execute a function only if a condition is true.
It uses the syntax of

	> If (funcname) "(condition)"

where funcname is the function to execute and condition is
the condition to execute it on. Remember, this language
has no types, so a zero (0) is true and a one (1) is false.

Eg.

	Func testFunc
	New var "5"
	End
	If testFunc "5 > 3"

If 5 is greater than 3, execute function testFunc, which will
create a new variable named var equivalent to 5.

The function could also be executed instantly by the Call
statement.

	Call testfunc

Comments can be placed using the # keyword. If the first
character on a line is the comment keyword, then the line
is ignored, just as empty lines are.

Examples

	New b "12"
	New func testFunc
	New a "3 + b"
	New ARG1 "a"
	Escape Print
	End
	Call testFunc

The vm provides some decent math and string operations.
Math operations include

	+  - add two numbers
	-  - subtract two numbers
	/  - divide two numbers
	*  - multiply two numbers
	== - compare two numbers
	>  - compare if greater than
	<  - compare if less than

String operators include

	-?= - contains?
	e?= - contains at the end?
	s?= - contains at the start?
	?=  - equal?
	s++ - merge two strings

Math and string operators can be performed via the New
and If keywords. The values are automatically substituted
before the instruction is interpreted for New.

Comparison operations return 0 if true and 1 if false.
Other operators simply return the result.

Examples

	New a "ab -?= cd" # stores 0 if true
	New b "ab e?= cd" # stores 0 if true
	New c "ab s?= cd" # stores 0 if true
	New d "ab ?= cd" # stores 0 if true
	New e "ab s++ cd" # stores "abcd"
	New f "e s++ cd" # stores "abcdcd"

In a math operation, the values are assumed to be
a variable unless they are not found.

You may be thinking, "Where are my loops?" and such
other features. The vm stays small by making existing
primitives expressive enough to build more complex
ones on top of it.

Eg. a loop could literally be

	Func count
	New ARG1 'counter'
	Escape Print
	New counter "counter - 1"
	If count "counter > 0"
	End


	New counter '10'
	Call count

And now you have a loop. Pretty simple, hm?

The build script (build.zig) allows for the standard
Zig optimization targets of Debug, ReleaseSafe,
ReleaseFast, and ReleaseSmall. However, if Debug is
chosen, then vm debug output is enabled. This will
dump information on the vm state once before every
instruction executes.


The standard library can be found from the source tree
at libs/zig/ - this directory contains everything defined
as an Escape operation and is compiled into the vm.

The operations include

Print - Print data 
	Takes one variable, ARG1, as an indirect to another
	variable. Prints the data in the second variable
	to standard output.

		New msg "Hello, World!" # define text
		Mew ARG1 'msg' # Set ARG1 to have text msg
		Escape Print  # escape from VM and Print

Input - Get user input
	Reads from user input until newline and stores it as
	variable input.

		Escape Input # pauses, gets user input, saves it
			     # to var input, returns to execution

Fread - Read a file
	Takes one variable, ARG1, as an indirect to another
	variable. Reads the contents of the file under the
	name held in the second variable and stores it to
	a variable named fileData.

		New file 'file' # set the file name
		New ARG1 'file' # set the variable holding the 
				# file name
		Escape Fread 	# read the file - var fileData holds 
				# the file data now

Fwrite - Write to a file
	Takes two variables, ARG1, as an indirect to the data
	to write to the file and ARG2 as an indirect to the
	name of the file to write. Fwrite handles escape sequences
	and formatting.

		New ARG2 'file'
		New ARG1 'msg'
		New file 'text.txt'
		New msg 'Hello from tbdlang!\n'
		Escape Fwrite

Fbwrite - Write binary to a file
	Just like Fwrite, but it does not interpret the data in
	any way - it just writes it as raw binary.

Random - Generate a random number
	Generates a random u32 number and places it into 
	variable random.

		Escape Random # var random now contains a 
			      # random number

StrLen - Get the length of a string
	Takes one variable, ARG1, as an indirect to another
	variable. Returns the length of the string in the 
	variable referenced by ARG1 and returns it into a
	variable named len.

		New ARG1 'str'
		New str 'hi'
		Escape StrLen # var len now has 2 in it

StrSplitNumL - get the contents of a string before N chars
	Takes two variables, ARG1 as an indirect to the
	variable holding the string and ARG2 as an indirect 
	to the number of chars until the end. The new data
	is saved to a var named strLeft. (minus 1 char)

		New ARG1 'str'
		New str 'hello'
		New ARG2 'numb'
		New numb '3'
		Escape StrSplitNumL # strLeft now contains
				    # characters 'lo'

StrSplitNumR - get the contents of a string after N chars
	Same thing as StrSplitNumL but addressing the
	characters after the reference and outputting
	to var strRight (plus 1 char relative to the last)


A module from the standard library can be removed by editing
src/escapes.zig and commenting out the line marking the escape.
