nomen-lang 0.1.0 → 0.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nomen-lang",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "The CLI for the Nomen programming language.",
5
5
  "keywords": [],
6
6
  "license": "ISC",
package/src/index.ts CHANGED
@@ -104,7 +104,12 @@ try {
104
104
  const root = args.in ?? process.cwd();
105
105
  const filter = args.filter ? new RegExp(args.filter) : undefined;
106
106
  const arch = args.arch ?? "aarch64";
107
- const ok = runTests(root, { arch, filter });
107
+ const ok = runTests(root, {
108
+ arch,
109
+ filter,
110
+ audit: args.audit,
111
+ audit_runtime: args.audit_runtime,
112
+ });
108
113
  process.exit(ok ? 0 : 1);
109
114
  }
110
115
 
package/src/test.ts CHANGED
@@ -259,6 +259,8 @@ export function run_test_file(
259
259
  entry_path: string,
260
260
  lib_path: string | undefined,
261
261
  arch: string,
262
+ audit = false,
263
+ audit_runtime?: string,
262
264
  ): TestFileResult {
263
265
  const start = performance.now();
264
266
  const source_text = fs.readFileSync(entry_path, "utf8");
@@ -294,7 +296,10 @@ export function run_test_file(
294
296
  return result;
295
297
  }
296
298
 
297
- const buildResult = build(parsed.root, { arch: arch as "aarch64" | "c", audit: false });
299
+ const buildResult = build(parsed.root, {
300
+ arch: arch as "aarch64" | "c",
301
+ audit,
302
+ });
298
303
  if (buildResult.errors && buildResult.errors.length) {
299
304
  result.ok = false;
300
305
  result.crashed = buildResult.errors
@@ -306,6 +311,24 @@ export function run_test_file(
306
311
 
307
312
  const buildDir = build_dir_for(resolved, true);
308
313
  if (!fs.existsSync(buildDir)) fs.mkdirSync(buildDir, { recursive: true });
314
+ // With --audit, compile the audit runtime (malloc/free counting) and link
315
+ // it in; the generated main calls nomen_audit_check() at exit, printing
316
+ // "LEAK: N allocation(s)" when the balance is nonzero.
317
+ let audit_obj: string | undefined;
318
+ if (audit) {
319
+ const runtime_src = audit_runtime
320
+ ? path.resolve(audit_runtime)
321
+ : find_audit_runtime(path.dirname(resolved));
322
+ if (!runtime_src || !fs.existsSync(runtime_src)) {
323
+ result.ok = false;
324
+ result.crashed =
325
+ "Audit enabled but audit_runtime.c was not found. Pass --audit-runtime <path>.";
326
+ result.ms = performance.now() - start;
327
+ return result;
328
+ }
329
+ audit_obj = path.join(buildDir, "audit_runtime.o");
330
+ execFileSync("clang", ["-c", runtime_src, "-o", audit_obj]);
331
+ }
309
332
  const ext = arch === "aarch64" ? ".s" : ".c";
310
333
  const codefile = path.join(buildDir, path.basename(entry_path, ".nm") + ext);
311
334
  const outfile = path.join(buildDir, path.basename(entry_path, ".nm"));
@@ -316,8 +339,10 @@ export function run_test_file(
316
339
 
317
340
  // Link the harness binary. The harness uses only Console/Time (printf,
318
341
  // clock_gettime), so no platform frameworks are required.
342
+ const link_args = ["-o", outfile, codefile];
343
+ if (audit_obj) link_args.push(audit_obj);
319
344
  try {
320
- execFileSync("clang", ["-o", outfile, codefile], {
345
+ execFileSync("clang", link_args, {
321
346
  encoding: "utf8",
322
347
  stdio: ["ignore", "pipe", "pipe"],
323
348
  });
@@ -427,6 +452,25 @@ export function report_file(result: TestFileResult): void {
427
452
  export interface RunTestsOptions {
428
453
  arch?: string;
429
454
  filter?: RegExp;
455
+ audit?: boolean;
456
+ audit_runtime?: string;
457
+ }
458
+
459
+ /**
460
+ * Locate audit_runtime.c for an audited test build: an explicit path wins,
461
+ * otherwise walk up from `dir` looking for a `src/audit_runtime.c` (the same
462
+ * convention the run/build commands use).
463
+ */
464
+ function find_audit_runtime(dir: string): string | undefined {
465
+ let cur = dir;
466
+ for (let i = 0; i < 20; i++) {
467
+ const candidate = path.join(cur, "src", "audit_runtime.c");
468
+ if (fs.existsSync(candidate)) return candidate;
469
+ const parent = path.dirname(cur);
470
+ if (parent === cur) break;
471
+ cur = parent;
472
+ }
473
+ return undefined;
430
474
  }
431
475
 
432
476
  /** Discover, run, and report every `*.test.nm` under `root`. */
@@ -441,7 +485,7 @@ export function runTests(root: string, options: RunTestsOptions = {}): boolean {
441
485
 
442
486
  const results: TestFileResult[] = [];
443
487
  for (const file of files) {
444
- const result = run_test_file(file, lib, arch);
488
+ const result = run_test_file(file, lib, arch, options.audit, options.audit_runtime);
445
489
  report_file(result);
446
490
  results.push(result);
447
491
  }