@sdeverywhere/compile 0.7.9 → 0.7.11
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 +7 -6
- package/src/_shared/helpers.js +11 -11
- package/src/_shared/subscript.js +5 -0
- package/src/generate/code-gen.js +38 -42
- package/src/generate/direct-data-helpers.js +86 -0
- package/src/generate/equation-gen.js +79 -52
- package/src/generate/expand-var-names.js +115 -0
- package/src/generate/gen-const-list.js +89 -0
- package/src/generate/gen-direct-const.js +91 -0
- package/src/generate/gen-equation.js +273 -0
- package/src/generate/gen-expr.js +851 -0
- package/src/generate/gen-lookup-from-direct.js +105 -0
- package/src/generate/gen-lookup-from-external.js +115 -0
- package/src/generate/gen-lookup-from-points.js +85 -0
- package/src/model/equation-reader.js +32 -26
- package/src/model/model.js +160 -17
- package/src/model/read-equation-fn-delay.js +312 -0
- package/src/model/read-equation-fn-npv.js +67 -0
- package/src/model/read-equation-fn-smooth.js +133 -0
- package/src/model/read-equation-fn-trend.js +44 -0
- package/src/model/read-equation-fn-with-lookup.js +37 -0
- package/src/model/read-equations.js +795 -0
- package/src/model/read-subscripts.js +77 -0
- package/src/model/read-variables.js +264 -0
- package/src/model/reduce-variables.js +166 -0
- package/src/model/subscript-range-reader.js +4 -1
- package/src/model/variable.js +7 -2
- package/src/parse/parser.js +8 -4
- package/src/parse-and-generate.js +65 -12
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
import path from 'path'
|
|
4
4
|
import B from 'bufx'
|
|
5
5
|
|
|
6
|
+
import { parseVensimModel } from '@sdeverywhere/parse'
|
|
7
|
+
|
|
6
8
|
import { readXlsx } from './_shared/helpers.js'
|
|
7
9
|
import { readDat } from './_shared/read-dat.js'
|
|
8
10
|
import { printSubscripts, yamlSubsList } from './_shared/subscript.js'
|
|
9
|
-
import { parseModel } from './parse/parser.js'
|
|
11
|
+
import { parseModel as legacyParseVensimModel } from './parse/parser.js'
|
|
10
12
|
import Model from './model/model.js'
|
|
13
|
+
import { getDirectSubscripts } from './model/read-subscripts.js'
|
|
11
14
|
import { generateCode } from './generate/code-gen.js'
|
|
12
15
|
|
|
13
16
|
/**
|
|
@@ -15,24 +18,25 @@ import { generateCode } from './generate/code-gen.js'
|
|
|
15
18
|
*
|
|
16
19
|
* This is the primary entrypoint for the `sde generate` command.
|
|
17
20
|
*
|
|
18
|
-
* - If `
|
|
19
|
-
* - If `
|
|
21
|
+
* - If `operations` has 'generateC', the generated C code will be written to `buildDir`.
|
|
22
|
+
* - If `operations` has 'printVarList', variables and subscripts will be written to
|
|
20
23
|
* txt, yaml, and json files under `buildDir`.
|
|
21
|
-
* - If `operation`
|
|
22
|
-
* - If `operation`
|
|
24
|
+
* - If `operation` has 'printRefIdTest', reference identifiers will be printed to the console.
|
|
25
|
+
* - If `operation` has 'convertNames', no output will be generated, but the results of model
|
|
23
26
|
* analysis will be available.
|
|
24
27
|
*
|
|
25
28
|
* @param input The preprocessed Vensim model text.
|
|
26
29
|
* @param spec The model spec (from the JSON file).
|
|
27
|
-
* @param
|
|
28
|
-
*
|
|
30
|
+
* @param operations The set of operations to perform; can include 'generateC', 'printVarList',
|
|
31
|
+
* 'printRefIdTest', 'convertNames'. If the array is empty, the model will be read but no
|
|
32
|
+
* operation will be performed.
|
|
29
33
|
* @param modelDirname The absolute path to the directory containing the mdl file.
|
|
30
34
|
* The dat and xlsx files referenced by the spec will be relative to this directory.
|
|
31
35
|
* @param modelName The model name (without the mdl extension).
|
|
32
36
|
* @param buildDir The output directory where the C or list files will be written.
|
|
33
37
|
* @return A string containing the generated C code.
|
|
34
38
|
*/
|
|
35
|
-
export async function parseAndGenerate(input, spec,
|
|
39
|
+
export async function parseAndGenerate(input, spec, operations, modelDirname, modelName, buildDir) {
|
|
36
40
|
// Read time series from external DAT files into a single object.
|
|
37
41
|
// externalDatfiles is an array of either filenames or objects
|
|
38
42
|
// giving a variable name prefix as the key and a filename as the value.
|
|
@@ -63,20 +67,20 @@ export async function parseAndGenerate(input, spec, operation, modelDirname, mod
|
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
// Parse the model and generate code.
|
|
66
|
-
let
|
|
67
|
-
let code = generateCode(
|
|
70
|
+
let parsedModel = parseModel(input, modelDirname)
|
|
71
|
+
let code = generateCode(parsedModel, { spec, operations, extData, directData, modelDirname })
|
|
68
72
|
|
|
69
73
|
function writeOutput(filename, text) {
|
|
70
74
|
let outputPathname = path.join(buildDir, filename)
|
|
71
75
|
B.write(text, outputPathname)
|
|
72
76
|
}
|
|
73
77
|
|
|
74
|
-
if (
|
|
78
|
+
if (operations.includes('generateC')) {
|
|
75
79
|
// Write the generated C to a file
|
|
76
80
|
writeOutput(`${modelName}.c`, code)
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
if (
|
|
83
|
+
if (operations.includes('printVarList')) {
|
|
80
84
|
// Write variables to a text file.
|
|
81
85
|
writeOutput(`${modelName}_vars.txt`, Model.printVarList())
|
|
82
86
|
// Write subscripts to a text file.
|
|
@@ -114,3 +118,52 @@ export function printNames(namesPathname, operation) {
|
|
|
114
118
|
}
|
|
115
119
|
B.printBuf()
|
|
116
120
|
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Read and parse the given model text and return the parsed model structure.
|
|
124
|
+
*
|
|
125
|
+
* TODO: Fix return type
|
|
126
|
+
*
|
|
127
|
+
* @param {string} input The string containing the model text.
|
|
128
|
+
* @param {string} modelDir The absolute path to the directory containing the mdl file.
|
|
129
|
+
* The dat, xlsx, and csv files referenced by the model will be relative to this directory.
|
|
130
|
+
* @param {boolean} sort Whether to sort definitions alphabetically in the preprocess step.
|
|
131
|
+
* @return {*} A parsed tree representation of the model.
|
|
132
|
+
*/
|
|
133
|
+
export function parseModel(input, modelDir, sort = false) {
|
|
134
|
+
if (process.env.SDE_NONPUBLIC_USE_NEW_PARSE !== '1') {
|
|
135
|
+
// Use the legacy parser
|
|
136
|
+
return {
|
|
137
|
+
kind: 'vensim-legacy',
|
|
138
|
+
parseTree: legacyParseVensimModel(input)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Prepare the parse context that provides access to external data files
|
|
143
|
+
let parseContext /*: VensimParseContext*/
|
|
144
|
+
if (modelDir) {
|
|
145
|
+
parseContext = {
|
|
146
|
+
getDirectSubscripts(fileName, tabOrDelimiter, firstCell, lastCell /*, prefix*/) {
|
|
147
|
+
// Resolve the CSV file relative the model directory
|
|
148
|
+
const csvPath = path.resolve(modelDir, fileName)
|
|
149
|
+
|
|
150
|
+
// Read the subscripts from the CSV file
|
|
151
|
+
return getDirectSubscripts(csvPath, tabOrDelimiter, firstCell, lastCell)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Parse the model
|
|
157
|
+
// TODO: The `parseVensimModel` function currently implicitly runs the preprocess
|
|
158
|
+
// step on the input text. We should make this configurable (because `parseModel`
|
|
159
|
+
// is currently called after the legacy preprocessor has already been run).
|
|
160
|
+
// TODO: We currently sort the preprocessed definitions alphabetically for
|
|
161
|
+
// compatibility with the legacy preprocessor. Once we drop the legacy code
|
|
162
|
+
// we could remove this step and update the tests to use the original order.
|
|
163
|
+
const root = parseVensimModel(input, parseContext, sort)
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
kind: 'vensim',
|
|
167
|
+
root
|
|
168
|
+
}
|
|
169
|
+
}
|