Lenguage

From Esolang
Jump to navigation Jump to search

Lenguage is a language based on brainfuck, although its syntax is very different. It was invented by User:Pietu1998 in 2014 and inspired by this challenge.

Syntax

In a Lenguage program, the length of the program is the only thing that matters. The contents can be anything the programmer wants it to be.

First, the length of the program (in implementation-dependent characters) is calculated. Then, said length is converted to binary, left-padded by zeroes to a multiple of 3, and then evaluated like Binaryfuck.

Brainfuck Binaryfuck/Lenguage
+ 000
- 001
> 010
< 011
. 100
, 101
[ 110
] 111

Larger programs may will result in programs a little too large to be practical (see Hello World below).

Examples

Hello world

17498005810995570277424757300680353162371620393379153004301136096632219477184361459647073663110750484 of any characters.

That is about 1.75 * 1076 yottabytes in ASCII.

One-character cat program

Print the 1st character of the text in input

Reference implementation

This reference implementation is written in Python.

import sys

# From http://code.activestate.com/recipes/134892/
# "getch()-like unbuffered character reading from stdin
# on both Windows and Unix (Python recipe)"
class _Getch:
    """Gets a single character from standard input. Does not echo to the screen."""
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()
    def __call__(self): return self.impl()
class _GetchUnix:
    def __init__(self):
        import tty, sys
    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch
class _GetchWindows:
    def __init__(self):
        import msvcrt
    def __call__(self):
        import msvcrt
        return msvcrt.getch()
getch = _Getch()

if len(sys.argv) < 2:
    print("Usage: python lenguage.py <file>")
    sys.exit(1)
filename = sys.argv[1]
try:
    file = open(filename, "r")
    row = -1
    total = 0
    while row != "":
        row = file.readline()
        total += len(row)
    file.close()
except:
    print("Failed to read file")
    sys.exit(1)
binary = bin(total)[2:]
while len(binary) % 3 != 0: binary = '0' + binary
data = [0] * 65536
pointer = 0
sourceptr = 0
while sourceptr <= len(binary) / 3:
    source = binary[3 * sourceptr : 3 * sourceptr + 3]
    if source == '000':
        data[pointer] += 1
        if data[pointer] > 255:
            data[pointer] = 0
    elif source == '001':
        data[pointer] -= 1
        if data[pointer] < 0:
            data[pointer] = 255
    elif source == '010':
        pointer -= 1
        if pointer < 0:
            pointer = len(data) - 1
    elif source == '011':
        pointer += 1
        if pointer >= len(data):
            pointer = 0
    elif source == '100':
        print(chr(data[pointer]), end='')
    elif source == '101':
        data[pointer] = min(ord(getch()), 255)
    elif source == '110':
        if data[pointer] == 0:
            loop = 1
            while loop > 0:
                sourceptr += 1
                source = binary[3 * sourceptr : 3 * sourceptr + 3]
                if source == '110':
                    loop += 1
                elif source == '111':
                    loop -= 1
    elif source == '111':
        loop = 1
        while loop > 0:
            sourceptr -= 1
            source = binary[3 * sourceptr : 3 * sourceptr + 3]
            if source == '110':
                loop -= 1
            elif source == '111':
                loop += 1
        sourceptr -= 1
    sourceptr += 1

See also