Feat: Error on undefined function Fix: All ids are now prefix to prevent native var clashes. Chore: __check helper function for ease of use
235 lines
4.2 KiB
Markdown
235 lines
4.2 KiB
Markdown
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
|
|
/
|
|
```
|
|
|
|
```sh
|
|
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.
|
|
|
|
#### mapclear mapname
|
|
|
|
Maps are global and can be used from any function.
|
|
|
|
Clears all values set in the map named `mapname`.
|
|
|
|
#### mapgetkey mapname key
|
|
|
|
Maps are global and can be used from any function.
|
|
|
|
Looks up `key` in the map named `mapname` and returns it.
|
|
If not found, returns an empty string.
|
|
|
|
#### mapsetkey mapname key value
|
|
|
|
Maps are global and can be used from any function.
|
|
|
|
Adds a mapping from `key` to `value` to the map named `mapname`.
|
|
|
|
#### not a
|
|
|
|
Returns "1" if a is empty; otherwise, returns "".
|
|
|
|
#### 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
|
|
|
|
```sh
|
|
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`.
|