boot2

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

commit 549a5f48f3b58a04b3a7784d5c76ee303a9b8962
parent 71fc4b9777dfcce9ddeb91fda7bf0f95f3059cdf
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Thu, 30 Apr 2026 09:50:32 -0700

tests/cc-pp: expand to cover stdarg shape

Diffstat:
Atests/cc-pp/40-ifdef-active-typedef-fnmacro.c | 8++++++++
Atests/cc-pp/40-ifdef-active-typedef-fnmacro.expected-toks | 16++++++++++++++++
Atests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.c | 10++++++++++
Atests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.expected-toks | 16++++++++++++++++
Atests/cc-pp/42-ccscm-stdarg-gate.expected-exit | 1+
Atests/cc-pp/42-ccscm-stdarg-gate.scm | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/tests/cc-pp/40-ifdef-active-typedef-fnmacro.c b/tests/cc-pp/40-ifdef-active-typedef-fnmacro.c @@ -0,0 +1,8 @@ +#define CCSCM 1 +#ifdef CCSCM +typedef char *T; +#define M(x) (x) +#endif + +T a; +int x = M(0); diff --git a/tests/cc-pp/40-ifdef-active-typedef-fnmacro.expected-toks b/tests/cc-pp/40-ifdef-active-typedef-fnmacro.expected-toks @@ -0,0 +1,16 @@ +(KW typedef "40-ifdef-active-typedef-fnmacro.c" 3 1) +(KW char "40-ifdef-active-typedef-fnmacro.c" 3 9) +(PUNCT star "40-ifdef-active-typedef-fnmacro.c" 3 14) +(IDENT "T" "40-ifdef-active-typedef-fnmacro.c" 3 15) +(PUNCT semi "40-ifdef-active-typedef-fnmacro.c" 3 16) +(IDENT "T" "40-ifdef-active-typedef-fnmacro.c" 7 1) +(IDENT "a" "40-ifdef-active-typedef-fnmacro.c" 7 3) +(PUNCT semi "40-ifdef-active-typedef-fnmacro.c" 7 4) +(KW int "40-ifdef-active-typedef-fnmacro.c" 8 1) +(IDENT "x" "40-ifdef-active-typedef-fnmacro.c" 8 5) +(PUNCT assign "40-ifdef-active-typedef-fnmacro.c" 8 7) +(PUNCT lparen "40-ifdef-active-typedef-fnmacro.c" 4 14) +(INT 0 "40-ifdef-active-typedef-fnmacro.c" 8 11) +(PUNCT rparen "40-ifdef-active-typedef-fnmacro.c" 4 16) +(PUNCT semi "40-ifdef-active-typedef-fnmacro.c" 8 13) +(EOF #f "40-ifdef-active-typedef-fnmacro.c" 9 1) diff --git a/tests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.c b/tests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.c @@ -0,0 +1,10 @@ +#define CCSCM 1 +#ifndef CCSCM +extern int unreachable; +#else +typedef char *T; +#define M(x) (x) +#endif + +T a; +int x = M(0); diff --git a/tests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.expected-toks b/tests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.expected-toks @@ -0,0 +1,16 @@ +(KW typedef "41-ifndef-defined-else-typedef-fnmacro.c" 5 1) +(KW char "41-ifndef-defined-else-typedef-fnmacro.c" 5 9) +(PUNCT star "41-ifndef-defined-else-typedef-fnmacro.c" 5 14) +(IDENT "T" "41-ifndef-defined-else-typedef-fnmacro.c" 5 15) +(PUNCT semi "41-ifndef-defined-else-typedef-fnmacro.c" 5 16) +(IDENT "T" "41-ifndef-defined-else-typedef-fnmacro.c" 9 1) +(IDENT "a" "41-ifndef-defined-else-typedef-fnmacro.c" 9 3) +(PUNCT semi "41-ifndef-defined-else-typedef-fnmacro.c" 9 4) +(KW int "41-ifndef-defined-else-typedef-fnmacro.c" 10 1) +(IDENT "x" "41-ifndef-defined-else-typedef-fnmacro.c" 10 5) +(PUNCT assign "41-ifndef-defined-else-typedef-fnmacro.c" 10 7) +(PUNCT lparen "41-ifndef-defined-else-typedef-fnmacro.c" 6 14) +(INT 0 "41-ifndef-defined-else-typedef-fnmacro.c" 10 11) +(PUNCT rparen "41-ifndef-defined-else-typedef-fnmacro.c" 6 16) +(PUNCT semi "41-ifndef-defined-else-typedef-fnmacro.c" 10 13) +(EOF #f "41-ifndef-defined-else-typedef-fnmacro.c" 11 1) diff --git a/tests/cc-pp/42-ccscm-stdarg-gate.expected-exit b/tests/cc-pp/42-ccscm-stdarg-gate.expected-exit @@ -0,0 +1 @@ +0 diff --git a/tests/cc-pp/42-ccscm-stdarg-gate.scm b/tests/cc-pp/42-ccscm-stdarg-gate.scm @@ -0,0 +1,54 @@ +;; tests/cc-pp/42-ccscm-stdarg-gate.scm +;; +;; cc.scm pre-defines CCSCM as an empty object macro so test fixtures +;; can wrap their stdarg.h include in `#ifndef CCSCM ... #else ... #endif` +;; and route around #include (which cc.scm rejects). This test pins +;; that contract: with CCSCM in the initial-defines table, the #include +;; in the then-branch is never processed, the else branch's typedef +;; emits its tokens, and the else branch's function-like macro is +;; registered and expanded at the call site. + +(define src + "#ifndef CCSCM\n#include <stdarg.h>\n#else\ntypedef char *va_list;\n#define va_start(ap, n) __builtin_va_start(ap, n)\n#endif\nva_list ap;\nvoid f(int n) { va_start(ap, n); }\n") + +(define ccscm (cons "CCSCM" (%macro 'obj '() '()))) +(define toks (lex-tokenize src "src.c")) +(define out (pp-expand toks (list ccscm))) + +;; Helper: fail with a status-encoded reason if `cond` is false. +(define (must cond status) + (if cond #t (sys-exit status))) + +;; #include must NOT have been processed (it would have raised die from +;; %pp-do-include and aborted with status 1 before getting here). + +;; Walk `out` and assert: the typedef line is present, ap (va_list ident) +;; is present, and the va_start expansion landed on __builtin_va_start. +(define (find-ident name toks) + (cond + ((null? toks) #f) + ((and (eq? (tok-kind (car toks)) 'IDENT) + (bv= (tok-value (car toks)) name)) + toks) + (else (find-ident name (cdr toks))))) + +(must (find-ident "va_list" out) 11) +(must (find-ident "ap" out) 12) +(must (find-ident "f" out) 13) +(must (find-ident "__builtin_va_start" out) 14) + +;; Negative: __builtin_va_start should appear (from the macro body), but +;; the literal `va_start` identifier should NOT survive expansion at the +;; call site. +(define (count-ident name toks) + (let loop ((ts toks) (n 0)) + (cond + ((null? ts) n) + ((and (eq? (tok-kind (car ts)) 'IDENT) + (bv= (tok-value (car ts)) name)) + (loop (cdr ts) (+ n 1))) + (else (loop (cdr ts) n))))) + +(must (= (count-ident "va_start" out) 0) 15) + +(sys-exit 0)