Friday, April 15, 2022

OISC:2 It works! Mostly.

Here is a very basic implementation of OISC:2, written in Python.
Please feel free to play with it, but leave the attribution header.

Improved code with examples and a ReadMe can be found on GitHub.

# OISC2 without file reading or coprocessor.
# This is based on an implementation of Subleq found here:
#           https://rosettacode.org/wiki/Subleq#Python
# It has very limited error testing.  Buyer beware.
# McChuck, April 15, 2022

import sys

def oisc2(mem, negmem):

    negmem = [0,2,0,0,0,0,0]+negmem

#   IP, Next, Return, Reg a, Reg b, Reg c, Mode

    IP = -1

    NEXT = -2

    RET = -3

    negmem.reverse()

    mem=mem+negmem

    try:

        while mem[IP] >= 0:

            a=mem[mem[IP]]

            b=mem[mem[IP]+1]

            mem[NEXT]=mem[IP]+2

            if a>0:

                if b>0:

                    mem[b]-=mem[a]

                elif b==0:

                    print(chr(mem[a]), end="")

                else:

                    if mem[a]<=0:

                        mem[RET]=mem[NEXT]

                        mem[NEXT]=abs(b)

            elif a==0:

                if b>0:

                    mem[b]=ord(sys.stdin.read(1))

                elif b==0:

                    mem[NEXT]=-1

                else:

                    mem[mem[abs(b)]]=ord(sys.stdin.read(1))

            else:

                if b>0:

                    if mem[mem[abs(a)]]<=0:

                        mem[RET]=mem[NEXT]

                        mem[NEXT]=b

                elif b==0:

                    print(chr(mem[mem[abs(a)]]), end="")

                else:

                    mem[mem[abs(b)]]-=mem[mem[abs(a)]]

            mem[IP] = mem[NEXT]


        print("\nOISC2 completed successfully.")


    except (ValueError, IndexError, KeyboardInterrupt):

        print("OISC2 aborted at: ", ip)

        print("A: ", a, "B: ", b)

        print(mem)


    finally:

        print("\nFinished.")


oisc2([12, 12, 14, -30, 14, 0, 13, 2, 13, 4, 12, -2,
        0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 10, 0, 14,
        -29, 38, -29, 0, -40, -41, -40, 30, 0, 0, 13, 29], [0,0,1,2,3,4,5,6,0,0])


# 0 Z, Z     # You can't jump back to 0, so have to pad the beginning.
# 2 Start: L, -Cont
# 4 L, 0              # Print "Hello, world!" directly
# 6 M1, Start
# 8 M1, Start+2
# 10 Z, -Start
# 12 Z: 0 .
# 13 M1: -1 .
# 14 L: "Hello, world!\n"
# 29 LP: L .
# 30 Cont: -LP Halt
# 32 -LP 0            # Now print it again, but indirectly
# 34 -M1P -LPP
# 36 -M1P Cont
# 38 Halt: 0 0
# 40 M1P: M1 .
# 41 LPP: LP .


Thursday, April 14, 2022

Esolang OISC:3c

No, as a matter of fact I can't stop tinkering with things.

This is a simplification of OISC:3b, which had grown to be a rather unwieldy monster.

Instructions and data go in positive memory space.  Coprocessor functions and data go in negative memory space.  Negative addresses imply indirect addressing, unless specifically overridden below.  Jumping to a negative address Halts and Fails.  All words except NEXT are initialized to 0.

3 word instructions, A B C

A B C    Function
A B C    [C] = [B] - [A]   (Indirect is [[|-X|]])
0 B C    If [B] <= 0, Jump to C // [|-C|], else Next
A 0 C    If [A] <= 0, Relative Jump by #C (-2 is -2), else Next
A B 0    [#B] = [#B] - [#A] (-2 is -2)
A 0 0    Output [A] as character (if negative, Halt & Fail)
0 B 0    Input character to [B]
0 0 C    Output [C] as number
0 0 0    Halt and Succeed

Mem    Function
-1        IP
-2        NEXT (always IP+3)
-3        RETURN (set to NEXT before Jump)
-4        Register a
-5        Register b
-6        Register c
-7        Mode (immediately acts on a,b,c; then resets to 0)
-8        Flag
-9...     Data

Mode  Effect
0        NOP
1        c = bitwise NOT b
2        c = b bitwise AND a
3        c = b bitwise OR a
4        c = b bitwise XOR a
5        c = b << a bits
6        c = b >> a bits
7        c = Integer b*a
8        c = b/a (floored integer division)
                    (Halt & Fail on a=0)
9        c = b%a (Mod) (floored)
                    (Halt & Fail on a=0)
10        c = Sign of b (+1, 0, -1)
11        c = Floor of b
12        Int c --> Float c
13        Float c --> Int c
14        Int a,b --> Float a,b
15        Float a,b --> Int a,b
16        c = b-a
17        c = b+a
18        c = b*a
19        c = b/a
                    (Halt & Fail on a=0)
20        c = power a of b
21        c = root a of b
                    (Halt & Fail on a=0)
22        c = Log base b of a
                    (Halt & Fail on a=0 or b=0)
23        c = SIN b
24        c = COS b
25        c = TAN b
26        c = CSC b
27        c = SEC b
28        c = COT b
29        c = ASIN b
30        c = ACOS b
31        c = ATAN b
32        c = ACSC b
33        c = ASEC b
34        c = ACOT b
35        a = pi, b = e, c = phi
36        a = 1.0, b = 0.0, c = -1.0
37        c = b Rad --> Deg
38        c = b Deg --> Rad

Extensions to Mode are optional and left to the user.

Memories of Albania

 Yes, it was like this.  But the base was a corduroy road on slick spring mud, not rock.




And the next morning, we had to go back down.

Monday, April 11, 2022

Esolang: OISC 3b

In a (vain, I know) attempt to standardize things, here is OISC:3b, based on OISC:2.  I really do like this format better.  And there are 27 distinct combinations of +/0/- leading to obfuscatory effects!

Obfuscated Indirect Subleq with Coprocessor

Three word instruction:  A B C   

General form: C=B-A 
        Why not A-B=C?  Obfuscation is in the name!

Negative words are indirect addressing, which can be mixed: 
        [C]/[[|-C|]] = [B]/[[|-B|]] - [A]/[[|-A|]]

Instructions are only in positive memory.

If B=0 & C>0:  Output [A]/[[|-A|]] to I/O indicated by C. 

        1= STDOUT, 2= STDERR, 3...= File.
If A=0 & C>0:  Input [B]/[[|-B|]] from I/O indicated by C. 
        1= STDIN, 2= STDERR, 3...= File.

If B=0 & C<0:  Copy [A]/[[|-A|]] to [C]  (to negative memory)
If A=0 & C<0:  Copy [C] to [B]/[[|-B|]] (from negative memory)

If C=0:  If [A]/[[|-A|]] <=0, Jump B/[|-B|]
If A,C=0:  Jump [B]/[[|-B|]]
If B,C=0:  Relative Jump A

If A,B=0:  If [C]/[[|-C|]]<=0, HALT
If A,B,C=0:  HALT


Mem    Function

-1        IP (initialized to 0)
-2        NEXT (always IP+3)
-3        RETURN (set to NEXT before Jump]
-4        Register a
-5        Register b
-6        Register c
-7        Instruction Mode (activates on a,b,c; then resets to 0=NOP)
-8...     Data


Instruction Mode :  Takes immediate action on a,b,c, then resets to 0.

Mode       Effect

0        NOP
1        c = NOT a
2        c = b AND a
3        c = b OR a
4        c = b XOR a
5        c = b << a bits
6        c = b >> a bits
7        c = b*a
8        c = b/a (floored integer division) (HALT on /0)
9        c = b%a (Mod) (floored) (HALT on %0)
10        c = Sign of Int b (+1, 0, -1)
11        c = Sign of Float b (+1, 0, -1)
12        Int c --> Float c
13        Float c --> Int c
14        Int a,b --> Float a,b
15        Float a,b --> Int a,b
16        Float: c = b-a
17        Float: c = b+a
18        Float: c = b*a
19        Float: c = b/a (HALT on /0)
20        Float: c = power a of b
21        Float: c = root a of b (HALT on root 0)
22        Float: c = Log base b of a (HALT on base 0)
23        Float: c = SIN b
24        Float: c = COS b
25        Float: c = TAN b
26        Float: c = CSC b
27        Float: c = SEC b
28        Float: c = COT b
29        Float: c = ASIN b
30        Float: c = ACOS b
31        Float: c = ATAN b
32        Float: c = ACSC b
33        Float: c = ASEC b
34        Float: c = ACOT b
35        Float: a = pi, b = e, c = phi
36        Float: a = 1.0, b = 0.0, c = -1.0

Extensions to Mode are left to the user.

Sunday, April 10, 2022

Esolang: OISC:2

Continuing the attempt to make Subleq more concise.  Not faster or easier, mind.  I really like this one.  Not too easy, but more useful than standard Subleq.

Many thanks to Lawrence Woodman and also to the Truttle1 videos.

Two word instruction:  A B

If A&B are both positive; [B]=[B]-[A]
If A&B are both negative; [[B]]=[[B]]-[[A]]

If A is positive and B is negative; IF [A] <= 0 Jump |B|
If A is negative and B is positive; IF [[A]] <= 0 Jump B

If A is 0 and B is positive; STDIN -> [B]
If A is 0 and B is negative; STDIN -> [[B]] 

If A is positive and B is 0; [A] -> STDOUT
If A is negative and B is 0; [[A]] -> STDOUT

If A&B are 0; HALT

Negative memory can be addressed by indirection, but instructions are only in positive memory.

Mem    Function

-1        IP (initialized to 0)
-2        NEXT (always IP+2)
-3        RETURN (set to NEXT before Jump]
-4        Register a
-5    
    Register b
-6    
    Register c
-7    
    Instruction Mode (activates on a,b,c; then resets to 0=NOP)
-8        Flag (currently unimplemented and left to the user)
-9...     Data


Instruction Mode:  Takes immediate action on a,b,c, then resets to 0.

IM       Effect

0        No Op
1        c = NOT b
2        c = b AND a
3        c = b OR a
4        c = b XOR a
5        c = b << a bits
6        c = b >> a bits
7        c = integer b*a
8        c = b//a (floored integer division) (HALT on /0)
9        c = b%a (Mod) (floored) (HALT on %0)
10        c = Sign of b (+1, 0, -1)
11        c = Floor of b
12        Int c --> Float c
13        Float c --> Int c
14        Int a,b --> Float a,b
15        Float a,b --> Int a,b
16        c = b-a
17        c = b+a
18        c = b*a
19        c = b/a (HALT on /0)
20        c = power a of b
21        c = root a of b (HALT on root 0)
22        c = Log base b of a (HALT on base 0)
23        c = SIN b
24        c = COS b
25        c = TAN b
26        c = CSC b
27        c = SEC b
28        c = COT b
29        c = ASIN b
30        c = ACOS b
31        c = ATAN b
32        c = ACSC b
33        c = ASEC b
34        c = ACOT b
35        a = pi, b = e, c = phi
36        a = 1.0, b = 0.0, c = -1.0
37        c = b Rad --> Deg
38        c = b Deg --> Rad

Extensions to Mode are left to the user.

Friday, April 8, 2022

Esolang OISC:3

OISC:3 is a three word variant of OISC:4.  Naturally, we have to cut down on options.  It dispenses with the "if <=0, Jump" from every instruction.  Which, frankly, is no great loss.  I guess that makes this not technically a Subleq, but it keeps to the spirit of the thing.

Instruction A B C

If A>0:  Mem[C]=Mem[B]-Mem[A]
If A=0:  If Mem[B]<=0: Jump to C (Mem[|C|] if negative)

Negative addresses are indirect:  Mem[Mem[|A|]].

We can still use negative memory for data, but it has to be addressed indirectly.

Memory    Function
2             RET (set to NEXT before Jump)
1             NEXT (always IP+3)
0             IP (Initialized to 3) (HALT if negative)
-1           Input (replaces whichever A or B addressed it, -1 if none)
-2           Input Source and format
       (0 = wait for STDIN, 1 = immediate STDIN, 2... are Files)
-3           Output (outputs when a value is sent to it)
-4           Output Target and format
       (0 is STDOUT, 1 is STDERR, 2... are Files)
-5           Register a 
-6           Register b 
-7           Register c 
-8           Instruction Mode (IM) (activates Registers, then resets itself to 0)
-9...        Data

Thursday, April 7, 2022

Esolang OISC:4

Here is my esoteric language (esolang), Obfuscated Indirect Subleq with Coprocessor: 4 words per instruction (OISC:4).  {The joke is that OISC stands for One Instruction Set Computer.}

Instruction format:  A B C D are a 4 word instruction.
IP is the Instruction Pointer.  RET is the return pointer.
Positive memory:  Instructions and data, assumed to be signed integers.
Negative memory:  Coprocessor and data, may be integers or floats.

D>0:  Mem[C] = Mem[B] - Mem[A]; 
    if Mem[C]<=0, RET=NEXT, IP=D; else IP=NEXT

D=0:  Mem[C] = Mem[B] - A; (A is Literal)
    IP=NEXT

D<0:  Mem[Mem[C]] = Mem[Mem[B]] - Mem[Mem[A]]; (Indirect)
    if Mem[Mem[C]]<=0, RET=NEXT, IP=Mem[|D|]; else IP=NEXT

Low Memory

3        Z (initialized to 0)
2        RET (initialized to 4)
1        NEXT (always IP+4)
0        IP (if <0, HALT) initialized to 4
-1       Input (replaces whichever A or B addressed it, -1 if none)
-2       Input Source and format
       (0 = wait for STDIN, 1 = immediate STDIN, 2... are Files)
-3       Output (outputs when a value is sent to it)
-4       Output Target and format
       (0 is STDOUT, 1 is STDERR, 2... are Files)
-5       Register a 
-6       Register b 
-7       Register c 
-8       Instruction Mode (IM)
-9...    Data

Mode:  Takes immediate action on a,b,c, then resets to 0.

IM       Effect

0        No Op
1        c = NOT a
2        c = b AND a
3        c = b OR a
4        c = b XOR a
5        c = b << a bits
6        c = b >> a bits
7        c = b*a
8        c = b/a (floored integer division) (HALT on /0)
9        c = b%a (Mod) (floored) (HALT on %0)
10        c = Sign of Int b (+1, 0, -1)
11        c = Sign of Float b (+1, 0, -1)
12        Int c --> Float c
13        Float c --> Int c
14        Int a,b --> Float a,b
15        Float a,b --> Int a,b
16        Float: c = b-a
17        Float: c = b+a
18        Float: c = b*a
19        Float: c = b/a (HALT on /0)
20        Float: c = power a of b
21        Float: c = root a of b (HALT on root 0)

22        Float: c = Log base b of a (HALT on base 0)
23        Float: c = SIN b
24        Float: c = COS b
25        Float: c = TAN b
26        Float: c = CSC b
27        Float: c = SEC b
28        Float: c = COT b
29        Float: c = ASIN b
30        Float: c = ACOS b
31        Float: c = ATAN b
32        Float: c = ACSC b
33        Float: c = ASEC b
34        Float: c = ACOT b
35        Float: a = pi, b = e, c = phi
36        Float: a = 1.0, b = 0.0, c = -1.0

Extensions to Mode are left to the user.