Files
sex/tests/sex-programs/type-shapes.sex
alex-eg 2b73fcf1c4 answer where a written type ends in one place
An arglist entry, an array's bound and its element type ask one
question, and disagreed: `(unsigned int)' was a name plus a type, a
trailing typedef a bound, a subscript the type's second word.
2026-09-30 23:51:55 +03:00

73 lines
2.3 KiB
Scheme

(input)
(output "aggregate element: 3 4"
"pointer element: there"
"multi-word element: 9"
"through a pointer: 55"
"unsized of a typedef: 1 2"
"unsized of a pointer: 5"
"unnamed parameters: 7 -1 2")
(return 0)
;;; Three questions about a written type that used to be answered in
;;; three places and disagreed: is `(a b)' a named parameter or a bare
;;; type, is the last element of a `¤' its bound or the last word of
;;; its element type, and what is one element of an array.
;;;
;;; They are one question -- where does the type end -- so the answer
;;; lives in `types' and everything else asks it.
(include stdio.h)
(struct point ((x int) (y int)))
(typedef small int)
;;; a parameter that names nothing is a type, however many words it
;;; takes: `(unsigned int)' is one of them, not a `unsigned' called
;;; `int'
(fn width ((n unsigned int)) int
(return (cast n int)))
(fn sign ((c const char)) int
(if (== c #\a) (return -1))
(return 1))
(fn twice ((n small)) int
(return (* n 2)))
(pub fn main () int
;; an element keeps every word of its type, tag and all
(var pts (¤ (struct point) 2) #(#((struct point) : 1 2)
#((struct point) : 3 4)))
(var p _ (¤ pts 1))
(printf "aggregate element: %d %d\n" (. p x) (. p y))
(var names (¤ (* const char) 2) #("hi" "there"))
(var s _ (¤ names 1))
(printf "pointer element: %s\n" s)
(var nums (¤ unsigned int 3) #(7 8 9))
(var u _ (¤ nums 2))
(printf "multi-word element: %u\n" u)
;; subscripting a pointer answers the same as subscripting an array
(var q (* (struct point)) (& (¤ pts 0)))
(var r _ (¤ q 1))
(printf "through a pointer: %d\n" (+ (. r x) (* 13 (. r y))))
;; the last word of an unsized array's type is not its bound: neither
;; a typedef name nor the target of a `*' can be one
(var tail (¤ const small) #(1 2))
(printf "unsized of a typedef: %d %d\n" (¤ tail 0) (¤ tail 1))
(var one size-t 5)
(var sizes (¤ * size-t) #((& one)))
(var w _ (¤ sizes 0))
(printf "unsized of a pointer: %d\n" (cast (* w) int))
;; the same question in type position: `(fn ((unsigned int)) int)'
;; takes one parameter, not two
(var fp (fn ((unsigned int)) int) width)
(printf "unnamed parameters: %d %d %d\n" (fp 7) (sign #\a) (twice 1))
(return 0))