Skip to content
This repository has been archived by the owner on Nov 5, 2021. It is now read-only.

[Feat] MIPS: Support for Syntax Highlight and Basic Colorization #65

Merged
merged 1 commit into from Aug 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/mips/mips.contribution.ts
@@ -0,0 +1,15 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';

import { registerLanguage } from '../_.contribution';

registerLanguage({
id: 'mips',
extensions: ['.s'],
aliases: ['MIPS', 'MIPS-V'],
mimetypes: ['text/x-mips', 'text/mips', 'text/plaintext'],
loader: () => import('./mips')
});
213 changes: 213 additions & 0 deletions src/mips/mips.test.ts
@@ -0,0 +1,213 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

'use strict';

import { testTokenization } from '../test/testRunner';

testTokenization('mips', [
// Comments
[{
line: '#',
tokens: [
{ startIndex: 0, type: 'comment.mips' }
]
}],

[{
line: ' # a comment',
tokens: [
{ startIndex: 0, type: '' },
{ startIndex: 4, type: 'comment.mips' }
]
}],

[{
line: '# a comment',
tokens: [
{ startIndex: 0, type: 'comment.mips' }
]
}],

[{
line: '#sticky comment',
tokens: [
{ startIndex: 0, type: 'comment.mips' }
]
}],

[{
line: '$x, 1 # my comment # is a nice one',
tokens: [
{ startIndex: 0, type: 'variable.predefined.mips' },
{ startIndex: 2, type: 'delimiter.mips' },
{ startIndex: 3, type: '' },
{ startIndex: 4, type: 'number.mips' },
{ startIndex: 5, type: '' },
{ startIndex: 6, type: 'comment.mips' }
]
}],

[{
line: '$x, 1e #is a exponent number',
tokens: [
{ startIndex: 0, type: 'variable.predefined.mips' },
{ startIndex: 2, type: 'delimiter.mips' },
{ startIndex: 3, type: '' },
{ startIndex: 4, type: 'number.float.mips' },
{ startIndex: 6, type: '' },
{ startIndex: 7, type: 'comment.mips' }
]
}],

[{
line: '$x, 0x1F #is a hex number',
tokens: [
{ startIndex: 0, type: 'variable.predefined.mips' },
{ startIndex: 2, type: 'delimiter.mips' },
{ startIndex: 3, type: '' },
{ startIndex: 4, type: 'number.hex.mips' },
{ startIndex: 8, type: '' },
{ startIndex: 9, type: 'comment.mips' }
]
}],

// Keywords
[{
line: 'li $r0, 5',
tokens: [
{ startIndex: 0, type: 'keyword.li.mips' },
{ startIndex: 2, type: '' },
{ startIndex: 3, type: 'variable.predefined.mips' },
{ startIndex: 6, type: 'delimiter.mips' },
{ startIndex: 7, type: '' },
{ startIndex: 8, type: 'number.mips' },
]
}],

[{
line: '.data # Data declaration',
tokens: [
{ startIndex: 0, type: 'keyword.\.data.mips' },
{ startIndex: 5, type: '' },
{ startIndex: 6, type: 'comment.mips' },
]
}],

[{
line: 'even_str: .asciiz "The number is even!" # Output string for even integer',
tokens: [
{ startIndex: 0, type: '' },
{ startIndex: 8, type: 'delimiter.mips' },
{ startIndex: 9, type: '' },
{ startIndex: 18, type: 'string.mips' },
{ startIndex: 39, type: '' },
{ startIndex: 40, type: 'comment.mips' },
]
}],

[{
line: ' add ',
tokens: [
{ startIndex: 0, type: '' },
{ startIndex: 4, type: 'keyword.add.mips' },
{ startIndex: 7, type: '' }
]
}],

// Comments - range comment, single line
[{
line: '### a simple comment ###',
tokens: [
{ startIndex: 0, type: 'comment.mips' }
]
}],

[{
line: 'move $x, ### a simple comment ### 1',
tokens: [
{ startIndex: 0, type: 'keyword.move.mips' },
{ startIndex: 4, type: '' },
{ startIndex: 5, type: 'variable.predefined.mips' },
{ startIndex: 7, type: 'delimiter.mips' },
{ startIndex: 8, type: '' },
{ startIndex: 9, type: 'comment.mips' },
]
}],

[{
line: '$x ###/',
tokens: [
{ startIndex: 0, type: 'variable.predefined.mips' },
{ startIndex: 2, type: '' },
{ startIndex: 3, type: 'comment.mips' }
]
}],

// Numbers
[{
line: '0',
tokens: [
{ startIndex: 0, type: 'number.mips' }
]
}],

[{
line: ' 0',
tokens: [
{ startIndex: 0, type: '' },
{ startIndex: 1, type: 'number.mips' }
]
}],

[{
line: ' 0 ',
tokens: [
{ startIndex: 0, type: '' },
{ startIndex: 1, type: 'number.mips' },
{ startIndex: 2, type: '' }
]
}],

[{
line: '0 ',
tokens: [
{ startIndex: 0, type: 'number.mips' },
{ startIndex: 1, type: '' }
]
}],

[{
line: '0123',
tokens: [
{ startIndex: 0, type: 'number.octal.mips' }
]
}],

[{
line: '01239',
tokens: [
{ startIndex: 0, type: 'number.mips' }
]
}],

[{
line: '0x123',
tokens: [
{ startIndex: 0, type: 'number.hex.mips' }
]
}],

[{
line: '1,2,3',
tokens: [
{ startIndex: 0, type: 'number.mips' },
{ startIndex: 1, type: 'delimiter.mips' },
{ startIndex: 2, type: 'number.mips' },
{ startIndex: 3, type: 'delimiter.mips' },
{ startIndex: 4, type: 'number.mips' },
]
}]
]);
157 changes: 157 additions & 0 deletions src/mips/mips.ts
@@ -0,0 +1,157 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

'use strict';

import IRichLanguageConfiguration = monaco.languages.LanguageConfiguration;
import ILanguage = monaco.languages.IMonarchLanguage;

export const conf: IRichLanguageConfiguration = {
wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#%\^\&\*\(\)\=\$\-\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
comments: {
blockComment: ['###', '###'],
lineComment: '#'
},
folding: {
markers: {
start: new RegExp("^\\s*#region\\b"),
end: new RegExp("^\\s*#endregion\\b")
}
}
};

export const language = <ILanguage>{
defaultToken: '',
ignoreCase: false,
tokenPostfix: '.mips',

regEx: /\/(?!\/\/)(?:[^\/\\]|\\.)*\/[igm]*/,

keywords: [
'.data', '.text', 'syscall', 'trap',
'add', 'addu', 'addi', 'addiu', 'and', 'andi',
'div', 'divu', 'mult', 'multu', 'nor', 'or', 'ori',
'sll', 'slv', 'sra', 'srav', 'srl', 'srlv',
'sub', 'subu', 'xor', 'xori', 'lhi', 'lho',
'lhi', 'llo', 'slt', 'slti', 'sltu', 'sltiu',
'beq', 'bgtz', 'blez', 'bne', 'j', 'jal', 'jalr', 'jr',
'lb', 'lbu', 'lh', 'lhu', 'lw', 'li', 'la',
'sb', 'sh', 'sw', 'mfhi', 'mflo', 'mthi', 'mtlo', 'move',
],

// we include these common regular expressions
symbols: /[\.,\:]+/,
escapes: /\\(?:[abfnrtv\\"'$]|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,

// The main tokenizer for our languages
tokenizer: {
root: [

// identifiers and keywords
[/\$[a-zA-Z_]\w*/, 'variable.predefined'],
[/[.a-zA-Z_]\w*/, {
cases: {
'this': 'variable.predefined',
'@keywords': { token: 'keyword.$0' },
'@default': ''
}
}],

// whitespace
[/[ \t\r\n]+/, ''],

// Comments
[/#.*$/, 'comment'],

// regular expressions
['///', { token: 'regexp', next: '@hereregexp' }],

[/^(\s*)(@regEx)/, ['', 'regexp']],
[/(\,)(\s*)(@regEx)/, ['delimiter', '', 'regexp']],
[/(\:)(\s*)(@regEx)/, ['delimiter', '', 'regexp']],


// delimiters
[/@symbols/, 'delimiter'],

// numbers
[/\d+[eE]([\-+]?\d+)?/, 'number.float'],
[/\d+\.\d+([eE][\-+]?\d+)?/, 'number.float'],
[/0[xX][0-9a-fA-F]+/, 'number.hex'],
[/0[0-7]+(?!\d)/, 'number.octal'],
[/\d+/, 'number'],

// delimiter: after number because of .\d floats
[/[,.]/, 'delimiter'],

// strings:
[/"""/, 'string', '@herestring."""'],
[/'''/, 'string', '@herestring.\'\'\''],
[/"/, {
cases: {
'@eos': 'string',
'@default': { token: 'string', next: '@string."' }
}
}],
[/'/, {
cases: {
'@eos': 'string',
'@default': { token: 'string', next: '@string.\'' }
}
}],
],

string: [
[/[^"'\#\\]+/, 'string'],
[/@escapes/, 'string.escape'],
[/\./, 'string.escape.invalid'],
[/\./, 'string.escape.invalid'],

[/#{/, {
cases: {
'$S2=="': { token: 'string', next: 'root.interpolatedstring' },
'@default': 'string'
}
}],

[/["']/, {
cases: {
'$#==$S2': { token: 'string', next: '@pop' },
'@default': 'string'
}
}],
[/#/, 'string']
],

herestring: [
[/("""|''')/, {
cases: {
'$1==$S2': { token: 'string', next: '@pop' },
'@default': 'string'
}
}],
[/[^#\\'"]+/, 'string'],
[/['"]+/, 'string'],
[/@escapes/, 'string.escape'],
[/\./, 'string.escape.invalid'],

[/#{/, { token: 'string.quote', next: 'root.interpolatedstring' }],
[/#/, 'string']
],

comment: [
[/[^#]+/, 'comment',],
[/#/, 'comment'],
],

hereregexp: [
[/[^\\\/#]+/, 'regexp'],
[/\\./, 'regexp'],
[/#.*$/, 'comment'],
['///[igm]*', { token: 'regexp', next: '@pop' }],
[/\//, 'regexp'],
],
},
};
1 change: 1 addition & 0 deletions src/monaco.contribution.ts
Expand Up @@ -22,6 +22,7 @@ import './kotlin/kotlin.contribution';
import './less/less.contribution';
import './lua/lua.contribution';
import './markdown/markdown.contribution';
import './mips/mips.contribution';
import './msdax/msdax.contribution';
import './mysql/mysql.contribution';
import './objective-c/objective-c.contribution';
Expand Down