Sokolang

Sokolang is a programming language created by FLeckami that use Sokoban gameplay to execute commands.
==File structure==
Here is an exemple file (it prints "Hello, world!"):
// the level map
 ### 
##*##
#@H*#
#####
---
// the crate that hold the string
h:10,13,72,101,108,108,111,44,32,119,111,114,108,100,33
---
// Just 3 actions to print it !
rwu
The file has 3 distincts zones separated by ---
The first zone is the level map, the second one is the stack initialisation and the third one is the Player's actions.
Lines starting with // are ignored and can be used to write comments
==Level map==
The table below show the elements you can place on:
symbol 	name
@ 	player (required, only one)
# 	wall
: 	cloner
! 	destroyer
a letter: [a-zA-Z]	crate
a number: [0-9] 	portal
* 	mark (required, at least one)
. 	floor
Empty spaces are considered as walls.
Crates and the player are not on a mark at the begining.
If an element reach a portal, it will be teleported to the portal with the same number. If there are more than 2 portals with the same number, the element will be teleported to a random portal. The teleportation will be executed in each player movement.
A crate marked with a lowercase letter is a read-only crate. The stack cannot be modified, so a read-only crate cannot execute command and has no effect when it is on a mark
==Stack initialisation==
Every crate have their own stack which can be initialize like this:
n:123,45,6,... where n is a lowercase letter
a same letter, uppercase or lowercase, share the same stack
The player has also his stack. It is the same syntax as for crates. Just replace n by @
If you don't initialize a crate stack, the stack will be empty by default.
==Player's actions==
===actions===
After the stacks initialisation, the actions string is executed and loop infinitly if at least one mark is not covered by an element. The program ends if all mark are covered by a crate or the player
The player can push multiple crates at the same time but he can pull only one crate at the time.
The player can perform the following actions:
action 	description
u, d, l, r	move the player to the given direction (up, down, left, right)
p 	switch between push and pull (push at the beginning)
w 	wait a turn. Used to tranfert a value and execute commands
[...] 	actions group. Used to group a list of actions
a number can be added to execute an action or an action group as many time as this number. For exemple, 3u move the player up 3 times and 5[2rw3u] is the same as 2rw3u2rw3u2rw3u2rw3u2rw3u
===prefixes===
prefix	description
+ 	the action or action group is executed if the last test is true
- 	the action or action group is executed if the last test is false
@ 	execute the action or action group once, meaning that if the action sequence reach the end, actions or actions groups with this prefix are not executed during the next iterations
* 	execute the action or action group n times where n is the first value of the player stack (this value stay on the stack).If the stack is empty, n is 0. If n is negative, the player go to the opposite direction (w and p are not affected)
note: the 'test' refer to a flag that is either true or false. testeq and testneg are the only commands that can change this flag
===value transfert===
when the w action is executed, if the player has moved a crate in his last action, a value transfert has occured:
* if the player has pushed the crate n times, the n-th value of the player's stack is popped and pushed into the pushed crate stack. Nothing happend if the pushed crate is a read-only crate
* if the player has pulled the crate n times, the n-th value of the pulled crate stack is popped and pushed into the player's stack. If the pulled crate is read-only, the value stay on the crate stack 
* If a pushed/pulled crate land on a cloner, all values will be transfered according to the rule given above (the number of time the crate is being pushed/pulled doesn't matter). Values on the source element are not removed and no action will be performed if the target element is read-only.
* If an element land on a destroyer and is not read-only, all values on the stack will be removed.
note: if the player push multiple crate, the value transfert only affect the nearest pushed crate
===command===
When the value transfert is finished, every element (crate and player) on a mark execute a command, begin with the player then the crates in alphabetic order. If multiple crates have the same letter, they will be executed from left to right, top to bottom
If the stack is empty, nothing happend. Else the first value pop and correspond to the command code
code	name 	description 	exemple
0 	nop 	no instruction 	
1 	+ 	pop the first 2 values a and b and push a+b 	[1,123,45,6] -> [168,6]
2 	- 	pop the first 2 values a and b and push a-b 	[2,123,45,6] -> [78,6]
3 	* 	pop the first 2 values a and b and push a*b 	[3,123,45,6] -> [5535,6]
4 	/ 	pop the first 2 values a and b and push the integer part of a/b 	[4,123,45,6] -> [2,6]
5 	% 	pop the first 2 values a and b and push the reminder of a/b 	[5,123,45,6] -> [33,6]
6 	pow 	pop the first 2 values a and b and push a^b 	[6,3,3,45] -> [27,45]
10 	outstr 	pop the first value n of the stack correspond to the number of character to print, then pop the n next value and print them as ASCII character	[10,2,72,105] -> [] and print "Hi"
11 	outint 	pop the first value of the stack and print it 	[11,123,45,6] -> [45,6] and print "123"
12 	instr 	ask the user to input a string and push the number of character then the ASCII value of each character 	if input is "hello", then [12] -> [5,104,101,108,108,111]
13 	inint 	ask the user to input a number and push it 	if input is 56, then [13] -> [56]
20 	copy 	push the first value on the stack 	[20,123,45,6] -> [123,123,45,6]
21 	del 	pop the first value of the stack 	[21,123,45,6] -> [45,6]
22 	reverse	reverse the stack 	[22,123,45,6,78,9] -> [9,78,6,45,123]
23 	length 	push the length of the stack 	[23,123,45,6,78,9] -> [5,123,45,6,78,9]
24 	swap 	swap the 2 first values 	[24,123,45,6,78,9] -> [45,123,6,78,9]
25 	mark 	push the number of marks covered by an element 	
30 	testeq 	pop the first value. The test is true if this value is 0, otherwise it's false 	
31 	testneg	pop the first value. The test is true if this value is negative, otherwise it's false (0 is considered positive) 	
32 	not 	pop the first value and push 1 if this value is 0, otherwise 0 	
all unknown code are considered as nop
An error occured if a command try to pop on an empty stack
more commands can be added in the future
==Exemples==
Infinite loop:
#####
#@.*#
#####
---
// this initialization is useless
@:8
---
// the player will never reach the mark with this action sequence
rl
Cat:
 ###
##*##
#@C*#
#####
---
c:12
@:10
---
rlwrplprwu
XKCD's random number:
// chosen by fair dice roll.
// guaranteed to be random.
 ###
##*##
#@R*#
#####
---
r:11,4
---
rwu
A+B Problem:
 ###
 #*#
##I####
#@*.O*#
#..####
 #.#
 ###
---
@:13
i:13
o:1,11
---
rudwup2[dlr]dwp2u2r2[plw]prlwp2r2lud
Truth machine:
 ###
###d#
#@..##
###*.####
#p.*.*.t#
#########
---
@:13
t:30
p:11
d:20
---
@[2rdwupdwpu2d3rplwlp2l]+[prw2u2dr]r2updwpu2dlprwpl
Number generator: A user input a number n and print a random n digits number
#######################
###.#.#.#.#.#.#.#.#.#.#
#..a.b.c.d.e.f.g.h.i.j#
#.....................#
#.#1#1#1#1#1#1#1#1#1#1#
#.#####################
#.#########1#y#z#o#s###
#..........*..........#
###########.#........x#
 #@#####m#n#*#
 ### #######
---
a:0
b:1
c:2
d:3
e:4
f:5
g:6
h:7
i:8
j:9
z:30
y:20
o:11
s:24
m:2
n:1
@:13
---
@[2uw2rpdwpu2lw4rpdwpu4lw]+[10rdu10l]3updwp20l4d16rpdwpu6lw8rdpuwpdupdwpu8lw6rdpuwpdu6lw2rpdwpu2lw4rpdwpu4lw
Category:2021 Category:Stack-based Category:Languages