lenum
- 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