react 0.0.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmignore +6 -0
- package/Jakefile.js +8 -0
- package/README.md +226 -86
- package/examples/ast1.js +26 -0
- package/examples/chain-events1.js +34 -0
- package/examples/chain1.js +19 -0
- package/examples/default-events1.js +52 -0
- package/examples/default1.js +40 -0
- package/examples/fstr-events1.js +51 -0
- package/examples/fstr1.js +36 -0
- package/examples/pcode1.js +22 -0
- package/jake-tasks/jake-test.js +64 -0
- package/lib/base-task.js +115 -0
- package/lib/cb-task.js +67 -0
- package/lib/chain.js +148 -0
- package/lib/core.js +96 -0
- package/lib/dsl.js +122 -0
- package/lib/error.js +37 -0
- package/lib/event-manager.js +57 -0
- package/lib/finalcb-first-task.js +59 -0
- package/lib/finalcb-task.js +54 -0
- package/lib/fstr.js +110 -0
- package/lib/id.js +10 -0
- package/lib/input-parser.js +44 -0
- package/lib/parse.js +29 -0
- package/lib/pcode.js +164 -0
- package/lib/ret-task.js +67 -0
- package/lib/status.js +5 -0
- package/lib/task.js +234 -0
- package/lib/validate.js +102 -0
- package/lib/vcon.js +76 -0
- package/oldExamples/analyze.js +29 -0
- package/oldExamples/analyze2.js +29 -0
- package/oldExamples/example10-dsl.js +63 -0
- package/oldExamples/example11.js +62 -0
- package/oldExamples/example12.js +63 -0
- package/oldExamples/example13.js +63 -0
- package/oldExamples/example14.js +63 -0
- package/oldExamples/example15.js +75 -0
- package/{test → oldExamples}/example6-ast.js +4 -4
- package/{test → oldExamples}/example6-dsl.js +3 -2
- package/{test → oldExamples}/example8-ast.js +3 -2
- package/{test → oldExamples}/example8-dsl.js +3 -2
- package/{test → oldExamples}/example9-ast.js +3 -2
- package/{test → oldExamples}/example9-dsl.js +3 -2
- package/oldExamples/function-str-ex1.js +33 -0
- package/oldExamples/function-str-ex2.js +67 -0
- package/oldExamples/trait1.js +41 -0
- package/oldExamples/trait2.js +44 -0
- package/package.json +16 -6
- package/react.js +11 -1
- package/test/ast.test.js +69 -0
- package/test/cb-task.test.js +197 -0
- package/test/chain.test.js +239 -0
- package/test/core.test.js +519 -0
- package/test/dsl.test.js +237 -0
- package/test/event-manager.test.js +102 -0
- package/test/exec-options.test.js +32 -0
- package/test/finalcb-task.test.js +37 -0
- package/test/fstr.test.js +288 -0
- package/test/input-parser.test.js +62 -0
- package/test/module-use.test.js +317 -0
- package/test/pcode.test.js +321 -0
- package/test/ret-task.test.js +199 -0
- package/test/task.test.js +21 -0
- package/test/validate-cb-task.test.js +74 -0
- package/test/validate-ret-task.test.js +83 -0
- package/test/validate.test.js +218 -0
- package/test/vcon.test.js +160 -0
- package/lib/react.js +0 -239
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sprintf = require('sprintf').sprintf;
|
|
4
|
+
var util = require('util');
|
|
5
|
+
|
|
6
|
+
var STATUS = require('./status.js');
|
|
7
|
+
var VContext = require('./vcon.js');
|
|
8
|
+
|
|
9
|
+
var OUTTASK_A_REQ = 'ast.outTask.a should be an array of string param names';
|
|
10
|
+
|
|
11
|
+
function FinalCbFirstSuccTask(taskDef, cbFunc, tasks, vCon) {
|
|
12
|
+
var self = this;
|
|
13
|
+
Object.keys(taskDef).forEach(function (k) { self[k] = taskDef[k]; });
|
|
14
|
+
this.f = cbFunc;
|
|
15
|
+
this.tasks = tasks;
|
|
16
|
+
this.vCon = vCon;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function format_error(errmsg, obj) {
|
|
20
|
+
return sprintf('%s - %s', errmsg, util.inspect(obj));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
FinalCbFirstSuccTask.validate = function (taskDef) {
|
|
24
|
+
var errors = [];
|
|
25
|
+
if (! (Array.isArray(taskDef.a) &&
|
|
26
|
+
taskDef.a.every(function (x) { return (typeof(x) === 'string'); }))) {
|
|
27
|
+
errors.push(format_error(OUTTASK_A_REQ, taskDef));
|
|
28
|
+
}
|
|
29
|
+
return errors;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
FinalCbFirstSuccTask.create = function (taskDef, cbFunc, tasks, vCon) {
|
|
33
|
+
if (!(cbFunc && cbFunc instanceof Function)) throw new Error('callback is not a function');
|
|
34
|
+
return new FinalCbFirstSuccTask(taskDef, cbFunc, tasks, vCon);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
is ready to exit when any task comes back with non-null defined value
|
|
39
|
+
*/
|
|
40
|
+
FinalCbFirstSuccTask.prototype.isReady = function () {
|
|
41
|
+
var lastres = this.vCon.getLastResults();
|
|
42
|
+
if (!lastres) return false; // no results yet
|
|
43
|
+
return (lastres.some(function (v) { return (v !== undefined && v !== null); }));
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
FinalCbFirstSuccTask.prototype.exec = function (err) {
|
|
47
|
+
if (!this.f) return; //must have already been called
|
|
48
|
+
if (err) {
|
|
49
|
+
this.f.call(null, err); //call the final callback with the first error hit
|
|
50
|
+
} else { // no error, call with args
|
|
51
|
+
var vCon = this.vCon;
|
|
52
|
+
var finalArgs = this.a.map(function (k) { return vCon.getVar(k); });
|
|
53
|
+
finalArgs.unshift(null); //unshift err=null to front
|
|
54
|
+
this.f.apply(null, finalArgs);
|
|
55
|
+
}
|
|
56
|
+
this.f = null; // prevent multiple calls
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
module.exports = FinalCbFirstSuccTask;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sprintf = require('sprintf').sprintf;
|
|
4
|
+
var util = require('util');
|
|
5
|
+
|
|
6
|
+
var STATUS = require('./status.js');
|
|
7
|
+
|
|
8
|
+
var OUTTASK_A_REQ = 'ast.outTask.a should be an array of string param names';
|
|
9
|
+
|
|
10
|
+
function FinalCbTask(taskDef, cbFunc, tasks, vCon) {
|
|
11
|
+
var self = this;
|
|
12
|
+
Object.keys(taskDef).forEach(function (k) { self[k] = taskDef[k]; });
|
|
13
|
+
this.f = cbFunc;
|
|
14
|
+
this.tasks = tasks;
|
|
15
|
+
this.vCon = vCon;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function format_error(errmsg, obj) {
|
|
19
|
+
return sprintf('%s - %s', errmsg, util.inspect(obj));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
FinalCbTask.validate = function (taskDef) {
|
|
24
|
+
var errors = [];
|
|
25
|
+
if (! (Array.isArray(taskDef.a) &&
|
|
26
|
+
taskDef.a.every(function (x) { return (typeof(x) === 'string'); }))) {
|
|
27
|
+
errors.push(format_error(OUTTASK_A_REQ, taskDef));
|
|
28
|
+
}
|
|
29
|
+
return errors;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
FinalCbTask.create = function (taskDef, cbFunc, tasks, vCon) {
|
|
33
|
+
if (!(cbFunc && cbFunc instanceof Function)) throw new Error('callback is not a function');
|
|
34
|
+
return new FinalCbTask(taskDef, cbFunc, tasks, vCon);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
FinalCbTask.prototype.isReady = function () {
|
|
38
|
+
return (this.tasks.every(function (t) { return (t.status === STATUS.COMPLETE); }));
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
FinalCbTask.prototype.exec = function (err) {
|
|
42
|
+
if (!this.f) return; //must have already been called
|
|
43
|
+
if (err) {
|
|
44
|
+
this.f.call(null, err); //call the final callback with the first error hit
|
|
45
|
+
} else { // no error, call with args
|
|
46
|
+
var vCon = this.vCon;
|
|
47
|
+
var finalArgs = this.a.map(function (k) { return vCon.getVar(k); });
|
|
48
|
+
finalArgs.unshift(null); //unshift err=null to front
|
|
49
|
+
this.f.apply(null, finalArgs);
|
|
50
|
+
}
|
|
51
|
+
this.f = null; // prevent multiple calls
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
module.exports = FinalCbTask;
|
package/lib/fstr.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sprintf = require('sprintf').sprintf;
|
|
4
|
+
var core = require('./core.js');
|
|
5
|
+
var parse = require('./parse.js');
|
|
6
|
+
var tutil = require('./task.js');
|
|
7
|
+
|
|
8
|
+
var INPARAMS_NO_MATCH = 'input params in wrong format, wanted "foo, bar" - found: %s';
|
|
9
|
+
var OUTPARAMS_NO_MATCH = 'output params in wrong format, wanted "foo, bar" - found: %s';
|
|
10
|
+
var INOUT_PARAMS_NO_MATCH = 'task params in wrong format, wanted "foo, bar -> err, baz" - found: %s';
|
|
11
|
+
var EXTRA_TASKARG = 'extra unmatched task arg: %s';
|
|
12
|
+
|
|
13
|
+
var inOutDefParse = {
|
|
14
|
+
regex: /^([^-]*)(->)?\s*(er{0,2}\s*,|returns?\s+)?(.*)$/i,
|
|
15
|
+
fn: function (m) {
|
|
16
|
+
var reMatchReturns = /returns?/i;
|
|
17
|
+
return {
|
|
18
|
+
type: (m[3] && m[3].match(reMatchReturns)) ? 'ret' : 'cb',
|
|
19
|
+
inDef: parse.splitTrimFilterArgs(m[1]),
|
|
20
|
+
outDef: parse.splitTrimFilterArgs(m[4])
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function filterOutTrailingCbParam(args) { // if has trailing cb | callback param, filter it out
|
|
26
|
+
var cbNamesRe = /^cb|callback$/i; //cb, Cb, CB, callback, Callback
|
|
27
|
+
if (args.length && args[args.length - 1].match(cbNamesRe)) args.pop();
|
|
28
|
+
return args;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function parseInParams(str) {
|
|
32
|
+
var objDef = parse.parseStr(str, [inOutDefParse], INPARAMS_NO_MATCH);
|
|
33
|
+
objDef.inDef = filterOutTrailingCbParam(objDef.inDef);
|
|
34
|
+
return objDef;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function parseInOutParams(str) {
|
|
38
|
+
var objDef = parse.parseStr(str, [inOutDefParse], INOUT_PARAMS_NO_MATCH);
|
|
39
|
+
objDef.inDef = filterOutTrailingCbParam(objDef.inDef);
|
|
40
|
+
return objDef;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function parseOutParams(str) {
|
|
44
|
+
if (str.indexOf('->') === -1) str = '-> ' + str; // prefix so does out err process
|
|
45
|
+
return parse.parseStr(str, [inOutDefParse], OUTPARAMS_NO_MATCH);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function parseTasks(arr) {
|
|
49
|
+
var tasks = [];
|
|
50
|
+
var fn, obj, result;
|
|
51
|
+
while (arr.length >= 2) {
|
|
52
|
+
obj = {};
|
|
53
|
+
fn = arr.shift();
|
|
54
|
+
result = parseInOutParams(arr.shift());
|
|
55
|
+
if (typeof(arr[0]) === 'object') obj = arr.shift(); // has options, use as obj
|
|
56
|
+
obj.f = fn;
|
|
57
|
+
obj.a = result.inDef;
|
|
58
|
+
var type = result.type;
|
|
59
|
+
obj.out = result.outDef;
|
|
60
|
+
obj.type = type;
|
|
61
|
+
tasks.push(obj);
|
|
62
|
+
}
|
|
63
|
+
if (arr.length) throw new Error(sprintf(EXTRA_TASKARG, arr[0]));
|
|
64
|
+
return tasks;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
function fstrDefine(inParamStr, taskDefArr, outParamStr, options) {
|
|
69
|
+
if (!inParamStr) inParamStr = '';
|
|
70
|
+
if (!taskDefArr) taskDefArr = [];
|
|
71
|
+
if (!outParamStr) outParamStr = '';
|
|
72
|
+
|
|
73
|
+
var reactFn = core();
|
|
74
|
+
var ast = {
|
|
75
|
+
inParams: parseInParams(inParamStr).inDef,
|
|
76
|
+
tasks: parseTasks(taskDefArr),
|
|
77
|
+
outTask: { a: parseOutParams(outParamStr).outDef }
|
|
78
|
+
};
|
|
79
|
+
if (options) Object.keys(options).forEach(function (k) { ast[k] = options[k]; });
|
|
80
|
+
var errors = reactFn.setAndValidateAST(ast);
|
|
81
|
+
if (errors.length) {
|
|
82
|
+
var errorStr = errors.join('\n');
|
|
83
|
+
throw new Error(errorStr);
|
|
84
|
+
}
|
|
85
|
+
return reactFn;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function selectFirst(inParamStr, taskDefArr, outParamStr, options) {
|
|
89
|
+
if (!inParamStr) inParamStr = '';
|
|
90
|
+
if (!taskDefArr) taskDefArr = [];
|
|
91
|
+
if (!outParamStr) outParamStr = '';
|
|
92
|
+
var tasks = tutil.serializeTasks(parseTasks(taskDefArr));
|
|
93
|
+
|
|
94
|
+
var reactFn = core();
|
|
95
|
+
var ast = {
|
|
96
|
+
inParams: parseInParams(inParamStr).inDef,
|
|
97
|
+
tasks: tasks,
|
|
98
|
+
outTask: { type: 'finalcbFirst', a: parseOutParams(outParamStr).outDef },
|
|
99
|
+
};
|
|
100
|
+
if (options) Object.keys(options).forEach(function (k) { ast[k] = options[k]; });
|
|
101
|
+
var errors = reactFn.setAndValidateAST(ast);
|
|
102
|
+
if (errors.length) {
|
|
103
|
+
var errorStr = errors.join('\n');
|
|
104
|
+
throw new Error(errorStr);
|
|
105
|
+
}
|
|
106
|
+
return reactFn;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = fstrDefine;
|
|
110
|
+
module.exports.selectFirst = selectFirst;
|
package/lib/id.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var defaultExecOptions = {
|
|
4
|
+
reactExecOptions: true,
|
|
5
|
+
outputStyle: 'callback',
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
var OUTPUT_STYLES = {
|
|
9
|
+
CALLBACK: 'callback',
|
|
10
|
+
NONE: 'none'
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function isExecOptions(x) { return (x && x.reactExecOptions); }
|
|
14
|
+
function execOptionsFilter(x) { return isExecOptions(x); }
|
|
15
|
+
function nonExecOptionsFilter(x) { return !isExecOptions(x); }
|
|
16
|
+
function mergeExecOptions(accum, options) {
|
|
17
|
+
Object.keys(options).forEach(function (k) { accum[k] = options[k]; });
|
|
18
|
+
return accum;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function splitArgs(args, inParams, style) {
|
|
22
|
+
var result = { };
|
|
23
|
+
result.args = inParams.map(function (p) { return args.shift(); }); // take args for input params first
|
|
24
|
+
if (style === OUTPUT_STYLES.CALLBACK && args.length) result.cb = args.shift(); // next take the cb
|
|
25
|
+
result.extra = args; // these remaining were after the callback
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function inputParser(inputArgs, ast) {
|
|
30
|
+
var parsedInput = { };
|
|
31
|
+
var execOptionsArr = inputArgs.filter(execOptionsFilter);
|
|
32
|
+
execOptionsArr.unshift(defaultExecOptions);
|
|
33
|
+
parsedInput.options = execOptionsArr.reduce(mergeExecOptions, {});
|
|
34
|
+
|
|
35
|
+
var args = inputArgs.filter(nonExecOptionsFilter);
|
|
36
|
+
var splitResult = splitArgs(args, ast.inParams, parsedInput.options.outputStyle);
|
|
37
|
+
parsedInput.args = splitResult.args;
|
|
38
|
+
parsedInput.cb = splitResult.cb;
|
|
39
|
+
if (splitResult.extra) parsedInput.extraArgs = splitResult.extra;
|
|
40
|
+
return parsedInput;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = inputParser;
|
|
44
|
+
module.exports.defaultExecOptions = defaultExecOptions;
|
package/lib/parse.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sprintf = require('sprintf').sprintf;
|
|
4
|
+
|
|
5
|
+
function splitTrimFilterArgs(commaSepArgs) { //parse 'one, two' into ['one', 'two']
|
|
6
|
+
if (!commaSepArgs) return [];
|
|
7
|
+
return commaSepArgs.split(',') //split on commas
|
|
8
|
+
.map(function (s) { return s.trim(); }) //trim
|
|
9
|
+
.filter(function (s) { return (s); }); //filter out empty strings
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function parseReduce(accum, regexFn) {
|
|
13
|
+
if (typeof(accum) !== 'string') return accum; // already matched
|
|
14
|
+
var m = regexFn.regex.exec(accum);
|
|
15
|
+
if (m) return regexFn.fn(m); // return result obj
|
|
16
|
+
return accum; // no match, return str, will try next matcher
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function parseStr(str, parseMatchers, errStr) {
|
|
20
|
+
var result = parseMatchers.reduce(parseReduce, str);
|
|
21
|
+
if (typeof(result) !== 'string') { // matched
|
|
22
|
+
return result;
|
|
23
|
+
} else { // no match
|
|
24
|
+
throw new Error(sprintf(errStr, str));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
exports.splitTrimFilterArgs = splitTrimFilterArgs;
|
|
29
|
+
exports.parseStr = parseStr;
|
package/lib/pcode.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sprintf = require('sprintf').sprintf;
|
|
4
|
+
var core = require('./core.js');
|
|
5
|
+
var parse = require('./parse.js');
|
|
6
|
+
var tutil = require('./task.js');
|
|
7
|
+
|
|
8
|
+
var INPARAMS_NO_MATCH = 'input params in wrong format, wanted "foo, bar, cb" - found: %s';
|
|
9
|
+
var OUTPARAMS_NO_MATCH = 'output params in wrong format, wanted "cb(err, foo)" - found: %s';
|
|
10
|
+
var INOUT_PARAMS_NO_MATCH = 'task params in wrong format, wanted "foo, bar := func(baz, cat, cb) " - found: %s';
|
|
11
|
+
var EXTRA_TASKARG = 'extra unmatched task arg: %s';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
Examples:
|
|
15
|
+
var react = require('react');
|
|
16
|
+
|
|
17
|
+
var locals = { falpha: falpha, fbeta: fbeta, fcharlie: fcharlie };
|
|
18
|
+
var fn = react.pcodeDefine('a, b', [
|
|
19
|
+
'd := fbeta(a, b)',
|
|
20
|
+
'e = fcharlie(a, b)',
|
|
21
|
+
'c := falpha(a, b) when fbeta:done and fcharlie:done',
|
|
22
|
+
'cb(err, c, d, e);'
|
|
23
|
+
], locals);
|
|
24
|
+
|
|
25
|
+
function cb(err, d, e) { }
|
|
26
|
+
fn(10, 20, cb);
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
function splitAndFilterArgs(commaSepArgs) { // split, trim, filter out empty and (cb or callback)
|
|
30
|
+
var args = parse.splitTrimFilterArgs(commaSepArgs);
|
|
31
|
+
var cbNamesRe = /^cb|callback$/i; //cb, Cb, CB, callback, Callback
|
|
32
|
+
if (args.length && args[args.length - 1].match(cbNamesRe)) args.pop();
|
|
33
|
+
return args;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function extractNamesFromWhenClause(str) { //given 'foo:done and bar.baz:done' return ['foo', 'bar.baz']
|
|
37
|
+
var reSplit = /\s+and\s+/i;
|
|
38
|
+
var reDone = /^([^:]+):done$/i;
|
|
39
|
+
var names = str.split(reSplit).map(function (x) {
|
|
40
|
+
x = x.trim();
|
|
41
|
+
var m = x.match(reDone); // if foo:done, we'll use foo
|
|
42
|
+
return (m) ? m[1] : x;
|
|
43
|
+
});
|
|
44
|
+
return names;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
var inParse = {
|
|
48
|
+
regex: /^(.*)$/,
|
|
49
|
+
fn: function (m) {
|
|
50
|
+
return {
|
|
51
|
+
inDef: splitAndFilterArgs(m[1]),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
var cbParse = {
|
|
57
|
+
regex: /^\s*(var\s+)?([^:]*)\s*:=\s*([a-zA-Z0-9_\.-]+)\s*\(\s*([^)]*)\)\s*(when\s+([^;]+))?;?\s*$/,
|
|
58
|
+
fn: function (m) {
|
|
59
|
+
var taskDef = {
|
|
60
|
+
type: 'cb',
|
|
61
|
+
f: m[3],
|
|
62
|
+
inDef: (m[4]) ? splitAndFilterArgs(m[4]) : [],
|
|
63
|
+
outDef: (m[2]) ? parse.splitTrimFilterArgs(m[2]) : []
|
|
64
|
+
};
|
|
65
|
+
if (m[6]) taskDef.after = extractNamesFromWhenClause(m[6]);
|
|
66
|
+
return taskDef;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
var retParse = {
|
|
71
|
+
regex: /^\s*(var\s+)?([^:]*)\s*=\s*([a-zA-Z0-9_\.-]+)\s*\(\s*([^)]*)\)\s*(when\s+([^;]+))?;?\s*$/,
|
|
72
|
+
fn: function (m) {
|
|
73
|
+
var taskDef = {
|
|
74
|
+
type: 'ret',
|
|
75
|
+
f: m[3],
|
|
76
|
+
inDef: (m[4]) ? splitAndFilterArgs(m[4]) : [],
|
|
77
|
+
outDef: (m[2]) ? parse.splitTrimFilterArgs(m[2]) : []
|
|
78
|
+
};
|
|
79
|
+
if (m[6]) taskDef.after = extractNamesFromWhenClause(m[6]);
|
|
80
|
+
return taskDef;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
var finalCbParse = {
|
|
85
|
+
regex: /^\s*(cb|callback)\s*\((er{0,2}\s*,\s*)?([^)]*)\)\s*;?$/i,
|
|
86
|
+
fn: function (m) {
|
|
87
|
+
return {
|
|
88
|
+
outDef: (m[3]) ? parse.splitTrimFilterArgs(m[3]) : []
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
function parseInParams(str) {
|
|
94
|
+
return parse.parseStr(str, [inParse], INPARAMS_NO_MATCH);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function parseTask(str) {
|
|
98
|
+
var result = parse.parseStr(str, [cbParse, retParse], INOUT_PARAMS_NO_MATCH);
|
|
99
|
+
var type = result.type;
|
|
100
|
+
var task = {
|
|
101
|
+
f: result.f,
|
|
102
|
+
a: result.inDef
|
|
103
|
+
};
|
|
104
|
+
task.out = result.outDef;
|
|
105
|
+
task.type = type;
|
|
106
|
+
if (result.after) task.after = result.after;
|
|
107
|
+
return task;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function parseOutParams(str) {
|
|
111
|
+
if (!str.trim().length) return { outDef: [] };
|
|
112
|
+
return parse.parseStr(str, [finalCbParse], OUTPARAMS_NO_MATCH);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function parseTasks(arr) { return arr.map(parseTask); }
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
function pcodeDefine(inParamStr, taskStrArr, locals, options) {
|
|
119
|
+
if (!inParamStr) inParamStr = '';
|
|
120
|
+
if (!taskStrArr) taskStrArr = [];
|
|
121
|
+
var outTaskStr = (taskStrArr.length) ? taskStrArr.pop() : '';
|
|
122
|
+
if (!locals) locals = { };
|
|
123
|
+
|
|
124
|
+
var reactFn = core();
|
|
125
|
+
var ast = {
|
|
126
|
+
inParams: parseInParams(inParamStr).inDef,
|
|
127
|
+
tasks: parseTasks(taskStrArr),
|
|
128
|
+
outTask: { a: parseOutParams(outTaskStr).outDef },
|
|
129
|
+
locals: locals
|
|
130
|
+
};
|
|
131
|
+
if (options) Object.keys(options).forEach(function (k) { ast[k] = options[k]; });
|
|
132
|
+
var errors = reactFn.setAndValidateAST(ast);
|
|
133
|
+
if (errors.length) {
|
|
134
|
+
var errorStr = errors.join('\n');
|
|
135
|
+
throw new Error(errorStr);
|
|
136
|
+
}
|
|
137
|
+
return reactFn;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function selectFirst(inParamStr, taskStrArr, locals, options) {
|
|
141
|
+
if (!inParamStr) inParamStr = '';
|
|
142
|
+
if (!taskStrArr) taskStrArr = [];
|
|
143
|
+
var outTaskStr = (taskStrArr.length) ? taskStrArr.pop() : '';
|
|
144
|
+
if (!locals) locals = { };
|
|
145
|
+
var tasks = tutil.serializeTasks(parseTasks(taskStrArr));
|
|
146
|
+
|
|
147
|
+
var reactFn = core();
|
|
148
|
+
var ast = {
|
|
149
|
+
inParams: parseInParams(inParamStr).inDef,
|
|
150
|
+
tasks: tasks,
|
|
151
|
+
outTask: { type: 'finalcbFirst', a: parseOutParams(outTaskStr).outDef },
|
|
152
|
+
locals: locals
|
|
153
|
+
};
|
|
154
|
+
if (options) Object.keys(options).forEach(function (k) { ast[k] = options[k]; });
|
|
155
|
+
var errors = reactFn.setAndValidateAST(ast);
|
|
156
|
+
if (errors.length) {
|
|
157
|
+
var errorStr = errors.join('\n');
|
|
158
|
+
throw new Error(errorStr);
|
|
159
|
+
}
|
|
160
|
+
return reactFn;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
module.exports = pcodeDefine;
|
|
164
|
+
module.exports.selectFirst = selectFirst;
|