Merge commit 'origin/master'
This commit is contained in:
commit
07c36eb332
|
@ -180,10 +180,14 @@
|
|||
(loop (rest stmts)))]
|
||||
|
||||
[(DebugPrint? a-stmt)
|
||||
(cons a-stmt (loop (rest stmts)))]
|
||||
;(cons a-stmt (loop (rest stmts)))
|
||||
(loop (rest stmts))
|
||||
]
|
||||
|
||||
[(Comment? a-stmt)
|
||||
(cons a-stmt (loop (rest stmts)))]
|
||||
(loop (rest stmts))
|
||||
;(cons a-stmt (loop (rest stmts)))
|
||||
]
|
||||
|
||||
[(AssignImmediateStatement? a-stmt)
|
||||
(cons (make-AssignImmediateStatement (rewrite-target (AssignImmediateStatement-target a-stmt))
|
||||
|
@ -332,7 +336,8 @@
|
|||
#f]
|
||||
|
||||
[(DebugPrint? stmt)
|
||||
#f]
|
||||
;#f
|
||||
#t]
|
||||
|
||||
[(AssignImmediateStatement? stmt)
|
||||
(equal? (AssignImmediateStatement-target stmt)
|
||||
|
|
29
examples/mouse.rkt
Normal file
29
examples/mouse.rkt
Normal file
|
@ -0,0 +1,29 @@
|
|||
#lang planet dyoo/whalesong
|
||||
|
||||
(require (planet dyoo/whalesong/world)
|
||||
(planet dyoo/whalesong/image))
|
||||
|
||||
(define width 640)
|
||||
(define height 480)
|
||||
|
||||
(define-struct posn (x y))
|
||||
|
||||
(define (mouse world x y type)
|
||||
(cond
|
||||
|
||||
[(string=? type "move")
|
||||
(make-posn x y)]
|
||||
|
||||
[else
|
||||
world]))
|
||||
|
||||
(define (draw w)
|
||||
(place-image (circle 20 'solid 'red)
|
||||
(posn-x w)
|
||||
(posn-y w)
|
||||
(empty-scene width height)))
|
||||
|
||||
(printf "let's see how this works.\n\n")
|
||||
(big-bang (make-posn 0 0)
|
||||
(on-mouse mouse)
|
||||
(to-draw draw))
|
|
@ -202,12 +202,16 @@
|
|||
(define-values ids #,(on-expr #'expr)))]
|
||||
|
||||
[(define-syntaxes ids expr)
|
||||
(quasisyntax/loc stx
|
||||
(define-syntaxes ids #,(on-expr #'expr)))]
|
||||
#'(void)
|
||||
;(quasisyntax/loc stx
|
||||
; (define-syntaxes ids #,(on-expr #'expr)))
|
||||
]
|
||||
|
||||
[(define-values-for-syntax ids expr)
|
||||
(quasisyntax/loc stx
|
||||
(define-values-for-syntax ids #,(on-expr #'expr)))]
|
||||
#'(void)
|
||||
;(quasisyntax/loc stx
|
||||
; (define-values-for-syntax ids #,(on-expr #'expr)))
|
||||
]
|
||||
|
||||
[else
|
||||
(on-expr stx)]))
|
|
@ -46,8 +46,12 @@
|
|||
(error 'get-module-bytecode)]))
|
||||
|
||||
(with-handlers ([exn? (lambda (exn)
|
||||
;(printf "error? ~s\n" (exn-message exn))
|
||||
(define op (open-output-bytes))
|
||||
(write (alternative-f) op)
|
||||
;(printf "trying alternative to get bytecode\n")
|
||||
(define bytecode (alternative-f))
|
||||
;(printf "got the bytecode\n")
|
||||
(write bytecode op)
|
||||
(get-output-bytes op))])
|
||||
(define op (open-output-bytes))
|
||||
(write compiled-code op)
|
||||
|
@ -57,10 +61,11 @@
|
|||
|
||||
|
||||
(define base-namespace
|
||||
(lookup-language-namespace
|
||||
#;'racket/base
|
||||
`(file ,(path->string kernel-language-path)))
|
||||
#;(make-base-namespace))
|
||||
(make-base-namespace))
|
||||
;(lookup-language-namespace
|
||||
;;'racket/base
|
||||
;;`(file ,(path->string kernel-language-path)))
|
||||
;(make-base-namespace)))
|
||||
|
||||
|
||||
|
||||
|
@ -82,8 +87,11 @@
|
|||
;; get-compiled-code-from-port: input-port -> compiled-code
|
||||
;; Compiles the source from scratch.
|
||||
(define (get-compiled-code-from-port ip)
|
||||
;(printf "get-compiled-code-from-port\n")
|
||||
(parameterize ([read-accept-reader #t]
|
||||
[current-namespace base-namespace])
|
||||
(define stx (read-syntax (object-name ip) ip))
|
||||
;(printf "got stx; now expanding out the images\n")
|
||||
(define expanded-stx (expand-out-images stx))
|
||||
;(printf "now trying to compile the expanded syntax\n")
|
||||
(compile expanded-stx)))
|
|
@ -139,7 +139,7 @@ var makeCanvas = function(width, height) {
|
|||
|
||||
// KLUDGE: IE compatibility uses /js/excanvas.js, and dynamic
|
||||
// elements must be marked this way.
|
||||
if (window && typeof window.G_vmlCanvasManager != 'undefined') {
|
||||
if (window.G_vmlCanvasManager) {
|
||||
canvas = window.G_vmlCanvasManager.initElement(canvas);
|
||||
}
|
||||
return canvas;
|
||||
|
|
|
@ -10,15 +10,16 @@
|
|||
|
||||
|
||||
|
||||
(: assemble-op-expression (PrimitiveOperator -> String))
|
||||
(define (assemble-op-expression op)
|
||||
(: assemble-op-expression (PrimitiveOperator Blockht -> String))
|
||||
(define (assemble-op-expression op blockht)
|
||||
(cond
|
||||
[(GetCompiledProcedureEntry? op)
|
||||
"M.proc.label"]
|
||||
"M.p.label"]
|
||||
|
||||
[(MakeCompiledProcedure? op)
|
||||
(format "new RT.Closure(~a,~a,[~a],~a)"
|
||||
(assemble-label (make-Label (MakeCompiledProcedure-label op)))
|
||||
(assemble-label (make-Label (MakeCompiledProcedure-label op))
|
||||
blockht)
|
||||
(assemble-arity (MakeCompiledProcedure-arity op))
|
||||
(string-join (map
|
||||
assemble-env-reference/closure-capture
|
||||
|
@ -32,7 +33,8 @@
|
|||
|
||||
[(MakeCompiledProcedureShell? op)
|
||||
(format "new RT.Closure(~a,~a,undefined,~a)"
|
||||
(assemble-label (make-Label (MakeCompiledProcedureShell-label op)))
|
||||
(assemble-label (make-Label (MakeCompiledProcedureShell-label op))
|
||||
blockht)
|
||||
(assemble-arity (MakeCompiledProcedureShell-arity op))
|
||||
(assemble-display-name (MakeCompiledProcedureShell-display-name op)))]
|
||||
|
||||
|
@ -48,7 +50,7 @@
|
|||
(cond [(DefaultContinuationPromptTag? tag)
|
||||
(assemble-default-continuation-prompt-tag)]
|
||||
[(OpArg? tag)
|
||||
(assemble-oparg tag)])))]
|
||||
(assemble-oparg tag blockht)])))]
|
||||
|
||||
|
||||
[(MakeBoxedEnvironmentValue? op)
|
||||
|
@ -56,4 +58,4 @@
|
|||
(add1 (MakeBoxedEnvironmentValue-depth op)))]
|
||||
|
||||
[(CallKernelPrimitiveProcedure? op)
|
||||
(open-code-kernel-primitive-procedure op)]))
|
||||
(open-code-kernel-primitive-procedure op blockht)]))
|
|
@ -4,8 +4,13 @@
|
|||
"../compiler/expression-structs.rkt"
|
||||
"../compiler/lexical-structs.rkt"
|
||||
"../compiler/arity-structs.rkt"
|
||||
"assemble-structs.rkt"
|
||||
racket/list
|
||||
racket/string)
|
||||
racket/string
|
||||
racket/match)
|
||||
|
||||
|
||||
|
||||
|
||||
(provide assemble-oparg
|
||||
assemble-target
|
||||
|
@ -14,6 +19,7 @@
|
|||
assemble-prefix-reference
|
||||
assemble-whole-prefix-reference
|
||||
assemble-reg
|
||||
munge-label-name
|
||||
assemble-label
|
||||
assemble-listof-assembled-values
|
||||
assemble-default-continuation-prompt-tag
|
||||
|
@ -22,19 +28,21 @@
|
|||
assemble-jump
|
||||
assemble-display-name
|
||||
assemble-location
|
||||
assemble-numeric-constant)
|
||||
assemble-numeric-constant
|
||||
|
||||
block-looks-like-context-expected-values?)
|
||||
|
||||
(require/typed typed/racket/base
|
||||
[regexp-split (Regexp String -> (Listof String))])
|
||||
|
||||
|
||||
(: assemble-oparg (OpArg -> String))
|
||||
(define (assemble-oparg v)
|
||||
(: assemble-oparg (OpArg Blockht -> String))
|
||||
(define (assemble-oparg v blockht)
|
||||
(cond
|
||||
[(Reg? v)
|
||||
(assemble-reg v)]
|
||||
[(Label? v)
|
||||
(assemble-label v)]
|
||||
(assemble-label v blockht)]
|
||||
[(Const? v)
|
||||
(assemble-const v)]
|
||||
[(EnvLexicalReference? v)
|
||||
|
@ -44,7 +52,7 @@
|
|||
[(EnvWholePrefixReference? v)
|
||||
(assemble-whole-prefix-reference v)]
|
||||
[(SubtractArg? v)
|
||||
(assemble-subtractarg v)]
|
||||
(assemble-subtractarg v blockht)]
|
||||
[(ControlStackLabel? v)
|
||||
(assemble-control-stack-label v)]
|
||||
[(ControlStackLabel/MultipleValueReturn? v)
|
||||
|
@ -52,9 +60,9 @@
|
|||
[(ControlFrameTemporary? v)
|
||||
(assemble-control-frame-temporary v)]
|
||||
[(CompiledProcedureEntry? v)
|
||||
(assemble-compiled-procedure-entry v)]
|
||||
(assemble-compiled-procedure-entry v blockht)]
|
||||
[(CompiledProcedureClosureReference? v)
|
||||
(assemble-compiled-procedure-closure-reference v)]
|
||||
(assemble-compiled-procedure-closure-reference v blockht)]
|
||||
[(PrimitiveKernelValue? v)
|
||||
(assemble-primitive-kernel-value v)]
|
||||
[(ModuleEntry? v)
|
||||
|
@ -69,6 +77,8 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
(: assemble-target (Target -> (String -> String)))
|
||||
(define (assemble-target target)
|
||||
(cond
|
||||
|
@ -83,9 +93,9 @@
|
|||
(format "~a=~a;"
|
||||
(cond
|
||||
[(eq? target 'proc)
|
||||
"M.proc"]
|
||||
"M.p"]
|
||||
[(eq? target 'val)
|
||||
"M.val"]
|
||||
"M.v"]
|
||||
[(eq? target 'argcount)
|
||||
"M.a"]
|
||||
[(EnvLexicalReference? target)
|
||||
|
@ -103,7 +113,7 @@
|
|||
|
||||
(: assemble-control-frame-temporary (ControlFrameTemporary -> String))
|
||||
(define (assemble-control-frame-temporary t)
|
||||
(format "M.control[M.control.length-1].~a"
|
||||
(format "M.c[M.c.length-1].~a"
|
||||
(ControlFrameTemporary-name t)))
|
||||
|
||||
;; fixme: use js->string
|
||||
|
@ -279,60 +289,66 @@
|
|||
(let ([name (Reg-name a-reg)])
|
||||
(cond
|
||||
[(eq? name 'proc)
|
||||
"M.proc"]
|
||||
"M.p"]
|
||||
[(eq? name 'val)
|
||||
"M.val"]
|
||||
"M.v"]
|
||||
[(eq? name 'argcount)
|
||||
"M.a"])))
|
||||
|
||||
|
||||
|
||||
(: assemble-label (Label -> String))
|
||||
(define (assemble-label a-label)
|
||||
(let ([chunks
|
||||
(regexp-split #rx"[^a-zA-Z0-9]+"
|
||||
(symbol->string (Label-name a-label)))])
|
||||
(cond
|
||||
[(empty? chunks)
|
||||
(error "impossible: empty label ~s" a-label)]
|
||||
[(empty? (rest chunks))
|
||||
(string-append "_" (first chunks))]
|
||||
[else
|
||||
(string-append "_"
|
||||
(first chunks)
|
||||
(apply string-append (map string-titlecase (rest chunks))))])))
|
||||
(: munge-label-name (Label -> String))
|
||||
(define (munge-label-name a-label)
|
||||
(define chunks
|
||||
(regexp-split #rx"[^a-zA-Z0-9]+"
|
||||
(symbol->string (Label-name a-label))))
|
||||
(cond
|
||||
[(empty? chunks)
|
||||
(error "impossible: empty label ~s" a-label)]
|
||||
[(empty? (rest chunks))
|
||||
(string-append "_" (first chunks))]
|
||||
[else
|
||||
(string-append "_"
|
||||
(first chunks)
|
||||
(apply string-append (map string-titlecase (rest chunks))))]))
|
||||
|
||||
|
||||
|
||||
(: assemble-subtractarg (SubtractArg -> String))
|
||||
(define (assemble-subtractarg s)
|
||||
(: assemble-label (Label Blockht -> String))
|
||||
(define (assemble-label a-label Blockht)
|
||||
(munge-label-name a-label))
|
||||
|
||||
|
||||
|
||||
(: assemble-subtractarg (SubtractArg Blockht -> String))
|
||||
(define (assemble-subtractarg s blockht)
|
||||
(format "(~a-~a)"
|
||||
(assemble-oparg (SubtractArg-lhs s))
|
||||
(assemble-oparg (SubtractArg-rhs s))))
|
||||
(assemble-oparg (SubtractArg-lhs s) blockht)
|
||||
(assemble-oparg (SubtractArg-rhs s) blockht)))
|
||||
|
||||
|
||||
(: assemble-control-stack-label (ControlStackLabel -> String))
|
||||
(define (assemble-control-stack-label a-csl)
|
||||
"M.control[M.control.length-1].label")
|
||||
"M.c[M.c.length-1].label")
|
||||
|
||||
|
||||
(: assemble-control-stack-label/multiple-value-return (ControlStackLabel/MultipleValueReturn -> String))
|
||||
(define (assemble-control-stack-label/multiple-value-return a-csl)
|
||||
"M.control[M.control.length-1].label.mvr")
|
||||
"(M.c[M.c.length-1].label.mvr||RT.si_context_expected_1)")
|
||||
|
||||
|
||||
|
||||
(: assemble-compiled-procedure-entry (CompiledProcedureEntry -> String))
|
||||
(define (assemble-compiled-procedure-entry a-compiled-procedure-entry)
|
||||
(: assemble-compiled-procedure-entry (CompiledProcedureEntry Blockht -> String))
|
||||
(define (assemble-compiled-procedure-entry a-compiled-procedure-entry blockht)
|
||||
(format "(~a).label"
|
||||
(assemble-oparg (CompiledProcedureEntry-proc a-compiled-procedure-entry))))
|
||||
(assemble-oparg (CompiledProcedureEntry-proc a-compiled-procedure-entry)
|
||||
blockht)))
|
||||
|
||||
|
||||
(: assemble-compiled-procedure-closure-reference (CompiledProcedureClosureReference -> String))
|
||||
(define (assemble-compiled-procedure-closure-reference a-ref)
|
||||
(: assemble-compiled-procedure-closure-reference (CompiledProcedureClosureReference Blockht -> String))
|
||||
(define (assemble-compiled-procedure-closure-reference a-ref blockht)
|
||||
(format "(~a).closedVals[(~a).closedVals.length - ~a]"
|
||||
(assemble-oparg (CompiledProcedureClosureReference-proc a-ref))
|
||||
(assemble-oparg (CompiledProcedureClosureReference-proc a-ref))
|
||||
(assemble-oparg (CompiledProcedureClosureReference-proc a-ref) blockht)
|
||||
(assemble-oparg (CompiledProcedureClosureReference-proc a-ref) blockht)
|
||||
(add1 (CompiledProcedureClosureReference-n a-ref))))
|
||||
|
||||
|
||||
|
@ -379,9 +395,38 @@
|
|||
|
||||
|
||||
|
||||
(: assemble-jump (OpArg -> String))
|
||||
(define (assemble-jump target)
|
||||
(format "return(~a)(M);" (assemble-oparg target)))
|
||||
|
||||
(: assemble-jump (OpArg Blockht -> String))
|
||||
(define (assemble-jump target blockht)
|
||||
|
||||
(define (default)
|
||||
(format "return(~a)(M);" (assemble-oparg target blockht)))
|
||||
|
||||
;; Optimization: if the target of the jump goes to a block whose
|
||||
;; only body is a si-context-expected_1, then jump directly to that code.
|
||||
(cond
|
||||
[(Label? target)
|
||||
(define target-block (hash-ref blockht (Label-name target)))
|
||||
(cond
|
||||
[(block-looks-like-context-expected-values? target-block)
|
||||
=>
|
||||
(lambda (expected)
|
||||
(format "RT.si_context_expected(~a)(M);\n" expected))]
|
||||
[else
|
||||
(default)])]
|
||||
[else
|
||||
(default)]))
|
||||
|
||||
|
||||
|
||||
(: block-looks-like-context-expected-values? (BasicBlock -> (U Natural False)))
|
||||
(define (block-looks-like-context-expected-values? a-block)
|
||||
(match (BasicBlock-stmts a-block)
|
||||
[(list (struct PerformStatement ((struct RaiseContextExpectedValuesError! (expected))))
|
||||
stmts ...)
|
||||
expected]
|
||||
[else
|
||||
#f]))
|
||||
|
||||
|
||||
|
||||
|
@ -399,13 +444,13 @@
|
|||
|
||||
|
||||
|
||||
(: assemble-location ((U Reg Label) -> String))
|
||||
(define (assemble-location a-location)
|
||||
(: assemble-location ((U Reg Label) Blockht -> String))
|
||||
(define (assemble-location a-location blockht)
|
||||
(cond
|
||||
[(Reg? a-location)
|
||||
(assemble-reg a-location)]
|
||||
[(Label? a-location)
|
||||
(assemble-label a-location)]))
|
||||
(assemble-label a-location blockht)]))
|
||||
|
||||
|
||||
(: assemble-primitive-kernel-value (PrimitiveKernelValue -> String))
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"../compiler/il-structs.rkt"
|
||||
"../compiler/lexical-structs.rkt"
|
||||
"../compiler/kernel-primitives.rkt"
|
||||
"assemble-structs.rkt"
|
||||
racket/string
|
||||
racket/list
|
||||
typed/rackunit)
|
||||
|
@ -12,10 +13,12 @@
|
|||
|
||||
|
||||
|
||||
(: open-code-kernel-primitive-procedure (CallKernelPrimitiveProcedure -> String))
|
||||
(define (open-code-kernel-primitive-procedure op)
|
||||
(: open-code-kernel-primitive-procedure (CallKernelPrimitiveProcedure Blockht -> String))
|
||||
(define (open-code-kernel-primitive-procedure op blockht)
|
||||
(let*: ([operator : KernelPrimitiveName/Inline (CallKernelPrimitiveProcedure-operator op)]
|
||||
[operands : (Listof String) (map assemble-oparg (CallKernelPrimitiveProcedure-operands op))]
|
||||
[operands : (Listof String) (map (lambda: ([op : OpArg])
|
||||
(assemble-oparg op blockht))
|
||||
(CallKernelPrimitiveProcedure-operands op))]
|
||||
[checked-operands : (Listof String)
|
||||
(map (lambda: ([dom : OperandDomain]
|
||||
[pos : Natural]
|
||||
|
|
|
@ -3,14 +3,15 @@
|
|||
"../compiler/il-structs.rkt"
|
||||
"../compiler/lexical-structs.rkt"
|
||||
"../parameters.rkt"
|
||||
"assemble-structs.rkt"
|
||||
racket/string)
|
||||
|
||||
(provide assemble-op-statement)
|
||||
|
||||
|
||||
|
||||
(: assemble-op-statement (PrimitiveCommand -> String))
|
||||
(define (assemble-op-statement op)
|
||||
(: assemble-op-statement (PrimitiveCommand Blockht -> String))
|
||||
(define (assemble-op-statement op blockht)
|
||||
(cond
|
||||
|
||||
[(CheckToplevelBound!? op)
|
||||
|
@ -70,7 +71,7 @@
|
|||
",")))]
|
||||
|
||||
[(InstallClosureValues!? op)
|
||||
"M.e.push.apply(M.e,M.proc.closedVals);"]
|
||||
"M.e.push.apply(M.e,M.p.closedVals);"]
|
||||
|
||||
[(RestoreEnvironment!? op)
|
||||
"M.e=M.e[M.e.length-2].slice(0);"]
|
||||
|
@ -83,7 +84,7 @@
|
|||
[(DefaultContinuationPromptTag? tag)
|
||||
(assemble-default-continuation-prompt-tag)]
|
||||
[(OpArg? tag)
|
||||
(assemble-oparg tag)])))]
|
||||
(assemble-oparg tag blockht)])))]
|
||||
|
||||
[(FixClosureShellMap!? op)
|
||||
(format "M.e[M.e.length-~a].closedVals=[~a];"
|
||||
|
@ -98,22 +99,24 @@
|
|||
","))]
|
||||
|
||||
[(SetFrameCallee!? op)
|
||||
(format "M.control[M.control.length-1].proc=~a;"
|
||||
(assemble-oparg (SetFrameCallee!-proc op)))]
|
||||
(format "M.c[M.c.length-1].p=~a;"
|
||||
(assemble-oparg (SetFrameCallee!-proc op)
|
||||
blockht))]
|
||||
|
||||
[(SpliceListIntoStack!? op)
|
||||
(format "M.spliceListIntoStack(~a);"
|
||||
(assemble-oparg (SpliceListIntoStack!-depth op)))]
|
||||
(assemble-oparg (SpliceListIntoStack!-depth op)
|
||||
blockht))]
|
||||
|
||||
[(UnspliceRestFromStack!? op)
|
||||
(format "M.unspliceRestFromStack(~a,~a);"
|
||||
(assemble-oparg (UnspliceRestFromStack!-depth op))
|
||||
(assemble-oparg (UnspliceRestFromStack!-length op)))]
|
||||
(assemble-oparg (UnspliceRestFromStack!-depth op) blockht)
|
||||
(assemble-oparg (UnspliceRestFromStack!-length op) blockht))]
|
||||
|
||||
[(InstallContinuationMarkEntry!? op)
|
||||
(string-append "M.installContinuationMarkEntry("
|
||||
"M.control[M.control.length-1].pendingContinuationMarkKey,"
|
||||
"M.val);")]
|
||||
"M.c[M.c.length-1].pendingContinuationMarkKey,"
|
||||
"M.v);")]
|
||||
|
||||
[(RaiseContextExpectedValuesError!? op)
|
||||
(format "RT.raiseContextExpectedValuesError(M,~a);"
|
||||
|
@ -122,13 +125,13 @@
|
|||
|
||||
[(RaiseArityMismatchError!? op)
|
||||
(format "RT.raiseArityMismatchError(M,~a,~a);"
|
||||
(assemble-oparg (RaiseArityMismatchError!-proc op))
|
||||
(assemble-oparg (RaiseArityMismatchError!-received op)))]
|
||||
(assemble-oparg (RaiseArityMismatchError!-proc op) blockht)
|
||||
(assemble-oparg (RaiseArityMismatchError!-received op) blockht))]
|
||||
|
||||
|
||||
[(RaiseOperatorApplicationError!? op)
|
||||
(format "RT.raiseOperatorApplicationError(M,~a);"
|
||||
(assemble-oparg (RaiseOperatorApplicationError!-operator op)))]
|
||||
(assemble-oparg (RaiseOperatorApplicationError!-operator op) blockht))]
|
||||
|
||||
|
||||
[(RaiseUnimplementedPrimitiveError!? op)
|
||||
|
@ -140,7 +143,8 @@
|
|||
(format "M.modules[~s]=new RT.ModuleRecord(~s,~a);"
|
||||
(symbol->string (ModuleLocator-name (InstallModuleEntry!-path op)))
|
||||
(symbol->string (InstallModuleEntry!-name op))
|
||||
(assemble-label (make-Label (InstallModuleEntry!-entry-point op))))]
|
||||
(assemble-label (make-Label (InstallModuleEntry!-entry-point op))
|
||||
blockht))]
|
||||
|
||||
[(MarkModuleInvoked!? op)
|
||||
(format "M.modules[~s].isInvoked=true;"
|
||||
|
|
|
@ -13,3 +13,8 @@
|
|||
(define-struct: BasicBlock ([name : Symbol]
|
||||
[stmts : (Listof UnlabeledStatement)])
|
||||
#:transparent)
|
||||
|
||||
|
||||
|
||||
;; Represents a hashtable from symbols to basic blocks
|
||||
(define-type Blockht (HashTable Symbol BasicBlock))
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"assemble-helpers.rkt"
|
||||
"assemble-expression.rkt"
|
||||
"assemble-perform-statement.rkt"
|
||||
"optimize-basic-blocks.rkt"
|
||||
"fracture.rkt"
|
||||
"../compiler/il-structs.rkt"
|
||||
"../sets.rkt"
|
||||
|
@ -30,8 +29,6 @@
|
|||
(define current-emit-debug-trace? (make-parameter #f))
|
||||
|
||||
|
||||
;; Represents a hashtable from symbols to basic blocks
|
||||
(define-type Blockht (HashTable Symbol BasicBlock))
|
||||
|
||||
|
||||
|
||||
|
@ -49,12 +46,19 @@
|
|||
(define function-entry-and-exit-names
|
||||
(list->set (get-function-entry-and-exit-names stmts)))
|
||||
|
||||
(: blockht : Blockht)
|
||||
(define blockht (make-hash))
|
||||
|
||||
(for ([b basic-blocks])
|
||||
(hash-set! blockht (BasicBlock-name b) b))
|
||||
|
||||
(write-blocks basic-blocks
|
||||
blockht
|
||||
(list->set entry-points)
|
||||
function-entry-and-exit-names
|
||||
op)
|
||||
|
||||
(write-linked-label-attributes stmts op)
|
||||
(write-linked-label-attributes stmts blockht op)
|
||||
|
||||
(display "M.params.currentErrorHandler = fail;\n" op)
|
||||
(display "M.params.currentSuccessHandler = success;\n" op)
|
||||
|
@ -67,18 +71,14 @@ for (param in params) {
|
|||
EOF
|
||||
op)
|
||||
(fprintf op "M.trampoline(~a, true); })"
|
||||
(assemble-label (make-Label (BasicBlock-name (first basic-blocks))))))
|
||||
(assemble-label (make-Label (BasicBlock-name (first basic-blocks)))
|
||||
blockht)))
|
||||
|
||||
|
||||
|
||||
(: write-blocks ((Listof BasicBlock) (Setof Symbol) (Setof Symbol) Output-Port -> Void))
|
||||
(: write-blocks ((Listof BasicBlock) Blockht (Setof Symbol) (Setof Symbol) Output-Port -> Void))
|
||||
;; Write out all the basic blocks associated to an entry point.
|
||||
(define (write-blocks blocks entry-points function-entry-and-exit-names op)
|
||||
(: blockht : Blockht)
|
||||
(define blockht (make-hash))
|
||||
|
||||
(for ([b blocks])
|
||||
(hash-set! blockht (BasicBlock-name b) b))
|
||||
(define (write-blocks blocks blockht entry-points function-entry-and-exit-names op)
|
||||
|
||||
;; Since there may be cycles between the blocks, we cut the cycles by
|
||||
;; making them entry points as well.
|
||||
|
@ -125,24 +125,39 @@ EOF
|
|||
|
||||
|
||||
|
||||
(: write-linked-label-attributes ((Listof Statement) Output-Port -> 'ok))
|
||||
(define (write-linked-label-attributes stmts op)
|
||||
(: write-linked-label-attributes ((Listof Statement) Blockht Output-Port -> 'ok))
|
||||
(define (write-linked-label-attributes stmts blockht op)
|
||||
(cond
|
||||
[(empty? stmts)
|
||||
'ok]
|
||||
[else
|
||||
(let: ([stmt : Statement (first stmts)])
|
||||
|
||||
(define (next) (write-linked-label-attributes (rest stmts) op))
|
||||
(define (next) (write-linked-label-attributes (rest stmts) blockht op))
|
||||
|
||||
(cond
|
||||
[(symbol? stmt)
|
||||
(next)]
|
||||
[(LinkedLabel? stmt)
|
||||
;; Setting up multiple-value-return
|
||||
(fprintf op "~a.mvr=~a;\n"
|
||||
(assemble-label (make-Label (LinkedLabel-label stmt)))
|
||||
(assemble-label (make-Label (LinkedLabel-linked-to stmt))))
|
||||
;; Setting up multiple-value-return.
|
||||
;; Optimization: in the most common case (expecting only one), we optimize away
|
||||
;; the assignment, because there's a distinguished instruction, and it's implied
|
||||
;; that if .mvr is missing, that the block only expects one.
|
||||
(define linked-to-block (hash-ref blockht (LinkedLabel-linked-to stmt)))
|
||||
(cond
|
||||
[(block-looks-like-context-expected-values? linked-to-block)
|
||||
=> (lambda (expected)
|
||||
(cond
|
||||
[(= expected 1)
|
||||
(void)]
|
||||
[else
|
||||
(fprintf op "~a.mvr=RT.si_context_expected(~a);\n"
|
||||
(munge-label-name (make-Label (LinkedLabel-label stmt)))
|
||||
expected)]))]
|
||||
[else
|
||||
(fprintf op "~a.mvr=~a;\n"
|
||||
(munge-label-name (make-Label (LinkedLabel-label stmt)))
|
||||
(assemble-label (make-Label (LinkedLabel-linked-to stmt)) blockht))])
|
||||
(next)]
|
||||
[(DebugPrint? stmt)
|
||||
(next)]
|
||||
|
@ -180,15 +195,20 @@ EOF
|
|||
|
||||
(: assemble-basic-block (BasicBlock Blockht (Setof Symbol) (Setof Symbol) Output-Port -> 'ok))
|
||||
(define (assemble-basic-block a-basic-block blockht entry-points function-entry-and-exit-names op)
|
||||
(match (BasicBlock-stmts a-basic-block)
|
||||
[(list (struct PerformStatement ((struct RaiseContextExpectedValuesError! (expected))))
|
||||
stmts ...)
|
||||
(fprintf op "~a=RT.si_context_expected(~a);\n"
|
||||
(assemble-label (make-Label (BasicBlock-name a-basic-block)))
|
||||
expected)
|
||||
'ok]
|
||||
[else
|
||||
(default-assemble-basic-block a-basic-block blockht entry-points function-entry-and-exit-names op)]))
|
||||
(cond
|
||||
[(block-looks-like-context-expected-values? a-basic-block)
|
||||
=>
|
||||
(lambda (expected)
|
||||
(cond
|
||||
[(= expected 1)
|
||||
'ok]
|
||||
[else
|
||||
(fprintf op "~a=RT.si_context_expected(~a);\n"
|
||||
(munge-label-name (make-Label (BasicBlock-name a-basic-block)))
|
||||
expected)
|
||||
'ok]))]
|
||||
[else
|
||||
(default-assemble-basic-block a-basic-block blockht entry-points function-entry-and-exit-names op)]))
|
||||
|
||||
|
||||
|
||||
|
@ -197,11 +217,11 @@ EOF
|
|||
(cond
|
||||
[(set-contains? function-entry-and-exit-names (BasicBlock-name a-basic-block))
|
||||
(fprintf op "var ~a=function(M){if(--M.cbt<0){throw ~a;}\n"
|
||||
(assemble-label (make-Label (BasicBlock-name a-basic-block)))
|
||||
(assemble-label (make-Label (BasicBlock-name a-basic-block))))]
|
||||
(assemble-label (make-Label (BasicBlock-name a-basic-block)) blockht)
|
||||
(assemble-label (make-Label (BasicBlock-name a-basic-block)) blockht))]
|
||||
[else
|
||||
(fprintf op "var ~a=function(M){--M.cbt<0;\n"
|
||||
(assemble-label (make-Label (BasicBlock-name a-basic-block))))])
|
||||
(assemble-label (make-Label (BasicBlock-name a-basic-block)) blockht))])
|
||||
(assemble-block-statements (BasicBlock-name a-basic-block)
|
||||
(BasicBlock-stmts a-basic-block)
|
||||
blockht
|
||||
|
@ -222,7 +242,7 @@ EOF
|
|||
(not (GotoStatement? stmt)))
|
||||
(log-debug (format "Last statement of the block ~a is not a goto" name)))
|
||||
|
||||
(display (assemble-statement stmt) op)
|
||||
(display (assemble-statement stmt blockht) op)
|
||||
(newline op)
|
||||
(assemble-block-statements name
|
||||
(rest stmts)
|
||||
|
@ -254,30 +274,33 @@ EOF
|
|||
(define test-code (cond
|
||||
[(TestFalse? test)
|
||||
(format "if(~a===false)"
|
||||
(assemble-oparg (TestFalse-operand test)))]
|
||||
(assemble-oparg (TestFalse-operand test)
|
||||
blockht))]
|
||||
[(TestTrue? test)
|
||||
(format "if(~a!==false)"
|
||||
(assemble-oparg (TestTrue-operand test)))]
|
||||
(assemble-oparg (TestTrue-operand test)
|
||||
blockht))]
|
||||
[(TestOne? test)
|
||||
(format "if(~a===1)"
|
||||
(assemble-oparg (TestOne-operand test)))]
|
||||
(assemble-oparg (TestOne-operand test)
|
||||
blockht))]
|
||||
[(TestZero? test)
|
||||
(format "if(~a===0)"
|
||||
(assemble-oparg (TestZero-operand test)))]
|
||||
|
||||
;; [(TestPrimitiveProcedure? test)
|
||||
;; (format "if(typeof(~a)==='function')"
|
||||
;; (assemble-oparg (TestPrimitiveProcedure-operand test)))]
|
||||
|
||||
(assemble-oparg (TestZero-operand test)
|
||||
blockht))]
|
||||
|
||||
[(TestClosureArityMismatch? test)
|
||||
(format "if(!RT.isArityMatching((~a).racketArity,~a))"
|
||||
(assemble-oparg (TestClosureArityMismatch-closure test))
|
||||
(assemble-oparg (TestClosureArityMismatch-n test)))]))
|
||||
(assemble-oparg (TestClosureArityMismatch-closure test)
|
||||
blockht)
|
||||
(assemble-oparg (TestClosureArityMismatch-n test)
|
||||
blockht))]))
|
||||
(display test-code op)
|
||||
(display "{" op)
|
||||
(cond
|
||||
[(set-contains? entry-points (TestAndJumpStatement-label stmt))
|
||||
(display (assemble-jump (make-Label (TestAndJumpStatement-label stmt))) op)]
|
||||
(display (assemble-jump (make-Label (TestAndJumpStatement-label stmt))
|
||||
blockht) op)]
|
||||
[else
|
||||
(assemble-block-statements (BasicBlock-name
|
||||
(hash-ref blockht (TestAndJumpStatement-label stmt)))
|
||||
|
@ -307,7 +330,7 @@ EOF
|
|||
(GotoStatement? (first target-statements)))
|
||||
(loop (first target-statements))]
|
||||
[(set-contains? entry-points (Label-name target))
|
||||
(display (assemble-statement stmt) op)
|
||||
(display (assemble-statement stmt blockht) op)
|
||||
'ok]
|
||||
[else
|
||||
(log-debug (format "Assembling inlined jump into ~a" (Label-name target)) )
|
||||
|
@ -317,13 +340,13 @@ EOF
|
|||
entry-points
|
||||
op)])]
|
||||
[(Reg? target)
|
||||
(display (assemble-statement stmt) op)
|
||||
(display (assemble-statement stmt blockht) op)
|
||||
'ok]
|
||||
[(ModuleEntry? target)
|
||||
(display (assemble-statement stmt) op)
|
||||
(display (assemble-statement stmt blockht) op)
|
||||
'ok]
|
||||
[(CompiledProcedureEntry? target)
|
||||
(display (assemble-statement stmt) op)
|
||||
(display (assemble-statement stmt blockht) op)
|
||||
'ok]))]
|
||||
|
||||
|
||||
|
@ -430,79 +453,93 @@ EOF
|
|||
|
||||
|
||||
|
||||
(: assemble-statement (UnlabeledStatement -> String))
|
||||
(: assemble-statement (UnlabeledStatement Blockht -> String))
|
||||
;; Generates the code to assemble a statement.
|
||||
(define (assemble-statement stmt)
|
||||
(define (assemble-statement stmt blockht)
|
||||
(define assembled
|
||||
(cond
|
||||
[(DebugPrint? stmt)
|
||||
(format "M.params.currentOutputPort.writeDomNode(M, $('<span/>').text(~a));"
|
||||
(assemble-oparg (DebugPrint-value stmt)))]
|
||||
(assemble-oparg (DebugPrint-value stmt)
|
||||
blockht))]
|
||||
[(AssignImmediateStatement? stmt)
|
||||
(let: ([t : (String -> String) (assemble-target (AssignImmediateStatement-target stmt))]
|
||||
[v : OpArg (AssignImmediateStatement-value stmt)])
|
||||
(t (assemble-oparg v)))]
|
||||
(t (assemble-oparg v blockht)))]
|
||||
|
||||
[(AssignPrimOpStatement? stmt)
|
||||
((assemble-target (AssignPrimOpStatement-target stmt))
|
||||
(assemble-op-expression (AssignPrimOpStatement-op stmt)))]
|
||||
(assemble-op-expression (AssignPrimOpStatement-op stmt)
|
||||
blockht))]
|
||||
|
||||
[(PerformStatement? stmt)
|
||||
(assemble-op-statement (PerformStatement-op stmt))]
|
||||
(assemble-op-statement (PerformStatement-op stmt) blockht)]
|
||||
|
||||
[(TestAndJumpStatement? stmt)
|
||||
(let*: ([test : PrimitiveTest (TestAndJumpStatement-op stmt)]
|
||||
[jump : String (assemble-jump
|
||||
(make-Label (TestAndJumpStatement-label stmt)))])
|
||||
(make-Label (TestAndJumpStatement-label stmt))
|
||||
blockht)])
|
||||
;; to help localize type checks, we add a type annotation here.
|
||||
(ann (cond
|
||||
[(TestFalse? test)
|
||||
(format "if(~a===false){~a}"
|
||||
(assemble-oparg (TestFalse-operand test))
|
||||
(assemble-oparg (TestFalse-operand test)
|
||||
blockht)
|
||||
jump)]
|
||||
[(TestTrue? test)
|
||||
(format "if(~a!==false){~a}"
|
||||
(assemble-oparg (TestTrue-operand test))
|
||||
(assemble-oparg (TestTrue-operand test)
|
||||
blockht)
|
||||
jump)]
|
||||
[(TestOne? test)
|
||||
(format "if(~a===1){~a}"
|
||||
(assemble-oparg (TestOne-operand test))
|
||||
(assemble-oparg (TestOne-operand test)
|
||||
blockht)
|
||||
jump)]
|
||||
[(TestZero? test)
|
||||
(format "if(~a===0){~a}"
|
||||
(assemble-oparg (TestZero-operand test))
|
||||
(assemble-oparg (TestZero-operand test)
|
||||
blockht)
|
||||
jump)]
|
||||
[(TestClosureArityMismatch? test)
|
||||
(format "if(!RT.isArityMatching((~a).racketArity,~a)){~a}"
|
||||
(assemble-oparg (TestClosureArityMismatch-closure test))
|
||||
(assemble-oparg (TestClosureArityMismatch-n test))
|
||||
(assemble-oparg (TestClosureArityMismatch-closure test)
|
||||
blockht)
|
||||
(assemble-oparg (TestClosureArityMismatch-n test)
|
||||
blockht)
|
||||
jump)])
|
||||
String))]
|
||||
|
||||
[(GotoStatement? stmt)
|
||||
(assemble-jump (GotoStatement-target stmt))]
|
||||
(assemble-jump (GotoStatement-target stmt)
|
||||
blockht)]
|
||||
|
||||
[(PushControlFrame/Generic? stmt)
|
||||
"M.control.push(new RT.Frame());"]
|
||||
"M.c.push(new RT.Frame());"]
|
||||
|
||||
[(PushControlFrame/Call? stmt)
|
||||
(format "M.control.push(new RT.CallFrame(~a,M.proc));"
|
||||
(format "M.c.push(new RT.CallFrame(~a,M.p));"
|
||||
(let: ([label : (U Symbol LinkedLabel) (PushControlFrame/Call-label stmt)])
|
||||
(cond
|
||||
[(symbol? label)
|
||||
(assemble-label (make-Label label))]
|
||||
(assemble-label (make-Label label)
|
||||
blockht)]
|
||||
[(LinkedLabel? label)
|
||||
(assemble-label (make-Label (LinkedLabel-label label)))])))]
|
||||
(assemble-label (make-Label (LinkedLabel-label label))
|
||||
blockht)])))]
|
||||
|
||||
[(PushControlFrame/Prompt? stmt)
|
||||
;; fixme: use a different frame structure
|
||||
(format "M.control.push(new RT.PromptFrame(~a,~a));"
|
||||
(format "M.c.push(new RT.PromptFrame(~a,~a));"
|
||||
(let: ([label : (U Symbol LinkedLabel) (PushControlFrame/Prompt-label stmt)])
|
||||
(cond
|
||||
[(symbol? label)
|
||||
(assemble-label (make-Label label))]
|
||||
(assemble-label (make-Label label)
|
||||
blockht)]
|
||||
[(LinkedLabel? label)
|
||||
(assemble-label (make-Label (LinkedLabel-label label)))]))
|
||||
(assemble-label (make-Label (LinkedLabel-label label))
|
||||
blockht)]))
|
||||
|
||||
(let: ([tag : (U DefaultContinuationPromptTag OpArg)
|
||||
(PushControlFrame/Prompt-tag stmt)])
|
||||
|
@ -510,10 +547,10 @@ EOF
|
|||
[(DefaultContinuationPromptTag? tag)
|
||||
(assemble-default-continuation-prompt-tag)]
|
||||
[(OpArg? tag)
|
||||
(assemble-oparg tag)])))]
|
||||
(assemble-oparg tag blockht)])))]
|
||||
|
||||
[(PopControlFrame? stmt)
|
||||
"M.control.pop();"]
|
||||
"M.c.pop();"]
|
||||
|
||||
[(PushEnvironment? stmt)
|
||||
(cond [(= (PushEnvironment-n stmt) 0)
|
||||
|
@ -531,20 +568,22 @@ EOF
|
|||
(cond
|
||||
[(and (Const? skip) (= (ensure-natural (Const-const skip)) 0))
|
||||
(format "M.e.length-=~a;"
|
||||
(assemble-oparg (PopEnvironment-n stmt)))]
|
||||
(assemble-oparg (PopEnvironment-n stmt) blockht))]
|
||||
[else
|
||||
(format "M.e.splice(M.e.length-(~a+~a),~a);"
|
||||
(assemble-oparg (PopEnvironment-skip stmt))
|
||||
(assemble-oparg (PopEnvironment-n stmt))
|
||||
(assemble-oparg (PopEnvironment-n stmt)))]))]
|
||||
(assemble-oparg (PopEnvironment-skip stmt) blockht)
|
||||
(assemble-oparg (PopEnvironment-n stmt) blockht)
|
||||
(assemble-oparg (PopEnvironment-n stmt) blockht))]))]
|
||||
|
||||
[(PushImmediateOntoEnvironment? stmt)
|
||||
(format "M.e.push(~a);"
|
||||
(let: ([val-string : String
|
||||
(cond [(PushImmediateOntoEnvironment-box? stmt)
|
||||
(format "[~a]" (assemble-oparg (PushImmediateOntoEnvironment-value stmt)))]
|
||||
(format "[~a]" (assemble-oparg (PushImmediateOntoEnvironment-value stmt)
|
||||
blockht))]
|
||||
[else
|
||||
(assemble-oparg (PushImmediateOntoEnvironment-value stmt))])])
|
||||
(assemble-oparg (PushImmediateOntoEnvironment-value stmt)
|
||||
blockht)])])
|
||||
val-string))]
|
||||
[(Comment? stmt)
|
||||
;; TODO: maybe comments should be emitted as JavaScript comments.
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
#lang typed/racket/base
|
||||
|
||||
;; Does some basic optimizations at the level of basic blocks.
|
||||
|
||||
|
||||
(require "assemble-structs.rkt"
|
||||
"../compiler/il-structs.rkt"
|
||||
racket/list)
|
||||
|
||||
|
||||
(require/typed "../logger.rkt" [log-debug (String -> Void)])
|
||||
|
||||
|
||||
(provide optimize-basic-blocks)
|
||||
|
||||
|
||||
(define-type Blockht (HashTable Symbol BasicBlock))
|
||||
|
||||
;; We want maps from unlabeled statements to their respective blocks.
|
||||
(define-type Bodyht (HashTable (Listof UnlabeledStatement) (Listof Symbol)))
|
||||
|
||||
|
||||
(: optimize-basic-blocks ((Listof BasicBlock) -> (Listof BasicBlock)))
|
||||
(define (optimize-basic-blocks blocks)
|
||||
|
||||
(: blockht : Blockht)
|
||||
(define blockht (make-hasheq))
|
||||
|
||||
(: bodyht : Bodyht)
|
||||
(define bodyht (make-hasheq))
|
||||
|
||||
;; First, scan through the blocks, and pick up their names and bodies.
|
||||
(for ([b blocks])
|
||||
(hash-set! blockht (BasicBlock-name b) b)
|
||||
|
||||
(when (hash-has-key? bodyht (BasicBlock-stmts b))
|
||||
(log-debug (format "block ~a has the same content as another block" (BasicBlock-name b))))
|
||||
(hash-set! bodyht (BasicBlock-stmts b)
|
||||
(cons (BasicBlock-name b)
|
||||
(hash-ref bodyht (BasicBlock-stmts b) (lambda () '())))))
|
||||
|
||||
blocks
|
||||
#;(define inlined-blocks
|
||||
(map (lambda: ([b : BasicBlock])
|
||||
(optimize-block b blockht))
|
||||
blocks))
|
||||
#;inlined-blocks)
|
||||
|
||||
|
||||
|
||||
|
||||
(: optimize-block (BasicBlock Blockht -> BasicBlock))
|
||||
;; Simple optimization: optimize away single-statement goto blocks with their
|
||||
;; immediate contents.
|
||||
(define (optimize-block b blocks)
|
||||
(define stmts (BasicBlock-stmts b))
|
||||
(cond
|
||||
[(= (length stmts) 1)
|
||||
(define first-stmt (first stmts))
|
||||
(cond
|
||||
[(GotoStatement? first-stmt)
|
||||
(define target (GotoStatement-target first-stmt))
|
||||
(cond
|
||||
[(Label? target)
|
||||
(log-debug (format "inlining basic block ~a" (BasicBlock-name b)))
|
||||
(optimize-block (make-BasicBlock (BasicBlock-name b)
|
||||
(BasicBlock-stmts
|
||||
(hash-ref blocks (Label-name target))))
|
||||
blocks)]
|
||||
[else
|
||||
b])]
|
||||
[else
|
||||
b])]
|
||||
[else
|
||||
b]))
|
|
@ -164,7 +164,7 @@
|
|||
(function(MACHINE, EXPORTS){~a})(M, exports);
|
||||
~a
|
||||
modrec.privateExports = exports;
|
||||
return M.control.pop().label(M);"
|
||||
return M.c.pop().label(M);"
|
||||
(symbol->string name)
|
||||
text
|
||||
(get-provided-name-code bytecode))])
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
while (arity !== baselib.lists.EMPTY) {
|
||||
if (typeof(arity.first) === 'number') {
|
||||
if (arity.first === n) { return true; }
|
||||
} else if (isArityAtLeast(arity)) {
|
||||
} else if (isArityAtLeast(arity.first)) {
|
||||
if (n >= arityAtLeastValue(arity.first)) { return true; }
|
||||
}
|
||||
arity = arity.rest;
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
// as well as the function being called.
|
||||
var CallFrame = function(label, proc) {
|
||||
this.label = label;
|
||||
this.proc = proc;
|
||||
this.p = proc;
|
||||
|
||||
// The set of continuation marks.
|
||||
this.marks = [];
|
||||
|
|
|
@ -68,16 +68,16 @@
|
|||
MACHINE.e.length -= MACHINE.a;
|
||||
|
||||
if (returnArgs.length === 1) {
|
||||
MACHINE.val = returnArgs[0];
|
||||
return MACHINE.control.pop().label(MACHINE);
|
||||
MACHINE.v = returnArgs[0];
|
||||
return MACHINE.c.pop().label(MACHINE);
|
||||
} else if (returnArgs.length === 0) {
|
||||
MACHINE.a = 0;
|
||||
return MACHINE.control.pop().label.mvr(MACHINE);
|
||||
return (MACHINE.c.pop().label.mvr || plt.runtime.si_context_expected_1)(MACHINE);
|
||||
} else {
|
||||
MACHINE.a = returnArgs.length;
|
||||
MACHINE.val = returnArgs.shift();
|
||||
MACHINE.v = returnArgs.shift();
|
||||
MACHINE.e.push.apply(MACHINE.e, returnArgs.reverse());
|
||||
return MACHINE.control.pop().label.mvr(MACHINE);
|
||||
return (MACHINE.c.pop().label.mvr || plt.runtime.si_context_expected_1)(MACHINE);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -148,19 +148,19 @@
|
|||
MACHINE.captureContinuationMarks())));
|
||||
}
|
||||
|
||||
var oldVal = MACHINE.val;
|
||||
var oldVal = MACHINE.v;
|
||||
var oldArgcount = MACHINE.a;
|
||||
var oldProc = MACHINE.proc;
|
||||
var oldProc = MACHINE.p;
|
||||
|
||||
var oldErrorHandler = MACHINE.params['currentErrorHandler'];
|
||||
var afterGoodInvoke = function (MACHINE) {
|
||||
plt.runtime.PAUSE(
|
||||
function (restart) {
|
||||
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
|
||||
var returnValue = MACHINE.val;
|
||||
MACHINE.val = oldVal;
|
||||
var returnValue = MACHINE.v;
|
||||
MACHINE.v = oldVal;
|
||||
MACHINE.a = oldArgcount;
|
||||
MACHINE.proc = oldProc;
|
||||
MACHINE.p = oldProc;
|
||||
succ(returnValue);
|
||||
});
|
||||
};
|
||||
|
@ -168,30 +168,30 @@
|
|||
plt.runtime.PAUSE(
|
||||
function (restart) {
|
||||
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
|
||||
var returnValues = [MACHINE.val], i;
|
||||
var returnValues = [MACHINE.v], i;
|
||||
for (i = 0; i < MACHINE.a - 1; i++) {
|
||||
returnValues.push(MACHINE.e.pop());
|
||||
}
|
||||
MACHINE.val = oldVal;
|
||||
MACHINE.v = oldVal;
|
||||
MACHINE.a = oldArgcount;
|
||||
MACHINE.proc = oldProc;
|
||||
MACHINE.p = oldProc;
|
||||
succ.apply(null, returnValues);
|
||||
});
|
||||
};
|
||||
|
||||
MACHINE.control.push(
|
||||
MACHINE.c.push(
|
||||
new baselib.frames.CallFrame(afterGoodInvoke, v));
|
||||
MACHINE.a = arguments.length - 2;
|
||||
var i;
|
||||
for (i = 0; i < arguments.length - 2; i++) {
|
||||
MACHINE.e.push(arguments[arguments.length - 1 - i]);
|
||||
}
|
||||
MACHINE.proc = v;
|
||||
MACHINE.p = v;
|
||||
MACHINE.params['currentErrorHandler'] = function (MACHINE, e) {
|
||||
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
|
||||
MACHINE.val = oldVal;
|
||||
MACHINE.v = oldVal;
|
||||
MACHINE.a = oldArgcount;
|
||||
MACHINE.proc = oldProc;
|
||||
MACHINE.p = oldProc;
|
||||
fail(e);
|
||||
};
|
||||
MACHINE.trampoline(v.label);
|
||||
|
@ -246,48 +246,48 @@
|
|||
}
|
||||
success(result);
|
||||
} else if (isClosure(proc)) {
|
||||
oldVal = MACHINE.val;
|
||||
oldVal = MACHINE.v;
|
||||
oldArgcount = MACHINE.a;
|
||||
oldProc = MACHINE.proc;
|
||||
oldProc = MACHINE.p;
|
||||
|
||||
oldErrorHandler = MACHINE.params['currentErrorHandler'];
|
||||
var afterGoodInvoke = function (MACHINE) {
|
||||
plt.runtime.PAUSE(function (restart) {
|
||||
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
|
||||
var returnValue = MACHINE.val;
|
||||
MACHINE.val = oldVal;
|
||||
var returnValue = MACHINE.v;
|
||||
MACHINE.v = oldVal;
|
||||
MACHINE.a = oldArgcount;
|
||||
MACHINE.proc = oldProc;
|
||||
MACHINE.p = oldProc;
|
||||
success(returnValue);
|
||||
});
|
||||
};
|
||||
afterGoodInvoke.mvr = function (MACHINE) {
|
||||
plt.runtime.PAUSE(function (restart) {
|
||||
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
|
||||
var returnValues = [MACHINE.val];
|
||||
var returnValues = [MACHINE.v];
|
||||
var i;
|
||||
for (i = 0; i < MACHINE.a - 1; i++) {
|
||||
returnValues.push(MACHINE.e.pop());
|
||||
}
|
||||
MACHINE.val = oldVal;
|
||||
MACHINE.v = oldVal;
|
||||
MACHINE.a = oldArgcount;
|
||||
MACHINE.proc = oldProc;
|
||||
MACHINE.p = oldProc;
|
||||
success.apply(null, returnValues);
|
||||
});
|
||||
};
|
||||
|
||||
MACHINE.control.push(
|
||||
MACHINE.c.push(
|
||||
new baselib.frames.CallFrame(afterGoodInvoke, proc));
|
||||
MACHINE.a = arguments.length - 4;
|
||||
for (i = 0; i < arguments.length - 4; i++) {
|
||||
MACHINE.e.push(arguments[arguments.length - 1 - i]);
|
||||
}
|
||||
MACHINE.proc = proc;
|
||||
MACHINE.p = proc;
|
||||
MACHINE.params['currentErrorHandler'] = function (MACHINE, e) {
|
||||
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
|
||||
MACHINE.val = oldVal;
|
||||
MACHINE.v = oldVal;
|
||||
MACHINE.a = oldArgcount;
|
||||
MACHINE.proc = oldProc;
|
||||
MACHINE.p = oldProc;
|
||||
fail(e);
|
||||
};
|
||||
MACHINE.trampoline(proc.label);
|
||||
|
@ -324,9 +324,9 @@
|
|||
arity,
|
||||
function(M) {
|
||||
--M.cbt;
|
||||
M.val = f(M);
|
||||
M.v = f(M);
|
||||
M.e.length -= M.a;
|
||||
return M.control.pop().label(M);
|
||||
return M.c.pop().label(M);
|
||||
},
|
||||
[]);
|
||||
};
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
|
||||
fail(MACHINE, anError);
|
||||
};
|
||||
MACHINE.control.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null));
|
||||
MACHINE.c.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null));
|
||||
if (isInternal) {
|
||||
throw that.label;
|
||||
} else {
|
||||
|
|
|
@ -1150,7 +1150,7 @@
|
|||
checkList(M, 'apply', M.a - 1);
|
||||
M.spliceListIntoStack(M.a - 1);
|
||||
if (baselib.arity.isArityMatching(proc.racketArity, M.a)) {
|
||||
M.proc = proc;
|
||||
M.p = proc;
|
||||
if (baselib.functions.isPrimitiveProcedure(proc)) {
|
||||
return finalizeClosureCall(M, proc(M));
|
||||
} else {
|
||||
|
|
|
@ -1,513 +0,0 @@
|
|||
// Helper functions for whalesong.
|
||||
//
|
||||
// Note: this originally came from js-vm, and may have cruft that
|
||||
// doesn't belong in whalesong. I need to clean this up.
|
||||
|
||||
|
||||
|
||||
if (! this['plt']) { this['plt'] = {}; }
|
||||
|
||||
// Helpers library: includes a bunch of helper functions that will be used
|
||||
//
|
||||
//
|
||||
// FIXME: there's a circularity between this module and types, and that circularly
|
||||
// should not be there!
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// File of helper functions for primitives and world.
|
||||
|
||||
|
||||
(function(scope) {
|
||||
var helpers = {};
|
||||
scope.helpers = helpers;
|
||||
|
||||
|
||||
// types refers to plt.types, and will be initialized later.
|
||||
var types = scope['types'];
|
||||
scope.link.ready('types',
|
||||
function() {
|
||||
types = scope['types'];
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// forEachK: CPS( array CPS(array -> void) (error -> void) -> void )
|
||||
// Iterates through an array and applies f to each element using CPS
|
||||
// If an error is thrown, it catches the error and calls f_error on it
|
||||
var forEachK = function(a, f, f_error, k) {
|
||||
var forEachHelp = function(i) {
|
||||
if( i >= a.length ) {
|
||||
if (k) {
|
||||
return k();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return f(a[i], function() { return forEachHelp(i+1); });
|
||||
} catch (e) {
|
||||
f_error(e);
|
||||
}
|
||||
};
|
||||
return forEachHelp(0);
|
||||
};
|
||||
|
||||
|
||||
// reportError: (or exception string) -> void
|
||||
// Reports an error to the user, either at the console
|
||||
// if the console exists, or as alerts otherwise.
|
||||
var reportError = function(e) {
|
||||
var reporter;
|
||||
if (typeof(console) != 'undefined' &&
|
||||
typeof(console.log) != 'undefined') {
|
||||
reporter = (function(x) { console.log(x); });
|
||||
} else {
|
||||
reporter = (function(x) { alert(x); });
|
||||
}
|
||||
if (typeof e == 'string') {
|
||||
reporter(e);
|
||||
} else if ( types.isSchemeError(e) ) {
|
||||
if ( types.isExn(e.val) ) {
|
||||
reporter( types.exnMessage(e.val) );
|
||||
}
|
||||
else {
|
||||
reporter(e.val);
|
||||
}
|
||||
} else if ( types.isInternalError(e) ) {
|
||||
reporter(e.val);
|
||||
} else if (e.message) {
|
||||
reporter(e.message);
|
||||
} else {
|
||||
reporter(e.toString());
|
||||
}
|
||||
// if (plt.Kernel.lastLoc) {
|
||||
// var loc = plt.Kernel.lastLoc;
|
||||
// if (typeof(loc) === 'string') {
|
||||
// reporter("Error was raised around " + loc);
|
||||
// } else if (typeof(loc) !== 'undefined' &&
|
||||
// typeof(loc.line) !== 'undefined') {
|
||||
// reporter("Error was raised around: "
|
||||
// + plt.Kernel.locToString(loc));
|
||||
// }
|
||||
// }
|
||||
};
|
||||
|
||||
|
||||
var raise = function(v) {
|
||||
throw types.schemeError(v);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// var throwCheckError = function(details, pos, args) {
|
||||
// var errorFormatStr;
|
||||
// if (args && args.length > 1) {
|
||||
// var errorFormatStrBuffer = ['~a: expects type <~a> as ~a arguments, given: ~s; other arguments were:'];
|
||||
// for (var i = 0; i < args.length; i++) {
|
||||
// if ( i != pos-1 ) {
|
||||
// errorFormatStrBuffer.push(toWrittenString(args[i]));
|
||||
// }
|
||||
// }
|
||||
// errorFormatStr = errorFormatStrBuffer.join(' ');
|
||||
// }
|
||||
// else {
|
||||
// errorFormatStr = "~a: expects argument of type <~a>, given: ~s";
|
||||
// details.splice(2, 1);
|
||||
// }
|
||||
|
||||
// raise( types.incompleteExn(types.exnFailContract,
|
||||
// helpers.format(errorFormatStr, details),
|
||||
// []) );
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// var check = function(x, f, functionName, typeName, position, args) {
|
||||
// if ( !f(x) ) {
|
||||
// throwCheckError([functionName,
|
||||
// typeName,
|
||||
// helpers.ordinalize(position),
|
||||
// x],
|
||||
// position,
|
||||
// args);
|
||||
// }
|
||||
// };
|
||||
|
||||
var isList = function(x) {
|
||||
var seenPairs = plt.baselib.hash.makeLowLevelEqHash();
|
||||
while (true) {
|
||||
if (seenPairs.containsKey(x)) {
|
||||
return true;
|
||||
} else if (x === types.EMPTY) {
|
||||
return true;
|
||||
} else if (types.isPair(x)) {
|
||||
seenPairs.put(x, true);
|
||||
x = x.rest();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var isListOf = function(x, f) {
|
||||
var seenPairs = plt.baselib.hash.makeLowLevelEqHash();
|
||||
while (true) {
|
||||
if (seenPairs.containsKey(x)) {
|
||||
return true;
|
||||
} else if (x === types.EMPTY) {
|
||||
return true;
|
||||
} else if (types.isPair(x)) {
|
||||
seenPairs.put(x, true);
|
||||
if (f(x.first())) {
|
||||
x = x.rest();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// var checkListOf = function(lst, f, functionName, typeName, position, args) {
|
||||
// if ( !isListOf(lst, f) ) {
|
||||
// helpers.throwCheckError([functionName,
|
||||
// 'list of ' + typeName,
|
||||
// helpers.ordinalize(position),
|
||||
// lst],
|
||||
// position,
|
||||
// args);
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
// // remove: array any -> array
|
||||
// // removes the first instance of v in a
|
||||
// // or returns a copy of a if v does not exist
|
||||
// var remove = function(a, v) {
|
||||
// for (var i = 0; i < a.length; i++) {
|
||||
// if (a[i] === v) {
|
||||
// return a.slice(0, i).concat( a.slice(i+1, a.length) );
|
||||
// }
|
||||
// }
|
||||
// return a.slice(0);
|
||||
// };
|
||||
|
||||
// map: array (any -> any) -> array
|
||||
// applies f to each element of a and returns the result
|
||||
// as a new array
|
||||
var map = function(f, a) {
|
||||
var b = new Array(a.length);
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
b[i] = f(a[i]);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
||||
|
||||
var concatMap = function(f, a) {
|
||||
var b = [];
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
b = b.concat( f(a[i]) );
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
||||
|
||||
var schemeListToArray = function(lst) {
|
||||
var result = [];
|
||||
while ( !lst.isEmpty() ) {
|
||||
result.push(lst.first());
|
||||
lst = lst.rest();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// deepListToArray: any -> any
|
||||
// Converts list structure to array structure.
|
||||
var deepListToArray = function(x) {
|
||||
var thing = x;
|
||||
if (thing === types.EMPTY) {
|
||||
return [];
|
||||
} else if (types.isPair(thing)) {
|
||||
var result = [];
|
||||
while (!thing.isEmpty()) {
|
||||
result.push(deepListToArray(thing.first()));
|
||||
thing = thing.rest();
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var flattenSchemeListToArray = function(x) {
|
||||
if ( !isList(x) ) {
|
||||
return [x];
|
||||
}
|
||||
|
||||
var ret = [];
|
||||
while ( !x.isEmpty() ) {
|
||||
ret = ret.concat( flattenSchemeListToArray(x.first()) );
|
||||
x = x.rest();
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
|
||||
var ordinalize = function(n) {
|
||||
// special case for 11th:
|
||||
if ( n % 100 == 11 ) {
|
||||
return n + 'th';
|
||||
}
|
||||
var res = n;
|
||||
switch( n % 10 ) {
|
||||
case 1: res += 'st'; break;
|
||||
case 2: res += 'nd'; break;
|
||||
case 3: res += 'rd'; break;
|
||||
default: res += 'th'; break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// var wrapJsValue = function(x) {
|
||||
// if (x === undefined) {
|
||||
// return types.jsValue('undefined', x);
|
||||
// }
|
||||
// else if (x === null) {
|
||||
// return types.jsValue('null', x);
|
||||
// }
|
||||
// else if (typeof(x) == 'function') {
|
||||
// return types.jsValue('function', x);
|
||||
// }
|
||||
// else if ( x instanceof Array ) {
|
||||
// return types.jsValue('array', x);
|
||||
// }
|
||||
// else if ( typeof(x) == 'string' ) {
|
||||
// return types.jsValue("'" + x.toString() + "'", x);
|
||||
// }
|
||||
// else {
|
||||
// return types.jsValue(x.toString(), x);
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
var getKeyCodeName = function(e) {
|
||||
var code = e.charCode || e.keyCode;
|
||||
var keyname;
|
||||
switch(code) {
|
||||
case 16: keyname = "shift"; break;
|
||||
case 17: keyname = "control"; break;
|
||||
case 19: keyname = "pause"; break;
|
||||
case 27: keyname = "escape"; break;
|
||||
case 33: keyname = "prior"; break;
|
||||
case 34: keyname = "next"; break;
|
||||
case 35: keyname = "end"; break;
|
||||
case 36: keyname = "home"; break;
|
||||
case 37: keyname = "left"; break;
|
||||
case 38: keyname = "up"; break;
|
||||
case 39: keyname = "right"; break;
|
||||
case 40: keyname = "down"; break;
|
||||
case 42: keyname = "print"; break;
|
||||
case 45: keyname = "insert"; break;
|
||||
case 46: keyname = String.fromCharCode(127); break;
|
||||
case 106: keyname = "*"; break;
|
||||
case 107: keyname = "+"; break;
|
||||
case 109: keyname = "-"; break;
|
||||
case 110: keyname = "."; break;
|
||||
case 111: keyname = "/"; break;
|
||||
case 144: keyname = "numlock"; break;
|
||||
case 145: keyname = "scroll"; break;
|
||||
case 186: keyname = ";"; break;
|
||||
case 187: keyname = "="; break;
|
||||
case 188: keyname = ","; break;
|
||||
case 189: keyname = "-"; break;
|
||||
case 190: keyname = "."; break;
|
||||
case 191: keyname = "/"; break;
|
||||
case 192: keyname = "`"; break;
|
||||
case 219: keyname = "["; break;
|
||||
case 220: keyname = "\\"; break;
|
||||
case 221: keyname = "]"; break;
|
||||
case 222: keyname = "'"; break;
|
||||
default: if (code >= 96 && code <= 105) {
|
||||
keyname = (code - 96).toString();
|
||||
}
|
||||
else if (code >= 112 && code <= 123) {
|
||||
keyname = "f" + (code - 111);
|
||||
}
|
||||
else {
|
||||
keyname = String.fromCharCode(code).toLowerCase();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return keyname;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// maybeCallAfterAttach: dom-node -> void
|
||||
// walk the tree rooted at aNode, and call afterAttach if the element has
|
||||
// such a method.
|
||||
var maybeCallAfterAttach = function(aNode) {
|
||||
var stack = [aNode];
|
||||
while (stack.length !== 0) {
|
||||
var nextNode = stack.pop();
|
||||
if (nextNode.afterAttach) {
|
||||
nextNode.afterAttach(nextNode);
|
||||
}
|
||||
if (nextNode.hasChildNodes && nextNode.hasChildNodes()) {
|
||||
var children = nextNode.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
stack.push(children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// makeLocationDom: location -> dom
|
||||
// Dom type that has special support in the editor through the print hook.
|
||||
// The print hook is expected to look at the printing of dom values with
|
||||
// this particular structure. In the context of WeScheme, the environment
|
||||
// will rewrite these to be clickable links.
|
||||
var makeLocationDom = function(aLocation) {
|
||||
var locationSpan = document.createElement("span");
|
||||
var idSpan = document.createElement("span");
|
||||
var offsetSpan = document.createElement("span");
|
||||
var lineSpan = document.createElement("span");
|
||||
var columnSpan = document.createElement("span");
|
||||
var spanSpan = document.createElement("span");
|
||||
|
||||
locationSpan['className'] = 'location-reference';
|
||||
idSpan['className'] = 'location-id';
|
||||
offsetSpan['className'] = 'location-offset';
|
||||
lineSpan['className'] = 'location-line';
|
||||
columnSpan['className'] = 'location-column';
|
||||
spanSpan['className'] = 'location-span';
|
||||
|
||||
idSpan.appendChild(document.createTextNode(String(aLocation.id)));
|
||||
offsetSpan.appendChild(document.createTextNode(String(aLocation.offset)));
|
||||
lineSpan.appendChild(document.createTextNode(String(aLocation.line)));
|
||||
columnSpan.appendChild(document.createTextNode(String(aLocation.column)));
|
||||
spanSpan.appendChild(document.createTextNode(String(aLocation.span)));
|
||||
|
||||
locationSpan.appendChild(idSpan);
|
||||
locationSpan.appendChild(offsetSpan);
|
||||
locationSpan.appendChild(lineSpan);
|
||||
locationSpan.appendChild(columnSpan);
|
||||
locationSpan.appendChild(spanSpan);
|
||||
|
||||
return locationSpan;
|
||||
};
|
||||
|
||||
|
||||
var isLocationDom = function(thing) {
|
||||
return (thing
|
||||
&&
|
||||
(thing.nodeType === Node.TEXT_NODE ||
|
||||
thing.nodeType === Node.ELEMENT_NODE)
|
||||
&&
|
||||
thing['className'] === 'location-reference');
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Inheritance.
|
||||
var heir = function(parentPrototype) {
|
||||
var f = function() {}
|
||||
f.prototype = parentPrototype;
|
||||
return new f();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// clone: object -> object
|
||||
// Copies an object. The new object should respond like the old
|
||||
// object, including to things like instanceof
|
||||
var clone = function(obj) {
|
||||
var C = function() {}
|
||||
C.prototype = obj;
|
||||
var c = new C();
|
||||
for (property in obj) {
|
||||
if (obj.hasOwnProperty(property)) {
|
||||
c[property] = obj[property];
|
||||
}
|
||||
}
|
||||
return c;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
helpers.forEachK = forEachK;
|
||||
helpers.reportError = reportError;
|
||||
helpers.raise = raise;
|
||||
|
||||
// helpers.throwCheckError = throwCheckError;
|
||||
helpers.isList = isList;
|
||||
helpers.isListOf = isListOf;
|
||||
// helpers.check = check;
|
||||
// helpers.checkListOf = checkListOf;
|
||||
|
||||
// helpers.remove = remove;
|
||||
helpers.map = map;
|
||||
helpers.concatMap = concatMap;
|
||||
helpers.schemeListToArray = schemeListToArray;
|
||||
helpers.deepListToArray = deepListToArray;
|
||||
helpers.flattenSchemeListToArray = flattenSchemeListToArray;
|
||||
|
||||
helpers.ordinalize = ordinalize;
|
||||
// helpers.wrapJsValue = wrapJsValue;
|
||||
|
||||
helpers.getKeyCodeName = getKeyCodeName;
|
||||
|
||||
helpers.maybeCallAfterAttach = maybeCallAfterAttach;
|
||||
|
||||
helpers.makeLocationDom = makeLocationDom;
|
||||
helpers.isLocationDom = isLocationDom;
|
||||
|
||||
|
||||
helpers.heir = heir;
|
||||
|
||||
|
||||
|
||||
helpers.clone = clone;
|
||||
|
||||
|
||||
scope.link.announceReady('helpers');
|
||||
})(this['plt']);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
File diff suppressed because it is too large
Load Diff
|
@ -212,16 +212,19 @@
|
|||
|
||||
var Machine = function() {
|
||||
this.cbt = STACK_LIMIT_ESTIMATE; // calls before trampoline
|
||||
this.val = undefined; // value register
|
||||
this.proc = undefined; // procedure register
|
||||
this.v = undefined; // value register
|
||||
this.p = undefined; // procedure register
|
||||
this.a = undefined; // argument count
|
||||
this.e = []; // environment
|
||||
this.control = []; // control: Arrayof (U Frame CallFrame PromptFrame)
|
||||
this.c = []; // control: Arrayof (U Frame CallFrame PromptFrame)
|
||||
this.running = false;
|
||||
this.modules = {}; // String -> ModuleRecord
|
||||
this.mainModules = []; // Arrayof String
|
||||
this.params = {
|
||||
|
||||
// print-as-expression: boolean
|
||||
'print-as-expression' : true,
|
||||
|
||||
// currentDisplayer: DomNode -> Void
|
||||
// currentDisplayer is responsible for displaying to the browser.
|
||||
'currentDisplayer': function(MACHINE, domNode) {
|
||||
|
@ -293,10 +296,10 @@
|
|||
Machine.prototype.captureControl = function(skip, tag) {
|
||||
var MACHINE = this;
|
||||
var i;
|
||||
for (i = MACHINE.control.length - 1 - skip; i >= 0; i--) {
|
||||
if (MACHINE.control[i].tag === tag) {
|
||||
return MACHINE.control.slice(i + 1,
|
||||
MACHINE.control.length - skip);
|
||||
for (i = MACHINE.c.length - 1 - skip; i >= 0; i--) {
|
||||
if (MACHINE.c[i].tag === tag) {
|
||||
return MACHINE.c.slice(i + 1,
|
||||
MACHINE.c.length - skip);
|
||||
}
|
||||
}
|
||||
raise(MACHINE, new Error("captureControl: unable to find tag " + tag));
|
||||
|
@ -311,10 +314,10 @@
|
|||
Machine.prototype.restoreControl = function(tag) {
|
||||
var MACHINE = this;
|
||||
var i;
|
||||
for (i = MACHINE.control.length - 1; i >= 0; i--) {
|
||||
if (MACHINE.control[i].tag === tag) {
|
||||
MACHINE.control =
|
||||
MACHINE.control.slice(0, i+1).concat(
|
||||
for (i = MACHINE.c.length - 1; i >= 0; i--) {
|
||||
if (MACHINE.c[i].tag === tag) {
|
||||
MACHINE.c =
|
||||
MACHINE.c.slice(0, i+1).concat(
|
||||
MACHINE.e[MACHINE.e.length - 1]);
|
||||
return;
|
||||
}
|
||||
|
@ -359,7 +362,7 @@
|
|||
|
||||
// Save the continuation mark on the top control frame.
|
||||
Machine.prototype.installContinuationMarkEntry = function(key, value) {
|
||||
var frame = this.control[this.control.length - 1];
|
||||
var frame = this.c[this.c.length - 1];
|
||||
var marks = frame.marks;
|
||||
var i;
|
||||
for (i = 0; i < marks.length; i++) {
|
||||
|
@ -375,7 +378,7 @@
|
|||
Machine.prototype.captureContinuationMarks = function() {
|
||||
var kvLists = [];
|
||||
var i;
|
||||
var control = this.control;
|
||||
var control = this.c;
|
||||
var tracedCalleeKey = getTracedCalleeKey(this);
|
||||
for (i = control.length-1; i >= 0; i--) {
|
||||
if (control[i].marks.length !== 0) {
|
||||
|
@ -384,8 +387,8 @@
|
|||
|
||||
if (tracedCalleeKey !== null &&
|
||||
control[i] instanceof CallFrame &&
|
||||
control[i].proc !== null) {
|
||||
kvLists.push([[tracedCalleeKey, control[i].proc]]);
|
||||
control[i].p !== null) {
|
||||
kvLists.push([[tracedCalleeKey, control[i].p]]);
|
||||
}
|
||||
}
|
||||
return new baselib.contmarks.ContinuationMarkSet(kvLists);
|
||||
|
@ -661,11 +664,11 @@
|
|||
|
||||
|
||||
var checkClosureAndArity = function(M) {
|
||||
if(!(M.proc instanceof Closure)){
|
||||
raiseOperatorIsNotClosure(M,M.proc);
|
||||
if(!(M.p instanceof Closure)){
|
||||
raiseOperatorIsNotClosure(M,M.p);
|
||||
}
|
||||
if(!isArityMatching(M.proc.racketArity,M.a)) {
|
||||
raiseArityMismatchError(M, M.proc,M.a);
|
||||
if(!isArityMatching(M.p.racketArity,M.a)) {
|
||||
raiseArityMismatchError(M,M.p,M.a);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -675,7 +678,8 @@
|
|||
// Superinstructions to try to reduce code size.
|
||||
var si_context_expected = function(n) {
|
||||
if (n === 1) { return si_context_expected_1; }
|
||||
return function(M) { raiseContextExpectedValuesError(M, n); }
|
||||
var f = function(M) { raiseContextExpectedValuesError(M, n); };
|
||||
return f;
|
||||
};
|
||||
var si_context_expected_1 = function(M) { raiseContextExpectedValuesError(M, 1); }
|
||||
|
||||
|
@ -686,7 +690,6 @@
|
|||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -817,6 +820,7 @@
|
|||
exports['getTracedCalleeKey'] = getTracedCalleeKey;
|
||||
|
||||
exports['si_context_expected'] = si_context_expected;
|
||||
exports['si_context_expected_1'] = si_context_expected_1;
|
||||
exports['checkClosureAndArity'] = checkClosureAndArity;
|
||||
|
||||
|
||||
|
|
|
@ -1,573 +0,0 @@
|
|||
// The definitions of the basic types in Whalesong.
|
||||
//
|
||||
// Note: this originally came from js-vm, and as a result,
|
||||
// there's quite a lot of cruft and unused code in this module.
|
||||
// I need to filter and rip out the values that aren't used in Whalesong.
|
||||
|
||||
|
||||
if (! this['plt']) { this['plt'] = {}; }
|
||||
|
||||
// FIXME: there's a circularity between this module and helpers, and that circularly
|
||||
// should not be there!
|
||||
|
||||
|
||||
(function (scope) {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
var types = {};
|
||||
scope['types'] = types;
|
||||
|
||||
|
||||
|
||||
|
||||
var getEqHashCode = plt.baselib.hashes.getEqHashCode;
|
||||
// makeLowLevelEqHash: -> hashtable
|
||||
// Constructs an eq hashtable that uses Moby's getEqHashCode function.
|
||||
var makeLowLevelEqHash = plt.baselib.hashes.makeLowLevelEqHash;
|
||||
var toWrittenString = plt.baselib.format.toWrittenString;
|
||||
var toDisplayedString = plt.baselib.format.toDisplayedString;
|
||||
var toDomNode = plt.baselib.format.toDomNode;
|
||||
|
||||
|
||||
|
||||
var appendChild = function(parent, child) {
|
||||
parent.appendChild(child);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
var Symbol = plt.baselib.symbols.Symbol;
|
||||
var Empty = plt.baselib.lists.Empty;
|
||||
var Cons = plt.baselib.lists.Cons;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var isNumber = jsnums.isSchemeNumber;
|
||||
|
||||
var isReal = jsnums.isReal;
|
||||
var isRational = jsnums.isRational;
|
||||
var isComplex = isNumber;
|
||||
var isInteger = jsnums.isInteger;
|
||||
|
||||
var isNatural = function(x) {
|
||||
return (jsnums.isExact(x) && isInteger(x)
|
||||
&& jsnums.greaterThanOrEqual(x, 0));
|
||||
};
|
||||
var isNonNegativeReal = function(x) {
|
||||
return isReal(x) && jsnums.greaterThanOrEqual(x, 0);
|
||||
};
|
||||
|
||||
var isString = plt.baselib.strings.isString;
|
||||
|
||||
var equals = plt.baselib.equality.equals;
|
||||
|
||||
// isList: Any -> Boolean
|
||||
// Returns true if x is a list (a chain of pairs terminated by EMPTY).
|
||||
var isList = function(x) {
|
||||
while (x !== Empty.EMPTY) {
|
||||
if (x instanceof Cons){
|
||||
x = x.rest;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
var makeList = function() {
|
||||
var result = Empty.EMPTY;
|
||||
for(var i = arguments.length-1; i >= 0; i--) {
|
||||
result = Cons.makeInstance(arguments[i], result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
var makeVector = function() {
|
||||
return Vector.makeInstance(arguments.length, arguments);
|
||||
};
|
||||
|
||||
|
||||
var makeVectorImmutable = function() {
|
||||
var v = Vector.makeInstance(arguments.length, arguments);
|
||||
v.mutable = false;
|
||||
return v;
|
||||
};
|
||||
|
||||
|
||||
var makeString = function(s) {
|
||||
if (s instanceof plt.baselib.strings.Str) {
|
||||
return s;
|
||||
}
|
||||
else if (s instanceof Array) {
|
||||
// for (var i = 0; i < s.length; i++) {
|
||||
// if ( typeof s[i] !== 'string' || s[i].length != 1 ) {
|
||||
// return undefined;
|
||||
// }
|
||||
// }
|
||||
return plt.baselib.strings.Str.makeInstance(s);
|
||||
}
|
||||
else if (typeof s === 'string') {
|
||||
return plt.baselib.strings.Str.fromString(s);
|
||||
}
|
||||
else {
|
||||
throw types.internalError('makeString expects and array of 1-character strings or a string;' +
|
||||
' given ' + s.toString(),
|
||||
false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var makeHashEq = function(lst) {
|
||||
var newHash = new plt.baselib.hashes.EqHashTable();
|
||||
while ( !isEmpty(lst) ) {
|
||||
newHash.hash.put(lst.first.first, lst.first.rest);
|
||||
lst = lst.rest;
|
||||
}
|
||||
return newHash;
|
||||
};
|
||||
|
||||
|
||||
var makeHashEqual = function(lst) {
|
||||
var newHash = new plt.baselib.hashes.EqualHashTable();
|
||||
while ( !isEmpty(lst) ) {
|
||||
newHash.hash.put(lst.first.first, lst.first.rest);
|
||||
lst = lst.rest;
|
||||
}
|
||||
return newHash;
|
||||
};
|
||||
|
||||
|
||||
var Color = plt.baselib.structs.makeStructureType(
|
||||
'color', false, 3, 0, false, false);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// var JsValue = function(name, val) {
|
||||
// this.name = name;
|
||||
// this.val = val;
|
||||
// };
|
||||
|
||||
// JsValue.prototype.toString = function() {
|
||||
// return '#<js-value:' + typeof(this.val) + ':' + this.name + '>';
|
||||
// };
|
||||
|
||||
// JsValue.prototype.toDomNode = function(cache) {
|
||||
// return toDomNode(this.val, cache);
|
||||
// };
|
||||
|
||||
// JsValue.prototype.equals = function(other, aUnionFind) {
|
||||
// return (this.val === other.val);
|
||||
// };
|
||||
|
||||
// // unbox: jsvalue -> any
|
||||
// // Unwraps the value out of the JsValue box.
|
||||
// JsValue.prototype.unbox = function() {
|
||||
// return this.val;
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// var WrappedSchemeValue = function(val) {
|
||||
// this.val = val;
|
||||
// };
|
||||
|
||||
// WrappedSchemeValue.prototype.toString = function() { return toString(this.val); };
|
||||
// WrappedSchemeValue.prototype.toWrittenString = function(cache) { return toWrittenString(this.val, cache); };
|
||||
// WrappedSchemeValue.prototype.toDisplayedString = function(cache) { return toDisplayedString(this.val, cache); };
|
||||
|
||||
|
||||
// // unbox: jsvalue -> any
|
||||
// // Unwraps the value out of the WrappedSchemeValue box.
|
||||
// WrappedSchemeValue.prototype.unbox = function() {
|
||||
// return this.val;
|
||||
// };
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// var WorldConfig = function(startup, shutdown, startupArgs) {
|
||||
// this.startup = startup;
|
||||
// this.shutdown = shutdown;
|
||||
// this.startupArgs = startupArgs;
|
||||
// };
|
||||
|
||||
// WorldConfig.prototype.toString = function() {
|
||||
// return '#<world-config>';
|
||||
// };
|
||||
|
||||
// WorldConfig.prototype.equals = function(other, aUnionFind) {
|
||||
// return ( equals(this.startup, other.startup, aUnionFind) &&
|
||||
// equals(this.shutdown, other.shutdown, aUnionFind) &&
|
||||
// equals(this.shutdownArg, other.shutdownArg, aUnionFind) &&
|
||||
// equals(this.restartArg, other.restartArg, aUnionFind) );
|
||||
// };
|
||||
|
||||
|
||||
// var Effect = plt.baselib.structs.makeStructureType('effect', false, 0, 0, false, false);
|
||||
// Effect.type.prototype.invokeEffect = function() {
|
||||
// helpers.raise(types.incompleteExn(
|
||||
// types.exnFail,
|
||||
// 'effect type created without using make-effect-type',
|
||||
// []));
|
||||
// };
|
||||
|
||||
|
||||
// var makeEffectType = function(name, superType, initFieldCnt, impl, guard) {
|
||||
// if ( !superType ) {
|
||||
// superType = Effect;
|
||||
// }
|
||||
|
||||
// var newType = plt.baselib.structs.makeStructureType(name, superType, initFieldCnt, 0, false, guard);
|
||||
// var lastFieldIndex = newType.firstField + newType.numberOfFields;
|
||||
|
||||
// newType.type.prototype.invokeEffect = function(aBigBang, k) {
|
||||
// var schemeChangeWorld = new PrimProc('update-world', 1, false, false,
|
||||
// function(worldUpdater) {
|
||||
// //helpers.check(worldUpdater, helpers.procArityContains(1),
|
||||
// // 'update-world', 'procedure (arity 1)', 1);
|
||||
|
||||
// return new INTERNAL_PAUSE(
|
||||
// function(caller, onSuccess, onFail) {
|
||||
// aBigBang.changeWorld(function(w, k2) {
|
||||
// caller(worldUpdater,
|
||||
// [w], k2,
|
||||
// function(e) { throw e; },
|
||||
// 'change-world (effect)');
|
||||
// },
|
||||
// function() { onSuccess(VOID_VALUE, 'restarting (change-world (effect))'); });
|
||||
// });
|
||||
// });
|
||||
|
||||
// var args = this._fields.slice(0, lastFieldIndex);
|
||||
// args.unshift(schemeChangeWorld);
|
||||
// return aBigBang.caller(impl, args, k, function(e) { throw e; }, 'invoking effect ' + name);
|
||||
// }
|
||||
|
||||
// return newType;
|
||||
// };
|
||||
|
||||
|
||||
// var RenderEffect = plt.baselib.structs.makeStructureType('render-effect', false, 0, 0, false, false);
|
||||
// RenderEffect.type.prototype.callImplementation = function(caller, k) {
|
||||
// helpers.raise(types.incompleteExn(
|
||||
// types.exnFail,
|
||||
// 'render effect created without using make-render-effect-type',
|
||||
// []));
|
||||
// };
|
||||
|
||||
// var makeRenderEffectType = function(name, superType, initFieldCnt, impl, guard) {
|
||||
// if ( !superType ) {
|
||||
// superType = RenderEffect;
|
||||
// }
|
||||
|
||||
// var newType = plt.baselib.structs.makeStructureType(name, superType, initFieldCnt, 0, false, guard);
|
||||
// var lastFieldIndex = newType.firstField + newType.numberOfFields;
|
||||
|
||||
// newType.type.prototype.callImplementation = function(caller, k) {
|
||||
// var args = this._fields.slice(0, lastFieldIndex);
|
||||
// caller(impl, args, k);
|
||||
// }
|
||||
|
||||
// return newType;
|
||||
// };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// var makeOptionPrimitive = function(name,
|
||||
// numArgs,
|
||||
// defaultVals,
|
||||
// usesState,
|
||||
// bodyF) {
|
||||
// var makeNthPrimitive = function(n) {
|
||||
// return new PrimProc(name,
|
||||
// numArgs + n,
|
||||
// false,
|
||||
// usesState,
|
||||
// function() {
|
||||
// var expectedNumArgs = numArgs + n + (usesState ? 1 : 0);
|
||||
// assert.equal(arguments.length,
|
||||
// expectedNumArgs);
|
||||
// var args = [arguments];
|
||||
// for (var i = 0; i < arguments.length; i++) {
|
||||
// args.push(arguments[i]);
|
||||
// }
|
||||
// var startDefaults = i - numArgs - (usesState ? 1 : 0);
|
||||
// return bodyF.apply(
|
||||
// bodyF,
|
||||
// args.concat(defaultVals.slice(startDefaults)));
|
||||
// });
|
||||
// };
|
||||
|
||||
// var cases = [];
|
||||
// for (var i = 0; i <= defaultVals.length; i++) {
|
||||
// cases.push(makeNthPrimitive(i));
|
||||
// }
|
||||
// return new CasePrimitive(name, cases);
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// INTERNAL_CALL
|
||||
// used for interaction between the Primitives and the interpreter (callPrimitiveProcedure).
|
||||
// Don't confuse this with CallControl.
|
||||
// var INTERNAL_CALL = function(operator, operands, k) {
|
||||
// this.operator = operator;
|
||||
// this.operands = operands;
|
||||
// this.k = k;
|
||||
// };
|
||||
|
||||
// // INTERNAL_PAUSE
|
||||
// // used for interaction between the Primitive functions and the
|
||||
// // interpreter.
|
||||
// // Halts the interpreter, but passing onPause the functions necessary
|
||||
// // to restart computation.
|
||||
// var INTERNAL_PAUSE = function(onPause) {
|
||||
// this.onPause = onPause;
|
||||
// };
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// // ContinuationPromptTag: symbol | false -> ContinuationPromptTag
|
||||
// var ContinuationPromptTag = function(sym) {
|
||||
// this.sym = sym;
|
||||
// };
|
||||
|
||||
// var defaultContinuationPromptTag = new ContinuationPromptTag();
|
||||
|
||||
// var defaultContinuationPromptTagHandler = new PrimProc(
|
||||
// 'default-continuation-prompt-tag-handler',
|
||||
// 1,
|
||||
// false,
|
||||
// true,
|
||||
// function(aState, thunk) {
|
||||
// aState.pushControl(
|
||||
// new control.ApplicationControl(
|
||||
// new control.ConstantControl(thunk),
|
||||
// []));
|
||||
// });
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Exports
|
||||
|
||||
|
||||
|
||||
types.symbol = Symbol.makeInstance;
|
||||
types.rational = jsnums.makeRational;
|
||||
types.floatpoint = jsnums.makeFloat;
|
||||
types.complex = jsnums.makeComplex;
|
||||
types.bignum = jsnums.makeBignum;
|
||||
types.list = makeList;
|
||||
types.vector = makeVector;
|
||||
types.vectorImmutable = makeVectorImmutable;
|
||||
types.regexp = function(p) { return new plt.baselib.regexps.RegularExpression(p) ; }
|
||||
types.byteRegexp = function(p) { return new plt.baselib.regexps.ByteRegularExpression(p) ; }
|
||||
types.character = plt.baselib.chars.Char.makeInstance;
|
||||
types['string'] = makeString;
|
||||
types.placeholder = function(x) { return new plt.baselib.placeholders.Placeholder(x); };
|
||||
types.box = function(x) { return new plt.baselib.boxes.Box(x, true); };
|
||||
types.boxImmutable = function(x) { return new plt.baselib.boxes.Box(x, false); };
|
||||
types.path = function(x) { return new plt.baselib.paths.Path(x); };
|
||||
types.bytes = function(x, mutable) { return new plt.baselib.bytes.Bytes(x, mutable); };
|
||||
types.bytesImmutable = function(x) { return new plt.baselib.bytes.Bytes(x, false); };
|
||||
types.keyword = function(k) { return new plt.baselib.keywords.Keyword(k); };
|
||||
types.pair = function(x, y) { return plt.baselib.lists.Cons.makeInstance(x, y); };
|
||||
types.hash = makeHashEqual;
|
||||
types.hashEq = makeHashEq;
|
||||
// types.jsValue = function(name, val) { return new JsValue(name, val); };
|
||||
// types.wrappedSchemeValue = function(val) { return new WrappedSchemeValue(val); };
|
||||
|
||||
|
||||
types.color = Color.constructor;
|
||||
types.colorRed = function(x) { return Color.accessor(x, 0); };
|
||||
types.colorGreen = function(x) { return Color.accessor(x, 1); };
|
||||
types.colorBlue = function(x) { return Color.accessor(x, 2); };
|
||||
|
||||
|
||||
|
||||
types.FALSE = false;
|
||||
types.TRUE = true;
|
||||
types.EMPTY = Empty.EMPTY;
|
||||
|
||||
types.equals = equals;
|
||||
types.isNumber = isNumber;
|
||||
|
||||
types.isReal = jsnums.isReal;
|
||||
types.isRational = jsnums.isRational;
|
||||
types.isComplex = isNumber;
|
||||
types.isInteger = jsnums.isInteger;
|
||||
types.isNatural = isNatural;
|
||||
types.isNonNegativeReal = isNonNegativeReal;
|
||||
|
||||
|
||||
types.isSymbol = function(x) { return x instanceof Symbol; };
|
||||
types.isChar = function(x) { return x instanceof plt.baselib.chars.Char; };
|
||||
types.isString = isString;
|
||||
types.isPair = function(x) { return x instanceof Cons; };
|
||||
types.isList = isList;
|
||||
types.isEmpty = function(x) { return x === Empty.EMPTY; };
|
||||
types.isVector = function(x) { return x instanceof Vector; };
|
||||
types.isBox = function(x) { return x instanceof plt.baselib.boxes.Box; };
|
||||
types.isPlaceholder = function(x) { return x instanceof plt.baselib.placeholders.Placeholder; };
|
||||
types.isHash = function(x) { return (x instanceof plt.baselib.hashes.EqHashTable ||
|
||||
x instanceof plt.baselib.hashes.EqualHashTable); };
|
||||
types.isByteString = function(x) { return x instanceof plt.baselib.bytes.Bytes; };
|
||||
types.isStruct = function(x) { return x instanceof Struct; };
|
||||
types.isColor = Color.predicate;
|
||||
|
||||
// types.isFunction = function(x) {
|
||||
// return (x instanceof PrimProc);
|
||||
// };
|
||||
|
||||
|
||||
// types.isJsValue = function(x) { return x instanceof JsValue; };
|
||||
// types.isWrappedSchemeValue = function(x) { return x instanceof WrappedSchemeValue; };
|
||||
|
||||
types.cons = Cons.makeInstance;
|
||||
|
||||
types.VOID = plt.baselib.constants.VOID_VALUE;
|
||||
types.EOF = plt.baselib.constants.EOF_VALUE;
|
||||
|
||||
// types.ContinuationPromptTag = ContinuationPromptTag;
|
||||
// types.defaultContinuationPromptTag = defaultContinuationPromptTag;
|
||||
// types.defaultContinuationPromptTagHandler = defaultContinuationPromptTagHandler;
|
||||
// types.makeOptionPrimitive = makeOptionPrimitive;
|
||||
|
||||
// types.internalCall = function(op, args, k) { return new INTERNAL_CALL(op, args, k); };
|
||||
// types.isInternalCall = function(x) { return (x instanceof INTERNAL_CALL); };
|
||||
// types.internalPause = function(onPause) { return new INTERNAL_PAUSE(onPause) };
|
||||
// types.isInternalPause = function(x) { return (x instanceof INTERNAL_PAUSE); };
|
||||
|
||||
|
||||
types.continuationMarkSet = function(dict) { return new plt.baselib.contmarks.ContinuationMarkSet(dict); };
|
||||
types.isContinuationMarkSet = function(x) { return x instanceof plt.baselib.contmarks.ContinuationMarkSet; };
|
||||
// types.isContinuationPromptTag = function(x) { return x instanceof ContinuationPromptTag; };
|
||||
|
||||
|
||||
types.Box = plt.baselib.boxes.Box;
|
||||
types.Placeholder = plt.baselib.placeholders.Placeholder;
|
||||
|
||||
|
||||
|
||||
types.isStructType = function(x) { return x instanceof plt.baselib.structs.StructType; };
|
||||
|
||||
// types.StructProc = StructProc;
|
||||
// types.StructConstructorProc = StructConstructorProc;
|
||||
// types.StructPredicateProc = StructPredicateProc;
|
||||
// types.StructAccessorProc = StructAccessorProc;
|
||||
// types.StructMutatorProc = StructMutatorProc;
|
||||
|
||||
|
||||
|
||||
|
||||
types.makeLowLevelEqHash = makeLowLevelEqHash;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// World-specific exports
|
||||
|
||||
// // big bang info to be passed into a make-world-config startup argument
|
||||
// var BigBangInfo = plt.baselib.structs.makeStructureType('bb-info', false, 2, 0, false,
|
||||
// function(args, name, k) {
|
||||
// //helpers.check(args[0], helpers.procArityContains(1), name, 'procedure (arity 1)', 1);
|
||||
// //helpers.check(args[1], types.isJsValue, name, 'js-object', 2);
|
||||
// return k(args);
|
||||
// });
|
||||
// types.BigBangInfo = BigBangInfo;
|
||||
// types.makeBigBangInfo = BigBangInfo.constructor;
|
||||
// types.isBigBangInfo = BigBangInfo.predicate;
|
||||
// types.bbInfoChangeWorld = function(info) { return BigBangInfo.accessor(info, 0); };
|
||||
// types.bbInfoToplevelNode = function(info) { return BigBangInfo.accessor(info, 1); };
|
||||
|
||||
|
||||
|
||||
// World config information for user-defined configurations
|
||||
// types.worldConfig = function(startup, shutdown, pause, restart) { return new WorldConfig(startup, shutdown, pause, restart); };
|
||||
// types.isWorldConfig = function(x) { return x instanceof WorldConfig; };
|
||||
|
||||
|
||||
// exporting information to create effect types
|
||||
// types.makeEffectType = makeEffectType;
|
||||
// types.isEffectType = function(x) {
|
||||
// return ((x instanceof plt.baselib.structs.StructType)&& x.type.prototype.invokeEffect) ? true : false;
|
||||
// };
|
||||
|
||||
// types.isEffect = Effect.predicate;
|
||||
|
||||
|
||||
// exporting functions to create render effect types
|
||||
// types.makeRenderEffectType = makeRenderEffectType;
|
||||
// types.isRenderEffectType = function(x) {
|
||||
// return (x instanceof plt.baselib.structs.StructType && x.type.prototype.callImplementation) ? true : false;
|
||||
// };
|
||||
|
||||
// types.isRenderEffect = RenderEffect.predicate;
|
||||
|
||||
|
||||
|
||||
|
||||
scope.link.announceReady('types');
|
||||
})(this['plt']);
|
||||
|
|
@ -1856,5 +1856,6 @@ and suggesting improvements.
|
|||
"Robby Findler"
|
||||
"Gregor Kiczales"
|
||||
"Cristina Teodoropol"
|
||||
"Matthew Flatt"
|
||||
) string<?))
|
||||
)
|
4
tests/more-tests/map.expected
Normal file
4
tests/more-tests/map.expected
Normal file
|
@ -0,0 +1,4 @@
|
|||
(5 7 9)
|
||||
(5 7 9)
|
||||
(12 15 18)
|
||||
(1 2 3)
|
6
tests/more-tests/map.rkt
Normal file
6
tests/more-tests/map.rkt
Normal file
|
@ -0,0 +1,6 @@
|
|||
#lang planet dyoo/whalesong
|
||||
|
||||
(map (lambda (x y) (+ x y)) (list 1 2 3) (list 4 5 6))
|
||||
(map + (list 1 2 3) (list 4 5 6))
|
||||
(map + (list 1 2 3) (list 4 5 6) (list 7 8 9))
|
||||
(map + (list 1 2 3))
|
40
tests/more-tests/nqueens.rkt
Normal file
40
tests/more-tests/nqueens.rkt
Normal file
|
@ -0,0 +1,40 @@
|
|||
#lang planet dyoo/whalesong/base
|
||||
;;; NQUEENS -- Compute number of solutions to 8-queens problem.
|
||||
;; 2006/08 -- renamed `try' to `try-it' to avoid Bigloo collision (mflatt)
|
||||
;; 2010/04 -- got rid of the one-armed id (stamourv)
|
||||
|
||||
(define trace? #f)
|
||||
|
||||
(define (nqueens n)
|
||||
|
||||
(define (one-to n)
|
||||
(let loop ((i n) (l '()))
|
||||
(if (= i 0) l (loop (- i 1) (cons i l)))))
|
||||
|
||||
(define (try-it x y z)
|
||||
(if (null? x)
|
||||
(if (null? y)
|
||||
(begin (if trace? (begin (write z) (newline)) #t) 1)
|
||||
0)
|
||||
(+ (if (ok? (car x) 1 z)
|
||||
(try-it (append (cdr x) y) '() (cons (car x) z))
|
||||
0)
|
||||
(try-it (cdr x) (cons (car x) y) z))))
|
||||
|
||||
(define (ok? row dist placed)
|
||||
(if (null? placed)
|
||||
#t
|
||||
(and (not (= (car placed) (+ row dist)))
|
||||
(not (= (car placed) (- row dist)))
|
||||
(ok? row (+ dist 1) (cdr placed)))))
|
||||
|
||||
(try-it (one-to n) '() '()))
|
||||
|
||||
(let loop ((n 1000 ;10000
|
||||
)
|
||||
(v 0))
|
||||
(if (zero? n)
|
||||
v
|
||||
(loop (- n 1) (nqueens 8
|
||||
; (if input 8 0)
|
||||
))))
|
|
@ -14,6 +14,7 @@
|
|||
(test "more-tests/hello.rkt")
|
||||
(test "more-tests/sharing.rkt")
|
||||
(test "more-tests/simple-functions.rkt")
|
||||
(test "more-tests/map.rkt")
|
||||
(test "more-tests/quasi.rkt")
|
||||
(test "more-tests/sk-generator.rkt")
|
||||
(test "more-tests/sk-generator-2.rkt")
|
||||
|
|
|
@ -21,6 +21,12 @@ var checkProcedureWithKey = plt.baselib.check.makeCheckArgumentType(
|
|||
plt.baselib.arity.isArityMatching(x.racketArity, 2)); },
|
||||
'procedure that consumes a world argument and a key');
|
||||
|
||||
var checkProcedureWithMouse = plt.baselib.check.makeCheckArgumentType(
|
||||
function(x) { return (plt.baselib.functions.isProcedure(x) &&
|
||||
plt.baselib.arity.isArityMatching(x.racketArity, 4)); },
|
||||
'procedure that consumes a world argument, an x and y coordinate, and a mouse event');
|
||||
|
||||
|
||||
|
||||
var checkHandler = plt.baselib.check.makeCheckArgumentType(
|
||||
isWorldConfigOption,
|
||||
|
@ -97,6 +103,17 @@ EXPORTS['on-key'] =
|
|||
return new OnKey(f);
|
||||
});
|
||||
|
||||
EXPORTS['on-mouse'] =
|
||||
makePrimitiveProcedure(
|
||||
'on-mouse',
|
||||
1,
|
||||
function(MACHINE) {
|
||||
var f = checkProcedureWithMouse(MACHINE, "on-key", 0);
|
||||
return new OnMouse(f);
|
||||
});
|
||||
|
||||
|
||||
|
||||
EXPORTS['key=?'] =
|
||||
makePrimitiveProcedure(
|
||||
'on-key',
|
||||
|
|
888
world/kernel.js
888
world/kernel.js
|
@ -233,6 +233,27 @@ var getKeyCodeName = function(e) {
|
|||
|
||||
|
||||
|
||||
var OnMouse = function(handler) {
|
||||
WorldConfigOption.call(this, 'on-mouse');
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
OnMouse.prototype = plt.baselib.heir(WorldConfigOption.prototype);
|
||||
|
||||
OnMouse.prototype.toRawHandler = function(MACHINE, toplevelNode) {
|
||||
var that = this;
|
||||
var worldFunction = adaptWorldFunction(that.handler);
|
||||
return rawJsworld.on_mouse(
|
||||
function(w, x, y, type, success) {
|
||||
worldFunction(w, x, y, type, success);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var OutputConfig = function() {}
|
||||
|
@ -351,870 +372,3 @@ StopWhen.prototype.toRawHandler = function(MACHINE, toplevelNode) {
|
|||
var worldFunction = adaptWorldFunction(that.handler);
|
||||
return rawJsworld.stop_when(worldFunction);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // This needs to be cleaned up!
|
||||
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
|
||||
// // The real low-level jsworld module:
|
||||
// var _js = jsworld.Jsworld;
|
||||
|
||||
|
||||
// var caller;
|
||||
// var setCaller = function(c) {
|
||||
// caller = function(op, args, k) {
|
||||
// c(op, args, k, handleError);
|
||||
// };
|
||||
// };
|
||||
// var unsetCaller = function() {
|
||||
// caller = function(op, args, k) {
|
||||
// throw new Error('caller not defined!');
|
||||
// };
|
||||
// };
|
||||
// unsetCaller();
|
||||
|
||||
// // The restarted and things to set it
|
||||
// // Note that we never want to restart the same computation
|
||||
// // more than once, so we throw an error if someone tries to do that
|
||||
// var restarter;
|
||||
// var setRestarter = function(r) {
|
||||
// var hasRestarted = false;
|
||||
// restarter = function(v) {
|
||||
// if (hasRestarted) {
|
||||
// throw new Error('Cannot restart twice!');
|
||||
// }
|
||||
// hasRestarted = true;
|
||||
// r(v);
|
||||
// };
|
||||
// };
|
||||
// var unsetRestarter = function() {
|
||||
// restarter = function() {
|
||||
// throw new Error('restarter not defined!');
|
||||
// };
|
||||
// };
|
||||
// unsetRestarter();
|
||||
|
||||
|
||||
// var errorReporter = function(e) {
|
||||
// // default: do nothing.
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// var terminator;
|
||||
// var setTerminator = function(t) {
|
||||
// terminator = t;
|
||||
// };
|
||||
// var unsetTerminator = function() {
|
||||
// terminator = function() {
|
||||
// throw new Error('terminator not defined!');
|
||||
// };
|
||||
// };
|
||||
// unsetTerminator();
|
||||
|
||||
|
||||
|
||||
// // mutateStringsInDeepArray: array -> array
|
||||
// // walks and in-place mutates Scheme strings to primitive strings.
|
||||
// var mutateStringsInDeepArray = function(thing) {
|
||||
// var i, length;
|
||||
// if (typeof(thing) === 'object' &&
|
||||
// thing.constructor === Array) {
|
||||
// length = thing.length;
|
||||
// for (i = 0; i < length; i++) {
|
||||
// thing[i] = mutateStringsInDeepArray(thing[i]);
|
||||
// }
|
||||
// } else if (types.isString(thing)) {
|
||||
// return thing.toString();
|
||||
// }
|
||||
// return thing;
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
// var userConfigs = [];
|
||||
|
||||
// var startUserConfigs = function(k) {
|
||||
// helpers.forEachK(userConfigs,
|
||||
// function(aConfig, k2) {
|
||||
// caller(aConfig.startup, aConfig.startupArgs,
|
||||
// function(res) {
|
||||
// aConfig.isRunning = true;
|
||||
// aConfig.shutdownArg = res;
|
||||
// k2()
|
||||
// });
|
||||
// },
|
||||
// handleError,
|
||||
// k);
|
||||
// }
|
||||
|
||||
// var shutdownUserConfigs = function(k) {
|
||||
// // console.log('shutting down user configs');
|
||||
// var theConfigs = userConfigs;
|
||||
// userConfigs = []
|
||||
// helpers.forEachK(theConfigs,
|
||||
// function(aConfig, k2) {
|
||||
// // console.log(' shutting down a config');
|
||||
// if (aConfig.isRunning) {
|
||||
// aConfig.isRunning = false;
|
||||
// caller(aConfig.shutdown, [aConfig.shutdownArg], k2);
|
||||
// } else {
|
||||
// k2();
|
||||
// }
|
||||
// },
|
||||
// handleError,
|
||||
// k);
|
||||
// }
|
||||
|
||||
// var expandHandler = function(handler) {
|
||||
// return types.jsValue('function', function() {
|
||||
// var wrappedStimulusArgs = [];
|
||||
// for (var i = 0; i < arguments.length; i++) {
|
||||
// wrappedStimulusArgs.push( helpers.wrapJsValue(arguments[i]) );
|
||||
// }
|
||||
|
||||
// Jsworld.updateWorld(
|
||||
// function(w, k) {
|
||||
// var args = [w].concat(wrappedStimulusArgs);
|
||||
// caller(handler, args, k);
|
||||
// },
|
||||
// function() {});
|
||||
// });
|
||||
// };
|
||||
|
||||
|
||||
// // var unwrapWorldEffects = function(w) {
|
||||
// // if ( _js.has_effects(w) ) {
|
||||
// // var unwrappedEffects =
|
||||
// // helpers.map(function(e) {
|
||||
// // if ( types.isEffect(e) ) {
|
||||
// // return types.makeJsworldEffect(function(k) {
|
||||
// // caller(types.effectThunk(e), [], k);
|
||||
// // });
|
||||
// // }
|
||||
// // else {
|
||||
// // return e;
|
||||
// // }
|
||||
// // },
|
||||
// // w.getEffects());
|
||||
// // var returnVal = _js.with_multiple_effects(w.getWorld(), unwrappedEffects);
|
||||
// // return returnVal;
|
||||
// // }
|
||||
// // else {
|
||||
// // return w;
|
||||
// // }
|
||||
// // };
|
||||
|
||||
|
||||
// var deepUnwrapJsValues = function(x, k) {
|
||||
// if ( types.isJsValue(x) ) {
|
||||
// k(x.unbox());
|
||||
// }
|
||||
// else if ( types.isRenderEffect(x) ) {
|
||||
// x.callImplementation(caller, function(y) { deepUnwrapJsValues(y, k); });
|
||||
// }
|
||||
// // var effects = helpers.schemeListToArray( types.renderEffectEffects(x) ).reverse();
|
||||
// // types.setRenderEffectEffects(x, types.EMPTY);
|
||||
// //
|
||||
// // helpers.forEachK(effects,
|
||||
// // function(ef, k2) { caller(ef, [], k2); },
|
||||
// // handleError,
|
||||
// // function() { deepUnwrapJsValues(types.renderEffectDomNode(x), k); });
|
||||
// // }
|
||||
// else if ( types.isPair(x) ) {
|
||||
// deepUnwrapJsValues(x.first(), function(first) {
|
||||
// deepUnwrapJsValues(x.rest(), function(rest) {
|
||||
// k( types.cons(first, rest) );
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// else {
|
||||
// k(x);
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // isHandler: X -> boolean
|
||||
// // Right now, a handler is a function that consumes and produces
|
||||
// // configs. We should tighten up the type check eventually.
|
||||
// var isHandler = function(x) {
|
||||
// return typeof(x) == 'function';
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
// //From this point forward, we define wrappers to integrate jsworld
|
||||
// //with Moby.
|
||||
|
||||
|
||||
// // getBigBangWindow: -> window
|
||||
// var getBigBangWindow = function() {
|
||||
// if (window.document.getElementById("jsworld-div") !== undefined) {
|
||||
// return window;
|
||||
// } else {
|
||||
// var newDiv = window.document.createElement("div");
|
||||
// newDiv.id = 'jsworld-div';
|
||||
// window.document.appendChild(newDiv);
|
||||
// return window;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// // types are
|
||||
// // sexp: (cons node (listof sexp))
|
||||
// // css-style: (node (listof (list string string)))
|
||||
|
||||
// // Exports:
|
||||
|
||||
|
||||
|
||||
|
||||
// var isPair = types.isPair;
|
||||
// var isEmpty = function(x) { return x === types.EMPTY; };
|
||||
// var isList = function(x) { return (isPair(x) || isEmpty(x)); };
|
||||
|
||||
|
||||
|
||||
// // The default printWorldHook will write the written content of the node.
|
||||
// // We probably want to invoke the pretty printer here instead!
|
||||
// Jsworld.printWorldHook = function(world, node) {
|
||||
// var newNode;
|
||||
// if(node.lastChild == null) {
|
||||
// newNode = types.toDomNode(world);
|
||||
// node.appendChild(newNode);
|
||||
// helpers.maybeCallAfterAttach(newNode);
|
||||
// } else {
|
||||
// newNode = types.toDomNode(world);
|
||||
// node.replaceChild(newNode, node.lastChild);
|
||||
// helpers.maybeCallAfterAttach(newNode);
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// // Figure out the target of an event.
|
||||
// // http://www.quirksmode.org/js/events_properties.html#target
|
||||
// var findEventTarget = function(e) {
|
||||
// var targ;
|
||||
// if (e.target)
|
||||
// targ = e.target;
|
||||
// else if (e.srcElement)
|
||||
// targ = e.srcElement;
|
||||
// if (targ.nodeType == 3) // defeat Safari bug
|
||||
// targ = targ.parentNode;
|
||||
// return targ;
|
||||
// }
|
||||
|
||||
// // isNode: any -> boolean
|
||||
// // Returns true if the thing has a nodeType.
|
||||
// var isNode = function(thing) {
|
||||
// return thing && typeof(thing.nodeType) != 'undefined';
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// // checkWellFormedDomTree: X X (or number undefined) -> void
|
||||
// // Check to see if the tree is well formed. If it isn't,
|
||||
// // we need to raise a meaningful error so the user can repair
|
||||
// // the structure.
|
||||
// //
|
||||
// // Invariants:
|
||||
// // The dom tree must be a pair.
|
||||
// // The first element must be a node.
|
||||
// // Each of the rest of the elements must be dom trees.
|
||||
// // If the first element is a text node, it must NOT have children.
|
||||
// var checkWellFormedDomTree = function(x, top, index) {
|
||||
// var fail = function(formatStr, formatArgs) {
|
||||
// throw types.schemeError(
|
||||
// types.incompleteExn(types.exnFailContract,
|
||||
// helpers.format(formatStr, formatArgs),
|
||||
// []));
|
||||
// }
|
||||
|
||||
// if (_js.isPage(x)) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (types.isPair(x)) {
|
||||
// var firstElt = x.first();
|
||||
// var restElts = x.rest();
|
||||
|
||||
// if (! isNode(firstElt)) {
|
||||
// fail("on-draw: expected a dom-element, but received ~s instead, the first element within ~s", [firstElt, top]);
|
||||
// }
|
||||
|
||||
// if (firstElt.nodeType == Node.TEXT_NODE && !restElts.isEmpty() ) {
|
||||
// fail("on-draw: the text node ~s must not have children. It has ~s", [firstElt, restElts]);
|
||||
// }
|
||||
|
||||
// var i = 2;
|
||||
// while( !restElts.isEmpty() ) {
|
||||
// checkWellFormedDomTree(restElts.first(), x, i);
|
||||
// restElts = restElts.rest();
|
||||
// i++;
|
||||
// }
|
||||
// } else {
|
||||
// var formatStr = "on-draw: expected a dom-s-expression, but received ~s instead";
|
||||
// var formatArgs = [x];
|
||||
// if (index != undefined) {
|
||||
// formatStr += ", the ~a element within ~s";
|
||||
// formatArgs.push( helpers.ordinalize(index) );
|
||||
// formatArgs.push(top);
|
||||
// }
|
||||
// formatStr += ".";
|
||||
|
||||
// fail(formatStr, formatArgs);
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
// // Compatibility for attaching events to nodes.
|
||||
// var attachEvent = function(node, eventName, fn) {
|
||||
// if (node.addEventListener) {
|
||||
// // Mozilla
|
||||
// node.addEventListener(eventName, fn, false);
|
||||
// } else {
|
||||
// // IE
|
||||
// node.attachEvent('on' + eventName, fn, false);
|
||||
// }
|
||||
// return function() {
|
||||
// detachEvent(node, eventName, fn);
|
||||
// }
|
||||
// };
|
||||
|
||||
// var detachEvent = function(node, eventName, fn) {
|
||||
// if (node.addEventListener) {
|
||||
// // Mozilla
|
||||
// node.removeEventListener(eventName, fn, false);
|
||||
// } else {
|
||||
// // IE
|
||||
// node.detachEvent('on' + eventName, fn, false);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// var preventDefault = function(event) {
|
||||
// if (event.preventDefault) {
|
||||
// event.preventDefault();
|
||||
// } else {
|
||||
// event.returnValue = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// var stopPropagation = function(event) {
|
||||
// if (event.stopPropagation) {
|
||||
// event.stopPropagation();
|
||||
// } else {
|
||||
// event.cancelBubble = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// // bigBang: world dom (listof (list string string)) (arrayof handler) -> world
|
||||
// Jsworld.bigBang = function(initWorld, toplevelNode, handlers, theCaller, theRestarter, onFail) {
|
||||
// // shutdownListeners: arrayof (-> void)
|
||||
// // We maintain a list of thunks that need to be called as soon as we come out of
|
||||
// // bigBang, to do cleanup.
|
||||
// var shutdownListeners = [];
|
||||
|
||||
// var onTermination = function(w) {
|
||||
// for (var i = 0; i < shutdownListeners.length; i++) {
|
||||
// try {
|
||||
// shutdownListeners[i]();
|
||||
// } catch (e) { }
|
||||
// }
|
||||
// shutdownUserConfigs(function() {
|
||||
// unsetCaller();
|
||||
// theRestarter(w);
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// //console.log('in high level big-bang');
|
||||
// errorReporter = onFail;
|
||||
|
||||
// setCaller(theCaller);
|
||||
// setRestarter(theRestarter);
|
||||
// setTerminator(function(w) {
|
||||
// detachEvent(toplevelNode, 'click', absorber);
|
||||
// shutdownUserConfigs(function() {
|
||||
// unsetCaller();
|
||||
// unsetTerminator();
|
||||
// restarter(w);
|
||||
// });
|
||||
// });
|
||||
|
||||
// var attribs = types.EMPTY;
|
||||
|
||||
// // Ensure that the toplevelNode can be focused by mouse or keyboard
|
||||
// toplevelNode.tabIndex = 0;
|
||||
|
||||
// // Absorb all click events so they don't bubble up.
|
||||
// var absorber = function(e) {
|
||||
// preventDefault(e);
|
||||
// stopPropagation(e);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// attachEvent(toplevelNode, 'click', absorber);
|
||||
// shutdownListeners.push(function() { detachEvent(toplevelNode, 'click', absorber)});
|
||||
|
||||
|
||||
|
||||
// var config = new world.Kernel.config.WorldConfig();
|
||||
// for(var i = 0; i < handlers.length; i++) {
|
||||
// if (isList(handlers[i])) {
|
||||
// attribs = handlers[i];
|
||||
// }
|
||||
// else if (isHandler(handlers[i])) {
|
||||
// config = handlers[i](config);
|
||||
// }
|
||||
// else if ( types.isWorldConfig(handlers[i]) ) {
|
||||
// handlers[i].startupArgs = helpers.map(expandHandler, handlers[i].startupArgs);
|
||||
// userConfigs.push(handlers[i]);
|
||||
// }
|
||||
// }
|
||||
// config = config.updateAll({'changeWorld': Jsworld.updateWorld,
|
||||
// 'shutdownWorld': Jsworld.shutdownWorld});
|
||||
// var stimuli = new world.Kernel.stimuli.StimuliHandler(config, caller, restarter);
|
||||
|
||||
// var wrappedHandlers = [];
|
||||
// var wrappedRedraw;
|
||||
// var wrappedRedrawCss;
|
||||
|
||||
|
||||
// if (config.lookup('onDraw')) {
|
||||
// wrappedRedraw = function(w, k) {
|
||||
// try {
|
||||
// caller(config.lookup('onDraw'), [w],
|
||||
// function(newDomTree) {
|
||||
// deepUnwrapJsValues(newDomTree, function(unwrappedTree) {
|
||||
// checkWellFormedDomTree(unwrappedTree, unwrappedTree, undefined);
|
||||
// var result = [toplevelNode,
|
||||
// helpers.deepListToArray(unwrappedTree)];
|
||||
// k(result);
|
||||
// });
|
||||
// });
|
||||
// } catch (e) {
|
||||
// handleError(e);
|
||||
// // throw e;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (config.lookup('onDrawCss')) {
|
||||
// wrappedRedrawCss = function(w, k) {
|
||||
// try {
|
||||
// caller(config.lookup('onDrawCss'), [w],
|
||||
// function(res) {
|
||||
// var result = helpers.deepListToArray(res);
|
||||
// result = mutateStringsInDeepArray(result);
|
||||
// // plt.Kernel.setLastLoc(undefined);
|
||||
// k(result);
|
||||
// });
|
||||
// } catch (e) {
|
||||
// handleError(e);
|
||||
// // throw e;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// wrappedRedrawCss = function(w, k) { k([]); };
|
||||
// }
|
||||
// wrappedHandlers.push(_js.on_draw(wrappedRedraw, wrappedRedrawCss));
|
||||
// } else if (config.lookup('onRedraw')) {
|
||||
// var reusableCanvas = undefined;
|
||||
// var reusableCanvasNode = undefined;
|
||||
|
||||
// wrappedRedraw = function(w, k) {
|
||||
// try {
|
||||
// //console.log('in onRedraw handler');
|
||||
// caller(config.lookup('onRedraw'), [w],
|
||||
// function(aScene) {
|
||||
// // Performance hack: if we're using onRedraw, we know
|
||||
// // we've got a scene, so we optimize away the repeated
|
||||
// // construction of a canvas object.
|
||||
// if ( world.Kernel.isImage(aScene) ) {
|
||||
// var width = aScene.getWidth();
|
||||
// var height = aScene.getHeight();
|
||||
|
||||
// if (! reusableCanvas) {
|
||||
// reusableCanvas = world.Kernel.makeCanvas(width, height);
|
||||
// // Note: the canvas object may itself manage objects,
|
||||
// // as in the case of an excanvas. In that case, we must make
|
||||
// // sure jsworld doesn't try to disrupt its contents!
|
||||
// reusableCanvas.jsworldOpaque = true;
|
||||
// reusableCanvasNode = _js.node_to_tree(reusableCanvas);
|
||||
// }
|
||||
|
||||
// reusableCanvas.width = width;
|
||||
// reusableCanvas.height = height;
|
||||
// var ctx = reusableCanvas.getContext("2d");
|
||||
// aScene.render(ctx, 0, 0);
|
||||
|
||||
// k([toplevelNode, reusableCanvasNode]);
|
||||
// } else {
|
||||
// k([toplevelNode, _js.node_to_tree(types.toDomNode(aScene))]);
|
||||
// }
|
||||
// });
|
||||
// } catch (e) {
|
||||
// handleError(e);
|
||||
// // throw e;
|
||||
// }
|
||||
// }
|
||||
|
||||
// wrappedRedrawCss = function(w, k) {
|
||||
// //console.log('in RedrawCss handler');
|
||||
// k([[reusableCanvas,
|
||||
// ["width", reusableCanvas.width + "px"],
|
||||
// ["height", reusableCanvas.height + "px"]]]);
|
||||
// }
|
||||
// wrappedHandlers.push(_js.on_draw(wrappedRedraw, wrappedRedrawCss));
|
||||
// } else {
|
||||
// wrappedHandlers.push(_js.on_world_change
|
||||
// (function(w, k) {
|
||||
// Jsworld.printWorldHook(w, toplevelNode);
|
||||
// k();
|
||||
// }));
|
||||
// }
|
||||
|
||||
// if (config.lookup('tickDelay')) {
|
||||
// var wrappedTick = function(w, k) {
|
||||
// caller(config.lookup('onTick'),
|
||||
// [w],
|
||||
// k);
|
||||
// }
|
||||
// var wrappedDelay = jsnums.toFixnum( config.lookup('tickDelay') );
|
||||
// wrappedHandlers.push(_js.on_tick(wrappedDelay, wrappedTick));
|
||||
// }
|
||||
|
||||
// if (config.lookup('stopWhen')) {
|
||||
// wrappedHandlers.push(_js.stop_when(
|
||||
// function(w, k) {
|
||||
// caller(config.lookup('stopWhen'), [w],
|
||||
// function(res) { k(res); });
|
||||
// }));
|
||||
// }
|
||||
|
||||
|
||||
// if (config.lookup('onKey')) {
|
||||
// var wrappedKey = function(w, e, k) {
|
||||
// caller(config.lookup('onKey'), [w, helpers.getKeyCodeName(e)], k);
|
||||
// }
|
||||
// wrappedHandlers.push(_js.on_key(wrappedKey));
|
||||
// toplevelNode.focus();
|
||||
// }
|
||||
|
||||
|
||||
// if (config.lookup('initialEffect')) {
|
||||
// var updaters =
|
||||
// world.Kernel.applyEffect(config.lookup('initialEffect'));
|
||||
// for (var i = 0 ; i < updaters.length; i++) {
|
||||
// if (config.lookup('stopWhen') &&
|
||||
// config.lookup('stopWhen')([initWorld])) {
|
||||
// break;
|
||||
// } else {
|
||||
// initWorld = updaters[i](initWorld);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// _js.big_bang(toplevelNode,
|
||||
// initWorld,
|
||||
// wrappedHandlers,
|
||||
// helpers.assocListToHash(attribs),
|
||||
// terminator);
|
||||
|
||||
// startUserConfigs(function() {});
|
||||
|
||||
// return {
|
||||
// breaker: function() {
|
||||
// handleError(types.schemeError(
|
||||
// types.incompleteExn(types.exnBreak, 'user break', [])));
|
||||
// }
|
||||
// };
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// var handleError = function(e) {
|
||||
// // helpers.reportError(e);
|
||||
// // When something bad happens, shut down
|
||||
// // the world computation.
|
||||
// // helpers.reportError("Shutting down jsworld computations");
|
||||
// // world.Kernel.stimuli.onShutdown();
|
||||
// world.Kernel.stimuli.massShutdown();
|
||||
// shutdownUserConfigs(function() {
|
||||
// errorReporter(e);
|
||||
// // console.log('Got an error, the error was:');
|
||||
// // console.log(e);
|
||||
// if (typeof(console) !== 'undefined' && console.log) {
|
||||
// if (e.stack) {
|
||||
// console.log(e.stack);
|
||||
// }
|
||||
// else {
|
||||
// console.log(e);
|
||||
// }
|
||||
// }
|
||||
// if ( types.isSchemeError(e) ) {
|
||||
// terminator(e);
|
||||
// }
|
||||
// else if ( types.isInternalError(e) ) {
|
||||
// terminator(e);
|
||||
// }
|
||||
// else if (typeof(e) == 'string') {
|
||||
// terminator( types.schemeError(types.incompleteExn(types.exnFail, e, [])) );
|
||||
// }
|
||||
// else if (e instanceof Error) {
|
||||
// terminator( types.schemeError(types.incompleteExn(types.exnFail, e.message, [])) );
|
||||
// }
|
||||
// else {
|
||||
// terminator( types.schemeError(e) );
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// // updateWorld: CPS( CPS(world -> world) -> void )
|
||||
// Jsworld.updateWorld = function(updater, k) {
|
||||
// var wrappedUpdater = function(w, k2) {
|
||||
// try {
|
||||
// updater(w, k2);
|
||||
// } catch (e) {
|
||||
// if (typeof(console) !== 'undefined' && console.log && e.stack) {
|
||||
// console.log(e.stack);
|
||||
// }
|
||||
// handleError(e);
|
||||
// // k2(w);
|
||||
// }
|
||||
// }
|
||||
|
||||
// _js.change_world(wrappedUpdater, k);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// // shutdownWorld: -> void
|
||||
// // Shut down all world computations.
|
||||
// Jsworld.shutdownWorld = function() {
|
||||
// _js.shutdown();
|
||||
// };
|
||||
|
||||
|
||||
// // var getAttribs = function(args) {
|
||||
// // if (args.length == 0) {
|
||||
// // return []
|
||||
// // }
|
||||
// // if (args.length == 1) {
|
||||
// // return helpers.assocListToHash(args[0]);
|
||||
// // } else {
|
||||
// // throw new Error("getAttribs recevied unexpected value for args: "
|
||||
// // + args);
|
||||
// // }
|
||||
// // }
|
||||
|
||||
|
||||
// Jsworld.p = _js.p;
|
||||
|
||||
// Jsworld.div = _js.div;
|
||||
|
||||
// Jsworld.buttonBang = function(updateWorldF, effectF, attribs) {
|
||||
// var wrappedF = function(w, evt, k) {
|
||||
// try {
|
||||
// // FIXME: Get effects back online!
|
||||
// // caller(effectF, [world],
|
||||
// // function(effect) {
|
||||
// caller(updateWorldF, [w],
|
||||
// function(newWorld) {
|
||||
// // world.Kernel.applyEffect(effect);
|
||||
// k(newWorld);
|
||||
// });
|
||||
// // });
|
||||
// } catch (e) {
|
||||
// if (typeof(console) !== 'undefined' && console.log && e.stack) {
|
||||
// console.log(e.stack);
|
||||
// }
|
||||
// handleError(e);
|
||||
// // k(w);
|
||||
// }
|
||||
// }
|
||||
// return _js.button(wrappedF, attribs);
|
||||
// };
|
||||
|
||||
|
||||
// Jsworld.input = function(type, updateF, attribs) {
|
||||
// var wrappedUpdater = function(w, evt, k) {
|
||||
// caller(updateF, [w, evt], k);
|
||||
// }
|
||||
// return _js.input(type, wrappedUpdater, attribs);
|
||||
// };
|
||||
|
||||
|
||||
// Jsworld.get_dash_input_dash_value = function(node) {
|
||||
// // plt.Kernel.check(node,
|
||||
// // function(x) { return (plt.Kernel.isString(node) ||
|
||||
// // node.nodeType ==
|
||||
// // Node.ELEMENT_NODE) },
|
||||
// // "get-input-value",
|
||||
// // "dom-node",
|
||||
// // 1);
|
||||
// if (types.isString(node)) {
|
||||
// return (document.getElementById(node).value || "");
|
||||
// } else {
|
||||
// return (node.value || "");
|
||||
// }
|
||||
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// // Images.
|
||||
// Jsworld.img = _js.img;
|
||||
|
||||
// // text: string -> node
|
||||
// Jsworld.text = _js.text;
|
||||
|
||||
// Jsworld.select = function(options, updateF, attribs) {
|
||||
// var wrappedUpdater = function(w, e, k) {
|
||||
// // console.log(e);
|
||||
// caller(updateF, [w, e.target.value], k);
|
||||
// }
|
||||
// return _js.select(attribs, options, wrappedUpdater);
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
// Jsworld.emptyPage = _js.emptyPage;
|
||||
|
||||
// Jsworld.placeOnPage = function(elt, left, top, page) {
|
||||
// deepUnwrapJsValues(elt, function(newElt) {
|
||||
// elt = types.toDomNode(newElt);});
|
||||
// return _js.placeOnPage(elt, left, top, page);
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// var convertAttribList = function(attribList) {
|
||||
// var nextElt;
|
||||
// var key, val;
|
||||
// var hash = {};
|
||||
// while (attribList !== EMPTY) {
|
||||
// nextElt = attribList.first;
|
||||
|
||||
// key = nextElt.first;
|
||||
// val = nextElt.rest.first;
|
||||
|
||||
// key = String(key);
|
||||
|
||||
// if (isString(val)) {
|
||||
// val = String(val);
|
||||
// } else if (isBoolean(val)) {
|
||||
// // do nothing: the representation is the same.
|
||||
// } else if (isSymbol(val)) {
|
||||
// if (String(val) === 'true') {
|
||||
// val = true;
|
||||
// } else if (String(val) === 'false') {
|
||||
// val = false;
|
||||
// } else {
|
||||
// val = String(val);
|
||||
// }
|
||||
// } else {
|
||||
// // raise error: neither string nor boolean
|
||||
// throw new Error(
|
||||
// plt.baselib.format.format(
|
||||
// "attribute value ~s neither a string nor a boolean",
|
||||
// [val]));
|
||||
// }
|
||||
// hash[key] = val;
|
||||
// attribList = attribList.rest;
|
||||
// }
|
||||
// return hash;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#:provided-values (big-bang
|
||||
on-tick
|
||||
on-key
|
||||
on-mouse
|
||||
key=?
|
||||
to-draw
|
||||
stop-when))
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#lang s-exp "../lang/base.rkt"
|
||||
|
||||
(provide big-bang
|
||||
on-tick
|
||||
to-draw
|
||||
on-tick
|
||||
on-mouse
|
||||
on-key
|
||||
key=?
|
||||
stop-when)
|
||||
|
@ -13,23 +14,27 @@
|
|||
|
||||
|
||||
(define (big-bang initial-world . args)
|
||||
(error 'big-bang "not done yet"))
|
||||
(error 'big-bang "must be run in JavaScript context"))
|
||||
|
||||
|
||||
(define on-tick
|
||||
(case-lambda [(handler)
|
||||
(error 'on-tick "not done yet")]
|
||||
(error 'on-tick "must be run in JavaScript context")]
|
||||
[(handler interval)
|
||||
(error 'on-tick "not done yet")]))
|
||||
(error 'on-tick "must be run in JavaScript context")]))
|
||||
|
||||
|
||||
(define (on-mouse handle)
|
||||
(error 'on-mouse "must be run in JavaScript context"))
|
||||
|
||||
(define (to-draw handler)
|
||||
(error 'to-draw "not done yet"))
|
||||
(error 'to-draw "must be run in JavaScript context"))
|
||||
|
||||
(define (on-key handler)
|
||||
(error 'on-key "not done yet"))
|
||||
(error 'on-key "must be run in JavaScript context"))
|
||||
|
||||
(define (key=? key-1 key-2)
|
||||
(error 'key=? "not done yet"))
|
||||
(error 'key=? "must be run in JavaScript context"))
|
||||
|
||||
(define (stop-when handler)
|
||||
(error 'stop-when "not done yet"))
|
||||
(error 'stop-when "must be run in JavaScript context"))
|
||||
|
|
1762
world/raw-jsworld.js
1762
world/raw-jsworld.js
File diff suppressed because it is too large
Load Diff
|
@ -1,82 +0,0 @@
|
|||
#lang s-exp "../lang/base.rkt"
|
||||
|
||||
(require "jsworld.rkt")
|
||||
|
||||
(require (for-syntax racket/base))
|
||||
|
||||
(provide define-effect)
|
||||
|
||||
(define-syntax (define-effect stx)
|
||||
(syntax-case stx ()
|
||||
|
||||
[(_ name (field ...) #:impl impl)
|
||||
(identifier? #'name)
|
||||
(syntax/loc stx
|
||||
(define-effect (name #f) (field ...) #:impl impl))]
|
||||
|
||||
[(_ (name supertype) (field ...) #:impl impl)
|
||||
(with-syntax ([field-count
|
||||
(length (syntax->list #'(field ...)))]
|
||||
[struct:name
|
||||
(datum->syntax #'name
|
||||
(string->symbol
|
||||
(format "struct:~a"
|
||||
(syntax-e #'name))))]
|
||||
[make-name
|
||||
(datum->syntax #'name
|
||||
(string->symbol
|
||||
(format "make-~a"
|
||||
(syntax-e #'name))))]
|
||||
[name?
|
||||
(datum->syntax #'name
|
||||
(string->symbol
|
||||
(format "~a?"
|
||||
(syntax-e #'name))))]
|
||||
[(field-index ...)
|
||||
(build-list (length (syntax->list
|
||||
#'(field ...)))
|
||||
(lambda (i) i))]
|
||||
[(accessor ...)
|
||||
(map (lambda (field)
|
||||
(datum->syntax
|
||||
field
|
||||
(string->symbol
|
||||
(format "~a-~a"
|
||||
(syntax-e #'name)
|
||||
(syntax-e field)))))
|
||||
(syntax->list #'(field ...)))]
|
||||
|
||||
[(mutator ...)
|
||||
(map (lambda (field)
|
||||
(datum->syntax
|
||||
field
|
||||
(string->symbol
|
||||
(format "set-~a-~a!"
|
||||
(syntax-e #'name)
|
||||
(syntax-e field)))))
|
||||
(syntax->list #'(field ...)))])
|
||||
|
||||
(syntax/loc stx
|
||||
(begin (define-values (struct:name
|
||||
make-name
|
||||
name?
|
||||
name-accessor
|
||||
name-mutator)
|
||||
(make-effect-type 'name
|
||||
supertype
|
||||
field-count
|
||||
impl))
|
||||
(begin
|
||||
(define accessor
|
||||
(make-struct-field-accessor
|
||||
name-accessor field-index 'field))
|
||||
...)
|
||||
|
||||
(begin
|
||||
(define mutator
|
||||
(make-struct-field-mutator
|
||||
name-mutator field-index 'field))
|
||||
...)
|
||||
|
||||
)))]))
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,50 +0,0 @@
|
|||
#lang s-exp "../lang/js-impl/js-impl.rkt"
|
||||
|
||||
;; Loaded so we have access to image library stuff, as well as the world kernel
|
||||
(require "../world/kernel.rkt"
|
||||
"../image/image.rkt")
|
||||
|
||||
|
||||
(require-js "private/jsworld/jsworld.js"
|
||||
"private/jsworld.js"
|
||||
"jsworld.js")
|
||||
|
||||
|
||||
(provide big-bang
|
||||
to-draw
|
||||
to-draw-page
|
||||
|
||||
key=?
|
||||
on-tick on-tick!
|
||||
on-key on-key!
|
||||
stop-when stop-when!
|
||||
|
||||
initial-effect
|
||||
|
||||
js-p
|
||||
js-div
|
||||
js-button
|
||||
js-button!
|
||||
js-input
|
||||
js-img
|
||||
js-text
|
||||
js-select
|
||||
|
||||
|
||||
empty-page
|
||||
place-on-page
|
||||
|
||||
make-world-config
|
||||
make-effect-type
|
||||
effect-type?
|
||||
effect?
|
||||
|
||||
#;make-render-effect-type
|
||||
#;render-effect-type?
|
||||
|
||||
world-with-effects
|
||||
|
||||
#;make-render-effect
|
||||
#;render-effect?
|
||||
#;render-effect-dom-node
|
||||
#;render-effect-effects)
|
|
@ -1,777 +0,0 @@
|
|||
// Depends on world.js, world-config.js
|
||||
|
||||
(function() {
|
||||
|
||||
var world = {};
|
||||
world.Kernel = STATE.invokedModules["mzscheme-vm/world/kernel"].lookup("kernel");
|
||||
|
||||
|
||||
|
||||
var Jsworld = jsworld.MobyJsworld = {};
|
||||
|
||||
// The real low-level jsworld module:
|
||||
var _js = jsworld.Jsworld;
|
||||
|
||||
|
||||
var caller;
|
||||
var setCaller = function(c) {
|
||||
caller = function(op, args, k) {
|
||||
c(op, args, k, handleError);
|
||||
};
|
||||
};
|
||||
var unsetCaller = function() {
|
||||
caller = function(op, args, k) {
|
||||
throw new Error('caller not defined!');
|
||||
};
|
||||
};
|
||||
unsetCaller();
|
||||
|
||||
// The restarted and things to set it
|
||||
// Note that we never want to restart the same computation
|
||||
// more than once, so we throw an error if someone tries to do that
|
||||
var restarter;
|
||||
var setRestarter = function(r) {
|
||||
var hasRestarted = false;
|
||||
restarter = function(v) {
|
||||
if (hasRestarted) {
|
||||
throw new Error('Cannot restart twice!');
|
||||
}
|
||||
hasRestarted = true;
|
||||
r(v);
|
||||
};
|
||||
};
|
||||
var unsetRestarter = function() {
|
||||
restarter = function() {
|
||||
throw new Error('restarter not defined!');
|
||||
};
|
||||
};
|
||||
unsetRestarter();
|
||||
|
||||
|
||||
var errorReporter = function(e) {
|
||||
// default: do nothing.
|
||||
};
|
||||
|
||||
|
||||
|
||||
var terminator;
|
||||
var setTerminator = function(t) {
|
||||
terminator = t;
|
||||
};
|
||||
var unsetTerminator = function() {
|
||||
terminator = function() {
|
||||
throw new Error('terminator not defined!');
|
||||
};
|
||||
};
|
||||
unsetTerminator();
|
||||
|
||||
|
||||
|
||||
// mutateStringsInDeepArray: array -> array
|
||||
// walks and in-place mutates Scheme strings to primitive strings.
|
||||
var mutateStringsInDeepArray = function(thing) {
|
||||
var i, length;
|
||||
if (typeof(thing) === 'object' &&
|
||||
thing.constructor === Array) {
|
||||
length = thing.length;
|
||||
for (i = 0; i < length; i++) {
|
||||
thing[i] = mutateStringsInDeepArray(thing[i]);
|
||||
}
|
||||
} else if (types.isString(thing)) {
|
||||
return thing.toString();
|
||||
}
|
||||
return thing;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
var userConfigs = [];
|
||||
|
||||
var startUserConfigs = function(k) {
|
||||
helpers.forEachK(userConfigs,
|
||||
function(aConfig, k2) {
|
||||
caller(aConfig.startup, aConfig.startupArgs,
|
||||
function(res) {
|
||||
aConfig.isRunning = true;
|
||||
aConfig.shutdownArg = res;
|
||||
k2()
|
||||
});
|
||||
},
|
||||
handleError,
|
||||
k);
|
||||
}
|
||||
|
||||
var shutdownUserConfigs = function(k) {
|
||||
// console.log('shutting down user configs');
|
||||
var theConfigs = userConfigs;
|
||||
userConfigs = []
|
||||
helpers.forEachK(theConfigs,
|
||||
function(aConfig, k2) {
|
||||
// console.log(' shutting down a config');
|
||||
if (aConfig.isRunning) {
|
||||
aConfig.isRunning = false;
|
||||
caller(aConfig.shutdown, [aConfig.shutdownArg], k2);
|
||||
} else {
|
||||
k2();
|
||||
}
|
||||
},
|
||||
handleError,
|
||||
k);
|
||||
}
|
||||
|
||||
var expandHandler = function(handler) {
|
||||
return types.jsValue('function', function() {
|
||||
var wrappedStimulusArgs = [];
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
wrappedStimulusArgs.push( helpers.wrapJsValue(arguments[i]) );
|
||||
}
|
||||
|
||||
Jsworld.updateWorld(
|
||||
function(w, k) {
|
||||
var args = [w].concat(wrappedStimulusArgs);
|
||||
caller(handler, args, k);
|
||||
},
|
||||
function() {});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// var unwrapWorldEffects = function(w) {
|
||||
// if ( _js.has_effects(w) ) {
|
||||
// var unwrappedEffects =
|
||||
// helpers.map(function(e) {
|
||||
// if ( types.isEffect(e) ) {
|
||||
// return types.makeJsworldEffect(function(k) {
|
||||
// caller(types.effectThunk(e), [], k);
|
||||
// });
|
||||
// }
|
||||
// else {
|
||||
// return e;
|
||||
// }
|
||||
// },
|
||||
// w.getEffects());
|
||||
// var returnVal = _js.with_multiple_effects(w.getWorld(), unwrappedEffects);
|
||||
// return returnVal;
|
||||
// }
|
||||
// else {
|
||||
// return w;
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
var deepUnwrapJsValues = function(x, k) {
|
||||
if ( types.isJsValue(x) ) {
|
||||
k(x.unbox());
|
||||
}
|
||||
else if ( types.isRenderEffect(x) ) {
|
||||
x.callImplementation(caller, function(y) { deepUnwrapJsValues(y, k); });
|
||||
}
|
||||
// var effects = helpers.schemeListToArray( types.renderEffectEffects(x) ).reverse();
|
||||
// types.setRenderEffectEffects(x, types.EMPTY);
|
||||
//
|
||||
// helpers.forEachK(effects,
|
||||
// function(ef, k2) { caller(ef, [], k2); },
|
||||
// handleError,
|
||||
// function() { deepUnwrapJsValues(types.renderEffectDomNode(x), k); });
|
||||
// }
|
||||
else if ( types.isPair(x) ) {
|
||||
deepUnwrapJsValues(x.first(), function(first) {
|
||||
deepUnwrapJsValues(x.rest(), function(rest) {
|
||||
k( types.cons(first, rest) );
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
k(x);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// isHandler: X -> boolean
|
||||
// Right now, a handler is a function that consumes and produces
|
||||
// configs. We should tighten up the type check eventually.
|
||||
var isHandler = function(x) {
|
||||
return typeof(x) == 'function';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//From this point forward, we define wrappers to integrate jsworld
|
||||
//with Moby.
|
||||
|
||||
|
||||
// getBigBangWindow: -> window
|
||||
var getBigBangWindow = function() {
|
||||
if (window.document.getElementById("jsworld-div") !== undefined) {
|
||||
return window;
|
||||
} else {
|
||||
var newDiv = window.document.createElement("div");
|
||||
newDiv.id = 'jsworld-div';
|
||||
window.document.appendChild(newDiv);
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// types are
|
||||
// sexp: (cons node (listof sexp))
|
||||
// css-style: (node (listof (list string string)))
|
||||
|
||||
// Exports:
|
||||
|
||||
|
||||
|
||||
|
||||
var isPair = types.isPair;
|
||||
var isEmpty = function(x) { return x === types.EMPTY; };
|
||||
var isList = function(x) { return (isPair(x) || isEmpty(x)); };
|
||||
|
||||
|
||||
|
||||
// The default printWorldHook will write the written content of the node.
|
||||
// We probably want to invoke the pretty printer here instead!
|
||||
Jsworld.printWorldHook = function(world, node) {
|
||||
var newNode;
|
||||
if(node.lastChild == null) {
|
||||
newNode = types.toDomNode(world);
|
||||
node.appendChild(newNode);
|
||||
helpers.maybeCallAfterAttach(newNode);
|
||||
} else {
|
||||
newNode = types.toDomNode(world);
|
||||
node.replaceChild(newNode, node.lastChild);
|
||||
helpers.maybeCallAfterAttach(newNode);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Figure out the target of an event.
|
||||
// http://www.quirksmode.org/js/events_properties.html#target
|
||||
var findEventTarget = function(e) {
|
||||
var targ;
|
||||
if (e.target)
|
||||
targ = e.target;
|
||||
else if (e.srcElement)
|
||||
targ = e.srcElement;
|
||||
if (targ.nodeType == 3) // defeat Safari bug
|
||||
targ = targ.parentNode;
|
||||
return targ;
|
||||
}
|
||||
|
||||
// isNode: any -> boolean
|
||||
// Returns true if the thing has a nodeType.
|
||||
var isNode = function(thing) {
|
||||
return thing && typeof(thing.nodeType) != 'undefined';
|
||||
}
|
||||
|
||||
|
||||
|
||||
// checkWellFormedDomTree: X X (or number undefined) -> void
|
||||
// Check to see if the tree is well formed. If it isn't,
|
||||
// we need to raise a meaningful error so the user can repair
|
||||
// the structure.
|
||||
//
|
||||
// Invariants:
|
||||
// The dom tree must be a pair.
|
||||
// The first element must be a node.
|
||||
// Each of the rest of the elements must be dom trees.
|
||||
// If the first element is a text node, it must NOT have children.
|
||||
var checkWellFormedDomTree = function(x, top, index) {
|
||||
var fail = function(formatStr, formatArgs) {
|
||||
throw types.schemeError(
|
||||
types.incompleteExn(types.exnFailContract,
|
||||
helpers.format(formatStr, formatArgs),
|
||||
[]));
|
||||
}
|
||||
|
||||
if (_js.isPage(x)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (types.isPair(x)) {
|
||||
var firstElt = x.first();
|
||||
var restElts = x.rest();
|
||||
|
||||
if (! isNode(firstElt)) {
|
||||
fail("on-draw: expected a dom-element, but received ~s instead, the first element within ~s", [firstElt, top]);
|
||||
}
|
||||
|
||||
if (firstElt.nodeType == Node.TEXT_NODE && !restElts.isEmpty() ) {
|
||||
fail("on-draw: the text node ~s must not have children. It has ~s", [firstElt, restElts]);
|
||||
}
|
||||
|
||||
var i = 2;
|
||||
while( !restElts.isEmpty() ) {
|
||||
checkWellFormedDomTree(restElts.first(), x, i);
|
||||
restElts = restElts.rest();
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
var formatStr = "on-draw: expected a dom-s-expression, but received ~s instead";
|
||||
var formatArgs = [x];
|
||||
if (index != undefined) {
|
||||
formatStr += ", the ~a element within ~s";
|
||||
formatArgs.push( helpers.ordinalize(index) );
|
||||
formatArgs.push(top);
|
||||
}
|
||||
formatStr += ".";
|
||||
|
||||
fail(formatStr, formatArgs);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Compatibility for attaching events to nodes.
|
||||
var attachEvent = function(node, eventName, fn) {
|
||||
if (node.addEventListener) {
|
||||
// Mozilla
|
||||
node.addEventListener(eventName, fn, false);
|
||||
} else {
|
||||
// IE
|
||||
node.attachEvent('on' + eventName, fn, false);
|
||||
}
|
||||
return function() {
|
||||
detachEvent(node, eventName, fn);
|
||||
}
|
||||
};
|
||||
|
||||
var detachEvent = function(node, eventName, fn) {
|
||||
if (node.addEventListener) {
|
||||
// Mozilla
|
||||
node.removeEventListener(eventName, fn, false);
|
||||
} else {
|
||||
// IE
|
||||
node.detachEvent('on' + eventName, fn, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var preventDefault = function(event) {
|
||||
if (event.preventDefault) {
|
||||
event.preventDefault();
|
||||
} else {
|
||||
event.returnValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
var stopPropagation = function(event) {
|
||||
if (event.stopPropagation) {
|
||||
event.stopPropagation();
|
||||
} else {
|
||||
event.cancelBubble = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// bigBang: world dom (listof (list string string)) (arrayof handler) -> world
|
||||
Jsworld.bigBang = function(initWorld, toplevelNode, handlers, theCaller, theRestarter, onFail) {
|
||||
// shutdownListeners: arrayof (-> void)
|
||||
// We maintain a list of thunks that need to be called as soon as we come out of
|
||||
// bigBang, to do cleanup.
|
||||
var shutdownListeners = [];
|
||||
|
||||
var onTermination = function(w) {
|
||||
for (var i = 0; i < shutdownListeners.length; i++) {
|
||||
try {
|
||||
shutdownListeners[i]();
|
||||
} catch (e) { }
|
||||
}
|
||||
shutdownUserConfigs(function() {
|
||||
unsetCaller();
|
||||
theRestarter(w);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//console.log('in high level big-bang');
|
||||
errorReporter = onFail;
|
||||
|
||||
setCaller(theCaller);
|
||||
setRestarter(theRestarter);
|
||||
setTerminator(function(w) {
|
||||
detachEvent(toplevelNode, 'click', absorber);
|
||||
shutdownUserConfigs(function() {
|
||||
unsetCaller();
|
||||
unsetTerminator();
|
||||
restarter(w);
|
||||
});
|
||||
});
|
||||
|
||||
var attribs = types.EMPTY;
|
||||
|
||||
// Ensure that the toplevelNode can be focused by mouse or keyboard
|
||||
toplevelNode.tabIndex = 0;
|
||||
|
||||
// Absorb all click events so they don't bubble up.
|
||||
var absorber = function(e) {
|
||||
preventDefault(e);
|
||||
stopPropagation(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
attachEvent(toplevelNode, 'click', absorber);
|
||||
shutdownListeners.push(function() { detachEvent(toplevelNode, 'click', absorber)});
|
||||
|
||||
|
||||
|
||||
var config = new world.Kernel.config.WorldConfig();
|
||||
for(var i = 0; i < handlers.length; i++) {
|
||||
if (isList(handlers[i])) {
|
||||
attribs = handlers[i];
|
||||
}
|
||||
else if (isHandler(handlers[i])) {
|
||||
config = handlers[i](config);
|
||||
}
|
||||
else if ( types.isWorldConfig(handlers[i]) ) {
|
||||
handlers[i].startupArgs = helpers.map(expandHandler, handlers[i].startupArgs);
|
||||
userConfigs.push(handlers[i]);
|
||||
}
|
||||
}
|
||||
config = config.updateAll({'changeWorld': Jsworld.updateWorld,
|
||||
'shutdownWorld': Jsworld.shutdownWorld});
|
||||
var stimuli = new world.Kernel.stimuli.StimuliHandler(config, caller, restarter);
|
||||
|
||||
var wrappedHandlers = [];
|
||||
var wrappedRedraw;
|
||||
var wrappedRedrawCss;
|
||||
|
||||
|
||||
if (config.lookup('onDraw')) {
|
||||
wrappedRedraw = function(w, k) {
|
||||
try {
|
||||
caller(config.lookup('onDraw'), [w],
|
||||
function(newDomTree) {
|
||||
deepUnwrapJsValues(newDomTree, function(unwrappedTree) {
|
||||
checkWellFormedDomTree(unwrappedTree, unwrappedTree, undefined);
|
||||
var result = [toplevelNode,
|
||||
helpers.deepListToArray(unwrappedTree)];
|
||||
k(result);
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
handleError(e);
|
||||
// throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (config.lookup('onDrawCss')) {
|
||||
wrappedRedrawCss = function(w, k) {
|
||||
try {
|
||||
caller(config.lookup('onDrawCss'), [w],
|
||||
function(res) {
|
||||
var result = helpers.deepListToArray(res);
|
||||
result = mutateStringsInDeepArray(result);
|
||||
// plt.Kernel.setLastLoc(undefined);
|
||||
k(result);
|
||||
});
|
||||
} catch (e) {
|
||||
handleError(e);
|
||||
// throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
wrappedRedrawCss = function(w, k) { k([]); };
|
||||
}
|
||||
wrappedHandlers.push(_js.on_draw(wrappedRedraw, wrappedRedrawCss));
|
||||
} else if (config.lookup('onRedraw')) {
|
||||
var reusableCanvas = undefined;
|
||||
var reusableCanvasNode = undefined;
|
||||
|
||||
wrappedRedraw = function(w, k) {
|
||||
try {
|
||||
//console.log('in onRedraw handler');
|
||||
caller(config.lookup('onRedraw'), [w],
|
||||
function(aScene) {
|
||||
// Performance hack: if we're using onRedraw, we know
|
||||
// we've got a scene, so we optimize away the repeated
|
||||
// construction of a canvas object.
|
||||
if ( world.Kernel.isImage(aScene) ) {
|
||||
var width = aScene.getWidth();
|
||||
var height = aScene.getHeight();
|
||||
|
||||
if (! reusableCanvas) {
|
||||
reusableCanvas = world.Kernel.makeCanvas(width, height);
|
||||
// Note: the canvas object may itself manage objects,
|
||||
// as in the case of an excanvas. In that case, we must make
|
||||
// sure jsworld doesn't try to disrupt its contents!
|
||||
reusableCanvas.jsworldOpaque = true;
|
||||
reusableCanvasNode = _js.node_to_tree(reusableCanvas);
|
||||
}
|
||||
|
||||
reusableCanvas.width = width;
|
||||
reusableCanvas.height = height;
|
||||
var ctx = reusableCanvas.getContext("2d");
|
||||
aScene.render(ctx, 0, 0);
|
||||
|
||||
k([toplevelNode, reusableCanvasNode]);
|
||||
} else {
|
||||
k([toplevelNode, _js.node_to_tree(types.toDomNode(aScene))]);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
handleError(e);
|
||||
// throw e;
|
||||
}
|
||||
}
|
||||
|
||||
wrappedRedrawCss = function(w, k) {
|
||||
//console.log('in RedrawCss handler');
|
||||
k([[reusableCanvas,
|
||||
["width", reusableCanvas.width + "px"],
|
||||
["height", reusableCanvas.height + "px"]]]);
|
||||
}
|
||||
wrappedHandlers.push(_js.on_draw(wrappedRedraw, wrappedRedrawCss));
|
||||
} else {
|
||||
wrappedHandlers.push(_js.on_world_change
|
||||
(function(w, k) {
|
||||
Jsworld.printWorldHook(w, toplevelNode);
|
||||
k();
|
||||
}));
|
||||
}
|
||||
|
||||
if (config.lookup('tickDelay')) {
|
||||
var wrappedTick = function(w, k) {
|
||||
caller(config.lookup('onTick'),
|
||||
[w],
|
||||
k);
|
||||
}
|
||||
var wrappedDelay = jsnums.toFixnum( config.lookup('tickDelay') );
|
||||
wrappedHandlers.push(_js.on_tick(wrappedDelay, wrappedTick));
|
||||
}
|
||||
|
||||
if (config.lookup('stopWhen')) {
|
||||
wrappedHandlers.push(_js.stop_when(
|
||||
function(w, k) {
|
||||
caller(config.lookup('stopWhen'), [w],
|
||||
function(res) { k(res); });
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
if (config.lookup('onKey')) {
|
||||
var wrappedKey = function(w, e, k) {
|
||||
caller(config.lookup('onKey'), [w, helpers.getKeyCodeName(e)], k);
|
||||
}
|
||||
wrappedHandlers.push(_js.on_key(wrappedKey));
|
||||
toplevelNode.focus();
|
||||
}
|
||||
|
||||
|
||||
if (config.lookup('initialEffect')) {
|
||||
var updaters =
|
||||
world.Kernel.applyEffect(config.lookup('initialEffect'));
|
||||
for (var i = 0 ; i < updaters.length; i++) {
|
||||
if (config.lookup('stopWhen') &&
|
||||
config.lookup('stopWhen')([initWorld])) {
|
||||
break;
|
||||
} else {
|
||||
initWorld = updaters[i](initWorld);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_js.big_bang(toplevelNode,
|
||||
initWorld,
|
||||
wrappedHandlers,
|
||||
helpers.assocListToHash(attribs),
|
||||
terminator);
|
||||
|
||||
startUserConfigs(function() {});
|
||||
|
||||
return {
|
||||
breaker: function() {
|
||||
handleError(types.schemeError(
|
||||
types.incompleteExn(types.exnBreak, 'user break', [])));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
var handleError = function(e) {
|
||||
// helpers.reportError(e);
|
||||
// When something bad happens, shut down
|
||||
// the world computation.
|
||||
// helpers.reportError("Shutting down jsworld computations");
|
||||
// world.Kernel.stimuli.onShutdown();
|
||||
world.Kernel.stimuli.massShutdown();
|
||||
shutdownUserConfigs(function() {
|
||||
errorReporter(e);
|
||||
// console.log('Got an error, the error was:');
|
||||
// console.log(e);
|
||||
if (typeof(console) !== 'undefined' && console.log) {
|
||||
if (e.stack) {
|
||||
console.log(e.stack);
|
||||
}
|
||||
else {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
if ( types.isSchemeError(e) ) {
|
||||
terminator(e);
|
||||
}
|
||||
else if ( types.isInternalError(e) ) {
|
||||
terminator(e);
|
||||
}
|
||||
else if (typeof(e) == 'string') {
|
||||
terminator( types.schemeError(types.incompleteExn(types.exnFail, e, [])) );
|
||||
}
|
||||
else if (e instanceof Error) {
|
||||
terminator( types.schemeError(types.incompleteExn(types.exnFail, e.message, [])) );
|
||||
}
|
||||
else {
|
||||
terminator( types.schemeError(e) );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// updateWorld: CPS( CPS(world -> world) -> void )
|
||||
Jsworld.updateWorld = function(updater, k) {
|
||||
var wrappedUpdater = function(w, k2) {
|
||||
try {
|
||||
updater(w, k2);
|
||||
} catch (e) {
|
||||
if (typeof(console) !== 'undefined' && console.log && e.stack) {
|
||||
console.log(e.stack);
|
||||
}
|
||||
handleError(e);
|
||||
// k2(w);
|
||||
}
|
||||
}
|
||||
|
||||
_js.change_world(wrappedUpdater, k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// shutdownWorld: -> void
|
||||
// Shut down all world computations.
|
||||
Jsworld.shutdownWorld = function() {
|
||||
_js.shutdown();
|
||||
};
|
||||
|
||||
|
||||
// var getAttribs = function(args) {
|
||||
// if (args.length == 0) {
|
||||
// return []
|
||||
// }
|
||||
// if (args.length == 1) {
|
||||
// return helpers.assocListToHash(args[0]);
|
||||
// } else {
|
||||
// throw new Error("getAttribs recevied unexpected value for args: "
|
||||
// + args);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
Jsworld.p = _js.p;
|
||||
|
||||
Jsworld.div = _js.div;
|
||||
|
||||
Jsworld.buttonBang = function(updateWorldF, effectF, attribs) {
|
||||
var wrappedF = function(w, evt, k) {
|
||||
try {
|
||||
// FIXME: Get effects back online!
|
||||
// caller(effectF, [world],
|
||||
// function(effect) {
|
||||
caller(updateWorldF, [w],
|
||||
function(newWorld) {
|
||||
// world.Kernel.applyEffect(effect);
|
||||
k(newWorld);
|
||||
});
|
||||
// });
|
||||
} catch (e) {
|
||||
if (typeof(console) !== 'undefined' && console.log && e.stack) {
|
||||
console.log(e.stack);
|
||||
}
|
||||
handleError(e);
|
||||
// k(w);
|
||||
}
|
||||
}
|
||||
return _js.button(wrappedF, attribs);
|
||||
};
|
||||
|
||||
|
||||
Jsworld.input = function(type, updateF, attribs) {
|
||||
var wrappedUpdater = function(w, evt, k) {
|
||||
caller(updateF, [w, evt], k);
|
||||
}
|
||||
return _js.input(type, wrappedUpdater, attribs);
|
||||
};
|
||||
|
||||
|
||||
Jsworld.get_dash_input_dash_value = function(node) {
|
||||
// plt.Kernel.check(node,
|
||||
// function(x) { return (plt.Kernel.isString(node) ||
|
||||
// node.nodeType ==
|
||||
// Node.ELEMENT_NODE) },
|
||||
// "get-input-value",
|
||||
// "dom-node",
|
||||
// 1);
|
||||
if (types.isString(node)) {
|
||||
return (document.getElementById(node).value || "");
|
||||
} else {
|
||||
return (node.value || "");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Images.
|
||||
Jsworld.img = _js.img;
|
||||
|
||||
// text: string -> node
|
||||
Jsworld.text = _js.text;
|
||||
|
||||
Jsworld.select = function(options, updateF, attribs) {
|
||||
var wrappedUpdater = function(w, e, k) {
|
||||
// console.log(e);
|
||||
caller(updateF, [w, e.target.value], k);
|
||||
}
|
||||
return _js.select(attribs, options, wrappedUpdater);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
Jsworld.emptyPage = _js.emptyPage;
|
||||
|
||||
Jsworld.placeOnPage = function(elt, left, top, page) {
|
||||
deepUnwrapJsValues(elt, function(newElt) {
|
||||
elt = types.toDomNode(newElt);});
|
||||
return _js.placeOnPage(elt, left, top, page);
|
||||
};
|
||||
|
||||
|
||||
// fixme: add support for textarea, h1, canvas
|
||||
|
||||
|
||||
// // raw_node: scheme-value assoc -> node
|
||||
// Jsworld.rawNode = function(x, args) {
|
||||
// var attribs = getAttribs(args);
|
||||
// var node = _js.raw_node(types.toDomNode(x), attribs);
|
||||
// node.toWrittenString = function(cache) { return "(js-raw-node ...)"; }
|
||||
// node.toDisplayedString = node.toWrittenString;
|
||||
// node.toDomNode = function(cache) { return node; }
|
||||
// return node;
|
||||
// };
|
||||
|
||||
|
||||
|
||||
})();
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +0,0 @@
|
|||
#lang s-exp "../lang/js-impl/js-impl.rkt"
|
||||
|
||||
(require-js "kernel.js")
|
Loading…
Reference in New Issue
Block a user