Every program in the compiler's own examples/ directory.
Copied verbatim from examples/ in the Voxlang repo, from a one-line hello to a shell-free process supervisor.
Checked against vox 0.4.16 on 2026-10-16: 27 of 27 examples passed.
The smallest complete Voxlang program: one sentence, compiled straight to a working binary.
Print "Hello, World!".
A greeter that reads its own command line and environment through the 's property syntax, then asks your name and answers you.
(A greeter. It reads its own command line and environment through the 's property syntax, then asks for your name and answers you.) Print "The command line". A number called 'argument count' is arguments's count. Print "Arguments, counting the program's own name: {argument count}". A text called program is arguments's name. Print "This program was started as {program}". (Greet whoever is named first on the command line, or else the world) A text called name is "World". If arguments's count is greater than 1 then, the name is arguments's first. Print "Hello, {name}!". If arguments's empty then, Print "(Nothing was given after the program's name.)". Print "". Print "The environment". A number called 'variable count' is environment's count. Print "Environment variables: {variable count}". (An environment variable is read by its name) A text called user is environment's "USER". Print "You are logged in as {user}.". A text called home is environment's "HOME". Print "Your home directory is {home}.". A text called 'first variable' is environment's first. Print "The first entry in the environment is {first variable}.". Print "". Print "A conversation". Open a file for writing called screen at "/dev/stdout". Open a file for reading called keyboard at "/dev/stdin". A buffer called answer is 256 bytes in size. Print "What's your name?". (A line read from the keyboard keeps the newline typed after it, so the answer ends the greeting's line by itself) Read line from keyboard into answer. A text called 'your name' is answer. Write "Nice to meet you, {your name}" to screen.
FizzBuzz over 1–15, with a defined function and chained "but if" conditions.
To 'divides evenly' with a number called dividend and a number called divisor. Return a boolean, dividend modulo divisor is 0. Print each number from 1 to 15, but if 'divides evenly' with the number and 15 print "FizzBuzz", but if 'divides evenly' with the number and 3 print "Fizz", but if 'divides evenly' with the number and 5 print "Buzz".
Add, subtract, multiply, divide and modulo, said in words and worked through apples and pears, a room in metres, a recipe changed step by step, and a walk in kilometres.
(Arithmetic in Vox is said in words: plus, minus, times, divide and modulo. Each line below says the sum aloud, then works it out in braces.) Print "Whole numbers". Set apples to 10. Set pears to 3. Print "The bowl holds 10 apples and 3 pears.". Print "". Print "Pieces of fruit altogether, apples plus pears: {apples plus pears}". Print "How many more apples than pears, apples minus pears: {apples minus pears}". Print "Ways to pick one apple and one pear, apples times pears: {apples times pears}". Print "Apples for each pear, apples divided by pears: {apples divide pears}". Print "Apples left over, the remainder of apples divided by pears: {apples modulo pears}". Print "". Print "Decimals". Set length to 10.5. Set width to 3.2. Print "The room is 10.5 metres long and 3.2 metres wide.". Print "". (A decimal is a 64-bit float, so a sum like 10.5 plus 3.2 shows the rounding of its last binary digit) Print "Half the way around the walls, length plus width: {length plus width}". Print "How much longer than wide, length minus width: {length minus width}". Print "Floor area, length times width: {length times width}". Print "How many widths make the length, length divided by width: {length divide width}". Print "". Print "One value, changed step by step". Set flour to 5.0. Print "The recipe starts with 5.0 cups of flour.". Set flour to flour plus 2.5. Print "After adding 2.5 cups: {flour}". Set flour to flour times 2.0. Print "After doubling the recipe: {flour}". Set flour to flour minus 3.0. Print "After setting 3.0 cups aside: {flour}". Set flour to flour divide 2.0. Print "Shared between two bowls, each bowl holds: {flour}". Print "". Print "Comparisons". If length is greater than 10.0 then, print "The room is more than 10 metres long.". Otherwise, print "The room is 10 metres long or less.". If width is less than 3.5 then, print "It is narrower than 3.5 metres.". Otherwise, print "It is 3.5 metres wide or more.". If flour is equal to 6.0 then, print "Each bowl holds exactly 6.0 cups.". Otherwise, print "The bowls hold something other than 6.0 cups.". Print "". Print "Counting with a decimal". Print "A five-kilometre walk, one marker at a time:". Set kilometres to 0.0. While kilometres is less than 5.0, Print kilometres, Set kilometres to kilometres plus 1.0.
Converting between floats, numbers, text and booleans with the word 'as': truncating, rounding by adding a half first, and casting inline inside a Print.
(The word "as" turns a value into another type: "the pi as a number".) Print "Number and float conversions". (A float becomes a number by dropping everything after the point) A float called pi is 3.14159. A number called 'pi truncated' is the pi as a number. Print "3.14159 as a number: {pi truncated}". A number called quantity is 42. Print "42 as a float: {quantity as a float}". (Adding a half before truncating rounds to the nearest whole number; the braces make the sum happen before the cast) A float called measurement is 3.7. A number called rounded is {the measurement add 0.5} as a number. Print "3.7 rounded: {rounded}". Print "". Print "Number and text conversions". A number called age is 25. Print "Age: {age as text}". Print "". Print "Boolean and number conversions". A boolean called 'switched on' is true. Print "true as a number: {'switched on' as a number}". A boolean called 'switched off' is false. Print "false as a number: {'switched off' as a number}". Print "". Print "3.99, cast to a number where it is printed:". Print 3.99 as a number.
Curly-brace interpolation in printed text: variables and calculations inside a string, decimal places, padding, hex, binary and octal, and literal braces.
(A name in braces inside a string prints its value there, and a colon after the name says how to lay the value out) Print "Basic string interpolation". A text called name is "Alice". A number called age is 25. Print "Hello, {name}! You are {age} years old.". A text called city is "London". Print "{name} lives in {city} and is {age}.". Print "". Print "Number formatting". (A point and a count give the number of decimal places) A float called pi is 3.14159265358979. Print "Pi to 2 decimals: {pi:.2}". Print "Pi to 4 decimals: {pi:.4}". Print "Pi to 0 decimals: {pi:.0}". (A width pads with spaces, or with zeros when it starts with 0) A number called score is 42. Print "Padded to 6 chars: [{score:6}]". Print "Zero-padded: [{score:06}]". Print "". Print "Different number bases". (Hexadecimal and octal always carry their 0x and 0o, and a width counts only the digits after it) A number called value is 255. Print "Decimal: {value}". Print "Hexadecimal: {value:x}". Print "Hex uppercase: {value:X}". Print "Binary: {value:b}". Print "Octal: {value:o}". Print "With prefix: {value:x}". Print "Padded hex: {value:04x}". Print "". Print "Escape sequences". (Doubled braces print as braces, not as a value) Print "Use {{braces}} for literal braces.". Print "Tab:\there". Print "Newline in string:\nSecond line". Print "". Print "Formatting expressions". (Arithmetic works inside the braces too) A number called x is 10. A number called y is 3. Print "x + y = {x add y}". Print "x * y = {x multiply y}". Print "Argument count: {arguments's count}". Print "". Print "In practice". A float called price is 19.99. Print "Total: ${price:.2}". A float called ratio is 0.756. Print "Progress: {ratio multiply 100:.1}%".
The word 'and' doing the jobs it does in English: joining two conditions, listing parameters and arguments, ending a list of subjects before 'are', and pairing two 'each' clauses.
(The word "and" does the jobs in Vox that it does in English. It joins two conditions, it lists a function's parameters and a call's arguments, it ends a list of subjects before "are", and it joins two "each" clauses so that one call runs for every pair.) To total with a number called first and a number called second. Return a number, first add second. To volume with a number called length and a number called width and a number called height. Return a number, length multiply width multiply height. To 'suggest an outfit' with a text called shirt and a text called tie. Print "a {shirt} shirt with a {tie} tie". Print "Joining two conditions". A boolean called sunny is true. A boolean called warm is true. A boolean called raining is false. If sunny and warm then, Print "Perfect weather for a picnic!". If sunny and raining then, Print "Look out for a rainbow!". Otherwise, Print "No rainbow today.". Print "". Print "Listing parameters and arguments". Print "The total of 3 and 5: {total of 3 and 5}". Print "The volume of a box 2 by 3 by 4: {volume of 2 and 3 and 4}". A number called 'morning visitors' is 10. A number called 'afternoon visitors' is 20. Print "Visitors all day: {total with 'morning visitors' and 'afternoon visitors'}". Print "". Print "Ending a list of subjects". A boolean called 'engine running' is false. A boolean called 'doors locked' is false. A boolean called 'seatbelt fastened' is false. If 'engine running', 'doors locked', and 'seatbelt fastened' are not true then, Print "Everything is off, so it is safe to leave the car.". Set 'engine running' to true. Set 'doors locked' to true. Set 'seatbelt fastened' to true. If 'engine running', 'doors locked', and 'seatbelt fastened' are true then, Print "Everything is on, so the car is ready to drive.". A boolean called 'left door shut' is true. A boolean called 'right door shut' is true. If 'left door shut' and 'right door shut' then, Print "Both doors are shut.". Print "". Print "Several uses in one sentence". If sunny and warm then, Print "Picnic baskets for the morning and afternoon visitors: {total of 'morning visitors' and 'afternoon visitors'}". Print "". Print "Joining two each clauses". Print "Every shirt with every tie:". 'suggest an outfit' of each shirt from ["white", "blue"] and each tie from ["red", "green"].
Loop expansion turns one action into a loop: one each clause runs it once per item, two make a grid, and a but if clause flags the one class that is full.
(Loop expansion turns one action into a loop: an action that takes "each craft from crafts" runs once for every craft. Several each clauses make a grid, and a but if clause branches inside it.) To 'announce a class' with a text called craft. Print "This week: {craft}.". A list called crafts is ["pottery", "weaving", "smithing"]. (A single each clause turns one call into one per item) 'announce a class' of each craft from crafts. Print "". To 'pair a tool with a material' with a text called tool and a text called material. Print "{tool} works {material}". A list called tools is ["chisel", "loom"]. A list called materials is ["clay", "wool"]. (Two each clauses chain into a grid: the leftmost clause is the outer loop, so every tool gets a turn with every material) 'pair a tool with a material' of each tool from tools and each material from materials. Print "". To 'schedule a class' with a text called weekday and a text called craft. Print "{weekday}: {craft} class". A list called weekdays is ["Monday", "Wednesday"]. (A but if branch is checked on every call of a grid, so its condition can read every loop variable at once: here it flags the one booked slot) 'schedule a class' of each weekday from weekdays and each craft from crafts, but if weekday is "Wednesday" and craft is "smithing" print "{weekday}: smithing is full, try next week".
Lists of numbers, booleans and words: looping over each element, reading one by position counting from 1, taking the first, last and size, and catching an out-of-range read with On error.
Print "Lists". Print "Integer list [10, 20, 30]:". A list called 'the numbers' is [10, 20, 30]. For each number in 'the numbers', print the number. Print "". (Elements are counted from 1, the way a person counts them) Print "Second element of the numbers: {element 2 of 'the numbers'}". Print "Boolean list [true, true, false]:". A list called answers is [true, true, false]. For each answer in answers, print the answer. Print "". Print "First answer: {answers's first}". Print "Last answer: {answers's last}". Print "Number of answers: {answers's size}". Print "You should see an error below". (Reading past the end is what raises the error caught on the next line) A boolean called 'answer out of range' is element 100 of answers. On error print "Cannot access element 100 - out of bounds!". Print "Word list [\"hello\", \"world\"]:". A list called words is ["hello", "world"]. For each word in words, print the word.
Key/value maps: literals, reading and setting by key, iterating keys and values, a list and another map nested inside one, and a missing key caught with On error.
(A map holds values under text keys and keeps them in the order they were added. Looking up a missing key raises the error that "on error" catches. A map passed as a value keeps its type through the call, so it still prints as a map.) To 'print the record' with a value called record. Print record. A map called person is {"name": "Ada", "age": 36, "city": "London"}. Print "The record: {person}". A text called name is person's "name". Print "The name is {name}.". Set person's "age" to 37. A number called age is person's "age". Print "After a birthday the age is {age}, and the record holds {person's length} entries.". Print "Keys:". For each key in person's keys, print key. Print "Values:". For each detail in person's values, print detail. A map called nested is {"tags": ["a", "b"], "meta": {"id": 1}}. Print "Nested: {nested}". A list called tags is nested's "tags". Print "Tags: {tags}". A map called meta is nested's "meta". A number called id is meta's "id". Print "The meta id is {id}.". Print "The record, printed by a function that takes any value:". 'print the record' of person. Print person's "nope". On error print "Looked up a missing key.".
Lists inside lists: a tree of numbers, words and branches, one branch read out on its own, and "is a list" telling a branch from a single value.
(A list element may itself be a list, and "is a list" tells the two apart) A list called tree is [1, [2, 3], "four", [5, [6, 7]]]. Print tree. A list called branch is element 2 of tree. Print branch. Print branch's length. For each number in branch, print number. For each item in tree, if item is a list then, print "list". Otherwise, print "scalar".
A mixed list of a number, a text and a decimal, classified by type and round-tripped through a value-returning function.
(A value parameter carries a type alongside its contents, so one function can take a number, a text or a decimal and ask which it was given. A value returned from a function carries its type back out, so it survives the trip in both directions.) To 'name the type' with a value called item. If item is a number, print "number". Otherwise if item is a text, print "text". Otherwise print "decimal". To echo with a value called item. Return a value, item. A list called samples is [42, "hello", 3.14]. Print "Classifying each element:". For each item in samples, 'name the type' of item. A list called echoed is []. For each item in samples, append echo of item to echoed. Print "After round-trip through echo, still:". For each item in echoed, 'name the type' of item.
A morning's delivery round built from types of the program's own making: stops and legs that copy whole, print themselves and compare corner for corner.
(A morning's deliveries, written with types of the program's own making. A stop is a corner of the town grid; a leg is one drive between two stops. Kept as loose numbers this would be four variables per leg, held in step by hand and easy to get wrong. Kept as things, a stop travels as one value: it copies whole, it prints itself, and two stops compare corner for corner.) A thing called stop has a function called 'at the corner of', a number called street is 0, a number called avenue is 0. A thing called leg has a stop called start, a stop called end. To do the stop's 'at the corner of', with a number called street and a number called avenue. A stop called corner. Set corner's street to street. Set corner's avenue to avenue. Return a stop, corner. (The van drives along the streets and never through the buildings, so a leg is as long as the blocks crossed one way plus the blocks crossed the other. Its first parameter is a whole leg, which is what lets a leg be asked for its own length: drive's 'the blocks driven'.) To 'the blocks driven' with a leg called drive. A number called 'streets crossed' is drive's end's street subtract drive's start's street. If 'streets crossed' is less than 0 then, Set 'streets crossed' to 0 subtract 'streets crossed'. A number called 'avenues crossed' is drive's end's avenue subtract drive's start's avenue. If 'avenues crossed' is less than 0 then, Set 'avenues crossed' to 0 subtract 'avenues crossed'. Return a number, 'streets crossed' add 'avenues crossed'. The depot is a stop's 'at the corner of' with 1 and 1. The bakery is a stop's 'at the corner of' with 4 and 1. The school is a stop's 'at the corner of' with 4 and 5. Print "The depot stands at {depot}.". (Each leg begins where the last one ended, so the whole round is one leg moved along, not a fresh pair of corners every time.) A leg called drive. A number called 'blocks driven today' is 0. Set drive's start to depot. Set drive's end to bakery. Print "The first leg is {drive}.". Set 'blocks driven today' to 'blocks driven today' add drive's 'the blocks driven'. Print "The bakery is {drive's 'the blocks driven'} blocks from the depot.". Set drive's start to drive's end. Set drive's end to school. Set 'blocks driven today' to 'blocks driven today' add drive's 'the blocks driven'. Print "Then {drive's 'the blocks driven'} blocks on to the school.". Set drive's start to drive's end. Set drive's end to depot. Set 'blocks driven today' to 'blocks driven today' add drive's 'the blocks driven'. Print "And {drive's 'the blocks driven'} blocks home again.". Print "The round comes to {blocks driven today} blocks.". (A thing is a value, so the van parked at the school holds a copy of that corner. Sending the van on cannot move the school.) A stop called van is school. Set van's avenue to 9. Print "The van has gone on to {van}, and the school is still at {school}.". (Two stops are equal when they are the same corner, field for field.) If drive's end is depot then, Print "The van is home for the day.".
Hex and binary literals, bitwise and, or, xor and shifts, and a buffer read, patched and copied one byte at a time, ending in a small hex dump.
(Hex and binary literals, bitwise operations, and a buffer read and written one byte at a time) Print "Hexadecimal literals". A number called red is 0xFF. A number called green is 0x80. A number called blue is 0x40. Print "Red component: {red} ({red:02X})". Print "Green component: {green} ({green:02X})". Print "Blue component: {blue} ({blue:02X})". (Red is the high byte of a colour and blue the low one) A number called rgb is red multiply 65536 add green multiply 256 add blue. Print "Combined RGB: {rgb:06X}". Print "". Print "Binary literals". A number called flags is 0b10110100. Print "Flags: {flags} (binary: {flags:b})". Print "Flags padded: {flags:08b}". Print "". Print "Working with the bytes of a buffer". Create a buffer called memory of size 16. (Bytes are counted from 1, the way a person counts them) Set byte 1 of memory to 0x48. Set byte 2 of memory to 0x65. Set byte 3 of memory to 0x6C. Set byte 4 of memory to 0x6C. Set byte 5 of memory to 0x6F. A number called 'first byte' is byte 1 of memory. Print "First byte: {first byte:02X}". Print "Buffer contents: {memory}". Print "". Print "Changing a byte". Set byte 5 of memory to 0x21. Print "After changing byte 5 to '!': {memory}". Print "". Print "Bitwise operations". A number called 'high bits' is 0b11110000. A number called 'alternate bits' is 0b10101010. A number called result is 'high bits' bit-and 'alternate bits'. Print "{high bits:08b} AND {alternate bits:08b} = {result:08b}". Set result to 'high bits' bit-or 'alternate bits'. Print "{high bits:08b} OR {alternate bits:08b} = {result:08b}". Set result to 'high bits' bit-xor 'alternate bits'. Print "{high bits:08b} XOR {alternate bits:08b} = {result:08b}". (Exclusive or with a byte of all ones flips every bit, which is NOT) Set result to 'high bits' bit-xor 0xFF. Print "NOT {high bits:08b} = {result:08b}". Set result to 'high bits' bit-shift-left 2. Print "{high bits:08b} << 2 = {result:08b}". Set result to 'high bits' bit-shift-right 2. Print "{high bits:08b} >> 2 = {result:08b}". Print "". Print "A simple hex dump". A list called 'magic bytes' is [0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE]. For each position from 1 to 8, set byte position of memory to element position of 'magic bytes'. Print "Hex dump of first 8 bytes:". Set position to 1. While position is less than or equal to 8, a number called 'byte value' is byte position of memory, Print "{byte value:02X} " without newline, increment position. Print "". Print "". Print "Patching a binary value". (A 32-bit value is stored lowest byte first, so each byte is worth 256 times the one before it) A number called 'lowest byte' is byte 1 of memory. A number called 'second byte' is byte 2 of memory. A number called 'third byte' is byte 3 of memory. A number called 'highest byte' is byte 4 of memory. A number called 'stored value' is 'lowest byte' add 'second byte' multiply 256 add 'third byte' multiply 65536 add 'highest byte' multiply 16777216. Print "32-bit value at offset 0: {stored value:08X}". A number called 'new value' is 0x12345678. Set byte 1 of memory to 'new value' bit-and 0xFF. Set byte 2 of memory to 'new value' bit-shift-right 8 bit-and 0xFF. Set byte 3 of memory to 'new value' bit-shift-right 16 bit-and 0xFF. Set byte 4 of memory to 'new value' bit-shift-right 24 bit-and 0xFF. Print "After patching with 0x12345678:". Set position to 1. While position is less than or equal to 4, Set 'byte value' to byte position of memory, Print "{byte value:02X} " without newline, increment position. Print "". (Declaring one buffer from another copies its bytes, so changing the copy leaves memory as it was) A buffer called 'the copy' is memory. Print "Buffer contents: {the copy}". Set byte 1 of 'the copy' to 'A'. Print "After setting byte 1 to 'A': {the copy}".
A working reimplementation of Unix cat: flags, multiple files, and a stdin fallback.
(The cat command, written in Vox: concatenate files and print them to standard output) A flag called 'wants help' is "--help" or "-h", it is a boolean. A flag called 'wants version' is "--version" or "-v", it is a boolean. A flag called 'we are numbering lines' is "--number" or "-n", it is a boolean. A text called program is arguments's name. To 'show version'. Print "{program} (vox) by Josjuar Lister". Exit 0. If 'wants help' then, Print "{program} - concatenate files and print to standard output", Print "Usage: {program} [OPTION]... [FILE]...", Print "With no FILE, or when FILE is -, read standard input.", Print "\nOptions:", Print " -h, --help display this help and exit", Print " -n, --number number all output lines", Print " -v, --version output version information and exit", Print "\nExamples:", Print "\t{program} f - g\tOutput f's contents, then standard input, then g's contents", Print "\t{program}\t\tCopy standard input to standard output", Print "See https://github.com/vox-lang/vox for more information.", Exit 0. If 'wants version' then, 'show version'. A boolean called 'failed to open a file' is false. Open a file for writing called output at 1 (standard output). On error print "{program}: /dev/stdout: Could not open pipe", exit 1. A number called 'line number' is 1. To 'read the file' with a file called source. Create a buffer called 'staged output'. Create a buffer called content. On error print "{program}: failed to create buffer". Read line from source into content. While content is not empty, if 'we are numbering lines' then, Append "{line number:6}\t{content}" to 'staged output', increment the 'line number'. Otherwise, Append content to 'staged output'. If 'staged output's size is greater than 65535 then, Write 'staged output' to output, Clear 'staged output'. Read line from the source into content. Close source. Return 'staged output'. If arguments's empty then, Open a file for reading called source at 0 (standard input), On error print "{program}: /dev/stdin: Could not open pipe", exit 1. A buffer called 'staged output' is 'read the file' with source, Write 'staged output' to output, Clear 'staged output', Exit 0. (One sentence opens every file named on the command line, in order) Open a file called source for reading at each filename from arguments's all treating "-" as "/dev/stdin", On error print "{program}: {filename}: No such file or directory", set 'failed to open a file' to true, continue. A buffer called 'staged output' is 'read the file' with source, Write 'staged output' to output, Clear 'staged output'. If 'failed to open a file' then, Exit 1. Otherwise, Exit 0.
Writes three lines to a file, reads them back into a buffer that grows as needed, then deletes the file.
Print "Secure file I/O". Print "Creating a buffer with no fixed size, which grows to fit what it reads.". A buffer called contents. Print "Writing to file...". Open a file for writing called output at "./secure_test.txt". Write "Line 1: Hello from secure file I/O!" to output. Write a newline to output. Write "Line 2: Buffers grow automatically." to output. Write a newline to output. Write "Line 3: Files auto-close on exit if forgotten." to output. Close the output. Print "Reading back...". Open a file for reading called source at "./secure_test.txt". Read from source into contents. Close the source. Print "Contents:". Print contents. Print "Cleaning up...". Delete the file "./secure_test.txt".
A compiler-style front end that declares five command-line flags, parses them in one sentence, and reads what is left plus the environment through the 's property syntax.
(A program reads its command line and its environment through the 's property syntax. Run it as: ./args_and_env -v -o out.bin main.vox) (A flag is declared once, and Parse flags takes every declared flag off the command line, so arguments's all holds only what is left: here, the files to compile. A boolean flag takes no value; any other flag takes the word after it, and when a flag is given twice the last one wins. A lone -- ends the flags, so every word after it is positional.) A flag called optimize is "-O" or "--optimize", it is a boolean with default false. A flag called output is "-o" or "--output", it is a text with default "a.out". A flag called jobs is "-j" or "--jobs", it is a number with default 1. A flag called verbose is "-v" or "--verbose", it is a boolean with default false. A flag called debug is "-g" or "--debug", it is a boolean with default false. Parse flags. A list called 'source files' is arguments's all. If 'source files' is empty then, Print "Error: No source files provided.", Exit with 1. If the verbose then, Print "Compiling with optimization: {the optimize}", Print "Output: {the output}", Print "Parallel jobs: {the jobs}". For each 'source file' in the 'source files', Print "Compiling: {source file}". Print "Arguments". (The count includes the program's own name, which arguments's name reads) A number called 'argument count' is arguments's count. Print "Number of arguments: {argument count}". A text called program is arguments's name. Print "Program name: {program}". If arguments's count is greater than 1 then, a text called 'first argument' is arguments's first, Print "First user argument: {first argument}". Print "". If arguments's empty then, Print "No user arguments provided.". Otherwise, Print "User arguments were provided.". A text called 'last argument' is arguments's last. Print "Last argument: {last argument}". Print "". Print "Environment". (An environment variable is read by its name) A text called home is environment's "HOME". Print "Home directory: {home}". A text called user is environment's "USER". Print "Current user: {user}". A text called shell is environment's "SHELL". Print "Shell: {shell}". If the environment variable "DEBUG" exists then, Print "Debug mode is enabled via environment.". Otherwise, Print "DEBUG environment variable not set.". Print "". A number called 'variable count' is environment's count. Print "Total environment variables: {variable count}". A text called 'first variable' is environment's first. Print "First environment variable: {first variable}". Print "". Print "Greeting". (A name given on the command line wins over GREET_NAME in the environment, and either one wins over the world) A text called 'greeting name' is "World". If arguments's count is greater than 1 then, the 'greeting name' is arguments's first. But if the environment variable "GREET_NAME" exists then, the 'greeting name' is environment's "GREET_NAME". Print "Hello, {greeting name}!".
A timer measures how long a job takes, and the clock reads today's date and time down to the second.
(A timer measures how long a job takes, and the clock reads today's date and time) Print "Starting job...". Create a timer called 'job timer'. Start the 'job timer'. (Waiting stands in for the job's work) Wait 1 second. A number called 'seconds so far' is the 'job timer's elapsed seconds. Print "Seconds elapsed so far: {seconds so far}". Wait 500 milliseconds. Stop the 'job timer'. A number called 'milliseconds taken' is the 'job timer's duration in milliseconds. Print "Finished the job in {milliseconds taken} milliseconds.". (A timer also keeps the unix time it started and stopped at) A number called started is the 'job timer's 'start time'. A number called stopped is the 'job timer's 'end time'. Print "Started at unix time {started}, stopped at unix time {stopped}.". Get current time into now. Print "Today is {now's year}-{now's month:02}-{now's day:02} and the time is {now's hour:02}:{now's minute:02}:{now's second:02}.". (The current time can be read where it is needed, without a name) Print "It is currently hour {current time's hour} of the day.".
Pi worked out from the Nilakantha series over 500,000 terms in 64-bit floats, then set beside the real value.
(Calculating Pi using the Nilakantha Series) (A beautiful infinite series that converges to π) (π = 3 + 4/(2×3×4) - 4/(4×5×6) + 4/(6×7×8) - ...) Print "The Quest for Pi". Print "". Print "Using the Nilakantha series, we shall approximate". Print "the most famous constant in mathematics...". Print "". (Our approximation begins with three) A float pi is 3.0. (The denominator starts at two and grows by two each step) A float denominator is 2.0. (We alternate between adding and subtracting) A float direction is 1.0. (Count our iterations) An int steps is 0. While steps is less than 500000, (Calculate the three consecutive numbers for this term) a float called smallest is the denominator, a float called middle is the denominator add 1.0, a float called largest is the denominator add 2.0, (The denominator is their product) a float called product is the smallest times the middle, the product is the product times the largest, (Calculate this term of the series) a float term is 4.0 divide product, the term is term times direction, (Add this term to our approximation) the pi is pi add term, (Flip the direction for the next term) the direction is 0.0 subtract direction, (Move to the next triple of numbers) the denominator is denominator add 2.0, increment the steps. Print "". Print "After 500,000 terms of the series:". Print "". Print " Calculated pi: {pi}". Print " Actual pi: 3.14159265358979323846...". Print "". Print "(64-bit floats give us about 15 digits of precision)".
Conway's Game of Life on a 40x20 toroidal grid, the entire generation loop driven by a single loop-expansion statement and timed with a timer.
(Conway's Game of Life on a board whose edges wrap around, so a glider that leaves on one side comes back on the other) A number called width is 40. A number called height is 20. A number called generations is 14. A buffer called grid is 800 bytes in size. A buffer called 'next grid' is 800 bytes in size. (Step off one edge of the board and come back on at the opposite edge) To wrap with a number called position and a number called step and a number called 'board size'. A number called 'cells past the first' is {position subtract 1} add step add 'board size'. Return a number, {'cells past the first' modulo 'board size'} add 1. To 'cell index' with a number called row and a number called column. Return a number, {{row subtract 1} multiply width} add column. To 'bring to life' with a number called row and a number called column. Set byte {'cell index' of row and column} of grid to 1. (A living cell holds 1 and an empty one 0, so adding up states counts the living) To 'the state at' with a number called row and a number called column. Return a number, byte {'cell index' of row and column} of grid. (The three-by-three square around a cell holds its eight neighbours and the cell itself, so the cell's own state comes off the total) To 'alive neighbors' with a number called row and a number called column. A number called tally is 0. For each 'row step' from -1 to 1, a number called 'neighbor row' is wrap of row and 'row step' and height, For each 'column step' from -1 to 1, a number called 'neighbor column' is wrap of column and 'column step' and width, the tally is tally add 'the state at' of 'neighbor row' and 'neighbor column'.. Return a number, tally subtract 'the state at' of row and column. (A row is built up in one buffer and printed once, so it comes out as one line) To 'print row' with a number called row. A buffer called line is 64 bytes in size. For each column from 1 to width, a text called mark is ".", If 'the state at' of row and column is 1 then, the mark is "#". Append mark to line. Print line. (Every cell's next state is worked out from the current grid alone, into the next grid, so the cells can be stepped in any order) To 'step cell' with a number called row and a number called column. A number called neighbors is 'alive neighbors' of row and column. A number called state is 'the state at' of row and column. A number called 'next state' is 0. If state is 1 and neighbors is 2 then, the 'next state' is 1. If state is 1 and neighbors is 3 then, the 'next state' is 1. If state is 0 and neighbors is 3 then, the 'next state' is 1. Set byte {'cell index' of row and column} of 'next grid' to 'next state'. To 'run generation' with a number called generation. Print "Generation {generation} of {generations}:". 'print row' of each row from 1 to height. 'step cell' of each row from 1 to height and each column from 1 to width. Copy 'next grid' to grid. (An R-pentomino: five cells that stay restless for about 1100 generations on a board without edges) 'bring to life' of 9 and 20. 'bring to life' of 9 and 21. 'bring to life' of 10 and 19. 'bring to life' of 10 and 20. 'bring to life' of 11 and 20. (A glider, which drifts diagonally away from the top corner) 'bring to life' of 2 and 3. 'bring to life' of 3 and 4. 'bring to life' of 4 and 2. 'bring to life' of 4 and 3. 'bring to life' of 4 and 4. Print "Conway's Game of Life on a 40 by 20 board whose edges wrap, seeded with an R-pentomino and a glider". Create a timer called clock. Start the clock. 'run generation' of each generation from 1 to generations. Stop the clock. A number called 'time taken' is the clock's duration in milliseconds. Print "Ran {generations} generations on an 800-cell grid in {time taken} milliseconds, as native machine code.".
A process supervisor with no shell and no coreutils: fork, poll-reap, signal, and decode the exit status.
(A supervisor for child processes, written entirely in Vox, with no shell and no coreutils. The parent starts two jobs. The first does a scrap of work and finishes on its own; the second hangs, so the supervisor runs out of patience, kills it, and reports how it died. Every step is a system call that Vox says as a sentence: fork the process, reap a child without waiting, send a signal, and read the reaped status.) (The kernel packs how a child ended into one status word: the low seven bits are the signal that ended it, and the next eight its exit code. Decoding that is ordinary arithmetic, so it is written here in Vox.) To 'exit code' with a number called status. Return a number, status divide 256 modulo 256. To signal with a number called status. Return a number, status bit-and 127. To crashed with a number called status. A number called 'terminating signal' is status bit-and 127. Return a boolean, 'terminating signal' is not 0. To 'exited normally' with a number called status. A number called 'terminating signal' is status bit-and 127. Return a boolean, 'terminating signal' is 0. (A job that has not finished within this long is a job that never will.) A number called 'the patience in milliseconds' is 300. (Poll the child instead of blocking on it, so the clock is still being read while the child runs. One non-blocking reap answers all three questions at once: the child's own pid means it has finished, a zero means it is still running, and a negative means there was never such a child.) To supervise with a number called pid. A timer called clock. Start the clock. A boolean called 'the child is still running' is true. A boolean called 'the child ran out of time' is false. While 'the child is still running', a number called 'the reaped child' is reap child pid without waiting, If 'the reaped child' is pid then, Set 'the child is still running' to false. If 'the child is still running' then, a number called 'the milliseconds waited' is the clock's elapsed in milliseconds, If 'the milliseconds waited' is greater than 'the patience in milliseconds' then, Send signal 9 to child pid, Set 'the reaped child' to reap child pid, Set 'the child is still running' to false, Set 'the child ran out of time' to true. If 'the child is still running' then, Wait 5 milliseconds. Stop the clock. A number called status is the reaped status. If 'the child ran out of time' then, Print " it outstayed its welcome, so it was sent signal 9". If crashed of status then, Print " it died by signal {signal of status}". If 'exited normally' of status then, Print " it finished on its own with exit code {'exit code' of status}". Print "The tidy job:". A number called 'the tidy child' is fork the process. If 'the tidy child' is 0 then, (In the child: a scrap of work, then an exit code for the parent to read back.) Wait 20 milliseconds, Exit 3. supervise with 'the tidy child'. Print "The stuck job:". A number called 'the stuck child' is fork the process. If 'the stuck child' is 0 then, (In the child: hang for far longer than the supervisor will allow.) Wait 30 seconds, Exit 0. supervise with 'the stuck child'. (Signal 0 delivers nothing and only asks whether a process is there at all, which is the safe way to find out that a pid is gone.) Send signal 0 to process 'the stuck child'. On error print "The stuck job is gone: no process answers to its pid.".
A small interactive shell, vsh, that splits each line into words and runs the command through fork and execute, looking in /bin and /usr/bin.
(A small interactive shell, vsh. It reads a command line, splits it into words, and runs the first word as a command with the rest as its arguments, trying it as given, then under /bin and /usr/bin. Type "exit" to leave. A word is gathered byte by byte in one buffer and copied out as a text, "{word}", so every word keeps its own copy and the buffer can gather the next one.) Open a file at 0 for reading called 'standard input'. Create a buffer called line. A buffer called word is 256 bytes in size. (A space, a tab or a newline ends a word; any other byte joins it) A number called space is 32. A number called tab is 9. A number called newline is 10. While true, print "vsh $ " without newline, clear line, read line from 'standard input' into line, if line is empty then, exit 0. (A space at the end finishes the last word, even on a line that arrived without a newline) Append " " to line, a list called 'command arguments' is [], a text called command is "", a text called 'finished word' is "", a boolean called 'we have a command' is false, a number called 'line length' is line's size, a number called position is 1, a number called 'this byte' is 0, a number called 'the next place' is 1, a boolean called 'at a separator' is false, a boolean called 'the word is finished' is false, clear word, While position is less than or equal to 'line length', set 'this byte' to byte position of line, set 'at a separator' to false, if 'this byte' is space or 'this byte' is tab or 'this byte' is newline then, set 'at a separator' to true. Set 'the next place' to word's size add 1, if not 'at a separator' then, set byte 'the next place' of word to 'this byte'. Set 'the word is finished' to false, if 'at a separator' and word's size is greater than 0 then, set 'the word is finished' to true. If 'the word is finished' then, a text called 'finished word' is "{word}". (A word joins the arguments only once there is a command, so the command itself never lands in its own argument list) If 'the word is finished' and 'we have a command' then, append 'finished word' to 'command arguments'. If 'the word is finished' and not 'we have a command' then, set command to 'finished word', set 'we have a command' to true. If 'the word is finished' then, clear word. Increment position. A number called pid is 0, if command is "exit" then, exit 0. If 'we have a command' then, set pid to fork the process. (In the child, Execute returns only when it fails, so each failure falls through to the next place to look) If pid is 0 and 'we have a command' then, Execute command with arguments 'command arguments', a text called 'path in bin' is "/bin/{command}", Execute 'path in bin' with arguments 'command arguments', a text called 'path in usr bin' is "/usr/bin/{command}", Execute 'path in usr bin' with arguments 'command arguments', print "vsh: {command}: command not found", exit 127. (The parent waits for the child, so the next prompt comes after its output) If pid is greater than 0 then, set 'reaped child' to reap process pid. Set 'the word is finished' to false.
A door-and-elevator control system: three booleans, combined with 'and' and 'not', decide whether it is safe to open the door.
Print "The door will open if: door is not open, elevator not moving, and lift is not full.". Print "". Print "Conditions:". A boolean called 'door open' is true. A boolean called 'lift moving' is true. A boolean called 'lift full' is true. If 'door open' then, Print "Door is open.". Otherwise, Print "Door is closed.". If 'lift moving' then, Print "Elevator is moving.". Otherwise, Print "Elevator is not moving.". If 'lift full' then, Print "Elevator is full.". Otherwise, Print "Elevator is not full.". Print "". Print "Action:". If 'door open', 'lift moving', and 'lift full' are not true then, Print "Opening the Door.". Otherwise, Print "Not opening the Door.". If 'door open' and 'lift moving' then, Print "EMERGENCY STOP".
The first program an initramfs runs: it mounts the system's virtual filesystems, waits for the root disk, pivots onto it and hands over to its init.
(The first program an initramfs runs: it mounts the system's virtual filesystems, waits for the root disk, and hands over to its init) Print "Initramfs setup starting...". Create a directory called "/proc". Create a directory called "/sys". Create a directory called "/dev". Create a directory called "/dev/pts". Create a directory called "/dev/shm". Create a directory called "/run". Create a directory called "/tmp". Create a directory called "/newroot". Mount "proc" at "/proc" with type "proc". On error print "Failed to mount /proc", exit 1. Mount "sysfs" at "/sys" with type "sysfs". On error print "Failed to mount /sys", exit 1. Mount "devtmpfs" at "/dev" with type "devtmpfs". On error print "Failed to mount /dev", exit 1. Mount "devpts" at "/dev/pts" with type "devpts" with options "gid=5,mode=620". On error print "Failed to mount /dev/pts", exit 1. Mount "tmpfs" at "/dev/shm" with type "tmpfs". On error print "Failed to mount /dev/shm", exit 1. Mount "tmpfs" at "/run" with type "tmpfs". On error print "Failed to mount /run", exit 1. Mount "tmpfs" at "/tmp" with type "tmpfs". On error print "Failed to mount /tmp", exit 1. (In case devtmpfs did not already make these) Create a device node called "/dev/null" with type "c" major 1 minor 3. Create a device node called "/dev/zero" with type "c" major 1 minor 5. Create a device node called "/dev/random" with type "c" major 1 minor 8. Create a device node called "/dev/urandom" with type "c" major 1 minor 9. (Programs expect these names for a process's open files) Create symbolic link from "/proc/self/fd" to "/dev/fd". Create symbolic link from "/proc/self/fd/0" to "/dev/stdin". Create symbolic link from "/proc/self/fd/1" to "/dev/stdout". Create symbolic link from "/proc/self/fd/2" to "/dev/stderr". (The disk can appear a moment after boot, so wait for it) Print "Waiting for root device...". A text called 'root device' is "/dev/sda1". While the 'root device' is not available, Sleep for 100 milliseconds, Print "." without newline. Print "". Print "Mounting root filesystem...". Mount the 'root device' at "/newroot" with type "ext4". On error print "Failed to mount root filesystem", exit 1. (The old root has to move to a directory inside the new root, which exists only now that the new root is mounted) Create a directory called "/newroot/oldroot". On error print "Failed to create /newroot/oldroot", exit 1. (The virtual filesystems move with the system, so they need not be mounted again) Mount "/proc" at "/newroot/proc" with type "none" with options "move". Mount "/sys" at "/newroot/sys" with type "none" with options "move". Mount "/dev" at "/newroot/dev" with type "none" with options "move". Mount "/run" at "/newroot/run" with type "none" with options "move". Print "Switching to new root...". Pivot root to "/newroot" with old root "/newroot/oldroot". On error print "Failed to pivot_root", exit 1. Change directory to "/". On error print "Failed to chdir to new root", exit 1. (The old root stays busy while this program runs from it, so it is detached lazily and released once this program is gone) Unmount "/oldroot" lazily. On error print "Failed to detach old root", exit 1. (Execute replaces this program with init and returns only if it fails) Print "Executing init...". Execute "/sbin/init" with arguments []. On error print "Failed to execute init", exit 1.
A small shared library, built with vox --shared, exporting an addition function and a greeter.
(A small shared library, built with: vox examples/mathkit_lib.vox --shared -o examples/libmathkit.so mathkit_consumer.vox calls it from Vox.) Library mathkit version "1.0". To 'add two numbers' with a number called first and a number called second. Return a number, first add second. To greet. Print "hello from mathkit".
Consumes the mathkit shared library through its .lib file: 'see' resolves it, and the call links against the compiled .so.
(Calls the mathkit library. The see sentence reads libmathkit.lib, which lists what the library offers, so 'add two numbers' is checked against it here and linked against libmathkit.so. Build both, then run: vox examples/mathkit_lib.vox --shared -o examples/libmathkit.so vox examples/mathkit_consumer.vox -o examples/mathkit_consumer ./examples/mathkit_consumer It prints 7.) See mathkit version "1.0" from "./libmathkit.lib". A number called sum is 'add two numbers' of 3 and 4. Print the sum.