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 result, if any, 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. You can not give an argument if your function is never used in `call`. ### 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 functions #### addstringchar a b `b` is expected to have length 1. 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. #### intinc a Available in it2 runtime and onwards. Interprets string `a` as an integer, increases it by one and returns it (as a string). If `a` cannot be interpreted as an integer, or has additional bytes, this function returns 1. #### lt a b `a` and `b` are expected to have length 1. Return true if a would sort before b. #### mapclear mapname Available in it2 runtime and onwards. Maps are global and can be used from any function. Clears all values set in the map named `mapname`. #### mapgetkey mapname key Available in it2 runtime and onwards. 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 Available in it2 runtime and onwards. Maps are global and can be used from any function. Adds a mapping from `key` to `value` to the map named `mapname`. #### 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. ![A graph of the build setup](t-diagram.png) 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`.