From b031381ff7813739b6d18e85b2d73d1eaa291daa Mon Sep 17 00:00:00 2001 From: Tangent Wantwight Date: Fri, 25 Aug 2023 12:46:16 -0400 Subject: [PATCH] Factor out script/command/word/bare-word patterns to permit making bracket variations --- src/notcl.ts | 91 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/src/notcl.ts b/src/notcl.ts index 4fff10b..6b99b34 100644 --- a/src/notcl.ts +++ b/src/notcl.ts @@ -6,6 +6,7 @@ import { TextWord, EnchantedWord as EnchantedWordType, SimplifyWord, + InterpolatedPiece, } from "./words"; const Comment = Regex(/#[^\n]*/y) @@ -22,23 +23,27 @@ const BackslashEscape = Regex(/\\(.)/y) .expects("\\") .map(([, char]) => ({ text: char })); -const BareWord = Sequence( - AtLeast( - 1, - Choose( - BackslashEscape, - Regex(/[^\s\\;]+/y) - .expects("CHAR") - .map(([text]) => ({ text })) +const BARE_WORD_CHAR = /[^\s\\;]+/y; + +function bareWordTmpl(charRegex: RegExp) { + return Sequence( + AtLeast( + 1, + Choose( + BackslashEscape, + Regex(charRegex) + .expects("CHAR") + .map(([text]) => ({ text })) + ) ) - ) -).map(([pieces]) => SimplifyWord(pieces)); + ).map(([pieces]) => SimplifyWord(pieces)); +} const QuotedWord = Sequence( Regex(/"/y).expects('"'), AtLeast( 0, - Choose( + Choose( BackslashEscape, Regex(/[^"\\]+/y) .expects("CHAR") @@ -67,40 +72,50 @@ const Brace: Pattern = Sequence( Regex(/\}/y).expects("}") ).map(([, fragments]) => fragments.join("")); -const Word = Choose( - EnchantedWord, - Brace.map((text) => ({ text } as TextWord)), - QuotedWord, - BareWord -); +function wordTmpl(bareWordCharRegex: RegExp): Pattern { + return Choose( + EnchantedWord, + Brace.map((text) => ({ text } as TextWord)), + QuotedWord, + bareWordTmpl(bareWordCharRegex) + ); +} const CommandTerminator = Regex(/[\n;]/y) .expects("NEWLINE | ;") .map(() => true); -const Command = Sequence( - Word, - AtLeast( - 0, - Sequence(PreWordWhitespace, Word).map(([, word]) => word) - ), - AtLeast(0, PreWordWhitespace) -).map(([word, moreWords]) => [word].concat(moreWords)); +function commandTmpl(bareWordCharRegex: RegExp) { + const word = wordTmpl(bareWordCharRegex); + return Sequence( + word, + AtLeast( + 0, + Sequence(PreWordWhitespace, word).map(([, word]) => word) + ), + AtLeast(0, PreWordWhitespace) + ).map(([word, moreWords]) => [word].concat(moreWords)); +} -const Script = Sequence( - AtLeast( - 0, - Choose( - PreWordWhitespace.map(() => []), - CommandTerminator.map(() => []), - Sequence(Comment, Choose(CommandTerminator, End())).map(() => []), - Sequence(Command, Choose(CommandTerminator, End())).map( - ([words]) => words +function scriptTmpl(bareWordCharRegex: RegExp, endPattern: Pattern) { + return Sequence( + AtLeast( + 0, + Choose( + PreWordWhitespace.map(() => []), + CommandTerminator.map(() => []), + Sequence(Comment, Choose(CommandTerminator, endPattern)).map(() => []), + Sequence( + commandTmpl(bareWordCharRegex), + Choose(CommandTerminator, endPattern) + ).map(([words]) => words) ) - ) - ), - End() -).map(([commands]) => commands.filter((command) => command.length > 0)); + ), + endPattern + ).map(([commands]) => commands.filter((command) => command.length > 0)); +} + +const Script = scriptTmpl(BARE_WORD_CHAR, End()); const ERROR_CONTEXT = /(?<=([^\n]{0,50}))([^\n]{0,50})/y;