From dffb2ebf1f1e93799ec6cbf1d42155ace35e892c Mon Sep 17 00:00:00 2001 From: JC Chu Date: Wed, 28 Oct 2020 00:24:34 +0800 Subject: [PATCH] Add Modula-3 support --- src/m3/m3.contribution.ts | 13 +++ src/m3/m3.test.ts | 119 +++++++++++++++++++ src/m3/m3.ts | 226 +++++++++++++++++++++++++++++++++++++ src/monaco.contribution.ts | 1 + 4 files changed, 359 insertions(+) create mode 100644 src/m3/m3.contribution.ts create mode 100644 src/m3/m3.test.ts create mode 100644 src/m3/m3.ts diff --git a/src/m3/m3.contribution.ts b/src/m3/m3.contribution.ts new file mode 100644 index 00000000..bbb84fb1 --- /dev/null +++ b/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') +}); diff --git a/src/m3/m3.test.ts b/src/m3/m3.test.ts new file mode 100644 index 00000000..c089527e --- /dev/null +++ b/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' }] + } + ] +]); diff --git a/src/m3/m3.ts b/src/m3/m3.ts new file mode 100644 index 00000000..243f36bd --- /dev/null +++ b/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 = { + 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'] + ] + } +}; diff --git a/src/monaco.contribution.ts b/src/monaco.contribution.ts index d67526d5..23151390 100644 --- a/src/monaco.contribution.ts +++ b/src/monaco.contribution.ts @@ -30,6 +30,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';