lang0/README.md
2025-02-01 17:54:02 +01:00

3.9 KiB

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

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.

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.

func args*

Calls the given function with the given arguments. The result, if any, is ignored.

Builtins

trace

Writes the name and value of the variable passed to stderr if the TRACE environment variable is set.

Standard library functions

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.

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.

fileget path

Reads a file named path from the current directory into a string.

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.

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.

skipchar a

Advances stdin a single character, if it matches the first character of a. Otherwise, exits the program.

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

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.