nomen-lang 0.2.0 → 0.2.1

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
@@ -24379,13 +24379,17 @@ function emit_struct_address(node, status) {
24379
24379
  /**
24380
24380
  * Whether an argument expression is a fat string VALUE: either its static
24381
24381
  * type names `string`, or it is a string literal (whose ValueNode.type may
24382
- * be unset). Literals ride the pair ABI like any string.
24382
+ * be unset). Literals ride the pair ABI like any string. A `view string`
24383
+ * counts too — it IS the same (ptr, len) pair at runtime, so a view
24384
+ * argument to a non-view `string` param (e.g. a `.slice` receiver) must
24385
+ * occupy two slots just like an owned string. (`view` DECLARED params are
24386
+ * unaffected: the view_arg_set check runs first.)
24383
24387
  */
24384
24388
  function arg_is_string$1(node) {
24385
24389
  const v = node;
24386
24390
  if (node.node_type === "value" && typeof v.value === "string" && v.value.startsWith("\"")) return true;
24387
24391
  const t = type_from_value_node$1(node);
24388
- return t?.name === "string" && !t.is_view && !t.is_array;
24392
+ return t?.name === "string" && !t.is_array;
24389
24393
  }
24390
24394
  function build_function_call_node$1(node, status) {
24391
24395
  if (node.is_enum_shorthand && node.params.length > 0) {
@@ -29176,13 +29180,14 @@ function build_access_field(node, status) {
29176
29180
  /**
29177
29181
  * Whether an argument expression is a fat string VALUE: either its static
29178
29182
  * type names `string`, or it is a string literal (whose ValueNode.type may
29179
- * be unset). Literals ride the pair ABI like any string.
29183
+ * be unset). Literals ride the pair ABI like any string. A `view string`
29184
+ * counts too — same pair ABI (see build_function_call_node).
29180
29185
  */
29181
29186
  function arg_is_string(node) {
29182
29187
  const v = node;
29183
29188
  if (node.node_type === "value" && typeof v.value === "string" && v.value.startsWith("\"")) return true;
29184
29189
  const t = type_from_value_node$1(node);
29185
- return t?.name === "string" && !t.is_view && !t.is_array;
29190
+ return t?.name === "string" && !t.is_array;
29186
29191
  }
29187
29192
  function build_access_method(node, access_func, status) {
29188
29193
  let target_type = type_from_value_node$1(node.target);
@@ -29742,7 +29747,7 @@ function build_access_method(node, access_func, status) {
29742
29747
  status.stack_offsets.set(temp_addr, temp_offset);
29743
29748
  status.code += `add x8, x29, #${temp_offset}\n`;
29744
29749
  }
29745
- const receiver_is_string = !access_func.is_static && target_type?.name === "string" && !target_type.is_view && !target_type.is_array && !method_self_is_ref;
29750
+ const receiver_is_string = !access_func.is_static && target_type?.name === "string" && !target_type.is_array && !method_self_is_ref;
29746
29751
  let frees_string_receiver = false;
29747
29752
  if (receiver_is_string) {
29748
29753
  status.last_result_is_heap = false;
@@ -32535,8 +32540,9 @@ function build_struct_functions(node, status, skip_init = false) {
32535
32540
  } else if (return_type.startsWith("Array_")) status.code += `void* ${emit_label}(`;
32536
32541
  else if (func.return_type.is_view) status.code += `nomen_view ${emit_label}(`;
32537
32542
  else {
32538
- const return_struct = status.structs.find((s) => s.name === return_type && !s.is_simple_type);
32539
- const return_trait = status.traits.find((t) => t.name === return_type);
32543
+ const mono_return_type = mono_type_name(func.return_type);
32544
+ const return_struct = status.structs.find((s) => s.name === mono_return_type && !s.is_simple_type);
32545
+ const return_trait = status.traits.find((t) => t.name === mono_return_type);
32540
32546
  if (return_struct && !return_struct.is_class) {
32541
32547
  const swap = status.code;
32542
32548
  status.code = status.headers;
@@ -32544,7 +32550,7 @@ function build_struct_functions(node, status, skip_init = false) {
32544
32550
  status.headers = status.code;
32545
32551
  status.code = swap;
32546
32552
  }
32547
- if (return_struct || return_trait) status.code += `struct ${return_type}`;
32553
+ if (return_struct || return_trait) status.code += `struct ${mono_return_type}`;
32548
32554
  else status.code += `${c_type(return_type)}`;
32549
32555
  if (return_struct?.is_class || return_trait) status.code += `*`;
32550
32556
  status.code += ` ${emit_label}(`;
@@ -35329,6 +35335,17 @@ function build_access_node(node, status) {
35329
35335
  status.code += `]`;
35330
35336
  return;
35331
35337
  }
35338
+ if (access_func.name === "slice" && target_type.name === "string" && access_func.params.length === 2) {
35339
+ const tmp = `_vsl_${status.label_counter = (status.label_counter ?? 0) + 1}`;
35340
+ status.code += `({ nomen_view ${tmp} = `;
35341
+ build_node(node.target, status);
35342
+ status.code += `; long _s = `;
35343
+ build_node(access_func.params[0], status);
35344
+ status.code += `; nomen_view _r; _r.ptr = (void*)((char*)${tmp}.ptr + _s); _r.len = (long)(`;
35345
+ build_node(access_func.params[1], status);
35346
+ status.code += ` - _s); _r; })`;
35347
+ return;
35348
+ }
35332
35349
  if (access_func.name === "to_string" && target_type.name === "string") {
35333
35350
  const tmp = `_vts_${status.label_counter = (status.label_counter ?? 0) + 1}`;
35334
35351
  status.code += `({ nomen_view ${tmp} = `;
@@ -40363,7 +40380,7 @@ function evaluate_operation(op, status) {
40363
40380
  const right_base_name = right_str.split(".")[0];
40364
40381
  const rdecl = status.values.findLast((v) => v.name === right_base_name);
40365
40382
  const ra = rdecl?.alias_of ? parse_offset_expr(rdecl.alias_of) : void 0;
40366
- const right_base = ra ? ra.base : right_str;
40383
+ const right_base = ra && !(right_str === ra.base || ra.offset === 0 && right_str.startsWith(ra.base + ".")) ? ra.base : right_str;
40367
40384
  const right_off = ra ? ra.offset : 0;
40368
40385
  if (left_base === right_base) {
40369
40386
  const d = left_off - right_off;
@@ -43981,12 +43998,24 @@ function check_function_call(node, status, func, target_type, self_value, self_p
43981
43998
  });
43982
43999
  if (self_value && self_value !== "?") {
43983
44000
  const self_type = target_type || func.params[0]?.type;
44001
+ const self_path_or_value = self_path ?? self_value;
44002
+ const self_base = status.values.findLast((v) => v.name === self_path_or_value.split(".")[0]);
43984
44003
  status.values.push({
43985
44004
  declaration: "const",
43986
44005
  name: "self",
43987
44006
  type: self_type,
43988
44007
  is_set: true,
43989
- alias_of: self_path ?? self_value
44008
+ alias_of: self_path_or_value,
44009
+ range_lower: self_base?.range_lower,
44010
+ range_upper: self_base?.range_upper,
44011
+ upper_bound_exprs: self_base?.upper_bound_exprs?.slice(),
44012
+ lower_bound_exprs: self_base?.lower_bound_exprs?.slice(),
44013
+ upper_bound_inclusive_exprs: self_base?.upper_bound_inclusive_exprs?.slice(),
44014
+ lower_bound_inclusive_exprs: self_base?.lower_bound_inclusive_exprs?.slice(),
44015
+ upper_bound_expr: self_base?.upper_bound_expr,
44016
+ lower_bound_expr: self_base?.lower_bound_expr,
44017
+ known_length: self_base?.known_length,
44018
+ path_bounds: self_base?.path_bounds
43990
44019
  });
43991
44020
  }
43992
44021
  const satisfied = evaluate_const_condition(func_param.constraint, status);
@@ -49276,6 +49305,14 @@ function project_root_for(input_path) {
49276
49305
  function build_dir_for(input_path, is_test) {
49277
49306
  return is_test ? path.join(project_root_for(input_path), "build", "test") : path.join(project_root_for(input_path), "build");
49278
49307
  }
49308
+ /**
49309
+ * The linked binary path for `input_path`: an explicit `--out` wins,
49310
+ * otherwise `<build dir>/<entry basename>`.
49311
+ */
49312
+ function outfile_for(input_path, is_test, out) {
49313
+ if (out) return path.resolve(out);
49314
+ return path.join(build_dir_for(input_path, is_test), path.basename(input_path, ".nm"));
49315
+ }
49279
49316
  //#endregion
49280
49317
  //#region src/test.ts
49281
49318
  const RECORD_PREFIX = "\\nomen|";
@@ -49746,6 +49783,7 @@ try {
49746
49783
  if (args.audit_runtime) config.audit_runtime = args.audit_runtime;
49747
49784
  if (args.release) config.release = args.release;
49748
49785
  if (args.fast_math) config.fast_math = args.fast_math;
49786
+ if (args.out) config.out = args.out;
49749
49787
  if (fs.lstatSync(args.in).isDirectory()) {
49750
49788
  if (args.watch) watchPath(args.in, config, mode, args.program_args);
49751
49789
  else processFolder(args.in, config, mode, args.program_args);
@@ -49872,7 +49910,8 @@ function processFile(filename, config, mode, program_args) {
49872
49910
  const ext = arch === "aarch64" ? ".s" : platform === "macos" || platform === "ios" ? ".m" : ".c";
49873
49911
  const headerfile = path.join(buildDir, "main.h");
49874
49912
  const codefile = path.join(buildDir, basename + ext);
49875
- const outfile = path.join(buildDir, basename);
49913
+ const outfile = outfile_for(resolved_path, filename.endsWith(".test.nm"), config.out);
49914
+ if (!fs.existsSync(path.dirname(outfile))) fs.mkdirSync(path.dirname(outfile), { recursive: true });
49876
49915
  fs.writeFileSync(headerfile, result.headers);
49877
49916
  fs.writeFileSync(codefile, result.code);
49878
49917
  let companionfile;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nomen-lang",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "The CLI for the Nomen programming language.",
5
5
  "keywords": [],
6
6
  "license": "ISC",
package/src/index.ts CHANGED
@@ -14,7 +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
+ import { build_dir_for, outfile_for } from "./paths.ts";
18
18
  import { runTests } from "./test.ts";
19
19
  import type Config from "./types/Config.ts";
20
20
 
@@ -170,6 +170,7 @@ try {
170
170
  if (args.audit_runtime) config.audit_runtime = args.audit_runtime;
171
171
  if (args.release) config.release = args.release;
172
172
  if (args.fast_math) config.fast_math = args.fast_math;
173
+ if (args.out) config.out = args.out;
173
174
 
174
175
  // Is the --in path a folder
175
176
  if (fs.lstatSync(args.in).isDirectory()) {
@@ -370,7 +371,8 @@ function processFile(filename: string, config: Config, mode: Mode, program_args:
370
371
  }
371
372
 
372
373
  const basename = path.basename(filename, ".nm");
373
- // Output lives in the project's `build/` — `build/test` for *.test.nm.
374
+ // Output lives in the project's `build/` — `build/test` for *.test.nm
375
+ // unless an explicit --out names the linked binary.
374
376
  const buildDir = build_dir_for(resolved_path, filename.endsWith(".test.nm"));
375
377
  if (!fs.existsSync(buildDir)) {
376
378
  fs.mkdirSync(buildDir, { recursive: true });
@@ -378,7 +380,10 @@ function processFile(filename: string, config: Config, mode: Mode, program_args:
378
380
  const ext = arch === "aarch64" ? ".s" : platform === "macos" || platform === "ios" ? ".m" : ".c";
379
381
  const headerfile = path.join(buildDir, "main.h");
380
382
  const codefile = path.join(buildDir, basename + ext);
381
- const outfile = path.join(buildDir, basename);
383
+ const outfile = outfile_for(resolved_path, filename.endsWith(".test.nm"), config.out);
384
+ if (!fs.existsSync(path.dirname(outfile))) {
385
+ fs.mkdirSync(path.dirname(outfile), { recursive: true });
386
+ }
382
387
  fs.writeFileSync(headerfile, result.headers);
383
388
  fs.writeFileSync(codefile, result.code);
384
389
 
package/src/paths.ts CHANGED
@@ -26,3 +26,12 @@ export function build_dir_for(input_path: string, is_test: boolean): string {
26
26
  ? path.join(project_root_for(input_path), "build", "test")
27
27
  : path.join(project_root_for(input_path), "build");
28
28
  }
29
+
30
+ /**
31
+ * The linked binary path for `input_path`: an explicit `--out` wins,
32
+ * otherwise `<build dir>/<entry basename>`.
33
+ */
34
+ export function outfile_for(input_path: string, is_test: boolean, out?: string): string {
35
+ if (out) return path.resolve(out);
36
+ return path.join(build_dir_for(input_path, is_test), path.basename(input_path, ".nm"));
37
+ }
@@ -6,4 +6,5 @@ export default interface Config {
6
6
  audit_runtime?: string;
7
7
  release?: boolean;
8
8
  fast_math?: boolean;
9
+ out?: string;
9
10
  }