shell-dsl 0.0.38 → 0.0.40
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 +118 -3
- package/dist/cjs/index.cjs +2 -1
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/commands/exit/exit.cjs +84 -0
- package/dist/cjs/src/commands/exit/exit.cjs.map +10 -0
- package/dist/cjs/src/commands/index.cjs +22 -2
- package/dist/cjs/src/commands/index.cjs.map +3 -3
- package/dist/cjs/src/commands/printf/printf.cjs +416 -0
- package/dist/cjs/src/commands/printf/printf.cjs.map +10 -0
- package/dist/cjs/src/commands/sh/sh.cjs +134 -0
- package/dist/cjs/src/commands/sh/sh.cjs.map +10 -0
- package/dist/cjs/src/index.cjs +2 -1
- package/dist/cjs/src/index.cjs.map +3 -3
- package/dist/cjs/src/interpreter/context.cjs +4 -1
- package/dist/cjs/src/interpreter/context.cjs.map +3 -3
- package/dist/cjs/src/interpreter/index.cjs +2 -1
- package/dist/cjs/src/interpreter/index.cjs.map +3 -3
- package/dist/cjs/src/interpreter/interpreter.cjs +301 -76
- package/dist/cjs/src/interpreter/interpreter.cjs.map +3 -3
- package/dist/cjs/src/lexer/lexer.cjs +13 -1
- package/dist/cjs/src/lexer/lexer.cjs.map +3 -3
- package/dist/cjs/src/parser/parser.cjs +11 -1
- package/dist/cjs/src/parser/parser.cjs.map +3 -3
- package/dist/cjs/src/types.cjs.map +2 -2
- package/dist/mjs/index.mjs +3 -1
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/src/commands/exit/exit.mjs +44 -0
- package/dist/mjs/src/commands/exit/exit.mjs.map +10 -0
- package/dist/mjs/src/commands/index.mjs +22 -2
- package/dist/mjs/src/commands/index.mjs.map +3 -3
- package/dist/mjs/src/commands/printf/printf.mjs +376 -0
- package/dist/mjs/src/commands/printf/printf.mjs.map +10 -0
- package/dist/mjs/src/commands/sh/sh.mjs +94 -0
- package/dist/mjs/src/commands/sh/sh.mjs.map +10 -0
- package/dist/mjs/src/index.mjs +3 -2
- package/dist/mjs/src/index.mjs.map +3 -3
- package/dist/mjs/src/interpreter/context.mjs +4 -1
- package/dist/mjs/src/interpreter/context.mjs.map +3 -3
- package/dist/mjs/src/interpreter/index.mjs +3 -2
- package/dist/mjs/src/interpreter/index.mjs.map +2 -2
- package/dist/mjs/src/interpreter/interpreter.mjs +301 -76
- package/dist/mjs/src/interpreter/interpreter.mjs.map +3 -3
- package/dist/mjs/src/lexer/lexer.mjs +13 -1
- package/dist/mjs/src/lexer/lexer.mjs.map +3 -3
- package/dist/mjs/src/parser/parser.mjs +11 -1
- package/dist/mjs/src/parser/parser.mjs.map +3 -3
- package/dist/mjs/src/types.mjs.map +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/src/commands/exit/exit.d.ts +2 -0
- package/dist/types/src/commands/index.d.ts +3 -0
- package/dist/types/src/commands/printf/printf.d.ts +2 -0
- package/dist/types/src/commands/sh/sh.d.ts +5 -0
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/interpreter/context.d.ts +2 -1
- package/dist/types/src/interpreter/index.d.ts +1 -1
- package/dist/types/src/interpreter/interpreter.d.ts +24 -0
- package/dist/types/src/types.d.ts +13 -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 {\n ASTNode,\n CommandNode,\n Redirect,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n WordNode,\n WordPart,\n} from \"../parser/ast.mjs\";\nimport type { Command, VirtualFS, ExecResult, OutputCollector, RedirectObjectMap } from \"../types.mjs\";\nimport { createCommandContext } from \"./context.mjs\";\nimport { createStdin } from \"../io/stdin.mjs\";\nimport { createStdout, createStderr, createPipe, PipeBuffer, createBufferTargetCollector } from \"../io/stdout.mjs\";\nimport { isDevNullPath } from \"../fs/special-files.mjs\";\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\ninterface ExpandedSegment {\n value: string;\n quoted: boolean;\n}\n\ninterface ExpandedField {\n segments: ExpandedSegment[];\n}\n\nconst DEFAULT_IFS = \" \\t\\n\";\nconst GLOB_META_CHARS = /[*?[{]/;\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 unknown 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 const assignmentEnv = { ...this.env };\n for (const assignment of node.assignments) {\n assignmentEnv[assignment.name] = await this.expandWordScalar(assignment.value, assignmentEnv);\n }\n\n const expandedWords = await this.expandCommandWords(node, this.env);\n const [name, ...args] = expandedWords;\n\n if (name === undefined || name === \"\") {\n if (node.assignments.length > 0) {\n for (const assignment of node.assignments) {\n this.env[assignment.name] = assignmentEnv[assignment.name] ?? \"\";\n }\n }\n return 0;\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 this.env\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.expandWordScalar(redirect.target, this.env);\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 exec closure for sub-command invocation\n const exec = async (cmdName: string, cmdArgs: string[]) => {\n const cmd = this.commands[cmdName];\n if (!cmd) {\n return {\n stdout: Buffer.alloc(0),\n stderr: Buffer.from(`${cmdName}: command not found\\n`),\n exitCode: 127,\n };\n }\n const subStdout = createStdout();\n const subStderr = createStderr();\n const subCtx = createCommandContext({\n args: cmdArgs,\n stdin: createStdin(null),\n stdout: subStdout,\n stderr: subStderr,\n fs: this.fs,\n cwd: this.cwd,\n env: { ...assignmentEnv },\n setCwd: (path: string) => this.setCwd(path),\n exec,\n });\n let exitCode: number;\n try {\n exitCode = await cmd(subCtx);\n } catch (err) {\n if (err instanceof BreakException || err instanceof ContinueException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await subStderr.writeText(`${cmdName}: ${message}\\n`);\n exitCode = 1;\n }\n subStdout.close();\n subStderr.close();\n return {\n stdout: await subStdout.collect(),\n stderr: await subStderr.collect(),\n exitCode,\n };\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: assignmentEnv,\n setCwd: (path: string) => this.setCwd(path),\n exec,\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.expandWordScalar(writeRedirects[writeRedirects.length - 1]!.target, this.env)\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 env: Record<string, string>\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.expandWordScalar(redirect.target, env);\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 const expandedItems: string[] = [];\n for (const item of node.items) {\n expandedItems.push(...(await this.expandWordForCommand(item, this.env)));\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.expandWordScalar(node.word, this.env);\n\n for (const clause of node.clauses) {\n for (const patternNode of clause.patterns) {\n const pattern = await this.expandWordScalar(patternNode, this.env);\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 expandCommandWords(node: CommandNode, env: Record<string, string>): Promise<string[]> {\n const expanded: string[] = [];\n for (const word of [node.name, ...node.args]) {\n expanded.push(...(await this.expandWordForCommand(word, env)));\n }\n return expanded;\n }\n\n private async expandWordForCommand(word: WordNode, env: Record<string, string>): Promise<string[]> {\n const fields = await this.expandWordFields(word, env);\n const expanded: string[] = [];\n for (const field of fields) {\n expanded.push(...(await this.expandPathname(field)));\n }\n return expanded;\n }\n\n private async expandWordScalar(word: WordNode, env: Record<string, string>): Promise<string> {\n let result = \"\";\n for (const part of word.parts) {\n result += await this.expandWordPart(part, env);\n }\n return result;\n }\n\n private async expandWordFields(word: WordNode, env: Record<string, string>): Promise<ExpandedField[]> {\n const fields: ExpandedField[] = [this.createExpandedField()];\n const ifs = this.getIFS(env);\n\n for (const part of word.parts) {\n if (part.type === \"text\") {\n this.appendSegment(fields[fields.length - 1]!, part.value, part.quoted);\n continue;\n }\n\n const value = await this.expandWordPart(part, env);\n if (part.quoted) {\n this.appendSegment(fields[fields.length - 1]!, value, true);\n continue;\n }\n\n const splitFields = this.splitUnquotedExpansion(value, ifs);\n if (splitFields.length === 0) {\n continue;\n }\n\n this.appendSegment(fields[fields.length - 1]!, splitFields[0]!, false);\n for (let i = 1; i < splitFields.length; i++) {\n const field = this.createExpandedField();\n this.appendSegment(field, splitFields[i]!, false);\n fields.push(field);\n }\n }\n\n return fields.filter((field) => field.segments.length > 0);\n }\n\n private async expandWordPart(part: WordPart, env: Record<string, string>): Promise<string> {\n switch (part.type) {\n case \"text\":\n return part.value;\n case \"variable\":\n return env[part.name] ?? \"\";\n case \"substitution\":\n return this.executeSubstitution(part.command, env);\n case \"arithmetic\":\n return String(this.evaluateArithmetic(part.expression, env));\n default:\n throw new Error(\"Cannot expand unknown word part\");\n }\n }\n\n private async executeSubstitution(command: ASTNode, env: Record<string, string>): Promise<string> {\n const interpreter = new Interpreter({\n fs: this.fs,\n cwd: this.cwd,\n env,\n commands: this.commands,\n redirectObjects: this.redirectObjects,\n isTTY: false,\n });\n const result = await interpreter.execute(command);\n return result.stdout.toString(\"utf-8\").replace(/\\n+$/, \"\");\n }\n\n private getIFS(env: Record<string, string>): string {\n return env.IFS ?? DEFAULT_IFS;\n }\n\n private splitUnquotedExpansion(value: string, ifs: string): string[] {\n if (value.length === 0) {\n return [];\n }\n if (ifs === \"\") {\n return [value];\n }\n\n const ifsChars = new Set(ifs);\n const isIfsWhitespace = (char: string) =>\n ifsChars.has(char) && (char === \" \" || char === \"\\t\" || char === \"\\n\");\n const isIfsNonWhitespace = (char: string) => ifsChars.has(char) && !isIfsWhitespace(char);\n\n const fields: string[] = [];\n let i = 0;\n\n while (i < value.length && isIfsWhitespace(value[i]!)) {\n i++;\n }\n\n let fieldStart = i;\n let lastDelimiterWasNonWhitespace = false;\n\n while (i < value.length) {\n const char = value[i]!;\n\n if (isIfsNonWhitespace(char)) {\n fields.push(value.slice(fieldStart, i));\n i++;\n while (i < value.length && isIfsWhitespace(value[i]!)) {\n i++;\n }\n fieldStart = i;\n lastDelimiterWasNonWhitespace = true;\n continue;\n }\n\n if (isIfsWhitespace(char)) {\n fields.push(value.slice(fieldStart, i));\n while (i < value.length && isIfsWhitespace(value[i]!)) {\n i++;\n }\n if (i < value.length && isIfsNonWhitespace(value[i]!)) {\n i++;\n while (i < value.length && isIfsWhitespace(value[i]!)) {\n i++;\n }\n lastDelimiterWasNonWhitespace = true;\n } else {\n lastDelimiterWasNonWhitespace = false;\n }\n fieldStart = i;\n continue;\n }\n\n lastDelimiterWasNonWhitespace = false;\n i++;\n }\n\n if (fieldStart < value.length) {\n fields.push(value.slice(fieldStart));\n } else if (lastDelimiterWasNonWhitespace) {\n fields.push(\"\");\n }\n\n return fields;\n }\n\n private createExpandedField(): ExpandedField {\n return { segments: [] };\n }\n\n private appendSegment(field: ExpandedField, value: string, quoted: boolean): void {\n const lastSegment = field.segments[field.segments.length - 1];\n if (lastSegment && lastSegment.quoted === quoted) {\n lastSegment.value += value;\n return;\n }\n field.segments.push({ value, quoted });\n }\n\n private async expandPathname(field: ExpandedField): Promise<string[]> {\n if (!this.hasUnquotedGlobMeta(field)) {\n return [this.fieldToString(field)];\n }\n\n const pattern = this.fieldToGlobPattern(field);\n const matches = await this.fs.glob(pattern, { cwd: this.cwd });\n return matches.length > 0 ? matches : [this.fieldToString(field)];\n }\n\n private hasUnquotedGlobMeta(field: ExpandedField): boolean {\n return field.segments.some((segment) => !segment.quoted && GLOB_META_CHARS.test(segment.value));\n }\n\n private fieldToString(field: ExpandedField): string {\n return field.segments.map((segment) => segment.value).join(\"\");\n }\n\n private fieldToGlobPattern(field: ExpandedField): string {\n return field.segments\n .map((segment) => (segment.quoted ? this.escapeLiteralGlobChars(segment.value) : segment.value))\n .join(\"\");\n }\n\n private escapeLiteralGlobChars(value: string): string {\n return value\n .replaceAll(\"[\", \"[[]\")\n .replaceAll(\"]\", \"[]]\")\n .replaceAll(\"*\", \"[*]\")\n .replaceAll(\"?\", \"[?]\")\n .replaceAll(\"{\", \"[{]\")\n .replaceAll(\"}\", \"[}]\");\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 {\n ASTNode,\n CommandNode,\n Redirect,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n WordNode,\n WordPart,\n} from \"../parser/ast.mjs\";\nimport type { Command, VirtualFS, ExecResult, OutputCollector, RedirectObjectMap, ShellCommandApi } from \"../types.mjs\";\nimport { createCommandContext } from \"./context.mjs\";\nimport { Lexer } from \"../lexer/lexer.mjs\";\nimport { Parser } from \"../parser/parser.mjs\";\nimport { createStdin } from \"../io/stdin.mjs\";\nimport { createStdout, createStderr, createPipe, PipeBuffer, createBufferTargetCollector } from \"../io/stdout.mjs\";\nimport { isDevNullPath } from \"../fs/special-files.mjs\";\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 argv0?: string;\n positionalParameters?: string[];\n lastExitCode?: number;\n}\n\ninterface ExpandedSegment {\n value: string;\n quoted: boolean;\n}\n\ninterface ExpandedField {\n segments: ExpandedSegment[];\n}\n\nconst DEFAULT_IFS = \" \\t\\n\";\nconst GLOB_META_CHARS = /[*?[{]/;\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 ExitException extends Error {\n constructor(public exitCode: number) {\n super(\"exit\");\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 private argv0: string;\n private positionalParameters: string[];\n private lastExitCode: number;\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 this.argv0 = options.argv0 ?? \"sh\";\n this.positionalParameters = [...(options.positionalParameters ?? [])];\n this.lastExitCode = options.lastExitCode ?? 0;\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 let exitCode: number;\n try {\n exitCode = await this.executeNode(ast, null, stdout, stderr);\n } catch (err) {\n if (!(err instanceof ExitException)) {\n throw err;\n }\n exitCode = err.exitCode;\n this.lastExitCode = exitCode;\n }\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 let exitCode: number;\n switch (node.type) {\n case \"command\":\n exitCode = await this.executeCommand(node, stdinSource, stdout, stderr);\n break;\n case \"pipeline\":\n exitCode = await this.executePipeline(node.commands, stdinSource, stdout, stderr);\n break;\n case \"sequence\":\n exitCode = await this.executeSequence(node.commands, stdinSource, stdout, stderr);\n break;\n case \"and\":\n exitCode = await this.executeAnd(node.left, node.right, stdinSource, stdout, stderr);\n break;\n case \"or\":\n exitCode = await this.executeOr(node.left, node.right, stdinSource, stdout, stderr);\n break;\n case \"if\":\n exitCode = await this.executeIf(node, stdinSource, stdout, stderr);\n break;\n case \"for\":\n exitCode = await this.executeFor(node, stdinSource, stdout, stderr);\n break;\n case \"while\":\n exitCode = await this.executeWhile(node, stdinSource, stdout, stderr);\n break;\n case \"until\":\n exitCode = await this.executeUntil(node, stdinSource, stdout, stderr);\n break;\n case \"case\":\n exitCode = await this.executeCase(node, stdinSource, stdout, stderr);\n break;\n default:\n throw new Error(\"Cannot execute unknown node type\");\n }\n this.lastExitCode = exitCode;\n return exitCode;\n }\n\n private async executeCommand(\n node: CommandNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const assignmentEnv = { ...this.env };\n for (const assignment of node.assignments) {\n assignmentEnv[assignment.name] = await this.expandWordScalar(assignment.value, assignmentEnv);\n }\n\n const expandedWords = await this.expandCommandWords(node, this.env);\n const [name, ...args] = expandedWords;\n\n if (name === undefined || name === \"\") {\n if (node.assignments.length > 0) {\n for (const assignment of node.assignments) {\n this.env[assignment.name] = assignmentEnv[assignment.name] ?? \"\";\n }\n }\n return 0;\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 this.env\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.expandWordScalar(redirect.target, this.env);\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 let exitCode = await this.invokeCommand(\n name,\n args,\n actualStdin,\n actualStdout,\n actualStderr,\n assignmentEnv\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.expandWordScalar(writeRedirects[writeRedirects.length - 1]!.target, this.env)\n : \"unknown\";\n await stderr.writeText(`sh: ${target}: ${message}\\n`);\n exitCode = 1;\n }\n\n return exitCode;\n }\n\n private async invokeCommand(\n name: string,\n args: string[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector,\n env: Record<string, string>\n ): Promise<number> {\n const command = this.commands[name];\n if (command) {\n return this.invokeRegisteredCommand(name, command, args, stdinSource, stdout, stderr, env);\n }\n\n if (name.includes(\"/\")) {\n return this.executeExecutableFile(name, args, stdinSource, stdout, stderr, env);\n }\n\n await stderr.writeText(`${name}: command not found\\n`);\n return 127;\n }\n\n private async invokeRegisteredCommand(\n name: string,\n command: Command,\n args: string[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector,\n env: Record<string, string>\n ): Promise<number> {\n const exec = this.createExec(env);\n const shell = this.createShellApi(stdinSource, stdout, stderr, env);\n const ctx = createCommandContext({\n args,\n stdin: createStdin(stdinSource),\n stdout,\n stderr,\n fs: this.fs,\n cwd: this.cwd,\n env,\n setCwd: (path: string) => this.setCwd(path),\n exec,\n shell,\n });\n\n try {\n return await command(ctx);\n } catch (err) {\n if (err instanceof BreakException || err instanceof ContinueException || err instanceof ExitException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`${name}: ${message}\\n`);\n return 1;\n }\n }\n\n private createExec(env: Record<string, string>): (name: string, args: string[]) => Promise<ExecResult> {\n return async (name: string, args: string[]) => {\n const subStdout = createStdout();\n const subStderr = createStderr();\n const exitCode = await this.invokeCommand(name, args, null, subStdout, subStderr, { ...env });\n\n subStdout.close();\n subStderr.close();\n\n return {\n stdout: await subStdout.collect(),\n stderr: await subStderr.collect(),\n exitCode,\n };\n };\n }\n\n private createShellApi(\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector,\n env: Record<string, string>\n ): ShellCommandApi {\n return {\n eval: (source: string) =>\n this.executeSourceInCurrentFrame(source, stdinSource, stdout, stderr, \"eval\"),\n source: (path: string, args: string[] = []) =>\n this.sourceFile(path, args, stdinSource, stdout, stderr),\n runScript: (path: string, args: string[] = []) =>\n this.executeExecutableFile(path, args, stdinSource, stdout, stderr, { ...env }),\n runShell: (source: string, options = {}) =>\n this.executeIsolatedShellSource(\n source,\n options.argv0 ?? \"sh\",\n options.args ?? [],\n stdinSource,\n stdout,\n stderr,\n env\n ),\n getLastExitCode: () => this.lastExitCode,\n exit: (exitCode = this.lastExitCode) => {\n throw new ExitException(this.normalizeExitCode(exitCode));\n },\n };\n }\n\n private async executeExecutableFile(\n pathName: string,\n args: string[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector,\n env: Record<string, string>\n ): Promise<number> {\n const loaded = await this.loadScriptSource(pathName, stderr, 127);\n if (!loaded.ok) {\n return loaded.exitCode;\n }\n\n const shebang = this.parseShebang(loaded.source);\n if (!shebang || shebang.command === \"sh\") {\n return this.executeIsolatedShellSource(\n loaded.source,\n pathName,\n args,\n stdinSource,\n stdout,\n stderr,\n env\n );\n }\n\n const command = this.commands[shebang.command];\n if (!command) {\n await stderr.writeText(`${pathName}: unsupported interpreter: ${shebang.display}\\n`);\n return 126;\n }\n\n const child = new Interpreter({\n fs: this.fs,\n cwd: this.cwd,\n env: { ...env },\n commands: this.commands,\n redirectObjects: this.redirectObjects,\n isTTY: this.isTTY,\n argv0: shebang.command,\n positionalParameters: [],\n });\n\n return child.invokeRegisteredCommand(\n shebang.command,\n command,\n [...shebang.args, pathName, ...args],\n stdinSource,\n stdout,\n stderr,\n { ...env }\n );\n }\n\n private async sourceFile(\n pathName: string,\n args: string[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const loaded = await this.loadScriptSource(pathName, stderr, 1);\n if (!loaded.ok) {\n return loaded.exitCode;\n }\n\n return this.executeSourceInCurrentFrame(\n loaded.source,\n stdinSource,\n stdout,\n stderr,\n pathName,\n args.length > 0 ? { args } : undefined\n );\n }\n\n private async executeIsolatedShellSource(\n source: string,\n argv0: string,\n args: string[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector,\n env: Record<string, string>\n ): Promise<number> {\n const interpreter = new Interpreter({\n fs: this.fs,\n cwd: this.cwd,\n env: { ...env },\n commands: this.commands,\n redirectObjects: this.redirectObjects,\n isTTY: this.isTTY,\n argv0,\n positionalParameters: args,\n });\n\n try {\n return await interpreter.executeSourceInCurrentFrame(source, stdinSource, stdout, stderr, argv0);\n } catch (err) {\n if (err instanceof ExitException) {\n return err.exitCode;\n }\n throw err;\n }\n }\n\n private async executeSourceInCurrentFrame(\n source: string,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector,\n errorName: string,\n positionalOverride?: { argv0?: string; args?: string[] }\n ): Promise<number> {\n const previousArgv0 = this.argv0;\n const previousPositionals = this.positionalParameters;\n\n if (positionalOverride?.argv0 !== undefined) {\n this.argv0 = positionalOverride.argv0;\n }\n if (positionalOverride?.args !== undefined) {\n this.positionalParameters = [...positionalOverride.args];\n }\n\n try {\n const ast = this.parseSource(source);\n if (!ast) {\n return 0;\n }\n return await this.executeNode(ast, stdinSource, stdout, stderr);\n } catch (err) {\n if (err instanceof BreakException || err instanceof ContinueException || err instanceof ExitException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`${errorName}: ${message}\\n`);\n return 2;\n } finally {\n if (positionalOverride?.argv0 !== undefined) {\n this.argv0 = previousArgv0;\n }\n if (positionalOverride?.args !== undefined) {\n this.positionalParameters = previousPositionals;\n }\n }\n }\n\n private parseSource(source: string): ASTNode | null {\n const tokens = new Lexer(source, { preserveNewlines: true }).tokenize();\n if (tokens.every((token) => token.type === \"newline\" || token.type === \"eof\")) {\n return null;\n }\n return new Parser(tokens).parse();\n }\n\n private async loadScriptSource(\n pathName: string,\n stderr: OutputCollector,\n missingExitCode: number\n ): Promise<{ ok: true; path: string; source: string } | { ok: false; exitCode: number }> {\n const path = this.fs.resolve(this.cwd, pathName);\n\n if (!(await this.fs.exists(path))) {\n await stderr.writeText(`${pathName}: No such file or directory\\n`);\n return { ok: false, exitCode: missingExitCode };\n }\n\n const stat = await this.fs.stat(path);\n if (stat.isDirectory()) {\n await stderr.writeText(`${pathName}: is a directory\\n`);\n return { ok: false, exitCode: 126 };\n }\n if (!stat.isFile()) {\n await stderr.writeText(`${pathName}: not a file\\n`);\n return { ok: false, exitCode: 126 };\n }\n\n try {\n return { ok: true, path, source: await this.fs.readFile(path, \"utf-8\") };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`${pathName}: ${message}\\n`);\n return { ok: false, exitCode: 126 };\n }\n }\n\n private parseShebang(source: string): { command: string; args: string[]; display: string } | null {\n if (!source.startsWith(\"#!\")) {\n return null;\n }\n\n const lineEnd = source.indexOf(\"\\n\");\n const line = source.slice(2, lineEnd === -1 ? undefined : lineEnd).trim();\n if (line === \"\") {\n return { command: \"sh\", args: [], display: \"sh\" };\n }\n\n const parts = line.split(/\\s+/);\n const executable = parts[0]!;\n const executableName = this.fs.basename(executable);\n\n if (executableName === \"env\") {\n const envCommand = parts[1];\n if (!envCommand) {\n return { command: \"env\", args: [], display: line };\n }\n return {\n command: this.fs.basename(envCommand),\n args: parts.slice(2),\n display: line,\n };\n }\n\n return {\n command: executableName,\n args: parts.slice(1),\n display: line,\n };\n }\n\n private async handleRedirect(\n redirect: Redirect,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector,\n env: Record<string, string>\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.expandWordScalar(redirect.target, env);\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 (isDevNullPath(target)) {\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 const expandedItems: string[] = [];\n for (const item of node.items) {\n expandedItems.push(...(await this.expandWordForCommand(item, this.env)));\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.expandWordScalar(node.word, this.env);\n\n for (const clause of node.clauses) {\n for (const patternNode of clause.patterns) {\n const pattern = await this.expandWordScalar(patternNode, this.env);\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 expandCommandWords(node: CommandNode, env: Record<string, string>): Promise<string[]> {\n const expanded: string[] = [];\n for (const word of [node.name, ...node.args]) {\n expanded.push(...(await this.expandWordForCommand(word, env)));\n }\n return expanded;\n }\n\n private async expandWordForCommand(word: WordNode, env: Record<string, string>): Promise<string[]> {\n const fields = await this.expandWordFields(word, env);\n const expanded: string[] = [];\n for (const field of fields) {\n expanded.push(...(await this.expandPathname(field)));\n }\n return expanded;\n }\n\n private async expandWordScalar(word: WordNode, env: Record<string, string>): Promise<string> {\n let result = \"\";\n for (const part of word.parts) {\n result += await this.expandWordPart(part, env);\n }\n return result;\n }\n\n private async expandWordFields(word: WordNode, env: Record<string, string>): Promise<ExpandedField[]> {\n const fields: ExpandedField[] = [this.createExpandedField()];\n const ifs = this.getIFS(env);\n\n for (const part of word.parts) {\n if (part.type === \"text\") {\n this.appendSegment(fields[fields.length - 1]!, part.value, part.quoted);\n continue;\n }\n\n if (part.type === \"variable\" && part.name === \"@\" && part.quoted) {\n this.appendQuotedPositionalParameters(fields);\n continue;\n }\n\n const value = await this.expandWordPart(part, env);\n if (part.quoted) {\n this.appendSegment(fields[fields.length - 1]!, value, true);\n continue;\n }\n\n const splitFields = this.splitUnquotedExpansion(value, ifs);\n if (splitFields.length === 0) {\n continue;\n }\n\n this.appendSegment(fields[fields.length - 1]!, splitFields[0]!, false);\n for (let i = 1; i < splitFields.length; i++) {\n const field = this.createExpandedField();\n this.appendSegment(field, splitFields[i]!, false);\n fields.push(field);\n }\n }\n\n return fields.filter((field) => field.segments.length > 0);\n }\n\n private async expandWordPart(part: WordPart, env: Record<string, string>): Promise<string> {\n switch (part.type) {\n case \"text\":\n return part.value;\n case \"variable\":\n return this.getVariableValue(part.name, env);\n case \"substitution\":\n return this.executeSubstitution(part.command, env);\n case \"arithmetic\":\n return String(this.evaluateArithmetic(part.expression, env));\n default:\n throw new Error(\"Cannot expand unknown word part\");\n }\n }\n\n private getVariableValue(name: string, env: Record<string, string>): string {\n if (name === \"0\") {\n return this.argv0;\n }\n if (name === \"#\") {\n return String(this.positionalParameters.length);\n }\n if (name === \"?\") {\n return String(this.lastExitCode);\n }\n if (name === \"*\" || name === \"@\") {\n return this.positionalParameters.join(\" \");\n }\n if (/^[1-9]$/.test(name)) {\n return this.positionalParameters[Number(name) - 1] ?? \"\";\n }\n return env[name] ?? \"\";\n }\n\n private appendQuotedPositionalParameters(fields: ExpandedField[]): void {\n if (this.positionalParameters.length === 0) {\n return;\n }\n\n this.appendSegment(fields[fields.length - 1]!, this.positionalParameters[0]!, true);\n for (let i = 1; i < this.positionalParameters.length; i++) {\n const field = this.createExpandedField();\n this.appendSegment(field, this.positionalParameters[i]!, true);\n fields.push(field);\n }\n }\n\n private async executeSubstitution(command: ASTNode, env: Record<string, string>): Promise<string> {\n const interpreter = new Interpreter({\n fs: this.fs,\n cwd: this.cwd,\n env,\n commands: this.commands,\n redirectObjects: this.redirectObjects,\n isTTY: false,\n argv0: this.argv0,\n positionalParameters: this.positionalParameters,\n lastExitCode: this.lastExitCode,\n });\n const result = await interpreter.execute(command);\n return result.stdout.toString(\"utf-8\").replace(/\\n+$/, \"\");\n }\n\n private getIFS(env: Record<string, string>): string {\n return env.IFS ?? DEFAULT_IFS;\n }\n\n private splitUnquotedExpansion(value: string, ifs: string): string[] {\n if (value.length === 0) {\n return [];\n }\n if (ifs === \"\") {\n return [value];\n }\n\n const ifsChars = new Set(ifs);\n const isIfsWhitespace = (char: string) =>\n ifsChars.has(char) && (char === \" \" || char === \"\\t\" || char === \"\\n\");\n const isIfsNonWhitespace = (char: string) => ifsChars.has(char) && !isIfsWhitespace(char);\n\n const fields: string[] = [];\n let i = 0;\n\n while (i < value.length && isIfsWhitespace(value[i]!)) {\n i++;\n }\n\n let fieldStart = i;\n let lastDelimiterWasNonWhitespace = false;\n\n while (i < value.length) {\n const char = value[i]!;\n\n if (isIfsNonWhitespace(char)) {\n fields.push(value.slice(fieldStart, i));\n i++;\n while (i < value.length && isIfsWhitespace(value[i]!)) {\n i++;\n }\n fieldStart = i;\n lastDelimiterWasNonWhitespace = true;\n continue;\n }\n\n if (isIfsWhitespace(char)) {\n fields.push(value.slice(fieldStart, i));\n while (i < value.length && isIfsWhitespace(value[i]!)) {\n i++;\n }\n if (i < value.length && isIfsNonWhitespace(value[i]!)) {\n i++;\n while (i < value.length && isIfsWhitespace(value[i]!)) {\n i++;\n }\n lastDelimiterWasNonWhitespace = true;\n } else {\n lastDelimiterWasNonWhitespace = false;\n }\n fieldStart = i;\n continue;\n }\n\n lastDelimiterWasNonWhitespace = false;\n i++;\n }\n\n if (fieldStart < value.length) {\n fields.push(value.slice(fieldStart));\n } else if (lastDelimiterWasNonWhitespace) {\n fields.push(\"\");\n }\n\n return fields;\n }\n\n private createExpandedField(): ExpandedField {\n return { segments: [] };\n }\n\n private appendSegment(field: ExpandedField, value: string, quoted: boolean): void {\n const lastSegment = field.segments[field.segments.length - 1];\n if (lastSegment && lastSegment.quoted === quoted) {\n lastSegment.value += value;\n return;\n }\n field.segments.push({ value, quoted });\n }\n\n private async expandPathname(field: ExpandedField): Promise<string[]> {\n if (!this.hasUnquotedGlobMeta(field)) {\n return [this.fieldToString(field)];\n }\n\n const pattern = this.fieldToGlobPattern(field);\n const matches = await this.fs.glob(pattern, { cwd: this.cwd });\n return matches.length > 0 ? matches : [this.fieldToString(field)];\n }\n\n private hasUnquotedGlobMeta(field: ExpandedField): boolean {\n return field.segments.some((segment) => !segment.quoted && GLOB_META_CHARS.test(segment.value));\n }\n\n private fieldToString(field: ExpandedField): string {\n return field.segments.map((segment) => segment.value).join(\"\");\n }\n\n private fieldToGlobPattern(field: ExpandedField): string {\n return field.segments\n .map((segment) => (segment.quoted ? this.escapeLiteralGlobChars(segment.value) : segment.value))\n .join(\"\");\n }\n\n private escapeLiteralGlobChars(value: string): string {\n return value\n .replaceAll(\"[\", \"[[]\")\n .replaceAll(\"]\", \"[]]\")\n .replaceAll(\"*\", \"[*]\")\n .replaceAll(\"?\", \"[?]\")\n .replaceAll(\"{\", \"[{]\")\n .replaceAll(\"}\", \"[}]\");\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_]*|[0-9#*@?])/g, (_, name) => {\n return this.getVariableValue(name, env) || \"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 private normalizeExitCode(exitCode: number): number {\n if (!Number.isFinite(exitCode)) {\n return 2;\n }\n return ((Math.trunc(exitCode) % 256) + 256) % 256;\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": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "37348867B8905B5F64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -206,6 +206,12 @@ class Lexer {
|
|
|
206
206
|
}
|
|
207
207
|
return { type: "variable", name: name2 };
|
|
208
208
|
}
|
|
209
|
+
if (["#", "*", "@", "?"].includes(this.peek())) {
|
|
210
|
+
return { type: "variable", name: this.advance() };
|
|
211
|
+
}
|
|
212
|
+
if (/[0-9]/.test(this.peek())) {
|
|
213
|
+
return { type: "variable", name: this.advance() };
|
|
214
|
+
}
|
|
209
215
|
let name = "";
|
|
210
216
|
while (!this.isAtEnd() && this.isVarChar(this.peek())) {
|
|
211
217
|
name += this.advance();
|
|
@@ -433,6 +439,12 @@ class Lexer {
|
|
|
433
439
|
i++;
|
|
434
440
|
}
|
|
435
441
|
tokens.push({ type: "variable", name: varName });
|
|
442
|
+
} else if (["#", "*", "@", "?"].includes(value[i])) {
|
|
443
|
+
tokens.push({ type: "variable", name: value[i] });
|
|
444
|
+
i++;
|
|
445
|
+
} else if (/[0-9]/.test(value[i])) {
|
|
446
|
+
tokens.push({ type: "variable", name: value[i] });
|
|
447
|
+
i++;
|
|
436
448
|
} else if (/[a-zA-Z_]/.test(value[i])) {
|
|
437
449
|
let varName = "";
|
|
438
450
|
while (i < value.length && /[a-zA-Z0-9_]/.test(value[i])) {
|
|
@@ -667,4 +679,4 @@ export {
|
|
|
667
679
|
Lexer
|
|
668
680
|
};
|
|
669
681
|
|
|
670
|
-
//# debugId=
|
|
682
|
+
//# debugId=1A7BD45CCD45F2A164756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lexer/lexer.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { LexError } from \"../errors.mjs\";\nimport type { Token, RedirectMode, KeywordValue } from \"./tokens.mjs\";\nimport { KEYWORDS } from \"./tokens.mjs\";\n\nconst GLOB_CHARS = new Set([\"*\", \"?\", \"[\", \"{\", \"}\"]);\nconst WORD_BREAK_CHARS = new Set([\n \" \",\n \"\\t\",\n \"\\n\",\n \"\\r\",\n \"|\",\n \"&\",\n \";\",\n \">\",\n \"<\",\n \"(\",\n \")\",\n \"$\",\n \"'\",\n '\"',\n \"`\",\n]);\n\nexport class Lexer {\n private source: string;\n private pos: number = 0;\n private line: number = 1;\n private column: number = 1;\n private tokenQueue: Token[] = [];\n private preserveNewlines: boolean;\n\n constructor(source: string, options?: { preserveNewlines?: boolean }) {\n this.source = source;\n this.preserveNewlines = options?.preserveNewlines ?? false;\n }\n\n private isWordLikeToken(token: Token): boolean {\n return (\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 );\n }\n\n tokenize(): Token[] {\n const tokens: Token[] = [];\n\n while (!this.isAtEnd() || this.tokenQueue.length > 0) {\n // Drain token queue first (for heredoc handling)\n if (this.tokenQueue.length > 0) {\n tokens.push(this.tokenQueue.shift()!);\n continue;\n }\n\n const posBeforeWhitespace = this.pos;\n this.skipWhitespaceExceptNewlines();\n const hadWhitespace = this.pos > posBeforeWhitespace;\n if (this.isAtEnd()) break;\n\n const token = this.nextToken();\n if (token) {\n // Merge adjacent word-like tokens (no whitespace between them)\n const prev = tokens[tokens.length - 1];\n if (!hadWhitespace && prev && this.isWordLikeToken(token) && (Array.isArray(prev) || this.isWordLikeToken(prev))) {\n // Merge into an array token (concat)\n if (Array.isArray(prev)) {\n (prev as Token[]).push(token);\n } else {\n tokens[tokens.length - 1] = [prev, token] as unknown as Token;\n }\n } else {\n tokens.push(token);\n }\n }\n }\n\n tokens.push({ type: \"eof\" });\n return tokens;\n }\n\n private nextToken(): Token | null {\n // Check token queue first (used for heredoc handling)\n if (this.tokenQueue.length > 0) {\n return this.tokenQueue.shift()!;\n }\n\n const char = this.peek();\n\n // Newlines - significant for control flow\n if (char === \"\\n\") {\n this.advance();\n // Skip consecutive newlines\n while (this.peek() === \"\\n\") {\n this.advance();\n }\n if (this.preserveNewlines) {\n return { type: \"newline\" };\n }\n return null;\n }\n\n // Comments\n if (char === \"#\") {\n this.skipComment();\n return null;\n }\n\n // Parentheses - for case pattern grouping\n if (char === \"(\") {\n this.advance();\n return { type: \"openParen\" };\n }\n\n if (char === \")\") {\n this.advance();\n return { type: \"closeParen\" };\n }\n\n // Operators and redirects\n if (char === \"|\") {\n this.advance();\n if (this.peek() === \"|\") {\n this.advance();\n return { type: \"or\" };\n }\n return { type: \"pipe\" };\n }\n\n if (char === \"&\") {\n this.advance();\n if (this.peek() === \"&\") {\n this.advance();\n return { type: \"and\" };\n }\n if (this.peek() === \">\") {\n this.advance();\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \"&>>\" };\n }\n return { type: \"redirect\", mode: \"&>\" };\n }\n // Background execution (&) - treat as word for now\n return { type: \"word\", value: \"&\" };\n }\n\n if (char === \";\") {\n this.advance();\n // Check for double semicolon (case terminator)\n if (this.peek() === \";\") {\n this.advance();\n return { type: \"doubleSemicolon\" };\n }\n return { type: \"semicolon\" };\n }\n\n // Redirects\n if (char === \">\") {\n this.advance();\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \">>\" };\n }\n return { type: \"redirect\", mode: \">\" };\n }\n\n if (char === \"<\") {\n this.advance();\n if (this.peek() === \"<\") {\n this.advance();\n return this.readHeredoc();\n }\n return { type: \"redirect\", mode: \"<\" };\n }\n\n // File descriptor redirects (2>, 2>>, 2>&1, 1>&2)\n if (char === \"1\" || char === \"2\") {\n const fd = char;\n const nextChar = this.peekAhead(1);\n if (nextChar === \">\") {\n this.advance(); // consume fd\n this.advance(); // consume >\n if (fd === \"2\") {\n if (this.peek() === \"&\" && this.peekAhead(1) === \"1\") {\n this.advance(); // consume &\n this.advance(); // consume 1\n return { type: \"redirect\", mode: \"2>&1\" };\n }\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \"2>>\" };\n }\n return { type: \"redirect\", mode: \"2>\" };\n } else {\n // 1>&2\n if (this.peek() === \"&\" && this.peekAhead(1) === \"2\") {\n this.advance(); // consume &\n this.advance(); // consume 2\n return { type: \"redirect\", mode: \"1>&2\" };\n }\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \">>\" };\n }\n return { type: \"redirect\", mode: \">\" };\n }\n }\n }\n\n // Variables and substitutions\n if (char === \"$\") {\n return this.readVariable();\n }\n\n // Single quotes\n if (char === \"'\") {\n return this.readSingleQuote();\n }\n\n // Double quotes\n if (char === '\"') {\n return this.readDoubleQuote();\n }\n\n // Word (including potential globs and assignments)\n return this.readWord();\n }\n\n private readVariable(): Token {\n this.advance(); // consume $\n\n // Arithmetic expansion $((...)) or command substitution $(...)\n if (this.peek() === \"(\") {\n this.advance(); // consume first (\n // Check for arithmetic expansion $((...))\n if (this.peek() === \"(\") {\n this.advance(); // consume second (\n const expression = this.readUntilDoubleCloseParen();\n return { type: \"arithmetic\", expression };\n }\n const command = this.readUntilMatchingParen();\n return { type: \"substitution\", command };\n }\n\n // ${VAR} syntax\n if (this.peek() === \"{\") {\n this.advance(); // consume {\n let name = \"\";\n while (!this.isAtEnd() && this.peek() !== \"}\") {\n name += this.advance();\n }\n if (this.peek() === \"}\") {\n this.advance(); // consume }\n }\n return { type: \"variable\", name };\n }\n\n // $VAR syntax\n let name = \"\";\n while (!this.isAtEnd() && this.isVarChar(this.peek())) {\n name += this.advance();\n }\n\n if (name === \"\") {\n return { type: \"word\", value: \"$\" };\n }\n\n return { type: \"variable\", name };\n }\n\n private readUntilDoubleCloseParen(): string {\n let depth = 1;\n let result = \"\";\n\n while (!this.isAtEnd() && depth > 0) {\n const char = this.peek();\n if (char === \"(\" && this.peekAhead(1) === \"(\") {\n depth++;\n result += this.advance();\n result += this.advance();\n } else if (char === \")\" && this.peekAhead(1) === \")\") {\n depth--;\n if (depth === 0) {\n this.advance(); // consume first )\n this.advance(); // consume second )\n break;\n }\n result += this.advance();\n result += this.advance();\n } else {\n result += this.advance();\n }\n }\n\n return result;\n }\n\n private readUntilMatchingParen(): string {\n let depth = 1;\n let result = \"\";\n\n while (!this.isAtEnd() && depth > 0) {\n const char = this.peek();\n if (char === \"(\") {\n depth++;\n } else if (char === \")\") {\n depth--;\n if (depth === 0) {\n this.advance(); // consume closing )\n break;\n }\n }\n result += this.advance();\n }\n\n return result;\n }\n\n private readSingleQuote(): Token {\n this.advance(); // consume opening '\n let value = \"\";\n\n while (!this.isAtEnd() && this.peek() !== \"'\") {\n value += this.advance();\n }\n\n if (this.peek() === \"'\") {\n this.advance(); // consume closing '\n } else {\n throw new LexError(\"Unterminated single quote\", this.pos, this.line, this.column);\n }\n\n return { type: \"singleQuote\", value };\n }\n\n private readDoubleQuote(): Token {\n this.advance(); // consume opening \"\n const parts: Array<string | Token> = [];\n let currentString = \"\";\n\n while (!this.isAtEnd() && this.peek() !== '\"') {\n const char = this.peek();\n\n if (char === \"\\\\\") {\n this.advance();\n if (!this.isAtEnd()) {\n const escaped = this.advance();\n // In double quotes, only certain chars are special\n if ([\"$\", '\"', \"\\\\\", \"`\", \"\\n\"].includes(escaped)) {\n currentString += escaped;\n } else {\n currentString += \"\\\\\" + escaped;\n }\n }\n } else if (char === \"$\") {\n if (currentString) {\n parts.push(currentString);\n currentString = \"\";\n }\n parts.push(this.readVariable());\n } else {\n currentString += this.advance();\n }\n }\n\n if (currentString) {\n parts.push(currentString);\n }\n\n if (this.peek() === '\"') {\n this.advance(); // consume closing \"\n } else {\n throw new LexError(\"Unterminated double quote\", this.pos, this.line, this.column);\n }\n\n return { type: \"doubleQuote\", parts };\n }\n\n private readWord(): Token {\n let value = \"\";\n let hasGlobChars = false;\n\n while (!this.isAtEnd() && !this.isWordBreak(this.peek())) {\n const char = this.peek();\n\n if (char === \"\\\\\") {\n this.advance();\n if (!this.isAtEnd()) {\n value += this.advance();\n }\n } else {\n if (GLOB_CHARS.has(char)) {\n hasGlobChars = true;\n }\n value += this.advance();\n }\n }\n\n // Check if this looks like an assignment with value starting with $ or quote\n // e.g., VAR=$(...) or VAR=\"...\" or VAR='...'\n const assignmentPrefixMatch = value.match(/^([a-zA-Z_][a-zA-Z0-9_]*)=$/);\n if (assignmentPrefixMatch && (this.peek() === \"$\" || this.peek() === \"'\" || this.peek() === '\"')) {\n const name = assignmentPrefixMatch[1]!;\n // Read the value part\n const valueTokens = this.readAssignmentValueTokens();\n return {\n type: \"assignment\",\n name,\n value: valueTokens.length === 1 && valueTokens[0]!.type === \"word\"\n ? (valueTokens[0] as { type: \"word\"; value: string }).value\n : valueTokens,\n };\n }\n\n // Check if this is an assignment (VAR=value)\n const assignmentMatch = value.match(/^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$/);\n if (assignmentMatch) {\n const name = assignmentMatch[1]!;\n const rawValue = assignmentMatch[2]!;\n\n // Parse the value to handle variables and arithmetic\n const parsedValue = this.parseAssignmentValue(rawValue);\n return {\n type: \"assignment\",\n name,\n value: parsedValue,\n };\n }\n\n // Check if this is a keyword\n if (KEYWORDS.has(value)) {\n return { type: \"keyword\", value: value as KeywordValue };\n }\n\n if (hasGlobChars) {\n return { type: \"glob\", pattern: value };\n }\n\n return { type: \"word\", value };\n }\n\n private readAssignmentValueTokens(): Token[] {\n const tokens: Token[] = [];\n\n // Read tokens until we hit a space, newline, semicolon, etc.\n while (!this.isAtEnd()) {\n const char = this.peek();\n\n // Stop at whitespace or command terminators\n if (char === \" \" || char === \"\\t\" || char === \"\\n\" || char === \"\\r\" ||\n char === \";\" || char === \"|\" || char === \"&\" || char === \">\" || char === \"<\") {\n break;\n }\n\n if (char === \"$\") {\n tokens.push(this.readVariable());\n } else if (char === \"'\") {\n tokens.push(this.readSingleQuote());\n } else if (char === '\"') {\n tokens.push(this.readDoubleQuote());\n } else {\n // Read until word break\n let word = \"\";\n while (!this.isAtEnd() && !this.isWordBreak(this.peek())) {\n word += this.advance();\n }\n if (word) {\n tokens.push({ type: \"word\", value: word });\n } else {\n break;\n }\n }\n }\n\n return tokens;\n }\n\n private parseAssignmentValue(value: string): string | Token[] {\n // If value contains no special characters, return as string\n if (!value.includes(\"$\")) {\n return value;\n }\n\n // Parse the value to handle $VAR, ${VAR}, $((expr))\n const tokens: Token[] = [];\n let i = 0;\n let currentString = \"\";\n\n while (i < value.length) {\n if (value[i] === \"$\") {\n if (currentString) {\n tokens.push({ type: \"word\", value: currentString });\n currentString = \"\";\n }\n\n i++; // consume $\n if (i >= value.length) {\n tokens.push({ type: \"word\", value: \"$\" });\n break;\n }\n\n // Arithmetic expansion $((expr))\n if (value[i] === \"(\" && value[i + 1] === \"(\") {\n i += 2; // consume ((\n let depth = 1;\n let expr = \"\";\n while (i < value.length && depth > 0) {\n if (value[i] === \"(\" && value[i + 1] === \"(\") {\n depth++;\n expr += value[i]! + value[i + 1]!;\n i += 2;\n } else if (value[i] === \")\" && value[i + 1] === \")\") {\n depth--;\n if (depth > 0) {\n expr += value[i]! + value[i + 1]!;\n i += 2;\n } else {\n i += 2; // consume ))\n }\n } else {\n expr += value[i];\n i++;\n }\n }\n tokens.push({ type: \"arithmetic\", expression: expr });\n }\n // ${VAR} syntax\n else if (value[i] === \"{\") {\n i++; // consume {\n let varName = \"\";\n while (i < value.length && value[i] !== \"}\") {\n varName += value[i];\n i++;\n }\n if (i < value.length && value[i] === \"}\") {\n i++; // consume }\n }\n tokens.push({ type: \"variable\", name: varName });\n }\n // $VAR syntax\n else if (/[a-zA-Z_]/.test(value[i]!)) {\n let varName = \"\";\n while (i < value.length && /[a-zA-Z0-9_]/.test(value[i]!)) {\n varName += value[i];\n i++;\n }\n tokens.push({ type: \"variable\", name: varName });\n }\n // $(cmd) command substitution\n else if (value[i] === \"(\") {\n i++; // consume (\n let depth = 1;\n let cmd = \"\";\n while (i < value.length && depth > 0) {\n if (value[i] === \"(\") depth++;\n else if (value[i] === \")\") depth--;\n if (depth > 0) {\n cmd += value[i];\n }\n i++;\n }\n tokens.push({ type: \"substitution\", command: cmd });\n }\n else {\n // Not a variable, just a $\n currentString += \"$\";\n }\n } else {\n currentString += value[i];\n i++;\n }\n }\n\n if (currentString) {\n tokens.push({ type: \"word\", value: currentString });\n }\n\n if (tokens.length === 1 && tokens[0]!.type === \"word\") {\n return (tokens[0] as { type: \"word\"; value: string }).value;\n }\n\n return tokens.length > 0 ? tokens : value;\n }\n\n private readHeredoc(): Token {\n // Check for tab-stripping variant (<<-)\n const stripTabs = this.peek() === \"-\";\n if (stripTabs) {\n this.advance();\n }\n\n // Skip whitespace before delimiter\n while (this.peek() === \" \" || this.peek() === \"\\t\") {\n this.advance();\n }\n\n // Read delimiter and determine if expansion is enabled\n const { delimiter, expand } = this.readHeredocDelimiter();\n\n // Tokenize the rest of the current line and queue those tokens\n this.tokenizeRestOfLine();\n\n // Skip the newline that starts the heredoc content\n if (this.peek() === \"\\n\") {\n this.advance();\n }\n\n // Read content until closing delimiter\n let content = \"\";\n while (!this.isAtEnd()) {\n const lineStart = this.pos;\n let line = \"\";\n\n // Read until end of line or end of input\n while (!this.isAtEnd() && this.peek() !== \"\\n\") {\n line += this.advance();\n }\n\n // Check if this line is the delimiter (after stripping leading tabs if <<-)\n const strippedLine = stripTabs ? line.replace(/^\\t+/, \"\") : line;\n if (strippedLine === delimiter) {\n // Found closing delimiter, consume newline if present\n if (this.peek() === \"\\n\") {\n this.advance();\n }\n break;\n }\n\n // Add the line to content\n if (stripTabs) {\n content += line.replace(/^\\t+/, \"\");\n } else {\n content += line;\n }\n\n // Add newline if present\n if (this.peek() === \"\\n\") {\n content += this.advance();\n }\n }\n\n return { type: \"heredoc\", content, expand };\n }\n\n private readHeredocDelimiter(): { delimiter: string; expand: boolean } {\n const quoteChar = this.peek();\n\n // Quoted delimiter - no expansion\n if (quoteChar === \"'\" || quoteChar === '\"') {\n this.advance(); // consume opening quote\n let delimiter = \"\";\n while (!this.isAtEnd() && this.peek() !== quoteChar && this.peek() !== \"\\n\") {\n delimiter += this.advance();\n }\n if (this.peek() === quoteChar) {\n this.advance(); // consume closing quote\n }\n return { delimiter, expand: false };\n }\n\n // Unquoted delimiter - expansion enabled\n let delimiter = \"\";\n while (!this.isAtEnd() && !this.isWordBreak(this.peek()) && this.peek() !== \"\\n\") {\n if (this.peek() === \"\\\\\") {\n this.advance();\n if (!this.isAtEnd()) {\n delimiter += this.advance();\n }\n } else {\n delimiter += this.advance();\n }\n }\n\n return { delimiter, expand: true };\n }\n\n private tokenizeRestOfLine(): void {\n // Tokenize the rest of the line (until newline or end)\n while (!this.isAtEnd() && this.peek() !== \"\\n\") {\n // Skip only spaces and tabs, not newlines\n while (this.peek() === \" \" || this.peek() === \"\\t\") {\n this.advance();\n }\n if (this.isAtEnd() || this.peek() === \"\\n\") break;\n\n const token = this.readRestOfLineToken();\n if (token) {\n this.tokenQueue.push(token);\n }\n }\n }\n\n private readRestOfLineToken(): Token | null {\n const char = this.peek();\n\n if (char === \"|\") {\n this.advance();\n if (this.peek() === \"|\") {\n this.advance();\n return { type: \"or\" };\n }\n return { type: \"pipe\" };\n }\n\n if (char === \"&\") {\n this.advance();\n if (this.peek() === \"&\") {\n this.advance();\n return { type: \"and\" };\n }\n return { type: \"word\", value: \"&\" };\n }\n\n if (char === \";\") {\n this.advance();\n return { type: \"semicolon\" };\n }\n\n if (char === \">\") {\n this.advance();\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \">>\" };\n }\n return { type: \"redirect\", mode: \">\" };\n }\n\n if (char === \"<\") {\n this.advance();\n return { type: \"redirect\", mode: \"<\" };\n }\n\n if (char === \"$\") {\n return this.readVariable();\n }\n\n if (char === \"'\") {\n return this.readSingleQuote();\n }\n\n if (char === '\"') {\n return this.readDoubleQuote();\n }\n\n // Read a word but stop at newline\n let value = \"\";\n while (!this.isAtEnd() && !this.isWordBreak(this.peek()) && this.peek() !== \"\\n\") {\n if (this.peek() === \"\\\\\") {\n this.advance();\n if (!this.isAtEnd()) {\n value += this.advance();\n }\n } else {\n value += this.advance();\n }\n }\n\n if (value === \"\") return null;\n return { type: \"word\", value };\n }\n\n private isWordBreak(char: string): boolean {\n return WORD_BREAK_CHARS.has(char);\n }\n\n private isVarChar(char: string): boolean {\n return /[a-zA-Z0-9_]/.test(char);\n }\n\n private skipWhitespace(): void {\n while (!this.isAtEnd() && /\\s/.test(this.peek())) {\n this.advance();\n }\n }\n\n private skipWhitespaceExceptNewlines(): void {\n while (!this.isAtEnd() && /[ \\t\\r]/.test(this.peek())) {\n this.advance();\n }\n }\n\n private skipComment(): void {\n while (!this.isAtEnd() && this.peek() !== \"\\n\") {\n this.advance();\n }\n }\n\n private peek(): string {\n return this.source[this.pos] ?? \"\";\n }\n\n private peekAhead(n: number): string {\n return this.source[this.pos + n] ?? \"\";\n }\n\n private advance(): string {\n const char = this.source[this.pos]!;\n this.pos++;\n if (char === \"\\n\") {\n this.line++;\n this.column = 1;\n } else {\n this.column++;\n }\n return char;\n }\n\n private isAtEnd(): boolean {\n return this.pos >= this.source.length;\n }\n}\n\nexport function lex(source: string, options?: { preserveNewlines?: boolean }): Token[] {\n return new Lexer(source, options).tokenize();\n}\n"
|
|
5
|
+
"import { LexError } from \"../errors.mjs\";\nimport type { Token, RedirectMode, KeywordValue } from \"./tokens.mjs\";\nimport { KEYWORDS } from \"./tokens.mjs\";\n\nconst GLOB_CHARS = new Set([\"*\", \"?\", \"[\", \"{\", \"}\"]);\nconst WORD_BREAK_CHARS = new Set([\n \" \",\n \"\\t\",\n \"\\n\",\n \"\\r\",\n \"|\",\n \"&\",\n \";\",\n \">\",\n \"<\",\n \"(\",\n \")\",\n \"$\",\n \"'\",\n '\"',\n \"`\",\n]);\n\nexport class Lexer {\n private source: string;\n private pos: number = 0;\n private line: number = 1;\n private column: number = 1;\n private tokenQueue: Token[] = [];\n private preserveNewlines: boolean;\n\n constructor(source: string, options?: { preserveNewlines?: boolean }) {\n this.source = source;\n this.preserveNewlines = options?.preserveNewlines ?? false;\n }\n\n private isWordLikeToken(token: Token): boolean {\n return (\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 );\n }\n\n tokenize(): Token[] {\n const tokens: Token[] = [];\n\n while (!this.isAtEnd() || this.tokenQueue.length > 0) {\n // Drain token queue first (for heredoc handling)\n if (this.tokenQueue.length > 0) {\n tokens.push(this.tokenQueue.shift()!);\n continue;\n }\n\n const posBeforeWhitespace = this.pos;\n this.skipWhitespaceExceptNewlines();\n const hadWhitespace = this.pos > posBeforeWhitespace;\n if (this.isAtEnd()) break;\n\n const token = this.nextToken();\n if (token) {\n // Merge adjacent word-like tokens (no whitespace between them)\n const prev = tokens[tokens.length - 1];\n if (!hadWhitespace && prev && this.isWordLikeToken(token) && (Array.isArray(prev) || this.isWordLikeToken(prev))) {\n // Merge into an array token (concat)\n if (Array.isArray(prev)) {\n (prev as Token[]).push(token);\n } else {\n tokens[tokens.length - 1] = [prev, token] as unknown as Token;\n }\n } else {\n tokens.push(token);\n }\n }\n }\n\n tokens.push({ type: \"eof\" });\n return tokens;\n }\n\n private nextToken(): Token | null {\n // Check token queue first (used for heredoc handling)\n if (this.tokenQueue.length > 0) {\n return this.tokenQueue.shift()!;\n }\n\n const char = this.peek();\n\n // Newlines - significant for control flow\n if (char === \"\\n\") {\n this.advance();\n // Skip consecutive newlines\n while (this.peek() === \"\\n\") {\n this.advance();\n }\n if (this.preserveNewlines) {\n return { type: \"newline\" };\n }\n return null;\n }\n\n // Comments\n if (char === \"#\") {\n this.skipComment();\n return null;\n }\n\n // Parentheses - for case pattern grouping\n if (char === \"(\") {\n this.advance();\n return { type: \"openParen\" };\n }\n\n if (char === \")\") {\n this.advance();\n return { type: \"closeParen\" };\n }\n\n // Operators and redirects\n if (char === \"|\") {\n this.advance();\n if (this.peek() === \"|\") {\n this.advance();\n return { type: \"or\" };\n }\n return { type: \"pipe\" };\n }\n\n if (char === \"&\") {\n this.advance();\n if (this.peek() === \"&\") {\n this.advance();\n return { type: \"and\" };\n }\n if (this.peek() === \">\") {\n this.advance();\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \"&>>\" };\n }\n return { type: \"redirect\", mode: \"&>\" };\n }\n // Background execution (&) - treat as word for now\n return { type: \"word\", value: \"&\" };\n }\n\n if (char === \";\") {\n this.advance();\n // Check for double semicolon (case terminator)\n if (this.peek() === \";\") {\n this.advance();\n return { type: \"doubleSemicolon\" };\n }\n return { type: \"semicolon\" };\n }\n\n // Redirects\n if (char === \">\") {\n this.advance();\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \">>\" };\n }\n return { type: \"redirect\", mode: \">\" };\n }\n\n if (char === \"<\") {\n this.advance();\n if (this.peek() === \"<\") {\n this.advance();\n return this.readHeredoc();\n }\n return { type: \"redirect\", mode: \"<\" };\n }\n\n // File descriptor redirects (2>, 2>>, 2>&1, 1>&2)\n if (char === \"1\" || char === \"2\") {\n const fd = char;\n const nextChar = this.peekAhead(1);\n if (nextChar === \">\") {\n this.advance(); // consume fd\n this.advance(); // consume >\n if (fd === \"2\") {\n if (this.peek() === \"&\" && this.peekAhead(1) === \"1\") {\n this.advance(); // consume &\n this.advance(); // consume 1\n return { type: \"redirect\", mode: \"2>&1\" };\n }\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \"2>>\" };\n }\n return { type: \"redirect\", mode: \"2>\" };\n } else {\n // 1>&2\n if (this.peek() === \"&\" && this.peekAhead(1) === \"2\") {\n this.advance(); // consume &\n this.advance(); // consume 2\n return { type: \"redirect\", mode: \"1>&2\" };\n }\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \">>\" };\n }\n return { type: \"redirect\", mode: \">\" };\n }\n }\n }\n\n // Variables and substitutions\n if (char === \"$\") {\n return this.readVariable();\n }\n\n // Single quotes\n if (char === \"'\") {\n return this.readSingleQuote();\n }\n\n // Double quotes\n if (char === '\"') {\n return this.readDoubleQuote();\n }\n\n // Word (including potential globs and assignments)\n return this.readWord();\n }\n\n private readVariable(): Token {\n this.advance(); // consume $\n\n // Arithmetic expansion $((...)) or command substitution $(...)\n if (this.peek() === \"(\") {\n this.advance(); // consume first (\n // Check for arithmetic expansion $((...))\n if (this.peek() === \"(\") {\n this.advance(); // consume second (\n const expression = this.readUntilDoubleCloseParen();\n return { type: \"arithmetic\", expression };\n }\n const command = this.readUntilMatchingParen();\n return { type: \"substitution\", command };\n }\n\n // ${VAR} syntax\n if (this.peek() === \"{\") {\n this.advance(); // consume {\n let name = \"\";\n while (!this.isAtEnd() && this.peek() !== \"}\") {\n name += this.advance();\n }\n if (this.peek() === \"}\") {\n this.advance(); // consume }\n }\n return { type: \"variable\", name };\n }\n\n if ([\"#\", \"*\", \"@\", \"?\"].includes(this.peek())) {\n return { type: \"variable\", name: this.advance() };\n }\n\n if (/[0-9]/.test(this.peek())) {\n return { type: \"variable\", name: this.advance() };\n }\n\n // $VAR syntax\n let name = \"\";\n while (!this.isAtEnd() && this.isVarChar(this.peek())) {\n name += this.advance();\n }\n\n if (name === \"\") {\n return { type: \"word\", value: \"$\" };\n }\n\n return { type: \"variable\", name };\n }\n\n private readUntilDoubleCloseParen(): string {\n let depth = 1;\n let result = \"\";\n\n while (!this.isAtEnd() && depth > 0) {\n const char = this.peek();\n if (char === \"(\" && this.peekAhead(1) === \"(\") {\n depth++;\n result += this.advance();\n result += this.advance();\n } else if (char === \")\" && this.peekAhead(1) === \")\") {\n depth--;\n if (depth === 0) {\n this.advance(); // consume first )\n this.advance(); // consume second )\n break;\n }\n result += this.advance();\n result += this.advance();\n } else {\n result += this.advance();\n }\n }\n\n return result;\n }\n\n private readUntilMatchingParen(): string {\n let depth = 1;\n let result = \"\";\n\n while (!this.isAtEnd() && depth > 0) {\n const char = this.peek();\n if (char === \"(\") {\n depth++;\n } else if (char === \")\") {\n depth--;\n if (depth === 0) {\n this.advance(); // consume closing )\n break;\n }\n }\n result += this.advance();\n }\n\n return result;\n }\n\n private readSingleQuote(): Token {\n this.advance(); // consume opening '\n let value = \"\";\n\n while (!this.isAtEnd() && this.peek() !== \"'\") {\n value += this.advance();\n }\n\n if (this.peek() === \"'\") {\n this.advance(); // consume closing '\n } else {\n throw new LexError(\"Unterminated single quote\", this.pos, this.line, this.column);\n }\n\n return { type: \"singleQuote\", value };\n }\n\n private readDoubleQuote(): Token {\n this.advance(); // consume opening \"\n const parts: Array<string | Token> = [];\n let currentString = \"\";\n\n while (!this.isAtEnd() && this.peek() !== '\"') {\n const char = this.peek();\n\n if (char === \"\\\\\") {\n this.advance();\n if (!this.isAtEnd()) {\n const escaped = this.advance();\n // In double quotes, only certain chars are special\n if ([\"$\", '\"', \"\\\\\", \"`\", \"\\n\"].includes(escaped)) {\n currentString += escaped;\n } else {\n currentString += \"\\\\\" + escaped;\n }\n }\n } else if (char === \"$\") {\n if (currentString) {\n parts.push(currentString);\n currentString = \"\";\n }\n parts.push(this.readVariable());\n } else {\n currentString += this.advance();\n }\n }\n\n if (currentString) {\n parts.push(currentString);\n }\n\n if (this.peek() === '\"') {\n this.advance(); // consume closing \"\n } else {\n throw new LexError(\"Unterminated double quote\", this.pos, this.line, this.column);\n }\n\n return { type: \"doubleQuote\", parts };\n }\n\n private readWord(): Token {\n let value = \"\";\n let hasGlobChars = false;\n\n while (!this.isAtEnd() && !this.isWordBreak(this.peek())) {\n const char = this.peek();\n\n if (char === \"\\\\\") {\n this.advance();\n if (!this.isAtEnd()) {\n value += this.advance();\n }\n } else {\n if (GLOB_CHARS.has(char)) {\n hasGlobChars = true;\n }\n value += this.advance();\n }\n }\n\n // Check if this looks like an assignment with value starting with $ or quote\n // e.g., VAR=$(...) or VAR=\"...\" or VAR='...'\n const assignmentPrefixMatch = value.match(/^([a-zA-Z_][a-zA-Z0-9_]*)=$/);\n if (assignmentPrefixMatch && (this.peek() === \"$\" || this.peek() === \"'\" || this.peek() === '\"')) {\n const name = assignmentPrefixMatch[1]!;\n // Read the value part\n const valueTokens = this.readAssignmentValueTokens();\n return {\n type: \"assignment\",\n name,\n value: valueTokens.length === 1 && valueTokens[0]!.type === \"word\"\n ? (valueTokens[0] as { type: \"word\"; value: string }).value\n : valueTokens,\n };\n }\n\n // Check if this is an assignment (VAR=value)\n const assignmentMatch = value.match(/^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$/);\n if (assignmentMatch) {\n const name = assignmentMatch[1]!;\n const rawValue = assignmentMatch[2]!;\n\n // Parse the value to handle variables and arithmetic\n const parsedValue = this.parseAssignmentValue(rawValue);\n return {\n type: \"assignment\",\n name,\n value: parsedValue,\n };\n }\n\n // Check if this is a keyword\n if (KEYWORDS.has(value)) {\n return { type: \"keyword\", value: value as KeywordValue };\n }\n\n if (hasGlobChars) {\n return { type: \"glob\", pattern: value };\n }\n\n return { type: \"word\", value };\n }\n\n private readAssignmentValueTokens(): Token[] {\n const tokens: Token[] = [];\n\n // Read tokens until we hit a space, newline, semicolon, etc.\n while (!this.isAtEnd()) {\n const char = this.peek();\n\n // Stop at whitespace or command terminators\n if (char === \" \" || char === \"\\t\" || char === \"\\n\" || char === \"\\r\" ||\n char === \";\" || char === \"|\" || char === \"&\" || char === \">\" || char === \"<\") {\n break;\n }\n\n if (char === \"$\") {\n tokens.push(this.readVariable());\n } else if (char === \"'\") {\n tokens.push(this.readSingleQuote());\n } else if (char === '\"') {\n tokens.push(this.readDoubleQuote());\n } else {\n // Read until word break\n let word = \"\";\n while (!this.isAtEnd() && !this.isWordBreak(this.peek())) {\n word += this.advance();\n }\n if (word) {\n tokens.push({ type: \"word\", value: word });\n } else {\n break;\n }\n }\n }\n\n return tokens;\n }\n\n private parseAssignmentValue(value: string): string | Token[] {\n // If value contains no special characters, return as string\n if (!value.includes(\"$\")) {\n return value;\n }\n\n // Parse the value to handle $VAR, ${VAR}, $((expr))\n const tokens: Token[] = [];\n let i = 0;\n let currentString = \"\";\n\n while (i < value.length) {\n if (value[i] === \"$\") {\n if (currentString) {\n tokens.push({ type: \"word\", value: currentString });\n currentString = \"\";\n }\n\n i++; // consume $\n if (i >= value.length) {\n tokens.push({ type: \"word\", value: \"$\" });\n break;\n }\n\n // Arithmetic expansion $((expr))\n if (value[i] === \"(\" && value[i + 1] === \"(\") {\n i += 2; // consume ((\n let depth = 1;\n let expr = \"\";\n while (i < value.length && depth > 0) {\n if (value[i] === \"(\" && value[i + 1] === \"(\") {\n depth++;\n expr += value[i]! + value[i + 1]!;\n i += 2;\n } else if (value[i] === \")\" && value[i + 1] === \")\") {\n depth--;\n if (depth > 0) {\n expr += value[i]! + value[i + 1]!;\n i += 2;\n } else {\n i += 2; // consume ))\n }\n } else {\n expr += value[i];\n i++;\n }\n }\n tokens.push({ type: \"arithmetic\", expression: expr });\n }\n // ${VAR} syntax\n else if (value[i] === \"{\") {\n i++; // consume {\n let varName = \"\";\n while (i < value.length && value[i] !== \"}\") {\n varName += value[i];\n i++;\n }\n if (i < value.length && value[i] === \"}\") {\n i++; // consume }\n }\n tokens.push({ type: \"variable\", name: varName });\n }\n // Special and positional parameters\n else if ([\"#\", \"*\", \"@\", \"?\"].includes(value[i]!)) {\n tokens.push({ type: \"variable\", name: value[i]! });\n i++;\n }\n else if (/[0-9]/.test(value[i]!)) {\n tokens.push({ type: \"variable\", name: value[i]! });\n i++;\n }\n // $VAR syntax\n else if (/[a-zA-Z_]/.test(value[i]!)) {\n let varName = \"\";\n while (i < value.length && /[a-zA-Z0-9_]/.test(value[i]!)) {\n varName += value[i];\n i++;\n }\n tokens.push({ type: \"variable\", name: varName });\n }\n // $(cmd) command substitution\n else if (value[i] === \"(\") {\n i++; // consume (\n let depth = 1;\n let cmd = \"\";\n while (i < value.length && depth > 0) {\n if (value[i] === \"(\") depth++;\n else if (value[i] === \")\") depth--;\n if (depth > 0) {\n cmd += value[i];\n }\n i++;\n }\n tokens.push({ type: \"substitution\", command: cmd });\n }\n else {\n // Not a variable, just a $\n currentString += \"$\";\n }\n } else {\n currentString += value[i];\n i++;\n }\n }\n\n if (currentString) {\n tokens.push({ type: \"word\", value: currentString });\n }\n\n if (tokens.length === 1 && tokens[0]!.type === \"word\") {\n return (tokens[0] as { type: \"word\"; value: string }).value;\n }\n\n return tokens.length > 0 ? tokens : value;\n }\n\n private readHeredoc(): Token {\n // Check for tab-stripping variant (<<-)\n const stripTabs = this.peek() === \"-\";\n if (stripTabs) {\n this.advance();\n }\n\n // Skip whitespace before delimiter\n while (this.peek() === \" \" || this.peek() === \"\\t\") {\n this.advance();\n }\n\n // Read delimiter and determine if expansion is enabled\n const { delimiter, expand } = this.readHeredocDelimiter();\n\n // Tokenize the rest of the current line and queue those tokens\n this.tokenizeRestOfLine();\n\n // Skip the newline that starts the heredoc content\n if (this.peek() === \"\\n\") {\n this.advance();\n }\n\n // Read content until closing delimiter\n let content = \"\";\n while (!this.isAtEnd()) {\n const lineStart = this.pos;\n let line = \"\";\n\n // Read until end of line or end of input\n while (!this.isAtEnd() && this.peek() !== \"\\n\") {\n line += this.advance();\n }\n\n // Check if this line is the delimiter (after stripping leading tabs if <<-)\n const strippedLine = stripTabs ? line.replace(/^\\t+/, \"\") : line;\n if (strippedLine === delimiter) {\n // Found closing delimiter, consume newline if present\n if (this.peek() === \"\\n\") {\n this.advance();\n }\n break;\n }\n\n // Add the line to content\n if (stripTabs) {\n content += line.replace(/^\\t+/, \"\");\n } else {\n content += line;\n }\n\n // Add newline if present\n if (this.peek() === \"\\n\") {\n content += this.advance();\n }\n }\n\n return { type: \"heredoc\", content, expand };\n }\n\n private readHeredocDelimiter(): { delimiter: string; expand: boolean } {\n const quoteChar = this.peek();\n\n // Quoted delimiter - no expansion\n if (quoteChar === \"'\" || quoteChar === '\"') {\n this.advance(); // consume opening quote\n let delimiter = \"\";\n while (!this.isAtEnd() && this.peek() !== quoteChar && this.peek() !== \"\\n\") {\n delimiter += this.advance();\n }\n if (this.peek() === quoteChar) {\n this.advance(); // consume closing quote\n }\n return { delimiter, expand: false };\n }\n\n // Unquoted delimiter - expansion enabled\n let delimiter = \"\";\n while (!this.isAtEnd() && !this.isWordBreak(this.peek()) && this.peek() !== \"\\n\") {\n if (this.peek() === \"\\\\\") {\n this.advance();\n if (!this.isAtEnd()) {\n delimiter += this.advance();\n }\n } else {\n delimiter += this.advance();\n }\n }\n\n return { delimiter, expand: true };\n }\n\n private tokenizeRestOfLine(): void {\n // Tokenize the rest of the line (until newline or end)\n while (!this.isAtEnd() && this.peek() !== \"\\n\") {\n // Skip only spaces and tabs, not newlines\n while (this.peek() === \" \" || this.peek() === \"\\t\") {\n this.advance();\n }\n if (this.isAtEnd() || this.peek() === \"\\n\") break;\n\n const token = this.readRestOfLineToken();\n if (token) {\n this.tokenQueue.push(token);\n }\n }\n }\n\n private readRestOfLineToken(): Token | null {\n const char = this.peek();\n\n if (char === \"|\") {\n this.advance();\n if (this.peek() === \"|\") {\n this.advance();\n return { type: \"or\" };\n }\n return { type: \"pipe\" };\n }\n\n if (char === \"&\") {\n this.advance();\n if (this.peek() === \"&\") {\n this.advance();\n return { type: \"and\" };\n }\n return { type: \"word\", value: \"&\" };\n }\n\n if (char === \";\") {\n this.advance();\n return { type: \"semicolon\" };\n }\n\n if (char === \">\") {\n this.advance();\n if (this.peek() === \">\") {\n this.advance();\n return { type: \"redirect\", mode: \">>\" };\n }\n return { type: \"redirect\", mode: \">\" };\n }\n\n if (char === \"<\") {\n this.advance();\n return { type: \"redirect\", mode: \"<\" };\n }\n\n if (char === \"$\") {\n return this.readVariable();\n }\n\n if (char === \"'\") {\n return this.readSingleQuote();\n }\n\n if (char === '\"') {\n return this.readDoubleQuote();\n }\n\n // Read a word but stop at newline\n let value = \"\";\n while (!this.isAtEnd() && !this.isWordBreak(this.peek()) && this.peek() !== \"\\n\") {\n if (this.peek() === \"\\\\\") {\n this.advance();\n if (!this.isAtEnd()) {\n value += this.advance();\n }\n } else {\n value += this.advance();\n }\n }\n\n if (value === \"\") return null;\n return { type: \"word\", value };\n }\n\n private isWordBreak(char: string): boolean {\n return WORD_BREAK_CHARS.has(char);\n }\n\n private isVarChar(char: string): boolean {\n return /[a-zA-Z0-9_]/.test(char);\n }\n\n private skipWhitespace(): void {\n while (!this.isAtEnd() && /\\s/.test(this.peek())) {\n this.advance();\n }\n }\n\n private skipWhitespaceExceptNewlines(): void {\n while (!this.isAtEnd() && /[ \\t\\r]/.test(this.peek())) {\n this.advance();\n }\n }\n\n private skipComment(): void {\n while (!this.isAtEnd() && this.peek() !== \"\\n\") {\n this.advance();\n }\n }\n\n private peek(): string {\n return this.source[this.pos] ?? \"\";\n }\n\n private peekAhead(n: number): string {\n return this.source[this.pos + n] ?? \"\";\n }\n\n private advance(): string {\n const char = this.source[this.pos]!;\n this.pos++;\n if (char === \"\\n\") {\n this.line++;\n this.column = 1;\n } else {\n this.column++;\n }\n return char;\n }\n\n private isAtEnd(): boolean {\n return this.pos >= this.source.length;\n }\n}\n\nexport function lex(source: string, options?: { preserveNewlines?: boolean }): Token[] {\n return new Lexer(source, options).tokenize();\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "1A7BD45CCD45F2A164756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -404,6 +404,16 @@ class Parser {
|
|
|
404
404
|
parts.push({ type: "variable", name, quoted: false });
|
|
405
405
|
continue;
|
|
406
406
|
}
|
|
407
|
+
if (["#", "*", "@", "?"].includes(content[i] ?? "")) {
|
|
408
|
+
parts.push({ type: "variable", name: content[i], quoted: false });
|
|
409
|
+
i++;
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
if (/[0-9]/.test(content[i] ?? "")) {
|
|
413
|
+
parts.push({ type: "variable", name: content[i], quoted: false });
|
|
414
|
+
i++;
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
407
417
|
if (content[i] === "(" && content[i + 1] === "(") {
|
|
408
418
|
i += 2;
|
|
409
419
|
let depth = 1;
|
|
@@ -515,4 +525,4 @@ export {
|
|
|
515
525
|
Parser
|
|
516
526
|
};
|
|
517
527
|
|
|
518
|
-
//# debugId=
|
|
528
|
+
//# debugId=326DB598A25C1C2F64756E2164756E21
|