NOR

From Esolang
Jump to navigation Jump to search

Description

NOR is an esoteric language created by Dylan Turner to replicate how a processor interprets data on a physical transistor level.

However, instead of using all the logic gates (AND, OR, NOT, NAND, XOR, etc.) it just uses NOR.

NOR is a universal logic gate and thus can be used to make the other gates, just in a much less convenient way.

Data Manipulation

NOR stores data in a strange way. Instead of a data pointer or variables, every time you call the NOR operation, it stores that operation as that line's value. This can be accessed by other NOR calls and outputs. You can access these stored values for lines by placing a "#" followed by a number, a ":", and a default value ("0" or "1"). When the interpreter reads this value, it does the default value if the number hasn't happened yet. It also as an array of input values for program input. At the beginning of each program, you place a line of a single number which is the size of that array. You access the values of this array by saying "IN" and then the index of that array.

Example to show Data Manipulation:

"100 NOR #300:0, 1" - stores the NOR of line 300 and 1 into line 100. Except that at the start, line 300 hasn't happened yet, so it does the default value of 0.

"200 OUT #100:1" - prints the value of that last NOR

"300 NOR 0, IN0" - stores the NOR of 0 and input[0]

"400 JMP 100" - Jumps back to 100, now with a value for line 300

Op Codes

NOR has 10 OpCodes: NOR, INP, OUT, OLN, JMP, REM, RND, OFF, MUX, and RST, and it works much like basic, with line numbers. Commas are optional, but they help to make the code look nice.

OpCode Arguments Meaning
NOR LN NOR #1, #2 At line LN, set the line value to the NOR operation of #1 and #2
INP LN INP IN# At line LN, input a 0 or 1 to the array of input values
OUT LN OUT # At line LN, prints out the value of #
OLN LN OLN At line LN, prints a new line
JMP LN JMP # At line LN, jump to line #
REM LN REM blah blah blah Works as a comment (NOTE: still needs a line number)
RND LN RND IN# At line LN, sets input[#] to a random value between 0 and 1, or without argument sets the line to a random number.
OFF LN OFF At Line LN, turn off the circuit (end the program)
MUX LN MUX #, Jump1, Jump2 At line LN, if # is 0 go to line Jump1, and if # is 1 go to line Jump2. This is essentially a multiplexer.
RST LN RST At line LN, reset all line values to nonexistance

Obviously the key opcode is the NOR opcode. Not only does it work as a NOR, but it can be used to represent some conditionals.

LN NOR #, 0

Is the same as:

if (# == 0)
    line[LN]=1
else
    line[LN]=0

Where line is an infinite array that stores the value of each line number, and # is a value equal to 0, 1, line[some number], or input[some number].

For the multiplexer command:

LN MUX #, Jump1, Jump2

Is the same as

if(# == 0)
    Goto Jump1
else if(# == 1)
    Goto Jump2

Turing Completeness

NOR was previously proven to not be Turing-complete because it was possible to solve for the halting problem, but that was before the OFF and MUX commands were added which change this result. No longer is that known.

Example Programs

Here are a few example programs:

1bit Adder.nor

Adds two 1bit numbers together (w/ carry):

2

0 INP IN0
100 INP IN1
150 OLN

200 REM XOR logic here
  300 NOR IN0, IN0
  400 NOR IN1, IN1
  500 NOR #300:0, #400:0
  600 NOR IN0, IN1
  650 NOR #600:0, #620:0
700 REM AND logic here
  800 NOR IN0, IN0
  900 NOR IN1, IN1
  1000 NOR #800:0, #900:0
1100 REM Output carry then value
  1200 OUT #1000:0
  1300 OUT #650:0
  1310 OLN
1325 JMP 1375

1350 OFF

1375 REM Input and repeat if 1
  1400 INP IN0
  1500 MUX IN0, 1350, 1600

1600 OLN
1700 JMP 0

Infinite Loop.nor

Infinitely prints 0 and 1 (alternating)

0
0 REM Infinite loop
50 NOR #50:0, 0
100 OUT #50:0
200 JMP 50

Truth Machine.nor

Prints 0 if input is 0.

Prints 1 infinitely if input is 1

1
0 REM Input a value
10 INP in1

20 REM Split the circuit into two paths:
30 REM if 0, goto OUT 0 (Line 70)
40 REM if 1, goto OUT 1 (Line 100 - the infinite loop)
50 MUX in1, 70, 100

60 REM Print 0 and then quit
    70 OUT 0
    80 OFF

90 REM Print 1 indefinitely 
    100 OUT 1
    110 JMP 100

Hello, world.nor

You can't print ascii values directly, but you can print the binary equivalent

Also, you can print directly 1s and 0s with OUT, but I take the long way, changing individual line values and printing a string of changing values

Because of its tediousness, I only go to print "Hello" in ascii

1
0 REM store the H in line values
 10 NOR 0, 1
 20 NOR 0, 0
 30 NOR 0, 1
 40 NOR 0, 1
 50 NOR 0, 0
 60 NOR 0, 1
 70 NOR 0, 1
 80 NOR 0, 1
90 REM print it all out
 100 OUT #10:0
 110 OUT #20:0
 120 OUT #30:0
 130 OUT #40:0
 140 OUT #50:0
 150 OUT #60:0
 160 OUT #70:0
 170 OUT #80:0
 175 OLN
180 REM Change to little e
 190 NOR #30:0, 0
 200 NOR #50:0, 0
 210 NOR #60:0, 0
 230 NOR #80:0, 0
240 REM Output with replaced values
 250 OUT #10:0
 260 OUT #20:0
 270 OUT #190:0
 280 OUT #40:0
 290 OUT #200:0
 300 OUT #210:0
 310 OUT #70:0
 320 OUT #230:0
 325 OLN
330 REM Change to little l
 340 NOR #200:0, 0
 350 NOR #230:0, 0
 360 REM Output little l twice
 370 OUT #10:0
 380 OUT #20:0
 390 OUT #190:0
 400 OUT #40:0
 410 OUT #340:0
 420 OUT #210:0
 430 OUT #70:0
 440 OUT #350:0
 445 OLN
 450 OUT #10:0
 460 OUT #20:0
 470 OUT #190:0
 480 OUT #40:0
 490 OUT #340:0
 500 OUT #210:0
 510 OUT #70:0
 520 OUT #350:0
 525 OLN
530 REM Change to little o
 540 NOR #70:0, 0
 550 NOR #350:0, 0
560 REM Output little o
 570 OUT #10:0
 580 OUT #20:0
 590 OUT #190:0
 600 OUT #40:0
 610 OUT #340:0
 620 OUT #210:0
 630 OUT #540:0
 640 OUT #550:0
 645 OLN
650 REM Pause at end
 660 INP in0

Decrement Test.nor

A program which counts down two line numbers.

It outputs 11, 10, 01, 00.

1
0 REM Decreases line values from 11 -> 10 -> 0 -> 00
10 NOR #90:0, #90:0
20 NOR #60:0, #60:0

30 NOR #10:1, #20:1
40 MUX #30:0, 50, 100

50 NOR #20:1, 0
60 NOR #50:0, #50:0

70 NOR #10:1, #10:1
80 NOR #70:1, #50:0
90 NOR #80:1, #80:1

95 JMP 10

24 OUT #10:1
25 OUT #20:1
26 OLN

100 INP IN0

Guess the Number (4-bit).nor

Input 4 bits of a number as your guess.

It says "L" in binary if your guess is less than the number, meaning you should guess higher.

It says "G" in binary if your guess is greater than the number, meaning you should guess lower.

It says "W" in binary if you guess the number and waits to see if you want to play again.

It says "D" in binary if you run out of guesses (you start with 3) and waits to see if you want to play again.

At the end it inputs a value: a 0 ends the program, a 1 has you play again.

4
99 REM Get 4 inputs and 4 random numbers
  100 RND
  101 RND
  102 RND
  103 RND
  150 INP in0
  200 INP in1
  250 INP in2
  300 INP in3
  
301 REM Store value of lives, starting with lives = 11 (3)
  302 NOR #4101:0, #4101:0
  303 NOR #4051:0, #4051:0

349 REM Check for in0 == 1 && #100 == 0
  350 NOR in0, 0
  400 NOR #100:0, #350:0
450 REM if #400 == 0, Move on, else Check for error
  500 MUX #400:1, 650, 550
550 REM Number is greater than #100: print "G" in binary
  599 OLN
  600 OUT 0
  601 OUT 1
  602 OUT 0
  603 OUT 0
  604 OUT 0
  605 OUT 1
  606 OUT 1
  607 OUT 1
  608 OLN
  610 JMP 4000

4000 REM Decrease lives and retake input
  4050 NOR #303:1, 0
  4051 NOR #4050:0, #4050:0
  
  4052 NOR #302:1, #302:1
  4100 NOR #4052:0, #4050:0
  4101 NOR #4100:0, #4100:0

  4102 REM Check if dead
    4103 NOR #4100:1, #4050:1
    4104 MUX #4103:0, 4150, 4200

  4150 JMP 150

4200 REM Game over: print "D" in binary
  4249 OLN
  4250 OUT 0
  4251 OUT 1
  4252 OUT 0
  4253 OUT 0
  4254 OUT 0
  4255 OUT 1
  4256 OUT 0
  4257 OUT 0
  4300 OLN
  4350 JMP 2560

650 REM Check for less than => in0 == 0 && #100 = 1
  700 NOR #100:1, 0
  750 NOR #700:0, in0
  800 MUX #750:1, 950, 850
850 REM if input is less than #100: print "L" in binary
  900 OLN
  901 OUT 0
  902 OUT 1
  903 OUT 0
  904 OUT 0
  905 OUT 1
  906 OUT 1
  907 OUT 0
  908 OUT 0
  909 OLN
  910 JMP 4000
950 REM they must be equal, so repeat with next part of the nibble

1000 REM Check for in0 == 1 && #100 == 0
  1050 NOR in0, 0
  1100 NOR #100:0, #350:0
1150 REM if #400 == 0, Move on, else Check for error
  1200 MUX #400:1, 1250, 550
1250 REM Check for less than => in0 == 0 && #100 = 1
  1300 NOR #100:1, 0
  1350 NOR #700:0, in0
  1400 MUX #750:1, 1450, 850
1450 REM Next part is equal, so move on

1500 REM Check for in0 == 1 && #100 == 0
  1550 NOR in0, 0
  1600 NOR #100:0, #350:0
1650 REM if #400 == 0, Move on, else Check for error
  1700 MUX #400:1, 1750, 550
1750 REM Check for less than => in0 == 0 && #100 = 1
  1800 NOR #100:1, 0
  1850 NOR #700:0, in0
  1900 MUX #750:1, 1950, 850
1950 REM Next part is equal, so move on

2000 REM Check for in0 == 1 && #100 == 0
  2050 NOR in0, 0
  2100 NOR #100:0, #350:0
2150 REM if #400 == 0, Move on, else Check for error
  2200 MUX #400:1, 2250, 550
2250 REM Check for less than => in0 == 0 && #100 = 1
  2300 NOR #100:1, 0
  2350 NOR #700:0, in0
  2400 MUX #750:1, 2450, 850
2450 REM Last part is equal, you win
2500 REM print W in binary
  2550 OLN
  2551 OUT 0
  2552 OUT 1
  2553 OUT 0
  2554 OUT 1
  2555 OUT 0
  2556 OUT 1
  2557 OUT 1
  2558 OUT 1
  2559 OLN
  2560 INP in0
  2600 MUX in0, 2650, 2700
2650 OFF

2700 RST
2750 JMP 99

Interpreter/Compiler

So far there's just one interpreter made in C# for the language: NOR Language Interpreter which can run all NOR programs.