Gene

From Esolang
Jump to navigation Jump to search

Gene is a language based on sexual reproduction of processes created by User:Sinthorion.

Core design principles

  • A program consists of multiple processes (ideally implemented as true system processes, but may be simulated in a VM)
  • Each process is limited in various ways: The amount of code it can have, how long it can live, etc
  • Each process has a sex assigned at birth, determined from its code
  • To create new processes, two processes of opposite sex must mate with each other
  • Newly created processes randomly inherit code from both parents

Basic structure

<LIMIT> refers to the global limit for each process. This should be 256.

While running, the program consists of any number of processes, each of which has:

  • A unique process ID (PID; for other processes to reference it).
  • A stack of unlimited size, containing unbounded (signed?) integers.
  • Exactly <LIMIT> instructions, each with a single parameter, which is an unsigned integer up to <LIMIT>.
  • A communication buffer (COMM), which stores incoming communications with sender PID and value (0-<LIMIT). May be limited (eg. to <LIMIT> communications) or arbitrary growing.

Additionally, there may be a special (main) process from the interpreter, which is not strictly speaking part of the program. To start a program, there are two ways:

  • Run the interpreter with a list of process codes which it will all start at the same time.
  • Run the interpreter with a single process code a specified number of times, each having a chance of some random mutations to its instructions.

Each process code is up to <LIMIT> instruction+argument pair (see details below); these will be filled up with NOP 0 instructions up to <LIMIT>.

Mating and Mutations

When two processes successfully mate (using the MATE instruction; see below), the following happens:

  1. A new process is spawned
  2. The code of this process is determined from the code of the two parents: For each instruction index, randomly use the instruction and argument of either of the two parents at the same index.
  3. Optionally the interpreter might additionally have a small chance to mutate each instruction and each argument value.
  4. Push the PIDs of both parents on the stack of the new process.
  5. Push the PID of the child on the stacks of both parents.
  6. Allow all 3 processes to continue execution.

Sex

Each process has a sex, and can only mate with processes of the opposite sex. This is deterministically determined from the process code, which means processes with exactly the same code have the same sex and cannot mate.

The sex is determined as follows:

  1. Encode each instruction as a byte.
  2. XOR all instruction bytes and all argument bytes.
  3. XOR all bits in that byte.
  4. The resulting bit is the sex.

We can call the sex for bit 0 "left" and for bit 1 "right".

Instruction Set

Each instruction is one instruction keyword from the lists below plus one argument. The argument is an integer in the range from 0 to <LIMIT>. In the following instruction descriptions, "n" refers to the argument value.

Basic stack operations:

  • PUSH n to stack
  • POP n vals from stack
  • ROTate highest n values on stack (=swap if n is 2; maybe distinguish between left and right rotate)
  • CLEAR the stack

Control flow:

  • LOOP n times
  • SLEEP n seconds
  • IF top is null, skip next n instructions

Arithmetic:

  • ADD n to top
  • SUBtract n from top
  • MULTiply n with top
  • SUM of highest n values
  • PRODuct of highest n values
  • DIVMOD top by n, pushing first div then mod result on stack
  • TOGGLE top by n if n is 0 (TOGGLE 1 is effectively a NOT with false = 0 and true = 1)

Social:

  • MATE with process with popped pid (or all if popped val is 0); waits for up to n seconds, then returns the child pid on success or 0 on failure
  • TELL n to process with popped pid, moving n to their comm buffer
  • SHOUT n to all other processes
  • LISTEN to comm buffer, moving the value to stack; listen only to comm from pid n unless n is 0
  • WAIT same as listen but blocks until the result would be nonnull

Implementation

Not yet implemented...