forked from rauschma/op_overload
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpoint.js
90 lines (82 loc) · 2.37 KB
/
point.js
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
function Point(x, y) {
if (arguments.length === 0) {
x = 0;
y = 0;
} else if (arguments.length !== 2) {
throw new Error("Need either 0 or 2 arguments");
}
this.x = x;
this.y = y;
}
//-------------- Operator overloading
Point.operands = [];
Point.prototype.valueOf = function () {
Point.operands.push(this);
// Lowest natural number x where the following are all different:
// x + x, x - x, x * x, x / x
return 3;
}
Object.defineProperty(Point.prototype, "_", {
set: function (value) {
var ops = Point.operands;
var operator;
if (ops.length === 2 && value === 0) { // 3 - 3
operator = this.setSubtract;
} else if (ops.length === 2 && value === 1) { // 3 / 3
operator = this.setDivide;
} else if (ops.length >= 2 && (value === 3 * ops.length)) { // 3 + 3 + 3 + ...
operator = this.setAdd;
} else if (ops.length >= 2 && (value === Math.pow(3, ops.length))) { // 3 * 3 * 3 * ...
operator = this.setMultiply;
} else {
throw new Error("Unsupported operation (code "+value+")");
}
Point.operands = []; // reset
return operator.apply(this, ops);
},
/**
* "" + mypoint won't invoke toString(), but valueOf().
* Work-around: "" + mypoint._
*/
get: function () {
return this.toString();
}
});
//-------------- Operator implementations
Point.prototype.setSubtract = function (l, r) {
this.x = l.x - r.x;
this.y = l.y - r.y;
return this;
}
Point.prototype.setDivide = function (l, r) {
this.x = l.x / r.x;
this.y = l.y / r.y;
return this;
}
Point.prototype.setAdd = function (first) {
this.x = first.x;
this.y = first.y;
[].slice.call(arguments, 1).forEach(function (op) {
this.x += op.x;
this.y += op.y;
}, this);
return this;
}
Point.prototype.setMultiply = function (first) {
this.x = first.x;
this.y = first.y;
[].slice.call(arguments, 1).forEach(function (op) {
this.x *= op.x;
this.y *= op.y;
}, this);
return this;
}
//-------------- Various helpers
Point.prototype.toString = function () {
return "Point("+this.x+", "+this.y+")";
}
Point.prototype.equals = function (other) {
return this.x === other.x && this.y === other.y;
}
//-------------- Exports
exports.Point = Point;