Feat: add now can add two full strings Fix: it2 would have different working for emit eof Fix: eq and lt would return bools on it0 and it1 Fix: Functions always return something (there is no such thing as an empty type). Fix: Return value from main is now always ignored. Fix: Output from check is same on all iterations
lang0
The base of language; a language designed to be just a compiler for other languages.
And you probably won't write your custom language in lang0, but in a system language built in lang0.
The language
lang0 is designed for building small compilers. As such, it has a number of primitives specific for that.
Examples
See example0.lang0:
main:
declare char
declare isa
declare isnota
calc char peek
calc isa eq char "a"
calc isnota not isa
if isa
emit "Got a"
emit eol
/
if isnota
emit "Did not get a"
emit eol
/
return
/
make it2
cat example0.lang0 | ./it2-out > example0.c
gcc example0.c -o example0
echo 'a' | ./example0
# Got a
echo 'b' | ./example0
# Did not get a
Formatting
Indentation is done using tabs.
Parsing
Pre declaration (functions)
Functions need to be pre-declared if you intend to use them before you have defined them:
func result/
...
func result:
return result
/
Pre declaration (variables)
Variables will need to be declared before you can use them:
func:
declare result
set result "Result"
return result
/
Variables
calc var func args*
Calls func with args and stores the output in var.
declare var
Pre-declares var.
set var "const"
Sets var to "const".
Flow control
break
Exits the deepest forever loop.
func args*
Calls the function name func with the given arguments. The return value is ignored.
if arg
Evaluates arg. If found to be true, descends in the block. Otherwise, skips the block
forever
Repeats the block until break or return is called.
return var?
Returns the given value. If you don't give something to return, the function will return the empty string.
Builtins
check func [arg0..] : msg [arg0..]
Calls the given function with the given arguments. If the function's return value is not found to be true, outputs the given msg and halts the program.
trace
Writes the name and value of the variable passed to stderr if the TRACE environment variable is set.
Standard library constants
eof
End of file character, zero byte.
eol
End of line character.
quote
Double quote character.
Standard library functions
add a b
Creates a new string with b appended to a.
emit arg
Writes the given string to standard output.
eq a b
Return true if the given strings are the same.
lt a b
a and b are expected to have length 1.
Return true if a would sort before b.
peek
Checks stdin for the next character and returns it.
skip
Advances stdin a single character.
stdincolno
Returns the column number for stdin (starting at 1)
stdinlineno
Returns the line number for stdin (starting at 1)
Typing
Every variable is of type string. Every function gets a number of strings as output, and returns another string.
The if statement accept all non-empty strings as true, and the empty string as false.
Notes
You can declare variables and functions ahead of time. This is necessary for some interpreters.
Bootstrap stairs
The first iteration is written by hand, both the compiler and the compiler compiler. It targets python3 as an interpreter.
The second version only has the compile written by hand, with the compiler compiler being the output of iteration 1. It targets gcc as interpreter.
We compile every iteration 3 times, to ensure that the the compiler round trips properly.
How to run
Install python3 and make
make clean all
Get more info
make TRACE=1 clean all
You will now have a lang0 compiler in python for python in ./it1-out.py, and one written in C for C in ./it2-out.
