Commitcce2c6e0Recorded31 Mar 2026Repositorysigil-r7rs
Extract R7RS-small compatibility modules from sigil-stdlib
Message
Standalone package providing standard (scheme *) module paths for programs targeting the R7RS-small specification.
Changed
.gitignore | 1 +
README.md | 63 +++++++++++++++++++++++++++++++
dev-redirects.sgl | 6 +++
package.sgl | 23 ++++++++++++
src/scheme/base.sgl | 334 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/scheme/case-lambda.sgl | 11 ++++++
src/scheme/char.sgl | 41 ++++++++++++++++++++
src/scheme/cxr.sgl | 57 ++++++++++++++++++++++++++++
src/scheme/eval.sgl | 10 +++++
src/scheme/file.sgl | 23 ++++++++++++
src/scheme/inexact.sgl | 58 ++++++++++++++++++++++++++++
src/scheme/lazy.sgl | 49 ++++++++++++++++++++++++
src/scheme/load.sgl | 10 +++++
src/scheme/process-context.sgl | 18 +++++++++
src/scheme/read.sgl | 11 ++++++
src/scheme/repl.sgl | 10 +++++
src/scheme/time.sgl | 13 +++++++
src/scheme/write.sgl | 14 +++++++
18 files changed, 752 insertions(+)Diff
.gitignoreadded
@@ -0,0 +1 @@
+1
build/README.mdadded
@@ -0,0 +1,63 @@
+1
# sigil-r7rs+2
+3
R7RS-small compatibility library for [Sigil](https://codeberg.org/sigil/sigil).+4
+5
This package provides the standard `(scheme *)` module paths defined by [R7RS-small](https://small.r7rs.org/), allowing programs written against the R7RS standard library to run on Sigil without modification.+6
+7
## Modules+8
+9
| Module | R7RS Section |+10
|--------|-------------|+11
| `(scheme base)` | Core library: arithmetic, lists, strings, I/O, control flow |+12
| `(scheme case-lambda)` | Case-lambda dispatch |+13
| `(scheme char)` | Character predicates and case conversion |+14
| `(scheme cxr)` | Compositions of `car` and `cdr` |+15
| `(scheme eval)` | `eval` and `environment` |+16
| `(scheme file)` | File I/O |+17
| `(scheme inexact)` | Inexact arithmetic (`sin`, `cos`, `sqrt`, etc.) |+18
| `(scheme lazy)` | `delay`, `force`, `make-promise` |+19
| `(scheme load)` | `load` |+20
| `(scheme process-context)` | `command-line`, `exit`, environment variables |+21
| `(scheme read)` | `read` |+22
| `(scheme repl)` | `interaction-environment` |+23
| `(scheme time)` | `current-second`, `current-jiffy` |+24
| `(scheme write)` | `display`, `write`, `write-shared` |+25
+26
## Usage+27
+28
Add as a dependency in your `package.sgl`:+29
+30
```scheme+31
(define sigil-repo "codeberg:sigil/sigil")+32
+33
(package+34
...+35
dependencies: (list+36
(from-git url: "codeberg:sigil/sigil-r7rs")))+37
```+38
+39
Then import standard Scheme modules:+40
+41
```scheme+42
(import (scheme base)+43
(scheme write))+44
+45
(display "Hello from R7RS!")+46
(newline)+47
```+48
+49
## Building+50
+51
```+52
sigil build+53
```+54
+55
For local development with monorepo redirects:+56
+57
```+58
sigil build --redirects dev-redirects.sgl+59
```+60
+61
## License+62
+63
BSD-3-Clausedev-redirects.sgladded
@@ -0,0 +1,6 @@
+1
;; Development redirects — point dependencies at local checkouts+2
(redirects+3
repos: (list+4
(for-repo+5
url: "codeberg:sigil/sigil"+6
use: (from-path dir: "../sigil"))))package.sgladded
@@ -0,0 +1,23 @@
+1
(define sigil-repo "codeberg:sigil/sigil")+2
+3
(package+4
name: "sigil-r7rs"+5
version: "0.9.0"+6
description: "R7RS-small compatibility library for Sigil"+7
url: "https://codeberg.org/sigil/sigil-r7rs"+8
license: "BSD-3-Clause"+9
authors: (list "David Wilson <[email protected]>")+10
+11
configs: (list+12
(config name: 'dev output-dir: "build/dev" debug?: #t optimize: 0)+13
(config name: 'release output-dir: "build/release" debug?: #f optimize: 2))+14
+15
dependencies: (list+16
(from-git url: sigil-repo package: "sigil-stdlib"))+17
+18
tasks: (list+19
(task+20
name: 'build+21
description: "Compile R7RS compatibility modules"+22
steps: (list+23
(compile-sigil-modules sources: "src/**/*.sgl")))))src/scheme/base.sgladded
@@ -0,0 +1,334 @@
+1
;;; (scheme base) - R7RS Base Library+2
;;;+3
;;; The core R7RS library containing fundamental procedures, syntax, and values.+4
;;; This provides the standard Scheme interface for portable code.+5
;;;+6
;;; See: [R7RS Small](https://small.r7rs.org/) §6.1-6.14+7
;;;+8
;;; For Sigil-specific extensions, use `(sigil core)` instead.+9
+10
(define-library (scheme base)+11
(import (sigil io)+12
(sigil math)+13
(sigil string)+14
(sigil list)+15
(sigil core)+16
(srfi srfi-9))+17
(export+18
;; Equivalence predicates+19
eq?+20
eqv?+21
equal?+22
+23
;; Booleans+24
not+25
boolean?+26
boolean=?+27
+28
;; Pairs and lists+29
pair?+30
cons+31
car+32
cdr+33
set-car!+34
set-cdr!+35
caar cadr cdar cddr+36
null?+37
list?+38
list+39
make-list+40
length+41
append+42
reverse+43
list-ref+44
list-tail+45
list-set!+46
memq+47
memv+48
member+49
assq+50
assv+51
assoc+52
list-copy+53
map+54
for-each+55
+56
;; Symbols+57
symbol?+58
symbol=?+59
symbol->string+60
string->symbol+61
+62
;; Numbers+63
number?+64
integer?+65
exact-integer?+66
real?+67
exact?+68
inexact?+69
exact+70
inexact+71
=+72
<+73
>+74
<=+75
>=+76
zero?+77
positive?+78
negative?+79
odd?+80
even?+81
max+82
min+83
++84
-+85
*+86
/+87
abs+88
floor+89
ceiling+90
truncate+91
round+92
quotient+93
remainder+94
modulo+95
gcd+96
lcm+97
expt+98
square+99
floor-quotient+100
floor-remainder+101
floor/+102
truncate-quotient+103
truncate-remainder+104
truncate/+105
number->string+106
string->number+107
+108
;; Characters+109
char?+110
char=?+111
char<?+112
char>?+113
char<=?+114
char>=?+115
char->integer+116
integer->char+117
+118
;; Strings+119
string?+120
make-string+121
string+122
string-length+123
string-ref+124
string-set!+125
string=?+126
string<?+127
string>?+128
string<=?+129
string>=?+130
substring+131
string-append+132
string-copy+133
string-copy!+134
string-fill!+135
string-upcase+136
string-downcase+137
string-foldcase+138
string->list+139
list->string+140
string-for-each+141
string-map+142
vector->string+143
string->vector+144
+145
;; Vectors+146
vector?+147
make-vector+148
vector+149
vector-length+150
vector-ref+151
vector-set!+152
vector->list+153
list->vector+154
vector-copy+155
vector-copy!+156
vector-fill!+157
vector-for-each+158
vector-map+159
+160
;; Bytevectors+161
bytevector?+162
make-bytevector+163
bytevector+164
bytevector-length+165
bytevector-u8-ref+166
bytevector-u8-set!+167
bytevector-copy+168
bytevector-copy!+169
bytevector-append+170
utf8->string+171
string->utf8+172
+173
;; Control features+174
procedure?+175
apply+176
call-with-current-continuation+177
call/cc+178
values+179
call-with-values+180
dynamic-wind+181
+182
;; Multiple values+183
let-values+184
let*-values+185
define-values+186
+187
;; Exceptions+188
error+189
error-object?+190
error-object-message+191
error-object-irritants+192
error-object-type+193
file-error?+194
read-error?+195
raise+196
raise-continuable+197
guard+198
with-exception-handler+199
+200
;; I/O+201
input-port?+202
output-port?+203
textual-port?+204
binary-port?+205
port?+206
current-input-port+207
current-output-port+208
current-error-port+209
close-port+210
close-input-port+211
close-output-port+212
port-open?+213
input-port-open?+214
output-port-open?+215
open-input-string+216
open-output-string+217
get-output-string+218
flush-output-port+219
read-char+220
peek-char+221
read-line+222
read-string+223
read-u8+224
peek-u8+225
write-u8+226
read-bytevector+227
read-bytevector!+228
write-bytevector+229
open-input-bytevector+230
open-output-bytevector+231
get-output-bytevector+232
char-ready?+233
u8-ready?+234
write-char+235
write-string+236
newline+237
eof-object+238
eof-object?+239
call-with-port+240
+241
;; Parameters+242
make-parameter+243
parameterize+244
+245
;; System+246
features+247
+248
;; Syntax+249
define+250
define-syntax+251
define-record-type+252
lambda+253
if+254
cond+255
case+256
and+257
or+258
when+259
unless+260
let+261
let*+262
letrec+263
letrec*+264
begin+265
do+266
set!+267
quote+268
quasiquote+269
unquote+270
unquote-splicing+271
syntax-rules)+272
+273
;; Most bindings come from the prelude and native builtins.+274
;; Module-scoped bindings are re-exported from (sigil math), (sigil string),+275
;; (sigil io), and (sigil core).+276
+277
(begin+278
;; R7RS requires multi-list map and for-each.+279
;; The prelude provides single-list versions, so we wrap list-map/list-for-each.+280
(define (map proc lst . rest)+281
(apply list-map proc lst rest))+282
+283
(define (for-each proc lst . rest)+284
(apply list-for-each proc lst rest))+285
+286
;; R7RS real? - in Sigil all numbers are real (no complex numbers)+287
(define real? number?)+288
+289
;; R7RS boolean=? - test if all arguments are booleans with the same value+290
(define (boolean=? b1 b2 . rest)+291
(and (boolean? b1)+292
(boolean? b2)+293
(eq? b1 b2)+294
(or (null? rest)+295
(let loop ((prev b2) (args rest))+296
(or (null? args)+297
(and (boolean? (car args))+298
(eq? prev (car args))+299
(loop (car args) (cdr args))))))))+300
+301
;; R7RS symbol=? - test if all arguments are the same symbol+302
(define (symbol=? s1 s2 . rest)+303
(and (symbol? s1)+304
(symbol? s2)+305
(eq? s1 s2)+306
(or (null? rest)+307
(let loop ((prev s2) (args rest))+308
(or (null? args)+309
(and (symbol? (car args))+310
(eq? prev (car args))+311
(loop (car args) (cdr args))))))))+312
+313
;; R7RS list-tail - return the sublist after skipping k elements+314
(define (list-tail lst k)+315
(if (zero? k)+316
lst+317
(list-tail (cdr lst) (- k 1))))+318
+319
;; R7RS list-set! - mutate the k-th element of a list+320
(define (list-set! lst k val)+321
(set-car! (list-tail lst k) val))+322
+323
;; R7RS list-copy - shallow copy of a list+324
(define (list-copy lst)+325
(if (pair? lst)+326
(cons (car lst) (list-copy (cdr lst)))+327
lst))+328
+329
;; R7RS input-port-open? / output-port-open?+330
(define (input-port-open? port)+331
(and (input-port? port) (port-open? port)))+332
+333
(define (output-port-open? port)+334
(and (output-port? port) (port-open? port)))))src/scheme/case-lambda.sgladded
@@ -0,0 +1,11 @@
+1
;;; (scheme case-lambda) - R7RS Case-Lambda Library+2
;;;+3
;;; Define procedures that dispatch on argument count. Each clause specifies+4
;;; a different arity with its own parameter list and body.+5
;;;+6
;;; See: [R7RS Small](https://small.r7rs.org/) §4.2.9+7
+8
(define-library (scheme case-lambda)+9
(export case-lambda))+10
+11
;;; case-lambda is a syntax provided by the prelude.src/scheme/char.sgladded
@@ -0,0 +1,41 @@
+1
;;; (scheme char) - R7RS Character Library+2
;;;+3
;;; Character comparison and conversion procedures.+4
;;;+5
;;; See: [R7RS Small](https://small.r7rs.org/) §6.6+6
+7
(define-library (scheme char)+8
(import (sigil string))+9
(export char=?+10
char<?+11
char>?+12
char<=?+13
char>=?+14
char->integer+15
integer->char+16
char-alphabetic?+17
char-numeric?+18
char-whitespace?+19
char-upper-case?+20
char-lower-case?+21
char-upcase+22
char-downcase+23
char-foldcase+24
digit-value+25
char-ci=?+26
char-ci<?+27
char-ci>?+28
char-ci<=?+29
char-ci>=?+30
string-upcase+31
string-downcase+32
string-foldcase+33
string-ci=?+34
string-ci<?+35
string-ci>?+36
string-ci<=?+37
string-ci>=?))+38
+39
;;; Character and string classification/comparison.+40
;;; Native builtins provide char predicates and case conversion.+41
;;; String CI comparisons come from (sigil string).src/scheme/cxr.sgladded
@@ -0,0 +1,57 @@
+1
;;; (scheme cxr) - R7RS CXR Library+2
;;;+3
;;; Extended car/cdr accessor procedures for nested pair structures.+4
;;; Provides all compositions of `car` and `cdr` from three to four levels deep+5
;;; (e.g., `caaddr`, `cddddr`).+6
;;;+7
;;; For basic two-level accessors (`caar`, `cadr`, `cdar`, `cddr`), use+8
;;; `(scheme base)` or the prelude.+9
;;;+10
;;; See: [R7RS Small](https://small.r7rs.org/) §6.4+11
+12
(define-library (scheme cxr)+13
(export+14
;; Three-level accessors+15
caaar caadr cadar caddr+16
cdaar cdadr cddar cdddr+17
;; Four-level accessors+18
caaaar caaadr caadar caaddr+19
cadaar cadadr caddar cadddr+20
cdaaar cdaadr cdadar cdaddr+21
cddaar cddadr cdddar cddddr)+22
+23
(begin+24
+25
;; ============================================================+26
;; Three-level accessors+27
;; ============================================================+28
+29
(define (caaar x) (car (car (car x))))+30
(define (caadr x) (car (car (cdr x))))+31
(define (cadar x) (car (cdr (car x))))+32
(define (caddr x) (car (cdr (cdr x))))+33
(define (cdaar x) (cdr (car (car x))))+34
(define (cdadr x) (cdr (car (cdr x))))+35
(define (cddar x) (cdr (cdr (car x))))+36
(define (cdddr x) (cdr (cdr (cdr x))))+37
+38
;; ============================================================+39
;; Four-level accessors+40
;; ============================================================+41
+42
(define (caaaar x) (car (car (car (car x)))))+43
(define (caaadr x) (car (car (car (cdr x)))))+44
(define (caadar x) (car (car (cdr (car x)))))+45
(define (caaddr x) (car (car (cdr (cdr x)))))+46
(define (cadaar x) (car (cdr (car (car x)))))+47
(define (cadadr x) (car (cdr (car (cdr x)))))+48
(define (caddar x) (car (cdr (cdr (car x)))))+49
(define (cadddr x) (car (cdr (cdr (cdr x)))))+50
(define (cdaaar x) (cdr (car (car (car x)))))+51
(define (cdaadr x) (cdr (car (car (cdr x)))))+52
(define (cdadar x) (cdr (car (cdr (car x)))))+53
(define (cdaddr x) (cdr (car (cdr (cdr x)))))+54
(define (cddaar x) (cdr (cdr (car (car x)))))+55
(define (cddadr x) (cdr (cdr (car (cdr x)))))+56
(define (cdddar x) (cdr (cdr (cdr (car x)))))+57
(define (cddddr x) (cdr (cdr (cdr (cdr x)))))))src/scheme/eval.sgladded
@@ -0,0 +1,10 @@
+1
;;; (scheme eval) - R7RS Eval Library+2
;;;+3
;;; Runtime evaluation of Scheme expressions.+4
;;;+5
;;; See: [R7RS Small](https://small.r7rs.org/) §6.12+6
+7
(define-library (scheme eval)+8
(export eval))+9
+10
;;; eval is provided as a native builtin.src/scheme/file.sgladded
@@ -0,0 +1,23 @@
+1
;;; (scheme file) - R7RS File Library+2
;;;+3
;;; File input/output operations for opening, reading, and writing files.+4
;;;+5
;;; See: [R7RS Small](https://small.r7rs.org/) §6.13.1+6
;;;+7
;;; For extended filesystem operations (directories, globs, metadata),+8
;;; use `(sigil fs)` instead.+9
+10
(define-library (scheme file)+11
(import (sigil io))+12
(export call-with-input-file+13
call-with-output-file+14
with-input-from-file+15
with-output-to-file+16
open-input-file+17
open-output-file+18
open-binary-input-file+19
open-binary-output-file+20
file-exists?+21
delete-file))+22
+23
;;; File operations are provided by (sigil io) and native builtins.src/scheme/inexact.sgladded
@@ -0,0 +1,58 @@
+1
;;; (scheme inexact) - R7RS Inexact Library+2
;;;+3
;;; Mathematical functions for inexact (floating-point) numbers including+4
;;; trigonometric, exponential, and logarithmic operations.+5
;;;+6
;;; See: [R7RS Small](https://small.r7rs.org/) §6.2.6+7
+8
(define-library (scheme inexact)+9
(export exp+10
log+11
sin+12
cos+13
tan+14
asin+15
acos+16
atan+17
sqrt+18
finite?+19
infinite?+20
nan?)+21
+22
(begin+23
;;; Test if a number is finite.+24
;;;+25
;;; Returns `#t` if the number is neither infinite nor NaN.+26
;;;+27
;;; ```scheme+28
;;; (finite? 42) ; => #t+29
;;; (finite? 3.14) ; => #t+30
;;; (finite? +inf.0) ; => #f+31
;;; (finite? +nan.0) ; => #f+32
;;; ```+33
(%set-docstring! finite?)+34
+35
;;; Test if a number is infinite.+36
;;;+37
;;; Returns `#t` if the number is positive or negative infinity.+38
;;;+39
;;; ```scheme+40
;;; (infinite? +inf.0) ; => #t+41
;;; (infinite? -inf.0) ; => #t+42
;;; (infinite? 42) ; => #f+43
;;; (infinite? +nan.0) ; => #f+44
;;; ```+45
(%set-docstring! infinite?)+46
+47
;;; Test if a number is NaN (not a number).+48
;;;+49
;;; Returns `#t` if the number is the special NaN value, which results+50
;;; from undefined operations like `(/ 0.0 0.0)`.+51
;;;+52
;;; ```scheme+53
;;; (nan? +nan.0) ; => #t+54
;;; (nan? (/ 0.0 0.0)) ; => #t+55
;;; (nan? 42) ; => #f+56
;;; (nan? +inf.0) ; => #f+57
;;; ```+58
(%set-docstring! nan?)))src/scheme/lazy.sgladded
@@ -0,0 +1,49 @@
+1
;;; (scheme lazy) - R7RS Lazy Evaluation Library+2
;;;+3
;;; Lazy evaluation with promises. Defer computation until explicitly needed+4
;;; with `force`. Promises cache their result so repeated forcing is efficient.+5
;;;+6
;;; See: [R7RS Small](https://small.r7rs.org/) §4.2.5+7
+8
(define-library (scheme lazy)+9
(export delay+10
delay-force+11
force+12
make-promise+13
promise?)+14
+15
(begin+16
;; delay and delay-force are syntaxes provided by the prelude+17
+18
;;; Force evaluation of a promise.+19
;;;+20
;;; If the promise has not been forced before, evaluates its expression+21
;;; and caches the result. Returns the cached value on subsequent calls.+22
;;;+23
;;; ```scheme+24
;;; (define p (delay (begin (display "computing...") 42)))+25
;;; (force p) ; prints "computing...", returns 42+26
;;; (force p) ; returns 42 (no output, cached)+27
;;; ```+28
(%set-docstring! force)+29
+30
;;; Create a promise from an already-computed value.+31
;;;+32
;;; Unlike `delay`, does not defer computation. The value is stored+33
;;; immediately.+34
;;;+35
;;; ```scheme+36
;;; (define p (make-promise 42))+37
;;; (force p) ; => 42+38
;;; (promise? p) ; => #t+39
;;; ```+40
(%set-docstring! make-promise)+41
+42
;;; Test if an object is a promise.+43
;;;+44
;;; ```scheme+45
;;; (promise? (delay 42)) ; => #t+46
;;; (promise? (make-promise 1)) ; => #t+47
;;; (promise? 42) ; => #f+48
;;; ```+49
(%set-docstring! promise?)))src/scheme/load.sgladded
@@ -0,0 +1,10 @@
+1
;;; (scheme load) - R7RS Load Library+2
;;;+3
;;; Load and evaluate Scheme source files at runtime.+4
;;;+5
;;; See: [R7RS Small](https://small.r7rs.org/) §6.12+6
+7
(define-library (scheme load)+8
(export load))+9
+10
;;; load is provided as a native builtin.src/scheme/process-context.sgladded
@@ -0,0 +1,18 @@
+1
;;; (scheme process-context) - R7RS Process-Context Library+2
;;;+3
;;; Access to the program's calling context: command-line arguments,+4
;;; environment variables, and process termination.+5
;;;+6
;;; See: [R7RS Small](https://small.r7rs.org/) §6.14+7
+8
(define-library (scheme process-context)+9
(import (sigil process))+10
(export command-line+11
exit+12
emergency-exit+13
get-environment-variable+14
get-environment-variables)+15
+16
(begin+17
;; R7RS name for getenv+18
(define get-environment-variable getenv)))src/scheme/read.sgladded
@@ -0,0 +1,11 @@
+1
;;; (scheme read) - R7RS Read Library+2
;;;+3
;;; Parse S-expressions from input ports.+4
;;;+5
;;; See: [R7RS Small](https://small.r7rs.org/) §6.13.2+6
+7
(define-library (scheme read)+8
(import (sigil io))+9
(export read))+10
+11
;;; read is provided by (sigil io).src/scheme/repl.sgladded
@@ -0,0 +1,10 @@
+1
;;; (scheme repl) - R7RS REPL Library+2
;;;+3
;;; Provides the interaction environment for use with eval.+4
;;;+5
;;; See: [R7RS Small](https://small.r7rs.org/) §6.12+6
+7
(define-library (scheme repl)+8
(export interaction-environment))+9
+10
;;; interaction-environment is a native builtin.src/scheme/time.sgladded
@@ -0,0 +1,13 @@
+1
;;; (scheme time) - R7RS Time Library+2
;;;+3
;;; Access to time-related values. Provides the current time in seconds+4
;;; since an epoch, a monotonic counter in jiffies, and the resolution+5
;;; of the jiffy counter.+6
;;;+7
;;; See: [R7RS Small](https://small.r7rs.org/) §6.14+8
+9
(define-library (scheme time)+10
(import (sigil time))+11
(export current-second+12
current-jiffy+13
jiffies-per-second))src/scheme/write.sgladded
@@ -0,0 +1,14 @@
+1
;;; (scheme write) - R7RS Write Library+2
;;;+3
;;; Output procedures for displaying and writing Scheme values.+4
;;;+5
;;; See: [R7RS Small](https://small.r7rs.org/) §6.13.3+6
+7
(define-library (scheme write)+8
(export display+9
write+10
write-shared+11
write-simple+12
newline))+13
+14
;;; display, write, write-shared, write-simple, and newline are native builtins.