diff --git a/js-assembler/get-runtime.rkt b/js-assembler/get-runtime.rkt index 9a1c82d..f15e3e7 100644 --- a/js-assembler/get-runtime.rkt +++ b/js-assembler/get-runtime.rkt @@ -44,17 +44,19 @@ baselib-unionfind.js baselib-equality.js baselib-format.js - + + baselib-constants.js baselib-lists.js baselib-vectors.js baselib-chars.js - baselib-symbol.js + baselib-symbols.js baselib-strings.js baselib-bytes.js baselib-hash.js baselib-regexps.js baselib-paths.js baselib-boxes.js + baselib-placeholders.js baselib-keywords.js baselib-structs.js diff --git a/js-assembler/runtime-src/baselib-boxes.js b/js-assembler/runtime-src/baselib-boxes.js index a50b29e..0cb47d0 100644 --- a/js-assembler/runtime-src/baselib-boxes.js +++ b/js-assembler/runtime-src/baselib-boxes.js @@ -51,9 +51,25 @@ plt.baselib.equality.equals(this.val, other.val, aUnionFind)); }; + var makeBox = function(x) { + return new Box(x, true); + }; + var makeImmutableBox = function(x) { + return new Box(x, false); + }; + + var isBox = function(x) { + return x instanceof Box; + }; + + + + ////////////////////////////////////////////////////////////////////// exports.Box = Box; - + exports.isBox = isBox; + exports.makeBox = makeBox; + exports.makeImmutableBox = makeImmutableBox; })(this['plt'].baselib); \ No newline at end of file diff --git a/js-assembler/runtime-src/baselib-constants.js b/js-assembler/runtime-src/baselib-constants.js new file mode 100644 index 0000000..38c398a --- /dev/null +++ b/js-assembler/runtime-src/baselib-constants.js @@ -0,0 +1,25 @@ +// Other miscellaneous constants +(function(baselib) { + var exports = {}; + baselib.constants = exports; + + + var VoidValue = function() {}; + VoidValue.prototype.toString = function() { + return "#"; + }; + + var VOID_VALUE = new VoidValue(); + + + var EofValue = function() {}; + EofValue.prototype.toString = function() { + return "#"; + } + + var EOF_VALUE = new EofValue(); + + + exports.VOID_VALUE = VOID_VALUE; + exports.EOF_VALUE = EOF_VALUE; +})(this['plt'].baselib); \ No newline at end of file diff --git a/js-assembler/runtime-src/baselib-contmarks.js b/js-assembler/runtime-src/baselib-contmarks.js new file mode 100644 index 0000000..b1711ae --- /dev/null +++ b/js-assembler/runtime-src/baselib-contmarks.js @@ -0,0 +1,35 @@ +// Continuation marks +(function(baselib) { + var exports = {}; + baselib.contmarks = exports; + + + var ContinuationMarkSet = function(dict) { + this.dict = dict; + } + + ContinuationMarkSet.prototype.toDomNode = function(cache) { + var dom = document.createElement("span"); + dom.appendChild(document.createTextNode('#')); + return dom; + }; + + ContinuationMarkSet.prototype.toWrittenString = function(cache) { + return '#'; + }; + + ContinuationMarkSet.prototype.toDisplayedString = function(cache) { + return '#'; + }; + + ContinuationMarkSet.prototype.ref = function(key) { + if ( this.dict.containsKey(key) ) { + return this.dict.get(key); + } + return []; + }; + + exports.ContinuationMarkSet = ContinuationMarkSet; + + +})(this['plt'].baselib); \ No newline at end of file diff --git a/js-assembler/runtime-src/baselib-exceptions.js b/js-assembler/runtime-src/baselib-exceptions.js index ba7fc4d..c6f2489 100644 --- a/js-assembler/runtime-src/baselib-exceptions.js +++ b/js-assembler/runtime-src/baselib-exceptions.js @@ -54,8 +54,11 @@ - ////////////////////////////////////////////////////////////////////// + var exceptionHandlerKey = new plt.baselib.symbols.Symbol("exnh"); + + + ////////////////////////////////////////////////////////////////////// // Exports exceptions.InternalError = InternalError; @@ -110,6 +113,7 @@ exceptions.isExnFailContractDivisionByZero = ExnFailContractDivisionByZero.predicate; + exceptions.exceptionHandlerKey = exceptionHandlerKey; })(this['plt'].baselib); \ No newline at end of file diff --git a/js-assembler/runtime-src/baselib_placeholders.js b/js-assembler/runtime-src/baselib-placeholders.js similarity index 100% rename from js-assembler/runtime-src/baselib_placeholders.js rename to js-assembler/runtime-src/baselib-placeholders.js diff --git a/js-assembler/runtime-src/baselib-structs.js b/js-assembler/runtime-src/baselib-structs.js index a918798..dd58cf7 100644 --- a/js-assembler/runtime-src/baselib-structs.js +++ b/js-assembler/runtime-src/baselib-structs.js @@ -114,7 +114,7 @@ var args = [].slice.call(arguments); return newType.applyGuard( args, - baselib.Symbol.makeInstance(theName), + baselib.symbols.Symbol.makeInstance(theName), function(res) { return new rawConstructor(theName, res); }); }, diff --git a/js-assembler/runtime-src/baselib-symbol.js b/js-assembler/runtime-src/baselib-symbols.js similarity index 84% rename from js-assembler/runtime-src/baselib-symbol.js rename to js-assembler/runtime-src/baselib-symbols.js index 2a2d1a8..9536f0b 100644 --- a/js-assembler/runtime-src/baselib-symbol.js +++ b/js-assembler/runtime-src/baselib-symbols.js @@ -1,7 +1,9 @@ // Structure types (function(baselib) { - + + var exports = {}; + baselib.symbols = exports; ////////////////////////////////////////////////////////////////////// @@ -44,12 +46,8 @@ }; + ////////////////////////////////////////////////////////////////////// - - baselib.Symbol = Symbol; - - - - + exports.Symbol = Symbol; })(this['plt'].baselib); \ No newline at end of file diff --git a/js-assembler/runtime-src/runtime.js b/js-assembler/runtime-src/runtime.js index b66073f..ffbe9f7 100644 --- a/js-assembler/runtime-src/runtime.js +++ b/js-assembler/runtime-src/runtime.js @@ -34,7 +34,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } var NULL = types.EMPTY; - var VOID = types.VOID; + var VOID = plt.baselib.constants.VOID_VALUE; + var EOF = plt.baselib.constants.EOF_VALUE; var makeVector = types.vector; var makeList = types.list; @@ -46,8 +47,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } var toDisplayedString = plt.baselib.format.toDisplayedString; - var makeBox = types.box; - var isBox = types.isBox; + var makeBox = plt.baselib.boxes.makeBox; + var isBox = plt.baselib.boxes.isBox; //////////////////////////////////////////////////////////////////////] @@ -1318,8 +1319,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } 1, function(MACHINE) { var firstArg = MACHINE.env[MACHINE.env.length-1]; - var result = [firstArg]; - return result; + return makeBox(firstArg); }); installPrimitiveProcedure( @@ -1327,7 +1327,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } 1, function(MACHINE) { var firstArg = MACHINE.env[MACHINE.env.length-1]; - return firstArg[0]; + // FIXME: typecheck for box + return firstArg.ref(); }); installPrimitiveProcedure( @@ -1336,7 +1337,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } function(MACHINE) { var firstArg = MACHINE.env[MACHINE.env.length-1]; var secondArg = MACHINE.env[MACHINE.env.length-2]; - firstArg[0] = secondArg; + // FIXME: typecheck for box + firstArg.set(secondArg); return VOID; }); diff --git a/js-assembler/runtime-src/types.js b/js-assembler/runtime-src/types.js index a15b23c..0e42851 100644 --- a/js-assembler/runtime-src/types.js +++ b/js-assembler/runtime-src/types.js @@ -36,70 +36,34 @@ if (! this['plt']) { this['plt'] = {}; } - var Symbol = plt.baselib.Symbol; + var Symbol = plt.baselib.symbols.Symbol; var Empty = plt.baselib.lists.Empty; var Cons = plt.baselib.lists.Cons; - ////////////////////////////////////////////////////////////////////// - - - - - ////////////////////////////////////////////////////////////////////// + var isNumber = jsnums.isSchemeNumber; + var isReal = jsnums.isReal; + var isRational = jsnums.isRational; + var isComplex = isNumber; + var isInteger = jsnums.isInteger; + var isNatural = function(x) { + return (jsnums.isExact(x) && isInteger(x) + && jsnums.greaterThanOrEqual(x, 0)); + }; + var isNonNegativeReal = function(x) { + return isReal(x) && jsnums.greaterThanOrEqual(x, 0); + }; + var isString = plt.baselib.strings.isString; - - - - - - - - - - - - ////////////////////////////////////////////////////////////////////// - - - - - ////////////////////////////////////////////////////////////////////// - - - - - ////////////////////////////////////////////////////////////////////// - - - - - ////////////////////////////////////////////////////////////////////// - - - - - - ////////////////////////////////////////////////////////////////////// - - - - - ////////////////////////////////////////////////////////////////////// - - - ////////////////////////////////////////////////////////////////////// - - - + var equals = plt.baselib.equality.equals; // isList: Any -> Boolean // Returns true if x is a list (a chain of pairs terminated by EMPTY). @@ -115,18 +79,72 @@ if (! this['plt']) { this['plt'] = {}; } }; + var makeList = function() { + var result = Empty.EMPTY; + for(var i = arguments.length-1; i >= 0; i--) { + result = Cons.makeInstance(arguments[i], result); + } + return result; + }; - ////////////////////////////////////////////////////////////////////// + var makeVector = function() { + return Vector.makeInstance(arguments.length, arguments); + }; - ////////////////////////////////////////////////////////////////////// + var makeVectorImmutable = function() { + var v = Vector.makeInstance(arguments.length, arguments); + v.mutable = false; + return v; + }; + var makeString = function(s) { + if (s instanceof plt.baselib.strings.Str) { + return s; + } + else if (s instanceof Array) { + // for (var i = 0; i < s.length; i++) { + // if ( typeof s[i] !== 'string' || s[i].length != 1 ) { + // return undefined; + // } + // } + return plt.baselib.strings.Str.makeInstance(s); + } + else if (typeof s === 'string') { + return plt.baselib.strings.Str.fromString(s); + } + else { + throw types.internalError('makeString expects and array of 1-character strings or a string;' + + ' given ' + s.toString(), + false); + } + }; + var makeHashEq = function(lst) { + var newHash = new plt.baselib.hash.EqHashTable(); + while ( !isEmpty(lst) ) { + newHash.hash.put(lst.first.first, lst.first.rest); + lst = lst.rest; + } + return newHash; + }; + var makeHashEqual = function(lst) { + var newHash = new plt.baselib.hash.EqualHashTable(); + while ( !isEmpty(lst) ) { + newHash.hash.put(lst.first.first, lst.first.rest); + lst = lst.rest; + } + return newHash; + }; + + + var Color = plt.baselib.structs.makeStructureType( + 'color', false, 3, 0, false, false); @@ -280,154 +298,7 @@ if (! this['plt']) { this['plt'] = {}; } - var isNumber = jsnums.isSchemeNumber; - - var isReal = jsnums.isReal; - var isRational = jsnums.isRational; - var isComplex = isNumber; - var isInteger = jsnums.isInteger; - - var isNatural = function(x) { - return (jsnums.isExact(x) && isInteger(x) - && jsnums.greaterThanOrEqual(x, 0)); - }; - var isNonNegativeReal = function(x) { - return isReal(x) && jsnums.greaterThanOrEqual(x, 0); - }; - - - - - - - var isString = plt.baselib.strings.isString; - - - - - var equals = plt.baselib.equality.equals; - - - - // liftToplevelToFunctionValue: primitive-function string fixnum scheme-value -> scheme-value - // Lifts a primitive toplevel or module-bound value to a scheme value. - var liftToplevelToFunctionValue = function(primitiveF, - name, - minArity, - procedureArityDescription) { - if (! primitiveF._mobyLiftedFunction) { - var lifted = function(args) { - return primitiveF.apply(null, args.slice(0, minArity).concat([args.slice(minArity)])); - }; - lifted.equals = function(other, cache) { - return this === other; - } - lifted.toWrittenString = function(cache) { - return "#"; - }; - lifted.toDisplayedString = lifted.toWrittenString; - lifted.procedureArity = procedureArityDescription; - primitiveF._mobyLiftedFunction = lifted; - - } - return primitiveF._mobyLiftedFunction; - }; - - - ////////////////////////////////////////////////////////////////////// - var ThreadCell = function(v, isPreserved) { - this.v = v; - this.isPreserved = isPreserved || false; - }; - - - - ////////////////////////////////////////////////////////////////////// - - - - - var UndefinedValue = function() { - }; - UndefinedValue.prototype.toString = function() { - return "#"; - }; - var UNDEFINED_VALUE = new UndefinedValue(); - - var VoidValue = function() {}; - VoidValue.prototype.toString = function() { - return "#"; - }; - - var VOID_VALUE = new VoidValue(); - - - var EofValue = function() {}; - EofValue.prototype.toString = function() { - return "#"; - } - - var EOF_VALUE = new EofValue(); - - - - - - - - - - ////////////////////////////////////////////////////////////////////// - - // Continuation Marks - - var ContMarkRecordControl = function(dict) { - this.dict = dict || makeLowLevelEqHash(); - }; - - ContMarkRecordControl.prototype.invoke = function(state) { - // No-op: the record will simply pop off the control stack. - }; - - ContMarkRecordControl.prototype.update = function(key, val) { - var newDict = makeLowLevelEqHash(); - // FIXME: what's the javascript idiom for hash key copy? - // Maybe we should use a rbtree instead? - var oldKeys = this.dict.keys(); - for (var i = 0; i < oldKeys.length; i++) { - newDict.put( oldKeys[i], this.dict.get(oldKeys[i]) ); - } - newDict.put(key, val); - return new ContMarkRecordControl(newDict); - }; - - - - var ContinuationMarkSet = function(dict) { - this.dict = dict; - } - - ContinuationMarkSet.prototype.toDomNode = function(cache) { - var dom = document.createElement("span"); - dom.appendChild(document.createTextNode('#')); - return dom; - }; - - ContinuationMarkSet.prototype.toWrittenString = function(cache) { - return '#'; - }; - - ContinuationMarkSet.prototype.toDisplayedString = function(cache) { - return '#'; - }; - - ContinuationMarkSet.prototype.ref = function(key) { - if ( this.dict.containsKey(key) ) { - return this.dict.get(key); - } - return []; - }; ////////////////////////////////////////////////////////////////////// @@ -534,89 +405,11 @@ if (! this['plt']) { this['plt'] = {}; } - var makeList = function() { - var result = Empty.EMPTY; - for(var i = arguments.length-1; i >= 0; i--) { - result = Cons.makeInstance(arguments[i], result); - } - return result; - }; - - - var makeVector = function() { - return Vector.makeInstance(arguments.length, arguments); - }; - - - var makeVectorImmutable = function() { - var v = Vector.makeInstance(arguments.length, arguments); - v.mutable = false; - return v; - }; - - - var makeString = function(s) { - if (s instanceof plt.baselib.strings.Str) { - return s; - } - else if (s instanceof Array) { - // for (var i = 0; i < s.length; i++) { - // if ( typeof s[i] !== 'string' || s[i].length != 1 ) { - // return undefined; - // } - // } - return plt.baselib.strings.Str.makeInstance(s); - } - else if (typeof s === 'string') { - return plt.baselib.strings.Str.fromString(s); - } - else { - throw types.internalError('makeString expects and array of 1-character strings or a string;' + - ' given ' + s.toString(), - false); - } - }; - - - var makeHashEq = function(lst) { - var newHash = new plt.baselib.hash.EqHashTable(); - while ( !isEmpty(lst) ) { - newHash.hash.put(lst.first.first, lst.first.rest); - lst = lst.rest; - } - return newHash; - }; - - - var makeHashEqual = function(lst) { - var newHash = new plt.baselib.hash.EqualHashTable(); - while ( !isEmpty(lst) ) { - newHash.hash.put(lst.first.first, lst.first.rest); - lst = lst.rest; - } - return newHash; - }; - - - var Color = plt.baselib.structs.makeStructureType('color', false, 3, 0, false, false); ////////////////////////////////////////////////////////////////////// - - - - - - - - ////////////////////////////////////////////////////////////////////// - - - - - - types.exceptionHandlerKey = new Symbol("exnh"); + // Exports @@ -632,8 +425,8 @@ if (! this['plt']) { this['plt'] = {}; } types.byteRegexp = function(p) { return new plt.baselib.regexps.ByteRegularExpression(p) ; } types.character = plt.baselib.chars.Char.makeInstance; types['string'] = makeString; + types.placeholder = function(x) { return new plt.baselib.placeholders.Placeholder(x); }; types.box = function(x) { return new plt.baselib.boxes.Box(x, true); }; - types.placeholder = function(x) { return new Placeholder(x); }; types.boxImmutable = function(x) { return new plt.baselib.boxes.Box(x, false); }; types.path = function(x) { return new plt.baselib.paths.Path(x); }; types.bytes = function(x, mutable) { return new plt.baselib.bytes.Bytes(x, mutable); }; @@ -676,7 +469,7 @@ if (! this['plt']) { this['plt'] = {}; } types.isEmpty = function(x) { return x === Empty.EMPTY; }; types.isVector = function(x) { return x instanceof Vector; }; types.isBox = function(x) { return x instanceof plt.baselib.boxes.Box; }; - types.isPlaceholder = function(x) { return x instanceof Placeholder; }; + types.isPlaceholder = function(x) { return x instanceof plt.baselib.placeholders.Placeholder; }; types.isHash = function(x) { return (x instanceof plt.baselib.hash.EqHashTable || x instanceof plt.baselib.hash.EqualHashTable); }; types.isByteString = function(x) { return x instanceof plt.baselib.bytes.Bytes; }; @@ -693,9 +486,8 @@ if (! this['plt']) { this['plt'] = {}; } types.cons = Cons.makeInstance; - types.UNDEFINED = UNDEFINED_VALUE; - types.VOID = VOID_VALUE; - types.EOF = EOF_VALUE; + types.VOID = plt.baselib.constants.VOID_VALUE; + types.EOF = plt.baselib.constants.EOF_VALUE; // types.ContinuationPromptTag = ContinuationPromptTag; // types.defaultContinuationPromptTag = defaultContinuationPromptTag; @@ -707,16 +499,15 @@ if (! this['plt']) { this['plt'] = {}; } // types.internalPause = function(onPause) { return new INTERNAL_PAUSE(onPause) }; // types.isInternalPause = function(x) { return (x instanceof INTERNAL_PAUSE); }; - types.contMarkRecordControl = function(dict) { return new ContMarkRecordControl(dict); }; - types.isContMarkRecordControl = function(x) { return x instanceof ContMarkRecordControl; }; - types.continuationMarkSet = function(dict) { return new ContinuationMarkSet(dict); }; - types.isContinuationMarkSet = function(x) { return x instanceof ContinuationMarkSet; }; + + types.continuationMarkSet = function(dict) { return new plt.baselib.contmarks.ContinuationMarkSet(dict); }; + types.isContinuationMarkSet = function(x) { return x instanceof plt.baselib.contmarks.ContinuationMarkSet; }; // types.isContinuationPromptTag = function(x) { return x instanceof ContinuationPromptTag; }; types.Box = plt.baselib.boxes.Box; - types.Placeholder = Placeholder; - types.ThreadCell = ThreadCell; + types.Placeholder = plt.baselib.placeholders.Placeholder; + types.isStructType = function(x) { return x instanceof plt.baselib.structs.StructType; }; diff --git a/scribblings/manual.scrbl b/scribblings/manual.scrbl index 0cf1d27..99018dd 100644 --- a/scribblings/manual.scrbl +++ b/scribblings/manual.scrbl @@ -694,9 +694,12 @@ return @tt{plt.runtime.VOID}. @subsection{Undefined} -The undefined values is +The undefined value is JavaScript's @tt{undefined}. +@subsection{EOF} +The eof object is @tt{plt.runtime.EOF} + @subsubsection{Boxes} Boxes can be constructed with @tt{plt.runtime.makeBox(x)}. They can be diff --git a/tests/more-tests/man-vs-boy.expected b/tests/more-tests/man-vs-boy.expected new file mode 100644 index 0000000..be5aefe --- /dev/null +++ b/tests/more-tests/man-vs-boy.expected @@ -0,0 +1 @@ +-67 diff --git a/tests/more-tests/man-vs-boy.rkt b/tests/more-tests/man-vs-boy.rkt new file mode 100644 index 0000000..8583b87 --- /dev/null +++ b/tests/more-tests/man-vs-boy.rkt @@ -0,0 +1,19 @@ +#lang planet dyoo/whalesong + +;; Knuth's Man-or-boy-test. +;; http://rosettacode.org/wiki/Man_or_boy_test +(define (A k x1 x2 x3 x4 x5) + (letrec ([B (lambda () + (set! k (- k 1)) + (A k B x1 x2 x3 x4))]) + (if (<= k 0) + (+ (x4) (x5)) + (B)))) +(displayln (A 10 + (lambda () 1) + (lambda () -1) + (lambda () -1) + (lambda () 1) + (lambda () 0))) + +