Sokolang

From Esolang
Jump to navigation Jump to search

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 [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