(name: string)
| 230 | } |
| 231 | |
| 232 | private parseStepsCall(name: string): ExprNode { |
| 233 | const args: ExprNode[] = []; |
| 234 | this.skipWhitespace(); |
| 235 | if (this.consumeIf(")")) { |
| 236 | this.fail('steps() requires at least one "threshold: value" pair'); |
| 237 | } |
| 238 | |
| 239 | args.push(this.parseExpr()); |
| 240 | let pairCount = 0; |
| 241 | |
| 242 | while (true) { |
| 243 | this.skipWhitespace(); |
| 244 | if (!this.consumeIf(",")) break; |
| 245 | this.skipWhitespace(); |
| 246 | const threshold = this.parseStepThreshold(); |
| 247 | this.skipWhitespace(); |
| 248 | if (!this.consumeIf(":")) { |
| 249 | this.fail('Expected ":" in steps() threshold:value pair'); |
| 250 | } |
| 251 | const valueExpr = this.parseExpr(); |
| 252 | args.push({ kind: "number", value: threshold }, valueExpr); |
| 253 | pairCount++; |
| 254 | } |
| 255 | |
| 256 | this.skipWhitespace(); |
| 257 | if (!this.consumeIf(")")) this.fail('Expected ")" after steps()'); |
| 258 | if (pairCount === 0) { |
| 259 | this.fail('steps() requires at least one "threshold: value" pair'); |
| 260 | } |
| 261 | return { kind: "call", name, args: Object.freeze(args) }; |
| 262 | } |
| 263 | |
| 264 | private parseStepThreshold(): number { |
| 265 | const token = this.parseNumberNode(); |
no test coverage detected