diff --git a/NOTES b/NOTES index 2e949a3..3e6487e 100644 --- a/NOTES +++ b/NOTES @@ -728,6 +728,8 @@ Working out the type mappings between values in Racket and values in JavaScript case-lambda + undefined undefined + void plt.runtime.VOID ---------------------------------------------------------------------- diff --git a/js-assembler/assemble-helpers.rkt b/js-assembler/assemble-helpers.rkt index d2647ce..76911cd 100644 --- a/js-assembler/assemble-helpers.rkt +++ b/js-assembler/assemble-helpers.rkt @@ -107,7 +107,7 @@ [(boolean? val) (if val "true" "false")] [(void? val) - "null"] + "RUNTIME.VOID"] [(empty? val) (format "RUNTIME.NULL")] [(number? val) diff --git a/js-assembler/runtime-src/helpers.js b/js-assembler/runtime-src/helpers.js index b7ac741..bbd363d 100644 --- a/js-assembler/runtime-src/helpers.js +++ b/js-assembler/runtime-src/helpers.js @@ -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 "#"; } 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 "#"; } @@ -689,6 +692,12 @@ if (! this['plt']) { this['plt'] = {}; } if (jsnums.isSchemeNumber(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 (params.containsKey(x)) { diff --git a/js-assembler/runtime-src/runtime.js b/js-assembler/runtime-src/runtime.js index 54e6bf7..bfe263d 100644 --- a/js-assembler/runtime-src/runtime.js +++ b/js-assembler/runtime-src/runtime.js @@ -34,6 +34,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } var isList = types.isList; var isVector = types.isVector; var NULL = types.EMPTY; + var VOID = types.VOID; var makeVector = types.vector; var makeList = types.list; @@ -41,6 +42,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } var heir = helpers.heir; var toDomNode = helpers.toDomNode; + var toWrittenString = helpers.toWrittenString; + var toDisplayedString = helpers.toDisplayedString; //////////////////////////////////////////////////////////////////////] @@ -530,6 +533,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } outputPort = MACHINE.env[MACHINE.env.length-2]; } outputPort.writeDomNode(MACHINE, toDomNode(firstArg, 'display')); + return VOID; }; Primitives['display'].arity = makeList(1, 2); Primitives['display'].displayName = 'display'; @@ -547,6 +551,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } outputPort = MACHINE.env[MACHINE.env.length-1]; } outputPort.writeDomNode(MACHINE, toDomNode("\n", 'display')); + return VOID; }; Primitives['newline'].arity = makeList(0, 1); Primitives['newline'].displayName = 'newline'; @@ -566,6 +571,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } } outputPort.writeDomNode(MACHINE, toDomNode(firstArg, 'display')); outputPort.writeDomNode(MACHINE, toDomNode("\n", 'display')); + return VOID; }; Primitives['displayln'].arity = makeList(1, 2); Primitives['displayln'].displayName = 'displayln'; @@ -876,6 +882,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } var firstArg = MACHINE.env[MACHINE.env.length-1]; var secondArg = MACHINE.env[MACHINE.env.length-2]; firstArg.first = secondArg; + return VOID; }; Primitives['set-car!'].arity = 2; Primitives['set-car!'].displayName = 'set-car!'; @@ -890,6 +897,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } var firstArg = MACHINE.env[MACHINE.env.length-1]; var secondArg = MACHINE.env[MACHINE.env.length-2]; firstArg.rest = secondArg; + return VOID; }; Primitives['set-cdr!'].arity = 2; Primitives['set-cdr!'].displayName = 'set-cdr!'; @@ -916,8 +924,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 makeVector.apply(null, result); + var newVector = makeVector.apply(null, result); + return newVector; }; Primitives['vector'].arity = new ArityAtLeast(0); Primitives['vector'].displayName = 'vector'; @@ -973,11 +981,17 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length - 1], 0, 'vector-set!'); + 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 null; + return VOID; }; Primitives['vector-set!'].arity = 3; Primitives['vector-set!'].displayName = 'vector-set!'; @@ -1073,13 +1087,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'; @@ -1347,6 +1361,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; @@ -1382,10 +1397,15 @@ 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; diff --git a/js-assembler/runtime-src/types.js b/js-assembler/runtime-src/types.js index 4517ac6..9bd9db8 100644 --- a/js-assembler/runtime-src/types.js +++ b/js-assembler/runtime-src/types.js @@ -1951,12 +1951,12 @@ String.prototype.toDisplayedString = function(cache) { }; - var makeVector = function(arguments) { + var makeVector = function() { return Vector.makeInstance(arguments.length, arguments); }; - var makeVectorImmutable = function(arguments) { + var makeVectorImmutable = function() { var v = Vector.makeInstance(arguments.length, arguments); v.mutable = false; return v; @@ -1983,7 +1983,7 @@ String.prototype.toDisplayedString = function(cache) { ' given ' + s.toString(), false); } - } + }; var makeHashEq = function(lst) { @@ -1993,7 +1993,7 @@ String.prototype.toDisplayedString = function(cache) { lst = lst.rest; } return newHash; - } + }; var makeHashEqual = function(lst) { @@ -2003,7 +2003,7 @@ String.prototype.toDisplayedString = function(cache) { lst = lst.rest; } return newHash; - } + }; var Color = makeStructureType('color', false, 3, 0, false, false); diff --git a/tests/test-assemble.rkt b/tests/test-assemble.rkt index 5efb59a..42a6354 100644 --- a/tests/test-assemble.rkt +++ b/tests/test-assemble.rkt @@ -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") + "#") ;; Assigning to proc means val should still be uninitialized. (test (E-single (make-AssignImmediateStatement 'proc (make-Const "Danny"))) - "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") + "#") (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")