-
Notifications
You must be signed in to change notification settings - Fork 0
/
Pipe.js
147 lines (137 loc) · 3.93 KB
/
Pipe.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
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
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
([], function(){
"use strict";
var uniqNumber = 0;
function Arg(name){
this.name = name;
}
function Pipe(){
this.stages = [];
// stages is an array of objects with following components:
//
// type: a required string corresponding to one of
// primitive operations (see below)
//
// Following optional properties represent an executable code
// either by an array of strings, or as a function:
//
// code: this code is executed on every operation
// head: this code is executed once before a loop
// tail: this code is executed once after a loop
//
// Following optional properties represent a list of variables
// as an array of strings:
//
// args: a list of additional argument names
// vars: a list of additional internal variables
// possibly with initializers
//
// value: a literal value required by some operations, or
// an Arg object, which tells a name of an argument
// receiving the value (should be in args already)
}
Pipe.Arg = Arg;
Pipe.arg = function(name){ return new Arg(name); };
function prepareCode(code){
if(typeof code == "function"){
return code;
}
if(typeof code == "string"){
return code.split("\n");
}
if(code && code instanceof Array){
return code.slice(0);
}
//TODO: add asserts
return null;
}
Pipe.prototype = {
add: function(type, stage, context, value){
if(type && type instanceof Pipe){
if(type.stages.length){
this.stages.push.apply(this.stages, type.stages);
}
return this;
}
var s = {type: type};
if(stage){
if(typeof stage == "string"){
s.code = stage.split("\n");
}else if(stage instanceof Array){
s.code = stage.slice(0);
}else if(typeof stage == "function"){
s.code = context ? stage.bind(context) : stage;
}else{
// copying arrays
stage.args && (s.args = stage.args.slice(0));
stage.vars && (s.vars = stage.vars.slice(0));
stage.head && (s.head = prepareCode(stage.head));
stage.code && (s.code = prepareCode(stage.code));
stage.tail && (s.tail = prepareCode(stage.tail));
if(stage.hasOwnProperty("value")){
s.value = stage.value;
}
}
}
if(arguments.length > 3){
s.value = value; // literal value
}
this.stages.push(s);
return this;
},
getName: function(){
return this.stages.map(function(stage){ return stage.type; }).join("-") +
"_" + (uniqNumber++) + ".js";
},
// standard operations
forEach: function(code, context){
return this.add("forEach", code, context);
},
transform: function(code, context){
return this.add("transform", code, context);
},
map: function(code, context){
return this.add("map", code, context);
},
filter: function(code, context){
return this.add("filter", code, context);
},
indexOf: function(value){
return this.add("indexOf", null, null, value);
},
every: function(code, context){
return this.add("every", code, context);
},
some: function(code, context){
return this.add("some", code, context);
},
fold: function(code, value){
return this.add("fold", code, null, value);
},
scan: function(code, value){
return this.add("scan", code, null, value);
},
skip: function(value){
return this.add("skip", null, null, value);
},
take: function(value){
return this.add("take", null, null, value);
},
skipWhile: function(code, context){
return this.add("skipWhile", code, context);
},
takeWhile: function(code, context){
return this.add("takeWhile", code, context);
},
voidResult: function(){
return this.add("voidResult");
},
find: function(code, context){
return this.add("find", code, context);
},
findIndex: function(code, context){
return this.add("findIndex", code, context);
}
};
return Pipe;
});