From 756c606af68be8ccca7aced3b9c3d56fb2d5087f Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Mon, 6 Jul 2020 20:04:41 -0400 Subject: - Implemented a new opcode table. - Added a new preifx called the OF prefix, which adds the contents of a specific register to the current operand. - Added a table generator, which parses opcode table csv files. --- programs/sub-suite/lexer.s | 180 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 138 insertions(+), 42 deletions(-) (limited to 'programs/sub-suite/lexer.s') diff --git a/programs/sub-suite/lexer.s b/programs/sub-suite/lexer.s index 315bee4..cd7a33a 100644 --- a/programs/sub-suite/lexer.s +++ b/programs/sub-suite/lexer.s @@ -97,16 +97,16 @@ util_data: lex: ldx #0 ; Reset X. txa ; Reset A. - phy #2 ; Preserve the screen buffer index. + phy.w ; Preserve the screen buffer index. txy ; Reset Y. sty.q idx0 ; Clear the first index. sty.q idx1 ; Clear the second index. sty.q idx2 ; Clear the third index. sty b ; Clear the isop flag. ; lda (ptr), y ; Get a character from the line. -; pha #1 ; Preserve the character. +; pha ; Preserve the character. ; jsr isdigit ; Is this character a digit? -; pla #1 ; Get the character back. +; pla ; Get the character back. @getline: lda #2 ; Get the third byte, of the line table address. lsl #$10 ; Shift it by 2 bytes. @@ -126,27 +126,27 @@ lex: @spaces: ldy.w idx0 ; Get the string index. lda (ptr), y ; Get a character from the line. - pha #1 ; Preserve the character. + pha ; Preserve the character. jsr isdelm ; Get the delimiter. and #$10 ; Is this character, a space, or tab? - pla #1 ; Get the character back. + pla ; Get the character back. beq @isstart ; No, so check for the start of the line. inc.w idx0 ; Yes, so increment the string index. cmp #' ' ; Is this character, a space? beq @incs ; Yes, so increment the starting space count. cmp #'\t' ; No, but is it a tab? beq @inct ; Yes, so increment the starting tab count. - jmp @spaces ; No, so Keep looping. + bra @spaces ; No, so Keep looping. @incs: inc idx1 ; Increment the space count. - jmp @spaces ; Keep looping. + bra @spaces ; Keep looping. @inct: inc idx1+1 ; Increment the tab count. - jmp @spaces ; Keep looping. + bra @spaces ; Keep looping. @isstart: - pha #2 ; Preserve the character. + pha.w ; Preserve the character. lda.w idx1 ; Was there any whitespace? - pla #2 ; Get the character back. + pla.w ; Get the character back. beq @switch ; No, so start lexing. cpb #1 ; Yes, and are we at the start of the line? bne @switch ; No, so start lexing. @@ -163,27 +163,27 @@ lex: jsr get_ptok ; Get the pre-token. jsr parse_ptok ; Parse the pre-token. ; beq @end ; We got to the end of the string. - jmp @loop ; Keep looping. + bra @loop ; Keep looping. @end: - ply #2 ; Get the screen buffer index back. + ply.w ; Get the screen buffer index back. rts ; End of lex. parse_ptok: - pha #1 ; Preserve the pre-token. + pha ; Preserve the pre-token. ldb #2 ; Set the third pointer lda.w #swtab ; to the start of the jump table. jsr set_ptr ; and #0 ; Reset A. - pla #1 ; Get the pre-token back. - phy #2 ; Preserve Y. + pla ; Get the pre-token back. + phy.w ; Preserve Y. lsl #1 ; Multiply the pre-token by two, to get the jump index. tay ; Get the index of the jump table. lda.w (ptr3), y ; Get the address to jump to. jsr set_ptr ; Set the third pointer to the case address. and #0 ; Reset A. tab ; Reset B. - ply #2 ; Get Y back. + ply.w ; Get Y back. jmp (ptr3) ; Jump to the case label. ptok_dot: ldb #1 ; Make init_lex increment the string index. @@ -200,7 +200,7 @@ ptok_dot: dey ; Decrement the lexeme index. lda (ptr3), y ; Get the suffix character. jsr get_rs ; Get the register size. - jmp @end ; We are done. + bra @end ; We are done. @dir: lda #TOK_DIR ; Set the lexeme type to TOK_DIR. sta lex_type ; @@ -211,9 +211,9 @@ ptok_dot: lda.w #dir ; Get pointer to the start of the directive table. clc ; Prepare for a non carrying add. adc.w idx2 ; Offset the pointer, by the length of the previous string. - pha #8 ; Preserve the directive string pointer. + pha.q ; Preserve the directive string pointer. jsr strcasecmp ; Is the lexeme buffer, the same as the directive string? - pla #8 ; Get the directive string pointer back. + pla.q ; Get the directive string pointer back. beq @found ; Yes, so create a new token. ldb idx1 ; No, so Get the directive ID. cpb #6 ; Have we reached the end of the directive table? @@ -226,7 +226,7 @@ ptok_dot: clc ; Prepare for a non carrying add. adc.w idx2 ; Add the string offset to the current length sta.w idx2 ; Save the offset in the third index. - jmp @dir_loop ; Keep looping. + bra @dir_loop ; Keep looping. @found: nop ; @end: @@ -234,59 +234,102 @@ ptok_dot: jsr set_cmdbuf ; Set the first pointer to the command buffer. rts ; End of parse_ptok. ptok_at: + inc.w idx0 ; rts ; End of parse_ptok. ptok_col: + inc.w idx0 ; rts ; End of parse_ptok. ptok_equ: + inc.w idx0 ; rts ; End of parse_ptok. ptok_plus: + inc.w idx0 ; rts ; End of parse_ptok. ptok_min: + inc.w idx0 ; rts ; End of parse_ptok. ptok_gt: + inc.w idx0 ; rts ; End of parse_ptok. ptok_lt: + inc.w idx0 ; rts ; End of parse_ptok. ptok_lbrk: + inc.w idx0 ; rts ; End of parse_ptok. ptok_rbrk: + inc.w idx0 ; rts ; End of parse_ptok. ptok_com: + inc.w idx0 ; rts ; End of parse_ptok. ptok_xr: + inc.w idx0 ; rts ; End of parse_ptok. ptok_yr: + inc.w idx0 ; rts ; End of parse_ptok. ptok_dqu: ldb #1 ; Make init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. ldb #4 ; Set the delimiter comparison value to a double quote. jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. -@term: +@end: rts ; End of parse_ptok. ptok_squ: + ldb #1 ; Make init_lex increment the string index. + jsr init_lex ; Initialize the lexeme buffer for copying. + ldb #8 ; Set the delimiter comparison value to a single quote. + jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. +@end: rts ; End of parse_ptok. ptok_hash: + inc.w idx0 ; rts ; End of parse_ptok. ptok_scol: + ldb #1 ; Make init_lex increment the string index. + jsr init_lex ; Initialize the lexeme buffer for copying. + jsr delmcpy ; Copy the string, to the lexeme buffer, until EOL. +@end: rts ; End of parse_ptok. ptok_dolr: - rts ; End of parse_ptok. + lda #TOK_HEX ; Set the lexeme type to TOK_HEX. + sta lex_type ; + lda #$10 ; Set the base to Hexadecimal. + ldb #1 ; Make init_lex increment the string index. + bra ptok_num2 ; Parse the value. ptok_prcn: - rts ; End of parse_ptok. + lda #TOK_BIN ; Set the lexeme type to TOK_BIN. + sta lex_type ; + lda #2 ; Set the base to Binary. + ldb #1 ; Make init_lex increment the string index. + bra ptok_num2 ; Parse the value. ptok_num: + lda #TOK_DEC ; Set the lexeme type to TOK_DEC. + sta lex_type ; + lda #10 ; Set the base to Decimal. + ldb #0 ; Do not let init_lex increment the string index. +ptok_num2: + pha ; Preserve the base. + jsr init_lex ; Initialize the lexeme buffer for copying. + ldb #3 ; Set the delimiter to both the EOL, or a comma. + jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. + pla ; Get the base back. + jsr strtoull ; Convert the string into a numeric value. + jsr make_tok ; Create the token. + jsr set_cmdbuf ; Set the first pointer to the command buffer. rts ; End of parse_ptok. ptok_alph: ldb #0 ; Do not let init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. - ldb #1 ; Stop at any possible delimiter, except whitespace. + ldb #3 ; Stop at any possible delimiter. tba ; Use isdelm2 for the comparison. jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. lda #0 ; Reset A. sta b ; Clear the isop flag. @isop: ldb #0 ; Make the lexeme buffer, the first pointer. - stb.q idx1 ; Reset the first index. + stb.q idx1 ; Reset the second index. jsr set_lexptr ; Set up the lexeme buffer. @isop_loop: lda.w #mne ; Get pointer to the start of the instruction table. @@ -303,7 +346,7 @@ ptok_alph: clc ; Prepare for a non carrying multiply. mul idx1 ; Multiply the base offset, by the instruction ID. sta.w idx2 ; Save the offset in the third index. - jmp @isop_loop ; Keep looping. + bra @isop_loop ; Keep looping. @found: lda #TOK_MNE ; Set the lexeme type to TOK_MNE. sta lex_type ; @@ -313,6 +356,7 @@ ptok_alph: jsr set_cmdbuf ; Set the first pointer to the command buffer. rts ; End of parse_ptok. ptok_othr: + inc.w idx0 ; rts ; End of parse_ptok. @@ -322,6 +366,7 @@ set_lexptr: and #0 ; Reset A. tab ; Reset B. sta.q idx1 ; Reset the second index. + sta.q idx2 ; Reset the third index rts ; End of set_lexptr. @@ -340,11 +385,19 @@ init_lex: @inc_str: inc.w idx0 ; Yes, so increment the string index. @init: - lda #0 ; Reset A. - sta.q idx1 ; Reset the second index - sta.q idx2 ; Reset the third index ldb #2 ; Make the lexeme buffer, the third pointer. jsr set_lexptr ; Set up the lexeme buffer. + phy.w ; Preserve Y. + tay ; Reset Y. +@loop: + lda (ptr3), y ; Have we hit the end of the previous lexeme string? + beq @end ; Yes, so we're done. + lda #0 ; No, so start clearing the character. + sta (ptr3), y ; Clear the character. + iny ; Increment the lexeme index. + bra @loop ; Keep looping. +@end: + ply.w ; Get Y back. rts ; End of init_lex. @@ -352,37 +405,80 @@ delmcpy: sta a ; Save the delimiter check flag. stb c ; Save the delimiter comparison value. @loop: + ldb #0 ; Reset the B register. + stb g ; Reset the byte count. ldy.w idx0 ; Get the string index. - lda (ptr), y ; Get a character from the line. - pha #1 ; Preserve the character. + lda.q (ptr), y ; Get eight bytes from the current line. +@loop1: + pha.q ; Save the string buffer. + and #$FF ; Get the current byte. + pha ; Preserve the character. lda a ; Are we calling isdelm2? - pla #1 ; Get the character back. + pla ; Get the character back. bne @isdelm2 ; Yes, so use isdelm2. jsr isdelm ; No, so get the delimiter value from isdelm. +@delmchk: and c ; Are both delimiter values, the same? + pla.q ; Get back the string buffer. bne @end ; Yes, so we're done. - jmp @copy ; No, so start copying the character. + bra @copy ; No, so start copying the character. @isdelm2: jsr isdelm2 ; Get the delimiter value from isdelm2. - cmp c ; Are both delimiter values, the same? - beq @end ; Yes, so we're done. + bra @delmchk ; Check the delimiter. @copy: - lda (ptr), y ; Get a character from the line. ldy.w idx1 ; Get the lexeme index. - sta (ptr3), y ; Copy the character to the lexeme buffer. + sta (ptr3), y ; Copy one byte from the screen buffer, to the command buffer. inc.w idx0 ; Increment the string index. inc.w idx1 ; Increment the lexeme index. - jmp @loop ; Keep looping. + lsr #8 ; Shift in the next byte. + inc g ; Increment the byte count. + ldb g ; Get back the byte count. + cpb #7 ; Did we shift in eight bytes? + beq @loop ; Yes, so get eight more bytes. + bra @loop1 ; No, so keep shifting in more bytes. @end: - lda #0 ; Terminate the lexeme buffer. - sta (ptr3), y ; + ldb #0 ; Reset B. + ldy.w idx1 ; Get the lexeme index. + stb (ptr3), y ; Terminate the command buffer. +@end1: + ldy.w idx0 ; Get the string index. + tba ; Reset A. rts ; End of delmcpy. +;@loop: +; ldy.w idx0 ; Get the string index. +; lda (ptr), y ; Get a character from the line. +; pha ; Preserve the character. +; lda a ; Are we calling isdelm2? +; pla ; Get the character back. +; bne @isdelm2 ; Yes, so use isdelm2. +; jsr isdelm ; No, so get the delimiter value from isdelm. +;@delmchk: +; and c ; Are both delimiter values, the same? +; bne @end ; Yes, so we're done. +; bra @copy ; No, so start copying the character. +;@isdelm2: +; jsr isdelm2 ; Get the delimiter value from isdelm2. +; bra @delmchk ; Check the delimiter. +;@copy: +; lda (ptr), y ; Get a character from the line. +; ldy.w idx1 ; Get the lexeme index. +; sta (ptr3), y ; Copy the character to the lexeme buffer. +; inc.w idx0 ; Increment the string index. +; inc.w idx1 ; Increment the lexeme index. +; bra @loop ; Keep looping. +;@end: +; ldy.w idx1 ; Get the lexeme index. +; lda #0 ; Terminate the lexeme buffer. +; sta (ptr3), y ; +; ldy.w idx0 ; Get the string index. +; rts ; End of delmcpy. + get_rs: - phb #1 ; Preserve B. + phb ; Preserve B. ldb #0 ; Set the isop flag to false. - plb #1 ; Get B back. + plb ; Get B back. jsr tolower ; Convert the character to lowercase. cmp #'w' ; Is it .w? beq @r1 ; Yes, so return 1. -- cgit v1.2.3-13-gbd6f