Browse Source

Merge remote-tracking branch 'origin/master' into pr/VarghaSabee/121

Alexandru Dima 4 years ago
parent
commit
f1f9faf666

+ 25 - 0
.github/workflows/ci.yml

@@ -0,0 +1,25 @@
+name: CI
+
+on: push
+
+jobs:
+  ci:
+    name: CI
+    runs-on: ubuntu-latest
+    env:
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+    steps:
+      - uses: actions/checkout@v2
+
+      - uses: actions/setup-node@v2
+        with:
+          node-version: 12
+
+      - name: npm install
+        run: npm install
+
+      - name: Compile
+        run: npm run compile
+
+      - name: Test
+        run: npm test

+ 0 - 28
azure-pipelines.yml

@@ -1,28 +0,0 @@
-# Node.js
-# Build a general Node.js project with npm.
-# Add steps that analyze code, save build artifacts, deploy, and more:
-# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
-
-trigger:
-  - master
-
-pool:
-  vmImage: 'ubuntu-latest'
-
-steps:
-  - task: NodeTool@0
-    inputs:
-      versionSpec: '10.x'
-    displayName: 'Install Node.js'
-
-  - script: |
-      npm install
-    displayName: 'npm install'
-
-  - script: |
-      npm run compile
-    displayName: 'compile'
-
-  - script: |
-      npm test
-    displayName: 'test'

+ 13 - 0
src/ecl/ecl.contribution.ts

@@ -0,0 +1,13 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { registerLanguage } from '../_.contribution';
+
+registerLanguage({
+	id: 'ecl',
+	extensions: ['.ecl'],
+	aliases: ['ECL', 'Ecl', 'ecl'],
+	loader: () => import('./ecl')
+});

+ 8 - 0
src/ecl/ecl.test.ts

@@ -0,0 +1,8 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { testTokenization } from '../test/testRunner';
+
+testTokenization('ecl', []);

+ 481 - 0
src/ecl/ecl.ts

@@ -0,0 +1,481 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import type { languages } from '../fillers/monaco-editor-core';
+
+export const conf: languages.LanguageConfiguration = {
+	comments: {
+		lineComment: '//',
+		blockComment: ['/*', '*/']
+	},
+	brackets: [
+		['{', '}'],
+		['[', ']'],
+		['(', ')']
+	],
+	autoClosingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: "'", close: "'", notIn: ['string', 'comment'] },
+		{ open: '"', close: '"', notIn: ['string', 'comment'] }
+	],
+	surroundingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '<', close: '>' },
+		{ open: "'", close: "'" },
+		{ open: '"', close: '"' }
+	]
+};
+
+export const language = <languages.IMonarchLanguage>{
+	defaultToken: '',
+	tokenPostfix: '.ecl',
+	ignoreCase: true,
+
+	brackets: [
+		{ open: '{', close: '}', token: 'delimiter.curly' },
+		{ open: '[', close: ']', token: 'delimiter.square' },
+		{ open: '(', close: ')', token: 'delimiter.parenthesis' },
+		{ open: '<', close: '>', token: 'delimiter.angle' }
+	],
+
+	pounds: [
+		'append',
+		'break',
+		'declare',
+		'demangle',
+		'end',
+		'for',
+		'getdatatype',
+		'if',
+		'inmodule',
+		'loop',
+		'mangle',
+		'onwarning',
+		'option',
+		'set',
+		'stored',
+		'uniquename'
+	].join('|'),
+
+	keywords: [
+		'__compressed__',
+		'after',
+		'all',
+		'and',
+		'any',
+		'as',
+		'atmost',
+		'before',
+		'beginc',
+		'best',
+		'between',
+		'case',
+		'cluster',
+		'compressed',
+		'compression',
+		'const',
+		'counter',
+		'csv',
+		'default',
+		'descend',
+		'embed',
+		'encoding',
+		'encrypt',
+		'end',
+		'endc',
+		'endembed',
+		'endmacro',
+		'enum',
+		'escape',
+		'except',
+		'exclusive',
+		'expire',
+		'export',
+		'extend',
+		'fail',
+		'few',
+		'fileposition',
+		'first',
+		'flat',
+		'forward',
+		'from',
+		'full',
+		'function',
+		'functionmacro',
+		'group',
+		'grouped',
+		'heading',
+		'hole',
+		'ifblock',
+		'import',
+		'in',
+		'inner',
+		'interface',
+		'internal',
+		'joined',
+		'keep',
+		'keyed',
+		'last',
+		'left',
+		'limit',
+		'linkcounted',
+		'literal',
+		'little_endian',
+		'load',
+		'local',
+		'locale',
+		'lookup',
+		'lzw',
+		'macro',
+		'many',
+		'maxcount',
+		'maxlength',
+		'min skew',
+		'module',
+		'mofn',
+		'multiple',
+		'named',
+		'namespace',
+		'nocase',
+		'noroot',
+		'noscan',
+		'nosort',
+		'not',
+		'noxpath',
+		'of',
+		'onfail',
+		'only',
+		'opt',
+		'or',
+		'outer',
+		'overwrite',
+		'packed',
+		'partition',
+		'penalty',
+		'physicallength',
+		'pipe',
+		'prefetch',
+		'quote',
+		'record',
+		'repeat',
+		'retry',
+		'return',
+		'right',
+		'right1',
+		'right2',
+		'rows',
+		'rowset',
+		'scan',
+		'scope',
+		'self',
+		'separator',
+		'service',
+		'shared',
+		'skew',
+		'skip',
+		'smart',
+		'soapaction',
+		'sql',
+		'stable',
+		'store',
+		'terminator',
+		'thor',
+		'threshold',
+		'timelimit',
+		'timeout',
+		'token',
+		'transform',
+		'trim',
+		'type',
+		'unicodeorder',
+		'unordered',
+		'unsorted',
+		'unstable',
+		'update',
+		'use',
+		'validate',
+		'virtual',
+		'whole',
+		'width',
+		'wild',
+		'within',
+		'wnotrim',
+		'xml',
+		'xpath'
+	],
+
+	functions: [
+		'abs',
+		'acos',
+		'aggregate',
+		'allnodes',
+		'apply',
+		'ascii',
+		'asin',
+		'assert',
+		'asstring',
+		'atan',
+		'atan2',
+		'ave',
+		'build',
+		'buildindex',
+		'case',
+		'catch',
+		'choose',
+		'choosen',
+		'choosesets',
+		'clustersize',
+		'combine',
+		'correlation',
+		'cos',
+		'cosh',
+		'count',
+		'covariance',
+		'cron',
+		'dataset',
+		'dedup',
+		'define',
+		'denormalize',
+		'dictionary',
+		'distribute',
+		'distributed',
+		'distribution',
+		'ebcdic',
+		'enth',
+		'error',
+		'evaluate',
+		'event',
+		'eventextra',
+		'eventname',
+		'exists',
+		'exp',
+		'fail',
+		'failcode',
+		'failmessage',
+		'fetch',
+		'fromunicode',
+		'fromxml',
+		'getenv',
+		'getisvalid',
+		'global',
+		'graph',
+		'group',
+		'hash',
+		'hash32',
+		'hash64',
+		'hashcrc',
+		'hashmd5',
+		'having',
+		'httpcall',
+		'httpheader',
+		'if',
+		'iff',
+		'index',
+		'intformat',
+		'isvalid',
+		'iterate',
+		'join',
+		'keydiff',
+		'keypatch',
+		'keyunicode',
+		'length',
+		'library',
+		'limit',
+		'ln',
+		'loadxml',
+		'local',
+		'log',
+		'loop',
+		'map',
+		'matched',
+		'matchlength',
+		'matchposition',
+		'matchtext',
+		'matchunicode',
+		'max',
+		'merge',
+		'mergejoin',
+		'min',
+		'nofold',
+		'nolocal',
+		'nonempty',
+		'normalize',
+		'nothor',
+		'notify',
+		'output',
+		'parallel',
+		'parse',
+		'pipe',
+		'power',
+		'preload',
+		'process',
+		'project',
+		'pull',
+		'random',
+		'range',
+		'rank',
+		'ranked',
+		'realformat',
+		'recordof',
+		'regexfind',
+		'regexreplace',
+		'regroup',
+		'rejected',
+		'rollup',
+		'round',
+		'roundup',
+		'row',
+		'rowdiff',
+		'sample',
+		'sequential',
+		'set',
+		'sin',
+		'sinh',
+		'sizeof',
+		'soapcall',
+		'sort',
+		'sorted',
+		'sqrt',
+		'stepped',
+		'stored',
+		'sum',
+		'table',
+		'tan',
+		'tanh',
+		'thisnode',
+		'topn',
+		'tounicode',
+		'toxml',
+		'transfer',
+		'transform',
+		'trim',
+		'truncate',
+		'typeof',
+		'ungroup',
+		'unicodeorder',
+		'variance',
+		'wait',
+		'which',
+		'workunit',
+		'xmldecode',
+		'xmlencode',
+		'xmltext',
+		'xmlunicode'
+	],
+
+	typesint: ['integer', 'unsigned'].join('|'),
+
+	typesnum: ['data', 'qstring', 'string', 'unicode', 'utf8', 'varstring', 'varunicode'],
+
+	typesone: [
+		'ascii',
+		'big_endian',
+		'boolean',
+		'data',
+		'decimal',
+		'ebcdic',
+		'grouped',
+		'integer',
+		'linkcounted',
+		'pattern',
+		'qstring',
+		'real',
+		'record',
+		'rule',
+		'set of',
+		'streamed',
+		'string',
+		'token',
+		'udecimal',
+		'unicode',
+		'unsigned',
+		'utf8',
+		'varstring',
+		'varunicode'
+	].join('|'),
+
+	operators: ['+', '-', '/', ':=', '<', '<>', '=', '>', '\\', 'and', 'in', 'not', 'or'],
+
+	symbols: /[=><!~?:&|+\-*\/\^%]+/,
+
+	// escape sequences
+	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: [
+			[/@typesint[4|8]/, 'type'],
+			[/#(@pounds)/, 'type'],
+			[/@typesone/, 'type'],
+
+			[
+				/[a-zA-Z_$][\w-$]*/,
+				{
+					cases: {
+						'@functions': 'keyword.function',
+						'@keywords': 'keyword',
+						'@operators': 'operator'
+					}
+				}
+			],
+
+			// whitespace
+			{ include: '@whitespace' },
+
+			[/[{}()\[\]]/, '@brackets'],
+			[/[<>](?!@symbols)/, '@brackets'],
+			[
+				/@symbols/,
+				{
+					cases: {
+						'@operators': 'delimiter',
+						'@default': ''
+					}
+				}
+			],
+
+			// numbers
+			[/[0-9_]*\.[0-9_]+([eE][\-+]?\d+)?/, 'number.float'],
+			[/0[xX][0-9a-fA-F_]+/, 'number.hex'],
+			[/0[bB][01]+/, 'number.hex'], // binary: use same theme style as hex
+			[/[0-9_]+/, 'number'],
+
+			// delimiter: after number because of .\d floats
+			[/[;,.]/, 'delimiter'],
+
+			// strings
+			[/"([^"\\]|\\.)*$/, 'string.invalid'],
+			[/"/, 'string', '@string'],
+
+			// characters
+			[/'[^\\']'/, 'string'],
+			[/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
+			[/'/, 'string.invalid']
+		],
+
+		whitespace: [
+			[/[ \t\v\f\r\n]+/, ''],
+			[/\/\*/, 'comment', '@comment'],
+			[/\/\/.*$/, 'comment']
+		],
+
+		comment: [
+			[/[^\/*]+/, 'comment'],
+			[/\*\//, 'comment', '@pop'],
+			[/[\/*]/, 'comment']
+		],
+
+		string: [
+			[/[^\\']+/, 'string'],
+			[/@escapes/, 'string.escape'],
+			[/\\./, 'string.escape.invalid'],
+			[/'/, 'string', '@pop']
+		]
+	}
+};

+ 29 - 0
src/hcl/hcl.test.ts

@@ -992,6 +992,35 @@ testTokenization('hcl', [
 		}
 	],
 	/*
+      foo = <<-EOF
+      bar
+      EOF
+    */
+	[
+		{
+			line: '  foo = <<-EOF',
+			tokens: [
+				{ startIndex: 0, type: '' },
+				{ startIndex: 2, type: 'variable.hcl' },
+				{ startIndex: 5, type: '' },
+				{ startIndex: 6, type: 'operator.hcl' },
+				{ startIndex: 7, type: '' },
+				{ startIndex: 8, type: 'string.heredoc.delimiter.hcl' }
+			]
+		},
+		{
+			line: '  bar',
+			tokens: [{ startIndex: 0, type: 'string.heredoc.hcl' }]
+		},
+		{
+			line: '  EOF',
+			tokens: [
+				{ startIndex: 0, type: 'string.heredoc.hcl' },
+				{ startIndex: 2, type: 'string.heredoc.delimiter.hcl' }
+			]
+		}
+	],
+	/*
     foo = <<EOF
     bar
     EOF

+ 1 - 1
src/hcl/hcl.ts

@@ -143,7 +143,7 @@ export const language = <languages.IMonarchLanguage>{
 		],
 		heredocBody: [
 			[
-				/^([\w\-]+)$/,
+				/([\w\-]+)$/,
 				{
 					cases: {
 						'$1==$S2': [

+ 13 - 0
src/m3/m3.contribution.ts

@@ -0,0 +1,13 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { registerLanguage } from '../_.contribution';
+
+registerLanguage({
+	id: 'm3',
+	extensions: ['.m3', '.i3', '.mg', '.ig'],
+	aliases: ['Modula-3', 'Modula3', 'modula3', 'm3'],
+	loader: () => import('./m3')
+});

+ 119 - 0
src/m3/m3.test.ts

@@ -0,0 +1,119 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { testTokenization } from '../test/testRunner';
+
+testTokenization('m3', [
+	[
+		{
+			line: '(**)',
+			tokens: [{ startIndex: 0, type: 'comment.m3' }]
+		}
+	],
+
+	[
+		{
+			line: '    (* a comment *)',
+			tokens: [
+				{ startIndex: 0, type: 'white.m3' },
+				{ startIndex: 4, type: 'comment.m3' }
+			]
+		}
+	],
+
+	[
+		{
+			line: '(* Lorem ipsum dolor sit amet, consectetur ',
+			tokens: [{ startIndex: 0, type: 'comment.m3' }]
+		},
+		{
+			line: '   adipiscing elit, sed do eiusmod tempor',
+			tokens: [{ startIndex: 0, type: 'comment.m3' }]
+		},
+		{
+			line: '  incididunt ut labore et dolore magna aliqua. *)',
+			tokens: [{ startIndex: 0, type: 'comment.m3' }]
+		}
+	],
+
+	[
+		{
+			line: '(* Lorem ipsum dolor sit amet (*, consectetur ',
+			tokens: [{ startIndex: 0, type: 'comment.m3' }]
+		},
+		{
+			line: '   adipiscing elit, sed do eiusmod tempor',
+			tokens: [{ startIndex: 0, type: 'comment.m3' }]
+		},
+		{
+			line: '  incididunt*) ut labore et dolore magna aliqua. *)',
+			tokens: [{ startIndex: 0, type: 'comment.m3' }]
+		}
+	],
+
+	[
+		{
+			line: 'MODULE Test EXPORTS Main; FROM IO IMPORT Put; BEGIN Put("test\\n") END Test.',
+			tokens: [
+				{ startIndex: 0, type: 'keyword.MODULE.m3' },
+				{ startIndex: 6, type: 'white.m3' },
+				{ startIndex: 7, type: 'identifier.m3' },
+				{ startIndex: 11, type: 'white.m3' },
+				{ startIndex: 12, type: 'keyword.EXPORTS.m3' },
+				{ startIndex: 19, type: 'white.m3' },
+				{ startIndex: 20, type: 'identifier.m3' },
+				{ startIndex: 24, type: 'delimiter.m3' },
+				{ startIndex: 25, type: 'white.m3' },
+
+				{ startIndex: 26, type: 'keyword.FROM.m3' },
+				{ startIndex: 30, type: 'white.m3' },
+				{ startIndex: 31, type: 'identifier.m3' },
+				{ startIndex: 33, type: 'white.m3' },
+				{ startIndex: 34, type: 'keyword.IMPORT.m3' },
+				{ startIndex: 40, type: 'white.m3' },
+				{ startIndex: 41, type: 'identifier.m3' },
+				{ startIndex: 44, type: 'delimiter.m3' },
+				{ startIndex: 45, type: 'white.m3' },
+
+				{ startIndex: 46, type: 'keyword.BEGIN.m3' },
+				{ startIndex: 51, type: 'white.m3' },
+				{ startIndex: 52, type: 'identifier.m3' },
+				{ startIndex: 55, type: 'delimiter.parenthesis.m3' },
+				{ startIndex: 56, type: 'string.text.m3' },
+				{ startIndex: 61, type: 'string.escape.m3' },
+				{ startIndex: 63, type: 'string.text.m3' },
+				{ startIndex: 64, type: 'delimiter.parenthesis.m3' },
+				{ startIndex: 65, type: 'white.m3' },
+
+				{ startIndex: 66, type: 'keyword.END.m3' },
+				{ startIndex: 69, type: 'white.m3' },
+				{ startIndex: 70, type: 'identifier.m3' },
+				{ startIndex: 74, type: 'operators.m3' }
+			]
+		}
+	],
+
+	[
+		{
+			line: '0',
+			tokens: [{ startIndex: 0, type: 'number.m3' }]
+		}
+	],
+	[
+		{
+			line: '-16_B33f',
+			tokens: [
+				{ startIndex: 0, type: 'operators.m3' },
+				{ startIndex: 1, type: 'number.m3' }
+			]
+		}
+	],
+	[
+		{
+			line: '2.0D-5',
+			tokens: [{ startIndex: 0, type: 'number.float.m3' }]
+		}
+	]
+]);

+ 226 - 0
src/m3/m3.ts

@@ -0,0 +1,226 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import type { languages } from '../fillers/monaco-editor-core';
+
+export const conf: languages.LanguageConfiguration = {
+	comments: {
+		blockComment: ['(*', '*)']
+	},
+	brackets: [
+		['{', '}'],
+		['[', ']'],
+		['(', ')']
+	],
+	autoClosingPairs: [
+		{ open: '[', close: ']' },
+		{ open: '{', close: '}' },
+		{ open: '(', close: ')' },
+		{ open: '(*', close: '*)' },
+		{ open: '<*', close: '*>' },
+		{ open: "'", close: "'", notIn: ['string', 'comment'] },
+		{ open: '"', close: '"', notIn: ['string', 'comment'] }
+	]
+};
+
+export const language = <languages.IMonarchLanguage>{
+	defaultToken: '',
+	tokenPostfix: '.m3',
+
+	brackets: [
+		{ token: 'delimiter.curly', open: '{', close: '}' },
+		{ token: 'delimiter.parenthesis', open: '(', close: ')' },
+		{ token: 'delimiter.square', open: '[', close: ']' }
+	],
+	keywords: [
+		'AND',
+		'ANY',
+		'ARRAY',
+		'AS',
+		'BEGIN',
+		'BITS',
+		'BRANDED',
+		'BY',
+		'CASE',
+		'CONST',
+		'DIV',
+		'DO',
+		'ELSE',
+		'ELSIF',
+		'END',
+		'EVAL',
+		'EXCEPT',
+		'EXCEPTION',
+		'EXIT',
+		'EXPORTS',
+		'FINALLY',
+		'FOR',
+		'FROM',
+		'GENERIC',
+		'IF',
+		'IMPORT',
+		'IN',
+		'INTERFACE',
+		'LOCK',
+		'LOOP',
+		'METHODS',
+		'MOD',
+		'MODULE',
+		'NOT',
+		'OBJECT',
+		'OF',
+		'OR',
+		'OVERRIDES',
+		'PROCEDURE',
+		'RAISE',
+		'RAISES',
+		'READONLY',
+		'RECORD',
+		'REF',
+		'REPEAT',
+		'RETURN',
+		'REVEAL',
+		'SET',
+		'THEN',
+		'TO',
+		'TRY',
+		'TYPE',
+		'TYPECASE',
+		'UNSAFE',
+		'UNTIL',
+		'UNTRACED',
+		'VALUE',
+		'VAR',
+		'WHILE',
+		'WITH'
+	],
+	reservedConstNames: [
+		'ABS',
+		'ADR',
+		'ADRSIZE',
+		'BITSIZE',
+		'BYTESIZE',
+		'CEILING',
+		'DEC',
+		'DISPOSE',
+		'FALSE',
+		'FIRST',
+		'FLOAT',
+		'FLOOR',
+		'INC',
+		'ISTYPE',
+		'LAST',
+		'LOOPHOLE',
+		'MAX',
+		'MIN',
+		'NARROW',
+		'NEW',
+		'NIL',
+		'NUMBER',
+		'ORD',
+		'ROUND',
+		'SUBARRAY',
+		'TRUE',
+		'TRUNC',
+		'TYPECODE',
+		'VAL'
+	],
+	reservedTypeNames: [
+		'ADDRESS',
+		'ANY',
+		'BOOLEAN',
+		'CARDINAL',
+		'CHAR',
+		'EXTENDED',
+		'INTEGER',
+		'LONGCARD',
+		'LONGINT',
+		'LONGREAL',
+		'MUTEX',
+		'NULL',
+		'REAL',
+		'REFANY',
+		'ROOT',
+		'TEXT'
+	],
+	operators: ['+', '-', '*', '/', '&', '^', '.'],
+	relations: ['=', '#', '<', '<=', '>', '>=', '<:', ':'],
+	delimiters: ['|', '..', '=>', ',', ';', ':='],
+	symbols: /[>=<#.,:;+\-*/&^]+/,
+	escapes: /\\(?:[\\fnrt"']|[0-7]{3})/,
+
+	tokenizer: {
+		root: [
+			// Identifiers and keywords
+			[/_\w*/, 'invalid'],
+			[
+				/[a-zA-Z][a-zA-Z0-9_]*/,
+				{
+					cases: {
+						'@keywords': { token: 'keyword.$0' },
+						'@reservedConstNames': { token: 'constant.reserved.$0' },
+						'@reservedTypeNames': { token: 'type.reserved.$0' },
+						'@default': 'identifier'
+					}
+				}
+			],
+
+			// Whitespace
+			{ include: '@whitespace' },
+			[/[{}()\[\]]/, '@brackets'],
+
+			// Integer- and real literals
+			[/[0-9]+\.[0-9]+(?:[DdEeXx][\+\-]?[0-9]+)?/, 'number.float'],
+			[/[0-9]+(?:\_[0-9a-fA-F]+)?L?/, 'number'],
+
+			// Operators, relations, and delimiters
+			[
+				/@symbols/,
+				{
+					cases: {
+						'@operators': 'operators',
+						'@relations': 'operators',
+						'@delimiters': 'delimiter',
+						'@default': 'invalid'
+					}
+				}
+			],
+
+			// Character literals
+			[/'[^\\']'/, 'string.char'],
+			[/(')(@escapes)(')/, ['string.char', 'string.escape', 'string.char']],
+			[/'/, 'invalid'],
+
+			// Text literals
+			[/"([^"\\]|\\.)*$/, 'invalid'],
+			[/"/, 'string.text', '@text']
+		],
+
+		text: [
+			[/[^\\"]+/, 'string.text'],
+			[/@escapes/, 'string.escape'],
+			[/\\./, 'invalid'],
+			[/"/, 'string.text', '@pop']
+		],
+
+		comment: [
+			[/\(\*/, 'comment', '@push'],
+			[/\*\)/, 'comment', '@pop'],
+			[/./, 'comment']
+		],
+
+		pragma: [
+			[/<\*/, 'keyword.pragma', '@push'],
+			[/\*>/, 'keyword.pragma', '@pop'],
+			[/./, 'keyword.pragma']
+		],
+
+		whitespace: [
+			[/[ \t\r\n]+/, 'white'],
+			[/\(\*/, 'comment', '@comment'],
+			[/<\*/, 'keyword.pragma', '@pragma']
+		]
+	}
+};

+ 2 - 0
src/monaco.contribution.ts

@@ -16,6 +16,7 @@ import './csp/csp.contribution';
 import './css/css.contribution';
 import './dart/dart.contribution';
 import './dockerfile/dockerfile.contribution';
+import './ecl/ecl.contribution';
 import './fsharp/fsharp.contribution';
 import './go/go.contribution';
 import './graphql/graphql.contribution';
@@ -30,6 +31,7 @@ import './kotlin/kotlin.contribution';
 import './less/less.contribution';
 import './lexon/lexon.contribution';
 import './lua/lua.contribution';
+import './m3/m3.contribution';
 import './markdown/markdown.contribution';
 import './mips/mips.contribution';
 import './msdax/msdax.contribution';