-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathfunc.js
100 lines (91 loc) · 2.33 KB
/
func.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
var R = require('ramda');
var parse = require('./parse');
var transformers = {
expr: function(node) {
return { c: function(vals) { return '(' + vals[0] + ')'; },
subs: node.children };
},
literal: function(node) {
var str = '' + node.options.value;
if (!R.contains('.', str)) {
str += '.0';
}
return { c: function() { return str; },
subs: [] };
},
name: function(node) {
var key = node.options.key,
upperKey = key.toUpperCase();
if (R.prop(upperKey, Math)) {
return {
c: function() {
return 'Math.' + upperKey;
},
subs: []
};
}
return {
c: function() {
return 'symbols["' + key + '"]';
},
subs: []
};
},
func: function(node) {
var key = node.options.key;
var narys = {
product: '*',
div: '/',
mod: '%',
sum: '+',
minus: '-',
lessThan: '<',
greaterThan: '>'
};
if (narys[key]) {
return {
c: function(args) { return '(' + args.join(narys[key]) + ')'; },
subs: node.children
};
}
if (key === 'neg') {
return {
c: function(args) { return '(-' + args[0] + ')'; },
subs: node.children
};
}
if (R.prop(key, Math)) {
return {
c: function(args) { return 'Math.' + key + '(' + args.join(',') + ')'; },
subs: node.children
};
}
return { c: function(args) { return 'symbols["' + node.options.key + '"]' +
'(' + args.join(',') + ')'; }, subs: node.children };
}
};
var compileAST = function comp(ASTNode) {
var transformer = transformers[ASTNode.node](ASTNode);
return transformer.c(R.map(comp, transformer.subs));
};
var functionify = function(expr) {
/* istanbul ignore next */
var templateFn = function(symbols, expr) {
symbols = symbols || {};
return expr;
};
var body = templateFn
.toString()
.split('\n')
.slice(1, -1) // drop function header and closing }
.join('\n')
.replace('expr', expr);
/* jslint evil:true */
return new Function('symbols', body);
/* jslint evil:false */
};
var compile = R.pipe(parse, compileAST, functionify);
compile.fromAST = R.pipe(compileAST, functionify);
compile.express = R.pipe(parse, compileAST);
compile.express.fromAST = compileAST;
module.exports = compile;