fix(lang): a function named like a compiler built-in is refused; reseed
A program's own `run` was never called: every call to it lowered to the built-in System.run (C's system()), and clang failed on the IR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ae61e99e06
commit
3d2a103dfb
6 changed files with 10686 additions and 10500 deletions
|
|
@ -120,7 +120,8 @@ Screens are drawn through a registered renderer. `Value` gains a float kind.
|
|||
|
||||
Also:
|
||||
- A program's function named like one of the runtime's is refused; it had been silently taking the
|
||||
runtime's own calls.
|
||||
runtime's own calls. So is one named like a compiler built-in (`run`, `exit`, `free`, `fill`,
|
||||
...): every call to a program's own `run` compiled into C's `system()`, and clang failed on the IR.
|
||||
- An index is evaluated before the slice's elements are read. A `xs[f()]` whose `f` grew `xs`
|
||||
read stale memory.
|
||||
- A runtime error names the file its expression is in, not the program's.
|
||||
|
|
|
|||
7
examples/rejected/builtin_name.ludic
Normal file
7
examples/rejected/builtin_name.ludic
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# builtin_name.ludic - a function named like a compiler built-in. `run` is the low-level System.run
|
||||
# (C's system()): every call to a program's own `run` compiled into that instead, and the program
|
||||
# failed in clang with a type error in the IR. (Rejected on purpose: tools/ludic-cli/test.ludic.)
|
||||
program BuiltinName {
|
||||
function run(hz: int) -> string { return `{hz}` }
|
||||
entry { print(run(60)) }
|
||||
}
|
||||
|
|
@ -148,8 +148,15 @@ function ck_listener(l: Node) -> void {
|
|||
ck_pop(m)
|
||||
}
|
||||
# a program's function named like one of the runtime's takes every call the runtime makes to its
|
||||
# own - the runtime's ui_measure started answering to a package's - so the name is refused
|
||||
# own - the runtime's ui_measure started answering to a package's - so the name is refused; one
|
||||
# named like a compiler built-in never ran at all (every call to `run` was C's system()), so too
|
||||
function ck_runtime_shadows() -> void {
|
||||
var u = 0
|
||||
while u < g_prog_user_end {
|
||||
let d = prog[u]
|
||||
if d.kind == N_FN and (is_intrinsic(d.s) or is_intrinsic2(d.s)) { ck_err("shadow", d, `{d.s} is a built-in of the compiler, and a call to it would never reach this function; choose another name`) }
|
||||
u += 1
|
||||
}
|
||||
var r = g_prog_user_end
|
||||
while r < len(prog) {
|
||||
let d = prog[r]
|
||||
|
|
|
|||
10583
selfhost/ludicc.seed.ll
10583
selfhost/ludicc.seed.ll
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -717,6 +717,7 @@ function cmd_dev_test() -> int {
|
|||
feat_case("events/answer", "", "10 20 0", "answer.ludic (a listener's return ends that listener, not the dispatch)")
|
||||
reject_case("rejected/duplicate_const", "'KEY_LEFT' is defined twice", "a const defined twice is refused, naming both places")
|
||||
reject_case("rejected/duplicate_property", "'Look' is defined twice", "a property defined twice is refused")
|
||||
reject_case("rejected/builtin_name", "run is a built-in of the compiler", "a function named like a compiler built-in (run, exit, free...) is refused")
|
||||
reject_case("rejected/redeclared_local", "'v0' is declared twice in this block", "a local declared twice in one block is refused")
|
||||
reject_case("rejected/missing_return", "can reach its end without returning", "a function that can run off its end without its result is refused")
|
||||
feat_case("functions/values", "", "42 10 25 49 81 1.5 1", "values.ludic (L2: fn types, fn name, calls through a local, global, field, element, parameter, result)")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue