From 70822c8427f76715a804cad448dcdd8142c3dc3d Mon Sep 17 00:00:00 2001 From: YurySinev Date: Sun, 3 Nov 2019 17:19:11 +0400 Subject: [PATCH 01/13] Added nesasm lexer --- lib/rouge/demos/NesAsm | 11 +++++++ lib/rouge/lexers/NesAsm.rb | 60 ++++++++++++++++++++++++++++++++++++++ spec/lexers/NesAsm_spec.rb | 14 +++++++++ spec/visual/samples/NesAsm | 51 ++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 lib/rouge/demos/NesAsm create mode 100644 lib/rouge/lexers/NesAsm.rb create mode 100644 spec/lexers/NesAsm_spec.rb create mode 100644 spec/visual/samples/NesAsm diff --git a/lib/rouge/demos/NesAsm b/lib/rouge/demos/NesAsm new file mode 100644 index 0000000000..91a0f972f3 --- /dev/null +++ b/lib/rouge/demos/NesAsm @@ -0,0 +1,11 @@ + .bank 0 + .org $C000 +Reset: + jsr WaitSync ; wait for VSYNC + jsr ClearRAM ; clear RAM + jsr WaitSync ; wait for VSYNC (and PPU warmup) + + lda #$3f ; $3F -> A register + ldy #$00 ; $00 -> Y register + sta PPU_ADDR ; write #HIGH byte first + sty PPU_ADDR ; $3F00 -> PPU address \ No newline at end of file diff --git a/lib/rouge/lexers/NesAsm.rb b/lib/rouge/lexers/NesAsm.rb new file mode 100644 index 0000000000..5661f326ef --- /dev/null +++ b/lib/rouge/lexers/NesAsm.rb @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class NesAsm < RegexLexer + title "NesAsm" + desc "Nesasm3 assembly (6502 asm)" + tag 'NesAsm' + aliases 'nesasm', 'nes' + filenames '*.asm' + + keywords = %w( + ADC AND ASL BIT BRK CMP CPX CPY + DEC EOR INC JMP JSR LDA LDX LDY LSR NOP ORA + ROL ROR RTI RTS SBC STA STX STY + TAX TXA DEX INX TAY TYA DEY INY + BPL BMI BVC BVS BCC BCS BNE BEQ + CLC SEC CLI SEI CLV CLD SED + TXS TSX PHA PLA PHP PLP + ) + + keywords_type = %w( + DB DW BYTE WORD + ) + + keywords_reserved = %w( + INCBIN INCLUDE ORG BANK RSSET RS + MACRO ENDM DS PROC ENDP PROCGROUP ENDPROCGROUP + INCCHR DEFCHR ZP BSS CODE DATA IF IFDEF IFNDEF + ELSE ENDIF FAIL INESPRG INESCHR INESMAP INESMIR + ) + + state :root do + rule %r/\s+/m, Text + rule %r(;.*?$), Comment::Single + + rule %r/\w*\:/, Name::Function #label: + rule %r/[\(\)\,\.\[\]]/, Punctuation + rule %r/\#*\%[0-1]+/, Num::Bin # #%00110011 %00110011 + rule %r/\$\h+/, Num::Hex # $1f + rule %r/\#\$\h+/, Num::Hex #$1f + rule %r/\#*[0-9]+/, Num # 10 #10 + rule %r([~&*+=\|?:<>/-]), Operator + + rule %r/\b(?:#{keywords.join('|')})\b/i, Keyword + rule %r/\b(?:#{keywords_type.join('|')})\b/i, Keyword::Type + rule %r/\b(?:#{keywords_reserved.join('|')})\b/i, Keyword::Reserved + rule %r/(?:#*LOW|#*HIGH)\(.*\)/i, Keyword::Reserved # LOW() #HIGH() + + rule %r/\#\w+/, Name::Function # #LABEL + rule %r/\#\(/, Punctuation # #() + + rule %r/".*"/, Str # "" + rule %r/\w*/, Name::Function # other labels/variables/names etc + end + + end + end +end diff --git a/spec/lexers/NesAsm_spec.rb b/spec/lexers/NesAsm_spec.rb new file mode 100644 index 0000000000..39fdec67bd --- /dev/null +++ b/spec/lexers/NesAsm_spec.rb @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +describe Rouge::Lexers::NesAsm do + let(:subject) { Rouge::Lexers::NesAsm.new } + + describe 'guessing' do + include Support::Guessing + + it 'guesses by filename' do + assert_guess :filename => 'foo.asm' + end + end +end diff --git a/spec/visual/samples/NesAsm b/spec/visual/samples/NesAsm new file mode 100644 index 0000000000..9ff74c7fcf --- /dev/null +++ b/spec/visual/samples/NesAsm @@ -0,0 +1,51 @@ + .inesprg 2 ; 2x 16KB PRG code banks + .ineschr 1 ; 1x 8KB CHR data banks + .inesmap 0 ; mapper (0 = NROM), no bank swapping + .inesmir 0 ; 0 = horizontal background mirroring (for vertical scrolling) + + ;;;;;; VARIABLES + .rsset $0000 ; zero page + +gamestate .rs 1 +playerx .rs 2 + + .bank 1 + .org $C000 + +Reset: + jsr WaitSync ; wait for VSYNC + jsr ClearRAM ; clear RAM + jsr WaitSync ; wait for VSYNC (and PPU warmup) + +NMI: + LoadSprites: + ldx #$00 +LoadSpritesLoop: + lda Sprites, x + sta OAM_RAM, x + inx + cpx #$10 + bne LoadSpritesLoop + + lda #HIGH(background) + sta backHi + lda #LOW(background) + sta backLo + +Sprites: + ;vert tile attr horiz + .db $80, $01, %00000000, $80 ;sprite 0 + .db $80, $02, %00110011, $88 ;sprite 1 + .db $88, $03, %00110011, $80 ;sprite 2 + .db $88, $05, %00000000, $88 ;sprite 3 + + .include "somefile.asm" + .incbin "somefile.chr" + background: + .incbin "background.chr" + +;; CPU interrupts + .org $FFFA + .dw NMI ; vblank NMI + .dw RESET ; Reset + .dw 0 ; IRQ \ No newline at end of file From 900b7e86aee12496823ab86f1b895a6c905e8aee Mon Sep 17 00:00:00 2001 From: YurySinev Date: Sun, 3 Nov 2019 19:12:59 +0400 Subject: [PATCH 02/13] Fixed rake errors: .asm extension was used by nasm lexer --- lib/rouge/lexers/NesAsm.rb | 2 +- spec/lexers/NesAsm_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rouge/lexers/NesAsm.rb b/lib/rouge/lexers/NesAsm.rb index 5661f326ef..bd143b8e26 100644 --- a/lib/rouge/lexers/NesAsm.rb +++ b/lib/rouge/lexers/NesAsm.rb @@ -8,7 +8,7 @@ class NesAsm < RegexLexer desc "Nesasm3 assembly (6502 asm)" tag 'NesAsm' aliases 'nesasm', 'nes' - filenames '*.asm' + filenames '*.nesasm' keywords = %w( ADC AND ASL BIT BRK CMP CPX CPY diff --git a/spec/lexers/NesAsm_spec.rb b/spec/lexers/NesAsm_spec.rb index 39fdec67bd..7b37f931e6 100644 --- a/spec/lexers/NesAsm_spec.rb +++ b/spec/lexers/NesAsm_spec.rb @@ -8,7 +8,7 @@ include Support::Guessing it 'guesses by filename' do - assert_guess :filename => 'foo.asm' + assert_guess :filename => 'foo.nesasm' end end end From 82a169b7e2b65bc822dd4b97c698498bb5a929e1 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Mon, 11 Nov 2019 09:05:00 +0900 Subject: [PATCH 03/13] Rename files --- lib/rouge/demos/{NesAsm => nesasm} | 0 lib/rouge/lexers/{NesAsm.rb => nesasm.rb} | 0 spec/lexers/{NesAsm_spec.rb => nesasm_spec.rb} | 0 spec/visual/samples/{NesAsm => nesasm} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename lib/rouge/demos/{NesAsm => nesasm} (100%) rename lib/rouge/lexers/{NesAsm.rb => nesasm.rb} (100%) rename spec/lexers/{NesAsm_spec.rb => nesasm_spec.rb} (100%) rename spec/visual/samples/{NesAsm => nesasm} (100%) diff --git a/lib/rouge/demos/NesAsm b/lib/rouge/demos/nesasm similarity index 100% rename from lib/rouge/demos/NesAsm rename to lib/rouge/demos/nesasm diff --git a/lib/rouge/lexers/NesAsm.rb b/lib/rouge/lexers/nesasm.rb similarity index 100% rename from lib/rouge/lexers/NesAsm.rb rename to lib/rouge/lexers/nesasm.rb diff --git a/spec/lexers/NesAsm_spec.rb b/spec/lexers/nesasm_spec.rb similarity index 100% rename from spec/lexers/NesAsm_spec.rb rename to spec/lexers/nesasm_spec.rb diff --git a/spec/visual/samples/NesAsm b/spec/visual/samples/nesasm similarity index 100% rename from spec/visual/samples/NesAsm rename to spec/visual/samples/nesasm From 3e762792ac9f3d268e5927f735fa350604221c34 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Mon, 11 Nov 2019 14:53:21 +0900 Subject: [PATCH 04/13] Memoise keywords --- lib/rouge/lexers/nesasm.rb | 63 ++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index bd143b8e26..3d757bd62a 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -6,30 +6,32 @@ module Lexers class NesAsm < RegexLexer title "NesAsm" desc "Nesasm3 assembly (6502 asm)" - tag 'NesAsm' - aliases 'nesasm', 'nes' + tag 'nesasm' + aliases 'nes' filenames '*.nesasm' - keywords = %w( - ADC AND ASL BIT BRK CMP CPX CPY - DEC EOR INC JMP JSR LDA LDX LDY LSR NOP ORA - ROL ROR RTI RTS SBC STA STX STY - TAX TXA DEX INX TAY TYA DEY INY - BPL BMI BVC BVS BCC BCS BNE BEQ - CLC SEC CLI SEI CLV CLD SED - TXS TSX PHA PLA PHP PLP - ) - - keywords_type = %w( + def self.keywords + @keywords ||= %w( + ADC AND ASL BIT BRK CMP CPX CPY DEC EOR INC JMP JSR LDA LDX LDY LSR + NOP ORA ROL ROR RTI RTS SBC STA STX STY TAX TXA DEX INX TAY TYA DEY + INY BPL BMI BVC BVS BCC BCS BNE BEQ CLC SEC CLI SEI CLV CLD SED TXS + TSX PHA PLA PHP PLP + ) + end + + def self.keywords_type + @keywords_type ||= %w( DB DW BYTE WORD - ) - - keywords_reserved = %w( - INCBIN INCLUDE ORG BANK RSSET RS - MACRO ENDM DS PROC ENDP PROCGROUP ENDPROCGROUP - INCCHR DEFCHR ZP BSS CODE DATA IF IFDEF IFNDEF - ELSE ENDIF FAIL INESPRG INESCHR INESMAP INESMIR - ) + ) + end + + def self.keywords_reserved + @keywords_reserved ||= %w( + INCBIN INCLUDE ORG BANK RSSET RS MACRO ENDM DS PROC ENDP PROCGROUP + ENDPROCGROUP INCCHR DEFCHR ZP BSS CODE DATA IF IFDEF IFNDEF ELSE + ENDIF FAIL INESPRG INESCHR INESMAP INESMIR + ) + end state :root do rule %r/\s+/m, Text @@ -43,16 +45,25 @@ class NesAsm < RegexLexer rule %r/\#*[0-9]+/, Num # 10 #10 rule %r([~&*+=\|?:<>/-]), Operator - rule %r/\b(?:#{keywords.join('|')})\b/i, Keyword - rule %r/\b(?:#{keywords_type.join('|')})\b/i, Keyword::Type - rule %r/\b(?:#{keywords_reserved.join('|')})\b/i, Keyword::Reserved + rule %r/\b\#?\w+\b/i do |m| + name = m[0].upcase + + if self.class.keywords.include? name + token Keyword + elsif self.class.keywords_type.include? name + token Keyword::Type + elsif self.class.keywords_reserved.include? name + token Keyword::Reserved + else + token Name::Function + end + end + rule %r/(?:#*LOW|#*HIGH)\(.*\)/i, Keyword::Reserved # LOW() #HIGH() - rule %r/\#\w+/, Name::Function # #LABEL rule %r/\#\(/, Punctuation # #() rule %r/".*"/, Str # "" - rule %r/\w*/, Name::Function # other labels/variables/names etc end end From ce303bea36763122e7e124a99b9e4cc84cc0d4b1 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Mon, 11 Nov 2019 14:54:56 +0900 Subject: [PATCH 05/13] Simplify comment rule --- lib/rouge/lexers/nesasm.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index 3d757bd62a..80433db108 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -35,7 +35,7 @@ def self.keywords_reserved state :root do rule %r/\s+/m, Text - rule %r(;.*?$), Comment::Single + rule %r(;.*), Comment::Single rule %r/\w*\:/, Name::Function #label: rule %r/[\(\)\,\.\[\]]/, Punctuation From b132ddd21f2c4f4cd82899423687ddfb06635ce4 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Mon, 11 Nov 2019 14:58:19 +0900 Subject: [PATCH 06/13] Simplify number rules --- lib/rouge/lexers/nesasm.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index 80433db108..cc6bd7ab53 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -39,10 +39,9 @@ def self.keywords_reserved rule %r/\w*\:/, Name::Function #label: rule %r/[\(\)\,\.\[\]]/, Punctuation - rule %r/\#*\%[0-1]+/, Num::Bin # #%00110011 %00110011 - rule %r/\$\h+/, Num::Hex # $1f - rule %r/\#\$\h+/, Num::Hex #$1f - rule %r/\#*[0-9]+/, Num # 10 #10 + rule %r/\#?\%[0-1]+/, Num::Bin # #%00110011 %00110011 + rule %r/\#?\$\h+/, Num::Hex # $1f #$1f + rule %r/\#?\d+/, Num # 10 #10 rule %r([~&*+=\|?:<>/-]), Operator rule %r/\b\#?\w+\b/i do |m| From 6406fb5721ee0dc9f62691fd474a6608377f0cd4 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Mon, 11 Nov 2019 15:00:22 +0900 Subject: [PATCH 07/13] Simplify high/low rule --- lib/rouge/lexers/nesasm.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index cc6bd7ab53..be55c8b792 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -58,7 +58,7 @@ def self.keywords_reserved end end - rule %r/(?:#*LOW|#*HIGH)\(.*\)/i, Keyword::Reserved # LOW() #HIGH() + rule %r/\#?(?:LOW|HIGH)\(.*\)/i, Keyword::Reserved # LOW() #HIGH() rule %r/\#\(/, Punctuation # #() From 7171b1aa125cbc5e9ebae7ab536087fe5ea669a2 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Mon, 11 Nov 2019 15:06:36 +0900 Subject: [PATCH 08/13] Add more sophisticated string tokenising --- lib/rouge/lexers/nesasm.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index be55c8b792..f28028ea2d 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -62,9 +62,14 @@ def self.keywords_reserved rule %r/\#\(/, Punctuation # #() - rule %r/".*"/, Str # "" + rule %r/"/, Str, :string + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\"?/, Str + rule %r/[^"\\]+/m, Str end - end end end From b74b75c17d0e808a98bc1adb2301e54cb2fc27b8 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Mon, 11 Nov 2019 15:10:03 +0900 Subject: [PATCH 09/13] Rationalise function rules --- lib/rouge/lexers/nesasm.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index f28028ea2d..e3fccc9501 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -37,14 +37,13 @@ def self.keywords_reserved rule %r/\s+/m, Text rule %r(;.*), Comment::Single - rule %r/\w*\:/, Name::Function #label: rule %r/[\(\)\,\.\[\]]/, Punctuation rule %r/\#?\%[0-1]+/, Num::Bin # #%00110011 %00110011 rule %r/\#?\$\h+/, Num::Hex # $1f #$1f rule %r/\#?\d+/, Num # 10 #10 rule %r([~&*+=\|?:<>/-]), Operator - rule %r/\b\#?\w+\b/i do |m| + rule %r/\#?\w+:?/i do |m| name = m[0].upcase if self.class.keywords.include? name From 64b32d8c67a6bbee34d5969d19f95067def7c7c2 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Tue, 12 Nov 2019 22:58:15 +0900 Subject: [PATCH 10/13] Change token for escaped quotation marks --- lib/rouge/lexers/nesasm.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index e3fccc9501..34c6e8a090 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -66,7 +66,7 @@ def self.keywords_reserved state :string do rule %r/"/, Str, :pop! - rule %r/\\"?/, Str + rule %r/\\"?/, Str::Escape rule %r/[^"\\]+/m, Str end end From c7ab5136593120a035d23a9db2b5fd2754590dc0 Mon Sep 17 00:00:00 2001 From: YurySinev Date: Tue, 12 Nov 2019 18:40:23 +0400 Subject: [PATCH 11/13] Add rules for chars and bultin parameters inside functions and macros --- lib/rouge/lexers/nesasm.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index 34c6e8a090..75a5d7be93 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -62,6 +62,10 @@ def self.keywords_reserved rule %r/\#\(/, Punctuation # #() rule %r/"/, Str, :string + + rule %r/'\w'/, Str::Char # 'A' for example + + rule %r/\\\??[1-9\@\#]/, Name::Builtin # builtin parameters for use inside macros and functions: \1-\9 , \?1-\?9 , \# , \@ end state :string do From fc7bf748b735001adbf77ea77a695afc39d01a42 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Wed, 13 Nov 2019 02:38:06 +0900 Subject: [PATCH 12/13] Simplify regex for built-in params --- lib/rouge/lexers/nesasm.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index 75a5d7be93..0b8b50da51 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -65,7 +65,7 @@ def self.keywords_reserved rule %r/'\w'/, Str::Char # 'A' for example - rule %r/\\\??[1-9\@\#]/, Name::Builtin # builtin parameters for use inside macros and functions: \1-\9 , \?1-\?9 , \# , \@ + rule %r/\\\??[\d@#]/, Name::Builtin # builtin parameters for use inside macros and functions: \1-\9 , \?1-\?9 , \# , \@ end state :string do From 134cc213b85eea9532042200f016c2b7038c0f5d Mon Sep 17 00:00:00 2001 From: YurySinev Date: Tue, 12 Nov 2019 23:10:44 +0400 Subject: [PATCH 13/13] Add FUNC keyword and update visual demo --- lib/rouge/lexers/nesasm.rb | 2 +- spec/visual/samples/nesasm | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/rouge/lexers/nesasm.rb b/lib/rouge/lexers/nesasm.rb index 0b8b50da51..a296414e04 100644 --- a/lib/rouge/lexers/nesasm.rb +++ b/lib/rouge/lexers/nesasm.rb @@ -29,7 +29,7 @@ def self.keywords_reserved @keywords_reserved ||= %w( INCBIN INCLUDE ORG BANK RSSET RS MACRO ENDM DS PROC ENDP PROCGROUP ENDPROCGROUP INCCHR DEFCHR ZP BSS CODE DATA IF IFDEF IFNDEF ELSE - ENDIF FAIL INESPRG INESCHR INESMAP INESMIR + ENDIF FAIL INESPRG INESCHR INESMAP INESMIR FUNC ) end diff --git a/spec/visual/samples/nesasm b/spec/visual/samples/nesasm index 9ff74c7fcf..6615b3c6a2 100644 --- a/spec/visual/samples/nesasm +++ b/spec/visual/samples/nesasm @@ -17,6 +17,24 @@ Reset: jsr ClearRAM ; clear RAM jsr WaitSync ; wait for VSYNC (and PPU warmup) +SCR_ADDR .func (\1) + ((\2) << 5) + +abs .macro + lda \1 + bpl .x\@ + eor #$FF + inc A + sta \1 + + lda \# + sta numberOfParams + + lda \?4 + sta typeOfParam + + .x\@: + .endm + NMI: LoadSprites: ldx #$00