Repository: alecthomas/chroma
Pull request #531 (2021-07-17 17:52:17)

ARM ASM 
ARM Assembly (32bit, GAS) lexer added 


Patch:
diff --git a/lexers/a/armasm.go b/lexers/a/armasm.go
new file mode 100644
index 0000000..a2bdcee
--- /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")},
+		},
+	}
+}


Test patch:
diff --git a/lexers/testdata/armasm.actual b/lexers/testdata/armasm.actual
new file mode 100644
index 0000000..f3fefdc
--- /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 0000000..c36bb24
--- /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":"\""}
+]