!!!Batch

From Esolang
Jump to navigation Jump to search
!!!Batch
Paradigm(s) imperative, self-modifying
Designed by Shubshub
Appeared in 2012
Memory system variables
Dimensions one-dimensional
Computational class Turing complete
Reference implementation !!!Batch/Interpreters, !Py!Batch (MediaFire)
Influenced by Batch
Influenced !!!
File extension(s) unknown

!!!Batch is another derivative of the Batch programming language created by Shubshub :D. !!!Batch is an encoding of Batch where each character is in the form of a question mark, followed by some amount of exclamation marks, then an optional marking character, and finally another question mark. Other characters are returned as-is. Since !!!Batch is an encoding of Batch, and Batch is Turing complete, so is !!!Batch.

Syntax

Source code for version 1.3 is formatted as set str=<code>, with <code> being the !!!Batch source code. The code is decoded into ASCII characters which are then put into a Batch file. The output file always begins with @echo off and ends with pause. Since the input file is executed as a Batch file, it has access to the entire language before being compiled, effectively making Batch its meta-language.

Further versions have code formatted plainly in a file. The file is no longer executed, and the heading @echo off and footing pause are omitted. Additionally, the official translators also execute the resulting output file.

Encoding

Each version has a different alphabet.

  • Version 1.3: abcdefghijklmnopqrstuvwxyz& ?!\/.:0123456789|
  • Version 1.5: abcdefghijklmnopqrstuvwxyz& ?!%/.:0123456789=+-<>@*, upper ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • Version 2.0: abcdefghijklmnopqrstuvwxyz, middle & ?!%/.:0123456789=+-<>@*, upper ABCDEFGHIJKLMNOPQRSTUVWXYZ

The number of exclamation marks in a character's encoding corresponds to its 1-based index in its alphabet, e.g. a has 1 mark, z 26, A 1, etc. If the character in the upper alphabet a plus is appended, or if in the middle, a hyphen minus. Characters in the normal alphabet don't have a character appended. Finally, the result is surrounded by a question mark on both sides. Select encodings in version 2.0:

  • a: ?!?
  • b: ?!!?
  • %: ?!!!!!-?
  • A: ?!+?
  • D: ?!!!!+?

Examples

Hello world (version 1.3)

Hello World In !!!Batch :D

set str=?!!!!!??!!!??!!!!!!!!??!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!!!!!!!!!!!??!!!!!!!!??!!!!!??!!!!!!!!!!!!??!!!!!!!!!!!!??!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!??!!!!!!!!!!!!??!!!!??!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!?

Hello world (version 1.5)

Hello world example (because some of the code has changed). This outputs Hello World! (Because !!!Batch now supports capital lettering).

?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!??!!!!!??!!!??!!!!!!!!??!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!??!!!!!!??!!!!!!?
?!!!!!??!!!??!!!!!!!!??!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!!!!!!!!!!!??!!!!!!!!+??!!!!!??!!!!!!!!!!!!??!!!!!!!!!!!!??!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!!!!!!+??!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!??!!!!!!!!!!!!??!!!!??!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!?
?!!!!!!!!!!!!!!!!??!??!!!!!!!!!!!!!!!!!!!!!??!!!!!!!!!!!!!!!!!!!??!!!!!?

This converts to

@echo off
echo hello world!

Multi version translator

This Python script supports translating the major versions of !!!Batch into ASCII. It doesn't support use of Batch as a meta-language while being translated.

import argparse


lowerbet = ('abcdefghijklmnopqrstuvwxyz', '')
middlebet13 = ('& ?!\/.:0123456789|', '')
middlebet15 = ('& ?!%/.:0123456789=+-<>@*', '-')
upperbet = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', '+')

version_bets = {
    '1.3': [(lowerbet[0] + middlebet13[0], '')],
    '1.5': [(lowerbet[0] + middlebet15[0], ''), upperbet],
    '2.0': [lowerbet, middlebet15, upperbet]
}


def translate(s, version='2.0'):
    for bet, symbol in version_bets[version]:
        for i, c in enumerate(bet):
            s = s.replace('?' + '!' * (i + 1) + symbol + '?', c)
    return s


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('source')
    parser.add_argument('--output', '-o', default='runscript.bat')
    parser.add_argument('--std', '-s',
        choices=version_bets.keys(), default='2.0'
    )
    args = parser.parse_args()

    with open(args.source) as f:
        s = f.read()

    s = translate(s, args.std)

    with open(args.output, 'w') as f:
        f.write(s)


if __name__ == '__main__':
    main()