Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
55a95d3c54
62
NOTES
62
NOTES
|
@ -683,4 +683,64 @@ circularity between helpers and types.
|
|||
|
||||
|
||||
The parameters I'm using to control bounce are too high for Firefox,
|
||||
leading it to raise the dialog about an out of control jva process. Not good.
|
||||
leading it to raise the dialog about an out of control jva process. Not good.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Working out the type mappings between values in Racket and values in JavaScript
|
||||
|
||||
|
||||
|
||||
Racket JavaScript Switched over?
|
||||
|
||||
|
||||
number jsnums.SchemeNumber yes
|
||||
immutable strings JavaScript string
|
||||
mutable strings types.Str
|
||||
|
||||
vector
|
||||
|
||||
|
||||
regular-expressions
|
||||
path
|
||||
bytes
|
||||
box
|
||||
placeholder
|
||||
character
|
||||
symbol
|
||||
keyword
|
||||
|
||||
pair yes
|
||||
empty yes
|
||||
|
||||
eq-hashtable
|
||||
equal-hashtable
|
||||
|
||||
struct-type
|
||||
struct
|
||||
|
||||
path
|
||||
|
||||
continuation-mark-set
|
||||
|
||||
primitive-procedure
|
||||
closure
|
||||
case-lambda
|
||||
|
||||
|
||||
undefined undefined
|
||||
void plt.runtime.VOID
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
I should add the functions:
|
||||
|
||||
get-viewport-width
|
||||
get-viewport-height
|
||||
|
||||
Other notes from Shriram: too slow, inconsistent positioning from jsworld.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Added base as the default planet language.
|
19
README
19
README
|
@ -3,6 +3,7 @@ Whalesong: a compiler from Racket to JavaScript.
|
|||
|
||||
Danny Yoo (dyoo@cs.wpi.edu)
|
||||
|
||||
|
||||
======================================================================
|
||||
|
||||
|
||||
|
@ -16,9 +17,25 @@ amount of time.
|
|||
|
||||
Example usage
|
||||
|
||||
[FIXME]
|
||||
|
||||
|
||||
Create a simple, standalong executable of your program. At the
|
||||
moment, the program must be written in the base language of whalesong.
|
||||
(This restriction currently prevents arbitrary racket/base programs
|
||||
from compiling, and we'll be working to remove this restriction.)
|
||||
|
||||
$ cat hello.rkt
|
||||
#lang planet dyoo/whalesong
|
||||
(display "hello world")
|
||||
(newline)
|
||||
|
||||
$ ./whalesong.rkt build hello.rkt
|
||||
|
||||
$ ls -l hello.xhtml
|
||||
-rw-rw-r-- 1 dyoo nogroup 692213 Jun 7 18:00 hello.xhtml
|
||||
|
||||
|
||||
[FIXME: add more examples]
|
||||
|
||||
|
||||
======================================================================
|
||||
|
|
|
@ -321,7 +321,7 @@
|
|||
;; that has not yet been invoked.
|
||||
;; fixme: This also needs to generate code for the requires and provides.
|
||||
(match mod
|
||||
[(struct Module (name path prefix requires code))
|
||||
[(struct Module (name path prefix requires provides code))
|
||||
(let*: ([after-module-body (make-label 'afterModuleBody)]
|
||||
[module-entry (make-label 'module-entry)]
|
||||
[names : (Listof (U False Symbol GlobalBucket ModuleVariable))
|
||||
|
@ -2156,6 +2156,7 @@
|
|||
(Module-path exp)
|
||||
(Module-prefix exp)
|
||||
(Module-requires exp)
|
||||
(Module-provides exp)
|
||||
(adjust-expression-depth (Module-code exp) n (add1 skip)))]
|
||||
|
||||
[(Constant? exp)
|
||||
|
|
|
@ -37,10 +37,18 @@
|
|||
[path : ModuleLocator]
|
||||
[prefix : Prefix]
|
||||
[requires : (Listof ModuleLocator)]
|
||||
[provides : (Listof ModuleProvide)]
|
||||
[code : Expression])
|
||||
#:transparent)
|
||||
|
||||
|
||||
(define-struct: ModuleProvide ([internal-name : Symbol]
|
||||
[external-name : Symbol]
|
||||
[source : ModuleLocator])
|
||||
#:transparent)
|
||||
|
||||
|
||||
|
||||
(define-struct: Top ([prefix : Prefix]
|
||||
[code : Expression]) #:transparent)
|
||||
|
||||
|
|
|
@ -334,10 +334,10 @@
|
|||
#:transparent)
|
||||
|
||||
;; Check the closure procedure value in 'proc and make sure it can accept the
|
||||
;; # of arguments (stored as a number in the val register.).
|
||||
(define-struct: CheckClosureArity! ([arity : OpArg])
|
||||
;; # of arguments (stored as a number in the argcount register.).
|
||||
(define-struct: CheckClosureArity! ([num-args : OpArg])
|
||||
#:transparent)
|
||||
(define-struct: CheckPrimitiveArity! ([arity : OpArg])
|
||||
(define-struct: CheckPrimitiveArity! ([num-args : OpArg])
|
||||
#:transparent)
|
||||
|
||||
|
||||
|
|
3
examples/alert.rkt
Normal file
3
examples/alert.rkt
Normal file
|
@ -0,0 +1,3 @@
|
|||
#lang planet dyoo/whalesong
|
||||
(require (planet dyoo/whalesong/js))
|
||||
(alert "hello world")
|
37
examples/dom-play.rkt
Normal file
37
examples/dom-play.rkt
Normal file
|
@ -0,0 +1,37 @@
|
|||
#lang planet dyoo/whalesong
|
||||
|
||||
(require (planet dyoo/whalesong/js))
|
||||
|
||||
|
||||
;; insert-break: -> void
|
||||
(define (insert-break)
|
||||
(call ($ "<br/>") "appendTo" body)
|
||||
(void))
|
||||
|
||||
|
||||
(define (write-message msg)
|
||||
(void (call (call (call ($ "<span/>") "text" msg)
|
||||
"css" "white-space" "pre")
|
||||
"appendTo"
|
||||
body)))
|
||||
|
||||
|
||||
|
||||
;; Set the background green.
|
||||
(void (call body "css" "background-color" "lightgreen"))
|
||||
(void (call ($ "<h1>Hello World</h1>") "appendTo" body))
|
||||
(write-message "Hello, this is a test!")
|
||||
(insert-break)
|
||||
(let loop ([i 0])
|
||||
(cond
|
||||
[(= i 10)
|
||||
(void)]
|
||||
[else
|
||||
(write-message "iteration ") (write-message i)
|
||||
(insert-break)
|
||||
(loop (add1 i))]))
|
||||
|
||||
(write-message "viewport-width: ") (write-message (viewport-width))
|
||||
(insert-break)
|
||||
(write-message "viewport-height: ") (write-message (viewport-height))
|
||||
(insert-break)
|
4
examples/hello.rkt
Normal file
4
examples/hello.rkt
Normal file
|
@ -0,0 +1,4 @@
|
|||
#lang planet dyoo/whalesong
|
||||
|
||||
(display "hello world")
|
||||
(newline)
|
9
examples/simple-world-program.rkt
Normal file
9
examples/simple-world-program.rkt
Normal file
|
@ -0,0 +1,9 @@
|
|||
#lang planet dyoo/whalesong
|
||||
(require (planet dyoo/whalesong/world))
|
||||
|
||||
(display "hello again")
|
||||
(newline)
|
||||
|
||||
(is-color? "red")
|
||||
(is-color? "blue")
|
||||
(is-color? 42)
|
7
examples/window-size.rkt
Normal file
7
examples/window-size.rkt
Normal file
|
@ -0,0 +1,7 @@
|
|||
#lang planet dyoo/whalesong
|
||||
|
||||
(when (in-javascript-context?)
|
||||
(viewport-width))
|
||||
|
||||
(when (in-javascript-context?)
|
||||
(viewport-height))
|
|
@ -101,13 +101,13 @@
|
|||
(cond [(symbol? val)
|
||||
(format "~s" (symbol->string val))]
|
||||
[(pair? val)
|
||||
(format "[~a, ~a]"
|
||||
(format "RUNTIME.makePair(~a, ~a)"
|
||||
(loop (car val))
|
||||
(loop (cdr val)))]
|
||||
[(boolean? val)
|
||||
(if val "true" "false")]
|
||||
[(void? val)
|
||||
"null"]
|
||||
"RUNTIME.VOID"]
|
||||
[(empty? val)
|
||||
(format "RUNTIME.NULL")]
|
||||
[(number? val)
|
||||
|
@ -122,7 +122,7 @@
|
|||
[(empty? vals)
|
||||
"RUNTIME.NULL"]
|
||||
[else
|
||||
(format "[~a, ~a]" (first vals) (loop (rest vals)))])))
|
||||
(format "RUNTIME.makePair(~a, ~a)" (first vals) (loop (rest vals)))])))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -68,26 +68,21 @@
|
|||
|
||||
[(>=)
|
||||
(assemble-boolean-chain "jsnums.greaterThanOrEqual" checked-operands)]
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
[(cons)
|
||||
(format "[~a, ~a]" (first checked-operands) (second checked-operands))]
|
||||
(format "RUNTIME.makePair(~a, ~a)"
|
||||
(first checked-operands)
|
||||
(second checked-operands))]
|
||||
|
||||
[(car)
|
||||
(format "(~a)[0]" (first checked-operands))]
|
||||
(format "(~a).first" (first checked-operands))]
|
||||
|
||||
[(cdr)
|
||||
(format "(~a)[1]" (first checked-operands))]
|
||||
(format "(~a).rest" (first checked-operands))]
|
||||
|
||||
[(list)
|
||||
(let loop ([checked-operands checked-operands])
|
||||
(cond
|
||||
[(empty? checked-operands)
|
||||
"RUNTIME.NULL"]
|
||||
[else
|
||||
(format "[~a,~a]" (first checked-operands) (loop (rest checked-operands)))]))]
|
||||
(assemble-listof-assembled-values checked-operands))]
|
||||
|
||||
[(null?)
|
||||
(format "(~a === RUNTIME.NULL)" (first checked-operands))]
|
||||
|
@ -151,17 +146,15 @@
|
|||
(let: ([test-string : String
|
||||
(case domain
|
||||
[(number)
|
||||
(format "(jsnums.isSchemeNumber(~a))"
|
||||
(format "jsnums.isSchemeNumber(~a)"
|
||||
operand-string)]
|
||||
[(string)
|
||||
(format "(typeof(~a) === 'string')"
|
||||
operand-string)]
|
||||
[(list)
|
||||
(format "(~a === [] || (typeof(~a) === 'object' && (~a).length === 2))"
|
||||
operand-string operand-string operand-string)]
|
||||
(format "RUNTIME.isList(~a)" operand-string)]
|
||||
[(pair)
|
||||
(format "(typeof(~a) === 'object' && (~a).length === 2)"
|
||||
operand-string operand-string)]
|
||||
(format "RUNTIME.isPair(~a)" operand-string)]
|
||||
[(box)
|
||||
(format "(typeof(~a) === 'object' && (~a).length === 1)"
|
||||
operand-string operand-string)])])
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
RUNTIME.raiseOperatorIsNotClosure(MACHINE, MACHINE.proc);
|
||||
}
|
||||
if (! RUNTIME.isArityMatching(MACHINE.proc.arity, ~a)) {
|
||||
RUNTIME.raiseArityMismatchError(MACHINE.proc,
|
||||
RUNTIME.raiseArityMismatchError(MACHINE,
|
||||
MACHINE.proc,
|
||||
MACHINE.proc.arity,
|
||||
~a);
|
||||
}
|
||||
EOF
|
||||
(assemble-oparg (CheckClosureArity!-arity op))
|
||||
(assemble-oparg (CheckClosureArity!-arity op)))]
|
||||
(assemble-oparg (CheckClosureArity!-num-args op))
|
||||
(assemble-oparg (CheckClosureArity!-num-args op)))]
|
||||
|
||||
|
||||
[(CheckPrimitiveArity!? op)
|
||||
|
@ -42,13 +43,14 @@ EOF
|
|||
RUNTIME.raiseOperatorIsNotPrimitiveProcedure(MACHINE, MACHINE.proc);
|
||||
}
|
||||
if (! RUNTIME.isArityMatching(MACHINE.proc.arity, ~a)) {
|
||||
RUNTIME.raiseArityMismatchError(MACHINE.proc,
|
||||
RUNTIME.raiseArityMismatchError(MACHINE,
|
||||
MACHINE.proc,
|
||||
MACHINE.proc.arity,
|
||||
~a);
|
||||
}
|
||||
EOF
|
||||
(assemble-oparg (CheckPrimitiveArity!-arity op))
|
||||
(assemble-oparg (CheckPrimitiveArity!-arity op)))]
|
||||
(assemble-oparg (CheckPrimitiveArity!-num-args op))
|
||||
(assemble-oparg (CheckPrimitiveArity!-num-args op)))]
|
||||
|
||||
|
||||
[(ExtendEnvironment/Prefix!? op)
|
||||
|
|
|
@ -186,7 +186,7 @@ EOF
|
|||
"")
|
||||
(cond
|
||||
[(DebugPrint? stmt)
|
||||
(format "MACHINE.params.currentOutputPort.write(MACHINE, ~a);" (assemble-oparg (DebugPrint-value stmt)))]
|
||||
(format "MACHINE.params.currentOutputPort.writeDomNode(MACHINE, $('<span/>').text(~a));" (assemble-oparg (DebugPrint-value stmt)))]
|
||||
[(AssignImmediateStatement? stmt)
|
||||
(let: ([t : String (assemble-target (AssignImmediateStatement-target stmt))]
|
||||
[v : OpArg (AssignImmediateStatement-value stmt)])
|
||||
|
|
|
@ -2,8 +2,14 @@
|
|||
|
||||
(require "assemble.rkt"
|
||||
"quote-cdata.rkt"
|
||||
"../make.rkt"
|
||||
"../make-structs.rkt"
|
||||
"../make/make.rkt"
|
||||
"../make/make-structs.rkt"
|
||||
"../parameters.rkt"
|
||||
"../compiler/expression-structs.rkt"
|
||||
"../parser/path-rewriter.rkt"
|
||||
"../parser/parse-bytecode.rkt"
|
||||
racket/match
|
||||
(prefix-in query: "../lang/js/query.rkt")
|
||||
(planet dyoo/closure-compile:1:1)
|
||||
(prefix-in runtime: "get-runtime.rkt")
|
||||
(prefix-in racket: racket/base))
|
||||
|
@ -21,52 +27,172 @@
|
|||
write-runtime)
|
||||
|
||||
|
||||
|
||||
;; notify: string (listof any)* -> void
|
||||
;; Print out log message during the build process.
|
||||
(define (notify msg . args)
|
||||
(displayln (apply format msg args)))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(define-struct js-impl (name ;; symbol
|
||||
real-path ;; path
|
||||
src ;; string
|
||||
)
|
||||
#:transparent)
|
||||
|
||||
|
||||
;; Packager: produce single .js files to be included to execute a
|
||||
;; program.
|
||||
|
||||
|
||||
|
||||
(define (package-anonymous source-code
|
||||
#:should-follow? should-follow?
|
||||
#:should-follow-children? should-follow?
|
||||
#:output-port op)
|
||||
(fprintf op "(function() {\n")
|
||||
(package source-code
|
||||
#:should-follow? should-follow?
|
||||
#:should-follow-children? should-follow?
|
||||
#:output-port op)
|
||||
(fprintf op " return invoke; })\n"))
|
||||
|
||||
|
||||
|
||||
;; source-is-javascript-module?: Source -> boolean
|
||||
;; Returns true if the source looks like a Javascript-implemented module.
|
||||
(define (source-is-javascript-module? src)
|
||||
(cond
|
||||
[(StatementsSource? src)
|
||||
#f]
|
||||
[(MainModuleSource? src)
|
||||
(source-is-javascript-module? (MainModuleSource-source src))]
|
||||
[(ModuleSource? src)
|
||||
(query:has-javascript-implementation? `(file ,(path->string (ModuleSource-path src))))]
|
||||
[(SexpSource? src)
|
||||
#f]
|
||||
[(UninterpretedSource? src)
|
||||
#f]))
|
||||
|
||||
|
||||
;; get-javascript-implementation: source -> UninterpretedSource
|
||||
(define (get-javascript-implementation src)
|
||||
|
||||
(define (get-provided-name-code bytecode)
|
||||
(match bytecode
|
||||
[(struct Top [_ (struct Module (name path prefix requires provides code))])
|
||||
(apply string-append
|
||||
(map (lambda (p)
|
||||
(format "modrec.namespace[~s] = exports[~s];\n"
|
||||
(symbol->string (ModuleProvide-internal-name p))
|
||||
(symbol->string (ModuleProvide-external-name p))))
|
||||
provides))]
|
||||
[else
|
||||
""]))
|
||||
(cond
|
||||
[(StatementsSource? src)
|
||||
(error 'get-javascript-implementation src)]
|
||||
[(MainModuleSource? src)
|
||||
(get-javascript-implementation (MainModuleSource-source src))]
|
||||
[(ModuleSource? src)
|
||||
(let ([name (rewrite-path (ModuleSource-path src))]
|
||||
[text (query:query `(file ,(path->string (ModuleSource-path src))))]
|
||||
[bytecode (parse-bytecode (ModuleSource-path src))])
|
||||
(make-UninterpretedSource
|
||||
(format "
|
||||
MACHINE.modules[~s] =
|
||||
new plt.runtime.ModuleRecord(~s,
|
||||
function(MACHINE) {
|
||||
if(--MACHINE.callsBeforeTrampoline<0) { throw arguments.callee; }
|
||||
var modrec = MACHINE.modules[~s];
|
||||
var exports = {};
|
||||
modrec.isInvoked = true;
|
||||
(function(MACHINE, RUNTIME, EXPORTS){~a})(MACHINE, plt.runtime, exports);
|
||||
// FIXME: we need to inject the namespace with the values defined in exports.
|
||||
~a
|
||||
return MACHINE.control.pop().label(MACHINE);
|
||||
});
|
||||
"
|
||||
(symbol->string name)
|
||||
(symbol->string name)
|
||||
(symbol->string name)
|
||||
text
|
||||
(get-provided-name-code bytecode))))]
|
||||
[(SexpSource? src)
|
||||
(error 'get-javascript-implementation)]
|
||||
[(UninterpretedSource? src)
|
||||
(error 'get-javascript-implementation)]))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;; package: Source (path -> boolean) output-port -> void
|
||||
|
||||
;; Compile package for the given source program. should-follow?
|
||||
;; indicates whether we should continue following module paths.
|
||||
;; Compile package for the given source program.
|
||||
;;
|
||||
;; should-follow-children? indicates whether we should continue
|
||||
;; following module paths of a source's dependencies.
|
||||
;;
|
||||
;; The generated output defines a function called 'invoke' with
|
||||
;; four arguments (MACHINE, SUCCESS, FAIL, PARAMS). When called, it will
|
||||
;; execute the code to either run standalone expressions or
|
||||
;; load in modules.
|
||||
(define (package source-code
|
||||
#:should-follow? should-follow?
|
||||
#:should-follow-children? should-follow?
|
||||
#:output-port op)
|
||||
|
||||
|
||||
;; wrap-source: source -> source
|
||||
;; Translate all JavaScript-implemented sources into uninterpreted sources;
|
||||
;; we'll leave its interpretation to on-visit-src.
|
||||
(define (wrap-source src)
|
||||
(cond
|
||||
[(source-is-javascript-module? src)
|
||||
(get-javascript-implementation src)]
|
||||
[else
|
||||
src]))
|
||||
|
||||
|
||||
(define (on-visit-src src ast stmts)
|
||||
(cond
|
||||
[(UninterpretedSource? src)
|
||||
(fprintf op (UninterpretedSource-datum src))]
|
||||
[else
|
||||
(assemble/write-invoke stmts op)
|
||||
(fprintf op "(MACHINE, function() { ")]))
|
||||
|
||||
|
||||
(define (after-visit-src src ast stmts)
|
||||
(cond
|
||||
[(UninterpretedSource? src)
|
||||
(void)]
|
||||
[else
|
||||
(fprintf op " }, FAIL, PARAMS);")]))
|
||||
|
||||
|
||||
(define (on-last-src)
|
||||
(fprintf op "SUCCESS();"))
|
||||
|
||||
|
||||
(define packaging-configuration
|
||||
(make-Configuration
|
||||
|
||||
wrap-source
|
||||
|
||||
should-follow?
|
||||
|
||||
;; on
|
||||
(lambda (src ast stmts)
|
||||
(assemble/write-invoke stmts op)
|
||||
(fprintf op "(MACHINE, function() { "))
|
||||
on-visit-src
|
||||
|
||||
;; after
|
||||
(lambda (src ast stmts)
|
||||
(fprintf op " }, FAIL, PARAMS);"))
|
||||
|
||||
after-visit-src
|
||||
|
||||
;; last
|
||||
(lambda ()
|
||||
(fprintf op "SUCCESS();"))))
|
||||
on-last-src))
|
||||
|
||||
|
||||
(fprintf op "var invoke = (function(MACHINE, SUCCESS, FAIL, PARAMS) {")
|
||||
|
@ -90,10 +216,15 @@
|
|||
|
||||
;; write-runtime: output-port -> void
|
||||
(define (write-runtime op)
|
||||
|
||||
(define (wrap-source src) src)
|
||||
(let ([packaging-configuration
|
||||
(make-Configuration
|
||||
;; should-follow?
|
||||
(lambda (src p) #t)
|
||||
|
||||
wrap-source
|
||||
|
||||
;; should-follow-children?
|
||||
(lambda (src) #t)
|
||||
;; on
|
||||
(lambda (src ast stmts)
|
||||
(assemble/write-invoke stmts op)
|
||||
|
@ -114,12 +245,19 @@
|
|||
(make (list only-bootstrapped-code) packaging-configuration)
|
||||
(fprintf op "})(plt.runtime.currentMachine,\nfunction(){ plt.runtime.setReadyTrue(); },\nfunction(){},\n{});\n")))
|
||||
|
||||
|
||||
|
||||
|
||||
(define (compress x)
|
||||
(if (current-compress-javascript?)
|
||||
(closure-compile x)
|
||||
x))
|
||||
|
||||
|
||||
|
||||
(define *the-runtime*
|
||||
(let ([buffer (open-output-string)])
|
||||
(write-runtime buffer)
|
||||
(closure-compile
|
||||
(compress
|
||||
(get-output-string buffer))))
|
||||
|
||||
|
||||
|
@ -150,9 +288,9 @@ EOF
|
|||
(define (get-code source-code)
|
||||
(let ([buffer (open-output-string)])
|
||||
(package source-code
|
||||
#:should-follow? (lambda (src p) #t)
|
||||
#:should-follow-children? (lambda (src) #t)
|
||||
#:output-port buffer)
|
||||
(closure-compile
|
||||
(compress
|
||||
(get-output-string buffer))))
|
||||
|
||||
|
||||
|
@ -161,14 +299,14 @@ EOF
|
|||
(define (get-standalone-code source-code)
|
||||
(let ([buffer (open-output-string)])
|
||||
(write-standalone-code source-code buffer)
|
||||
(closure-compile
|
||||
(compress
|
||||
(get-output-string buffer))))
|
||||
|
||||
|
||||
;; write-standalone-code: source output-port -> void
|
||||
(define (write-standalone-code source-code op)
|
||||
(package-anonymous source-code
|
||||
#:should-follow? (lambda (src p) #t)
|
||||
#:should-follow-children? (lambda (src) #t)
|
||||
#:output-port op)
|
||||
(fprintf op "()(plt.runtime.currentMachine, function() {}, function() {}, {});\n"))
|
||||
|
||||
|
@ -193,6 +331,8 @@ var invokeMainModule = function() {
|
|||
if (console && console.log) {
|
||||
console.log(e.stack || e);
|
||||
}
|
||||
MACHINE.params.currentErrorDisplayer(
|
||||
MACHINE, $(plt.helpers.toDomNode(e.stack || e)).css('color', 'red'));
|
||||
})},
|
||||
function() {
|
||||
// On module loading failure
|
||||
|
|
|
@ -549,8 +549,8 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
|
||||
|
||||
var makeLowLevelEqHash = function() {
|
||||
return new _Hashtable(function(x) { return getEqHashCode(x); },
|
||||
function(x, y) { return x === y; });
|
||||
return new Hashtable(function(x) { return getEqHashCode(x); },
|
||||
function(x, y) { return x === y; });
|
||||
};
|
||||
|
||||
|
||||
|
@ -570,14 +570,15 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
if (! cache) {
|
||||
cache = makeLowLevelEqHash();
|
||||
}
|
||||
|
||||
if (x === null) {
|
||||
return "null";
|
||||
}
|
||||
if (typeof(x) === 'object') {
|
||||
if (cache.containsKey(x)) {
|
||||
return "...";
|
||||
}
|
||||
}
|
||||
|
||||
if (x == undefined || x == null) {
|
||||
if (x == undefined) {
|
||||
return "#<undefined>";
|
||||
}
|
||||
if (typeof(x) == 'string') {
|
||||
|
@ -606,12 +607,14 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
if (! cache) {
|
||||
cache = makeLowLevelEqHash();
|
||||
}
|
||||
if (x === null) {
|
||||
return "null";
|
||||
}
|
||||
if (typeof(x) === 'object') {
|
||||
if (cache.containsKey(x)) {
|
||||
return "...";
|
||||
}
|
||||
}
|
||||
|
||||
if (x == undefined || x == null) {
|
||||
return "#<undefined>";
|
||||
}
|
||||
|
@ -635,24 +638,74 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
};
|
||||
|
||||
|
||||
// toDomNode: scheme-value -> dom-node
|
||||
var toDomNode = function(x, cache) {
|
||||
if (! cache) {
|
||||
cache = makeLowLevelEqHash();
|
||||
|
||||
|
||||
var ToDomNodeParameters = function(params) {
|
||||
if (! params) { params = {}; }
|
||||
this.cache = makeLowLevelEqHash();
|
||||
for (var k in params) {
|
||||
if (params.hasOwnProperty(k)) {
|
||||
this[k] = params[k];
|
||||
}
|
||||
}
|
||||
this.objectCounter = 0;
|
||||
};
|
||||
|
||||
// getMode: -> (U "print" "display" "write")
|
||||
ToDomNodeParameters.prototype.getMode = function() {
|
||||
if (this.mode) {
|
||||
return this.mode;
|
||||
}
|
||||
return 'print';
|
||||
};
|
||||
|
||||
ToDomNodeParameters.prototype.containsKey = function(x) {
|
||||
return this.cache.containsKey(x);
|
||||
};
|
||||
|
||||
ToDomNodeParameters.prototype.get = function(x) {
|
||||
return this.cache.get(x);
|
||||
};
|
||||
|
||||
ToDomNodeParameters.prototype.remove = function(x) {
|
||||
return this.cache.remove(x);
|
||||
};
|
||||
|
||||
ToDomNodeParameters.prototype.put = function(x) {
|
||||
this.objectCounter++;
|
||||
return this.cache.put(x, this.objectCounter);
|
||||
};
|
||||
|
||||
|
||||
// toDomNode: scheme-value -> dom-node
|
||||
var toDomNode = function(x, params) {
|
||||
if (params === 'write') {
|
||||
params = new ToDomNodeParameters({'mode' : 'write'});
|
||||
} else if (params === 'print') {
|
||||
params = new ToDomNodeParameters({'mode' : 'print'});
|
||||
} else if (params === 'display') {
|
||||
params = new ToDomNodeParameters({'mode' : 'display'});
|
||||
} else {
|
||||
params = params || new ToDomNodeParameters({'mode' : 'display'});
|
||||
}
|
||||
|
||||
if (jsnums.isSchemeNumber(x)) {
|
||||
return numberToDomNode(x);
|
||||
return numberToDomNode(x, params);
|
||||
}
|
||||
|
||||
if (x === null) {
|
||||
var node = document.createElement("span");
|
||||
node.appendChild(document.createTextNode("null"));
|
||||
return node;
|
||||
}
|
||||
|
||||
if (typeof(x) == 'object') {
|
||||
if (cache.containsKey(x)) {
|
||||
if (params.containsKey(x)) {
|
||||
var node = document.createElement("span");
|
||||
node.appendChild(document.createTextNode("..."));
|
||||
node.appendChild(document.createTextNode("#" + params.get(x)));
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
if (x == undefined || x == null) {
|
||||
var node = document.createElement("span");
|
||||
node.appendChild(document.createTextNode("#<undefined>"));
|
||||
|
@ -661,11 +714,17 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
|
||||
if (typeof(x) == 'string') {
|
||||
var wrapper = document.createElement("span");
|
||||
wrapper.style["white-space"] = "pre";
|
||||
var node = document.createTextNode(toWrittenString(x));
|
||||
wrapper.style["white-space"] = "pre";
|
||||
var node;
|
||||
if (params.getMode() === 'write' || params.getMode() === 'print') {
|
||||
node = document.createTextNode(toWrittenString(x));
|
||||
} else {
|
||||
node = document.createTextNode(toDisplayedString(x));
|
||||
}
|
||||
wrapper.appendChild(node);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (typeof(x) != 'object' && typeof(x) != 'function') {
|
||||
var node = document.createElement("span");
|
||||
node.appendChild(document.createTextNode(x.toString()));
|
||||
|
@ -676,22 +735,23 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
if (x.nodeType) {
|
||||
returnVal = x;
|
||||
} else if (typeof(x.toDomNode) !== 'undefined') {
|
||||
returnVal = x.toDomNode(cache);
|
||||
} else if (typeof(x.toWrittenString) !== 'undefined') {
|
||||
|
||||
returnVal = x.toDomNode(params);
|
||||
} else if (params.getMode() === 'write' &&
|
||||
typeof(x.toWrittenString) !== 'undefined') {
|
||||
var node = document.createElement("span");
|
||||
node.appendChild(document.createTextNode(x.toWrittenString(cache)));
|
||||
node.appendChild(document.createTextNode(x.toWrittenString(params)));
|
||||
returnVal = node;
|
||||
} else if (typeof(x.toDisplayedString) !== 'undefined') {
|
||||
} else if (params.getMode() === 'display' &&
|
||||
typeof(x.toDisplayedString) !== 'undefined') {
|
||||
var node = document.createElement("span");
|
||||
node.appendChild(document.createTextNode(x.toDisplayedString(cache)));
|
||||
node.appendChild(document.createTextNode(x.toDisplayedString(params)));
|
||||
returnVal = node;
|
||||
} else {
|
||||
var node = document.createElement("span");
|
||||
node.appendChild(document.createTextNode(x.toString()));
|
||||
returnVal = node;
|
||||
}
|
||||
cache.remove(x);
|
||||
params.remove(x);
|
||||
return returnVal;
|
||||
};
|
||||
|
||||
|
@ -699,7 +759,7 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
|
||||
// numberToDomNode: jsnum -> dom
|
||||
// Given a jsnum, produces a dom-node representation.
|
||||
var numberToDomNode = function(n) {
|
||||
var numberToDomNode = function(n, params) {
|
||||
var node;
|
||||
if (jsnums.isExact(n)) {
|
||||
if (jsnums.isInteger(n)) {
|
||||
|
@ -726,16 +786,49 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
|
||||
// rationalToDomNode: rational -> dom-node
|
||||
var rationalToDomNode = function(n) {
|
||||
var node = document.createElement("span");
|
||||
var repeatingDecimalNode = document.createElement("span");
|
||||
var chunks = jsnums.toRepeatingDecimal(jsnums.numerator(n),
|
||||
jsnums.denominator(n));
|
||||
node.appendChild(document.createTextNode(chunks[0] + '.'))
|
||||
node.appendChild(document.createTextNode(chunks[1]));
|
||||
var overlineSpan = document.createElement("span");
|
||||
overlineSpan.style.textDecoration = 'overline';
|
||||
overlineSpan.appendChild(document.createTextNode(chunks[2]));
|
||||
node.appendChild(overlineSpan);
|
||||
return node;
|
||||
jsnums.denominator(n),
|
||||
{limit: 25});
|
||||
repeatingDecimalNode.appendChild(document.createTextNode(chunks[0] + '.'))
|
||||
repeatingDecimalNode.appendChild(document.createTextNode(chunks[1]));
|
||||
if (chunks[2] === '...') {
|
||||
repeatingDecimalNode.appendChild(
|
||||
document.createTextNode(chunks[2]));
|
||||
} else if (chunks[2] !== '0') {
|
||||
var overlineSpan = document.createElement("span");
|
||||
overlineSpan.style.textDecoration = 'overline';
|
||||
overlineSpan.appendChild(document.createTextNode(chunks[2]));
|
||||
repeatingDecimalNode.appendChild(overlineSpan);
|
||||
}
|
||||
|
||||
|
||||
var fractionalNode = document.createElement("span");
|
||||
var numeratorNode = document.createElement("sup");
|
||||
numeratorNode.appendChild(document.createTextNode(String(jsnums.numerator(n))));
|
||||
var denominatorNode = document.createElement("sub");
|
||||
denominatorNode.appendChild(document.createTextNode(String(jsnums.denominator(n))));
|
||||
fractionalNode.appendChild(numeratorNode);
|
||||
fractionalNode.appendChild(document.createTextNode("/"));
|
||||
fractionalNode.appendChild(denominatorNode);
|
||||
|
||||
|
||||
var numberNode = document.createElement("span");
|
||||
numberNode.appendChild(repeatingDecimalNode);
|
||||
numberNode.appendChild(fractionalNode);
|
||||
fractionalNode.style['display'] = 'none';
|
||||
|
||||
var showingRepeating = true;
|
||||
|
||||
numberNode.onclick = function(e) {
|
||||
showingRepeating = !showingRepeating;
|
||||
repeatingDecimalNode.style['display'] =
|
||||
(showingRepeating ? 'inline' : 'none')
|
||||
fractionalNode.style['display'] =
|
||||
(!showingRepeating ? 'inline' : 'none')
|
||||
};
|
||||
numberNode.style['cursor'] = 'pointer';
|
||||
return numberNode;
|
||||
}
|
||||
|
||||
|
||||
|
@ -743,6 +836,62 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
|
||||
|
||||
|
||||
var escapeString = function(s) {
|
||||
return '"' + replaceUnprintableStringChars(s) + '"';
|
||||
};
|
||||
|
||||
var replaceUnprintableStringChars = function(s) {
|
||||
var ret = [];
|
||||
for (var i = 0; i < s.length; i++) {
|
||||
var val = s.charCodeAt(i);
|
||||
switch(val) {
|
||||
case 7: ret.push('\\a'); break;
|
||||
case 8: ret.push('\\b'); break;
|
||||
case 9: ret.push('\\t'); break;
|
||||
case 10: ret.push('\\n'); break;
|
||||
case 11: ret.push('\\v'); break;
|
||||
case 12: ret.push('\\f'); break;
|
||||
case 13: ret.push('\\r'); break;
|
||||
case 34: ret.push('\\"'); break;
|
||||
case 92: ret.push('\\\\'); break;
|
||||
default: if (val >= 32 && val <= 126) {
|
||||
ret.push( s.charAt(i) );
|
||||
}
|
||||
else {
|
||||
var numStr = val.toString(16).toUpperCase();
|
||||
while (numStr.length < 4) {
|
||||
numStr = '0' + numStr;
|
||||
}
|
||||
ret.push('\\u' + numStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret.join('');
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -783,15 +932,16 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
helpers.makeLowLevelEqHash = makeLowLevelEqHash;
|
||||
|
||||
helpers.heir = heir;
|
||||
|
||||
|
||||
|
||||
|
||||
helpers.escapeString = escapeString;
|
||||
helpers.toWrittenString = toWrittenString;
|
||||
helpers.toDisplayedString = toDisplayedString;
|
||||
helpers.toDomNode = toDomNode;
|
||||
|
||||
|
||||
helpers.toDomNode = toDomNode;
|
||||
helpers.ToDomNodeParameters = ToDomNodeParameters;
|
||||
|
||||
helpers.clone = clone;
|
||||
|
||||
|
||||
scope.link.announceReady('helpers');
|
||||
})(this['plt']);
|
||||
|
|
|
@ -195,7 +195,7 @@ That way, we can do a simple grep.
|
|||
var length = function(lst) {
|
||||
checkList(lst, 'length', 1, [lst]);
|
||||
var ret = 0;
|
||||
for (; !lst.isEmpty(); lst = lst.rest()) {
|
||||
for (; !lst.isEmpty(); lst = lst.rest) {
|
||||
ret = ret+1;
|
||||
}
|
||||
return ret;
|
||||
|
@ -224,8 +224,8 @@ That way, we can do a simple grep.
|
|||
var fArgs = [];
|
||||
var argsRest = [];
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
fArgs.push(args[i].first());
|
||||
argsRest.push(args[i].rest());
|
||||
fArgs.push(args[i].first);
|
||||
argsRest.push(args[i].rest);
|
||||
}
|
||||
fArgs.push(acc);
|
||||
return CALL(f, fArgs,
|
||||
|
@ -246,20 +246,20 @@ That way, we can do a simple grep.
|
|||
}
|
||||
|
||||
var compYes = new PrimProc('compYes', 1, false, false,
|
||||
function(x) { return CALL(comp, [x, lst.first()], id); });
|
||||
function(x) { return CALL(comp, [x, lst.first], id); });
|
||||
var compNo = new PrimProc('compNo', 1, false, false,
|
||||
function(x) { return CALL(comp, [x, lst.first()],
|
||||
function(x) { return CALL(comp, [x, lst.first],
|
||||
function(res) { return !res; });
|
||||
});
|
||||
|
||||
return CALL(PRIMITIVES['filter'],
|
||||
[compYes, lst.rest()],
|
||||
[compYes, lst.rest],
|
||||
quicksortHelp(function(sorted1) {
|
||||
return CALL(PRIMITIVES['filter'],
|
||||
[compNo, lst.rest()],
|
||||
[compNo, lst.rest],
|
||||
quicksortHelp(function(sorted2) {
|
||||
return k( append([sorted1,
|
||||
types.list([lst.first()]),
|
||||
types.list([lst.first]),
|
||||
sorted2]) );
|
||||
}));
|
||||
}));
|
||||
|
@ -487,7 +487,7 @@ That way, we can do a simple grep.
|
|||
|
||||
|
||||
var isAssocList = function(x) {
|
||||
return isPair(x) && isPair(x.rest()) && isEmpty(x.rest().rest());
|
||||
return isPair(x) && isPair(x.rest) && isEmpty(x.rest.rest);
|
||||
};
|
||||
|
||||
|
||||
|
@ -725,8 +725,8 @@ That way, we can do a simple grep.
|
|||
var argsFirst = [];
|
||||
var argsRest = [];
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
argsFirst.push(args[i].first());
|
||||
argsRest.push(args[i].rest());
|
||||
argsFirst.push(args[i].first);
|
||||
argsRest.push(args[i].rest);
|
||||
}
|
||||
|
||||
return CALL(f, argsFirst,
|
||||
|
@ -1109,11 +1109,11 @@ That way, we can do a simple grep.
|
|||
|
||||
return CALL(new PrimProc('', 1, false, false,
|
||||
function(args) {
|
||||
return callWithValues(fList.first(), args);
|
||||
return callWithValues(fList.first, args);
|
||||
}),
|
||||
[x],
|
||||
function(result) {
|
||||
return composeHelp(result, fList.rest());
|
||||
return composeHelp(result, fList.rest);
|
||||
});
|
||||
}
|
||||
return new PrimProc('', 0, true, false,
|
||||
|
@ -2032,9 +2032,9 @@ That way, we can do a simple grep.
|
|||
var nextResult = parse(child);
|
||||
if (isString(nextResult) &&
|
||||
!result.isEmpty() &&
|
||||
isString(result.first())) {
|
||||
result = types.cons(result.first() + nextResult,
|
||||
result.rest());
|
||||
isString(result.first)) {
|
||||
result = types.cons(result.first + nextResult,
|
||||
result.rest);
|
||||
} else {
|
||||
result = types.cons(nextResult, result);
|
||||
}
|
||||
|
@ -2219,7 +2219,7 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, isPair, 'car', 'pair', 1);
|
||||
return lst.first();
|
||||
return lst.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['cdr'] =
|
||||
|
@ -2228,7 +2228,7 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function (lst) {
|
||||
check(lst, isPair, 'cdr', 'pair', 1);
|
||||
return lst.rest();
|
||||
return lst.rest;
|
||||
});
|
||||
|
||||
PRIMITIVES['caar'] =
|
||||
|
@ -2236,9 +2236,9 @@ That way, we can do a simple grep.
|
|||
1,
|
||||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return (isPair(x) && isPair(x.first())); },
|
||||
check(lst, function(x) { return (isPair(x) && isPair(x.first)); },
|
||||
'caar', 'caarable value', 1);
|
||||
return lst.first().first();
|
||||
return lst.first.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['cadr'] =
|
||||
|
@ -2246,9 +2246,9 @@ That way, we can do a simple grep.
|
|||
1,
|
||||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return isPair(x) && isPair(x.rest()); },
|
||||
check(lst, function(x) { return isPair(x) && isPair(x.rest); },
|
||||
'cadr', 'cadrable value', 1);
|
||||
return lst.rest().first();
|
||||
return lst.rest.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['cdar'] =
|
||||
|
@ -2256,9 +2256,9 @@ That way, we can do a simple grep.
|
|||
1,
|
||||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return isPair(x) && isPair(x.first()); },
|
||||
check(lst, function(x) { return isPair(x) && isPair(x.first); },
|
||||
'cdar', 'cdarable value', 1);
|
||||
return lst.first().rest();
|
||||
return lst.first.rest;
|
||||
});
|
||||
|
||||
PRIMITIVES['cddr'] =
|
||||
|
@ -2266,9 +2266,9 @@ That way, we can do a simple grep.
|
|||
1,
|
||||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return isPair(x) && isPair(x.rest()); },
|
||||
check(lst, function(x) { return isPair(x) && isPair(x.rest); },
|
||||
'cddr', 'cddrable value', 1);
|
||||
return lst.rest().rest();
|
||||
return lst.rest.rest;
|
||||
});
|
||||
|
||||
PRIMITIVES['caaar'] =
|
||||
|
@ -2277,10 +2277,10 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return ( isPair(x) &&
|
||||
isPair(x.first()) &&
|
||||
isPair(x.first().first()) ); },
|
||||
isPair(x.first) &&
|
||||
isPair(x.first.first) ); },
|
||||
'caaar', 'caaarable value', 1);
|
||||
return lst.first().first().first();
|
||||
return lst.first.first.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['caadr'] =
|
||||
|
@ -2289,10 +2289,10 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return ( isPair(x) &&
|
||||
isPair(x.rest()) &&
|
||||
isPair(x.rest().first()) ); },
|
||||
isPair(x.rest) &&
|
||||
isPair(x.rest.first) ); },
|
||||
'caadr', 'caadrable value', 1);
|
||||
return lst.rest().first().first();
|
||||
return lst.rest.first.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['cadar'] =
|
||||
|
@ -2301,10 +2301,10 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return ( isPair(x) &&
|
||||
isPair(x.first()) &&
|
||||
isPair(x.first().rest()) ); },
|
||||
isPair(x.first) &&
|
||||
isPair(x.first.rest) ); },
|
||||
'cadar', 'cadarable value', 1);
|
||||
return lst.first().rest().first();
|
||||
return lst.first.rest.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['cdaar'] =
|
||||
|
@ -2313,10 +2313,10 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return ( isPair(x) &&
|
||||
isPair(x.first()) &&
|
||||
isPair(x.first().first()) ); },
|
||||
isPair(x.first) &&
|
||||
isPair(x.first.first) ); },
|
||||
'cdaar', 'cdaarable value', 1);
|
||||
return lst.first().first().rest();
|
||||
return lst.first.first.rest;
|
||||
});
|
||||
|
||||
PRIMITIVES['cdadr'] =
|
||||
|
@ -2325,10 +2325,10 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return ( isPair(x) &&
|
||||
isPair(x.rest()) &&
|
||||
isPair(x.rest().first()) ); },
|
||||
isPair(x.rest) &&
|
||||
isPair(x.rest.first) ); },
|
||||
'cdadr', 'cdadrable value', 1);
|
||||
return lst.rest().first().rest();
|
||||
return lst.rest.first.rest;
|
||||
});
|
||||
|
||||
PRIMITIVES['cddar'] =
|
||||
|
@ -2337,10 +2337,10 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return ( isPair(x) &&
|
||||
isPair(x.first()) &&
|
||||
isPair(x.first().rest()) ); },
|
||||
isPair(x.first) &&
|
||||
isPair(x.first.rest) ); },
|
||||
'cddar', 'cddarable value', 1);
|
||||
return lst.first().rest().rest();
|
||||
return lst.first.rest.rest;
|
||||
});
|
||||
|
||||
PRIMITIVES['caddr'] =
|
||||
|
@ -2349,10 +2349,10 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return ( isPair(x) &&
|
||||
isPair(x.rest()) &&
|
||||
isPair(x.rest().rest()) ); },
|
||||
isPair(x.rest) &&
|
||||
isPair(x.rest.rest) ); },
|
||||
'caddr', 'caddrable value', 1);
|
||||
return lst.rest().rest().first();
|
||||
return lst.rest.rest.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['cdddr'] =
|
||||
|
@ -2361,10 +2361,10 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return ( isPair(x) &&
|
||||
isPair(x.rest()) &&
|
||||
isPair(x.rest().rest()) ); },
|
||||
isPair(x.rest) &&
|
||||
isPair(x.rest.rest) ); },
|
||||
'cdddr', 'cdddrable value', 1);
|
||||
return lst.rest().rest().rest();
|
||||
return lst.rest.rest.rest;
|
||||
});
|
||||
|
||||
PRIMITIVES['cadddr'] =
|
||||
|
@ -2373,11 +2373,11 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
check(lst, function(x) { return ( isPair(x) &&
|
||||
isPair(x.rest()) &&
|
||||
isPair(x.rest().rest()) &&
|
||||
isPair(x.rest().rest().rest()) ); },
|
||||
isPair(x.rest) &&
|
||||
isPair(x.rest.rest) &&
|
||||
isPair(x.rest.rest.rest) ); },
|
||||
'cadddr', 'cadddrable value', 1);
|
||||
return lst.rest().rest().rest().first();
|
||||
return lst.rest.rest.rest.first;
|
||||
});
|
||||
|
||||
|
||||
|
@ -2388,7 +2388,7 @@ That way, we can do a simple grep.
|
|||
function(lst) {
|
||||
check(lst, function(x) { return isList(x) && !isEmpty(x); },
|
||||
'rest', 'non-empty list', 1);
|
||||
return lst.rest();
|
||||
return lst.rest;
|
||||
});
|
||||
|
||||
PRIMITIVES['first'] =
|
||||
|
@ -2398,7 +2398,7 @@ That way, we can do a simple grep.
|
|||
function(lst) {
|
||||
check(lst, function(x) { return isList(x) && !isEmpty(x); },
|
||||
'first', 'non-empty list', 1);
|
||||
return lst.first();
|
||||
return lst.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['second'] =
|
||||
|
@ -2407,7 +2407,7 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
checkListOfLength(lst, 2, 'second', 1);
|
||||
return lst.rest().first();
|
||||
return lst.rest.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['third'] =
|
||||
|
@ -2416,7 +2416,7 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
checkListOfLength(lst, 3, 'third', 1);
|
||||
return lst.rest().rest().first();
|
||||
return lst.rest.rest.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['fourth'] =
|
||||
|
@ -2425,7 +2425,7 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
checkListOfLength(lst, 4, 'fourth', 1);
|
||||
return lst.rest().rest().rest().first();
|
||||
return lst.rest.rest.rest.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['fifth'] =
|
||||
|
@ -2434,7 +2434,7 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
checkListOfLength(lst, 5, 'fifth', 1);
|
||||
return lst.rest().rest().rest().rest().first();
|
||||
return lst.rest.rest.rest.rest.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['sixth'] =
|
||||
|
@ -2443,7 +2443,7 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
checkListOfLength(lst, 6, 'sixth', 1);
|
||||
return lst.rest().rest().rest().rest().rest().first();
|
||||
return lst.rest.rest.rest.rest.rest.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['seventh'] =
|
||||
|
@ -2453,7 +2453,7 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
checkListOfLength(lst, 7, 'seventh', 1);
|
||||
return lst.rest().rest().rest().rest().rest().rest().first();
|
||||
return lst.rest.rest.rest.rest.rest.rest.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['eighth'] =
|
||||
|
@ -2462,7 +2462,7 @@ That way, we can do a simple grep.
|
|||
false, false,
|
||||
function(lst) {
|
||||
checkListOfLength(lst, 8, 'eighth', 1);
|
||||
return lst.rest().rest().rest().rest().rest().rest().rest().first();
|
||||
return lst.rest.rest.rest.rest.rest.rest.rest.first;
|
||||
});
|
||||
|
||||
|
||||
|
@ -2536,7 +2536,7 @@ That way, we can do a simple grep.
|
|||
helpers.toDisplayedString(origList));
|
||||
raise( types.incompleteExn(types.exnFailContract, msg, []) );
|
||||
}
|
||||
lst = lst.rest();
|
||||
lst = lst.rest;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2548,7 +2548,7 @@ That way, we can do a simple grep.
|
|||
msg,
|
||||
[]) );
|
||||
}
|
||||
return lst.first();
|
||||
return lst.first;
|
||||
});
|
||||
|
||||
PRIMITIVES['list-tail'] =
|
||||
|
@ -2578,7 +2578,7 @@ That way, we can do a simple grep.
|
|||
helpers.toDisplayedString(origList));
|
||||
raise( types.incompleteExn(types.exnFailContract, msg, []) );
|
||||
}
|
||||
lst = lst.rest();
|
||||
lst = lst.rest;
|
||||
}
|
||||
return lst;
|
||||
});
|
||||
|
@ -2622,8 +2622,8 @@ That way, we can do a simple grep.
|
|||
var argsFirst = [];
|
||||
var argsRest = [];
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
argsFirst.push(args[i].first());
|
||||
argsRest.push(args[i].rest());
|
||||
argsFirst.push(args[i].first);
|
||||
argsRest.push(args[i].rest);
|
||||
}
|
||||
var result = CALL(f, argsFirst,
|
||||
function(result) {
|
||||
|
@ -2658,8 +2658,8 @@ That way, we can do a simple grep.
|
|||
var argsFirst = [];
|
||||
var argsRest = [];
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
argsFirst.push(args[i].first());
|
||||
argsRest.push(args[i].rest());
|
||||
argsFirst.push(args[i].first);
|
||||
argsRest.push(args[i].rest);
|
||||
}
|
||||
|
||||
return CALL(f, argsFirst,
|
||||
|
@ -2699,8 +2699,8 @@ That way, we can do a simple grep.
|
|||
var argsFirst = [];
|
||||
var argsRest = [];
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
argsFirst.push(args[i].first());
|
||||
argsRest.push(args[i].rest());
|
||||
argsFirst.push(args[i].first);
|
||||
argsRest.push(args[i].rest);
|
||||
}
|
||||
|
||||
return CALL(f, argsFirst,
|
||||
|
@ -2734,10 +2734,10 @@ That way, we can do a simple grep.
|
|||
}
|
||||
while ( !lst.isEmpty() ) {
|
||||
|
||||
if ( isEq(item, lst.first()) ) {
|
||||
if ( isEq(item, lst.first) ) {
|
||||
return lst;
|
||||
}
|
||||
lst = lst.rest();
|
||||
lst = lst.rest;
|
||||
if (! isPair(lst) && lst !== types.EMPTY) {
|
||||
var msg = ('memq: not a proper list: ' +
|
||||
helpers.toDisplayedString(origList));
|
||||
|
@ -2764,10 +2764,10 @@ That way, we can do a simple grep.
|
|||
[]) );
|
||||
}
|
||||
while ( !lst.isEmpty() ) {
|
||||
if ( isEqv(item, lst.first()) ) {
|
||||
if ( isEqv(item, lst.first) ) {
|
||||
return lst;
|
||||
}
|
||||
lst = lst.rest();
|
||||
lst = lst.rest;
|
||||
if (! isPair(lst) && lst !== types.EMPTY) {
|
||||
var msg = ('memv: not a proper list: ' +
|
||||
helpers.toDisplayedString(origList));
|
||||
|
@ -2795,10 +2795,10 @@ That way, we can do a simple grep.
|
|||
[]) );
|
||||
}
|
||||
while ( !lst.isEmpty() ) {
|
||||
if ( isEqual(item, lst.first()) ) {
|
||||
if ( isEqual(item, lst.first) ) {
|
||||
return lst;
|
||||
}
|
||||
lst = lst.rest();
|
||||
lst = lst.rest;
|
||||
|
||||
if (! isPair(lst) && lst !== types.EMPTY) {
|
||||
var msg = ('member: not a proper list: ' +
|
||||
|
@ -2825,12 +2825,12 @@ That way, we can do a simple grep.
|
|||
return false;
|
||||
}
|
||||
|
||||
return CALL(f, [lst.first()],
|
||||
return CALL(f, [lst.first],
|
||||
function(result) {
|
||||
if (result) {
|
||||
return lst;
|
||||
}
|
||||
return memfHelp(lst.rest());
|
||||
return memfHelp(lst.rest);
|
||||
});
|
||||
}
|
||||
return memfHelp(initList);
|
||||
|
@ -2852,18 +2852,18 @@ That way, we can do a simple grep.
|
|||
[]) );
|
||||
}
|
||||
while ( !lst.isEmpty() ) {
|
||||
if (! isPair(lst.first())) {
|
||||
if (! isPair(lst.first)) {
|
||||
var msg = ('assq: non-pair found in list: ' +
|
||||
helpers.toDisplayedString(lst.first()) +' in ' +
|
||||
helpers.toDisplayedString(lst.first) +' in ' +
|
||||
helpers.toDisplayedString(origList));
|
||||
raise( types.incompleteExn(types.exnFailContract,
|
||||
msg,
|
||||
[]) );
|
||||
}
|
||||
if ( isEq(item, lst.first().first()) ) {
|
||||
return lst.first();
|
||||
if ( isEq(item, lst.first.first) ) {
|
||||
return lst.first;
|
||||
}
|
||||
lst = lst.rest();
|
||||
lst = lst.rest;
|
||||
|
||||
if (! isPair(lst) && lst !== types.EMPTY) {
|
||||
var msg = ('assq: not a proper list: ' +
|
||||
|
@ -2892,18 +2892,18 @@ That way, we can do a simple grep.
|
|||
[]) );
|
||||
}
|
||||
while ( !lst.isEmpty() ) {
|
||||
if (! isPair(lst.first())) {
|
||||
if (! isPair(lst.first)) {
|
||||
var msg = ('assv: non-pair found in list: ' +
|
||||
helpers.toDisplayedString(lst.first()) +' in ' +
|
||||
helpers.toDisplayedString(lst.first) +' in ' +
|
||||
helpers.toDisplayedString(origList));
|
||||
raise( types.incompleteExn(types.exnFailContract,
|
||||
msg,
|
||||
[]) );
|
||||
}
|
||||
if ( isEqv(item, lst.first().first()) ) {
|
||||
return lst.first();
|
||||
if ( isEqv(item, lst.first.first) ) {
|
||||
return lst.first;
|
||||
}
|
||||
lst = lst.rest();
|
||||
lst = lst.rest;
|
||||
if (! isPair(lst) && lst !== types.EMPTY) {
|
||||
var msg = ('assv: not a proper list: ' +
|
||||
helpers.toDisplayedString(origList));
|
||||
|
@ -2931,18 +2931,18 @@ That way, we can do a simple grep.
|
|||
[]) );
|
||||
}
|
||||
while ( !lst.isEmpty() ) {
|
||||
if (! isPair(lst.first())) {
|
||||
if (! isPair(lst.first)) {
|
||||
var msg = ('assoc: non-pair found in list: ' +
|
||||
helpers.toDisplayedString(lst.first()) +' in ' +
|
||||
helpers.toDisplayedString(lst.first) +' in ' +
|
||||
helpers.toDisplayedString(origList));
|
||||
raise( types.incompleteExn(types.exnFailContract,
|
||||
msg,
|
||||
[]) );
|
||||
}
|
||||
if ( isEqual(item, lst.first().first()) ) {
|
||||
return lst.first();
|
||||
if ( isEqual(item, lst.first.first) ) {
|
||||
return lst.first;
|
||||
}
|
||||
lst = lst.rest();
|
||||
lst = lst.rest;
|
||||
|
||||
if (! isPair(lst) && lst !== types.EMPTY) {
|
||||
var msg = ('assoc: not a proper list: ' +
|
||||
|
@ -2965,11 +2965,11 @@ That way, we can do a simple grep.
|
|||
var originalLst = lst;
|
||||
var result = types.EMPTY;
|
||||
while ( !lst.isEmpty() ) {
|
||||
if ( isEqual(item, lst.first()) ) {
|
||||
return append([result.reverse(), lst.rest()]);
|
||||
if ( isEqual(item, lst.first) ) {
|
||||
return append([result.reverse(), lst.rest]);
|
||||
} else {
|
||||
result = types.cons(lst.first(), result);
|
||||
lst = lst.rest();
|
||||
result = types.cons(lst.first, result);
|
||||
lst = lst.rest;
|
||||
}
|
||||
}
|
||||
return originalLst;
|
||||
|
@ -2989,14 +2989,14 @@ That way, we can do a simple grep.
|
|||
return acc.reverse();
|
||||
}
|
||||
|
||||
return CALL(f, [lst.first()],
|
||||
return CALL(f, [lst.first],
|
||||
function(result) {
|
||||
if (result) {
|
||||
return filterHelp(f, lst.rest(),
|
||||
types.cons(lst.first(), acc));
|
||||
return filterHelp(f, lst.rest,
|
||||
types.cons(lst.first, acc));
|
||||
}
|
||||
else {
|
||||
return filterHelp(f, lst.rest(), acc);
|
||||
return filterHelp(f, lst.rest, acc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -3055,22 +3055,22 @@ That way, we can do a simple grep.
|
|||
return curMaxElt;
|
||||
}
|
||||
|
||||
return CALL(f, [lst.first()],
|
||||
return CALL(f, [lst.first],
|
||||
function(result) {
|
||||
check(result, isReal, 'argmax',
|
||||
'procedure that returns real numbers', 1, args);
|
||||
if (jsnums.greaterThan(result, curMaxVal)) {
|
||||
return argmaxHelp(lst.rest(), result, lst.first());
|
||||
return argmaxHelp(lst.rest, result, lst.first);
|
||||
}
|
||||
else {
|
||||
return argmaxHelp(lst.rest(), curMaxVal, curMaxElt);
|
||||
return argmaxHelp(lst.rest, curMaxVal, curMaxElt);
|
||||
}
|
||||
});
|
||||
}
|
||||
return CALL(f, [initList.first()],
|
||||
return CALL(f, [initList.first],
|
||||
function(result) {
|
||||
check(result, isReal, 'argmax', 'procedure that returns real numbers', 1, args);
|
||||
return argmaxHelp(initList.rest(), result, initList.first());
|
||||
return argmaxHelp(initList.rest, result, initList.first);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -3089,22 +3089,22 @@ That way, we can do a simple grep.
|
|||
return curMaxElt;
|
||||
}
|
||||
|
||||
return CALL(f, [lst.first()],
|
||||
return CALL(f, [lst.first],
|
||||
function(result) {
|
||||
check(result, isReal, 'argmin',
|
||||
'procedure that returns real numbers', 1, args);
|
||||
if (jsnums.lessThan(result, curMaxVal)) {
|
||||
return argminHelp(lst.rest(), result, lst.first());
|
||||
return argminHelp(lst.rest, result, lst.first);
|
||||
}
|
||||
else {
|
||||
return argminHelp(lst.rest(), curMaxVal, curMaxElt);
|
||||
return argminHelp(lst.rest, curMaxVal, curMaxElt);
|
||||
}
|
||||
});
|
||||
}
|
||||
return CALL(f, [initList.first()],
|
||||
return CALL(f, [initList.first],
|
||||
function(result) {
|
||||
check(result, isReal, 'argmin', 'procedure that returns real numbers', 1, args);
|
||||
return argminHelp(initList.rest(), result, initList.first());
|
||||
return argminHelp(initList.rest, result, initList.first);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -3614,8 +3614,8 @@ That way, we can do a simple grep.
|
|||
|
||||
var ret = [];
|
||||
while( !lst.isEmpty() ) {
|
||||
ret.push(lst.first().val);
|
||||
lst = lst.rest();
|
||||
ret.push(lst.first.val);
|
||||
lst = lst.rest;
|
||||
}
|
||||
return types.string(ret);
|
||||
});
|
||||
|
@ -3728,8 +3728,8 @@ That way, we can do a simple grep.
|
|||
'implode', 'list of 1-letter strings', 1);
|
||||
var ret = [];
|
||||
while ( !lst.isEmpty() ) {
|
||||
ret.push( lst.first().toString() );
|
||||
lst = lst.rest();
|
||||
ret.push( lst.first.toString() );
|
||||
lst = lst.rest;
|
||||
}
|
||||
return types.string(ret);
|
||||
});
|
||||
|
@ -4139,8 +4139,8 @@ That way, we can do a simple grep.
|
|||
|
||||
var ret = [];
|
||||
while ( !lst.isEmpty() ) {
|
||||
ret.push(lst.first());
|
||||
lst = lst.rest();
|
||||
ret.push(lst.first);
|
||||
lst = lst.rest;
|
||||
}
|
||||
return types.bytes(ret, true);
|
||||
});
|
||||
|
|
|
@ -8,16 +8,10 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
var runtime = {};
|
||||
scope['runtime'] = runtime;
|
||||
|
||||
var helpers = plt.helpers;
|
||||
var types = plt.types;
|
||||
|
||||
|
||||
// Type helpers
|
||||
//
|
||||
// Defines inheritance between prototypes.
|
||||
var heir = function(parentPrototype) {
|
||||
var f = function() {}
|
||||
f.prototype = parentPrototype;
|
||||
return new f();
|
||||
};
|
||||
|
||||
// Consumes a class and creates a predicate that recognizes subclasses.
|
||||
var makeClassPredicate = function(aClass) {
|
||||
|
@ -25,27 +19,35 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
};
|
||||
|
||||
|
||||
var isNumber = jsnums.isSchemeNumber;
|
||||
|
||||
var isNatural = function(x) { return (jsnums.isInteger(x) &&
|
||||
jsnums.greaterThanOrEqual(x, 0)); }
|
||||
|
||||
var isPair = function(x) { return (typeof(x) == 'object' &&
|
||||
x.length === 2 &&
|
||||
x.type !== 'vector') };
|
||||
var isList = function(x) {
|
||||
while (x !== NULL) {
|
||||
if (typeof(x) == 'object' && x.length === 2) {
|
||||
x = x[1];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
var isVector = function(x) { return (typeof(x) == 'object' &&
|
||||
x.type === 'vector') };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// We try to isolate the effect of external modules: all the identifiers we
|
||||
// pull from external modules should be listed here, and should otherwise not
|
||||
// show up outside this section!
|
||||
var isNumber = types.isNumber;
|
||||
var isNatural = types.isNatural;
|
||||
var isPair = types.isPair;
|
||||
var isList = types.isList;
|
||||
var isVector = types.isVector;
|
||||
var NULL = types.EMPTY;
|
||||
var VOID = types.VOID;
|
||||
|
||||
var makeVector = types.vector;
|
||||
var makeList = types.list;
|
||||
var makePair = types.pair;
|
||||
|
||||
var heir = helpers.heir;
|
||||
var toDomNode = helpers.toDomNode;
|
||||
var toWrittenString = helpers.toWrittenString;
|
||||
var toDisplayedString = helpers.toDisplayedString;
|
||||
//////////////////////////////////////////////////////////////////////]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// This value will be dynamically determined.
|
||||
|
@ -67,13 +69,25 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
|
||||
// currentDisplayer: DomNode -> Void
|
||||
// currentDisplayer is responsible for displaying to the browser.
|
||||
'currentDisplayer': function(v) {
|
||||
$(document.body).append(v);
|
||||
'currentDisplayer': function(MACHINE, domNode) {
|
||||
$(domNode).appendTo(document.body);
|
||||
},
|
||||
|
||||
// currentErrorDisplayer: DomNode -> Void
|
||||
// currentErrorDisplayer is responsible for displaying errors to the browser.
|
||||
'currentErrorDisplayer': function(MACHINE, domNode) {
|
||||
$(domNode).appendTo(document.body);
|
||||
},
|
||||
|
||||
|
||||
'currentOutputPort': new StandardOutputPort(),
|
||||
'currentErrorPort': new StandardErrorPort(),
|
||||
'currentSuccessHandler': function(MACHINE) {},
|
||||
'currentErrorHandler': function(MACHINE, exn) {},
|
||||
'currentErrorHandler': function(MACHINE, exn) {
|
||||
MACHINE.params.currentErrorDisplayer(
|
||||
MACHINE,
|
||||
exn);
|
||||
},
|
||||
|
||||
'currentNamespace': {},
|
||||
|
||||
|
@ -99,9 +113,9 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
var elt = MACHINE.env.pop();
|
||||
var outputPort =
|
||||
MACHINE.params.currentOutputPort;
|
||||
if (elt !== undefined) {
|
||||
outputPort.write(MACHINE, elt);
|
||||
outputPort.write(MACHINE, "\n");
|
||||
if (elt !== VOID) {
|
||||
outputPort.writeDomNode(MACHINE, toDomNode(elt, 'print'));
|
||||
outputPort.writeDomNode(MACHINE, toDomNode("\n", 'display'));
|
||||
}
|
||||
var frame = MACHINE.control.pop();
|
||||
return frame.label(MACHINE);
|
||||
|
@ -166,6 +180,9 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// A generic frame just holds marks.
|
||||
var Frame = function() {
|
||||
// The set of continuation marks.
|
||||
|
@ -218,31 +235,30 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Output Ports
|
||||
|
||||
var OutputPort = function() {};
|
||||
var isOutputPort = makeClassPredicate(OutputPort);
|
||||
|
||||
|
||||
var StandardOutputPort = function() {};
|
||||
StandardOutputPort.prototype = heir(OutputPort.prototype);
|
||||
StandardOutputPort.prototype.write = function(MACHINE, v) {
|
||||
var domNode;
|
||||
// TODO: v must be coerced into a DOMNode in a more systematic way.
|
||||
// This function may need to be a Closure.
|
||||
if(typeof(v) === 'string' ||
|
||||
typeof(v) === 'number' ||
|
||||
typeof(v) === 'boolean' ||
|
||||
typeof(v) === 'null' ||
|
||||
typeof(v) === 'undefined') {
|
||||
domNode = $('<span/>').text(String(v)).css('white-space', 'pre');
|
||||
} else {
|
||||
domNode = $('<span/>').text(String(v)).css('white-space', 'pre');
|
||||
}
|
||||
MACHINE.params['currentDisplayer'](domNode);
|
||||
var StandardOutputPort = function() {
|
||||
OutputPort.call(this);
|
||||
};
|
||||
StandardOutputPort.prototype = heir(OutputPort.prototype);
|
||||
StandardOutputPort.prototype.writeDomNode = function(MACHINE, domNode) {
|
||||
MACHINE.params['currentDisplayer'](MACHINE, domNode);
|
||||
};
|
||||
|
||||
var StandardErrorPort = function() {
|
||||
OutputPort.call(this);
|
||||
};
|
||||
StandardErrorPort.prototype = heir(OutputPort.prototype);
|
||||
StandardErrorPort.prototype.writeDomNode = function(MACHINE, domNode) {
|
||||
MACHINE.params['currentErrorDisplayer'](MACHINE, domNode);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -250,8 +266,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
this.buf = [];
|
||||
};
|
||||
OutputStringPort.prototype = heir(OutputPort.prototype);
|
||||
OutputStringPort.prototype.write = function(MACHINE, v) {
|
||||
this.buf.push(String(v));
|
||||
OutputStringPort.prototype.writeDomNode = function(MACHINE, v) {
|
||||
this.buf.push($(v).text());
|
||||
};
|
||||
OutputStringPort.prototype.getOutputString = function() {
|
||||
return this.buf.join('');
|
||||
|
@ -310,7 +326,6 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
new ContinuationPromptTag("default-continuation-prompt-tag");
|
||||
|
||||
|
||||
var NULL = [];
|
||||
|
||||
|
||||
var raise = function(MACHINE, e) {
|
||||
|
@ -348,7 +363,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
if (observed < minimum || observed > maximum) {
|
||||
raise(MACHINE, new Error(callerName + ": expected at least " + minimum
|
||||
+ " arguments "
|
||||
+ " but received " + observer));
|
||||
+ " but received " + observed));
|
||||
|
||||
}
|
||||
};
|
||||
|
@ -366,7 +381,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
raise(MACHINE,
|
||||
new Error(callerName + ": expected " + expectedTypeName
|
||||
+ " as argument " + (argumentOffset + 1)
|
||||
+ " but received " + actualValue));
|
||||
+ " but received " + helpers.toWrittenString(actualValue)));
|
||||
};
|
||||
|
||||
var raiseContextExpectedValuesError = function(MACHINE, expected) {
|
||||
|
@ -378,23 +393,23 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
|
||||
var raiseArityMismatchError = function(MACHINE, proc, expected, received) {
|
||||
raise(MACHINE,
|
||||
new Error("expected " + expected + " values, received " + received + " values"));
|
||||
new Error(proc.displayName + ": " + "expected " + expected
|
||||
+ " value(s), received " + received + " value(s)"));
|
||||
};
|
||||
|
||||
var raiseOperatorApplicationError = function(MACHINE, operator) {
|
||||
raise(MACHINE,
|
||||
new Error("not a procedure: " + expected +
|
||||
operator));
|
||||
new Error("not a procedure: " + helpers.toWrittenString(operator)));
|
||||
};
|
||||
|
||||
var raiseOperatorIsNotClosure = function(MACHINE, operator) {
|
||||
raise(MACHINE,
|
||||
new Error("not a closure: " + operator));
|
||||
new Error("not a closure: " + helpers.toWrittenString(operator)));
|
||||
};
|
||||
|
||||
var raiseOperatorIsNotPrimitiveProcedure = function(MACHINE, operator) {
|
||||
raise(MACHINE,
|
||||
new Error("not a primitive procedure: " + operator));
|
||||
new Error("not a primitive procedure: " + helpers.toWrittenString(operator)));
|
||||
};
|
||||
|
||||
|
||||
|
@ -448,8 +463,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
var lst = MACHINE.env[MACHINE.env.length - 1 - depth];
|
||||
var vals = [];
|
||||
while(lst !== NULL) {
|
||||
vals.push(lst[0]);
|
||||
lst = lst[1];
|
||||
vals.push(lst.first);
|
||||
lst = lst.rest;
|
||||
}
|
||||
vals.reverse();
|
||||
MACHINE.env.splice.apply(MACHINE.env,
|
||||
|
@ -462,7 +477,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
var lst = NULL;
|
||||
var i;
|
||||
for (i = 0; i < length; i++) {
|
||||
lst = [MACHINE.env[MACHINE.env.length - depth - length + i], lst];
|
||||
lst = makePair(MACHINE.env[MACHINE.env.length - depth - length + i],
|
||||
lst);
|
||||
}
|
||||
MACHINE.env.splice(MACHINE.env.length - depth - length,
|
||||
length,
|
||||
|
@ -488,12 +504,12 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
return n >= arity.value;
|
||||
} else {
|
||||
while (arity !== NULL) {
|
||||
if (typeof(arity[0]) === 'number') {
|
||||
if (arity[0] === n) { return true; }
|
||||
if (typeof(arity.first) === 'number') {
|
||||
if (arity.first === n) { return true; }
|
||||
} else if (arity instanceof ArityAtLeast) {
|
||||
if (n >= arity[0].value) { return true; }
|
||||
if (n >= arity.first.value) { return true; }
|
||||
}
|
||||
arity = arity[1];
|
||||
arity = arity.rest;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -508,129 +524,119 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
// are coded here; several of them (including call/cc) are injected by
|
||||
// the bootstrapping code.
|
||||
var Primitives = {};
|
||||
Primitives['display'] = function(MACHINE) {
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var outputPort = MACHINE.params.currentOutputPort;
|
||||
if (MACHINE.argcount === 2) {
|
||||
testArgument(MACHINE,
|
||||
'isOutputPort',
|
||||
isOutputPort,
|
||||
MACHINE.env.length-2,
|
||||
1,
|
||||
'display');
|
||||
outputPort = MACHINE.env[MACHINE.env.length-2];
|
||||
}
|
||||
outputPort.write(MACHINE, firstArg);
|
||||
|
||||
var installPrimitiveProcedure = function(name, arity, f) {
|
||||
Primitives[name] = f;
|
||||
Primitives[name].arity = arity;
|
||||
Primitives[name].displayName = name;
|
||||
};
|
||||
Primitives['display'].arity = [1, [2, NULL]];
|
||||
Primitives['display'].displayName = 'display';
|
||||
|
||||
|
||||
Primitives['newline'] = function(MACHINE) {
|
||||
var outputPort = MACHINE.params.currentOutputPort;
|
||||
if (MACHINE.argcount === 1) {
|
||||
testArgument(MACHINE,
|
||||
'isOutputPort',
|
||||
isOutputPort,
|
||||
MACHINE.env.length-1,
|
||||
1,
|
||||
'newline');
|
||||
outputPort = MACHINE.env[MACHINE.env.length-1];
|
||||
}
|
||||
outputPort.write(MACHINE, "\n");
|
||||
var makePrimitiveProcedure = function(name, arity, f) {
|
||||
f.arity = arity;
|
||||
f.displayName = name;
|
||||
return f;
|
||||
};
|
||||
Primitives['newline'].arity = [0, [1, NULL]];
|
||||
Primitives['newline'].displayName = 'newline';
|
||||
|
||||
|
||||
Primitives['displayln'] = function(MACHINE){
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var outputPort = MACHINE.params.currentOutputPort;
|
||||
if (MACHINE.argcount === 2) {
|
||||
testArgument(MACHINE,
|
||||
'isOutputPort',
|
||||
isOutputPort,
|
||||
MACHINE.env.length-2,
|
||||
1,
|
||||
'displayln');
|
||||
outputPort = MACHINE.env[MACHINE.env.length-2];
|
||||
}
|
||||
outputPort.write(MACHINE, firstArg);
|
||||
outputPort.write(MACHINE, "\n");
|
||||
var installPrimitiveConstant = function(name, v) {
|
||||
Primitives[name] = v;
|
||||
};
|
||||
Primitives['displayln'].arity = [1, [2, NULL]];
|
||||
Primitives['displayln'].displayName = 'displayln';
|
||||
|
||||
|
||||
installPrimitiveConstant('pi', jsnums.pi);
|
||||
installPrimitiveConstant('e', jsnums.e);
|
||||
|
||||
Primitives['current-print'] = function(MACHINE) {
|
||||
return MACHINE.params['current-print'];
|
||||
};
|
||||
Primitives['current-print'].arity = [0, [1, NULL]];
|
||||
Primitives['current-print'].displayName = "current-print";
|
||||
|
||||
|
||||
// // This should be attached to the module corresponding for print-values
|
||||
// Primitives['print-values'] = new Closure(
|
||||
// function(MACHINE) {
|
||||
// var outputPort = MACHINE.params.currentOutputPort;
|
||||
// var prependNewline = false;
|
||||
// if (MACHINE.argcount > 0) {
|
||||
// if (MACHINE.val !== undefined) {
|
||||
// if (prependNewline) {
|
||||
// outputPort.write(MACHINE, "\n");
|
||||
// }
|
||||
// outputPort.write(MACHINE, MACHINE.val);
|
||||
// prependNewline = true;
|
||||
// }
|
||||
|
||||
// for(var i = 0; i < MACHINE.argcount - 1; i++) {
|
||||
// if (MACHINE.env[MACHINE.env.length - 1 - i] !== undefined) {
|
||||
// if (prependNewline) {
|
||||
// outputPort.write(MACHINE, "\n");
|
||||
// }
|
||||
// outputPort.write(MACHINE,
|
||||
// MACHINE.env[MACHINE.env.length - 1 - i]);
|
||||
// prependNewline = true;
|
||||
// }
|
||||
// }
|
||||
// outputPort.write(MACHINE, "\n");
|
||||
// }
|
||||
// MACHINE.env.length = MACHINE.env.length - MACHINE.argcount;
|
||||
// var frame = MACHINE.control.pop();
|
||||
// return frame.label(MACHINE);
|
||||
// },
|
||||
// new ArityAtLeast(0),
|
||||
// [],
|
||||
// "print-values"
|
||||
// );
|
||||
|
||||
|
||||
|
||||
Primitives['pi'] = jsnums.pi;
|
||||
|
||||
Primitives['e'] = jsnums.e;
|
||||
|
||||
Primitives['='] = function(MACHINE) {
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
testArgument(MACHINE, 'number', isNumber, firstArg, 0, '=');
|
||||
for (var i = 0; i < MACHINE.argcount - 1; i++) {
|
||||
testArgument(MACHINE,
|
||||
'number',
|
||||
isNumber,
|
||||
MACHINE.env[MACHINE.env.length - 1 - i],
|
||||
i,
|
||||
'=');
|
||||
if (! (jsnums.equals(MACHINE.env[MACHINE.env.length - 1 - i],
|
||||
MACHINE.env[MACHINE.env.length - 1 - i - 1]))) {
|
||||
return false;
|
||||
installPrimitiveProcedure(
|
||||
'display', makeList(1, 2),
|
||||
function(MACHINE) {
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var outputPort = MACHINE.params.currentOutputPort;
|
||||
if (MACHINE.argcount === 2) {
|
||||
testArgument(MACHINE,
|
||||
'isOutputPort',
|
||||
isOutputPort,
|
||||
MACHINE.env.length-2,
|
||||
1,
|
||||
'display');
|
||||
outputPort = MACHINE.env[MACHINE.env.length-2];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
Primitives['='].arity = new ArityAtLeast(2);
|
||||
Primitives['='].displayName = '=';
|
||||
outputPort.writeDomNode(MACHINE, toDomNode(firstArg, 'display'));
|
||||
return VOID;
|
||||
});
|
||||
|
||||
installPrimitiveProcedure(
|
||||
'newline', makeList(0, 1),
|
||||
function(MACHINE) {
|
||||
var outputPort = MACHINE.params.currentOutputPort;
|
||||
if (MACHINE.argcount === 1) {
|
||||
testArgument(MACHINE,
|
||||
'isOutputPort',
|
||||
isOutputPort,
|
||||
MACHINE.env.length-1,
|
||||
1,
|
||||
'newline');
|
||||
outputPort = MACHINE.env[MACHINE.env.length-1];
|
||||
}
|
||||
outputPort.writeDomNode(MACHINE, toDomNode("\n", 'display'));
|
||||
return VOID;
|
||||
});
|
||||
|
||||
installPrimitiveProcedure(
|
||||
'displayln',
|
||||
makeList(1, 2),
|
||||
function(MACHINE){
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var outputPort = MACHINE.params.currentOutputPort;
|
||||
if (MACHINE.argcount === 2) {
|
||||
testArgument(MACHINE,
|
||||
'isOutputPort',
|
||||
isOutputPort,
|
||||
MACHINE.env.length-2,
|
||||
1,
|
||||
'displayln');
|
||||
outputPort = MACHINE.env[MACHINE.env.length-2];
|
||||
}
|
||||
outputPort.writeDomNode(MACHINE, toDomNode(firstArg, 'display'));
|
||||
outputPort.writeDomNode(MACHINE, toDomNode("\n", 'display'));
|
||||
return VOID;
|
||||
});
|
||||
|
||||
|
||||
installPrimitiveProcedure(
|
||||
'current-print',
|
||||
makeList(0, 1),
|
||||
function(MACHINE) {
|
||||
if (MACHINE.argcount === 1) {
|
||||
MACHINE.params['current-print'] = MACHINE.env[MACHINE.env.length - 1];
|
||||
return VOID;
|
||||
} else {
|
||||
return MACHINE.params['current-print'];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
installPrimitiveProcedure(
|
||||
'=',
|
||||
new ArityAtLeast(2),
|
||||
function(MACHINE) {
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
testArgument(MACHINE, 'number', isNumber, firstArg, 0, '=');
|
||||
for (var i = 0; i < MACHINE.argcount - 1; i++) {
|
||||
testArgument(MACHINE,
|
||||
'number',
|
||||
isNumber,
|
||||
MACHINE.env[MACHINE.env.length - 1 - i],
|
||||
i,
|
||||
'=');
|
||||
if (! (jsnums.equals(MACHINE.env[MACHINE.env.length - 1 - i],
|
||||
MACHINE.env[MACHINE.env.length - 1 - i - 1]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
// TODO: use installPrimitiveProcedure for the rest...
|
||||
|
||||
Primitives['<'] = function(MACHINE) {
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
|
@ -845,7 +851,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
Primitives['cons'] = function(MACHINE) {
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var secondArg = MACHINE.env[MACHINE.env.length-2];
|
||||
return [firstArg, secondArg];
|
||||
return makePair(firstArg, secondArg);
|
||||
};
|
||||
Primitives['cons'].arity = 2;
|
||||
Primitives['cons'].displayName = 'cons';
|
||||
|
@ -854,8 +860,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
Primitives['list'] = function(MACHINE) {
|
||||
var result = NULL;
|
||||
for (var i = 0; i < MACHINE.argcount; i++) {
|
||||
result = [MACHINE.env[MACHINE.env.length - (MACHINE.argcount - i)],
|
||||
result];
|
||||
result = makePair(MACHINE.env[MACHINE.env.length - (MACHINE.argcount - i)],
|
||||
result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
@ -870,7 +876,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
0,
|
||||
'car');
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
return firstArg[0];
|
||||
return firstArg.first;
|
||||
};
|
||||
Primitives['car'].arity = 1;
|
||||
Primitives['car'].displayName = 'car';
|
||||
|
@ -883,7 +889,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
0,
|
||||
'cdr');
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
return firstArg[1];
|
||||
return firstArg.rest;
|
||||
};
|
||||
Primitives['cdr'].arity = 1;
|
||||
Primitives['cdr'].displayName = 'cdr';
|
||||
|
@ -904,7 +910,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
'set-car!');
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var secondArg = MACHINE.env[MACHINE.env.length-2];
|
||||
firstArg[0] = secondArg;
|
||||
firstArg.first = secondArg;
|
||||
return VOID;
|
||||
};
|
||||
Primitives['set-car!'].arity = 2;
|
||||
Primitives['set-car!'].displayName = 'set-car!';
|
||||
|
@ -918,7 +925,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
'set-cdr!');
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var secondArg = MACHINE.env[MACHINE.env.length-2];
|
||||
firstArg[1] = secondArg;
|
||||
firstArg.rest = secondArg;
|
||||
return VOID;
|
||||
};
|
||||
Primitives['set-cdr!'].arity = 2;
|
||||
Primitives['set-cdr!'].displayName = 'set-cdr!';
|
||||
|
@ -945,8 +953,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
for (i = 0; i < MACHINE.argcount; i++) {
|
||||
result.push(MACHINE.env[MACHINE.env.length-1-i]);
|
||||
}
|
||||
result.type = 'vector';
|
||||
return result;
|
||||
var newVector = makeVector.apply(null, result);
|
||||
return newVector;
|
||||
};
|
||||
Primitives['vector'].arity = new ArityAtLeast(0);
|
||||
Primitives['vector'].displayName = 'vector';
|
||||
|
@ -958,11 +966,11 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
MACHINE.env[MACHINE.env.length - 1],
|
||||
0,
|
||||
'vector->list');
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var elts = MACHINE.env[MACHINE.env.length-1].elts;
|
||||
var i;
|
||||
var result = NULL;
|
||||
for (i = 0; i < firstArg.length; i++) {
|
||||
result = [firstArg[firstArg.length - 1 - i], result];
|
||||
for (i = 0; i < elts.length; i++) {
|
||||
result = makePair(elts[elts.length - 1 - i], result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
@ -973,11 +981,10 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var result = [];
|
||||
while (firstArg !== NULL) {
|
||||
result.push(firstArg[0]);
|
||||
firstArg = firstArg[1];
|
||||
result.push(firstArg.first);
|
||||
firstArg = firstArg.rest;
|
||||
}
|
||||
result.type='vector';
|
||||
return result;
|
||||
return makeVector.apply(null, result);
|
||||
};
|
||||
Primitives['list->vector'].arity = 1;
|
||||
Primitives['list->vector'].displayName = 'list->vector';
|
||||
|
@ -989,9 +996,9 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
MACHINE.env[MACHINE.env.length - 1],
|
||||
0,
|
||||
'vector-ref');
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var secondArg = MACHINE.env[MACHINE.env.length-2];
|
||||
return firstArg[secondArg];
|
||||
var elts = MACHINE.env[MACHINE.env.length-1].elts;
|
||||
var index = MACHINE.env[MACHINE.env.length-2];
|
||||
return elts[index];
|
||||
};
|
||||
Primitives['vector-ref'].arity = 2;
|
||||
Primitives['vector-ref'].displayName = 'vector-ref';
|
||||
|
@ -1003,11 +1010,17 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
MACHINE.env[MACHINE.env.length - 1],
|
||||
0,
|
||||
'vector-set!');
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var secondArg = jsnums.toFixnum(MACHINE.env[MACHINE.env.length-2]);
|
||||
var thirdArg = MACHINE.env[MACHINE.env.length-3];
|
||||
firstArg[secondArg] = thirdArg;
|
||||
return null;
|
||||
testArgument(MACHINE,
|
||||
'natural',
|
||||
isNatural,
|
||||
MACHINE.env[MACHINE.env.length - 2],
|
||||
1,
|
||||
'vector-set!');
|
||||
var elts = MACHINE.env[MACHINE.env.length-1].elts;
|
||||
var index = jsnums.toFixnum(MACHINE.env[MACHINE.env.length-2]);
|
||||
var val = MACHINE.env[MACHINE.env.length-3];
|
||||
elts[index] = val;
|
||||
return VOID;
|
||||
};
|
||||
Primitives['vector-set!'].arity = 3;
|
||||
Primitives['vector-set!'].displayName = 'vector-set!';
|
||||
|
@ -1020,7 +1033,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
MACHINE.env[MACHINE.env.length - 1],
|
||||
0,
|
||||
'vector-length');
|
||||
var firstArg = MACHINE.env[jsnums.toFixnum(MACHINE.env.length-1)];
|
||||
var firstArg = MACHINE.env[MACHINE.env.length-1].elts;
|
||||
return firstArg.length;
|
||||
};
|
||||
Primitives['vector-length'].arity = 1;
|
||||
|
@ -1043,10 +1056,9 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
for(var i = 0; i < length; i++) {
|
||||
arr[i] = value;
|
||||
}
|
||||
arr.type='vector';
|
||||
return arr;
|
||||
return makeVector.apply(null, arr);
|
||||
};
|
||||
Primitives['make-vector'].arity = [1, [2, NULL]];
|
||||
Primitives['make-vector'].arity = makeList(1, 2);
|
||||
Primitives['make-vector'].displayName = 'make-vector';
|
||||
|
||||
|
||||
|
@ -1104,13 +1116,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||
var secondArg = MACHINE.env[MACHINE.env.length-2];
|
||||
firstArg[0] = secondArg;
|
||||
return;
|
||||
return VOID;
|
||||
};
|
||||
Primitives['set-box!'].arity = 2;
|
||||
Primitives['set-box!'].displayName = 'set-box!';
|
||||
|
||||
Primitives['void'] = function(MACHINE) {
|
||||
return;
|
||||
return VOID;
|
||||
};
|
||||
Primitives['void'].arity = new ArityAtLeast(0);
|
||||
Primitives['void'].displayName = 'void';
|
||||
|
@ -1132,27 +1144,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
Primitives['equal?'].displayName = 'equal?';
|
||||
|
||||
|
||||
|
||||
var isEqual = function(firstArg, secondArg) {
|
||||
var lset = [firstArg], rset = [secondArg];
|
||||
while (lset.length !== 0 && rset.length !== 0) {
|
||||
var lhs = lset.pop();
|
||||
var rhs = rset.pop();
|
||||
if (lhs === rhs) {
|
||||
continue;
|
||||
} else if (typeof(lhs) === 'object' &&
|
||||
typeof(rhs) === 'object' &&
|
||||
typeof(lhs.length) === 'number' &&
|
||||
typeof(rhs.length) === 'number' &&
|
||||
lhs.length === rhs.length) {
|
||||
lset.push.apply(lset, lhs);
|
||||
rset.push.apply(rset, rhs);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
var isEqual = types.isEqual;
|
||||
|
||||
|
||||
Primitives['member'] = function(MACHINE) {
|
||||
|
@ -1168,10 +1160,10 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
if (lst === NULL) {
|
||||
return false;
|
||||
}
|
||||
if (isEqual(x, (lst[0]))) {
|
||||
if (isEqual(x, (lst.first))) {
|
||||
return lst;
|
||||
}
|
||||
lst = lst[1];
|
||||
lst = lst.rest;
|
||||
}
|
||||
};
|
||||
Primitives['member'].arity = 2;
|
||||
|
@ -1185,8 +1177,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
while(lst !== NULL) {
|
||||
testArgument(MACHINE,
|
||||
'pair', isPair, lst, 0, 'reverse');
|
||||
rev = [lst[0], rev];
|
||||
lst = lst[1];
|
||||
rev = makePair(lst.first, rev);
|
||||
lst = lst.rest;
|
||||
}
|
||||
return rev;
|
||||
};
|
||||
|
@ -1198,6 +1190,30 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
|
||||
|
||||
|
||||
// Extensions. A small experiment.
|
||||
installPrimitiveProcedure(
|
||||
'viewport-width',
|
||||
0,
|
||||
function(MACHINE) {
|
||||
return $(window).width();
|
||||
});
|
||||
|
||||
installPrimitiveProcedure(
|
||||
'viewport-height',
|
||||
0,
|
||||
function(MACHINE) {
|
||||
return $(window).height();
|
||||
});
|
||||
|
||||
|
||||
installPrimitiveProcedure(
|
||||
'in-javascript-context?',
|
||||
0,
|
||||
function(MACHINE) {
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
// recomputeGas: state number -> number
|
||||
|
@ -1379,6 +1395,10 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
exports['currentMachine'] = new Machine();
|
||||
exports['invokeMains'] = invokeMains;
|
||||
|
||||
|
||||
// installing new primitives
|
||||
exports['installPrimitiveProcedure'] = installPrimitiveProcedure;
|
||||
exports['makePrimitiveProcedure'] = makePrimitiveProcedure;
|
||||
exports['Primitives'] = Primitives;
|
||||
|
||||
exports['ready'] = ready;
|
||||
|
@ -1398,6 +1418,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
exports['DEFAULT_CONTINUATION_PROMPT_TAG'] =
|
||||
DEFAULT_CONTINUATION_PROMPT_TAG;
|
||||
exports['NULL'] = NULL;
|
||||
exports['VOID'] = VOID;
|
||||
|
||||
exports['testArgument'] = testArgument;
|
||||
exports['testArity'] = testArity;
|
||||
|
@ -1423,6 +1444,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
exports['unspliceRestFromStack'] = unspliceRestFromStack;
|
||||
|
||||
|
||||
// Type predicates
|
||||
exports['isNumber'] = isNumber;
|
||||
exports['isNatural'] = isNatural;
|
||||
exports['isPair'] = isPair;
|
||||
|
@ -1432,6 +1454,17 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
exports['isOutputStringPort'] = isOutputStringPort;
|
||||
exports['isEqual'] = isEqual;
|
||||
|
||||
exports['toDomNode'] = toDomNode;
|
||||
exports['toWrittenString'] = toWrittenString;
|
||||
exports['toDisplayedString'] = toDisplayedString;
|
||||
|
||||
|
||||
// Type constructors
|
||||
exports['makeList'] = makeList;
|
||||
exports['makePair'] = makePair;
|
||||
exports['makeVector'] = makeVector;
|
||||
|
||||
|
||||
exports['ArityAtLeast'] = ArityAtLeast;
|
||||
exports['isArityMatching'] = isArityMatching;
|
||||
|
||||
|
@ -1441,5 +1474,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
|
|||
exports['HaltError'] = HaltError;
|
||||
|
||||
|
||||
|
||||
|
||||
scope.link.announceReady('runtime');
|
||||
})(this['plt']);
|
|
@ -47,8 +47,6 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
// Union/find for circular equality testing.
|
||||
|
||||
var UnionFind = function() {
|
||||
|
@ -85,7 +83,7 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
StructType = function(name, type, numberOfArgs, numberOfFields, firstField,
|
||||
var StructType = function(name, type, numberOfArgs, numberOfFields, firstField,
|
||||
applyGuard, constructor, predicate, accessor, mutator) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
|
@ -698,17 +696,24 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
return b;
|
||||
};
|
||||
|
||||
Cons = function(f, r) {
|
||||
this.f = f;
|
||||
this.r = r;
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Cons Pairs
|
||||
|
||||
var Cons = function(f, r) {
|
||||
this.first = f;
|
||||
this.rest = r;
|
||||
};
|
||||
|
||||
Cons.prototype.reverse = function() {
|
||||
var lst = this;
|
||||
var ret = Empty.EMPTY;
|
||||
while (!lst.isEmpty()){
|
||||
ret = Cons.makeInstance(lst.first(), ret);
|
||||
lst = lst.rest();
|
||||
ret = Cons.makeInstance(lst.first, ret);
|
||||
lst = lst.rest;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
@ -717,28 +722,21 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
return new Cons(f, r);
|
||||
};
|
||||
|
||||
|
||||
// FIXME: can we reduce the recursion on this?
|
||||
Cons.prototype.isEqual = function(other, aUnionFind) {
|
||||
if (! (other instanceof Cons)) {
|
||||
return Logic.FALSE;
|
||||
}
|
||||
return (isEqual(this.first(), other.first(), aUnionFind) &&
|
||||
isEqual(this.rest(), other.rest(), aUnionFind));
|
||||
};
|
||||
|
||||
Cons.prototype.first = function() {
|
||||
return this.f;
|
||||
};
|
||||
|
||||
Cons.prototype.rest = function() {
|
||||
return this.r;
|
||||
return (isEqual(this.first, other.first, aUnionFind) &&
|
||||
isEqual(this.rest, other.rest, aUnionFind));
|
||||
};
|
||||
|
||||
|
||||
Cons.prototype.isEmpty = function() {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
// Cons.append: (listof X) -> (listof X)
|
||||
Cons.prototype.append = function(b){
|
||||
if (b === Empty.EMPTY)
|
||||
|
@ -746,8 +744,8 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
var ret = b;
|
||||
var lst = this.reverse();
|
||||
while ( !lst.isEmpty() ) {
|
||||
ret = Cons.makeInstance(lst.first(), ret);
|
||||
lst = lst.rest();
|
||||
ret = Cons.makeInstance(lst.first, ret);
|
||||
lst = lst.rest;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -759,8 +757,8 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
var texts = [];
|
||||
var p = this;
|
||||
while ( p instanceof Cons ) {
|
||||
texts.push(toWrittenString(p.first(), cache));
|
||||
p = p.rest();
|
||||
texts.push(toWrittenString(p.first, cache));
|
||||
p = p.rest;
|
||||
if (typeof(p) === 'object' && cache.containsKey(p)) {
|
||||
break;
|
||||
}
|
||||
|
@ -779,8 +777,8 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
var texts = [];
|
||||
var p = this;
|
||||
while ( p instanceof Cons ) {
|
||||
texts.push(toDisplayedString(p.first(), cache));
|
||||
p = p.rest();
|
||||
texts.push(toDisplayedString(p.first, cache));
|
||||
p = p.rest;
|
||||
if (typeof(p) === 'object' && cache.containsKey(p)) {
|
||||
break;
|
||||
}
|
||||
|
@ -789,17 +787,6 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
texts.push('.');
|
||||
texts.push(toDisplayedString(p, cache));
|
||||
}
|
||||
// while (true) {
|
||||
// if ((!(p instanceof Cons)) && (!(p instanceof Empty))) {
|
||||
// texts.push(".");
|
||||
// texts.push(toDisplayedString(p, cache));
|
||||
// break;
|
||||
// }
|
||||
// if (p.isEmpty())
|
||||
// break;
|
||||
// texts.push(toDisplayedString(p.first(), cache));
|
||||
// p = p.rest();
|
||||
// }
|
||||
return "(" + texts.join(" ") + ")";
|
||||
};
|
||||
|
||||
|
@ -811,8 +798,8 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
node.appendChild(document.createTextNode("("));
|
||||
var p = this;
|
||||
while ( p instanceof Cons ) {
|
||||
appendChild(node, toDomNode(p.first(), cache));
|
||||
p = p.rest();
|
||||
appendChild(node, toDomNode(p.first, cache));
|
||||
p = p.rest;
|
||||
if ( p !== Empty.EMPTY ) {
|
||||
appendChild(node, document.createTextNode(" "));
|
||||
}
|
||||
|
@ -825,27 +812,27 @@ if (! this['plt']) { this['plt'] = {}; }
|
|||
appendChild(node, document.createTextNode(" "));
|
||||
appendChild(node, toDomNode(p, cache));
|
||||
}
|
||||
// while (true) {
|
||||
// if ((!(p instanceof Cons)) && (!(p instanceof Empty))) {
|
||||
// appendChild(node, document.createTextNode(" "));
|
||||
// appendChild(node, document.createTextNode("."));
|
||||
// appendChild(node, document.createTextNode(" "));
|
||||
// appendChild(node, toDomNode(p, cache));
|
||||
// break;
|
||||
// }
|
||||
// if (p.isEmpty())
|
||||
// break;
|
||||
// appendChild(node, toDomNode(p.first(), cache));
|
||||
// p = p.rest();
|
||||
// if (! p.isEmpty()) {
|
||||
// appendChild(node, document.createTextNode(" "));
|
||||
// }
|
||||
// }
|
||||
|
||||
node.appendChild(document.createTextNode(")"));
|
||||
return node;
|
||||
};
|
||||
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1955,22 +1942,22 @@ String.prototype.toDisplayedString = function(cache) {
|
|||
|
||||
|
||||
|
||||
var makeList = function(args) {
|
||||
var makeList = function() {
|
||||
var result = Empty.EMPTY;
|
||||
for(var i = args.length-1; i >= 0; i--) {
|
||||
result = Cons.makeInstance(args[i], result);
|
||||
for(var i = arguments.length-1; i >= 0; i--) {
|
||||
result = Cons.makeInstance(arguments[i], result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
var makeVector = function(args) {
|
||||
return Vector.makeInstance(args.length, args);
|
||||
var makeVector = function() {
|
||||
return Vector.makeInstance(arguments.length, arguments);
|
||||
};
|
||||
|
||||
|
||||
var makeVectorImmutable = function(args) {
|
||||
var v = Vector.makeInstance(args.length, args);
|
||||
var makeVectorImmutable = function() {
|
||||
var v = Vector.makeInstance(arguments.length, arguments);
|
||||
v.mutable = false;
|
||||
return v;
|
||||
};
|
||||
|
@ -1996,27 +1983,27 @@ String.prototype.toDisplayedString = function(cache) {
|
|||
' given ' + s.toString(),
|
||||
false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var makeHashEq = function(lst) {
|
||||
var newHash = new EqHashTable();
|
||||
while ( !lst.isEmpty() ) {
|
||||
newHash.hash.put(lst.first().first(), lst.first().rest());
|
||||
lst = lst.rest();
|
||||
newHash.hash.put(lst.first.first, lst.first.rest);
|
||||
lst = lst.rest;
|
||||
}
|
||||
return newHash;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var makeHashEqual = function(lst) {
|
||||
var newHash = new EqualHashTable();
|
||||
while ( !lst.isEmpty() ) {
|
||||
newHash.hash.put(lst.first().first(), lst.first().rest());
|
||||
lst = lst.rest();
|
||||
newHash.hash.put(lst.first.first, lst.first.rest);
|
||||
lst = lst.rest;
|
||||
}
|
||||
return newHash;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var Color = makeStructureType('color', false, 3, 0, false, false);
|
||||
|
@ -2042,10 +2029,10 @@ String.prototype.toDisplayedString = function(cache) {
|
|||
}
|
||||
|
||||
if (types.isPair(x)) {
|
||||
var consPair = types.cons(x.first(), x.rest());
|
||||
var consPair = types.cons(x.first, x.rest);
|
||||
objectHash.put(x, consPair);
|
||||
consPair.f = readerGraph(x.first(), objectHash, n+1);
|
||||
consPair.r = readerGraph(x.rest(), objectHash, n+1);
|
||||
consPair.f = readerGraph(x.first, objectHash, n+1);
|
||||
consPair.r = readerGraph(x.rest, objectHash, n+1);
|
||||
return consPair;
|
||||
}
|
||||
|
||||
|
@ -2071,7 +2058,7 @@ String.prototype.toDisplayedString = function(cache) {
|
|||
}
|
||||
|
||||
if (types.isStruct(x)) {
|
||||
var aStruct = clone(x);
|
||||
var aStruct = helpers.clone(x);
|
||||
objectHash.put(x, aStruct);
|
||||
for(var i = 0 ;i < x._fields.length; i++) {
|
||||
x._fields[i] = readerGraph(x._fields[i], objectHash, n+1);
|
||||
|
@ -2088,22 +2075,6 @@ String.prototype.toDisplayedString = function(cache) {
|
|||
|
||||
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -2170,6 +2141,7 @@ String.prototype.toDisplayedString = function(cache) {
|
|||
types.isChar = function(x) { return x instanceof 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 Box; };
|
||||
|
|
3
js.rkt
Normal file
3
js.rkt
Normal file
|
@ -0,0 +1,3 @@
|
|||
#lang s-exp "lang/base.rkt"
|
||||
(require "js/main.rkt")
|
||||
(provide (all-from-out "js/main.rkt"))
|
36
js/js-impl.js
Normal file
36
js/js-impl.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
EXPORTS['alert'] =
|
||||
RUNTIME.makePrimitiveProcedure(
|
||||
'is-color?',
|
||||
1,
|
||||
function(MACHINE) {
|
||||
var elt = MACHINE.env[MACHINE.env.length - 1];
|
||||
alert(String(elt));
|
||||
return RUNTIME.VOID;
|
||||
});
|
||||
|
||||
|
||||
EXPORTS['body'] = $(document.body);
|
||||
|
||||
EXPORTS['$'] =
|
||||
RUNTIME.makePrimitiveProcedure(
|
||||
'$',
|
||||
1,
|
||||
function(MACHINE) {
|
||||
var obj = MACHINE.env[MACHINE.env.length - 1];
|
||||
return $(obj);
|
||||
});
|
||||
|
||||
EXPORTS['call'] =
|
||||
RUNTIME.makePrimitiveProcedure(
|
||||
'call',
|
||||
new RUNTIME.ArityAtLeast(2),
|
||||
function(MACHINE) {
|
||||
var obj = MACHINE.env[MACHINE.env.length - 1];
|
||||
var methodName = MACHINE.env[MACHINE.env.length - 2];
|
||||
var args = [];
|
||||
for (var i = 0; i < MACHINE.argcount - 2; i++) {
|
||||
args.push(MACHINE.env[MACHINE.env.length -1 - 2 - i]);
|
||||
}
|
||||
var result = obj[methodName].apply(obj, args);
|
||||
return result;
|
||||
});
|
9
js/main.rkt
Normal file
9
js/main.rkt
Normal file
|
@ -0,0 +1,9 @@
|
|||
#lang s-exp "../lang/js/js.rkt"
|
||||
|
||||
(declare-implementation
|
||||
#:racket "racket-impl.rkt"
|
||||
#:javascript ("js-impl.js")
|
||||
#:provided-values (alert
|
||||
body
|
||||
call
|
||||
$))
|
15
js/racket-impl.rkt
Normal file
15
js/racket-impl.rkt
Normal file
|
@ -0,0 +1,15 @@
|
|||
#lang s-exp "../lang/base.rkt"
|
||||
|
||||
(provide alert body call $)
|
||||
|
||||
(define (alert x)
|
||||
(display x)
|
||||
(newline))
|
||||
|
||||
(define body 'blah)
|
||||
|
||||
(define (call object method . args)
|
||||
'not-done-yet)
|
||||
|
||||
(define ($ name)
|
||||
'not-done-yet)
|
9
lang/base/reader.rkt
Normal file
9
lang/base/reader.rkt
Normal file
|
@ -0,0 +1,9 @@
|
|||
#lang s-exp syntax/module-reader
|
||||
|
||||
;; http://docs.racket-lang.org/planet/hash-lang-planet.html
|
||||
|
||||
#:language (lambda (ip)
|
||||
`(file ,(path->string base-lang-path)))
|
||||
|
||||
(require racket/runtime-path)
|
||||
(define-runtime-path base-lang-path "../base.rkt")
|
|
@ -1,57 +0,0 @@
|
|||
#lang racket/base
|
||||
|
||||
;; Special language level where implementation is done in Javascript.
|
||||
|
||||
(require (for-syntax racket/base)
|
||||
(for-syntax racket/file)
|
||||
(for-syntax syntax/modresolve)
|
||||
(for-syntax "record.rkt"))
|
||||
|
||||
|
||||
(define-for-syntax (read-implementation a-module-path)
|
||||
(let ([a-path (parameterize ([current-directory (or (current-load-relative-directory)
|
||||
(current-directory))])
|
||||
(resolve-module-path a-module-path #f))])
|
||||
(file->string a-path)))
|
||||
|
||||
|
||||
(define-syntax (require-js stx)
|
||||
(syntax-case stx ()
|
||||
[(_ path ...)
|
||||
(andmap (compose string? syntax-e) (syntax->list #'(path ...)))
|
||||
(with-syntax
|
||||
([(impl ...) (map (compose read-implementation syntax-e)
|
||||
(syntax->list #'(path ...)))])
|
||||
(syntax/loc stx
|
||||
(begin
|
||||
(begin-for-syntax
|
||||
(let* ([this-module (variable-reference->resolved-module-path (#%variable-reference))]
|
||||
[key (resolved-module-path-name this-module)])
|
||||
(record-implementations! key (list (#%datum . impl) ...))))
|
||||
(void))))]))
|
||||
|
||||
|
||||
(define-syntax (-provide stx)
|
||||
(syntax-case stx ()
|
||||
[(_ name ...)
|
||||
(andmap (compose symbol? syntax-e) (syntax->list #'(name ...)))
|
||||
(syntax/loc stx
|
||||
(begin
|
||||
(begin-for-syntax
|
||||
(let* ([this-module (variable-reference->resolved-module-path (#%variable-reference))]
|
||||
[key (resolved-module-path-name this-module)])
|
||||
(record-exports! key (list (#%datum . name) ...))))
|
||||
(provide name ...)
|
||||
(begin (define name (lambda args
|
||||
(error (quote name)
|
||||
"Must be evaluated within Javascript"))) ...)))]))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(provide require-js
|
||||
require
|
||||
planet
|
||||
(rename-out (-provide provide)
|
||||
(#%plain-module-begin #%module-begin)))
|
|
@ -1,39 +0,0 @@
|
|||
#lang racket/base
|
||||
|
||||
(require racket/contract
|
||||
racket/runtime-path
|
||||
racket/list
|
||||
syntax/modresolve)
|
||||
|
||||
|
||||
(define-struct js-module (impls exports))
|
||||
|
||||
(provide/contract [query
|
||||
(module-path? . -> . (or/c js-module? false/c))]
|
||||
[struct js-module ([impls (listof string?)]
|
||||
[exports (listof symbol?)])])
|
||||
|
||||
|
||||
|
||||
|
||||
(define-runtime-path record.rkt "record.rkt")
|
||||
(define ns (make-base-empty-namespace))
|
||||
|
||||
|
||||
|
||||
;; query: module-path -> (listof string)
|
||||
;; Given a module, see if it's implemented via Javascript.
|
||||
(define (query a-module-path)
|
||||
(let ([resolved-path (resolve-module-path a-module-path #f)])
|
||||
(parameterize ([current-namespace ns])
|
||||
(dynamic-require a-module-path (void)) ;; get the compile-time code running.
|
||||
(let ([result
|
||||
((dynamic-require-for-syntax record.rkt 'lookup-implementations) resolved-path)])
|
||||
(cond
|
||||
[(empty? result)
|
||||
#f]
|
||||
[else
|
||||
(make-js-module result
|
||||
((dynamic-require-for-syntax record.rkt 'lookup-exports) resolved-path))])))))
|
||||
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
#lang racket/base
|
||||
|
||||
(provide record-implementations!
|
||||
record-exports!
|
||||
lookup-implementations
|
||||
lookup-exports)
|
||||
|
||||
(define-struct record (path impls))
|
||||
(define-struct export (path exports))
|
||||
|
||||
(define records '())
|
||||
(define exports '())
|
||||
|
||||
;; record!: path (listof string) -> void
|
||||
(define (record-implementations! a-path impls)
|
||||
(set! records (cons (make-record a-path impls)
|
||||
records)))
|
||||
|
||||
|
||||
;; record-exports!: path (listof symbol) -> void
|
||||
(define (record-exports! a-path export-names)
|
||||
(set! exports (cons (make-export a-path export-names)
|
||||
exports)))
|
||||
|
||||
|
||||
(define (my-foldl f acc lst)
|
||||
(cond
|
||||
[(null? lst)
|
||||
acc]
|
||||
[else
|
||||
(my-foldl f (f (car lst) acc) (cdr lst))]))
|
||||
|
||||
|
||||
(define (my-filter f lst)
|
||||
(cond
|
||||
[(null? lst)
|
||||
'()]
|
||||
[(f (car lst))
|
||||
(cons (car lst) (my-filter f (cdr lst)))]
|
||||
[else
|
||||
(my-filter f (cdr lst))]))
|
||||
|
||||
|
||||
;; lookup-implementations: path -> (listof string)
|
||||
(define (lookup-implementations a-path)
|
||||
(my-foldl (lambda (a-record perms)
|
||||
(append (record-impls a-record) perms))
|
||||
'()
|
||||
(my-filter (lambda (a-record)
|
||||
(equal? a-path (record-path a-record)))
|
||||
records)))
|
||||
|
||||
|
||||
;; lookup-exports: path -> (listof symbol)
|
||||
(define (lookup-exports a-path)
|
||||
(my-foldl (lambda (an-export exports)
|
||||
(append (export-exports an-export) exports))
|
||||
'()
|
||||
(my-filter (lambda (an-export)
|
||||
(equal? a-path (export-path an-export)))
|
||||
exports)))
|
|
@ -17,10 +17,11 @@
|
|||
(file->string a-path)))
|
||||
|
||||
|
||||
(define-syntax (declare-conditional-implementation stx)
|
||||
(define-syntax (declare-implementation stx)
|
||||
(syntax-parse stx
|
||||
[(_ #:racket racket-module-name
|
||||
#:javascript (javascript-module-name ...))
|
||||
#:javascript (javascript-module-name ...)
|
||||
#:provided-values (provided-name ...))
|
||||
(with-syntax
|
||||
([resolved-racket-module-name
|
||||
(my-resolve-path (syntax-e #'racket-module-name))]
|
||||
|
@ -28,7 +29,8 @@
|
|||
(string-join
|
||||
(map (compose read-implementation syntax-e)
|
||||
(syntax->list #'(javascript-module-name ...)))
|
||||
"\n")])
|
||||
"\n")]
|
||||
[(internal-name ...) (generate-temporaries #'(provided-name ...))])
|
||||
(syntax/loc stx
|
||||
(begin
|
||||
|
||||
|
@ -42,11 +44,14 @@
|
|||
[key (resolved-module-path-name this-module)])
|
||||
(record-redirection! (#%datum . resolved-racket-module-name)
|
||||
key)
|
||||
(record-javascript-implementation! key (#%datum . impl))))
|
||||
(record-javascript-implementation! key (#%datum . impl))
|
||||
;;(record-exported-name! key 'internal-name 'provided-name) ...
|
||||
))
|
||||
|
||||
(require racket-module-name)
|
||||
(provide (all-from-out racket-module-name)))))]))
|
||||
(define internal-name provided-name) ...
|
||||
(provide (rename-out [internal-name provided-name] ...)))))]))
|
||||
|
||||
|
||||
(provide declare-conditional-implementation
|
||||
(provide declare-implementation
|
||||
(rename-out [#%plain-module-begin #%module-begin]))
|
|
@ -9,7 +9,8 @@
|
|||
[has-javascript-implementation? (module-path? . -> . boolean?)]
|
||||
|
||||
[redirected? (path? . -> . boolean?)]
|
||||
[follow-redirection (path? . -> . path?)])
|
||||
[follow-redirection (path? . -> . path?)]
|
||||
[collect-redirections-to (path? . -> . (listof path?))])
|
||||
|
||||
(define-runtime-path record.rkt "record.rkt")
|
||||
(define ns (make-base-empty-namespace))
|
||||
|
@ -49,3 +50,12 @@
|
|||
((dynamic-require-for-syntax record.rkt 'follow-redirection)
|
||||
resolved-path))))
|
||||
|
||||
|
||||
|
||||
;; collect-redirections-to: module-path -> (listof path)
|
||||
(define (collect-redirections-to a-module-path)
|
||||
(let ([resolved-path (resolve-module-path a-module-path #f)])
|
||||
(parameterize ([current-namespace ns])
|
||||
(dynamic-require a-module-path (void)) ;; get the compile-time code running.
|
||||
((dynamic-require-for-syntax record.rkt 'collect-redirections-to)
|
||||
resolved-path))))
|
|
@ -5,7 +5,11 @@
|
|||
lookup-javascript-implementation
|
||||
|
||||
record-redirection!
|
||||
follow-redirection)
|
||||
follow-redirection
|
||||
|
||||
record-exported-name!
|
||||
|
||||
collect-redirections-to)
|
||||
|
||||
|
||||
(define-struct record (path impl))
|
||||
|
@ -59,4 +63,21 @@
|
|||
[(equal? (redirection-from (car redirections)) a-path)
|
||||
(redirection-to (car redirections))]
|
||||
[else
|
||||
(loop (cdr redirections))])))
|
||||
(loop (cdr redirections))])))
|
||||
|
||||
|
||||
(define (record-exported-name! a-path internal-name external-name)
|
||||
(printf "I need to remember to export ~s as ~s\n" internal-name external-name)
|
||||
(void))
|
||||
|
||||
|
||||
;; collect-redirections-to: path -> (listof path)
|
||||
(define (collect-redirections-to a-path)
|
||||
(let loop ([redirections redirections])
|
||||
(cond
|
||||
[(null? redirections)
|
||||
'()]
|
||||
[(equal? (redirection-to (car redirections)) a-path)
|
||||
(redirection-from (car redirections))]
|
||||
[else
|
||||
(loop (cdr redirections))])))
|
|
@ -148,7 +148,7 @@
|
|||
display
|
||||
newline
|
||||
|
||||
#;displayln
|
||||
;; displayln
|
||||
|
||||
;; current-print
|
||||
;; current-continuation-marks
|
||||
|
@ -175,7 +175,7 @@
|
|||
;; compose
|
||||
;; current-inexact-milliseconds
|
||||
;; current-seconds
|
||||
;; void
|
||||
void
|
||||
;; random
|
||||
;; sleep
|
||||
;; (identity -identity)
|
||||
|
@ -394,6 +394,36 @@
|
|||
;; make-reader-graph
|
||||
;; make-placeholder
|
||||
;; placeholder-set!
|
||||
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(provide
|
||||
;; FIXME:
|
||||
;; Extensions: these may need to be hidden in a JavaScript-implemented module
|
||||
in-javascript-context?
|
||||
viewport-width
|
||||
viewport-height)
|
||||
|
||||
|
||||
|
||||
;; in-javascript-context: -> boolean
|
||||
;; Produces true if we're in a JavaScript context.
|
||||
(define (in-javascript-context?)
|
||||
#f)
|
||||
|
||||
|
||||
;; viewport-width: -> natural
|
||||
;; The viewport width in pixels.
|
||||
(define (viewport-width)
|
||||
(error 'viewport-width "Not available outside JavaScript context."))
|
||||
|
||||
|
||||
;; viewport-height: -> natural
|
||||
;; The viewport height in pixels.
|
||||
(define (viewport-height)
|
||||
(error 'viewport-width "Not available outside JavaScript context."))
|
||||
|
||||
|
||||
|
|
9
lang/reader.rkt
Normal file
9
lang/reader.rkt
Normal file
|
@ -0,0 +1,9 @@
|
|||
#lang s-exp syntax/module-reader
|
||||
|
||||
;; http://docs.racket-lang.org/planet/hash-lang-planet.html
|
||||
|
||||
#:language (lambda (ip)
|
||||
`(file ,(path->string base-lang-path)))
|
||||
|
||||
(require racket/runtime-path)
|
||||
(define-runtime-path base-lang-path "base.rkt")
|
|
@ -1,7 +1,7 @@
|
|||
#lang typed/racket/base
|
||||
(require "compiler/expression-structs.rkt"
|
||||
"compiler/lexical-structs.rkt"
|
||||
"sets.rkt")
|
||||
(require "../compiler/expression-structs.rkt"
|
||||
"../compiler/lexical-structs.rkt"
|
||||
"../sets.rkt")
|
||||
|
||||
;; Collect the complete list of dependencies for a module.
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#lang typed/racket/base
|
||||
|
||||
(require "compiler/il-structs.rkt"
|
||||
"compiler/bootstrapped-primitives.rkt"
|
||||
"compiler/expression-structs.rkt"
|
||||
(require "../compiler/il-structs.rkt"
|
||||
"../compiler/bootstrapped-primitives.rkt"
|
||||
"../compiler/expression-structs.rkt"
|
||||
"get-dependencies.rkt")
|
||||
|
||||
|
||||
|
@ -13,7 +13,9 @@
|
|||
(define-type Source (U StatementsSource
|
||||
MainModuleSource
|
||||
ModuleSource
|
||||
SexpSource))
|
||||
SexpSource
|
||||
UninterpretedSource
|
||||
))
|
||||
|
||||
(define-struct: StatementsSource ([stmts : (Listof Statement)])
|
||||
#:transparent)
|
||||
|
@ -23,10 +25,14 @@
|
|||
#:transparent)
|
||||
(define-struct: SexpSource ([sexp : Any])
|
||||
#:transparent)
|
||||
(define-struct: UninterpretedSource ([datum : String])
|
||||
#:transparent)
|
||||
|
||||
|
||||
|
||||
(define-struct: Configuration
|
||||
([should-follow? : (Source Path -> Boolean)]
|
||||
([wrap-source : (Source -> Source)]
|
||||
[should-follow-children? : (Source -> Boolean)]
|
||||
[on-module-statements : (Source
|
||||
(U Expression #f)
|
||||
(Listof Statement)
|
||||
|
@ -40,7 +46,8 @@
|
|||
|
||||
(define debug-configuration
|
||||
(make-Configuration
|
||||
(lambda (src p) #t)
|
||||
(lambda (src) src)
|
||||
(lambda (src) #t)
|
||||
(lambda (src ast stmt)
|
||||
(when (and ast (expression-module-path ast))
|
||||
(printf "debug build configuration: visiting ~s\n"
|
|
@ -1,22 +1,22 @@
|
|||
#lang typed/racket/base
|
||||
|
||||
(require "compiler/compiler.rkt"
|
||||
"compiler/il-structs.rkt"
|
||||
"compiler/lexical-structs.rkt"
|
||||
"compiler/compiler-structs.rkt"
|
||||
"compiler/expression-structs.rkt"
|
||||
(require "../compiler/compiler.rkt"
|
||||
"../compiler/il-structs.rkt"
|
||||
"../compiler/lexical-structs.rkt"
|
||||
"../compiler/compiler-structs.rkt"
|
||||
"../compiler/expression-structs.rkt"
|
||||
"../parameters.rkt"
|
||||
"../sets.rkt"
|
||||
"get-dependencies.rkt"
|
||||
"parameters.rkt"
|
||||
"sets.rkt"
|
||||
"make-structs.rkt"
|
||||
racket/list
|
||||
racket/match)
|
||||
|
||||
|
||||
(require/typed "parser/parse-bytecode.rkt"
|
||||
(require/typed "../parser/parse-bytecode.rkt"
|
||||
[parse-bytecode (Any -> Expression)])
|
||||
|
||||
(require/typed "get-module-bytecode.rkt"
|
||||
(require/typed "../get-module-bytecode.rkt"
|
||||
[get-module-bytecode ((U String Path Input-Port) -> Bytes)])
|
||||
|
||||
|
||||
|
@ -41,6 +41,9 @@
|
|||
[(StatementsSource? a-source)
|
||||
(values #f (StatementsSource-stmts a-source))]
|
||||
|
||||
[(UninterpretedSource? a-source)
|
||||
(values #f '())]
|
||||
|
||||
[(MainModuleSource? a-source)
|
||||
(let-values ([(ast stmts)
|
||||
(get-ast-and-statements (MainModuleSource-source a-source))])
|
||||
|
@ -82,6 +85,7 @@
|
|||
(and path (? ModuleLocator?))
|
||||
prefix
|
||||
requires
|
||||
provides
|
||||
code))))
|
||||
path]
|
||||
[else
|
||||
|
@ -96,7 +100,8 @@
|
|||
((inst new-seteq Symbol))])
|
||||
|
||||
(match config
|
||||
[(struct Configuration (should-follow?
|
||||
[(struct Configuration (wrap-source
|
||||
should-follow-children?
|
||||
on-module-statements
|
||||
after-module-statements
|
||||
after-last))
|
||||
|
@ -112,20 +117,19 @@
|
|||
(cond
|
||||
[(eq? ast #f)
|
||||
empty]
|
||||
[(not (should-follow-children? this-source))
|
||||
empty]
|
||||
[else
|
||||
(let* ([dependent-module-names (get-dependencies ast)]
|
||||
[paths
|
||||
(foldl (lambda: ([mp : ModuleLocator]
|
||||
[acc : (Listof Source)])
|
||||
(let ([rp [ModuleLocator-real-path mp]])
|
||||
|
||||
(cond [((current-kernel-module-locator?)
|
||||
mp)
|
||||
acc]
|
||||
[(and (path? rp)
|
||||
(should-follow? this-source rp)
|
||||
(cons (make-ModuleSource rp)
|
||||
acc))]
|
||||
[(path? rp)
|
||||
(cons (make-ModuleSource rp) acc)]
|
||||
[else
|
||||
acc])))
|
||||
'()
|
||||
|
@ -146,9 +150,8 @@
|
|||
[(ast stmts)
|
||||
(get-ast-and-statements this-source)])
|
||||
(on-module-statements this-source ast stmts)
|
||||
(loop (append (collect-new-dependencies this-source ast)
|
||||
(loop (append (map wrap-source (collect-new-dependencies this-source ast))
|
||||
(rest sources)))
|
||||
(after-module-statements this-source ast stmts))])))
|
||||
|
||||
(follow-dependencies sources)])))
|
||||
|
||||
(follow-dependencies (map wrap-source sources))])))
|
|
@ -11,7 +11,8 @@
|
|||
current-root-path
|
||||
current-warn-unimplemented-kernel-primitive
|
||||
current-seen-unimplemented-kernel-primitives
|
||||
current-kernel-module-locator?)
|
||||
current-kernel-module-locator?
|
||||
current-compress-javascript?)
|
||||
|
||||
|
||||
|
||||
|
@ -47,6 +48,9 @@
|
|||
|
||||
|
||||
|
||||
(: current-compress-javascript? (Parameterof Boolean))
|
||||
(define current-compress-javascript? (make-parameter #f))
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -163,12 +163,14 @@
|
|||
(struct ModuleLocator ('self 'self))
|
||||
module-prefix
|
||||
module-requires
|
||||
module-provides
|
||||
module-code))))
|
||||
(make-Top top-prefix
|
||||
(make-Module name
|
||||
(make-ModuleLocator name name) (current-module-path)
|
||||
module-prefix
|
||||
module-requires
|
||||
module-provides
|
||||
module-code))]
|
||||
[else
|
||||
exp]))
|
||||
|
@ -369,6 +371,7 @@
|
|||
(make-ModuleLocator self-path self-path)
|
||||
(parse-prefix prefix)
|
||||
(parse-mod-requires self-modidx requires)
|
||||
(parse-mod-provides self-modidx provides)
|
||||
(parse-mod-body body))]
|
||||
[else
|
||||
(let ([rewritten-path (rewrite-path self-path)])
|
||||
|
@ -379,6 +382,7 @@
|
|||
(normalize-path self-path))
|
||||
(parse-prefix prefix)
|
||||
(parse-mod-requires self-modidx requires)
|
||||
(parse-mod-provides self-modidx provides)
|
||||
(parse-mod-body body))]
|
||||
[else
|
||||
(error 'parse-mod "Internal error: unable to resolve module path ~s" self-path)]))]))]))
|
||||
|
@ -407,6 +411,34 @@
|
|||
|
||||
|
||||
|
||||
(define (parse-mod-provides enclosing-module-path-index provides)
|
||||
(let* ([resolver
|
||||
(current-module-path-index-resolver)]
|
||||
[enclosing-path
|
||||
(resolver enclosing-module-path-index (current-module-path))]
|
||||
[subresolver
|
||||
(lambda (p)
|
||||
(cond
|
||||
[(symbol? enclosing-path)
|
||||
(wrap-module-name (resolver p (current-module-path)))]
|
||||
[(path? enclosing-path)
|
||||
(wrap-module-name (resolver p enclosing-path))]))])
|
||||
(let loop ([provides provides])
|
||||
(cond
|
||||
[(empty? provides)
|
||||
empty]
|
||||
[(= (first (first provides)) 0)
|
||||
(let ([provided-values (second (first provides))])
|
||||
(for/list ([v provided-values])
|
||||
(match v
|
||||
[(struct provided (name src src-name nom-mod
|
||||
src-phase protected? insp))
|
||||
(make-ModuleProvide src-name name (subresolver src))])))]
|
||||
[else
|
||||
(loop (rest provides))]))))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -312,10 +312,10 @@
|
|||
(cond
|
||||
[(closure? clos)
|
||||
(if (arity-match? (closure-arity clos)
|
||||
(ensure-natural (evaluate-oparg m (CheckClosureArity!-arity op))))
|
||||
(ensure-natural (evaluate-oparg m (CheckClosureArity!-num-args op))))
|
||||
'ok
|
||||
(error 'check-closure-arity "arity mismatch: passed ~s args to ~s"
|
||||
(ensure-natural (evaluate-oparg m (CheckClosureArity!-arity op)))
|
||||
(ensure-natural (evaluate-oparg m (CheckClosureArity!-num-args op)))
|
||||
(closure-display-name clos)))]
|
||||
[else
|
||||
(error 'check-closure-arity "not a closure: ~s" clos)]))]
|
||||
|
@ -325,10 +325,10 @@
|
|||
(cond
|
||||
[(primitive-proc? clos)
|
||||
(if (arity-match? (primitive-proc-arity clos)
|
||||
(ensure-natural (evaluate-oparg m (CheckPrimitiveArity!-arity op))))
|
||||
(ensure-natural (evaluate-oparg m (CheckPrimitiveArity!-num-args op))))
|
||||
'ok
|
||||
(error 'check-primitive-arity "arity mismatch: passed ~s args to ~s"
|
||||
(ensure-natural (evaluate-oparg m (CheckPrimitiveArity!-arity op)))
|
||||
(ensure-natural (evaluate-oparg m (CheckPrimitiveArity!-num-args op)))
|
||||
(primitive-proc-display-name clos)))]
|
||||
[else
|
||||
(error 'check-primitive-arity "not a primitive: ~s" clos)]))]
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
[program (second javascript-compiler+program)])
|
||||
|
||||
(with-handlers ([exn:fail? (lambda (exn)
|
||||
(displayln exn)
|
||||
(let ([sentinel
|
||||
(format
|
||||
#<<EOF
|
||||
|
@ -220,7 +221,7 @@ var comet = function() {
|
|||
}
|
||||
var output = [];
|
||||
var startTime, endTime;
|
||||
var params = { currentDisplayer: function(v) {
|
||||
var params = { currentDisplayer: function(MACHINE, v) {
|
||||
$(document.body).append(v);
|
||||
output.push($(v).text()); } };
|
||||
|
||||
|
@ -236,7 +237,7 @@ var comet = function() {
|
|||
var onFail = function(machine, e) {
|
||||
endTime = new Date();
|
||||
sendRequest("/eval", function(req) { setTimeout(comet, 0); },
|
||||
"e=" + encodeURIComponent(String(e)) +
|
||||
"e=" + encodeURIComponent(String(e.stack || e)) +
|
||||
"&t=" + encodeURIComponent(String(endTime - startTime)));
|
||||
};
|
||||
startTime = new Date();
|
||||
|
|
826
tests/earley/earley.rkt
Normal file
826
tests/earley/earley.rkt
Normal file
|
@ -0,0 +1,826 @@
|
|||
#lang s-exp "../../lang/base.rkt"
|
||||
(begin
|
||||
(define make-parser
|
||||
(lambda (grammar lexer)
|
||||
(letrec ((non-terminals
|
||||
(lambda (grammar)
|
||||
(letrec ((add-nt (lambda (nt nts) (if (member nt nts) nts (cons nt nts)))))
|
||||
((letrec ((def-loop
|
||||
(lambda (defs nts)
|
||||
(if (pair? defs)
|
||||
(let ((def (car defs)))
|
||||
(let ((head (car def)))
|
||||
((letrec ((rule-loop
|
||||
(lambda (rules nts)
|
||||
(if (pair? rules)
|
||||
(let ((rule (car rules)))
|
||||
((letrec ((loop
|
||||
(lambda (l nts)
|
||||
(if (pair? l)
|
||||
(let ((nt (car l)))
|
||||
(loop (cdr l) (add-nt nt nts)))
|
||||
(rule-loop (cdr rules) nts)))))
|
||||
loop)
|
||||
rule
|
||||
nts))
|
||||
(def-loop (cdr defs) nts)))))
|
||||
rule-loop)
|
||||
(cdr def)
|
||||
(add-nt head nts))))
|
||||
(list->vector (reverse nts))))))
|
||||
def-loop)
|
||||
grammar
|
||||
'()))))
|
||||
(ind
|
||||
(lambda (nt nts)
|
||||
((letrec ((loop
|
||||
(lambda (i)
|
||||
(if (>= i '0) (if (equal? (vector-ref nts i) nt) i (loop (- i '1))) '#f))))
|
||||
loop)
|
||||
(- (vector-length nts) '1))))
|
||||
(nb-configurations
|
||||
(lambda (grammar)
|
||||
((letrec ((def-loop
|
||||
(lambda (defs nb-confs)
|
||||
(if (pair? defs)
|
||||
(let ((def (car defs)))
|
||||
((letrec ((rule-loop
|
||||
(lambda (rules nb-confs)
|
||||
(if (pair? rules)
|
||||
(let ((rule (car rules)))
|
||||
((letrec ((loop
|
||||
(lambda (l nb-confs)
|
||||
(if (pair? l)
|
||||
(loop (cdr l) (+ nb-confs '1))
|
||||
(rule-loop (cdr rules) (+ nb-confs '1))))))
|
||||
loop)
|
||||
rule
|
||||
nb-confs))
|
||||
(def-loop (cdr defs) nb-confs)))))
|
||||
rule-loop)
|
||||
(cdr def)
|
||||
nb-confs))
|
||||
nb-confs))))
|
||||
def-loop)
|
||||
grammar
|
||||
'0))))
|
||||
(let ((nts (non-terminals grammar)))
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
(let ((nb-confs (+ (nb-configurations grammar) nb-nts)))
|
||||
(let ((starters (make-vector nb-nts '())))
|
||||
(let ((enders (make-vector nb-nts '())))
|
||||
(let ((predictors (make-vector nb-nts '())))
|
||||
(let ((steps (make-vector nb-confs '#f)))
|
||||
(let ((names (make-vector nb-confs '#f)))
|
||||
(letrec ((setup-tables
|
||||
(lambda (grammar nts starters enders predictors steps names)
|
||||
(letrec ((add-conf
|
||||
(lambda (conf nt nts class)
|
||||
(let ((i (ind nt nts)))
|
||||
(vector-set! class i (cons conf (vector-ref class i)))))))
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
((letrec ((nt-loop
|
||||
(lambda (i)
|
||||
(if (>= i '0)
|
||||
(begin
|
||||
(vector-set! steps i (- i nb-nts))
|
||||
(vector-set! names i (list (vector-ref nts i) '0))
|
||||
(vector-set! enders i (list i))
|
||||
(nt-loop (- i '1)))
|
||||
'#f))))
|
||||
nt-loop)
|
||||
(- nb-nts '1))
|
||||
((letrec ((def-loop
|
||||
(lambda (defs conf)
|
||||
(if (pair? defs)
|
||||
(let ((def (car defs)))
|
||||
(let ((head (car def)))
|
||||
((letrec ((rule-loop
|
||||
(lambda (rules conf rule-num)
|
||||
(if (pair? rules)
|
||||
(let ((rule (car rules)))
|
||||
(vector-set!
|
||||
names
|
||||
conf
|
||||
(list head rule-num))
|
||||
(add-conf conf head nts starters)
|
||||
((letrec ((loop
|
||||
(lambda (l conf)
|
||||
(if (pair? l)
|
||||
(let ((nt (car l)))
|
||||
(vector-set!
|
||||
steps
|
||||
conf
|
||||
(ind nt nts))
|
||||
(add-conf
|
||||
conf
|
||||
nt
|
||||
nts
|
||||
predictors)
|
||||
(loop
|
||||
(cdr l)
|
||||
(+ conf '1)))
|
||||
(begin
|
||||
(vector-set!
|
||||
steps
|
||||
conf
|
||||
(-
|
||||
(ind head nts)
|
||||
nb-nts))
|
||||
(add-conf
|
||||
conf
|
||||
head
|
||||
nts
|
||||
enders)
|
||||
(rule-loop
|
||||
(cdr rules)
|
||||
(+ conf '1)
|
||||
(+ rule-num '1)))))))
|
||||
loop)
|
||||
rule
|
||||
conf))
|
||||
(def-loop (cdr defs) conf)))))
|
||||
rule-loop)
|
||||
(cdr def)
|
||||
conf
|
||||
'1)))
|
||||
'#f))))
|
||||
def-loop)
|
||||
grammar
|
||||
(vector-length nts)))))))
|
||||
(setup-tables grammar nts starters enders predictors steps names)
|
||||
(let ((parser-descr (vector lexer nts starters enders predictors steps names)))
|
||||
(lambda (input)
|
||||
(letrec ((ind
|
||||
(lambda (nt nts)
|
||||
((letrec ((loop
|
||||
(lambda (i)
|
||||
(if (>= i '0)
|
||||
(if (equal? (vector-ref nts i) nt) i (loop (- i '1)))
|
||||
'#f))))
|
||||
loop)
|
||||
(- (vector-length nts) '1))))
|
||||
(comp-tok
|
||||
(lambda (tok nts)
|
||||
((letrec ((loop
|
||||
(lambda (l1 l2)
|
||||
(if (pair? l1)
|
||||
(let ((i (ind (car l1) nts)))
|
||||
(if i (loop (cdr l1) (cons i l2)) (loop (cdr l1) l2)))
|
||||
(cons (car tok) (reverse l2))))))
|
||||
loop)
|
||||
(cdr tok)
|
||||
'())))
|
||||
(input->tokens
|
||||
(lambda (input lexer nts)
|
||||
(list->vector (map (lambda (tok) (comp-tok tok nts)) (lexer input)))))
|
||||
(make-states
|
||||
(lambda (nb-toks nb-confs)
|
||||
(let ((states (make-vector (+ nb-toks '1) '#f)))
|
||||
((letrec ((loop
|
||||
(lambda (i)
|
||||
(if (>= i '0)
|
||||
(let ((v (make-vector (+ nb-confs '1) '#f)))
|
||||
(vector-set! v '0 '-1)
|
||||
(vector-set! states i v)
|
||||
(loop (- i '1)))
|
||||
states))))
|
||||
loop)
|
||||
nb-toks))))
|
||||
(conf-set-get (lambda (state conf) (vector-ref state (+ conf '1))))
|
||||
(conf-set-get*
|
||||
(lambda (state state-num conf)
|
||||
(let ((conf-set (conf-set-get state conf)))
|
||||
(if conf-set
|
||||
conf-set
|
||||
(let ((conf-set (make-vector (+ state-num '6) '#f)))
|
||||
(vector-set! conf-set '1 '-3)
|
||||
(vector-set! conf-set '2 '-1)
|
||||
(vector-set! conf-set '3 '-1)
|
||||
(vector-set! conf-set '4 '-1)
|
||||
(vector-set! state (+ conf '1) conf-set)
|
||||
conf-set)))))
|
||||
(conf-set-merge-new!
|
||||
(lambda (conf-set)
|
||||
(vector-set!
|
||||
conf-set
|
||||
(+ (vector-ref conf-set '1) '5)
|
||||
(vector-ref conf-set '4))
|
||||
(vector-set! conf-set '1 (vector-ref conf-set '3))
|
||||
(vector-set! conf-set '3 '-1)
|
||||
(vector-set! conf-set '4 '-1)))
|
||||
(conf-set-head (lambda (conf-set) (vector-ref conf-set '2)))
|
||||
(conf-set-next (lambda (conf-set i) (vector-ref conf-set (+ i '5))))
|
||||
(conf-set-member?
|
||||
(lambda (state conf i)
|
||||
(let ((conf-set (vector-ref state (+ conf '1))))
|
||||
(if conf-set (conf-set-next conf-set i) '#f))))
|
||||
(conf-set-adjoin
|
||||
(lambda (state conf-set conf i)
|
||||
(let ((tail (vector-ref conf-set '3)))
|
||||
(vector-set! conf-set (+ i '5) '-1)
|
||||
(vector-set! conf-set (+ tail '5) i)
|
||||
(vector-set! conf-set '3 i)
|
||||
(if (< tail '0)
|
||||
(begin
|
||||
(vector-set! conf-set '0 (vector-ref state '0))
|
||||
(vector-set! state '0 conf))
|
||||
'#f))))
|
||||
(conf-set-adjoin*
|
||||
(lambda (states state-num l i)
|
||||
(let ((state (vector-ref states state-num)))
|
||||
((letrec ((loop
|
||||
(lambda (l1)
|
||||
(if (pair? l1)
|
||||
(let ((conf (car l1)))
|
||||
(let ((conf-set (conf-set-get* state state-num conf)))
|
||||
(if (not (conf-set-next conf-set i))
|
||||
(begin
|
||||
(conf-set-adjoin state conf-set conf i)
|
||||
(loop (cdr l1)))
|
||||
(loop (cdr l1)))))
|
||||
'#f))))
|
||||
loop)
|
||||
l))))
|
||||
(conf-set-adjoin**
|
||||
(lambda (states states* state-num conf i)
|
||||
(let ((state (vector-ref states state-num)))
|
||||
(if (conf-set-member? state conf i)
|
||||
(let ((state* (vector-ref states* state-num)))
|
||||
(let ((conf-set* (conf-set-get* state* state-num conf)))
|
||||
(if (not (conf-set-next conf-set* i))
|
||||
(conf-set-adjoin state* conf-set* conf i)
|
||||
'#f)
|
||||
'#t))
|
||||
'#f))))
|
||||
(conf-set-union
|
||||
(lambda (state conf-set conf other-set)
|
||||
((letrec ((loop
|
||||
(lambda (i)
|
||||
(if (>= i '0)
|
||||
(if (not (conf-set-next conf-set i))
|
||||
(begin
|
||||
(conf-set-adjoin state conf-set conf i)
|
||||
(loop (conf-set-next other-set i)))
|
||||
(loop (conf-set-next other-set i)))
|
||||
'#f))))
|
||||
loop)
|
||||
(conf-set-head other-set))))
|
||||
(forw
|
||||
(lambda (states state-num starters enders predictors steps nts)
|
||||
(letrec ((predict
|
||||
(lambda (state state-num conf-set conf nt starters enders)
|
||||
((letrec ((loop1
|
||||
(lambda (l)
|
||||
(if (pair? l)
|
||||
(let ((starter (car l)))
|
||||
(let ((starter-set
|
||||
(conf-set-get*
|
||||
state
|
||||
state-num
|
||||
starter)))
|
||||
(if (not
|
||||
(conf-set-next
|
||||
starter-set
|
||||
state-num))
|
||||
(begin
|
||||
(conf-set-adjoin
|
||||
state
|
||||
starter-set
|
||||
starter
|
||||
state-num)
|
||||
(loop1 (cdr l)))
|
||||
(loop1 (cdr l)))))
|
||||
'#f))))
|
||||
loop1)
|
||||
(vector-ref starters nt))
|
||||
((letrec ((loop2
|
||||
(lambda (l)
|
||||
(if (pair? l)
|
||||
(let ((ender (car l)))
|
||||
(if (conf-set-member? state ender state-num)
|
||||
(let ((next (+ conf '1)))
|
||||
(let ((next-set
|
||||
(conf-set-get*
|
||||
state
|
||||
state-num
|
||||
next)))
|
||||
(conf-set-union
|
||||
state
|
||||
next-set
|
||||
next
|
||||
conf-set)
|
||||
(loop2 (cdr l))))
|
||||
(loop2 (cdr l))))
|
||||
'#f))))
|
||||
loop2)
|
||||
(vector-ref enders nt))))
|
||||
(reduce
|
||||
(lambda (states state state-num conf-set head preds)
|
||||
((letrec ((loop1
|
||||
(lambda (l)
|
||||
(if (pair? l)
|
||||
(let ((pred (car l)))
|
||||
((letrec ((loop2
|
||||
(lambda (i)
|
||||
(if (>= i '0)
|
||||
(let ((pred-set
|
||||
(conf-set-get
|
||||
(vector-ref states i)
|
||||
pred)))
|
||||
(if pred-set
|
||||
(let ((next (+ pred '1)))
|
||||
(let ((next-set
|
||||
(conf-set-get*
|
||||
state
|
||||
state-num
|
||||
next)))
|
||||
(conf-set-union
|
||||
state
|
||||
next-set
|
||||
next
|
||||
pred-set)))
|
||||
'#f)
|
||||
(loop2
|
||||
(conf-set-next
|
||||
conf-set
|
||||
i)))
|
||||
(loop1 (cdr l))))))
|
||||
loop2)
|
||||
head))
|
||||
'#f))))
|
||||
loop1)
|
||||
preds))))
|
||||
(let ((state (vector-ref states state-num))
|
||||
(nb-nts (vector-length nts)))
|
||||
((letrec ((loop
|
||||
(lambda ()
|
||||
(let ((conf (vector-ref state '0)))
|
||||
(if (>= conf '0)
|
||||
(let ((step (vector-ref steps conf)))
|
||||
(let ((conf-set (vector-ref state (+ conf '1))))
|
||||
(let ((head (vector-ref conf-set '4)))
|
||||
(vector-set!
|
||||
state
|
||||
'0
|
||||
(vector-ref conf-set '0))
|
||||
(conf-set-merge-new! conf-set)
|
||||
(if (>= step '0)
|
||||
(predict
|
||||
state
|
||||
state-num
|
||||
conf-set
|
||||
conf
|
||||
step
|
||||
starters
|
||||
enders)
|
||||
(let ((preds
|
||||
(vector-ref
|
||||
predictors
|
||||
(+ step nb-nts))))
|
||||
(reduce
|
||||
states
|
||||
state
|
||||
state-num
|
||||
conf-set
|
||||
head
|
||||
preds)))
|
||||
(loop))))
|
||||
'#f)))))
|
||||
loop))))))
|
||||
(forward
|
||||
(lambda (starters enders predictors steps nts toks)
|
||||
(let ((nb-toks (vector-length toks)))
|
||||
(let ((nb-confs (vector-length steps)))
|
||||
(let ((states (make-states nb-toks nb-confs)))
|
||||
(let ((goal-starters (vector-ref starters '0)))
|
||||
(conf-set-adjoin* states '0 goal-starters '0)
|
||||
(forw states '0 starters enders predictors steps nts)
|
||||
((letrec ((loop
|
||||
(lambda (i)
|
||||
(if (< i nb-toks)
|
||||
(let ((tok-nts (cdr (vector-ref toks i))))
|
||||
(conf-set-adjoin* states (+ i '1) tok-nts i)
|
||||
(forw
|
||||
states
|
||||
(+ i '1)
|
||||
starters
|
||||
enders
|
||||
predictors
|
||||
steps
|
||||
nts)
|
||||
(loop (+ i '1)))
|
||||
'#f))))
|
||||
loop)
|
||||
'0)
|
||||
states))))))
|
||||
(produce
|
||||
(lambda (conf i j enders steps toks states states* nb-nts)
|
||||
(let ((prev (- conf '1)))
|
||||
(if (if (>= conf nb-nts) (>= (vector-ref steps prev) '0) '#f)
|
||||
((letrec ((loop1
|
||||
(lambda (l)
|
||||
(if (pair? l)
|
||||
(let ((ender (car l)))
|
||||
(let ((ender-set
|
||||
(conf-set-get (vector-ref states j) ender)))
|
||||
(if ender-set
|
||||
((letrec ((loop2
|
||||
(lambda (k)
|
||||
(if (>= k '0)
|
||||
(begin
|
||||
(if (>= k i)
|
||||
(if (conf-set-adjoin**
|
||||
states
|
||||
states*
|
||||
k
|
||||
prev
|
||||
i)
|
||||
(conf-set-adjoin**
|
||||
states
|
||||
states*
|
||||
j
|
||||
ender
|
||||
k)
|
||||
'#f)
|
||||
'#f)
|
||||
(loop2
|
||||
(conf-set-next ender-set k)))
|
||||
(loop1 (cdr l))))))
|
||||
loop2)
|
||||
(conf-set-head ender-set))
|
||||
(loop1 (cdr l)))))
|
||||
'#f))))
|
||||
loop1)
|
||||
(vector-ref enders (vector-ref steps prev)))
|
||||
'#f))))
|
||||
(back
|
||||
(lambda (states states* state-num enders steps nb-nts toks)
|
||||
(let ((state* (vector-ref states* state-num)))
|
||||
((letrec ((loop1
|
||||
(lambda ()
|
||||
(let ((conf (vector-ref state* '0)))
|
||||
(if (>= conf '0)
|
||||
(let ((conf-set (vector-ref state* (+ conf '1))))
|
||||
(let ((head (vector-ref conf-set '4)))
|
||||
(vector-set! state* '0 (vector-ref conf-set '0))
|
||||
(conf-set-merge-new! conf-set)
|
||||
((letrec ((loop2
|
||||
(lambda (i)
|
||||
(if (>= i '0)
|
||||
(begin
|
||||
(produce
|
||||
conf
|
||||
i
|
||||
state-num
|
||||
enders
|
||||
steps
|
||||
toks
|
||||
states
|
||||
states*
|
||||
nb-nts)
|
||||
(loop2
|
||||
(conf-set-next conf-set i)))
|
||||
(loop1)))))
|
||||
loop2)
|
||||
head)))
|
||||
'#f)))))
|
||||
loop1)))))
|
||||
(backward
|
||||
(lambda (states enders steps nts toks)
|
||||
(let ((nb-toks (vector-length toks)))
|
||||
(let ((nb-confs (vector-length steps)))
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
(let ((states* (make-states nb-toks nb-confs)))
|
||||
(let ((goal-enders (vector-ref enders '0)))
|
||||
((letrec ((loop1
|
||||
(lambda (l)
|
||||
(if (pair? l)
|
||||
(let ((conf (car l)))
|
||||
(conf-set-adjoin**
|
||||
states
|
||||
states*
|
||||
nb-toks
|
||||
conf
|
||||
'0)
|
||||
(loop1 (cdr l)))
|
||||
'#f))))
|
||||
loop1)
|
||||
goal-enders)
|
||||
((letrec ((loop2
|
||||
(lambda (i)
|
||||
(if (>= i '0)
|
||||
(begin
|
||||
(back
|
||||
states
|
||||
states*
|
||||
i
|
||||
enders
|
||||
steps
|
||||
nb-nts
|
||||
toks)
|
||||
(loop2 (- i '1)))
|
||||
'#f))))
|
||||
loop2)
|
||||
nb-toks)
|
||||
states*)))))))
|
||||
(parsed?
|
||||
(lambda (nt i j nts enders states)
|
||||
(let ((nt* (ind nt nts)))
|
||||
(if nt*
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
((letrec ((loop
|
||||
(lambda (l)
|
||||
(if (pair? l)
|
||||
(let ((conf (car l)))
|
||||
(if (conf-set-member?
|
||||
(vector-ref states j)
|
||||
conf
|
||||
i)
|
||||
'#t
|
||||
(loop (cdr l))))
|
||||
'#f))))
|
||||
loop)
|
||||
(vector-ref enders nt*)))
|
||||
'#f))))
|
||||
(deriv-trees
|
||||
(lambda (conf i j enders steps names toks states nb-nts)
|
||||
(let ((name (vector-ref names conf)))
|
||||
(if name
|
||||
(if (< conf nb-nts)
|
||||
(list (list name (car (vector-ref toks i))))
|
||||
(list (list name)))
|
||||
(let ((prev (- conf '1)))
|
||||
((letrec ((loop1
|
||||
(lambda (l1 l2)
|
||||
(if (pair? l1)
|
||||
(let ((ender (car l1)))
|
||||
(let ((ender-set
|
||||
(conf-set-get
|
||||
(vector-ref states j)
|
||||
ender)))
|
||||
(if ender-set
|
||||
((letrec ((loop2
|
||||
(lambda (k l2)
|
||||
(if (>= k '0)
|
||||
(if (if (>= k i)
|
||||
(conf-set-member?
|
||||
(vector-ref states k)
|
||||
prev
|
||||
i)
|
||||
'#f)
|
||||
(let ((prev-trees
|
||||
(deriv-trees
|
||||
prev
|
||||
i
|
||||
k
|
||||
enders
|
||||
steps
|
||||
names
|
||||
toks
|
||||
states
|
||||
nb-nts))
|
||||
(ender-trees
|
||||
(deriv-trees
|
||||
ender
|
||||
k
|
||||
j
|
||||
enders
|
||||
steps
|
||||
names
|
||||
toks
|
||||
states
|
||||
nb-nts)))
|
||||
((letrec ((loop3
|
||||
(lambda (l3 l2)
|
||||
(if (pair? l3)
|
||||
(let ((ender-tree
|
||||
(list
|
||||
(car
|
||||
l3))))
|
||||
((letrec ((loop4
|
||||
(lambda (l4
|
||||
l2)
|
||||
(if (pair?
|
||||
l4)
|
||||
(loop4
|
||||
(cdr
|
||||
l4)
|
||||
(cons
|
||||
(append
|
||||
(car
|
||||
l4)
|
||||
ender-tree)
|
||||
l2))
|
||||
(loop3
|
||||
(cdr
|
||||
l3)
|
||||
l2)))))
|
||||
loop4)
|
||||
prev-trees
|
||||
l2))
|
||||
(loop2
|
||||
(conf-set-next
|
||||
ender-set
|
||||
k)
|
||||
l2)))))
|
||||
loop3)
|
||||
ender-trees
|
||||
l2))
|
||||
(loop2
|
||||
(conf-set-next ender-set k)
|
||||
l2))
|
||||
(loop1 (cdr l1) l2)))))
|
||||
loop2)
|
||||
(conf-set-head ender-set)
|
||||
l2)
|
||||
(loop1 (cdr l1) l2))))
|
||||
l2))))
|
||||
loop1)
|
||||
(vector-ref enders (vector-ref steps prev))
|
||||
'()))))))
|
||||
(deriv-trees*
|
||||
(lambda (nt i j nts enders steps names toks states)
|
||||
(let ((nt* (ind nt nts)))
|
||||
(if nt*
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
((letrec ((loop
|
||||
(lambda (l trees)
|
||||
(if (pair? l)
|
||||
(let ((conf (car l)))
|
||||
(if (conf-set-member?
|
||||
(vector-ref states j)
|
||||
conf
|
||||
i)
|
||||
(loop
|
||||
(cdr l)
|
||||
(append
|
||||
(deriv-trees
|
||||
conf
|
||||
i
|
||||
j
|
||||
enders
|
||||
steps
|
||||
names
|
||||
toks
|
||||
states
|
||||
nb-nts)
|
||||
trees))
|
||||
(loop (cdr l) trees)))
|
||||
trees))))
|
||||
loop)
|
||||
(vector-ref enders nt*)
|
||||
'()))
|
||||
'#f))))
|
||||
(nb-deriv-trees
|
||||
(lambda (conf i j enders steps toks states nb-nts)
|
||||
(let ((prev (- conf '1)))
|
||||
(if (let ((or-part (< conf nb-nts)))
|
||||
(if or-part or-part (< (vector-ref steps prev) '0)))
|
||||
'1
|
||||
((letrec ((loop1
|
||||
(lambda (l n)
|
||||
(if (pair? l)
|
||||
(let ((ender (car l)))
|
||||
(let ((ender-set
|
||||
(conf-set-get (vector-ref states j) ender)))
|
||||
(if ender-set
|
||||
((letrec ((loop2
|
||||
(lambda (k n)
|
||||
(if (>= k '0)
|
||||
(if (if (>= k i)
|
||||
(conf-set-member?
|
||||
(vector-ref states k)
|
||||
prev
|
||||
i)
|
||||
'#f)
|
||||
(let ((nb-prev-trees
|
||||
(nb-deriv-trees
|
||||
prev
|
||||
i
|
||||
k
|
||||
enders
|
||||
steps
|
||||
toks
|
||||
states
|
||||
nb-nts))
|
||||
(nb-ender-trees
|
||||
(nb-deriv-trees
|
||||
ender
|
||||
k
|
||||
j
|
||||
enders
|
||||
steps
|
||||
toks
|
||||
states
|
||||
nb-nts)))
|
||||
(loop2
|
||||
(conf-set-next ender-set k)
|
||||
(+
|
||||
n
|
||||
(*
|
||||
nb-prev-trees
|
||||
nb-ender-trees))))
|
||||
(loop2
|
||||
(conf-set-next ender-set k)
|
||||
n))
|
||||
(loop1 (cdr l) n)))))
|
||||
loop2)
|
||||
(conf-set-head ender-set)
|
||||
n)
|
||||
(loop1 (cdr l) n))))
|
||||
n))))
|
||||
loop1)
|
||||
(vector-ref enders (vector-ref steps prev))
|
||||
'0)))))
|
||||
(nb-deriv-trees*
|
||||
(lambda (nt i j nts enders steps toks states)
|
||||
(let ((nt* (ind nt nts)))
|
||||
(if nt*
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
((letrec ((loop
|
||||
(lambda (l nb-trees)
|
||||
(if (pair? l)
|
||||
(let ((conf (car l)))
|
||||
(if (conf-set-member?
|
||||
(vector-ref states j)
|
||||
conf
|
||||
i)
|
||||
(loop
|
||||
(cdr l)
|
||||
(+
|
||||
(nb-deriv-trees
|
||||
conf
|
||||
i
|
||||
j
|
||||
enders
|
||||
steps
|
||||
toks
|
||||
states
|
||||
nb-nts)
|
||||
nb-trees))
|
||||
(loop (cdr l) nb-trees)))
|
||||
nb-trees))))
|
||||
loop)
|
||||
(vector-ref enders nt*)
|
||||
'0))
|
||||
'#f)))))
|
||||
(let ((lexer (vector-ref parser-descr '0)))
|
||||
(let ((nts (vector-ref parser-descr '1)))
|
||||
(let ((starters (vector-ref parser-descr '2)))
|
||||
(let ((enders (vector-ref parser-descr '3)))
|
||||
(let ((predictors (vector-ref parser-descr '4)))
|
||||
(let ((steps (vector-ref parser-descr '5)))
|
||||
(let ((names (vector-ref parser-descr '6)))
|
||||
(let ((toks (input->tokens input lexer nts)))
|
||||
(vector
|
||||
nts
|
||||
starters
|
||||
enders
|
||||
predictors
|
||||
steps
|
||||
names
|
||||
toks
|
||||
(backward
|
||||
(forward starters enders predictors steps nts toks)
|
||||
enders
|
||||
steps
|
||||
nts
|
||||
toks)
|
||||
parsed?
|
||||
deriv-trees*
|
||||
nb-deriv-trees*))))))))))))))))))))))))
|
||||
(define parse->parsed?
|
||||
(lambda (parse nt i j)
|
||||
(let ((nts (vector-ref parse '0)))
|
||||
(let ((enders (vector-ref parse '2)))
|
||||
(let ((states (vector-ref parse '7)))
|
||||
(let ((parsed? (vector-ref parse '8))) (parsed? nt i j nts enders states)))))))
|
||||
(define parse->trees
|
||||
(lambda (parse nt i j)
|
||||
(let ((nts (vector-ref parse '0)))
|
||||
(let ((enders (vector-ref parse '2)))
|
||||
(let ((steps (vector-ref parse '4)))
|
||||
(let ((names (vector-ref parse '5)))
|
||||
(let ((toks (vector-ref parse '6)))
|
||||
(let ((states (vector-ref parse '7)))
|
||||
(let ((deriv-trees* (vector-ref parse '9)))
|
||||
(deriv-trees* nt i j nts enders steps names toks states))))))))))
|
||||
(define parse->nb-trees
|
||||
(lambda (parse nt i j)
|
||||
(let ((nts (vector-ref parse '0)))
|
||||
(let ((enders (vector-ref parse '2)))
|
||||
(let ((steps (vector-ref parse '4)))
|
||||
(let ((toks (vector-ref parse '6)))
|
||||
(let ((states (vector-ref parse '7)))
|
||||
(let ((nb-deriv-trees* (vector-ref parse '10)))
|
||||
(nb-deriv-trees* nt i j nts enders steps toks states)))))))))
|
||||
(define test
|
||||
(lambda (k)
|
||||
(let ((p (make-parser '((s (a) (s s)))
|
||||
(lambda (l)
|
||||
(map (lambda (x) (list x x)) l)))))
|
||||
(let ((x (p (vector->list (make-vector k 'a)))))
|
||||
(display (length (parse->trees x 's '0 k)))
|
||||
(newline)))))
|
||||
(test '12))
|
|
@ -45,11 +45,12 @@
|
|||
"(function() { "
|
||||
|
||||
runtime
|
||||
"var RUNTIME = plt.runtime;"
|
||||
"var MACHINE = new plt.runtime.Machine();\n"
|
||||
|
||||
"return function(success, fail, params){"
|
||||
snippet
|
||||
(format "success(String(~a)); };" inspector)
|
||||
(format "success(plt.runtime.toDisplayedString(~a)); };" inspector)
|
||||
"});")])
|
||||
(displayln snippet)
|
||||
(display code op))))))
|
||||
|
@ -63,6 +64,7 @@
|
|||
[inspector (cdr a-statement+inspector)])
|
||||
|
||||
(display runtime op)
|
||||
"var RUNTIME = plt.runtime;"
|
||||
(display "var MACHINE = new plt.runtime.Machine();\n" op)
|
||||
(display "(function() { " op)
|
||||
(display "var myInvoke = " op)
|
||||
|
@ -70,7 +72,7 @@
|
|||
(display ";" op)
|
||||
|
||||
(fprintf op
|
||||
"return function(succ, fail, params) { myInvoke(MACHINE, function(v) { succ(String(~a));}, fail, params); }"
|
||||
"return function(succ, fail, params) { myInvoke(MACHINE, function(v) { succ(plt.runtime.toDisplayedString(~a));}, fail, params); }"
|
||||
inspector)
|
||||
(display "})" op))))))
|
||||
(define (E-many stmts (inspector "MACHINE.val"))
|
||||
|
@ -91,13 +93,13 @@
|
|||
"Danny")
|
||||
;; Assigning a cons
|
||||
(test (E-single (make-AssignImmediateStatement 'val (make-Const (cons 1 2))))
|
||||
"1,2")
|
||||
"(1 . 2)")
|
||||
;; Assigning a void
|
||||
(test (E-single (make-AssignImmediateStatement 'val (make-Const (void))))
|
||||
"null")
|
||||
"#<void>")
|
||||
;; Assigning to proc means val should still be uninitialized.
|
||||
(test (E-single (make-AssignImmediateStatement 'proc (make-Const "Danny")))
|
||||
"undefined")
|
||||
"#<undefined>")
|
||||
;; But we should see the assignment if we inspect MACHINE.proc.
|
||||
(test (E-single (make-AssignImmediateStatement 'proc (make-Const "Danny"))
|
||||
"MACHINE.proc")
|
||||
|
@ -133,7 +135,7 @@
|
|||
(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f)
|
||||
(make-Const 12345)))
|
||||
"MACHINE.env[0]")
|
||||
"undefined")
|
||||
"#<undefined>")
|
||||
(test (E-many (list (make-PushEnvironment 2 #f)
|
||||
(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f)
|
||||
(make-Const 12345)))
|
||||
|
@ -143,7 +145,7 @@
|
|||
|
||||
;; Toplevel Environment loading
|
||||
(test (E-single (make-PerformStatement (make-ExtendEnvironment/Prefix! '(pi)))
|
||||
"String(MACHINE.env[0]).slice(0, 5)")
|
||||
"plt.runtime.toWrittenString(MACHINE.env[0]).slice(0, 5)")
|
||||
"3.141")
|
||||
|
||||
|
||||
|
@ -210,7 +212,7 @@
|
|||
(make-Const 0))
|
||||
(make-GotoStatement (make-Label 'closureStart))
|
||||
'theEnd)
|
||||
"String(MACHINE.env.length) + ',' + MACHINE.env[1] + ',' + MACHINE.env[0]")
|
||||
"plt.runtime.toWrittenString(MACHINE.env.length) + ',' + MACHINE.env[1] + ',' + MACHINE.env[0]")
|
||||
"2,hello,world")
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#lang racket
|
||||
(require "browser-evaluate.rkt"
|
||||
"../js-assembler/package.rkt"
|
||||
"../make-structs.rkt")
|
||||
"../make/make-structs.rkt")
|
||||
|
||||
(printf "test-browser-evaluate.rkt\n")
|
||||
|
||||
|
||||
(define should-follow? (lambda (src p) #t))
|
||||
(define should-follow? (lambda (src) #t))
|
||||
|
||||
(define evaluate (make-evaluate
|
||||
(lambda (program op)
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
(fprintf op "var innerInvoke = ")
|
||||
(package-anonymous (make-SexpSource program)
|
||||
#:should-follow? should-follow?
|
||||
#:should-follow-children? should-follow?
|
||||
#:output-port op)
|
||||
(fprintf op "();\n")
|
||||
|
||||
|
@ -63,7 +63,7 @@ EOF
|
|||
(let ([r (evaluate s)])
|
||||
(raise-syntax-error #f (format "Expected exception, but got ~s" r)
|
||||
#'stx)))])
|
||||
(unless (string=? exp (error-happened-str an-error-happened))
|
||||
(unless (regexp-match (regexp-quote exp) (error-happened-str an-error-happened))
|
||||
(printf " error!\n")
|
||||
(raise-syntax-error #f (format "Expected ~s, got ~s" exp (error-happened-str an-error-happened))
|
||||
#'stx))
|
||||
|
@ -99,20 +99,21 @@ EOF
|
|||
"7")
|
||||
|
||||
(test/exn (evaluate '(+ "hello" 3))
|
||||
"Error: +: expected number as argument 1 but received hello")
|
||||
"Error: +: expected number as argument 1 but received \"hello\"")
|
||||
|
||||
|
||||
(test '(display (/ 100 4))
|
||||
"25")
|
||||
;; fixme: symbols need to be represented separately from strings.
|
||||
(test/exn (evaluate '(/ 3 'four))
|
||||
"Error: /: expected number as argument 2 but received four")
|
||||
"Error: /: expected number as argument 2 but received \"four\"")
|
||||
|
||||
|
||||
(test '(display (- 1))
|
||||
"-1")
|
||||
|
||||
(test/exn '(- 'one)
|
||||
"Error: -: expected number as argument 1 but received one")
|
||||
"Error: -: expected number as argument 1 but received \"one\"")
|
||||
|
||||
(test '(display (- 5 4))
|
||||
"1")
|
||||
|
@ -121,7 +122,7 @@ EOF
|
|||
"51")
|
||||
|
||||
(test/exn '(* "three" 17)
|
||||
"Error: *: expected number as argument 1 but received three")
|
||||
"Error: *: expected number as argument 1 but received \"three\"")
|
||||
|
||||
(test '(display '#t)
|
||||
"true")
|
||||
|
@ -154,13 +155,13 @@ EOF
|
|||
|
||||
|
||||
(test/exn '(displayln (add1 "0"))
|
||||
"Error: add1: expected number as argument 1 but received 0")
|
||||
"Error: add1: expected number as argument 1 but received \"0\"")
|
||||
|
||||
(test '(displayln (sub1 1))
|
||||
"0\n")
|
||||
|
||||
(test/exn '(displayln (sub1 "0"))
|
||||
"Error: sub1: expected number as argument 1 but received 0")
|
||||
"Error: sub1: expected number as argument 1 but received \"0\"")
|
||||
|
||||
(test '(displayln (< 1 2))
|
||||
"true\n")
|
||||
|
@ -381,7 +382,7 @@ EOF
|
|||
(test/exn '(let ([x 0])
|
||||
(set! x "foo")
|
||||
(add1 x))
|
||||
"Error: add1: expected number as argument 1 but received foo")
|
||||
"Error: add1: expected number as argument 1 but received \"foo\"")
|
||||
|
||||
|
||||
|
||||
|
@ -479,6 +480,31 @@ EOF
|
|||
"false\n")
|
||||
|
||||
|
||||
;;(test '(displayln 2/3)
|
||||
;; "2/3\n")
|
||||
|
||||
|
||||
;;(test '(displayln -2/3)
|
||||
;; "-2/3\n")
|
||||
|
||||
|
||||
(test '(displayln -0.0)
|
||||
"-0.0\n")
|
||||
|
||||
(test '(displayln +nan.0)
|
||||
"+nan.0\n")
|
||||
|
||||
(test '(displayln +inf.0)
|
||||
"+inf.0\n")
|
||||
|
||||
(test '(displayln -inf.0)
|
||||
"-inf.0\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;; Knuth's Man-or-boy-test.
|
||||
|
|
|
@ -1368,7 +1368,6 @@
|
|||
20116)
|
||||
|
||||
|
||||
|
||||
(test '(let () (define (f x y z)
|
||||
(values y x z))
|
||||
(call-with-values (lambda () (f 3 1 4))
|
||||
|
@ -1376,6 +1375,7 @@
|
|||
'((1 3 4))
|
||||
#:with-bootstrapping? #t)
|
||||
|
||||
|
||||
(test '(let () (define (f x y z)
|
||||
(begin0 (values y x z)
|
||||
(display "")))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#lang racket
|
||||
(require "browser-evaluate.rkt"
|
||||
"../js-assembler/package.rkt"
|
||||
"../make-structs.rkt"
|
||||
"../make/make-structs.rkt"
|
||||
racket/port
|
||||
racket/runtime-path)
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
|||
|
||||
(fprintf op "var innerInvoke = ")
|
||||
(package-anonymous (make-SexpSource program)
|
||||
#:should-follow? (lambda (src p) #t)
|
||||
#:should-follow-children? (lambda (src) #t)
|
||||
#:output-port op)
|
||||
(fprintf op "();\n")
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#lang racket
|
||||
(require "browser-evaluate.rkt"
|
||||
"../js-assembler/package.rkt"
|
||||
"../make-structs.rkt"
|
||||
"../make/make-structs.rkt"
|
||||
racket/port
|
||||
racket/runtime-path
|
||||
racket/runtime-path
|
||||
|
@ -23,7 +23,7 @@
|
|||
|
||||
(fprintf op "var innerInvoke = ")
|
||||
(package-anonymous (make-SexpSource program)
|
||||
#:should-follow? (lambda (src path) #t)
|
||||
#:should-follow-children? (lambda (src) #t)
|
||||
#:output-port op)
|
||||
(fprintf op "();\n")
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#lang racket
|
||||
(require "../get-dependencies.rkt"
|
||||
(require "../make/get-dependencies.rkt"
|
||||
"../get-module-bytecode.rkt"
|
||||
"../parser/parse-bytecode.rkt"
|
||||
"../compiler/lexical-structs.rkt"
|
||||
|
@ -11,7 +11,7 @@
|
|||
|
||||
|
||||
(define-runtime-path get-dependencies-path
|
||||
(build-path ".." "get-dependencies.rkt"))
|
||||
(build-path ".." "make" "get-dependencies.rkt"))
|
||||
(define-runtime-path get-module-bytecode-path
|
||||
(build-path ".." "get-module-bytecode.rkt"))
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../js-assembler/package.rkt"
|
||||
"../make-structs.rkt")
|
||||
"../make/make-structs.rkt")
|
||||
|
||||
(printf "test-package.rkt\n")
|
||||
|
||||
|
||||
(define (follow? src p)
|
||||
(define (follow? src)
|
||||
#t)
|
||||
|
||||
(define (test s-exp)
|
||||
(package (make-SexpSource s-exp)
|
||||
#:should-follow? follow?
|
||||
#:should-follow-children? follow?
|
||||
#:output-port (open-output-string) #;(current-output-port)))
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
(require racket/list
|
||||
racket/string
|
||||
"make-structs.rkt"
|
||||
"make/make-structs.rkt"
|
||||
"js-assembler/package.rkt")
|
||||
|
||||
|
||||
|
|
3
world.rkt
Normal file
3
world.rkt
Normal file
|
@ -0,0 +1,3 @@
|
|||
#lang s-exp "lang/base.rkt"
|
||||
(require "world/main.rkt")
|
||||
(provide (all-from-out "world/main.rkt"))
|
205
world/colordb.js
Normal file
205
world/colordb.js
Normal file
|
@ -0,0 +1,205 @@
|
|||
// Color database
|
||||
var ColorDb = function() {
|
||||
this.colors = {};
|
||||
};
|
||||
|
||||
var types = plt.types;
|
||||
|
||||
|
||||
ColorDb.prototype.put = function(name, color) {
|
||||
this.colors[name] = color;
|
||||
};
|
||||
|
||||
ColorDb.prototype.get = function(name) {
|
||||
return this.colors[name.toString().toUpperCase()];
|
||||
};
|
||||
|
||||
|
||||
// FIXME: update toString to handle the primitive field values.
|
||||
|
||||
var colorDb = new ColorDb();
|
||||
colorDb.put("ORANGE", types.color(255, 165, 0));
|
||||
colorDb.put("RED", types.color(255, 0, 0));
|
||||
colorDb.put("ORANGERED", types.color(255, 69, 0));
|
||||
colorDb.put("TOMATO", types.color(255, 99, 71));
|
||||
colorDb.put("DARKRED", types.color(139, 0, 0));
|
||||
colorDb.put("RED", types.color(255, 0, 0));
|
||||
colorDb.put("FIREBRICK", types.color(178, 34, 34));
|
||||
colorDb.put("CRIMSON", types.color(220, 20, 60));
|
||||
colorDb.put("DEEPPINK", types.color(255, 20, 147));
|
||||
colorDb.put("MAROON", types.color(176, 48, 96));
|
||||
colorDb.put("INDIAN RED", types.color(205, 92, 92));
|
||||
colorDb.put("INDIANRED", types.color(205, 92, 92));
|
||||
colorDb.put("MEDIUM VIOLET RED", types.color(199, 21, 133));
|
||||
colorDb.put("MEDIUMVIOLETRED", types.color(199, 21, 133));
|
||||
colorDb.put("VIOLET RED", types.color(208, 32, 144));
|
||||
colorDb.put("VIOLETRED", types.color(208, 32, 144));
|
||||
colorDb.put("LIGHTCORAL", types.color(240, 128, 128));
|
||||
colorDb.put("HOTPINK", types.color(255, 105, 180));
|
||||
colorDb.put("PALEVIOLETRED", types.color(219, 112, 147));
|
||||
colorDb.put("LIGHTPINK", types.color(255, 182, 193));
|
||||
colorDb.put("ROSYBROWN", types.color(188, 143, 143));
|
||||
colorDb.put("PINK", types.color(255, 192, 203));
|
||||
colorDb.put("ORCHID", types.color(218, 112, 214));
|
||||
colorDb.put("LAVENDERBLUSH", types.color(255, 240, 245));
|
||||
colorDb.put("SNOW", types.color(255, 250, 250));
|
||||
colorDb.put("CHOCOLATE", types.color(210, 105, 30));
|
||||
colorDb.put("SADDLEBROWN", types.color(139, 69, 19));
|
||||
colorDb.put("BROWN", types.color(132, 60, 36));
|
||||
colorDb.put("DARKORANGE", types.color(255, 140, 0));
|
||||
colorDb.put("CORAL", types.color(255, 127, 80));
|
||||
colorDb.put("SIENNA", types.color(160, 82, 45));
|
||||
colorDb.put("ORANGE", types.color(255, 165, 0));
|
||||
colorDb.put("SALMON", types.color(250, 128, 114));
|
||||
colorDb.put("PERU", types.color(205, 133, 63));
|
||||
colorDb.put("DARKGOLDENROD", types.color(184, 134, 11));
|
||||
colorDb.put("GOLDENROD", types.color(218, 165, 32));
|
||||
colorDb.put("SANDYBROWN", types.color(244, 164, 96));
|
||||
colorDb.put("LIGHTSALMON", types.color(255, 160, 122));
|
||||
colorDb.put("DARKSALMON", types.color(233, 150, 122));
|
||||
colorDb.put("GOLD", types.color(255, 215, 0));
|
||||
colorDb.put("YELLOW", types.color(255, 255, 0));
|
||||
colorDb.put("OLIVE", types.color(128, 128, 0));
|
||||
colorDb.put("BURLYWOOD", types.color(222, 184, 135));
|
||||
colorDb.put("TAN", types.color(210, 180, 140));
|
||||
colorDb.put("NAVAJOWHITE", types.color(255, 222, 173));
|
||||
colorDb.put("PEACHPUFF", types.color(255, 218, 185));
|
||||
colorDb.put("KHAKI", types.color(240, 230, 140));
|
||||
colorDb.put("DARKKHAKI", types.color(189, 183, 107));
|
||||
colorDb.put("MOCCASIN", types.color(255, 228, 181));
|
||||
colorDb.put("WHEAT", types.color(245, 222, 179));
|
||||
colorDb.put("BISQUE", types.color(255, 228, 196));
|
||||
colorDb.put("PALEGOLDENROD", types.color(238, 232, 170));
|
||||
colorDb.put("BLANCHEDALMOND", types.color(255, 235, 205));
|
||||
colorDb.put("MEDIUM GOLDENROD", types.color(234, 234, 173));
|
||||
colorDb.put("MEDIUMGOLDENROD", types.color(234, 234, 173));
|
||||
colorDb.put("PAPAYAWHIP", types.color(255, 239, 213));
|
||||
colorDb.put("MISTYROSE", types.color(255, 228, 225));
|
||||
colorDb.put("LEMONCHIFFON", types.color(255, 250, 205));
|
||||
colorDb.put("ANTIQUEWHITE", types.color(250, 235, 215));
|
||||
colorDb.put("CORNSILK", types.color(255, 248, 220));
|
||||
colorDb.put("LIGHTGOLDENRODYELLOW", types.color(250, 250, 210));
|
||||
colorDb.put("OLDLACE", types.color(253, 245, 230));
|
||||
colorDb.put("LINEN", types.color(250, 240, 230));
|
||||
colorDb.put("LIGHTYELLOW", types.color(255, 255, 224));
|
||||
colorDb.put("SEASHELL", types.color(255, 245, 238));
|
||||
colorDb.put("BEIGE", types.color(245, 245, 220));
|
||||
colorDb.put("FLORALWHITE", types.color(255, 250, 240));
|
||||
colorDb.put("IVORY", types.color(255, 255, 240));
|
||||
colorDb.put("GREEN", types.color(0, 255, 0));
|
||||
colorDb.put("LAWNGREEN", types.color(124, 252, 0));
|
||||
colorDb.put("CHARTREUSE", types.color(127, 255, 0));
|
||||
colorDb.put("GREEN YELLOW", types.color(173, 255, 47));
|
||||
colorDb.put("GREENYELLOW", types.color(173, 255, 47));
|
||||
colorDb.put("YELLOW GREEN", types.color(154, 205, 50));
|
||||
colorDb.put("YELLOWGREEN", types.color(154, 205, 50));
|
||||
colorDb.put("MEDIUM FOREST GREEN", types.color(107, 142, 35));
|
||||
colorDb.put("OLIVEDRAB", types.color(107, 142, 35));
|
||||
colorDb.put("MEDIUMFORESTGREEN", types.color(107, 142, 35));
|
||||
colorDb.put("DARK OLIVE GREEN", types.color(85, 107, 47));
|
||||
colorDb.put("DARKOLIVEGREEN", types.color(85, 107, 47));
|
||||
colorDb.put("DARKSEAGREEN", types.color(143, 188, 139));
|
||||
colorDb.put("LIME", types.color(0, 255, 0));
|
||||
colorDb.put("DARK GREEN", types.color(0, 100, 0));
|
||||
colorDb.put("DARKGREEN", types.color(0, 100, 0));
|
||||
colorDb.put("LIME GREEN", types.color(50, 205, 50));
|
||||
colorDb.put("LIMEGREEN", types.color(50, 205, 50));
|
||||
colorDb.put("FOREST GREEN", types.color(34, 139, 34));
|
||||
colorDb.put("FORESTGREEN", types.color(34, 139, 34));
|
||||
colorDb.put("SPRING GREEN", types.color(0, 255, 127));
|
||||
colorDb.put("SPRINGGREEN", types.color(0, 255, 127));
|
||||
colorDb.put("MEDIUM SPRING GREEN", types.color(0, 250, 154));
|
||||
colorDb.put("MEDIUMSPRINGGREEN", types.color(0, 250, 154));
|
||||
colorDb.put("SEA GREEN", types.color(46, 139, 87));
|
||||
colorDb.put("SEAGREEN", types.color(46, 139, 87));
|
||||
colorDb.put("MEDIUM SEA GREEN", types.color(60, 179, 113));
|
||||
colorDb.put("MEDIUMSEAGREEN", types.color(60, 179, 113));
|
||||
colorDb.put("AQUAMARINE", types.color(112, 216, 144));
|
||||
colorDb.put("LIGHTGREEN", types.color(144, 238, 144));
|
||||
colorDb.put("PALE GREEN", types.color(152, 251, 152));
|
||||
colorDb.put("PALEGREEN", types.color(152, 251, 152));
|
||||
colorDb.put("MEDIUM AQUAMARINE", types.color(102, 205, 170));
|
||||
colorDb.put("MEDIUMAQUAMARINE", types.color(102, 205, 170));
|
||||
colorDb.put("TURQUOISE", types.color(64, 224, 208));
|
||||
colorDb.put("LIGHTSEAGREEN", types.color(32, 178, 170));
|
||||
colorDb.put("MEDIUM TURQUOISE", types.color(72, 209, 204));
|
||||
colorDb.put("MEDIUMTURQUOISE", types.color(72, 209, 204));
|
||||
colorDb.put("HONEYDEW", types.color(240, 255, 240));
|
||||
colorDb.put("MINTCREAM", types.color(245, 255, 250));
|
||||
colorDb.put("ROYALBLUE", types.color(65, 105, 225));
|
||||
colorDb.put("DODGERBLUE", types.color(30, 144, 255));
|
||||
colorDb.put("DEEPSKYBLUE", types.color(0, 191, 255));
|
||||
colorDb.put("CORNFLOWERBLUE", types.color(100, 149, 237));
|
||||
colorDb.put("STEEL BLUE", types.color(70, 130, 180));
|
||||
colorDb.put("STEELBLUE", types.color(70, 130, 180));
|
||||
colorDb.put("LIGHTSKYBLUE", types.color(135, 206, 250));
|
||||
colorDb.put("DARK TURQUOISE", types.color(0, 206, 209));
|
||||
colorDb.put("DARKTURQUOISE", types.color(0, 206, 209));
|
||||
colorDb.put("CYAN", types.color(0, 255, 255));
|
||||
colorDb.put("AQUA", types.color(0, 255, 255));
|
||||
colorDb.put("DARKCYAN", types.color(0, 139, 139));
|
||||
colorDb.put("TEAL", types.color(0, 128, 128));
|
||||
colorDb.put("SKY BLUE", types.color(135, 206, 235));
|
||||
colorDb.put("SKYBLUE", types.color(135, 206, 235));
|
||||
colorDb.put("CADET BLUE", types.color(96, 160, 160));
|
||||
colorDb.put("CADETBLUE", types.color(95, 158, 160));
|
||||
colorDb.put("DARK SLATE GRAY", types.color(47, 79, 79));
|
||||
colorDb.put("DARKSLATEGRAY", types.color(47, 79, 79));
|
||||
colorDb.put("LIGHTSLATEGRAY", types.color(119, 136, 153));
|
||||
colorDb.put("SLATEGRAY", types.color(112, 128, 144));
|
||||
colorDb.put("LIGHT STEEL BLUE", types.color(176, 196, 222));
|
||||
colorDb.put("LIGHTSTEELBLUE", types.color(176, 196, 222));
|
||||
colorDb.put("LIGHT BLUE", types.color(173, 216, 230));
|
||||
colorDb.put("LIGHTBLUE", types.color(173, 216, 230));
|
||||
colorDb.put("POWDERBLUE", types.color(176, 224, 230));
|
||||
colorDb.put("PALETURQUOISE", types.color(175, 238, 238));
|
||||
colorDb.put("LIGHTCYAN", types.color(224, 255, 255));
|
||||
colorDb.put("ALICEBLUE", types.color(240, 248, 255));
|
||||
colorDb.put("AZURE", types.color(240, 255, 255));
|
||||
colorDb.put("MEDIUM BLUE", types.color(0, 0, 205));
|
||||
colorDb.put("MEDIUMBLUE", types.color(0, 0, 205));
|
||||
colorDb.put("DARKBLUE", types.color(0, 0, 139));
|
||||
colorDb.put("MIDNIGHT BLUE", types.color(25, 25, 112));
|
||||
colorDb.put("MIDNIGHTBLUE", types.color(25, 25, 112));
|
||||
colorDb.put("NAVY", types.color(36, 36, 140));
|
||||
colorDb.put("BLUE", types.color(0, 0, 255));
|
||||
colorDb.put("INDIGO", types.color(75, 0, 130));
|
||||
colorDb.put("BLUE VIOLET", types.color(138, 43, 226));
|
||||
colorDb.put("BLUEVIOLET", types.color(138, 43, 226));
|
||||
colorDb.put("MEDIUM SLATE BLUE", types.color(123, 104, 238));
|
||||
colorDb.put("MEDIUMSLATEBLUE", types.color(123, 104, 238));
|
||||
colorDb.put("SLATE BLUE", types.color(106, 90, 205));
|
||||
colorDb.put("SLATEBLUE", types.color(106, 90, 205));
|
||||
colorDb.put("PURPLE", types.color(160, 32, 240));
|
||||
colorDb.put("DARK SLATE BLUE", types.color(72, 61, 139));
|
||||
colorDb.put("DARKSLATEBLUE", types.color(72, 61, 139));
|
||||
colorDb.put("DARKVIOLET", types.color(148, 0, 211));
|
||||
colorDb.put("DARK ORCHID", types.color(153, 50, 204));
|
||||
colorDb.put("DARKORCHID", types.color(153, 50, 204));
|
||||
colorDb.put("MEDIUMPURPLE", types.color(147, 112, 219));
|
||||
colorDb.put("CORNFLOWER BLUE", types.color(68, 64, 108));
|
||||
colorDb.put("MEDIUM ORCHID", types.color(186, 85, 211));
|
||||
colorDb.put("MEDIUMORCHID", types.color(186, 85, 211));
|
||||
colorDb.put("MAGENTA", types.color(255, 0, 255));
|
||||
colorDb.put("FUCHSIA", types.color(255, 0, 255));
|
||||
colorDb.put("DARKMAGENTA", types.color(139, 0, 139));
|
||||
colorDb.put("VIOLET", types.color(238, 130, 238));
|
||||
colorDb.put("PLUM", types.color(221, 160, 221));
|
||||
colorDb.put("LAVENDER", types.color(230, 230, 250));
|
||||
colorDb.put("THISTLE", types.color(216, 191, 216));
|
||||
colorDb.put("GHOSTWHITE", types.color(248, 248, 255));
|
||||
colorDb.put("WHITE", types.color(255, 255, 255));
|
||||
colorDb.put("WHITESMOKE", types.color(245, 245, 245));
|
||||
colorDb.put("GAINSBORO", types.color(220, 220, 220));
|
||||
colorDb.put("LIGHT GRAY", types.color(211, 211, 211));
|
||||
colorDb.put("LIGHTGRAY", types.color(211, 211, 211));
|
||||
colorDb.put("SILVER", types.color(192, 192, 192));
|
||||
colorDb.put("GRAY", types.color(190, 190, 190));
|
||||
colorDb.put("DARK GRAY", types.color(169, 169, 169));
|
||||
colorDb.put("DARKGRAY", types.color(169, 169, 169));
|
||||
colorDb.put("DIM GRAY", types.color(105, 105, 105));
|
||||
colorDb.put("DIMGRAY", types.color(105, 105, 105));
|
||||
colorDb.put("BLACK", types.color(0, 0, 0));
|
||||
|
||||
|
||||
EXPORTS['_colorDb'] = colorDb;
|
11
world/js-impl.js
Normal file
11
world/js-impl.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
EXPORTS['is-color?'] =
|
||||
plt.runtime.makePrimitiveProcedure(
|
||||
'is-color?',
|
||||
1,
|
||||
function(MACHINE) {
|
||||
var elt = MACHINE.env[MACHINE.env.length - 1];
|
||||
return (//(plt.runtime.isString(elt) || plt.runtime.isSymbol(elt)) &&
|
||||
typeof(colorDb.get(elt)) != 'undefined');
|
||||
});
|
1739
world/kernel.js
Normal file
1739
world/kernel.js
Normal file
File diff suppressed because it is too large
Load Diff
8
world/main.rkt
Normal file
8
world/main.rkt
Normal file
|
@ -0,0 +1,8 @@
|
|||
#lang s-exp "../lang/js/js.rkt"
|
||||
|
||||
(declare-implementation
|
||||
#:racket "racket-impl.rkt"
|
||||
#:javascript ("colordb.js"
|
||||
"kernel.js"
|
||||
"js-impl.js")
|
||||
#:provided-values (is-color?))
|
6
world/racket-impl.rkt
Normal file
6
world/racket-impl.rkt
Normal file
|
@ -0,0 +1,6 @@
|
|||
#lang s-exp "../lang/base.rkt"
|
||||
|
||||
(provide is-color?)
|
||||
|
||||
(define (is-color? x)
|
||||
true)
|
Loading…
Reference in New Issue
Block a user