kopia lustrzana https://github.com/backface/turtlestitch
1 wiersz
15 KiB
XML
1 wiersz
15 KiB
XML
<blocks app="Snap! 5.0, http://snap.berkeley.edu" version="1"><block-definition s="USE BIGNUMS %'bool'" type="command" category="operators"><comment x="0" y="0" w="303.3333333333333" collapsed="false">call with True to turn on the entire Scheme numeric tower, including infinite-precision integers, exact rationals, and complex numbers; call with False to restore native JavaScript arithmetic.</comment><header></header><code></code><translations></translations><inputs><input type="%b"></input></inputs><script><block s="doDeclareVariables"><list><l>isDone</l></list></block><block s="doSetVar"><l>isDone</l><block s="evaluate"><block s="reportJSFunction"><list><l>useBigNums</l></list><l>var done = false;

function initialize (callback) {
 var bigScript = document.createElement('script');
 bigScript.src = '//snap.berkeley.edu/snapsource/libraries/biginteger.js';
 bigScript.onload = loadScheme;
 document.head.appendChild(bigScript);

 function loadScheme () {
 var schemeScript = document.createElement('script');
 schemeScript.src = '//snap.berkeley.edu/snapsource/libraries/schemeNumber.js';
 schemeScript.onload = finish;
 document.head.appendChild(schemeScript);
 }

 function finish () {
 makeGlobalObject();
 callback();
 }
}

function makeGlobalObject () {
 window.bigNumbers = {
 originalEvaluate: InputSlotMorph.prototype.evaluate,
 originalChangeVar: VariableFrame.prototype.changeVar,
 originalPrims: {
 reportSum: Process.prototype.reportSum,
 reportDifference: Process.prototype.reportDifference,
 reportProduct: Process.prototype.reportProduct,
 reportQuotient: Process.prototype.reportQuotient,
 reportModulus: Process.prototype.reportModulus,
 reportRandom: Process.prototype.reportRandom,
 reportLessThan: Process.prototype.reportLessThan,
 reportGreaterThan: Process.prototype.reportGreaterThan,
 reportEquals: Process.prototype.reportEquals,
 reportIsIdentical: Process.prototype.reportIsIdentical,
 reportMonadic: Process.prototype.reportMonadic
 }
 };
}

function loadBlocks () {
 var fn = SchemeNumber.fn;
 var originalPrims = window.bigNumbers.originalPrims;
 if (useBigNums) {
 InputSlotMorph.prototype.evaluate = function () {
 var contents = this.contents();
 if (this.constant) {
 return this.constant;
 }
 if (this.isNumeric) {
 return parseNumber(contents.text || '0');
 }
 return contents.text;
 };
 VariableFrame.prototype.changeVar = function (name, delta, sender) {
 var frame = this.find(name),
 value,
 newValue;
 if (frame) {
 value = parseNumber(frame.vars[name].value);
 newValue = value !== value ? delta : value + parseNumber(delta);
 if (sender instanceof SpriteMorph &&
 (frame.owner instanceof SpriteMorph) &&
 (sender !== frame.owner)) {
 sender.shadowVar(name, newValue);
 } else {
 frame.vars[name].value = newValue;
 }

 }
 };
 Object.assign(Process.prototype, {
 reportSum: function (a, b) {
 a = parseNumber(a);
 b = parseNumber(b);
 if (a !== a || b !== b) return NaN;
 return fn['+'](a, b);
 },
 reportDifference: function (a, b) {
 a = parseNumber(a);
 b = parseNumber(b);
 if (a !== a || b !== b) return NaN;
 return fn['-'](a, b);
 },
 reportProduct: function (a, b) {
 a = parseNumber(a);
 b = parseNumber(b);
 if (a !== a || b !== b) return NaN;
 return fn['*'](a, b);
 },
 reportQuotient: function (a, b) {
 a = parseNumber(a);
 b = parseNumber(b);
 if (fn['='](b, '0') && !fn['='](a, '0')) {
 return (fn['<'](a, '0') ? SchemeNumber('-inf.0') : SchemeNumber('+inf.0'))
 };
 if (a !== a || b !== b || fn['='](b, '0')) return SchemeNumber('+nan.0');
 return fn['/'](a, b);
 },
 reportModulus: function (a, b) {
 a = parseNumber(a);
 b = parseNumber(b);
 if (a !== a || b !== b) return NaN;
 var result = fn.mod(a, b);
 if (fn['<'](b, '0') && fn['>'](result, '0')) {
 result = fn['+'](result, b);
 }
 return result;
 },
 reportRandom: function (min, max) {
 var floor = parseNumber(min),
 ceil = parseNumber(max);
 if (floor !== floor || ceil !== ceil) return NaN;
 if (!fn['='](fn.mod(floor, '1'), '0') || !fn['='](fn.mod(ceil, '1'), '0')) {
 // One of the numbers isn't whole. Include the decimal.
 return fn['+'](
 fn['*'](
 Math.random(),
 fn['-'](ceil, floor)
 ),
 floor
 );
 }
 return fn.floor(
 fn['+'](
 fn['*'](
 Math.random(),
 fn['+'](
 fn['-'](ceil, floor),
 '1'
 )
 ),
 floor
 )
 );
 },
 reportLessThan: function (a, b) {
 a = parseNumber(a);
 b = parseNumber(b);
 if (a !== a || b !== b) return NaN;
 return fn['<'](a, b);
 },
 reportGreaterThan: function (a, b) {
 a = parseNumber(a);
 b = parseNumber(b);
 if (a !== a || b !== b) return NaN;
 return fn['>'](a, b);
 },
 reportGreaterThan: function (a, b) {
 a = parseNumber(a);
 b = parseNumber(b);
 if (a !== a || b !== b) return NaN;
 return fn['>'](a, b);
 },
 reportEqual: function (a, b) {
 x = parseNumber(a);
 y = parseNumber(b);
 if (x !== x || y !== y) return snapEquals(a, b);
 return fn['='](x, y);
 },
 reportIsIdentical: function (a, b) {
 x = parseNumber(a);
 y = parseNumber(b);
 if (x !== x || y !== y) return originalPrims.reportIsIdentical(a, b);
 return fn['='](x, y);
 },
 reportMonadic: function (fname, n) {
 n = parseNumber(n);
 if (n !== n) return NaN;

 switch (Process.prototype.inputOption(fname)) {
 case 'abs':
 return fn.abs(n);
 case 'ceiling':
 return fn.ceiling(n);
 case 'floor':
 return fn.floor(n);
 case 'sqrt':
 return sqrt(n);
 case 'sin':
 return fn.sin(radians(n));
 case 'cos':
 return fn.cos(radians(n));
 case 'tan':
 return fn.tan(radians(n));
 case 'asin':
 return degrees(fn.asin(n));
 case 'acos':
 return degrees(fn.acos(n));
 case 'atan':
 return degrees(fn.atan(n));
 case 'ln':
 return fn.log(n);
 case 'log':
 return fn.log(n, '10');
 case 'e^':
 return fn.exp(n);
 case '10^':
 return fn.expt('10', n);
 default:
 return SchemeNumber('0');
 }
 }
 });
 } else {
 InputSlotMorph.prototype.evaluate = window.bigNumbers.originalEvaluate;
 VariableFrame.prototype.changeVar = window.bigNumbers.originalChangeVar;
 Object.assign(Process.prototype, originalPrims);
 }
 done = true;
}

function parseNumber (n) {
 var fn = SchemeNumber.fn;
 if (!fn['number?'](n)) {
 n = '' + n;
 try {
 return parseENotation(n) || SchemeNumber(n);
 } catch (err) {
 return NaN;
 }
 }
 return n;
}

function parseENotation (n) {
 var fn = SchemeNumber.fn;

 var numbers = n.match(/^(-?\d+\.?\d*|-?\.\d+)e(-?\d+)$/i);
 if (!numbers) return null;

 var coefficient = numbers[1];
 var exponent = numbers[2];
 return fn['*'](
 coefficient,
 fn.expt('10', exponent)
 );
}

function sqrt (n) {
 var fn = SchemeNumber.fn;

 if (!fn['exact?'](n) || !fn['rational?'](n) || fn['<'](n,'0')) return fn.sqrt(n);

 var rootNumerator = fn['exact-integer-sqrt'](fn.numerator(n));
 if (!fn['='](rootNumerator[1], '0')) return fn.sqrt(n);

 var rootDenominator = fn['exact-integer-sqrt'](fn.denominator(n));
 if (!fn['='](rootDenominator[1], '0')) return fn.sqrt(n);

 return fn['/'](rootNumerator[0], rootDenominator[0]);
}

function isDone () {
 return done;
}

if (window.bigNumbers) {
 loadBlocks();
} else {
 initialize(loadBlocks);
}

return isDone;</l></block><list><block var="bool"/></list></block></block><block s="doWaitUntil"><block s="evaluate"><block var="isDone"/><list></list></block></block></script></block-definition><block-definition s="%'n' !" type="reporter" category="operators"><header></header><code></code><translations></translations><inputs><input type="%n"></input></inputs><script><block s="doReport"><block s="reportIfElse"><block s="reportEquals"><block var="n"/><l>0</l></block><l>1</l><block s="reportProduct"><block var="n"/><custom-block s="%n !"><block s="reportDifference"><block var="n"/><l>1</l></block></custom-block></block></block></block></script></block-definition><block-definition s="%'x'" type="reporter" category="operators"><header></header><code></code><translations></translations><inputs><input type="%s"></input></inputs><script><block s="doReport"><block var="x"/></block></script></block-definition><block-definition s="Scheme number %'function' of %'number'" type="reporter" category="operators"><comment x="0" y="0" w="300" collapsed="true">Provides Scheme arithmetic functions not in JavaScript</comment><header></header><code></code><translations></translations><inputs><input type="%s" readonly="true"><options>number?
complex?
real?
rational?
integer?
exact?
inexact?
exact
inexact
finite?
infinite?
nan?
numerator
denominator
real-part
imag-part
magnitude
angle</options></input><input type="%s"></input></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list><l>which</l><l>num</l></list><l>function parseNumber (n) {
 var fn = SchemeNumber.fn;
 if (!fn['number?'](n)) {
 n = '' + n;
 try {
 return parseENotation(n) || SchemeNumber(n);
 } catch (err) {
 return NaN;
 }
 }
 return n;
}

function parseENotation (n) {
 var fn = SchemeNumber.fn;

 var numbers = n.match(/^(-?\d+\.?\d*|-?\.\d+)e(-?\d+)$/i);
 if (!numbers) return null;

 var coefficient = numbers[1];
 var exponent = numbers[2];
 return fn['*'](
 coefficient,
 fn.expt('10', exponent)
 );
}
var fn=SchemeNumber.fn,
 number=parseNumber(num);

switch (which) {
 case 'number?':
 case 'complex?':
 return (fn['number?'](number));
 case 'real?':
 return (fn['real?'](number) || fn['real-valued?'](number));
 case 'rational?':
 return (fn['rational?'](number) || (fn['='](number, fn.rationalize(number, parseNumber('1.0e-5')))));
 case 'integer?':
 return (fn['integer?'](number) || fn['integer-valued?'](number));
 case 'exact?':
 case 'inexact?':
 case 'finite?':
 case 'infinite?':
 case 'nan?':
 case 'real-part':
 case 'imag-part':
 return (fn[which](number));
 case 'magnitude':
 return (fn.magnitude(number));
 case 'angle':
 return (fn.angle(number));
 case 'numerator':
 return (fn.numerator(number));
 case 'denominator':
 return (fn.denominator(number));
 case 'exact':
 return (fn.exact(number));
case 'inexact':
 return (fn.inexact(number));
}</l></block><list><block var="function"/><block var="number"/></list></block></block></script></block-definition></blocks> |