LogicGates

From Esolang
Jump to navigation Jump to search

LogicGates is an esolang invented by User:None1.

Memory

It uses a bit accmulator, an unbounded bit tape and a pointer. All bits are initially 0.

Commands

  • </>: Move the pointer to the left/right.
  • [CODE]: While accmulator isn't 0, do CODE.
  • Logic gates represented by uppercase and lowercase letters.
Gate (0,0) (0,1) (1,0) (1,1) Equivalence (x, y)
A    0     0     0     0     False
B    0     0     0     1     AND
C    0     0     1     0     x AND NOT y
D    0     0     1     1     x
E    0     1     0     0     y AND NOT x
F    0     1     0     1     y
G    0     1     1     0     XOR
H    0     1     1     1     OR
J    1     0     0     0     NOR
K    1     0     0     1     XNOR
L    1     0     1     0     NOT y
M    1     0     1     1     x OR NOT y
N    1     1     0     0     NOT x
P    1     1     0     1     y OR NOT x
Q    1     1     1     0     NAND
R    1     1     1     1     True

The first operand is the accumulator and the second is the current cell. Uppercase letters store result in the accmulator, but their corresponding lowercase letters store in the current cell.

  • . (optional): Output bit in the accumulator.
  • , (optional): Input a bit and store in the accumulator.
  • (STUFF) (optional): Comment, can be nested.
  • Other commands are ignored.

Examples

Bit Inversion

,N.

Bit A+B

,d,G.

Unary XKCD Random Number

R....

Binary XKCD Random Number

R.A..

Looping counter

R[[>F]rR[.<F]A.R]

Prints:

10110111011110...

Basic logic gates

AND: B/b
OR: H/h
XOR: G/g
NOT (accumulator): N/n
NOT (current cell): L/l
NAND: Q/q
NOR: J/j

Computational class

All commands in boolfuck are available in LogicGates, except for +, which can be implemented using the logic gates, so this esolang is Turing complete.

Interpreters

Python

import sys
def logic_gates(code):
    gates={'a': (0, 0, 0, 0), 'b': (0, 0, 0, 1), 'c': (0, 0, 1, 0), 'd': (0, 0, 1, 1), 'e': (0, 1, 0, 0), 'f': (0, 1, 0, 1), 'g': (0, 1, 1, 0), 'h': (0, 1, 1, 1), 'j': (1, 0, 0, 0), 'k': (1, 0, 0, 1), 'l': (1, 0, 1, 0), 'm': (1, 0, 1, 1), 'n': (1, 1, 0, 0), 'p': (1, 1, 0, 1), 'q': (1, 1, 1, 0), 'r': (1, 1, 1, 1)}
    s=[]
    matches={}
    tape=[0]*1000000
    for i,j in enumerate(code):
        if j=='[':
            s.append(i)
        if j==']':
            m=s.pop()
            matches[m]=i
            matches[i]=m
        if j=='(':
            s.append(i)
        if j==')':
            m=s.pop()
            matches[m]=i
            matches[i]=m
    cp=0
    p=0
    acc=0
    while cp<len(code):
        if code[cp]in 'abcdefghjklmnpqrABCDEFGHJKLMNPQR':
            if code[cp].isupper():
                acc=gates[code[cp].lower()][acc*2+tape[p]]
            else:
                tape[p]=gates[code[cp].lower()][acc*2+tape[p]]
        if code[cp]==',':
            c=sys.stdin.read(1)
            acc=(ord(c) if c else 0)&1
        if code[cp]=='.':
            print(acc,end='')
        if code[cp]=='<':
            p-=1
        if code[cp]=='>':
            p+=1
        if code[cp]=='[':
            if not acc:
                cp=matches[cp]
        if code[cp]==']':
            if acc:
                cp=matches[cp]
        if code[cp]=='(':
            if 1:
                cp=matches[cp]
        if code[cp]==')':
            if 0:
                cp=matches[cp]
        cp+=1
logic_gates(sys.stdin.read())

Lua

By: User:Aadenboy

Output is parsed as a MSB character stream. Use the flag --writedigits to write the individual bits instead, or use --dumpbits to dump the final bit stream at the end of execution.

local flags = {}
for i=1, #arg do
    if arg[i]:match("^%-%-") then
        flags[arg[i]:sub(3)] = true
    end
end
local program = io.read()
local buffer, bufflen = 0, 0
local out = {}
function push(bit)
    buffer = buffer * 2 + bit
    bufflen = bufflen + 1
    if flags.writedigits then io.write(tostring(bit)) end
    if bufflen == 8 then
        out[#out + 1] = string.char(buffer)
        if not flags.writedigits then io.write(out[#out]) end
        buffer, bufflen = 0, 0
    end
end
function strbit(str, bit)
    return math.floor(str:byte(bit/256+1, bit/256+1) / 2^(bit % 256) % 2)
end
local tape = {[0] = 0}
local accumulator = 0
local pointer = 0
local i = 1
repeat
    local char = program:sub(i, i)
    if char:match("[A-HJ-NPQRa-hj-npqr]") then
        local num = char:byte() - 65
        local upper = num < 32
        num = num - (upper and 0 or 32) - (char:match("[J-Nj-n]") and 1 or (char:match("[PQRpqr]") and 2 or 0))
        local result = math.floor(num / 2^(3 - accumulator * 2 - tape[pointer]) % 2)
        if upper then accumulator = result
        else tape[pointer] = result end
    elseif char == "<" or char == ">" then
        pointer = pointer + (char == "<" and -1 or 1)
        tape[pointer] = tape[pointer] or 0
    elseif char == "[" and accumulator == 0 then
        i = program:sub(i):match("^%b[]()") - 1
    elseif char == "]" and accumulator ~= 0 then
        i = program:sub(1, i):match("()%b[]$")
    elseif char == "(" then
        i = program:sub(i):match("^%b()()") - 1
    elseif char == "." then
        push(accumulator)
    elseif char == "," then
        accumulator = strbit(io.read(), 0)
    end
    i = i + 1
until i > #program
for i=1, 8-bufflen do push(0) end
if flags.dumpbits then
    for i,v in ipairs(out) do for j=7, 0, -1 do
        io.write(tostring(strbit(v, j)))
    end end
    io.write(" ")
end

Dialects

exGates