SADOL

From Esolang
Jump to navigation Jump to search

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
If m is 2, returns a one-character-long string containing a character corresponding to the ASCII code c. eg. '2,237 = "%"

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.
If t is 1 reads a line and returns it as an integer (trying to convert it).
If t is 2 reads a line and returns it as a double (trying to convert it).
If t is 3 reads a line and returns 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