boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

commit 09de1d17f8f599531493ac4e43f680b88154f128
parent 5947945ef1b00beb0744635095b6e1a6259a6a2a
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Fri,  1 May 2026 18:48:04 -0700

merge: lex/pp bug fixes (4 bugs)

Diffstat:
Mcc/cc.scm | 72+++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Atests/cc-pp/50-stringize-char-special.c | 2++
Atests/cc-pp/50-stringize-char-special.expected-toks | 2++
Atests/cc-pp/52-digraph-hash-directive.c | 2++
Atests/cc-pp/52-digraph-hash-directive.expected-toks | 2++
Atests/cc-pp/53-line-directive-effect.c | 4++++
Atests/cc-pp/53-line-directive-effect.expected-toks | 4++++
Atests/cc-pp/54-elif-after-else.c | 7+++++++
Atests/cc-pp/54-elif-after-else.expected-exit | 1+
9 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/cc/cc.scm b/cc/cc.scm @@ -1651,7 +1651,12 @@ (else (let* ((r (%lex-read-punct src pos1 line1 col1 file)) (tok (car r)) (rest (cdr r))) - (set! kind 'PUNCT) (set! val (tok-value tok)) + ;; Line-leading `%:` digraph also acts as HASH for directives. + (cond + ((and bol? (eq? (tok-value tok) 'hash)) + (set! kind 'HASH)) + (else + (set! kind 'PUNCT) (set! val (tok-value tok)))) (set! npos (car rest)) (set! nline (car (cdr rest))) (set! ncol (car (cdr (cdr rest)))))))))) @@ -1769,19 +1774,22 @@ (bv= name %pp-bv-STDC-VERSION) (bv= name %pp-bv-STDC-HOSTED))) (define (%pp-expand-builtin name loc state) + ;; Emit the token at the ORIGINAL loc; %pp-relocate downstream will + ;; apply pps-cur-file / pps-line-delta. Doing the rewrite here too + ;; (then letting relocate re-apply it) double-shifts __LINE__'s loc. + ;; The VALUE of __LINE__ / __FILE__ already reflects the post-#line + ;; mapping because we compute `file`/`line` from cur-file/line-delta. (let* ((file (or (pps-cur-file state) (loc-file loc))) - (line (+ (loc-line loc) (pps-line-delta state))) - (col (loc-col loc)) - (here (%loc file line col))) + (line (+ (loc-line loc) (pps-line-delta state)))) (cond - ((bv= name %pp-bv-FILE) (list (%tok 'STR file here '()))) - ((bv= name %pp-bv-LINE) (list (%tok 'INT line here '()))) - ((bv= name %pp-bv-STDC) (list (%tok 'INT 1 here '()))) - ((bv= name %pp-bv-LISPCC) (list (%tok 'INT 1 here '()))) - ((bv= name %pp-bv-DATE) (list (%tok 'STR %pp-bv-DATE-VALUE here '()))) - ((bv= name %pp-bv-TIME) (list (%tok 'STR %pp-bv-TIME-VALUE here '()))) - ((bv= name %pp-bv-STDC-VERSION) (list (%tok 'INT 199901 here '()))) - ((bv= name %pp-bv-STDC-HOSTED) (list (%tok 'INT 1 here '()))) + ((bv= name %pp-bv-FILE) (list (%tok 'STR file loc '()))) + ((bv= name %pp-bv-LINE) (list (%tok 'INT line loc '()))) + ((bv= name %pp-bv-STDC) (list (%tok 'INT 1 loc '()))) + ((bv= name %pp-bv-LISPCC) (list (%tok 'INT 1 loc '()))) + ((bv= name %pp-bv-DATE) (list (%tok 'STR %pp-bv-DATE-VALUE loc '()))) + ((bv= name %pp-bv-TIME) (list (%tok 'STR %pp-bv-TIME-VALUE loc '()))) + ((bv= name %pp-bv-STDC-VERSION) (list (%tok 'INT 199901 loc '()))) + ((bv= name %pp-bv-STDC-HOSTED) (list (%tok 'INT 1 loc '()))) (else (die loc "internal: not a builtin" name))))) ;; --- buf-list: simple reversed-list buffer of toks --- @@ -2072,32 +2080,42 @@ (else (cons (car al) (%pp-alist-drop key (cdr al)))))) ;; --- #if / #ifdef / #ifndef / #elif / #else / #endif --- +;; cond-stack frame: (active? taken? else?). active? gates the body +;; until the next #elif/#else/#endif; taken? records whether ANY arm +;; (the original #if branch or any #elif) has matched, so later arms +;; stay inactive; else? records that we have already passed an #else +;; in this frame, so a subsequent #elif/#else is rejected. +(define (%pp-frame a? t? e?) (list a? t? e?)) +(define (%pp-frame-active? f) (car f)) +(define (%pp-frame-taken? f) (car (cdr f))) +(define (%pp-frame-else? f) (car (cdr (cdr f)))) + (define (%pp-do-if line state) (cond ((not (%pp-active? state)) - (pps-cond-stack-set! state (cons (cons #f #f) (pps-cond-stack state)))) + (pps-cond-stack-set! state (cons (%pp-frame #f #f #f) (pps-cond-stack state)))) (else (let* ((v (pp-eval-cexpr line (pps-macros state))) (a? (not (= v 0)))) - (pps-cond-stack-set! state (cons (cons a? a?) (pps-cond-stack state))))))) + (pps-cond-stack-set! state (cons (%pp-frame a? a? #f) (pps-cond-stack state))))))) (define (%pp-do-ifdef line state) (cond ((not (%pp-active? state)) - (pps-cond-stack-set! state (cons (cons #f #f) (pps-cond-stack state)))) + (pps-cond-stack-set! state (cons (%pp-frame #f #f #f) (pps-cond-stack state)))) (else (let ((d? (%pp-defined? (%pp-name-of-single line) state))) (pps-cond-stack-set! state - (cons (cons d? d?) (pps-cond-stack state))))))) + (cons (%pp-frame d? d? #f) (pps-cond-stack state))))))) (define (%pp-do-ifndef line state) (cond ((not (%pp-active? state)) - (pps-cond-stack-set! state (cons (cons #f #f) (pps-cond-stack state)))) + (pps-cond-stack-set! state (cons (%pp-frame #f #f #f) (pps-cond-stack state)))) (else (let ((a? (not (%pp-defined? (%pp-name-of-single line) state)))) (pps-cond-stack-set! state - (cons (cons a? a?) (pps-cond-stack state))))))) + (cons (%pp-frame a? a? #f) (pps-cond-stack state))))))) (define (%pp-name-of-single line) (cond @@ -2117,16 +2135,18 @@ ((null? cs) (die #f "#elif outside #if")) (else (let* ((top (car cs)) (rest (cdr cs)) - (taken? (cdr top)) + (taken? (%pp-frame-taken? top)) + (else? (%pp-frame-else? top)) (par? (%pp-parent-active? state))) (cond + (else? (die #f "#elif after #else")) ((or (not par?) taken?) - (pps-cond-stack-set! state (cons (cons #f taken?) rest))) + (pps-cond-stack-set! state (cons (%pp-frame #f taken? #f) rest))) (else (let* ((v (pp-eval-cexpr line (pps-macros state))) (a? (not (= v 0)))) (pps-cond-stack-set! state - (cons (cons a? (or a? taken?)) rest)))))))))) + (cons (%pp-frame a? (or a? taken?) #f) rest)))))))))) (define (%pp-do-else line state) (let ((cs (pps-cond-stack state))) @@ -2134,15 +2154,17 @@ ((null? cs) (die #f "#else outside #if")) (else (let* ((top (car cs)) (rest (cdr cs)) - (taken? (cdr top)) + (taken? (%pp-frame-taken? top)) + (else? (%pp-frame-else? top)) (par? (%pp-parent-active? state))) (cond + (else? (die #f "#else after #else")) ((not par?) - (pps-cond-stack-set! state (cons (cons #f taken?) rest))) + (pps-cond-stack-set! state (cons (%pp-frame #f taken? #t) rest))) (taken? - (pps-cond-stack-set! state (cons (cons #f #t) rest))) + (pps-cond-stack-set! state (cons (%pp-frame #f #t #t) rest))) (else - (pps-cond-stack-set! state (cons (cons #t #t) rest))))))))) + (pps-cond-stack-set! state (cons (%pp-frame #t #t #t) rest))))))))) (define (%pp-do-endif line state) (let ((cs (pps-cond-stack state))) diff --git a/tests/cc-pp/50-stringize-char-special.c b/tests/cc-pp/50-stringize-char-special.c @@ -0,0 +1,2 @@ +#define S(x) #x +S('\n') diff --git a/tests/cc-pp/50-stringize-char-special.expected-toks b/tests/cc-pp/50-stringize-char-special.expected-toks @@ -0,0 +1,2 @@ +(STR "'\\n'" "50-stringize-char-special.c" 1 14) +(EOF #f "50-stringize-char-special.c" 3 1) diff --git a/tests/cc-pp/52-digraph-hash-directive.c b/tests/cc-pp/52-digraph-hash-directive.c @@ -0,0 +1,2 @@ +%:define FOO 7 +FOO diff --git a/tests/cc-pp/52-digraph-hash-directive.expected-toks b/tests/cc-pp/52-digraph-hash-directive.expected-toks @@ -0,0 +1,2 @@ +(INT 7 "52-digraph-hash-directive.c" 1 14) +(EOF #f "52-digraph-hash-directive.c" 3 1) diff --git a/tests/cc-pp/53-line-directive-effect.c b/tests/cc-pp/53-line-directive-effect.c @@ -0,0 +1,4 @@ +__LINE__ +#line 100 "x.c" +__LINE__ +__FILE__ diff --git a/tests/cc-pp/53-line-directive-effect.expected-toks b/tests/cc-pp/53-line-directive-effect.expected-toks @@ -0,0 +1,4 @@ +(INT 1 "53-line-directive-effect.c" 1 1) +(INT 100 "x.c" 100 1) +(STR "x.c" "x.c" 101 1) +(EOF #f "53-line-directive-effect.c" 5 1) diff --git a/tests/cc-pp/54-elif-after-else.c b/tests/cc-pp/54-elif-after-else.c @@ -0,0 +1,7 @@ +#if 0 +1 +#else +2 +#elif 1 +3 +#endif diff --git a/tests/cc-pp/54-elif-after-else.expected-exit b/tests/cc-pp/54-elif-after-else.expected-exit @@ -0,0 +1 @@ +1