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.
73 lines
2.3 KiB
Scheme
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))
|