SADOL
SADOL (Sadistic And Damn Odd Language) is an esoteric programming language made by Martin 'nooga' Gasperowicz (User:nooga) in 2005.
Description
SADOL was designed to be hard to learn and maximally illegible but still efficient (but many people say that's an easy one). SADOL is based on Lisp concepts. Like its ancestor, it uses forward polish notation and the main feature that makes SADOL so ugly is a lack of grouping parentheses like ( and ) in Lisp. SADOL is (most probably) Turing complete.
History
The language was invented by Martin 'nooga' Gasperowicz in the summer 2005, when he was on holiday in a small village and didn't have a computer except for an old 486 DX IBM laptop. The first implementation was done in Turbo Pascal (it was the only compiler on his laptop); it was not very efficient and was very buggy. Second and better--but still not completely compliant with SADOL specification (the author hasn't got any specification)—was BDSM (Badly Developed Sadol Machine), written by Adam 'Regedit' Sawicki (User:Regedit). Recently he has finished a new interpreter - BDSM2 - which is fully compliant with the specification and very efficient.
Syntax
SADOL has "unknown -arity" functions, so its syntax can't be described in formal grammar. See Hollerith strings.
- Code is a list of function calls; no delimiter is necessary.
- A function call is a symbol (function name) followed by one of:
- a finite list of its arguments.
- a constant representing the number of following arguments, and these arguments.
- nothing, if the called function takes no arguments.
- An argument is a function call.
- A symbol is any printable ASCII character (range 33..126).
Symbol scope
All symbols except a..z are global. The symbols a..z are local to within the function that defined them. (If a function hasn't defined one of these local variables, it uses the definition from the function that called it.)
A little example should illustrate it better:
:A1 :a2 ~f 0 (6 !A !a :a3 :A4 !a !A f !a !A
This should produce the following output: 1 2 3 4 2 4 (I've added spaces.)
Types
Generally SADOL recognizes 3 types (one of which has 2 subtypes), and these are:
- Number
- Double
- Integer
- String
- List
Number
Numbers divide into 2 types: Double and Integer. The choice of type is managed by the interpreter.
String
SADOL strings are sequences of characters. Escape codes (\n,\t) are permitted. Strings are indexed from 0 and put together almost like lists. Strings can be concatenated with other strings (and numbers) by using the + function. The ] function pushes a character onto the end of the string, and [ pops one from the end and returns its ASCII code. The # function also works with strings. To retrieve a string's length, read its -1 index (#s-01).
List
To be honest, lists in SADOL are really vectors. They act like stacks with access to all elements in constant time. List elements can be strings, numbers or other lists. Retrieving a list's length is exactly the same as with strings: #l-01.
Automatic conversions
- When a string or list is used where a number should be - its length is used.
- When a number is used where a string should be - it's converted to a string in decimal format.
- When an integer is used where a double should be - it's converted to a double.
- When a double is used where an integer should be - it's rounded.
- When a number or a string is used where a list should be - it's converted into a one-element list.
Built-in functions
Arithmetic
SADOL | C | Description |
---|---|---|
: s v | s = v | Assigns a value (v) to symbol (s) and returns v. |
+ a b | a + b | Returns the result of adding a to b. It also works with strings (as concatenation). |
- a b | a - b | Returns the result of subtracting a from b. |
* a b | a * b | Returns the result of multiplying a by b. |
/ a b | a / b | Returns the result of dividing a by b. |
% a b | a % b | Returns the remainder from dividing a by b. |
^ a b | pow(a,b) | Returns a raised to the bth power. |
\ a | floor(a) | Returns a rounded down. |
Expressing constants
SADOL | C | Description |
---|---|---|
0 .. 9 | 0 .. 9 | 10 argumentless functions which return integers containing the values of the digits represented by the function names. |
, n d | e.g. 1337 | Returns a number written decimally in d whose number of digits is n.
e.g. ,41337 = 1337 |
. n d | e.g. 0.1337f | Acts like the , function, except that the return value is multiplied by 10-n. |
" n c | e.g. "A hedgehog." | Returns a string n characters long whose content is c.
eg. "5A pie = "A pie" |
' m c | 'c' | If m is 0, returns c as an integer containing its ASCII code. eg. '0% = 37 If m is 1 and c is a string, returns c's first character as an integer containing its ASCII code. eg. '1"1% = 37 |
Lists
SADOL | C | Description |
---|---|---|
$ n v | ? | ? Returns an n element list containing the elements v.
eg. $3"5A pie"1L+,3100.11 = ("A pie","L",100.1) |
# l n | l[n] | Returns an n-th element of l list (a reference). if n = -1 it returns l's length. Also works with strings. |
] l v | ? | Pushes v on top of l and returns l. Also works with strings. |
[ l | ? | Pops the last element of l and returns it. Also works with strings. |
Function defining
SADOL | C | Description |
---|---|---|
~ n a b | f(a) {b} | Defines a function named n that takes a arguments and executes b when called. if a (the function's arity) is -1 the function takes the arity form the first argument when called. |
_ | ? | Returns the current argument list. Only useful in functions' bodies. |
Program flow
SADOL | C | Description |
---|---|---|
( n t | {t} | A progn - executes n number of terms (t) in order and returns the value of the last one.
eg. (3 :a,213 !"6Hello! a will return the value - 13. |
? c t f | (c)?t:f | If condition c is fulfilled, executes t, else executes f. Returns the value of the executed branch. |
@ c b | while(c) b | While condition c is fulfilled, executes b. Returns the value of the last b execution. If there were no b executions, returns 0. |
Comparison
SADOL | C | Description |
---|---|---|
= a b | a == b | Returns 1 (true) if a is exactly equal to b, else returns 0 (false). |
> a b | a > b | Returns 1 (true) if a is greather than b, else returns 0 (false). |
< a b | a < b | Returns 1 (true) if a is less than b, else returns 0 (false). |
Logics
SADOL | C | Description |
---|---|---|
& a b | a && b | Returns 1 if a and b are >=1 (true), else returns 0 (false). |
| a b | a || b | Returns 1 if either a or b (or both) is/are >=1 (true), else returns 0 (false). |
Note that negation in SADOL can be done like this: - 1 v where v is the value to be negated.
Input/Output
SADOL | C | Description |
---|---|---|
! a | printf(a) | Prints a in the console. If a returns an integer value it's printed without a fractional part. If needed, numbers may be printed in any precision or in a scientific format. |
; t | ? | Waits for user input and returns it. If t is 0 reads one character and return it as a string. |
Other
SADOL | C | Description |
---|---|---|
` s | ? | Executes a string s containing SADOL code and returns the result of its last term. |
{..} | /* .. */ | A Comment, returns nothing and is skipped by the interpreter. A comment cannot contain } inside it. |
Examples
Hello world
!",212Hello world!
Quine
{by Jaro3000} (4:C",216!"9(4:C",216!C!C!"9(4:C",216!C!C
eniuQ, reversed quine
{by Jaro3000} (7:C",228!R!C!"7822,"R:!R!"9822,"C:7(:R",228(7:C",2289"!R!:R",2287"!C!RR!C!"7822,"R:!R!"9822,"C:7(
99 Bottles of beer
A bigger example...
{ 99 bottles of beer in SADOL by Marinus Oosters marinuso@zeelandnet.nl } (3~s1(,213!#_0!"7 bottle?=#_01!"1 !"2s !",221of beer on the wall, !#_0!"7 bottle?=#_01!"1 !"2s !"9of beer, !",230Take one down, pass it around !-#_01!"7 bottle?=-#_011!"1 !"2s !",222of beer on the wall. ~b1?>#_00(2s#_0b-#_01!",212Out of beer b,299
External resources
- BDSM2/SADOL Documentation A cool documentation by regedit
- SADOL Homepage - Old, to be changed soon.
- BDSM - Badly Developed SADOL Machine, a SADOL interpreter