Dogless

From Esolang
Jump to navigation Jump to search

Dogless (spelled dogless when not at the beginning of a sentence) is a string-based self-modifying programming language developed as a spiritual successor to the much simpler dupdog language. It's intended to be Turing complete, although it's currently unknown if it is.

Overview

Dogless programs are represented as a sequence of characters, where each character represents an instruction with the possibility of zero or more characters as parameters. The instruction itself along with its parameters are referred to as an instruction body. In addition, there are two metainstructions which take a subsequent instruction body as their parameters.

The | character marks the entry point of execution of a dogless program, and is referred to as the marker. There can be many | characters in a dogless program, but only the first occurrence is considered the marker. The character after the marker is the current instruction, and its effect will be executed as part of the current execution step. The source code on the left-side of the marker is referred to as the presource; the source code on the right-side of the current instruction body is referred to as the postsource. If there is no marker, then the program terminates, with its source code as the output of the program.


[                  S O U R C E  C O D E                ]
[presource][marker][instruction][parameters][postsource]
                   [    instruction body   ]
   abc         |        $          a   b        def


The above diagram labels the sections of the dogless program abc|$abdef. Whitespace is only used above to separate sections of the source code, and shouldn't be considered part of the source itself; whitespace is significant in dogless.

Each dogless instruction has the effect of modifying the source code in some way. In addition, every dogless instruction has the effect of removing its instruction body from the source code before its effect is executed.

Dogless has no concept of input distinct from the source code of the program itself.

Instructions

|

The marker, when encountered as an instruction, has no effect. Thus:

 abc||def

becomes:

abc|def

$

$ is an instruction that takes 2 characters as parameters and substitutes the first occurrence of its first parameter within the source code with its second parameter. Thus:

hello|$abaabb

becomes:

 hello|babb

and:

 hallo|$ae

becomes:

hello|

"

The quote deletes everything following it, up to the next quote or until the end of the string. Thus:

 abc|"def"g 

becomes:

 abc|g 

?

? reverses the source code. Thus:

 abc|?def 

becomes:

 fed|cba 

^

^ swaps the presource with the postsource. So:

 abc|^d|ef

becomes:

d|ef|abc

~

Appends the source code, including the ~ instruction, to the end of the current source. Thus:

 abc|~def

becomes:

 abc|defabc|~def 

!

Deletes the entire source, including the marker. So:

abc|!def

becomes:


\

\ serves as an escape character. It takes a single parameter, and appends its parameter to the end of the presource. Thus:

 abc|\$ab

becomes:

 abc$|ab 

Any other character

Non-special characters are appended to the presource when executed. Thus:

 abc|def 

becomes:

 abcd|ef 

End of string

When the marker is encountered at the end of the string, then the marker is removed from the source code and the program terminates.

It should also be noted that all instructions that expect parameters are not treated as the same instruction when encountered at the end of the string with some of its parameters missing. So, for example, an $ encountered at the end of a string is simply appended to the presource like any other non-special character.

Metainstructions

The following instructions expect as their parameters the full body of another instruction, termed the subinstruction. Note that metainstructions can be subinstructions to other metainstructions.

Both metainstructions have the effect of altering what their subinstruction considers to be "the source code", and consequently what it considers the presource and postsource to be.

<

The < instruction executes its subinstruction in the context of the presource. In other words, the presource temporarily becomes "the source code" for the subinstruction. For example:

 abc|<?def 

becomes:

 cba|def 

>

Likewise, the > instruction executes its subinstruction in the context of the postsource. For example:

 abc|>?def 

becomes:

 abc|fed 

Since the postsource temporarily becomes the new source code, this also has the effect of altering what the presource and postsource are. Thus, nesting a metainstruction within another metainstruction will skip forward through segments of source code delimited by markers. For example:

 abc|>>?de|fg 

becomes:

 abc|de|gf 

and:

 abc|><?de|fg 

becomes:

 abc|ed|fg 

Implementations