Skip to content

Commit

Permalink
fix: update to latest antlr4-vensim with support for Unicode characte…
Browse files Browse the repository at this point in the history
…rs in variable names (#533)

Fixes #532
  • Loading branch information
chrispcampbell authored Sep 15, 2024
1 parent b3d856e commit c921657
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/parse/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"dependencies": {
"antlr4": "4.12.0",
"antlr4-vensim": "0.6.2",
"antlr4-vensim": "0.6.3",
"assert-never": "^1.2.1",
"split-string": "^6.1.0"
},
Expand Down
29 changes: 25 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions tests/integration/unicode/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "unicode",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"clean": "rm -rf sde-prep",
"build-js": "GEN_FORMAT=js sde bundle",
"build-wasm": "GEN_FORMAT=c sde bundle",
"run-tests": "./run-tests.js",
"test-js": "run-s build-js run-tests",
"test-wasm": "run-s build-wasm run-tests",
"ci:int-test": "run-s clean test-js clean test-wasm"
},
"dependencies": {
"@sdeverywhere/build": "workspace:*",
"@sdeverywhere/cli": "workspace:*",
"@sdeverywhere/plugin-wasm": "workspace:*",
"@sdeverywhere/plugin-worker": "workspace:*",
"@sdeverywhere/runtime": "workspace:*",
"@sdeverywhere/runtime-async": "workspace:*"
}
}
86 changes: 86 additions & 0 deletions tests/integration/unicode/run-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env node

import { readFile } from 'fs/promises'
import { join as joinPath } from 'path'

import { createInputValue, createSynchronousModelRunner } from '@sdeverywhere/runtime'
import { spawnAsyncModelRunner } from '@sdeverywhere/runtime-async'

import loadGeneratedModel from './sde-prep/generated-model.js'

/*
* This is a JS-level integration test that verifies that the compile and runtime
* packages work correctly when used with a model that contains Unicode (non-Latin)
* variable names.
*/

function verify(runnerKind, outputs, inputY) {
const series = outputs.getSeriesForVar('_中文输出变量_z')
for (let time = 2000; time <= 2002; time += 1) {
const actualZ = series.getValueAtTime(time)
const expectedZ = time + inputY
if (actualZ !== expectedZ) {
console.error(
`Test failed for ${runnerKind} runner at time=${time} with y=${inputY}: expected z=${expectedZ}, got z=${actualZ}`
)
process.exit(1)
}
}
}

async function runTests(runnerKind, modelRunner) {
// Create the set of inputs
const inputY = createInputValue('_中文变量名_y', 0)
const inputs = [inputY]

// Create the buffer to hold the outputs
let outputs = modelRunner.createOutputs()

// Run the model with input at default (0)
outputs = await modelRunner.runModel(inputs, outputs)

// Verify outputs
verify(runnerKind, outputs, 0)

// Run the model with input at 1
inputY.set(1)
outputs = await modelRunner.runModel(inputs, outputs)

// Verify outputs
verify(runnerKind, outputs, 1)

// Terminate the model runner
await modelRunner.terminate()
}

async function createSynchronousRunner() {
// TODO: This test app is using ESM-style modules, and `__dirname` is not defined
// in an ESM context. The `generated-model.js` file (if it contains a Wasm model)
// may contain a reference to `__dirname`, so we need to define it here. We should
// fix the generated Wasm file so that it works for either ESM or CommonJS.
global.__dirname = '.'

// Initialize the synchronous `ModelRunner` that drives the generated model
const generatedModel = await loadGeneratedModel()
return createSynchronousModelRunner(generatedModel)
}

async function createAsynchronousRunner() {
// Initialize the aynchronous `ModelRunner` that drives the generated model
const modelWorkerJs = await readFile(joinPath('sde-prep', 'worker.js'), 'utf8')
return await spawnAsyncModelRunner({ source: modelWorkerJs })
}

async function main() {
// Verify with the synchronous model runner
const syncRunner = await createSynchronousRunner()
await runTests('synchronous', syncRunner)

// Verify with the asynchronous model runner
const asyncRunner = await createAsynchronousRunner()
await runTests('asynchronous', asyncRunner)

console.log('Tests passed!\n')
}

main()
27 changes: 27 additions & 0 deletions tests/integration/unicode/sde.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { wasmPlugin } from '@sdeverywhere/plugin-wasm'
import { workerPlugin } from '@sdeverywhere/plugin-worker'

const genFormat = process.env.GEN_FORMAT === 'c' ? 'c' : 'js'

export async function config() {
return {
genFormat,
modelFiles: ['unicode.mdl'],

modelSpec: async () => {
return {
inputs: ['中文变量名 Y'],
outputs: ['中文输出变量 Z']
}
},

plugins: [
// If targeting WebAssembly, generate a `generated-model.js` file
// containing the Wasm model
genFormat === 'c' && wasmPlugin(),

// Generate a `worker.js` file that runs the generated model in a worker
workerPlugin()
]
}
}
16 changes: 16 additions & 0 deletions tests/integration/unicode/unicode.mdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{UTF-8}

中文变量名 X = TIME ~~|

中文变量名 Y = 0
~ [-10,10,0.1]
~
|

中文输出变量 Z = 中文变量名 X + 中文变量名 Y
~~|

INITIAL TIME = 2000 ~~|
FINAL TIME = 2002 ~~|
TIME STEP = 1 ~~|
SAVEPER = TIME STEP ~~|

0 comments on commit c921657

Please sign in to comment.