TAPASM

From Esolang
Jump to: navigation, search

TAPASM is an esoteric language by Christian Irwan (talk) using sticky tape. It resembles assembly. (Note, it's incomplete, so I want your preferences)

Register

TAPASM has 8 register, named tpa, tpb, tpc, tpd, tpe, tpf, tpg, tph. In the instruction section, tp1 and tp2 can be replaced with that. Register is place in the tape of program. It is initialized in leftmost area.

Register opcodes are:

STICK tp1, tp2 ; Stick tape in tape location 1 with tape location 2. Throw exception if it has been stick, tp1 and tp2 is overlap or have different length. Temporary the value tp1 and tp2 will added together

STICK tp1      ; Stick tp1 with nontape, thus does nothing until released that divided it by two () . 
RELES tp1      ; Release tape in tape location 1. Any tape that stick in this tape location will be unstick. Area that is unstick will have it's value averaged by other place that is also unstick (With 10% tolerance, but longer it's sticked, the tolerance is lower until it 0% alias it will correctly averaged). 
SCRTH tp1      ; Make tp1 off
LNGTH tp1, imm ; set tp1's length absolute to imm. Right bound will be adjusted.
LNGTH tp1, tp2 ; set tp1's length absolute to tp2. Right bound will be adjusted.
LNGTR tp1, imm ; set tp1's length relative to imm. Imm is signed. Right bound will beadjusted.
LNGTR tp1, tp2 ; set tp1's length relative to tp2. Tp2 is signed. Right bound will be adjusted.
SHRLF tp1, imm ; shift tp1 left by imm. Throws error if the result is off the tape
SHRLF tp1, tp2 ; shift tp1 left by tp2. Throws error if the result is off the tape
SHRRG tp1, imm ; shift tp1 right by imm. Throws error if the result is off the tape
SHRRG tp1, tp2 ; shift tp1 right by tp2. Throws error if the result is off the tape
SETTP tp1, imm ; Set the tape location 1 to using imm-th tape cut.


Flags

Like ordinary assembly, there are flags in there. Flags is used to control movement by serve as conditional for many operator. The defined flags are:

0 FF Full flag
1 ZF Zero Flag

FF = 1 and ZF = 1 is possible and used for indicating error.

Undefined flag can be used for many usages as you want, example error handling. Flag opcodes are:

TEST tp1 ; Set FF if all of tp1 is set and ZF is all of tp1 is not set.
SF imm ; Set the imm-th flag
CF imm ; clear the imm-th flag
SIE imm, tp1 ; Set the imm-th flag if tp1 is all clear 
SIF imm, tp1 ; Set the imm-th flag if tp1 is all set
CIE imm, tp1 ; Clear the imm-th flag if tp1 is all clear
CIF imm, tp1 ; Clear the imm-th flag if tp1 is all set

And the jump instruction is: (Jump instruction always in form Jnn xxxxxxxx where Jnn is opcode and xxxxxxxx is a label, except)

JF ; Jump if FF is set and ZF is not set
JP ; Jump if both FF and ZF not set
JE ; Jump if ZF is set and FF is not set
JER ; Jump if both ZF and FF is set 
JFL xx, xxxxxxxx ; Jump if xx-th flag is set
JNFL xx, xxxxxxxx ; Jump if xx-th flag is not set
JMP xxxxxxxx ; Jump unconditionally. 

Tape

TAPASM has 1 infinite tape to right. The tape can be cut, stick to other tape location, and released. Released tape have it averaged with it's counterpart until it turns zero. Defined by tape segment. Reached tape if not stick will reduce it's value. Example, a cell's value is 1, can go down to 0.9 until zero

The only code that is only for tape that hasn't any role for register is:

CUT tp1 ; Cut the tape to three pieces divided by tp1. Any segment that have data will be pushed to global tapes.

Tape Segment

TAPASM's tape data declarated by following:

#Section Tape ;Begin a section tape
 #Roll        ;Declare a infinite tape
 df 0.6       ;Declare a byte. Look below
 #Part        ;Begin a part. Ended by next segment of tape
  db 25       ;Declare a byte
  dw 501      ;Declare a word
  df 0.55     ;Declare a byte, but in this, byte is ranged from 0 to 1 with 0.5 above equals true
#Section Code

Then data is stored from top to bottom. So, the tape result is (With .. means infinite): |[0.6][1][1][1]..|[0][0][0][1][1][0][0][1] [0][0][0][0][0][0][0][1][1][1][1][1][0][1][0][1][0.55]|

Interrupt

TAPASM has interrupt that behave differently about one interpreter and another. But if the interrupt is not supported, quit with exit code same as interrupt number. Example of interrupt

int 0 ;exit happily (Must be implemented as is)
int 1 ;set the tpa with STDIN. tpa's length is set first to 8. 
int 2 ;output the tpa to STDOUT. tpa's length is set first to 8.
INT imm        ; do a interrup that is supported by assembler/interpreter. If it's not supported, exit with error number imm.

Execution

TAPASM is like assembly. There are call stack, so you can do CALLs and RETurns.

CALL xxxxxxxx ; Call The xxxxxxxx part of code
RET           ; Return to the caller

Well, there are no stack in TAPASM, so you must allocate one roll(or infinite part) to imitate that.

Example

Hello World program:

#Section Tape
 db 48
 db 65
 db 6C
 db 6C
 db 6F
 db 20
 db 57
 db 6F
 db 72
 db 6C
 db 64
#Section Code
 Main:
 LENGTH tpa, 8
 INT 2
 #Repeat 10   ;A preprocessor to repeat 10 times
 SHRLF tpa, 8
 INT 2
 #End Repeat