FerNANDo

From Esolang

Jump to: navigation, search

ferNANDo is an esoteric programming language by User:Whtspc. It's based on NAND-logic and uses no other syntax-elements than variable names. When variables names are chosen carefully, programs may sound quite poetic.

At initialization every possible variable is set to 0. (Actually every time the program encounters an undefined variable, it creates this variable with the value 0.)

The amount of words (variables) in a sentence determine what type of command will be executed. There are 3 commands.


Contents

[edit] The NAND command

A B C

The NAND command is executed when there are 3 variables in a sentence. It sets the value of the first variable to the NAND of the second and third. In the above example it sets 'A' to 'B NAND C'. Since the variables are set to 0 by default, A will be 0 NAND 0, which is 1.

[edit] The output command

A B C D E F G H

The output command is executed when there are 8 variables in a sentence. The value of the binary digit represented by the values of the variables in the sentence together is displayed as ascii character.

[edit] The conditional loop command

loop 
loop loop loop
loop

When there's only one variable in a sentence and this variable has value 1, program points back to the line right after the previous sentence that's exactly the same. If there isn't a correspondenting sentence back in the program, the command is ignored and program continues without any further action. The same happens when the value of the variable is 0.

So, walking through the example above:

-the word 'loop' is unknown, and undefined therefore. The variable 'loop' is created with value 0.

-Since the value is 0 we ignore the command in line 1.

-In the second line the variable 'loop' is set to 'loop NAND loop', or 0 NAND 0, which is 1. The variable 'loop' now has value 1.

-In the third line we have one variable with value 1, so we have to go back to the line after the previous sentence that's exactly the same. In this case line 1 is exactly the same, so the program points back to line 2.

-In line 2 'loop' is set to 'loop NAND loop', loop is 1 by now, 1 NAND 1 = 0, loop is set to 0.

-We encounter line 3 again, loop is now 0, so the command is ignored. Since there are no other lines left, program execution is stopped.

[edit] Example programs

[edit] Hello world

The following program displays 'Hello, world!'

ave ave ave
terra ave terra terra ave terra terra terra
terra ave ave terra terra ave terra ave
terra ave ave terra ave ave terra terra
terra ave ave terra ave ave terra terra
terra ave ave terra ave ave ave ave
terra terra ave terra ave ave terra terra
terra terra ave terra terra terra terra terra
terra ave ave ave terra ave ave ave
terra ave ave terra ave ave ave ave
terra ave ave ave terra terra ave terra
terra ave ave terra ave ave terra terra
terra ave ave terra terra ave terra terra
terra terra ave terra terra terra terra ave

[edit] Other logic gates

To place the value of logic gate(a,b) into O:

NOT:

O A A

AND:

O A B
O O O

OR:

C A A
D B B
O C D

NOR:

C A A
D B B
O C D
O O O

XOR: (this might be simplifiable)

C A A
D B B
E A D
F C B
O E F

NXOR: (this might be simplifiable)

C A A
D B B
E A B
F C D
O E F

A IMPLIES B:

C B B
O A C

[edit] bounded rule30 automaton

It's very small, but it's there.

x x x
h h h
x
z z x z z z a a
z z x z z z b b
z z x z z z c c
z z x z z z d d
z z x z z z e e 
z z x z z z f f
z z x z z z g g
z z x z z z h h
z z z z x z x z
i a a
j b b
o i j
i null null
j o o
k null j
l i o
aa k l
i b b
j c c
o i j
i a a
j o o
k a j
l i o
bb k l
i c c
j d d
o i j
i b b
j o o
k b j
l i o
cc k l
i d d
j e e
o i j
i c c
j o o
k c j
l i o
dd k l
i e e
j f f
o i j
i d d
j o o
k d j
l i o
ee k l
i f f
j g g
o i j
i e e
j o o
k e j
l i o
ff k l
i g g
j h h
o i j
i f f
j o o
k f j
l i o
gg k l
i h h
j null null
o i j
i g g
j o o
k g j
l i o
hh k l
a aa aa
a a a
b bb bb
b b b
c cc cc
c c c
d dd dd
d d d
e ee ee
e e e
f ff ff
f f f
g gg gg
g g g
h hh hh
h h h
x

[edit] Haskell implementation

import qualified Data.Map as M
import System.Environment (getArgs)

type Prog = [[String]]
data LabelData = L (M.Map String LabelData) Prog

value v vs = M.findWithDefault False v vs
x `nand` y = not (x && y)

runCmds :: M.Map String Bool -> M.Map String LabelData -> [[String]] -> String
runCmds vars labels prog@([label]:rest)
    = case (value label vars, M.lookup label labels) of
        (True, Just (L labels' prog'))
            -> runCmds vars labels' prog'
        _   -> runCmds vars labels' rest
          where labels' = M.insert label (L labels' rest) labels
runCmds vars labels ([v1,v2,v3]:rest)
    = runCmds (M.insert v1 (value v2 vars `nand` value v3 vars) vars)
        labels rest
runCmds vars labels (vs@[_,_,_,_,_,_,_,_]:rest)
    = c : runCmds vars labels rest
  where
    c = toEnum $ foldl (\n b -> n*2 + fromEnum (value b vars)) 0 vs
runCmds _ _ [] = ""
runCmds _ _ (snt:_) = error $ "Undefined sentence: " ++ unwords snt

interpret = runCmds M.empty M.empty . map words . lines

main = do
    args <- getArgs
    case args of
        [] -> interact interpret
        [fileName] -> putStr . interpret =<< readFile fileName
        _ -> error "Too many arguments, only one supported"

[edit] Python implementation

# FerNANDo Interpreter
# Runs fernando programs, used command line style.
# By Orange
# Version 0.1
# With anonymous modifications by 164.67.235.79 and 131.179.32.131

# You're free to use this code as you wish

def add_vars(varlist,toadd):
    ''' adds the items in toadd if not in varlist '''
    for v in toadd:
        if v not in varlist:
            varlist[v] = 0

def FerNANDo(program,debug=0):
    ''' Run a FerNANDo program '''
    p = program.split('\n') #Split the string into a
                            #Sequence of lines
    pc = 0      #program counter
    var = {}    #holds variables
    labels = [] #format: [linenumber,labelname]
    
    while pc<len(p):
        #Split the current line into the variable line
        line = p[pc].split(' ')
        
        while True: #Remove spaces
            try: line.remove('')
            except: break
        
        if debug: print '\t',len(line),line
        
        #See how many varibales on a line
        #If 1,3,or 8, execute a command
        if len(line)==3: #NAND
            add_vars(var,line)
            a = var[line[0]]
            b = var[line[1]]
            c = var[line[2]]
            var[line[0]] = not (a and b)
        
        if len(line)==1: #Jump
            add_vars(var,line)
            if var[line[0]]:
                pc = p.index(line[0])
        
        if len(line)==8: #Output
            add_vars(var,line)
            a,b,c,d,e,f,g,h = line
            ascii = (var[h]<<0)|(var[g]<<1)|(var[f]<<2)|(var[e]<<3)|(var[d]<<4)|(var[c]<<5)|(var[b]<<6)|(var[a]<<7)
            sys.stdout.write(chr(ascii))
        pc += 1
    
    print'\nDone.'


import sys

try:
    f = open(sys.argv[1])
    FerNANDo(f.read())
except IOError:
    print"Error: Can't open file"
except IndexError:
    print"Error: Missing file to run"
    print"Usage:\n\tnand.py filetorun.nand"
Personal tools