diff --git a/lexers/a/armasm.go b/lexers/a/armasm.go new file mode 100644 index 000000000..a2bdceebb --- /dev/null +++ b/lexers/a/armasm.go @@ -0,0 +1,72 @@ +package a + +import ( + . "github.com/alecthomas/chroma" // nolint + "github.com/alecthomas/chroma/lexers/internal" +) + +var ArmAsm = internal.Register(MustNewLazyLexer( + &Config{ + Name: "ArmAsm", + Aliases: []string{"armasm"}, + EnsureNL: true, + Filenames: []string{"*.s", "*.S"}, + MimeTypes: []string{"text/x-armasm", "text/x-asm"}, + }, + armasmRules, +)) + +func armasmRules() Rules { + return Rules{ + "commentsandwhitespace": { + {`\s+`, Text, nil}, + {`[@;].*?\n`, CommentSingle, nil}, + {`/\*.*?\*/`, CommentMultiline, nil}, + }, + "literal": { + // Binary + {`0b[01]+`, NumberBin, Pop(1)}, + // Hex + {`0x\w{1,8}`, NumberHex, Pop(1)}, + // Octal + {`0\d+`, NumberOct, Pop(1)}, + // Float + {`\d+?\.\d+?`, NumberFloat, Pop(1)}, + // Integer + {`\d+`, NumberInteger, Pop(1)}, + // String + {`(")(.+)(")`, ByGroups(Punctuation, StringDouble, Punctuation), Pop(1)}, + // Char + {`(')(.{1}|\\.{1})(')`, ByGroups(Punctuation, StringChar, Punctuation), Pop(1)}, + }, + "opcode": { + // Escape at line end + {`\n`, Text, Pop(1)}, + // Comment + {`(@|;).*\n`, CommentSingle, Pop(1)}, + // Whitespace + {`(\s+|,)`, Text, nil}, + // Register by number + {`[rapcfxwbhsdqv]\d{1,2}`, NameClass, nil}, + // Address by hex + {`=0x\w+`, ByGroups(Text, NameLabel), nil}, + // Pseudo address by label + {`(=)(\w+)`, ByGroups(Text, NameLabel), nil}, + // Immediate + {`#`, Text, Push("literal")}, + }, + "root": { + Include("commentsandwhitespace"), + // Directive with optional param + {`(\.\w+)([ \t]+\w+\s+?)?`, ByGroups(KeywordNamespace, NameLabel), nil}, + // Label with data + {`(\w+)(:)(\s+\.\w+\s+)`, ByGroups(NameLabel, Punctuation, KeywordNamespace), Push("literal")}, + // Label + {`(\w+)(:)`, ByGroups(NameLabel, Punctuation), nil}, + // Syscall Op + {`svc\s+\w+`, NameNamespace, nil}, + // Opcode + {`[a-zA-Z]+`, Text, Push("opcode")}, + }, + } +} diff --git a/lexers/testdata/armasm.actual b/lexers/testdata/armasm.actual new file mode 100644 index 000000000..f3fefdc61 --- /dev/null +++ b/lexers/testdata/armasm.actual @@ -0,0 +1,17 @@ +@ Hello World in ARM Assembly for Linux system + +.global _start + +_start: + mov r7, #4 @ Setup service call 4 (write) + mov r0, #1 @ param 1 - File descriptor 1 = stdout + ldr r1, =hello @ param 2 - address of string to print + mov r2, #13 @ param 3 - length of hello world string + svc 0 @ ask linux to write to stdout + + mov r7, #1 @ Setup service call 1 (exit) + mov r0, #0 @ param 1 - 0 = normal exit + svc 0 @ ask linux to terminate us + +.data +hello: .ascii "Hello World!\n" \ No newline at end of file diff --git a/lexers/testdata/armasm.expected b/lexers/testdata/armasm.expected new file mode 100644 index 000000000..c36bb2455 --- /dev/null +++ b/lexers/testdata/armasm.expected @@ -0,0 +1,62 @@ +[ + {"type":"CommentSingle","value":"@ Hello World in ARM Assembly for Linux system\n"}, + {"type":"Text","value":"\n"}, + {"type":"KeywordNamespace","value":".global"}, + {"type":"NameLabel","value":" _start\n"}, + {"type":"Text","value":"\n"}, + {"type":"NameLabel","value":"_start"}, + {"type":"Punctuation","value":":"}, + {"type":"Text","value":"\n mov "}, + {"type":"NameClass","value":"r7"}, + {"type":"Text","value":", #"}, + {"type":"LiteralNumberInteger","value":"4"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"@ Setup service call 4 (write)\n"}, + {"type":"Text","value":" mov "}, + {"type":"NameClass","value":"r0"}, + {"type":"Text","value":", #"}, + {"type":"LiteralNumberInteger","value":"1"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"@ param 1 - File descriptor 1 = stdout\n"}, + {"type":"Text","value":" ldr "}, + {"type":"NameClass","value":"r1"}, + {"type":"Text","value":", ="}, + {"type":"NameLabel","value":"hello"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"@ param 2 - address of string to print\n"}, + {"type":"Text","value":" mov "}, + {"type":"NameClass","value":"r2"}, + {"type":"Text","value":", #"}, + {"type":"LiteralNumberInteger","value":"13"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"@ param 3 - length of hello world string\n"}, + {"type":"Text","value":" "}, + {"type":"NameNamespace","value":"svc 0"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"@ ask linux to write to stdout\n"}, + {"type":"Text","value":"\n mov "}, + {"type":"NameClass","value":"r7"}, + {"type":"Text","value":", #"}, + {"type":"LiteralNumberInteger","value":"1"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"@ Setup service call 1 (exit)\n"}, + {"type":"Text","value":" mov "}, + {"type":"NameClass","value":"r0"}, + {"type":"Text","value":", #"}, + {"type":"LiteralNumberInteger","value":"0"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"@ param 1 - 0 = normal exit\n"}, + {"type":"Text","value":" "}, + {"type":"NameNamespace","value":"svc 0"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"@ ask linux to terminate us\n"}, + {"type":"Text","value":"\n"}, + {"type":"KeywordNamespace","value":".data"}, + {"type":"Text","value":"\n"}, + {"type":"NameLabel","value":"hello"}, + {"type":"Punctuation","value":":"}, + {"type":"KeywordNamespace","value":" .ascii "}, + {"type":"Punctuation","value":"\""}, + {"type":"LiteralStringDouble","value":"Hello World!\\n"}, + {"type":"Punctuation","value":"\""} +]