summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavisrichard437 <85075437+davisrichard437@users.noreply.github.com>2022-09-21 06:03:56 -0400
committerGitHub <noreply@github.com>2022-09-21 12:03:56 +0200
commit3fe62d2869677f8d0c12f0922d37982cbf819a5e (patch)
tree8b761682156836708458730f5226151dcd28b5b4
parentfd632c046fb23c9d139549b0991c488eab233ba2 (diff)
downloadpygments-git-3fe62d2869677f8d0c12f0922d37982cbf819a5e.tar.gz
Adding MIPS Lexer (#2228)
-rw-r--r--pygments/lexers/_mapping.py1
-rw-r--r--pygments/lexers/mips.py126
-rw-r--r--tests/examplefiles/mips/function_with_stack.mips84
-rw-r--r--tests/examplefiles/mips/function_with_stack.mips.output338
-rw-r--r--tests/snippets/mips/deprecated_substrings.txt34
-rw-r--r--tests/snippets/mips/keyword_substrings.txt254
-rw-r--r--tests/snippets/mips/variable_substrings.txt102
7 files changed, 939 insertions, 0 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py
index 89a286f9..22c70738 100644
--- a/pygments/lexers/_mapping.py
+++ b/pygments/lexers/_mapping.py
@@ -274,6 +274,7 @@ LEXERS = {
'LuaLexer': ('pygments.lexers.scripting', 'Lua', ('lua',), ('*.lua', '*.wlua'), ('text/x-lua', 'application/x-lua')),
'MCFunctionLexer': ('pygments.lexers.mcfunction', 'MCFunction', ('mcfunction', 'mcf'), ('*.mcfunction',), ('text/mcfunction',)),
'MIMELexer': ('pygments.lexers.mime', 'MIME', ('mime',), (), ('multipart/mixed', 'multipart/related', 'multipart/alternative')),
+ 'MIPSLexer': ('pygments.lexers.mips', 'MIPS', ('mips',), ('*.mips', '*.MIPS'), ()),
'MOOCodeLexer': ('pygments.lexers.scripting', 'MOOCode', ('moocode', 'moo'), ('*.moo',), ('text/x-moocode',)),
'MSDOSSessionLexer': ('pygments.lexers.shell', 'MSDOS Session', ('doscon',), (), ()),
'Macaulay2Lexer': ('pygments.lexers.macaulay2', 'Macaulay2', ('macaulay2',), ('*.m2',), ()),
diff --git a/pygments/lexers/mips.py b/pygments/lexers/mips.py
new file mode 100644
index 00000000..7b737d7b
--- /dev/null
+++ b/pygments/lexers/mips.py
@@ -0,0 +1,126 @@
+"""
+ pygments.lexers.mips
+ ~~~~~~~~~~~~~~~~~~~~
+ Lexers for MIPS assembly.
+ :copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import re
+from pygments.lexer import RegexLexer, words
+from pygments.token import Whitespace, Comment, String, Keyword, Name, Text
+
+__all__ = ["MIPSLexer"]
+
+
+class MIPSLexer(RegexLexer):
+ """
+ A MIPS Assembly Lexer.
+
+ Based on the Emacs major mode by hlissner:
+ https://github.com/hlissner/emacs-mips-mode
+ """
+
+ name = 'MIPS'
+ aliases = ['mips']
+ # TODO: add '*.s' and '*.asm', which will require designing an analyse_text
+ # method for this lexer and refactoring those from Gas and Nasm in order to
+ # have relatively reliable detection
+ filenames = ['*.mips', '*.MIPS']
+
+ keywords = [
+ # Arithmetic insturctions
+ "add", "sub", "subu", "addi", "subi", "addu", "addiu",
+ # Multiplication/division
+ "mul", "mult", "multu", "mulu", "madd", "maddu", "msub", "msubu", "div", "divu",
+ # Bitwise operations
+ "and", "or", "nor", "xor", "andi", "ori", "xori", "clo", "clz",
+ # Shifts
+ "sll", "srl", "sllv", "srlv", "sra", "srav",
+ # Comparisons
+ "slt", "sltu", "slti", "sltiu",
+ # Move data
+ "mfhi", "mthi", "mflo", "mtlo", "movn", "movz", "movf", "movt",
+ # Jump
+ "j", "jal", "jalr", "jr",
+ # branch
+ "bc1f", "bc1t", "beq", "bgez", "bgezal", "bgtz", "blez", "bltzal", "bltz", "bne",
+ # Load
+ "lui", "lb", "lbu", "lh", "lhu", "lw", "lwcl", "lwl", "lwr",
+ # Store
+ "sb", "sh", "sw", "swl", "swr", # coproc: swc1 sdc1
+ # Concurrent load/store
+ "ll", "sc",
+ # Trap handling
+ "teq", "teqi", "tne", "tneqi", "tge", "tgeu", "tgei", "tgeiu", "tlt", "tltu", "tlti",
+ "tltiu",
+ # Exception / Interrupt
+ "eret", "break", "bop", "syscall",
+ #--- Floats -----------------------------------------------------
+ # Arithmetic
+ "add.s", "add.d", "sub.s", "sub.d", "mul.s", "mul.d", "div.s", "div.d", "neg.d",
+ "neg.s",
+ # Comparison
+ "c.e.d", "c.e.s", "c.le.d", "c.le.s", "c.lt.s", "c.lt.d", # "c.gt.s", "c.gt.d",
+ "madd.s", "madd.d", "msub.s", "msub.d",
+ # Move Floats
+ "mov.d", "move.s", "movf.d", "movf.s", "movt.d", "movt.s", "movn.d", "movn.s",
+ "movnzd", "movz.s", "movz.d",
+ # Conversion
+ "cvt.d.s", "cvt.d.w", "cvt.s.d", "cvt.s.w", "cvt.w.d", "cvt.w.s", "trunc.w.d",
+ "trunc.w.s",
+ # Math
+ "abs.s", "abs.d", "sqrt.s", "sqrt.d", "ceil.w.d", "ceil.w.s", "floor.w.d",
+ "floor.w.s", "round.w.d", "round.w.s",
+ ]
+
+ pseudoinstructions = [
+ # Arithmetic & logical
+ "rem", "remu", "mulo", "mulou", "abs", "neg", "negu", "not", "rol", "ror",
+ # branches
+ "b", "beqz", "bge", "bgeu", "bgt", "bgtu", "ble", "bleu", "blt", "bltu", "bnez",
+ # loads
+ "la", "li", "ld", "ulh", "ulhu", "ulw",
+ # Store
+ "sd", "ush", "usw",
+ # move
+ "move", # coproc: "mfc1.d",
+ # comparisons
+ "sgt", "sgtu", "sge", "sgeu", "sle", "sleu", "sne", "seq",
+ #--- Floats -----------------------------------------------------
+ # load-store
+ "l.d", "l.s", "s.d", "s.s",
+ ]
+
+ directives = [
+ ".align", ".ascii", ".asciiz", ".byte", ".data", ".double", ".extern", ".float",
+ ".globl", ".half", ".kdata", ".ktext", ".space", ".text", ".word",
+ ]
+
+ deprecated = [
+ "beql", "bnel", "bgtzl", "bgezl", "bltzl", "blezl", "bltzall", "bgezall",
+ ]
+
+ tokens = {
+ 'root': [
+ (r'\s+', Whitespace),
+ (r'#.*', Comment),
+ (r'"', String, 'string'),
+ (r'-?[0-9]+?', Keyword.Constant),
+ (r'\w*:', Name.Function),
+ (words(deprecated, suffix=r'\b'), Keyword.Pseudo), # need warning face
+ (words(pseudoinstructions, suffix=r'\b'), Name.Variable),
+ (words(keywords, suffix=r'\b'), Keyword),
+ (r'[slm][ftwd]c[0-9]([.]d)?', Keyword),
+ (r'\$(f?[0-2][0-9]|f?3[01]|[ft]?[0-9]|[vk][01]|a[0-3]|s[0-7]|[gsf]p|ra|at|zero)', Keyword.Type),
+ (words(directives, suffix=r'\b'), Name.Entity), # Preprocessor?
+ (r':|,|;|\{|\}|=>|@|\$|=', Name.Builtin),
+ (r'\w+', Text),
+ (r'.', Text),
+ ],
+ 'string': [
+ (r'\\.', String.Escape),
+ (r'"', String, '#pop'),
+ (r'[^\\"]+', String),
+ ],
+ }
diff --git a/tests/examplefiles/mips/function_with_stack.mips b/tests/examplefiles/mips/function_with_stack.mips
new file mode 100644
index 00000000..b9d606f6
--- /dev/null
+++ b/tests/examplefiles/mips/function_with_stack.mips
@@ -0,0 +1,84 @@
+# Simple routine to demo functions
+# USING a stack in this example to preserve
+# values of calling function
+
+# ------------------------------------------------------------------
+
+ .text
+
+ .globl main
+main:
+ # Register assignments
+ # $s0 = x
+ # $s1 = y
+
+ # Initialize registers
+ lw $s0, x # Reg $s0 = x
+ lw $s1, y # Reg $s1 = y
+
+ # Call function
+ move $a0, $s0 # Argument 1: x ($s0)
+ jal fun # Save current PC in $ra, and jump to fun
+ move $s1,$v0 # Return value saved in $v0. This is y ($s1)
+
+ # Print msg1
+ li $v0, 4 # print_string syscall code = 4
+ la $a0, msg1
+ syscall
+
+ # Print result (y)
+ li $v0,1 # print_int syscall code = 1
+ move $a0, $s1 # Load integer to print in $a0
+ syscall
+
+ # Print newline
+ li $v0,4 # print_string syscall code = 4
+ la $a0, lf
+ syscall
+
+ # Exit
+ li $v0,10 # exit
+ syscall
+
+# ------------------------------------------------------------------
+
+ # FUNCTION: int fun(int a)
+ # Arguments are stored in $a0
+ # Return value is stored in $v0
+ # Return address is stored in $ra (put there by jal instruction)
+ # Typical function operation is:
+
+fun: # This function overwrites $s0 and $s1
+ # We should save those on the stack
+ # This is PUSH'ing onto the stack
+ addi $sp,$sp,-4 # Adjust stack pointer
+ sw $s0,0($sp) # Save $s0
+ addi $sp,$sp,-4 # Adjust stack pointer
+ sw $s1,0($sp) # Save $s1
+
+ # Do the function math
+ li $s0, 3
+ mul $s1,$s0,$a0 # s1 = 3*$a0 (i.e. 3*a)
+ addi $s1,$s1,5 # 3*a+5
+
+ # Save the return value in $v0
+ move $v0,$s1
+
+ # Restore saved register values from stack in opposite order
+ # This is POP'ing from the stack
+ lw $s1,0($sp) # Restore $s1
+ addi $sp,$sp,4 # Adjust stack pointer
+ lw $s0,0($sp) # Restore $s0
+ addi $sp,$sp,4 # Adjust stack pointer
+
+ # Return from function
+ jr $ra # Jump to addr stored in $ra
+
+# ------------------------------------------------------------------
+
+ # Start .data segment (data!)
+ .data
+x: .word 5
+y: .word 0
+msg1: .asciiz "y="
+lf: .asciiz "\n"
diff --git a/tests/examplefiles/mips/function_with_stack.mips.output b/tests/examplefiles/mips/function_with_stack.mips.output
new file mode 100644
index 00000000..552b9360
--- /dev/null
+++ b/tests/examplefiles/mips/function_with_stack.mips.output
@@ -0,0 +1,338 @@
+'# Simple routine to demo functions' Comment
+'\n' Text.Whitespace
+
+'# USING a stack in this example to preserve' Comment
+'\n' Text.Whitespace
+
+'# values of calling function' Comment
+'\n\n' Text.Whitespace
+
+'# ------------------------------------------------------------------' Comment
+'\n\n ' Text.Whitespace
+'.text' Name.Entity
+'\n\n ' Text.Whitespace
+'.globl' Name.Entity
+' ' Text.Whitespace
+'main' Text
+'\n' Text.Whitespace
+
+'main:' Name.Function
+'\n ' Text.Whitespace
+'# Register assignments' Comment
+'\n ' Text.Whitespace
+'# $s0 = x' Comment
+'\n ' Text.Whitespace
+'# $s1 = y' Comment
+'\n\n ' Text.Whitespace
+'# Initialize registers' Comment
+'\n ' Text.Whitespace
+'lw' Keyword
+' ' Text.Whitespace
+'$s0' Keyword.Type
+',' Name.Builtin
+' ' Text.Whitespace
+'x' Text
+' ' Text.Whitespace
+'# Reg $s0 = x' Comment
+'\n ' Text.Whitespace
+'lw' Keyword
+' ' Text.Whitespace
+'$s1' Keyword.Type
+',' Name.Builtin
+' ' Text.Whitespace
+'y' Text
+' ' Text.Whitespace
+'# Reg $s1 = y' Comment
+'\n\n ' Text.Whitespace
+'# Call function' Comment
+'\n ' Text.Whitespace
+'move' Name.Variable
+' ' Text.Whitespace
+'$a0' Keyword.Type
+',' Name.Builtin
+' ' Text.Whitespace
+'$s0' Keyword.Type
+' ' Text.Whitespace
+'# Argument 1: x ($s0)' Comment
+'\n ' Text.Whitespace
+'jal' Keyword
+' ' Text.Whitespace
+'fun' Text
+' ' Text.Whitespace
+'# Save current PC in $ra, and jump to fun' Comment
+'\n ' Text.Whitespace
+'move' Name.Variable
+' ' Text.Whitespace
+'$s1' Keyword.Type
+',' Name.Builtin
+'$v0' Keyword.Type
+' ' Text.Whitespace
+'# Return value saved in $v0. This is y ($s1)' Comment
+'\n\n ' Text.Whitespace
+'# Print msg1' Comment
+'\n ' Text.Whitespace
+'li' Name.Variable
+' ' Text.Whitespace
+'$v0' Keyword.Type
+',' Name.Builtin
+' ' Text.Whitespace
+'4' Keyword.Constant
+' ' Text.Whitespace
+'# print_string syscall code = 4' Comment
+'\n ' Text.Whitespace
+'la' Name.Variable
+' ' Text.Whitespace
+'$a0' Keyword.Type
+',' Name.Builtin
+' ' Text.Whitespace
+'msg1' Text
+'\n ' Text.Whitespace
+'syscall' Keyword
+'\n\n ' Text.Whitespace
+'# Print result (y)' Comment
+'\n ' Text.Whitespace
+'li' Name.Variable
+' ' Text.Whitespace
+'$v0' Keyword.Type
+',' Name.Builtin
+'1' Keyword.Constant
+' ' Text.Whitespace
+'# print_int syscall code = 1' Comment
+'\n ' Text.Whitespace
+'move' Name.Variable
+' ' Text.Whitespace
+'$a0' Keyword.Type
+',' Name.Builtin
+' ' Text.Whitespace
+'$s1' Keyword.Type
+' ' Text.Whitespace
+'# Load integer to print in $a0' Comment
+'\n ' Text.Whitespace
+'syscall' Keyword
+'\n\n ' Text.Whitespace
+'# Print newline' Comment
+'\n ' Text.Whitespace
+'li' Name.Variable
+' ' Text.Whitespace
+'$v0' Keyword.Type
+',' Name.Builtin
+'4' Keyword.Constant
+' ' Text.Whitespace
+'# print_string syscall code = 4' Comment
+'\n ' Text.Whitespace
+'la' Name.Variable
+' ' Text.Whitespace
+'$a0' Keyword.Type
+',' Name.Builtin
+' ' Text.Whitespace
+'lf' Text
+'\n ' Text.Whitespace
+'syscall' Keyword
+'\n\n ' Text.Whitespace
+'# Exit' Comment
+'\n ' Text.Whitespace
+'li' Name.Variable
+' ' Text.Whitespace
+'$v0' Keyword.Type
+',' Name.Builtin
+'1' Keyword.Constant
+'0' Keyword.Constant
+' ' Text.Whitespace
+'# exit' Comment
+'\n ' Text.Whitespace
+'syscall' Keyword
+'\n\n' Text.Whitespace
+
+'# ------------------------------------------------------------------' Comment
+'\n\n ' Text.Whitespace
+'# FUNCTION: int fun(int a)' Comment
+'\n ' Text.Whitespace
+'# Arguments are stored in $a0' Comment
+'\n ' Text.Whitespace
+'# Return value is stored in $v0' Comment
+'\n ' Text.Whitespace
+'# Return address is stored in $ra (put there by jal instruction)' Comment
+'\n ' Text.Whitespace
+'# Typical function operation is:' Comment
+'\n\n' Text.Whitespace
+
+'fun:' Name.Function
+' ' Text.Whitespace
+'# This function overwrites $s0 and $s1' Comment
+'\n ' Text.Whitespace
+'# We should save those on the stack' Comment
+'\n ' Text.Whitespace
+"# This is PUSH'ing onto the stack" Comment
+'\n ' Text.Whitespace
+'addi' Keyword
+' ' Text.Whitespace
+'$sp' Keyword.Type
+',' Name.Builtin
+'$sp' Keyword.Type
+',' Name.Builtin
+'-4' Keyword.Constant
+' ' Text.Whitespace
+'# Adjust stack pointer' Comment
+'\n ' Text.Whitespace
+'sw' Keyword
+' ' Text.Whitespace
+'$s0' Keyword.Type
+',' Name.Builtin
+'0' Keyword.Constant
+'(' Text
+'$sp' Keyword.Type
+')' Text
+' ' Text.Whitespace
+'# Save $s0' Comment
+'\n ' Text.Whitespace
+'addi' Keyword
+' ' Text.Whitespace
+'$sp' Keyword.Type
+',' Name.Builtin
+'$sp' Keyword.Type
+',' Name.Builtin
+'-4' Keyword.Constant
+' ' Text.Whitespace
+'# Adjust stack pointer' Comment
+'\n ' Text.Whitespace
+'sw' Keyword
+' ' Text.Whitespace
+'$s1' Keyword.Type
+',' Name.Builtin
+'0' Keyword.Constant
+'(' Text
+'$sp' Keyword.Type
+')' Text
+' ' Text.Whitespace
+'# Save $s1' Comment
+'\n\n ' Text.Whitespace
+'# Do the function math' Comment
+'\n ' Text.Whitespace
+'li' Name.Variable
+' ' Text.Whitespace
+'$s0' Keyword.Type
+',' Name.Builtin
+' ' Text.Whitespace
+'3' Keyword.Constant
+'\n ' Text.Whitespace
+'mul' Keyword
+' ' Text.Whitespace
+'$s1' Keyword.Type
+',' Name.Builtin
+'$s0' Keyword.Type
+',' Name.Builtin
+'$a0' Keyword.Type
+' ' Text.Whitespace
+'# s1 = 3*$a0 (i.e. 3*a)' Comment
+'\n ' Text.Whitespace
+'addi' Keyword
+' ' Text.Whitespace
+'$s1' Keyword.Type
+',' Name.Builtin
+'$s1' Keyword.Type
+',' Name.Builtin
+'5' Keyword.Constant
+' ' Text.Whitespace
+'# 3*a+5' Comment
+'\n\n ' Text.Whitespace
+'# Save the return value in $v0' Comment
+'\n ' Text.Whitespace
+'move' Name.Variable
+' ' Text.Whitespace
+'$v0' Keyword.Type
+',' Name.Builtin
+'$s1' Keyword.Type
+'\n\n ' Text.Whitespace
+'# Restore saved register values from stack in opposite order' Comment
+'\n ' Text.Whitespace
+"# This is POP'ing from the stack" Comment
+'\n ' Text.Whitespace
+'lw' Keyword
+' ' Text.Whitespace
+'$s1' Keyword.Type
+',' Name.Builtin
+'0' Keyword.Constant
+'(' Text
+'$sp' Keyword.Type
+')' Text
+' ' Text.Whitespace
+'# Restore $s1' Comment
+'\n ' Text.Whitespace
+'addi' Keyword
+' ' Text.Whitespace
+'$sp' Keyword.Type
+',' Name.Builtin
+'$sp' Keyword.Type
+',' Name.Builtin
+'4' Keyword.Constant
+' ' Text.Whitespace
+'# Adjust stack pointer' Comment
+'\n ' Text.Whitespace
+'lw' Keyword
+' ' Text.Whitespace
+'$s0' Keyword.Type
+',' Name.Builtin
+'0' Keyword.Constant
+'(' Text
+'$sp' Keyword.Type
+')' Text
+' ' Text.Whitespace
+'# Restore $s0' Comment
+'\n ' Text.Whitespace
+'addi' Keyword
+' ' Text.Whitespace
+'$sp' Keyword.Type
+',' Name.Builtin
+'$sp' Keyword.Type
+',' Name.Builtin
+'4' Keyword.Constant
+' ' Text.Whitespace
+'# Adjust stack pointer' Comment
+'\n\n ' Text.Whitespace
+'# Return from function' Comment
+'\n ' Text.Whitespace
+'jr' Keyword
+' ' Text.Whitespace
+'$ra' Keyword.Type
+' ' Text.Whitespace
+'# Jump to addr stored in $ra' Comment
+'\n\n' Text.Whitespace
+
+'# ------------------------------------------------------------------' Comment
+'\n\n ' Text.Whitespace
+'# Start .data segment (data!)' Comment
+'\n ' Text.Whitespace
+'.data' Name.Entity
+'\n' Text.Whitespace
+
+'x:' Name.Function
+' ' Text.Whitespace
+'.word' Name.Entity
+' ' Text.Whitespace
+'5' Keyword.Constant
+'\n' Text.Whitespace
+
+'y:' Name.Function
+' ' Text.Whitespace
+'.word' Name.Entity
+' ' Text.Whitespace
+'0' Keyword.Constant
+'\n' Text.Whitespace
+
+'msg1:' Name.Function
+' ' Text.Whitespace
+'.asciiz' Name.Entity
+' ' Text.Whitespace
+'"' Literal.String
+'y=' Literal.String
+'"' Literal.String
+'\n' Text.Whitespace
+
+'lf:' Name.Function
+' ' Text.Whitespace
+'.asciiz' Name.Entity
+' ' Text.Whitespace
+'"' Literal.String
+'\\n' Literal.String.Escape
+'"' Literal.String
+'\n' Text.Whitespace
diff --git a/tests/snippets/mips/deprecated_substrings.txt b/tests/snippets/mips/deprecated_substrings.txt
new file mode 100644
index 00000000..4e7aa7d3
--- /dev/null
+++ b/tests/snippets/mips/deprecated_substrings.txt
@@ -0,0 +1,34 @@
+---input---
+beql
+bnel
+bgtzl
+bgezl
+bltzl
+blezl
+bltzall
+bgezall
+
+---tokens---
+'beql' Keyword.Pseudo
+'\n' Text.Whitespace
+
+'bnel' Keyword.Pseudo
+'\n' Text.Whitespace
+
+'bgtzl' Keyword.Pseudo
+'\n' Text.Whitespace
+
+'bgezl' Keyword.Pseudo
+'\n' Text.Whitespace
+
+'bltzl' Keyword.Pseudo
+'\n' Text.Whitespace
+
+'blezl' Keyword.Pseudo
+'\n' Text.Whitespace
+
+'bltzall' Keyword.Pseudo
+'\n' Text.Whitespace
+
+'bgezall' Keyword.Pseudo
+'\n' Text.Whitespace
diff --git a/tests/snippets/mips/keyword_substrings.txt b/tests/snippets/mips/keyword_substrings.txt
new file mode 100644
index 00000000..70d68d57
--- /dev/null
+++ b/tests/snippets/mips/keyword_substrings.txt
@@ -0,0 +1,254 @@
+---input---
+subu
+subi
+sub
+addu
+addiu
+addi
+add
+multu
+mult
+mulu
+mul
+maddu
+madd
+msubu
+msub
+divu
+div
+nor
+xor
+andi
+and
+ori
+xori
+or
+sllv
+sll
+srlv
+srl
+srav
+sra
+sltiu
+sltu
+slti
+slt
+jalr
+jal
+jr
+j
+bgezal
+bgez
+bltzal
+bltz
+lbu
+lb
+lhu
+lh
+lwr
+lw
+swl
+swr
+sw
+teqi
+teq
+tneqi
+tne
+tgeiu
+tgeu
+tgei
+tge
+tltiu
+tltu
+tlti
+tlt
+
+---tokens---
+'subu' Keyword
+'\n' Text.Whitespace
+
+'subi' Keyword
+'\n' Text.Whitespace
+
+'sub' Keyword
+'\n' Text.Whitespace
+
+'addu' Keyword
+'\n' Text.Whitespace
+
+'addiu' Keyword
+'\n' Text.Whitespace
+
+'addi' Keyword
+'\n' Text.Whitespace
+
+'add' Keyword
+'\n' Text.Whitespace
+
+'multu' Keyword
+'\n' Text.Whitespace
+
+'mult' Keyword
+'\n' Text.Whitespace
+
+'mulu' Keyword
+'\n' Text.Whitespace
+
+'mul' Keyword
+'\n' Text.Whitespace
+
+'maddu' Keyword
+'\n' Text.Whitespace
+
+'madd' Keyword
+'\n' Text.Whitespace
+
+'msubu' Keyword
+'\n' Text.Whitespace
+
+'msub' Keyword
+'\n' Text.Whitespace
+
+'divu' Keyword
+'\n' Text.Whitespace
+
+'div' Keyword
+'\n' Text.Whitespace
+
+'nor' Keyword
+'\n' Text.Whitespace
+
+'xor' Keyword
+'\n' Text.Whitespace
+
+'andi' Keyword
+'\n' Text.Whitespace
+
+'and' Keyword
+'\n' Text.Whitespace
+
+'ori' Keyword
+'\n' Text.Whitespace
+
+'xori' Keyword
+'\n' Text.Whitespace
+
+'or' Keyword
+'\n' Text.Whitespace
+
+'sllv' Keyword
+'\n' Text.Whitespace
+
+'sll' Keyword
+'\n' Text.Whitespace
+
+'srlv' Keyword
+'\n' Text.Whitespace
+
+'srl' Keyword
+'\n' Text.Whitespace
+
+'srav' Keyword
+'\n' Text.Whitespace
+
+'sra' Keyword
+'\n' Text.Whitespace
+
+'sltiu' Keyword
+'\n' Text.Whitespace
+
+'sltu' Keyword
+'\n' Text.Whitespace
+
+'slti' Keyword
+'\n' Text.Whitespace
+
+'slt' Keyword
+'\n' Text.Whitespace
+
+'jalr' Keyword
+'\n' Text.Whitespace
+
+'jal' Keyword
+'\n' Text.Whitespace
+
+'jr' Keyword
+'\n' Text.Whitespace
+
+'j' Keyword
+'\n' Text.Whitespace
+
+'bgezal' Keyword
+'\n' Text.Whitespace
+
+'bgez' Keyword
+'\n' Text.Whitespace
+
+'bltzal' Keyword
+'\n' Text.Whitespace
+
+'bltz' Keyword
+'\n' Text.Whitespace
+
+'lbu' Keyword
+'\n' Text.Whitespace
+
+'lb' Keyword
+'\n' Text.Whitespace
+
+'lhu' Keyword
+'\n' Text.Whitespace
+
+'lh' Keyword
+'\n' Text.Whitespace
+
+'lwr' Keyword
+'\n' Text.Whitespace
+
+'lw' Keyword
+'\n' Text.Whitespace
+
+'swl' Keyword
+'\n' Text.Whitespace
+
+'swr' Keyword
+'\n' Text.Whitespace
+
+'sw' Keyword
+'\n' Text.Whitespace
+
+'teqi' Keyword
+'\n' Text.Whitespace
+
+'teq' Keyword
+'\n' Text.Whitespace
+
+'tneqi' Keyword
+'\n' Text.Whitespace
+
+'tne' Keyword
+'\n' Text.Whitespace
+
+'tgeiu' Keyword
+'\n' Text.Whitespace
+
+'tgeu' Keyword
+'\n' Text.Whitespace
+
+'tgei' Keyword
+'\n' Text.Whitespace
+
+'tge' Keyword
+'\n' Text.Whitespace
+
+'tltiu' Keyword
+'\n' Text.Whitespace
+
+'tltu' Keyword
+'\n' Text.Whitespace
+
+'tlti' Keyword
+'\n' Text.Whitespace
+
+'tlt' Keyword
+'\n' Text.Whitespace
diff --git a/tests/snippets/mips/variable_substrings.txt b/tests/snippets/mips/variable_substrings.txt
new file mode 100644
index 00000000..85e845d3
--- /dev/null
+++ b/tests/snippets/mips/variable_substrings.txt
@@ -0,0 +1,102 @@
+---input---
+remu
+rem
+mulou
+mulo
+negu
+neg
+beqz
+bgeu
+bge
+bgtu
+bgt
+bleu
+ble
+bltu
+blt
+bnez
+b
+ulhu
+ulh
+sgtu
+sgt
+sgeu
+sge
+sleu
+sle
+
+---tokens---
+'remu' Name.Variable
+'\n' Text.Whitespace
+
+'rem' Name.Variable
+'\n' Text.Whitespace
+
+'mulou' Name.Variable
+'\n' Text.Whitespace
+
+'mulo' Name.Variable
+'\n' Text.Whitespace
+
+'negu' Name.Variable
+'\n' Text.Whitespace
+
+'neg' Name.Variable
+'\n' Text.Whitespace
+
+'beqz' Name.Variable
+'\n' Text.Whitespace
+
+'bgeu' Name.Variable
+'\n' Text.Whitespace
+
+'bge' Name.Variable
+'\n' Text.Whitespace
+
+'bgtu' Name.Variable
+'\n' Text.Whitespace
+
+'bgt' Name.Variable
+'\n' Text.Whitespace
+
+'bleu' Name.Variable
+'\n' Text.Whitespace
+
+'ble' Name.Variable
+'\n' Text.Whitespace
+
+'bltu' Name.Variable
+'\n' Text.Whitespace
+
+'blt' Name.Variable
+'\n' Text.Whitespace
+
+'bnez' Name.Variable
+'\n' Text.Whitespace
+
+'b' Name.Variable
+'\n' Text.Whitespace
+
+'ulhu' Name.Variable
+'\n' Text.Whitespace
+
+'ulh' Name.Variable
+'\n' Text.Whitespace
+
+'sgtu' Name.Variable
+'\n' Text.Whitespace
+
+'sgt' Name.Variable
+'\n' Text.Whitespace
+
+'sgeu' Name.Variable
+'\n' Text.Whitespace
+
+'sge' Name.Variable
+'\n' Text.Whitespace
+
+'sleu' Name.Variable
+'\n' Text.Whitespace
+
+'sle' Name.Variable
+'\n' Text.Whitespace