UNPKG

noshift.js

Version:
1 lines 46.3 kB
{"version":3,"sources":["../src/index.ts","../src/convert.ts","../package.json","../src/header.ts"],"sourcesContent":["/**\n * NoShift.js Public API\n *\n * Programmatic interface for compiling NoShift.js code to JavaScript.\n *\n * @example\n * import { compile } from \"noshift.js\";\n *\n * const result = compile('console.log^8^2^6hello^2^9;');\n * console.log(result.outputText);\n * // => console.log(\"Hello\");\n *\n * @example\n * // With options\n * const result = compile(code, { capitalizeInStrings: false });\n */\n\nimport convertNsjsToJs, { diagnose as _diagnose } from \"./convert.js\";\nimport { addHeader } from \"./header.js\";\nimport type { DiagnosticError } from \"./convert.js\";\n\nexport type { DiagnosticError } from \"./convert.js\";\nexport type { UppercaseWarning } from \"./convert.js\";\n\nexport interface CompileOptions {\n capitalizeInStrings?: boolean;\n noHeader?: boolean;\n}\n\nexport interface CompileResult {\n outputText: string;\n}\n\n/**\n * Compile NoShift.js source code to JavaScript.\n *\n * @param source - NoShift.js source code\n * @param options - Compiler options\n * @returns Compilation result\n */\nexport function compile(\n source: string,\n options: CompileOptions = {},\n): CompileResult {\n let outputText = convertNsjsToJs(source, {\n capitalizeInStrings: options.capitalizeInStrings !== false,\n });\n if (!options.noHeader && outputText.length > 0) {\n outputText = addHeader(outputText);\n }\n return { outputText };\n}\n\n/**\n * Diagnose NoShift.js source code for syntax errors.\n *\n * @param source - NoShift.js source code\n * @returns Array of diagnostic errors\n */\nexport function diagnose(source: string): DiagnosticError[] {\n return _diagnose(source);\n}\n\nexport default compile;\n","// ======\n// NoShift.js → JavaScript 置換用マップ\n// ======\nconst noShiftMap: Record<string, string> = {\n // \"^@^@^@\": \"```\", // マルチバックチック\n \"^4^[\": \"${\", // テンプレート式展開開始\n \"^0\": \"^\",\n \"^1\": \"!\",\n \"^2\": '\"',\n \"^3\": \"#\",\n \"^4\": \"$\",\n \"^5\": \"%\",\n \"^7\": \"'\",\n \"^8\": \"(\",\n \"^9\": \")\",\n \"^-\": \"=\",\n \"^^\": \"~\",\n \"^\\\\\": \"_\",\n \"^@\": \"`\",\n \"^[\": \"{\",\n \"^]\": \"}\",\n \"^;\": \"+\",\n \"^:\": \"*\",\n \"^,\": \"<\",\n \"^.\": \">\",\n \"^/\": \"?\",\n};\n\n// 逆引きマップ: JavaScript 記号 → NoShift 表記(単一記号のみ)\nconst symbolToNoshift: Record<string, string> = Object.fromEntries(\n Object.entries(noShiftMap)\n .filter(([key, value]) => key.length === 2 && value.length === 1)\n .map(([key, value]) => [value, key]),\n);\n\ninterface ConvertOptions {\n capitalizeInStrings?: boolean;\n _silent?: boolean;\n}\n\n// ======\n// キーワード置換マップ(コード部分のみ適用、文字列・コメント内はスキップ)\n// 長いものから先にマッチさせる\n// ======\nconst keywordReplacements: [string, string][] = [\n [\"@or^-\", \"|=\"],\n [\"@and^-\", \"&=\"],\n [\"or^-\", \"||=\"],\n [\"and^-\", \"&&=\"],\n [\"@or\", \"|\"],\n [\"@and\", \"&\"],\n];\n\n// 単語境界で囲まれたキーワード(変数名との衝突を防ぐ)\nconst wordKeywordReplacements: [string, string][] = [\n [\"or\", \"||\"],\n [\"and\", \"&&\"],\n];\n\nexport default function convertNsjsToJs(\n nsjsCode: string,\n options: ConvertOptions = {},\n): string {\n const capitalizeInStrings = options.capitalizeInStrings !== false;\n let jsCode = \"\";\n let i = 0;\n const len_ns = nsjsCode.length;\n\n // ======\n // 各種状態 (State) を定義\n // ======\n const STATE = {\n NORMAL: \"NORMAL\", // 普通のコード\n IN_DQ_STRING: \"IN_DQ_STRING\", // \"\" の中\n IN_SQ_STRING: \"IN_SQ_STRING\", // ' … ' の中\n IN_BT_SINGLE_STRING: \"IN_BT_SINGLE_STRING\", // ` … ` の中\n IN_BT_MULTI_STRING: \"IN_BT_MULTI_STRING\", // ``` … ``` の中\n IN_TEMPLATE_EXPRESSION: \"IN_TEMPLATE_EXPRESSION\", // ${ … } の中\n RAW_DQ_IN_EXPR: \"RAW_DQ_IN_EXPR\", // テンプレート式内の \"\" の中 (NoShift 変換なし)\n RAW_SQ_IN_EXPR: \"RAW_SQ_IN_EXPR\", // テンプレート式内の ' … ' の中 (NoShift 変換なし)\n IN_LINE_COMMENT: \"IN_LINE_COMMENT\", // // … の中\n IN_BLOCK_COMMENT: \"IN_BLOCK_COMMENT\", // /^: … ^:/ の中\n } as const;\n\n type StateType = (typeof STATE)[keyof typeof STATE];\n\n let currentState: StateType = STATE.NORMAL;\n const stateStack: StateType[] = [];\n\n // マッピングキーは長いものからマッチさせる\n const sortedNsKeys = Object.keys(noShiftMap).sort(\n (a, b) => b.length - a.length,\n );\n\n /**\n * tryConsumeNsjsSequence:\n * - カーソル i の位置に noShiftMap のキーまたは特殊シーケンスがあれば消費し、\n * jsCode に出力して true を返す。なければ false を返す。\n *\n * 優先度:\n * 1) テンプレートリテラル中の式展開開始 (^4^[ / ^4[)\n * 2) テンプレート式中の式閉じ (^])\n * 3) 通常コード/テンプレート式外の文字列開閉 (^2, ^7, ^@^@^@, ^@)\n * 4) テンプレート式中の JS 文字列開閉 (^2, ^7 → RAW_DQ_IN_EXPR / RAW_SQ_IN_EXPR)\n * 5) RAW_DQ_IN_EXPR/RAW_SQ_IN_EXPR 内の終端 (^2 / ^7 → 戻る)\n * 6) 通常の NoShift 置換 (NORMAL または IN_TEMPLATE_EXPRESSION のとき)\n */\n function tryConsumeNsjsSequence(): boolean {\n let allowGeneral = false;\n if (\n currentState === STATE.NORMAL ||\n currentState === STATE.IN_TEMPLATE_EXPRESSION\n ) {\n allowGeneral = true;\n }\n\n for (const nsKey of sortedNsKeys) {\n if (!nsjsCode.startsWith(nsKey, i)) continue;\n\n // ======\n // 1) テンプレートリテラル中の式展開開始\n // ======\n if (\n (nsKey === \"^4^[\" || nsjsCode.startsWith(\"^4[\", i)) &&\n (currentState === STATE.IN_BT_SINGLE_STRING ||\n currentState === STATE.IN_BT_MULTI_STRING)\n ) {\n jsCode += \"${\";\n i += nsKey === \"^4^[\" ? nsKey.length : 3;\n stateStack.push(currentState);\n currentState = STATE.IN_TEMPLATE_EXPRESSION;\n return true;\n }\n\n // ======\n // 2) テンプレート式中の式閉じ\n // ======\n if (nsKey === \"^]\" && currentState === STATE.IN_TEMPLATE_EXPRESSION) {\n jsCode += \"}\";\n i += nsKey.length;\n currentState = stateStack.pop()!;\n return true;\n }\n\n // ======\n // 3) 通常コード/テンプレート式外の文字列開閉\n // ======\n\n // 3-1) \"^2\": ダブルクォート開閉\n if (nsKey === \"^2\" && currentState === STATE.NORMAL) {\n jsCode += '\"';\n i += nsKey.length;\n stateStack.push(currentState);\n currentState = STATE.IN_DQ_STRING;\n return true;\n }\n if (nsKey === \"^2\" && currentState === STATE.IN_DQ_STRING) {\n jsCode += '\"';\n i += nsKey.length;\n currentState = stateStack.pop()!;\n return true;\n }\n\n // 3-2) \"^7\": シングルクォート開閉\n if (nsKey === \"^7\" && currentState === STATE.NORMAL) {\n jsCode += \"'\";\n i += nsKey.length;\n stateStack.push(currentState);\n currentState = STATE.IN_SQ_STRING;\n return true;\n }\n if (nsKey === \"^7\" && currentState === STATE.IN_SQ_STRING) {\n jsCode += \"'\";\n i += nsKey.length;\n currentState = stateStack.pop()!;\n return true;\n }\n\n // このブロックを削除\n // 3-3) \"^@^@^@\": マルチバックチック開閉\n /*\n if (\n nsKey === \"^@^@^@\" &&\n (currentState === STATE.NORMAL ||\n currentState === STATE.IN_TEMPLATE_EXPRESSION)\n ) {\n jsCode += \"```\";\n i += nsKey.length;\n stateStack.push(currentState);\n currentState = STATE.IN_BT_MULTI_STRING;\n return true;\n }\n if (nsKey === \"^@^@^@\" && currentState === STATE.IN_BT_MULTI_STRING) {\n jsCode += \"```\";\n i += nsKey.length;\n currentState = stateStack.pop()!;\n return true;\n }\n */\n\n // 3-4) \"^@\": シングルバックチック開閉\n if (\n nsKey === \"^@\" &&\n (currentState === STATE.NORMAL ||\n currentState === STATE.IN_TEMPLATE_EXPRESSION)\n ) {\n jsCode += \"`\";\n i += nsKey.length;\n stateStack.push(currentState);\n currentState = STATE.IN_BT_SINGLE_STRING;\n return true;\n }\n if (nsKey === \"^@\" && currentState === STATE.IN_BT_SINGLE_STRING) {\n jsCode += \"`\";\n i += nsKey.length;\n currentState = stateStack.pop()!;\n return true;\n }\n\n // ======\n // 4) テンプレート式中の JS 文字列開閉\n // ======\n if (nsKey === \"^2\" && currentState === STATE.IN_TEMPLATE_EXPRESSION) {\n jsCode += '\"';\n i += nsKey.length;\n stateStack.push(currentState);\n currentState = STATE.RAW_DQ_IN_EXPR;\n return true;\n }\n if (nsKey === \"^7\" && currentState === STATE.IN_TEMPLATE_EXPRESSION) {\n jsCode += \"'\";\n i += nsKey.length;\n stateStack.push(currentState);\n currentState = STATE.RAW_SQ_IN_EXPR;\n return true;\n }\n\n // ======\n // 5) RAW_DQ_IN_EXPR / RAW_SQ_IN_EXPR 内の終端\n // ======\n if (nsKey === \"^2\" && currentState === STATE.RAW_DQ_IN_EXPR) {\n jsCode += '\"';\n i += nsKey.length;\n currentState = stateStack.pop()!;\n return true;\n }\n if (nsKey === \"^7\" && currentState === STATE.RAW_SQ_IN_EXPR) {\n jsCode += \"'\";\n i += nsKey.length;\n currentState = stateStack.pop()!;\n return true;\n }\n\n // ======\n // 6) 通常の NoShift 置換 (NORMAL or IN_TEMPLATE_EXPRESSION のとき)\n // ======\n if (allowGeneral) {\n jsCode += noShiftMap[nsKey];\n i += nsKey.length;\n return true;\n }\n }\n\n return false;\n }\n\n // ======\n // メインループ\n // ======\n while (i < len_ns) {\n let consumed = false;\n\n // ======\n // ステップ1: 文字列内でのエスケープ処理\n // ======\n\n // (A) IN_DQ_STRING 内 (\"\")\n if (currentState === STATE.IN_DQ_STRING) {\n if (nsjsCode.startsWith(\"\\\\^6\", i)) {\n jsCode += \"^6\"; // \"\\^6\" を文字列中のリテラル \"^6\" として出力\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\^2\", i)) {\n jsCode += \"^2\"; // \"\\^2\" を文字列中の \"^2\" として出力\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\\\\\\", i)) {\n jsCode += \"\\\\\\\\\\\\\\\\\"; // \"\\\\\" を JSコード内で \"\\\\\\\\\" に出力\n i += 2;\n consumed = true;\n }\n }\n // (B) IN_SQ_STRING 内 (' … ')\n else if (currentState === STATE.IN_SQ_STRING) {\n if (nsjsCode.startsWith(\"\\\\^6\", i)) {\n jsCode += \"^6\";\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\^7\", i)) {\n jsCode += \"^7\";\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\\\\\\", i)) {\n jsCode += \"\\\\\\\\\\\\\\\\\";\n i += 2;\n consumed = true;\n }\n }\n // (C) RAW_DQ_IN_EXPR 内 (テンプレート式中の \"\")\n else if (currentState === STATE.RAW_DQ_IN_EXPR) {\n if (nsjsCode.startsWith(\"\\\\^6\", i)) {\n jsCode += \"^6\";\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\^2\", i)) {\n jsCode += \"^2\";\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\\\\\\", i)) {\n jsCode += \"\\\\\\\\\\\\\\\\\";\n i += 2;\n consumed = true;\n } else if (nsjsCode.startsWith(\"^2\", i)) {\n jsCode += '\"'; // 終端\n i += 2;\n currentState = stateStack.pop()!;\n consumed = true;\n }\n if (consumed) {\n continue; // 生文字扱いなので NoShift 変換せず次へ\n } else {\n jsCode += nsjsCode[i];\n i += 1;\n continue;\n }\n }\n // (D) RAW_SQ_IN_EXPR 内 (テンプレート式中の ' … ')\n else if (currentState === STATE.RAW_SQ_IN_EXPR) {\n if (nsjsCode.startsWith(\"\\\\^6\", i)) {\n jsCode += \"^6\";\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\^7\", i)) {\n jsCode += \"^7\";\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\\\\\\", i)) {\n jsCode += \"\\\\\\\\\\\\\\\\\";\n i += 2;\n consumed = true;\n } else if (nsjsCode.startsWith(\"^7\", i)) {\n jsCode += \"'\";\n i += 2;\n currentState = stateStack.pop()!;\n consumed = true;\n }\n if (consumed) {\n continue;\n } else {\n jsCode += nsjsCode[i];\n i += 1;\n continue;\n }\n }\n // (E) IN_BT_SINGLE_STRING 内 (` … `)\n else if (currentState === STATE.IN_BT_SINGLE_STRING) {\n if (nsjsCode.startsWith(\"\\\\^6\", i)) {\n jsCode += \"^6\";\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\^@\", i)) {\n jsCode += \"^@\";\n i += 3;\n consumed = true;\n } else if (nsjsCode.startsWith(\"\\\\\\\\\", i)) {\n jsCode += \"\\\\\\\\\\\\\\\\\";\n i += 2;\n consumed = true;\n }\n }\n // (F) IN_BT_MULTI_STRING 内 (``` … ```)\n else if (currentState === STATE.IN_BT_MULTI_STRING) {\n /* if (nsjsCode.startsWith(\"\\\\^@^@^@\", i)) {\n jsCode += \"^@^@^@\";\n i += 7;\n consumed = true;\n } else */\n if (nsjsCode.startsWith(\"\\\\\\\\\", i)) {\n jsCode += \"\\\\\\\\\\\\\\\\\";\n i += 2;\n consumed = true;\n }\n }\n\n // ======\n // ステップ2: ^6 大文字化モディファイア (RAW 状態とコメント以外で動作)\n // - コード上 (NORMAL, IN_TEMPLATE_EXPRESSION) では常に有効\n // - 文字列内は capitalizeInStrings オプションに従う\n // - RAW_DQ_IN_EXPR / RAW_SQ_IN_EXPR は else-if の continue で既に除外済み\n // ======\n if (\n !consumed &&\n currentState !== STATE.IN_LINE_COMMENT &&\n currentState !== STATE.IN_BLOCK_COMMENT\n ) {\n if (nsjsCode.startsWith(\"^6\", i)) {\n const inString =\n currentState === STATE.IN_DQ_STRING ||\n currentState === STATE.IN_SQ_STRING ||\n currentState === STATE.IN_BT_SINGLE_STRING ||\n currentState === STATE.IN_BT_MULTI_STRING;\n if (!inString || capitalizeInStrings) {\n i += 2;\n if (i < len_ns) {\n jsCode += nsjsCode[i].toUpperCase();\n i += 1;\n }\n consumed = true;\n }\n }\n }\n\n // ======\n // ステップ2.5: コメントの処理\n // ======\n if (!consumed) {\n // 行コメント開始 (//)\n if (currentState === STATE.NORMAL && nsjsCode.startsWith(\"//\", i)) {\n jsCode += \"//\";\n i += 2;\n stateStack.push(currentState);\n currentState = STATE.IN_LINE_COMMENT;\n consumed = true;\n }\n // 行コメント終了 (改行)\n else if (currentState === STATE.IN_LINE_COMMENT) {\n if (nsjsCode[i] === \"\\n\") {\n jsCode += \"\\n\";\n i += 1;\n currentState = stateStack.pop()!;\n } else {\n jsCode += nsjsCode[i];\n i += 1;\n }\n consumed = true;\n }\n // ブロックコメント開始 (/^:)\n else if (currentState === STATE.NORMAL && nsjsCode.startsWith(\"/^:\", i)) {\n jsCode += \"/*\";\n i += 3;\n stateStack.push(currentState);\n currentState = STATE.IN_BLOCK_COMMENT;\n consumed = true;\n }\n // ブロックコメント終了 (^:/)\n else if (\n currentState === STATE.IN_BLOCK_COMMENT &&\n nsjsCode.startsWith(\"^:/\", i)\n ) {\n jsCode += \"*/\";\n i += 3;\n currentState = stateStack.pop()!;\n consumed = true;\n }\n // ブロックコメント内の文字 (そのまま出力)\n else if (currentState === STATE.IN_BLOCK_COMMENT) {\n jsCode += nsjsCode[i];\n i += 1;\n consumed = true;\n }\n }\n\n // ======\n // ステップ2.7: キーワード置換 (NORMAL / IN_TEMPLATE_EXPRESSION のみ)\n // ======\n if (\n !consumed &&\n (currentState === STATE.NORMAL ||\n currentState === STATE.IN_TEMPLATE_EXPRESSION)\n ) {\n // @or^- / @and^- / or^- / and^- / @or / @and\n for (const [kw, replacement] of keywordReplacements) {\n if (nsjsCode.startsWith(kw, i)) {\n jsCode += replacement;\n i += kw.length;\n consumed = true;\n break;\n }\n }\n // 単語境界キーワード: or / and\n if (!consumed) {\n for (const [kw, replacement] of wordKeywordReplacements) {\n if (nsjsCode.startsWith(kw, i)) {\n // 前方の境界チェック\n const prevChar = i > 0 ? nsjsCode[i - 1] : \" \";\n const prevIsBoundary = !/[a-zA-Z0-9_$]/.test(prevChar);\n // 後方の境界チェック\n const afterPos = i + kw.length;\n const nextChar = afterPos < len_ns ? nsjsCode[afterPos] : \" \";\n const nextIsBoundary = !/[a-zA-Z0-9_$]/.test(nextChar);\n if (prevIsBoundary && nextIsBoundary) {\n jsCode += replacement;\n i += kw.length;\n consumed = true;\n break;\n }\n }\n }\n }\n }\n\n // ======\n // ステップ3: NoShift シーケンスや文字列/テンプレートの開閉、式展開を試す\n // ======\n if (!consumed) {\n consumed = tryConsumeNsjsSequence();\n }\n\n // ======\n // ステップ4: 何も消費しなかったら文字をそのまま出力\n // ======\n if (!consumed) {\n jsCode += nsjsCode[i];\n i += 1;\n }\n }\n\n // スタックに残りがあればリテラル/テンプレートの閉じ忘れ\n if (stateStack.length > 0) {\n // diagnostics モードでない場合のみ警告を出す\n if (!options._silent) {\n console.warn(\n `Warning: Unmatched literal/templating states. Final state: ${currentState}, Remaining stack: ${stateStack.join(\n \", \",\n )}`,\n );\n }\n }\n return jsCode;\n}\n\nexport interface UppercaseWarning {\n line: number;\n column: number;\n char: string;\n message: string;\n}\n\n/**\n * ソースコード内の大文字、_, $, # の使用を警告する。\n * コメント内は無視する。\n * capitalizeInStrings が true の場合、文字列内の大文字も警告する。\n */\nexport function checkUppercaseWarnings(\n nsjsCode: string,\n options: { capitalizeInStrings?: boolean } = {},\n): UppercaseWarning[] {\n const capitalizeInStrings = options.capitalizeInStrings !== false;\n const warnings: UppercaseWarning[] = [];\n const lines = nsjsCode.split(\"\\n\");\n\n // シンプルな状態追跡(文字列・コメント内を除外)\n let inDQ = false; // ^2...^2\n let inSQ = false; // ^7...^7\n let inBT = false; // ^@...^@\n let inLineComment = false;\n let inBlockComment = false;\n\n // 先頭行の shebang 検出\n const firstLine = lines[0] ?? \"\";\n const hasNoShiftShebang = firstLine.startsWith(\"#^1\"); // #^1 → valid NoShift shebang\n const hasRawShebang = firstLine.startsWith(\"#!\"); // #! → raw shebang(警告対象)\n\n // #! を使っている場合は警告\n if (hasRawShebang) {\n warnings.push({\n line: 1,\n column: 1,\n char: \"#\",\n message: \"Shebang '#!' found. Use '#^1' instead.\",\n });\n }\n\n for (let lineNum = 0; lineNum < lines.length; lineNum++) {\n const line = lines[lineNum];\n inLineComment = false; // 行コメントは行ごとにリセット\n\n // 先頭行の shebang 行はスキップ(#^1 / #! どちらも行全体をスキップ)\n if (lineNum === 0 && (hasNoShiftShebang || hasRawShebang)) {\n continue;\n }\n\n for (let col = 0; col < line.length; col++) {\n const ch = line[col];\n const next = line[col + 1];\n\n // エスケープ (\\^2, \\^7, \\^@) をスキップ\n if (ch === \"\\\\\" && next === \"^\") {\n col += 2;\n continue;\n }\n\n // ブロックコメント終了 (^:/)\n if (\n inBlockComment &&\n ch === \"^\" &&\n next === \":\" &&\n line[col + 2] === \"/\"\n ) {\n inBlockComment = false;\n col += 2;\n continue;\n }\n if (inBlockComment) continue;\n\n // 行コメント開始\n if (!inDQ && !inSQ && !inBT && ch === \"/\" && next === \"/\") {\n inLineComment = true;\n break;\n }\n // ブロックコメント開始 (/^:)\n if (\n !inDQ &&\n !inSQ &&\n !inBT &&\n ch === \"/\" &&\n next === \"^\" &&\n line[col + 2] === \":\"\n ) {\n inBlockComment = true;\n col += 2;\n continue;\n }\n\n if (inLineComment) continue;\n\n // ^6 モディファイア → 次の文字はスキップ(意図的な大文字化)\n if (ch === \"^\" && next === \"6\") {\n col += 2; // ^6 と次の文字をスキップ\n continue;\n }\n\n // 文字列リテラルの開閉\n if (ch === \"^\" && next === \"2\") {\n inDQ = !inDQ;\n col += 1;\n continue;\n }\n if (ch === \"^\" && next === \"7\") {\n inSQ = !inSQ;\n col += 1;\n continue;\n }\n if (ch === \"^\" && next === \"@\") {\n inBT = !inBT;\n col += 1;\n continue;\n }\n\n // 文字列内の処理\n if (inDQ || inSQ || inBT) {\n // capitalizeInStrings が有効なら、文字列内の大文字も警告\n if (capitalizeInStrings && /[A-Z]/.test(ch)) {\n warnings.push({\n line: lineNum + 1,\n column: col + 1,\n char: ch,\n message: `Uppercase letter '${ch}' found in string. Use ^6${ch.toLowerCase()} instead.`,\n });\n }\n continue;\n }\n\n // 他の ^X シーケンスをスキップ\n if (ch === \"^\" && next && /[0-9\\-^\\\\@\\[\\];:,./]/.test(next)) {\n col += 1;\n continue;\n }\n\n // 大文字の警告\n if (/[A-Z]/.test(ch)) {\n warnings.push({\n line: lineNum + 1,\n column: col + 1,\n char: ch,\n message: `Uppercase letter '${ch}' found. Use ^6${ch.toLowerCase()} instead.`,\n });\n }\n // Shift キーが必要な記号の警告(_ と # は別途警告)\n else if (symbolToNoshift[ch] && ch !== \"_\" && ch !== \"#\") {\n warnings.push({\n line: lineNum + 1,\n column: col + 1,\n char: ch,\n message: `Symbol '${ch}' found. Use ${symbolToNoshift[ch]} instead.`,\n });\n }\n // _ の警告(^\\ で代用可能)\n else if (ch === \"_\") {\n warnings.push({\n line: lineNum + 1,\n column: col + 1,\n char: ch,\n message: \"Underscore '_' found in code. Use ^\\\\ instead.\",\n });\n }\n // # の警告(^3 で入力可能)\n else if (ch === \"#\") {\n warnings.push({\n line: lineNum + 1,\n column: col + 1,\n char: ch,\n message: \"Hash '#' found in code. Use ^3 instead.\",\n });\n }\n }\n }\n\n return warnings;\n}\n\n// ======\n// 有効な ^X シーケンスの一覧(^3 は別扱い)\n// ======\nconst validCaretKeys = new Set(Object.keys(noShiftMap).map((k) => k[1]));\n// ^6 (capitalize) も有効\nvalidCaretKeys.add(\"6\");\n\nexport interface DiagnosticError {\n line: number;\n column: number;\n message: string;\n}\n\n/**\n * NoShift.js ソースコードの構文エラーを検出する。\n *\n * 検出するエラー:\n * - 閉じられていない文字列リテラル (^2, ^7, ^@)\n * - 閉じられていないブロックコメント (/^:)\n * - 閉じられていないテンプレート式 (^4^[)\n * - ファイル末尾の ^6 (大文字化対象の文字がない)\n * - 不明な ^ シーケンス\n */\nexport function diagnose(nsjsCode: string): DiagnosticError[] {\n const errors: DiagnosticError[] = [];\n const lines = nsjsCode.split(\"\\n\");\n\n // 状態: \"NORMAL\" | \"DQ\" | \"SQ\" | \"BT\" | \"BLOCK_COMMENT\" | \"LINE_COMMENT\" | \"TEMPLATE_EXPR\"\n type DiagnoseState =\n | \"NORMAL\"\n | \"DQ\"\n | \"SQ\"\n | \"BT\"\n | \"BLOCK_COMMENT\"\n | \"LINE_COMMENT\"\n | \"TEMPLATE_EXPR\";\n\n let state: DiagnoseState = \"NORMAL\";\n const stateStack: DiagnoseState[] = [];\n // 開始位置のスタック (エラー報告用)\n interface OpenPosition {\n line: number;\n column: number;\n type: string;\n }\n const openPositions: OpenPosition[] = [];\n\n for (let lineNum = 0; lineNum < lines.length; lineNum++) {\n const line = lines[lineNum];\n\n // 行コメントは行ごとにリセット\n if (state === \"LINE_COMMENT\") {\n state = stateStack.pop() || \"NORMAL\";\n }\n\n for (let col = 0; col < line.length; col++) {\n const ch = line[col];\n const next = col + 1 < line.length ? line[col + 1] : undefined;\n const next2 = col + 2 < line.length ? line[col + 2] : undefined;\n\n // エスケープ (\\^X) をスキップ\n if (ch === \"\\\\\" && next === \"^\") {\n col += 2;\n continue;\n }\n // \\\\\\\\ をスキップ\n if (ch === \"\\\\\" && next === \"\\\\\") {\n col += 1;\n continue;\n }\n\n // ── ブロックコメント内 ──\n if (state === \"BLOCK_COMMENT\") {\n if (ch === \"^\" && next === \":\" && next2 === \"/\") {\n state = stateStack.pop() || \"NORMAL\";\n openPositions.pop();\n col += 2;\n }\n continue;\n }\n\n // ── 行コメント内 ──\n if (state === \"LINE_COMMENT\") {\n continue; // 改行で自動リセット(上で処理済み)\n }\n\n // ── 文字列内 ──\n if (state === \"DQ\") {\n if (ch === \"^\" && next === \"2\") {\n state = stateStack.pop() || \"NORMAL\";\n openPositions.pop();\n col += 1;\n }\n continue;\n }\n if (state === \"SQ\") {\n if (ch === \"^\" && next === \"7\") {\n state = stateStack.pop() || \"NORMAL\";\n openPositions.pop();\n col += 1;\n }\n continue;\n }\n if (state === \"BT\") {\n // テンプレート式展開開始\n if (ch === \"^\" && next === \"4\" && (next2 === \"^\" || next2 === \"[\")) {\n if (next2 === \"^\" && col + 3 < line.length && line[col + 3] === \"[\") {\n stateStack.push(state);\n openPositions.push({\n line: lineNum + 1,\n column: col + 1,\n type: \"TEMPLATE_EXPR\",\n });\n state = \"TEMPLATE_EXPR\";\n col += 3;\n } else if (next2 === \"[\") {\n stateStack.push(state);\n openPositions.push({\n line: lineNum + 1,\n column: col + 1,\n type: \"TEMPLATE_EXPR\",\n });\n state = \"TEMPLATE_EXPR\";\n col += 2;\n }\n continue;\n }\n if (ch === \"^\" && next === \"@\") {\n state = stateStack.pop() || \"NORMAL\";\n openPositions.pop();\n col += 1;\n }\n continue;\n }\n\n // ── テンプレート式内 ──\n if (state === \"TEMPLATE_EXPR\") {\n if (ch === \"^\" && next === \"]\") {\n state = stateStack.pop() || \"NORMAL\";\n openPositions.pop();\n col += 1;\n continue;\n }\n // テンプレート式内の文字列もチェック → fall through to NORMAL logic\n }\n\n // ── NORMAL / TEMPLATE_EXPR 共通 ──\n\n // 行コメント開始\n if (ch === \"/\" && next === \"/\") {\n stateStack.push(state);\n state = \"LINE_COMMENT\";\n break; // 行末まで読み飛ばし\n }\n\n // ブロックコメント開始 (/^:)\n if (ch === \"/\" && next === \"^\" && next2 === \":\") {\n stateStack.push(state);\n openPositions.push({\n line: lineNum + 1,\n column: col + 1,\n type: \"BLOCK_COMMENT\",\n });\n state = \"BLOCK_COMMENT\";\n col += 2;\n continue;\n }\n\n // ダブルクォート文字列開始 (^2)\n if (ch === \"^\" && next === \"2\") {\n stateStack.push(state);\n openPositions.push({ line: lineNum + 1, column: col + 1, type: \"DQ\" });\n state = \"DQ\";\n col += 1;\n continue;\n }\n\n // シングルクォート文字列開始 (^7)\n if (ch === \"^\" && next === \"7\") {\n stateStack.push(state);\n openPositions.push({ line: lineNum + 1, column: col + 1, type: \"SQ\" });\n state = \"SQ\";\n col += 1;\n continue;\n }\n\n // テンプレートリテラル開始 (^@)\n if (ch === \"^\" && next === \"@\") {\n stateStack.push(state);\n openPositions.push({ line: lineNum + 1, column: col + 1, type: \"BT\" });\n state = \"BT\";\n col += 1;\n continue;\n }\n\n // ^6 大文字化: 次の文字がなければエラー\n if (ch === \"^\" && next === \"6\") {\n if (col + 2 >= line.length && lineNum === lines.length - 1) {\n errors.push({\n line: lineNum + 1,\n column: col + 1,\n message:\n \"^6 at end of file with no following character to capitalize.\",\n });\n }\n col += 2; // ^6 + 次の1文字をスキップ\n continue;\n }\n\n // その他の ^X シーケンス: 有効性チェック\n if (ch === \"^\" && next !== undefined) {\n if (!validCaretKeys.has(next)) {\n errors.push({\n line: lineNum + 1,\n column: col + 1,\n message: `Unknown sequence '^${next}'.`,\n });\n }\n col += 1;\n continue;\n }\n\n // ファイル末尾の孤立 ^\n if (ch === \"^\" && next === undefined && lineNum === lines.length - 1) {\n errors.push({\n line: lineNum + 1,\n column: col + 1,\n message: \"Lone '^' at end of file.\",\n });\n }\n }\n }\n\n // ── 閉じられていない構造を報告 ──\n while (openPositions.length > 0) {\n const pos = openPositions.pop()!;\n const labels: Record<string, string> = {\n DQ: \"string literal (^2...^2)\",\n SQ: \"string literal (^7...^7)\",\n BT: \"template literal (^@...^@)\",\n BLOCK_COMMENT: \"block comment (/^:...^:/)\",\n TEMPLATE_EXPR: \"template expression (^4^[...^])\",\n };\n errors.push({\n line: pos.line,\n column: pos.column,\n message: `Unclosed ${labels[pos.type] || pos.type} opened here.`,\n });\n }\n\n return errors;\n}\n","{\n \"name\": \"noshift.js\",\n \"version\": \"0.15.1\",\n \"description\": \"Joke language.\",\n \"bin\": {\n \"nsc\": \"./dist/cli.cjs\"\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.mts\",\n \"default\": \"./dist/index.mjs\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n }\n },\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"tsup\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"tsc --noEmit\",\n \"format\": \"prettier --write ./src/\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/otoneko1102/NoShift.js.git\"\n },\n \"keywords\": [\n \"noshift\",\n \"nsjs\",\n \"joke\",\n \"language\",\n \"lang\"\n ],\n \"author\": \"otoneko.\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/otoneko1102/NoShift.js/issues\"\n },\n \"homepage\": \"https://noshift.js.org\",\n \"dependencies\": {\n \"commander\": \"^14.0.3\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.3.0\",\n \"prettier\": \"^3.8.1\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.9.3\",\n \"vitest\": \"^4.0.18\"\n },\n \"engines\": {\n \"node\": \">=22.12.0\"\n }\n}\n","import pkg from \"../package.json\";\n\nfunction getVersion(): string {\n return pkg.version;\n}\n/**\n * コンパイル済み JS にヘッダーコメントを挿入する。\n * shebang (#!) がある場合はその行の直後に挿入。\n *\n * @param js - コンパイル済み JavaScript\n * @param version - バージョン文字列(省略時は package.json から取得)\n * @returns ヘッダー付き JavaScript\n */\nexport function addHeader(js: string, version?: string): string {\n const ver = version ?? getVersion();\n const header = `// Generated by NoShift.js ${ver}`;\n\n if (js.startsWith(\"#!\")) {\n const newlineIndex = js.indexOf(\"\\n\");\n if (newlineIndex === -1) {\n // shebang のみでコードがない\n return js + \"\\n\" + header + \"\\n\";\n }\n const shebang = js.slice(0, newlineIndex + 1);\n const rest = js.slice(newlineIndex + 1);\n return shebang + header + \"\\n\" + rest;\n }\n\n return header + \"\\n\" + js;\n}\n"],"mappings":"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","names":["diagnose","diagnose"]}