(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))