ccgoto: fix overflows

This commit is contained in:
mehbark 2026-02-19 19:15:38 -05:00
parent a36fd874ec
commit 13f1113536
Signed by: mbk
GPG key ID: E333EC1335FFCCDB

View file

@ -146,7 +146,7 @@ operator.
The `k` that `call/cc` calls its argument with represents, roughly, the rest of the computation. The `k` that `call/cc` calls its argument with represents, roughly, the rest of the computation.
The “current continuation” is what will be executed next at the point that `call/cc` is called. The “current continuation” is what will be executed next at the point that `call/cc` is called.
Incidentally, this helps me understand schemes multiple return values; `(values v1 v2 ...)` is just `(call/cc (lambda (k) (k v1 v2 ...)))`. Incidentally, this helps me understand schemes multiple return values; `(values v1 v2 ...)` is just <code class="long">(call/cc (lambda (k) (k v1 v2 ...)))</code>.
I recommend reading about continuations in Dybvigs [<i>The Scheme Programming Language</i>](https://www.scheme.com/tspl4/further.html#g63) I recommend reading about continuations in Dybvigs [<i>The Scheme Programming Language</i>](https://www.scheme.com/tspl4/further.html#g63)
if youre (justly) dissatisfied with my explanation or just want to learn more precisely how they work and their applications. if youre (justly) dissatisfied with my explanation or just want to learn more precisely how they work and their applications.
@ -223,7 +223,12 @@ done
Ill explain this macro one part at a time. Ill explain this macro one part at a time.
First, `(define-syntax goto (syntax-rules () [...]))` defines `goto` as a syntax transformer (more precise name for a macro) using the `syntax-rules` pattern-matching language. First,
```scheme
(define-syntax goto
(syntax-rules () [...]))
```
defines `goto` as a syntax transformer (more precise name for a macro) using the `syntax-rules` pattern-matching language.
The `()` after `syntax-rules` is the empty list of literals; we don't have any special words here, so it doesn't apply. The `()` after `syntax-rules` is the empty list of literals; we don't have any special words here, so it doesn't apply.
You can read more about how `syntax-rules` works in [TSPL](https://scheme.com/tspl4/syntax.html#./syntax:s14), but we'll only be using the most basic features here. You can read more about how `syntax-rules` works in [TSPL](https://scheme.com/tspl4/syntax.html#./syntax:s14), but we'll only be using the most basic features here.
The important thing is to know that matched names are replaced in the output and that `x ...` matches/splices zero or more expressions. The important thing is to know that matched names are replaced in the output and that `x ...` matches/splices zero or more expressions.
@ -292,7 +297,12 @@ We wrap the body of `with-goto` in `(call/cc (lambda (k) ...))`.
Inside the body, if we call `k` like `(k (label))` we effectively replace the body with the result of calling `label`. Inside the body, if we call `k` like `(k (label))` we effectively replace the body with the result of calling `label`.
We accomplished a jump! We accomplished a jump!
`(set! goto (lambda (label) (k (label))))` makes `goto` do exactly this (note that function arguments have to be evaluated before the procedure call takes place). ```scheme
(set! goto
(lambda (label)
(k (label))))
```
makes `goto` do exactly this (note that function arguments have to be evaluated before the procedure call takes place).
We use `(define goto #f)` combined with a `set!` because the labels we defined earlier need to be able to see the `goto` function. We use `(define goto #f)` combined with a `set!` because the labels we defined earlier need to be able to see the `goto` function.
This is what our first `with-goto` looks like when we expand it: This is what our first `with-goto` looks like when we expand it: