shell-dsl 0.0.39 → 0.0.41
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 +183 -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 +18 -2
- package/dist/cjs/src/commands/index.cjs.map +3 -3
- 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 +9 -1
- package/dist/cjs/src/index.cjs.map +3 -3
- package/dist/cjs/src/input-analysis.cjs +154 -0
- package/dist/cjs/src/input-analysis.cjs.map +10 -0
- package/dist/cjs/src/interpreter/context.cjs +6 -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 +434 -82
- package/dist/cjs/src/interpreter/interpreter.cjs.map +3 -3
- package/dist/cjs/src/io/async-queue.cjs +105 -0
- package/dist/cjs/src/io/async-queue.cjs.map +10 -0
- package/dist/cjs/src/io/index.cjs +4 -1
- package/dist/cjs/src/io/index.cjs.map +3 -3
- package/dist/cjs/src/io/input-controller.cjs +113 -0
- package/dist/cjs/src/io/input-controller.cjs.map +10 -0
- package/dist/cjs/src/io/stdout.cjs +9 -6
- package/dist/cjs/src/io/stdout.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/shell-dsl.cjs +13 -5
- package/dist/cjs/src/shell-dsl.cjs.map +3 -3
- package/dist/cjs/src/shell-session.cjs +128 -0
- package/dist/cjs/src/shell-session.cjs.map +10 -0
- package/dist/cjs/src/types.cjs.map +2 -2
- 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 +18 -2
- package/dist/mjs/src/commands/index.mjs.map +3 -3
- 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 +19 -3
- package/dist/mjs/src/index.mjs.map +3 -3
- package/dist/mjs/src/input-analysis.mjs +114 -0
- package/dist/mjs/src/input-analysis.mjs.map +10 -0
- package/dist/mjs/src/interpreter/context.mjs +6 -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 +434 -82
- package/dist/mjs/src/interpreter/interpreter.mjs.map +3 -3
- package/dist/mjs/src/io/async-queue.mjs +64 -0
- package/dist/mjs/src/io/async-queue.mjs.map +10 -0
- package/dist/mjs/src/io/index.mjs +4 -1
- package/dist/mjs/src/io/index.mjs.map +3 -3
- package/dist/mjs/src/io/input-controller.mjs +72 -0
- package/dist/mjs/src/io/input-controller.mjs.map +10 -0
- package/dist/mjs/src/io/stdout.mjs +9 -6
- package/dist/mjs/src/io/stdout.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/shell-dsl.mjs +13 -5
- package/dist/mjs/src/shell-dsl.mjs.map +3 -3
- package/dist/mjs/src/shell-session.mjs +88 -0
- package/dist/mjs/src/shell-session.mjs.map +10 -0
- package/dist/mjs/src/types.mjs.map +2 -2
- package/dist/types/src/commands/exit/exit.d.ts +2 -0
- package/dist/types/src/commands/index.d.ts +2 -0
- package/dist/types/src/commands/sh/sh.d.ts +5 -0
- package/dist/types/src/index.d.ts +6 -3
- package/dist/types/src/input-analysis.d.ts +14 -0
- package/dist/types/src/interpreter/context.d.ts +4 -1
- package/dist/types/src/interpreter/index.d.ts +1 -1
- package/dist/types/src/interpreter/interpreter.d.ts +36 -1
- package/dist/types/src/io/async-queue.d.ts +12 -0
- package/dist/types/src/io/index.d.ts +1 -0
- package/dist/types/src/io/input-controller.d.ts +15 -0
- package/dist/types/src/io/stdout.d.ts +4 -3
- package/dist/types/src/shell-dsl.d.ts +2 -0
- package/dist/types/src/shell-session.d.ts +23 -0
- package/dist/types/src/types.d.ts +52 -0
- package/package.json +1 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/io/input-controller.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { ShellInputController } from \"../types.cjs\";\n\ntype Waiter = {\n resolve: () => void;\n reject: (reason?: unknown) => void;\n};\n\nexport class ShellInputControllerImpl implements ShellInputController {\n private chunks: Uint8Array[] = [];\n private closed = false;\n private aborted = false;\n private abortReason: unknown;\n private waiters: Waiter[] = [];\n\n async write(chunk: Uint8Array | string): Promise<void> {\n if (this.closed) {\n throw new Error(\"Input stream is closed\");\n }\n if (this.aborted) {\n throw this.abortReason ?? new Error(\"Input stream aborted\");\n }\n\n this.chunks.push(typeof chunk === \"string\" ? new TextEncoder().encode(chunk) : chunk);\n this.wake();\n }\n\n close(): void {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.wake();\n }\n\n abort(reason?: unknown): void {\n if (this.aborted) {\n return;\n }\n this.aborted = true;\n this.abortReason = reason ?? new Error(\"Input stream aborted\");\n this.wakeWithError(this.abortReason);\n }\n\n async *[Symbol.asyncIterator](): AsyncIterator<Uint8Array> {\n while (true) {\n while (this.chunks.length > 0) {\n yield this.chunks.shift()!;\n }\n\n if (this.aborted) {\n throw this.abortReason ?? new Error(\"Input stream aborted\");\n }\n if (this.closed) {\n break;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.waiters.push({ resolve, reject });\n });\n }\n }\n\n private wake(): void {\n const waiters = this.waiters;\n this.waiters = [];\n for (const waiter of waiters) {\n waiter.resolve();\n }\n }\n\n private wakeWithError(reason?: unknown): void {\n const waiters = this.waiters;\n this.waiters = [];\n for (const waiter of waiters) {\n waiter.reject(reason);\n }\n }\n}\n\nexport function createShellInput(): ShellInputController {\n return new ShellInputControllerImpl();\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOO,MAAM,yBAAyD;AAAA,EAC5D,SAAuB,CAAC;AAAA,EACxB,SAAS;AAAA,EACT,UAAU;AAAA,EACV;AAAA,EACA,UAAoB,CAAC;AAAA,OAEvB,MAAK,CAAC,OAA2C;AAAA,IACrD,IAAI,KAAK,QAAQ;AAAA,MACf,MAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AAAA,IACA,IAAI,KAAK,SAAS;AAAA,MAChB,MAAM,KAAK,eAAe,IAAI,MAAM,sBAAsB;AAAA,IAC5D;AAAA,IAEA,KAAK,OAAO,KAAK,OAAO,UAAU,WAAW,IAAI,YAAY,EAAE,OAAO,KAAK,IAAI,KAAK;AAAA,IACpF,KAAK,KAAK;AAAA;AAAA,EAGZ,KAAK,GAAS;AAAA,IACZ,IAAI,KAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA,IACA,KAAK,SAAS;AAAA,IACd,KAAK,KAAK;AAAA;AAAA,EAGZ,KAAK,CAAC,QAAwB;AAAA,IAC5B,IAAI,KAAK,SAAS;AAAA,MAChB;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AAAA,IACf,KAAK,cAAc,UAAU,IAAI,MAAM,sBAAsB;AAAA,IAC7D,KAAK,cAAc,KAAK,WAAW;AAAA;AAAA,UAG7B,OAAO,cAAc,GAA8B;AAAA,IACzD,OAAO,MAAM;AAAA,MACX,OAAO,KAAK,OAAO,SAAS,GAAG;AAAA,QAC7B,MAAM,KAAK,OAAO,MAAM;AAAA,MAC1B;AAAA,MAEA,IAAI,KAAK,SAAS;AAAA,QAChB,MAAM,KAAK,eAAe,IAAI,MAAM,sBAAsB;AAAA,MAC5D;AAAA,MACA,IAAI,KAAK,QAAQ;AAAA,QACf;AAAA,MACF;AAAA,MAEA,MAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAAA,QAC3C,KAAK,QAAQ,KAAK,EAAE,SAAS,OAAO,CAAC;AAAA,OACtC;AAAA,IACH;AAAA;AAAA,EAGM,IAAI,GAAS;AAAA,IACnB,MAAM,UAAU,KAAK;AAAA,IACrB,KAAK,UAAU,CAAC;AAAA,IAChB,WAAW,UAAU,SAAS;AAAA,MAC5B,OAAO,QAAQ;AAAA,IACjB;AAAA;AAAA,EAGM,aAAa,CAAC,QAAwB;AAAA,IAC5C,MAAM,UAAU,KAAK;AAAA,IACrB,KAAK,UAAU,CAAC;AAAA,IAChB,WAAW,UAAU,SAAS;AAAA,MAC5B,OAAO,OAAO,MAAM;AAAA,IACtB;AAAA;AAEJ;AAEO,SAAS,gBAAgB,GAAyB;AAAA,EACvD,OAAO,IAAI;AAAA;",
|
|
8
|
+
"debugId": "23B26B983781CA8B64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -56,14 +56,17 @@ class OutputCollectorImpl {
|
|
|
56
56
|
resolveWait = null;
|
|
57
57
|
waitPromise = null;
|
|
58
58
|
isTTY;
|
|
59
|
-
|
|
59
|
+
onWrite;
|
|
60
|
+
constructor(isTTY = false, onWrite) {
|
|
60
61
|
this.isTTY = isTTY;
|
|
62
|
+
this.onWrite = onWrite;
|
|
61
63
|
}
|
|
62
64
|
async write(chunk) {
|
|
63
65
|
if (this.closed) {
|
|
64
66
|
throw new Error("Output stream is closed");
|
|
65
67
|
}
|
|
66
68
|
this.chunks.push(chunk);
|
|
69
|
+
await this.onWrite?.(chunk);
|
|
67
70
|
if (this.resolveWait) {
|
|
68
71
|
this.resolveWait();
|
|
69
72
|
this.resolveWait = null;
|
|
@@ -162,11 +165,11 @@ class PipeBuffer {
|
|
|
162
165
|
}
|
|
163
166
|
}
|
|
164
167
|
}
|
|
165
|
-
function createStdout(isTTY = false) {
|
|
166
|
-
return new OutputCollectorImpl(isTTY);
|
|
168
|
+
function createStdout(isTTY = false, onWrite) {
|
|
169
|
+
return new OutputCollectorImpl(isTTY, onWrite);
|
|
167
170
|
}
|
|
168
|
-
function createStderr(isTTY = false) {
|
|
169
|
-
return new OutputCollectorImpl(isTTY);
|
|
171
|
+
function createStderr(isTTY = false, onWrite) {
|
|
172
|
+
return new OutputCollectorImpl(isTTY, onWrite);
|
|
170
173
|
}
|
|
171
174
|
function createPipe() {
|
|
172
175
|
return new PipeBuffer;
|
|
@@ -216,4 +219,4 @@ function createBufferTargetCollector(target) {
|
|
|
216
219
|
return new BufferTargetCollector(target);
|
|
217
220
|
}
|
|
218
221
|
|
|
219
|
-
//# debugId=
|
|
222
|
+
//# debugId=2F5A4E06A0B3D2B364756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/io/stdout.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { Stdout, Stderr, OutputCollector } from \"../types.cjs\";\n\nexport class OutputCollectorImpl implements OutputCollector {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private closeResolvers: Array<() => void> = [];\n private resolveWait: (() => void) | null = null;\n private waitPromise: Promise<void> | null = null;\n public isTTY: boolean;\n\n constructor(isTTY: boolean = false) {\n this.isTTY = isTTY;\n }\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Output stream is closed\");\n }\n this.chunks.push(chunk);\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n // Wake up anyone waiting for close\n for (const resolve of this.closeResolvers) {\n resolve();\n }\n this.closeResolvers = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.closeResolvers.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n let index = 0;\n\n while (true) {\n while (index < this.chunks.length) {\n yield this.chunks[index]!;\n index++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data or close\n if (!this.waitPromise) {\n this.waitPromise = new Promise<void>((resolve) => {\n this.resolveWait = resolve;\n });\n }\n await this.waitPromise;\n }\n }\n}\n\nexport class PipeBuffer implements OutputCollector, Stdout {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private waitingReaders: Array<() => void> = [];\n private readIndex: number = 0;\n public readonly isTTY: boolean = false;\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Pipe is closed\");\n }\n this.chunks.push(chunk);\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n while (true) {\n // Yield any available chunks\n while (this.readIndex < this.chunks.length) {\n yield this.chunks[this.readIndex]!;\n this.readIndex++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n }\n}\n\nexport function createStdout(isTTY: boolean = false): OutputCollector {\n return new OutputCollectorImpl(isTTY);\n}\n\nexport function createStderr(isTTY: boolean = false): OutputCollector {\n return new OutputCollectorImpl(isTTY);\n}\n\nexport function createPipe(): PipeBuffer {\n return new PipeBuffer();\n}\n\nexport class BufferTargetCollector implements OutputCollector {\n private target: Buffer;\n private offset: number = 0;\n private closed: boolean = false;\n private closeResolvers: Array<() => void> = [];\n public readonly isTTY: boolean = false;\n\n constructor(target: Buffer) {\n this.target = target;\n }\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Output stream is closed\");\n }\n for (let i = 0; i < chunk.length && this.offset < this.target.length; i++) {\n this.target[this.offset++] = chunk[i]!;\n }\n }\n\n async writeText(str: string): Promise<void> {\n const bytes = new TextEncoder().encode(str);\n await this.write(bytes);\n }\n\n close(): void {\n this.closed = true;\n for (const resolve of this.closeResolvers) {\n resolve();\n }\n this.closeResolvers = [];\n }\n\n async collect(): Promise<Buffer> {\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.closeResolvers.push(resolve);\n });\n }\n return this.target.subarray(0, this.offset) as Buffer;\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n yield this.target.subarray(0, this.offset);\n }\n}\n\nexport function createBufferTargetCollector(target: Buffer): OutputCollector {\n return new BufferTargetCollector(target);\n}\n"
|
|
5
|
+
"import type { Stdout, Stderr, OutputCollector } from \"../types.cjs\";\n\nexport class OutputCollectorImpl implements OutputCollector {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private closeResolvers: Array<() => void> = [];\n private resolveWait: (() => void) | null = null;\n private waitPromise: Promise<void> | null = null;\n public isTTY: boolean;\n private onWrite?: (chunk: Uint8Array) => void | Promise<void>;\n\n constructor(isTTY: boolean = false, onWrite?: (chunk: Uint8Array) => void | Promise<void>) {\n this.isTTY = isTTY;\n this.onWrite = onWrite;\n }\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Output stream is closed\");\n }\n this.chunks.push(chunk);\n await this.onWrite?.(chunk);\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n // Wake up anyone waiting for close\n for (const resolve of this.closeResolvers) {\n resolve();\n }\n this.closeResolvers = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.closeResolvers.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n let index = 0;\n\n while (true) {\n while (index < this.chunks.length) {\n yield this.chunks[index]!;\n index++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data or close\n if (!this.waitPromise) {\n this.waitPromise = new Promise<void>((resolve) => {\n this.resolveWait = resolve;\n });\n }\n await this.waitPromise;\n }\n }\n}\n\nexport class PipeBuffer implements OutputCollector, Stdout {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private waitingReaders: Array<() => void> = [];\n private readIndex: number = 0;\n public readonly isTTY: boolean = false;\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Pipe is closed\");\n }\n this.chunks.push(chunk);\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n while (true) {\n // Yield any available chunks\n while (this.readIndex < this.chunks.length) {\n yield this.chunks[this.readIndex]!;\n this.readIndex++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n }\n}\n\nexport function createStdout(\n isTTY: boolean = false,\n onWrite?: (chunk: Uint8Array) => void | Promise<void>\n): OutputCollector {\n return new OutputCollectorImpl(isTTY, onWrite);\n}\n\nexport function createStderr(\n isTTY: boolean = false,\n onWrite?: (chunk: Uint8Array) => void | Promise<void>\n): OutputCollector {\n return new OutputCollectorImpl(isTTY, onWrite);\n}\n\nexport function createPipe(): PipeBuffer {\n return new PipeBuffer();\n}\n\nexport class BufferTargetCollector implements OutputCollector {\n private target: Buffer;\n private offset: number = 0;\n private closed: boolean = false;\n private closeResolvers: Array<() => void> = [];\n public readonly isTTY: boolean = false;\n\n constructor(target: Buffer) {\n this.target = target;\n }\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Output stream is closed\");\n }\n for (let i = 0; i < chunk.length && this.offset < this.target.length; i++) {\n this.target[this.offset++] = chunk[i]!;\n }\n }\n\n async writeText(str: string): Promise<void> {\n const bytes = new TextEncoder().encode(str);\n await this.write(bytes);\n }\n\n close(): void {\n this.closed = true;\n for (const resolve of this.closeResolvers) {\n resolve();\n }\n this.closeResolvers = [];\n }\n\n async collect(): Promise<Buffer> {\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.closeResolvers.push(resolve);\n });\n }\n return this.target.subarray(0, this.offset) as Buffer;\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n yield this.target.subarray(0, this.offset);\n }\n}\n\nexport function createBufferTargetCollector(target: Buffer): OutputCollector {\n return new BufferTargetCollector(target);\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,MAAM,oBAA+C;AAAA,EAClD,SAAuB,CAAC;AAAA,EACxB,SAAkB;AAAA,EAClB,iBAAoC,CAAC;AAAA,EACrC,cAAmC;AAAA,EACnC,cAAoC;AAAA,EACrC;AAAA,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "2F5A4E06A0B3D2B364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -250,6 +250,12 @@ class Lexer {
|
|
|
250
250
|
}
|
|
251
251
|
return { type: "variable", name: name2 };
|
|
252
252
|
}
|
|
253
|
+
if (["#", "*", "@", "?"].includes(this.peek())) {
|
|
254
|
+
return { type: "variable", name: this.advance() };
|
|
255
|
+
}
|
|
256
|
+
if (/[0-9]/.test(this.peek())) {
|
|
257
|
+
return { type: "variable", name: this.advance() };
|
|
258
|
+
}
|
|
253
259
|
let name = "";
|
|
254
260
|
while (!this.isAtEnd() && this.isVarChar(this.peek())) {
|
|
255
261
|
name += this.advance();
|
|
@@ -477,6 +483,12 @@ class Lexer {
|
|
|
477
483
|
i++;
|
|
478
484
|
}
|
|
479
485
|
tokens.push({ type: "variable", name: varName });
|
|
486
|
+
} else if (["#", "*", "@", "?"].includes(value[i])) {
|
|
487
|
+
tokens.push({ type: "variable", name: value[i] });
|
|
488
|
+
i++;
|
|
489
|
+
} else if (/[0-9]/.test(value[i])) {
|
|
490
|
+
tokens.push({ type: "variable", name: value[i] });
|
|
491
|
+
i++;
|
|
480
492
|
} else if (/[a-zA-Z_]/.test(value[i])) {
|
|
481
493
|
let varName = "";
|
|
482
494
|
while (i < value.length && /[a-zA-Z0-9_]/.test(value[i])) {
|
|
@@ -707,4 +719,4 @@ function lex(source, options) {
|
|
|
707
719
|
return new Lexer(source, options).tokenize();
|
|
708
720
|
}
|
|
709
721
|
|
|
710
|
-
//# debugId=
|
|
722
|
+
//# debugId=58176089C4A24CD964756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lexer/lexer.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { LexError } from \"../errors.cjs\";\nimport type { Token, RedirectMode, KeywordValue } from \"./tokens.cjs\";\nimport { KEYWORDS } from \"./tokens.cjs\";\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.cjs\";\nimport type { Token, RedirectMode, KeywordValue } from \"./tokens.cjs\";\nimport { KEYWORDS } from \"./tokens.cjs\";\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": "58176089C4A24CD964756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -448,6 +448,16 @@ class Parser {
|
|
|
448
448
|
parts.push({ type: "variable", name, quoted: false });
|
|
449
449
|
continue;
|
|
450
450
|
}
|
|
451
|
+
if (["#", "*", "@", "?"].includes(content[i] ?? "")) {
|
|
452
|
+
parts.push({ type: "variable", name: content[i], quoted: false });
|
|
453
|
+
i++;
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
if (/[0-9]/.test(content[i] ?? "")) {
|
|
457
|
+
parts.push({ type: "variable", name: content[i], quoted: false });
|
|
458
|
+
i++;
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
451
461
|
if (content[i] === "(" && content[i + 1] === "(") {
|
|
452
462
|
i += 2;
|
|
453
463
|
let depth = 1;
|
|
@@ -555,4 +565,4 @@ function parse(tokens) {
|
|
|
555
565
|
return new Parser(tokens).parse();
|
|
556
566
|
}
|
|
557
567
|
|
|
558
|
-
//# debugId=
|
|
568
|
+
//# debugId=BB94E2D814E2C9C664756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/parser/parser.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { ParseError } from \"../errors.cjs\";\nimport { Lexer } from \"../lexer/lexer.cjs\";\nimport type { Token, KeywordValue } from \"../lexer/tokens.cjs\";\nimport type {\n ASTNode,\n Redirect,\n RedirectMode,\n CommandNode,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n CaseClause,\n WordNode,\n WordPart,\n} from \"./ast.cjs\";\n\nexport class Parser {\n private tokens: Token[];\n private pos: number = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n parse(): ASTNode {\n const result = this.parseSequence();\n if (!this.isAtEnd()) {\n throw new ParseError(`Unexpected token: ${JSON.stringify(this.peek())}`);\n }\n return result;\n }\n\n // sequence := and_or ((';'|'\\n') and_or)*\n private parseSequence(): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n commands.push(this.parseAndOr());\n\n while (this.match(\"semicolon\") || this.match(\"newline\")) {\n this.skipNewlines();\n if (this.isAtEnd() || this.check(\"semicolon\") || this.check(\"newline\") || this.isTerminatingKeyword()) continue;\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private skipNewlines(): void {\n while (this.match(\"newline\")) {\n // keep consuming newlines\n }\n }\n\n private isTerminatingKeyword(): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return [\"then\", \"elif\", \"else\", \"fi\", \"do\", \"done\", \"esac\"].includes(token.value);\n }\n\n // and_or := pipeline (('&&'|'||') pipeline)*\n private parseAndOr(): ASTNode {\n let left = this.parsePipeline();\n\n while (this.check(\"and\") || this.check(\"or\")) {\n if (this.match(\"and\")) {\n const right = this.parsePipeline();\n left = { type: \"and\", left, right };\n } else if (this.match(\"or\")) {\n const right = this.parsePipeline();\n left = { type: \"or\", left, right };\n }\n }\n\n return left;\n }\n\n // pipeline := command ('|' command)*\n private parsePipeline(): ASTNode {\n const commands: ASTNode[] = [];\n commands.push(this.parseCompoundOrCommand());\n\n while (this.match(\"pipe\")) {\n this.skipNewlines();\n commands.push(this.parseCompoundOrCommand());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"pipeline\", commands };\n }\n\n // compound_or_command := compound_command | simple_command\n private parseCompoundOrCommand(): ASTNode {\n this.skipNewlines();\n const token = this.peek();\n\n if (token.type === \"keyword\") {\n switch (token.value) {\n case \"if\":\n return this.parseIf();\n case \"for\":\n return this.parseFor();\n case \"while\":\n return this.parseWhile();\n case \"until\":\n return this.parseUntil();\n case \"case\":\n return this.parseCase();\n }\n }\n\n return this.parseCommand();\n }\n\n // if := 'if' compound_list 'then' compound_list ('elif' compound_list 'then' compound_list)* ['else' compound_list] 'fi'\n private parseIf(): IfNode {\n this.expectKeyword(\"if\");\n const condition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const thenBranch = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n\n const elifBranches: Array<{ condition: ASTNode; body: ASTNode }> = [];\n while (this.checkKeyword(\"elif\")) {\n this.expectKeyword(\"elif\");\n const elifCondition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const elifBody = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n elifBranches.push({ condition: elifCondition, body: elifBody });\n }\n\n let elseBranch: ASTNode | undefined;\n if (this.checkKeyword(\"else\")) {\n this.expectKeyword(\"else\");\n elseBranch = this.parseCompoundList([\"fi\"]);\n }\n\n this.expectKeyword(\"fi\");\n\n return {\n type: \"if\",\n condition,\n thenBranch,\n elifBranches,\n elseBranch,\n };\n }\n\n // for := 'for' NAME ['in' word*] (';'|'\\n') 'do' compound_list 'done'\n private parseFor(): ForNode {\n this.expectKeyword(\"for\");\n\n const varToken = this.peek();\n if (varToken.type !== \"word\") {\n throw new ParseError(\"Expected variable name after 'for'\");\n }\n this.advance();\n const variable = varToken.value;\n\n const items: WordNode[] = [];\n if (this.checkKeyword(\"in\")) {\n this.expectKeyword(\"in\");\n while (!this.isAtEnd() && !this.check(\"semicolon\") && !this.check(\"newline\") && !this.checkKeyword(\"do\")) {\n items.push(this.parseWordArg());\n }\n }\n\n if (!this.match(\"semicolon\")) {\n this.match(\"newline\");\n }\n this.skipNewlines();\n\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"for\",\n variable,\n items,\n body,\n };\n }\n\n // while := 'while' compound_list 'do' compound_list 'done'\n private parseWhile(): WhileNode {\n this.expectKeyword(\"while\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"while\",\n condition,\n body,\n };\n }\n\n // until := 'until' compound_list 'do' compound_list 'done'\n private parseUntil(): UntilNode {\n this.expectKeyword(\"until\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"until\",\n condition,\n body,\n };\n }\n\n // case := 'case' word 'in' case_clause* 'esac'\n private parseCase(): CaseNode {\n this.expectKeyword(\"case\");\n const word = this.parseWordArg();\n this.expectKeyword(\"in\");\n this.skipNewlines();\n\n const clauses: CaseClause[] = [];\n\n while (!this.isAtEnd() && !this.checkKeyword(\"esac\")) {\n this.match(\"openParen\");\n\n const patterns: WordNode[] = [];\n patterns.push(this.parseCasePattern());\n\n while (this.match(\"pipe\")) {\n patterns.push(this.parseCasePattern());\n }\n\n if (!this.match(\"closeParen\")) {\n throw new ParseError(\"Expected ')' after case pattern\");\n }\n\n const body = this.parseCaseBody();\n clauses.push({ patterns, body });\n\n this.match(\"doubleSemicolon\");\n this.skipNewlines();\n }\n\n this.expectKeyword(\"esac\");\n\n return {\n type: \"case\",\n word,\n clauses,\n };\n }\n\n private parseCasePattern(): WordNode {\n const token = this.peek();\n\n if (token.type === \"word\" || token.type === \"glob\" || token.type === \"singleQuote\" || token.type === \"doubleQuote\") {\n return this.parseWordArg();\n }\n\n throw new ParseError(`Expected pattern in case clause, got ${token.type}`);\n }\n\n private parseCaseBody(): ASTNode {\n const commands: ASTNode[] = [];\n this.skipNewlines();\n\n while (!this.isAtEnd() && !this.check(\"doubleSemicolon\") && !this.checkKeyword(\"esac\")) {\n commands.push(this.parseAndOr());\n if (!this.match(\"semicolon\") && !this.match(\"newline\")) {\n break;\n }\n this.skipNewlines();\n if (this.check(\"doubleSemicolon\") || this.checkKeyword(\"esac\")) {\n break;\n }\n }\n\n if (commands.length === 0) {\n return this.createNoopCommand();\n }\n if (commands.length === 1) {\n return commands[0]!;\n }\n return { type: \"sequence\", commands };\n }\n\n // compound_list := and_or ((';'|'\\n') and_or)* [';'|'\\n']\n private parseCompoundList(terminators: KeywordValue[]): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n\n if (this.isCompoundListTerminator(terminators)) {\n return this.createNoopCommand();\n }\n\n commands.push(this.parseAndOr());\n\n while ((this.match(\"semicolon\") || this.match(\"newline\")) && !this.isAtEnd()) {\n this.skipNewlines();\n if (this.isCompoundListTerminator(terminators)) {\n break;\n }\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private createNoopCommand(): CommandNode {\n return {\n type: \"command\",\n name: this.createTextWord(\"true\"),\n args: [],\n redirects: [],\n assignments: [],\n };\n }\n\n private createTextWord(value: string, quoted = false): WordNode {\n return {\n type: \"word\",\n parts: value === \"\" && !quoted ? [] : [{ type: \"text\", value, quoted }],\n };\n }\n\n private isCompoundListTerminator(terminators: KeywordValue[]): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return terminators.includes(token.value);\n }\n\n private checkKeyword(value: KeywordValue): boolean {\n const token = this.peek();\n return token.type === \"keyword\" && token.value === value;\n }\n\n private expectKeyword(value: KeywordValue): void {\n if (!this.checkKeyword(value)) {\n throw new ParseError(`Expected '${value}'`);\n }\n this.advance();\n }\n\n // command := assignment* word+ redirect*\n private parseCommand(): CommandNode {\n const assignments: Array<{ name: string; value: WordNode }> = [];\n const args: WordNode[] = [];\n const redirects: Redirect[] = [];\n\n while (this.check(\"assignment\")) {\n const token = this.advance() as Token & { type: \"assignment\" };\n assignments.push({\n name: token.name,\n value: this.tokenToWord(token.value),\n });\n }\n\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToWord(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n\n while (this.check(\"redirect\")) {\n const redirect = this.parseRedirect();\n redirects.push(redirect);\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToWord(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n }\n\n if (args.length === 0 && assignments.length === 0 && redirects.length === 0) {\n throw new ParseError(\"Expected command\");\n }\n\n const name = args.shift() ?? this.createTextWord(redirects.length > 0 ? \":\" : \"\");\n\n return {\n type: \"command\",\n name,\n args,\n redirects,\n assignments,\n };\n }\n\n private parseWordArg(): WordNode {\n const token = this.advance();\n return this.tokenToWord(token);\n }\n\n private tokenToWord(token: Token | string | Token[]): WordNode {\n const parts = this.tokenToWordParts(token);\n return {\n type: \"word\",\n parts,\n };\n }\n\n private tokenToWordParts(token: Token | string | Token[], quoted = false): WordPart[] {\n if (typeof token === \"string\") {\n return [{ type: \"text\", value: token, quoted }];\n }\n\n if (Array.isArray(token)) {\n return token.flatMap((part) => this.tokenToWordParts(part, quoted));\n }\n\n switch (token.type) {\n case \"word\":\n return [{ type: \"text\", value: token.value, quoted }];\n case \"singleQuote\":\n return [{ type: \"text\", value: token.value, quoted: true }];\n case \"doubleQuote\":\n return this.parseDoubleQuoteParts(token.parts);\n case \"variable\":\n return [{ type: \"variable\", name: token.name, quoted }];\n case \"substitution\": {\n const innerParser = new Parser(\n new Lexer(token.command, { preserveNewlines: true }).tokenize()\n );\n return [{ type: \"substitution\", command: innerParser.parse(), quoted }];\n }\n case \"arithmetic\":\n return [{ type: \"arithmetic\", expression: token.expression, quoted }];\n case \"glob\":\n return [{ type: \"text\", value: token.pattern, quoted }];\n case \"assignment\":\n return this.tokenToWordParts(token.value, quoted);\n case \"heredoc\":\n return token.expand\n ? this.parseHeredocContent(token.content).parts\n : [{ type: \"text\", value: token.content, quoted: true }];\n default:\n throw new ParseError(`Unexpected token type: ${(token as Token).type}`);\n }\n }\n\n private parseDoubleQuoteParts(parts: Array<string | Token>): WordPart[] {\n if (parts.length === 0) {\n return [{ type: \"text\", value: \"\", quoted: true }];\n }\n\n return parts.flatMap((part) => this.tokenToWordParts(part, true));\n }\n\n private parseHeredocContent(content: string): WordNode {\n const parts: WordPart[] = [];\n let currentText = \"\";\n let i = 0;\n\n const pushText = () => {\n if (currentText.length > 0) {\n parts.push({ type: \"text\", value: currentText, quoted: false });\n currentText = \"\";\n }\n };\n\n while (i < content.length) {\n if (content[i] !== \"$\") {\n currentText += content[i];\n i++;\n continue;\n }\n\n pushText();\n i++;\n\n if (i >= content.length) {\n currentText += \"$\";\n break;\n }\n\n if (content[i] === \"{\") {\n i++;\n let name = \"\";\n while (i < content.length && content[i] !== \"}\") {\n name += content[i];\n i++;\n }\n if (i < content.length && content[i] === \"}\") {\n i++;\n }\n parts.push({ type: \"variable\", name, quoted: false });\n continue;\n }\n\n if (content[i] === \"(\" && content[i + 1] === \"(\") {\n i += 2;\n let depth = 1;\n let expression = \"\";\n while (i < content.length && depth > 0) {\n if (content[i] === \"(\" && content[i + 1] === \"(\") {\n depth++;\n expression += content[i]! + content[i + 1]!;\n i += 2;\n continue;\n }\n if (content[i] === \")\" && content[i + 1] === \")\") {\n depth--;\n if (depth === 0) {\n i += 2;\n break;\n }\n expression += content[i]! + content[i + 1]!;\n i += 2;\n continue;\n }\n expression += content[i]!;\n i++;\n }\n parts.push({ type: \"arithmetic\", expression, quoted: false });\n continue;\n }\n\n if (content[i] === \"(\") {\n i++;\n let depth = 1;\n let command = \"\";\n while (i < content.length && depth > 0) {\n if (content[i] === \"(\") {\n depth++;\n } else if (content[i] === \")\") {\n depth--;\n if (depth === 0) {\n i++;\n break;\n }\n }\n command += content[i]!;\n i++;\n }\n const innerParser = new Parser(\n new Lexer(command, { preserveNewlines: true }).tokenize()\n );\n parts.push({ type: \"substitution\", command: innerParser.parse(), quoted: false });\n continue;\n }\n\n if (/[a-zA-Z_]/.test(content[i] ?? \"\")) {\n let name = \"\";\n while (i < content.length && /[a-zA-Z0-9_]/.test(content[i] ?? \"\")) {\n name += content[i];\n i++;\n }\n parts.push({ type: \"variable\", name, quoted: false });\n continue;\n }\n\n currentText += \"$\";\n }\n\n pushText();\n\n return {\n type: \"word\",\n parts,\n };\n }\n\n private parseRedirect(): Redirect {\n const token = this.advance() as Token & { type: \"redirect\" };\n const mode = token.mode as RedirectMode;\n\n if (mode === \"2>&1\" || mode === \"1>&2\") {\n return { mode, target: this.createTextWord(\"\") };\n }\n\n if (!this.isWordToken()) {\n throw new ParseError(`Expected redirect target after ${mode}`);\n }\n\n const target = this.parseWordArg();\n return { mode, target };\n }\n\n private isWordToken(): boolean {\n const token = this.peek();\n return (\n Array.isArray(token) ||\n token.type === \"word\" ||\n token.type === \"singleQuote\" ||\n token.type === \"doubleQuote\" ||\n token.type === \"variable\" ||\n token.type === \"substitution\" ||\n token.type === \"arithmetic\" ||\n token.type === \"glob\" ||\n token.type === \"heredoc\"\n );\n }\n\n private check(type: Token[\"type\"]): boolean {\n return this.peek().type === type;\n }\n\n private match(type: Token[\"type\"]): boolean {\n if (this.check(type)) {\n this.advance();\n return true;\n }\n return false;\n }\n\n private peek(): Token {\n return this.tokens[this.pos] ?? { type: \"eof\" };\n }\n\n private advance(): Token {\n const token = this.peek();\n this.pos++;\n return token;\n }\n\n private isAtEnd(): boolean {\n return this.peek().type === \"eof\";\n }\n}\n\nexport function parse(tokens: Token[]): ASTNode {\n return new Parser(tokens).parse();\n}\n"
|
|
5
|
+
"import { ParseError } from \"../errors.cjs\";\nimport { Lexer } from \"../lexer/lexer.cjs\";\nimport type { Token, KeywordValue } from \"../lexer/tokens.cjs\";\nimport type {\n ASTNode,\n Redirect,\n RedirectMode,\n CommandNode,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n CaseClause,\n WordNode,\n WordPart,\n} from \"./ast.cjs\";\n\nexport class Parser {\n private tokens: Token[];\n private pos: number = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n parse(): ASTNode {\n const result = this.parseSequence();\n if (!this.isAtEnd()) {\n throw new ParseError(`Unexpected token: ${JSON.stringify(this.peek())}`);\n }\n return result;\n }\n\n // sequence := and_or ((';'|'\\n') and_or)*\n private parseSequence(): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n commands.push(this.parseAndOr());\n\n while (this.match(\"semicolon\") || this.match(\"newline\")) {\n this.skipNewlines();\n if (this.isAtEnd() || this.check(\"semicolon\") || this.check(\"newline\") || this.isTerminatingKeyword()) continue;\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private skipNewlines(): void {\n while (this.match(\"newline\")) {\n // keep consuming newlines\n }\n }\n\n private isTerminatingKeyword(): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return [\"then\", \"elif\", \"else\", \"fi\", \"do\", \"done\", \"esac\"].includes(token.value);\n }\n\n // and_or := pipeline (('&&'|'||') pipeline)*\n private parseAndOr(): ASTNode {\n let left = this.parsePipeline();\n\n while (this.check(\"and\") || this.check(\"or\")) {\n if (this.match(\"and\")) {\n const right = this.parsePipeline();\n left = { type: \"and\", left, right };\n } else if (this.match(\"or\")) {\n const right = this.parsePipeline();\n left = { type: \"or\", left, right };\n }\n }\n\n return left;\n }\n\n // pipeline := command ('|' command)*\n private parsePipeline(): ASTNode {\n const commands: ASTNode[] = [];\n commands.push(this.parseCompoundOrCommand());\n\n while (this.match(\"pipe\")) {\n this.skipNewlines();\n commands.push(this.parseCompoundOrCommand());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"pipeline\", commands };\n }\n\n // compound_or_command := compound_command | simple_command\n private parseCompoundOrCommand(): ASTNode {\n this.skipNewlines();\n const token = this.peek();\n\n if (token.type === \"keyword\") {\n switch (token.value) {\n case \"if\":\n return this.parseIf();\n case \"for\":\n return this.parseFor();\n case \"while\":\n return this.parseWhile();\n case \"until\":\n return this.parseUntil();\n case \"case\":\n return this.parseCase();\n }\n }\n\n return this.parseCommand();\n }\n\n // if := 'if' compound_list 'then' compound_list ('elif' compound_list 'then' compound_list)* ['else' compound_list] 'fi'\n private parseIf(): IfNode {\n this.expectKeyword(\"if\");\n const condition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const thenBranch = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n\n const elifBranches: Array<{ condition: ASTNode; body: ASTNode }> = [];\n while (this.checkKeyword(\"elif\")) {\n this.expectKeyword(\"elif\");\n const elifCondition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const elifBody = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n elifBranches.push({ condition: elifCondition, body: elifBody });\n }\n\n let elseBranch: ASTNode | undefined;\n if (this.checkKeyword(\"else\")) {\n this.expectKeyword(\"else\");\n elseBranch = this.parseCompoundList([\"fi\"]);\n }\n\n this.expectKeyword(\"fi\");\n\n return {\n type: \"if\",\n condition,\n thenBranch,\n elifBranches,\n elseBranch,\n };\n }\n\n // for := 'for' NAME ['in' word*] (';'|'\\n') 'do' compound_list 'done'\n private parseFor(): ForNode {\n this.expectKeyword(\"for\");\n\n const varToken = this.peek();\n if (varToken.type !== \"word\") {\n throw new ParseError(\"Expected variable name after 'for'\");\n }\n this.advance();\n const variable = varToken.value;\n\n const items: WordNode[] = [];\n if (this.checkKeyword(\"in\")) {\n this.expectKeyword(\"in\");\n while (!this.isAtEnd() && !this.check(\"semicolon\") && !this.check(\"newline\") && !this.checkKeyword(\"do\")) {\n items.push(this.parseWordArg());\n }\n }\n\n if (!this.match(\"semicolon\")) {\n this.match(\"newline\");\n }\n this.skipNewlines();\n\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"for\",\n variable,\n items,\n body,\n };\n }\n\n // while := 'while' compound_list 'do' compound_list 'done'\n private parseWhile(): WhileNode {\n this.expectKeyword(\"while\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"while\",\n condition,\n body,\n };\n }\n\n // until := 'until' compound_list 'do' compound_list 'done'\n private parseUntil(): UntilNode {\n this.expectKeyword(\"until\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"until\",\n condition,\n body,\n };\n }\n\n // case := 'case' word 'in' case_clause* 'esac'\n private parseCase(): CaseNode {\n this.expectKeyword(\"case\");\n const word = this.parseWordArg();\n this.expectKeyword(\"in\");\n this.skipNewlines();\n\n const clauses: CaseClause[] = [];\n\n while (!this.isAtEnd() && !this.checkKeyword(\"esac\")) {\n this.match(\"openParen\");\n\n const patterns: WordNode[] = [];\n patterns.push(this.parseCasePattern());\n\n while (this.match(\"pipe\")) {\n patterns.push(this.parseCasePattern());\n }\n\n if (!this.match(\"closeParen\")) {\n throw new ParseError(\"Expected ')' after case pattern\");\n }\n\n const body = this.parseCaseBody();\n clauses.push({ patterns, body });\n\n this.match(\"doubleSemicolon\");\n this.skipNewlines();\n }\n\n this.expectKeyword(\"esac\");\n\n return {\n type: \"case\",\n word,\n clauses,\n };\n }\n\n private parseCasePattern(): WordNode {\n const token = this.peek();\n\n if (token.type === \"word\" || token.type === \"glob\" || token.type === \"singleQuote\" || token.type === \"doubleQuote\") {\n return this.parseWordArg();\n }\n\n throw new ParseError(`Expected pattern in case clause, got ${token.type}`);\n }\n\n private parseCaseBody(): ASTNode {\n const commands: ASTNode[] = [];\n this.skipNewlines();\n\n while (!this.isAtEnd() && !this.check(\"doubleSemicolon\") && !this.checkKeyword(\"esac\")) {\n commands.push(this.parseAndOr());\n if (!this.match(\"semicolon\") && !this.match(\"newline\")) {\n break;\n }\n this.skipNewlines();\n if (this.check(\"doubleSemicolon\") || this.checkKeyword(\"esac\")) {\n break;\n }\n }\n\n if (commands.length === 0) {\n return this.createNoopCommand();\n }\n if (commands.length === 1) {\n return commands[0]!;\n }\n return { type: \"sequence\", commands };\n }\n\n // compound_list := and_or ((';'|'\\n') and_or)* [';'|'\\n']\n private parseCompoundList(terminators: KeywordValue[]): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n\n if (this.isCompoundListTerminator(terminators)) {\n return this.createNoopCommand();\n }\n\n commands.push(this.parseAndOr());\n\n while ((this.match(\"semicolon\") || this.match(\"newline\")) && !this.isAtEnd()) {\n this.skipNewlines();\n if (this.isCompoundListTerminator(terminators)) {\n break;\n }\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private createNoopCommand(): CommandNode {\n return {\n type: \"command\",\n name: this.createTextWord(\"true\"),\n args: [],\n redirects: [],\n assignments: [],\n };\n }\n\n private createTextWord(value: string, quoted = false): WordNode {\n return {\n type: \"word\",\n parts: value === \"\" && !quoted ? [] : [{ type: \"text\", value, quoted }],\n };\n }\n\n private isCompoundListTerminator(terminators: KeywordValue[]): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return terminators.includes(token.value);\n }\n\n private checkKeyword(value: KeywordValue): boolean {\n const token = this.peek();\n return token.type === \"keyword\" && token.value === value;\n }\n\n private expectKeyword(value: KeywordValue): void {\n if (!this.checkKeyword(value)) {\n throw new ParseError(`Expected '${value}'`);\n }\n this.advance();\n }\n\n // command := assignment* word+ redirect*\n private parseCommand(): CommandNode {\n const assignments: Array<{ name: string; value: WordNode }> = [];\n const args: WordNode[] = [];\n const redirects: Redirect[] = [];\n\n while (this.check(\"assignment\")) {\n const token = this.advance() as Token & { type: \"assignment\" };\n assignments.push({\n name: token.name,\n value: this.tokenToWord(token.value),\n });\n }\n\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToWord(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n\n while (this.check(\"redirect\")) {\n const redirect = this.parseRedirect();\n redirects.push(redirect);\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToWord(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n }\n\n if (args.length === 0 && assignments.length === 0 && redirects.length === 0) {\n throw new ParseError(\"Expected command\");\n }\n\n const name = args.shift() ?? this.createTextWord(redirects.length > 0 ? \":\" : \"\");\n\n return {\n type: \"command\",\n name,\n args,\n redirects,\n assignments,\n };\n }\n\n private parseWordArg(): WordNode {\n const token = this.advance();\n return this.tokenToWord(token);\n }\n\n private tokenToWord(token: Token | string | Token[]): WordNode {\n const parts = this.tokenToWordParts(token);\n return {\n type: \"word\",\n parts,\n };\n }\n\n private tokenToWordParts(token: Token | string | Token[], quoted = false): WordPart[] {\n if (typeof token === \"string\") {\n return [{ type: \"text\", value: token, quoted }];\n }\n\n if (Array.isArray(token)) {\n return token.flatMap((part) => this.tokenToWordParts(part, quoted));\n }\n\n switch (token.type) {\n case \"word\":\n return [{ type: \"text\", value: token.value, quoted }];\n case \"singleQuote\":\n return [{ type: \"text\", value: token.value, quoted: true }];\n case \"doubleQuote\":\n return this.parseDoubleQuoteParts(token.parts);\n case \"variable\":\n return [{ type: \"variable\", name: token.name, quoted }];\n case \"substitution\": {\n const innerParser = new Parser(\n new Lexer(token.command, { preserveNewlines: true }).tokenize()\n );\n return [{ type: \"substitution\", command: innerParser.parse(), quoted }];\n }\n case \"arithmetic\":\n return [{ type: \"arithmetic\", expression: token.expression, quoted }];\n case \"glob\":\n return [{ type: \"text\", value: token.pattern, quoted }];\n case \"assignment\":\n return this.tokenToWordParts(token.value, quoted);\n case \"heredoc\":\n return token.expand\n ? this.parseHeredocContent(token.content).parts\n : [{ type: \"text\", value: token.content, quoted: true }];\n default:\n throw new ParseError(`Unexpected token type: ${(token as Token).type}`);\n }\n }\n\n private parseDoubleQuoteParts(parts: Array<string | Token>): WordPart[] {\n if (parts.length === 0) {\n return [{ type: \"text\", value: \"\", quoted: true }];\n }\n\n return parts.flatMap((part) => this.tokenToWordParts(part, true));\n }\n\n private parseHeredocContent(content: string): WordNode {\n const parts: WordPart[] = [];\n let currentText = \"\";\n let i = 0;\n\n const pushText = () => {\n if (currentText.length > 0) {\n parts.push({ type: \"text\", value: currentText, quoted: false });\n currentText = \"\";\n }\n };\n\n while (i < content.length) {\n if (content[i] !== \"$\") {\n currentText += content[i];\n i++;\n continue;\n }\n\n pushText();\n i++;\n\n if (i >= content.length) {\n currentText += \"$\";\n break;\n }\n\n if (content[i] === \"{\") {\n i++;\n let name = \"\";\n while (i < content.length && content[i] !== \"}\") {\n name += content[i];\n i++;\n }\n if (i < content.length && content[i] === \"}\") {\n i++;\n }\n parts.push({ type: \"variable\", name, quoted: false });\n continue;\n }\n\n if ([\"#\", \"*\", \"@\", \"?\"].includes(content[i] ?? \"\")) {\n parts.push({ type: \"variable\", name: content[i]!, quoted: false });\n i++;\n continue;\n }\n\n if (/[0-9]/.test(content[i] ?? \"\")) {\n parts.push({ type: \"variable\", name: content[i]!, quoted: false });\n i++;\n continue;\n }\n\n if (content[i] === \"(\" && content[i + 1] === \"(\") {\n i += 2;\n let depth = 1;\n let expression = \"\";\n while (i < content.length && depth > 0) {\n if (content[i] === \"(\" && content[i + 1] === \"(\") {\n depth++;\n expression += content[i]! + content[i + 1]!;\n i += 2;\n continue;\n }\n if (content[i] === \")\" && content[i + 1] === \")\") {\n depth--;\n if (depth === 0) {\n i += 2;\n break;\n }\n expression += content[i]! + content[i + 1]!;\n i += 2;\n continue;\n }\n expression += content[i]!;\n i++;\n }\n parts.push({ type: \"arithmetic\", expression, quoted: false });\n continue;\n }\n\n if (content[i] === \"(\") {\n i++;\n let depth = 1;\n let command = \"\";\n while (i < content.length && depth > 0) {\n if (content[i] === \"(\") {\n depth++;\n } else if (content[i] === \")\") {\n depth--;\n if (depth === 0) {\n i++;\n break;\n }\n }\n command += content[i]!;\n i++;\n }\n const innerParser = new Parser(\n new Lexer(command, { preserveNewlines: true }).tokenize()\n );\n parts.push({ type: \"substitution\", command: innerParser.parse(), quoted: false });\n continue;\n }\n\n if (/[a-zA-Z_]/.test(content[i] ?? \"\")) {\n let name = \"\";\n while (i < content.length && /[a-zA-Z0-9_]/.test(content[i] ?? \"\")) {\n name += content[i];\n i++;\n }\n parts.push({ type: \"variable\", name, quoted: false });\n continue;\n }\n\n currentText += \"$\";\n }\n\n pushText();\n\n return {\n type: \"word\",\n parts,\n };\n }\n\n private parseRedirect(): Redirect {\n const token = this.advance() as Token & { type: \"redirect\" };\n const mode = token.mode as RedirectMode;\n\n if (mode === \"2>&1\" || mode === \"1>&2\") {\n return { mode, target: this.createTextWord(\"\") };\n }\n\n if (!this.isWordToken()) {\n throw new ParseError(`Expected redirect target after ${mode}`);\n }\n\n const target = this.parseWordArg();\n return { mode, target };\n }\n\n private isWordToken(): boolean {\n const token = this.peek();\n return (\n Array.isArray(token) ||\n token.type === \"word\" ||\n token.type === \"singleQuote\" ||\n token.type === \"doubleQuote\" ||\n token.type === \"variable\" ||\n token.type === \"substitution\" ||\n token.type === \"arithmetic\" ||\n token.type === \"glob\" ||\n token.type === \"heredoc\"\n );\n }\n\n private check(type: Token[\"type\"]): boolean {\n return this.peek().type === type;\n }\n\n private match(type: Token[\"type\"]): boolean {\n if (this.check(type)) {\n this.advance();\n return true;\n }\n return false;\n }\n\n private peek(): Token {\n return this.tokens[this.pos] ?? { type: \"eof\" };\n }\n\n private advance(): Token {\n const token = this.peek();\n this.pos++;\n return token;\n }\n\n private isAtEnd(): boolean {\n return this.peek().type === \"eof\";\n }\n}\n\nexport function parse(tokens: Token[]): ASTNode {\n return new Parser(tokens).parse();\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "BB94E2D814E2C9C664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -59,6 +59,8 @@ class ShellDSL {
|
|
|
59
59
|
commands;
|
|
60
60
|
shouldThrow = true;
|
|
61
61
|
isTTY;
|
|
62
|
+
terminal;
|
|
63
|
+
externalCommand;
|
|
62
64
|
constructor(config) {
|
|
63
65
|
this.fs = config.fs;
|
|
64
66
|
this.initialCwd = config.cwd;
|
|
@@ -66,7 +68,9 @@ class ShellDSL {
|
|
|
66
68
|
this.currentCwd = config.cwd;
|
|
67
69
|
this.currentEnv = { ...config.env };
|
|
68
70
|
this.commands = config.commands;
|
|
69
|
-
this.
|
|
71
|
+
this.terminal = config.terminal ?? { isTTY: config.isTTY ?? false };
|
|
72
|
+
this.isTTY = this.terminal.isTTY;
|
|
73
|
+
this.externalCommand = config.externalCommand;
|
|
70
74
|
}
|
|
71
75
|
tag(strings, ...values) {
|
|
72
76
|
let source = strings[0] ?? "";
|
|
@@ -117,7 +121,8 @@ class ShellDSL {
|
|
|
117
121
|
env,
|
|
118
122
|
commands: shell.commands,
|
|
119
123
|
redirectObjects: options?.redirectObjects,
|
|
120
|
-
|
|
124
|
+
terminal: shell.terminal,
|
|
125
|
+
externalCommand: shell.externalCommand
|
|
121
126
|
});
|
|
122
127
|
const tokens = shell.lex(source);
|
|
123
128
|
const ast = shell.parse(tokens);
|
|
@@ -164,7 +169,8 @@ class ShellDSL {
|
|
|
164
169
|
cwd: this.currentCwd,
|
|
165
170
|
env: this.currentEnv,
|
|
166
171
|
commands: this.commands,
|
|
167
|
-
|
|
172
|
+
terminal: this.terminal,
|
|
173
|
+
externalCommand: this.externalCommand
|
|
168
174
|
});
|
|
169
175
|
return interpreter.execute(program.ast);
|
|
170
176
|
}
|
|
@@ -183,7 +189,9 @@ function createShellDSL(config) {
|
|
|
183
189
|
currentEnv: shell.currentEnv,
|
|
184
190
|
commands: shell.commands,
|
|
185
191
|
shouldThrow: shell.shouldThrow,
|
|
186
|
-
isTTY: shell.isTTY
|
|
192
|
+
isTTY: shell.isTTY,
|
|
193
|
+
terminal: shell.terminal,
|
|
194
|
+
externalCommand: shell.externalCommand
|
|
187
195
|
});
|
|
188
196
|
tag.cwd = shell.cwd.bind(shell);
|
|
189
197
|
tag.env = shell.env.bind(shell);
|
|
@@ -199,4 +207,4 @@ function createShellDSL(config) {
|
|
|
199
207
|
return tag;
|
|
200
208
|
}
|
|
201
209
|
|
|
202
|
-
//# debugId=
|
|
210
|
+
//# debugId=ECF0DF1AD7027E4E64756E2164756E21
|