;Pep/9 BrainF**k Compiler
;Written by Christine E. Meyer
;University of Illinois at Springfield
;5/8/20
;
;The following Pep/9 code runs a compiler that can take batch
;or terminal input terminating in an * end sentinel, and
;compiles from it a BrainF**k program.
;
;More details about the language here:
;https://esolangs.org/wiki/brainfuck
;
;It runs with a 256 byte size cell long tape starting at address
;location 0x02C7 and ending at 0x03C6. Compiled code begins at,
;and runs from, address location 0x03C7. It catches and reports
;various errors such as moving beyond tape bounds, trying to
;move beyond cell size limits, or not properly pairing the
;looping brackets.
;
         BR      main        
jmpaddr: .EQUATE 2           ;formal parameter
code:    .EQUATE 0x03C7      
main:    LDWX    0x0000,i    
compile: LDWA    0x0000,i    
         LDBA    charIn,d    
         CPWA    '*',i       
         BRNE    parser      
         BR      init        
parser:  CPWA    '>',i       
         BRNE    parsel      
         CALL    r           
         BR      compile     
parsel:  CPWA    '<',i       
         BRNE    parseinc    
         CALL    l           
         BR      compile     
parseinc:CPWA    '+',i       
         BRNE    parsedec    
         CALL    inc         
         BR      compile     
parsedec:CPWA    '-',i       
         BRNE    parseout    
         CALL    dec         
         BR      compile     
parseout:CPWA    '.',i       
         BRNE    parsein     
         CALL    out         
         BR      compile     
parsein: CPWA    ',',i       
         BRNE    parsellp    
         CALL    in          
         BR      compile     
parsellp:CPWA    '[',i       
         BRNE    parserlp    
         SUBSP   2,i         ;push #jmpaddr ;WARNING: jmpaddr not specified in .EQUATE
         CALL    llp         
         BR      compile     
parserlp:CPWA    ']',i       
         BRNE    comment     
         CALL    rlp         
         ADDSP   2,i         ;pop #jmpaddr ;WARNING: jmpaddr not specified in .EQUATE
comment: BR      compile     
;
;
; >
r:       LDWA    0xA801,i    
         STWA    0x03C7,x    
         LDWA    0x001A,i    
         STWA    0x03C9,x    
         LDWA    0x03C7,i    
         STWX    -2,s        
         ADDA    -2,s        
         ADDA    0x000A,i    
         STWA    0x03CB,x    
         LDWA    0x4902,i    
         STWA    0x03CD,x    
         LDWA    0x6A00,i    
         STWA    0x03CF,x    
         LDWA    0x6800,i    
         STWA    0x03D1,x    
         LDBA    0x0001,i    
         STBA    0x03D3,x    
         ADDX    0x000D,i    
         RET                 
;
;
; <
l:       LDWA    0xA800,i    
         STWA    0x03C7,x    
         LDWA    0x001A,i    
         STWA    0x03C9,x    
         LDWA    0x03C7,i    
         STWX    -2,s        
         ADDA    -2,s        
         ADDA    0x000A,i    
         STWA    0x03CB,x    
         LDWA    0x4902,i    
         STWA    0x03CD,x    
         LDWA    0x7800,i    
         STWA    0x03CF,x    
         LDWA    0x7800,i    
         STWA    0x03D1,x    
         LDWA    0x0001,i    
         STWA    0x03D2,x    
         ADDX    0x000D,i    
         RET                 
;
;
; +
inc:     LDWA    0xD502,i    
         STWA    0x03C7,x    
         LDWA    0xC6B0,i    
         STWA    0x03C9,x    
         LDWA    0x00FF,i    
         STWA    0x03CB,x    
         LDBA    0x001A,i    
         STBA    0x03CD,x    
         LDWA    0x03C7,i    
         STWX    -2,s        
         ADDA    -2,s        
         ADDA    0x000D,i    
         STWA    0x03CE,x    
         LDBA    0x0049,i    
         STBA    0x03D0,x    
         LDWA    0x0286,i    
         STWA    0x03D1,x    
         LDWA    0x0060,i    
         STWA    0x03D3,x    
         LDWA    0x0001,i    
         STWA    0x03D5,x    
         LDWA    0xF502,i    
         STWA    0x03D7,x    
         LDBA    0x00C6,i    
         STBA    0x03D9,x    
         ADDX    0x0013,i    
         RET                 
;
;
; -
dec:     LDWA    0xD502,i    
         STWA    0x03C7,x    
         LDWA    0xC6B0,i    
         STWA    0x03C9,x    
         LDWA    0x0000,i    
         STWA    0x03CB,x    
         LDBA    0x001A,i    
         STBA    0x03CD,x    
         LDWA    0x03C7,i    
         STWX    -2,s        
         ADDA    -2,s        
         ADDA    0x000D,i    
         STWA    0x03CE,x    
         LDBA    0x0049,i    
         STBA    0x03D0,x    
         LDWA    0x0290,i    
         STWA    0x03D1,x    
         LDWA    0x0070,i    
         STWA    0x03D3,x    
         LDWA    0x0001,i    
         STWA    0x03D5,x    
         LDWA    0xF502,i    
         STWA    0x03D7,x    
         LDBA    0x00C6,i    
         STBA    0x03D9,x    
         ADDX    0x0013,i    
         RET                 
;
;
; .
out:     LDWA    0xD502,i    
         STWA    0x03C7,x    
         LDWA    0xC6F1,i    
         STWA    0x03C9,x    
         LDWA    0xFC16,i    
         STWA    0x03CB,x    
         ADDX    0x0006,i    
         RET                 
;
;
; ,
in:      LDWA    0xD1FC,i    
         STWA    0x03C7,x    
         LDWA    0x15F5,i    
         STWA    0x03C9,x    
         LDWA    0x02C6,i    
         STWA    0x03CB,x    
         ADDX    0x0006,i    
         RET                 
;
;
; [
llp:     STWX    jmpaddr,s   
         LDWA    jmpaddr,s   
         ADDA    0x03C7,i    
         STWA    jmpaddr,s   
         LDWA    0xD502,i    
         STWA    0x03C7,x    
         LDWA    0xC6B0,i    
         STWA    0x03C9,x    
         LDWA    0x0000,i    
         STWA    0x03CB,x    
         LDBA    0x001A,i    
         STBA    0x03CD,x    
         LDWA    0x03C7,i    
         STWX    -2,s        
         ADDA    -2,s        
         ADDA    0x000C,i    
         STWA    0x03CE,x    
         LDBA    0x0012,i    
         STBA    0x03D0,x    
         LDWA    0x0000,i    
         STWA    0x03D1,x    
         ADDX    0x000C,i    
         RET                 
;
;
; ]
rlp:     MOVSPA              
         CPWA    0xFB8D,i    
         BRNE    elserlp     
         STRO    error5,d    
         STOP                
elserlp: LDWA    0xD502,i    
         STWA    0x03C7,x    
         LDWA    0xC6B0,i    
         STWA    0x03C9,x    
         LDWA    0x0000,i    
         STWA    0x03CB,x    
         LDBA    0x0018,i    
         STBA    0x03CD,x    
         LDWA    0x03C7,i    
         STWX    -2,s        
         ADDA    -2,s        
         ADDA    0x000C,i    
         STWA    0x03CE,x    
         LDBA    0x0012,i    
         STBA    0x03D0,x    
         LDWA    jmpaddr,s   
         ADDA    0x000C,i    
         STWA    0x03D1,x    
         SUBA    0x0002,i    
         STWA    jmpaddr,s   
         STWX    -2,s        
         LDWA    -2,s        
         ADDA    0x03D3,i    
         STWA    jmpaddr,sf  
         ADDX    0x000C,i    
         RET                 
;
;
; Initialize compiled code
init:    LDWA    0x0000,i    ;Inserts a stop at the end of the program.
         STBA    code,x      
         MOVSPA              ;Ensures there are no unpaired [ commands.
         CPWA    0xFB8F,i    
         BREQ    elseinit    
         STRO    error6,d    
         STOP                
elseinit:LDWA    0x0000,i    ;Clears registers.
         LDWX    0x0000,i    
         STRO    success,d   
         BR      code        ;Jumps to compiled code.
error1:  .ASCII  "End of tape >\x00"

error2:  .ASCII  "End of tape <\x00"

error3:  .ASCII  "Cell full\x00"

erorr4:  .ASCII  "Cell empty\x00"

error5:  .ASCII  "Unmatched ]\x00"

error6:  .ASCII  "Unmatched [\x00"

success: .ASCII  "Compile successful\n\x00"

         .BLOCK  0x0100      
         .END                  
