From 16850dd85ac8834857e0f7ed5f9a20221e89f377 Mon Sep 17 00:00:00 2001 From: "REDMOND\\anburton" Date: Fri, 25 Jun 2021 21:28:07 -0700 Subject: [PATCH 1/3] onboard qsharp --- src/monaco.contribution.ts | 1 + src/qsharp/qsharp.contribution.ts | 13 ++ src/qsharp/qsharp.test.ts | 10 ++ src/qsharp/qsharp.ts | 279 ++++++++++++++++++++++++++++++ 4 files changed, 303 insertions(+) create mode 100644 src/qsharp/qsharp.contribution.ts create mode 100644 src/qsharp/qsharp.test.ts create mode 100644 src/qsharp/qsharp.ts diff --git a/src/monaco.contribution.ts b/src/monaco.contribution.ts index 3a633c2f..7675f1c4 100644 --- a/src/monaco.contribution.ts +++ b/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'; diff --git a/src/qsharp/qsharp.contribution.ts b/src/qsharp/qsharp.contribution.ts new file mode 100644 index 00000000..09c59b38 --- /dev/null +++ b/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') +}); diff --git a/src/qsharp/qsharp.test.ts b/src/qsharp/qsharp.test.ts new file mode 100644 index 00000000..f24f344d --- /dev/null +++ b/src/qsharp/qsharp.test.ts @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * 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', [ + +]); diff --git a/src/qsharp/qsharp.ts b/src/qsharp/qsharp.ts new file mode 100644 index 00000000..f5c2eb32 --- /dev/null +++ b/src/qsharp/qsharp.ts @@ -0,0 +1,279 @@ +/*--------------------------------------------------------------------------------------------- + * 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 language = { + // Set defaultToken to invalid to see what you do not tokenize yet + defaultToken: 'invalid', + + 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/=' + ], + + symbols: /[=> Date: Tue, 29 Jun 2021 10:46:23 -0700 Subject: [PATCH 2/3] add language configuration --- src/qsharp/qsharp.ts | 210 +++++++++++++++++++++++-------------------- 1 file changed, 113 insertions(+), 97 deletions(-) diff --git a/src/qsharp/qsharp.ts b/src/qsharp/qsharp.ts index f5c2eb32..3093fef6 100644 --- a/src/qsharp/qsharp.ts +++ b/src/qsharp/qsharp.ts @@ -5,8 +5,30 @@ 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 = { +export const language = { // Set defaultToken to invalid to see what you do not tokenize yet defaultToken: 'invalid', @@ -45,7 +67,7 @@ export const language = { 'intrinsic', 'let', 'set', - 'w\/', + 'w/', 'new', 'not', 'and', @@ -55,7 +77,7 @@ export const language = { 'using', 'borrowing', 'mutable' - ], + ], typeKeywords: [ 'Unit', @@ -136,16 +158,7 @@ export const language = { 'volatile' ], - constants: [ - 'true', - 'false', - 'PauliI', - 'PauliX', - 'PauliY', - 'PauliZ', - 'One', - 'Zero' - ], + constants: ['true', 'false', 'PauliI', 'PauliX', 'PauliY', 'PauliZ', 'One', 'Zero'], builtin: [ 'X', @@ -179,101 +192,104 @@ export const language = { ], operators: [ - 'and=', - '<-', - '->', - '*', - '*=', - '@', - '!', - '^', - '^=', - ':', - '::', - '..', - '==', - '...', - '=', - '=>', - '>', - '>=', - '<', - '<=', - '-', - '-=', - '!=', - 'or=', - '%', - '%=', - '|', - '+', - '+=', - '?', - '/', - '/=', - '&&&', - '&&&=', - '^^^', - '^^^=', - '>>>', - '>>>=', - '<<<', - '<<<=', - '|||', - '|||=', - '~~~', - '_', - 'w/', - 'w/=' + 'and=', + '<-', + '->', + '*', + '*=', + '@', + '!', + '^', + '^=', + ':', + '::', + '..', + '==', + '...', + '=', + '=>', + '>', + '>=', + '<', + '<=', + '-', + '-=', + '!=', + 'or=', + '%', + '%=', + '|', + '+', + '+=', + '?', + '/', + '/=', + '&&&', + '&&&=', + '^^^', + '^^^=', + '>>>', + '>>>=', + '<<<', + '<<<=', + '|||', + '|||=', + '~~~', + '_', + 'w/', + 'w/=' ], - symbols: /[=> Date: Tue, 6 Jul 2021 11:45:52 -0700 Subject: [PATCH 3/3] initial test --- src/qsharp/qsharp.test.ts | 154 +++++++++++++++++++++++++++++++++++++- src/qsharp/qsharp.ts | 15 +++- 2 files changed, 166 insertions(+), 3 deletions(-) diff --git a/src/qsharp/qsharp.test.ts b/src/qsharp/qsharp.test.ts index f24f344d..c2889067 100644 --- a/src/qsharp/qsharp.test.ts +++ b/src/qsharp/qsharp.test.ts @@ -6,5 +6,157 @@ 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' }] + } + ] ]); diff --git a/src/qsharp/qsharp.ts b/src/qsharp/qsharp.ts index 3093fef6..f4141338 100644 --- a/src/qsharp/qsharp.ts +++ b/src/qsharp/qsharp.ts @@ -30,8 +30,6 @@ export const conf: languages.LanguageConfiguration = { export const language = { // Set defaultToken to invalid to see what you do not tokenize yet - defaultToken: 'invalid', - keywords: [ 'namespace', 'open', @@ -240,6 +238,8 @@ export const language = { 'w/=' ], + namespaceFollows: ['namespace', 'open'], + symbols: /[=>{ /[a-zA-Z_$][\w$]*/, { cases: { + '@namespaceFollows': { + token: 'keyword.$0', + next: '@namespace' + }, '@typeKeywords': 'type', '@keywords': 'keyword', '@constants': 'constant', @@ -287,6 +291,13 @@ export const language = { [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] ], + namespace: [ + { include: '@whitespace' }, + [/[A-Za-z]\w*/, 'namespace'], + [/[\.=]/, 'delimiter'], + ['', '', '@pop'] + ], + whitespace: [ [/[ \t\r\n]+/, 'white'], [/(\/\/).*/, 'comment']