shell-dsl 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -2
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/commands/cut/cut.cjs +188 -0
- package/dist/cjs/src/commands/cut/cut.cjs.map +10 -0
- package/dist/cjs/src/commands/index.cjs +6 -2
- package/dist/cjs/src/commands/index.cjs.map +3 -3
- package/dist/cjs/src/commands/ls/ls.cjs +2 -2
- package/dist/cjs/src/commands/ls/ls.cjs.map +3 -3
- package/dist/cjs/src/interpreter/interpreter.cjs +5 -3
- package/dist/cjs/src/interpreter/interpreter.cjs.map +3 -3
- package/dist/cjs/src/io/stdout.cjs +11 -5
- package/dist/cjs/src/io/stdout.cjs.map +3 -3
- package/dist/cjs/src/parser/parser.cjs +3 -2
- package/dist/cjs/src/parser/parser.cjs.map +3 -3
- package/dist/cjs/src/shell-dsl.cjs +9 -4
- package/dist/cjs/src/shell-dsl.cjs.map +3 -3
- package/dist/cjs/src/types.cjs.map +2 -2
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/src/commands/cut/cut.mjs +158 -0
- package/dist/mjs/src/commands/cut/cut.mjs.map +10 -0
- package/dist/mjs/src/commands/index.mjs +6 -2
- package/dist/mjs/src/commands/index.mjs.map +3 -3
- package/dist/mjs/src/commands/ls/ls.mjs +2 -2
- package/dist/mjs/src/commands/ls/ls.mjs.map +3 -3
- package/dist/mjs/src/interpreter/interpreter.mjs +5 -3
- package/dist/mjs/src/interpreter/interpreter.mjs.map +3 -3
- package/dist/mjs/src/io/stdout.mjs +11 -5
- package/dist/mjs/src/io/stdout.mjs.map +3 -3
- package/dist/mjs/src/parser/parser.mjs +3 -5
- package/dist/mjs/src/parser/parser.mjs.map +3 -3
- package/dist/mjs/src/shell-dsl.mjs +9 -4
- package/dist/mjs/src/shell-dsl.mjs.map +3 -3
- package/dist/mjs/src/types.mjs.map +2 -2
- package/dist/types/src/commands/cut/cut.d.ts +2 -0
- package/dist/types/src/commands/index.d.ts +1 -0
- package/dist/types/src/interpreter/interpreter.d.ts +2 -0
- package/dist/types/src/io/stdout.d.ts +6 -2
- package/dist/types/src/shell-dsl.d.ts +1 -0
- package/dist/types/src/types.d.ts +3 -0
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/interpreter/interpreter.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { ASTNode, CommandNode, Redirect, IfNode, ForNode, WhileNode, UntilNode, CaseNode } from \"../parser/ast.cjs\";\nimport type { Command, VirtualFS, ExecResult, OutputCollector, RedirectObjectMap } from \"../types.cjs\";\nimport { createCommandContext } from \"./context.cjs\";\nimport { createStdin } from \"../io/stdin.cjs\";\nimport { createStdout, createStderr, createPipe, PipeBuffer, createBufferTargetCollector } from \"../io/stdout.cjs\";\nimport { Lexer } from \"../lexer/lexer.cjs\";\nimport { Parser } from \"../parser/parser.cjs\";\n\nexport interface InterpreterOptions {\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n commands: Record<string, Command>;\n redirectObjects?: RedirectObjectMap;\n}\n\n// Loop control flow exceptions\nexport class BreakException extends Error {\n constructor(public levels: number = 1) {\n super(\"break\");\n }\n}\n\nexport class ContinueException extends Error {\n constructor(public levels: number = 1) {\n super(\"continue\");\n }\n}\n\nexport class Interpreter {\n private fs: VirtualFS;\n private cwd: string;\n private env: Record<string, string>;\n private commands: Record<string, Command>;\n private redirectObjects: RedirectObjectMap;\n private loopDepth: number = 0;\n\n constructor(options: InterpreterOptions) {\n this.fs = options.fs;\n this.cwd = options.cwd;\n this.env = { ...options.env };\n this.commands = options.commands;\n this.redirectObjects = options.redirectObjects ?? {};\n }\n\n getLoopDepth(): number {\n return this.loopDepth;\n }\n\n async execute(ast: ASTNode): Promise<ExecResult> {\n const stdout = createStdout();\n const stderr = createStderr();\n\n const exitCode = await this.executeNode(ast, null, stdout, stderr);\n\n stdout.close();\n stderr.close();\n\n return {\n stdout: await stdout.collect(),\n stderr: await stderr.collect(),\n exitCode,\n };\n }\n\n private async executeNode(\n node: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n switch (node.type) {\n case \"command\":\n return this.executeCommand(node, stdinSource, stdout, stderr);\n case \"pipeline\":\n return this.executePipeline(node.commands, stdinSource, stdout, stderr);\n case \"sequence\":\n return this.executeSequence(node.commands, stdinSource, stdout, stderr);\n case \"and\":\n return this.executeAnd(node.left, node.right, stdinSource, stdout, stderr);\n case \"or\":\n return this.executeOr(node.left, node.right, stdinSource, stdout, stderr);\n case \"if\":\n return this.executeIf(node, stdinSource, stdout, stderr);\n case \"for\":\n return this.executeFor(node, stdinSource, stdout, stderr);\n case \"while\":\n return this.executeWhile(node, stdinSource, stdout, stderr);\n case \"until\":\n return this.executeUntil(node, stdinSource, stdout, stderr);\n case \"case\":\n return this.executeCase(node, stdinSource, stdout, stderr);\n default:\n throw new Error(`Cannot execute node type: ${node.type}`);\n }\n }\n\n private async executeCommand(\n node: CommandNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Create local env with assignments\n const localEnv = { ...this.env };\n for (const assignment of node.assignments) {\n localEnv[assignment.name] = await this.evaluateNode(assignment.value);\n }\n\n // If there's no command name but there are assignments, just update env\n const name = await this.evaluateNode(node.name);\n if (name === \"\" && node.assignments.length > 0) {\n for (const assignment of node.assignments) {\n this.env[assignment.name] = await this.evaluateNode(assignment.value);\n }\n return 0;\n }\n\n // Evaluate arguments using localEnv for scoped variable expansion\n const args: string[] = [];\n for (const arg of node.args) {\n const evaluated = await this.evaluateNode(arg, localEnv);\n // Glob expansion returns multiple values\n if (arg.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n args.push(...matches);\n } else {\n // No matches - use pattern as-is\n args.push(evaluated);\n }\n } else {\n args.push(evaluated);\n }\n }\n\n // Handle redirects\n let actualStdin = stdinSource;\n let actualStdout: OutputCollector = stdout;\n let actualStderr: OutputCollector = stderr;\n let stderrToStdout = false;\n let stdoutToStderr = false;\n const fileWritePromises: Promise<void>[] = [];\n\n for (const redirect of node.redirects) {\n try {\n const result = await this.handleRedirect(\n redirect,\n actualStdin,\n actualStdout,\n actualStderr\n );\n actualStdin = result.stdin;\n actualStdout = result.stdout;\n actualStderr = result.stderr;\n stderrToStdout = result.stderrToStdout || stderrToStdout;\n stdoutToStderr = result.stdoutToStderr || stdoutToStderr;\n if (result.fileWritePromise) {\n fileWritePromises.push(result.fileWritePromise);\n }\n } catch (err) {\n const target = await this.evaluateNode(redirect.target);\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`sh: ${target}: ${message}\\n`);\n return 1;\n }\n }\n\n // Handle stderr->stdout redirect\n if (stderrToStdout) {\n actualStderr = actualStdout;\n }\n if (stdoutToStderr) {\n actualStdout = actualStderr;\n }\n\n // Look up command\n const command = this.commands[name];\n if (!command) {\n await stderr.writeText(`${name}: command not found\\n`);\n return 127;\n }\n\n // Create context and execute\n const ctx = createCommandContext({\n args,\n stdin: createStdin(actualStdin),\n stdout: actualStdout,\n stderr: actualStderr,\n fs: this.fs,\n cwd: this.cwd,\n env: localEnv,\n setCwd: (path: string) => this.setCwd(path),\n });\n\n let exitCode: number;\n try {\n exitCode = await command(ctx);\n } catch (err) {\n // Re-throw loop control exceptions\n if (err instanceof BreakException || err instanceof ContinueException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`${name}: ${message}\\n`);\n exitCode = 1;\n }\n\n // Close redirect collectors and wait for file writes\n if (actualStdout !== stdout) {\n actualStdout.close();\n }\n if (actualStderr !== stderr && actualStderr !== actualStdout) {\n actualStderr.close();\n }\n\n // Wait for all file write operations to complete\n try {\n await Promise.all(fileWritePromises);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n // Find the redirect target for the error message\n const writeRedirects = node.redirects.filter(r => r.mode !== \"<\" && r.mode !== \"2>&1\" && r.mode !== \"1>&2\");\n const target = writeRedirects.length > 0\n ? await this.evaluateNode(writeRedirects[writeRedirects.length - 1]!.target)\n : \"unknown\";\n await stderr.writeText(`sh: ${target}: ${message}\\n`);\n exitCode = 1;\n }\n\n return exitCode;\n }\n\n private async handleRedirect(\n redirect: Redirect,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n const target = await this.evaluateNode(redirect.target);\n\n // Check if target is a redirect object marker\n if (target in this.redirectObjects) {\n return this.handleObjectRedirect(redirect.mode, this.redirectObjects[target]!, stdin, stdout, stderr);\n }\n\n switch (redirect.mode) {\n case \"<\": {\n if (redirect.heredocContent) {\n // Heredoc: target is already the content\n return {\n stdin: (async function* () {\n yield new TextEncoder().encode(target);\n })(),\n stdout,\n stderr,\n };\n }\n // /dev/null: empty input\n if (target === \"/dev/null\") {\n return {\n stdin: (async function* () {})(),\n stdout,\n stderr,\n };\n }\n // Input redirect from file\n const path = this.fs.resolve(this.cwd, target);\n const content = await this.fs.readFile(path);\n return {\n stdin: (async function* () {\n yield new Uint8Array(content);\n })(),\n stdout,\n stderr,\n };\n }\n case \">\": {\n // Output redirect (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \">>\": {\n // Output redirect (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \"2>\": {\n // Stderr redirect (overwrite)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"2>>\": {\n // Stderr redirect (append)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"&>\": {\n // Both to file (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"&>>\": {\n // Both to file (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"2>&1\":\n return { stdin, stdout, stderr, stderrToStdout: true };\n case \"1>&2\":\n return { stdin, stdout, stderr, stdoutToStderr: true };\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async handleObjectRedirect(\n mode: string,\n obj: Buffer | Blob | Response | string,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n switch (mode) {\n case \"<\": {\n // Input from object\n const data = await this.readFromObject(obj);\n return {\n stdin: (async function* () {\n yield data;\n })(),\n stdout,\n stderr,\n };\n }\n case \">\":\n case \">>\": {\n // Output to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Output redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr };\n }\n case \"2>\":\n case \"2>>\": {\n // Stderr to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Stderr redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout, stderr: collector };\n }\n case \"&>\":\n case \"&>>\": {\n // Both to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Combined redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr: collector };\n }\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async readFromObject(obj: Buffer | Blob | Response | string): Promise<Uint8Array> {\n if (Buffer.isBuffer(obj)) {\n return new Uint8Array(obj);\n }\n if (obj instanceof Blob) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (obj instanceof Response) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (typeof obj === \"string\") {\n return new TextEncoder().encode(obj);\n }\n throw new Error(\"Unsupported redirect object type\");\n }\n\n private async executePipeline(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n if (commands.length === 0) return 0;\n if (commands.length === 1) {\n return this.executeNode(commands[0]!, stdinSource, stdout, stderr);\n }\n\n // Create pipes between commands\n const pipes: PipeBuffer[] = [];\n for (let i = 0; i < commands.length - 1; i++) {\n pipes.push(createPipe());\n }\n\n // Execute all commands concurrently\n const promises: Promise<number>[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const command = commands[i]!;\n const cmdStdin = i === 0 ? stdinSource : pipes[i - 1]!.getReadableStream();\n const cmdStdout = i === commands.length - 1 ? stdout : pipes[i]!;\n\n promises.push(\n this.executeNode(command, cmdStdin, cmdStdout, stderr).then((code) => {\n // Close pipe when command finishes\n if (i < commands.length - 1) {\n pipes[i]!.close();\n }\n return code;\n })\n );\n }\n\n // Wait for all commands and return last exit code\n const results = await Promise.all(promises);\n return results[results.length - 1]!;\n }\n\n private async executeSequence(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n\n for (const command of commands) {\n lastExitCode = await this.executeNode(command, stdinSource, stdout, stderr);\n }\n\n return lastExitCode;\n }\n\n private async executeAnd(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode !== 0) {\n return leftCode;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeOr(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode === 0) {\n return 0;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeIf(\n node: IfNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Execute condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n\n if (conditionCode === 0) {\n // Condition succeeded, execute then branch\n return this.executeNode(node.thenBranch, stdinSource, stdout, stderr);\n }\n\n // Check elif branches\n for (const elif of node.elifBranches) {\n const elifConditionCode = await this.executeNode(elif.condition, stdinSource, stdout, stderr);\n if (elifConditionCode === 0) {\n return this.executeNode(elif.body, stdinSource, stdout, stderr);\n }\n }\n\n // Execute else branch if present\n if (node.elseBranch) {\n return this.executeNode(node.elseBranch, stdinSource, stdout, stderr);\n }\n\n return 0;\n }\n\n private async executeFor(\n node: ForNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Evaluate items and expand globs\n const expandedItems: string[] = [];\n for (const item of node.items) {\n const evaluated = await this.evaluateNode(item);\n if (item.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n expandedItems.push(...matches);\n } else {\n expandedItems.push(evaluated);\n }\n } else {\n expandedItems.push(evaluated);\n }\n }\n\n // If no items provided, use positional parameters (not implemented, so empty)\n if (expandedItems.length === 0) {\n return 0;\n }\n\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n for (const value of expandedItems) {\n // Set the loop variable\n this.env[node.variable] = value;\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeWhile(\n node: WhileNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode !== 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeUntil(\n node: UntilNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition - loop until condition succeeds\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode === 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeCase(\n node: CaseNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const word = await this.evaluateNode(node.word);\n\n for (const clause of node.clauses) {\n for (const patternNode of clause.patterns) {\n const pattern = await this.evaluateNode(patternNode);\n\n if (this.matchCasePattern(word, pattern)) {\n return this.executeNode(clause.body, stdinSource, stdout, stderr);\n }\n }\n }\n\n return 0;\n }\n\n private matchCasePattern(word: string, pattern: string): boolean {\n // Convert shell glob pattern to regex\n // * matches any string, ? matches any single character\n let regexStr = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n if (char === \"*\") {\n regexStr += \".*\";\n } else if (char === \"?\") {\n regexStr += \".\";\n } else if (char === \"[\") {\n // Character class - find closing bracket\n let j = i + 1;\n while (j < pattern.length && pattern[j] !== \"]\") {\n j++;\n }\n if (j < pattern.length) {\n regexStr += pattern.slice(i, j + 1);\n i = j;\n } else {\n regexStr += \"\\\\[\";\n }\n } else if (/[.+^${}()|\\\\]/.test(char!)) {\n // Escape regex special characters\n regexStr += \"\\\\\" + char;\n } else {\n regexStr += char;\n }\n }\n regexStr += \"$\";\n\n try {\n const regex = new RegExp(regexStr);\n return regex.test(word);\n } catch {\n // If regex fails, fall back to exact match\n return word === pattern;\n }\n }\n\n private async evaluateNode(node: ASTNode, localEnv?: Record<string, string>): Promise<string> {\n const env = localEnv ?? this.env;\n switch (node.type) {\n case \"literal\":\n return node.value;\n case \"variable\":\n return env[node.name] ?? \"\";\n case \"glob\":\n return node.pattern;\n case \"concat\": {\n const parts = await Promise.all(node.parts.map((p) => this.evaluateNode(p, localEnv)));\n return parts.join(\"\");\n }\n case \"substitution\": {\n // Execute the command and capture output\n const subStdout = createStdout();\n const subStderr = createStderr();\n await this.executeNode(node.command, null, subStdout, subStderr);\n subStdout.close();\n const output = await subStdout.collect();\n // Trim trailing newlines\n return output.toString(\"utf-8\").replace(/\\n+$/, \"\");\n }\n case \"arithmetic\": {\n const result = this.evaluateArithmetic(node.expression, env);\n return String(result);\n }\n default:\n throw new Error(`Cannot evaluate node type: ${node.type}`);\n }\n }\n\n private evaluateArithmetic(expression: string, env: Record<string, string>): number {\n // Expand variables in the expression\n let expandedExpr = expression;\n // Replace $VAR and ${VAR} with their values\n expandedExpr = expandedExpr.replace(/\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n expandedExpr = expandedExpr.replace(/\\$([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n // Also handle bare variable names (in arithmetic, variables can be referenced without $)\n expandedExpr = expandedExpr.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) => {\n // Don't replace if it looks like a number\n if (/^\\d+$/.test(match)) return match;\n return env[match] ?? \"0\";\n });\n\n // Parse and evaluate the expression\n return this.parseArithmeticExpr(expandedExpr.trim());\n }\n\n private parseArithmeticExpr(expr: string): number {\n // Simple arithmetic expression parser\n // Supports: +, -, *, /, %, ==, !=, <, >, <=, >=, &&, ||, parentheses\n // Uses a simple recursive descent parser\n\n let pos = 0;\n\n const skipWhitespace = () => {\n while (pos < expr.length && /\\s/.test(expr[pos]!)) pos++;\n };\n\n const parseNumber = (): number => {\n skipWhitespace();\n let numStr = \"\";\n const negative = expr[pos] === \"-\";\n if (negative) {\n pos++;\n skipWhitespace();\n }\n while (pos < expr.length && /[0-9]/.test(expr[pos]!)) {\n numStr += expr[pos];\n pos++;\n }\n if (numStr === \"\") return 0;\n return negative ? -parseInt(numStr, 10) : parseInt(numStr, 10);\n };\n\n const parsePrimary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"(\") {\n pos++; // consume (\n const result = parseOr();\n skipWhitespace();\n if (expr[pos] === \")\") pos++; // consume )\n return result;\n }\n return parseNumber();\n };\n\n const parseUnary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\")) {\n pos++;\n return -parseUnary();\n }\n if (expr[pos] === \"!\") {\n pos++;\n return parseUnary() === 0 ? 1 : 0;\n }\n return parsePrimary();\n };\n\n const parseMulDiv = (): number => {\n let left = parseUnary();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"*\" || op === \"/\" || op === \"%\") {\n pos++;\n const right = parseUnary();\n if (op === \"*\") left = left * right;\n else if (op === \"/\") left = right === 0 ? 0 : Math.trunc(left / right);\n else left = right === 0 ? 0 : left % right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAddSub = (): number => {\n let left = parseMulDiv();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"+\" || (op === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\"))) {\n pos++;\n const right = parseMulDiv();\n if (op === \"+\") left = left + right;\n else left = left - right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseComparison = (): number => {\n let left = parseAddSub();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"<=\") {\n pos += 2;\n const right = parseAddSub();\n left = left <= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \">=\") {\n pos += 2;\n const right = parseAddSub();\n left = left >= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"==\") {\n pos += 2;\n const right = parseAddSub();\n left = left === right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"!=\") {\n pos += 2;\n const right = parseAddSub();\n left = left !== right ? 1 : 0;\n } else if (expr[pos] === \"<\") {\n pos++;\n const right = parseAddSub();\n left = left < right ? 1 : 0;\n } else if (expr[pos] === \">\") {\n pos++;\n const right = parseAddSub();\n left = left > right ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAnd = (): number => {\n let left = parseComparison();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"&&\") {\n pos += 2;\n const right = parseComparison();\n left = (left !== 0 && right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseOr = (): number => {\n let left = parseAnd();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"||\") {\n pos += 2;\n const right = parseAnd();\n left = (left !== 0 || right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n return parseOr();\n }\n\n setCwd(cwd: string): void {\n this.env.OLDPWD = this.cwd;\n this.cwd = cwd;\n }\n\n setEnv(vars: Record<string, string>): void {\n Object.assign(this.env, vars);\n }\n\n getCwd(): string {\n return this.cwd;\n }\n\n getEnv(): Record<string, string> {\n return { ...this.env };\n }\n}\n"
|
|
5
|
+
"import type { ASTNode, CommandNode, Redirect, IfNode, ForNode, WhileNode, UntilNode, CaseNode } from \"../parser/ast.cjs\";\nimport type { Command, VirtualFS, ExecResult, OutputCollector, RedirectObjectMap } from \"../types.cjs\";\nimport { createCommandContext } from \"./context.cjs\";\nimport { createStdin } from \"../io/stdin.cjs\";\nimport { createStdout, createStderr, createPipe, PipeBuffer, createBufferTargetCollector } from \"../io/stdout.cjs\";\nimport { Lexer } from \"../lexer/lexer.cjs\";\nimport { Parser } from \"../parser/parser.cjs\";\n\nexport interface InterpreterOptions {\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n commands: Record<string, Command>;\n redirectObjects?: RedirectObjectMap;\n isTTY?: boolean;\n}\n\n// Loop control flow exceptions\nexport class BreakException extends Error {\n constructor(public levels: number = 1) {\n super(\"break\");\n }\n}\n\nexport class ContinueException extends Error {\n constructor(public levels: number = 1) {\n super(\"continue\");\n }\n}\n\nexport class Interpreter {\n private fs: VirtualFS;\n private cwd: string;\n private env: Record<string, string>;\n private commands: Record<string, Command>;\n private redirectObjects: RedirectObjectMap;\n private loopDepth: number = 0;\n private isTTY: boolean;\n\n constructor(options: InterpreterOptions) {\n this.fs = options.fs;\n this.cwd = options.cwd;\n this.env = { ...options.env };\n this.commands = options.commands;\n this.redirectObjects = options.redirectObjects ?? {};\n this.isTTY = options.isTTY ?? false;\n }\n\n getLoopDepth(): number {\n return this.loopDepth;\n }\n\n async execute(ast: ASTNode): Promise<ExecResult> {\n const stdout = createStdout(this.isTTY);\n const stderr = createStderr(this.isTTY);\n\n const exitCode = await this.executeNode(ast, null, stdout, stderr);\n\n stdout.close();\n stderr.close();\n\n return {\n stdout: await stdout.collect(),\n stderr: await stderr.collect(),\n exitCode,\n };\n }\n\n private async executeNode(\n node: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n switch (node.type) {\n case \"command\":\n return this.executeCommand(node, stdinSource, stdout, stderr);\n case \"pipeline\":\n return this.executePipeline(node.commands, stdinSource, stdout, stderr);\n case \"sequence\":\n return this.executeSequence(node.commands, stdinSource, stdout, stderr);\n case \"and\":\n return this.executeAnd(node.left, node.right, stdinSource, stdout, stderr);\n case \"or\":\n return this.executeOr(node.left, node.right, stdinSource, stdout, stderr);\n case \"if\":\n return this.executeIf(node, stdinSource, stdout, stderr);\n case \"for\":\n return this.executeFor(node, stdinSource, stdout, stderr);\n case \"while\":\n return this.executeWhile(node, stdinSource, stdout, stderr);\n case \"until\":\n return this.executeUntil(node, stdinSource, stdout, stderr);\n case \"case\":\n return this.executeCase(node, stdinSource, stdout, stderr);\n default:\n throw new Error(`Cannot execute node type: ${node.type}`);\n }\n }\n\n private async executeCommand(\n node: CommandNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Create local env with assignments\n const localEnv = { ...this.env };\n for (const assignment of node.assignments) {\n localEnv[assignment.name] = await this.evaluateNode(assignment.value);\n }\n\n // If there's no command name but there are assignments, just update env\n const name = await this.evaluateNode(node.name);\n if (name === \"\" && node.assignments.length > 0) {\n for (const assignment of node.assignments) {\n this.env[assignment.name] = await this.evaluateNode(assignment.value);\n }\n return 0;\n }\n\n // Evaluate arguments using localEnv for scoped variable expansion\n const args: string[] = [];\n for (const arg of node.args) {\n const evaluated = await this.evaluateNode(arg, localEnv);\n // Glob expansion returns multiple values\n if (arg.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n args.push(...matches);\n } else {\n // No matches - use pattern as-is\n args.push(evaluated);\n }\n } else {\n args.push(evaluated);\n }\n }\n\n // Handle redirects\n let actualStdin = stdinSource;\n let actualStdout: OutputCollector = stdout;\n let actualStderr: OutputCollector = stderr;\n let stderrToStdout = false;\n let stdoutToStderr = false;\n const fileWritePromises: Promise<void>[] = [];\n\n for (const redirect of node.redirects) {\n try {\n const result = await this.handleRedirect(\n redirect,\n actualStdin,\n actualStdout,\n actualStderr\n );\n actualStdin = result.stdin;\n actualStdout = result.stdout;\n actualStderr = result.stderr;\n stderrToStdout = result.stderrToStdout || stderrToStdout;\n stdoutToStderr = result.stdoutToStderr || stdoutToStderr;\n if (result.fileWritePromise) {\n fileWritePromises.push(result.fileWritePromise);\n }\n } catch (err) {\n const target = await this.evaluateNode(redirect.target);\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`sh: ${target}: ${message}\\n`);\n return 1;\n }\n }\n\n // Handle stderr->stdout redirect\n if (stderrToStdout) {\n actualStderr = actualStdout;\n }\n if (stdoutToStderr) {\n actualStdout = actualStderr;\n }\n\n // Look up command\n const command = this.commands[name];\n if (!command) {\n await stderr.writeText(`${name}: command not found\\n`);\n return 127;\n }\n\n // Create context and execute\n const ctx = createCommandContext({\n args,\n stdin: createStdin(actualStdin),\n stdout: actualStdout,\n stderr: actualStderr,\n fs: this.fs,\n cwd: this.cwd,\n env: localEnv,\n setCwd: (path: string) => this.setCwd(path),\n });\n\n let exitCode: number;\n try {\n exitCode = await command(ctx);\n } catch (err) {\n // Re-throw loop control exceptions\n if (err instanceof BreakException || err instanceof ContinueException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`${name}: ${message}\\n`);\n exitCode = 1;\n }\n\n // Close redirect collectors and wait for file writes\n if (actualStdout !== stdout) {\n actualStdout.close();\n }\n if (actualStderr !== stderr && actualStderr !== actualStdout) {\n actualStderr.close();\n }\n\n // Wait for all file write operations to complete\n try {\n await Promise.all(fileWritePromises);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n // Find the redirect target for the error message\n const writeRedirects = node.redirects.filter(r => r.mode !== \"<\" && r.mode !== \"2>&1\" && r.mode !== \"1>&2\");\n const target = writeRedirects.length > 0\n ? await this.evaluateNode(writeRedirects[writeRedirects.length - 1]!.target)\n : \"unknown\";\n await stderr.writeText(`sh: ${target}: ${message}\\n`);\n exitCode = 1;\n }\n\n return exitCode;\n }\n\n private async handleRedirect(\n redirect: Redirect,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n const target = await this.evaluateNode(redirect.target);\n\n // Check if target is a redirect object marker\n if (target in this.redirectObjects) {\n return this.handleObjectRedirect(redirect.mode, this.redirectObjects[target]!, stdin, stdout, stderr);\n }\n\n switch (redirect.mode) {\n case \"<\": {\n if (redirect.heredocContent) {\n // Heredoc: target is already the content\n return {\n stdin: (async function* () {\n yield new TextEncoder().encode(target);\n })(),\n stdout,\n stderr,\n };\n }\n // /dev/null: empty input\n if (target === \"/dev/null\") {\n return {\n stdin: (async function* () {})(),\n stdout,\n stderr,\n };\n }\n // Input redirect from file\n const path = this.fs.resolve(this.cwd, target);\n const content = await this.fs.readFile(path);\n return {\n stdin: (async function* () {\n yield new Uint8Array(content);\n })(),\n stdout,\n stderr,\n };\n }\n case \">\": {\n // Output redirect (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \">>\": {\n // Output redirect (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \"2>\": {\n // Stderr redirect (overwrite)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"2>>\": {\n // Stderr redirect (append)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"&>\": {\n // Both to file (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"&>>\": {\n // Both to file (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"2>&1\":\n return { stdin, stdout, stderr, stderrToStdout: true };\n case \"1>&2\":\n return { stdin, stdout, stderr, stdoutToStderr: true };\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async handleObjectRedirect(\n mode: string,\n obj: Buffer | Blob | Response | string,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n switch (mode) {\n case \"<\": {\n // Input from object\n const data = await this.readFromObject(obj);\n return {\n stdin: (async function* () {\n yield data;\n })(),\n stdout,\n stderr,\n };\n }\n case \">\":\n case \">>\": {\n // Output to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Output redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr };\n }\n case \"2>\":\n case \"2>>\": {\n // Stderr to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Stderr redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout, stderr: collector };\n }\n case \"&>\":\n case \"&>>\": {\n // Both to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Combined redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr: collector };\n }\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async readFromObject(obj: Buffer | Blob | Response | string): Promise<Uint8Array> {\n if (Buffer.isBuffer(obj)) {\n return new Uint8Array(obj);\n }\n if (obj instanceof Blob) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (obj instanceof Response) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (typeof obj === \"string\") {\n return new TextEncoder().encode(obj);\n }\n throw new Error(\"Unsupported redirect object type\");\n }\n\n private async executePipeline(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n if (commands.length === 0) return 0;\n if (commands.length === 1) {\n return this.executeNode(commands[0]!, stdinSource, stdout, stderr);\n }\n\n // Create pipes between commands\n const pipes: PipeBuffer[] = [];\n for (let i = 0; i < commands.length - 1; i++) {\n pipes.push(createPipe());\n }\n\n // Execute all commands concurrently\n const promises: Promise<number>[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const command = commands[i]!;\n const cmdStdin = i === 0 ? stdinSource : pipes[i - 1]!.getReadableStream();\n const cmdStdout = i === commands.length - 1 ? stdout : pipes[i]!;\n\n promises.push(\n this.executeNode(command, cmdStdin, cmdStdout, stderr).then((code) => {\n // Close pipe when command finishes\n if (i < commands.length - 1) {\n pipes[i]!.close();\n }\n return code;\n })\n );\n }\n\n // Wait for all commands and return last exit code\n const results = await Promise.all(promises);\n return results[results.length - 1]!;\n }\n\n private async executeSequence(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n\n for (const command of commands) {\n lastExitCode = await this.executeNode(command, stdinSource, stdout, stderr);\n }\n\n return lastExitCode;\n }\n\n private async executeAnd(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode !== 0) {\n return leftCode;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeOr(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode === 0) {\n return 0;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeIf(\n node: IfNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Execute condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n\n if (conditionCode === 0) {\n // Condition succeeded, execute then branch\n return this.executeNode(node.thenBranch, stdinSource, stdout, stderr);\n }\n\n // Check elif branches\n for (const elif of node.elifBranches) {\n const elifConditionCode = await this.executeNode(elif.condition, stdinSource, stdout, stderr);\n if (elifConditionCode === 0) {\n return this.executeNode(elif.body, stdinSource, stdout, stderr);\n }\n }\n\n // Execute else branch if present\n if (node.elseBranch) {\n return this.executeNode(node.elseBranch, stdinSource, stdout, stderr);\n }\n\n return 0;\n }\n\n private async executeFor(\n node: ForNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Evaluate items and expand globs\n const expandedItems: string[] = [];\n for (const item of node.items) {\n const evaluated = await this.evaluateNode(item);\n if (item.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n expandedItems.push(...matches);\n } else {\n expandedItems.push(evaluated);\n }\n } else {\n expandedItems.push(evaluated);\n }\n }\n\n // If no items provided, use positional parameters (not implemented, so empty)\n if (expandedItems.length === 0) {\n return 0;\n }\n\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n for (const value of expandedItems) {\n // Set the loop variable\n this.env[node.variable] = value;\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeWhile(\n node: WhileNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode !== 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeUntil(\n node: UntilNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition - loop until condition succeeds\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode === 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeCase(\n node: CaseNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const word = await this.evaluateNode(node.word);\n\n for (const clause of node.clauses) {\n for (const patternNode of clause.patterns) {\n const pattern = await this.evaluateNode(patternNode);\n\n if (this.matchCasePattern(word, pattern)) {\n return this.executeNode(clause.body, stdinSource, stdout, stderr);\n }\n }\n }\n\n return 0;\n }\n\n private matchCasePattern(word: string, pattern: string): boolean {\n // Convert shell glob pattern to regex\n // * matches any string, ? matches any single character\n let regexStr = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n if (char === \"*\") {\n regexStr += \".*\";\n } else if (char === \"?\") {\n regexStr += \".\";\n } else if (char === \"[\") {\n // Character class - find closing bracket\n let j = i + 1;\n while (j < pattern.length && pattern[j] !== \"]\") {\n j++;\n }\n if (j < pattern.length) {\n regexStr += pattern.slice(i, j + 1);\n i = j;\n } else {\n regexStr += \"\\\\[\";\n }\n } else if (/[.+^${}()|\\\\]/.test(char!)) {\n // Escape regex special characters\n regexStr += \"\\\\\" + char;\n } else {\n regexStr += char;\n }\n }\n regexStr += \"$\";\n\n try {\n const regex = new RegExp(regexStr);\n return regex.test(word);\n } catch {\n // If regex fails, fall back to exact match\n return word === pattern;\n }\n }\n\n private async evaluateNode(node: ASTNode, localEnv?: Record<string, string>): Promise<string> {\n const env = localEnv ?? this.env;\n switch (node.type) {\n case \"literal\":\n return node.value;\n case \"variable\":\n return env[node.name] ?? \"\";\n case \"glob\":\n return node.pattern;\n case \"concat\": {\n const parts = await Promise.all(node.parts.map((p) => this.evaluateNode(p, localEnv)));\n return parts.join(\"\");\n }\n case \"substitution\": {\n // Execute the command and capture output\n const subStdout = createStdout();\n const subStderr = createStderr();\n await this.executeNode(node.command, null, subStdout, subStderr);\n subStdout.close();\n const output = await subStdout.collect();\n // Trim trailing newlines\n return output.toString(\"utf-8\").replace(/\\n+$/, \"\");\n }\n case \"arithmetic\": {\n const result = this.evaluateArithmetic(node.expression, env);\n return String(result);\n }\n default:\n throw new Error(`Cannot evaluate node type: ${node.type}`);\n }\n }\n\n private evaluateArithmetic(expression: string, env: Record<string, string>): number {\n // Expand variables in the expression\n let expandedExpr = expression;\n // Replace $VAR and ${VAR} with their values\n expandedExpr = expandedExpr.replace(/\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n expandedExpr = expandedExpr.replace(/\\$([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n // Also handle bare variable names (in arithmetic, variables can be referenced without $)\n expandedExpr = expandedExpr.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) => {\n // Don't replace if it looks like a number\n if (/^\\d+$/.test(match)) return match;\n return env[match] ?? \"0\";\n });\n\n // Parse and evaluate the expression\n return this.parseArithmeticExpr(expandedExpr.trim());\n }\n\n private parseArithmeticExpr(expr: string): number {\n // Simple arithmetic expression parser\n // Supports: +, -, *, /, %, ==, !=, <, >, <=, >=, &&, ||, parentheses\n // Uses a simple recursive descent parser\n\n let pos = 0;\n\n const skipWhitespace = () => {\n while (pos < expr.length && /\\s/.test(expr[pos]!)) pos++;\n };\n\n const parseNumber = (): number => {\n skipWhitespace();\n let numStr = \"\";\n const negative = expr[pos] === \"-\";\n if (negative) {\n pos++;\n skipWhitespace();\n }\n while (pos < expr.length && /[0-9]/.test(expr[pos]!)) {\n numStr += expr[pos];\n pos++;\n }\n if (numStr === \"\") return 0;\n return negative ? -parseInt(numStr, 10) : parseInt(numStr, 10);\n };\n\n const parsePrimary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"(\") {\n pos++; // consume (\n const result = parseOr();\n skipWhitespace();\n if (expr[pos] === \")\") pos++; // consume )\n return result;\n }\n return parseNumber();\n };\n\n const parseUnary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\")) {\n pos++;\n return -parseUnary();\n }\n if (expr[pos] === \"!\") {\n pos++;\n return parseUnary() === 0 ? 1 : 0;\n }\n return parsePrimary();\n };\n\n const parseMulDiv = (): number => {\n let left = parseUnary();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"*\" || op === \"/\" || op === \"%\") {\n pos++;\n const right = parseUnary();\n if (op === \"*\") left = left * right;\n else if (op === \"/\") left = right === 0 ? 0 : Math.trunc(left / right);\n else left = right === 0 ? 0 : left % right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAddSub = (): number => {\n let left = parseMulDiv();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"+\" || (op === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\"))) {\n pos++;\n const right = parseMulDiv();\n if (op === \"+\") left = left + right;\n else left = left - right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseComparison = (): number => {\n let left = parseAddSub();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"<=\") {\n pos += 2;\n const right = parseAddSub();\n left = left <= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \">=\") {\n pos += 2;\n const right = parseAddSub();\n left = left >= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"==\") {\n pos += 2;\n const right = parseAddSub();\n left = left === right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"!=\") {\n pos += 2;\n const right = parseAddSub();\n left = left !== right ? 1 : 0;\n } else if (expr[pos] === \"<\") {\n pos++;\n const right = parseAddSub();\n left = left < right ? 1 : 0;\n } else if (expr[pos] === \">\") {\n pos++;\n const right = parseAddSub();\n left = left > right ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAnd = (): number => {\n let left = parseComparison();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"&&\") {\n pos += 2;\n const right = parseComparison();\n left = (left !== 0 && right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseOr = (): number => {\n let left = parseAnd();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"||\") {\n pos += 2;\n const right = parseAnd();\n left = (left !== 0 || right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n return parseOr();\n }\n\n setCwd(cwd: string): void {\n this.env.OLDPWD = this.cwd;\n this.cwd = cwd;\n }\n\n setEnv(vars: Record<string, string>): void {\n Object.assign(this.env, vars);\n }\n\n getCwd(): string {\n return this.cwd;\n }\n\n getEnv(): Record<string, string> {\n return { ...this.env };\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEqC,IAArC;AAC4B,IAA5B;AACgG,IAAhG;AAAA;AAaO,MAAM,uBAAuB,MAAM;AAAA,EACrB;AAAA,EAAnB,WAAW,CAAQ,SAAiB,GAAG;AAAA,IACrC,MAAM,OAAO;AAAA,IADI;AAAA;AAGrB;AAAA;AAEO,MAAM,0BAA0B,MAAM;AAAA,EACxB;AAAA,EAAnB,WAAW,CAAQ,SAAiB,GAAG;AAAA,IACrC,MAAM,UAAU;AAAA,IADC;AAAA;AAGrB;AAAA;AAEO,MAAM,YAAY;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAoB;AAAA,EAE5B,WAAW,CAAC,SAA6B;AAAA,IACvC,KAAK,KAAK,QAAQ;AAAA,IAClB,KAAK,MAAM,QAAQ;AAAA,IACnB,KAAK,MAAM,KAAK,QAAQ,IAAI;AAAA,IAC5B,KAAK,WAAW,QAAQ;AAAA,IACxB,KAAK,kBAAkB,QAAQ,mBAAmB,CAAC;AAAA;AAAA,EAGrD,YAAY,GAAW;AAAA,IACrB,OAAO,KAAK;AAAA;AAAA,OAGR,QAAO,CAAC,KAAmC;AAAA,IAC/C,MAAM,SAAS,2BAAa;AAAA,IAC5B,MAAM,SAAS,2BAAa;AAAA,IAE5B,MAAM,WAAW,MAAM,KAAK,YAAY,KAAK,MAAM,QAAQ,MAAM;AAAA,IAEjE,OAAO,MAAM;AAAA,IACb,OAAO,MAAM;AAAA,IAEb,OAAO;AAAA,MACL,QAAQ,MAAM,OAAO,QAAQ;AAAA,MAC7B,QAAQ,MAAM,OAAO,QAAQ;AAAA,MAC7B;AAAA,IACF;AAAA;AAAA,OAGY,YAAW,CACvB,MACA,aACA,QACA,QACiB;AAAA,IACjB,QAAQ,KAAK;AAAA,WACN;AAAA,QACH,OAAO,KAAK,eAAe,MAAM,aAAa,QAAQ,MAAM;AAAA,WACzD;AAAA,QACH,OAAO,KAAK,gBAAgB,KAAK,UAAU,aAAa,QAAQ,MAAM;AAAA,WACnE;AAAA,QACH,OAAO,KAAK,gBAAgB,KAAK,UAAU,aAAa,QAAQ,MAAM;AAAA,WACnE;AAAA,QACH,OAAO,KAAK,WAAW,KAAK,MAAM,KAAK,OAAO,aAAa,QAAQ,MAAM;AAAA,WACtE;AAAA,QACH,OAAO,KAAK,UAAU,KAAK,MAAM,KAAK,OAAO,aAAa,QAAQ,MAAM;AAAA,WACrE;AAAA,QACH,OAAO,KAAK,UAAU,MAAM,aAAa,QAAQ,MAAM;AAAA,WACpD;AAAA,QACH,OAAO,KAAK,WAAW,MAAM,aAAa,QAAQ,MAAM;AAAA,WACrD;AAAA,QACH,OAAO,KAAK,aAAa,MAAM,aAAa,QAAQ,MAAM;AAAA,WACvD;AAAA,QACH,OAAO,KAAK,aAAa,MAAM,aAAa,QAAQ,MAAM;AAAA,WACvD;AAAA,QACH,OAAO,KAAK,YAAY,MAAM,aAAa,QAAQ,MAAM;AAAA;AAAA,QAEzD,MAAM,IAAI,MAAM,6BAA6B,KAAK,MAAM;AAAA;AAAA;AAAA,OAIhD,eAAc,CAC1B,MACA,aACA,QACA,QACiB;AAAA,IAEjB,MAAM,WAAW,KAAK,KAAK,IAAI;AAAA,IAC/B,WAAW,cAAc,KAAK,aAAa;AAAA,MACzC,SAAS,WAAW,QAAQ,MAAM,KAAK,aAAa,WAAW,KAAK;AAAA,IACtE;AAAA,IAGA,MAAM,OAAO,MAAM,KAAK,aAAa,KAAK,IAAI;AAAA,IAC9C,IAAI,SAAS,MAAM,KAAK,YAAY,SAAS,GAAG;AAAA,MAC9C,WAAW,cAAc,KAAK,aAAa;AAAA,QACzC,KAAK,IAAI,WAAW,QAAQ,MAAM,KAAK,aAAa,WAAW,KAAK;AAAA,MACtE;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,OAAiB,CAAC;AAAA,IACxB,WAAW,OAAO,KAAK,MAAM;AAAA,MAC3B,MAAM,YAAY,MAAM,KAAK,aAAa,KAAK,QAAQ;AAAA,MAEvD,IAAI,IAAI,SAAS,QAAQ;AAAA,QACvB,MAAM,UAAU,MAAM,KAAK,GAAG,KAAK,WAAW,EAAE,KAAK,KAAK,IAAI,CAAC;AAAA,QAC/D,IAAI,QAAQ,SAAS,GAAG;AAAA,UACtB,KAAK,KAAK,GAAG,OAAO;AAAA,QACtB,EAAO;AAAA,UAEL,KAAK,KAAK,SAAS;AAAA;AAAA,MAEvB,EAAO;AAAA,QACL,KAAK,KAAK,SAAS;AAAA;AAAA,IAEvB;AAAA,IAGA,IAAI,cAAc;AAAA,IAClB,IAAI,eAAgC;AAAA,IACpC,IAAI,eAAgC;AAAA,IACpC,IAAI,iBAAiB;AAAA,IACrB,IAAI,iBAAiB;AAAA,IACrB,MAAM,oBAAqC,CAAC;AAAA,IAE5C,WAAW,YAAY,KAAK,WAAW;AAAA,MACrC,IAAI;AAAA,QACF,MAAM,SAAS,MAAM,KAAK,eACxB,UACA,aACA,cACA,YACF;AAAA,QACA,cAAc,OAAO;AAAA,QACrB,eAAe,OAAO;AAAA,QACtB,eAAe,OAAO;AAAA,QACtB,iBAAiB,OAAO,kBAAkB;AAAA,QAC1C,iBAAiB,OAAO,kBAAkB;AAAA,QAC1C,IAAI,OAAO,kBAAkB;AAAA,UAC3B,kBAAkB,KAAK,OAAO,gBAAgB;AAAA,QAChD;AAAA,QACA,OAAO,KAAK;AAAA,QACZ,MAAM,SAAS,MAAM,KAAK,aAAa,SAAS,MAAM;AAAA,QACtD,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC/D,MAAM,OAAO,UAAU,OAAO,WAAW;AAAA,CAAW;AAAA,QACpD,OAAO;AAAA;AAAA,IAEX;AAAA,IAGA,IAAI,gBAAgB;AAAA,MAClB,eAAe;AAAA,IACjB;AAAA,IACA,IAAI,gBAAgB;AAAA,MAClB,eAAe;AAAA,IACjB;AAAA,IAGA,MAAM,UAAU,KAAK,SAAS;AAAA,IAC9B,IAAI,CAAC,SAAS;AAAA,MACZ,MAAM,OAAO,UAAU,GAAG;AAAA,CAA2B;AAAA,MACrD,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,MAAM,oCAAqB;AAAA,MAC/B;AAAA,MACA,OAAO,yBAAY,WAAW;AAAA,MAC9B,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,IAAI,KAAK;AAAA,MACT,KAAK,KAAK;AAAA,MACV,KAAK;AAAA,MACL,QAAQ,CAAC,SAAiB,KAAK,OAAO,IAAI;AAAA,IAC5C,CAAC;AAAA,IAED,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,WAAW,MAAM,QAAQ,GAAG;AAAA,MAC5B,OAAO,KAAK;AAAA,MAEZ,IAAI,eAAe,kBAAkB,eAAe,mBAAmB;AAAA,QACrE,MAAM;AAAA,MACR;AAAA,MACA,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC/D,MAAM,OAAO,UAAU,GAAG,SAAS;AAAA,CAAW;AAAA,MAC9C,WAAW;AAAA;AAAA,IAIb,IAAI,iBAAiB,QAAQ;AAAA,MAC3B,aAAa,MAAM;AAAA,IACrB;AAAA,IACA,IAAI,iBAAiB,UAAU,iBAAiB,cAAc;AAAA,MAC5D,aAAa,MAAM;AAAA,IACrB;AAAA,IAGA,IAAI;AAAA,MACF,MAAM,QAAQ,IAAI,iBAAiB;AAAA,MACnC,OAAO,KAAK;AAAA,MACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAE/D,MAAM,iBAAiB,KAAK,UAAU,OAAO,OAAK,EAAE,SAAS,OAAO,EAAE,SAAS,UAAU,EAAE,SAAS,MAAM;AAAA,MAC1G,MAAM,SAAS,eAAe,SAAS,IACnC,MAAM,KAAK,aAAa,eAAe,eAAe,SAAS,GAAI,MAAM,IACzE;AAAA,MACJ,MAAM,OAAO,UAAU,OAAO,WAAW;AAAA,CAAW;AAAA,MACpD,WAAW;AAAA;AAAA,IAGb,OAAO;AAAA;AAAA,OAGK,eAAc,CAC1B,UACA,OACA,QACA,QAQC;AAAA,IACD,MAAM,SAAS,MAAM,KAAK,aAAa,SAAS,MAAM;AAAA,IAGtD,IAAI,UAAU,KAAK,iBAAiB;AAAA,MAClC,OAAO,KAAK,qBAAqB,SAAS,MAAM,KAAK,gBAAgB,SAAU,OAAO,QAAQ,MAAM;AAAA,IACtG;AAAA,IAEA,QAAQ,SAAS;AAAA,WACV,KAAK;AAAA,QACR,IAAI,SAAS,gBAAgB;AAAA,UAE3B,OAAO;AAAA,YACL,OAAQ,gBAAgB,GAAG;AAAA,cACzB,MAAM,IAAI,YAAY,EAAE,OAAO,MAAM;AAAA,cACpC;AAAA,YACH;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,QAEA,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO;AAAA,YACL,OAAQ,gBAAgB,GAAG,GAAI;AAAA,YAC/B;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,QAEA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,UAAU,MAAM,KAAK,GAAG,SAAS,IAAI;AAAA,QAC3C,OAAO;AAAA,UACL,OAAQ,gBAAgB,GAAG;AAAA,YACzB,MAAM,IAAI,WAAW,OAAO;AAAA,YAC3B;AAAA,UACH;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,WACK,KAAK;AAAA,QAER,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,WAAW,OAAO;AAAA,QAC5C;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,UAAU,MAAM,IAAI;AAAA,WACjC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,iBAAiB;AAAA,MAC9D;AAAA,WACK,MAAM;AAAA,QAET,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,WAAW,OAAO;AAAA,QAC5C;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,WAAW,MAAM,IAAI;AAAA,WAClC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,iBAAiB;AAAA,MAC9D;AAAA,WACK,MAAM;AAAA,QAET,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,QAAQ,UAAU;AAAA,QAC5C;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,UAAU,MAAM,IAAI;AAAA,WACjC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,QAAQ,WAAW,iBAAiB;AAAA,MAC9D;AAAA,WACK,OAAO;AAAA,QAEV,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,QAAQ,UAAU;AAAA,QAC5C;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,WAAW,MAAM,IAAI;AAAA,WAClC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,QAAQ,WAAW,iBAAiB;AAAA,MAC9D;AAAA,WACK,MAAM;AAAA,QAET,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,UAAU;AAAA,QACvD;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,UAAU,MAAM,IAAI;AAAA,WACjC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,WAAW,iBAAiB;AAAA,MACzE;AAAA,WACK,OAAO;AAAA,QAEV,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,UAAU;AAAA,QACvD;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,WAAW,MAAM,IAAI;AAAA,WAClC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,WAAW,iBAAiB;AAAA,MACzE;AAAA,WACK;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,QAAQ,gBAAgB,KAAK;AAAA,WAClD;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,QAAQ,gBAAgB,KAAK;AAAA;AAAA,QAErD,OAAO,EAAE,OAAO,QAAQ,OAAO;AAAA;AAAA;AAAA,OAIvB,qBAAoB,CAChC,MACA,KACA,OACA,QACA,QAQC;AAAA,IACD,QAAQ;AAAA,WACD,KAAK;AAAA,QAER,MAAM,OAAO,MAAM,KAAK,eAAe,GAAG;AAAA,QAC1C,OAAO;AAAA,UACL,OAAQ,gBAAgB,GAAG;AAAA,YACzB,MAAM;AAAA,YACL;AAAA,UACH;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,WACK;AAAA,WACA,MAAM;AAAA,QAET,IAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AAAA,UACzB,MAAM,IAAI,MAAM,iDAAiD;AAAA,QACnE;AAAA,QACA,MAAM,YAAY,0CAA4B,GAAG;AAAA,QACjD,OAAO,EAAE,OAAO,QAAQ,WAAW,OAAO;AAAA,MAC5C;AAAA,WACK;AAAA,WACA,OAAO;AAAA,QAEV,IAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AAAA,UACzB,MAAM,IAAI,MAAM,iDAAiD;AAAA,QACnE;AAAA,QACA,MAAM,YAAY,0CAA4B,GAAG;AAAA,QACjD,OAAO,EAAE,OAAO,QAAQ,QAAQ,UAAU;AAAA,MAC5C;AAAA,WACK;AAAA,WACA,OAAO;AAAA,QAEV,IAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AAAA,UACzB,MAAM,IAAI,MAAM,mDAAmD;AAAA,QACrE;AAAA,QACA,MAAM,YAAY,0CAA4B,GAAG;AAAA,QACjD,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,UAAU;AAAA,MACvD;AAAA;AAAA,QAEE,OAAO,EAAE,OAAO,QAAQ,OAAO;AAAA;AAAA;AAAA,OAIvB,eAAc,CAAC,KAA6D;AAAA,IACxF,IAAI,OAAO,SAAS,GAAG,GAAG;AAAA,MACxB,OAAO,IAAI,WAAW,GAAG;AAAA,IAC3B;AAAA,IACA,IAAI,eAAe,MAAM;AAAA,MACvB,OAAO,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;AAAA,IAC/C;AAAA,IACA,IAAI,eAAe,UAAU;AAAA,MAC3B,OAAO,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;AAAA,IAC/C;AAAA,IACA,IAAI,OAAO,QAAQ,UAAU;AAAA,MAC3B,OAAO,IAAI,YAAY,EAAE,OAAO,GAAG;AAAA,IACrC;AAAA,IACA,MAAM,IAAI,MAAM,kCAAkC;AAAA;AAAA,OAGtC,gBAAe,CAC3B,UACA,aACA,QACA,QACiB;AAAA,IACjB,IAAI,SAAS,WAAW;AAAA,MAAG,OAAO;AAAA,IAClC,IAAI,SAAS,WAAW,GAAG;AAAA,MACzB,OAAO,KAAK,YAAY,SAAS,IAAK,aAAa,QAAQ,MAAM;AAAA,IACnE;AAAA,IAGA,MAAM,QAAsB,CAAC;AAAA,IAC7B,SAAS,IAAI,EAAG,IAAI,SAAS,SAAS,GAAG,KAAK;AAAA,MAC5C,MAAM,KAAK,yBAAW,CAAC;AAAA,IACzB;AAAA,IAGA,MAAM,WAA8B,CAAC;AAAA,IAErC,SAAS,IAAI,EAAG,IAAI,SAAS,QAAQ,KAAK;AAAA,MACxC,MAAM,UAAU,SAAS;AAAA,MACzB,MAAM,WAAW,MAAM,IAAI,cAAc,MAAM,IAAI,GAAI,kBAAkB;AAAA,MACzE,MAAM,YAAY,MAAM,SAAS,SAAS,IAAI,SAAS,MAAM;AAAA,MAE7D,SAAS,KACP,KAAK,YAAY,SAAS,UAAU,WAAW,MAAM,EAAE,KAAK,CAAC,SAAS;AAAA,QAEpE,IAAI,IAAI,SAAS,SAAS,GAAG;AAAA,UAC3B,MAAM,GAAI,MAAM;AAAA,QAClB;AAAA,QACA,OAAO;AAAA,OACR,CACH;AAAA,IACF;AAAA,IAGA,MAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ;AAAA,IAC1C,OAAO,QAAQ,QAAQ,SAAS;AAAA;AAAA,OAGpB,gBAAe,CAC3B,UACA,aACA,QACA,QACiB;AAAA,IACjB,IAAI,eAAe;AAAA,IAEnB,WAAW,WAAW,UAAU;AAAA,MAC9B,eAAe,MAAM,KAAK,YAAY,SAAS,aAAa,QAAQ,MAAM;AAAA,IAC5E;AAAA,IAEA,OAAO;AAAA;AAAA,OAGK,WAAU,CACtB,MACA,OACA,aACA,QACA,QACiB;AAAA,IACjB,MAAM,WAAW,MAAM,KAAK,YAAY,MAAM,aAAa,QAAQ,MAAM;AAAA,IACzE,IAAI,aAAa,GAAG;AAAA,MAClB,OAAO;AAAA,IACT;AAAA,IACA,OAAO,KAAK,YAAY,OAAO,aAAa,QAAQ,MAAM;AAAA;AAAA,OAG9C,UAAS,CACrB,MACA,OACA,aACA,QACA,QACiB;AAAA,IACjB,MAAM,WAAW,MAAM,KAAK,YAAY,MAAM,aAAa,QAAQ,MAAM;AAAA,IACzE,IAAI,aAAa,GAAG;AAAA,MAClB,OAAO;AAAA,IACT;AAAA,IACA,OAAO,KAAK,YAAY,OAAO,aAAa,QAAQ,MAAM;AAAA;AAAA,OAG9C,UAAS,CACrB,MACA,aACA,QACA,QACiB;AAAA,IAEjB,MAAM,gBAAgB,MAAM,KAAK,YAAY,KAAK,WAAW,aAAa,QAAQ,MAAM;AAAA,IAExF,IAAI,kBAAkB,GAAG;AAAA,MAEvB,OAAO,KAAK,YAAY,KAAK,YAAY,aAAa,QAAQ,MAAM;AAAA,IACtE;AAAA,IAGA,WAAW,QAAQ,KAAK,cAAc;AAAA,MACpC,MAAM,oBAAoB,MAAM,KAAK,YAAY,KAAK,WAAW,aAAa,QAAQ,MAAM;AAAA,MAC5F,IAAI,sBAAsB,GAAG;AAAA,QAC3B,OAAO,KAAK,YAAY,KAAK,MAAM,aAAa,QAAQ,MAAM;AAAA,MAChE;AAAA,IACF;AAAA,IAGA,IAAI,KAAK,YAAY;AAAA,MACnB,OAAO,KAAK,YAAY,KAAK,YAAY,aAAa,QAAQ,MAAM;AAAA,IACtE;AAAA,IAEA,OAAO;AAAA;AAAA,OAGK,WAAU,CACtB,MACA,aACA,QACA,QACiB;AAAA,IAEjB,MAAM,gBAA0B,CAAC;AAAA,IACjC,WAAW,QAAQ,KAAK,OAAO;AAAA,MAC7B,MAAM,YAAY,MAAM,KAAK,aAAa,IAAI;AAAA,MAC9C,IAAI,KAAK,SAAS,QAAQ;AAAA,QACxB,MAAM,UAAU,MAAM,KAAK,GAAG,KAAK,WAAW,EAAE,KAAK,KAAK,IAAI,CAAC;AAAA,QAC/D,IAAI,QAAQ,SAAS,GAAG;AAAA,UACtB,cAAc,KAAK,GAAG,OAAO;AAAA,QAC/B,EAAO;AAAA,UACL,cAAc,KAAK,SAAS;AAAA;AAAA,MAEhC,EAAO;AAAA,QACL,cAAc,KAAK,SAAS;AAAA;AAAA,IAEhC;AAAA,IAGA,IAAI,cAAc,WAAW,GAAG;AAAA,MAC9B,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,eAAe;AAAA,IACnB,KAAK;AAAA,IAEL,IAAI;AAAA,MACF,WAAW,SAAS,eAAe;AAAA,QAEjC,KAAK,IAAI,KAAK,YAAY;AAAA,QAE1B,IAAI;AAAA,UACF,eAAe,MAAM,KAAK,YAAY,KAAK,MAAM,aAAa,QAAQ,MAAM;AAAA,UAC5E,OAAO,GAAG;AAAA,UACV,IAAI,aAAa,mBAAmB;AAAA,YAClC,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,IAAI,aAAa,gBAAgB;AAAA,YAC/B,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,MAAM;AAAA;AAAA,MAEV;AAAA,cACA;AAAA,MACA,KAAK;AAAA;AAAA,IAGP,OAAO;AAAA;AAAA,OAGK,aAAY,CACxB,MACA,aACA,QACA,QACiB;AAAA,IACjB,IAAI,eAAe;AAAA,IACnB,KAAK;AAAA,IAEL,IAAI;AAAA,MACF,OAAO,MAAM;AAAA,QAEX,MAAM,gBAAgB,MAAM,KAAK,YAAY,KAAK,WAAW,aAAa,QAAQ,MAAM;AAAA,QACxF,IAAI,kBAAkB,GAAG;AAAA,UACvB;AAAA,QACF;AAAA,QAEA,IAAI;AAAA,UACF,eAAe,MAAM,KAAK,YAAY,KAAK,MAAM,aAAa,QAAQ,MAAM;AAAA,UAC5E,OAAO,GAAG;AAAA,UACV,IAAI,aAAa,mBAAmB;AAAA,YAClC,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,IAAI,aAAa,gBAAgB;AAAA,YAC/B,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,MAAM;AAAA;AAAA,MAEV;AAAA,cACA;AAAA,MACA,KAAK;AAAA;AAAA,IAGP,OAAO;AAAA;AAAA,OAGK,aAAY,CACxB,MACA,aACA,QACA,QACiB;AAAA,IACjB,IAAI,eAAe;AAAA,IACnB,KAAK;AAAA,IAEL,IAAI;AAAA,MACF,OAAO,MAAM;AAAA,QAEX,MAAM,gBAAgB,MAAM,KAAK,YAAY,KAAK,WAAW,aAAa,QAAQ,MAAM;AAAA,QACxF,IAAI,kBAAkB,GAAG;AAAA,UACvB;AAAA,QACF;AAAA,QAEA,IAAI;AAAA,UACF,eAAe,MAAM,KAAK,YAAY,KAAK,MAAM,aAAa,QAAQ,MAAM;AAAA,UAC5E,OAAO,GAAG;AAAA,UACV,IAAI,aAAa,mBAAmB;AAAA,YAClC,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,IAAI,aAAa,gBAAgB;AAAA,YAC/B,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,MAAM;AAAA;AAAA,MAEV;AAAA,cACA;AAAA,MACA,KAAK;AAAA;AAAA,IAGP,OAAO;AAAA;AAAA,OAGK,YAAW,CACvB,MACA,aACA,QACA,QACiB;AAAA,IACjB,MAAM,OAAO,MAAM,KAAK,aAAa,KAAK,IAAI;AAAA,IAE9C,WAAW,UAAU,KAAK,SAAS;AAAA,MACjC,WAAW,eAAe,OAAO,UAAU;AAAA,QACzC,MAAM,UAAU,MAAM,KAAK,aAAa,WAAW;AAAA,QAEnD,IAAI,KAAK,iBAAiB,MAAM,OAAO,GAAG;AAAA,UACxC,OAAO,KAAK,YAAY,OAAO,MAAM,aAAa,QAAQ,MAAM;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAAA,IAEA,OAAO;AAAA;AAAA,EAGD,gBAAgB,CAAC,MAAc,SAA0B;AAAA,IAG/D,IAAI,WAAW;AAAA,IACf,SAAS,IAAI,EAAG,IAAI,QAAQ,QAAQ,KAAK;AAAA,MACvC,MAAM,OAAO,QAAQ;AAAA,MACrB,IAAI,SAAS,KAAK;AAAA,QAChB,YAAY;AAAA,MACd,EAAO,SAAI,SAAS,KAAK;AAAA,QACvB,YAAY;AAAA,MACd,EAAO,SAAI,SAAS,KAAK;AAAA,QAEvB,IAAI,IAAI,IAAI;AAAA,QACZ,OAAO,IAAI,QAAQ,UAAU,QAAQ,OAAO,KAAK;AAAA,UAC/C;AAAA,QACF;AAAA,QACA,IAAI,IAAI,QAAQ,QAAQ;AAAA,UACtB,YAAY,QAAQ,MAAM,GAAG,IAAI,CAAC;AAAA,UAClC,IAAI;AAAA,QACN,EAAO;AAAA,UACL,YAAY;AAAA;AAAA,MAEhB,EAAO,SAAI,gBAAgB,KAAK,IAAK,GAAG;AAAA,QAEtC,YAAY,OAAO;AAAA,MACrB,EAAO;AAAA,QACL,YAAY;AAAA;AAAA,IAEhB;AAAA,IACA,YAAY;AAAA,IAEZ,IAAI;AAAA,MACF,MAAM,QAAQ,IAAI,OAAO,QAAQ;AAAA,MACjC,OAAO,MAAM,KAAK,IAAI;AAAA,MACtB,MAAM;AAAA,MAEN,OAAO,SAAS;AAAA;AAAA;AAAA,OAIN,aAAY,CAAC,MAAe,UAAoD;AAAA,IAC5F,MAAM,MAAM,YAAY,KAAK;AAAA,IAC7B,QAAQ,KAAK;AAAA,WACN;AAAA,QACH,OAAO,KAAK;AAAA,WACT;AAAA,QACH,OAAO,IAAI,KAAK,SAAS;AAAA,WACtB;AAAA,QACH,OAAO,KAAK;AAAA,WACT,UAAU;AAAA,QACb,MAAM,QAAQ,MAAM,QAAQ,IAAI,KAAK,MAAM,IAAI,CAAC,MAAM,KAAK,aAAa,GAAG,QAAQ,CAAC,CAAC;AAAA,QACrF,OAAO,MAAM,KAAK,EAAE;AAAA,MACtB;AAAA,WACK,gBAAgB;AAAA,QAEnB,MAAM,YAAY,2BAAa;AAAA,QAC/B,MAAM,YAAY,2BAAa;AAAA,QAC/B,MAAM,KAAK,YAAY,KAAK,SAAS,MAAM,WAAW,SAAS;AAAA,QAC/D,UAAU,MAAM;AAAA,QAChB,MAAM,SAAS,MAAM,UAAU,QAAQ;AAAA,QAEvC,OAAO,OAAO,SAAS,OAAO,EAAE,QAAQ,QAAQ,EAAE;AAAA,MACpD;AAAA,WACK,cAAc;AAAA,QACjB,MAAM,SAAS,KAAK,mBAAmB,KAAK,YAAY,GAAG;AAAA,QAC3D,OAAO,OAAO,MAAM;AAAA,MACtB;AAAA;AAAA,QAEE,MAAM,IAAI,MAAM,8BAA8B,KAAK,MAAM;AAAA;AAAA;AAAA,EAIvD,kBAAkB,CAAC,YAAoB,KAAqC;AAAA,IAElF,IAAI,eAAe;AAAA,IAEnB,eAAe,aAAa,QAAQ,mCAAmC,CAAC,GAAG,SAAS;AAAA,MAClF,OAAO,IAAI,SAAS;AAAA,KACrB;AAAA,IACD,eAAe,aAAa,QAAQ,+BAA+B,CAAC,GAAG,SAAS;AAAA,MAC9E,OAAO,IAAI,SAAS;AAAA,KACrB;AAAA,IAED,eAAe,aAAa,QAAQ,iCAAiC,CAAC,UAAU;AAAA,MAE9E,IAAI,QAAQ,KAAK,KAAK;AAAA,QAAG,OAAO;AAAA,MAChC,OAAO,IAAI,UAAU;AAAA,KACtB;AAAA,IAGD,OAAO,KAAK,oBAAoB,aAAa,KAAK,CAAC;AAAA;AAAA,EAG7C,mBAAmB,CAAC,MAAsB;AAAA,IAKhD,IAAI,MAAM;AAAA,IAEV,MAAM,iBAAiB,MAAM;AAAA,MAC3B,OAAO,MAAM,KAAK,UAAU,KAAK,KAAK,KAAK,IAAK;AAAA,QAAG;AAAA;AAAA,IAGrD,MAAM,cAAc,MAAc;AAAA,MAChC,eAAe;AAAA,MACf,IAAI,SAAS;AAAA,MACb,MAAM,WAAW,KAAK,SAAS;AAAA,MAC/B,IAAI,UAAU;AAAA,QACZ;AAAA,QACA,eAAe;AAAA,MACjB;AAAA,MACA,OAAO,MAAM,KAAK,UAAU,QAAQ,KAAK,KAAK,IAAK,GAAG;AAAA,QACpD,UAAU,KAAK;AAAA,QACf;AAAA,MACF;AAAA,MACA,IAAI,WAAW;AAAA,QAAI,OAAO;AAAA,MAC1B,OAAO,WAAW,CAAC,SAAS,QAAQ,EAAE,IAAI,SAAS,QAAQ,EAAE;AAAA;AAAA,IAG/D,MAAM,eAAe,MAAc;AAAA,MACjC,eAAe;AAAA,MACf,IAAI,KAAK,SAAS,KAAK;AAAA,QACrB;AAAA,QACA,MAAM,SAAS,QAAQ;AAAA,QACvB,eAAe;AAAA,QACf,IAAI,KAAK,SAAS;AAAA,UAAK;AAAA,QACvB,OAAO;AAAA,MACT;AAAA,MACA,OAAO,YAAY;AAAA;AAAA,IAGrB,MAAM,aAAa,MAAc;AAAA,MAC/B,eAAe;AAAA,MACf,IAAI,KAAK,SAAS,OAAO,CAAC,QAAQ,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG;AAAA,QAC3D;AAAA,QACA,OAAO,CAAC,WAAW;AAAA,MACrB;AAAA,MACA,IAAI,KAAK,SAAS,KAAK;AAAA,QACrB;AAAA,QACA,OAAO,WAAW,MAAM,IAAI,IAAI;AAAA,MAClC;AAAA,MACA,OAAO,aAAa;AAAA;AAAA,IAGtB,MAAM,cAAc,MAAc;AAAA,MAChC,IAAI,OAAO,WAAW;AAAA,MACtB,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,MAAM,KAAK,KAAK;AAAA,QAChB,IAAI,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAAA,UAC1C;AAAA,UACA,MAAM,QAAQ,WAAW;AAAA,UACzB,IAAI,OAAO;AAAA,YAAK,OAAO,OAAO;AAAA,UACzB,SAAI,OAAO;AAAA,YAAK,OAAO,UAAU,IAAI,IAAI,KAAK,MAAM,OAAO,KAAK;AAAA,UAChE;AAAA,mBAAO,UAAU,IAAI,IAAI,OAAO;AAAA,QACvC,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,MAAM,cAAc,MAAc;AAAA,MAChC,IAAI,OAAO,YAAY;AAAA,MACvB,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,MAAM,KAAK,KAAK;AAAA,QAChB,IAAI,OAAO,OAAQ,OAAO,OAAO,CAAC,QAAQ,KAAK,KAAK,MAAM,MAAM,EAAE,GAAI;AAAA,UACpE;AAAA,UACA,MAAM,QAAQ,YAAY;AAAA,UAC1B,IAAI,OAAO;AAAA,YAAK,OAAO,OAAO;AAAA,UACzB;AAAA,mBAAO,OAAO;AAAA,QACrB,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,MAAM,kBAAkB,MAAc;AAAA,MACpC,IAAI,OAAO,YAAY;AAAA,MACvB,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,IAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UACrC,OAAO;AAAA,UACP,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,QAAQ,QAAQ,IAAI;AAAA,QAC7B,EAAO,SAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UAC5C,OAAO;AAAA,UACP,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,QAAQ,QAAQ,IAAI;AAAA,QAC7B,EAAO,SAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UAC5C,OAAO;AAAA,UACP,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,SAAS,QAAQ,IAAI;AAAA,QAC9B,EAAO,SAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UAC5C,OAAO;AAAA,UACP,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,SAAS,QAAQ,IAAI;AAAA,QAC9B,EAAO,SAAI,KAAK,SAAS,KAAK;AAAA,UAC5B;AAAA,UACA,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,OAAO,QAAQ,IAAI;AAAA,QAC5B,EAAO,SAAI,KAAK,SAAS,KAAK;AAAA,UAC5B;AAAA,UACA,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,OAAO,QAAQ,IAAI;AAAA,QAC5B,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,MAAM,WAAW,MAAc;AAAA,MAC7B,IAAI,OAAO,gBAAgB;AAAA,MAC3B,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,IAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UACrC,OAAO;AAAA,UACP,MAAM,QAAQ,gBAAgB;AAAA,UAC9B,OAAQ,SAAS,KAAK,UAAU,IAAK,IAAI;AAAA,QAC3C,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,MAAM,UAAU,MAAc;AAAA,MAC5B,IAAI,OAAO,SAAS;AAAA,MACpB,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,IAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UACrC,OAAO;AAAA,UACP,MAAM,QAAQ,SAAS;AAAA,UACvB,OAAQ,SAAS,KAAK,UAAU,IAAK,IAAI;AAAA,QAC3C,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,OAAO,QAAQ;AAAA;AAAA,EAGjB,MAAM,CAAC,KAAmB;AAAA,IACxB,KAAK,IAAI,SAAS,KAAK;AAAA,IACvB,KAAK,MAAM;AAAA;AAAA,EAGb,MAAM,CAAC,MAAoC;AAAA,IACzC,OAAO,OAAO,KAAK,KAAK,IAAI;AAAA;AAAA,EAG9B,MAAM,GAAW;AAAA,IACf,OAAO,KAAK;AAAA;AAAA,EAGd,MAAM,GAA2B;AAAA,IAC/B,OAAO,KAAK,KAAK,IAAI;AAAA;AAEzB;",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "7B263C6315A30CB564756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -45,6 +45,10 @@ class OutputCollectorImpl {
|
|
|
45
45
|
closeResolvers = [];
|
|
46
46
|
resolveWait = null;
|
|
47
47
|
waitPromise = null;
|
|
48
|
+
isTTY;
|
|
49
|
+
constructor(isTTY = false) {
|
|
50
|
+
this.isTTY = isTTY;
|
|
51
|
+
}
|
|
48
52
|
async write(chunk) {
|
|
49
53
|
if (this.closed) {
|
|
50
54
|
throw new Error("Output stream is closed");
|
|
@@ -104,6 +108,7 @@ class PipeBuffer {
|
|
|
104
108
|
closed = false;
|
|
105
109
|
waitingReaders = [];
|
|
106
110
|
readIndex = 0;
|
|
111
|
+
isTTY = false;
|
|
107
112
|
async write(chunk) {
|
|
108
113
|
if (this.closed) {
|
|
109
114
|
throw new Error("Pipe is closed");
|
|
@@ -147,11 +152,11 @@ class PipeBuffer {
|
|
|
147
152
|
}
|
|
148
153
|
}
|
|
149
154
|
}
|
|
150
|
-
function createStdout() {
|
|
151
|
-
return new OutputCollectorImpl;
|
|
155
|
+
function createStdout(isTTY = false) {
|
|
156
|
+
return new OutputCollectorImpl(isTTY);
|
|
152
157
|
}
|
|
153
|
-
function createStderr() {
|
|
154
|
-
return new OutputCollectorImpl;
|
|
158
|
+
function createStderr(isTTY = false) {
|
|
159
|
+
return new OutputCollectorImpl(isTTY);
|
|
155
160
|
}
|
|
156
161
|
function createPipe() {
|
|
157
162
|
return new PipeBuffer;
|
|
@@ -162,6 +167,7 @@ class BufferTargetCollector {
|
|
|
162
167
|
offset = 0;
|
|
163
168
|
closed = false;
|
|
164
169
|
closeResolvers = [];
|
|
170
|
+
isTTY = false;
|
|
165
171
|
constructor(target) {
|
|
166
172
|
this.target = target;
|
|
167
173
|
}
|
|
@@ -200,4 +206,4 @@ function createBufferTargetCollector(target) {
|
|
|
200
206
|
return new BufferTargetCollector(target);
|
|
201
207
|
}
|
|
202
208
|
|
|
203
|
-
//# debugId=
|
|
209
|
+
//# debugId=0D868D44E2116D2364756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/io/stdout.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { Stdout, Stderr, OutputCollector } from \"../types.cjs\";\n\nexport class OutputCollectorImpl implements OutputCollector {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private closeResolvers: Array<() => void> = [];\n private resolveWait: (() => void) | null = null;\n private waitPromise: Promise<void> | null = null;\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Output stream is closed\");\n }\n this.chunks.push(chunk);\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n // Wake up anyone waiting for close\n for (const resolve of this.closeResolvers) {\n resolve();\n }\n this.closeResolvers = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.closeResolvers.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n let index = 0;\n\n while (true) {\n while (index < this.chunks.length) {\n yield this.chunks[index]!;\n index++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data or close\n if (!this.waitPromise) {\n this.waitPromise = new Promise<void>((resolve) => {\n this.resolveWait = resolve;\n });\n }\n await this.waitPromise;\n }\n }\n}\n\nexport class PipeBuffer implements OutputCollector, Stdout {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private waitingReaders: Array<() => void> = [];\n private readIndex: number = 0;\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Pipe is closed\");\n }\n this.chunks.push(chunk);\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n while (true) {\n // Yield any available chunks\n while (this.readIndex < this.chunks.length) {\n yield this.chunks[this.readIndex]!;\n this.readIndex++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n }\n}\n\nexport function createStdout(): OutputCollector {\n return new OutputCollectorImpl();\n}\n\nexport function createStderr(): OutputCollector {\n return new OutputCollectorImpl();\n}\n\nexport function createPipe(): PipeBuffer {\n return new PipeBuffer();\n}\n\nexport class BufferTargetCollector implements OutputCollector {\n private target: Buffer;\n private offset: number = 0;\n private closed: boolean = false;\n private closeResolvers: Array<() => void> = [];\n\n constructor(target: Buffer) {\n this.target = target;\n }\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Output stream is closed\");\n }\n for (let i = 0; i < chunk.length && this.offset < this.target.length; i++) {\n this.target[this.offset++] = chunk[i]!;\n }\n }\n\n async writeText(str: string): Promise<void> {\n const bytes = new TextEncoder().encode(str);\n await this.write(bytes);\n }\n\n close(): void {\n this.closed = true;\n for (const resolve of this.closeResolvers) {\n resolve();\n }\n this.closeResolvers = [];\n }\n\n async collect(): Promise<Buffer> {\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.closeResolvers.push(resolve);\n });\n }\n return this.target.subarray(0, this.offset) as Buffer;\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n yield this.target.subarray(0, this.offset);\n }\n}\n\nexport function createBufferTargetCollector(target: Buffer): OutputCollector {\n return new BufferTargetCollector(target);\n}\n"
|
|
5
|
+
"import type { Stdout, Stderr, OutputCollector } from \"../types.cjs\";\n\nexport class OutputCollectorImpl implements OutputCollector {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private closeResolvers: Array<() => void> = [];\n private resolveWait: (() => void) | null = null;\n private waitPromise: Promise<void> | null = null;\n public isTTY: boolean;\n\n constructor(isTTY: boolean = false) {\n this.isTTY = isTTY;\n }\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Output stream is closed\");\n }\n this.chunks.push(chunk);\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n // Wake up anyone waiting for close\n for (const resolve of this.closeResolvers) {\n resolve();\n }\n this.closeResolvers = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.closeResolvers.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n let index = 0;\n\n while (true) {\n while (index < this.chunks.length) {\n yield this.chunks[index]!;\n index++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data or close\n if (!this.waitPromise) {\n this.waitPromise = new Promise<void>((resolve) => {\n this.resolveWait = resolve;\n });\n }\n await this.waitPromise;\n }\n }\n}\n\nexport class PipeBuffer implements OutputCollector, Stdout {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private waitingReaders: Array<() => void> = [];\n private readIndex: number = 0;\n public readonly isTTY: boolean = false;\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Pipe is closed\");\n }\n this.chunks.push(chunk);\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n while (true) {\n // Yield any available chunks\n while (this.readIndex < this.chunks.length) {\n yield this.chunks[this.readIndex]!;\n this.readIndex++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n }\n}\n\nexport function createStdout(isTTY: boolean = false): OutputCollector {\n return new OutputCollectorImpl(isTTY);\n}\n\nexport function createStderr(isTTY: boolean = false): OutputCollector {\n return new OutputCollectorImpl(isTTY);\n}\n\nexport function createPipe(): PipeBuffer {\n return new PipeBuffer();\n}\n\nexport class BufferTargetCollector implements OutputCollector {\n private target: Buffer;\n private offset: number = 0;\n private closed: boolean = false;\n private closeResolvers: Array<() => void> = [];\n public readonly isTTY: boolean = false;\n\n constructor(target: Buffer) {\n this.target = target;\n }\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Output stream is closed\");\n }\n for (let i = 0; i < chunk.length && this.offset < this.target.length; i++) {\n this.target[this.offset++] = chunk[i]!;\n }\n }\n\n async writeText(str: string): Promise<void> {\n const bytes = new TextEncoder().encode(str);\n await this.write(bytes);\n }\n\n close(): void {\n this.closed = true;\n for (const resolve of this.closeResolvers) {\n resolve();\n }\n this.closeResolvers = [];\n }\n\n async collect(): Promise<Buffer> {\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.closeResolvers.push(resolve);\n });\n }\n return this.target.subarray(0, this.offset) as Buffer;\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n yield this.target.subarray(0, this.offset);\n }\n}\n\nexport function createBufferTargetCollector(target: Buffer): OutputCollector {\n return new BufferTargetCollector(target);\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,MAAM,oBAA+C;AAAA,EAClD,SAAuB,CAAC;AAAA,EACxB,SAAkB;AAAA,EAClB,iBAAoC,CAAC;AAAA,EACrC,cAAmC;AAAA,EACnC,cAAoC;AAAA,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "0D868D44E2116D2364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -34,6 +34,7 @@ __export(exports_parser, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(exports_parser);
|
|
36
36
|
var import_errors = require("../errors.cjs");
|
|
37
|
+
var import_lexer = require("../lexer/lexer.cjs");
|
|
37
38
|
|
|
38
39
|
class Parser {
|
|
39
40
|
tokens;
|
|
@@ -362,7 +363,7 @@ class Parser {
|
|
|
362
363
|
case "variable":
|
|
363
364
|
return { type: "variable", name: token.name };
|
|
364
365
|
case "substitution":
|
|
365
|
-
const innerParser = new Parser(new
|
|
366
|
+
const innerParser = new Parser(new import_lexer.Lexer(token.command, { preserveNewlines: true }).tokenize());
|
|
366
367
|
return { type: "substitution", command: innerParser.parse() };
|
|
367
368
|
case "arithmetic":
|
|
368
369
|
return { type: "arithmetic", expression: token.expression };
|
|
@@ -494,4 +495,4 @@ function parse(tokens) {
|
|
|
494
495
|
return new Parser(tokens).parse();
|
|
495
496
|
}
|
|
496
497
|
|
|
497
|
-
//# debugId=
|
|
498
|
+
//# debugId=4B60404E2B30A49A64756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/parser/parser.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { ParseError } from \"../errors.cjs\";\nimport type { Token, KeywordValue } from \"../lexer/tokens.cjs\";\nimport type { ASTNode, Redirect, RedirectMode, CommandNode, IfNode, ForNode, WhileNode, UntilNode, CaseNode, CaseClause } from \"./ast.cjs\";\n\nexport class Parser {\n private tokens: Token[];\n private pos: number = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n parse(): ASTNode {\n const result = this.parseSequence();\n if (!this.isAtEnd()) {\n throw new ParseError(`Unexpected token: ${JSON.stringify(this.peek())}`);\n }\n return result;\n }\n\n // sequence := and_or ((';'|'\\n') and_or)*\n private parseSequence(): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n commands.push(this.parseAndOr());\n\n while (this.match(\"semicolon\") || this.match(\"newline\")) {\n this.skipNewlines();\n // Skip empty commands after separator, or stop at terminating keywords\n if (this.isAtEnd() || this.check(\"semicolon\") || this.check(\"newline\") || this.isTerminatingKeyword()) continue;\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private skipNewlines(): void {\n while (this.match(\"newline\")) {\n // keep consuming newlines\n }\n }\n\n private isTerminatingKeyword(): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return [\"then\", \"elif\", \"else\", \"fi\", \"do\", \"done\", \"esac\"].includes(token.value);\n }\n\n // and_or := pipeline (('&&'|'||') pipeline)*\n private parseAndOr(): ASTNode {\n let left = this.parsePipeline();\n\n while (this.check(\"and\") || this.check(\"or\")) {\n if (this.match(\"and\")) {\n const right = this.parsePipeline();\n left = { type: \"and\", left, right };\n } else if (this.match(\"or\")) {\n const right = this.parsePipeline();\n left = { type: \"or\", left, right };\n }\n }\n\n return left;\n }\n\n // pipeline := command ('|' command)*\n private parsePipeline(): ASTNode {\n const commands: ASTNode[] = [];\n commands.push(this.parseCompoundOrCommand());\n\n while (this.match(\"pipe\")) {\n this.skipNewlines();\n commands.push(this.parseCompoundOrCommand());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"pipeline\", commands };\n }\n\n // compound_or_command := compound_command | simple_command\n private parseCompoundOrCommand(): ASTNode {\n this.skipNewlines();\n const token = this.peek();\n\n if (token.type === \"keyword\") {\n switch (token.value) {\n case \"if\":\n return this.parseIf();\n case \"for\":\n return this.parseFor();\n case \"while\":\n return this.parseWhile();\n case \"until\":\n return this.parseUntil();\n case \"case\":\n return this.parseCase();\n }\n }\n\n return this.parseCommand();\n }\n\n // if := 'if' compound_list 'then' compound_list ('elif' compound_list 'then' compound_list)* ['else' compound_list] 'fi'\n private parseIf(): IfNode {\n this.expectKeyword(\"if\");\n const condition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const thenBranch = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n\n const elifBranches: Array<{ condition: ASTNode; body: ASTNode }> = [];\n while (this.checkKeyword(\"elif\")) {\n this.expectKeyword(\"elif\");\n const elifCondition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const elifBody = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n elifBranches.push({ condition: elifCondition, body: elifBody });\n }\n\n let elseBranch: ASTNode | undefined;\n if (this.checkKeyword(\"else\")) {\n this.expectKeyword(\"else\");\n elseBranch = this.parseCompoundList([\"fi\"]);\n }\n\n this.expectKeyword(\"fi\");\n\n return {\n type: \"if\",\n condition,\n thenBranch,\n elifBranches,\n elseBranch,\n };\n }\n\n // for := 'for' NAME ['in' word*] (';'|'\\n') 'do' compound_list 'done'\n private parseFor(): ForNode {\n this.expectKeyword(\"for\");\n\n // Get variable name\n const varToken = this.peek();\n if (varToken.type !== \"word\") {\n throw new ParseError(\"Expected variable name after 'for'\");\n }\n this.advance();\n const variable = varToken.value;\n\n // Parse optional 'in' clause\n const items: ASTNode[] = [];\n if (this.checkKeyword(\"in\")) {\n this.expectKeyword(\"in\");\n // Read items until semicolon, newline, or 'do'\n while (!this.isAtEnd() && !this.check(\"semicolon\") && !this.check(\"newline\") && !this.checkKeyword(\"do\")) {\n items.push(this.parseWordArg());\n }\n }\n\n // Consume separator (semicolon or newline)\n if (!this.match(\"semicolon\")) {\n this.match(\"newline\");\n }\n this.skipNewlines();\n\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"for\",\n variable,\n items,\n body,\n };\n }\n\n // while := 'while' compound_list 'do' compound_list 'done'\n private parseWhile(): WhileNode {\n this.expectKeyword(\"while\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"while\",\n condition,\n body,\n };\n }\n\n // until := 'until' compound_list 'do' compound_list 'done'\n private parseUntil(): UntilNode {\n this.expectKeyword(\"until\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"until\",\n condition,\n body,\n };\n }\n\n // case := 'case' word 'in' (pattern ('|' pattern)* ')' compound_list ';;')* 'esac'\n private parseCase(): CaseNode {\n this.expectKeyword(\"case\");\n const word = this.parseWordArg();\n this.expectKeyword(\"in\");\n this.skipNewlines();\n\n const clauses: CaseClause[] = [];\n\n while (!this.isAtEnd() && !this.checkKeyword(\"esac\")) {\n // Parse patterns separated by '|'\n // Skip leading '(' if present\n this.match(\"openParen\");\n\n const patterns: ASTNode[] = [];\n patterns.push(this.parseCasePattern());\n\n while (this.match(\"pipe\")) {\n patterns.push(this.parseCasePattern());\n }\n\n // Expect ')'\n if (!this.match(\"closeParen\")) {\n throw new ParseError(\"Expected ')' after case pattern\");\n }\n\n // Parse body until ';;' or 'esac'\n const body = this.parseCaseBody();\n\n clauses.push({ patterns, body });\n\n // ';;' is optional for the last clause\n this.match(\"doubleSemicolon\");\n this.skipNewlines();\n }\n\n this.expectKeyword(\"esac\");\n\n return {\n type: \"case\",\n word,\n clauses,\n };\n }\n\n private parseCasePattern(): ASTNode {\n const token = this.peek();\n\n // Handle glob patterns and words\n if (token.type === \"word\" || token.type === \"glob\" || token.type === \"singleQuote\" || token.type === \"doubleQuote\") {\n return this.parseWordArg();\n }\n\n throw new ParseError(`Expected pattern in case clause, got ${token.type}`);\n }\n\n private parseCaseBody(): ASTNode {\n const commands: ASTNode[] = [];\n this.skipNewlines();\n\n // Parse until ';;' or 'esac'\n while (!this.isAtEnd() && !this.check(\"doubleSemicolon\") && !this.checkKeyword(\"esac\")) {\n commands.push(this.parseAndOr());\n // Consume separator\n if (!this.match(\"semicolon\") && !this.match(\"newline\")) {\n break;\n }\n this.skipNewlines();\n // Check for terminators after consuming separators\n if (this.check(\"doubleSemicolon\") || this.checkKeyword(\"esac\")) {\n break;\n }\n }\n\n if (commands.length === 0) {\n return { type: \"command\", name: { type: \"literal\", value: \"true\" }, args: [], redirects: [], assignments: [] };\n }\n if (commands.length === 1) {\n return commands[0]!;\n }\n return { type: \"sequence\", commands };\n }\n\n // compound_list := and_or ((';'|'\\n') and_or)* [';'|'\\n']\n private parseCompoundList(terminators: KeywordValue[]): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n\n // Check for empty list\n if (this.isCompoundListTerminator(terminators)) {\n // Return a no-op command for empty list\n return { type: \"command\", name: { type: \"literal\", value: \"true\" }, args: [], redirects: [], assignments: [] };\n }\n\n commands.push(this.parseAndOr());\n\n while ((this.match(\"semicolon\") || this.match(\"newline\")) && !this.isAtEnd()) {\n this.skipNewlines();\n // Check for terminators\n if (this.isCompoundListTerminator(terminators)) {\n break;\n }\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private isCompoundListTerminator(terminators: KeywordValue[]): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return terminators.includes(token.value);\n }\n\n private checkKeyword(value: KeywordValue): boolean {\n const token = this.peek();\n return token.type === \"keyword\" && token.value === value;\n }\n\n private expectKeyword(value: KeywordValue): void {\n if (!this.checkKeyword(value)) {\n throw new ParseError(`Expected '${value}'`);\n }\n this.advance();\n // Don't skip newlines here - let the caller handle them\n // Newlines are significant as command separators in compound lists\n }\n\n // command := assignment* word+ redirect*\n private parseCommand(): CommandNode {\n const assignments: Array<{ name: string; value: ASTNode }> = [];\n const args: ASTNode[] = [];\n const redirects: Redirect[] = [];\n\n // Collect leading assignments\n while (this.check(\"assignment\")) {\n const token = this.advance() as Token & { type: \"assignment\" };\n assignments.push({\n name: token.name,\n value: this.tokenToNode(token.value),\n });\n }\n\n // Collect command name and arguments\n while (this.isWordToken()) {\n // Check if it's a heredoc token - convert to input redirect\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToNode(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n\n // Collect redirects\n while (this.check(\"redirect\")) {\n const redirect = this.parseRedirect();\n redirects.push(redirect);\n // After a redirect, there might be more words\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToNode(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n }\n\n if (args.length === 0 && assignments.length === 0 && redirects.length === 0) {\n throw new ParseError(\"Expected command\");\n }\n\n const name = args.shift() ?? { type: \"literal\" as const, value: redirects.length > 0 ? \":\" : \"\" };\n\n return {\n type: \"command\",\n name,\n args,\n redirects,\n assignments,\n };\n }\n\n private parseWordArg(): ASTNode {\n const token = this.advance();\n return this.tokenToNode(token);\n }\n\n private tokenToNode(token: Token | string | Token[]): ASTNode {\n if (typeof token === \"string\") {\n return { type: \"literal\", value: token };\n }\n\n if (Array.isArray(token)) {\n const parts = token.map((t) => this.tokenToNode(t));\n if (parts.length === 1) return parts[0]!;\n return { type: \"concat\", parts };\n }\n\n switch (token.type) {\n case \"word\":\n return { type: \"literal\", value: token.value };\n case \"singleQuote\":\n return { type: \"literal\", value: token.value };\n case \"doubleQuote\":\n return this.parseDoubleQuoteParts(token.parts);\n case \"variable\":\n return { type: \"variable\", name: token.name };\n case \"substitution\":\n // Parse the inner command\n const innerParser = new Parser(\n new (require(\"../lexer/lexer.ts\").Lexer)(token.command, { preserveNewlines: true }).tokenize()\n );\n return { type: \"substitution\", command: innerParser.parse() };\n case \"arithmetic\":\n return { type: \"arithmetic\", expression: token.expression };\n case \"glob\":\n return { type: \"glob\", pattern: token.pattern };\n case \"assignment\":\n return this.tokenToNode(token.value);\n case \"heredoc\":\n if (token.expand) {\n return this.parseHeredocContent(token.content);\n }\n return { type: \"literal\", value: token.content };\n default:\n throw new ParseError(`Unexpected token type: ${(token as Token).type}`);\n }\n }\n\n private parseDoubleQuoteParts(parts: Array<string | Token>): ASTNode {\n if (parts.length === 0) {\n return { type: \"literal\", value: \"\" };\n }\n\n if (parts.length === 1) {\n const part = parts[0]!;\n if (typeof part === \"string\") {\n return { type: \"literal\", value: part };\n }\n return this.tokenToNode(part);\n }\n\n const nodes: ASTNode[] = parts.map((part) => {\n if (typeof part === \"string\") {\n return { type: \"literal\" as const, value: part };\n }\n return this.tokenToNode(part);\n });\n\n return { type: \"concat\", parts: nodes };\n }\n\n private parseHeredocContent(content: string): ASTNode {\n // Parse content looking for $VAR and ${VAR} patterns\n const parts: ASTNode[] = [];\n let currentLiteral = \"\";\n let i = 0;\n\n while (i < content.length) {\n if (content[i] === \"$\") {\n // Flush current literal\n if (currentLiteral) {\n parts.push({ type: \"literal\", value: currentLiteral });\n currentLiteral = \"\";\n }\n\n i++; // consume $\n if (i >= content.length) {\n currentLiteral += \"$\";\n break;\n }\n\n if (content[i] === \"{\") {\n // ${VAR} syntax\n i++; // consume {\n let varName = \"\";\n while (i < content.length && content[i] !== \"}\") {\n varName += content[i];\n i++;\n }\n if (i < content.length && content[i] === \"}\") {\n i++; // consume }\n }\n if (varName) {\n parts.push({ type: \"variable\", name: varName });\n }\n } else if (/[a-zA-Z_]/.test(content[i] ?? \"\")) {\n // $VAR syntax\n let varName = \"\";\n while (i < content.length && /[a-zA-Z0-9_]/.test(content[i] ?? \"\")) {\n varName += content[i];\n i++;\n }\n parts.push({ type: \"variable\", name: varName });\n } else {\n // Not a variable, keep the $\n currentLiteral += \"$\";\n }\n } else {\n currentLiteral += content[i];\n i++;\n }\n }\n\n // Flush remaining literal\n if (currentLiteral) {\n parts.push({ type: \"literal\", value: currentLiteral });\n }\n\n if (parts.length === 0) {\n return { type: \"literal\", value: \"\" };\n }\n if (parts.length === 1) {\n return parts[0]!;\n }\n return { type: \"concat\", parts };\n }\n\n private parseRedirect(): Redirect {\n const token = this.advance() as Token & { type: \"redirect\" };\n const mode = token.mode as RedirectMode;\n\n // 2>&1 and 1>&2 don't have a target\n if (mode === \"2>&1\" || mode === \"1>&2\") {\n return { mode, target: { type: \"literal\", value: \"\" } };\n }\n\n if (!this.isWordToken()) {\n throw new ParseError(`Expected redirect target after ${mode}`);\n }\n\n const target = this.parseWordArg();\n return { mode, target };\n }\n\n private isWordToken(): boolean {\n const token = this.peek();\n return (\n Array.isArray(token) ||\n token.type === \"word\" ||\n token.type === \"singleQuote\" ||\n token.type === \"doubleQuote\" ||\n token.type === \"variable\" ||\n token.type === \"substitution\" ||\n token.type === \"arithmetic\" ||\n token.type === \"glob\" ||\n token.type === \"heredoc\"\n );\n }\n\n private check(type: Token[\"type\"]): boolean {\n return this.peek().type === type;\n }\n\n private match(type: Token[\"type\"]): boolean {\n if (this.check(type)) {\n this.advance();\n return true;\n }\n return false;\n }\n\n private peek(): Token {\n return this.tokens[this.pos] ?? { type: \"eof\" };\n }\n\n private advance(): Token {\n const token = this.peek();\n this.pos++;\n return token;\n }\n\n private isAtEnd(): boolean {\n return this.peek().type === \"eof\";\n }\n}\n\nexport function parse(tokens: Token[]): ASTNode {\n return new Parser(tokens).parse();\n}\n"
|
|
5
|
+
"import { ParseError } from \"../errors.cjs\";\nimport { Lexer } from \"../lexer/lexer.cjs\";\nimport type { Token, KeywordValue } from \"../lexer/tokens.cjs\";\nimport type { ASTNode, Redirect, RedirectMode, CommandNode, IfNode, ForNode, WhileNode, UntilNode, CaseNode, CaseClause } from \"./ast.cjs\";\n\nexport class Parser {\n private tokens: Token[];\n private pos: number = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n parse(): ASTNode {\n const result = this.parseSequence();\n if (!this.isAtEnd()) {\n throw new ParseError(`Unexpected token: ${JSON.stringify(this.peek())}`);\n }\n return result;\n }\n\n // sequence := and_or ((';'|'\\n') and_or)*\n private parseSequence(): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n commands.push(this.parseAndOr());\n\n while (this.match(\"semicolon\") || this.match(\"newline\")) {\n this.skipNewlines();\n // Skip empty commands after separator, or stop at terminating keywords\n if (this.isAtEnd() || this.check(\"semicolon\") || this.check(\"newline\") || this.isTerminatingKeyword()) continue;\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private skipNewlines(): void {\n while (this.match(\"newline\")) {\n // keep consuming newlines\n }\n }\n\n private isTerminatingKeyword(): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return [\"then\", \"elif\", \"else\", \"fi\", \"do\", \"done\", \"esac\"].includes(token.value);\n }\n\n // and_or := pipeline (('&&'|'||') pipeline)*\n private parseAndOr(): ASTNode {\n let left = this.parsePipeline();\n\n while (this.check(\"and\") || this.check(\"or\")) {\n if (this.match(\"and\")) {\n const right = this.parsePipeline();\n left = { type: \"and\", left, right };\n } else if (this.match(\"or\")) {\n const right = this.parsePipeline();\n left = { type: \"or\", left, right };\n }\n }\n\n return left;\n }\n\n // pipeline := command ('|' command)*\n private parsePipeline(): ASTNode {\n const commands: ASTNode[] = [];\n commands.push(this.parseCompoundOrCommand());\n\n while (this.match(\"pipe\")) {\n this.skipNewlines();\n commands.push(this.parseCompoundOrCommand());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"pipeline\", commands };\n }\n\n // compound_or_command := compound_command | simple_command\n private parseCompoundOrCommand(): ASTNode {\n this.skipNewlines();\n const token = this.peek();\n\n if (token.type === \"keyword\") {\n switch (token.value) {\n case \"if\":\n return this.parseIf();\n case \"for\":\n return this.parseFor();\n case \"while\":\n return this.parseWhile();\n case \"until\":\n return this.parseUntil();\n case \"case\":\n return this.parseCase();\n }\n }\n\n return this.parseCommand();\n }\n\n // if := 'if' compound_list 'then' compound_list ('elif' compound_list 'then' compound_list)* ['else' compound_list] 'fi'\n private parseIf(): IfNode {\n this.expectKeyword(\"if\");\n const condition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const thenBranch = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n\n const elifBranches: Array<{ condition: ASTNode; body: ASTNode }> = [];\n while (this.checkKeyword(\"elif\")) {\n this.expectKeyword(\"elif\");\n const elifCondition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const elifBody = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n elifBranches.push({ condition: elifCondition, body: elifBody });\n }\n\n let elseBranch: ASTNode | undefined;\n if (this.checkKeyword(\"else\")) {\n this.expectKeyword(\"else\");\n elseBranch = this.parseCompoundList([\"fi\"]);\n }\n\n this.expectKeyword(\"fi\");\n\n return {\n type: \"if\",\n condition,\n thenBranch,\n elifBranches,\n elseBranch,\n };\n }\n\n // for := 'for' NAME ['in' word*] (';'|'\\n') 'do' compound_list 'done'\n private parseFor(): ForNode {\n this.expectKeyword(\"for\");\n\n // Get variable name\n const varToken = this.peek();\n if (varToken.type !== \"word\") {\n throw new ParseError(\"Expected variable name after 'for'\");\n }\n this.advance();\n const variable = varToken.value;\n\n // Parse optional 'in' clause\n const items: ASTNode[] = [];\n if (this.checkKeyword(\"in\")) {\n this.expectKeyword(\"in\");\n // Read items until semicolon, newline, or 'do'\n while (!this.isAtEnd() && !this.check(\"semicolon\") && !this.check(\"newline\") && !this.checkKeyword(\"do\")) {\n items.push(this.parseWordArg());\n }\n }\n\n // Consume separator (semicolon or newline)\n if (!this.match(\"semicolon\")) {\n this.match(\"newline\");\n }\n this.skipNewlines();\n\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"for\",\n variable,\n items,\n body,\n };\n }\n\n // while := 'while' compound_list 'do' compound_list 'done'\n private parseWhile(): WhileNode {\n this.expectKeyword(\"while\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"while\",\n condition,\n body,\n };\n }\n\n // until := 'until' compound_list 'do' compound_list 'done'\n private parseUntil(): UntilNode {\n this.expectKeyword(\"until\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"until\",\n condition,\n body,\n };\n }\n\n // case := 'case' word 'in' (pattern ('|' pattern)* ')' compound_list ';;')* 'esac'\n private parseCase(): CaseNode {\n this.expectKeyword(\"case\");\n const word = this.parseWordArg();\n this.expectKeyword(\"in\");\n this.skipNewlines();\n\n const clauses: CaseClause[] = [];\n\n while (!this.isAtEnd() && !this.checkKeyword(\"esac\")) {\n // Parse patterns separated by '|'\n // Skip leading '(' if present\n this.match(\"openParen\");\n\n const patterns: ASTNode[] = [];\n patterns.push(this.parseCasePattern());\n\n while (this.match(\"pipe\")) {\n patterns.push(this.parseCasePattern());\n }\n\n // Expect ')'\n if (!this.match(\"closeParen\")) {\n throw new ParseError(\"Expected ')' after case pattern\");\n }\n\n // Parse body until ';;' or 'esac'\n const body = this.parseCaseBody();\n\n clauses.push({ patterns, body });\n\n // ';;' is optional for the last clause\n this.match(\"doubleSemicolon\");\n this.skipNewlines();\n }\n\n this.expectKeyword(\"esac\");\n\n return {\n type: \"case\",\n word,\n clauses,\n };\n }\n\n private parseCasePattern(): ASTNode {\n const token = this.peek();\n\n // Handle glob patterns and words\n if (token.type === \"word\" || token.type === \"glob\" || token.type === \"singleQuote\" || token.type === \"doubleQuote\") {\n return this.parseWordArg();\n }\n\n throw new ParseError(`Expected pattern in case clause, got ${token.type}`);\n }\n\n private parseCaseBody(): ASTNode {\n const commands: ASTNode[] = [];\n this.skipNewlines();\n\n // Parse until ';;' or 'esac'\n while (!this.isAtEnd() && !this.check(\"doubleSemicolon\") && !this.checkKeyword(\"esac\")) {\n commands.push(this.parseAndOr());\n // Consume separator\n if (!this.match(\"semicolon\") && !this.match(\"newline\")) {\n break;\n }\n this.skipNewlines();\n // Check for terminators after consuming separators\n if (this.check(\"doubleSemicolon\") || this.checkKeyword(\"esac\")) {\n break;\n }\n }\n\n if (commands.length === 0) {\n return { type: \"command\", name: { type: \"literal\", value: \"true\" }, args: [], redirects: [], assignments: [] };\n }\n if (commands.length === 1) {\n return commands[0]!;\n }\n return { type: \"sequence\", commands };\n }\n\n // compound_list := and_or ((';'|'\\n') and_or)* [';'|'\\n']\n private parseCompoundList(terminators: KeywordValue[]): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n\n // Check for empty list\n if (this.isCompoundListTerminator(terminators)) {\n // Return a no-op command for empty list\n return { type: \"command\", name: { type: \"literal\", value: \"true\" }, args: [], redirects: [], assignments: [] };\n }\n\n commands.push(this.parseAndOr());\n\n while ((this.match(\"semicolon\") || this.match(\"newline\")) && !this.isAtEnd()) {\n this.skipNewlines();\n // Check for terminators\n if (this.isCompoundListTerminator(terminators)) {\n break;\n }\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private isCompoundListTerminator(terminators: KeywordValue[]): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return terminators.includes(token.value);\n }\n\n private checkKeyword(value: KeywordValue): boolean {\n const token = this.peek();\n return token.type === \"keyword\" && token.value === value;\n }\n\n private expectKeyword(value: KeywordValue): void {\n if (!this.checkKeyword(value)) {\n throw new ParseError(`Expected '${value}'`);\n }\n this.advance();\n // Don't skip newlines here - let the caller handle them\n // Newlines are significant as command separators in compound lists\n }\n\n // command := assignment* word+ redirect*\n private parseCommand(): CommandNode {\n const assignments: Array<{ name: string; value: ASTNode }> = [];\n const args: ASTNode[] = [];\n const redirects: Redirect[] = [];\n\n // Collect leading assignments\n while (this.check(\"assignment\")) {\n const token = this.advance() as Token & { type: \"assignment\" };\n assignments.push({\n name: token.name,\n value: this.tokenToNode(token.value),\n });\n }\n\n // Collect command name and arguments\n while (this.isWordToken()) {\n // Check if it's a heredoc token - convert to input redirect\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToNode(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n\n // Collect redirects\n while (this.check(\"redirect\")) {\n const redirect = this.parseRedirect();\n redirects.push(redirect);\n // After a redirect, there might be more words\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToNode(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n }\n\n if (args.length === 0 && assignments.length === 0 && redirects.length === 0) {\n throw new ParseError(\"Expected command\");\n }\n\n const name = args.shift() ?? { type: \"literal\" as const, value: redirects.length > 0 ? \":\" : \"\" };\n\n return {\n type: \"command\",\n name,\n args,\n redirects,\n assignments,\n };\n }\n\n private parseWordArg(): ASTNode {\n const token = this.advance();\n return this.tokenToNode(token);\n }\n\n private tokenToNode(token: Token | string | Token[]): ASTNode {\n if (typeof token === \"string\") {\n return { type: \"literal\", value: token };\n }\n\n if (Array.isArray(token)) {\n const parts = token.map((t) => this.tokenToNode(t));\n if (parts.length === 1) return parts[0]!;\n return { type: \"concat\", parts };\n }\n\n switch (token.type) {\n case \"word\":\n return { type: \"literal\", value: token.value };\n case \"singleQuote\":\n return { type: \"literal\", value: token.value };\n case \"doubleQuote\":\n return this.parseDoubleQuoteParts(token.parts);\n case \"variable\":\n return { type: \"variable\", name: token.name };\n case \"substitution\":\n // Parse the inner command\n const innerParser = new Parser(\n new Lexer(token.command, { preserveNewlines: true }).tokenize()\n );\n return { type: \"substitution\", command: innerParser.parse() };\n case \"arithmetic\":\n return { type: \"arithmetic\", expression: token.expression };\n case \"glob\":\n return { type: \"glob\", pattern: token.pattern };\n case \"assignment\":\n return this.tokenToNode(token.value);\n case \"heredoc\":\n if (token.expand) {\n return this.parseHeredocContent(token.content);\n }\n return { type: \"literal\", value: token.content };\n default:\n throw new ParseError(`Unexpected token type: ${(token as Token).type}`);\n }\n }\n\n private parseDoubleQuoteParts(parts: Array<string | Token>): ASTNode {\n if (parts.length === 0) {\n return { type: \"literal\", value: \"\" };\n }\n\n if (parts.length === 1) {\n const part = parts[0]!;\n if (typeof part === \"string\") {\n return { type: \"literal\", value: part };\n }\n return this.tokenToNode(part);\n }\n\n const nodes: ASTNode[] = parts.map((part) => {\n if (typeof part === \"string\") {\n return { type: \"literal\" as const, value: part };\n }\n return this.tokenToNode(part);\n });\n\n return { type: \"concat\", parts: nodes };\n }\n\n private parseHeredocContent(content: string): ASTNode {\n // Parse content looking for $VAR and ${VAR} patterns\n const parts: ASTNode[] = [];\n let currentLiteral = \"\";\n let i = 0;\n\n while (i < content.length) {\n if (content[i] === \"$\") {\n // Flush current literal\n if (currentLiteral) {\n parts.push({ type: \"literal\", value: currentLiteral });\n currentLiteral = \"\";\n }\n\n i++; // consume $\n if (i >= content.length) {\n currentLiteral += \"$\";\n break;\n }\n\n if (content[i] === \"{\") {\n // ${VAR} syntax\n i++; // consume {\n let varName = \"\";\n while (i < content.length && content[i] !== \"}\") {\n varName += content[i];\n i++;\n }\n if (i < content.length && content[i] === \"}\") {\n i++; // consume }\n }\n if (varName) {\n parts.push({ type: \"variable\", name: varName });\n }\n } else if (/[a-zA-Z_]/.test(content[i] ?? \"\")) {\n // $VAR syntax\n let varName = \"\";\n while (i < content.length && /[a-zA-Z0-9_]/.test(content[i] ?? \"\")) {\n varName += content[i];\n i++;\n }\n parts.push({ type: \"variable\", name: varName });\n } else {\n // Not a variable, keep the $\n currentLiteral += \"$\";\n }\n } else {\n currentLiteral += content[i];\n i++;\n }\n }\n\n // Flush remaining literal\n if (currentLiteral) {\n parts.push({ type: \"literal\", value: currentLiteral });\n }\n\n if (parts.length === 0) {\n return { type: \"literal\", value: \"\" };\n }\n if (parts.length === 1) {\n return parts[0]!;\n }\n return { type: \"concat\", parts };\n }\n\n private parseRedirect(): Redirect {\n const token = this.advance() as Token & { type: \"redirect\" };\n const mode = token.mode as RedirectMode;\n\n // 2>&1 and 1>&2 don't have a target\n if (mode === \"2>&1\" || mode === \"1>&2\") {\n return { mode, target: { type: \"literal\", value: \"\" } };\n }\n\n if (!this.isWordToken()) {\n throw new ParseError(`Expected redirect target after ${mode}`);\n }\n\n const target = this.parseWordArg();\n return { mode, target };\n }\n\n private isWordToken(): boolean {\n const token = this.peek();\n return (\n Array.isArray(token) ||\n token.type === \"word\" ||\n token.type === \"singleQuote\" ||\n token.type === \"doubleQuote\" ||\n token.type === \"variable\" ||\n token.type === \"substitution\" ||\n token.type === \"arithmetic\" ||\n token.type === \"glob\" ||\n token.type === \"heredoc\"\n );\n }\n\n private check(type: Token[\"type\"]): boolean {\n return this.peek().type === type;\n }\n\n private match(type: Token[\"type\"]): boolean {\n if (this.check(type)) {\n this.advance();\n return true;\n }\n return false;\n }\n\n private peek(): Token {\n return this.tokens[this.pos] ?? { type: \"eof\" };\n }\n\n private advance(): Token {\n const token = this.peek();\n this.pos++;\n return token;\n }\n\n private isAtEnd(): boolean {\n return this.peek().type === \"eof\";\n }\n}\n\nexport function parse(tokens: Token[]): ASTNode {\n return new Parser(tokens).parse();\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "4B60404E2B30A49A64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -48,6 +48,7 @@ class ShellDSL {
|
|
|
48
48
|
currentEnv;
|
|
49
49
|
commands;
|
|
50
50
|
shouldThrow = true;
|
|
51
|
+
isTTY;
|
|
51
52
|
constructor(config) {
|
|
52
53
|
this.fs = config.fs;
|
|
53
54
|
this.initialCwd = config.cwd;
|
|
@@ -55,6 +56,7 @@ class ShellDSL {
|
|
|
55
56
|
this.currentCwd = config.cwd;
|
|
56
57
|
this.currentEnv = { ...config.env };
|
|
57
58
|
this.commands = config.commands;
|
|
59
|
+
this.isTTY = config.isTTY ?? false;
|
|
58
60
|
}
|
|
59
61
|
tag(strings, ...values) {
|
|
60
62
|
let source = strings[0] ?? "";
|
|
@@ -104,7 +106,8 @@ class ShellDSL {
|
|
|
104
106
|
cwd,
|
|
105
107
|
env,
|
|
106
108
|
commands: shell.commands,
|
|
107
|
-
redirectObjects: options?.redirectObjects
|
|
109
|
+
redirectObjects: options?.redirectObjects,
|
|
110
|
+
isTTY: shell.isTTY
|
|
108
111
|
});
|
|
109
112
|
const tokens = shell.lex(source);
|
|
110
113
|
const ast = shell.parse(tokens);
|
|
@@ -150,7 +153,8 @@ class ShellDSL {
|
|
|
150
153
|
fs: this.fs,
|
|
151
154
|
cwd: this.currentCwd,
|
|
152
155
|
env: this.currentEnv,
|
|
153
|
-
commands: this.commands
|
|
156
|
+
commands: this.commands,
|
|
157
|
+
isTTY: this.isTTY
|
|
154
158
|
});
|
|
155
159
|
return interpreter.execute(program.ast);
|
|
156
160
|
}
|
|
@@ -168,7 +172,8 @@ function createShellDSL(config) {
|
|
|
168
172
|
currentCwd: shell.currentCwd,
|
|
169
173
|
currentEnv: shell.currentEnv,
|
|
170
174
|
commands: shell.commands,
|
|
171
|
-
shouldThrow: shell.shouldThrow
|
|
175
|
+
shouldThrow: shell.shouldThrow,
|
|
176
|
+
isTTY: shell.isTTY
|
|
172
177
|
});
|
|
173
178
|
tag.cwd = shell.cwd.bind(shell);
|
|
174
179
|
tag.env = shell.env.bind(shell);
|
|
@@ -184,4 +189,4 @@ function createShellDSL(config) {
|
|
|
184
189
|
return tag;
|
|
185
190
|
}
|
|
186
191
|
|
|
187
|
-
//# debugId=
|
|
192
|
+
//# debugId=4F2755F3D7D4D32164756E2164756E21
|