فهرست منبع

add sophia syntax

Milen Radkov 6 سال پیش
والد
کامیت
987f04155a
6فایلهای تغییر یافته به همراه475 افزوده شده و 0 حذف شده
  1. 1 0
      scripts/bundle.js
  2. 1 0
      src/monaco.contribution.ts
  3. 14 0
      src/sophia/sophia.contribution.ts
  4. 281 0
      src/sophia/sophia.test.ts
  5. 177 0
      src/sophia/sophia.ts
  6. 1 0
      test/setup.js

+ 1 - 0
scripts/bundle.js

@@ -58,6 +58,7 @@ bundleOne('typescript/typescript');
 bundleOne('vb/vb');
 bundleOne('xml/xml');
 bundleOne('yaml/yaml');
+bundleOne('sophia/sophia');
 bundleOne('solidity/solidity');
 bundleOne('sb/sb');
 bundleOne('mysql/mysql');

+ 1 - 0
src/monaco.contribution.ts

@@ -41,6 +41,7 @@ import './ruby/ruby.contribution';
 import './rust/rust.contribution';
 import './sb/sb.contribution';
 import './scss/scss.contribution';
+import './sophia/sophia.contribution';
 import './solidity/solidity.contribution';
 import './sql/sql.contribution';
 import './st/st.contribution';

+ 14 - 0
src/sophia/sophia.contribution.ts

@@ -0,0 +1,14 @@
+/*---------------------------------------------------------------------------------------------
+ *  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: 'aes',
+	extensions: ['.aes'],
+	aliases: ['aes', 'sophia', 'Sophia'],
+	loader: () => import('./sophia')
+});

+ 281 - 0
src/sophia/sophia.test.ts

@@ -0,0 +1,281 @@
+/*---------------------------------------------------------------------------------------------
+ *  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('aes', [
+
+	// contract HackBG =
+	// 	record state = { developers : map(address, developer) }
+	// 	record developer = { name : string, experience : int, skillset : list(string) }
+	// 	entrypoint init() = { developers = {} }
+
+	[{
+		line: 'contract HackBG =',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.contract.aes' },
+			{ startIndex: 8, type: '' },
+			{ startIndex: 9, type: 'identifier.aes' },
+			{ startIndex: 15, type: '' },
+			{ startIndex: 16, type: 'delimiter.aes' },
+		]
+	}],
+
+	[{
+		line: 'record state = { developers : list(developer) }',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.record.aes' },
+			{ startIndex: 6, type: '' },
+			{ startIndex: 7, type: 'keyword.state.aes' },
+			{ startIndex: 12, type: '' },
+			{ startIndex: 13, type: 'delimiter.aes' },
+			{ startIndex: 14, type: '' },
+			{ startIndex: 15, type: 'delimiter.curly.aes' },
+			{ startIndex: 16, type: '' },
+			{ startIndex: 17, type: 'identifier.aes' },
+			{ startIndex: 27, type: '' },
+			{ startIndex: 28, type: 'delimiter.aes' },
+			{ startIndex: 29, type: '' },
+			{ startIndex: 30, type: 'keyword.list.aes' },
+			{ startIndex: 34, type: 'delimiter.parenthesis.aes' },
+			{ startIndex: 35, type: 'identifier.aes' },
+			{ startIndex: 44, type: 'delimiter.parenthesis.aes' },
+			{ startIndex: 45, type: '' },
+			{ startIndex: 46, type: 'delimiter.curly.aes' },
+		]
+	}],
+
+	[{
+		line: 'record developer = {',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.record.aes' },
+			{ startIndex: 6, type: '' },
+			{ startIndex: 7, type: 'identifier.aes' },
+			{ startIndex: 16, type: '' },
+			{ startIndex: 17, type: 'delimiter.aes' },
+			{ startIndex: 18, type: '' },
+			{ startIndex: 19, type: 'delimiter.curly.aes' }
+		]
+	}],
+
+	[{
+		line: 'name : string,',
+		tokens: [
+			{ startIndex: 0, type: 'identifier.aes' },
+			{ startIndex: 4, type: '' },
+			{ startIndex: 5, type: 'delimiter.aes' },
+			{ startIndex: 6, type: '' },
+			{ startIndex: 7, type: 'keyword.string.aes' },
+			{ startIndex: 13, type: 'delimiter.aes' }
+
+		]
+	}],
+
+	[{
+		line: 'experience : int,',
+		tokens: [
+			{ startIndex: 0, type: 'identifier.aes' },
+			{ startIndex: 10, type: '' },
+			{ startIndex: 11, type: 'delimiter.aes' },
+			{ startIndex: 12, type: '' },
+			{ startIndex: 13, type: 'keyword.int.aes' },
+			{ startIndex: 16, type: 'delimiter.aes' }
+
+		]
+	}],
+
+	[{
+		line: 'skillset : list(string) }',
+		tokens: [
+			{ startIndex: 0, type: 'identifier.aes' },
+			{ startIndex: 8, type: '' },
+			{ startIndex: 9, type: 'delimiter.aes' },
+			{ startIndex: 10, type: '' },
+			{ startIndex: 11, type: 'keyword.list.aes' },
+			{ startIndex: 15, type: 'delimiter.parenthesis.aes' },
+			{ startIndex: 16, type: 'keyword.string.aes' },
+			{ startIndex: 22, type: 'delimiter.parenthesis.aes' },
+			{ startIndex: 23, type: '' },
+			{ startIndex: 24, type: 'delimiter.curly.aes' },
+		]
+	}],
+
+	[{
+		line: 'entrypoint init() = { developers = {} }',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.entrypoint.aes' },
+			{ startIndex: 10, type: '' },
+			{ startIndex: 11, type: 'identifier.aes' },
+			{ startIndex: 15, type: 'delimiter.parenthesis.aes' },
+			{ startIndex: 17, type: '' },
+			{ startIndex: 18, type: 'delimiter.aes' },
+			{ startIndex: 19, type: '' },
+			{ startIndex: 20, type: 'delimiter.curly.aes' },
+			{ startIndex: 21, type: '' },
+			{ startIndex: 22, type: 'identifier.aes' },
+			{ startIndex: 32, type: '' },
+			{ startIndex: 33, type: 'delimiter.aes' },
+			{ startIndex: 34, type: '' },
+			{ startIndex: 35, type: 'delimiter.curly.aes' },
+			{ startIndex: 37, type: '' },
+			{ startIndex: 38, type: 'delimiter.curly.aes' }
+		]
+	}],
+
+	// Comments - single line
+	[{
+		line: '//',
+		tokens: [
+			{ startIndex: 0, type: 'comment.aes' }
+		]
+	}],
+
+	[{
+		line: '    // a comment',
+		tokens: [
+			{ startIndex: 0, type: '' },
+			{ startIndex: 4, type: 'comment.aes' }
+		]
+	}],
+
+	[{
+		line: '// a comment',
+		tokens: [
+			{ startIndex: 0, type: 'comment.aes' }
+		]
+	}],
+
+	[{
+		line: '//sticky comment',
+		tokens: [
+			{ startIndex: 0, type: 'comment.aes' }
+		]
+	}],
+
+	[{
+		line: '/almost a comment',
+		tokens: [
+			{ startIndex: 0, type: 'delimiter.aes' },
+			{ startIndex: 1, type: 'identifier.aes' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'identifier.aes' },
+			{ startIndex: 9, type: '' },
+			{ startIndex: 10, type: 'identifier.aes' }
+		]
+	}],
+
+	[{
+		line: '/* //*/ a',
+		tokens: [
+			{ startIndex: 0, type: 'comment.aes' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'identifier.aes' }
+		]
+	}],
+
+	[{
+		line: '1 / 2 /* comment',
+		tokens: [
+			{ startIndex: 0, type: 'number.aes' },
+			{ startIndex: 1, type: '' },
+			{ startIndex: 2, type: 'delimiter.aes' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'number.aes' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'comment.aes' }
+		]
+	}],
+
+	[{
+		line: 'let x : int = 1 // my comment // is a nice one',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.let.aes' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.aes' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.aes' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'keyword.int.aes' },
+			{ startIndex: 11, type: '' },
+			{ startIndex: 12, type: 'delimiter.aes' },
+			{ startIndex: 13, type: '' },
+			{ startIndex: 14, type: 'number.aes' },
+			{ startIndex: 15, type: '' },
+			{ startIndex: 16, type: 'comment.aes' }
+		]
+	}],
+
+	// Comments - range comment, single line
+	[{
+		line: '/* a simple comment */',
+		tokens: [
+			{ startIndex: 0, type: 'comment.aes' }
+		]
+	}],
+
+	[{
+		line: 'let x : int = /* a simple comment */ 1',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.let.aes' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.aes' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.aes' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'keyword.int.aes' },
+			{ startIndex: 11, type: '' },
+			{ startIndex: 12, type: 'delimiter.aes' },
+			{ startIndex: 13, type: '' },
+			{ startIndex: 14, type: 'comment.aes' },
+			{ startIndex: 36, type: '' },
+			{ startIndex: 37, type: 'number.aes' },
+		]
+	}],
+
+	[{
+		line: 'let x = /* comment */ 1 */',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.let.aes' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.aes' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.aes' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'comment.aes' },
+			{ startIndex: 21, type: '' },
+			{ startIndex: 22, type: 'number.aes' },
+			{ startIndex: 23, type: '' }
+		]
+	}],
+
+	[{
+		line: 'let x = /**/',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.let.aes' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.aes' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.aes' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'comment.aes' },
+		]
+	}],
+
+	[{
+		line: 'let x = /*/',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.let.aes' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.aes' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.aes' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'comment.aes' }
+		]
+	}],
+
+]);

+ 177 - 0
src/sophia/sophia.ts

@@ -0,0 +1,177 @@
+/*---------------------------------------------------------------------------------------------
+ *  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 = {
+	comments: {
+		lineComment: '//',
+		blockComment: ['/*', '*/'],
+	},
+	brackets: [['{', '}'], ['[', ']'], ['(', ')'], ['<', '>']],
+	autoClosingPairs: [
+		{ open: '"', close: '"', notIn: ['string', 'comment'] },
+		{ open: '{', close: '}', notIn: ['string', 'comment'] },
+		{ open: '[', close: ']', notIn: ['string', 'comment'] },
+		{ open: '(', close: ')', notIn: ['string', 'comment'] },
+	]
+};
+
+export const language = <ILanguage>{
+	defaultToken: '',
+	tokenPostfix: '.aes',
+
+	brackets: [
+		{ token: 'delimiter.curly', open: '{', close: '}' },
+		{ token: 'delimiter.parenthesis', open: '(', close: ')' },
+		{ token: 'delimiter.square', open: '[', close: ']' },
+		{ token: 'delimiter.angle', open: '<', close: '>' }
+	],
+
+	keywords: [
+		// Main keywords
+		'contract',
+		'library',
+		'entrypoint',
+		'function',
+		'stateful',
+		'state',
+		'hash',
+		'signature',
+		'tuple',
+		'list',
+		'address',
+		'string',
+		'bool',
+		'int',
+		'record',
+		'datatype',
+		'type',
+		'option',
+		'oracle',
+		'oracle_query',
+		'Call',
+		'Bits',
+		'Bytes',
+		'Oracle',
+		'String',
+		'Crypto',
+		'Address',
+		'Auth',
+		'Chain',
+		'bits',
+		'bytes',
+		'event',
+		'let',
+		'map',
+		'private',
+		'public',
+		'true',
+		'false',
+		'var',
+		'if',
+		'else',
+		'throw'
+	],
+
+	operators: [
+		'=', '>', '<', '!', '~', '?', '::', ':',
+		'==', '<=', '>=', '!=', '&&', '||', '++', '--',
+		'+', '-', '*', '/', '&', '|', '^', '%', '<<',
+		'>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=',
+		'^=', '%=', '<<=', '>>=', '>>>='
+	],
+
+	// 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})/,
+	integersuffix: /(ll|LL|u|U|l|L)?(ll|LL|u|U|l|L)?/,
+	floatsuffix: /[fFlL]?/,
+
+	// The main tokenizer for our languages
+	tokenizer: {
+		root: [
+			// identifiers and keywords
+			[/[a-zA-Z_]\w*/, {
+				cases: {
+					'@keywords': { token: 'keyword.$0' },
+					'@default': 'identifier'
+				}
+			}],
+
+			// whitespace
+			{ include: '@whitespace' },
+
+			// [[ attributes ]].
+			[/\[\[.*\]\]/, 'annotation'],
+
+			// Preprocessor directive
+			[/^\s*#\w+/, 'keyword'],
+
+			//DataTypes
+			[/int\d*/, 'keyword'],
+
+			// delimiters and operators
+			[/[{}()\[\]]/, '@brackets'],
+			[/[<>](?!@symbols)/, '@brackets'],
+			[/@symbols/, {
+				cases: {
+					'@operators': 'delimiter',
+					'@default': ''
+				}
+			}],
+
+			// numbers
+			[/\d*\d+[eE]([\-+]?\d+)?(@floatsuffix)/, 'number.float'],
+			[/\d*\.\d+([eE][\-+]?\d+)?(@floatsuffix)/, 'number.float'],
+			[/0[xX][0-9a-fA-F']*[0-9a-fA-F](@integersuffix)/, 'number.hex'],
+			[/0[0-7']*[0-7](@integersuffix)/, 'number.octal'],
+			[/0[bB][0-1']*[0-1](@integersuffix)/, 'number.binary'],
+			[/\d[\d']*\d(@integersuffix)/, 'number'],
+			[/\d(@integersuffix)/, 'number'],
+
+			// delimiter: after number because of .\d floats
+			[/[;,.]/, 'delimiter'],
+
+			// strings
+			[/"([^"\\]|\\.)*$/, 'string.invalid'],  // non-teminated string
+			[/"/, 'string', '@string'],
+
+			// characters
+			[/'[^\\']'/, 'string'],
+			[/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
+			[/'/, 'string.invalid']
+		],
+
+		whitespace: [
+			[/[ \t\r\n]+/, ''],
+			[/\/\*\*(?!\/)/, 'comment.doc', '@doccomment'],
+			[/\/\*/, 'comment', '@comment'],
+			[/\/\/.*$/, 'comment'],
+		],
+
+		comment: [
+			[/[^\/*]+/, 'comment'],
+			[/\*\//, 'comment', '@pop'],
+			[/[\/*]/, 'comment']
+		],
+		//Identical copy of comment above, except for the addition of .doc
+		doccomment: [
+			[/[^\/*]+/, 'comment.doc'],
+			[/\*\//, 'comment.doc', '@pop'],
+			[/[\/*]/, 'comment.doc']
+		],
+
+		string: [
+			[/[^\\"]+/, 'string'],
+			[/@escapes/, 'string.escape'],
+			[/\\./, 'string.escape.invalid'],
+			[/"/, 'string', '@pop']
+		],
+	},
+};

+ 1 - 0
test/setup.js

@@ -68,6 +68,7 @@ define(['require'], function () {
 			'release/dev/scheme/scheme.test',
 			'release/dev/scss/scss.test',
 			'release/dev/shell/shell.test',
+			'release/dev/sophia/sophia.test',
 			'release/dev/solidity/solidity.test',
 			'release/dev/sql/sql.test',
 			'release/dev/st/st.test',