hclang 0.5.14 → 0.16.0

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 (163) hide show
  1. package/README.md +246 -25
  2. package/esm/_dnt.polyfills.js +144 -0
  3. package/esm/_dnt.shims.js +61 -0
  4. package/esm/cli/hc.js +180 -0
  5. package/esm/cli/prompt.js +58 -0
  6. package/esm/cli/resource-store.js +125 -0
  7. package/esm/cli/runfile.js +62 -0
  8. package/esm/deps/jsr.io/@nothing628/chalk/1.0.1/src/ansi-styles/index.js +209 -0
  9. package/esm/deps/jsr.io/@nothing628/chalk/1.0.1/src/mod.js +170 -0
  10. package/esm/deps/jsr.io/@nothing628/chalk/1.0.1/src/supports-color/index.js +155 -0
  11. package/esm/deps/jsr.io/@nothing628/chalk/1.0.1/src/utilities.js +32 -0
  12. package/esm/deps/jsr.io/@std/cli/1.0.32/parse_args.js +372 -0
  13. package/esm/lib/execute/env-visibility.js +80 -0
  14. package/esm/lib/execute/eval-pipe.js +34 -0
  15. package/esm/lib/execute/hc-eval.js +233 -0
  16. package/esm/lib/execute/hc-log.js +46 -0
  17. package/esm/lib/execute/hc-test.js +220 -0
  18. package/esm/lib/execute/lex-pipe.js +94 -0
  19. package/esm/lib/execute/lex-run.js +134 -0
  20. package/esm/lib/execute/lex.js +170 -0
  21. package/esm/lib/execute/parse-pipe.js +113 -0
  22. package/esm/lib/execute/sigilizer.js +75 -0
  23. package/esm/lib/execute/syntax.js +80 -0
  24. package/esm/lib/execute/terminals.js +62 -0
  25. package/esm/lib/frames/atom-syntax.js +67 -0
  26. package/esm/lib/frames/bound-method.js +123 -0
  27. package/esm/lib/frames/clock.js +177 -0
  28. package/esm/lib/frames/context.js +41 -0
  29. package/esm/lib/frames/dimensional-algebra.js +43 -0
  30. package/esm/lib/frames/effect-marker.js +36 -0
  31. package/esm/lib/frames/evaluation-scope.js +389 -0
  32. package/esm/lib/frames/frame-alias.js +143 -0
  33. package/esm/lib/frames/frame-arg.js +149 -0
  34. package/esm/lib/frames/frame-array.js +129 -0
  35. package/esm/lib/frames/frame-atom.js +36 -0
  36. package/esm/lib/frames/frame-blob.js +181 -0
  37. package/esm/lib/frames/frame-bytes.js +176 -0
  38. package/esm/lib/frames/frame-comment.js +65 -0
  39. package/esm/lib/frames/frame-decimal.js +172 -0
  40. package/esm/lib/frames/frame-doc.js +114 -0
  41. package/esm/lib/frames/frame-expr.js +135 -0
  42. package/esm/lib/frames/frame-group.js +45 -0
  43. package/esm/lib/frames/frame-handle.js +132 -0
  44. package/esm/lib/frames/frame-int.js +208 -0
  45. package/esm/lib/frames/frame-lazy.js +138 -0
  46. package/esm/lib/frames/frame-list.js +145 -0
  47. package/esm/lib/frames/frame-match.js +9 -0
  48. package/esm/lib/frames/frame-name.js +132 -0
  49. package/esm/lib/frames/frame-note.js +132 -0
  50. package/esm/lib/frames/frame-number.js +101 -0
  51. package/esm/lib/frames/frame-numeric.js +246 -0
  52. package/esm/lib/frames/frame-rational.js +143 -0
  53. package/esm/lib/frames/frame-resource.js +212 -0
  54. package/esm/lib/frames/frame-schema.js +84 -0
  55. package/esm/lib/frames/frame-scope-anchor.js +169 -0
  56. package/esm/lib/frames/frame-sequence.js +102 -0
  57. package/esm/lib/frames/frame-string.js +185 -0
  58. package/esm/lib/frames/frame-symbol.js +443 -0
  59. package/esm/lib/frames/frame-text.js +32 -0
  60. package/esm/lib/frames/frame-time.js +555 -0
  61. package/esm/lib/frames/frame-type.js +41 -0
  62. package/esm/lib/frames/frame-typed-number.js +128 -0
  63. package/esm/lib/frames/frame-uri.js +128 -0
  64. package/esm/lib/frames/frame.js +457 -0
  65. package/esm/lib/frames/meta-frame.js +332 -0
  66. package/esm/lib/frames/resource-binding.js +11 -0
  67. package/esm/lib/frames/resource-handlers.js +114 -0
  68. package/esm/lib/frames/resource-reference.js +153 -0
  69. package/esm/lib/frames/resource-store.js +52 -0
  70. package/esm/lib/frames/schema-bit-matcher.js +153 -0
  71. package/esm/lib/frames/schema-compiler.js +7 -0
  72. package/esm/lib/frames/schema-matcher.js +49 -0
  73. package/esm/lib/frames/schema-structural-matcher.js +46 -0
  74. package/esm/lib/frames/stringify.js +32 -0
  75. package/esm/lib/frames.js +48 -0
  76. package/esm/lib/ops/conditionals.js +13 -0
  77. package/esm/lib/ops/frame-curry.js +52 -0
  78. package/esm/lib/ops/frame-ops.js +27 -0
  79. package/esm/lib/ops/iterators.js +36 -0
  80. package/esm/lib/ops/math.js +25 -0
  81. package/esm/lib/ops/type-operations.js +24 -0
  82. package/esm/lib/ops.js +31 -0
  83. package/esm/lib/scan.js +14 -0
  84. package/esm/lib/version.js +1 -0
  85. package/esm/package.json +3 -0
  86. package/package.json +19 -78
  87. package/lib/src/cli/hc.js +0 -40
  88. package/lib/src/cli/runfile.js +0 -28
  89. package/lib/src/execute/eval-pipe.js +0 -15
  90. package/lib/src/execute/evaluate.js +0 -10
  91. package/lib/src/execute/execute.js +0 -18
  92. package/lib/src/execute/frame-space.js +0 -17
  93. package/lib/src/execute/hc-eval.js +0 -105
  94. package/lib/src/execute/hc-log.js +0 -39
  95. package/lib/src/execute/hc-test.js +0 -44
  96. package/lib/src/execute/lex-bytes.js +0 -42
  97. package/lib/src/execute/lex-pipe.js +0 -63
  98. package/lib/src/execute/lex.js +0 -110
  99. package/lib/src/execute/lexer.js +0 -24
  100. package/lib/src/execute/parse-pipe.js +0 -55
  101. package/lib/src/execute/syntax.js +0 -36
  102. package/lib/src/execute/terminals.js +0 -54
  103. package/lib/src/execute.js +0 -3
  104. package/lib/src/frames/frame-alias.js +0 -45
  105. package/lib/src/frames/frame-arg.js +0 -62
  106. package/lib/src/frames/frame-array.js +0 -47
  107. package/lib/src/frames/frame-atom.js +0 -41
  108. package/lib/src/frames/frame-blob.js +0 -104
  109. package/lib/src/frames/frame-bytes.js +0 -31
  110. package/lib/src/frames/frame-comment.js +0 -28
  111. package/lib/src/frames/frame-doc.js +0 -19
  112. package/lib/src/frames/frame-expr.js +0 -34
  113. package/lib/src/frames/frame-group.js +0 -31
  114. package/lib/src/frames/frame-lazy.js +0 -39
  115. package/lib/src/frames/frame-list.js +0 -58
  116. package/lib/src/frames/frame-name.js +0 -29
  117. package/lib/src/frames/frame-note.js +0 -104
  118. package/lib/src/frames/frame-number.js +0 -88
  119. package/lib/src/frames/frame-schema.js +0 -47
  120. package/lib/src/frames/frame-string.js +0 -41
  121. package/lib/src/frames/frame-symbol.js +0 -82
  122. package/lib/src/frames/frame.js +0 -76
  123. package/lib/src/frames/meta-frame.js +0 -83
  124. package/lib/src/frames.js +0 -24
  125. package/lib/src/index.js +0 -5
  126. package/lib/src/maml/tag.js +0 -17
  127. package/lib/src/maml.js +0 -26
  128. package/lib/src/ops/conditionals.js +0 -14
  129. package/lib/src/ops/frame-curry.js +0 -17
  130. package/lib/src/ops/frame-ops.js +0 -24
  131. package/lib/src/ops/iterators.js +0 -28
  132. package/lib/src/ops/math.js +0 -68
  133. package/lib/src/ops.js +0 -24
  134. package/lib/src/version.js +0 -3
  135. package/lib/test/execute/eval-pipe-spec.js +0 -45
  136. package/lib/test/execute/evaluate-spec.js +0 -133
  137. package/lib/test/execute/execute-spec.js +0 -115
  138. package/lib/test/execute/hc-eval-spec.js +0 -68
  139. package/lib/test/execute/hc-test-spec.js +0 -53
  140. package/lib/test/execute/lex-pipe-spec.js +0 -25
  141. package/lib/test/execute/parse-spec.js +0 -67
  142. package/lib/test/execute/script-spec.js +0 -24
  143. package/lib/test/frames/frame-alias-spec.js +0 -36
  144. package/lib/test/frames/frame-arg-spec.js +0 -57
  145. package/lib/test/frames/frame-array-spec.js +0 -54
  146. package/lib/test/frames/frame-blob-spec.js +0 -56
  147. package/lib/test/frames/frame-bytes-spec.js +0 -16
  148. package/lib/test/frames/frame-comment-spec.js +0 -17
  149. package/lib/test/frames/frame-doc-spec.js +0 -17
  150. package/lib/test/frames/frame-expr-spec.js +0 -60
  151. package/lib/test/frames/frame-group-spec.js +0 -27
  152. package/lib/test/frames/frame-lazy-spec.js +0 -49
  153. package/lib/test/frames/frame-name-spec.js +0 -26
  154. package/lib/test/frames/frame-note-spec.js +0 -48
  155. package/lib/test/frames/frame-number-spec.js +0 -23
  156. package/lib/test/frames/frame-schema-spec.js +0 -54
  157. package/lib/test/frames/frame-spec.js +0 -31
  158. package/lib/test/frames/frame-string-spec.js +0 -43
  159. package/lib/test/frames/frame-symbol-spec.js +0 -64
  160. package/lib/test/frames/meta-frame-spec.js +0 -75
  161. package/lib/test/maml/maml-spec.js +0 -42
  162. package/lib/test/maml/tag-spec.js +0 -53
  163. package/lib/test/ops/iterators-spec.js +0 -70
package/README.md CHANGED
@@ -1,50 +1,271 @@
1
- # Homiconic C
2
- version: 0.5.11
1
+ # Homoiconic C
3
2
 
4
- [![Codeship Status for TheSwanFactory/hclang](https://app.codeship.com/projects/b1198f30-aee9-0137-5fdc-4a1003a17a1c/status?branch=master)](https://app.codeship.com/projects/362584)
3
+ [![JSR](https://jsr.io/badges/@swanfactory/hclang)](https://jsr.io/@swanfactory/hclang)
4
+ [![JSR Score](https://jsr.io/badges/@swanfactory/hclang/score)](https://jsr.io/@swanfactory/hclang)
5
+
6
+ A universal language for code and data.
5
7
 
6
8
  ## Introduction
7
9
 
8
- [Homoiconic C](https://theswanfactory.wordpress.com/2016/12/20/homoiconic-c-a-universal-language-for-code-and-data/) (HC) is a single universal language for code and data. This repository contains the first implementation of HC as an interpreter written in TypeScript running on `nodejs`. It also contains a sample application called MAML, the [*Multipurpose Abstract Markup Language*](https://theswanfactory.wordpress.com/2016/11/08/introducing-maml-a-draft-proposal-for-html6/). MAML is a radically simple proposal for replacing all the existing web technologies (HMTL, CSS, JavaScript, SVG, etc.) with a single format based on HC. It can also be used to define easily-parseable variants of other common file formats (e.g., HCSV, HCSON).
10
+ [Homoiconic C](https://theswanfactory.wordpress.com/2016/12/20/homoiconic-c-a-universal-language-for-code-and-data/)
11
+ (HC) is a single universal language for code and data. This monorepo contains
12
+ the first implementation of HC as an interpreter written in TypeScript running
13
+ on [Deno](https://deno.land/).
9
14
 
10
- ## Usage
15
+ The repository includes several packages:
16
+
17
+ - **[@swanfactory/hclang](https://jsr.io/@swanfactory/hclang)** - Core library
18
+ published to JSR
19
+ - **CLI** - Interactive REPL and command-line tools
20
+ - **MAML** -
21
+ [_Multipurpose Abstract Markup Language_](https://theswanfactory.wordpress.com/2016/11/08/introducing-maml-a-draft-proposal-for-html6/),
22
+ a radically simple proposal for replacing web technologies (HTML, CSS,
23
+ JavaScript, SVG) with a single format based on HC
24
+ - **Web** - Web components and Fresh framework integration
25
+
26
+ HC can also be used to define easily-parseable variants of other common file
27
+ formats (e.g., HCSV, HCSON).
28
+
29
+ ## Quick Start
30
+
31
+ ### Try it Online
32
+
33
+ Visit [hclang.deno.dev](https://hclang.deno.dev) to try HC directly in your
34
+ browser with no installation required.
35
+
36
+ ### Use as a Library
37
+
38
+ ```bash
39
+ # Deno
40
+ deno add jsr:@swanfactory/hclang
11
41
 
42
+ # Node.js/npm
43
+ npx jsr add @swanfactory/hclang
12
44
  ```
13
- $ npm install
14
- $ export DEBUG=true # optional
15
- $ npm run hc
45
+
46
+ Then in your code:
47
+
48
+ ```typescript
49
+ import { execute } from "@swanfactory/hclang";
50
+
51
+ const result = execute("1 + 1");
52
+ console.log(result); // Output: '2'
16
53
  ```
17
- This will launch the interpreter.
18
54
 
19
- ## BitScheme
55
+ See the [library documentation](https://jsr.io/@swanfactory/hclang/doc) for more
56
+ details.
57
+
58
+ ### Run the CLI
20
59
 
21
- To generate and run the BitScheme documentation, type:
60
+ With Node.js 24 or newer, run the current CLI directly from npm. Deno is not
61
+ required:
62
+
63
+ ```bash
64
+ # Interactive REPL
65
+ npx hclang@latest
66
+
67
+ # Evaluate a file
68
+ npx hclang@latest path/to/program.hc
69
+
70
+ # Verify executable examples in an HC document
71
+ npx hclang@latest path/to/examples.hc --testdoc
22
72
  ```
23
- $ npm run bs:all
73
+
74
+ From source:
75
+
76
+ ```bash
77
+ git clone https://github.com/TheSwanFactory/hclang.git
78
+ cd hclang
79
+ deno task hc
80
+ ```
81
+
82
+ This will launch the interactive HC interpreter.
83
+
84
+ ### Run Tests
85
+
86
+ ```bash
87
+ deno task test
88
+ ```
89
+
90
+ ## Usage
91
+
92
+ ### Available Tasks
93
+
94
+ The root `deno.json` provides several tasks:
95
+
96
+ | Task | Description |
97
+ | ---------------------- | ------------------------------------------------- |
98
+ | `deno task hc` | Launch the HC REPL |
99
+ | `deno task setup` | Install pre-commit hooks |
100
+ | `deno task test` | Run all tests (setup, format, lint, and tests) |
101
+ | `deno task test:setup` | Run all pre-commit hooks on all files |
102
+ | `deno task test:cli` | Test CLI package |
103
+ | `deno task test:lib` | Test library package |
104
+ | `deno task test:maml` | Test MAML package |
105
+ | `deno task test:web` | Test web package |
106
+ | `deno task test:bs` | Test BitScheme documentation |
107
+ | `deno task test:doc` | Test HC documentation examples |
108
+ | `deno task build` | Build native, npm, and web artifacts |
109
+ | `deno task build:npm` | Generate the Node.js CLI package in `dist/npm` |
110
+ | `deno task test:npm` | Pack and smoke-test the CLI package through `npx` |
111
+
112
+ ### BitScheme
113
+
114
+ [BitScheme](cli/hc/BitScheme.hc) is a specialized scripting language for
115
+ declaratively parsing, manipulating, and generating binary data. It includes
116
+ executable documentation that can be tested:
117
+
118
+ ```bash
119
+ deno task test:bs
120
+ ```
121
+
122
+ This runs the BitScheme interpreter on its own documentation, executing embedded
123
+ code examples and verifying outputs.
124
+
125
+ ### Debug Mode
126
+
127
+ Enable verbose debugging output:
128
+
129
+ ```bash
130
+ export DEBUG=true
131
+ deno task hc
24
132
  ```
25
- This will open the BitScheme.html file, and also run the documentation through the testdoc evaluator which will generate pass/fail messages.
26
133
 
27
134
  ## Development
28
135
 
29
- 1. Install the [Atom editor](http://flight-manual.atom.io/getting-started/sections/installing-atom/).
136
+ ### Setup
137
+
138
+ 1. Clone the [GitHub repository](https://github.com/TheSwanFactory/hclang.git):
139
+
140
+ ```bash
141
+ git clone https://github.com/TheSwanFactory/hclang.git
142
+ cd hclang
143
+ ```
144
+
145
+ 2. Install [Deno](https://github.com/denoland/deno):
146
+
147
+ ```bash
148
+ # macOS
149
+ brew install deno
150
+
151
+ # Other platforms: see https://deno.land/
152
+ ```
153
+
154
+ 3. (Optional) Install [pre-commit](https://pre-commit.com/) for automatic code
155
+ quality checks:
156
+
157
+ ```bash
158
+ # macOS
159
+ brew install pre-commit
160
+
161
+ # Other platforms: pip install pre-commit
162
+ ```
163
+
164
+ Pre-commit hooks are automatically installed when you run `deno task test` or
165
+ manually with `deno task setup`.
166
+
167
+ 4. Run tests:
168
+
169
+ ```bash
170
+ deno task test
171
+ ```
172
+
173
+ This will automatically set up pre-commit hooks, format code, run linters,
174
+ and execute the test suite.
175
+
176
+ ### Project Structure
177
+
178
+ This is a Deno workspace (monorepo) with the following packages:
179
+
180
+ ```text
181
+ hclang/
182
+ ├── cli/ # HC command-line interface & REPL
183
+ ├── lib/ # Core library (published to JSR)
184
+ ├── maml/ # MAML markup language
185
+ ├── web/ # Web components
186
+ ├── doc/ # Documentation and papers
187
+ └── deno.json # Workspace root configuration
188
+ ```
189
+
190
+ ### VS Code Extension
191
+
192
+ The VS Code extension for HC is now included in this repository at
193
+ [vscode-extension/](vscode-extension/). It provides comprehensive syntax
194
+ highlighting for all HC language features based on the complete grammar
195
+ specification.
196
+
197
+ **Installation:**
198
+
199
+ ```bash
200
+ # Install from source
201
+ deno task vscode:install
202
+
203
+ # Or package for distribution
204
+ deno task vscode:package
205
+
206
+ # Or publish to marketplace
207
+ deno task vscode:publish
208
+ ```
209
+
210
+ The extension recognizes `.hc` files and provides:
211
+
212
+ - Syntax highlighting for all HC elements (numbers, strings, identifiers,
213
+ operators, etc.)
214
+ - Smart bracket matching for `{}`, `[]`, `()`
215
+ - Auto-closing pairs
216
+ - Comment toggling with `#`
217
+
218
+ **Note:** The old standalone
219
+ [language-hclang](https://github.com/TheSwanFactory/language-hclang) repository
220
+ is now deprecated in favor of this integrated extension.
221
+
222
+ ## Publishing
223
+
224
+ For maintainers publishing new versions:
225
+
226
+ 1. Ensure all tests pass:
227
+
228
+ ```bash
229
+ deno task test
230
+ ```
30
231
 
31
- 2. Install the [language-maml](https://github.com/TheSwanFactory/language-maml) Atom package.
232
+ 2. Update version everywhere:
32
233
 
33
- 3. Clone the [github repository](https://github.com/TheSwanFactory/hclang.git).
234
+ ```bash
235
+ deno task bump
236
+ ```
34
237
 
35
- 4. Install [node.js](https://nodejs.org/).
36
- * e.g., `brew install node` on macOS.
238
+ This updates `deno.json`, `lib/version.ts`, and all workspace package
239
+ versions, then commits the changes.
37
240
 
38
- 5. Run `npm test`.
241
+ 3. Merge the PR to the `master` branch.
39
242
 
40
- ## Publishing
243
+ GitHub Actions compares the version in `deno.json` with the version before
244
+ the merge. When the version changed, it publishes the libraries to
245
+ [JSR](https://jsr.io/@swanfactory/hclang), publishes the exact `hclang`
246
+ tarball exercised through `npx`, and creates a GitHub Release tagged
247
+ `v<version>` with generated notes. Each registry is checked independently, so
248
+ a rerun resumes a partial release instead of retrying versions that are
249
+ already immutable. Merges without a version bump do not publish or create a
250
+ release; no manual tag is required.
41
251
 
42
- From the feature branch:
252
+ npm publishing runs in the protected `npm-publish` GitHub environment using a
253
+ trusted publisher for the public `hclang` package. Its npm settings must
254
+ authorize the `TheSwanFactory/hclang` repository,
255
+ `.github/workflows/deno.js.yml`, the `npm-publish` environment, and direct
256
+ `npm publish` before merging a release bump. The build/PR job has no OIDC
257
+ token permission.
43
258
 
44
- 1. Update CHANGELOG.md
259
+ ## Links
45
260
 
46
- 1. Run `npm run done` to bump version and tag
261
+ - **JSR Package**: [@swanfactory/hclang](https://jsr.io/@swanfactory/hclang)
262
+ - **Documentation**: [JSR Docs](https://jsr.io/@swanfactory/hclang/doc)
263
+ - **GitHub**: [TheSwanFactory/hclang](https://github.com/TheSwanFactory/hclang)
264
+ - **Blog**:
265
+ [Homoiconic C Introduction](https://theswanfactory.wordpress.com/2016/12/20/homoiconic-c-a-universal-language-for-code-and-data/)
266
+ - **MAML**:
267
+ [HTML6 Proposal](https://theswanfactory.wordpress.com/2016/11/08/introducing-maml-a-draft-proposal-for-html6/)
47
268
 
48
- 1. Merge PR
269
+ ## License
49
270
 
50
- Should automatically publish to [npmjs](https://www.npmjs.com/package/hclang).
271
+ MIT
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Based on [import-meta-ponyfill](https://github.com/gaubee/import-meta-ponyfill),
3
+ * but instead of using npm to install additional dependencies,
4
+ * this approach manually consolidates cjs/mjs/d.ts into a single file.
5
+ *
6
+ * Note that this code might be imported multiple times
7
+ * (for example, both dnt.test.polyfills.ts and dnt.polyfills.ts contain this code;
8
+ * or Node.js might dynamically clear the cache and then force a require).
9
+ * Therefore, it's important to avoid redundant writes to global objects.
10
+ * Additionally, consider that commonjs is used alongside esm,
11
+ * so the two ponyfill functions are stored independently in two separate global objects.
12
+ */
13
+ //@ts-ignore
14
+ import { createRequire } from "node:module";
15
+ //@ts-ignore
16
+ import { fileURLToPath, pathToFileURL } from "node:url";
17
+ //@ts-ignore
18
+ import { dirname } from "node:path";
19
+ const defineGlobalPonyfill = (symbolFor, fn) => {
20
+ if (!Reflect.has(globalThis, Symbol.for(symbolFor))) {
21
+ Object.defineProperty(globalThis, Symbol.for(symbolFor), {
22
+ configurable: true,
23
+ get() {
24
+ return fn;
25
+ },
26
+ });
27
+ }
28
+ };
29
+ export let import_meta_ponyfill_commonjs = (Reflect.get(globalThis, Symbol.for("import-meta-ponyfill-commonjs")) ??
30
+ (() => {
31
+ const moduleImportMetaWM = new WeakMap();
32
+ return (require, module) => {
33
+ let importMetaCache = moduleImportMetaWM.get(module);
34
+ if (importMetaCache == null) {
35
+ const importMeta = Object.assign(Object.create(null), {
36
+ url: pathToFileURL(module.filename).href,
37
+ main: require.main == module,
38
+ resolve: (specifier, parentURL = importMeta.url) => {
39
+ return pathToFileURL((importMeta.url === parentURL
40
+ ? require
41
+ : createRequire(parentURL))
42
+ .resolve(specifier)).href;
43
+ },
44
+ filename: module.filename,
45
+ dirname: module.path,
46
+ });
47
+ moduleImportMetaWM.set(module, importMeta);
48
+ importMetaCache = importMeta;
49
+ }
50
+ return importMetaCache;
51
+ };
52
+ })());
53
+ defineGlobalPonyfill("import-meta-ponyfill-commonjs", import_meta_ponyfill_commonjs);
54
+ export let import_meta_ponyfill_esmodule = (Reflect.get(globalThis, Symbol.for("import-meta-ponyfill-esmodule")) ??
55
+ ((importMeta) => {
56
+ const resolveFunStr = String(importMeta.resolve);
57
+ const shimWs = new WeakSet();
58
+ //@ts-ignore
59
+ const mainUrl = ("file:///" + process.argv[1].replace(/\\/g, "/"))
60
+ .replace(/\/{3,}/, "///");
61
+ const commonShim = (importMeta) => {
62
+ if (typeof importMeta.main !== "boolean") {
63
+ importMeta.main = importMeta.url === mainUrl;
64
+ }
65
+ if (typeof importMeta.filename !== "string") {
66
+ importMeta.filename = fileURLToPath(importMeta.url);
67
+ importMeta.dirname = dirname(importMeta.filename);
68
+ }
69
+ };
70
+ if (
71
+ // v16.2.0+, v14.18.0+: Add support for WHATWG URL object to parentURL parameter.
72
+ resolveFunStr === "undefined" ||
73
+ // v20.0.0+, v18.19.0+"" This API now returns a string synchronously instead of a Promise.
74
+ resolveFunStr.startsWith("async")
75
+ // enable by --experimental-import-meta-resolve flag
76
+ ) {
77
+ import_meta_ponyfill_esmodule = (importMeta) => {
78
+ if (!shimWs.has(importMeta)) {
79
+ shimWs.add(importMeta);
80
+ const importMetaUrlRequire = {
81
+ url: importMeta.url,
82
+ require: createRequire(importMeta.url),
83
+ };
84
+ // note: the parameter types must be explicitly annotated because
85
+ // `@types/node` also declares `ImportMeta.resolve`, which makes
86
+ // the contextual type an overload set that provides no inference
87
+ importMeta.resolve = function resolve(specifier, parentURL = importMeta.url) {
88
+ return pathToFileURL((importMetaUrlRequire.url === parentURL
89
+ ? importMetaUrlRequire.require
90
+ : createRequire(parentURL)).resolve(specifier)).href;
91
+ };
92
+ commonShim(importMeta);
93
+ }
94
+ return importMeta;
95
+ };
96
+ }
97
+ else {
98
+ /// native support
99
+ import_meta_ponyfill_esmodule = (importMeta) => {
100
+ if (!shimWs.has(importMeta)) {
101
+ shimWs.add(importMeta);
102
+ commonShim(importMeta);
103
+ }
104
+ return importMeta;
105
+ };
106
+ }
107
+ return import_meta_ponyfill_esmodule(importMeta);
108
+ }));
109
+ defineGlobalPonyfill("import-meta-ponyfill-esmodule", import_meta_ponyfill_esmodule);
110
+ export let import_meta_ponyfill = ((...args) => {
111
+ const _MODULE = (() => {
112
+ if (typeof require === "function" && typeof module === "object") {
113
+ return "commonjs";
114
+ }
115
+ else {
116
+ // eval("typeof import.meta");
117
+ return "esmodule";
118
+ }
119
+ })();
120
+ if (_MODULE === "commonjs") {
121
+ //@ts-ignore
122
+ import_meta_ponyfill = (r, m) => import_meta_ponyfill_commonjs(r, m);
123
+ }
124
+ else {
125
+ //@ts-ignore
126
+ import_meta_ponyfill = (im) => import_meta_ponyfill_esmodule(im);
127
+ }
128
+ //@ts-ignore
129
+ return import_meta_ponyfill(...args);
130
+ });
131
+ // https://github.com/tc39/proposal-accessible-object-hasownproperty/blob/main/polyfill.js
132
+ if (!Object.hasOwn) {
133
+ Object.defineProperty(Object, "hasOwn", {
134
+ value: function (object, property) {
135
+ if (object == null) {
136
+ throw new TypeError("Cannot convert undefined or null to object");
137
+ }
138
+ return Object.prototype.hasOwnProperty.call(Object(object), property);
139
+ },
140
+ configurable: true,
141
+ enumerable: false,
142
+ writable: true,
143
+ });
144
+ }
@@ -0,0 +1,61 @@
1
+ import { Deno } from "@deno/shim-deno";
2
+ export { Deno } from "@deno/shim-deno";
3
+ const dntGlobals = {
4
+ Deno,
5
+ };
6
+ export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
7
+ function createMergeProxy(baseObj, extObj) {
8
+ return new Proxy(baseObj, {
9
+ get(_target, prop, _receiver) {
10
+ if (prop in extObj) {
11
+ return extObj[prop];
12
+ }
13
+ else {
14
+ return baseObj[prop];
15
+ }
16
+ },
17
+ set(_target, prop, value) {
18
+ if (prop in extObj) {
19
+ delete extObj[prop];
20
+ }
21
+ baseObj[prop] = value;
22
+ return true;
23
+ },
24
+ deleteProperty(_target, prop) {
25
+ let success = false;
26
+ if (prop in extObj) {
27
+ delete extObj[prop];
28
+ success = true;
29
+ }
30
+ if (prop in baseObj) {
31
+ delete baseObj[prop];
32
+ success = true;
33
+ }
34
+ return success;
35
+ },
36
+ ownKeys(_target) {
37
+ const baseKeys = Reflect.ownKeys(baseObj);
38
+ const extKeys = Reflect.ownKeys(extObj);
39
+ const extKeysSet = new Set(extKeys);
40
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
41
+ },
42
+ defineProperty(_target, prop, desc) {
43
+ if (prop in extObj) {
44
+ delete extObj[prop];
45
+ }
46
+ Reflect.defineProperty(baseObj, prop, desc);
47
+ return true;
48
+ },
49
+ getOwnPropertyDescriptor(_target, prop) {
50
+ if (prop in extObj) {
51
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
52
+ }
53
+ else {
54
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
55
+ }
56
+ },
57
+ has(_target, prop) {
58
+ return prop in extObj || prop in baseObj;
59
+ },
60
+ });
61
+ }
package/esm/cli/hc.js ADDED
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env node
2
+ import "../_dnt.polyfills.js";
3
+ import * as dntShim from "../_dnt.shims.js";
4
+ import { visibleEnvironment } from "../lib/execute/env-visibility.js";
5
+ import { HCEval, make_context } from "../lib/execute/hc-eval.js";
6
+ import { HCLog } from "../lib/execute/hc-log.js";
7
+ import { HCTest } from "../lib/execute/hc-test.js";
8
+ import { parseArgs } from "../deps/jsr.io/@std/cli/1.0.32/parse_args.js";
9
+ import { runfile } from "./runfile.js";
10
+ import { Prompt } from "./prompt.js";
11
+ import { DenoFileStore } from "./resource-store.js";
12
+ import { CLOCK_SCHEME, ClockHandler, Frame, FrameResource, RealClock, RESOURCE_ROOT_KEY, ResourceHandlers, } from "../lib/frames.js";
13
+ /**
14
+ * @module hc
15
+ *
16
+ * This is the main entry point for the hc command-line interface (CLI).
17
+ */
18
+ /**
19
+ * aliases to short form of command-line interface (CLI) options.
20
+ */
21
+ const aliases = {
22
+ e: "evaluate",
23
+ h: "help",
24
+ i: "interactive",
25
+ t: "testdoc",
26
+ v: "verbose",
27
+ V: "version",
28
+ };
29
+ /**
30
+ * Parses command-line arguments and returns the options.
31
+ *
32
+ * @param args - The array of command-line arguments (only).
33
+ * @returns The parsed options object.
34
+ */
35
+ export function getOptions(args) {
36
+ return parseArgs(args, {
37
+ alias: aliases,
38
+ boolean: ["help", "interactive", "testdoc", "verbose", "version"],
39
+ string: ["evaluate"],
40
+ });
41
+ }
42
+ /**
43
+ * Creates and returns an instance of `HCEval` initialized with the provided environment variables.
44
+ *
45
+ * The host namespace also carries this harness's root binding, so a resource
46
+ * identifier resolves against a fresh temp directory rather than against the
47
+ * working directory. That is a narrowing: the process still holds whatever the
48
+ * harness granted it, and the root binding is the ceiling the language enforces
49
+ * inside it.
50
+ *
51
+ * @param env - An object containing key-value pairs of environment variables.
52
+ * @param out - Optional output sink. Tests inject a capture frame; the CLI uses HCLog.
53
+ * @returns An instance of `HCEval` configured with the provided environment variables.
54
+ */
55
+ export function getEval(env, out) {
56
+ const context = make_context(env);
57
+ const output = out ?? new HCLog(context);
58
+ return new HCEval(output, new Frame(), getHost(context));
59
+ }
60
+ /**
61
+ * Builds this harness's host namespace, root binding included.
62
+ *
63
+ * Exported so a test can run a source unit under the authority the CLI actually
64
+ * grants, rather than under an empty namespace that would make the resource
65
+ * primitive invisible.
66
+ *
67
+ * @param context - Host bindings, which are copied rather than adopted.
68
+ * @returns A frame reachable from HC source through `$$`.
69
+ */
70
+ export function getHost(context = {}) {
71
+ // Copied, because a Frame adopts the Context object it is handed and the
72
+ // logger holds the same one: the root binding belongs to the host namespace
73
+ // and nowhere else.
74
+ const host = new Frame({ ...context });
75
+ host.set(RESOURCE_ROOT_KEY, FrameResource.root(new DenoFileStore(), getHandlers()));
76
+ return host;
77
+ }
78
+ /**
79
+ * This harness's scheme table.
80
+ *
81
+ * One entry, and the emptiness of every other slot is the point: `'https://…'`
82
+ * refuses because nothing is bound to `https`, not because a rule forbids it.
83
+ * The CLI installs the real clock, which is the only thing this harness can
84
+ * honestly implement that the root binding does not already cover.
85
+ *
86
+ * Exported so a test can run under the table the CLI actually grants.
87
+ *
88
+ * @returns The scheme handlers reachable from a CLI evaluation.
89
+ */
90
+ export function getHandlers() {
91
+ return ResourceHandlers.of({
92
+ [CLOCK_SCHEME]: new ClockHandler(new RealClock()),
93
+ });
94
+ }
95
+ /**
96
+ * The main function for the CLI application.
97
+ *
98
+ * @param hc_eval - An instance of HCEval.
99
+ * @param options - The options object returned by the getOptions function.
100
+ *
101
+ * The function performs the following tasks:
102
+ * - Logs the options if the verbose flag is set.
103
+ * - Creates a context and output logger.
104
+ * - Initializes the HCEval instance.
105
+ * - If the testdoc option is set, initializes the HCTest instance and updates the HCEval instance.
106
+ * - If the evaluate option is set, evaluates the provided code.
107
+ * - Iterates over the files provided in the options and runs each file.
108
+ * - If the interactive option is set or no evaluation has been performed, starts the REPL.
109
+ */
110
+ export async function main(hcEval, options) {
111
+ let evaluated = false;
112
+ let sourceStarted = false;
113
+ let lexicalComplete = true;
114
+ let test;
115
+ if (options.verbose) {
116
+ console.error("options", options);
117
+ }
118
+ if (options.testdoc) {
119
+ test = new HCTest(hcEval.out);
120
+ hcEval = hcEval.withOutput(test);
121
+ evaluated = true;
122
+ }
123
+ const finishSource = (evaluator) => {
124
+ const complete = evaluator.finish();
125
+ if (!complete) {
126
+ const reason = evaluator.error() ?? "incomplete lexical input";
127
+ console.error(`HCEval.finish.failed: ${reason}`);
128
+ }
129
+ return complete;
130
+ };
131
+ if (options.evaluate) {
132
+ sourceStarted = true;
133
+ hcEval.call(options.evaluate.toString());
134
+ evaluated = true;
135
+ lexicalComplete = finishSource(hcEval);
136
+ }
137
+ for (const file of options._) {
138
+ if (!lexicalComplete)
139
+ break;
140
+ if (typeof file !== "string") {
141
+ console.error("Invalid file argument", file);
142
+ continue;
143
+ }
144
+ if (sourceStarted)
145
+ hcEval = hcEval.nextSourceUnit();
146
+ sourceStarted = true;
147
+ evaluated = await runfile(hcEval, file);
148
+ lexicalComplete = finishSource(hcEval);
149
+ }
150
+ if (lexicalComplete && (options.interactive || !evaluated)) {
151
+ if (sourceStarted)
152
+ hcEval = hcEval.nextSourceUnit();
153
+ sourceStarted = true;
154
+ if (hcEval.out instanceof HCLog)
155
+ hcEval.out.prompt = true;
156
+ await new Prompt(hcEval).repl();
157
+ lexicalComplete = finishSource(hcEval);
158
+ }
159
+ if (!sourceStarted) {
160
+ lexicalComplete = finishSource(hcEval);
161
+ }
162
+ if (test && lexicalComplete) {
163
+ test.finish();
164
+ }
165
+ return lexicalComplete ? test?.exitCode ?? 0 : 1;
166
+ }
167
+ if (globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).main) {
168
+ // One name at a time, through the dictionary. A wholesale read would hand the
169
+ // whole process environment to `$$` again, and the flags this harness runs
170
+ // under are a derived artifact rather than the bound.
171
+ const env = visibleEnvironment((name) => dntShim.Deno.env.get(name));
172
+ const options = getOptions(dntShim.Deno.args);
173
+ const hc_eval = getEval(env);
174
+ main(hc_eval, options).then((exitCode) => {
175
+ dntShim.Deno.exit(exitCode);
176
+ }).catch((err) => {
177
+ console.error(err);
178
+ dntShim.Deno.exit(1);
179
+ });
180
+ }