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.
This commit is contained in:
2026-09-30 12:54:21 +03:00
parent 9daaa42d6a
commit 2b73fcf1c4
8 changed files with 173 additions and 54 deletions

View File

@@ -13,6 +13,7 @@
(chicken irregex) ; unkebabify
srfi-1 ; lists
srfi-13 ; strings
types ; array-bound?, named-arg?
utils)
;;; egg `tree' not ported to CHICKEN 6 yet
@@ -292,27 +293,6 @@ forms, and what remains."
(list)
(walk-expr (drop form 3)))))) ; optional init expression
;;; `(¤ int N)' is N of int
;;; `(¤ unsigned int)' is an unsized array of unsigned int
;;; An aggregate is the exception -- `(¤ struct point)' ends in a tag,
;;; which is part of the type and not a bound.
(define +c-type-words+
'(void char short int long float double signed unsigned
bool _Bool complex _Complex _Atomic const volatile restrict))
(define (array-bound? array-type)
(and (> (length array-type) 1)
(let ((bound (last array-type))
(preceding (last (drop-right array-type 1))))
(cond
((not (symbol? bound)) #t)
((memq bound +c-type-words+) #f)
;; a tag always follows its keyword, so `(¤ * struct tt)' ends
;; in a name belonging to the type
((memq preceding '(struct union enum)) #f)
(else #t)))))
(define (walk-type form)
;; int -> int
;; (const int) -> const int
@@ -323,16 +303,11 @@ forms, and what remains."
;; (fn ((int) (float)) void) -> (%fun void ((int) (float)))
(match form
(('¤ . array-type)
(if (array-bound? array-type)
;; sized array
(let* ((type-list (drop-right array-type 1))
(type (maybe-unwrap-type type-list))
(size (last array-type)))
`(%array ,(walk-type type)
,size))
(if (array-bound? form)
`(%array ,(walk-type (array-element-type form)) ,(last array-type))
;; sugar for pointer... Do we really need it? Guess why not,
;; it's a strong semantic cue
`(%array ,(walk-type (maybe-unwrap-type array-type)))))
`(%array ,(walk-type (array-element-type form)))))
(('fn arglist ret-type)
`(%fun ,(walk-type ret-type) ,(walk-arg-types arglist)))
(('fn . _)
@@ -398,21 +373,6 @@ forms, and what remains."
.
,(walk-body maybe-body)))))
;;; TODO: isn't there a better way?
(define (is-probably-type form)
(case (car form)
((¤ * const volatile struct union) #t)
(else #f)))
;;; Does the parameter name itself?
;;; (f1 float) does
;;; (float), (const char) and (¤ float 4) do not
(define (named-arg? arg)
(and (pair? arg)
(pair? (cdr arg)) ; 1 element args are always type
(not (eq? (car arg) '¤))
(not (is-probably-type arg))))
;;; The type of one parameter
(define (arg-type arg)
(if (named-arg? arg)