1
0
forked from alex-eg/sex

scope and promote the way C does

A `while' or `switch' body is a block with no `do' around it, and its
declarations landed in the enclosing frame. Two operands of one narrow
type skipped the conversions, so `(+ c c)' answered `char'.
This commit is contained in:
2026-09-30 14:13:19 +03:00
parent 2da5b5005b
commit 578feb6b73
2 changed files with 50 additions and 7 deletions

View File

@@ -6,8 +6,10 @@
"arrays: 30"
"loop: 0 1 2"
"shadowed: 9 then 42"
"still an int: 200"
"partial: 1 2.5"
"joined: 43.5 84 49 1"
"promoted: 200 60000 3705032704"
"from elements: 4 9 0")
(return 0)
@@ -55,11 +57,24 @@
(printf " %d" i))
(printf "\n")
;; a block's declarations end with it
;; a block's declarations end with it, and so do the declarations of
;; everything else C brackets -- a `while' body is a block with no
;; `do' written around it
(do (var n _ 9)
(printf "shadowed: %d then " n))
(printf "%d\n" n)
(var wide int 200)
(while false (var wide char 1) (printf "%d" wide))
(if false (do (var wide char 1) (printf "%d" wide)))
;; a statement before the declaration: a label may not be followed by
;; one until C23
(switch a (case 1 (printf "") (var wide char 1) (printf "%d" wide) (break)))
;; a copy, not a sum: an arithmetic result would be promoted to `int'
;; whatever leaked, and say nothing
(var copy _ wide)
(printf "still an int: %d\n" copy)
;; a wildcard inside a written type: only it is solved
(var pp2 (* _) (& p))
(printf "partial: %d %g\n" (-> pp2 x) (-> pp2 y))
@@ -74,6 +89,17 @@
(var single _ (+ g g))
(printf "joined: %g %d %ld %g\n" mixed same wider single)
;; ...including the promotions, which two operands of one narrow type
;; are exactly where they show: `char' + `char' is an `int'
(var c1 char 100)
(var c2 char 100)
(var h1 short 30000)
(var narrow _ (+ c1 c2))
(var narrower _ (+ h1 h1))
(var kept (unsigned int) 4000000000)
(var unpromoted _ (+ kept kept))
(printf "promoted: %d %d %u\n" narrow narrower unpromoted)
;; a brace initializer has no type of its own, but its elements solve
;; the hole in the array type around it -- and the length stays as
;; written, whether or not every slot is initialized