Circuit Diagram

From Esolang
Jump to: navigation, search

Circuit Diagram is a programming language created by Quincunx. It is simply an ASCII "art" way of representing and executing a circuit diagram (specifically the type for computers).

Logic gates

Circuit Diagram is largely based off of logic gates.

Symbol Corresponding Gate
a AND
A NAND
o OR
O NOR
x XOR
X XNOR
~ NOT

Logic gates (other than NOT) take two inputs from .'s from the left and output the answer to a . to the right. When one input has arrived, but the other has not, the gate waits until the other input comes before it outputs the correct answer. If, before the other input has arrived, the first input changes to something other than Null, then the gate takes that into account. NOT takes one input from the left and outputs it to the right. Sample (for AND):

.
 a.
.

The first and third lines are input, the second line is the output.

And for NOT:

.~.

Wiring

Basic wiring

In order to talk about wires, we first need to know how wires are connected to each other:

In the following, connections are shown by the c's

  • - is the horizontal wire. Connection:
c-c
  • | is the vertical wire. Connection:
c
|
c
  • / is a diagonal wire. Connection:
  c
 /
c
  • \ is a diagonal wire. Connection:
c
 \
  c
  • . connects with every surrounding wire:
ccc
c.c
ccc
  • = is special. It allows crossover connection. When a wire connects to this, the connection is extended one more character. Thus, in -=-, the two -'s are connected. In the following, opposite wires are connected.
\|/
-=-
/|\

For there to be a connection, a wire must be connected both ways (that is, the wire a wire is wired to must also be wired to the first wire). -| or even .| are not valid connections.

Note: the . from the logic gates are also the wire .

What it does

Let's say we have an individual group of connected wires (that is, each wire is directly or indirectly (but not through gates) connected to every other wire). Let's call that a wiring. A wiring cannot connect to both the input(s) and output of any gate / function. Each wiring holds one of three values: Null (denoted by N), 1, and 0. N signifies that the wiring has no signal. If, for some reason, a wiring is being outputted to with multiple values that are not N, the wiring takes a value that is the XOR of all of the inputs.

Multiple wiring

Any wire can instead be a multi-wire variation. This is shown on this page as -n- where n stands for the number of wires. The number can indeed be multiple digit, and the wires can indeed be at different angles. Note that you can add as many number labels as you want to the code; even with the + sign (e.g.: -1+2-) as long as the number is consistent with the number of wires. Otherwise, you get a compiler error. Additionally, multiple wire wires can be labeled with letters (or multiple letters) such as -variable- and it will be able to accept any constant amount of wires. It is important to note that the number applies to the whole wire.

Sample multiple wiring:

-3-:

That signifies three wires. The : returns all three wires.

 .--
.n--
 \
  .-

In this case, every one of those wires has n wires.

With some code like -4-, the wires are parsed as:
-1-
-2-
-3-
-4-

Where the numbers are labels on the wire. Whenever the first few wires are mentioned, we are talking about the first few wires according to the numerical ordering of those labels.

Multiple wires can also be inputted into any of the logic gates.

  • AND with multi-input will always output one wire which is 1 if all the other inputs are 1, 0 otherwise
  • NAND is the opposite of AND: 0 if all the inputs are 1, 1 otherwise.
  • OR is 1 iff there is an input which is 1, 0 otherwise.
  • NOR is 1 iff there are no inputs which are 1.
  • XOR is 1 iff there is exactly one 1 in the input.
  • XNOR is 1 iff there are only 0's or more than one 1 in the input.
  • NOT inverts every wire; it returns the same number of wires.

Input and Output

A - at the beginning of a line signifies one bit of input.

A : signifies output. This returns either a 0 or a 1, depending on the value of the - directly to the left of it. : cannot have any wires other than - flow into it, and the - must be directly to its left.

If the : appears in the main program, it prints the 0 or 1.

Functions

A function is basically a custom gate. Functions are defined by a {, followed by the function name (only unused words made only of alphabetical letters) and are ended by a } on its own line. In this case, input is in the same from, but from TWO or ONE wires, as in the gates. To have other amounts of input, multiple wire wires must be used. : returns the result; Multiple of them return to a multiple wire.

A function exists to supply power (ie 1) to the number of wires to its right:

)

Another function supplies a 0 to the number of wires to its right:

(

These are used as:

)-2-

and

(-2-

To allow for splitting wires (from multiple), this function is provided:

{<
     .-:
-n-.?
     .-:
}

The ? is a magical piece of code which splits the multiple wire in half, sending half (rounded down) to the upper output wire and half to the lower output wire. Note that this is used as follows:

    .-
-2-<
    .-

The .'s are unnecessary for this specific function; that is, any wire that connects to the < from the upper right or lower right receives the wire.

This similar function combines wires into one, with the second input being appended to the first:

{>
-n-.
    ?.-:
-m-.
}

Again, the ? is magic. This is used in the same form as <:

-n.
   >-n+m-
-m.

This function takes two multiple-input wires and outputs the second of them with the first n wires removed from the second.

{%
-n-.
    ?.-:
-m-.
}

Again, the ? is magic.

Another function is available:

t

This returns a 32 bit number (on a size 32 wire) representing the current time in seconds since the beginning of the year 2000 (for future compatibility, the year will have to be changed).

Execution

Execution works similarly to a cellular automaton. In each generation, if both of a gate's or function's inputs are non-null, it outputs the correct value to the wiring on its right, during the next generation. This means that a construction like a flip-flop is possible, but acts weirdly:

--.~.
   =
  .~.--

In this example, the wiring going to the right will output the following (with each character signifying a generation, also assuming a 1 as input):

1N1N1N1N...

It is possible to produce a constant output:

     .
--.-. a.----.--.~.
   \ .     /    =
    \     /    .~.-----
     .~.~.

Examples

4 bit prime tester

Written according to this (generated by minterms)

       .~..
      /    ..         .-.
     <.----=-----    .   o.
    / .~. /.   .---.    .  >.
-4-<     =  >.=--.  o.-=--.  \
    \ . . ..      ..  /       .
     < =    = .------=-----.   >.
      = .~..-=--.~.-.       .-.  a.-:
     / \    / \                 .
    .   .===.  .               /
     \   o.  \  o.------------.
      .-.     ..