I mean that an R7RS program (the same is true for R6RS) has initially an empty top-level environment and at least one `import' clause is needed at the beginning. (Which also means that the `import' clause is not part of the actual program because `import' is not resolved by looking it up in the top-level environment but just part of the static top-level program structure.) In particular, `cond-expand' won't be bound before `(scheme base)' is imported. But then it is already too late because the existence of `(scheme base)' would have been assumed. A second problem with R7RS's `cond-expand' at expression level is that it is not well-specified. The R7RS gives a definition as a hygienic macro but this doesn't make any sense because it would mean that even the library name parts would be matched hygienically.
What is well-defined and what works in R7RS is `cond-expand' as part of a library definition.
So because of the above, I have written that the "script" executed by `scheme-script-ce' won't neither be a top-level R6RS nor a top-level R7RS program (nor a library) but of a new type of source, which I am going to call "ce-script" for brevity. A ce-script has to be parsed and interpreted by `scheme-script-ce' and can then expand into a top-level program (with or without accompanying libraries) of a supported implementation. This means that we have some freedom in specifying ce-scripts because we don't have to use the common denominator of all Scheme standards we want to support. For example, we could even allow library definitions for helper libraries in the script.
A ce-script should have a more flexible syntax than that of a list of external representations of Scheme datums. In particular, it shouldn't be read using `read'. The problem is that lexical extensions would otherwise cause problems:
(cond-expand
((foo-scheme)
##foo)
(else
...)))
Here, the implementation for a hypothetical "foo-scheme" wants to make use of special lexical syntax, namely `##foo', of which `scheme-script-ce' may have no idea so that the above cannot work. A similar problem occurs when we want to mix R6RS and R7RS versions of a program; in the R6RS version, `#vu8(' is used to introduce bytevectors vs. `#u8' for the R7RS world.
So what we do need is a capability of raw textual substitution in ce-scripts, e.g. as follows:
#!/usr/bin/env scheme-script-ce
(cond-expand
((foo-scheme)
(include-chunk <<foo>>))
(else
...))
#!eof
<<foo>>=
##foo
@
Here, I have used special lexical syntax (to be understood by `scheme-script-ce') to mark the end of the list of external representations of Scheme datums. Afterward, chunks in the style of the "noweb" program follow. (I have used its syntax just for demonstration purposes so that I didn't have to invent my own.)
`include-chunk' will insert the referenced text into the final program that is fed by `scheme-script-ce' to a supported implementation.