shell-dsl 0.0.15 → 0.0.16

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.
Files changed (42) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/commands/cd/cd.cjs +66 -0
  3. package/dist/cjs/src/commands/cd/cd.cjs.map +10 -0
  4. package/dist/cjs/src/commands/index.cjs +10 -2
  5. package/dist/cjs/src/commands/index.cjs.map +3 -3
  6. package/dist/cjs/src/commands/sed/sed.cjs +291 -76
  7. package/dist/cjs/src/commands/sed/sed.cjs.map +3 -3
  8. package/dist/cjs/src/commands/tr/tr.cjs +223 -0
  9. package/dist/cjs/src/commands/tr/tr.cjs.map +10 -0
  10. package/dist/cjs/src/commands/tree/tree.cjs +7 -4
  11. package/dist/cjs/src/commands/tree/tree.cjs.map +3 -3
  12. package/dist/cjs/src/interpreter/context.cjs +3 -2
  13. package/dist/cjs/src/interpreter/context.cjs.map +3 -3
  14. package/dist/cjs/src/interpreter/interpreter.cjs +4 -2
  15. package/dist/cjs/src/interpreter/interpreter.cjs.map +3 -3
  16. package/dist/cjs/src/parser/parser.cjs +11 -2
  17. package/dist/cjs/src/parser/parser.cjs.map +3 -3
  18. package/dist/cjs/src/types.cjs.map +2 -2
  19. package/dist/mjs/package.json +1 -1
  20. package/dist/mjs/src/commands/cd/cd.mjs +36 -0
  21. package/dist/mjs/src/commands/cd/cd.mjs.map +10 -0
  22. package/dist/mjs/src/commands/index.mjs +10 -2
  23. package/dist/mjs/src/commands/index.mjs.map +3 -3
  24. package/dist/mjs/src/commands/sed/sed.mjs +291 -76
  25. package/dist/mjs/src/commands/sed/sed.mjs.map +3 -3
  26. package/dist/mjs/src/commands/tr/tr.mjs +193 -0
  27. package/dist/mjs/src/commands/tr/tr.mjs.map +10 -0
  28. package/dist/mjs/src/commands/tree/tree.mjs +7 -4
  29. package/dist/mjs/src/commands/tree/tree.mjs.map +3 -3
  30. package/dist/mjs/src/interpreter/context.mjs +3 -2
  31. package/dist/mjs/src/interpreter/context.mjs.map +3 -3
  32. package/dist/mjs/src/interpreter/interpreter.mjs +4 -2
  33. package/dist/mjs/src/interpreter/interpreter.mjs.map +3 -3
  34. package/dist/mjs/src/parser/parser.mjs +11 -2
  35. package/dist/mjs/src/parser/parser.mjs.map +3 -3
  36. package/dist/mjs/src/types.mjs.map +2 -2
  37. package/dist/types/src/commands/cd/cd.d.ts +2 -0
  38. package/dist/types/src/commands/index.d.ts +2 -0
  39. package/dist/types/src/commands/tr/tr.d.ts +2 -0
  40. package/dist/types/src/interpreter/context.d.ts +1 -0
  41. package/dist/types/src/types.d.ts +1 -0
  42. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "shell-dsl",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "type": "commonjs"
5
5
  }
@@ -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/commands/cd/cd.ts
30
+ var exports_cd = {};
31
+ __export(exports_cd, {
32
+ cd: () => cd
33
+ });
34
+ module.exports = __toCommonJS(exports_cd);
35
+ var cd = async (ctx) => {
36
+ if (ctx.args.length === 0) {
37
+ return 0;
38
+ }
39
+ let target = ctx.args[0];
40
+ if (target === "-") {
41
+ const oldpwd = ctx.env.OLDPWD;
42
+ if (!oldpwd) {
43
+ await ctx.stderr.writeText(`cd: OLDPWD not set
44
+ `);
45
+ return 1;
46
+ }
47
+ target = oldpwd;
48
+ }
49
+ const resolved = ctx.fs.resolve(ctx.cwd, target);
50
+ try {
51
+ const stat = await ctx.fs.stat(resolved);
52
+ if (!stat.isDirectory()) {
53
+ await ctx.stderr.writeText(`cd: not a directory: ${target}
54
+ `);
55
+ return 1;
56
+ }
57
+ } catch {
58
+ await ctx.stderr.writeText(`cd: not a directory: ${target}
59
+ `);
60
+ return 1;
61
+ }
62
+ ctx.setCwd(resolved);
63
+ return 0;
64
+ };
65
+
66
+ //# debugId=F71D097361CBA61564756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/commands/cd/cd.ts"],
4
+ "sourcesContent": [
5
+ "import type { Command } from \"../../types.cjs\";\n\nexport const cd: Command = async (ctx) => {\n if (ctx.args.length === 0) {\n return 0;\n }\n\n let target = ctx.args[0]!;\n\n if (target === \"-\") {\n const oldpwd = ctx.env.OLDPWD;\n if (!oldpwd) {\n await ctx.stderr.writeText(\"cd: OLDPWD not set\\n\");\n return 1;\n }\n target = oldpwd;\n }\n\n const resolved = ctx.fs.resolve(ctx.cwd, target);\n\n try {\n const stat = await ctx.fs.stat(resolved);\n if (!stat.isDirectory()) {\n await ctx.stderr.writeText(`cd: not a directory: ${target}\\n`);\n return 1;\n }\n } catch {\n await ctx.stderr.writeText(`cd: not a directory: ${target}\\n`);\n return 1;\n }\n\n ctx.setCwd(resolved);\n\n return 0;\n};\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,IAAM,KAAc,OAAO,QAAQ;AAAA,EACxC,IAAI,IAAI,KAAK,WAAW,GAAG;AAAA,IACzB,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,SAAS,IAAI,KAAK;AAAA,EAEtB,IAAI,WAAW,KAAK;AAAA,IAClB,MAAM,SAAS,IAAI,IAAI;AAAA,IACvB,IAAI,CAAC,QAAQ;AAAA,MACX,MAAM,IAAI,OAAO,UAAU;AAAA,CAAsB;AAAA,MACjD,OAAO;AAAA,IACT;AAAA,IACA,SAAS;AAAA,EACX;AAAA,EAEA,MAAM,WAAW,IAAI,GAAG,QAAQ,IAAI,KAAK,MAAM;AAAA,EAE/C,IAAI;AAAA,IACF,MAAM,OAAO,MAAM,IAAI,GAAG,KAAK,QAAQ;AAAA,IACvC,IAAI,CAAC,KAAK,YAAY,GAAG;AAAA,MACvB,MAAM,IAAI,OAAO,UAAU,wBAAwB;AAAA,CAAU;AAAA,MAC7D,OAAO;AAAA,IACT;AAAA,IACA,MAAM;AAAA,IACN,MAAM,IAAI,OAAO,UAAU,wBAAwB;AAAA,CAAU;AAAA,IAC7D,OAAO;AAAA;AAAA,EAGT,IAAI,OAAO,QAAQ;AAAA,EAEnB,OAAO;AAAA;",
8
+ "debugId": "F71D097361CBA61564756E2164756E21",
9
+ "names": []
10
+ }
@@ -33,6 +33,7 @@ __export(exports_commands, {
33
33
  uniq: () => import_uniq.uniq,
34
34
  trueCmd: () => import_true_false.trueCmd,
35
35
  tree: () => import_tree.tree,
36
+ tr: () => import_tr.tr,
36
37
  touch: () => import_touch.touch,
37
38
  test: () => import_test.test,
38
39
  tee: () => import_tee.tee,
@@ -52,6 +53,7 @@ __export(exports_commands, {
52
53
  cp: () => import_cp.cp,
53
54
  continueCmd: () => import_break_continue.continueCmd,
54
55
  colon: () => import_colon.colon,
56
+ cd: () => import_cd.cd,
55
57
  cat: () => import_cat.cat,
56
58
  builtinCommands: () => builtinCommands,
57
59
  breakCmd: () => import_break_continue.breakCmd,
@@ -83,6 +85,8 @@ var import_sed = require("./sed/sed.cjs");
83
85
  var import_awk = require("./awk/awk.cjs");
84
86
  var import_break_continue = require("./break-continue/break-continue.cjs");
85
87
  var import_colon = require("./colon/colon.cjs");
88
+ var import_cd = require("./cd/cd.cjs");
89
+ var import_tr = require("./tr/tr.cjs");
86
90
  var import_echo2 = require("./echo/echo.cjs");
87
91
  var import_cat2 = require("./cat/cat.cjs");
88
92
  var import_grep2 = require("./grep/grep.cjs");
@@ -107,6 +111,8 @@ var import_sed2 = require("./sed/sed.cjs");
107
111
  var import_awk2 = require("./awk/awk.cjs");
108
112
  var import_break_continue2 = require("./break-continue/break-continue.cjs");
109
113
  var import_colon2 = require("./colon/colon.cjs");
114
+ var import_cd2 = require("./cd/cd.cjs");
115
+ var import_tr2 = require("./tr/tr.cjs");
110
116
  var builtinCommands = {
111
117
  echo: import_echo2.echo,
112
118
  cat: import_cat2.cat,
@@ -134,7 +140,9 @@ var builtinCommands = {
134
140
  awk: import_awk2.awk,
135
141
  break: import_break_continue2.breakCmd,
136
142
  continue: import_break_continue2.continueCmd,
137
- ":": import_colon2.colon
143
+ ":": import_colon2.colon,
144
+ cd: import_cd2.cd,
145
+ tr: import_tr2.tr
138
146
  };
139
147
 
140
- //# debugId=A797E42D013860AF64756E2164756E21
148
+ //# debugId=17598CDDC0006B1664756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/commands/index.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../types.cjs\";\n\nexport { echo } from \"./echo/echo.cjs\";\nexport { cat } from \"./cat/cat.cjs\";\nexport { grep } from \"./grep/grep.cjs\";\nexport { wc } from \"./wc/wc.cjs\";\nexport { head } from \"./head/head.cjs\";\nexport { tail } from \"./tail/tail.cjs\";\nexport { sort } from \"./sort/sort.cjs\";\nexport { uniq } from \"./uniq/uniq.cjs\";\nexport { pwd } from \"./pwd/pwd.cjs\";\nexport { ls } from \"./ls/ls.cjs\";\nexport { mkdir } from \"./mkdir/mkdir.cjs\";\nexport { rm } from \"./rm/rm.cjs\";\nexport { test, bracket } from \"./test/test.cjs\";\nexport { trueCmd, falseCmd } from \"./true-false/true-false.cjs\";\nexport { touch } from \"./touch/touch.cjs\";\nexport { cp } from \"./cp/cp.cjs\";\nexport { mv } from \"./mv/mv.cjs\";\nexport { tee } from \"./tee/tee.cjs\";\nexport { tree } from \"./tree/tree.cjs\";\nexport { find } from \"./find/find.cjs\";\nexport { sed } from \"./sed/sed.cjs\";\nexport { awk } from \"./awk/awk.cjs\";\nexport { breakCmd, continueCmd } from \"./break-continue/break-continue.cjs\";\nexport { colon } from \"./colon/colon.cjs\";\n\n// Re-export all commands as a bundle\nimport { echo } from \"./echo/echo.cjs\";\nimport { cat } from \"./cat/cat.cjs\";\nimport { grep } from \"./grep/grep.cjs\";\nimport { wc } from \"./wc/wc.cjs\";\nimport { head } from \"./head/head.cjs\";\nimport { tail } from \"./tail/tail.cjs\";\nimport { sort } from \"./sort/sort.cjs\";\nimport { uniq } from \"./uniq/uniq.cjs\";\nimport { pwd } from \"./pwd/pwd.cjs\";\nimport { ls } from \"./ls/ls.cjs\";\nimport { mkdir } from \"./mkdir/mkdir.cjs\";\nimport { rm } from \"./rm/rm.cjs\";\nimport { test, bracket } from \"./test/test.cjs\";\nimport { trueCmd, falseCmd } from \"./true-false/true-false.cjs\";\nimport { touch } from \"./touch/touch.cjs\";\nimport { cp } from \"./cp/cp.cjs\";\nimport { mv } from \"./mv/mv.cjs\";\nimport { tee } from \"./tee/tee.cjs\";\nimport { tree } from \"./tree/tree.cjs\";\nimport { find } from \"./find/find.cjs\";\nimport { sed } from \"./sed/sed.cjs\";\nimport { awk } from \"./awk/awk.cjs\";\nimport { breakCmd, continueCmd } from \"./break-continue/break-continue.cjs\";\nimport { colon } from \"./colon/colon.cjs\";\n\nexport const builtinCommands: Record<string, Command> = {\n echo,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n \"[\": bracket,\n true: trueCmd,\n false: falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n break: breakCmd,\n continue: continueCmd,\n \":\": colon,\n};\n"
5
+ "import type { Command } from \"../types.cjs\";\n\nexport { echo } from \"./echo/echo.cjs\";\nexport { cat } from \"./cat/cat.cjs\";\nexport { grep } from \"./grep/grep.cjs\";\nexport { wc } from \"./wc/wc.cjs\";\nexport { head } from \"./head/head.cjs\";\nexport { tail } from \"./tail/tail.cjs\";\nexport { sort } from \"./sort/sort.cjs\";\nexport { uniq } from \"./uniq/uniq.cjs\";\nexport { pwd } from \"./pwd/pwd.cjs\";\nexport { ls } from \"./ls/ls.cjs\";\nexport { mkdir } from \"./mkdir/mkdir.cjs\";\nexport { rm } from \"./rm/rm.cjs\";\nexport { test, bracket } from \"./test/test.cjs\";\nexport { trueCmd, falseCmd } from \"./true-false/true-false.cjs\";\nexport { touch } from \"./touch/touch.cjs\";\nexport { cp } from \"./cp/cp.cjs\";\nexport { mv } from \"./mv/mv.cjs\";\nexport { tee } from \"./tee/tee.cjs\";\nexport { tree } from \"./tree/tree.cjs\";\nexport { find } from \"./find/find.cjs\";\nexport { sed } from \"./sed/sed.cjs\";\nexport { awk } from \"./awk/awk.cjs\";\nexport { breakCmd, continueCmd } from \"./break-continue/break-continue.cjs\";\nexport { colon } from \"./colon/colon.cjs\";\nexport { cd } from \"./cd/cd.cjs\";\nexport { tr } from \"./tr/tr.cjs\";\n\n// Re-export all commands as a bundle\nimport { echo } from \"./echo/echo.cjs\";\nimport { cat } from \"./cat/cat.cjs\";\nimport { grep } from \"./grep/grep.cjs\";\nimport { wc } from \"./wc/wc.cjs\";\nimport { head } from \"./head/head.cjs\";\nimport { tail } from \"./tail/tail.cjs\";\nimport { sort } from \"./sort/sort.cjs\";\nimport { uniq } from \"./uniq/uniq.cjs\";\nimport { pwd } from \"./pwd/pwd.cjs\";\nimport { ls } from \"./ls/ls.cjs\";\nimport { mkdir } from \"./mkdir/mkdir.cjs\";\nimport { rm } from \"./rm/rm.cjs\";\nimport { test, bracket } from \"./test/test.cjs\";\nimport { trueCmd, falseCmd } from \"./true-false/true-false.cjs\";\nimport { touch } from \"./touch/touch.cjs\";\nimport { cp } from \"./cp/cp.cjs\";\nimport { mv } from \"./mv/mv.cjs\";\nimport { tee } from \"./tee/tee.cjs\";\nimport { tree } from \"./tree/tree.cjs\";\nimport { find } from \"./find/find.cjs\";\nimport { sed } from \"./sed/sed.cjs\";\nimport { awk } from \"./awk/awk.cjs\";\nimport { breakCmd, continueCmd } from \"./break-continue/break-continue.cjs\";\nimport { colon } from \"./colon/colon.cjs\";\nimport { cd } from \"./cd/cd.cjs\";\nimport { tr } from \"./tr/tr.cjs\";\n\nexport const builtinCommands: Record<string, Command> = {\n echo,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n \"[\": bracket,\n true: trueCmd,\n false: falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n break: breakCmd,\n continue: continueCmd,\n \":\": colon,\n cd,\n tr,\n};\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEqB,IAArB;AACoB,IAApB;AACqB,IAArB;AACmB,IAAnB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACmB,IAAnB;AACsB,IAAtB;AACmB,IAAnB;AAC8B,IAA9B;AACkC,IAAlC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AACoB,IAApB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACoB,IAApB;AACsC,IAAtC;AACsB,IAAtB;AAGqB,IAArB;AACoB,IAApB;AACqB,IAArB;AACmB,IAAnB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACmB,IAAnB;AACsB,IAAtB;AACmB,IAAnB;AAC8B,IAA9B;AACkC,IAAlC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AACoB,IAApB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACoB,IAApB;AACsC,IAAtC;AACsB,IAAtB;AAEO,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,KAAK;AACP;",
8
- "debugId": "A797E42D013860AF64756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEqB,IAArB;AACoB,IAApB;AACqB,IAArB;AACmB,IAAnB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACmB,IAAnB;AACsB,IAAtB;AACmB,IAAnB;AAC8B,IAA9B;AACkC,IAAlC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AACoB,IAApB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACoB,IAApB;AACsC,IAAtC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AAGqB,IAArB;AACoB,IAApB;AACqB,IAArB;AACmB,IAAnB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACmB,IAAnB;AACsB,IAAtB;AACmB,IAAnB;AAC8B,IAA9B;AACkC,IAAlC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AACoB,IAApB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACoB,IAApB;AACsC,IAAtC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AAEO,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,KAAK;AAAA,EACL;AAAA,EACA;AACF;",
8
+ "debugId": "17598CDDC0006B1664756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -56,40 +56,110 @@ function parseSubstitution(script) {
56
56
  }
57
57
  function parseCommand(script) {
58
58
  const trimmed = script.trim();
59
- const addressMatch = trimmed.match(/^\/(.+?)\/([dp])$/);
60
- if (addressMatch) {
61
- const [, addressPatternStr, cmd] = addressMatch;
62
- try {
63
- return {
64
- type: cmd,
65
- addressPattern: new RegExp(addressPatternStr),
66
- globalFlag: false,
67
- printFlag: false
68
- };
69
- } catch {
70
- return null;
71
- }
59
+ if (trimmed.startsWith(":")) {
60
+ return {
61
+ type: "label",
62
+ label: trimmed.slice(1).trim(),
63
+ globalFlag: false,
64
+ printFlag: false
65
+ };
72
66
  }
73
- if (trimmed === "d") {
74
- return { type: "d", globalFlag: false, printFlag: false };
67
+ if (trimmed === "b" || trimmed.startsWith("b ") || trimmed.startsWith("b\t")) {
68
+ return {
69
+ type: "b",
70
+ label: trimmed.length > 1 ? trimmed.slice(1).trim() : undefined,
71
+ globalFlag: false,
72
+ printFlag: false
73
+ };
75
74
  }
76
- if (trimmed === "p") {
77
- return { type: "p", globalFlag: false, printFlag: false };
75
+ if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
76
+ const inner = trimmed.slice(1, -1).trim();
77
+ const parts = splitScriptParts(inner);
78
+ const children = [];
79
+ for (const part of parts) {
80
+ const cmd = parseCommand(part);
81
+ if (cmd)
82
+ children.push(cmd);
83
+ }
84
+ return {
85
+ type: "group",
86
+ children,
87
+ globalFlag: false,
88
+ printFlag: false
89
+ };
78
90
  }
79
- const addressSubMatch = trimmed.match(/^\/(.+?)\/s(.)(.+?)\2(.*?)\2([gi]*)$/);
80
- if (addressSubMatch) {
81
- const [, addressPatternStr, , patternStr, replacement, flags] = addressSubMatch;
82
- const globalFlag = flags.includes("g");
83
- const caseInsensitive = flags.includes("i");
91
+ const simpleCommands = {
92
+ h: "h",
93
+ H: "H",
94
+ g: "g_hold",
95
+ G: "G",
96
+ x: "x",
97
+ n: "n",
98
+ N: "N",
99
+ P: "P",
100
+ D: "D",
101
+ d: "d",
102
+ p: "p"
103
+ };
104
+ if (simpleCommands[trimmed]) {
105
+ return {
106
+ type: simpleCommands[trimmed],
107
+ globalFlag: false,
108
+ printFlag: false
109
+ };
110
+ }
111
+ const addressWithCmd = trimmed.match(/^\/(.+?)\/(!)?\s*(.*)$/);
112
+ if (addressWithCmd) {
113
+ const [, addressPatternStr, negation, rest] = addressWithCmd;
114
+ const negated = negation === "!";
115
+ const restTrimmed = rest.trim();
84
116
  try {
85
- return {
86
- type: "s",
87
- addressPattern: new RegExp(addressPatternStr),
88
- pattern: new RegExp(patternStr, caseInsensitive ? "i" : ""),
89
- replacement,
90
- globalFlag,
91
- printFlag: false
92
- };
117
+ const addressPattern = new RegExp(addressPatternStr);
118
+ if (!restTrimmed)
119
+ return null;
120
+ if (simpleCommands[restTrimmed]) {
121
+ return {
122
+ type: simpleCommands[restTrimmed],
123
+ addressPattern,
124
+ negated,
125
+ globalFlag: false,
126
+ printFlag: false
127
+ };
128
+ }
129
+ if (restTrimmed === "b" || restTrimmed.startsWith("b ")) {
130
+ return {
131
+ type: "b",
132
+ addressPattern,
133
+ negated,
134
+ label: restTrimmed.length > 1 ? restTrimmed.slice(1).trim() : undefined,
135
+ globalFlag: false,
136
+ printFlag: false
137
+ };
138
+ }
139
+ if (restTrimmed.startsWith("{") && restTrimmed.endsWith("}")) {
140
+ const inner = restTrimmed.slice(1, -1).trim();
141
+ const parts = splitScriptParts(inner);
142
+ const children = [];
143
+ for (const part of parts) {
144
+ const cmd = parseCommand(part);
145
+ if (cmd)
146
+ children.push(cmd);
147
+ }
148
+ return {
149
+ type: "group",
150
+ addressPattern,
151
+ negated,
152
+ children,
153
+ globalFlag: false,
154
+ printFlag: false
155
+ };
156
+ }
157
+ const subCmd2 = parseSubstitution(restTrimmed);
158
+ if (subCmd2) {
159
+ subCmd2.addressPattern = addressPattern;
160
+ subCmd2.negated = negated;
161
+ return subCmd2;
162
+ }
93
163
  } catch {
94
164
  return null;
95
165
  }
@@ -103,8 +173,17 @@ function splitScriptParts(script) {
103
173
  const parts = [];
104
174
  let i = 0;
105
175
  let current = "";
176
+ let braceDepth = 0;
106
177
  while (i < script.length) {
107
- if (script[i] === "s" && i + 1 < script.length) {
178
+ if (script[i] === "{") {
179
+ braceDepth++;
180
+ current += script[i];
181
+ i++;
182
+ } else if (script[i] === "}") {
183
+ braceDepth--;
184
+ current += script[i];
185
+ i++;
186
+ } else if (script[i] === "s" && braceDepth === 0 && i + 1 < script.length && !/[a-zA-Z0-9]/.test(script[i + 1])) {
108
187
  const delim = script[i + 1];
109
188
  let j = i + 2;
110
189
  let delimCount = 0;
@@ -121,7 +200,7 @@ function splitScriptParts(script) {
121
200
  j++;
122
201
  current += script.slice(i, j);
123
202
  i = j;
124
- } else if (script[i] === ";") {
203
+ } else if (script[i] === ";" && braceDepth === 0) {
125
204
  const trimmed2 = current.trim();
126
205
  if (trimmed2)
127
206
  parts.push(trimmed2);
@@ -194,9 +273,12 @@ function parseArgs(args) {
194
273
  error: { type: "missing_value", option: "-e" }
195
274
  };
196
275
  }
197
- const cmd = parseCommand(script);
198
- if (cmd)
199
- options.commands.push(cmd);
276
+ const parts = splitScriptParts(script);
277
+ for (const part of parts) {
278
+ const cmd = parseCommand(part);
279
+ if (cmd)
280
+ options.commands.push(cmd);
281
+ }
200
282
  break;
201
283
  } else {
202
284
  return {
@@ -249,37 +331,141 @@ function applySubstitution(line, cmd) {
249
331
  return line.replace(cmd.pattern, cmd.replacement);
250
332
  }
251
333
  }
252
- function processLine(line, commands, suppressOutput) {
253
- let currentLine = line;
254
- let deleted = false;
255
- let printed = false;
256
- for (const cmd of commands) {
257
- if (cmd.addressPattern && !cmd.addressPattern.test(currentLine)) {
334
+ function addressMatches(cmd, state) {
335
+ if (!cmd.addressPattern) {
336
+ return cmd.negated ? false : true;
337
+ }
338
+ const matches = cmd.addressPattern.test(state.patternSpace);
339
+ return cmd.negated ? !matches : matches;
340
+ }
341
+ function findLabel(commands, label) {
342
+ for (let i = 0;i < commands.length; i++) {
343
+ if (commands[i].type === "label" && commands[i].label === label) {
344
+ return i;
345
+ }
346
+ }
347
+ return -1;
348
+ }
349
+ function executeCommands(commands, state, topLevel) {
350
+ let pc = 0;
351
+ while (pc < commands.length) {
352
+ const cmd = commands[pc];
353
+ if (cmd.type === "label") {
354
+ pc++;
355
+ continue;
356
+ }
357
+ if (!addressMatches(cmd, state)) {
358
+ pc++;
258
359
  continue;
259
360
  }
260
361
  switch (cmd.type) {
261
362
  case "s":
262
- currentLine = applySubstitution(currentLine, cmd);
363
+ state.patternSpace = applySubstitution(state.patternSpace, cmd);
263
364
  break;
264
365
  case "d":
265
- deleted = true;
266
- return { output: null, deleted: true };
366
+ state.deleted = true;
367
+ return { branchToEnd: false, deleted: true, nextLine: false, restart: false };
267
368
  case "p":
268
- printed = true;
369
+ state.output.push(state.patternSpace);
370
+ break;
371
+ case "h":
372
+ state.holdSpace = state.patternSpace;
373
+ break;
374
+ case "H":
375
+ state.holdSpace = state.holdSpace + `
376
+ ` + state.patternSpace;
377
+ break;
378
+ case "g_hold":
379
+ state.patternSpace = state.holdSpace;
380
+ break;
381
+ case "G":
382
+ state.patternSpace = state.patternSpace + `
383
+ ` + state.holdSpace;
384
+ break;
385
+ case "x": {
386
+ const tmp = state.patternSpace;
387
+ state.patternSpace = state.holdSpace;
388
+ state.holdSpace = tmp;
389
+ break;
390
+ }
391
+ case "n":
392
+ if (!state.suppressOutput) {
393
+ state.output.push(state.patternSpace);
394
+ }
395
+ state.lineIndex++;
396
+ if (state.lineIndex < state.lines.length) {
397
+ state.patternSpace = state.lines[state.lineIndex];
398
+ } else {
399
+ state.deleted = true;
400
+ return { branchToEnd: false, deleted: true, nextLine: false, restart: false };
401
+ }
402
+ break;
403
+ case "N":
404
+ state.lineIndex++;
405
+ if (state.lineIndex < state.lines.length) {
406
+ state.patternSpace = state.patternSpace + `
407
+ ` + state.lines[state.lineIndex];
408
+ } else {
409
+ if (!state.suppressOutput) {
410
+ state.output.push(state.patternSpace);
411
+ }
412
+ state.deleted = true;
413
+ return { branchToEnd: false, deleted: true, nextLine: false, restart: false };
414
+ }
415
+ break;
416
+ case "P": {
417
+ const nlIdx = state.patternSpace.indexOf(`
418
+ `);
419
+ if (nlIdx >= 0) {
420
+ state.output.push(state.patternSpace.slice(0, nlIdx));
421
+ } else {
422
+ state.output.push(state.patternSpace);
423
+ }
424
+ break;
425
+ }
426
+ case "D": {
427
+ const nlIdx2 = state.patternSpace.indexOf(`
428
+ `);
429
+ if (nlIdx2 >= 0) {
430
+ state.patternSpace = state.patternSpace.slice(nlIdx2 + 1);
431
+ state.restart = true;
432
+ return { branchToEnd: false, deleted: false, nextLine: false, restart: true };
433
+ } else {
434
+ state.deleted = true;
435
+ return { branchToEnd: false, deleted: true, nextLine: false, restart: false };
436
+ }
437
+ }
438
+ case "b":
439
+ if (cmd.label) {
440
+ if (topLevel) {
441
+ const idx = findLabel(commands, cmd.label);
442
+ if (idx >= 0) {
443
+ pc = idx;
444
+ continue;
445
+ }
446
+ }
447
+ return { branchToEnd: true, branchLabel: cmd.label, deleted: false, nextLine: false, restart: false };
448
+ }
449
+ return { branchToEnd: true, deleted: false, nextLine: false, restart: false };
450
+ case "group":
451
+ if (cmd.children) {
452
+ const result = executeCommands(cmd.children, state, false);
453
+ if (result.deleted || result.branchToEnd || result.restart) {
454
+ if (result.branchLabel && topLevel) {
455
+ const idx = findLabel(commands, result.branchLabel);
456
+ if (idx >= 0) {
457
+ pc = idx;
458
+ continue;
459
+ }
460
+ }
461
+ return result;
462
+ }
463
+ }
269
464
  break;
270
465
  }
466
+ pc++;
271
467
  }
272
- if (deleted) {
273
- return { output: null, deleted: true };
274
- }
275
- if (suppressOutput) {
276
- return { output: printed ? currentLine : null, deleted: false };
277
- }
278
- if (printed) {
279
- return { output: currentLine + `
280
- ` + currentLine, deleted: false };
281
- }
282
- return { output: currentLine, deleted: false };
468
+ return { branchToEnd: false, deleted: false, nextLine: false, restart: false };
283
469
  }
284
470
  var sed = async (ctx) => {
285
471
  const { options, files, error } = parseArgs(ctx.args);
@@ -298,34 +484,59 @@ var sed = async (ctx) => {
298
484
  if (lines.length > 0 && lines[lines.length - 1] === "") {
299
485
  lines.pop();
300
486
  }
301
- for (const line of lines) {
302
- const { output } = processLine(line, options.commands, options.suppressOutput);
303
- if (output !== null) {
304
- await ctx.stdout.writeText(output + `
305
- `);
487
+ const allOutput = [];
488
+ const state = {
489
+ patternSpace: "",
490
+ holdSpace: "",
491
+ lineIndex: 0,
492
+ lines,
493
+ suppressOutput: options.suppressOutput,
494
+ output: [],
495
+ deleted: false,
496
+ restart: false
497
+ };
498
+ while (state.lineIndex < lines.length) {
499
+ state.patternSpace = lines[state.lineIndex];
500
+ state.deleted = false;
501
+ state.output = [];
502
+ let restarting = true;
503
+ while (restarting) {
504
+ restarting = false;
505
+ state.restart = false;
506
+ const result = executeCommands(options.commands, state, true);
507
+ if (result.restart) {
508
+ restarting = true;
509
+ allOutput.push(...state.output);
510
+ state.output = [];
511
+ continue;
512
+ }
513
+ if (result.deleted) {
514
+ allOutput.push(...state.output);
515
+ state.lineIndex++;
516
+ break;
517
+ }
518
+ allOutput.push(...state.output);
519
+ if (!options.suppressOutput) {
520
+ allOutput.push(state.patternSpace);
521
+ }
522
+ state.lineIndex++;
306
523
  }
307
524
  }
525
+ return allOutput;
308
526
  };
309
527
  if (files.length === 0) {
310
528
  const content = await ctx.stdin.text();
311
- await processContent(content);
529
+ const outputLines = await processContent(content);
530
+ for (const line of outputLines) {
531
+ await ctx.stdout.writeText(line + `
532
+ `);
533
+ }
312
534
  } else if (options.inPlace) {
313
535
  for (const file of files) {
314
536
  try {
315
537
  const path = ctx.fs.resolve(ctx.cwd, file);
316
538
  const content = await ctx.fs.readFile(path);
317
- const lines = content.toString().split(`
318
- `);
319
- if (lines.length > 0 && lines[lines.length - 1] === "") {
320
- lines.pop();
321
- }
322
- const outputLines = [];
323
- for (const line of lines) {
324
- const { output } = processLine(line, options.commands, options.suppressOutput);
325
- if (output !== null) {
326
- outputLines.push(output);
327
- }
328
- }
539
+ const outputLines = await processContent(content.toString());
329
540
  const result = outputLines.length > 0 ? outputLines.join(`
330
541
  `) + `
331
542
  ` : "";
@@ -342,7 +553,11 @@ var sed = async (ctx) => {
342
553
  try {
343
554
  const path = ctx.fs.resolve(ctx.cwd, file);
344
555
  const content = await ctx.fs.readFile(path);
345
- await processContent(content.toString());
556
+ const outputLines = await processContent(content.toString());
557
+ for (const line of outputLines) {
558
+ await ctx.stdout.writeText(line + `
559
+ `);
560
+ }
346
561
  } catch (err) {
347
562
  const message = err instanceof Error ? err.message : String(err);
348
563
  await ctx.stderr.writeText(`sed: ${file}: ${message}
@@ -354,4 +569,4 @@ var sed = async (ctx) => {
354
569
  return 0;
355
570
  };
356
571
 
357
- //# debugId=9484A386918DB8C764756E2164756E21
572
+ //# debugId=54C2879933482FB364756E2164756E21