summaryrefslogtreecommitdiff
path: root/engines/kokompe/temp/KoRuleProcessor.js
blob: e007f6464c96fc4913c4a28daf11159df9870161 (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
// Based in part on http://snippets.dzone.com/posts/show/2207 by Jonas Raoni.

KoRuleProcessor = function(){
	this.BinaryOperations = {
		"+": function(a, b){ return +a + b; },
		"-": function(a, b){ return a - b; },
		"%": function(a, b){ return a % b; },
		"/": function(a, b){ return a / b; },
		"*": function(a, b){ return a * b; },
		"^": function(a, b){ return Math.pow(a, b); },
		"~": function(a, b){ return a == b; }
	};
	this.UnaryOperations = {
		"+": 1, 
		"-": -1, 
	};
	this.OperatorPrecedence = { "^": 3, "~": 3, "*": 2, "/": 2, "%": 1, "+": 0, "-": 0 };
	this.Parenthesis = {"(": 1, ")": -1};
};

KoRuleProcessor.prototype = {
	
	Parse: function(input){
		for (var n, x, tokens = [], s = [x = this.RPN(input.replace(/ /g, "").split(""))]; s.length;) {
			while (token = s.pop()) {
				tokens.push(n);
				s[s.length] = token[3];
				token = token[2]
			}
		}
		while ((n = tokens.pop()) != undefined; ) {
			n[0] = this.tokens[n[0]](isNaN(n[2][0]) ? this.f(n[2][0]) : n[2][0], isNaN(n[3][0]) ? this.f(n[3][0]) : n[3][0]);
		}
		return +x[0];
	},

	methods = {
		"div": function(a, b){ return parseInt(a / b); },
		"frac": function(a){ return a - parseInt(a); },
		"sum": function(n1, n2, n3, n){ for(var r = 0, a, l = (a = arguments).length; l; r += a[--l]); return r; },
		"average": function(n1, n2, n3, n){ for(var r = 0, a, l = (a = arguments).length; l; r += a[--l]); return r/(arguments.length) },
		"sin": funtion(a){ return Math.sin(a); },
		"cos": funtion(a){ return Math.cos(a); },
		"tan": funtion(a){ return Math.tan(a); },
		"sqrt": function(a){ return Math.sqrt(a); }
	},

	error: function(s){
		throw new Error("KoRuleProcessor: " + (s || "Error in expression"));
	},

	RPN: function(e){
		var _, r, c = r = [, , , 0];
		if(e[0] in this.u || !e.unshift("+"))
			for(; e[1] in this.u; e[0] = this.u[e.shift()] * this.u[e[0]] + 1 ? "+" : "-");
		(c[3] = [this.u[e.shift()], c, , 0])[1][0] = "*", (r = [, , c, 0])[2][1] = r;
		(c[2] = this.v(e))[1] = c;
		(!e.length && (r = c)) || (e[0] in this.s && ((c = r)[0] = e.shift(), !e.length && this.error()));
		while(e.length){
			if(e[0] in this.u){
				for(; e[1] in this.u; e[0] = this.u[e.shift()] * this.u[e[0]] + 1 ? "+" : "-");
				(c = c[3] = ["*", c, , 0])[2] = [-1, c, , 0];
			}
			(c[3] = this.v(e))[1] = c;
			e[0] in this.s && (c = this.s[e[0]] > this.s[c[0]] ?
			((c[3] = (_ = c[3], c[2]))[1][2] = [e.shift(), c, _, 0])[2][1] = c[2]
				: r == c ? (r = [e.shift(), , c, 0])[2][1] = r
				: ((r[2] = (_ = r[2], [e.shift(), r, ,0]))[2] = _)[1] = r[2]);
		}
		return r;
	},

	v: function(e){
		if("0123456789.".indexOf(e[0]) + 1){
			for(var i = -1, l = e.length; ++i < l && "0123456789.".indexOf(e[i]) + 1;);
			return [+e.splice(0,i).join(""), , , 0];
		} else if(e[0] == "("){
			for(var i = 0, l = e.length, j = 1; ++i < l && (e[i] in this.p && (j += this.p[e[i]]), j););
			return this.RPN(l = e.splice(0,i), l.shift(), !j && e.shift());
		} else {
			var i = 0, c = e[0].toLowerCase();
			if((c >= "a" && c <= "z") || c == "_"){
				while(((c = e[++i].toLowerCase()) >= "a" && c <= "z") || c == "_" || (c >= 0 && c <= 9));
				if(c == "(") {
					for(var l = e.length, j = 1; ++i < l && (e[i] in this.p && (j += this.p[e[i]]), j););
					return [e.splice(0,i+1).join(""), , , 0];
				}
			}
		}
		this.error();
	},

	f: function(e) {
		var i = 0, n;
		if(((e = e.split(""))[i] >= "a" && e[i] <= "z") || e[i] == "_"){
			while((e[++i] >= "a" && e[i] <= "z") || e[i] == "_" || (e[i] >= 0 && e[i] <= 9));
			if(e[i] == "("){
				!this.methods[n = e.splice(0, i).join("")] && this.error("Funtion \"" + n + "\" not found."), e.shift();
				for(var a = [], i = -1, j = 1; e[++i] && (e[i] in this.p && (j += this.p[e[i]]), j);)
					j == 1 && e[i] == "," && (a.push(this.parse(e.splice(0, i).join(""))), e.shift(), i = -1);
				a.push(this.parse(e.splice(0,i).join(""))), !j && e.shift();
			}
			return this.methods[n].apply(this, a);
		}
	}
};