@sdeverywhere/compile 0.7.16 → 0.7.18
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/package.json +1 -3
- package/src/generate/expand-var-names.js +0 -10
- package/src/generate/{code-gen.js → gen-code-c.js} +192 -103
- package/src/generate/gen-code-js.js +616 -0
- package/src/generate/gen-code.js +36 -0
- package/src/generate/gen-equation.js +16 -6
- package/src/generate/gen-expr.js +205 -48
- package/src/generate/gen-lookup-from-direct.js +14 -6
- package/src/generate/gen-lookup-from-external.js +20 -5
- package/src/generate/gen-lookup-from-points.js +28 -6
- package/src/index.js +38 -3
- package/src/model/model.js +94 -151
- package/src/model/read-equation-fn-game.js +50 -0
- package/src/model/read-equations.js +9 -10
- package/src/model/read-variables.js +2 -2
- package/src/model/variable.js +6 -21
- package/src/parse-and-generate.js +22 -19
- package/src/preprocess/preprocessor.js +2 -2
- package/src/generate/equation-gen.js +0 -1268
- package/src/generate/model-lhs-reader.js +0 -88
- package/src/model/equation-reader.js +0 -723
- package/src/model/expr-reader.js +0 -202
- package/src/model/subscript-range-reader.js +0 -143
- package/src/model/var-name-reader.js +0 -40
- package/src/model/variable-reader.js +0 -172
- package/src/parse/model-reader.js +0 -141
- package/src/parse/parser.js +0 -36
package/package.json
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdeverywhere/compile",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.18",
|
|
4
4
|
"description": "The core Vensim to C compiler for the SDEverywhere tool suite.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@sdeverywhere/parse": "^0.1.0",
|
|
9
|
-
"antlr4": "4.12.0",
|
|
10
|
-
"antlr4-vensim": "0.6.2",
|
|
11
9
|
"bufx": "^1.0.5",
|
|
12
10
|
"byline": "^5.0.0",
|
|
13
11
|
"csv-parse": "^5.3.3",
|
|
@@ -5,8 +5,6 @@ import { sub, isDimension } from '../_shared/subscript.js'
|
|
|
5
5
|
|
|
6
6
|
import Model from '../model/model.js'
|
|
7
7
|
|
|
8
|
-
import ModelLHSReader from './model-lhs-reader.js'
|
|
9
|
-
|
|
10
8
|
/**
|
|
11
9
|
* Return an array of names for all variable in the model, sorted alphabetically and expanded to
|
|
12
10
|
* include the full set of subscripted variants for variables that include subscripts.
|
|
@@ -43,14 +41,6 @@ export function expandVarNames(canonical) {
|
|
|
43
41
|
* @returns {string[]} An array of expanded names for the given variable.
|
|
44
42
|
*/
|
|
45
43
|
function namesForVar(v) {
|
|
46
|
-
if (process.env.SDE_NONPUBLIC_USE_NEW_PARSE === '0') {
|
|
47
|
-
// TODO: When the old parsing code is active, use the old ModelLHSReader. This code path
|
|
48
|
-
// will be removed when the old parsing code is removed.
|
|
49
|
-
let modelLHSReader = new ModelLHSReader()
|
|
50
|
-
modelLHSReader.read(v.modelLHS)
|
|
51
|
-
return modelLHSReader.names()
|
|
52
|
-
}
|
|
53
|
-
|
|
54
44
|
if (v.parsedEqn === undefined) {
|
|
55
45
|
// XXX: The special `Time` variable does not have a `parsedEqn`, so use the raw LHS
|
|
56
46
|
return [v.modelLHS]
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as R from 'ramda'
|
|
2
2
|
|
|
3
|
-
import { asort, lines, strlist, mapIndexed } from '../_shared/helpers.js'
|
|
3
|
+
import { asort, canonicalVensimName, lines, strlist, mapIndexed } from '../_shared/helpers.js'
|
|
4
4
|
import { sub, allDimensions, allMappings, subscriptFamilies } from '../_shared/subscript.js'
|
|
5
5
|
import Model from '../model/model.js'
|
|
6
6
|
|
|
7
7
|
import { generateEquation } from './gen-equation.js'
|
|
8
|
-
import EquationGen from './equation-gen.js'
|
|
9
8
|
import { expandVarNames } from './expand-var-names.js'
|
|
10
9
|
|
|
11
|
-
export function
|
|
10
|
+
export function generateC(parsedModel, opts) {
|
|
12
11
|
return codeGenerator(parsedModel, opts).generate()
|
|
13
12
|
}
|
|
14
13
|
|
|
@@ -17,21 +16,10 @@ let codeGenerator = (parsedModel, opts) => {
|
|
|
17
16
|
// Set to 'decl', 'init-lookups', 'eval', etc depending on the section being generated.
|
|
18
17
|
let mode = ''
|
|
19
18
|
// Set to true to output all variables when there is no model run spec.
|
|
20
|
-
let outputAllVars
|
|
21
|
-
if (spec.outputVars && spec.outputVars.length > 0) {
|
|
22
|
-
outputAllVars = false
|
|
23
|
-
} else if (spec.outputVarNames && spec.outputVarNames.length > 0) {
|
|
24
|
-
outputAllVars = false
|
|
25
|
-
} else {
|
|
26
|
-
outputAllVars = true
|
|
27
|
-
}
|
|
19
|
+
let outputAllVars = spec.outputVarNames === undefined || spec.outputVarNames.length === 0
|
|
28
20
|
// Function to generate a section of the code
|
|
29
21
|
let generateSection = R.map(v => {
|
|
30
|
-
|
|
31
|
-
return new EquationGen(v, extData, directData, mode, modelDirname).generate()
|
|
32
|
-
} else {
|
|
33
|
-
return generateEquation(v, mode, extData, directData, modelDirname)
|
|
34
|
-
}
|
|
22
|
+
return generateEquation(v, mode, extData, directData, modelDirname, 'c')
|
|
35
23
|
})
|
|
36
24
|
let section = R.pipe(generateSection, R.flatten, lines)
|
|
37
25
|
function generate() {
|
|
@@ -93,51 +81,54 @@ ${section(Model.dataVars())}
|
|
|
93
81
|
//
|
|
94
82
|
function emitInitLookupsCode() {
|
|
95
83
|
mode = 'init-lookups'
|
|
96
|
-
let code =
|
|
84
|
+
let code = `\
|
|
85
|
+
// Internal state
|
|
97
86
|
bool lookups_initialized = false;
|
|
98
87
|
bool data_initialized = false;
|
|
88
|
+
|
|
99
89
|
`
|
|
100
90
|
code += chunkedFunctions(
|
|
101
91
|
'initLookups',
|
|
102
92
|
Model.lookupVars(),
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
93
|
+
`\
|
|
94
|
+
// Initialize lookups.
|
|
95
|
+
if (lookups_initialized) {
|
|
96
|
+
return;
|
|
97
|
+
}`,
|
|
98
|
+
' lookups_initialized = true;'
|
|
109
99
|
)
|
|
110
100
|
code += chunkedFunctions(
|
|
111
101
|
'initData',
|
|
112
102
|
Model.dataVars(),
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
103
|
+
`\
|
|
104
|
+
// Initialize data.
|
|
105
|
+
if (data_initialized) {
|
|
106
|
+
return;
|
|
107
|
+
}`,
|
|
108
|
+
' data_initialized = true;'
|
|
119
109
|
)
|
|
120
110
|
return code
|
|
121
111
|
}
|
|
122
112
|
|
|
123
113
|
function emitInitConstantsCode() {
|
|
124
114
|
mode = 'init-constants'
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
|
|
115
|
+
return chunkedFunctions(
|
|
116
|
+
'initConstants',
|
|
117
|
+
Model.constVars(),
|
|
118
|
+
' // Initialize constants.',
|
|
119
|
+
' initLookups();\n initData();'
|
|
120
|
+
)
|
|
128
121
|
}
|
|
129
122
|
|
|
130
123
|
function emitInitLevelsCode() {
|
|
131
124
|
mode = 'init-levels'
|
|
132
|
-
return
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
`
|
|
125
|
+
return chunkedFunctions(
|
|
126
|
+
'initLevels',
|
|
127
|
+
Model.initVars(),
|
|
128
|
+
`\
|
|
137
129
|
// Initialize variables with initialization values, such as levels, and the variables they depend on.
|
|
138
130
|
_time = _initial_time;`
|
|
139
|
-
)
|
|
140
|
-
`
|
|
131
|
+
)
|
|
141
132
|
}
|
|
142
133
|
|
|
143
134
|
//
|
|
@@ -146,40 +137,96 @@ ${chunkedFunctions(
|
|
|
146
137
|
function emitEvalCode() {
|
|
147
138
|
mode = 'eval'
|
|
148
139
|
|
|
149
|
-
return
|
|
150
|
-
${chunkedFunctions('evalAux', Model.auxVars(), ' // Evaluate auxiliaries in order from the bottom up.')}
|
|
151
|
-
|
|
152
|
-
${chunkedFunctions('evalLevels', Model.levelVars(), ' // Evaluate levels.')}
|
|
153
|
-
`
|
|
140
|
+
return `\
|
|
141
|
+
${chunkedFunctions('evalAux', Model.auxVars(), ' // Evaluate auxiliaries in order from the bottom up.')}\
|
|
142
|
+
${chunkedFunctions('evalLevels', Model.levelVars(), ' // Evaluate levels.')}`
|
|
154
143
|
}
|
|
155
144
|
|
|
156
145
|
//
|
|
157
146
|
// Input/output section
|
|
158
147
|
//
|
|
159
148
|
function emitIOCode() {
|
|
160
|
-
|
|
161
|
-
|
|
149
|
+
// Configure the body of the `setLookup` function depending on the value
|
|
150
|
+
// of the `customLookups` property in the spec file
|
|
151
|
+
// TODO: The fprintf calls should be replaced with a mechanism that throws
|
|
152
|
+
// an error (we could add a wrapper function at the JS level)
|
|
153
|
+
let setLookupBody
|
|
154
|
+
if (spec.customLookups === true || Array.isArray(spec.customLookups)) {
|
|
155
|
+
setLookupBody = `\
|
|
156
|
+
switch (varIndex) {
|
|
157
|
+
${setLookupImpl(Model.varIndexInfo(), spec.customLookups)}
|
|
158
|
+
default:
|
|
159
|
+
fprintf(stderr, "No lookup found for var index %zu in setLookup\\n", varIndex);
|
|
160
|
+
break;
|
|
161
|
+
}`
|
|
162
|
+
} else {
|
|
163
|
+
let msg = 'The setLookup function was not enabled for the generated model. '
|
|
164
|
+
msg += 'Set the customLookups property in the spec/config file to allow for overriding lookups at runtime.'
|
|
165
|
+
setLookupBody = `\
|
|
166
|
+
fprintf(stderr, "${msg}\\n");`
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Configure the output variables that appear in the generated `getHeader`
|
|
170
|
+
// and `storeOutputData` functions
|
|
171
|
+
let headerVarNames = outputAllVars ? expandedVarNames(true) : spec.outputVarNames
|
|
172
|
+
let outputVarIds = outputAllVars ? expandedVarNames() : spec.outputVars
|
|
173
|
+
|
|
174
|
+
// Configure the body of the `storeOutput` function depending on the value
|
|
175
|
+
// of the `customOutputs` property in the spec file
|
|
176
|
+
let storeOutputBody
|
|
177
|
+
if (spec.customOutputs === true || Array.isArray(spec.customOutputs)) {
|
|
178
|
+
storeOutputBody = `\
|
|
179
|
+
switch (varIndex) {
|
|
180
|
+
${customOutputSection(Model.varIndexInfo(), spec.customOutputs)}
|
|
181
|
+
default:
|
|
182
|
+
fprintf(stderr, "No variable found for var index %zu in storeOutput\\n", varIndex);
|
|
183
|
+
break;
|
|
184
|
+
}`
|
|
185
|
+
} else {
|
|
186
|
+
let msg = 'The storeOutput function was not enabled for the generated model. '
|
|
187
|
+
msg +=
|
|
188
|
+
'Set the customOutputs property in the spec/config file to allow for capturing arbitrary variables at runtime.'
|
|
189
|
+
storeOutputBody = `\
|
|
190
|
+
fprintf(stderr, "${msg}\\n");`
|
|
191
|
+
}
|
|
192
|
+
|
|
162
193
|
mode = 'io'
|
|
163
|
-
return
|
|
194
|
+
return `\
|
|
195
|
+
void setInputs(const char* inputData) {
|
|
196
|
+
${inputsFromStringImpl()}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
void setInputsFromBuffer(double* inputData) {
|
|
200
|
+
${inputsFromBufferImpl()}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
void replaceLookup(Lookup** lookup, double* points, size_t numPoints) {
|
|
204
|
+
if (lookup == NULL) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (*lookup != NULL) {
|
|
208
|
+
__delete_lookup(*lookup);
|
|
209
|
+
*lookup = NULL;
|
|
210
|
+
}
|
|
211
|
+
if (points != NULL) {
|
|
212
|
+
*lookup = __new_lookup(numPoints, /*copy=*/true, points);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
164
215
|
|
|
165
|
-
void
|
|
216
|
+
void setLookup(size_t varIndex, size_t* subIndices, double* points, size_t numPoints) {
|
|
217
|
+
${setLookupBody}
|
|
218
|
+
}
|
|
166
219
|
|
|
167
220
|
const char* getHeader() {
|
|
168
|
-
return "${R.map(varName =>
|
|
221
|
+
return "${R.map(varName => varName.replace(/"/g, '\\"'), headerVarNames).join('\\t')}";
|
|
169
222
|
}
|
|
170
223
|
|
|
171
224
|
void storeOutputData() {
|
|
172
|
-
${specOutputSection(
|
|
225
|
+
${specOutputSection(outputVarIds)}
|
|
173
226
|
}
|
|
174
227
|
|
|
175
|
-
void storeOutput(size_t varIndex, size_t
|
|
176
|
-
|
|
177
|
-
switch (varIndex) {
|
|
178
|
-
${fullOutputSection(Model.varIndexInfo())}
|
|
179
|
-
default:
|
|
180
|
-
break;
|
|
181
|
-
}
|
|
182
|
-
#endif
|
|
228
|
+
void storeOutput(size_t varIndex, size_t* subIndices) {
|
|
229
|
+
${storeOutputBody}
|
|
183
230
|
}
|
|
184
231
|
`
|
|
185
232
|
}
|
|
@@ -190,9 +237,9 @@ ${fullOutputSection(Model.varIndexInfo())}
|
|
|
190
237
|
function chunkedFunctions(name, vars, preStep, postStep) {
|
|
191
238
|
// Emit one function for each chunk
|
|
192
239
|
let func = (chunk, idx) => {
|
|
193
|
-
return
|
|
240
|
+
return `\
|
|
194
241
|
void ${name}${idx}() {
|
|
195
|
-
|
|
242
|
+
${section(chunk)}
|
|
196
243
|
}
|
|
197
244
|
`
|
|
198
245
|
}
|
|
@@ -220,22 +267,25 @@ void ${name}${idx}() {
|
|
|
220
267
|
chunks = [vars]
|
|
221
268
|
}
|
|
222
269
|
|
|
223
|
-
|
|
224
|
-
|
|
270
|
+
let funcsPart = funcs(chunks)
|
|
271
|
+
let callsPart = funcCalls(chunks)
|
|
272
|
+
|
|
273
|
+
let out = ''
|
|
274
|
+
if (funcsPart.length > 0) {
|
|
275
|
+
out += funcsPart + '\n'
|
|
225
276
|
}
|
|
226
|
-
|
|
227
|
-
|
|
277
|
+
out += `void ${name}() {\n`
|
|
278
|
+
if (preStep) {
|
|
279
|
+
out += preStep + '\n'
|
|
228
280
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
`
|
|
281
|
+
if (callsPart.length > 0) {
|
|
282
|
+
out += callsPart + '\n'
|
|
283
|
+
}
|
|
284
|
+
if (postStep) {
|
|
285
|
+
out += postStep + '\n'
|
|
286
|
+
}
|
|
287
|
+
out += '}\n\n'
|
|
288
|
+
return out
|
|
239
289
|
}
|
|
240
290
|
|
|
241
291
|
//
|
|
@@ -283,9 +333,6 @@ ${postStep}
|
|
|
283
333
|
} else {
|
|
284
334
|
decls = `const int numOutputs = ${spec.outputVars.length};`
|
|
285
335
|
}
|
|
286
|
-
decls += `\n#define SDE_USE_OUTPUT_INDICES 0`
|
|
287
|
-
decls += `\n#define SDE_MAX_OUTPUT_INDICES 1000`
|
|
288
|
-
decls += `\nconst int maxOutputIndices = SDE_USE_OUTPUT_INDICES ? SDE_MAX_OUTPUT_INDICES : 0;`
|
|
289
336
|
return decls
|
|
290
337
|
}
|
|
291
338
|
function arrayDimensionsSection() {
|
|
@@ -320,31 +367,44 @@ ${postStep}
|
|
|
320
367
|
// Input/output section helpers
|
|
321
368
|
//
|
|
322
369
|
function specOutputSection(varNames) {
|
|
323
|
-
// Emit
|
|
370
|
+
// Emit `outputVar` calls for all variables listed in the `outputVarNames`
|
|
371
|
+
// array in the spec file using varNames in C format.
|
|
324
372
|
let code = R.map(varName => ` outputVar(${varName});`)
|
|
325
373
|
let section = R.pipe(code, lines)
|
|
326
374
|
return section(varNames)
|
|
327
375
|
}
|
|
328
|
-
function
|
|
329
|
-
// Emit
|
|
376
|
+
function customOutputSection(varIndexInfo, customOutputs) {
|
|
377
|
+
// Emit `outputVar` calls for all variables that can be accessed as an output.
|
|
378
|
+
// This excludes data and lookup variables; at this time, the data for these
|
|
379
|
+
// cannot be output like for other types of variables.
|
|
380
|
+
let includeCase
|
|
381
|
+
if (Array.isArray(customOutputs)) {
|
|
382
|
+
// Only include a case statement if the variable was explicitly included
|
|
383
|
+
// in the `customOutputs` array in the spec file
|
|
384
|
+
const customOutputVarNames = customOutputs.map(varName => {
|
|
385
|
+
// The developer might specify a variable name that includes subscripts,
|
|
386
|
+
// but we will ignore the subscript part and only match on the base name
|
|
387
|
+
return canonicalVensimName(varName.split('[')[0])
|
|
388
|
+
})
|
|
389
|
+
includeCase = varName => customOutputVarNames.includes(varName)
|
|
390
|
+
} else {
|
|
391
|
+
// Include a case statement for all accessible variables
|
|
392
|
+
includeCase = () => true
|
|
393
|
+
}
|
|
394
|
+
const outputVars = R.filter(info => {
|
|
395
|
+
return info.varType !== 'lookup' && info.varType !== 'data' && includeCase(info.varName)
|
|
396
|
+
})
|
|
330
397
|
const code = R.map(info => {
|
|
331
398
|
let varAccess = info.varName
|
|
332
|
-
|
|
333
|
-
varAccess +=
|
|
399
|
+
for (let i = 0; i < info.subscriptCount; i++) {
|
|
400
|
+
varAccess += `[subIndices[${i}]]`
|
|
334
401
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
varAccess += '[subIndex2]'
|
|
340
|
-
}
|
|
341
|
-
let c = ''
|
|
342
|
-
c += ` case ${info.varIndex}:\n`
|
|
343
|
-
c += ` outputVar(${varAccess});\n`
|
|
344
|
-
c += ` break;`
|
|
345
|
-
return c
|
|
402
|
+
return `\
|
|
403
|
+
case ${info.varIndex}:
|
|
404
|
+
outputVar(${varAccess});
|
|
405
|
+
break;`
|
|
346
406
|
})
|
|
347
|
-
const section = R.pipe(code, lines)
|
|
407
|
+
const section = R.pipe(outputVars, code, lines)
|
|
348
408
|
return section(varIndexInfo)
|
|
349
409
|
}
|
|
350
410
|
function inputsFromStringImpl() {
|
|
@@ -353,7 +413,7 @@ ${postStep}
|
|
|
353
413
|
let inputVars = ''
|
|
354
414
|
if (spec.inputVars && spec.inputVars.length > 0) {
|
|
355
415
|
let inputVarPtrs = R.reduce((a, inputVar) => R.concat(a, ` &${inputVar},\n`), '', spec.inputVars)
|
|
356
|
-
inputVars =
|
|
416
|
+
inputVars = `\
|
|
357
417
|
static double* inputVarPtrs[] = {\n${inputVarPtrs} };
|
|
358
418
|
char* inputs = (char*)inputData;
|
|
359
419
|
char* token = strtok(inputs, " ");
|
|
@@ -366,24 +426,53 @@ ${postStep}
|
|
|
366
426
|
*inputVarPtrs[modelVarIndex] = value;
|
|
367
427
|
}
|
|
368
428
|
token = strtok(NULL, " ");
|
|
369
|
-
}
|
|
370
|
-
`
|
|
429
|
+
}`
|
|
371
430
|
}
|
|
372
431
|
return inputVars
|
|
373
432
|
}
|
|
374
433
|
function inputsFromBufferImpl() {
|
|
375
|
-
let inputVars =
|
|
434
|
+
let inputVars = []
|
|
376
435
|
if (spec.inputVars && spec.inputVars.length > 0) {
|
|
377
|
-
inputVars += '\n'
|
|
378
436
|
for (let i = 0; i < spec.inputVars.length; i++) {
|
|
379
437
|
const inputVar = spec.inputVars[i]
|
|
380
|
-
inputVars
|
|
438
|
+
inputVars.push(` ${inputVar} = inputData[${i}];`)
|
|
381
439
|
}
|
|
382
440
|
}
|
|
383
|
-
return inputVars
|
|
441
|
+
return inputVars.join('\n')
|
|
384
442
|
}
|
|
385
|
-
function
|
|
386
|
-
|
|
443
|
+
function setLookupImpl(varIndexInfo, customLookups) {
|
|
444
|
+
// Emit `replaceLookup` calls for all lookups and data variables that can be overridden
|
|
445
|
+
// at runtime
|
|
446
|
+
let includeCase
|
|
447
|
+
if (Array.isArray(customLookups)) {
|
|
448
|
+
// Only include a case statement if the variable was explicitly included
|
|
449
|
+
// in the `customLookups` array in the spec file
|
|
450
|
+
const customLookupVarNames = customLookups.map(varName => {
|
|
451
|
+
// The developer might specify a variable name that includes subscripts,
|
|
452
|
+
// but we will ignore the subscript part and only match on the base name
|
|
453
|
+
return canonicalVensimName(varName.split('[')[0])
|
|
454
|
+
})
|
|
455
|
+
includeCase = varName => customLookupVarNames.includes(varName)
|
|
456
|
+
} else {
|
|
457
|
+
// Include a case statement for all lookup and data variables
|
|
458
|
+
includeCase = () => true
|
|
459
|
+
}
|
|
460
|
+
const lookupAndDataVars = R.filter(info => {
|
|
461
|
+
return (info.varType === 'lookup' || info.varType === 'data') && includeCase(info.varName)
|
|
462
|
+
})
|
|
463
|
+
const code = R.map(info => {
|
|
464
|
+
let lookupVar = info.varName
|
|
465
|
+
for (let i = 0; i < info.subscriptCount; i++) {
|
|
466
|
+
lookupVar += `[subIndices[${i}]]`
|
|
467
|
+
}
|
|
468
|
+
let c = ''
|
|
469
|
+
c += ` case ${info.varIndex}:\n`
|
|
470
|
+
c += ` replaceLookup(&${lookupVar}, points, numPoints);\n`
|
|
471
|
+
c += ` break;`
|
|
472
|
+
return c
|
|
473
|
+
})
|
|
474
|
+
const section = R.pipe(lookupAndDataVars, code, lines)
|
|
475
|
+
return section(varIndexInfo)
|
|
387
476
|
}
|
|
388
477
|
|
|
389
478
|
return {
|