// The definitions of the basic types in Whalesong. // // Note: this originally came from js-vm, and as a result, // there's quite a lot of cruft and unused code in this module. // I need to filter and rip out the values that aren't used in Whalesong. if (! this['plt']) { this['plt'] = {}; } // FIXME: there's a circularity between this module and helpers, and that circularly // should not be there! (function (scope) { ////////////////////////////////////////////////////////////////////// var types = {}; scope['types'] = types; var getEqHashCode = plt.baselib.hashes.getEqHashCode; // makeLowLevelEqHash: -> hashtable // Constructs an eq hashtable that uses Moby's getEqHashCode function. var makeLowLevelEqHash = plt.baselib.hashes.makeLowLevelEqHash; var toWrittenString = plt.baselib.format.toWrittenString; var toDisplayedString = plt.baselib.format.toDisplayedString; var toDomNode = plt.baselib.format.toDomNode; var appendChild = function(parent, child) { parent.appendChild(child); }; var Symbol = plt.baselib.symbols.Symbol; var Empty = plt.baselib.lists.Empty; var Cons = plt.baselib.lists.Cons; var isNumber = jsnums.isSchemeNumber; var isReal = jsnums.isReal; var isRational = jsnums.isRational; var isComplex = isNumber; var isInteger = jsnums.isInteger; var isNatural = function(x) { return (jsnums.isExact(x) && isInteger(x) && jsnums.greaterThanOrEqual(x, 0)); }; var isNonNegativeReal = function(x) { return isReal(x) && jsnums.greaterThanOrEqual(x, 0); }; var isString = plt.baselib.strings.isString; var equals = plt.baselib.equality.equals; // isList: Any -> Boolean // Returns true if x is a list (a chain of pairs terminated by EMPTY). var isList = function(x) { while (x !== Empty.EMPTY) { if (x instanceof Cons){ x = x.rest; } else { return false; } } return true; }; var makeList = function() { var result = Empty.EMPTY; for(var i = arguments.length-1; i >= 0; i--) { result = Cons.makeInstance(arguments[i], result); } return result; }; var makeVector = function() { return Vector.makeInstance(arguments.length, arguments); }; var makeVectorImmutable = function() { var v = Vector.makeInstance(arguments.length, arguments); v.mutable = false; return v; }; var makeString = function(s) { if (s instanceof plt.baselib.strings.Str) { return s; } else if (s instanceof Array) { // for (var i = 0; i < s.length; i++) { // if ( typeof s[i] !== 'string' || s[i].length != 1 ) { // return undefined; // } // } return plt.baselib.strings.Str.makeInstance(s); } else if (typeof s === 'string') { return plt.baselib.strings.Str.fromString(s); } else { throw types.internalError('makeString expects and array of 1-character strings or a string;' + ' given ' + s.toString(), false); } }; var makeHashEq = function(lst) { var newHash = new plt.baselib.hashes.EqHashTable(); while ( !isEmpty(lst) ) { newHash.hash.put(lst.first.first, lst.first.rest); lst = lst.rest; } return newHash; }; var makeHashEqual = function(lst) { var newHash = new plt.baselib.hashes.EqualHashTable(); while ( !isEmpty(lst) ) { newHash.hash.put(lst.first.first, lst.first.rest); lst = lst.rest; } return newHash; }; var Color = plt.baselib.structs.makeStructureType( 'color', false, 3, 0, false, false); ////////////////////////////////////////////////////////////////////// // var JsValue = function(name, val) { // this.name = name; // this.val = val; // }; // JsValue.prototype.toString = function() { // return '#'; // }; // JsValue.prototype.toDomNode = function(cache) { // return toDomNode(this.val, cache); // }; // JsValue.prototype.equals = function(other, aUnionFind) { // return (this.val === other.val); // }; // // unbox: jsvalue -> any // // Unwraps the value out of the JsValue box. // JsValue.prototype.unbox = function() { // return this.val; // }; // var WrappedSchemeValue = function(val) { // this.val = val; // }; // WrappedSchemeValue.prototype.toString = function() { return toString(this.val); }; // WrappedSchemeValue.prototype.toWrittenString = function(cache) { return toWrittenString(this.val, cache); }; // WrappedSchemeValue.prototype.toDisplayedString = function(cache) { return toDisplayedString(this.val, cache); }; // // unbox: jsvalue -> any // // Unwraps the value out of the WrappedSchemeValue box. // WrappedSchemeValue.prototype.unbox = function() { // return this.val; // }; ////////////////////////////////////////////////////////////////////// // var WorldConfig = function(startup, shutdown, startupArgs) { // this.startup = startup; // this.shutdown = shutdown; // this.startupArgs = startupArgs; // }; // WorldConfig.prototype.toString = function() { // return '#'; // }; // WorldConfig.prototype.equals = function(other, aUnionFind) { // return ( equals(this.startup, other.startup, aUnionFind) && // equals(this.shutdown, other.shutdown, aUnionFind) && // equals(this.shutdownArg, other.shutdownArg, aUnionFind) && // equals(this.restartArg, other.restartArg, aUnionFind) ); // }; // var Effect = plt.baselib.structs.makeStructureType('effect', false, 0, 0, false, false); // Effect.type.prototype.invokeEffect = function() { // helpers.raise(types.incompleteExn( // types.exnFail, // 'effect type created without using make-effect-type', // [])); // }; // var makeEffectType = function(name, superType, initFieldCnt, impl, guard) { // if ( !superType ) { // superType = Effect; // } // var newType = plt.baselib.structs.makeStructureType(name, superType, initFieldCnt, 0, false, guard); // var lastFieldIndex = newType.firstField + newType.numberOfFields; // newType.type.prototype.invokeEffect = function(aBigBang, k) { // var schemeChangeWorld = new PrimProc('update-world', 1, false, false, // function(worldUpdater) { // //helpers.check(worldUpdater, helpers.procArityContains(1), // // 'update-world', 'procedure (arity 1)', 1); // return new INTERNAL_PAUSE( // function(caller, onSuccess, onFail) { // aBigBang.changeWorld(function(w, k2) { // caller(worldUpdater, // [w], k2, // function(e) { throw e; }, // 'change-world (effect)'); // }, // function() { onSuccess(VOID_VALUE, 'restarting (change-world (effect))'); }); // }); // }); // var args = this._fields.slice(0, lastFieldIndex); // args.unshift(schemeChangeWorld); // return aBigBang.caller(impl, args, k, function(e) { throw e; }, 'invoking effect ' + name); // } // return newType; // }; // var RenderEffect = plt.baselib.structs.makeStructureType('render-effect', false, 0, 0, false, false); // RenderEffect.type.prototype.callImplementation = function(caller, k) { // helpers.raise(types.incompleteExn( // types.exnFail, // 'render effect created without using make-render-effect-type', // [])); // }; // var makeRenderEffectType = function(name, superType, initFieldCnt, impl, guard) { // if ( !superType ) { // superType = RenderEffect; // } // var newType = plt.baselib.structs.makeStructureType(name, superType, initFieldCnt, 0, false, guard); // var lastFieldIndex = newType.firstField + newType.numberOfFields; // newType.type.prototype.callImplementation = function(caller, k) { // var args = this._fields.slice(0, lastFieldIndex); // caller(impl, args, k); // } // return newType; // }; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // var makeOptionPrimitive = function(name, // numArgs, // defaultVals, // usesState, // bodyF) { // var makeNthPrimitive = function(n) { // return new PrimProc(name, // numArgs + n, // false, // usesState, // function() { // var expectedNumArgs = numArgs + n + (usesState ? 1 : 0); // assert.equal(arguments.length, // expectedNumArgs); // var args = [arguments]; // for (var i = 0; i < arguments.length; i++) { // args.push(arguments[i]); // } // var startDefaults = i - numArgs - (usesState ? 1 : 0); // return bodyF.apply( // bodyF, // args.concat(defaultVals.slice(startDefaults))); // }); // }; // var cases = []; // for (var i = 0; i <= defaultVals.length; i++) { // cases.push(makeNthPrimitive(i)); // } // return new CasePrimitive(name, cases); // }; ////////////////////////////////////////////////////////////////////// // INTERNAL_CALL // used for interaction between the Primitives and the interpreter (callPrimitiveProcedure). // Don't confuse this with CallControl. // var INTERNAL_CALL = function(operator, operands, k) { // this.operator = operator; // this.operands = operands; // this.k = k; // }; // // INTERNAL_PAUSE // // used for interaction between the Primitive functions and the // // interpreter. // // Halts the interpreter, but passing onPause the functions necessary // // to restart computation. // var INTERNAL_PAUSE = function(onPause) { // this.onPause = onPause; // }; ////////////////////////////////////////////////////////////////////// // // ContinuationPromptTag: symbol | false -> ContinuationPromptTag // var ContinuationPromptTag = function(sym) { // this.sym = sym; // }; // var defaultContinuationPromptTag = new ContinuationPromptTag(); // var defaultContinuationPromptTagHandler = new PrimProc( // 'default-continuation-prompt-tag-handler', // 1, // false, // true, // function(aState, thunk) { // aState.pushControl( // new control.ApplicationControl( // new control.ConstantControl(thunk), // [])); // }); ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // Exports types.symbol = Symbol.makeInstance; types.rational = jsnums.makeRational; types.floatpoint = jsnums.makeFloat; types.complex = jsnums.makeComplex; types.bignum = jsnums.makeBignum; types.list = makeList; types.vector = makeVector; types.vectorImmutable = makeVectorImmutable; types.regexp = function(p) { return new plt.baselib.regexps.RegularExpression(p) ; } types.byteRegexp = function(p) { return new plt.baselib.regexps.ByteRegularExpression(p) ; } types.character = plt.baselib.chars.Char.makeInstance; types['string'] = makeString; types.placeholder = function(x) { return new plt.baselib.placeholders.Placeholder(x); }; types.box = function(x) { return new plt.baselib.boxes.Box(x, true); }; types.boxImmutable = function(x) { return new plt.baselib.boxes.Box(x, false); }; types.path = function(x) { return new plt.baselib.paths.Path(x); }; types.bytes = function(x, mutable) { return new plt.baselib.bytes.Bytes(x, mutable); }; types.bytesImmutable = function(x) { return new plt.baselib.bytes.Bytes(x, false); }; types.keyword = function(k) { return new plt.baselib.keywords.Keyword(k); }; types.pair = function(x, y) { return plt.baselib.lists.Cons.makeInstance(x, y); }; types.hash = makeHashEqual; types.hashEq = makeHashEq; // types.jsValue = function(name, val) { return new JsValue(name, val); }; // types.wrappedSchemeValue = function(val) { return new WrappedSchemeValue(val); }; types.color = Color.constructor; types.colorRed = function(x) { return Color.accessor(x, 0); }; types.colorGreen = function(x) { return Color.accessor(x, 1); }; types.colorBlue = function(x) { return Color.accessor(x, 2); }; types.FALSE = false; types.TRUE = true; types.EMPTY = Empty.EMPTY; types.equals = equals; types.isNumber = isNumber; types.isReal = jsnums.isReal; types.isRational = jsnums.isRational; types.isComplex = isNumber; types.isInteger = jsnums.isInteger; types.isNatural = isNatural; types.isNonNegativeReal = isNonNegativeReal; types.isSymbol = function(x) { return x instanceof Symbol; }; types.isChar = function(x) { return x instanceof plt.baselib.chars.Char; }; types.isString = isString; types.isPair = function(x) { return x instanceof Cons; }; types.isList = isList; types.isEmpty = function(x) { return x === Empty.EMPTY; }; types.isVector = function(x) { return x instanceof Vector; }; types.isBox = function(x) { return x instanceof plt.baselib.boxes.Box; }; types.isPlaceholder = function(x) { return x instanceof plt.baselib.placeholders.Placeholder; }; types.isHash = function(x) { return (x instanceof plt.baselib.hashes.EqHashTable || x instanceof plt.baselib.hashes.EqualHashTable); }; types.isByteString = function(x) { return x instanceof plt.baselib.bytes.Bytes; }; types.isStruct = function(x) { return x instanceof Struct; }; types.isColor = Color.predicate; // types.isFunction = function(x) { // return (x instanceof PrimProc); // }; // types.isJsValue = function(x) { return x instanceof JsValue; }; // types.isWrappedSchemeValue = function(x) { return x instanceof WrappedSchemeValue; }; types.cons = Cons.makeInstance; types.VOID = plt.baselib.constants.VOID_VALUE; types.EOF = plt.baselib.constants.EOF_VALUE; // types.ContinuationPromptTag = ContinuationPromptTag; // types.defaultContinuationPromptTag = defaultContinuationPromptTag; // types.defaultContinuationPromptTagHandler = defaultContinuationPromptTagHandler; // types.makeOptionPrimitive = makeOptionPrimitive; // types.internalCall = function(op, args, k) { return new INTERNAL_CALL(op, args, k); }; // types.isInternalCall = function(x) { return (x instanceof INTERNAL_CALL); }; // types.internalPause = function(onPause) { return new INTERNAL_PAUSE(onPause) }; // types.isInternalPause = function(x) { return (x instanceof INTERNAL_PAUSE); }; types.continuationMarkSet = function(dict) { return new plt.baselib.contmarks.ContinuationMarkSet(dict); }; types.isContinuationMarkSet = function(x) { return x instanceof plt.baselib.contmarks.ContinuationMarkSet; }; // types.isContinuationPromptTag = function(x) { return x instanceof ContinuationPromptTag; }; types.Box = plt.baselib.boxes.Box; types.Placeholder = plt.baselib.placeholders.Placeholder; types.isStructType = function(x) { return x instanceof plt.baselib.structs.StructType; }; // types.StructProc = StructProc; // types.StructConstructorProc = StructConstructorProc; // types.StructPredicateProc = StructPredicateProc; // types.StructAccessorProc = StructAccessorProc; // types.StructMutatorProc = StructMutatorProc; types.makeLowLevelEqHash = makeLowLevelEqHash; /////////////////////////////////////// // World-specific exports // // big bang info to be passed into a make-world-config startup argument // var BigBangInfo = plt.baselib.structs.makeStructureType('bb-info', false, 2, 0, false, // function(args, name, k) { // //helpers.check(args[0], helpers.procArityContains(1), name, 'procedure (arity 1)', 1); // //helpers.check(args[1], types.isJsValue, name, 'js-object', 2); // return k(args); // }); // types.BigBangInfo = BigBangInfo; // types.makeBigBangInfo = BigBangInfo.constructor; // types.isBigBangInfo = BigBangInfo.predicate; // types.bbInfoChangeWorld = function(info) { return BigBangInfo.accessor(info, 0); }; // types.bbInfoToplevelNode = function(info) { return BigBangInfo.accessor(info, 1); }; // World config information for user-defined configurations // types.worldConfig = function(startup, shutdown, pause, restart) { return new WorldConfig(startup, shutdown, pause, restart); }; // types.isWorldConfig = function(x) { return x instanceof WorldConfig; }; // exporting information to create effect types // types.makeEffectType = makeEffectType; // types.isEffectType = function(x) { // return ((x instanceof plt.baselib.structs.StructType)&& x.type.prototype.invokeEffect) ? true : false; // }; // types.isEffect = Effect.predicate; // exporting functions to create render effect types // types.makeRenderEffectType = makeRenderEffectType; // types.isRenderEffectType = function(x) { // return (x instanceof plt.baselib.structs.StructType && x.type.prototype.callImplementation) ? true : false; // }; // types.isRenderEffect = RenderEffect.predicate; scope.link.announceReady('types'); })(this['plt']);