lenum

From Esolang
Jump to navigation Jump to search
Note that lenum is typically lowercased except, often, at the start of a sentence.

Lenum (as in letter-number) is an esolang designed to be much harder to program in than it looks. It is created by User:Iddi01.

At first sight it looks much easier than bf, but it's actually incomparably more difficult and complex. (See Bf loop equivalent.)

Description

Every single command in lenum consists of two characters. The first must be a letter, while the second can be either a letter or a number. Comments of even lengths made of other characters are ignored. For ease of implementation, it is recommended to not include newlines, spaces or odd-length comments in a program.

Here are the commands:

Command Description
ix increase variable x by 1
dx decrease variable x by 1
bx go x instructions back
fx go x instructions forward
vx specify variable x to be used with next instruction
sx set specified variable to x. Must be used to "define" the variable before doing anything else with it.
ou output specified variable as a number
oc output specified variable as a character
if begin if statement
eq check if preceding and succeeding variable are equal
ne check if preceding and succeeding variable are not equal
gt check if preceding variable is greater than succeeding variable
lt check if preceding variable is lesser than succeeding variable
ex followed by an if statement, if the statement only has one variable, then if it is zero, skip the following instruction. If the statement has two variables and one of the four commands above between them, then if the statement is false, skip the following instruction.

Note that for 'vx', 'if', 'eq', 'ne', 'gt', and 'lt', only at the command after them are they actually executed. This is important to know when using b or f.

A variant with better readability is to separate commands with a space. Interpreters can be trivially altered to support this variant.

Since the 'x' in commands can only be a digit, this esolang is restrictive in many ways, such as allowing at most ten variables. Still, it's Turing-complete since all bf commands can be implemented and variables can be arbitrarily large through the 'i' command.

Examples

Bf loop equivalent

v0s1v9s0ifv0eqv9exf8i0v0ouf2b6ifv0exb4
The "f2b6" in the code is called a "relay point". Relay points are essential if you want your loop to contain more than a few commands. They are basically f or b commands that won't be triggered by normal code execution but will be targeted and executed by other f or b commands. The simplest way is following them by an 'f2'.

The bf equivalent of the above code is (surprisingly) +[+.].

Increment by nine

(Assuming v0 is already defined)
v2s9d2i0ifv2exb5
This code only optimized size from pure i0's by 1 command. If you're optimizing for speed, then it makes no sense to try this.

Hello, World!

v0s9v2s9d2i0ifv2exb5v2s9d2i0ifv2exb5v2s9d2i0ifv2exb5v2s9d2i0ifv2exb5v2s9d2i0ifv2exb5v2s9d2i0ifv2exb5v2s9d2i0ifv2exb5v0ocv2s9d2i0ifv2exb5v2s9d2i0ifv2exb5v2s9d2i0ifv2exb5i0i0v0oci0i0i0i0i0i0i0
v0ocv0oci0i0i0v0ocv1s9v2s9d2i1ifv2exb5v2s9d2i1ifv2exb5v2s9d2i1ifv2exb5i1i1i1i1i1i1i1i1v1ocv2s9d2d1ifv2exb5d1d1d1v1ocv2s9d2d0ifv2exb5v2s9d2d0ifv2exb5d0d0d0d0d0d0v0ocv2s9d2i0ifv2exb5v2s9d2i0ifv2
exb5i0i0i0i0i0i0v0oci0i0i0v0ocd0d0d0d0d0d0v0ocd0d0d0d0d0d0d0d0v0oci1v1oc

(Remove the newlines and spaces when actually running)

Cat program

(Assuming input is already stored at variables 0-9)
v0ocv1ocv2ocv3ocv4ocv5ocv6ocv7ocv8ocv9oc

Truth machine

(Assuming v0 is already defined)
v9s0ifv0eqv9exf5v0oub2v0ou

Looping counter

v3s1v0s9i0v1s9v2s9d2i1ifv2exb5v2s9d2i1ifv2exb5v2s9d2i1ifv2exb5v2s9d2i1ifv2exb5i1i1i1v4s0d3v1oci4f2b7ifv3exb9i3f2b7d4i3ifv4exb5f2b8v0ocb3

Fibonacci sequence generator

v0s1v1s1v2s0v3s0v0ouv1oud0i2ifv0exb5f2b7d1i3ifv1exb5f2b8d2i1ifv2exb5f2b8d3i0i1ifv3exb6f2b9v1oub3

Implementation

Here's a moderate Python implementation:

program = input("Program: ")
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
variables = {}
lastcomms = []
loc = 0
while True: try: chars = program[loc*2:loc*2+2].lower() except IndexError: break if len(chars) < 2: break if chars[0] in letters: try: if chars[0] == 'i': if chars != 'if': variables[chars[1]] += 1 elif chars[0] == 'd': variables[chars[1]] -= 1 elif chars[0] == 's': if lastcomms[0][0] == 'v': variables[lastcomms[0][1]] = int(chars[1]) elif chars[0] == 'b': loc -= int(chars[1])# + 1 lastcomms = [] if loc > 0:lastcomms.append(program[loc*2-2:loc*2].lower()) if loc > 1:lastcomms.append(program[loc*2-4:loc*2-2].lower()) if loc > 2:lastcomms.append(program[loc*2-6:loc*2-4].lower()) if loc > 3:lastcomms.append(program[loc*2-8:loc*2-6].lower()) elif chars[0] == 'f': #print(lastcomms) loc += int(chars[1])# - 1 lastcomms = [] lastcomms.append(program[loc*2-2:loc*2].lower()) lastcomms.append(program[loc*2-4:loc*2-2].lower()) lastcomms.append(program[loc*2-6:loc*2-4].lower()) lastcomms.append(program[loc*2-8:loc*2-6].lower()) elif chars == 'ex': if lastcomms[1] == 'if': if variables[lastcomms[0][1]] == 0: loc += 1 elif lastcomms[3] == 'if': if lastcomms[1] == 'eq': if variables[lastcomms[0][1]] != variables[lastcomms[2][1]]: loc += 1 elif lastcomms[1] == 'ne': if variables[lastcomms[0][1]] == variables[lastcomms[2][1]]: loc += 1 elif lastcomms[1] == 'gt': if variables[lastcomms[0][1]] >= variables[lastcomms[2][1]]: loc += 1 elif lastcomms[1] == 'lt': if variables[lastcomms[0][1]] <= variables[lastcomms[2][1]]: loc += 1 elif chars == 'ou': if lastcomms[0][0] == 'v': print(variables[lastcomms[0][1]]) elif chars == 'oc': if lastcomms[0][0] == 'v': print(chr(variables[lastcomms[0][1]]), end="") if chars[0] not in ['b', 'f']: lastcomms.insert(0, chars) loc += 1 except: print("Error at instruction %d" % loc) break