@sdeverywhere/parse 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/ast/print-expr.ts","../src/ast/reduce-expr.ts","../src/_shared/names.js","../src/ast/ast-builders.ts","../src/vensim/impl/subscript-range-reader.js","../src/vensim/impl/antlr-parser.js","../src/vensim/parse-vensim-subscript-range.ts","../src/vensim/impl/expr-reader.js","../src/vensim/parse-vensim-expr.ts","../src/vensim/impl/equation-reader.js","../src/vensim/parse-vensim-equation.ts","../src/vensim/preprocess-vensim.ts","../src/vensim/impl/model-reader.js","../src/vensim/parse-vensim-model.ts"],"sourcesContent":["// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nexport * from './ast/ast-types'\nexport * from './ast/print-expr'\nexport * from './ast/reduce-expr'\n\nexport * from './vensim/parse-vensim-subscript-range'\nexport * from './vensim/parse-vensim-expr'\nexport * from './vensim/parse-vensim-equation'\nexport * from './vensim/parse-vensim-model'\nexport * from './vensim/vensim-parse-context'\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport { assertNever } from 'assert-never'\n\nimport type { Expr, VariableRef } from '../ast/ast-types'\n\n/**\n * @hidden This is not yet part of the public API.\n */\nexport function debugPrintExpr(expr: Expr, indent = 0): void {\n const spaces = ' '.repeat(indent * 2)\n const log = (s: string) => {\n console.log(`${spaces}${s}`)\n }\n\n switch (expr.kind) {\n case 'number':\n log(`const: ${expr.text}`)\n break\n\n case 'string':\n log(`string: ${expr.text}`)\n break\n\n case 'keyword':\n log(`keyword: ${expr.text}`)\n break\n\n case 'variable-ref':\n log(`ref: ${fullIdForVarRef(expr)}`)\n break\n\n case 'unary-op':\n log(`unary-op: ${expr.op}`)\n debugPrintExpr(expr.expr, indent + 1)\n break\n\n case 'binary-op':\n log(`binary-op: ${expr.op}`)\n debugPrintExpr(expr.lhs, indent + 1)\n debugPrintExpr(expr.rhs, indent + 1)\n break\n\n case 'parens':\n log('parens')\n debugPrintExpr(expr.expr, indent + 1)\n break\n\n case 'lookup-def':\n // TODO: Include range and points?\n log(`lookup-def`)\n break\n\n case 'lookup-call':\n log(`lookup-call: ${debugPrintExpr(expr.varRef)}`)\n debugPrintExpr(expr.arg, indent + 1)\n break\n\n case 'function-call':\n log(`function-call: ${expr.fnId}`)\n expr.args.forEach(arg => debugPrintExpr(arg, indent + 1))\n break\n\n default:\n assertNever(expr)\n }\n}\n\n/**\n * @hidden This is not yet part of the public API.\n */\nexport type FormatVariableRefFunc = (varRef: VariableRef) => string\n\n/**\n * @hidden This is not yet part of the public API.\n */\nexport interface PrettyOpts {\n /**\n * Whether to use a compact representation without additional spaces. (The compact form mimics\n * the behavior of the legacy parser.\n */\n compact?: boolean\n html?: boolean\n formatVariableRef?: FormatVariableRefFunc\n}\n\n/**\n * @hidden This is not yet part of the public API.\n */\nexport function toPrettyString(expr: Expr, opts?: PrettyOpts): string {\n let lparen: string, rparen: string, spaceSep: string, commaSep: string\n if (opts?.compact === true) {\n lparen = '('\n rparen = ')'\n spaceSep = ''\n commaSep = ','\n } else {\n lparen = '( '\n rparen = ' )'\n spaceSep = ' '\n commaSep = ', '\n }\n\n switch (expr.kind) {\n case 'number':\n return expr.text\n\n case 'string':\n return `'${expr.text}'`\n\n case 'keyword':\n return expr.text\n\n case 'variable-ref':\n if (opts?.formatVariableRef) {\n return opts.formatVariableRef(expr)\n } else {\n if (expr.subscriptRefs?.length > 0) {\n return `${expr.varName}[${expr.subscriptRefs.map(ref => ref.subName).join(commaSep)}]`\n } else {\n return expr.varName\n }\n }\n\n case 'unary-op':\n if (expr.op === ':NOT:') {\n return `${expr.op} ${toPrettyString(expr.expr, opts)}`\n } else {\n return `${expr.op}${toPrettyString(expr.expr, opts)}`\n }\n\n case 'binary-op': {\n let op: string\n if (opts?.html === true) {\n switch (expr.op) {\n case '<':\n op = '&lt;'\n break\n case '<=':\n op = '&lt;='\n break\n case '>':\n op = '&gt;'\n break\n case '>=':\n op = '&gt;='\n break\n default:\n op = expr.op\n break\n }\n } else {\n op = expr.op\n }\n const lhs = toPrettyString(expr.lhs, opts)\n const rhs = toPrettyString(expr.rhs, opts)\n return `${lhs}${spaceSep}${op}${spaceSep}${rhs}`\n }\n\n case 'parens':\n return `${lparen}${toPrettyString(expr.expr, opts)}${rparen}`\n\n case 'lookup-def': {\n const pointString = (p: [number, number]) => {\n return `(${p[0]},${p[1]})`\n }\n const points = expr.points.map(pointString).join(commaSep)\n if (expr.range) {\n const min = pointString(expr.range.min)\n const max = pointString(expr.range.max)\n return `${lparen}[${min}-${max}]${commaSep}${points}${rparen}`\n } else {\n return `${lparen}${points}${rparen}`\n }\n }\n\n case 'lookup-call': {\n const varRef = toPrettyString(expr.varRef, opts)\n const arg = toPrettyString(expr.arg, opts)\n return `${varRef}${lparen}${arg}${rparen}`\n }\n\n case 'function-call': {\n const args = expr.args.map(arg => toPrettyString(arg, opts))\n return `${expr.fnName}${lparen}${args.join(commaSep)}${rparen}`\n }\n\n default:\n assertNever(expr)\n }\n}\n\n/**\n * @hidden This is not yet part of the public API.\n */\nexport function prettyPrintExpr(expr: Expr, indent = 0): void {\n const spaces = ' '.repeat(indent * 2)\n const log = (s: string) => {\n console.log(`${spaces}${s}`)\n }\n log(toPrettyString(expr))\n}\n\ntype CountMap = Map<string, number>\n\nclass Stats {\n constCount = 0\n varRefCount = 0\n readonly unaryOpCounts: CountMap = new Map()\n readonly binaryOpCounts: CountMap = new Map()\n readonly fnCallCounts: CountMap = new Map()\n readonly luCallCounts: CountMap = new Map()\n}\n\nfunction increment(map: CountMap, key: string): void {\n const count = map.get(key) || 0\n map.set(key, count + 1)\n}\n\nfunction getExprStats(expr: Expr, stats: Stats) {\n switch (expr.kind) {\n case 'number':\n stats.constCount++\n break\n\n case 'string':\n // TODO\n break\n\n case 'keyword':\n // TODO: Count this as a constant? (Currently only used for :NA: values.)\n break\n\n case 'variable-ref':\n stats.varRefCount++\n break\n\n case 'unary-op':\n getExprStats(expr.expr, stats)\n increment(stats.unaryOpCounts, expr.op)\n break\n\n case 'binary-op':\n getExprStats(expr.lhs, stats)\n getExprStats(expr.rhs, stats)\n increment(stats.binaryOpCounts, expr.op)\n break\n\n case 'parens':\n getExprStats(expr.expr, stats)\n break\n\n case 'lookup-def':\n // TODO\n break\n\n case 'lookup-call':\n increment(stats.luCallCounts, fullIdForVarRef(expr.varRef))\n getExprStats(expr.arg, stats)\n break\n\n case 'function-call':\n increment(stats.fnCallCounts, expr.fnId)\n expr.args.forEach(arg => getExprStats(arg, stats))\n break\n\n default:\n assertNever(expr)\n }\n}\n\n/**\n * @hidden This is not yet part of the public API.\n */\nexport function printExprStats(exprs: Expr[]): void {\n const stats = new Stats()\n for (const expr of exprs) {\n getExprStats(expr, stats)\n }\n\n function printCount(count: number, label: string) {\n console.log(`${count.toString().padStart(6)} ${label}`)\n }\n\n function printCounts(map: CountMap): number {\n const entries = [...map.entries()].sort((a, b) => a[0].localeCompare(b[0]))\n let total = 0\n for (const entry of entries) {\n printCount(entry[1], entry[0])\n total += entry[1]\n }\n printCount(total, 'total')\n return total\n }\n\n let nodeCount = 0\n\n printCount(stats.constCount, 'consts')\n nodeCount += stats.constCount\n\n printCount(stats.varRefCount, 'var refs')\n nodeCount += stats.varRefCount\n\n console.log()\n console.log('UNARY OPS')\n nodeCount += printCounts(stats.unaryOpCounts)\n\n console.log()\n console.log('BINARY OPS')\n nodeCount += printCounts(stats.binaryOpCounts)\n\n console.log()\n console.log('FUNCTION CALLS')\n nodeCount += printCounts(stats.fnCallCounts)\n\n console.log()\n console.log('LOOKUP CALLS')\n nodeCount += printCounts(stats.luCallCounts)\n\n console.log()\n console.log('TOTAL')\n printCount(nodeCount, 'nodes')\n}\n\n// TODO: Move to names.ts?\nfunction fullIdForVarRef(varRef: VariableRef): string {\n if (varRef.subscriptRefs?.length > 0) {\n return `${varRef.varId}[${varRef.subscriptRefs.map(ref => ref.subId).join(',')}]`\n } else {\n return varRef.varId\n }\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport { assertNever } from 'assert-never'\n\nimport { binaryOp, lookupCall, num, parens, unaryOp } from './ast-builders'\nimport type { Expr, NumberLiteral, VariableRef } from './ast-types'\n\n/**\n * @hidden This is not yet part of the public API.\n */\nexport interface ReduceExprOptions {\n /** A callback that returns the possibly reduced expression for the referenced variable. */\n resolveVarRef?: (varRef: VariableRef) => Expr | undefined\n}\n\n/**\n * @hidden This is not yet part of the public API.\n */\nexport function reduceExpr(expr: Expr, opts?: ReduceExprOptions): Expr {\n switch (expr.kind) {\n case 'number':\n case 'string':\n case 'keyword':\n return expr\n\n case 'variable-ref':\n if (opts?.resolveVarRef !== undefined) {\n // Note that we assume the resolved expression has already been reduced by\n // the callback, and don't attempt to reduce further\n const resolvedExpr = opts.resolveVarRef(expr)\n if (resolvedExpr) {\n return resolvedExpr\n }\n }\n return expr\n\n case 'unary-op': {\n // Reduce the child expression\n const child = reduceExpr(expr.expr, opts)\n switch (expr.op) {\n case '+':\n // When there is an explicit plus sign, we can take the child expression as is\n return child\n case '-':\n if (child.kind === 'number') {\n // Negate the number\n return num(-child.value)\n } else {\n // Cannot simplify further\n return unaryOp('-', child)\n }\n case ':NOT:':\n if (child.kind === 'number') {\n // Use the same behavior as C and negate the numeric value. (\"The result of the\n // logical negation operator ! is 0 if the value of its operand compares unequal\n // to 0, 1 if the value of its operand compares equal to 0.\")\n return num(child.value === 0 ? 1 : 0)\n } else {\n // Cannot simplify further\n return unaryOp(':NOT:', child)\n }\n default:\n assertNever(expr)\n }\n break\n }\n\n case 'binary-op': {\n // Reduce the lhs and rhs expressions\n // TODO: Don't visit rhs if expression can be reduced by looking at lhs alone\n const lhs = reduceExpr(expr.lhs, opts)\n const rhs = reduceExpr(expr.rhs, opts)\n if (lhs.kind === 'number' && rhs.kind === 'number') {\n // Perform basic arithmetic to reduce to a constant number\n switch (expr.op) {\n case '+':\n return num(lhs.value + rhs.value)\n case '-':\n return num(lhs.value - rhs.value)\n case '*':\n return num(lhs.value * rhs.value)\n case '/':\n // TODO: Catch divide-by-zero errors at compile time\n return num(lhs.value / rhs.value)\n case '^':\n return num(Math.pow(lhs.value, rhs.value))\n case '=':\n return num(lhs.value === rhs.value ? 1 : 0)\n case '<>':\n return num(lhs.value !== rhs.value ? 1 : 0)\n case '<':\n return num(lhs.value < rhs.value ? 1 : 0)\n case '>':\n return num(lhs.value > rhs.value ? 1 : 0)\n case '<=':\n return num(lhs.value <= rhs.value ? 1 : 0)\n case '>=':\n return num(lhs.value >= rhs.value ? 1 : 0)\n case ':AND:':\n // For AND expressions, if both sides are non-zero, then resolve to 1\n return num(lhs.value !== 0 && rhs.value !== 0 ? 1 : 0)\n case ':OR:':\n // For OR expressions, if either side is non-zero, then resolve to 1\n return num(lhs.value !== 0 || rhs.value !== 0 ? 1 : 0)\n default:\n assertNever(expr)\n }\n } else if (lhs.kind === 'number' || rhs.kind === 'number') {\n // Try to reduce identity expressions to a single value (x*1 == x, and so on)\n const lhsNum: number = lhs.kind === 'number' ? lhs.value : undefined\n const rhsNum: number = rhs.kind === 'number' ? rhs.value : undefined\n const numValue = lhsNum !== undefined ? lhsNum : rhsNum\n const otherSide = lhsNum !== undefined ? rhs : lhs\n switch (expr.op) {\n case '+': {\n if (numValue === 0) {\n // x+0 == x\n // 0+x == x\n return otherSide\n } else if (\n otherSide.kind === 'binary-op' &&\n otherSide.op === '+' &&\n (otherSide.lhs.kind === 'number' || otherSide.rhs.kind === 'number')\n ) {\n // In this case, one side is const and and the child is a '+' with a const, so we\n // can add the two consts and fold into a single add op\n const otherSideLhsNum: number = otherSide.lhs.kind === 'number' ? otherSide.lhs.value : undefined\n const otherSideRhsNum: number = otherSide.rhs.kind === 'number' ? otherSide.rhs.value : undefined\n const otherSideConstValue = otherSideLhsNum !== undefined ? otherSideLhsNum : otherSideRhsNum\n const otherSideOtherPart = otherSideLhsNum !== undefined ? otherSide.rhs : otherSide.lhs\n return binaryOp(num(numValue + otherSideConstValue), '+', otherSideOtherPart)\n }\n break\n }\n\n case '-': {\n if (rhsNum === 0) {\n // x-0 == x\n return lhs\n } else if (lhsNum === 0) {\n // 0-x == -x\n // TODO: This probably isn't too helpful\n return unaryOp('-', rhs)\n }\n break\n }\n\n case '*': {\n if (numValue === 0) {\n // x*0 == 0\n // 0*x == 0\n return num(0)\n } else if (numValue === 1) {\n // x*1 == x\n // 1*x == x\n return otherSide\n } else if (\n otherSide.kind === 'binary-op' &&\n otherSide.op === '*' &&\n (otherSide.lhs.kind === 'number' || otherSide.rhs.kind === 'number')\n ) {\n // In this case, one side is const and and the child is a '*' with a const, so we\n // can multiply the two consts and fold into a single multiply op\n const otherSideLhsNum: number = otherSide.lhs.kind === 'number' ? otherSide.lhs.value : undefined\n const otherSideRhsNum: number = otherSide.rhs.kind === 'number' ? otherSide.rhs.value : undefined\n const otherSideConstValue = otherSideLhsNum !== undefined ? otherSideLhsNum : otherSideRhsNum\n const otherSideOtherPart = otherSideLhsNum !== undefined ? otherSide.rhs : otherSide.lhs\n return binaryOp(num(numValue * otherSideConstValue), '*', otherSideOtherPart)\n }\n break\n }\n\n case '/': {\n if (rhsNum === 1) {\n // x/1 == x\n return lhs\n }\n break\n }\n\n case '^': {\n if (rhsNum === 0) {\n // x^0 == 1\n return num(1)\n } else if (rhsNum === 1) {\n // x^1 == x\n return lhs\n }\n break\n }\n\n case ':AND:':\n // For AND expressions:\n // - if the constant side is zero, then resolve to zero (false)\n // x && 0 == 0\n // 0 && x == 0\n // - if the constant side is non-zero, then resolve to the other side\n // x && 1 == x\n // 1 && x == x\n return numValue === 0 ? num(0) : otherSide\n\n case ':OR:':\n // For OR expressions:\n // - if the constant side is non-zero, then resolve to one (true)\n // x || 1 == 1\n // 1 || x == 1\n // - if the constant side is zero, resolve to the other side\n // x || 0 == x\n // 0 || x == x\n return numValue !== 0 ? num(1) : otherSide\n\n default:\n break\n }\n }\n\n // Cannot simplify further; return a new expression with the reduced child expressions\n return {\n kind: 'binary-op',\n lhs,\n op: expr.op,\n rhs\n }\n }\n\n case 'parens': {\n const child = reduceExpr(expr.expr, opts)\n return applyParens(child)\n }\n\n case 'lookup-def':\n // TODO: Reduce lookup def?\n return expr\n\n case 'lookup-call':\n // TODO: Reduce lookup call arg?\n return expr\n\n case 'function-call': {\n // Reduce each argument expression\n if (expr.fnId === '_IF_THEN_ELSE') {\n // If condition is a constant, we can eliminate the unused branch\n const conditionExpr = reduceExpr(expr.args[0], opts)\n if (conditionExpr.kind === 'number') {\n // The condition resolved to a simple numeric constant. If it is non-zero,\n // replace the `IF THEN ELSE` call with the \"true\" branch, otherwise replace\n // it with the \"false\" branch.\n const branchExpr = conditionExpr.value !== 0 ? reduceExpr(expr.args[1], opts) : reduceExpr(expr.args[2], opts)\n\n // Wrap the branch expression in parentheses if needed to ensure that the intent\n // of the original expression remains the same. For example:\n // a = IF THEN ELSE(1, b + c, d - e) * 10\n // In this case, the parentheses are important, and need to be preserved:\n // a = (b + c) * 10\n // If the parentheses are not needed (like when the branch resolve to a simple\n // constant or variable reference), the parentheses will be dropped.\n return applyParens(branchExpr)\n }\n }\n\n // If all args are constant, apply the function at compile time (for certain functions)\n const reducedArgs = expr.args.map(arg => reduceExpr(arg, opts))\n const allConst = reducedArgs.every(arg => arg.kind === 'number')\n if (allConst) {\n const constArg = (index: number) => {\n const num = reducedArgs[index] as NumberLiteral\n return num.value\n }\n switch (expr.fnId) {\n case '_ABS':\n return num(Math.abs(constArg(0)))\n case '_COS':\n return num(Math.cos(constArg(0)))\n case '_EXP':\n return num(Math.exp(constArg(0)))\n case '_INITIAL':\n return reducedArgs[0]\n case '_INTEGER':\n return num(Math.trunc(constArg(0)))\n case '_LN':\n return num(Math.log(constArg(0)))\n case '_MAX':\n return num(Math.max(constArg(0), constArg(1)))\n case '_MIN':\n return num(Math.min(constArg(0), constArg(1)))\n case '_MODULO':\n return num(constArg(0) % constArg(1))\n case '_POWER':\n return num(Math.pow(constArg(0), constArg(1)))\n case '_SIN':\n return num(Math.sin(constArg(0)))\n case '_SQRT':\n return num(Math.sqrt(constArg(0)))\n default:\n break\n }\n }\n\n return {\n kind: 'function-call',\n fnName: expr.fnName,\n fnId: expr.fnId,\n args: reducedArgs\n }\n }\n\n default:\n assertNever(expr)\n }\n}\n\n/**\n * A variant of `reduceExpr` that does not aggressively reduce the expression, but only\n * tries to eliminate the unused branch if a conditional (`IF THEN ELSE`) has a condition\n * that resolves to a constant.\n *\n * @hidden This is not yet part of the public API.\n *\n * @param expr The expression to reduce.\n * @param opts The reduce options.\n * @returns A possibly reduced expression.\n */\nexport function reduceConditionals(expr: Expr, opts?: ReduceExprOptions): Expr {\n switch (expr.kind) {\n case 'number':\n case 'string':\n case 'keyword':\n return expr\n\n case 'variable-ref':\n // If we get here, it means that we are processing an expression that is not\n // inside the condition expression for an `IF THEN ELSE`, so we do not attempt\n // to resolve the variable reference or reduce it further\n return expr\n\n case 'unary-op': {\n const child = reduceConditionals(expr.expr, opts)\n return unaryOp(expr.op, child)\n }\n\n case 'binary-op': {\n const lhs = reduceConditionals(expr.lhs, opts)\n const rhs = reduceConditionals(expr.rhs, opts)\n return binaryOp(lhs, expr.op, rhs)\n }\n\n case 'parens': {\n const child = reduceConditionals(expr.expr, opts)\n return applyParens(child)\n }\n\n case 'lookup-def':\n return expr\n\n case 'lookup-call': {\n const arg = reduceConditionals(expr.arg, opts)\n return lookupCall(expr.varRef, arg)\n }\n\n case 'function-call': {\n if (expr.fnId === '_IF_THEN_ELSE') {\n // Note that (unlike all other places in this function) we use `reduceExpr` here\n // to aggressively reduce the condition expression (the first argument for the\n // `IF THEN ELSE` call)\n const conditionExpr = reduceExpr(expr.args[0], opts)\n if (conditionExpr.kind === 'number') {\n // The condition resolved to a simple numeric constant. If it is non-zero,\n // replace the `IF THEN ELSE` call with the \"true\" branch, otherwise replace\n // it with the \"false\" branch.\n const branchExpr =\n conditionExpr.value !== 0 ? reduceConditionals(expr.args[1], opts) : reduceConditionals(expr.args[2], opts)\n\n // Wrap the branch expression in parentheses if needed to ensure that the intent\n // of the original expression remains the same. For example:\n // a = IF THEN ELSE(1, b + c, d - e) * 10\n // In this case, the parentheses are important, and need to be preserved:\n // a = (b + c) * 10\n // If the parentheses are not needed (like when the branch resolve to a simple\n // constant or variable reference), the parentheses will be dropped.\n return applyParens(branchExpr)\n }\n }\n\n // For all other kinds of function calls, call `reduceConditionals` on the args\n const reducedArgs = expr.args.map(arg => reduceConditionals(arg, opts))\n return {\n kind: 'function-call',\n fnName: expr.fnName,\n fnId: expr.fnId,\n args: reducedArgs\n }\n }\n\n default:\n assertNever(expr)\n }\n}\n\n/**\n * Reduce the given expression that may need to be wrapped in parentheses. If the parentheses\n * are not needed, the given `child` expression will be returned as is, otherwise it will be\n * wrapped in a \"parens\" node.\n *\n * @param child The child of a parens expression to reduce.\n * @returns A possibly reduced expression.\n */\nfunction applyParens(child: Expr): Expr {\n switch (child.kind) {\n case 'number':\n case 'string':\n case 'keyword':\n case 'variable-ref':\n // When the child expression resolves to something simple, drop the parens\n // TODO: Are there other cases where we should drop the parens?\n return child\n default:\n // Otherwise, preserve the parens\n return parens(child)\n }\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\n/**\n * Format a model variable name into a valid C identifier (with special characters\n * converted to underscore).\n *\n * @param {string} name The name of the variable in the source model, e.g., \"Variable name\".\n * @returns {string} The C identifier for the given name, e.g., \"_variable_name\".\n */\nexport function canonicalName(name) {\n // TODO: This is also defined in the compile package. Would be good to\n // define it in one place to reduce the chance of them getting out of sync.\n return (\n '_' +\n name\n .trim()\n .replace(/\"/g, '_')\n .replace(/\\s+!$/g, '!')\n .replace(/\\s/g, '_')\n .replace(/,/g, '_')\n .replace(/-/g, '_')\n .replace(/\\./g, '_')\n .replace(/\\$/g, '_')\n .replace(/'/g, '_')\n .replace(/&/g, '_')\n .replace(/%/g, '_')\n .replace(/\\//g, '_')\n .replace(/\\|/g, '_')\n .toLowerCase()\n )\n}\n\n/**\n * Format a model function name into a valid C identifier (with special characters\n * converted to underscore).\n *\n * @param {string} name The name of the variable in the source model, e.g., \"FUNCTION NAME\".\n * @returns {string} The C identifier for the given name, e.g., \"_FUNCTION_NAME\".\n */\nexport function cFunctionName(name) {\n return canonicalName(name).toUpperCase()\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport { canonicalName, cFunctionName } from '../_shared/names'\n\nimport type {\n BinaryOp,\n BinaryOpExpr,\n DimensionDef,\n DimName,\n DimOrSubName,\n Equation,\n Expr,\n FunctionCall,\n FunctionName,\n Keyword,\n LookupCall,\n LookupDef,\n LookupPoint,\n LookupRange,\n Model,\n NumberLiteral,\n ParensExpr,\n StringLiteral,\n SubName,\n SubscriptMapping,\n SubscriptRef,\n UnaryOp,\n UnaryOpExpr,\n VariableDef,\n VariableName,\n VariableRef\n} from './ast-types'\n\n//\n// NOTE: This file contains functions that allow for tersely defining AST nodes.\n// It is intended for internal use only (primarily in tests), so it is not exported\n// as part of the public API at this time.\n//\n\n//\n// DIMENSIONS + SUBSCRIPTS\n//\n\nexport function subRef(dimOrSubName: DimOrSubName): SubscriptRef {\n return {\n subName: dimOrSubName,\n subId: canonicalName(dimOrSubName)\n }\n}\n\nexport function subMapping(toDimName: DimName, dimOrSubNames: DimOrSubName[] = []): SubscriptMapping {\n return {\n toDimName,\n toDimId: canonicalName(toDimName),\n subscriptRefs: dimOrSubNames.map(subRef)\n }\n}\n\nexport function dimDef(\n dimName: DimName,\n familyName: DimName,\n dimOrSubNames: SubName[],\n subscriptMappings: SubscriptMapping[] = [],\n comment = '',\n group?: string\n): DimensionDef {\n return {\n dimName,\n dimId: canonicalName(dimName),\n familyName,\n familyId: canonicalName(familyName),\n subscriptRefs: dimOrSubNames.map(subRef),\n subscriptMappings,\n comment,\n ...(group ? { group } : {})\n }\n}\n\n//\n// EXPRESSIONS\n//\n\nexport function num(value: number, text?: string): NumberLiteral {\n return {\n kind: 'number',\n value,\n text: text || value.toString()\n }\n}\n\nexport function stringLiteral(text: string): StringLiteral {\n return {\n kind: 'string',\n text\n }\n}\n\nexport function keyword(text: string): Keyword {\n return {\n kind: 'keyword',\n text\n }\n}\n\nexport function varRef(varName: VariableName, subscriptNames?: DimOrSubName[]): VariableRef {\n return {\n kind: 'variable-ref',\n varName,\n varId: canonicalName(varName),\n subscriptRefs: subscriptNames?.map(subRef)\n }\n}\n\nexport function unaryOp(op: UnaryOp, expr: Expr): UnaryOpExpr {\n return {\n kind: 'unary-op',\n op,\n expr\n }\n}\n\nexport function binaryOp(lhs: Expr, op: BinaryOp, rhs: Expr): BinaryOpExpr {\n return {\n kind: 'binary-op',\n lhs,\n op,\n rhs\n }\n}\n\nexport function parens(expr: Expr): ParensExpr {\n return {\n kind: 'parens',\n expr\n }\n}\n\nexport function lookupDef(points: LookupPoint[], range?: LookupRange): LookupDef {\n return {\n kind: 'lookup-def',\n range,\n points\n }\n}\n\nexport function lookupCall(varRef: VariableRef, arg: Expr): LookupCall {\n return {\n kind: 'lookup-call',\n varRef,\n arg\n }\n}\n\nexport function call(fnName: FunctionName, ...args: Expr[]): FunctionCall {\n return {\n kind: 'function-call',\n fnName,\n fnId: cFunctionName(fnName),\n args\n }\n}\n\n//\n// EQUATIONS\n//\n\nexport function varDef(\n varName: VariableName,\n subscriptNames?: DimOrSubName[],\n exceptSubscriptNames?: DimOrSubName[][]\n): VariableDef {\n return {\n kind: 'variable-def',\n varName,\n varId: canonicalName(varName),\n subscriptRefs: subscriptNames?.map(subRef),\n exceptSubscriptRefSets: exceptSubscriptNames?.map(namesForSet => namesForSet.map(subRef))\n }\n}\n\nexport function exprEqn(varDef: VariableDef, expr: Expr, units = '', comment = '', group?: string): Equation {\n return {\n lhs: {\n varDef\n },\n rhs: {\n kind: 'expr',\n expr\n },\n units,\n comment,\n ...(group ? { group } : {})\n }\n}\n\nexport function constListEqn(varDef: VariableDef, constants: NumberLiteral[][], units = '', comment = ''): Equation {\n // For now, assume that the original text had a trailing semicolon if there are multiple groups\n let text = constants.map(arr => arr.map(constant => constant.text).join(',')).join(';')\n if (constants.length > 1) {\n text += ';'\n }\n return {\n lhs: {\n varDef\n },\n rhs: {\n kind: 'const-list',\n constants: constants.flat(),\n text\n },\n units,\n comment\n }\n}\n\nexport function dataVarEqn(varDef: VariableDef, units = '', comment = ''): Equation {\n return {\n lhs: {\n varDef\n },\n rhs: {\n kind: 'data'\n },\n units,\n comment\n }\n}\n\nexport function lookupVarEqn(varDef: VariableDef, lookupDef: LookupDef, units = '', comment = ''): Equation {\n return {\n lhs: {\n varDef\n },\n rhs: {\n kind: 'lookup',\n lookupDef\n },\n units,\n comment\n }\n}\n\n//\n// MODEL\n//\n\nexport function model(dimensions: DimensionDef[], equations: Equation[]): Model {\n return {\n dimensions,\n equations\n }\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport { ModelParser, ModelVisitor } from 'antlr4-vensim'\n\nimport { canonicalName, cFunctionName } from '../../_shared/names'\n\nimport { createAntlrParser } from './antlr-parser'\n\nexport class SubscriptRangeReader extends ModelVisitor {\n /**\n * @public\n * @param {import('../vensim-parse-context').VensimParseContext} parseContext An object\n * that provides access to file system resources (such as external data files) that are\n * referenced during the parse phase.\n */\n constructor(parseContext /*: VensimParseContext*/) {\n super()\n this.parseContext = parseContext\n }\n\n /**\n * Parse the given Vensim subscript range definition and return a `DimensionDef` AST node.\n *\n * @public\n * @param {string} subscriptRangeText A string containing the Vensim subscript range definition.\n * @returns {import('../../ast/ast-types').DimensionDef} A `DimensionDef` AST node.\n */\n /*public*/ parse(subscriptRangeText /*: string*/) /*: DimensionDef*/ {\n const parser = createAntlrParser(subscriptRangeText)\n const subscriptRangeCtx = parser.subscriptRange()\n return this.visitSubscriptRange(subscriptRangeCtx)\n }\n\n /**\n * Process the given ANTLR `SubscriptRangeContext` from an already parsed Vensim\n * subscript range definition.\n *\n * @public\n * @param {import('antlr4-vensim').SubscriptRangeContext} ctx The ANTLR `SubscriptRangeContext`.\n * @returns {import('../../ast/ast-types').Expr} A `SubscriptRange` AST node.\n */\n /*public*/ visitSubscriptRange(ctx /*: SubscriptRangeContext*/) /*: DimensionDef*/ {\n this.subscriptNames = []\n this.subscriptMappings = []\n\n // TODO: For now, fill in an empty string for the comment; this is mainly\n // for compatibility with unit tests that expect empty string instead of\n // undefined, but this should be revisited\n const comment = ''\n\n // A subscript alias has two identifiers, while a regular subscript range definition\n // has just one\n const ids = ctx.Id()\n if (ids.length === 1) {\n // This is a regular subscript range definition, which begins with the dimension name\n const dimName = ids[0].getText()\n const dimId = canonicalName(dimName)\n\n // Visit children to fill in the subscript range definition\n super.visitSubscriptRange(ctx)\n\n // Create a new subscript range definition (`DimensionDef`) from Vensim-format names.\n // - The family is provisionally set to the dimension name.\n // - It will be updated to the maximal dimension if this is a subdimension.\n // - The mapping value contains dimensions and indices in the toDim.\n // - It will be expanded and inverted to fromDim indices later.\n return {\n dimName,\n dimId,\n familyName: dimName,\n familyId: dimId,\n subscriptRefs: this.subscriptNames.map(subName => {\n return {\n subName,\n subId: canonicalName(subName)\n }\n }),\n subscriptMappings: this.subscriptMappings,\n comment\n }\n } else if (ids.length === 2) {\n // This is a dimension alias (`DimA <-> DimB`)\n const dimName = ids[0].getText()\n const dimId = canonicalName(dimName)\n const familyName = ids[1].getText()\n const familyId = canonicalName(familyName)\n return {\n dimName,\n dimId,\n familyName,\n familyId,\n subscriptRefs: [],\n subscriptMappings: [],\n comment\n }\n }\n }\n\n visitSubscriptDefList(ctx) {\n // A subscript def is either an `Id` (a single subscript name, like \"A1\") or a numeric range\n // like \"(A1-A3)\". Either form can appear in the list, for example, \"A1, (A5-A7), A9\".\n for (const subscriptDef of ctx.children) {\n if (subscriptDef.symbol?.type === ModelParser.Id) {\n this.subscriptNames.push(subscriptDef.getText())\n } else if (subscriptDef.ruleIndex === ModelParser.RULE_subscriptSequence) {\n this.visitSubscriptSequence(subscriptDef)\n }\n }\n }\n\n visitSubscriptSequence(ctx) {\n // This is a subscript sequence (aka numeric range), like \"(A1-A3)\".\n // Construct index names from the sequence start and end indices.\n // This assumes the indices begin with the same string and end with numbers.\n const re = /^(.*?)(\\d+)$/\n const ids = ctx.Id().map(id => id.getText())\n const matches = ids.map(id => re.exec(id))\n if (matches[0][1] === matches[1][1]) {\n const prefix = matches[0][1]\n const start = parseInt(matches[0][2])\n const end = parseInt(matches[1][2])\n for (let i = start; i <= end; i++) {\n this.subscriptNames.push(prefix + i)\n }\n }\n }\n\n visitSubscriptMapping(ctx) {\n // Get the name of the \"to\" part of the mapping\n const toDimName = ctx.Id().getText()\n\n // If a subscript list is part of the mapping, the names will be set by `visitSubscriptList`\n this.mappedSubscriptNames = []\n\n // Visit the rest of the mapping, which includes the subscript list portion\n super.visitSubscriptMapping(ctx)\n\n // Add the mappings\n this.subscriptMappings.push({\n toDimName,\n toDimId: canonicalName(toDimName),\n subscriptRefs: this.mappedSubscriptNames.map(subName => {\n return {\n subName,\n subId: canonicalName(subName)\n }\n })\n })\n }\n\n visitSubscriptList(ctx) {\n // When parsing subscript range definitions, a subscript list is only used in the context\n // of a subscript mapping. It contains a list of subscript index names.\n this.mappedSubscriptNames = ctx.Id().map(id => id.getText())\n }\n\n visitCall(ctx) {\n // A subscript range can have a `GET DIRECT SUBSCRIPT` call on the RHS\n const fnName = ctx.Id().getText()\n const fnId = cFunctionName(fnName)\n if (fnId === '_GET_DIRECT_SUBSCRIPT') {\n super.visitCall(ctx)\n } else {\n throw new Error(\n `Only 'GET DIRECT SUBSCRIPT' calls are supported in subscript range definitions, but saw '${fnName}'`\n )\n }\n }\n\n visitExprList(ctx) {\n // The only call that ends up here is `GET DIRECT SUBSCRIPT`. The arguments\n // are all strings that are delimited with single quotes, so strip those before\n // passing the arguments to the `getDirectSubscripts` function.\n const args = ctx.expr().map(expr => {\n const exprText = expr.getText()\n return exprText.replaceAll(\"'\", '')\n })\n\n // Delegate to the context\n const fileName = args[0]\n const tabOrDelimiter = args[1]\n const firstCell = args[2]\n const lastCell = args[3]\n const prefix = args[4]\n this.subscriptNames =\n this.parseContext?.getDirectSubscripts(fileName, tabOrDelimiter, firstCell, lastCell, prefix) || []\n }\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport antlr4 from 'antlr4'\nimport { ModelLexer, ModelParser } from 'antlr4-vensim'\n\n/**\n * Create a `ModelParser` for the given model text, which can be the\n * contents of an entire `mdl` file, or a portion of one (e.g., an\n * expression or definition).\n *\n * @param {string} input The string containing the model text.\n * @return {ModelParser} A `ModelParser` from which a parse tree can be obtained.\n */\nexport function createAntlrParser(input) {\n // Create a custom error handler that will override the defafult one, which\n // only logs errors to stderr. The custom handler will rethrow the error (for\n // fail-fast behavior).\n const errorListener = new CustomErrorListener(input)\n\n // Create a lexer for the input (with custom error handler)\n let chars = new antlr4.InputStream(input)\n let lexer = new ModelLexer(chars)\n lexer.removeErrorListeners()\n lexer.addErrorListener(errorListener)\n\n // Create a parser around the result of the lexer (with custom error handler)\n // error listener.\n let tokens = new antlr4.CommonTokenStream(lexer)\n let parser = new ModelParser(tokens)\n parser.buildParseTrees = true\n parser.removeErrorListeners()\n parser.addErrorListener(errorListener)\n\n return parser\n}\n\nclass CustomErrorListener extends antlr4.error.ErrorListener {\n constructor(input) {\n super()\n this.input = input\n }\n\n syntaxError(_recognizer, _offendingSymbol, line, column, msg /*, err*/) {\n throw new Error(msg, {\n cause: {\n code: 'VensimParseError',\n line,\n column\n }\n })\n }\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport type { DimensionDef } from '../ast/ast-types'\nimport type { VensimParseContext } from './vensim-parse-context'\nimport { SubscriptRangeReader } from './impl/subscript-range-reader'\n\n/**\n * Parse the given Vensim subscript range definition and return a `DimensionDef` AST node.\n *\n * @param input A string containing the Vensim subscript range definition.\n * @param context An object that provides access to file system resources (such as\n * external data files) that are referenced during the parse phase.\n * @returns A `DimensionDef` AST node.\n */\nexport function parseVensimSubscriptRange(input: string, context?: VensimParseContext): DimensionDef {\n // TODO: Reuse reader instance?\n const subscriptReader = new SubscriptRangeReader(context)\n return subscriptReader.parse(input)\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport { ModelLexer, ModelVisitor } from 'antlr4-vensim'\n\nimport { canonicalName, cFunctionName } from '../../_shared/names'\n\nimport { createAntlrParser } from './antlr-parser'\n\nexport class ExprReader extends ModelVisitor {\n constructor() {\n super()\n\n // Stack of function names and argument indices encountered on the RHS\n this.callStack = []\n }\n\n /**\n * Parse the given Vensim expression definition and return an `Expr` AST node.\n *\n * @public\n * @param {string} exprText A string containing the Vensim expression.\n * @returns {import('../../ast/ast-types').Expr} An `Expr` AST node.\n */\n /*public*/ parse(exprText /*: string*/) /*: Expr*/ {\n const parser = createAntlrParser(exprText)\n const exprCtx = parser.expr()\n return this.visitExpr(exprCtx)\n }\n\n /**\n * Process the given ANTLR `ExprContext` from an already parsed Vensim\n * expression definition.\n *\n * @public\n * @param {import('antlr4-vensim').ExprContext} ctx The ANTLR `ExprContext`.\n * @returns {import('../../ast/ast-types').Expr} An `Expr` AST node.\n */\n /*public*/ visitExpr(ctx /*: ExprContext*/) /*: Expr*/ {\n ctx.accept(this)\n return this.expr\n }\n\n //\n // Constants\n //\n\n visitConst(ctx) {\n const text = ctx.Const().getText()\n if (text.startsWith(\"'\") && text.endsWith(\"'\")) {\n // Treat it as a string\n this.expr = {\n kind: 'string',\n text: text.substr(1, text.length - 2)\n }\n } else {\n // Treat it as a number\n const value = parseFloat(text)\n this.expr = {\n kind: 'number',\n value,\n text\n }\n }\n }\n\n //\n // Keywords\n //\n\n visitKeyword(ctx) {\n const text = ctx.Keyword().getText()\n this.expr = {\n kind: 'keyword',\n text\n }\n }\n\n //\n // Function calls and variables\n //\n\n visitCall(ctx) {\n // Convert the function name from Vensim to C format\n const vensimFnName = ctx.Id().getText()\n const fnId = cFunctionName(vensimFnName)\n this.callStack.push({ fn: fnId, args: [] })\n super.visitCall(ctx)\n const callInfo = this.callStack.pop()\n this.expr = {\n kind: 'function-call',\n fnName: vensimFnName,\n fnId: fnId,\n args: callInfo.args\n }\n }\n\n visitExprList(ctx) {\n const exprs = ctx.expr()\n for (let i = 0; i < exprs.length; i++) {\n // this.setArgIndex(i)\n exprs[i].accept(this)\n const n = this.callStack.length\n if (n > 0) {\n this.callStack[n - 1].args.push(this.expr)\n }\n }\n }\n\n visitVar(ctx) {\n // Convert the variable name from Vensim to C format\n const vensimVarName = ctx.Id().getText().trim()\n const varId = canonicalName(vensimVarName)\n\n // Process the subscripts (if any) that follow the variable name\n this.subscripts = undefined\n super.visitVar(ctx)\n const subscriptNames = this.subscripts\n const subscriptRefs = subscriptNames?.map(name => {\n return {\n subName: name,\n subId: canonicalName(name)\n }\n })\n this.subscripts = undefined\n\n this.expr = {\n kind: 'variable-ref',\n varName: vensimVarName,\n varId: varId,\n subscriptRefs\n }\n }\n\n visitSubscriptList(ctx) {\n // Get the subscripts found in the var name\n this.subscripts = ctx.Id().map(id => id.getText())\n }\n\n //\n // Lookups\n //\n\n getPoint(lookupPoint) {\n const exprs = lookupPoint.expr()\n if (exprs.length >= 2) {\n return [parseFloat(exprs[0].getText()), parseFloat(exprs[1].getText())]\n }\n }\n\n visitLookupRange(ctx) {\n this.lookupRange = ctx.lookupPoint().map(p => this.getPoint(p))\n super.visitLookupRange(ctx)\n }\n\n visitLookupPointList(ctx) {\n this.lookupPoints = ctx.lookupPoint().map(p => this.getPoint(p))\n super.visitLookupPointList(ctx)\n }\n\n visitLookupArg(ctx) {\n super.visitLookupArg(ctx)\n let range\n if (this.lookupRange && this.lookupRange.length === 2) {\n range = {\n min: this.lookupRange[0],\n max: this.lookupRange[1]\n }\n }\n this.expr = {\n kind: 'lookup-def',\n range,\n points: this.lookupPoints\n }\n this.lookupRange = undefined\n this.lookupPoints = undefined\n }\n\n visitLookupCall(ctx) {\n // Process the lookup variable name\n const lookupVarName = ctx.Id().getText()\n const lookupVarId = canonicalName(lookupVarName)\n\n // Process any subscripts that follow the variable name\n if (ctx.subscriptList()) {\n ctx.subscriptList().accept(this)\n }\n const subscriptNames = this.subscripts\n const subscriptRefs = subscriptNames?.map(name => {\n return {\n subName: name,\n subId: canonicalName(name)\n }\n })\n this.subscripts = undefined\n\n const lookupVarRef = {\n kind: 'variable-ref',\n varName: lookupVarName,\n varId: lookupVarId,\n subscriptRefs\n }\n\n // Process the single lookup argument\n ctx.expr().accept(this)\n const lookupArg = this.expr\n\n this.expr = {\n kind: 'lookup-call',\n varRef: lookupVarRef,\n arg: lookupArg\n }\n }\n\n //\n // Unary operators\n //\n\n completeUnary(op /*: UnaryOp*/) {\n const child = this.expr\n this.expr = {\n kind: 'unary-op',\n op,\n expr: child\n }\n }\n\n visitNegative(ctx) {\n super.visitNegative(ctx)\n this.completeUnary('-')\n }\n\n visitPositive(ctx) {\n super.visitPositive(ctx)\n this.completeUnary('+')\n }\n\n visitNot(ctx) {\n super.visitNot(ctx)\n this.completeUnary(':NOT:')\n }\n\n //\n // Binary operators\n //\n\n visitBinaryArgs(ctx, op /*: BinaryOp*/) {\n ctx.expr(0).accept(this)\n const lhs = this.expr\n ctx.expr(1).accept(this)\n const rhs = this.expr\n this.expr = {\n kind: 'binary-op',\n lhs,\n op,\n rhs\n }\n }\n\n visitPower(ctx) {\n this.visitBinaryArgs(ctx, '^')\n }\n\n visitMulDiv(ctx) {\n this.visitBinaryArgs(ctx, ctx.op.type === ModelLexer.Star ? '*' : '/')\n }\n\n visitAddSub(ctx) {\n this.visitBinaryArgs(ctx, ctx.op.type === ModelLexer.Plus ? '+' : '-')\n }\n\n visitRelational(ctx) {\n let op\n switch (ctx.op.type) {\n case ModelLexer.Less:\n op = '<'\n break\n case ModelLexer.Greater:\n op = '>'\n break\n case ModelLexer.LessEqual:\n op = '<='\n break\n case ModelLexer.GreaterEqual:\n op = '>='\n break\n default:\n throw new Error(`Unexpected relational operator '${op}'`)\n }\n this.visitBinaryArgs(ctx, op)\n }\n\n visitEquality(ctx) {\n this.visitBinaryArgs(ctx, ctx.op.type === ModelLexer.Equal ? '=' : '<>')\n }\n\n visitAnd(ctx) {\n this.visitBinaryArgs(ctx, ':AND:')\n }\n\n visitOr(ctx) {\n this.visitBinaryArgs(ctx, ':OR:')\n }\n\n //\n // Tokens\n //\n\n visitParens(ctx) {\n super.visitParens(ctx)\n\n const child = this.expr\n this.expr = {\n kind: 'parens',\n expr: child\n }\n }\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport type { Expr } from '../ast/ast-types'\nimport { ExprReader } from './impl/expr-reader'\n\n/**\n * Parse the given Vensim expression definition and return an `Expr` AST node.\n *\n * @param input A string containing the Vensim expression.\n * @returns An `Expr` AST node.\n */\nexport function parseVensimExpr(input: string): Expr {\n // TODO: Reuse reader instance?\n const exprReader = new ExprReader()\n return exprReader.parse(input)\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport { ModelVisitor } from 'antlr4-vensim'\n\nimport { canonicalName } from '../../_shared/names'\n\nimport { createAntlrParser } from './antlr-parser'\nimport { ExprReader } from './expr-reader'\n\nexport class EquationReader extends ModelVisitor {\n constructor() {\n super()\n }\n\n /**\n * Parse the given Vensim equation definition and return an `Equation` AST node.\n *\n * @public\n * @param {string} equationText A string containing the Vensim equation definition.\n * @return {import('../../ast/ast-types').Equation} An `Equation` AST node.\n */\n /*public*/ parse(equationText /*: string*/) /*: Equation*/ {\n const parser = createAntlrParser(equationText)\n const equationCtx = parser.equation()\n return this.visitEquation(equationCtx)\n }\n\n /**\n * Process the given ANTLR `EquationContext` from an already parsed Vensim\n * equation definition.\n *\n * @public\n * @param {import('antlr4-vensim').EquationContext} ctx The ANTLR `EquationContext`.\n * @returns {import('../../ast/ast-types').Equation} An `Equation` AST node.\n */\n /*public*/ visitEquation(ctx /*: EquationContext*/) /*: Equation*/ {\n this.equationLhs = undefined\n this.lookupDef = undefined\n\n ctx.lhs().accept(this)\n\n let equationRhs\n const exprCtx = ctx.expr()\n if (exprCtx) {\n const exprReader = new ExprReader()\n const expr = exprReader.visitExpr(exprCtx)\n equationRhs = {\n kind: 'expr',\n expr\n }\n } else if (ctx.constList()) {\n ctx.constList().accept(this)\n equationRhs = {\n kind: 'const-list',\n constants: this.constants,\n text: this.constListText\n }\n } else if (ctx.lookup()) {\n ctx.lookup().accept(this)\n equationRhs = {\n kind: 'lookup',\n lookupDef: this.lookupDef\n }\n } else {\n equationRhs = {\n kind: 'data'\n }\n }\n\n if (this.equationLhs) {\n this.equation = {\n lhs: this.equationLhs,\n rhs: equationRhs,\n // TODO: For now, fill in an empty string for these two; this is mainly\n // for compatibility with unit tests that expect empty string instead of\n // undefined, but this should be revisited\n units: '',\n comment: ''\n }\n }\n\n return this.equation\n }\n\n visitSubscriptList(ctx) {\n // Get the subscripts found in the var name\n if (this.subscripts === undefined) {\n // These are the primary subscripts\n this.subscripts = ctx.Id().map(id => id.getText())\n } else {\n // These are subscripts that follow the :EXCEPT: keyword. Note that there\n // can be more than one set of subscripts following :EXCEPT:, so we need\n // to keep an array\n if (this.exceptSubscriptSets === undefined) {\n this.exceptSubscriptSets = []\n }\n this.exceptSubscriptSets.push(ctx.Id().map(id => id.getText()))\n }\n }\n\n visitLhs(ctx) {\n // Process the variable name\n const lhsVarName = ctx.Id().getText()\n const lhsVarId = canonicalName(lhsVarName)\n\n // Process any subscripts that follow the variable name\n super.visitLhs(ctx)\n const subscriptNames = this.subscripts\n const subscriptRefs = subscriptNames?.map(name => {\n return {\n subName: name,\n subId: canonicalName(name)\n }\n })\n\n // Process additional sets of subscripts that follow the :EXCEPT: keyword\n const exceptSubscriptSets = this.exceptSubscriptSets\n const exceptSubscriptRefSets = exceptSubscriptSets?.map(subscriptSet => {\n return subscriptSet.map(name => {\n return {\n subName: name,\n subId: canonicalName(name)\n }\n })\n })\n this.subscripts = undefined\n this.exceptSubscripts = undefined\n\n this.equationLhs = {\n varDef: {\n kind: 'variable-def',\n varName: lhsVarName,\n varId: lhsVarId,\n subscriptRefs,\n exceptSubscriptRefSets\n }\n }\n }\n\n //\n // CONST LISTS\n //\n\n visitConstList(ctx) {\n // TODO: It would be better if resolved to a `NumberLiteral[][]` (one array per dimension) to\n // better match how it appears in a model, but the antlr4-vensim grammar currently flattens\n // them into a single list (it doesn't make use of the semicolon separator), so we have to\n // do the same for now\n this.constants = ctx.expr().map(expr => {\n const text = expr.getText()\n const value = parseFloat(text)\n return {\n kind: 'number',\n value,\n text\n }\n })\n this.constListText = ctx.getText()\n }\n\n //\n // LOOKUPS\n //\n\n getPoint(lookupPoint) {\n const exprs = lookupPoint.expr()\n if (exprs.length >= 2) {\n return [parseFloat(exprs[0].getText()), parseFloat(exprs[1].getText())]\n }\n }\n\n visitLookup(ctx) {\n this.lookupRange = undefined\n this.lookupPoints = undefined\n\n if (ctx.lookupRange()) {\n ctx.lookupRange().accept(this)\n }\n if (ctx.lookupPointList()) {\n ctx.lookupPointList().accept(this)\n }\n\n let range\n if (this.lookupRange && this.lookupRange.length === 2) {\n range = {\n min: this.lookupRange[0],\n max: this.lookupRange[1]\n }\n }\n this.lookupDef = {\n kind: 'lookup-def',\n range,\n points: this.lookupPoints\n }\n }\n\n visitLookupRange(ctx) {\n this.lookupRange = ctx.lookupPoint().map(p => this.getPoint(p))\n super.visitLookupRange(ctx)\n }\n\n visitLookupPointList(ctx) {\n this.lookupPoints = ctx.lookupPoint().map(p => this.getPoint(p))\n super.visitLookupPointList(ctx)\n }\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport type { Equation } from '../ast/ast-types'\nimport { EquationReader } from './impl/equation-reader'\n\n/**\n * Parse the given Vensim equation definition and return an `Equation` AST node.\n *\n * @param input A string containing the Vensim equation definition.\n * @returns An `Equation` AST node.\n */\nexport function parseVensimEquation(input: string): Equation {\n // TODO: Reuse reader instance?\n const equationReader = new EquationReader()\n return equationReader.parse(input)\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport split from 'split-string'\n\n/**\n * A single Vensim definition (either a subscript range definition or an\n * equation definition). This contains the definition's text and metadata\n * that was extracted during preprocessing.\n */\nexport interface VensimDef {\n /**\n * A simplified key for the LHS of the definition, used for sorting\n * and/or flattening.\n */\n key: string\n /**\n * The preprocessed equation or subscript range definition (with\n * units and comment replaced with `~~|`).\n */\n def: string\n /**\n * The (1-based) line number where the definition begins.\n */\n line: number\n /**\n * The units text.\n */\n units: string\n /**\n * The comment text.\n */\n comment: string\n /**\n * The optional group name, if the definition is contained within a group.\n */\n group?: string\n}\n\n/**\n * A raw definition extracted during preprocessing. This may or may not\n * contain an actual definition (for example, it might contain a section\n * comment).\n */\ninterface RawDef {\n /**\n * The text of the raw definition.\n */\n text: string\n /**\n * The (1-based) line number where the definition begins.\n */\n line: number\n /**\n * The group in which the definition is contained (can be undefined if\n * the definition is not inside a group).\n */\n group?: string\n}\n\n/**\n * Process the given Vensim model content so that it can be parsed\n * by `antlr4-vensim`. This will:\n * - strip out group markers\n * - remove everything in the private Vensim sketch section\n * - join lines that are separated by a continuation (backslash)\n * - split the input into distinct definitions (equations and\n * subscript ranges)\n *\n * The definitions are further processed to preserve the units and\n * comment text in separate properties, but strips them from the\n * equation string (replaced with `~~`) to make it easier for\n * `antlr4-vensim` to process.\n *\n * @param input The original Vensim mdl file content.\n * @return An array of preprocessed Vensim definitions.\n */\nexport function preprocessVensimModel(input: string): VensimDef[] {\n // Split the model into an array of definitions (includes equations,\n // subscript ranges, and groups)\n const rawDefs = splitDefs(input)\n\n // Keep only equations and subscript range defintions\n const vensimDefs: VensimDef[] = []\n for (const rawDef of rawDefs) {\n // Process the definition\n const vensimDef = processDef(rawDef)\n if (vensimDef) {\n vensimDefs.push(vensimDef)\n }\n }\n return vensimDefs\n}\n\n/**\n * Split a Vensim model string into an array of definitions (including\n * equations, subscript ranges, and groups), without the \"|\" terminator.\n * This will allow \"|\" to occur in quoted variable names across line breaks.\n * Backslash characters will be retained.\n */\nfunction splitDefs(input: string): RawDef[] {\n // Split the full input string into definitions delineated by the \"|\" separator\n const defTexts = split(input, { separator: '|', quotes: ['\"'], keep: () => true })\n\n // Calculate starting line number for each definition by accounting for the\n // number of line breaks in that definition\n const rawDefs = []\n let lineNum = 1\n let currentGroup: string\n for (let defText of defTexts) {\n if (lineNum === 1) {\n // Strip the encoding (included in first def)\n defText = defText.replace('{UTF-8}', '')\n }\n\n if (defText.includes('\\\\---/// Sketch')) {\n // Skip everything starting with the first sketch section\n break\n }\n\n // Split on the first non-whitespace character\n const parts = defText.match(/(\\s*)(.*)/ms)\n\n // Take leading line breaks into account so that we find the line where the\n // actual definition begins\n const leadingLineBreaks = parts[1]?.match(/\\r\\n|\\n|\\r/gm)\n lineNum += leadingLineBreaks?.length || 0\n\n // See if this is a group header\n if (defText.includes('********************************************************')) {\n // This is a group; save the group name\n const groupLines = splitLines(defText).filter(s => s.trim().length > 0)\n currentGroup = undefined\n if (groupLines.length > 1) {\n const groupNameLine = groupLines[1]\n const groupNameParts = groupNameLine.match(/^\\s*\\.(.*)$/)\n if (groupNameParts) {\n currentGroup = groupNameParts[1]\n }\n }\n } else {\n // This is a regular definition; add it\n rawDefs.push({\n text: defText,\n line: lineNum,\n group: currentGroup\n })\n }\n\n // Increment by the number of line breaks that appear in the definition content\n const contentLineBreaks = parts[2]?.match(/\\r\\n|\\n|\\r/gm)\n lineNum += contentLineBreaks?.length || 0\n }\n\n return rawDefs\n}\n\n/**\n * Split a string into separate lines.\n */\nfunction splitLines(input: string): string[] {\n // Windows, Unix, or old Mac line endings\n return input.split(/\\r\\n|\\n|\\r/)\n}\n\n/**\n * Join lines that are separated by a continuation (backslash) character.\n */\nfunction processBackslashes(input: string): string {\n const inputLines = splitLines(input)\n\n let output = ''\n let prevLine = ''\n for (let line of inputLines) {\n // Join a previous line with a backslash ending to the current line\n if (prevLine !== '') {\n line = prevLine + line.trim()\n prevLine = ''\n }\n const continuation = line.match(/\\\\\\s*$/)\n if (continuation) {\n // If there is a backslash ending on this line, save it without the backslash\n prevLine = line.substr(0, continuation.index).replace(/\\s+$/, ' ')\n } else {\n // There is no continuation on this line, include in output\n output += line + '\\n'\n }\n }\n\n return output\n}\n\n/**\n * Match delimiters recursively. Replace delimited strings globally.\n *\n * @param str The string to operate on.\n * @param open The opening delimiter characters.\n * @param close The closing delimiter characters.\n * @param newStr The string to replace delimited substrings with.\n */\nfunction replaceDelimitedStrings(str: string, open: string, close: string, newStr: string): string {\n let result = ''\n let start = 0\n let depth = 0\n const n = str.length\n for (let i = 0; i < n; i++) {\n if (str.charAt(i) === open) {\n if (depth === 0) {\n result += str.substring(start, i)\n }\n depth++\n } else if (str.charAt(i) === close && depth > 0) {\n depth--\n if (depth === 0) {\n result += newStr\n start = i + 1\n }\n }\n }\n if (start < n) {\n result += str.substring(start)\n }\n return result\n}\n\n/**\n * Replace all newlines and redundant whitespace into single spaces so\n * that everything is on a single line.\n */\nfunction reduceWhitespace(input: string): string {\n return input.replace(/\\s\\s+/g, ' ').trim()\n}\n\n/**\n * Create a key from the given definition's LHS that can be used during\n * flattening and/or sorting.\n */\nfunction keyForDef(def: string): string {\n // Note: The steps in this function were lifted directly from the legacy\n // preprocessor, mainly so that we would retain compatibility when writing\n // tests that compare the legacy parser to the new one.\n\n let key = def\n\n // Strip the \":INTERPOLATE:\"; it should not be included in the key\n key = key.replace(/:INTERPOLATE:/g, '')\n\n if (key.includes('=')) {\n // The line contains an '='; treat this as an equation\n // kind = 'eqn'\n key = key.split('=')[0].trim()\n } else if (key.includes(':')) {\n // The line contains a ':'; treat this as an subscript declaration\n // kind = 'sub'\n key = key.split(':')[0].trim()\n } else {\n // Treat this as a general declaration\n // kind = 'decl'\n }\n\n // Ignore double quotes\n key = key.replace(/\"/g, '')\n\n // Ignore the lookup data if it starts on the first line\n key = key.split('(')[0]\n\n // Ignore any whitespace that remains\n key = key.trim()\n\n // Remove whitespace on the inside of the brackets\n key = key.replace(/\\[\\s*/g, '[')\n key = key.replace(/\\s*\\]/g, ']')\n\n // Ignore case\n key = key.toLowerCase()\n\n return key\n}\n\n/**\n * Strip out unnecessary parts of the given raw definition string and\n * return a `VensimDef` containing the processed definition along with\n * the units and comment strings.\n */\nfunction processDef(rawDef: RawDef): VensimDef | undefined {\n let input = rawDef.text\n\n // Remove \":RAW:\" flag; it is not needed by SDE and causes problems if left in\n input = input.replace(/:RAW:/g, '')\n\n // Remove inline comments\n input = replaceDelimitedStrings(input, '{', '}', '')\n\n // Remove whitespace\n input = input.trim()\n\n // Skip empty definitions\n if (input.length === 0) {\n return undefined\n }\n\n // Join lines that are separated by a continuation (backslash) character\n input = processBackslashes(input)\n\n // Split on the comment delimiters\n const parts = input.split('~')\n\n // If the definition is malformed, throw an error\n if (parts.length < 3) {\n throw new Error(`Found invalid model definition during preprocessing (missing comment delimiters?):\\n\\n${input}`)\n }\n\n // Get the raw def as a single line\n const rawDefText = reduceWhitespace(parts[0])\n\n // Create the key\n const key = keyForDef(rawDefText)\n\n // Rebuild the def with a simple `~~|` ending\n const def = `${rawDefText} ~~|`\n\n // Extract the units text\n const units = reduceWhitespace(parts[1])\n\n // Extract the comment text\n // TODO: Preserve newlines in comments?\n const comment = reduceWhitespace(parts[2])\n\n // TODO: Extract the `:SUPPLEMENTARY:` flags?\n\n // Preserve the group name, if defined\n const group = rawDef.group\n\n return {\n key,\n def,\n line: rawDef.line,\n units,\n comment,\n ...(group ? { group } : {})\n }\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport { ModelVisitor } from 'antlr4-vensim'\n\nimport { createAntlrParser } from './antlr-parser'\nimport { EquationReader } from './equation-reader'\nimport { SubscriptRangeReader } from './subscript-range-reader'\n\nexport class ModelReader extends ModelVisitor {\n /**\n * @public\n * @param {import('../vensim-parse-context').VensimParseContext} parseContext An object\n * that provides access to file system resources (such as external data files) that are\n * referenced during the parse phase.\n */\n constructor(parseContext /*: VensimParseContext*/) {\n super()\n this.parseContext = parseContext\n this.dimensions = []\n this.equations = []\n }\n\n /**\n * Parse the given Vensim model definition and return a `Model` AST node.\n *\n * @public\n * @param {string} modelText A string containing the Vensim model.\n * @returns {import('../../ast/ast-types').Model} A `Model` AST node.\n */\n /*public*/ parse(modelText /*: string*/) /*: Model*/ {\n const parser = createAntlrParser(modelText)\n const modelCtx = parser.model()\n modelCtx.accept(this)\n return this.model\n }\n\n visitModel(ctx) {\n const subscriptRangesCtx = ctx.subscriptRange()\n if (subscriptRangesCtx) {\n // TODO: Can we reuse reader instances?\n const subscriptReader = new SubscriptRangeReader(this.parseContext)\n for (const subscriptRangeCtx of subscriptRangesCtx) {\n const dimensionDef = subscriptReader.visitSubscriptRange(subscriptRangeCtx)\n this.dimensions.push(dimensionDef)\n }\n }\n\n const equationsCtx = ctx.equation()\n if (equationsCtx) {\n // TODO: Can we reuse reader instances?\n const equationReader = new EquationReader()\n for (const equationCtx of equationsCtx) {\n const equation = equationReader.visitEquation(equationCtx)\n this.equations.push(equation)\n }\n }\n\n this.model = {\n dimensions: this.dimensions,\n equations: this.equations\n }\n }\n}\n","// Copyright (c) 2023 Climate Interactive / New Venture Fund\n\nimport type { DimensionDef, Equation, Model } from '../ast/ast-types'\nimport { preprocessVensimModel } from './preprocess-vensim'\nimport type { VensimParseContext } from './vensim-parse-context'\nimport { ModelReader } from './impl/model-reader'\n\n/**\n * Parse the given Vensim model definition and return a `Model` AST node.\n *\n * @param input A string containing the Vensim model.\n * @param context An object that provides access to file system resources (such as\n * external data files) that are referenced during the parse phase.\n * @param sort Whether to sort definitions alphabetically during the preprocessing phase.\n * @returns A `Model` AST node.\n */\nexport function parseVensimModel(input: string, context?: VensimParseContext, sort = false): Model {\n const dimensions: DimensionDef[] = []\n const equations: Equation[] = []\n\n // Run the preprocessor on the input (to separate out units, comments, unsupported\n // sections, etc) so that it can be parsed more easily by `antlr4-vensim`.\n const defs = preprocessVensimModel(input)\n if (sort) {\n // XXX: This sorting is currently only needed for compatibility with the legacy\n // preprocessor, which sorted definitions alphabetically. Can consider removing this.\n defs.sort((a, b) => {\n return a.key < b.key ? -1 : a.key > b.key ? 1 : 0\n })\n }\n\n // Parse each subscript range or equation definition\n for (const def of defs) {\n // TODO: Reuse reader instance?\n let parsedModel: Model\n try {\n const modelReader = new ModelReader(context)\n parsedModel = modelReader.parse(def.def)\n } catch (e) {\n // Include context such as line/column numbers in the error message if available\n let linePart = ''\n if (e.cause?.code === 'VensimParseError') {\n if (e.cause.line) {\n // The line number reported by ANTLR is relative to the beginning of the\n // preprocessed definition (since we parse each definition individually),\n // so we need to add it to the line of the definition in the original source\n linePart += ` at line ${e.cause.line - 1 + def.line}`\n if (e.cause.column) {\n linePart += `, col ${e.cause.column}`\n }\n }\n }\n const msg = `Failed to parse Vensim model definition${linePart}:\\n${def.def}\\n\\nDetail:\\n ${e.message}`\n throw new Error(msg)\n }\n\n for (const dimensionDef of parsedModel.dimensions) {\n // Fold in the other strings that were extracted during preprocessing\n const group = def.group\n dimensions.push({\n ...dimensionDef,\n comment: def.comment,\n ...(group ? { group } : {})\n })\n }\n\n for (const equation of parsedModel.equations) {\n // Fold in the other strings that were extracted during preprocessing\n const group = def.group\n equations.push({\n ...equation,\n units: def.units,\n comment: def.comment,\n ...(group ? { group } : {})\n })\n }\n }\n\n return {\n dimensions,\n equations\n }\n}\n"],"mappings":"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","names":["import_assert_never","num","import_antlr4_vensim","antlr4","import_antlr4_vensim","import_antlr4_vensim","split","import_antlr4_vensim"]}