PRG
PRG is a weirdlang created by User:DigitalDetective47 where the entire program is made of three‐letter tokens.
Program structure
The entire program is made of a sequence of tokens, each of which is a series of three capital letters. Each token must be separated from its neighbors by exactly one space. Trailing spaces are not allowed. Newlines between tokens are allowed, and any multiple of four spaces at the beginning of a line are ignored.
Compiler errors
The term “compiler error” in this context is used to mean that a syntactical error is detected in the program. For a compiler, a successful compilation should give an exit code of 0 (if applicable). A compiler error should cause SRC ERR to be printed to standard error, and give an exit code of 1 (if applicable). An interpreter must check for compiler errors throughout the entirety of the source before beginning execution, and raise any error it may find. For an interpreter, a valid program should run without errors. A compiler error should result in SRC ERR to be printed to standard error, and the program should not attempt to run. Below is a list of causes for a compiler error:
- Token of incorrect length
- Token containing invalid characters
- Line contains trailing spaces
- Tokens have multiple spaces between them
- Line starts with a number of spaces that is not a multiple of four
- A naming conflict is found.
- An undefined syntax is detected.
Data model
Basic types
There are six basic data types in PRG, which are documented in the table below:
| Token | Description | Default value |
|---|---|---|
BIN |
Raw binary data. 64 bits in length. | 0x0000000000000000 |
BOL |
Boolean value. | False |
CHR |
Character. Can represent any Unicode character. Line feed is the canonical newline character. | Null character |
DEC |
64‐bit floating‐point number. Uses wikipedia:IEEE 754 binary64. | 0.0 |
INT |
64‐bit signed integer. Uses wikipedia:Two's complement | 0 |
NUL |
Null value. Mainly used for functions that have no return value. | Null |
Type conversions are supported between all possible pairs of types; these behaviors are documented below:
| To | |||||||
|---|---|---|---|---|---|---|---|
BIN |
BOL |
CHR |
DEC |
INT |
NUL
| ||
| From | BIN
|
Copy unchanged | 0x0000000000000000 → False Everything else → True |
Unicode character of value as integer modulo 1114111 | Decode binary data as float (big endian) | Decode binary data as integer (big endian) | Null |
BOL
|
False → 0x0000000000000000 True → 0x0000000000000001 |
Copy unchanged | False → Null character True → Start of Heading |
False → 0.0 True → 1.0 |
False → 0 True → 1 |
Null | |
CHR
|
Character's Unicode value in big endian | Null character → False Everything else → True |
Copy unchanged | Character's Unicode value as a float | Character's Unicode value | Null | |
DEC
|
Binary representation (big endian) | 0.0 → False Everything else → True |
Unicode character of value modulo 1114111 | Copy unchanged | Convert to an integer with the same numeric value. If the double is not an integer, it is truncated to be an integer. If the double is greater than 263−1, it is converted to 263−1. If it is less than −263, it is converted to −263. NaN is converted to 0. | Null | |
INT
|
Binary representation (big endian) | 0 → False Everything else → True |
Unicode character of value modulo 1114111 | Convert to a float of the same numeric value, using whatever rounding is default. | Copy unchanged | Null | |
NUL
|
0x0000000000000000 | False | Null character | 0.0 | 0 | Null | |
If a function is passed a value of an incorrect type, it is automatically converted to the correct type.
Arrays
An array is denoted by the token ARR. It is an immutable sequence of values of a single type. Arrays can be nested by specifying an array as the element type. When used as a type, it should be followed by the type of its elements. It can also be used to construct array literals, which happens automatically when the ARR token is encountered when a value is expected. In this case, it reads off a sequence of values until an END token is found outside of a value. An array literal's elements are automatically converted to the appropriate type for where it is used. It is worth noting that ARR END is a valid expression that returns an empty array. Arrays cannot be longer than 263−1; attempting to insert a value into an array containing the maximum number of elements will cause the final element to be removed. Array literals with more than 263−1 will raise a compiler error. An array is empty by default. If an array is passed into a function where a single value is expected, or if a single value is passed where an array is expected, a compiler error occurs. Type conversions on arrays act on their elements.
Functions
Computations are performed using functions, which are called by writing the function's name followed by its parameters.
User‐defined functions
A function can be defined using the DEF token. This is then followed by the return type, the function's name, a sequence of arguments, an END token, the function's code, and another END token. Each argument is specified by its type followed by its name. Functions cannot be defined within other functions. Within a function, the RET token can be used to return a value. It is followed by the value to return, and is automatically converted to the return type of the function. If a function reaches the end of its execution without reaching a RET, it will return the default value for its type. All function declarations must occur immediately after global variable declarations.
Built‐in functions
| Signature | Description |
|---|---|
DEC ADD DEC LFT DEC RGT |
Return LFT + RGT.
|
BIN AND BIN LFT BIN RGT |
Return a bitwise AND of LFT and RGT.
|
BIN BOR BIN LFT BIN RGT |
Return a bitwise OR of LFT and RGT.
|
DEC COS DEC VAL |
Return cos(val) in radians.
|
DEC DIV DEC LFT DEC RGT |
Return LFT ÷ RGT.
|
NUL ERR ARR CHR TXT |
Print TXT to standard error.
|
BOL FLS |
Boolean constant False. |
ARR CHR GET |
Get a line of text from the user, and return it as an array of characters. |
DEC INF |
Float constant ∞. |
INT LEN ARR NUL INA |
Return the length of INA.
|
DEC LOG DEC BAS DEC VAL |
Return logBAS(VAL).
|
DEC MAX DEC LFT DEC RGT |
Return whichever of LFT and RGT is larger.
|
DEC MIN DEC LFT DEC RGT |
Return whichever of LFT and RGT is smaller.
|
DEC MOD DEC LFT DEC RGT |
Return LFT mod RGT. Takes the sign of the second argument.
|
DEC MUL DEC LFT DEC RGT |
Return LFT × RGT.
|
DEC NAN |
Float constant NaN. |
INT ONE |
Integer constant 1. |
ARR DEC PIE |
Two‐element array containing float approximations of π and e. |
DEC POW DEC BAS DEC EXP |
Return BASEXP.
|
NUL PUT ARR CHR TXT |
Print TXT to standard output.
|
INT RNG |
Return a random integer. |
BIN ROT BIN VAL INT BTS |
wikipedia:Circular shift VAL BTS bits to the left.
|
BIN SFT BIN VAL INT BTS |
wikipedia:Logical shift VAL BTS bits to the left.
|
DEC SIN DEC VAL |
Return sin(val) in radians.
|
INT SIX |
Integer constant 6. |
DEC SUB DEC LFT DEC RGT |
Return LFT − RGT.
|
DEC TAN DEC VAL |
Return tan(val) in radians.
|
INT TEN |
Integer constant 10. |
BOL TRU |
Boolean constant True. |
INT TWO |
Integer constant 2. |
BIN XOR BIN LFT BIN RGT |
Return a bitwise XOR of LFT and RGT.
|
Generic array functions
The following functions act on arrays with any type, inheriting the type of their elements. The element type is referenced here as ELM. Note that ELM can be an array type. Array indices are automatically wrapped to fit within the bounds of the list, and these functions have special behavior when applied to the empty array.
| Signature | Description | Behavior on empty array |
|---|---|---|
ELM ACC ARR ELM AIN INT IDX |
Return the element of AIN at index IDX. |
Return Null. |
ARR ELM INS ARR ELM AIN ELM VAL INT IDX |
Return a copy of AIN with VAL inserted at index IDX. |
Return a one element array containing VAL.
|
ARR ELM DEL ARR ELM AIN INT IDX |
Return a copy of AIN without the element at index IDX. |
Return an empty array. |
Variables
Data is stored in variables, which are also tokens. A variable is defined using the VAR token, followed by the variable's type, followed by its name. All variable declarations must be at the top of the program, or at the top of their function. A variable can be accessed by its token. To set a variable's value, use the SET token, followed by the variable name and then the value to assign.
Control flow
There are three primary control flow structures available. The simplest of the three is IFT. It functions as an if block, taking a boolean parameter. The block extends to the matching END token. This can also be augmented with an ELS, which defines the else clause. If‐else blocks should only have a single END. The next simplest is WHL, which is a while loop. Its parameter is defined identically to IFT, and is also terminated by an END token. The most complex is FOR, which takes two parameters. The first parameter is an array, and the second parameter is a variable name. The for loop iterates over the elements of the array, setting the loop variable to the current element. The loop variable must be defined, and array elements are converted to the loop variable's type. After the for loop completes, the loop variable retains the final element of the array.
List of reserved tokens
ACCADDANDARRBINBOLBORCHRCOSDECDEFDELDIVELSENDERRFLSFORGETIFTINFINSINTLENLOGMAXMINMODMULNANNULONEPIEPOWPUTRETRNGROTSETSFTSINSIXSUBTANTENTRUTWOVARWHLXOR
Examples
Hello, world!
VAR CHR CHL
VAR CHR CHO
SET CHL SUB POW TEN TWO TEN
SET CHO SUB POW ADD TEN ONE TWO TEN
PUT ARR
MUL ADD TEN TWO SIX
ADD POW TEN TWO ONE
CHL
CHL
CHO
ADD MUL ADD SIX ONE SIX TWO
POW TWO SUB SIX ONE
ADD ADD CHL TEN ONE
CHO
SUB MUL ADD TEN TWO TEN SIX
CHL
POW TEN TWO
ADD POW TWO SUB SIX ONE ONE
END
Truth-machine
VAR ARR CHR UIN
SET UIN GET
IFT XOR ACC UIN FLS INT POW ADD SIX ONE TWO
PUT UIN
ELS
WHL TRU
PUT UIN
END
END
Cat program
WHL TRU
PUT INS GET TEN SUB ONE TWO
END
String to integer function
Doesn't work for numbers with a magnitude greater than 253.
DEF INT CTI ARR CHR VAL END
VAR ARR CHR REM
VAR DEC SUM
VAR DEC SGN
VAR DEC NEO
SET SUM FAL
SET NEO SUB ONE TWO
IFT XOR ACC VAL FAL SUB SUB POW ADD SIX ONE TWO TWO TWO
SET SGN ONE
SET REM VAL
ELS
SET SGN NEO
SET REM DEL VAL FAL
END
WHL LEN REM
SET SUM ADD MUL SUM TEN ACC REM NEO
SET REM DEL REM NEO
END
RET MUL SUM SGN
END
Integer to string function
Doesn't work for numbers with a magnitude greater than 253.
DEF ARR CHR ITC INT VAL END
VAR ARR CHR OUT
VAR INT REM
VAR BOL NEG
VAR DEC CHZ
SET CHZ SUB POW ADD SIX ONE TWO ONE
IFT VAL
IFT AND VAL POW TWO SUB POW TWO SIX ONE
SET NEG TRU
SET REM MUL VAL SUB ONE TWO
ELS
SET NEG FLS
SET REM VAL
END
WHL REM
SET OUT INS OUT ADD MOD REM TEN CHZ FAL
SET REM DIV REM TEN
END
IFT NEG
RET INS OUT SUB SUB POW ADD SIX ONE TWO TWO TWO FAL
ELS
RET OUT
END
ELS
RET ARR CHZ END
END
END
Fibonacci sequence
VAR ARR DEC FIB
VAR DEC CHZ
VAR CHR SPC
DEF ARR CHR ITC INT VAL END
VAR ARR CHR OUT
VAR INT REM
VAR BOL NEG
IFT VAL
IFT AND VAL POW TWO SUB POW TWO SIX ONE
SET NEG TRU
SET REM MUL VAL SUB ONE TWO
ELS
SET NEG FLS
SET REM VAL
END
WHL REM
SET OUT INS OUT ADD MOD REM TEN CHZ FAL
SET REM DIV REM TEN
END
IFT NEG
RET INS OUT SUB SUB POW ADD SIX ONE TWO TWO TWO FAL
ELS
RET OUT
END
ELS
RET ARR CHZ END
END
END
SET CHZ SUB POW ADD SIX ONE TWO ONE
SET SPC POW TWO SUB SIX ONE
PUT ARR CHZ SPC ADD CHZ ONE END
SET FIB ARR FAL ONE END
WHL TRU
SET FIB DEL INS FIB ADD ACC FIB FAL ACC FIB ONE TWO FAL
PUT INS ITC ACC FIB ONE SPC FAL
END
Ackermann function
DEF INT CTI ARR CHR VAL END
VAR ARR CHR REM
VAR DEC SUM
VAR DEC SGN
VAR DEC NEO
SET SUM FAL
SET NEO SUB ONE TWO
IFT XOR ACC VAL FAL SUB SUB POW ADD SIX ONE TWO TWO TWO
SET SGN ONE
SET REM VAL
ELS
SET SGN NEO
SET REM DEL VAL FAL
END
WHL LEN REM
SET SUM ADD MUL SUM TEN ACC REM NEO
SET REM DEL REM NEO
END
RET MUL SUM SGN
END
DEF ARR CHR ITC INT VAL END
VAR ARR CHR OUT
VAR INT REM
VAR BOL NEG
VAR DEC CHZ
SET CHZ SUB POW ADD SIX ONE TWO ONE
IFT VAL
IFT AND VAL POW TWO SUB POW TWO SIX ONE
SET NEG TRU
SET REM MUL VAL SUB ONE TWO
ELS
SET NEG FLS
SET REM VAL
END
WHL REM
SET OUT INS OUT ADD MOD REM TEN CHZ FAL
SET REM DIV REM TEN
END
IFT NEG
RET INS OUT SUB SUB POW ADD SIX ONE TWO TWO TWO FAL
ELS
RET OUT
END
ELS
RET ARR CHZ END
END
END
DEF INT ACK INT MMM INT NNN END
IFT MMM
IFT NNN
RET ACK SUB MMM ONE ACK MMM SUB NNN ONE
ELS
RET ACK SUB MMM ONE ONE
END
ELS
RET ADD NNN ONE
END
END
PUT ITC ACK CTI GET CTI GET
Factorial
VAR DEC IDX
VAR DEC PRD
DEF INT CTI ARR CHR VAL END
VAR ARR CHR REM
VAR DEC SUM
VAR DEC SGN
VAR DEC NEO
SET SUM FAL
SET NEO SUB ONE TWO
IFT XOR ACC VAL FAL SUB SUB POW ADD SIX ONE TWO TWO TWO
SET SGN ONE
SET REM VAL
ELS
SET SGN NEO
SET REM DEL VAL FAL
END
WHL LEN REM
SET SUM ADD MUL SUM TEN ACC REM NEO
SET REM DEL REM NEO
END
RET MUL SUM SGN
END
DEF ARR CHR ITC INT VAL END
VAR ARR CHR OUT
VAR INT REM
VAR BOL NEG
VAR DEC CHZ
SET CHZ SUB POW ADD SIX ONE TWO ONE
IFT VAL
IFT AND VAL POW TWO SUB POW TWO SIX ONE
SET NEG TRU
SET REM MUL VAL SUB ONE TWO
ELS
SET NEG FLS
SET REM VAL
END
WHL REM
SET OUT INS OUT ADD MOD REM TEN CHZ FAL
SET REM DIV REM TEN
END
IFT NEG
RET INS OUT SUB SUB POW ADD SIX ONE TWO TWO TWO FAL
ELS
RET OUT
END
ELS
RET ARR CHZ END
END
END
SET IDX CTI GET
SET PRD ONE
WHL IDX
SET PRD MUL PRD IDX
SET IDX SUB IDX ONE
END
PUT ITC PRD