parse.scm (62701B)
1 ;; cc/parse.scm — recursive-descent + Pratt parser. Minimal scheme1. 2 3 (define (make-pstate toks cg) 4 (%pstate toks (list '()) (list '()) '() #f '() cg)) 5 6 (define (peek ps) (car (ps-toks ps))) 7 (define (peek2 ps) 8 (let ((r (cdr (ps-toks ps)))) 9 (if (null? r) (car (ps-toks ps)) (car r)))) 10 (define (advance ps) 11 (let ((t (peek ps))) (ps-toks-set! ps (cdr (ps-toks ps))) t)) 12 (define (at-kw? ps s) 13 (let ((t (peek ps))) 14 (and (eq? (tok-kind t) 'KW) (eq? (tok-value t) s)))) 15 (define (at-punct? ps s) 16 (let ((t (peek ps))) 17 (and (eq? (tok-kind t) 'PUNCT) (eq? (tok-value t) s)))) 18 (define (expect-kw ps s) 19 (let ((t (peek ps))) 20 (if (and (eq? (tok-kind t) 'KW) (eq? (tok-value t) s)) 21 (advance ps) (die (tok-loc t) "expected kw" s)))) 22 (define (expect-punct ps s) 23 (let ((t (peek ps))) 24 (if (and (eq? (tok-kind t) 'PUNCT) (eq? (tok-value t) s)) 25 (advance ps) (die (tok-loc t) "expected punct" s)))) 26 27 (define (scope-enter! ps) 28 (ps-scope-set! ps (cons '() (ps-scope ps))) 29 (ps-tags-set! ps (cons '() (ps-tags ps)))) 30 (define (scope-leave! ps) 31 (ps-scope-set! ps (cdr (ps-scope ps))) 32 (ps-tags-set! ps (cdr (ps-tags ps)))) 33 (define (scope-bind! ps n s) 34 (let* ((f (ps-scope ps)) (top (car f)) (r (cdr f))) 35 (if (alist-ref n top) (die #f "dup decl" n) 36 (ps-scope-set! ps (cons (alist-set n s top) r))))) 37 (define (scope-lookup ps n) 38 (let loop ((f (ps-scope ps))) 39 (cond ((null? f) #f) 40 (else 41 (let ((v (alist-ref n (car f)))) 42 (if v v (loop (cdr f)))))))) 43 (define (tag-bind! ps n c) 44 (let* ((f (ps-tags ps)) (top (car f)) (r (cdr f))) 45 (ps-tags-set! ps (cons (alist-set n c top) r)))) 46 (define (tag-lookup ps n) 47 (let loop ((f (ps-tags ps))) 48 (cond ((null? f) #f) 49 (else (let ((v (alist-ref n (car f)))) 50 (if v v (loop (cdr f)))))))) 51 (define (typedef-add! ps n) 52 (ps-typedefs-set! ps (alist-set n #t (ps-typedefs ps)))) 53 (define (typedef? ps n) 54 (if (alist-ref n (ps-typedefs ps)) #t #f)) 55 56 (define (%mk-ptr p) (%ctype 'ptr 8 8 p)) 57 (define (%mk-arr e n) 58 (%ctype 'arr (if (< n 0) -1 (* n (ctype-size e))) 59 (ctype-align e) (cons e n))) 60 (define (%mk-fn r p v) (%ctype 'fn -1 -1 (list r p v))) 61 (define (ctype-is-ptr? t) (eq? (ctype-kind t) 'ptr)) 62 (define (ctype-is-fn? t) (eq? (ctype-kind t) 'fn)) 63 (define (ctype-is-arr? t) (eq? (ctype-kind t) 'arr)) 64 65 (define (eat-cv-quals! ps) 66 (cond ((or (at-kw? ps 'const) (at-kw? ps 'volatile) 67 (at-kw? ps 'restrict)) 68 (advance ps) (eat-cv-quals! ps)) 69 (else #t))) 70 71 (define (parse-decl-spec ps) 72 (let loop ((sto #f) (sn #f) (lg 0) (b #f) (saw #f)) 73 (let ((t (peek ps))) 74 (cond 75 ((or (at-kw? ps 'auto) (at-kw? ps 'register)) 76 (advance ps) (loop sto sn lg b #t)) 77 ((at-kw? ps 'static) (advance ps) (loop 'static sn lg b #t)) 78 ((at-kw? ps 'extern) (advance ps) (loop 'extern sn lg b #t)) 79 ((at-kw? ps 'typedef) (advance ps) (loop 'typedef sn lg b #t)) 80 ((or (at-kw? ps 'const) (at-kw? ps 'volatile) 81 (at-kw? ps 'restrict) (at-kw? ps 'inline)) 82 (advance ps) (loop sto sn lg b #t)) 83 ((at-kw? ps 'signed) (advance ps) (loop sto 'signed lg b #t)) 84 ((at-kw? ps 'unsigned) (advance ps) (loop sto 'unsigned lg b #t)) 85 ((at-kw? ps 'short) (advance ps) (loop sto sn -1 b #t)) 86 ((at-kw? ps 'long) (advance ps) (loop sto sn (+ lg 1) b #t)) 87 ((at-kw? ps 'void) (advance ps) (loop sto sn lg 'void #t)) 88 ((at-kw? ps 'char) (advance ps) (loop sto sn lg 'char #t)) 89 ((at-kw? ps 'int) (advance ps) (loop sto sn lg 'int #t)) 90 ((at-kw? ps '_Bool) (advance ps) (loop sto sn lg 'bool #t)) 91 ((or (at-kw? ps 'float) (at-kw? ps 'double) 92 (at-kw? ps '_Complex) (at-kw? ps '_Imaginary)) 93 (die (tok-loc t) "no float" (tok-value t))) 94 ((or (at-kw? ps '_Atomic) (at-kw? ps '_Thread_local) 95 (at-kw? ps '_Alignas) (at-kw? ps '_Generic) 96 (at-kw? ps '_Alignof) (at-kw? ps '_Static_assert)) 97 (die (tok-loc t) "rejected" (tok-value t))) 98 ((at-kw? ps 'struct) 99 (loop sto sn lg (parse-aggregate-spec ps 'struct) #t)) 100 ((at-kw? ps 'union) 101 (loop sto sn lg (parse-aggregate-spec ps 'union) #t)) 102 ((at-kw? ps 'enum) 103 (loop sto sn lg (parse-enum-spec ps) #t)) 104 ((and (not b) (eq? (tok-kind t) 'IDENT) 105 (typedef? ps (tok-value t))) 106 (let* ((tk (advance ps)) (sm (scope-lookup ps (tok-value tk)))) 107 (if (and sm (eq? (sym-kind sm) 'typedef)) 108 (loop sto sn lg (sym-type sm) #t) 109 (die (tok-loc tk) "typedef no sym" (tok-value tk))))) 110 (else 111 (cond ((not saw) (die (tok-loc t) "expected decl-spec" 112 (tok-value t))) 113 (else (cons sto (resolve-base t sn lg b))))))))) 114 115 (define (resolve-base loc sn lg b) 116 (cond 117 ((eq? b 'void) 118 (if (or sn (not (zero? lg))) (die loc "void+qual") %t-void)) 119 ((eq? b 'bool) 120 (if (or sn (not (zero? lg))) (die loc "bool+qual") %t-bool)) 121 ((eq? b 'char) 122 (cond ((eq? sn 'unsigned) %t-u8) (else %t-i8))) 123 ((or (eq? b 'int) (and (not b) (or sn (not (zero? lg))))) 124 (cond ((= lg -1) (if (eq? sn 'unsigned) %t-u16 %t-i16)) 125 ((= lg 0) (if (eq? sn 'unsigned) %t-u32 %t-i32)) 126 (else (if (eq? sn 'unsigned) %t-u64 %t-i64)))) 127 ((ctype? b) 128 (if (or sn (not (zero? lg))) (die loc "type+qual") b)) 129 (else (die loc "unknown decl-spec")))) 130 131 (define (parse-aggregate-spec ps kind) 132 (advance ps) 133 (let ((tag (cond ((eq? (tok-kind (peek ps)) 'IDENT) 134 (tok-value (advance ps))) (else #f)))) 135 (cond 136 ((at-punct? ps 'lbrace) 137 (advance ps) 138 (let* ((ex (and tag (tag-lookup ps tag))) 139 (ct (cond ((and ex (eq? (ctype-kind ex) kind)) ex) 140 (else (let ((c (%ctype kind -1 -1 141 (list (or tag #f) #f '())))) 142 (if tag (tag-bind! ps tag c)) c)))) 143 (fields (parse-struct-fields ps))) 144 (expect-punct ps 'rbrace) 145 (complete-agg! ct kind tag fields) ct)) 146 (tag (let ((ex (tag-lookup ps tag))) 147 (cond (ex ex) 148 (else (let ((c (%ctype kind -1 -1 149 (list tag #f '())))) 150 (tag-bind! ps tag c) c))))) 151 (else (die (tok-loc (peek ps)) "anon agg"))))) 152 153 (define (parse-struct-fields ps) 154 (let loop ((acc '()) (off 0)) 155 (cond 156 ((at-punct? ps 'rbrace) (reverse acc)) 157 (else 158 (let ((spec (parse-decl-spec ps))) 159 (let dl ((acc2 acc) (o2 off)) 160 (let* ((p (parse-declarator ps (cdr spec))) 161 (nm (car p)) (ty (cdr p)) 162 (al (max (ctype-align ty) 1)) 163 (sz (ctype-size ty)) 164 (oa (align-up o2 al))) 165 (cond 166 ((at-punct? ps 'comma) 167 (advance ps) 168 (dl (cons (list nm ty oa) acc2) 169 (+ oa (max sz 0)))) 170 ((at-punct? ps 'semi) 171 (advance ps) 172 (loop (cons (list nm ty oa) acc2) 173 (+ oa (max sz 0)))) 174 (else (die (tok-loc (peek ps)) "field")))))))))) 175 176 (define (complete-agg! ct k tag fs) 177 (let* ((ma (let m ((xs fs) (a 1)) 178 (if (null? xs) a 179 (m (cdr xs) (max a (ctype-align (cadr (car xs)))))))) 180 (last (let l ((xs fs) (e 0)) 181 (if (null? xs) e 182 (let* ((f (car xs)) (off (car (cddr f))) 183 (sz (ctype-size (cadr f)))) 184 (l (cdr xs) (max e (+ off (max sz 0)))))))) 185 (sz (cond ((eq? k 'union) 186 (let u ((xs fs) (s 0)) 187 (if (null? xs) s 188 (u (cdr xs) 189 (max s (ctype-size (cadr (car xs)))))))) 190 (else (align-up last ma))))) 191 (ctype-size-set! ct sz) 192 (ctype-align-set! ct ma) 193 (ctype-ext-set! ct (list tag #t fs)))) 194 195 (define (parse-enum-spec ps) 196 (advance ps) 197 (let ((tag (cond ((eq? (tok-kind (peek ps)) 'IDENT) 198 (tok-value (advance ps))) (else #f)))) 199 (cond 200 ((at-punct? ps 'lbrace) 201 (advance ps) 202 (let ((ct (%ctype 'enum 4 4 (list tag '())))) 203 (if tag (tag-bind! ps tag ct)) 204 (let loop ((vs '()) (nv 0)) 205 (cond 206 ((at-punct? ps 'rbrace) 207 (advance ps) 208 (ctype-ext-set! ct (list tag (reverse vs))) ct) 209 (else 210 (let* ((nt (advance ps)) (nm (tok-value nt)) 211 (val (cond ((at-punct? ps 'assign) 212 (advance ps) (parse-const-int ps)) 213 (else nv)))) 214 (scope-bind! ps nm 215 (%sym nm 'enum-const #f %t-i32 val)) 216 (cond ((at-punct? ps 'comma) (advance ps)) 217 ((at-punct? ps 'rbrace) #t) 218 (else (die (tok-loc (peek ps)) "enum"))) 219 (loop (cons (cons nm val) vs) (+ val 1)))))))) 220 (tag (let ((e (tag-lookup ps tag))) 221 (cond (e e) 222 (else (let ((c (%ctype 'enum 4 4 (list tag '())))) 223 (tag-bind! ps tag c) c))))) 224 (else (die (tok-loc (peek ps)) "enum"))))) 225 226 (define (parse-const-int ps) 227 (let ((t (peek ps))) 228 (cond 229 ((eq? (tok-kind t) 'INT) (tok-value (advance ps))) 230 ((and (eq? (tok-kind t) 'PUNCT) (eq? (tok-value t) 'minus)) 231 (advance ps) (- 0 (parse-const-int ps))) 232 ((and (eq? (tok-kind t) 'PUNCT) (eq? (tok-value t) 'plus)) 233 (advance ps) (parse-const-int ps)) 234 ((eq? (tok-kind t) 'IDENT) 235 (let ((sm (scope-lookup ps (tok-value t)))) 236 (cond ((and sm (eq? (sym-kind sm) 'enum-const)) 237 (advance ps) (sym-slot sm)) 238 (else (die (tok-loc t) "const?" (tok-value t)))))) 239 (else (die (tok-loc t) "const?" (tok-value t)))))) 240 241 (define (parse-declarator ps base) 242 ((cdr (parse-decl-cont ps)) base 243 (lambda (n t) (cons n t)))) 244 245 (define (parse-decl-cont ps) 246 (cond 247 ((at-punct? ps 'star) 248 (advance ps) (eat-cv-quals! ps) 249 (let* ((r (parse-decl-cont ps)) (rf (cdr r))) 250 (cons (car r) (lambda (b k) (rf (%mk-ptr b) k))))) 251 ((and (at-punct? ps 'lparen) (paren-is-group? ps)) 252 (advance ps) 253 (let* ((i (parse-decl-cont ps)) (if- (cdr i))) 254 (expect-punct ps 'rparen) 255 (let ((s (parse-decl-suf-cont ps))) 256 (cons (car i) (lambda (b k) (if- (s b) k)))))) 257 ((eq? (tok-kind (peek ps)) 'IDENT) 258 (let* ((tk (advance ps)) (n (tok-value tk)) 259 (s (parse-decl-suf-cont ps))) 260 (cons n (lambda (b k) (k n (s b)))))) 261 (else 262 (let ((s (parse-decl-suf-cont ps))) 263 (cons #f (lambda (b k) (k #f (s b)))))))) 264 265 (define (parse-decl-suf-cont ps) 266 ;; C declarator suffixes apply RIGHT-TO-LEFT (innermost first): 267 ;; int a[2][3] ⇒ arr (arr int 3) 2 (outer dim 2) 268 ;; not arr (arr int 2) 3 (which would treat the leftmost suffix as 269 ;; outermost). The recursive structure builds the inner suffix's 270 ;; result first, then this level wraps. 271 (cond 272 ((at-punct? ps 'lbrack) 273 (advance ps) 274 (let* ((ln (cond ((at-punct? ps 'rbrack) -1) 275 (else (parse-const-int ps)))) 276 (_ (expect-punct ps 'rbrack)) 277 (r (parse-decl-suf-cont ps))) 278 (lambda (b) (%mk-arr (r b) ln)))) 279 ((at-punct? ps 'lparen) 280 (advance ps) 281 (let* ((res (parse-fn-params ps)) 282 (p (car res)) (v (cdr res))) 283 (expect-punct ps 'rparen) 284 (let ((r (parse-decl-suf-cont ps))) 285 (lambda (b) (%mk-fn (r b) p v))))) 286 (else (lambda (b) b)))) 287 288 (define (paren-is-group? ps) 289 (let ((t (peek2 ps))) 290 (cond 291 ((eq? (tok-kind t) 'KW) 292 (let ((v (tok-value t))) 293 (cond ((or (eq? v 'void) (eq? v 'char) (eq? v 'short) 294 (eq? v 'int) (eq? v 'long) (eq? v 'signed) 295 (eq? v 'unsigned) (eq? v '_Bool) 296 (eq? v 'struct) (eq? v 'union) (eq? v 'enum) 297 (eq? v 'const) (eq? v 'volatile) 298 (eq? v 'restrict) (eq? v 'static) 299 (eq? v 'extern) (eq? v 'register)) #f) 300 (else #t)))) 301 ((eq? (tok-kind t) 'IDENT) 302 (cond ((typedef? ps (tok-value t)) #f) (else #t))) 303 ((eq? (tok-kind t) 'PUNCT) 304 (let ((v (tok-value t))) 305 (cond ((eq? v 'rparen) #f) 306 ((or (eq? v 'star) (eq? v 'lparen) (eq? v 'lbrack)) #t) 307 (else #f)))) 308 (else #f)))) 309 310 (define (parse-fn-params ps) 311 (cond 312 ((at-punct? ps 'rparen) (cons '() #f)) 313 ((and (at-kw? ps 'void) 314 (eq? (tok-kind (peek2 ps)) 'PUNCT) 315 (eq? (tok-value (peek2 ps)) 'rparen)) 316 (advance ps) (cons '() #f)) 317 (else 318 (let loop ((acc '())) 319 (cond 320 ((at-punct? ps 'ellipsis) 321 (advance ps) (cons (reverse acc) #t)) 322 (else 323 (let* ((sp (parse-decl-spec ps)) 324 (p (parse-declarator ps (cdr sp))) 325 (nm (car p)) (ty (cdr p)) 326 (ty2 (cond ((ctype-is-arr? ty) 327 (%mk-ptr (car (ctype-ext ty)))) 328 ((ctype-is-fn? ty) (%mk-ptr ty)) 329 (else ty)))) 330 (cond 331 ((at-punct? ps 'comma) 332 (advance ps) (loop (cons (cons nm ty2) acc))) 333 ((at-punct? ps 'rparen) 334 (cons (reverse (cons (cons nm ty2) acc)) #f)) 335 (else (die (tok-loc (peek ps)) "param")))))))))) 336 337 (define (parse-translation-unit ps) 338 (cond 339 ((eq? (tok-kind (peek ps)) 'EOF) #t) 340 (else (parse-decl-or-fn ps) (parse-translation-unit ps)))) 341 342 (define (parse-decl-or-fn ps) 343 (let* ((sp (parse-decl-spec ps)) 344 (sto (car sp)) (b (cdr sp))) 345 (cond 346 ((at-punct? ps 'semi) (advance ps) 'decl) 347 (else 348 (let* ((p (parse-declarator ps b)) 349 (n (car p)) (t (cdr p))) 350 (cond 351 ((and (ctype-is-fn? t) (at-punct? ps 'lbrace)) 352 (parse-fn-body ps n t) 'fn) 353 (else 354 (handle-decl ps sto n t) 355 (let lp () 356 (cond 357 ((at-punct? ps 'comma) 358 (advance ps) 359 (let* ((p2 (parse-declarator ps b)) 360 (n2 (car p2)) (t2 (cdr p2))) 361 (handle-decl ps sto n2 t2) (lp))) 362 (else (expect-punct ps 'semi) 'decl)))))))))) 363 364 (define (handle-decl ps sto n ty) 365 (cond 366 ((not n) (die #f "no name")) 367 ((eq? sto 'typedef) 368 (typedef-add! ps n) 369 (scope-bind! ps n (%sym n 'typedef #f ty #f))) 370 ((ctype-is-fn? ty) 371 (scope-bind! ps n 372 (%sym n 'fn (or sto 'extern) ty 373 (bytevector-append "cc__" n)))) 374 ;; §I: block-scope `static` routes to a global with a name mangled 375 ;; on the enclosing function so two functions can each have their 376 ;; own `static int n;` without colliding. The sym's NAME holds the 377 ;; mangled form (cg-push-sym / cg-emit-global both prefix "cc__" 378 ;; onto sym-name to derive the emitted label); scope-bind!s key 379 ;; remains the original identifier for source-level lookup. 380 ((and (eq? sto 'static) (ps-fn-ctx ps)) 381 (let* ((fname (fn-ctx-name (ps-fn-ctx ps))) 382 (mangled (bytevector-append fname "__" n)) 383 (sm (%sym mangled 'var 'static ty 384 (bytevector-append "cc__" mangled)))) 385 (scope-bind! ps n sm) 386 (cond 387 ((at-punct? ps 'assign) 388 (advance ps) 389 (cg-emit-global (ps-cg ps) sm (parse-init-global ps ty))) 390 (else (cg-emit-global (ps-cg ps) sm #f))))) 391 (else 392 (cond 393 ((not (ps-fn-ctx ps)) 394 (let ((sm (%sym n 'var (or sto 'extern) ty 395 (bytevector-append "cc__" n)))) 396 (scope-bind! ps n sm) 397 (cond 398 ((at-punct? ps 'assign) 399 (advance ps) 400 (cg-emit-global (ps-cg ps) sm 401 (parse-init-global ps ty))) 402 ((eq? sto 'extern) (cg-emit-extern (ps-cg ps) sm)) 403 (else (cg-emit-global (ps-cg ps) sm #f))))) 404 (else 405 (let* ((sz (max (ctype-size ty) 1)) 406 (al (max (ctype-align ty) 1)) 407 (sl (cg-alloc-slot (ps-cg ps) sz al)) 408 (sm (%sym n 'var (or sto 'auto) ty sl))) 409 (scope-bind! ps n sm) 410 (cond 411 ((at-punct? ps 'assign) 412 (advance ps) 413 (cond 414 ;; Aggregate locals get the per-element store treatment. 415 ((or (at-punct? ps 'lbrace) 416 (and (eq? (ctype-kind ty) 'arr) 417 (eq? (tok-kind (peek ps)) 'STR))) 418 (parse-init-local-aggregate ps sm ty)) 419 (else 420 (cg-push-sym (ps-cg ps) sm) 421 (parse-expr-bp ps 4) (rval! ps) 422 (cg-cast (ps-cg ps) ty) 423 (cg-assign (ps-cg ps)) 424 (cg-pop (ps-cg ps))))) 425 (else #t)))))))) 426 427 ;; ==================================================================== 428 ;; Initializers (CC.md §Variable initializers, §E of CC-PUNCHLIST). 429 ;; 430 ;; parse-init-global ps ty 431 ;; Reads the initializer following `=` for a file-scope or block-scope 432 ;; static var of static-storage type `ty` and returns a list of 433 ;; pieces suitable for cg-emit-global. See cg.scm §cg-emit-global for 434 ;; the piece grammar. 435 ;; 436 ;; parse-init-local ps sm ty 437 ;; Reads the initializer for an auto-storage variable bound to slot 438 ;; sym `sm` and emits per-element store cg ops. Returns unspecified. 439 ;; ==================================================================== 440 441 (define (%int->le-bv n nbytes) 442 ;; N-byte little-endian encoding of integer n into a fresh bv. Bytes 443 ;; >= sign-bit are filled by repeated >>8 (works for both signed and 444 ;; unsigned because we only keep the low N bytes). 445 (let ((out (make-bytevector nbytes 0))) 446 (let loop ((i 0) (v n)) 447 (cond 448 ((= i nbytes) out) 449 (else 450 (bytevector-u8-set! out i (bit-and v 255)) 451 (loop (+ i 1) (arithmetic-shift v -8))))))) 452 453 (define (%const-init-piece ps ty) 454 ;; Parse a non-brace initializer expression for scalar type `ty` and 455 ;; return a single piece. Recognised forms: 456 ;; - INT (with optional unary +/-) -> N-byte LE bv 457 ;; - enum-const IDENT -> N-byte LE bv 458 ;; - &IDENT (address of a global var/fn) -> (label-ref . cc__name) 459 ;; - IDENT (function name; decays to fn ptr) -> (label-ref . cc__name) 460 ;; - STR (only for char* targets) -> (label-ref . string-pool-label) 461 (let ((t (peek ps))) 462 (cond 463 ;; Address initializer: &ident -> label-ref 464 ((and (eq? (tok-kind t) 'PUNCT) (eq? (tok-value t) 'amp)) 465 (advance ps) 466 (let ((it (peek ps))) 467 (cond 468 ((eq? (tok-kind it) 'IDENT) 469 (advance ps) 470 (let ((sm (scope-lookup ps (tok-value it)))) 471 (cond 472 ((not sm) (die (tok-loc it) "init: undecl" (tok-value it))) 473 ((or (eq? (sym-kind sm) 'fn) 474 (and (eq? (sym-kind sm) 'var) 475 (or (eq? (sym-storage sm) 'static) 476 (eq? (sym-storage sm) 'extern)))) 477 (cons 'label-ref (sym-slot sm))) 478 (else 479 (die (tok-loc it) "init: &x must reference a global" 480 (tok-value it)))))) 481 (else (die (tok-loc it) "init: &?" (tok-value it)))))) 482 ;; Function name or array name as a label-ref initializer. 483 ;; (Both decay to a pointer when used as a value.) 484 ((and (eq? (tok-kind t) 'IDENT) 485 (let ((sm (scope-lookup ps (tok-value t)))) 486 (and sm 487 (or (eq? (sym-kind sm) 'fn) 488 (and (eq? (sym-kind sm) 'var) 489 (eq? (ctype-kind (sym-type sm)) 'arr) 490 (or (eq? (sym-storage sm) 'static) 491 (eq? (sym-storage sm) 'extern))))))) 492 (advance ps) 493 (let ((sm (scope-lookup ps (tok-value t)))) 494 (cons 'label-ref (sym-slot sm)))) 495 ;; Plain string literal as char* initializer. 496 ((eq? (tok-kind t) 'STR) 497 (advance ps) 498 (let ((lbl (cg-intern-string (ps-cg ps) (tok-value t)))) 499 (cons 'label-ref lbl))) 500 ;; Otherwise it's a const integer. 501 (else 502 (let ((v (parse-const-int ps))) 503 (%int->le-bv v (max (ctype-size ty) 1))))))) 504 505 (define (%init-array-elem-type ty) 506 (cond ((eq? (ctype-kind ty) 'arr) (car (ctype-ext ty))) 507 (else (die #f "init: not an array" ty)))) 508 509 (define (%init-array-decl-len ty) 510 ;; Declared array length (-1 = inferred). 511 (cond ((eq? (ctype-kind ty) 'arr) (cdr (ctype-ext ty))) (else -1))) 512 513 (define (%init-fix-array-size! ty count) 514 ;; Patch an inferred-length array to `count`. 515 (let ((elem (car (ctype-ext ty)))) 516 (ctype-ext-set! ty (cons elem count)) 517 (ctype-size-set! ty (* count (ctype-size elem))))) 518 519 (define (%init-struct-fields ty) 520 ;; Return ((name-bv ctype offset) ...) for a struct/union ctype. 521 (let ((ext (ctype-ext ty))) 522 (cond ((and (pair? ext) (pair? (cdr ext))) (car (cddr ext))) 523 (else (die #f "init: not a struct" ty))))) 524 525 (define (%find-field fields nm) 526 (cond ((null? fields) #f) 527 ((equal? (car (car fields)) nm) (car fields)) 528 (else (%find-field (cdr fields) nm)))) 529 530 (define (%pad-piece nbytes) 531 (make-bytevector nbytes 0)) 532 533 ;; ----- Global initializers --------------------------------------------- 534 (define (parse-init-global ps ty) 535 (cond 536 ;; String literal initializer for char[] 537 ((and (eq? (ctype-kind ty) 'arr) 538 (eq? (tok-kind (peek ps)) 'STR) 539 (let ((et (car (ctype-ext ty)))) 540 (or (eq? et %t-i8) (eq? et %t-u8)))) 541 (let* ((t (advance ps)) 542 (s (tok-value t)) 543 (slen (bytevector-length s)) 544 (decl (cdr (ctype-ext ty))) 545 (final (cond ((< decl 0) (+ slen 1)) (else decl)))) 546 (cond ((< decl 0) (%init-fix-array-size! ty final))) 547 (let ((bv (make-bytevector final 0))) 548 (let loop ((i 0)) 549 (cond 550 ((or (= i slen) (>= i final)) (list bv)) 551 (else 552 (bytevector-u8-set! bv i (bytevector-u8-ref s i)) 553 (loop (+ i 1)))))))) 554 ;; Brace-form 555 ((at-punct? ps 'lbrace) 556 (advance ps) 557 (cond 558 ((eq? (ctype-kind ty) 'arr) 559 (%parse-init-array-list ps ty)) 560 ((or (eq? (ctype-kind ty) 'struct) (eq? (ctype-kind ty) 'union)) 561 (%parse-init-struct-list ps ty)) 562 (else 563 ;; Brace-wrapped scalar: { expr } 564 (let ((piece (%const-init-piece ps ty))) 565 (cond ((at-punct? ps 'comma) (advance ps))) 566 (expect-punct ps 'rbrace) 567 (list piece))))) 568 ;; Bare scalar initializer 569 (else (list (%const-init-piece ps ty))))) 570 571 (define (%parse-init-array-list ps ty) 572 ;; Element-list array initializer; assumes `{` already consumed. 573 (let* ((elem (%init-array-elem-type ty)) 574 (esize (ctype-size elem)) 575 (decl (%init-array-decl-len ty))) 576 (let lp ((acc '()) (count 0)) 577 (cond 578 ((at-punct? ps 'rbrace) 579 (advance ps) 580 (cond ((< decl 0) (%init-fix-array-size! ty count))) 581 ;; Pad to declared length if longer than count. 582 (let* ((final (cond ((< decl 0) count) (else decl))) 583 (pad (- final count))) 584 (cond 585 ((> pad 0) 586 (reverse (cons (%pad-piece (* pad esize)) acc))) 587 (else (reverse acc))))) 588 (else 589 (let ((piece 590 (cond 591 ((at-punct? ps 'lbrace) 592 ;; Nested aggregate: brace-flatten via recursion. 593 (advance ps) 594 ;; element is itself struct/array 595 (cond 596 ((eq? (ctype-kind elem) 'arr) 597 (%parse-init-array-list ps elem)) 598 ((or (eq? (ctype-kind elem) 'struct) 599 (eq? (ctype-kind elem) 'union)) 600 (%parse-init-struct-list ps elem)) 601 (else 602 (let ((p (%const-init-piece ps elem))) 603 (cond ((at-punct? ps 'comma) (advance ps))) 604 (expect-punct ps 'rbrace) 605 (list p))))) 606 (else 607 (list (%const-init-piece ps elem)))))) 608 (cond ((at-punct? ps 'comma) (advance ps))) 609 (lp (append (reverse piece) acc) (+ count 1)))))))) 610 611 (define (%parse-init-struct-list ps ty) 612 ;; Struct/union initializer; assumes `{` already consumed. 613 ;; Supports positional and `.field = expr` forms. 614 (let* ((fields (%init-struct-fields ty)) 615 (size (ctype-size ty))) 616 (let lp ((acc '()) (filled 0) (rest fields)) 617 (cond 618 ((at-punct? ps 'rbrace) 619 (advance ps) 620 (cond 621 ((< filled size) 622 (reverse (cons (%pad-piece (- size filled)) acc))) 623 (else (reverse acc)))) 624 (else 625 (let* ((designated? (at-punct? ps 'dot)) 626 (target 627 (cond 628 (designated? 629 (advance ps) 630 (let ((nt (advance ps))) 631 (cond 632 ((not (eq? (tok-kind nt) 'IDENT)) 633 (die (tok-loc nt) "init: .field expects ident"))) 634 (let ((f (%find-field fields (tok-value nt)))) 635 (cond 636 ((not f) (die (tok-loc nt) "init: no such field" 637 (tok-value nt)))) 638 (expect-punct ps 'assign) 639 f))) 640 ((null? rest) 641 (die (tok-loc (peek ps)) "init: too many fields")) 642 (else (car rest)))) 643 (fname (car target)) 644 (fty (car (cdr target))) 645 (foff (car (cddr target))) 646 (fsize (ctype-size fty)) 647 ;; Pad from `filled` to `foff` if needed. 648 (pad-bytes (- foff filled)) 649 (piece-list 650 (cond 651 ((at-punct? ps 'lbrace) 652 (advance ps) 653 (cond 654 ((eq? (ctype-kind fty) 'arr) 655 (%parse-init-array-list ps fty)) 656 ((or (eq? (ctype-kind fty) 'struct) 657 (eq? (ctype-kind fty) 'union)) 658 (%parse-init-struct-list ps fty)) 659 (else 660 (let ((p (%const-init-piece ps fty))) 661 (cond ((at-punct? ps 'comma) (advance ps))) 662 (expect-punct ps 'rbrace) 663 (list p))))) 664 (else 665 (list (%const-init-piece ps fty))))) 666 (acc2 (cond ((> pad-bytes 0) 667 (cons (%pad-piece pad-bytes) acc)) 668 (else acc))) 669 (acc3 (append (reverse piece-list) acc2))) 670 (cond ((at-punct? ps 'comma) (advance ps))) 671 (lp acc3 (+ foff fsize) 672 (cond 673 (designated? 674 ;; designated init: drop fields up to and including target 675 (let drop ((xs fields)) 676 (cond 677 ((null? xs) '()) 678 ((equal? (car (car xs)) fname) (cdr xs)) 679 (else (drop (cdr xs)))))) 680 (else (cdr rest)))))))))) 681 682 ;; ----- Local aggregate initializers ------------------------------------ 683 ;; Emits per-element store sequences via cg ops into the slot of `sm` 684 ;; (a 'var sym whose slot is the frame offset). Assumes the assignment 685 ;; `=` has already been consumed. 686 (define (parse-init-local-aggregate ps sm ty) 687 (cond 688 ;; Local char[] = "string" — fill from string bytes. 689 ((and (eq? (ctype-kind ty) 'arr) 690 (eq? (tok-kind (peek ps)) 'STR) 691 (let ((et (car (ctype-ext ty)))) 692 (or (eq? et %t-i8) (eq? et %t-u8)))) 693 (let* ((t (advance ps)) 694 (s (tok-value t)) 695 (slen (bytevector-length s)) 696 (decl (cdr (ctype-ext ty))) 697 (final (cond ((< decl 0) (+ slen 1)) (else decl)))) 698 (cond ((< decl 0) (%init-fix-array-size! ty final))) 699 ;; Emit byte stores for each char in s, plus NUL for the 700 ;; trailing slot if final > slen. 701 (let loop ((i 0)) 702 (cond 703 ((>= i final) #t) 704 (else 705 (let ((b (cond ((< i slen) (bytevector-u8-ref s i)) 706 (else 0))) 707 (off (+ (sym-slot sm) i))) 708 (%push-frame-elem-lval ps off %t-u8) 709 (cg-push-imm (ps-cg ps) %t-u8 b) 710 (cg-assign (ps-cg ps)) 711 (cg-pop (ps-cg ps)) 712 (loop (+ i 1)))))))) 713 ((at-punct? ps 'lbrace) 714 (advance ps) 715 (cond 716 ((eq? (ctype-kind ty) 'arr) 717 (%parse-init-local-array-list ps sm (sym-slot sm) ty)) 718 ((or (eq? (ctype-kind ty) 'struct) (eq? (ctype-kind ty) 'union)) 719 (%parse-init-local-struct-list ps sm (sym-slot sm) ty)) 720 (else (die #f "init local: brace on scalar?")))) 721 (else (die (tok-loc (peek ps)) "init local aggregate?")))) 722 723 (define (%emit-local-elem-store ps sm rel-off elem-ty piece-or-thunk) 724 ;; Emit a single scalar store at slot[base + rel-off]. piece is the 725 ;; raw initializer expression — but here we want to actually evaluate 726 ;; it via parse-expr to allow non-const expressions for autos. 727 ;; Caller handles this; this helper handles the store-into-frame ops. 728 0) 729 730 (define (%push-frame-elem-lval ps base-off ty) 731 (cg-push (ps-cg ps) (%opnd 'frame ty base-off #t))) 732 733 (define (%parse-init-local-array-list ps sm base-off ty) 734 (let* ((elem (%init-array-elem-type ty)) 735 (esize (ctype-size elem)) 736 (decl (%init-array-decl-len ty))) 737 (let lp ((i 0)) 738 (cond 739 ((at-punct? ps 'rbrace) 740 (advance ps) 741 (cond ((< decl 0) (%init-fix-array-size! ty i))) 742 ;; Zero out remaining slots if any (declared length > i). 743 (let ((final (cond ((< decl 0) i) (else decl)))) 744 (let zlp ((k i)) 745 (cond 746 ((>= k final) #t) 747 (else 748 (let ((off (+ base-off (* k esize)))) 749 (cond 750 ((or (eq? (ctype-kind elem) 'arr) 751 (eq? (ctype-kind elem) 'struct) 752 (eq? (ctype-kind elem) 'union)) 753 ;; Zero each byte in this aggregate slot. 754 (let zb ((j 0)) 755 (cond 756 ((>= j esize) #t) 757 (else 758 (%push-frame-elem-lval ps (+ off j) %t-u8) 759 (cg-push-imm (ps-cg ps) %t-u8 0) 760 (cg-assign (ps-cg ps)) 761 (cg-pop (ps-cg ps)) 762 (zb (+ j 1)))))) 763 (else 764 (%push-frame-elem-lval ps off elem) 765 (cg-push-imm (ps-cg ps) elem 0) 766 (cg-assign (ps-cg ps)) 767 (cg-pop (ps-cg ps))))) 768 (zlp (+ k 1))))))) 769 (else 770 (let ((eoff (+ base-off (* i esize)))) 771 (cond 772 ((at-punct? ps 'lbrace) 773 (advance ps) 774 (cond 775 ((eq? (ctype-kind elem) 'arr) 776 (%parse-init-local-array-list ps sm eoff elem)) 777 ((or (eq? (ctype-kind elem) 'struct) 778 (eq? (ctype-kind elem) 'union)) 779 (%parse-init-local-struct-list ps sm eoff elem)) 780 (else 781 (%push-frame-elem-lval ps eoff elem) 782 (parse-expr-bp ps 4) (rval! ps) 783 (cg-cast (ps-cg ps) elem) 784 (cg-assign (ps-cg ps)) (cg-pop (ps-cg ps)) 785 (cond ((at-punct? ps 'comma) (advance ps))) 786 (expect-punct ps 'rbrace)))) 787 (else 788 (%push-frame-elem-lval ps eoff elem) 789 (parse-expr-bp ps 4) (rval! ps) 790 (cg-cast (ps-cg ps) elem) 791 (cg-assign (ps-cg ps)) (cg-pop (ps-cg ps)))) 792 (cond ((at-punct? ps 'comma) (advance ps))) 793 (lp (+ i 1)))))))) 794 795 (define (%parse-init-local-struct-list ps sm base-off ty) 796 (let ((fields (%init-struct-fields ty))) 797 (let lp ((rest fields)) 798 (cond 799 ((at-punct? ps 'rbrace) 800 (advance ps) 801 ;; Zero any remaining fields. 802 (let zlp ((xs rest)) 803 (cond 804 ((null? xs) #t) 805 (else 806 (let* ((f (car xs)) (fty (car (cdr f))) 807 (foff (car (cddr f))) (fsize (ctype-size fty))) 808 (let zb ((j 0)) 809 (cond 810 ((>= j fsize) #t) 811 (else 812 (%push-frame-elem-lval ps (+ base-off foff j) %t-u8) 813 (cg-push-imm (ps-cg ps) %t-u8 0) 814 (cg-assign (ps-cg ps)) 815 (cg-pop (ps-cg ps)) 816 (zb (+ j 1))))) 817 (zlp (cdr xs))))))) 818 (else 819 (let* ((designated? (at-punct? ps 'dot)) 820 (target 821 (cond 822 (designated? 823 (advance ps) 824 (let ((nt (advance ps))) 825 (let ((f (%find-field fields (tok-value nt)))) 826 (cond 827 ((not f) (die (tok-loc nt) "init: no such field" 828 (tok-value nt)))) 829 (expect-punct ps 'assign) 830 f))) 831 ((null? rest) 832 (die (tok-loc (peek ps)) "init: too many fields")) 833 (else (car rest)))) 834 (fname (car target)) 835 (fty (car (cdr target))) 836 (foff (car (cddr target))) 837 (eoff (+ base-off foff))) 838 (cond 839 ((at-punct? ps 'lbrace) 840 (advance ps) 841 (cond 842 ((eq? (ctype-kind fty) 'arr) 843 (%parse-init-local-array-list ps sm eoff fty)) 844 ((or (eq? (ctype-kind fty) 'struct) 845 (eq? (ctype-kind fty) 'union)) 846 (%parse-init-local-struct-list ps sm eoff fty)) 847 (else 848 (%push-frame-elem-lval ps eoff fty) 849 (parse-expr-bp ps 4) (rval! ps) 850 (cg-cast (ps-cg ps) fty) 851 (cg-assign (ps-cg ps)) (cg-pop (ps-cg ps)) 852 (cond ((at-punct? ps 'comma) (advance ps))) 853 (expect-punct ps 'rbrace)))) 854 (else 855 (%push-frame-elem-lval ps eoff fty) 856 (parse-expr-bp ps 4) (rval! ps) 857 (cg-cast (ps-cg ps) fty) 858 (cg-assign (ps-cg ps)) (cg-pop (ps-cg ps)))) 859 (cond ((at-punct? ps 'comma) (advance ps))) 860 (lp (cond 861 (designated? 862 (let drop ((xs fields)) 863 (cond 864 ((null? xs) '()) 865 ((equal? (car (car xs)) fname) (cdr xs)) 866 (else (drop (cdr xs)))))) 867 (else (cdr rest)))))))))) 868 869 870 (define (parse-fn-body ps name dt) 871 (let* ((e (ctype-ext dt)) (ret (car e)) 872 (par (cadr e)) (var (car (cddr e)))) 873 (cond ((not (scope-lookup ps name)) 874 (scope-bind! ps name 875 (%sym name 'fn 'extern dt 876 (bytevector-append "cc__" name))))) 877 (let ((psyms (cg-fn-begin/v (ps-cg ps) name par ret var))) 878 (ps-fn-ctx-set! ps 879 (%fn-ctx name ret (map cdr psyms) var '())) 880 (scope-enter! ps) 881 (for-each (lambda (p) (scope-bind! ps (car p) (cdr p))) 882 psyms) 883 (expect-punct ps 'lbrace) 884 (parse-cstmt-body ps) 885 (expect-punct ps 'rbrace) 886 (scope-leave! ps) 887 (ps-fn-ctx-set! ps #f) 888 (cg-fn-end (ps-cg ps))))) 889 890 (define (parse-stmt ps) 891 (cond 892 ((at-punct? ps 'lbrace) (parse-cstmt ps)) 893 ((at-kw? ps 'if) (parse-if-stmt ps)) 894 ((at-kw? ps 'while) (parse-while-stmt ps)) 895 ((at-kw? ps 'do) (parse-do-stmt ps)) 896 ((at-kw? ps 'for) (parse-for-stmt ps)) 897 ((at-kw? ps 'switch) (parse-switch-stmt ps)) 898 ((at-kw? ps 'return) (parse-return-stmt ps)) 899 ((at-kw? ps 'goto) (parse-goto-stmt ps)) 900 ((at-kw? ps 'break) 901 (advance ps) (expect-punct ps 'semi) (do-break ps)) 902 ((at-kw? ps 'continue) 903 (advance ps) (expect-punct ps 'semi) (do-continue ps)) 904 ((at-kw? ps 'case) (parse-case-stmt ps)) 905 ((at-kw? ps 'default) (parse-default-stmt ps)) 906 ((and (eq? (tok-kind (peek ps)) 'IDENT) 907 (eq? (tok-kind (peek2 ps)) 'PUNCT) 908 (eq? (tok-value (peek2 ps)) 'colon)) 909 (parse-labelled-stmt ps)) 910 ((stmt-starts-decl? ps) (parse-local-decl ps)) 911 (else (parse-expr-stmt ps)))) 912 913 (define (stmt-starts-decl? ps) 914 (let ((t (peek ps))) 915 (cond 916 ((eq? (tok-kind t) 'KW) 917 (let ((v (tok-value t))) 918 (or (eq? v 'auto) (eq? v 'register) (eq? v 'static) 919 (eq? v 'extern) (eq? v 'typedef) (eq? v 'const) 920 (eq? v 'volatile) (eq? v 'restrict) (eq? v 'inline) 921 (eq? v 'void) (eq? v 'char) (eq? v 'short) (eq? v 'int) 922 (eq? v 'long) (eq? v 'signed) (eq? v 'unsigned) 923 (eq? v '_Bool) (eq? v 'struct) (eq? v 'union) 924 (eq? v 'enum)))) 925 ((eq? (tok-kind t) 'IDENT) (typedef? ps (tok-value t))) 926 (else #f)))) 927 928 (define (parse-local-decl ps) 929 (let* ((sp (parse-decl-spec ps)) 930 (sto (car sp)) (b (cdr sp))) 931 (cond 932 ((at-punct? ps 'semi) (advance ps) #t) 933 (else 934 (let lp () 935 (let* ((p (parse-declarator ps b)) 936 (n (car p)) (t (cdr p))) 937 (handle-decl ps sto n t) 938 (cond ((at-punct? ps 'comma) (advance ps) (lp)) 939 (else (expect-punct ps 'semi) #t)))))))) 940 941 (define (parse-cstmt ps) 942 (expect-punct ps 'lbrace) 943 (scope-enter! ps) 944 (parse-cstmt-body ps) 945 (scope-leave! ps) 946 (expect-punct ps 'rbrace) #t) 947 948 (define (parse-cstmt-body ps) 949 (cond 950 ((at-punct? ps 'rbrace) #t) 951 ((eq? (tok-kind (peek ps)) 'EOF) 952 (die (tok-loc (peek ps)) "EOF in cstmt")) 953 (else (parse-stmt ps) (parse-cstmt-body ps)))) 954 955 (define (parse-compound-stmt ps) (parse-cstmt ps)) 956 957 (define (parse-if-stmt ps) 958 (expect-kw ps 'if) 959 (expect-punct ps 'lparen) 960 (parse-expr ps) (rval! ps) 961 (expect-punct ps 'rparen) 962 (cg-ifelse (ps-cg ps) 963 (lambda () (parse-stmt ps)) 964 (lambda () 965 (cond ((at-kw? ps 'else) 966 (advance ps) (parse-stmt ps)) 967 (else #t))))) 968 969 ;; cg-loop's body-thunk now receives the tag from cg (CC-CONTRACTS 970 ;; §3.3); the parser threads it into break/continue via loop-ctx. 971 972 (define (parse-while-stmt ps) 973 (expect-kw ps 'while) 974 (expect-punct ps 'lparen) 975 (cg-loop (ps-cg ps) 976 (lambda () (parse-expr ps) (rval! ps)) 977 (lambda (tag) 978 (expect-punct ps 'rparen) 979 (push-loop-ctx! ps 'while tag #t) 980 (parse-stmt ps) 981 (pop-loop-ctx! ps))) #t) 982 983 (define (parse-do-stmt ps) 984 (expect-kw ps 'do) 985 ;; do-while needs its tag known *before* the body parses, so we 986 ;; capture it inside the body-thunk and stash it for pop-loop-ctx 987 ;; via a side cell. 988 (cg-loop (ps-cg ps) 989 (lambda () #t) 990 (lambda (tag) 991 (push-loop-ctx! ps 'do tag #t) 992 (parse-stmt ps) 993 (pop-loop-ctx! ps) 994 (expect-kw ps 'while) (expect-punct ps 'lparen) 995 (parse-expr ps) (rval! ps) 996 (expect-punct ps 'rparen) (expect-punct ps 'semi) 997 (cg-unop (ps-cg ps) 'lnot) 998 (cg-if (ps-cg ps) 999 (lambda () (cg-break (ps-cg ps) tag))))) 1000 #t) 1001 1002 (define (parse-for-stmt ps) 1003 (expect-kw ps 'for) (expect-punct ps 'lparen) 1004 (scope-enter! ps) 1005 (cond 1006 ((at-punct? ps 'semi) (advance ps)) 1007 ((stmt-starts-decl? ps) (parse-local-decl ps)) 1008 (else (parse-expr ps) (cg-pop (ps-cg ps)) 1009 (expect-punct ps 'semi))) 1010 (cg-loop (ps-cg ps) 1011 (lambda () 1012 (cond ((at-punct? ps 'semi) 1013 (cg-push-imm (ps-cg ps) %t-i32 1)) 1014 (else (parse-expr ps) (rval! ps))) 1015 (expect-punct ps 'semi)) 1016 (lambda (tag) 1017 (let ((stk (collect-til-rparen ps))) 1018 (expect-punct ps 'rparen) 1019 (push-loop-ctx! ps 'for tag #t) 1020 (parse-stmt ps) 1021 (pop-loop-ctx! ps) 1022 (cond 1023 ((null? stk) #t) 1024 (else 1025 (let ((sv (ps-toks ps))) 1026 (ps-toks-set! ps 1027 (append stk (list (make-tok 'EOF #f #f)))) 1028 (parse-expr ps) (cg-pop (ps-cg ps)) 1029 (ps-toks-set! ps sv))))))) 1030 (scope-leave! ps) #t) 1031 1032 (define (collect-til-rparen ps) 1033 (let loop ((acc '()) (d 0)) 1034 (let ((t (peek ps))) 1035 (cond 1036 ((eq? (tok-kind t) 'EOF) 1037 (die (tok-loc t) "EOF in for-step")) 1038 ((and (zero? d) (eq? (tok-kind t) 'PUNCT) 1039 (eq? (tok-value t) 'rparen)) (reverse acc)) 1040 (else 1041 (let ((nt (advance ps))) 1042 (loop (cons nt acc) 1043 (cond ((not (eq? (tok-kind nt) 'PUNCT)) d) 1044 ((eq? (tok-value nt) 'lparen) (+ d 1)) 1045 ((eq? (tok-value nt) 'rparen) (- d 1)) 1046 (else d))))))))) 1047 1048 (define (parse-switch-stmt ps) 1049 (expect-kw ps 'switch) (expect-punct ps 'lparen) 1050 (parse-expr ps) (rval! ps) 1051 (expect-punct ps 'rparen) 1052 ;; Switch's break-target tag is the swctx's end-tag — cg owns it, 1053 ;; and we read it back so cg-break inside the switch body emits a 1054 ;; tag cg actually labels. 1055 (let* ((sw (cg-switch-begin (ps-cg ps))) 1056 (tg (swctx-end-tag sw))) 1057 (push-loop-ctx-sw! ps 'switch tg sw) 1058 (parse-stmt ps) 1059 (pop-loop-ctx! ps) 1060 (cg-switch-end (ps-cg ps) sw))) 1061 1062 (define (parse-case-stmt ps) 1063 (expect-kw ps 'case) 1064 (let ((v (parse-const-int ps))) 1065 (expect-punct ps 'colon) 1066 (cg-switch-case (ps-cg ps) (innermost-sw ps) v) 1067 (parse-stmt ps))) 1068 1069 (define (parse-default-stmt ps) 1070 (expect-kw ps 'default) (expect-punct ps 'colon) 1071 (cg-switch-default (ps-cg ps) (innermost-sw ps)) 1072 (parse-stmt ps)) 1073 1074 (define (parse-return-stmt ps) 1075 (expect-kw ps 'return) 1076 (cond 1077 ((at-punct? ps 'semi) (advance ps) (cg-return (ps-cg ps))) 1078 (else 1079 (parse-expr ps) (rval! ps) 1080 (let ((fc (ps-fn-ctx ps))) 1081 (cond 1082 ((and fc (not (eq? (ctype-kind (fn-ctx-return-type fc)) 'void))) 1083 (cg-cast (ps-cg ps) (fn-ctx-return-type fc))) 1084 (else #t))) 1085 (cg-return (ps-cg ps)) 1086 (expect-punct ps 'semi)))) 1087 1088 (define (parse-goto-stmt ps) 1089 (expect-kw ps 'goto) 1090 (let ((t (advance ps))) 1091 (cond ((eq? (tok-kind t) 'IDENT) 1092 (cg-goto (ps-cg ps) (tok-value t))) 1093 (else (die (tok-loc t) "label?")))) 1094 (expect-punct ps 'semi)) 1095 1096 (define (parse-labelled-stmt ps) 1097 (let ((t (advance ps))) 1098 (expect-punct ps 'colon) 1099 (cg-emit-label (ps-cg ps) (tok-value t)) 1100 (parse-stmt ps))) 1101 1102 (define (parse-expr-stmt ps) 1103 (cond 1104 ((at-punct? ps 'semi) (advance ps) #t) 1105 (else (parse-expr ps) (cg-pop (ps-cg ps)) 1106 (expect-punct ps 'semi)))) 1107 1108 (define (push-loop-ctx! ps k tg hc) 1109 (ps-loops-set! ps (cons (%loop-ctx k tg hc) (ps-loops ps)))) 1110 (define (push-loop-ctx-sw! ps k tg sw) 1111 (ps-loops-set! ps 1112 (cons (%loop-ctx k (cons tg sw) #f) (ps-loops ps)))) 1113 (define (pop-loop-ctx! ps) 1114 (ps-loops-set! ps (cdr (ps-loops ps)))) 1115 (define (do-break ps) 1116 (let ((c (innermost-loop ps))) 1117 (cond 1118 ((not c) (die #f "break outside")) 1119 ((eq? (loop-ctx-kind c) 'switch) 1120 (cg-break (ps-cg ps) (car (loop-ctx-tag c)))) 1121 (else (cg-break (ps-cg ps) (loop-ctx-tag c)))))) 1122 (define (do-continue ps) 1123 (let ((c (innermost-cont ps))) 1124 (cond ((not c) (die #f "cont outside")) 1125 (else (cg-continue (ps-cg ps) (loop-ctx-tag c)))))) 1126 (define (innermost-loop ps) 1127 (cond ((null? (ps-loops ps)) #f) (else (car (ps-loops ps))))) 1128 (define (innermost-cont ps) 1129 (let lp ((xs (ps-loops ps))) 1130 (cond ((null? xs) #f) 1131 ((eq? (loop-ctx-kind (car xs)) 'switch) (lp (cdr xs))) 1132 (else (car xs))))) 1133 (define (innermost-sw ps) 1134 (let lp ((xs (ps-loops ps))) 1135 (cond ((null? xs) (die #f "case outside switch")) 1136 ((eq? (loop-ctx-kind (car xs)) 'switch) 1137 (cdr (loop-ctx-tag (car xs)))) 1138 (else (lp (cdr xs)))))) 1139 1140 (define %binop-bp 1141 (list 1142 (cons 'comma (cons 1 2)) 1143 (cons 'assign (cons 4 3)) (cons 'plus-eq (cons 4 3)) 1144 (cons 'minus-eq (cons 4 3)) (cons 'star-eq (cons 4 3)) 1145 (cons 'slash-eq (cons 4 3)) (cons 'pct-eq (cons 4 3)) 1146 (cons 'shl-eq (cons 4 3)) (cons 'shr-eq (cons 4 3)) 1147 (cons 'amp-eq (cons 4 3)) (cons 'caret-eq (cons 4 3)) 1148 (cons 'bar-eq (cons 4 3)) (cons 'qmark (cons 6 5)) 1149 (cons 'lor (cons 10 11)) (cons 'land (cons 20 21)) 1150 (cons 'bar (cons 30 31)) (cons 'caret (cons 40 41)) 1151 (cons 'amp (cons 50 51)) 1152 (cons 'eq2 (cons 60 61)) (cons 'ne (cons 60 61)) 1153 (cons 'lt (cons 70 71)) (cons 'le (cons 70 71)) 1154 (cons 'gt (cons 70 71)) (cons 'ge (cons 70 71)) 1155 (cons 'shl (cons 80 81)) (cons 'shr (cons 80 81)) 1156 (cons 'plus (cons 90 91)) (cons 'minus (cons 90 91)) 1157 (cons 'star (cons 100 101)) (cons 'slash (cons 100 101)) 1158 (cons 'pct (cons 100 101)))) 1159 1160 (define (binop-bp-of s) (alist-ref/eq s %binop-bp)) 1161 1162 (define (punct-to-cgop s) 1163 (cond ((eq? s 'plus) 'add) ((eq? s 'minus) 'sub) 1164 ((eq? s 'star) 'mul) ((eq? s 'slash) 'div) 1165 ((eq? s 'pct) 'rem) ((eq? s 'amp) 'and) 1166 ((eq? s 'bar) 'or) ((eq? s 'caret) 'xor) 1167 ((eq? s 'shl) 'shl) ((eq? s 'shr) 'shr) 1168 ((eq? s 'eq2) 'eq) ((eq? s 'ne) 'ne) 1169 ((eq? s 'lt) 'lt) ((eq? s 'le) 'le) 1170 ((eq? s 'gt) 'gt) ((eq? s 'ge) 'ge) 1171 (else (die #f "binop" s)))) 1172 1173 (define (compound-op s) 1174 (cond ((eq? s 'plus-eq) 'add) ((eq? s 'minus-eq) 'sub) 1175 ((eq? s 'star-eq) 'mul) ((eq? s 'slash-eq) 'div) 1176 ((eq? s 'pct-eq) 'rem) ((eq? s 'shl-eq) 'shl) 1177 ((eq? s 'shr-eq) 'shr) ((eq? s 'amp-eq) 'and) 1178 ((eq? s 'caret-eq) 'xor) ((eq? s 'bar-eq) 'or) 1179 (else #f))) 1180 1181 (define (parse-expr ps) (parse-expr-bp ps 0)) 1182 1183 (define (parse-expr-bp ps mn) 1184 (parse-unary ps) (parse-binary-rhs ps mn)) 1185 1186 (define (parse-binary-rhs ps mn) 1187 (let ((t (peek ps))) 1188 (cond 1189 ((not (eq? (tok-kind t) 'PUNCT)) #t) 1190 (else 1191 (let ((bp (binop-bp-of (tok-value t)))) 1192 (cond 1193 ((not bp) #t) 1194 ((< (car bp) mn) #t) 1195 (else 1196 (let ((op (tok-value t)) (rb (cdr bp))) 1197 (advance ps) 1198 (cond 1199 ((eq? op 'comma) 1200 ;; lhs has been parsed; discard it and evaluate rhs. 1201 ;; Result of the comma expr is the rhs's rval. 1202 (cg-pop (ps-cg ps)) 1203 (parse-expr-bp ps rb) (rval! ps)) 1204 ((eq? op 'assign) 1205 (parse-expr-bp ps rb) (rval! ps) 1206 (cg-assign (ps-cg ps))) 1207 ((compound-op op) 1208 (let ((b (compound-op op))) 1209 (cg-dup (ps-cg ps)) 1210 (cg-load (ps-cg ps)) 1211 (parse-expr-bp ps rb) (rval! ps) 1212 (cg-arith-conv (ps-cg ps)) 1213 (cg-binop (ps-cg ps) b) 1214 (cg-assign (ps-cg ps)))) 1215 ((eq? op 'qmark) 1216 (rval! ps) 1217 (cg-ifelse-merge (ps-cg ps) 1218 (lambda () 1219 (parse-expr-bp ps 0) (rval! ps)) 1220 (lambda () 1221 (expect-punct ps 'colon) 1222 (parse-expr-bp ps rb) (rval! ps)))) 1223 ((eq? op 'land) 1224 (rval! ps) 1225 ;; Both branches must push i32 0/1. Right side is 1226 ;; coerced via `cg-cast bool` so the merge slot 1227 ;; carries i32 (per §H.2). 1228 (cg-ifelse-merge (ps-cg ps) 1229 (lambda () 1230 (parse-expr-bp ps rb) (rval! ps) 1231 (cg-cast (ps-cg ps) %t-bool) 1232 (cg-cast (ps-cg ps) %t-i32)) 1233 (lambda () 1234 (cg-push-imm (ps-cg ps) %t-i32 0)))) 1235 ((eq? op 'lor) 1236 (rval! ps) 1237 (cg-ifelse-merge (ps-cg ps) 1238 (lambda () 1239 (cg-push-imm (ps-cg ps) %t-i32 1)) 1240 (lambda () 1241 (parse-expr-bp ps rb) (rval! ps) 1242 (cg-cast (ps-cg ps) %t-bool) 1243 (cg-cast (ps-cg ps) %t-i32)))) 1244 (else 1245 (rval! ps) (cg-promote (ps-cg ps)) 1246 (parse-expr-bp ps rb) (rval! ps) 1247 (cg-promote (ps-cg ps)) 1248 (cg-arith-conv (ps-cg ps)) 1249 (cg-binop (ps-cg ps) (punct-to-cgop op)))) 1250 (parse-binary-rhs ps mn))))))))) 1251 1252 (define (parse-unary ps) 1253 (let ((t (peek ps))) 1254 (cond 1255 ((eq? (tok-kind t) 'PUNCT) 1256 (let ((v (tok-value t))) 1257 (cond 1258 ((eq? v 'amp) 1259 (advance ps) (parse-unary ps) 1260 (cg-take-addr (ps-cg ps))) 1261 ((eq? v 'star) 1262 (advance ps) (parse-unary ps) (rval! ps) 1263 (cg-push-deref (ps-cg ps))) 1264 ((eq? v 'plus) 1265 (advance ps) (parse-unary ps) 1266 (rval! ps) (cg-promote (ps-cg ps))) 1267 ((eq? v 'minus) 1268 (advance ps) (parse-unary ps) 1269 (rval! ps) (cg-promote (ps-cg ps)) 1270 (cg-unop (ps-cg ps) 'neg)) 1271 ((eq? v 'tilde) 1272 (advance ps) (parse-unary ps) 1273 (rval! ps) (cg-promote (ps-cg ps)) 1274 (cg-unop (ps-cg ps) 'bnot)) 1275 ((eq? v 'bang) 1276 (advance ps) (parse-unary ps) (rval! ps) 1277 (cg-unop (ps-cg ps) 'lnot)) 1278 ((eq? v 'inc) (advance ps) (parse-unary ps) 1279 (cg-dup (ps-cg ps)) 1280 (cg-load (ps-cg ps)) 1281 (cg-push-imm (ps-cg ps) %t-i32 1) 1282 (cg-binop (ps-cg ps) 'add) (cg-assign (ps-cg ps))) 1283 ((eq? v 'dec) (advance ps) (parse-unary ps) 1284 (cg-dup (ps-cg ps)) 1285 (cg-load (ps-cg ps)) 1286 (cg-push-imm (ps-cg ps) %t-i32 1) 1287 (cg-binop (ps-cg ps) 'sub) (cg-assign (ps-cg ps))) 1288 ((eq? v 'lparen) (parse-cast-or-unary ps)) 1289 (else (parse-postfix ps))))) 1290 ((and (eq? (tok-kind t) 'KW) (eq? (tok-value t) 'sizeof)) 1291 (advance ps) 1292 (cond 1293 ((at-punct? ps 'lparen) 1294 (advance ps) 1295 (cond 1296 ((token-is-decl? ps) 1297 (let* ((sp (parse-decl-spec ps)) 1298 (p (parse-declarator ps (cdr sp))) 1299 (ty (cdr p))) 1300 (expect-punct ps 'rparen) 1301 (cg-push-imm (ps-cg ps) %t-u64 1302 (max (ctype-size ty) 0)))) 1303 (else 1304 (parse-expr ps) (expect-punct ps 'rparen) 1305 (let* ((tp (cg-top (ps-cg ps))) 1306 (sz (max (ctype-size (opnd-type tp)) 0))) 1307 (cg-pop (ps-cg ps)) 1308 (cg-push-imm (ps-cg ps) %t-u64 sz))))) 1309 (else (parse-unary ps) 1310 (let* ((tp (cg-top (ps-cg ps))) 1311 (sz (max (ctype-size (opnd-type tp)) 0))) 1312 (cg-pop (ps-cg ps)) 1313 (cg-push-imm (ps-cg ps) %t-u64 sz))))) 1314 (else (parse-postfix ps))))) 1315 1316 (define (token-is-decl? ps) 1317 (let ((t (peek ps))) 1318 (cond 1319 ((eq? (tok-kind t) 'KW) 1320 (let ((v (tok-value t))) 1321 (or (eq? v 'void) (eq? v 'char) (eq? v 'short) (eq? v 'int) 1322 (eq? v 'long) (eq? v 'signed) (eq? v 'unsigned) 1323 (eq? v '_Bool) (eq? v 'struct) (eq? v 'union) 1324 (eq? v 'enum) (eq? v 'const) (eq? v 'volatile) 1325 (eq? v 'restrict) (eq? v 'inline)))) 1326 ((eq? (tok-kind t) 'IDENT) (typedef? ps (tok-value t))) 1327 (else #f)))) 1328 1329 (define (parse-cast-or-unary ps) 1330 (let ((t (peek2 ps))) 1331 (cond 1332 ((and (eq? (tok-kind t) 'KW) 1333 (let ((v (tok-value t))) 1334 (or (eq? v 'void) (eq? v 'char) (eq? v 'short) 1335 (eq? v 'int) (eq? v 'long) (eq? v 'signed) 1336 (eq? v 'unsigned) (eq? v '_Bool) 1337 (eq? v 'struct) (eq? v 'union) (eq? v 'enum) 1338 (eq? v 'const) (eq? v 'volatile) 1339 (eq? v 'restrict)))) 1340 (advance ps) 1341 (let* ((sp (parse-decl-spec ps)) 1342 (p (parse-declarator ps (cdr sp))) 1343 (ty (cdr p))) 1344 (expect-punct ps 'rparen) 1345 (parse-unary ps) 1346 ;; Cast operand undergoes lvalue conversion first (C semantics): 1347 ;; arrays decay to pointers, lvals become rvals. cg-cast then 1348 ;; bit-casts the resulting rval to the target type. 1349 (rval! ps) 1350 (cg-cast (ps-cg ps) ty))) 1351 ((and (eq? (tok-kind t) 'IDENT) (typedef? ps (tok-value t))) 1352 (advance ps) 1353 (let* ((sp (parse-decl-spec ps)) 1354 (p (parse-declarator ps (cdr sp))) 1355 (ty (cdr p))) 1356 (expect-punct ps 'rparen) 1357 (parse-unary ps) 1358 ;; Cast operand undergoes lvalue conversion first (C semantics): 1359 ;; arrays decay to pointers, lvals become rvals. cg-cast then 1360 ;; bit-casts the resulting rval to the target type. 1361 (rval! ps) 1362 (cg-cast (ps-cg ps) ty))) 1363 (else (advance ps) (parse-expr ps) 1364 (expect-punct ps 'rparen) 1365 (parse-postfix-rest ps))))) 1366 1367 (define (parse-postfix ps) 1368 (parse-primary ps) (parse-postfix-rest ps)) 1369 1370 (define (parse-postfix-rest ps) 1371 (let lp () 1372 (let ((t (peek ps))) 1373 (cond 1374 ((not (eq? (tok-kind t) 'PUNCT)) #t) 1375 (else 1376 (let ((v (tok-value t))) 1377 (cond 1378 ((eq? v 'lbrack) 1379 (advance ps) (rval! ps) 1380 (parse-expr ps) (rval! ps) 1381 (expect-punct ps 'rbrack) 1382 (cg-binop (ps-cg ps) 'add) 1383 (cg-push-deref (ps-cg ps)) (lp)) 1384 ((eq? v 'lparen) 1385 (advance ps) (rval-not-fn! ps) 1386 (let* ((fn-ty (call-fn-type (ps-cg ps))) 1387 (n (parse-call-args ps fn-ty)) 1388 ;; has-result? = #f for known void returns. Skips 1389 ;; the wasted ST a0 → frame-slot spill that 1390 ;; cg-call would otherwise emit for void calls. 1391 (has-result? 1392 (cond 1393 ((not fn-ty) #t) 1394 ((eq? (ctype-kind (car (ctype-ext fn-ty))) 'void) #f) 1395 (else #t)))) 1396 (expect-punct ps 'rparen) 1397 (cg-call (ps-cg ps) n has-result?) 1398 ;; Maintain parse's "one rval per expression" invariant 1399 ;; so comma / parse-expr-stmt / for-init/step pop sites 1400 ;; stay simple. The placeholder is vstack-only and 1401 ;; never materialized (cg-pop is a vstack op, no emit). 1402 (cond ((not has-result?) 1403 (cg-push-imm (ps-cg ps) %t-i32 0))) 1404 (lp))) 1405 ((eq? v 'dot) 1406 (advance ps) 1407 (let ((nt (advance ps))) 1408 (cond 1409 ((not (eq? (tok-kind nt) 'IDENT)) 1410 (die (tok-loc nt) "expected field name")) 1411 (else 1412 (cg-push-field (ps-cg ps) (tok-value nt)) (lp))))) 1413 ((eq? v 'arrow) 1414 (advance ps) 1415 (let ((nt (advance ps))) 1416 (cond 1417 ((not (eq? (tok-kind nt) 'IDENT)) 1418 (die (tok-loc nt) "expected field name")) 1419 (else 1420 ;; ptr -> field: load the pointer to rval, deref to 1421 ;; reach the struct lval, then push the field. 1422 (rval! ps) 1423 (cg-push-deref (ps-cg ps)) 1424 (cg-push-field (ps-cg ps) (tok-value nt)) (lp))))) 1425 ((eq? v 'inc) 1426 (advance ps) 1427 (cg-postinc (ps-cg ps)) (lp)) 1428 ((eq? v 'dec) 1429 (advance ps) 1430 (cg-postdec (ps-cg ps)) (lp)) 1431 (else #t)))))))) 1432 1433 ;; call-fn-type cg -> ctype-or-#f 1434 ;; The function operand sits at the top of the vstack when 1435 ;; parse-call-args runs (just after rval-not-fn!). Its type may be 1436 ;; `fn` directly (named callee) or `ptr -> fn` (function pointer). 1437 ;; Returns the underlying `fn` ctype, or #f if the operand isn't 1438 ;; recognizably callable (callsite still works — no per-arg cast). 1439 (define (call-fn-type cg) 1440 (let* ((tp (cg-top cg))) 1441 (cond 1442 ((not tp) #f) 1443 (else 1444 (let* ((ty (opnd-type tp)) 1445 (k (ctype-kind ty))) 1446 (cond 1447 ((eq? k 'fn) ty) 1448 ((eq? k 'ptr) 1449 (let ((pe (ctype-ext ty))) 1450 (cond ((and pe (eq? (ctype-kind pe) 'fn)) pe) 1451 (else #f)))) 1452 (else #f))))))) 1453 1454 ;; param-types-of fn-ty -> (params variadic?) with a #f fallback. 1455 (define (call-fn-param-info fn-ty) 1456 (cond 1457 ((not fn-ty) (cons '() #f)) 1458 (else 1459 (let ((ext (ctype-ext fn-ty))) 1460 (cons (cadr ext) (car (cddr ext))))))) 1461 1462 ;; parse-call-args ps fn-ty -> arg-count 1463 ;; Casts each fixed arg to the declared param type (CC.md §K.5). 1464 ;; For variadic args (index >= named-arg count, when variadic? = #t) 1465 ;; applies cg-promote (CC.md §G.1). 1466 (define (parse-call-args ps fn-ty) 1467 (cond 1468 ((at-punct? ps 'rparen) 0) 1469 (else 1470 (let* ((info (call-fn-param-info fn-ty)) 1471 (params (car info)) 1472 (var? (cdr info)) 1473 (nfix (length params))) 1474 (let lp ((n 0) (rem params)) 1475 (parse-expr-bp ps 4) (rval! ps) 1476 (cond 1477 ;; Fixed-arg: cast to declared param type. param entry shape 1478 ;; is (name . ctype) per cg-fn-begin's contract. 1479 ((not (null? rem)) 1480 (cg-cast (ps-cg ps) (cdr (car rem)))) 1481 ;; Variadic position (n >= nfix and var? is true): promote. 1482 (var? 1483 (cg-promote (ps-cg ps)))) 1484 (let ((m (+ n 1)) 1485 (rest (if (null? rem) '() (cdr rem)))) 1486 (cond ((at-punct? ps 'comma) (advance ps) (lp m rest)) 1487 (else m)))))))) 1488 1489 ;; -------------------------------------------------------------------- 1490 ;; __builtin_va_* (§G.2). va_list / va_start / va_arg / va_end in 1491 ;; <stdarg.h> alias these. Each is parsed as: name '(' args ')'. 1492 ;; va_start(ap, last) — last is parsed and discarded; cg only needs 1493 ;; the variadic-first-slot offset, which it already tracks. 1494 ;; va_arg(ap, T) — T is a type-name; result rval has that type. 1495 ;; va_end(ap) — no-op codegen; just consumes ap. 1496 ;; 1497 ;; Pushes a single imm 0 for va_start / va_end so they fit as 1498 ;; expression statements; va_arg pushes the rval. 1499 ;; -------------------------------------------------------------------- 1500 (define (parse-builtin-va-start ps) 1501 (advance ps) ; IDENT 1502 (expect-punct ps 'lparen) 1503 (parse-expr-bp ps 4) ; ap (must be lval) 1504 (expect-punct ps 'comma) 1505 ;; "last" is parsed for syntactic completeness then dropped — cg 1506 ;; doesn't need it; the variadic-first-slot was determined at 1507 ;; cg-fn-begin/v time. 1508 (parse-expr-bp ps 4) (cg-pop (ps-cg ps)) 1509 (expect-punct ps 'rparen) 1510 (cg-va-start (ps-cg ps)) 1511 ;; Push a placeholder rval so the call expression has a value 1512 ;; (matches va_start's "void" but our parser expects all 1513 ;; expressions to leave one rval). 1514 (cg-push-imm (ps-cg ps) %t-i32 0)) 1515 1516 (define (parse-builtin-va-arg ps) 1517 (advance ps) ; IDENT 1518 (expect-punct ps 'lparen) 1519 (parse-expr-bp ps 4) ; ap (lval) 1520 (expect-punct ps 'comma) 1521 (let* ((sp (parse-decl-spec ps)) 1522 (p (parse-declarator ps (cdr sp))) 1523 (ty (cdr p))) 1524 (expect-punct ps 'rparen) 1525 (cg-va-arg (ps-cg ps) ty))) 1526 1527 (define (parse-builtin-va-end ps) 1528 (advance ps) ; IDENT 1529 (expect-punct ps 'lparen) 1530 (parse-expr-bp ps 4) ; ap 1531 (expect-punct ps 'rparen) 1532 (cg-va-end (ps-cg ps)) 1533 (cg-push-imm (ps-cg ps) %t-i32 0)) 1534 1535 (define (parse-primary ps) 1536 (let ((t (peek ps))) 1537 (cond 1538 ((eq? (tok-kind t) 'INT) 1539 (advance ps) 1540 (cg-push-imm (ps-cg ps) %t-i32 (tok-value t))) 1541 ((eq? (tok-kind t) 'CHAR) 1542 (advance ps) 1543 (cg-push-imm (ps-cg ps) %t-i8 (tok-value t))) 1544 ((eq? (tok-kind t) 'STR) 1545 (advance ps) 1546 (cg-push-string (ps-cg ps) (tok-value t))) 1547 ((eq? (tok-kind t) 'IDENT) 1548 (cond 1549 ((bv= (tok-value t) "__builtin_va_start") 1550 (parse-builtin-va-start ps)) 1551 ((bv= (tok-value t) "__builtin_va_arg") 1552 (parse-builtin-va-arg ps)) 1553 ((bv= (tok-value t) "__builtin_va_end") 1554 (parse-builtin-va-end ps)) 1555 (else 1556 (let ((sm (scope-lookup ps (tok-value t)))) 1557 (advance ps) 1558 (cond 1559 ((not sm) (die (tok-loc t) "undecl" (tok-value t))) 1560 ((eq? (sym-kind sm) 'enum-const) 1561 (cg-push-imm (ps-cg ps) %t-i32 (sym-slot sm))) 1562 (else (cg-push-sym (ps-cg ps) sm))))))) 1563 ((eq? (tok-kind t) 'PUNCT) 1564 (cond 1565 ((eq? (tok-value t) 'lparen) 1566 (advance ps) (parse-expr ps) (expect-punct ps 'rparen)) 1567 (else (die (tok-loc t) "unexp" (tok-value t))))) 1568 (else (die (tok-loc t) "unexp" (tok-value t)))))) 1569 1570 (define (rval! ps) 1571 (let ((tp (cg-top (ps-cg ps)))) 1572 (cond ((and tp (opnd? tp) (opnd-lval? tp)) 1573 (cg-load (ps-cg ps))) 1574 (else #t)))) 1575 1576 (define (rval-not-fn! ps) 1577 (let ((tp (cg-top (ps-cg ps)))) 1578 (cond ((and tp (opnd? tp) (opnd-lval? tp) 1579 (not (ctype-is-fn? (opnd-type tp)))) 1580 (cg-load (ps-cg ps))) 1581 (else #t))))