nomen-lang 0.0.19 → 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/NOMEN_AGENTS.md +57 -12
- package/core/System/Array.nm +11 -11
- package/core/System/Buffer.nm +2 -2
- package/core/System/Channel.nm +146 -12
- package/core/System/ClassBuffer.nm +2 -2
- package/core/System/Console.nm +28 -17
- package/core/System/Controls/Button.nm +96 -8
- package/core/System/Controls/CheckBox.nm +117 -12
- package/core/System/Controls/Container.nm +114 -8
- package/core/System/Controls/Text.nm +98 -8
- package/core/System/Controls/TextBox.nm +120 -10
- package/core/System/Controls/Window.nm +231 -23
- package/core/System/Graph.nm +1 -1
- package/core/System/Init.nm +4 -8
- package/core/System/LinkedList.nm +1 -1
- package/core/System/List.nm +3 -3
- package/core/System/Map.nm +5 -5
- package/core/System/Math.nm +10 -32
- package/core/System/Result.nm +1 -1
- package/core/System/Set.nm +4 -4
- package/core/System/Stream/Directory.nm +189 -63
- package/core/System/Stream/DirectoryError.nm +21 -0
- package/core/System/Stream/File.nm +339 -141
- package/core/System/Stream/FileError.nm +21 -0
- package/core/System/Stream/Http.nm +109 -44
- package/core/System/Stream/HttpError.nm +20 -0
- package/core/System/String.nm +83 -69
- package/core/System/StringBuilder.nm +11 -13
- package/core/System/Task.nm +46 -12
- package/core/System/Test.nm +1 -1
- package/core/System/Text/Json.nm +5 -3
- package/core/System/Text/JsonTree.nm +23 -14
- package/core/System/Text/Regex.nm +124 -64
- package/core/System/Tree.nm +1 -1
- package/core/System/bool.nm +4 -9
- package/core/System/char.nm +3 -9
- package/core/System/float.nm +2 -1
- package/core/System/float32.nm +44 -0
- package/core/System/float64.nm +44 -0
- package/core/System/int.nm +3 -9
- package/core/System/int16.nm +47 -0
- package/core/System/int32.nm +47 -0
- package/core/System/int64.nm +3 -9
- package/core/System/int8.nm +3 -9
- package/core/System/ufloat.nm +44 -0
- package/core/System/ufloat32.nm +44 -0
- package/core/System/ufloat64.nm +44 -0
- package/core/System/uint.nm +3 -9
- package/core/System/uint16.nm +47 -0
- package/core/System/uint32.nm +47 -0
- package/core/System/uint64.nm +3 -9
- package/core/System/uint8.nm +3 -9
- package/core/docs/System/Channel.md +2 -0
- package/core/docs/System/Result.md +5 -1
- package/core/docs/System/Task.md +1 -1
- package/dist/index.mjs +38794 -21299
- package/package.json +38 -34
- package/src/args.ts +11 -0
- package/src/index.ts +21 -3
- package/src/init.ts +1 -1
- package/src/test.ts +48 -4
- package/src/types/Config.ts +2 -0
package/package.json
CHANGED
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
2
|
+
"name": "nomen-lang",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "The CLI for the Nomen programming language.",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"license": "ISC",
|
|
7
|
+
"author": "",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/andrewjk/nomen",
|
|
11
|
+
"directory": "cli"
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"nomen": "dist/index.mjs"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src",
|
|
19
|
+
"core",
|
|
20
|
+
"NOMEN_AGENTS.md"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^26.2.0",
|
|
25
|
+
"chokidar": "^5.0.0",
|
|
26
|
+
"tsx": "^4.23.12",
|
|
27
|
+
"typescript": "^7.0.2",
|
|
28
|
+
"vite-plus": "0.2.9"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "node scripts/bundle-assets.mjs && vp pack",
|
|
32
|
+
"dev": "node scripts/bundle-assets.mjs && vp pack --watch",
|
|
33
|
+
"test": "vp test",
|
|
34
|
+
"check": "vp check",
|
|
35
|
+
"format": "vp check --fix",
|
|
36
|
+
"go": "tsx src/index.ts",
|
|
37
|
+
"register": "pnpm build && pnpm add -g ."
|
|
38
|
+
}
|
|
39
|
+
}
|
package/src/args.ts
CHANGED
|
@@ -12,6 +12,10 @@ export interface Args {
|
|
|
12
12
|
audit: boolean;
|
|
13
13
|
audit_runtime?: string;
|
|
14
14
|
check: boolean;
|
|
15
|
+
release: boolean;
|
|
16
|
+
/** Opt in to FP reassociation: float reductions vectorize under NEON
|
|
17
|
+
* (results may differ in the last ulp vs the scalar loop). */
|
|
18
|
+
fast_math: boolean;
|
|
15
19
|
// Everything after a bare `--` on the command line — forwarded verbatim to
|
|
16
20
|
// the compiled program by `nomen run`. Lets a program receive its own argv
|
|
17
21
|
// (`nomen run --in app/main.nm -- arg1 arg2`).
|
|
@@ -42,6 +46,9 @@ const BOOLEAN_OPTIONS: Map<string, string> = new Map([
|
|
|
42
46
|
["w", "watch"],
|
|
43
47
|
["audit", "audit"],
|
|
44
48
|
["check", "check"],
|
|
49
|
+
["release", "release"],
|
|
50
|
+
["r", "release"],
|
|
51
|
+
["fast-math", "fast_math"],
|
|
45
52
|
]);
|
|
46
53
|
|
|
47
54
|
const DEFAULTS: Partial<Args> = {
|
|
@@ -49,6 +56,8 @@ const DEFAULTS: Partial<Args> = {
|
|
|
49
56
|
watch: false,
|
|
50
57
|
audit: false,
|
|
51
58
|
check: false,
|
|
59
|
+
release: false,
|
|
60
|
+
fast_math: false,
|
|
52
61
|
};
|
|
53
62
|
|
|
54
63
|
function set(args: Args, key: string, value: string | boolean): void {
|
|
@@ -166,6 +175,8 @@ export function print_help(): void {
|
|
|
166
175
|
" --lib, -l <path> Path to System library directory (containing package.jsonc)",
|
|
167
176
|
" --audit Audit the generated program for memory issues",
|
|
168
177
|
" --audit-runtime <path> Path to audit_runtime.c, linked in when --audit is set",
|
|
178
|
+
" --release, -r Build with optimizations (clang -O2; asm passes on aarch64)",
|
|
179
|
+
" --fast-math Allow FP reassociation (float loop reductions vectorize on aarch64)",
|
|
169
180
|
" --check For `nomen format`: report files that would change",
|
|
170
181
|
" -h, --help Show this help",
|
|
171
182
|
].join("\n"),
|
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, {
|
|
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
|
|
|
@@ -163,6 +168,8 @@ try {
|
|
|
163
168
|
if (args.lib) config.lib = args.lib;
|
|
164
169
|
if (args.audit) config.audit = args.audit;
|
|
165
170
|
if (args.audit_runtime) config.audit_runtime = args.audit_runtime;
|
|
171
|
+
if (args.release) config.release = args.release;
|
|
172
|
+
if (args.fast_math) config.fast_math = args.fast_math;
|
|
166
173
|
|
|
167
174
|
// Is the --in path a folder
|
|
168
175
|
if (fs.lstatSync(args.in).isDirectory()) {
|
|
@@ -349,7 +356,13 @@ function processFile(filename: string, config: Config, mode: Mode, program_args:
|
|
|
349
356
|
return;
|
|
350
357
|
}
|
|
351
358
|
|
|
352
|
-
const result = build(parsed.root, {
|
|
359
|
+
const result = build(parsed.root, {
|
|
360
|
+
arch,
|
|
361
|
+
platform,
|
|
362
|
+
audit: config.audit,
|
|
363
|
+
optimize: config.release,
|
|
364
|
+
fast_math: config.fast_math,
|
|
365
|
+
});
|
|
353
366
|
|
|
354
367
|
if (result.errors && result.errors.length > 0) {
|
|
355
368
|
console.log(render_errors(input, result.errors));
|
|
@@ -391,7 +404,12 @@ function processFile(filename: string, config: Config, mode: Mode, program_args:
|
|
|
391
404
|
platform === "macos" || platform === "ios"
|
|
392
405
|
? " -framework CoreGraphics -framework Foundation -framework AppKit -lobjc"
|
|
393
406
|
: "";
|
|
394
|
-
|
|
407
|
+
// Release mode compiles the C (and aarch64 companion C) with -O2,
|
|
408
|
+
// matching the optimized builds other toolchains produce by default.
|
|
409
|
+
// The aarch64 .s itself is assembled verbatim — its optimizations are
|
|
410
|
+
// the codegen passes enabled via `optimize` above.
|
|
411
|
+
const opt_flags = config.release ? " -O2" : "";
|
|
412
|
+
execSync(`clang${opt_flags} -o ${outfile} ${link_inputs}${framework_flags}`);
|
|
395
413
|
|
|
396
414
|
if (mode === "build") {
|
|
397
415
|
const buildTime = performance.now();
|
package/src/init.ts
CHANGED
package/src/test.ts
CHANGED
|
@@ -183,7 +183,7 @@ export function generate_harness(tests: TestFunction[], benches: BenchFunction[]
|
|
|
183
183
|
})
|
|
184
184
|
.join("\n");
|
|
185
185
|
|
|
186
|
-
let main = "\nimport System\nimport System
|
|
186
|
+
let main = "\nimport System\nimport System::Test\n\npub func main = () {\n";
|
|
187
187
|
main += "\tvar Tester t = Tester()\n";
|
|
188
188
|
for (const test of tests) {
|
|
189
189
|
main += `\tt.begin_test("${escape_nm_string(test.name)}")\n`;
|
|
@@ -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, {
|
|
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",
|
|
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
|
}
|