瀏覽代碼

Merge pull request #142 from anjbur/qsharp

Add support for Q#
Alexandru Dima 4 年之前
父節點
當前提交
772a333a1b
共有 4 個文件被更改,包括 482 次插入0 次删除
  1. 1 0
      src/monaco.contribution.ts
  2. 13 0
      src/qsharp/qsharp.contribution.ts
  3. 162 0
      src/qsharp/qsharp.test.ts
  4. 306 0
      src/qsharp/qsharp.ts

+ 1 - 0
src/monaco.contribution.ts

@@ -50,6 +50,7 @@ import './powerquery/powerquery.contribution';
 import './powershell/powershell.contribution';
 import './pug/pug.contribution';
 import './python/python.contribution';
+import './qsharp/qsharp.contribution';
 import './r/r.contribution';
 import './razor/razor.contribution';
 import './redis/redis.contribution';

+ 13 - 0
src/qsharp/qsharp.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: 'qsharp',
+	extensions: ['.qs'],
+	aliases: ['Q#', 'qsharp'],
+	loader: () => import('./qsharp')
+});

+ 162 - 0
src/qsharp/qsharp.test.ts

@@ -0,0 +1,162 @@
+/*---------------------------------------------------------------------------------------------
+ *  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('qsharp', [
+	// Generated from sample: https://github.com/microsoft/Quantum/blob/main/samples/azure-quantum/parallel-qrng/ParallelQrng.ipynb
+	[
+		{
+			line: 'open Microsoft.Quantum.Arrays;',
+			tokens: [
+				{ startIndex: 0, type: 'keyword.open.qsharp' },
+				{ startIndex: 4, type: 'white.qsharp' },
+				{ startIndex: 5, type: 'namespace.qsharp' },
+				{ startIndex: 14, type: 'delimiter.qsharp' },
+				{ startIndex: 15, type: 'namespace.qsharp' },
+				{ startIndex: 22, type: 'delimiter.qsharp' },
+				{ startIndex: 23, type: 'namespace.qsharp' },
+				{ startIndex: 29, type: 'delimiter.qsharp' }
+			]
+		},
+		{
+			line: 'open Microsoft.Quantum.Measurement;',
+			tokens: [
+				{ startIndex: 0, type: 'keyword.open.qsharp' },
+				{ startIndex: 4, type: 'white.qsharp' },
+				{ startIndex: 5, type: 'namespace.qsharp' },
+				{ startIndex: 14, type: 'delimiter.qsharp' },
+				{ startIndex: 15, type: 'namespace.qsharp' },
+				{ startIndex: 22, type: 'delimiter.qsharp' },
+				{ startIndex: 23, type: 'namespace.qsharp' },
+				{ startIndex: 34, type: 'delimiter.qsharp' }
+			]
+		},
+		{
+			line: '',
+			tokens: []
+		},
+		{
+			line: 'operation SampleRandomNumber(nQubits : Int) : Result[] {',
+			tokens: [
+				{ startIndex: 0, type: 'keyword.qsharp' },
+				{ startIndex: 9, type: 'white.qsharp' },
+				{ startIndex: 10, type: 'identifier.qsharp' },
+				{ startIndex: 28, type: 'delimiter.parenthesis.qsharp' },
+				{ startIndex: 29, type: 'identifier.qsharp' },
+				{ startIndex: 36, type: 'white.qsharp' },
+				{ startIndex: 37, type: 'operator.qsharp' },
+				{ startIndex: 38, type: 'white.qsharp' },
+				{ startIndex: 39, type: 'type.qsharp' },
+				{ startIndex: 42, type: 'delimiter.parenthesis.qsharp' },
+				{ startIndex: 43, type: 'white.qsharp' },
+				{ startIndex: 44, type: 'operator.qsharp' },
+				{ startIndex: 45, type: 'white.qsharp' },
+				{ startIndex: 46, type: 'type.qsharp' },
+				{ startIndex: 52, type: 'delimiter.square.qsharp' },
+				{ startIndex: 54, type: 'white.qsharp' },
+				{ startIndex: 55, type: 'delimiter.curly.qsharp' }
+			]
+		},
+		{
+			line: '	// We prepare a register of qubits in a uniform',
+			tokens: [
+				{ startIndex: 0, type: 'white.qsharp' },
+				{ startIndex: 1, type: 'comment.qsharp' }
+			]
+		},
+		{
+			line: '	// superposition state, such that when we measure,',
+			tokens: [
+				{ startIndex: 0, type: 'white.qsharp' },
+				{ startIndex: 1, type: 'comment.qsharp' }
+			]
+		},
+		{
+			line: '	// all bitstrings occur with equal probability.',
+			tokens: [
+				{ startIndex: 0, type: 'white.qsharp' },
+				{ startIndex: 1, type: 'comment.qsharp' }
+			]
+		},
+		{
+			line: '	use register = Qubit[nQubits] {',
+			tokens: [
+				{ startIndex: 0, type: 'white.qsharp' },
+				{ startIndex: 1, type: 'keyword.qsharp' },
+				{ startIndex: 4, type: 'white.qsharp' },
+				{ startIndex: 5, type: 'identifier.qsharp' },
+				{ startIndex: 13, type: 'white.qsharp' },
+				{ startIndex: 14, type: 'operator.qsharp' },
+				{ startIndex: 15, type: 'white.qsharp' },
+				{ startIndex: 16, type: 'type.qsharp' },
+				{ startIndex: 21, type: 'delimiter.square.qsharp' },
+				{ startIndex: 22, type: 'identifier.qsharp' },
+				{ startIndex: 29, type: 'delimiter.square.qsharp' },
+				{ startIndex: 30, type: 'white.qsharp' },
+				{ startIndex: 31, type: 'delimiter.curly.qsharp' }
+			]
+		},
+		{
+			line: '		// Set qubits in superposition.',
+			tokens: [
+				{ startIndex: 0, type: 'white.qsharp' },
+				{ startIndex: 2, type: 'comment.qsharp' }
+			]
+		},
+		{
+			line: '		ApplyToEachA(H, register);',
+			tokens: [
+				{ startIndex: 0, type: 'white.qsharp' },
+				{ startIndex: 2, type: 'identifier.qsharp' },
+				{ startIndex: 14, type: 'delimiter.parenthesis.qsharp' },
+				{ startIndex: 15, type: 'keyword.qsharp' },
+				{ startIndex: 16, type: 'delimiter.qsharp' },
+				{ startIndex: 17, type: 'white.qsharp' },
+				{ startIndex: 18, type: 'identifier.qsharp' },
+				{ startIndex: 26, type: 'delimiter.parenthesis.qsharp' },
+				{ startIndex: 27, type: 'delimiter.qsharp' }
+			]
+		},
+		{
+			line: '',
+			tokens: []
+		},
+		{
+			line: '		// Measure all qubits and return.',
+			tokens: [
+				{ startIndex: 0, type: 'white.qsharp' },
+				{ startIndex: 2, type: 'comment.qsharp' }
+			]
+		},
+		{
+			line: '		return ForEach(MResetZ, register);',
+			tokens: [
+				{ startIndex: 0, type: 'white.qsharp' },
+				{ startIndex: 2, type: 'keyword.qsharp' },
+				{ startIndex: 8, type: 'white.qsharp' },
+				{ startIndex: 9, type: 'identifier.qsharp' },
+				{ startIndex: 16, type: 'delimiter.parenthesis.qsharp' },
+				{ startIndex: 17, type: 'identifier.qsharp' },
+				{ startIndex: 24, type: 'delimiter.qsharp' },
+				{ startIndex: 25, type: 'white.qsharp' },
+				{ startIndex: 26, type: 'identifier.qsharp' },
+				{ startIndex: 34, type: 'delimiter.parenthesis.qsharp' },
+				{ startIndex: 35, type: 'delimiter.qsharp' }
+			]
+		},
+		{
+			line: '	}',
+			tokens: [
+				{ startIndex: 0, type: 'white.qsharp' },
+				{ startIndex: 1, type: 'delimiter.curly.qsharp' }
+			]
+		},
+		{
+			line: '}',
+			tokens: [{ startIndex: 0, type: 'delimiter.curly.qsharp' }]
+		}
+	]
+]);

+ 306 - 0
src/qsharp/qsharp.ts

@@ -0,0 +1,306 @@
+/*---------------------------------------------------------------------------------------------
+ *  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: '//'
+	},
+	brackets: [
+		['{', '}'],
+		['[', ']'],
+		['(', ')']
+	],
+	autoClosingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '"', close: '"', notIn: ['string', 'comment'] }
+	],
+	surroundingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '"', close: '"' }
+	]
+};
+
+export const language = <languages.IMonarchLanguage>{
+	// Set defaultToken to invalid to see what you do not tokenize yet
+	keywords: [
+		'namespace',
+		'open',
+		'as',
+		'operation',
+		'function',
+		'body',
+		'adjoint',
+		'newtype',
+		'controlled',
+		'if',
+		'elif',
+		'else',
+		'repeat',
+		'until',
+		'fixup',
+		'for',
+		'in',
+		'while',
+		'return',
+		'fail',
+		'within',
+		'apply',
+		'Adjoint',
+		'Controlled',
+		'Adj',
+		'Ctl',
+		'is',
+		'self',
+		'auto',
+		'distribute',
+		'invert',
+		'intrinsic',
+		'let',
+		'set',
+		'w/',
+		'new',
+		'not',
+		'and',
+		'or',
+		'use',
+		'borrow',
+		'using',
+		'borrowing',
+		'mutable'
+	],
+
+	typeKeywords: [
+		'Unit',
+		'Int',
+		'BigInt',
+		'Double',
+		'Bool',
+		'String',
+		'Qubit',
+		'Result',
+		'Pauli',
+		'Range'
+	],
+
+	invalidKeywords: [
+		'abstract',
+		'base',
+		'bool',
+		'break',
+		'byte',
+		'case',
+		'catch',
+		'char',
+		'checked',
+		'class',
+		'const',
+		'continue',
+		'decimal',
+		'default',
+		'delegate',
+		'do',
+		'double',
+		'enum',
+		'event',
+		'explicit',
+		'extern',
+		'finally',
+		'fixed',
+		'float',
+		'foreach',
+		'goto',
+		'implicit',
+		'int',
+		'interface',
+		'lock',
+		'long',
+		'null',
+		'object',
+		'operator',
+		'out',
+		'override',
+		'params',
+		'private',
+		'protected',
+		'public',
+		'readonly',
+		'ref',
+		'sbyte',
+		'sealed',
+		'short',
+		'sizeof',
+		'stackalloc',
+		'static',
+		'string',
+		'struct',
+		'switch',
+		'this',
+		'throw',
+		'try',
+		'typeof',
+		'unit',
+		'ulong',
+		'unchecked',
+		'unsafe',
+		'ushort',
+		'virtual',
+		'void',
+		'volatile'
+	],
+
+	constants: ['true', 'false', 'PauliI', 'PauliX', 'PauliY', 'PauliZ', 'One', 'Zero'],
+
+	builtin: [
+		'X',
+		'Y',
+		'Z',
+		'H',
+		'HY',
+		'S',
+		'T',
+		'SWAP',
+		'CNOT',
+		'CCNOT',
+		'MultiX',
+		'R',
+		'RFrac',
+		'Rx',
+		'Ry',
+		'Rz',
+		'R1',
+		'R1Frac',
+		'Exp',
+		'ExpFrac',
+		'Measure',
+		'M',
+		'MultiM',
+		'Message',
+		'Length',
+		'Assert',
+		'AssertProb',
+		'AssertEqual'
+	],
+
+	operators: [
+		'and=',
+		'<-',
+		'->',
+		'*',
+		'*=',
+		'@',
+		'!',
+		'^',
+		'^=',
+		':',
+		'::',
+		'..',
+		'==',
+		'...',
+		'=',
+		'=>',
+		'>',
+		'>=',
+		'<',
+		'<=',
+		'-',
+		'-=',
+		'!=',
+		'or=',
+		'%',
+		'%=',
+		'|',
+		'+',
+		'+=',
+		'?',
+		'/',
+		'/=',
+		'&&&',
+		'&&&=',
+		'^^^',
+		'^^^=',
+		'>>>',
+		'>>>=',
+		'<<<',
+		'<<<=',
+		'|||',
+		'|||=',
+		'~~~',
+		'_',
+		'w/',
+		'w/='
+	],
+
+	namespaceFollows: ['namespace', 'open'],
+
+	symbols: /[=><!~?:&|+\-*\/\^%@._]+/,
+
+	escapes: /\\[\s\S]/,
+
+	// The main tokenizer for our languages
+	tokenizer: {
+		root: [
+			// identifiers and keywords
+			[
+				/[a-zA-Z_$][\w$]*/,
+				{
+					cases: {
+						'@namespaceFollows': {
+							token: 'keyword.$0',
+							next: '@namespace'
+						},
+						'@typeKeywords': 'type',
+						'@keywords': 'keyword',
+						'@constants': 'constant',
+						'@builtin': 'keyword',
+						'@invalidKeywords': 'invalid',
+						'@default': 'identifier'
+					}
+				}
+			],
+
+			// whitespace
+			{ include: '@whitespace' },
+
+			// delimiters and operators
+			[/[{}()\[\]]/, '@brackets'],
+			[/@symbols/, { cases: { '@operators': 'operator', '@default': '' } }],
+
+			// numbers
+			[/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
+			[/\d+/, 'number'],
+
+			// delimiter: after number because of .\d floats
+			[/[;,.]/, 'delimiter'],
+
+			// strings
+			//[/"([^"\\]|\\.)*$/, 'string.invalid' ],  // non-teminated string
+			[/"/, { token: 'string.quote', bracket: '@open', next: '@string' }]
+		],
+
+		string: [
+			[/[^\\"]+/, 'string'],
+			[/@escapes/, 'string.escape'],
+			[/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }]
+		],
+
+		namespace: [
+			{ include: '@whitespace' },
+			[/[A-Za-z]\w*/, 'namespace'],
+			[/[\.=]/, 'delimiter'],
+			['', '', '@pop']
+		],
+
+		whitespace: [
+			[/[ \t\r\n]+/, 'white'],
+			[/(\/\/).*/, 'comment']
+		]
+	}
+};