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 CHANGED
@@ -16308,14 +16308,22 @@ function describe(token) {
16308
16308
  }
16309
16309
  //#endregion
16310
16310
  //#region ../src/join.ts
16311
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
16312
- const DEFAULT_LIB_PATH = path.resolve(__dirname, "../../core/src");
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") : DEFAULT_LIB_PATH;
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(a + b)}!\\n")
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 = path.join(path.dirname(resolved), "build");
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("✗")} ${C.bold(f.test)} ${C.dim(">")} ${f.message}`);
25577
- for (const b of result.benches) console.log(` ${C.cyan("⏱")} ${C.bold(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))}`);
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.fails ? 1 : 0), 0);
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 = path.join(build_root ?? path.dirname(filename), "build");
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nomen-lang",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "The CLI for the Nomen programming language.",
5
5
  "keywords": [],
6
6
  "license": "ISC",
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
- const buildDir = path.join(build_root ?? path.dirname(filename), "build");
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
@@ -26,7 +26,7 @@ const MAIN_NM = `import System
26
26
  pub func add = (int a, int b) => a + b
27
27
 
28
28
  pub func main = (Init init) {
29
- Console.write("Hello world, 2 + 2 is \\{add(a + b)}!\\n")
29
+ Console.write("Hello world, 2 + 2 is \\{add(2, 2)}!\\n")
30
30
  }
31
31
  `;
32
32
 
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 = path.join(path.dirname(resolved), "build");
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("✗")} ${C.bold(f.test)} ${C.dim(">")} ${f.message}`);
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("⏱")} ${C.bold(b.label)} ${C.dim(`(n=${b.n})`)} ` +
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.fails ? 1 : 0), 0);
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