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:
|
Also:
|
||||||
- A program's function named like one of the runtime's is refused; it had been silently taking the
|
- 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`
|
- An index is evaluated before the slice's elements are read. A `xs[f()]` whose `f` grew `xs`
|
||||||
read stale memory.
|
read stale memory.
|
||||||
- A runtime error names the file its expression is in, not the program's.
|
- 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)
|
ck_pop(m)
|
||||||
}
|
}
|
||||||
# a program's function named like one of the runtime's takes every call the runtime makes to its
|
# 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 {
|
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
|
var r = g_prog_user_end
|
||||||
while r < len(prog) {
|
while r < len(prog) {
|
||||||
let d = prog[r]
|
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)")
|
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_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/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/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")
|
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)")
|
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