From Esolang
Jump to navigation Jump to search

Trichotomy: The link between Subleq+ and OISC:3

Trichotomy is hack of Subleq, the one instruction language OISC. It is named for the property that numbers can take three forms: positive, negative, or zero. It uses these three forms to gain eight separate functions plus indirect addressing from the three integer addresses of its instruction format.

In Subleq, that instruction is SUBtract and branch if Less than or EQual to zero. Each instruction has the form A B C, where B = B-A; if B <= 0, jump to C.

Subleq+ Improved upon Subleq by using negative addresses as indirection.

OISC:3 took the Subleq form in a different direction, using zeros among A, B and C to indicate different instructions, and including a stack, call & return functions, and a relatively powerful coprocessor function that worked on the stack. The single instruction takes the form A B C, where C = B-A. It uses real numbers to indicate indirect addresses, because it uses negative addresses as a separate memory space used only for data.

Trichotomy takes a form very similar to OISC:3, but omits the coprocessor and negative memory space, and only uses integers. A relatively robust parser allows for convenient programming. Convenient, that is, given that the only significant abilities of the language are to move integers between cells, subtract one from another, call & return subroutines, push and pop from a stack, input a single character, and print a character or an integer. An important distinction is that in Trichotomy, the first address given in a program must be the location of the first instruction. Memory location 0 is the program counter, and is not directly addressable.


A, B, and C are addresses.  If negative, they are indirect addresses.  The [data] is at the address.  
A B C    [C] = [B] - [A]
A 0 C    If [A] <= 0, goto C
0 B C    If [B] <= 0, call C
0 B 0    If [B] < 0, return.  Halt if the return stack is empty.
A B 0    Perform I/O with [A] as a target and B as the format
            1:  Print [A] as a character
            2+: Print [A] as a number
            -1: Input a character with echo, store its value in A
            -2-:Input a character without echo, store its value in A
A 0 0    Push [A] to the stack
0 0 C    Pop the top of stack to [C]
0 0 0    Halt

Assembler/parser instructions

@        This address
?        The following address
!        0, useful for indicating alternate functions
#        What follows is a comment
*        Indirection.  Makes the following address negative.
" '      Quoted strings.  Can use the other mark inside.  Good form is to follow a string with a 0.
%        Data marker.  Data is unformatted, where instructions are always three integers.
:        At the end of a word creates a symbol, which the parser uses as an alias for an address.  
             Note that symbols are used without the trailing colon.
             Example:   .Message1: ? "The quick brown fox jumps over the lazy dog." 0          
+ -      Appended to a symbol allows simple math.  ? is equivalent to @+1.
ZERO     An addressed value of 0, automatically added by the compiler if not already present.
;        Separates commands.
/        Prepends an assembler macro.
   /sub A B C   C = B-A  Not necessary, but available.  Alternate: /subleq
   /sub A B     B = B-A  shorthand.  The "/sub" is not necessary.
   /sub A       A = A-A  shorthand.  The "/sub" is not necessary.
   /goto A C    If A is omitted, ZERO is inserted to make the branch mandatory.  Alternates: /goto? /jmp /jmp?  
   /call B C    If B is omitted, ZERO is inserted to make the branch mandatory.  Alternates: /call? /jsr /jsr? 
   /return B    If B is omitted, ZERO is inserted to make the branch mandatory.  Alternate: /return? /ret /ret? 
   /io A B      Perform input or output with A as target and B as format.  Alternate:  /inout
                    1: print character  2: print number  -1: echo input character  -2: noecho input character
   /print A     Prints A as a character.  "/print A 2" will print A as a number.  Alternates:  /output /out   
   /input A     Inputs a character to A.  "/input A -2" will input without echo.  Alternate:  /in
   /push A      Pushes A onto the stack.
   /pop C       Pops the top of stack and stores it in C.
   /halt        Unconditional program halt.
   /copy B C    Equivalent to ZERO B C.  Alternate:  /move

   //import filename   Imports module filename and appends its code to the main file.
                   Modules cannot import other modules.
   //import filename as handle     Replaces every instance of '$' in the code of the module with 'handle.' 
                       to avoid symbol duplication.
                   Example:  "import testmod.slm as Test" will rename "$function_test" in the module
                       to "Test.function_test".
                   If no "as handle" is given, each '$' in the module code (not literals) 
                       will be stripped off, so "$function_test" would become "function_test".

Example program

# This is a very simple "Hello world" type program in Trichotomy.
START    # Mandatory address where the first instruction resides.        # 4
%M1: -1                                                                  # -1
%cr: 10                                                                  # 10
%space: 32                                                               # 32  Not actually used, but helps line up the 3 number code blocks
/push msg1; /call PRINT                                                  # 16 0 0; 0 84 68
/print cr                                                                # 2 1 0
/halt                                                                    # 0 0 0 
% msg1: ? "Good morning, starshine.  The earth says, 'Hello!'" 0
# 17 71 111 111 100 32 109 111 114 110 105 110 103 44 32 115 116 97 114 115 104 105 110 101 46 32 32
# 84 104 101 32 101 97 114 116 104 32 115 97 121 115 44 32 39 72 101 108 108 111 33 39 0

/pop print_char                                                          # 0 0 83
/ret? *print_char   # looks for the trailing 0                           # 0 -83 0
/print *print_char 1                                                     # -83 1 0
M1 print_char    # To move the pointer along, you have to subtract -1.   # 1 83 83
/goto Print_Loop                                                         # 84 0 71
% print_char: 0                                                          # 0
# %ZERO: 0   added by parser                                             # 0

Computational class

Trichotomy is Turing complete. It derives from Subleq, but is easier to use.

See also

  • OISC One Instruction Set Computing.
  • Subleq The most successful OISC.
  • Subleq+ Subleq with indirect addressing.
  • OISC:3 Obfuscated Indirect Subleq with Coprocessor: 3 word instructions.

External resources

--McChuck (talk)