Skip to content

Commit 079fbb5

Browse files
committed
[js] Turn the nqp::iterator op into an $$iterator method call instead of having an if chain.
1 parent f566573 commit 079fbb5

File tree

6 files changed

+69
-63
lines changed

6 files changed

+69
-63
lines changed

src/vm/js/Operations.nqp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ class QAST::OperationsJS {
874874
add_simple_op('setelems', $T_OBJ, [$T_OBJ, $T_INT], :sideffects);
875875

876876

877-
add_simple_op('iterator', $T_OBJ, [$T_OBJ], :sideffects);
877+
add_simple_op('iterator', $T_OBJ, [$T_OBJ], sub ($over) {"$over.\$\$iterator()"}, :sideffects);
878878

879879
add_simple_op('iterval', $T_OBJ, [$T_OBJ], sub ($iter) {"$iter.iterval()"});
880880
add_simple_op('iterkey_s', $T_STR, [$T_OBJ], sub ($iter) {"$iter.iterkey_s()"});

src/vm/js/nqp-runtime/array.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22
var NQPException = require('./nqp-exception.js');
3+
var Iter = require('./iter.js');
34

45
function NQPArray(array) {
56
this.array = array;
@@ -130,6 +131,10 @@ NQPArray.prototype.$$atposnd = function(idx) {
130131
return this.array[index < 0 ? this.array.length + index : index];
131132
};
132133

134+
NQPArray.prototype.$$iterator = function() {
135+
return new Iter(this.array);
136+
};
137+
133138
NQPArray.prototype.$$atposnd_i = NQPArray.prototype.$$atposnd;
134139
NQPArray.prototype.$$atposnd_n = NQPArray.prototype.$$atposnd;
135140
NQPArray.prototype.$$atposnd_s = NQPArray.prototype.$$atposnd;

src/vm/js/nqp-runtime/core.js

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -81,69 +81,8 @@ op.setdebugtypename = function(type, debugName) {
8181
return type;
8282
};
8383

84-
function Iter(array) {
85-
this.array = array;
86-
this.target = array.length;
87-
this.idx = 0;
88-
}
89-
90-
Iter.prototype.$$shift = function() {
91-
return this.array[this.idx++];
92-
};
93-
94-
Iter.prototype.$$toBool = function(ctx) {
95-
return this.idx < this.target;
96-
};
97-
98-
function HashIter(hash) {
99-
this.hash = hash.content;
100-
this.keys = Object.keys(hash.$$toObject());
101-
this.target = this.keys.length;
102-
this.idx = 0;
103-
}
104-
105-
HashIter.prototype.$$shift = function() {
106-
return new IterPair(this.hash, this.keys[this.idx++]);
107-
};
108-
109-
HashIter.prototype.$$toBool = function(ctx) {
110-
return this.idx < this.target;
111-
};
112-
113-
function IterPair(hash, key) {
114-
this._key = key;
115-
this._hash = hash;
116-
}
117-
118-
IterPair.prototype.iterval = function() {
119-
return this._hash.get(this._key);
120-
};
121-
IterPair.prototype.iterkey_s = function() {
122-
return this._key;
123-
};
124-
125-
IterPair.prototype.Str = function(ctx, _NAMED, self) {
126-
return this._key;
127-
};
128-
129-
IterPair.prototype.key = function(ctx, _NAMED, self) {
130-
return this._key;
131-
};
132-
IterPair.prototype.value = function(ctx, _NAMED, self) {
133-
return this._hash.get(this._key);
134-
};
135-
136-
13784
op.iterator = function(obj) {
138-
if (obj instanceof NQPArray) {
139-
return new Iter(obj.array);
140-
} else if (obj instanceof Hash) {
141-
return new HashIter(obj);
142-
} else if (obj instanceof Ctx) {
143-
return new Iter(Object.keys(obj).filter(key => key.substr(0, 2) != '$$'));
144-
} else {
145-
throw 'unsupported thing to iterate over';
146-
}
85+
return obj.$$iterator();
14786
};
14887

14988

src/vm/js/nqp-runtime/ctx.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22
var CodeRef = require('./code-ref.js');
33
var NQPException = require('./nqp-exception.js');
4+
var Iter = require('./iter.js');
45

56
class Ctx {
67
constructor(callerCtx, outerCtx, callThis, codeRefAttr) {
@@ -142,6 +143,10 @@ class Ctx {
142143
}
143144
throw "Can't bind dynamic: " + name;
144145
}
146+
147+
$$iterator() {
148+
return new Iter(Object.keys(this).filter(key => key.substr(0, 2) != '$$'));
149+
}
145150
};
146151

147152
module.exports = Ctx;

src/vm/js/nqp-runtime/hash.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,41 @@
1+
function HashIter(hash) {
2+
this.hash = hash.content;
3+
this.keys = Object.keys(hash.$$toObject());
4+
this.target = this.keys.length;
5+
this.idx = 0;
6+
}
7+
8+
HashIter.prototype.$$shift = function() {
9+
return new IterPair(this.hash, this.keys[this.idx++]);
10+
};
11+
12+
HashIter.prototype.$$toBool = function(ctx) {
13+
return this.idx < this.target;
14+
};
15+
16+
function IterPair(hash, key) {
17+
this._key = key;
18+
this._hash = hash;
19+
}
20+
21+
IterPair.prototype.iterval = function() {
22+
return this._hash.get(this._key);
23+
};
24+
IterPair.prototype.iterkey_s = function() {
25+
return this._key;
26+
};
27+
28+
IterPair.prototype.Str = function(ctx, _NAMED, self) {
29+
return this._key;
30+
};
31+
32+
IterPair.prototype.key = function(ctx, _NAMED, self) {
33+
return this._key;
34+
};
35+
IterPair.prototype.value = function(ctx, _NAMED, self) {
36+
return this._hash.get(this._key);
37+
};
38+
139
function Hash() {
240
this.content = new Map();
341
}
@@ -48,4 +86,8 @@ Hash.prototype.$$toBool = function() {
4886
return this.content.size == 0 ? 0 : 1;
4987
};
5088

89+
Hash.prototype.$$iterator = function() {
90+
return new HashIter(this);
91+
};
92+
5193
module.exports = Hash;

src/vm/js/nqp-runtime/iter.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function Iter(array) {
2+
this.array = array;
3+
this.target = array.length;
4+
this.idx = 0;
5+
}
6+
7+
Iter.prototype.$$shift = function() {
8+
return this.array[this.idx++];
9+
};
10+
11+
Iter.prototype.$$toBool = function(ctx) {
12+
return this.idx < this.target;
13+
};
14+
15+
module.exports = Iter;

0 commit comments

Comments
 (0)