#lang s-exp "lang.ss"
(require "env.ss")
(require "helpers.ss")
(require "../collects/moby/runtime/permission-struct.ss")
(require "../collects/moby/runtime/binding.ss")
(require "../collects/moby/runtime/runtime-modules.ss")
(define kernel-misc-module
(make-module-binding 'moby/runtime/kernel/misc
"moby/runtime/kernel/misc"
(list (make-binding:function
'throw-cond-exhausted-error
"moby/runtime/kernel/misc"
1
false
"plt.kernel.misc.throwCondExhaustedError"
(list)
false)
(make-binding:function
'verify-boolean-branch-value
"moby/runtime/kernel/misc"
2
false
"plt.kernel.misc.verifyBooleanBranchValue"
(list)
false)
(make-binding:function
'check-operator-is-function
"moby/runtime/kernel/misc"
3
false
"plt.kernel.misc.checkOperatorIsFunction"
(list)
false))))
(define foreign-module
(make-module-binding 'moby/foreign
"moby/foreign"
(list (make-binding:function
'get-js-object
"moby/foreign"
2
false
"plt.foreign.get_dash_js_dash_object"
(list PERMISSION:FOREIGN-FUNCTION-INTERFACE)
false))))
(define world-effects-module
(local [ (define (bf name module-path arity vararity? java-string)
(make-binding:function name module-path arity vararity? java-string empty false))
(define module-path
"moby/world-effects")]
(make-module-binding 'world-effects
module-path
(list (bf 'make-effect:none module-path 0
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:none']")
(make-binding:function
'make-effect:beep module-path 0
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:beep']"
(list PERMISSION:VIBRATE)
false)
(bf 'make-effect:play-dtmf-tone module-path 2
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:play-dtmf-tone']")
(make-binding:function
'make-effect:send-sms module-path 2 false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:send-sms']"
(list PERMISSION:SEND-SMS)
false)
(make-binding:function
'make-effect:play-sound
module-path
1
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:play-sound']"
(list PERMISSION:INTERNET)
false)
(bf 'make-effect:stop-sound module-path 1
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:stop-sound']")
(bf 'make-effect:pause-sound module-path 1
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:pause-sound']")
(bf 'make-effect:set-sound-volume module-path 1
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:set-sound-volume']")
(bf 'make-effect:set-beep-volume module-path 1
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:set-beep-volume']")
(bf 'make-effect:raise-sound-volume module-path 0
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:raise-sound-volume']")
(bf 'make-effect:lower-sound-volume module-path 0
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:lower-sound-volume']")
(make-binding:function 'make-effect:set-wake-lock module-path 1
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:set-wake-lock']"
(list PERMISSION:WAKE-LOCK)
false)
(make-binding:function
'make-effect:release-wake-lock
module-path
0
false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:release-wake-lock']"
(list PERMISSION:WAKE-LOCK)
false)
(bf 'make-effect:pick-playlist module-path 1 false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:pick-playlist']")
(bf 'make-effect:pick-random module-path 2 false
"plt.Kernel.invokeModule('moby/runtime/effect-struct').EXPORTS['make-effect:pick-random']")
))))
(define world-handlers-module
(local [ (define (bf name module-path arity vararity? java-string)
(make-binding:function name module-path arity vararity? java-string empty false))
(define module-path
"moby/world-handlers")]
(make-module-binding 'world-config
module-path
(list (bf 'on-tick module-path 2 false "plt.world.config.Kernel.onTick")
(bf 'on-tick! module-path 3 false "plt.world.config.Kernel.onTick_star_")
(bf 'on-mouse module-path 1 false "plt.world.config.Kernel.onMouse")
(bf 'on-mouse! module-path 2 false "plt.world.config.Kernel.onMouse_star_")
(bf 'initial-effect module-path 1 false "plt.world.config.Kernel.initialEffect")
(bf 'on-key module-path 1 false "plt.world.config.Kernel.onKey")
(bf 'on-key! module-path 2 false "plt.world.config.Kernel.onKey_star_")
(bf 'on-announce module-path 1 false "plt.world.config.Kernel.onAnnounce")
(bf 'on-announce! module-path 2 false "plt.world.config.Kernel.onAnnounce_star_")
(make-binding:function
'on-location-change module-path 1 false
"plt.world.config.Kernel.onLocationChange"
(list PERMISSION:LOCATION)
false)
(make-binding:function
'on-location-change! module-path 2 false
"plt.world.config.Kernel.onLocationChange_star_"
(list PERMISSION:LOCATION)
false)
(make-binding:function
'on-tilt module-path 1 false
"plt.world.config.Kernel.onTilt"
(list PERMISSION:TILT)
false)
(make-binding:function
'on-tilt! module-path 2 false
"plt.world.config.Kernel.onTilt_star_"
(list PERMISSION:TILT)
false)
(make-binding:function
'on-acceleration module-path 1 false
"plt.world.config.Kernel.onAcceleration"
(list PERMISSION:TILT)
false)
(make-binding:function
'on-acceleration! module-path 2 false
"plt.world.config.Kernel.onAcceleration_star_"
(list PERMISSION:TILT)
false)
(make-binding:function
'on-sms-receive module-path 1 false
"plt.world.config.Kernel.onSmsReceive"
(list PERMISSION:RECEIVE-SMS)
false)
(make-binding:function
'on-sms-receive* module-path 1 false
"plt.world.config.Kernel.onSmsReceive_star"
(list PERMISSION:RECEIVE-SMS)
false)
(make-binding:function
'on-shake module-path 1 false
"plt.world.config.Kernel.onShake"
(list PERMISSION:SHAKE)
false)
(make-binding:function
'on-shake! module-path 2 false
"plt.world.config.Kernel.onShake_star_"
(list PERMISSION:SHAKE)
false)
(bf 'on-redraw module-path 1 false "plt.world.config.Kernel.onRedraw")
(bf 'on-draw module-path 2 false "plt.world.config.Kernel.onDraw")
(bf 'stop-when module-path 1 false "plt.world.config.Kernel.stopWhen")))))
(define (make-world-module module-path)
(local [ (define (bf name module-path arity vararity? java-string)
(make-binding:function name module-path arity vararity? java-string empty false))]
(make-module-binding 'world
module-path
(append (module-binding-bindings world-handlers-module)
(module-binding-bindings world-effects-module)
(list (bf 'big-bang module-path 3 true "plt.world.Kernel.bigBang")
(bf 'image? module-path 1 false "plt.world.Kernel.isImage")
(bf 'image=? module-path 2 false "plt.world.Kernel.image_equal__question_")
(bf 'make-color module-path 3 false "plt.world.Kernel.make_dash_color")
(bf 'empty-scene module-path 2 false
"plt.world.Kernel.emptyScene")
(bf 'place-image module-path 4 false
"plt.world.Kernel.placeImage")
(bf 'put-pinhole module-path 3 false
"plt.world.Kernel.put_dash_pinhole")
(bf 'circle module-path 3 false
"plt.world.Kernel.circle")
(bf 'star module-path 5 false
"plt.world.Kernel.star")
(bf 'nw:rectangle module-path 4 false
"plt.world.Kernel.nwRectangle")
(bf 'rectangle module-path 4 false
"plt.world.Kernel.rectangle")
(bf 'triangle module-path 3 false
"plt.world.Kernel.triangle")
(bf 'ellipse module-path 4 false
"plt.world.Kernel.ellipse")
(bf 'line module-path 3 false
"plt.world.Kernel.line")
(bf 'overlay module-path 2 true
"plt.world.Kernel.overlay")
(bf 'overlay/xy module-path 4 false
"plt.world.Kernel.overlay_slash_xy")
(bf 'key=? module-path 2 false
"plt.world.Kernel.isKeyEqual")
(bf 'text module-path 3 false
"plt.world.Kernel.text")
(bf 'open-image-url module-path 1 false
"plt.world.Kernel.openImageUrl")
(bf 'image-width module-path 1 false
"plt.world.Kernel.imageWidth")
(bf 'image-height module-path 1 false
"plt.world.Kernel.imageHeight")
(bf 'image-rotate module-path 2 false
"plt.world.Kernel.imageRotate")
)))))
(define world-module
(local [(define module-path
"moby/world")]
(make-world-module module-path)))
(define world-stub-module
(local [(define module-path
"moby/world")]
(make-world-module module-path)))
(define bootstrap-teachpack
(local [ (define (bf name module-path arity vararity? java-string)
(make-binding:function name module-path arity vararity? java-string empty false))
(define module-path
"moby/bootstrap-teachpack")
(define js-module-path
"plt._MODULES['bootstrap-teachpack.js']")
]
(make-module-binding 'moby/bootstrap-teachpack
module-path
(append
(list
(bf 'START module-path 14 false (string-append js-module-path ".EXPORTS['START']"))
(make-binding:constant 'test-frame
(string-append js-module-path ".EXPORTS['test-frame']")
empty)
(bf 'sq module-path 1 false (string-append js-module-path ".EXPORTS['sq']"))
(bf 'sine module-path 1 false (string-append js-module-path ".EXPORTS['sine']"))
(bf 'cosine module-path 1 false (string-append js-module-path ".EXPORTS['cosine']"))
(bf 'tangent module-path 1 false (string-append js-module-path ".EXPORTS['tangent']")))
(module-binding-bindings world-stub-module)))))
(define cage-teachpack
(local [ (define (bf name module-path arity vararity? java-string)
(make-binding:function name module-path arity vararity? java-string empty false))
(define module-path
"moby/cage-teachpack")
(define js-module-path
"plt._MODULES['cage-teachpack.js']")
]
(make-module-binding 'moby/cage-teachpack
module-path
(append
(list
(bf 'start module-path 1 false (string-append js-module-path ".EXPORTS['start']")))))))
(define function-teachpack
(local [ (define (bf name module-path arity vararity? java-string)
(make-binding:function name module-path arity vararity? java-string empty false))
(define module-path
"moby/function-teachpack")
(define js-module-path
"plt._MODULES['function-teachpack.js']")
]
(make-module-binding 'moby/function-teachpack
module-path
(append
(list
(bf 'start module-path 1 false (string-append js-module-path ".EXPORTS['start']")))))))
(define location-module
(local [(define module-path
"moby/geolocation")
(define (bf name module-path arity vararity? java-string)
(make-binding:function name module-path arity vararity? java-string
(list PERMISSION:LOCATION)
false))]
(make-module-binding 'location
module-path
(list (bf 'get-latitude module-path 0 false
"plt.lib.Location.getLatitude")
(bf 'get-longitude module-path 0 false
"plt.lib.Location.getLongitude")
(bf 'get-altitude module-path 0 false
"plt.lib.Location.getAltitude")
(bf 'get-bearing module-path 0 false
"plt.lib.Location.getBearing")
(bf 'get-speed module-path 0 false
"plt.lib.Location.getSpeed")
(bf 'location-distance module-path 4 false
"plt.lib.Location.getDistanceBetween")))))
(define tilt-module
(local [(define module-path
"moby/tilt")
(define (bf name arity vararity? java-string)
(make-binding:function name module-path arity vararity? java-string
(list PERMISSION:TILT)
true))]
(make-module-binding 'tilt
module-path
(list (bf 'get-x-acceleration 0 false
"plt.lib.Tilt.getXAcceleration")
(bf 'get-y-acceleration 0 false
"plt.lib.Tilt.getYAcceleration")
(bf 'get-z-acceleration 0 false
"plt.lib.Location.getZAcceleration")
(bf 'get-azimuth 0 false
"plt.lib.Tilt.getAzimuth")
(bf 'get-pitch 0 false
"plt.lib.Tilt.getPitch")
(bf 'get-roll 0 false
"plt.lib.Tilt.getRoll")))))
(define telephony-module
(local [(define module-path
"moby/telephony")]
(make-module-binding 'telephony
module-path
(list (make-binding:function 'get-signal-strengths
module-path
0
false
"plt.lib.Telephony.getSignalStrengths"
(list PERMISSION:TELEPHONY)
false)))))
(define net-module
(local [(define module-path
"moby/net")]
(make-module-binding 'net
module-path
(list (make-binding:function 'get-url
module-path
1
false
"plt.lib.Net.getUrl"
(list PERMISSION:INTERNET)
false)))))
(define parser-module
(local [(define module-path
"moby/parser")]
(make-module-binding 'parser
module-path
(list (make-binding:function 'xml->s-exp
module-path
1
false
"plt.lib.Parser.parseXml"
empty
false)
(make-binding:function 'split-whitespace
module-path
1
false
"plt.lib.Parser.splitWhitespace"
empty
false)))))
(define jsworld-module
(local [(define module-path
"moby/jsworld")
(define (bf name arity java-string)
(make-binding:function name module-path arity true java-string empty false))]
(make-module-binding 'jsworld
module-path
(list (make-binding:function
'js-big-bang
module-path
1
true
"plt.world.MobyJsworld.bigBang"
empty
false)
(make-binding:function 'js-text
module-path
1
false
"plt.world.MobyJsworld.text"
empty
false)
(bf 'js-div 0 "plt.world.MobyJsworld.div")
(bf 'js-p 0 "plt.world.MobyJsworld.p")
(bf 'js-button 1 "plt.world.MobyJsworld.button")
(bf 'js-button! 2 "plt.world.MobyJsworld.buttonStar")
(bf 'js-input 2 "plt.world.MobyJsworld.input")
(make-binding:function 'js-img module-path 1 true
"plt.world.MobyJsworld.img"
(list PERMISSION:INTERNET)
false)
(bf 'js-node 1 "plt.world.MobyJsworld.rawNode")
(bf 'js-select 2 "plt.world.MobyJsworld.select")))))
(define (extend-env/module-binding an-env a-module-binding)
(local [(define (loop an-env contents)
(cond
[(empty? contents)
an-env]
[else
(loop (env-extend an-env (first contents))
(rest contents))]))]
(loop an-env (module-binding-bindings a-module-binding))))
(define MOBY-RUNTIME-MODULES
(map (lambda (sexp)
(local [(define name (list-ref sexp 0))
(define path (list-ref sexp 1))
(define bindings (map sexp->binding (list-ref sexp 2)))]
(make-module-binding name
path
bindings)))
MOBY-RUNTIME-MODULE-BINDINGS))
(define moby-module-binding
(make-module-binding 'moby
"moby/moby"
(append
(module-binding-bindings world-stub-module)
(module-binding-bindings jsworld-module)
(module-binding-bindings telephony-module)
(module-binding-bindings location-module)
(module-binding-bindings net-module))))
(define known-modules (list* world-module
world-stub-module
location-module
tilt-module
net-module
parser-module
bootstrap-teachpack
function-teachpack
cage-teachpack
telephony-module
moby-module-binding
foreign-module
kernel-misc-module
MOBY-RUNTIME-MODULES))
(define (default-module-resolver a-name)
(local [(define (loop modules)
(cond
[(empty? modules)
false]
[(symbol=? (module-binding-name (first modules))
a-name)
(first modules)]
[else
(loop (rest modules))]))]
(loop known-modules)))
(define (default-module-path-resolver a-module-path parent-module-path)
(local [(define (loop modules)
(cond
[(empty? modules)
(cond
[(symbol? a-module-path)
a-module-path]
[(string? a-module-path)
(string->symbol
(module-path-join parent-module-path a-module-path))])]
[(module-path=? (module-path-join parent-module-path a-module-path)
(module-binding-source (first modules)))
(module-binding-name (first modules))]
[else
(loop (rest modules))]))]
(loop known-modules)))
(define (module-path-join p1 p2)
(local [(define (looks-like-relative-path? p)
(and (string? p)
(> (string-length p) 0)
(not (char=? (string-ref p 0) #\/))))
(define (butlast l)
(reverse (rest (reverse l))))
(define (path-only p)
(string-join (butlast (path-split p))
"/"))
(define (path-split p)
(string-split p #\/))
(define (path-simplify p)
(local [(define (loop current-chunks pieces)
(cond
[(empty? pieces)
(string-join (reverse current-chunks) "/")]
[(string=? (first pieces) "..")
(cond
[(empty? current-chunks)
(loop (cons (first pieces) current-chunks)
(rest pieces))]
[else
(loop (rest current-chunks) (rest pieces))])]
[else
(loop (cons (first pieces) current-chunks)
(rest pieces))]))]
(loop empty (path-split p))))]
(cond
[(symbol? p2)
p2]
[(string? p2)
(cond
[(and (string? p1)
(looks-like-relative-path? p2))
(if (string=? (path-only p1) "")
p2
(path-simplify
(string-append (path-only p1)
"/"
p2)))]
[else
(path-simplify p2)])])))
(provide/contract [extend-env/module-binding
(env? module-binding? . -> . env?)]
[moby-module-binding module-binding?]
[default-module-resolver (module-name? . -> . (or/c module-binding? false/c))]
[default-module-path-resolver (module-path? module-path? . -> . (or/c module-name? false/c))]
[module-path-join (module-path? module-path? . -> . module-path?)])