Dark

From Esolang
Jump to navigation Jump to search

Dark is an Esoteric programming language by user:David.werecat which is designed to be inherently evil.

Instructions

Introduction

Dark is a language based on manipulating entire worlds and dimensions to achieve goals and to build the best torturous reality possible. Each program is read as a series of commands to objects with the goal to twist each world as much as possible. Due to its poorly designed documentation, it's likely that even the descriptions of the language are inherently evil.

Language Basics

note: In all code examples, whenever {} brackets are used, they provide information about part of a command (eg. {objname}${function} would denote a line containing an object name followed by a colon, followed by a function name; an example of such a line could be something$action)

The language is based entirely on objects. At the start of every program, an object of type HELL must be declared (syntax: +{objname} hell). This object allows the creation and manipulation of other objects, and is the basis for the program. An object is used by specifying the object name and the function to run on that object (syntax: {objname}${function} {parameters}). All lines of the program with exception to the first line should be in this format, unless the line is either a blank line or a comment. Commented lines must start with a pipe symbol (|) and end with another pipe symbol. All object names are case sensitive.

Whenever a syntax error occurs, the program's sanity decreases by 1. The program's sanity starts at 100. If the program's sanity reaches zero, the interpreter goes insane. Whenever a general error occurs, the interpreter prints out the line "Murphy's Law is working correctly.".

When the program ends, any active objects will be dealt with and appropriate error messages will be output to the console detailing the cleanup process. As such it is recommended to destroy all objects before the program ends. Variables are also dealt with similarly.

Specifics

All objects are stored in a memory area known as the CONTROL_SPACE, separate from all variables. Variables are local to each manipulator and are stored in a memory location known as the WORLD_BLOCK. There is a global queue of strings known as the VOICELIST, which stores the values of signs.

Reference Interpreter

The reference interpreter is fully compliant with the Dark programming language. It accepts multiple source files are command line arguments. Each input file is interpreted separately and sequentially. Options may also be tweaked using the command line. Command line arguments only affect the source files after the argument. Possible arguments are:

Argument Description
-wimpmode Turns on wimpmode. This is not part of the official specification and is off by default. In wimpmode variables don't accumulate corruption and default error handlers are replaced with meaningful error messages.
-strict Turns off wimpmode. This ensures that the interpreter runs compliant to the full standard (except for the TRACE mode).
-traceon Taking the advice of Emiya Shirou, you will see everything that happens inside the interpreter. All lines are printed as they are executed, and all error handlers are replaced as in wimpmode. This is off by default, and will be removed in future versions of the interpreter.
-traceoff Turns off trace mode.
-stripcode Allows the interpreter to remove comments and empty lines upon loading a source file. This is on by default, and will result in better performance. The actual source file is not modified. While in wimpmode, this will cause invalid line numbers to be printed with the error messages.
-keepextra Forces the interpreter to keep all extra code, such as comments and empty lines. Only useful for debugging.
-breakonerror Causes the interpreter to stop execution and wait for a keypress after each error message. Again, this is off by default and will only affect wimpmode.
-continueonerror Does not stop when error messages are output. The default behavior of the interpreter.

The reference interpreter also complies to undocumented parts of the Dark standard.


Object Types

HELL

The hell object is the base object of the program, declared in the first line of code. There may only be one HELL object per program. A HELL object accepts the following commands:

Syntax Description
{object}$twist {objtype} {objname} Creates a new object.
{object}$consume {objname} Destroys an object.
{object}$empty Destroys all objects.
{object}$break Throws an error to the interpreter. The reference interpreter will print a simple error message when this function is issued.
{object}$break {errortext} Throws an error to the interpreter with customized error text.
{object}$apocalypse Immediately ends the program. All active objects are destroyed as usual.

MANIPULATOR

A manipulator is an object that allows the management of variables. A manipulator can hold a maximum of 1024 variables. When a variable is freed, it leaves decay behind. This decay must be cleared using the VOID function to reopen the variable spot to new variables. There are several variable mechanics. Variables with the same name as another variable in another manipulator can be defined, although when used can cause problems. A manipulator can only manipulate its own variables, therefore variable operations across manipulators must use a SIGN object as temporary storage. All variables are unsigned integers that can be either 8,16,32 or 64 bits long. When variables are not used for over 65536 cycles, they start to accumulate corruption. Corruption flips a single bit in the variable when it occurs. Each variable must have a disposition. If a variables with dispositions that are more than one apart are used in a function, they conflict and the variables are killed. Variables must also be defined as either a SERVANT or a MASTER. A servant must select a master variable. When the master dies, all servant variables attached to that master also die. This is useful for grouping and mass killing variables. A manipulator object accepts the following functions:

Syntax Description
{object}$manufacture {varname} {disposition} {size} master Creates a new master variable.
{object}$manufacture {varname} {disposition} {size} servant {mastername} Creates a new servant variable with a given master. The master can also be nonexistant, in which case the variable is considered lost and is treated as a master variable that cannot have servants.
{object}$suicide {varname} Forces a variable to kill itself, freeing it (remember though that it will leave decay).
{object}$kill {varname} Kills a variable. The same as the suicide function.
{object}$void Cleans up all decay. This ensures that all open variable spots are usable.
{object}$genocide {disposition} Kills all variables of a specified disposition. Remember, this only affects the variables directly under the manipulator's control and leaves decay just like all other functions.
{object}$omnicide Kills all variables. Works like genocide.
{object}$chaos {varname} Sets a variable to a random value. Uses the Global Chaos Generator.
{object}$set {varname} {value} Sets a variable to a given value. The value may be another variable from the same manipulator or a number.
{object}$add {varname} {val1} {val2} Sets a variable to the sum of two values. Once again, values may be either variables or numbers.
{object}$subtract {varname} {val1} {val2} Sets a variable to the difference of two values.
{object}$multiply {varname} {val1} {val2} Sets a variable to the product of two values.
{object}$divide {varname} {val1} {val2} Sets a variable to the quotient of two values.

ENTROPY

An entropy object allows program flow control. Labels may be nested, and will not be redefined inside other labels unless they are undefined. Choices may be nested, but each nested choice must be from a different entropy object. Accepted functions are:

Syntax Description
{object}$choice {val1} {comparator} {val2} Compares two values and executes the enclosed block if the condition is true. Works like an IF in most programming languages. The values can be either variables or numeric values; the variables can come from any manipulator objects. Accepted comparators are: = == > < >= <= != <>.
{object}$balance Defines the code block to run if the choice condition is false. Works like an ELSE in most programming languages.
{object}$reprogram Ends the previous choice or balance block. Works like an ENDIF in most programming languages.
{object}$corpse {lblname} Defines a label. If a label is already defined, the previous definition is kept. Some interpreters may cause a general error if a label already exists, therefore it is good practice to undefine nested labels and redefine them each iteration.
{object}$stumble {lblname} Causes execution to jump to a previously defined corpse (label).
{object}$illusion {lblname} Undefines a corpse. The corpse then can be properly redefined later.

STALKER

A stalker object controls all basic IO functions. A stalker starts uninitialized, it must be initialized using the stalk function. If a stalker is not initialized, any attempts to perform IO will result in depressing error messages to be written to the console. A stalker has two modes, DISTANT (default) and PERSONAL. While in distant mode, all output is written to a buffer and must be flushed to the console using the paracusia function. Switching modes will not cause the buffer to be flushed. When a stalker is in personal mode, all output is written to the console instantly.

Syntax Description
{object}$stalk Starts the stalker. Required in order to use the other functions.
{object}$control {varname} Causes the given variable to accept control, which sets the variable to the character code of the character read from the console.
{object}$control # {varname} Causes the given variable to accept control, which sets the variable to the value of the typed number. Invalid typing will cause general errors.
{object}$action {varname} Causes the given variable to take action, which causes a character with the character code equal to the value of the variable to be written to the console.
{object}$action # {varname} Causes the given variable to take action, which causes the numeric value of the variable to be written to the console.
{object}$echo Removes a value from the VOICELIST and writes it to the console.
{object}$distant Switches the object to DISTANT mode.
{object}$personal Switches the object to PERSONAL mode.
{object}$paracusia Flushes the buffer to the console. The buffer is reset to an empty value.

SIGN

Sign objects are containers for strings. A sign is a representation of a queue of character codes. Signs accept the following functions:

Syntax Description
{object}$scrawl {varname} Appends the character value of a variable to the current message.
{object}$scrawl # {varname} Appends the numerical value of a variable to the current message.
{object}$scrawl " {string} Appends a literal string to the current message.
{object}$tear Removes the first character from the message.
{object}$tear {count} Removes the first {count} characters from the message.
{object}$tear * Removes all characters from the message.
{object}$observe {varname} Sets a variable to the value of the first character in the message.
{object}$steal {varname} Sets a variable to the value of the first character in the message end erases the character from the message.
{object}$read Enqueues the current message in the VOICELIST, then erases the current message.
{object}$read ~ Enqueues the current message in the VOICELIST without erasing the current message.


Sample Programs

CAT Program

+deadcat hell
deadcat$twist stalker killer
deadcat$twist manipulator person
deadcat$twist entropy fate
killer$stalk
killer$personal
person$manufacture weapon 0 8 master
fate$corpse violence
killer$control weapon
killer$action weapon
fate$stumble violence
fate$illusion violence
person$kill weapon
deadcat$consume person
deadcat$consume killer
deadcat$consume fate
deadcat$apocalypse

Hello, world!

+hello hell
hello$twist sign hws
hello$twist stalker io
io$stalk
io$personal
hws$scrawl " Hello, world!
hws$read
io$echo
hello$empty
hello$apocalypse

Fibonacci Sequence

+fib hell
fib$twist stalker creep
fib$twist entropy cruelty
fib$twist manipulator darkone
creep$stalk
creep$personal
darkone$manufacture new 0 64 master
darkone$manufacture this 0 64 servant new
darkone$manufacture last 0 64 servant new
darkone$manufacture ltr 0 8 master
darkone$set this 1
cruelty$corpse fate
darkone$add new last this
darkone$set last this
darkone$set this new
creep$action # this
cruelty$choice this <= 9223372036854775807
	darkone$set ltr 44
	creep$action ltr
	darkone$set ltr 32
	creep$action ltr
	cruelty$stumble fate
cruelty$reprogram
darkone$omnicide
darkone$void
fib$empty
fib$apocalypse

General Language/Interpreter Test

+test hell
|Initialize objects|
test$twist manipulator overseer
test$twist manipulator leader
test$twist entropy fate
test$twist entropy path
test$twist stalker spy
test$twist sign bbs
test$twist sign keep_out
|Define a few variables|
overseer$manufacture politician 0 64 master
overseer$manufacture person1 0 32 servant politician
overseer$manufacture person2 0 16 servant politician
overseer$manufacture person3 0 8 servant none
leader$manufacture person1 0 16 master
leader$manufacture test1 0 32 servant politician
leader$manufacture test2 0 32 servant test3
leader$manufacture test3 0 32 servant test2
leader$manufacture hater 5 8 master
leader$manufacture hated 9 8 master
|Check that stalker is not initialized|
|Should give depressing errors|
spy$action politician
spy$control politician
|Initialize stalker|
spy$stalk
|Test io modes with fibonacci series|
|Should print Press any key to continue..., then will display the fibonacci series|
spy$distant
overseer$set person1 10
leader$set test1 0
leader$set test2 1
bbs$scrawl " , 
fate$corpse fibonacci_1
leader$add test3 test1 test2
leader$set test1 test2
leader$set test2 test3
spy$action # test1
bbs$read ~
spy$echo
fate$choice test1 < 1000000
	fate$stumble fibonacci_1
fate$reprogram
fate$illusion fibonacci_1
bbs$tear *
bbs$scrawl " Press any key to continue...
bbs$read
spy$personal
spy$echo
spy$action person1
spy$distant
spy$control test1
spy$action person1
spy$paracusia
|Test that choices work and nested choices are allowed|
|Should display True,True,False,True,True,True,False|
spy$personal
bbs$scrawl " True
bbs$scrawl person1
keep_out$scrawl " False
keep_out$scrawl person1
fate$choice 0 = 0
	bbs$read ~
	spy$echo
fate$reprogram
fate$choice 0 = 0
	bbs$read ~
	spy$echo
fate$balance
	keep_out$read ~
	spy$echo
fate$reprogram
fate$choice 0 <> 0
	bbs$read ~
	spy$echo
fate$balance
	keep_out$read ~
	spy$echo
fate$reprogram
fate$choice person2 = person3
	path$choice person2 = 0
		bbs$read ~
		bbs$read ~
		spy$echo
		spy$echo
	path$balance
		bbs$read ~
		keep_out$read ~
		spy$echo
		spy$echo
	path$reprogram
fate$balance
	path$choice person2 = 0
		keep_out$read ~
		bbs$read ~
		spy$echo
		spy$echo
	path$balance
		keep_out$read ~
		keep_out$read ~
		spy$echo
		spy$echo
	path$reprogram
fate$reprogram
fate$choice person2 = person3
	path$choice person2 = 1
		bbs$read ~
		bbs$read ~
		spy$echo
		spy$echo
	path$balance
		bbs$read ~
		keep_out$read ~
		spy$echo
		spy$echo
	path$reprogram
fate$balance
	path$choice person2 = 1
		keep_out$read ~
		bbs$read ~
		spy$echo
		spy$echo
	path$balance
		keep_out$read ~
		keep_out$read ~
		spy$echo
		spy$echo
	path$reprogram
fate$reprogram
bbs$tear *
keep_out$tear *
|Test Randomization|
overseer$chaos person2
spy$action # person2
spy$action person1
|Test getting rid of master variable|
overseer$suicide politician
|Test garbage collect|
overseer$void
|Test sign functionality|
|Shoud output ello, world!,world!,w,orld!,orld!,|
leader$set person1 10
bbs$tear *
bbs$scrawl " Hello, world!
bbs$scrawl person1
bbs$tear
bbs$read ~
spy$echo
bbs$tear 6
bbs$read ~
spy$echo
bbs$observe test1
spy$action test1
spy$action person1
bbs$steal test1
bbs$read ~
spy$echo
bbs$read
spy$echo
bbs$read
spy$echo
|Test disposition conflict|
leader$set hater hated
|Test murphy's law|
spy$action /THIS/IS/NOT/A/VALID/VARIABLE/NAME
|Cleanup|
test$twist manipulator final
final$manufacture temporary 0 8 master
final$empty
test$consume final
test$consume spy
test$consume fate
test$consume keep_out
leader$suicide test3
|Should show overseer melting person3, overseer dying, leader melting person1 test1 test2, leader dying, path, bbs|


External resources

Visual Basic.NET interpreter and sample programs