ERR/E4.1b: #caller_location + Source_Location (+ namespaced default fix, comptime flush)

Finishes Phase E4. `process.exit` / `assert` now report the caller's location.

#caller_location + Source_Location:
- new `hash_caller_location` token (lexer) + a leaf `caller_location` AST node
  (parser primary-expr; sema + lsp arms).
- `Source_Location :: struct { file; line; col; func }` in std.sx.
- expandCallDefaults rewrites a `#caller_location` param default to a marker
  carrying the CALL site's span + source_file.
- lowerCallerLocation synthesizes the struct: file + line:col via
  errors.SourceLoc.compute over the diagnostics file→source map, stamped with
  the enclosing (caller) function name. inferExprType resolves it to
  Source_Location. Explicitly forwarding a Source_Location through an inner
  call preserves the outermost site.

namespaced default-param expansion (pre-existing crash): expandCallDefaults
bailed on field_access callees, so `mod.fn(args)` with an omitted defaulted
param passed too few args → LLVM "incorrect number of arguments". Now resolves
the namespace fd (by field / qualified name); method-on-value calls (where
`self` shifts the count) stay excluded. Prerequisite for process.exit/assert
(always called namespaced) taking `loc = #caller_location`.

comptime flush: interp.callForeign flushes the interpreter's buffered print
output before invoking any host symbol, so a comptime diagnostic emitted just
before a terminating `_exit` (process.exit at comptime) survives.

process.exit/assert take `loc: Source_Location = #caller_location`; assert
prints `ASSERTION FAILED at <file>:<line>: <msg>`. examples 250 (assert
file:line), 251 (caller-location + forwarding). The two ffi-objc *.ir
snapshots are regenerated — adding Source_Location to std.sx renumbers the
global string pool the type/field-name tables index (benign, identical IR).
This commit is contained in:
agra
2026-06-01 12:00:03 +03:00
parent 6f77c55613
commit e04bec488b
17 changed files with 1212 additions and 968 deletions

View File

@@ -1,7 +1,7 @@
// `assert` (ERR step E4.1): a false condition prints `ASSERTION FAILED: <msg>`
// and exits 1; a true condition is a no-op. Built on `process.exit`. (The
// caller's `file:line` in the message rides on `#caller_location` — E4.1b.)
// Expected exit code: 1.
// `assert` (ERR steps E4.1 / E4.1b): a false condition prints `ASSERTION
// FAILED at <file>:<line>: <msg>` (the caller's location, via the
// `#caller_location` default param) and exits 1; a true condition is a no-op.
// Built on `process.exit`. Expected exit code: 1.
#import "modules/std.sx";
proc :: #import "modules/process.sx";

View File

@@ -0,0 +1,22 @@
// `#caller_location` (ERR step E4.1b). As a parameter's default value it
// resolves to a `Source_Location` of the CALL site — file, line:col, and the
// enclosing function — rather than the callee's signature. Explicitly
// forwarding a `Source_Location` through an inner call preserves the outermost
// site (so a logging wrapper reports where IT was called). Expected exit: 0.
#import "modules/std.sx";
note :: (loc: Source_Location = #caller_location) {
print("note from {} (line {})\n", loc.func, loc.line);
}
// Forwards its own caller location through to `note`.
wrap :: (loc: Source_Location = #caller_location) {
note(loc);
}
main :: () -> s32 {
note(); // call site → func main
wrap(); // forwarded → still reports this line in main
return 0;
}