From 6e3fe193956be29420cdb04f509e046e50484c20 Mon Sep 17 00:00:00 2001 From: Rokojori Date: Fri, 17 Jul 2026 23:42:43 +0200 Subject: [PATCH] code-panel: self-contained BrowserLexer; revert library-ts to fix ts-node Co-Authored-By: Claude Sonnet 4.6 --- source/components/code-panel/BrowserLexer.ts | 64 +++++++++++++++++++ source/components/code-panel/CSharpMode.ts | 45 +++++++------ .../code-panel/CodeMirrorLexerMode.ts | 6 +- source/library-ts | 2 +- 4 files changed, 90 insertions(+), 27 deletions(-) create mode 100644 source/components/code-panel/BrowserLexer.ts diff --git a/source/components/code-panel/BrowserLexer.ts b/source/components/code-panel/BrowserLexer.ts new file mode 100644 index 0000000..e87b30e --- /dev/null +++ b/source/components/code-panel/BrowserLexer.ts @@ -0,0 +1,64 @@ +function makeSticky( re: RegExp ): RegExp +{ + if ( re.sticky ) return re; + const flags = re.flags.includes( 'y' ) ? re.flags : re.flags + 'y'; + return new RegExp( re.source, flags ); +} + +export class BrowserMatcher +{ + readonly type: string; + private _re: RegExp; + + constructor( type: string, re: RegExp ) + { + this.type = type; + this._re = makeSticky( re ); + } + + matchLength( source: string, offset: number ): number + { + this._re.lastIndex = offset; + const result = this._re.exec( source ); + if ( result && result.index === offset ) return result[ 0 ].length; + return -1; + } +} + +export class BrowserLexer +{ + readonly modes = new Map(); + + addMatchers( ...matchers: BrowserMatcher[] ): void + { + const list = this.modes.get( 'default' ) ?? []; + list.push( ...matchers ); + this.modes.set( 'default', list ); + } +} + +export function cLikeLexer(): BrowserLexer +{ + const l = new BrowserLexer(); + l.addMatchers( + new BrowserMatcher( 'SINGLE_LINE_COMMENT', /\/\/.*/ ), + new BrowserMatcher( 'MULTI_LINE_COMMENT', /\/\*[\s\S]*?\*\// ), + new BrowserMatcher( 'DOUBLE_QUOTED_STRING', /"(?:[^"\\]|\\.)*"/ ), + new BrowserMatcher( 'SINGLE_QUOTED_STRING', /'(?:[^'\\]|\\.)*'/ ), + new BrowserMatcher( 'C_INSTRUCTION', /\#.*/ ), + new BrowserMatcher( 'NUMBER', /(?=\.\d|\d)(?:\d+)?(?:\.?\d*)(?:[eE][+-]?\d+)?/ ), + new BrowserMatcher( 'NULL', /\bnull\b/ ), + new BrowserMatcher( 'BOOL', /\b(?:true|false)\b/ ), + new BrowserMatcher( 'BREAK', /\r\n|\r|\n/ ), + new BrowserMatcher( 'WHITESPACE', /\s+/ ), + new BrowserMatcher( 'LOGIC', /\b(?:if|else|switch|do|while|for|break|continue|return|case)\b/ ), + new BrowserMatcher( 'BRACKET', /[()[\]{}]/ ), + new BrowserMatcher( 'ACCESS_MODIFIER', /\b(?:public|protected|private)\b/ ), + new BrowserMatcher( 'CLASS', /\bclass\b/ ), + new BrowserMatcher( 'OPERATOR', /==|\+\+|--|[+\-*\/^|~&%<>=!.:,;]/ ), + new BrowserMatcher( 'CFUNCTION', /[a-zA-Z_]\w*(?=\s*\()/ ), + new BrowserMatcher( 'CWORD', /[a-zA-Z_]\w*/ ), + new BrowserMatcher( 'ANY_SYMBOL', /./ ), + ); + return l; +} diff --git a/source/components/code-panel/CSharpMode.ts b/source/components/code-panel/CSharpMode.ts index 25f980d..e24ac17 100644 --- a/source/components/code-panel/CSharpMode.ts +++ b/source/components/code-panel/CSharpMode.ts @@ -1,27 +1,26 @@ -import { CLikeLexer } from '../../library-ts/browser/text/lexer/CLikeLexer.js'; -import { LexerTypes } from '../../library-ts/browser/text/lexer/LexerType.js'; +import { cLikeLexer } from './BrowserLexer.js'; import { CodeMirrorLexerMode } from './CodeMirrorLexerMode.js'; const TYPE_TO_CLASS: Record = { - [ LexerTypes.SINGLE_LINE_COMMENT ]: 'comment', - [ LexerTypes.MULTI_LINE_COMMENT ]: 'comment', - [ LexerTypes.DOUBLE_QUOTED_STRING ]: 'string', - [ LexerTypes.SINGLE_QUOTED_STRING ]: 'string', - [ LexerTypes.NUMBER ]: 'number', - [ LexerTypes.BOOL ]: 'atom', - [ LexerTypes.NULL ]: 'atom', - [ LexerTypes.LOGIC ]: 'keyword', - [ LexerTypes.CLASS ]: 'keyword', - [ LexerTypes.ACCESS_MODIFIER ]: 'keyword', - [ LexerTypes.C_INSTRUCTION ]: 'meta', - [ LexerTypes.CFUNCTION ]: 'variable-2', - [ LexerTypes.CWORD ]: 'variable', - [ LexerTypes.OPERATOR ]: 'operator', - [ LexerTypes.BRACKET ]: 'bracket', - [ LexerTypes.WHITESPACE ]: null, - [ LexerTypes.BREAK ]: null, - [ LexerTypes.ANY_SYMBOL ]: null, + SINGLE_LINE_COMMENT: 'comment', + MULTI_LINE_COMMENT: 'comment', + DOUBLE_QUOTED_STRING: 'string', + SINGLE_QUOTED_STRING: 'string', + NUMBER: 'number', + BOOL: 'atom', + NULL: 'atom', + LOGIC: 'keyword', + CLASS: 'keyword', + ACCESS_MODIFIER: 'keyword', + C_INSTRUCTION: 'meta', + CFUNCTION: 'variable-2', + CWORD: 'variable', + OPERATOR: 'operator', + BRACKET: 'bracket', + WHITESPACE: null, + BREAK: null, + ANY_SYMBOL: null, }; const CS_KEYWORDS = @@ -42,9 +41,9 @@ const CS_KEYWORDS = ]; export const csharpMode = new CodeMirrorLexerMode( - new CLikeLexer(), + cLikeLexer(), TYPE_TO_CLASS, - [ { type: LexerTypes.MULTI_LINE_COMMENT, start: /\/\*/, end: /\*\//, cmClass: 'comment' } ] + [ { type: 'MULTI_LINE_COMMENT', start: /\/\*/, end: /\*\//, cmClass: 'comment' } ] ); -csharpMode.setKeywordSet( 'keywords', CS_KEYWORDS, 'keyword', [ LexerTypes.CWORD ] ); +csharpMode.setKeywordSet( 'keywords', CS_KEYWORDS, 'keyword', [ 'CWORD' ] ); diff --git a/source/components/code-panel/CodeMirrorLexerMode.ts b/source/components/code-panel/CodeMirrorLexerMode.ts index 5287d4a..3c5b841 100644 --- a/source/components/code-panel/CodeMirrorLexerMode.ts +++ b/source/components/code-panel/CodeMirrorLexerMode.ts @@ -1,4 +1,4 @@ -import { Lexer } from '../../library-ts/browser/text/lexer/Lexer.js'; +import { BrowserLexer } from './BrowserLexer.js'; export interface MultiLineBlock { @@ -18,7 +18,7 @@ interface KeywordSet export class CodeMirrorLexerMode { - private _lexer: Lexer; + private _lexer: BrowserLexer; private _typeToClass: Record; private _multiLineBlocks: MultiLineBlock[]; private _multiLineTypes: Set; @@ -28,7 +28,7 @@ export class CodeMirrorLexerMode name: string = ''; constructor( - lexer: Lexer, + lexer: BrowserLexer, typeToClass: Record, multiLineBlocks: MultiLineBlock[] = [] ) diff --git a/source/library-ts b/source/library-ts index 3fa79fb..98895de 160000 --- a/source/library-ts +++ b/source/library-ts @@ -1 +1 @@ -Subproject commit 3fa79fb4f376c0a3903844edfcd8f3b529d2db0f +Subproject commit 98895de241f4f05e98ab46f9976e3756c2df5c7d