-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparsers.js
84 lines (75 loc) · 2.29 KB
/
parsers.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
function parseInteger(string){
if (/^[-+]?(\d+)$/.test(string)) {
return Number(string)
} else {
return null;
}
}
function parseFloat(string){
if (/^[-+]?(\d+)(.\d*)?(e[+-]?\d+)?$/.test(string)) {
return Number(string)
} else {
return null;
}
}
// Outputs the parsed projection function, not the compiled projection function
function parseProjection(string){
try{
let expressionTree = math.parse(string);
// Check that all symbols are correct. That is phi, theta, θ, φ, latitude, or longitude.
if(checkVariables(expressionTree)){
const parsedExpression = expressionTree.compile();
return(
function(theta, phi){
return parsedExpression.evaluate({theta,phi,longitude:theta,lattitude:phi,θ:theta,φ:phi});
}
);
}
else{
return null;
}
} catch(error){
return null;
}
}
function checkVariables(expressionNode){
const type = expressionNode.type
switch(type){
case 'ConstantNode':
if (expressionNode.value === undefined) {
return false;
}
else{
return true;
}
case 'FunctionNode':
const funArguments = expressionNode.args;
for(let argument of funArguments){
if(!checkVariables(argument)){
return false;
}
}
return true;
case 'ParenthesisNode':
return checkVariables(expressionNode.content);
case 'OperatorNode':
const opArguments = expressionNode.args;
for(let argument of opArguments){
if(!checkVariables(argument)){
return false;
}
}
return true;
case 'SymbolNode':
const name = expressionNode.name;
if(name === 'theta' || name === 'phi' || name === 'θ' || name === 'φ' || name === 'lattitude' || name === 'longitude' || name ==='pi'){
return true;
}
else{
return false;
}
default:
return false;
}
}
export {parseInteger, parseFloat, parseProjection};