moving the bootstrapping primitives code (like call/cc) into bootstrapped-primitives.rkt. About to implement map as well.
This commit is contained in:
parent
1c7bac3393
commit
54ee4e8da4
68
bootstrapped-primitives.rkt
Normal file
68
bootstrapped-primitives.rkt
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#lang typed/racket/base
|
||||||
|
(require "expression-structs.rkt"
|
||||||
|
"lexical-structs.rkt"
|
||||||
|
"il-structs.rkt"
|
||||||
|
"lexical-env.rkt"
|
||||||
|
"helpers.rkt"
|
||||||
|
"find-toplevel-variables.rkt"
|
||||||
|
"sets.rkt"
|
||||||
|
"compile.rkt"
|
||||||
|
racket/list)
|
||||||
|
|
||||||
|
(provide call/cc-label
|
||||||
|
make-call/cc-code)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; The primitive code necessary to do call/cc
|
||||||
|
|
||||||
|
(: call/cc-label Symbol)
|
||||||
|
(define call/cc-label 'callCCEntry)
|
||||||
|
(define call/cc-closure-entry 'callCCClosureEntry)
|
||||||
|
|
||||||
|
|
||||||
|
;; (call/cc f)
|
||||||
|
;; Tail-calls f, providing it a special object that knows how to do the low-level
|
||||||
|
;; manipulation of the environment and control stack.
|
||||||
|
(define (make-call/cc-code)
|
||||||
|
(statements
|
||||||
|
(append-instruction-sequences
|
||||||
|
(make-instruction-sequence
|
||||||
|
`(,call/cc-label
|
||||||
|
;; Precondition: the environment holds the f function that we want to jump into.
|
||||||
|
|
||||||
|
;; First, move f to the proc register
|
||||||
|
,(make-AssignImmediateStatement 'proc (make-EnvLexicalReference 0 #f))
|
||||||
|
|
||||||
|
;; Next, capture the envrionment and the current continuation closure,.
|
||||||
|
,(make-PushEnvironment 2 #f)
|
||||||
|
,(make-AssignPrimOpStatement (make-EnvLexicalReference 0 #f)
|
||||||
|
(make-CaptureControl 0))
|
||||||
|
,(make-AssignPrimOpStatement (make-EnvLexicalReference 1 #f)
|
||||||
|
;; When capturing, skip over f and the two slots we just added.
|
||||||
|
(make-CaptureEnvironment 3))
|
||||||
|
,(make-AssignPrimOpStatement (adjust-target-depth (make-EnvLexicalReference 0 #f) 2)
|
||||||
|
(make-MakeCompiledProcedure call/cc-closure-entry
|
||||||
|
1 ;; the continuation consumes a single value
|
||||||
|
(list (make-EnvLexicalReference 0 #f)
|
||||||
|
(make-EnvLexicalReference 1 #f))
|
||||||
|
'call/cc))
|
||||||
|
,(make-PopEnvironment 2 0)))
|
||||||
|
|
||||||
|
;; Finally, do a tail call into f.
|
||||||
|
(compile-procedure-call '()
|
||||||
|
(extend-lexical-environment/placeholders '() 1)
|
||||||
|
1
|
||||||
|
'val
|
||||||
|
'return)
|
||||||
|
|
||||||
|
;; The code for the continuation coe follows. It's supposed to
|
||||||
|
;; abandon the current continuation, initialize the control and environment, and then jump.
|
||||||
|
(make-instruction-sequence `(,call/cc-closure-entry
|
||||||
|
,(make-AssignImmediateStatement 'val (make-EnvLexicalReference 0 #f))
|
||||||
|
,(make-PerformStatement (make-InstallClosureValues!))
|
||||||
|
,(make-PerformStatement (make-RestoreControl!))
|
||||||
|
,(make-PerformStatement (make-RestoreEnvironment!))
|
||||||
|
,(make-AssignPrimOpStatement 'proc (make-GetControlStackLabel))
|
||||||
|
,(make-PopControlFrame)
|
||||||
|
,(make-GotoStatement (make-Reg 'proc)))))))
|
67
compile.rkt
67
compile.rkt
|
@ -12,9 +12,7 @@
|
||||||
(provide (rename-out [-compile compile])
|
(provide (rename-out [-compile compile])
|
||||||
compile-procedure-call
|
compile-procedure-call
|
||||||
append-instruction-sequences
|
append-instruction-sequences
|
||||||
|
adjust-target-depth)
|
||||||
call/cc-label
|
|
||||||
make-call/cc-code)
|
|
||||||
|
|
||||||
|
|
||||||
(: current-defined-name (Parameterof (U Symbol False)))
|
(: current-defined-name (Parameterof (U Symbol False)))
|
||||||
|
@ -32,10 +30,7 @@
|
||||||
exp)
|
exp)
|
||||||
(list)
|
(list)
|
||||||
target
|
target
|
||||||
linkage)
|
linkage)))))
|
||||||
(make-instruction-sequence `(,(make-GotoStatement (make-Label end))))
|
|
||||||
(make-call/cc-code)
|
|
||||||
end))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -652,61 +647,3 @@
|
||||||
(error 'ensure-natural "Not a natural: ~s\n" n)))
|
(error 'ensure-natural "Not a natural: ~s\n" n)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
;; The primitive code necessary to do call/cc
|
|
||||||
|
|
||||||
(: call/cc-label Symbol)
|
|
||||||
(define call/cc-label 'callCCEntry)
|
|
||||||
(define call/cc-closure-entry 'callCCClosureEntry)
|
|
||||||
|
|
||||||
|
|
||||||
;; (call/cc f)
|
|
||||||
;; Tail-calls f, providing it a special object that knows how to do the low-level
|
|
||||||
;; manipulation of the environment and control stack.
|
|
||||||
(define (make-call/cc-code)
|
|
||||||
(append-instruction-sequences
|
|
||||||
(make-instruction-sequence
|
|
||||||
`(,call/cc-label
|
|
||||||
;; Precondition: the environment holds the f function that we want to jump into.
|
|
||||||
|
|
||||||
;; First, move f to the proc register
|
|
||||||
,(make-AssignImmediateStatement 'proc (make-EnvLexicalReference 0 #f))
|
|
||||||
|
|
||||||
;; Next, capture the envrionment and the current continuation closure,.
|
|
||||||
,(make-PushEnvironment 2 #f)
|
|
||||||
,(make-AssignPrimOpStatement (make-EnvLexicalReference 0 #f)
|
|
||||||
(make-CaptureControl 0))
|
|
||||||
,(make-AssignPrimOpStatement (make-EnvLexicalReference 1 #f)
|
|
||||||
;; When capturing, skip over f and the two slots we just added.
|
|
||||||
(make-CaptureEnvironment 3))
|
|
||||||
,(make-AssignPrimOpStatement (adjust-target-depth (make-EnvLexicalReference 0 #f) 2)
|
|
||||||
(make-MakeCompiledProcedure call/cc-closure-entry
|
|
||||||
1 ;; the continuation consumes a single value
|
|
||||||
(list (make-EnvLexicalReference 0 #f)
|
|
||||||
(make-EnvLexicalReference 1 #f))
|
|
||||||
(current-defined-name)))
|
|
||||||
,(make-PopEnvironment 2 0)))
|
|
||||||
|
|
||||||
;; Finally, do a tail call into f.
|
|
||||||
(compile-procedure-call '()
|
|
||||||
(extend-lexical-environment/placeholders '() 1)
|
|
||||||
1
|
|
||||||
'val
|
|
||||||
'return)
|
|
||||||
|
|
||||||
;; The code for the continuation coe follows. It's supposed to
|
|
||||||
;; abandon the current continuation, initialize the control and environment, and then jump.
|
|
||||||
(make-instruction-sequence `(,call/cc-closure-entry
|
|
||||||
,(make-AssignImmediateStatement 'val (make-EnvLexicalReference 0 #f))
|
|
||||||
,(make-PerformStatement (make-InstallClosureValues!))
|
|
||||||
,(make-PerformStatement (make-RestoreControl!))
|
|
||||||
,(make-PerformStatement (make-RestoreEnvironment!))
|
|
||||||
,(make-AssignPrimOpStatement 'proc (make-GetControlStackLabel))
|
|
||||||
,(make-PopControlFrame)
|
|
||||||
,(make-GotoStatement (make-Reg 'proc))))))
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"assemble.rkt"
|
"assemble.rkt"
|
||||||
"typed-parse.rkt"
|
"typed-parse.rkt"
|
||||||
"il-structs.rkt"
|
"il-structs.rkt"
|
||||||
|
"bootstrapped-primitives.rkt"
|
||||||
racket/runtime-path
|
racket/runtime-path
|
||||||
racket/port)
|
racket/port)
|
||||||
|
|
||||||
|
@ -21,8 +22,7 @@
|
||||||
(for-each (lambda (code)
|
(for-each (lambda (code)
|
||||||
(displayln code op))
|
(displayln code op))
|
||||||
(map assemble-basic-block
|
(map assemble-basic-block
|
||||||
(fracture (statements
|
(fracture (make-call/cc-code))))
|
||||||
(make-call/cc-code)))))
|
|
||||||
|
|
||||||
;; The runtime code
|
;; The runtime code
|
||||||
(call-with-input-file* runtime.js
|
(call-with-input-file* runtime.js
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
(require "simulator-structs.rkt"
|
(require "simulator-structs.rkt"
|
||||||
"compile.rkt"
|
"compile.rkt"
|
||||||
|
"bootstrapped-primitives.rkt"
|
||||||
racket/math
|
racket/math
|
||||||
(for-syntax racket/base))
|
(for-syntax racket/base))
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
(require "il-structs.rkt"
|
(require "il-structs.rkt"
|
||||||
"simulator-structs.rkt"
|
"simulator-structs.rkt"
|
||||||
|
"bootstrapped-primitives.rkt"
|
||||||
racket/list
|
racket/list
|
||||||
racket/match
|
racket/match
|
||||||
(for-syntax racket/base))
|
(for-syntax racket/base))
|
||||||
|
@ -30,15 +31,27 @@
|
||||||
|
|
||||||
(: new-machine ((Listof Statement) -> machine))
|
(: new-machine ((Listof Statement) -> machine))
|
||||||
(define (new-machine program-text)
|
(define (new-machine program-text)
|
||||||
(let: ([m : machine (make-machine (make-undefined) (make-undefined) '() '() 0 (list->vector program-text) 0
|
(let*: ([after-bootstrapping : Symbol (make-label 'afterBootstrapping)]
|
||||||
((inst make-hash Symbol Natural)))])
|
[program-text : (Listof Statement)
|
||||||
(let: loop : Void ([i : Natural 0])
|
(append `(,(make-GotoStatement (make-Label after-bootstrapping)))
|
||||||
(when (< i (vector-length (machine-text m)))
|
(make-call/cc-code)
|
||||||
(let: ([stmt : Statement (vector-ref (machine-text m) i)])
|
`(,after-bootstrapping)
|
||||||
(when (symbol? stmt)
|
program-text)])
|
||||||
(hash-set! (machine-jump-table m) stmt i))
|
(let: ([m : machine (make-machine (make-undefined)
|
||||||
(loop (add1 i)))))
|
(make-undefined)
|
||||||
m))
|
'()
|
||||||
|
'()
|
||||||
|
0
|
||||||
|
(list->vector program-text)
|
||||||
|
0
|
||||||
|
((inst make-hash Symbol Natural)))])
|
||||||
|
(let: loop : Void ([i : Natural 0])
|
||||||
|
(when (< i (vector-length (machine-text m)))
|
||||||
|
(let: ([stmt : Statement (vector-ref (machine-text m) i)])
|
||||||
|
(when (symbol? stmt)
|
||||||
|
(hash-set! (machine-jump-table m) stmt i))
|
||||||
|
(loop (add1 i)))))
|
||||||
|
m)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"parse.rkt"
|
"parse.rkt"
|
||||||
"il-structs.rkt"
|
"il-structs.rkt"
|
||||||
"compile.rkt"
|
"compile.rkt"
|
||||||
|
"bootstrapped-primitives.rkt"
|
||||||
racket/port
|
racket/port
|
||||||
racket/promise
|
racket/promise
|
||||||
racket/runtime-path)
|
racket/runtime-path)
|
||||||
|
@ -45,8 +46,7 @@
|
||||||
|
|
||||||
;; The support code for call/cc
|
;; The support code for call/cc
|
||||||
(string-join (map assemble-basic-block
|
(string-join (map assemble-basic-block
|
||||||
(fracture (statements
|
(fracture (make-call/cc-code)))
|
||||||
(make-call/cc-code))))
|
|
||||||
"\n")
|
"\n")
|
||||||
|
|
||||||
runtime
|
runtime
|
||||||
|
@ -70,8 +70,7 @@
|
||||||
|
|
||||||
(display
|
(display
|
||||||
(string-join (map assemble-basic-block
|
(string-join (map assemble-basic-block
|
||||||
(fracture (statements
|
(fracture (make-call/cc-code)))
|
||||||
(make-call/cc-code))))
|
|
||||||
"\n")
|
"\n")
|
||||||
op)
|
op)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#'stx)))
|
#'stx)))
|
||||||
(printf " ok (~a milliseconds)\n" (evaluated-t result))))))]))
|
(printf " ok (~a milliseconds)\n" (evaluated-t result))))))]))
|
||||||
|
|
||||||
#|
|
|
||||||
(test '(begin (define (f x)
|
(test '(begin (define (f x)
|
||||||
(if (= x 0)
|
(if (= x 0)
|
||||||
0
|
0
|
||||||
|
@ -142,7 +141,7 @@
|
||||||
(displayln (tak 18 12 6)))
|
(displayln (tak 18 12 6)))
|
||||||
"7\n")
|
"7\n")
|
||||||
|
|
||||||
|#
|
|
||||||
|
|
||||||
(test (read (open-input-file "tests/conform/program1.sch"))
|
|
||||||
|
#;(test (read (open-input-file "tests/conform/program0.sch"))
|
||||||
(port->string (open-input-file "tests/conform/expected0.txt")))
|
(port->string (open-input-file "tests/conform/expected0.txt")))
|
Loading…
Reference in New Issue
Block a user