Seriously
Paradigm(s) | imperative |
---|---|
Designed by | Mego |
Appeared in | 2015 |
Computational class | Turing complete |
Reference implementation | Seriously on Github |
File extension(s) | .srs |
Seriously is a golfing language created by Mego in 2015 and still under development. It is a stack-based language with overloaded single-byte command names. In addition to the stack it has 2 named registers and an indexable permanent array. Its creation was inspired by this thread on PPCG and is being developed to be used in code golf challenges on PPCG.
Commands
The following are the currently implemented commands in Seriously (as viewed in CP437 encoding). When possible, the character at each code point is listed in parentheses following the ordinal. For non-printing characters (ordinals 0-31), this is not possible, so a description is provided instead. All bytecodes except for 00 will be implemented eventually. Commands are often described in terms of Python functions.
There are 4 data types in Seriously: numeric, string, list, and function. a represents any value. This usually means numeric values, but can represent any value of a type not specified in an alternate command definition. "a" represents a string value. [a] represents a list value (in most cases, a string value is also acceptable). z represents a complex value. Complex values are a proper subset of numeric values. f represents a function value.
Some commands have fixed arity. Others have variable arity. This is denoted by the number of values listed in the pop. Those commands that are not functional commands (such as delimiters) do not have arities, and so do not pop from the stack.
The functional commands each operate differently based on the data types of the values popped from the stack. In some cases, that order matters. In others, it does not. Each operation will be denoted by the different data types popped. If there is a conflict, the most restrictive applicable definition is used.
Hex | Character | Operation |
---|---|---|
00 | (NUL) | |
01 | (SOH) | |
02 | (STX) | |
03 | (ETX) | |
04 | (EOT) | |
05 | (ENQ) | |
06 | (ACK) | |
07 | (bell) | |
08 | (backspace) | |
09 | (tab) | push a single byte of unformatted input from STDIN (push sys.stdin.read(1)) |
0A | (line feed) | |
0B | (vertical tab) | |
0C | (form feed) | |
0D | (carriage return) | |
0E | (SO) | |
0F | (SI) | |
10 | (DLE) | |
11 | (DC1) | |
12 | (DC2) | |
13 | (DC3) | |
14 | (DC4) | |
15 | (NAK) | |
16 | (SYN) | |
17 | (ETB) | |
18 | (CAN) | |
19 | (EM) | |
1A | (SUB) | |
1B | (ESC) | |
1C | (FS) | |
1D | (GS) | |
1E | (RS) | |
1F | (US) | |
20 | ( ) | push the # of elements on the stack (push len(stack)) |
21 | (!) | pop a: push a! (factorial(a)) |
22 | (") | string literal, reads until next " and pushes value onto stack. An implied " is present at EOF if needed. |
23 | (#) | pop a: push list(a) |
24 | ($) | pop a: push str(a) |
25 | (%) | pop a,b: push a%b; pop "a",[b]: push "a"%[b] |
26 | (&) | pop a,b: push (a & b) |
27 | (') | pushes next character onto stack as character literal (length-1 string) |
28 | (() | rotates stack right by 1 |
29 | ()) | rotates stack left by 1 |
2A | (*) | pop a,b: push a*b; pop "a",b: repeat "a" b times, push "a" ("a"*b); pop a,[b] or [b],a: apply a* to each element in the array |
2B | (+) | pop a,b: push a+b; pop "a","b": push concatenation of "a" and "b"; pop [a],[b]: push [a][b] (append [b] to [a]); pop a,[b] or [b],a: apply a* to each element in the array |
2C | (,) | read value from stdin and push |
2D | (-) | pop a,b: push a-b; pop [a],[b]: push [a]-[b] (all elements of [a] not in [b]) |
2E | (.) | pop a: write a to stdout; pop f: f. (call f and execute . recursively) |
2F | (/) | pop a,b: push a/b (float division); pop [a]: rotate [a] right by 1, push [a] |
30 | (0) | push 0 |
31 | (1) | push 1 |
32 | (2) | push 2 |
33 | (3) | push 3 |
34 | (4) | push 4 |
35 | (5) | push 5 |
36 | (6) | push 6 |
37 | (7) | push 7 |
38 | (8) | push 8 |
39 | (9) | push 9 |
3A | (:) | numeric literal delimiter: pushes the string between it and the following : as a numeric value, or 0 if it cannot be converted. An implicit : is present at EOF if needed. |
3B | (;) | pop a: push a,a |
3C | (<) | pop a,b: push 1 if a<b else 0 |
3D | (=) | pop a,b: push 1 if a==b else 0 |
3E | (>) | pop a,b: push 1 if a>b else 0 |
3F | (?) | NOP, extended expressions if -e flag is passed |
40 | (@) | pop a,b: push a,b (rotate top 2 elements) |
41 | (A) | pop a: push abs(a) |
42 | (B) | pop a,b: push a random integer in [a,b) (randrange(a,b)) |
43 | (C) | pop a: push cos(a) |
44 | (D) | pop a: push a-1 |
45 | (E) | pop a: push erf(a); pop [a],b: push [a][b] (bth item in [a]) (also works for strings) |
46 | (F) | pop a: push Fib(a) (Fib(0)=0, Fib(1)=Fib(2)=1) |
47 | (G) | push a random float in the range [0,1) (push random()) |
48 | (H) | if stack is empty: push "Hello, World!" |
49 | (I) | pop a,b,c: push b if a is truthy, else push c |
4A | (J) | pop a: push a random integer in [0,a) (randrange(a)); pop [a] or "a": push a random element from [a] or "a" (random.choice([a]|"a")) |
4B | (K) | pop a: push ceil(a) |
4C | (L) | pop a: push floor(a) |
4D | (M) | pop f,[a], execute f for each element in [a], using the element as a temporary stack, push [a] (similar to map(f,[a])) |
4E | (N) | if stack is empty: push the lyrics to "99 Bottles of Beer" |
4F | (O) | pop "a" or [a]: push ord(c) for each c in "a" or [a], starting from the end. If a list is popped and it contains strings of length > 1, the strings are exploded in-place (["ABC"] -> [65,66,67], [["A","B","CD"]] -> [65,66,67,68]) |
50 | (P) | pop a: push the a-th prime (zero-indexed) |
51 | (Q) | if stack is empty: push the program's source code |
52 | (R) | pop f,[a]: call f, using [a] as a temporary stack, push [a] (similar to reduce(f,[a])); pop "a" or [a]: push reversed value ("a".reverse() or [a][::-1]); pop a: push [1,2,...,a] (range(1,a+1)) |
53 | (S) | pop a: push sin(a); pop "a" or [a]: push sorted(a) |
54 | (T) | pop a: push tan(a) |
55 | (U) | pop [a],[b]: push union of [a] and [b] |
56 | (V) | pop a,b: push uniform(a,b) (random float between a and b) |
57 | (W) | loop delimiter: peek top of stack, repeat code in loop while a evaluates to true |
58 | (X) | pop a: discard |
59 | (Y) | pop a: push !bool(a) (logical negate, opposite of b) |
5A | (Z) | pop [a],[b]: push zip([a],[b]); pop a, zip the next a lists |
5B | ([) | begin list literal, values are delimited by commas (,) |
5C | (\) | pop a,b: push a/b (integer division); pop [a]: rotate [a] left by 1, push [a] |
5D | (]) | end list literal |
5E | (^) | pop a,b: push pow(a,b) |
5F | (_) | pop a: push ln(a) |
60 | (`) | function literal delimiter, pushes function whose body contains all of the commands until the next `. An implied ` is present at EOF if needed. |
61 | (a) | invert the stack ([a,b,c,d] -> [d,c,b,a]) |
62 | (b) | pop a: push 0 if a==0 else 1; pop "a" or [a]: push 0 if len(a)==0 else 1; pop f: push 0 if len(f)==0 else 1 |
63 | (c) | pop a: push character at ordinal a%256; pop [a],b: push [a].count(b); pop "a","b": push "a".count("b") |
64 | (d) | pop [a]: dequeue b from [a], push [a],b |
65 | (e) | pop a: push exp(a) |
66 | (f) | pop a: push the Fibonacci index of a if a is a Fibonacci number, else -1; pop "a",[b]: push "a".format(*[b]) |
67 | (g) | pop a,b: push gcd(a,b) |
68 | (h) | pop a,b: push sqrt(a*a+b*b) (Euclidean norm) |
69 | (i) | pop "a": push atof(a); pop [a]: push each element from [a], starting from end (flatten) |
6A | (j) | pop "a",[b]: push "a".join([b]) (converting values in [b] to strings with $ if necessary) |
6B | (k) | pop all elements from stack, convert to list (in the order they were on the stack, starting from the top), and push |
6C | (l) | pop "a" or [a] or f: push len(a) (or len(f)) |
6D | (m) | pop a: push int(a),frac(a) (modf(a)) |
6E | (n) | pop a,b: push a b times; pop f,b: call f b times |
6F | (o) | pop [a],b: push b to [a], push [a] |
70 | (p) | pop a: push 1 if a is prime else 0; pop [a]: pop b from [a], push [a],b |
71 | (q) | pop [a],b: enqueue b in [a], push [a] |
72 | (r) | pop "a": push each character in "a", starting from the end (explode string); pop a: push [0,1,...,a-1] (range(0,a)) |
73 | (s) | pop a: push sgn(a) |
74 | (t) | pop all elements from stack, flatten any lists and explode any strings, and push them in the same order they were popped (full stack flatten/explode) |
75 | (u) | pop a: push a+1 |
76 | (v) | pop a: seed the RNG with a (random.seed(a)) |
77 | (w) | pop a: push the full factorization of a (18 -> [[2,1],[3,2]]) |
78 | (x) | pop a,b: push [a,b) (range(a,b)) |
79 | (y) | pop a: push the prime factors of a (18 -> [2,3]) |
7A | (z) | pop a: repeat . a times (pop a times and print to stdout) |
7B | ({) | pop a: rotate stack right a times |
7C | (|) | pop a,b: push (a | b) |
7D | (}) | pop a: rotate stack left a times |
7E | (~) | pop a: push ~a (unary bitwise negate) |
7F | (?⌂) | terminate the program (without implicit stack popping and printing) |
80 | (Ç) | pop a,b: push a+bi; pop [a]: pop pairs of real numerics b,c from [a] and push b+ci (appending 0 to [a] if len([a]) is odd) |
81 | (ü) | pop entire stack and print to stdout |
82 | (é) | pop entire stack (clear stack) |
83 | (â) | pop a: push asin(a) |
84 | (ä) | pop a: push acos(a) |
85 | (à) | pop a: push atan(a) |
86 | (å) | pop a,b: push atan2(a,b) |
87 | (ç) | pop a: push asinh(a) |
88 | (ê) | pop a: push acosh(a) |
89 | (ë) | pop a: push atanh(a) |
8A | (è) | pop a: push repr(a) |
8B | (ï) | push i, the imaginary unit (sqrt(-1) or 0+1i) |
8C | (î) | pop a, push 0+ai; pop [a], push [a] with every element multiplied by i |
8D | (ì) | pop a: push 1/a |
8E | (Ä) | pop a: push sinh(a) |
8F | (Å) | pop a: push cosh(a) |
90 | (É) | pop a: push tanh(a) |
91 | (æ) | pop [a]: push mean([a]) |
92 | (Æ) | pop "a","b","c": push "a".replace("b","c") |
93 | (ô) | pop "a": push "a".strip() |
94 | (ö) | pop "a": push "a".lstrip() |
95 | (ò) | pop "a": push "a".rstrip() |
96 | (û) | pop "a": push "a".upper() |
97 | (ù) | pop "a": push "a".lower() |
98 | (ÿ) | pop "a": push "a".title() |
99 | (Ö) | pop "a": push "a".swapcase() |
9A | (Ü) | pop [a]: push mode([a]) |
9B | (¢) | pop a,b: push abs(a)*sgn(b) |
9C | (£) | pop "a": push a function whose code is "a" |
9D | (¥) | pop [a],[b]: push the result of pairwise addition of [a] and [b], padding the shorter with 0s |
9E | (₧) | pop z: push phase(z) |
9F | (ƒ) | pop f: call f |
A0 | (á) | pop z: push the complex conjugate of z |
A1 | (í) | pop a,[b]: push [b].index(a) (0-based, -1 if not found) |
A2 | (ó) | pop a: if bool(a) push a, else terminate the program (conditional exit); terminate the program if the stack is empty |
A3 | (ú) | |
A4 | (ñ) | pop [a]: push enumerate([a]) ([[i,a[i]] for i in range(len(a))]) |
A5 | (Ñ) | |
A6 | (ª) | pop a: push a*a |
A7 | (º) | pop a: push degrees(a) |
A8 | (¿) | pop a,b: push int(a,b) (interpret a as a base-b int) |
A9 | (⌐) | pop a: push a+2 |
AA | (¬) | pop a: push a-2 |
AB | (½) | pop a: push a/2 (float division) |
AC | (¼) | pop a: push a/4 (float division) |
AD | (¡) | pop a,b: push a string representing a in base b |
AE | («) | pop a,b: insert b at position a, indexed from the bottom of the stack |
AF | (») | pop a,b: insert b at position a, indexed from the top of the stack |
B0 | (░) | pop [a],[b]: push [[a][i] if [b][i] for i in len(a)], pads [b] with 0s if necessary |
B1 | (▒) | pop a: push totient(a) (# of integers <= a that are coprime with a) |
B2 | (▓) | pop a: push pi(a) (# of primes <= a) |
B3 | (│) | duplicate stack ([a,b,c] => [a,b,c,a,b,c]) |
B4 | (┤) | pop a,b: push 1 if a and b are coprime else 0 |
B5 | (╡) | |
B6 | (╢) | |
B7 | (╖) | |
B8 | (╕) | |
B9 | (╣) | |
BA | (║) | pop [a] or "a": push median([a]/"a") (using ordinals if string) |
BB | (╗) | pop a: save a in register 0 |
BC | (╝) | pop a: save a in register 1 |
BD | (╜) | push the value in register 0 |
BE | (╛) | push the value in register 1 |
BF | (┐) | pop a,b: push b to register a |
C0 | (└) | pop a: push the value in register a |
C1 | (┴) | |
C2 | (┬) | |
C3 | (├) | |
C4 | (─) | |
C5 | (┼) | duplicate each element on stack ([a,b,c] => [a,a,b,b,c,c]) |
C6 | (╞) | pop a: make a total copies of each element on stack (3 [a,b,c] -> [a,a,a,b,b,b,c,c,c]) |
C7 | (╟) | pop a: pop a elements and push a list containing those elements in their original order |
C8 | (╚) | |
C9 | (╔) | |
CA | (╩) | |
CB | (╦) | push pi |
CC | (╠) | push e |
CD | (═) | |
CE | (╬) | pop f: while value on top of stack is truthy (peek), call f |
CF | (╧) | |
D0 | (╨) | |
D1 | (╤) | pop a: push 10**a |
D2 | (╥) | pop a: push log(a) (log base 10) |
D3 | (╙) | pop a: push 2**a |
D4 | (╘) | pop a: push lg(a) (log base 2) |
D5 | (╒) | push ln(2) |
D6 | (╓) | |
D7 | (╫) | |
D8 | (╪) | |
D9 | (┘) | |
DA | (┌) | |
DB | (█) | |
DC | (▄) | |
DD | (▌) | pop "a": push b64decode("a") |
DE | (▐) | pop "a": push b64encode("a") |
DF | (▀) | |
E0 | (α) | |
E1 | (ß) | |
E2 | (Γ) | pop a: push Gamma(a) |
E3 | (π) | pop [a]: push product([a]) |
E4 | (Σ) | pop [a]: push sum([a]) |
E5 | (σ) | |
E6 | (µ) | |
E7 | (τ) | pop a: push 2*a |
E8 | (Φ) | |
E9 | (Θ) | |
EA | (Ω) | |
EB | (δ) | |
EC | (∞) | eval delimiter: the code inside the delimiters is eval'd as Python code, and the result is pushed on the stack |
ED | (φ) | push phi (golden ratio) |
EE | (ε) | push "" (empty string) |
EF | (∩) | pop [a],[b]: push intersection of [a] and [b] |
F0 | (≡) | |
F1 | (±) | pop a: push -a (unary negate) |
F2 | (≥) | pop a,b: push a>=b |
F3 | (≤) | pop a,b: push a<=b |
F4 | (⌠) | |
F5 | (⌡) | |
F6 | (÷) | |
F7 | (≈) | pop a: push int(a) |
F8 | (°) | pop a: push radians(a) |
F9 | (∙) | |
FA | (·) | |
FB | (√) | pop a: push sqrt(a) |
FC | (ⁿ) | |
FD | (²) | |
FE | (■) | print the entire stack without popping, separated by spaces |
FF | (NBSP) |
Examples
Hello, World!
H
or
"Hello, World!"
Primality Test
,p
99 Bottles
N
Coprimality Test
,,┤
Counting the divisors of a number
,w`iXu`Mπ
Truth-machine
,W■
Implementation
In Python on Github
On the web: Try It Online