shell-dsl 0.0.1 → 0.0.2
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 +568 -28
- package/dist/cjs/index.cjs +72 -0
- package/dist/cjs/index.cjs.map +10 -0
- package/dist/cjs/package.json +5 -0
- package/dist/cjs/src/errors.cjs +73 -0
- package/dist/cjs/src/errors.cjs.map +10 -0
- package/dist/cjs/src/fs/index.cjs +37 -0
- package/dist/cjs/src/fs/index.cjs.map +10 -0
- package/dist/cjs/src/fs/memfs-adapter.cjs +221 -0
- package/dist/cjs/src/fs/memfs-adapter.cjs.map +10 -0
- package/dist/cjs/src/index.cjs +80 -0
- package/dist/cjs/src/index.cjs.map +10 -0
- package/dist/cjs/src/interpreter/context.cjs +47 -0
- package/dist/cjs/src/interpreter/context.cjs.map +10 -0
- package/dist/cjs/src/interpreter/index.cjs +39 -0
- package/dist/cjs/src/interpreter/index.cjs.map +10 -0
- package/dist/cjs/src/interpreter/interpreter.cjs +321 -0
- package/dist/cjs/src/interpreter/interpreter.cjs.map +10 -0
- package/dist/cjs/src/io/index.cjs +44 -0
- package/dist/cjs/src/io/index.cjs.map +10 -0
- package/dist/cjs/src/io/stdin.cjs +99 -0
- package/dist/cjs/src/io/stdin.cjs.map +10 -0
- package/dist/cjs/src/io/stdout.cjs +158 -0
- package/dist/cjs/src/io/stdout.cjs.map +10 -0
- package/dist/cjs/src/lexer/index.cjs +40 -0
- package/dist/cjs/src/lexer/index.cjs.map +10 -0
- package/dist/cjs/src/lexer/lexer.cjs +335 -0
- package/dist/cjs/src/lexer/lexer.cjs.map +10 -0
- package/dist/cjs/src/lexer/tokens.cjs +66 -0
- package/dist/cjs/src/lexer/tokens.cjs.map +10 -0
- package/dist/cjs/src/parser/ast.cjs +75 -0
- package/dist/cjs/src/parser/ast.cjs.map +10 -0
- package/dist/cjs/src/parser/index.cjs +49 -0
- package/dist/cjs/src/parser/index.cjs.map +10 -0
- package/dist/cjs/src/parser/parser.cjs +216 -0
- package/dist/cjs/src/parser/parser.cjs.map +10 -0
- package/dist/cjs/src/shell-dsl.cjs +162 -0
- package/dist/cjs/src/shell-dsl.cjs.map +10 -0
- package/dist/cjs/src/shell-promise.cjs +159 -0
- package/dist/cjs/src/shell-promise.cjs.map +10 -0
- package/dist/cjs/src/types.cjs +39 -0
- package/dist/cjs/src/types.cjs.map +10 -0
- package/dist/cjs/src/utils/escape.cjs +53 -0
- package/dist/cjs/src/utils/escape.cjs.map +10 -0
- package/dist/cjs/src/utils/index.cjs +38 -0
- package/dist/cjs/src/utils/index.cjs.map +10 -0
- package/dist/mjs/index.mjs +42 -0
- package/dist/mjs/index.mjs.map +10 -0
- package/dist/mjs/package.json +5 -0
- package/dist/mjs/src/errors.mjs +42 -0
- package/dist/mjs/src/errors.mjs.map +10 -0
- package/dist/mjs/src/fs/index.mjs +7 -0
- package/dist/mjs/src/fs/index.mjs.map +10 -0
- package/dist/mjs/src/fs/memfs-adapter.mjs +178 -0
- package/dist/mjs/src/fs/memfs-adapter.mjs.map +10 -0
- package/dist/mjs/src/index.mjs +61 -0
- package/dist/mjs/src/index.mjs.map +10 -0
- package/dist/mjs/src/interpreter/context.mjs +17 -0
- package/dist/mjs/src/interpreter/context.mjs.map +10 -0
- package/dist/mjs/src/interpreter/index.mjs +9 -0
- package/dist/mjs/src/interpreter/index.mjs.map +10 -0
- package/dist/mjs/src/interpreter/interpreter.mjs +291 -0
- package/dist/mjs/src/interpreter/interpreter.mjs.map +10 -0
- package/dist/mjs/src/io/index.mjs +14 -0
- package/dist/mjs/src/io/index.mjs.map +10 -0
- package/dist/mjs/src/io/stdin.mjs +68 -0
- package/dist/mjs/src/io/stdin.mjs.map +10 -0
- package/dist/mjs/src/io/stdout.mjs +127 -0
- package/dist/mjs/src/io/stdout.mjs.map +10 -0
- package/dist/mjs/src/lexer/index.mjs +10 -0
- package/dist/mjs/src/lexer/index.mjs.map +10 -0
- package/dist/mjs/src/lexer/lexer.mjs +305 -0
- package/dist/mjs/src/lexer/lexer.mjs.map +10 -0
- package/dist/mjs/src/lexer/tokens.mjs +36 -0
- package/dist/mjs/src/lexer/tokens.mjs.map +10 -0
- package/dist/mjs/src/parser/ast.mjs +45 -0
- package/dist/mjs/src/parser/ast.mjs.map +10 -0
- package/dist/mjs/src/parser/index.mjs +30 -0
- package/dist/mjs/src/parser/index.mjs.map +10 -0
- package/dist/mjs/src/parser/parser.mjs +189 -0
- package/dist/mjs/src/parser/parser.mjs.map +10 -0
- package/dist/mjs/src/shell-dsl.mjs +132 -0
- package/dist/mjs/src/shell-dsl.mjs.map +10 -0
- package/dist/mjs/src/shell-promise.mjs +129 -0
- package/dist/mjs/src/shell-promise.mjs.map +10 -0
- package/dist/mjs/src/types.mjs +9 -0
- package/dist/mjs/src/types.mjs.map +10 -0
- package/dist/mjs/src/utils/escape.mjs +23 -0
- package/dist/mjs/src/utils/escape.mjs.map +10 -0
- package/dist/mjs/src/utils/index.mjs +8 -0
- package/dist/mjs/src/utils/index.mjs.map +10 -0
- package/dist/types/commands/cat.d.ts +2 -0
- package/dist/types/commands/echo.d.ts +2 -0
- package/dist/types/commands/grep.d.ts +2 -0
- package/dist/types/commands/head.d.ts +2 -0
- package/dist/types/commands/index.d.ts +16 -0
- package/dist/types/commands/ls.d.ts +2 -0
- package/dist/types/commands/mkdir.d.ts +2 -0
- package/dist/types/commands/pwd.d.ts +2 -0
- package/dist/types/commands/rm.d.ts +2 -0
- package/dist/types/commands/sort.d.ts +2 -0
- package/dist/types/commands/tail.d.ts +2 -0
- package/dist/types/commands/test.d.ts +3 -0
- package/dist/types/commands/true-false.d.ts +3 -0
- package/dist/types/commands/uniq.d.ts +2 -0
- package/dist/types/commands/wc.d.ts +2 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/src/errors.d.ts +16 -0
- package/dist/types/src/fs/index.d.ts +1 -0
- package/dist/types/src/fs/memfs-adapter.d.ts +3 -0
- package/dist/types/src/index.d.ts +15 -0
- package/dist/types/src/interpreter/context.d.ts +11 -0
- package/dist/types/src/interpreter/index.d.ts +2 -0
- package/dist/types/src/interpreter/interpreter.d.ts +28 -0
- package/dist/types/src/io/index.d.ts +2 -0
- package/dist/types/src/io/stdin.d.ts +11 -0
- package/dist/types/src/io/stdout.d.ts +27 -0
- package/dist/types/src/lexer/index.d.ts +3 -0
- package/dist/types/src/lexer/lexer.d.ts +24 -0
- package/dist/types/src/lexer/tokens.d.ts +38 -0
- package/dist/types/src/parser/ast.d.ts +64 -0
- package/dist/types/src/parser/index.d.ts +3 -0
- package/dist/types/src/parser/parser.d.ts +23 -0
- package/dist/types/src/shell-dsl.d.ts +31 -0
- package/dist/types/src/shell-promise.d.ts +39 -0
- package/dist/types/src/types.d.ts +71 -0
- package/dist/types/src/utils/escape.d.ts +2 -0
- package/dist/types/src/utils/index.d.ts +1 -0
- package/package.json +46 -6
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
+
var __toCommonJS = (from) => {
|
|
7
|
+
var entry = __moduleCache.get(from), desc;
|
|
8
|
+
if (entry)
|
|
9
|
+
return entry;
|
|
10
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
+
get: () => from[key],
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
}));
|
|
16
|
+
__moduleCache.set(from, entry);
|
|
17
|
+
return entry;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/io/stdout.ts
|
|
30
|
+
var exports_stdout = {};
|
|
31
|
+
__export(exports_stdout, {
|
|
32
|
+
createStdout: () => createStdout,
|
|
33
|
+
createStderr: () => createStderr,
|
|
34
|
+
createPipe: () => createPipe,
|
|
35
|
+
PipeBuffer: () => PipeBuffer,
|
|
36
|
+
OutputCollectorImpl: () => OutputCollectorImpl
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(exports_stdout);
|
|
39
|
+
|
|
40
|
+
class OutputCollectorImpl {
|
|
41
|
+
chunks = [];
|
|
42
|
+
closed = false;
|
|
43
|
+
closeResolvers = [];
|
|
44
|
+
resolveWait = null;
|
|
45
|
+
waitPromise = null;
|
|
46
|
+
async write(chunk) {
|
|
47
|
+
if (this.closed) {
|
|
48
|
+
throw new Error("Output stream is closed");
|
|
49
|
+
}
|
|
50
|
+
this.chunks.push(chunk);
|
|
51
|
+
if (this.resolveWait) {
|
|
52
|
+
this.resolveWait();
|
|
53
|
+
this.resolveWait = null;
|
|
54
|
+
this.waitPromise = null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async writeText(str) {
|
|
58
|
+
await this.write(new TextEncoder().encode(str));
|
|
59
|
+
}
|
|
60
|
+
close() {
|
|
61
|
+
this.closed = true;
|
|
62
|
+
if (this.resolveWait) {
|
|
63
|
+
this.resolveWait();
|
|
64
|
+
this.resolveWait = null;
|
|
65
|
+
this.waitPromise = null;
|
|
66
|
+
}
|
|
67
|
+
for (const resolve of this.closeResolvers) {
|
|
68
|
+
resolve();
|
|
69
|
+
}
|
|
70
|
+
this.closeResolvers = [];
|
|
71
|
+
}
|
|
72
|
+
async collect() {
|
|
73
|
+
while (!this.closed) {
|
|
74
|
+
await new Promise((resolve) => {
|
|
75
|
+
this.closeResolvers.push(resolve);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return Buffer.concat(this.chunks);
|
|
79
|
+
}
|
|
80
|
+
async* getReadableStream() {
|
|
81
|
+
let index = 0;
|
|
82
|
+
while (true) {
|
|
83
|
+
while (index < this.chunks.length) {
|
|
84
|
+
yield this.chunks[index];
|
|
85
|
+
index++;
|
|
86
|
+
}
|
|
87
|
+
if (this.closed) {
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
if (!this.waitPromise) {
|
|
91
|
+
this.waitPromise = new Promise((resolve) => {
|
|
92
|
+
this.resolveWait = resolve;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
await this.waitPromise;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
class PipeBuffer {
|
|
101
|
+
chunks = [];
|
|
102
|
+
closed = false;
|
|
103
|
+
waitingReaders = [];
|
|
104
|
+
readIndex = 0;
|
|
105
|
+
async write(chunk) {
|
|
106
|
+
if (this.closed) {
|
|
107
|
+
throw new Error("Pipe is closed");
|
|
108
|
+
}
|
|
109
|
+
this.chunks.push(chunk);
|
|
110
|
+
for (const resolve of this.waitingReaders) {
|
|
111
|
+
resolve();
|
|
112
|
+
}
|
|
113
|
+
this.waitingReaders = [];
|
|
114
|
+
}
|
|
115
|
+
async writeText(str) {
|
|
116
|
+
await this.write(new TextEncoder().encode(str));
|
|
117
|
+
}
|
|
118
|
+
close() {
|
|
119
|
+
this.closed = true;
|
|
120
|
+
for (const resolve of this.waitingReaders) {
|
|
121
|
+
resolve();
|
|
122
|
+
}
|
|
123
|
+
this.waitingReaders = [];
|
|
124
|
+
}
|
|
125
|
+
async collect() {
|
|
126
|
+
while (!this.closed) {
|
|
127
|
+
await new Promise((resolve) => {
|
|
128
|
+
this.waitingReaders.push(resolve);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return Buffer.concat(this.chunks);
|
|
132
|
+
}
|
|
133
|
+
async* getReadableStream() {
|
|
134
|
+
while (true) {
|
|
135
|
+
while (this.readIndex < this.chunks.length) {
|
|
136
|
+
yield this.chunks[this.readIndex];
|
|
137
|
+
this.readIndex++;
|
|
138
|
+
}
|
|
139
|
+
if (this.closed) {
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
await new Promise((resolve) => {
|
|
143
|
+
this.waitingReaders.push(resolve);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function createStdout() {
|
|
149
|
+
return new OutputCollectorImpl;
|
|
150
|
+
}
|
|
151
|
+
function createStderr() {
|
|
152
|
+
return new OutputCollectorImpl;
|
|
153
|
+
}
|
|
154
|
+
function createPipe() {
|
|
155
|
+
return new PipeBuffer;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
//# debugId=05AE43B120FD6CB964756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/io/stdout.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Stdout, Stderr, OutputCollector } from \"../types.cjs\";\n\nexport class OutputCollectorImpl implements OutputCollector {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private closeResolvers: Array<() => void> = [];\n private resolveWait: (() => void) | null = null;\n private waitPromise: Promise<void> | null = null;\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Output stream is closed\");\n }\n this.chunks.push(chunk);\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n if (this.resolveWait) {\n this.resolveWait();\n this.resolveWait = null;\n this.waitPromise = null;\n }\n // Wake up anyone waiting for close\n for (const resolve of this.closeResolvers) {\n resolve();\n }\n this.closeResolvers = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.closeResolvers.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n let index = 0;\n\n while (true) {\n while (index < this.chunks.length) {\n yield this.chunks[index]!;\n index++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data or close\n if (!this.waitPromise) {\n this.waitPromise = new Promise<void>((resolve) => {\n this.resolveWait = resolve;\n });\n }\n await this.waitPromise;\n }\n }\n}\n\nexport class PipeBuffer implements OutputCollector, Stdout {\n private chunks: Uint8Array[] = [];\n private closed: boolean = false;\n private waitingReaders: Array<() => void> = [];\n private readIndex: number = 0;\n\n async write(chunk: Uint8Array): Promise<void> {\n if (this.closed) {\n throw new Error(\"Pipe is closed\");\n }\n this.chunks.push(chunk);\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async writeText(str: string): Promise<void> {\n await this.write(new TextEncoder().encode(str));\n }\n\n close(): void {\n this.closed = true;\n // Wake up any waiting readers\n for (const resolve of this.waitingReaders) {\n resolve();\n }\n this.waitingReaders = [];\n }\n\n async collect(): Promise<Buffer> {\n // Wait until closed\n while (!this.closed) {\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n return Buffer.concat(this.chunks);\n }\n\n async *getReadableStream(): AsyncIterable<Uint8Array> {\n while (true) {\n // Yield any available chunks\n while (this.readIndex < this.chunks.length) {\n yield this.chunks[this.readIndex]!;\n this.readIndex++;\n }\n\n if (this.closed) {\n break;\n }\n\n // Wait for more data\n await new Promise<void>((resolve) => {\n this.waitingReaders.push(resolve);\n });\n }\n }\n}\n\nexport function createStdout(): OutputCollector {\n return new OutputCollectorImpl();\n}\n\nexport function createStderr(): OutputCollector {\n return new OutputCollectorImpl();\n}\n\nexport function createPipe(): PipeBuffer {\n return new PipeBuffer();\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "05AE43B120FD6CB964756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
+
var __toCommonJS = (from) => {
|
|
7
|
+
var entry = __moduleCache.get(from), desc;
|
|
8
|
+
if (entry)
|
|
9
|
+
return entry;
|
|
10
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
+
get: () => from[key],
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
}));
|
|
16
|
+
__moduleCache.set(from, entry);
|
|
17
|
+
return entry;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/lexer/index.ts
|
|
30
|
+
var exports_lexer = {};
|
|
31
|
+
__export(exports_lexer, {
|
|
32
|
+
tokenToString: () => import_tokens.tokenToString,
|
|
33
|
+
lex: () => import_lexer.lex,
|
|
34
|
+
Lexer: () => import_lexer.Lexer
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(exports_lexer);
|
|
37
|
+
var import_lexer = require("./lexer.cjs");
|
|
38
|
+
var import_tokens = require("./tokens.cjs");
|
|
39
|
+
|
|
40
|
+
//# debugId=7C4C9186068ABA5464756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/lexer/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export { Lexer, lex } from \"./lexer.cjs\";\nexport type { Token, RedirectMode } from \"./tokens.cjs\";\nexport { tokenToString } from \"./tokens.cjs\";\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA2B,IAA3B;AAE8B,IAA9B;",
|
|
8
|
+
"debugId": "7C4C9186068ABA5464756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
+
var __toCommonJS = (from) => {
|
|
7
|
+
var entry = __moduleCache.get(from), desc;
|
|
8
|
+
if (entry)
|
|
9
|
+
return entry;
|
|
10
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
+
get: () => from[key],
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
}));
|
|
16
|
+
__moduleCache.set(from, entry);
|
|
17
|
+
return entry;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/lexer/lexer.ts
|
|
30
|
+
var exports_lexer = {};
|
|
31
|
+
__export(exports_lexer, {
|
|
32
|
+
lex: () => lex,
|
|
33
|
+
Lexer: () => Lexer
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(exports_lexer);
|
|
36
|
+
var import_errors = require("../errors.cjs");
|
|
37
|
+
var GLOB_CHARS = new Set(["*", "?", "[", "{", "}"]);
|
|
38
|
+
var WORD_BREAK_CHARS = new Set([
|
|
39
|
+
" ",
|
|
40
|
+
"\t",
|
|
41
|
+
`
|
|
42
|
+
`,
|
|
43
|
+
"\r",
|
|
44
|
+
"|",
|
|
45
|
+
"&",
|
|
46
|
+
";",
|
|
47
|
+
">",
|
|
48
|
+
"<",
|
|
49
|
+
"(",
|
|
50
|
+
")",
|
|
51
|
+
"$",
|
|
52
|
+
"'",
|
|
53
|
+
'"',
|
|
54
|
+
"`"
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
class Lexer {
|
|
58
|
+
source;
|
|
59
|
+
pos = 0;
|
|
60
|
+
line = 1;
|
|
61
|
+
column = 1;
|
|
62
|
+
constructor(source) {
|
|
63
|
+
this.source = source;
|
|
64
|
+
}
|
|
65
|
+
tokenize() {
|
|
66
|
+
const tokens = [];
|
|
67
|
+
while (!this.isAtEnd()) {
|
|
68
|
+
this.skipWhitespace();
|
|
69
|
+
if (this.isAtEnd())
|
|
70
|
+
break;
|
|
71
|
+
const token = this.nextToken();
|
|
72
|
+
if (token) {
|
|
73
|
+
tokens.push(token);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
tokens.push({ type: "eof" });
|
|
77
|
+
return tokens;
|
|
78
|
+
}
|
|
79
|
+
nextToken() {
|
|
80
|
+
const char = this.peek();
|
|
81
|
+
if (char === "#") {
|
|
82
|
+
this.skipComment();
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
if (char === "|") {
|
|
86
|
+
this.advance();
|
|
87
|
+
if (this.peek() === "|") {
|
|
88
|
+
this.advance();
|
|
89
|
+
return { type: "or" };
|
|
90
|
+
}
|
|
91
|
+
return { type: "pipe" };
|
|
92
|
+
}
|
|
93
|
+
if (char === "&") {
|
|
94
|
+
this.advance();
|
|
95
|
+
if (this.peek() === "&") {
|
|
96
|
+
this.advance();
|
|
97
|
+
return { type: "and" };
|
|
98
|
+
}
|
|
99
|
+
if (this.peek() === ">") {
|
|
100
|
+
this.advance();
|
|
101
|
+
if (this.peek() === ">") {
|
|
102
|
+
this.advance();
|
|
103
|
+
return { type: "redirect", mode: "&>>" };
|
|
104
|
+
}
|
|
105
|
+
return { type: "redirect", mode: "&>" };
|
|
106
|
+
}
|
|
107
|
+
return { type: "word", value: "&" };
|
|
108
|
+
}
|
|
109
|
+
if (char === ";") {
|
|
110
|
+
this.advance();
|
|
111
|
+
return { type: "semicolon" };
|
|
112
|
+
}
|
|
113
|
+
if (char === ">") {
|
|
114
|
+
this.advance();
|
|
115
|
+
if (this.peek() === ">") {
|
|
116
|
+
this.advance();
|
|
117
|
+
return { type: "redirect", mode: ">>" };
|
|
118
|
+
}
|
|
119
|
+
return { type: "redirect", mode: ">" };
|
|
120
|
+
}
|
|
121
|
+
if (char === "<") {
|
|
122
|
+
this.advance();
|
|
123
|
+
return { type: "redirect", mode: "<" };
|
|
124
|
+
}
|
|
125
|
+
if (char === "1" || char === "2") {
|
|
126
|
+
const fd = char;
|
|
127
|
+
const nextChar = this.peekAhead(1);
|
|
128
|
+
if (nextChar === ">") {
|
|
129
|
+
this.advance();
|
|
130
|
+
this.advance();
|
|
131
|
+
if (fd === "2") {
|
|
132
|
+
if (this.peek() === "&" && this.peekAhead(1) === "1") {
|
|
133
|
+
this.advance();
|
|
134
|
+
this.advance();
|
|
135
|
+
return { type: "redirect", mode: "2>&1" };
|
|
136
|
+
}
|
|
137
|
+
if (this.peek() === ">") {
|
|
138
|
+
this.advance();
|
|
139
|
+
return { type: "redirect", mode: "2>>" };
|
|
140
|
+
}
|
|
141
|
+
return { type: "redirect", mode: "2>" };
|
|
142
|
+
} else {
|
|
143
|
+
if (this.peek() === "&" && this.peekAhead(1) === "2") {
|
|
144
|
+
this.advance();
|
|
145
|
+
this.advance();
|
|
146
|
+
return { type: "redirect", mode: "1>&2" };
|
|
147
|
+
}
|
|
148
|
+
if (this.peek() === ">") {
|
|
149
|
+
this.advance();
|
|
150
|
+
return { type: "redirect", mode: ">>" };
|
|
151
|
+
}
|
|
152
|
+
return { type: "redirect", mode: ">" };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (char === "$") {
|
|
157
|
+
return this.readVariable();
|
|
158
|
+
}
|
|
159
|
+
if (char === "'") {
|
|
160
|
+
return this.readSingleQuote();
|
|
161
|
+
}
|
|
162
|
+
if (char === '"') {
|
|
163
|
+
return this.readDoubleQuote();
|
|
164
|
+
}
|
|
165
|
+
return this.readWord();
|
|
166
|
+
}
|
|
167
|
+
readVariable() {
|
|
168
|
+
this.advance();
|
|
169
|
+
if (this.peek() === "(") {
|
|
170
|
+
this.advance();
|
|
171
|
+
const command = this.readUntilMatchingParen();
|
|
172
|
+
return { type: "substitution", command };
|
|
173
|
+
}
|
|
174
|
+
if (this.peek() === "{") {
|
|
175
|
+
this.advance();
|
|
176
|
+
let name2 = "";
|
|
177
|
+
while (!this.isAtEnd() && this.peek() !== "}") {
|
|
178
|
+
name2 += this.advance();
|
|
179
|
+
}
|
|
180
|
+
if (this.peek() === "}") {
|
|
181
|
+
this.advance();
|
|
182
|
+
}
|
|
183
|
+
return { type: "variable", name: name2 };
|
|
184
|
+
}
|
|
185
|
+
let name = "";
|
|
186
|
+
while (!this.isAtEnd() && this.isVarChar(this.peek())) {
|
|
187
|
+
name += this.advance();
|
|
188
|
+
}
|
|
189
|
+
if (name === "") {
|
|
190
|
+
return { type: "word", value: "$" };
|
|
191
|
+
}
|
|
192
|
+
return { type: "variable", name };
|
|
193
|
+
}
|
|
194
|
+
readUntilMatchingParen() {
|
|
195
|
+
let depth = 1;
|
|
196
|
+
let result = "";
|
|
197
|
+
while (!this.isAtEnd() && depth > 0) {
|
|
198
|
+
const char = this.peek();
|
|
199
|
+
if (char === "(") {
|
|
200
|
+
depth++;
|
|
201
|
+
} else if (char === ")") {
|
|
202
|
+
depth--;
|
|
203
|
+
if (depth === 0) {
|
|
204
|
+
this.advance();
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
result += this.advance();
|
|
209
|
+
}
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
readSingleQuote() {
|
|
213
|
+
this.advance();
|
|
214
|
+
let value = "";
|
|
215
|
+
while (!this.isAtEnd() && this.peek() !== "'") {
|
|
216
|
+
value += this.advance();
|
|
217
|
+
}
|
|
218
|
+
if (this.peek() === "'") {
|
|
219
|
+
this.advance();
|
|
220
|
+
} else {
|
|
221
|
+
throw new import_errors.LexError("Unterminated single quote", this.pos, this.line, this.column);
|
|
222
|
+
}
|
|
223
|
+
return { type: "singleQuote", value };
|
|
224
|
+
}
|
|
225
|
+
readDoubleQuote() {
|
|
226
|
+
this.advance();
|
|
227
|
+
const parts = [];
|
|
228
|
+
let currentString = "";
|
|
229
|
+
while (!this.isAtEnd() && this.peek() !== '"') {
|
|
230
|
+
const char = this.peek();
|
|
231
|
+
if (char === "\\") {
|
|
232
|
+
this.advance();
|
|
233
|
+
if (!this.isAtEnd()) {
|
|
234
|
+
const escaped = this.advance();
|
|
235
|
+
if (["$", '"', "\\", "`", `
|
|
236
|
+
`].includes(escaped)) {
|
|
237
|
+
currentString += escaped;
|
|
238
|
+
} else {
|
|
239
|
+
currentString += "\\" + escaped;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
} else if (char === "$") {
|
|
243
|
+
if (currentString) {
|
|
244
|
+
parts.push(currentString);
|
|
245
|
+
currentString = "";
|
|
246
|
+
}
|
|
247
|
+
parts.push(this.readVariable());
|
|
248
|
+
} else {
|
|
249
|
+
currentString += this.advance();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (currentString) {
|
|
253
|
+
parts.push(currentString);
|
|
254
|
+
}
|
|
255
|
+
if (this.peek() === '"') {
|
|
256
|
+
this.advance();
|
|
257
|
+
} else {
|
|
258
|
+
throw new import_errors.LexError("Unterminated double quote", this.pos, this.line, this.column);
|
|
259
|
+
}
|
|
260
|
+
return { type: "doubleQuote", parts };
|
|
261
|
+
}
|
|
262
|
+
readWord() {
|
|
263
|
+
let value = "";
|
|
264
|
+
let hasGlobChars = false;
|
|
265
|
+
while (!this.isAtEnd() && !this.isWordBreak(this.peek())) {
|
|
266
|
+
const char = this.peek();
|
|
267
|
+
if (char === "\\") {
|
|
268
|
+
this.advance();
|
|
269
|
+
if (!this.isAtEnd()) {
|
|
270
|
+
value += this.advance();
|
|
271
|
+
}
|
|
272
|
+
} else {
|
|
273
|
+
if (GLOB_CHARS.has(char)) {
|
|
274
|
+
hasGlobChars = true;
|
|
275
|
+
}
|
|
276
|
+
value += this.advance();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const assignmentMatch = value.match(/^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$/);
|
|
280
|
+
if (assignmentMatch) {
|
|
281
|
+
return {
|
|
282
|
+
type: "assignment",
|
|
283
|
+
name: assignmentMatch[1],
|
|
284
|
+
value: assignmentMatch[2]
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
if (hasGlobChars) {
|
|
288
|
+
return { type: "glob", pattern: value };
|
|
289
|
+
}
|
|
290
|
+
return { type: "word", value };
|
|
291
|
+
}
|
|
292
|
+
isWordBreak(char) {
|
|
293
|
+
return WORD_BREAK_CHARS.has(char);
|
|
294
|
+
}
|
|
295
|
+
isVarChar(char) {
|
|
296
|
+
return /[a-zA-Z0-9_]/.test(char);
|
|
297
|
+
}
|
|
298
|
+
skipWhitespace() {
|
|
299
|
+
while (!this.isAtEnd() && /\s/.test(this.peek())) {
|
|
300
|
+
this.advance();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
skipComment() {
|
|
304
|
+
while (!this.isAtEnd() && this.peek() !== `
|
|
305
|
+
`) {
|
|
306
|
+
this.advance();
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
peek() {
|
|
310
|
+
return this.source[this.pos] ?? "";
|
|
311
|
+
}
|
|
312
|
+
peekAhead(n) {
|
|
313
|
+
return this.source[this.pos + n] ?? "";
|
|
314
|
+
}
|
|
315
|
+
advance() {
|
|
316
|
+
const char = this.source[this.pos];
|
|
317
|
+
this.pos++;
|
|
318
|
+
if (char === `
|
|
319
|
+
`) {
|
|
320
|
+
this.line++;
|
|
321
|
+
this.column = 1;
|
|
322
|
+
} else {
|
|
323
|
+
this.column++;
|
|
324
|
+
}
|
|
325
|
+
return char;
|
|
326
|
+
}
|
|
327
|
+
isAtEnd() {
|
|
328
|
+
return this.pos >= this.source.length;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function lex(source) {
|
|
332
|
+
return new Lexer(source).tokenize();
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
//# debugId=860EEAF9CC49FB9A64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/lexer/lexer.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { LexError } from \"../errors.cjs\";\nimport type { Token, RedirectMode } 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\n constructor(source: string) {\n this.source = source;\n }\n\n tokenize(): Token[] {\n const tokens: Token[] = [];\n\n while (!this.isAtEnd()) {\n this.skipWhitespace();\n if (this.isAtEnd()) break;\n\n const token = this.nextToken();\n if (token) {\n tokens.push(token);\n }\n }\n\n tokens.push({ type: \"eof\" });\n return tokens;\n }\n\n private nextToken(): Token | null {\n const char = this.peek();\n\n // Comments\n if (char === \"#\") {\n this.skipComment();\n return null;\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 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 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 // Command substitution $(...)\n if (this.peek() === \"(\") {\n this.advance(); // consume (\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 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 is an assignment (VAR=value)\n const assignmentMatch = value.match(/^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$/);\n if (assignmentMatch) {\n return {\n type: \"assignment\",\n name: assignmentMatch[1]!,\n value: assignmentMatch[2]!,\n };\n }\n\n if (hasGlobChars) {\n return { type: \"glob\", pattern: value };\n }\n\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 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): Token[] {\n return new Lexer(source).tokenize();\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "860EEAF9CC49FB9A64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
+
var __toCommonJS = (from) => {
|
|
7
|
+
var entry = __moduleCache.get(from), desc;
|
|
8
|
+
if (entry)
|
|
9
|
+
return entry;
|
|
10
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
+
get: () => from[key],
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
}));
|
|
16
|
+
__moduleCache.set(from, entry);
|
|
17
|
+
return entry;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/lexer/tokens.ts
|
|
30
|
+
var exports_tokens = {};
|
|
31
|
+
__export(exports_tokens, {
|
|
32
|
+
tokenToString: () => tokenToString
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(exports_tokens);
|
|
35
|
+
function tokenToString(token) {
|
|
36
|
+
switch (token.type) {
|
|
37
|
+
case "word":
|
|
38
|
+
return token.value;
|
|
39
|
+
case "pipe":
|
|
40
|
+
return "|";
|
|
41
|
+
case "and":
|
|
42
|
+
return "&&";
|
|
43
|
+
case "or":
|
|
44
|
+
return "||";
|
|
45
|
+
case "semicolon":
|
|
46
|
+
return ";";
|
|
47
|
+
case "redirect":
|
|
48
|
+
return token.mode;
|
|
49
|
+
case "variable":
|
|
50
|
+
return `$${token.name}`;
|
|
51
|
+
case "substitution":
|
|
52
|
+
return `$(${token.command})`;
|
|
53
|
+
case "glob":
|
|
54
|
+
return token.pattern;
|
|
55
|
+
case "singleQuote":
|
|
56
|
+
return `'${token.value}'`;
|
|
57
|
+
case "doubleQuote":
|
|
58
|
+
return `"${token.parts.map((p) => typeof p === "string" ? p : tokenToString(p)).join("")}"`;
|
|
59
|
+
case "assignment":
|
|
60
|
+
return `${token.name}=${typeof token.value === "string" ? token.value : token.value.map(tokenToString).join("")}`;
|
|
61
|
+
case "eof":
|
|
62
|
+
return "<EOF>";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//# debugId=96D73CDE1FEDB90164756E2164756E21
|