trying to get call/cc
This commit is contained in:
parent
beb592d251
commit
b9dfd90851
41
compile.rkt
41
compile.rkt
|
@ -552,18 +552,19 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
;; The primitive code necessary to do call/cc
|
;; The primitive code necessary to do call/cc
|
||||||
|
|
||||||
(: call/cc-label Symbol)
|
(: call/cc-label Symbol)
|
||||||
(define call/cc-label 'callCCEntry)
|
(define call/cc-label 'callCCEntry)
|
||||||
|
(define call/cc-closure-entry 'callCCClosureEntry)
|
||||||
|
|
||||||
|
|
||||||
;; (call/cc f)
|
;; (call/cc f)
|
||||||
;; Tail-calls f, providing it a special object that knows how to do the low-level
|
;; Tail-calls f, providing it a special object that knows how to do the low-level
|
||||||
;; manipulations.
|
;; manipulation of the environment and control stack.
|
||||||
|
|
||||||
(define (make-call/cc-code)
|
(define (make-call/cc-code)
|
||||||
(append-instruction-sequences
|
(append-instruction-sequences
|
||||||
(make-instruction-sequence
|
(make-instruction-sequence
|
||||||
|
@ -573,15 +574,39 @@
|
||||||
;; First, move f to the proc register
|
;; First, move f to the proc register
|
||||||
,(make-AssignImmediateStatement 'proc (make-EnvLexicalReference 0))
|
,(make-AssignImmediateStatement 'proc (make-EnvLexicalReference 0))
|
||||||
|
|
||||||
;; Next, capture the current continuation closure and target it into env[0].
|
|
||||||
|
;; Next, capture the envrionment and the current continuation closure,
|
||||||
|
;; targetting env[0].
|
||||||
;; FIXME!
|
;; FIXME!
|
||||||
,(make-AssignImmediateStatement (make-EnvLexicalReference 0) (make-Const "I should be a continuation"))))
|
,(make-PushEnvironment 2)
|
||||||
|
,(make-AssignPrimOpStatement (make-EnvLexicalReference 0)
|
||||||
|
;; When capturing, skip over f and the two slots we just added.
|
||||||
|
(make-CaptureEnvironment 3))
|
||||||
|
,(make-AssignPrimOpStatement (make-EnvLexicalReference 1)
|
||||||
|
(make-CaptureControl 0))
|
||||||
|
,(make-AssignPrimOpStatement (make-EnvLexicalReference 0)
|
||||||
|
(make-MakeCompiledProcedure call/cc-closure-entry
|
||||||
|
1 ;; the continuation consumes a single value
|
||||||
|
(list (make-EnvLexicalReference 0)
|
||||||
|
(make-EnvLexicalReference 1))))
|
||||||
|
,(make-PopEnvironment 2 0)))
|
||||||
|
|
||||||
|
|
||||||
;; Finally, tail call into f.
|
;; Finally, tail call into f.
|
||||||
(compile-procedure-call (extend-lexical-environment/placeholders '() 1)
|
(compile-procedure-call (extend-lexical-environment/placeholders '() 1)
|
||||||
(extend-lexical-environment/placeholders '() 1)
|
(extend-lexical-environment/placeholders '() 1)
|
||||||
1
|
1
|
||||||
'val
|
'val
|
||||||
'return)))
|
'return)
|
||||||
|
|
||||||
|
|
||||||
|
;; The code for the continuation
|
||||||
|
(make-instruction-sequence `(,call/cc-closure-entry
|
||||||
|
,(make-AssignImmediateStatement 'val (make-EnvLexicalReference 0))
|
||||||
|
|
||||||
|
,(make-PerformStatement (make-RestoreControl!))
|
||||||
|
,(make-PerformStatement (make-RestoreEnvironment!))
|
||||||
|
|
||||||
|
,(make-AssignPrimOpStatement 'proc (make-GetControlStackLabel))
|
||||||
|
,(make-PopControlFrame)
|
||||||
|
,(make-GotoStatement (make-Reg 'proc))))))
|
||||||
|
|
|
@ -119,7 +119,11 @@
|
||||||
(define-type PrimitiveOperator (U GetCompiledProcedureEntry
|
(define-type PrimitiveOperator (U GetCompiledProcedureEntry
|
||||||
MakeCompiledProcedure
|
MakeCompiledProcedure
|
||||||
ApplyPrimitiveProcedure
|
ApplyPrimitiveProcedure
|
||||||
GetControlStackLabel))
|
GetControlStackLabel
|
||||||
|
|
||||||
|
CaptureEnvironment
|
||||||
|
CaptureControl
|
||||||
|
))
|
||||||
|
|
||||||
;; Gets the label from the closure stored in the 'proc register and returns it.
|
;; Gets the label from the closure stored in the 'proc register and returns it.
|
||||||
(define-struct: GetCompiledProcedureEntry ()
|
(define-struct: GetCompiledProcedureEntry ()
|
||||||
|
@ -148,6 +152,13 @@
|
||||||
(define-struct: GetControlStackLabel ()
|
(define-struct: GetControlStackLabel ()
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
|
;; Capture the current environment, skipping skip frames.
|
||||||
|
(define-struct: CaptureEnvironment ([skip : Natural]))
|
||||||
|
|
||||||
|
;; Capture the control stack, skipping skip frames.
|
||||||
|
(define-struct: CaptureControl ([skip : Natural]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; The following is used with TestStatement: each is passed the register-rand and
|
;; The following is used with TestStatement: each is passed the register-rand and
|
||||||
|
@ -186,11 +197,23 @@
|
||||||
(define-struct: InstallClosureValues! ()
|
(define-struct: InstallClosureValues! ()
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
|
|
||||||
|
;; Changes over the control located at the given argument from the structure in env[1]
|
||||||
|
(define-struct: RestoreControl! ())
|
||||||
|
|
||||||
|
;; Changes over the environment located at the given argument from the structure in env[0]
|
||||||
|
(define-struct: RestoreEnvironment! ())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(define-type PrimitiveCommand (U
|
(define-type PrimitiveCommand (U
|
||||||
CheckToplevelBound!
|
CheckToplevelBound!
|
||||||
CheckClosureArity!
|
CheckClosureArity!
|
||||||
ExtendEnvironment/Prefix!
|
ExtendEnvironment/Prefix!
|
||||||
InstallClosureValues!))
|
InstallClosureValues!
|
||||||
|
|
||||||
|
RestoreEnvironment!
|
||||||
|
RestoreControl!))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,12 @@ var Primitives = (function() {
|
||||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||||
return firstArg - 1;
|
return firstArg - 1;
|
||||||
}
|
}
|
||||||
|
// ,
|
||||||
|
// 'call/cc': new Closure(callCCEntry,
|
||||||
|
// 1,
|
||||||
|
// [],
|
||||||
|
// "call/cc")
|
||||||
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user