nomen-lang 0.0.9 → 0.0.10
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/dist/index.mjs +43 -19
- package/package.json +1 -1
- package/src/index.ts +3 -13
- package/src/init.ts +1 -1
- package/src/paths.ts +28 -0
- package/src/test.ts +5 -4
package/dist/index.mjs
CHANGED
|
@@ -16308,14 +16308,22 @@ function describe(token) {
|
|
|
16308
16308
|
}
|
|
16309
16309
|
//#endregion
|
|
16310
16310
|
//#region ../src/join.ts
|
|
16311
|
-
const
|
|
16312
|
-
|
|
16311
|
+
const DEFAULT_LIB_REL = "../../core/src";
|
|
16312
|
+
let default_lib_path;
|
|
16313
|
+
function fallback_lib_path() {
|
|
16314
|
+
if (default_lib_path === void 0) try {
|
|
16315
|
+
default_lib_path = path.resolve(path.dirname(fileURLToPath(import.meta.url)), DEFAULT_LIB_REL);
|
|
16316
|
+
} catch {
|
|
16317
|
+
default_lib_path = "";
|
|
16318
|
+
}
|
|
16319
|
+
return default_lib_path;
|
|
16320
|
+
}
|
|
16313
16321
|
let test_src_dir;
|
|
16314
16322
|
function join$1(entry_file_path, lib_path, options) {
|
|
16315
16323
|
const folder_path = path.dirname(entry_file_path);
|
|
16316
16324
|
const file_path = path.basename(entry_file_path);
|
|
16317
16325
|
const inputs = /* @__PURE__ */ new Map();
|
|
16318
|
-
const resolved_lib_path = lib_path ? path.resolve(lib_path, "src") :
|
|
16326
|
+
const resolved_lib_path = lib_path ? path.resolve(lib_path, "src") : fallback_lib_path();
|
|
16319
16327
|
const for_test = options?.for_test ?? file_path.endsWith(".test.nm");
|
|
16320
16328
|
const prev_test_src_dir = test_src_dir;
|
|
16321
16329
|
test_src_dir = for_test ? resolve_src_module(folder_path) : void 0;
|
|
@@ -25223,7 +25231,7 @@ const MAIN_NM = `import System
|
|
|
25223
25231
|
pub func add = (int a, int b) => a + b
|
|
25224
25232
|
|
|
25225
25233
|
pub func main = (Init init) {
|
|
25226
|
-
Console.write("Hello world, 2 + 2 is \\{add(
|
|
25234
|
+
Console.write("Hello world, 2 + 2 is \\{add(2, 2)}!\\n")
|
|
25227
25235
|
}
|
|
25228
25236
|
`;
|
|
25229
25237
|
const TEST_NM = `import System
|
|
@@ -25307,6 +25315,30 @@ function run_init(name) {
|
|
|
25307
25315
|
console.log(`\nNext: cd ${name} && nomen run`);
|
|
25308
25316
|
}
|
|
25309
25317
|
//#endregion
|
|
25318
|
+
//#region src/paths.ts
|
|
25319
|
+
/**
|
|
25320
|
+
* The project root for `input_path`: the nearest ancestor folder (or the input
|
|
25321
|
+
* folder itself) containing a `package.jsonc`. Falls back to the input's own
|
|
25322
|
+
* folder for standalone files, so builds stay next to their source.
|
|
25323
|
+
*/
|
|
25324
|
+
function project_root_for(input_path) {
|
|
25325
|
+
let dir = fs.lstatSync(input_path).isDirectory() ? input_path : path.dirname(input_path);
|
|
25326
|
+
for (let i = 0; i < 20; i++) {
|
|
25327
|
+
if (fs.existsSync(path.join(dir, "package.jsonc"))) return dir;
|
|
25328
|
+
const parent = path.dirname(dir);
|
|
25329
|
+
if (parent === dir) break;
|
|
25330
|
+
dir = parent;
|
|
25331
|
+
}
|
|
25332
|
+
return path.dirname(input_path);
|
|
25333
|
+
}
|
|
25334
|
+
/**
|
|
25335
|
+
* The folder that receives compiler output for `input_path`: the project's
|
|
25336
|
+
* `build/`, or `build/test` for `*.test.nm` files.
|
|
25337
|
+
*/
|
|
25338
|
+
function build_dir_for(input_path, is_test) {
|
|
25339
|
+
return is_test ? path.join(project_root_for(input_path), "build", "test") : path.join(project_root_for(input_path), "build");
|
|
25340
|
+
}
|
|
25341
|
+
//#endregion
|
|
25310
25342
|
//#region src/test.ts
|
|
25311
25343
|
const RECORD_PREFIX = "\\nomen|";
|
|
25312
25344
|
/** Recursively collect `*.test.nm` files under `root`, skipping build output. */
|
|
@@ -25487,7 +25519,7 @@ function run_test_file(entry_path, lib_path, arch) {
|
|
|
25487
25519
|
result.ms = performance.now() - start;
|
|
25488
25520
|
return result;
|
|
25489
25521
|
}
|
|
25490
|
-
const buildDir =
|
|
25522
|
+
const buildDir = build_dir_for(resolved, true);
|
|
25491
25523
|
if (!fs.existsSync(buildDir)) fs.mkdirSync(buildDir, { recursive: true });
|
|
25492
25524
|
const ext = arch === "aarch64" ? ".s" : ".c";
|
|
25493
25525
|
const codefile = path.join(buildDir, path.basename(entry_path, ".nm") + ext);
|
|
@@ -25573,8 +25605,8 @@ function report_file(result) {
|
|
|
25573
25605
|
const mark = result.ok ? C.green("✓") : C.red("✗");
|
|
25574
25606
|
console.log(` ${mark} ${rel} ${C.dim(`(${totalTests} tests)`)} ${C.dim(format_duration(result.ms))}`);
|
|
25575
25607
|
if (result.crashed) console.log(C.red(` ${result.crashed}`));
|
|
25576
|
-
for (const f of result.fails) console.log(` ${C.red("✗")} ${
|
|
25577
|
-
for (const b of result.benches) console.log(` ${C.cyan("⏱")} ${
|
|
25608
|
+
for (const f of result.fails) console.log(` ${C.red("✗")} ${f.test} ${C.dim(">")} ${f.message}`);
|
|
25609
|
+
for (const b of result.benches) console.log(` ${C.cyan("⏱")} ${b.label} ${C.dim(`(n=${b.n})`)} ${C.dim("min")} ${fmt_ns(b.min)} ${C.dim("median")} ${fmt_ns(b.median)} ${C.dim("mean")} ${fmt_ns(Math.round(b.mean))} ${C.dim("max")} ${fmt_ns(b.max)} ${C.dim("±")} ${fmt_ns(Math.round(b.stddev))}`);
|
|
25578
25610
|
if (result.other.length) {
|
|
25579
25611
|
console.log(C.dim(" --- test stdout ---"));
|
|
25580
25612
|
for (const line of result.other) console.log(C.dim(` ${line}`));
|
|
@@ -25595,7 +25627,7 @@ function runTests(root, options = {}) {
|
|
|
25595
25627
|
}
|
|
25596
25628
|
const elapsed = performance.now() - startTime;
|
|
25597
25629
|
const totalFiles = results.length;
|
|
25598
|
-
const totalFilesFailed = results.reduce((a, r) => a + (r.
|
|
25630
|
+
const totalFilesFailed = results.reduce((a, r) => a + (r.ok ? 0 : 1), 0);
|
|
25599
25631
|
const totalFilesPassed = totalFiles - totalFilesFailed;
|
|
25600
25632
|
const totalTests = results.reduce((a, r) => a + r.tests.length, 0);
|
|
25601
25633
|
const totalFailed = results.reduce((a, r) => a + r.tests.reduce((x, t) => x + t.failed, 0), 0);
|
|
@@ -25667,7 +25699,6 @@ function collect_nm_files(folder) {
|
|
|
25667
25699
|
}
|
|
25668
25700
|
return out;
|
|
25669
25701
|
}
|
|
25670
|
-
let build_root;
|
|
25671
25702
|
console.error("\n~ NOMEN ~\n");
|
|
25672
25703
|
const args = parse_args();
|
|
25673
25704
|
const command = args.command;
|
|
@@ -25728,7 +25759,6 @@ try {
|
|
|
25728
25759
|
}
|
|
25729
25760
|
args.in = args.in ?? resolve_input();
|
|
25730
25761
|
if (!args.in) process.exit(0);
|
|
25731
|
-
if (!build_root) build_root = fs.lstatSync(args.in).isDirectory() ? args.in : path.dirname(args.in);
|
|
25732
25762
|
if (fs.existsSync(args.in)) {
|
|
25733
25763
|
let config = {
|
|
25734
25764
|
arch: "aarch64",
|
|
@@ -25758,19 +25788,13 @@ function resolve_input() {
|
|
|
25758
25788
|
if (fs.existsSync(config_path)) try {
|
|
25759
25789
|
const json = fs.readFileSync(config_path, "utf8").replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
25760
25790
|
const parsed = JSON.parse(json);
|
|
25761
|
-
if (parsed.entry)
|
|
25762
|
-
build_root = cwd;
|
|
25763
|
-
return path.resolve(cwd, parsed.entry);
|
|
25764
|
-
}
|
|
25791
|
+
if (parsed.entry) return path.resolve(cwd, parsed.entry);
|
|
25765
25792
|
} catch {}
|
|
25766
25793
|
let nm_files = [];
|
|
25767
25794
|
try {
|
|
25768
25795
|
nm_files = fs.readdirSync(cwd).filter((f) => f.endsWith(".nm"));
|
|
25769
25796
|
} catch {}
|
|
25770
|
-
if (nm_files.length === 1)
|
|
25771
|
-
build_root = cwd;
|
|
25772
|
-
return path.resolve(cwd, nm_files[0]);
|
|
25773
|
-
}
|
|
25797
|
+
if (nm_files.length === 1) return path.resolve(cwd, nm_files[0]);
|
|
25774
25798
|
if (nm_files.length > 1) {
|
|
25775
25799
|
console.log(`Found ${nm_files.length} .nm files in ${cwd}. Specify which to run with --in:\n ` + nm_files.join("\n "));
|
|
25776
25800
|
return;
|
|
@@ -25863,7 +25887,7 @@ function processFile(filename, config, mode) {
|
|
|
25863
25887
|
return;
|
|
25864
25888
|
}
|
|
25865
25889
|
const basename = path.basename(filename, ".nm");
|
|
25866
|
-
const buildDir =
|
|
25890
|
+
const buildDir = build_dir_for(resolved_path, filename.endsWith(".test.nm"));
|
|
25867
25891
|
if (!fs.existsSync(buildDir)) fs.mkdirSync(buildDir, { recursive: true });
|
|
25868
25892
|
const ext = arch === "aarch64" ? ".s" : platform === "macos" || platform === "ios" ? ".m" : ".c";
|
|
25869
25893
|
const headerfile = path.join(buildDir, "main.h");
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { parse_args, print_help, type Args } from "./args.ts";
|
|
|
14
14
|
import { run_docs } from "./docs.ts";
|
|
15
15
|
import render_errors, { render_warnings } from "./format_errors.ts";
|
|
16
16
|
import { find_bundled, run_init } from "./init.ts";
|
|
17
|
+
import { build_dir_for } from "./paths.ts";
|
|
17
18
|
import { runTests } from "./test.ts";
|
|
18
19
|
import type Config from "./types/Config.ts";
|
|
19
20
|
|
|
@@ -66,11 +67,6 @@ function collect_nm_files(folder: string): string[] {
|
|
|
66
67
|
return out;
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
// The folder whose `build/` subdirectory receives compiler output. Set during
|
|
70
|
-
// input resolution: the --in folder, the .nm file's folder, or — for
|
|
71
|
-
// package.jsonc discovery — the package folder (cwd), not the entry's folder.
|
|
72
|
-
let build_root: string | undefined;
|
|
73
|
-
|
|
74
70
|
console.error("\n~ NOMEN ~\n");
|
|
75
71
|
|
|
76
72
|
const args: Args = parse_args();
|
|
@@ -154,11 +150,6 @@ try {
|
|
|
154
150
|
if (!args.in) {
|
|
155
151
|
process.exit(0);
|
|
156
152
|
}
|
|
157
|
-
// For an explicit --in, build next to whatever was passed (the folder
|
|
158
|
-
// itself, or the file's folder). Discovery cases set build_root themselves.
|
|
159
|
-
if (!build_root) {
|
|
160
|
-
build_root = fs.lstatSync(args.in).isDirectory() ? args.in : path.dirname(args.in);
|
|
161
|
-
}
|
|
162
153
|
|
|
163
154
|
if (fs.existsSync(args.in)) {
|
|
164
155
|
let config: Config = { arch: "aarch64", platform: default_platform() };
|
|
@@ -213,7 +204,6 @@ function resolve_input(): string | undefined {
|
|
|
213
204
|
const json = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
214
205
|
const parsed = JSON.parse(json);
|
|
215
206
|
if (parsed.entry) {
|
|
216
|
-
build_root = cwd;
|
|
217
207
|
return path.resolve(cwd, parsed.entry);
|
|
218
208
|
}
|
|
219
209
|
} catch {
|
|
@@ -229,7 +219,6 @@ function resolve_input(): string | undefined {
|
|
|
229
219
|
// unreadable working folder
|
|
230
220
|
}
|
|
231
221
|
if (nm_files.length === 1) {
|
|
232
|
-
build_root = cwd;
|
|
233
222
|
return path.resolve(cwd, nm_files[0]);
|
|
234
223
|
}
|
|
235
224
|
if (nm_files.length > 1) {
|
|
@@ -368,7 +357,8 @@ function processFile(filename: string, config: Config, mode: Mode) {
|
|
|
368
357
|
}
|
|
369
358
|
|
|
370
359
|
const basename = path.basename(filename, ".nm");
|
|
371
|
-
|
|
360
|
+
// Output lives in the project's `build/` — `build/test` for *.test.nm.
|
|
361
|
+
const buildDir = build_dir_for(resolved_path, filename.endsWith(".test.nm"));
|
|
372
362
|
if (!fs.existsSync(buildDir)) {
|
|
373
363
|
fs.mkdirSync(buildDir, { recursive: true });
|
|
374
364
|
}
|
package/src/init.ts
CHANGED
package/src/paths.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The project root for `input_path`: the nearest ancestor folder (or the input
|
|
6
|
+
* folder itself) containing a `package.jsonc`. Falls back to the input's own
|
|
7
|
+
* folder for standalone files, so builds stay next to their source.
|
|
8
|
+
*/
|
|
9
|
+
export function project_root_for(input_path: string): string {
|
|
10
|
+
let dir = fs.lstatSync(input_path).isDirectory() ? input_path : path.dirname(input_path);
|
|
11
|
+
for (let i = 0; i < 20; i++) {
|
|
12
|
+
if (fs.existsSync(path.join(dir, "package.jsonc"))) return dir;
|
|
13
|
+
const parent = path.dirname(dir);
|
|
14
|
+
if (parent === dir) break;
|
|
15
|
+
dir = parent;
|
|
16
|
+
}
|
|
17
|
+
return path.dirname(input_path);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The folder that receives compiler output for `input_path`: the project's
|
|
22
|
+
* `build/`, or `build/test` for `*.test.nm` files.
|
|
23
|
+
*/
|
|
24
|
+
export function build_dir_for(input_path: string, is_test: boolean): string {
|
|
25
|
+
return is_test
|
|
26
|
+
? path.join(project_root_for(input_path), "build", "test")
|
|
27
|
+
: path.join(project_root_for(input_path), "build");
|
|
28
|
+
}
|
package/src/test.ts
CHANGED
|
@@ -8,6 +8,7 @@ import join from "../../src/join.ts";
|
|
|
8
8
|
import { get_library } from "../../src/lib.ts";
|
|
9
9
|
import parse from "../../src/parse.ts";
|
|
10
10
|
import { find_bundled } from "./init.ts";
|
|
11
|
+
import { build_dir_for } from "./paths.ts";
|
|
11
12
|
|
|
12
13
|
const RECORD_PREFIX = "\\nomen|";
|
|
13
14
|
|
|
@@ -303,7 +304,7 @@ export function run_test_file(
|
|
|
303
304
|
return result;
|
|
304
305
|
}
|
|
305
306
|
|
|
306
|
-
const buildDir =
|
|
307
|
+
const buildDir = build_dir_for(resolved, true);
|
|
307
308
|
if (!fs.existsSync(buildDir)) fs.mkdirSync(buildDir, { recursive: true });
|
|
308
309
|
const ext = arch === "aarch64" ? ".s" : ".c";
|
|
309
310
|
const codefile = path.join(buildDir, path.basename(entry_path, ".nm") + ext);
|
|
@@ -407,11 +408,11 @@ export function report_file(result: TestFileResult): void {
|
|
|
407
408
|
// short-circuiting a test has at most one failure, so the fail lines are
|
|
408
409
|
// the per-test detail and a separate count line would just repeat names.
|
|
409
410
|
for (const f of result.fails) {
|
|
410
|
-
console.log(` ${C.red("✗")} ${
|
|
411
|
+
console.log(` ${C.red("✗")} ${f.test} ${C.dim(">")} ${f.message}`);
|
|
411
412
|
}
|
|
412
413
|
for (const b of result.benches) {
|
|
413
414
|
console.log(
|
|
414
|
-
` ${C.cyan("⏱")} ${
|
|
415
|
+
` ${C.cyan("⏱")} ${b.label} ${C.dim(`(n=${b.n})`)} ` +
|
|
415
416
|
`${C.dim("min")} ${fmt_ns(b.min)} ${C.dim("median")} ${fmt_ns(b.median)} ` +
|
|
416
417
|
`${C.dim("mean")} ${fmt_ns(Math.round(b.mean))} ${C.dim("max")} ${fmt_ns(b.max)} ` +
|
|
417
418
|
`${C.dim("±")} ${fmt_ns(Math.round(b.stddev))}`,
|
|
@@ -447,7 +448,7 @@ export function runTests(root: string, options: RunTestsOptions = {}): boolean {
|
|
|
447
448
|
|
|
448
449
|
const elapsed = performance.now() - startTime;
|
|
449
450
|
const totalFiles = results.length;
|
|
450
|
-
const totalFilesFailed = results.reduce((a, r) => a + (r.
|
|
451
|
+
const totalFilesFailed = results.reduce((a, r) => a + (r.ok ? 0 : 1), 0);
|
|
451
452
|
const totalFilesPassed = totalFiles - totalFilesFailed;
|
|
452
453
|
// `tests[].failed` (from each test's `done` record) is the authoritative
|
|
453
454
|
// failure count; `result.fails` holds the same failures' messages for
|