Skip to content

Commit 5968f71

Browse files
committed
Implementing &continuation
1 parent cc03165 commit 5968f71

File tree

5 files changed

+79
-4
lines changed

5 files changed

+79
-4
lines changed

lib/core/conditions.scm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545

4646
&syntax-case syntax-case-condition?
4747
&syntax-pattern syntax-pattern-condition? condition-syntax-pattern
48+
49+
&continuation make-continuation-violation
50+
continuation-violation? continuation-violation-prompt-tag
4851
;; NB: we might want to use different type of mechanism of
4952
;; tracing stack trace, so don't export it for now.
5053
;; &stack-trace stack-trace-condition?
@@ -116,6 +119,8 @@
116119
(initialize-builtin-condition &syntax-case &condition)
117120
(initialize-builtin-condition &syntax-pattern &syntax-case pattern)
118121

122+
(initialize-builtin-condition &continuation &violation prompt-tag)
123+
119124
(define (condition-predicate rtd)
120125
(let ((class (slot-ref rtd 'class)))
121126
(lambda (o)
@@ -178,6 +183,9 @@
178183
(define condition-syntax-pattern
179184
(condition-accessor (record-type-rtd &syntax-pattern) &syntax-pattern))
180185

186+
(define continuation-violation-prompt-tag
187+
(condition-accessor (record-type-rtd &continuation)
188+
&continuation-violation-prompt-tag))
181189
(define-syntax define-condition-type
182190
(lambda (x)
183191
(syntax-case x ()

src/exceptions.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,7 @@ SG_DEFINE_BASE_CLASS(Sg_ViolationClass, SgCondition,
210210
condition0_printer, NULL, NULL, Sg_ConditionAllocate,
211211
serious_cpl);
212212
static SgClass *violation_cpl[] = {
213-
SG_CLASS_VIOLATION,
214-
SG_CLASS_SERIOUS,
215-
SG_CLASS_CONDITION,
216-
SG_CLASS_TOP,
213+
SG_VIOLATION_CPL,
217214
NULL
218215
};
219216
SG_DEFINE_BASE_CLASS(Sg_AssertionClass, SgCondition,

src/sagittarius/private/exceptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,13 @@ typedef struct SgSyntaxPatternConditionRec
340340
SG_CLASS_CONDITION, \
341341
SG_CLASS_TOP \
342342

343+
#define SG_VIOLATION_CPL \
344+
SG_CLASS_VIOLATION, \
345+
SG_CLASS_SERIOUS, \
346+
SG_CLASS_CONDITION, \
347+
SG_CLASS_TOP
348+
349+
343350
#define SG_DEFINE_CONDITION_ALLOCATOR(name, type) \
344351
static SgObject name(SgClass *klass, SgObject initargs) { \
345352
type *c = SG_ALLOCATE(type, klass); \

src/sagittarius/private/vm.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@
4444

4545
SG_CLASS_DECL(Sg_BoxClass);
4646
SG_CLASS_DECL(Sg_VMClass);
47+
/* &continuation */
48+
SG_CLASS_DECL(Sg_ContinuationViolationClass);
4749

4850
#define SG_CLASS_BOX (&Sg_BoxClass)
4951
#define SG_CLASS_VM (&Sg_VMClass)
52+
#define SG_CLASS_CONTINUATION_VIOLATION (&Sg_ContinuationViolationClass)
5053

5154
struct SgBoxRec
5255
{
@@ -57,6 +60,16 @@ struct SgBoxRec
5760
#define SG_BOX(obj) ((SgBox*)(obj))
5861
#define SG_BOXP(obj) SG_XTYPEP(obj, SG_CLASS_BOX)
5962

63+
typedef struct SgContinuationViolationRec
64+
{
65+
SG_INSTANCE_HEADER;
66+
SgObject promptTag;
67+
} SgContinuationViolation;
68+
#define SG_CONTINUATION_VIOLATION(o) ((SgContinuationViolation *)o)
69+
#define SG_CONTINUATION_VIOLATIONP(o) SG_ISA(o, SG_CLASS_CONTINUATION_VIOLATION)
70+
#define SG_CONTINUATION_VIOLATION_PROMPT_TAG(o) \
71+
SG_CONTINUATION_VIOLATION(o)->promptTag
72+
6073
/* continuation frame */
6174
typedef struct SgContFrameRec
6275
{

src/vm.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "sagittarius/private/core.h"
3737
#include "sagittarius/private/closure.h"
3838
#include "sagittarius/private/error.h"
39+
#include "sagittarius/private/exceptions.h"
3940
#include "sagittarius/private/file.h"
4041
#include "sagittarius/private/generic.h"
4142
#include "sagittarius/private/hashtable.h"
@@ -45,6 +46,7 @@
4546
#include "sagittarius/private/pair.h"
4647
#include "sagittarius/private/port.h"
4748
#include "sagittarius/private/transcoder.h"
49+
#include "sagittarius/private/record.h"
4850
#include "sagittarius/private/reader.h"
4951
#include "sagittarius/private/string.h"
5052
#include "sagittarius/private/symbol.h"
@@ -139,6 +141,46 @@ static void vm_print(SgObject obj, SgPort *port, SgWriteContext *ctx)
139141

140142
SG_DEFINE_BUILTIN_CLASS_SIMPLE(Sg_VMClass, vm_print);
141143

144+
static SgClass *violation_cpl[] = {
145+
SG_VIOLATION_CPL,
146+
NULL
147+
};
148+
149+
static void cont_violation_printer(SgObject o, SgPort *p, SgWriteContext *ctx)
150+
{
151+
Sg_Printf(p, UC("#<&continuation %S>"),
152+
SG_CONTINUATION_VIOLATION_PROMPT_TAG(o));
153+
}
154+
155+
static SgObject cont_violation_allocate(SgClass *klass, SgObject initargs)
156+
{
157+
SgContinuationViolation *c = SG_ALLOCATE(SgContinuationViolation, klass);
158+
SG_SET_CLASS(c, klass);
159+
return SG_OBJ(c);
160+
}
161+
162+
static void cont_violation_tag_set(SgContinuationViolation *c, SgObject tag)
163+
{
164+
if (!SG_CONTINUATION_VIOLATIONP(c)) {
165+
Sg_Error(UC("&continuation required but got %S"), c);
166+
}
167+
SG_CONTINUATION_VIOLATION_PROMPT_TAG(c) = tag;
168+
}
169+
170+
static SgObject cont_violation_tag(SgContinuationViolation *c)
171+
{
172+
return SG_CONTINUATION_VIOLATION_PROMPT_TAG(c);
173+
}
174+
175+
static SgSlotAccessor cont_violation_slot[] = {
176+
SG_CLASS_SLOT_SPEC("prompt-tag", 0, cont_violation_tag, cont_violation_tag_set),
177+
{{ NULL }}
178+
};
179+
180+
SG_DEFINE_BASE_CLASS(Sg_ContinuationViolationClass, SgContinuationViolation,
181+
cont_violation_printer, NULL, NULL, cont_violation_allocate,
182+
violation_cpl);
183+
142184
static SgObject copy_generics(SgObject lib)
143185
{
144186
SgObject h = SG_NIL, t = SG_NIL, gs;
@@ -3409,6 +3451,14 @@ void Sg__PostInitVM()
34093451
if (SG_UNBOUNDP(b)) {
34103452
Sg_Panic("`raise` was not found.");
34113453
}
3454+
SG_INIT_CONDITION(SG_CLASS_CONTINUATION_VIOLATION, lib, "&continuation",
3455+
cont_violation_slot);
3456+
SG_INIT_CONDITION_PRED(SG_CLASS_CONTINUATION_VIOLATION, lib,
3457+
"continuation-violation?");
3458+
SG_INIT_CONDITION_CTR(SG_CLASS_CONTINUATION_VIOLATION, lib,
3459+
"make-continuation-violation", 1);
3460+
SG_INIT_CONDITION_ACC(cont_violation_tag, lib,
3461+
"&continuation-violation-prompt-tag");
34123462
raise_proc = SG_GLOC_GET(SG_GLOC(b));
34133463
b = Sg_FindBinding(lib, SG_INTERN("raise-continuable"), SG_UNBOUND);
34143464
if (SG_UNBOUNDP(b)) {

0 commit comments

Comments
 (0)