TAPASM
- This is still a work in progress. It may be changed in the future.
TAPASM is an esoteric language by User:Christian Irwan using sticky tape. It resembles assembly code. (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