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:
@@ -130,25 +130,22 @@ clib_exit :: (code: s32) -> noreturn #foreign libc "_exit";
|
||||
// Stop the process immediately with exit code `code`. Does NOT unwind:
|
||||
// no `defer` / `onfail` cleanup runs, no error-trace frames are pushed —
|
||||
// it's the POSIX `_exit(2)` syscall. At comptime (`#run`) it terminates the
|
||||
// COMPILER with the same code after printing a short diagnostic; in compiled
|
||||
// code the `is_comptime()` branch folds away to just the syscall.
|
||||
//
|
||||
// (PLAN-ERR E4.1 also specifies a `loc: Source_Location = #caller_location`
|
||||
// parameter and an interpreter-frame dump in the comptime branch. Both ride
|
||||
// on the `#caller_location` directive — deferred to E4.1b.)
|
||||
exit :: (code: u8) -> noreturn {
|
||||
// COMPILER with the same code after printing a diagnostic naming the call site
|
||||
// (`loc` defaults to `#caller_location`); in compiled code the `is_comptime()`
|
||||
// branch folds away to just the syscall.
|
||||
exit :: (code: u8, loc: Source_Location = #caller_location) -> noreturn {
|
||||
if is_comptime() {
|
||||
print("\nprocess.exit({}) called at comptime\n", code);
|
||||
print("\nprocess.exit({}) called from {} at {}:{}\n", code, loc.func, loc.file, loc.line);
|
||||
}
|
||||
clib_exit(xx code);
|
||||
}
|
||||
|
||||
// Abort with a message when `cond` is false. Prints `ASSERTION FAILED: <msg>`
|
||||
// then exits 1; a true condition is a no-op. (E4.1b adds the caller's
|
||||
// `file:line` via `#caller_location`.)
|
||||
assert :: (cond: bool, msg: string) {
|
||||
// Abort with a message when `cond` is false. Prints `ASSERTION FAILED at
|
||||
// <file>:<line>: <msg>` (the caller's location, via `#caller_location`) then
|
||||
// exits 1; a true condition is a no-op.
|
||||
assert :: (cond: bool, msg: string, loc: Source_Location = #caller_location) {
|
||||
if !cond {
|
||||
print("ASSERTION FAILED: {}\n", msg);
|
||||
print("ASSERTION FAILED at {}:{}: {}\n", loc.file, loc.line, msg);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,16 @@ is_flags :: ($T: Type) -> bool #builtin;
|
||||
field_value_int :: ($T: Type, idx: s64) -> s64 #builtin;
|
||||
field_index :: ($T: Type, val: T) -> s64 #builtin;
|
||||
error_tag_name :: (e: $T) -> string #builtin;
|
||||
|
||||
// Call-site location, synthesized by the `#caller_location` directive when it
|
||||
// is a parameter's default value (ERR E4.1b). `process.exit` / `assert` use it
|
||||
// to report where they were invoked.
|
||||
Source_Location :: struct {
|
||||
file: string;
|
||||
line: s32;
|
||||
col: s32;
|
||||
func: string;
|
||||
}
|
||||
string :: []u8 #builtin;
|
||||
|
||||
#import "allocators.sx";
|
||||
|
||||
Reference in New Issue
Block a user