Enjamb

Enjamb is an esoteric programming language where it's not what's in your lines that matters — it's where you break them. It was created in 2019 by User:TartanLlama.
enjambment (/ɛnˈdʒæmbmənt/): the running on of the thought from one line, couplet, or stanza to the next without a syntactical break.
Enjamb is a stack-based language where instructions are encoded by the number of characters in each line of text. For example, a line with 14 characters in it means "take the top two values off of the stack, add them, and push the result." 
Here is a program which counts from 1 to 10:
 Up and up and up, a
 1
 makes
 gold
 if you believe in it
 
 believe in me, count
 up
 above the clouds, 1
 voice in a
 beautiful sky —
 & we fly
 past
 
 summer days count 1
 2
 3 with me, fly
 wishful
 gold
 wings
 past
 everything.
==Abstract Machine==
Enjamb runs on an abstract machine with:
* A program counter which marks the currently-executing instruction.
* A linear sequence of instructions, stored in memory inaccessible to the program.
* A stack of signed integers (called "the stack"). The current implementation uses 32-bit signed integers due to C++ limitation.
* An indexable array of signed integers (called "the heap"). The current implementation uses an array of 4096 signed 32-bit integers due to C++ limitation.
* A stack of program counters facilitating calling and returning from functions (called "the call stack").
==Instruction Set==
There are 22 instructions in Enjamb. Each opcode takes a single line of text, where the opcode is selected by the number of characters in that line. Some instructions take a single operand, which is encoded in the next line down.
Blank lines are no-ops, unless they come after an instruction which takes an operand, in which case they form the operand (see the specific instructions for details).
The instruction set is based on Whitespace.
Below are a list of the instructions along with their semantics, prepended with the number of characters required to encode that instruction. For example, print character could be encoded by a line with I, or a, or any other single character. exit could be encoded with exit please.
Some instructions take a label name as an operand. Labels are named by the text on the line after the opcode, and can contain any characters you like. For example, "Exit, pursued by a bear." is a valid Enjamb label.
I/O instructions 	I/O instructions 	I/O instructions
Encoding 	Instruction name 	Description
1 	print character 	Pop the top of the stack and print it as an ASCII character.
2 	print number 	Pop the top of the stack and print it as a signed integer.
3 	read character 	Read an ASCII character from stdin and push it on to the stack.
4 	read number 	Read a signed integer from stdin and push it on to the stack.
Control flow instructions	Control flow instructions	Control flow instructions
Encoding 	Instruction name 	Description
5 	label <label> 	Marks this part of the code with the label opcode
6 	call <label> 	Jumps to the instruction marked by the given label, and pushes the old program counter to the call stack.
7 	jump <label> 	Unconditionally jumps to the instruction marked by the given label.
8 	jump if zero <label> 	Jumps to the instruction marked by the given label if the value at the top of the stack is 0. Also pops the top of the stack.
9 	jump if neg <label> 	Jumps to the instruction marked by the given label if the value at the top of the stack is negative. Also pops the top of the stack.
10 	return 	Returns to the program counter at the top of the call stack.
11 	exit 	Exits the program, returning the value at the top of the stack.
Heap instructions 	Heap instructions 	Heap instructions
Encoding 	Instruction name 	Description
12 	store 	Pops the first two values from the stack and stores the first into heap[second].
13 	load 	Pops the top value from the stack and pushes heap[value].
Arithmetic instructions 	Arithmetic instructions 	Arithmetic instructions
Encoding 	Instruction name 	Description
14 	add 	Pop top two values of the stack, push the result of adding them.
15 	sub 	Pop top two values of the stack, push the result of subtracting them.
16 	mul 	Pop top two values of the stack, push the result of multiplying them.
17 	div 	Pop top two values of the stack, push the result of dividing (integer division) them.
18 	mod 	Pop top two values of the stack, push the result of the first modulo the second.
Stack instructions 	Stack instructions 	Stack instructions
Encoding 	Instruction name 	Description
19 	push <value> 	Pushes the value given as an operand onto the top of the stack. The operand is specified on the line following the opcode, and is encoded by the number of characters on that line.
20 	dup 	Duplicates the value on the top of the stack.
21 	swap 	Swaps the two values on top of the stack.
22 	pop 	Pops the top value from the stack, discarding it.
=="Characters"==
Enjamb source is UTF-8 encoded, and a "character" in Enjamb is a user-perceived character, approximated by Unicode as a grapheme cluster. As such, the German 'ß' is counted as a single character, even though it's encoded in two UTF-8 code units. 'g̈' — constucted from the latin 'g' and the combining diaeresis — is also a single character.
If your system locale changes grapheme cluster boundary rules (for example, if your system locale is Slovak, 'ch' will be one character instead of two) then you may get different results than intended by a program's author.
 
==Artistic Implications==
The language is mostly for fun, but there are some interesting artistic ideas which fall out of the design.
For one, if the programmer wishes to write an Enjamb program which also functions as a poem, then they are constrained by the language. As such, Enjamb constructs show up as patterns in the poetry. Since there's very little in the way of looping support in Enjamb, poems written as Enjamb programs will show similar structures where looping behaviour is required. Similarly, I/O intensive programs will read as faster-paced than compute-intensive programs because the opcode encodings of I/O instructions are shorter than arithmetic or stack operations.
Since labels are essentially free text, but must be repeated in order for jumps or function calls to occur, the writer is forced to repeat phrases and consider how they must be placed within the poem/program.
==Examples==
===Hello World===
 Hello, world, a far
 cry of albatross smoothed
 by rocks, by mudded
 wave
 I am here, world
 beyond laws, held by
 silences and shouts
 and tear
 drops darkened
 by an unclear dome,
 
 above us all
 our heads turned up,
 our lids shut and —
 icicle 
 
 falls from old
 skies shattered with
 bone tools and soft
 eye
 bleeding under,
 we can save nothing
 I
 can save you
 
 from the sharp break
 of the dome, of the
 waves on
 that rust sea,
 full of glass, sail
 half-mast in memory of the Earth
 as it once was, but
 I
 forgot a long
 time ago, as did we
 
 destroy wood,
 a home to albatross,
 or snake or vulture,
 or bright teeth, or
 a lover
 with boots high
 above blaze-scorched
 grass, glass shield
 inevitable, fracturing, head-
 bang, belt welt
 smash of life under
 closed eye.
 
 World
 sleeping, a new
 
 vision, we can't, yo—
 I
 can't build another
 I
 seep into soil,
 
 tumbling among dirt,
 waitwait
 another earth
 comes,
 sleeping, a new
 
 dream
 another earth
==Implementation==
An interpreter which is written in C++ and can run on the CLI or in a browser is available on GitHub. You can try the web-based implementation here
== See also ==
* Length
* Slam
Category:Languages Category:2019 Category:Implemented Category:Stack-based Category:Pseudonatural Category:Turing complete