summaryrefslogtreecommitdiff
path: root/js/dojo-1.6/dojox/calc/_Executor.xd.js
blob: d3968c303e7080f13a7d3e238d03277dcc1fc301 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
	Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
	Available via Academic Free License >= 2.1 OR the modified BSD license.
	see: http://dojotoolkit.org/license for details
*/


dojo._xdResourceLoaded(function(dojo, dijit, dojox){
return {depends: [["provide", "dojox.calc._Executor"],
["require", "dijit._Templated"],
["require", "dojox.math._base"]],
defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.calc._Executor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojox.calc._Executor"] = true;
dojo.provide("dojox.calc._Executor");
dojo.require("dijit._Templated");
dojo.require("dojox.math._base");



dojo.experimental("dojox.calc._Executor");

(function(){
var calcEnv; // private

// do not override toFrac's pow function if it won the race
if(!("pow" in dojox.calc)){
	dojox.calc.pow = function(/*Number*/ base, /*Number*/ exponent){
		// summary:
		//		Computes base ^ exponent
		//		Wrapper to Math.pow(base, exponent) to handle (-27) ^ (1/3)

		function isInt(n){
			return Math.floor(n) == n;
		}

		if(base >= 0 || isInt(exponent)){
			return Math.pow(base, exponent);
		}else{ // e.g. (1/3) root of -27 = -3
			var inv = 1 / exponent;
			// e.g. 1 / (1/3) must be an odd integer
			return (isInt(inv) && (inv & 1)) ? -Math.pow(-base, exponent) : NaN;
		}
	};
}


dojo.declare(
	"dojox.calc._Executor",
	[dijit._Widget, dijit._Templated],
{
	// summary:
	//		A graphing, scientific calculator
	//
	
	templateString: '<iframe src="' +
		dojo.moduleUrl("dojox.calc","_ExecutorIframe.html") +
		'" style="display:none;" onload="if(arguments[0] && arguments[0].Function)'+dijit._scopeName+'.byNode(this)._onLoad(arguments[0])"></iframe>',

	_onLoad: function(env){
		// summary
		//	prepare for communications between the user and the calculator by saving the calculator environment, storing the prompt function locally, and making dojox.math available
		//
		calcEnv = env;
		env.outerPrompt = window.prompt; // for IE who can't execute the iframe's prompt method without notifying the user first
		// let the user call dojo math functions
		env.dojox = {math: {}};
		for(var f in dojox.math){ env.dojox.math[f] = dojo.hitch(dojox.math, f); }
		if("toFrac" in dojox.calc){
			env.toFracCall = dojo.hitch(dojox.calc, 'toFrac');
			this.Function('toFrac', 'x', "return toFracCall(x)");
		}

		env.isJavaScriptLanguage = dojo.number.format(1.5, {pattern:'#.#'}) == "1.5";
		env.Ans = 0;
		env.pi = Math.PI;
		env.eps = Math.E;

		env.powCall = dojo.hitch(dojox.calc, 'pow');

		// TODO add Degrees support to trig functions


		//this.normalizedFunction('toString', 'number, radix', "return number.toString(radix)");
		this.normalizedFunction('sqrt', 'x', "return Math.sqrt(x)");
		this.normalizedFunction('sin', 'x', "return Math.sin(x)");
		this.normalizedFunction('cos', 'x', "return Math.cos(x)");
		this.normalizedFunction('tan', 'x', "return Math.tan(x)");
		this.normalizedFunction('asin', 'x', "return Math.asin(x)");
		this.normalizedFunction('acos', 'x', "return Math.acos(x)");
		this.normalizedFunction('atan', 'x', "return Math.atan(x)");
		this.normalizedFunction('atan2', 'y, x', "return Math.atan2(y, x)");
		this.normalizedFunction('Round', 'x', "return Math.round(x)");
		this.normalizedFunction('Int', 'x', "return Math.floor(x)");
		this.normalizedFunction('Ceil', 'x', "return Math.ceil(x)");
		this.normalizedFunction('ln', 'x', "return Math.log(x)");
		this.normalizedFunction('log', 'x', "return Math.log(x)/Math.log(10)");
		this.normalizedFunction('pow', 'x, y', "return powCall(x,y)");
		this.normalizedFunction('permutations', 'n, r', "return dojox.math.permutations(n, r);");
		this.normalizedFunction('P', 'n, r', "return dojox.math.permutations(n, r);");
		this.normalizedFunction('combinations', 'n, r', "return dojox.math.combinations(n, r);");
		this.normalizedFunction('C', 'n, r', "return dojox.math.combinations(n, r)");

		this.normalizedFunction('toRadix', 'number, baseOut', "if(!baseOut){ baseOut = 10; } if(typeof number == 'string'){ number = parseFloat(number); }return number.toString(baseOut);");
		this.normalizedFunction('toBin', 'number', "return toRadix(number, 2)");
		this.normalizedFunction('toOct', 'number', "return toRadix(number, 8)");
		this.normalizedFunction('toHex', 'number', "return toRadix(number, 16)");
		this.onLoad();
	},

	onLoad: function(){
		// summary:
		//	this should be overwritten and become a great place for making user predefined functions
		//
	},
	Function: function(name, args, body){
		// summary
		//	create an anonymous function to run the code the parser generates from the user input.
		// params
		//	name: this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
		//	args: the function arguments (a String)
		//	body: the function body, also a String
		//
		return dojo.hitch(calcEnv, calcEnv.Function.apply(calcEnv, arguments));
	},
	normalizedFunction: function(name, args, body){
		return dojo.hitch(calcEnv, calcEnv.normalizedFunction.apply(calcEnv, arguments));
	},
	deleteFunction: function(name){
		calcEnv[name] = undefined;
		delete calcEnv[name];
	},
	eval: function(text){
		// summary
		//	create an anonymous function to run the code the parser generates from the user input.
		// params
		//	text, type String, is the user input that needs to be parsed
		//
		return calcEnv.eval.apply(calcEnv, arguments);
	},
	destroy: function(){
		this.inherited(arguments);
		calcEnv = null; // assist garbage collection
	}
});
})();

(function(){
	var magicBigInt = (1 << 30) - 35; // 2^30 - 35 is a prime that ensures approx(n/(2^k)) != n/(2^k) for k >= 1 and n < 2^k
	dojo.mixin(dojox.calc, {
		approx: function(r){
			// summary:
			//	Return a less exact approximation of r such that approx(r * (1 +- eps)) == approx(r)
			if(typeof r == "number"){
				return Math.round(r * magicBigInt) / magicBigInt;
			}
			return r;
		}
	});
})();

}

}};});