(node: Ast.Node, scope: Scope, callStack: readonly CallInfo[])
| 472 | |
| 473 | @autobind |
| 474 | private async __eval(node: Ast.Node, scope: Scope, callStack: readonly CallInfo[]): Promise<Value | Control> { |
| 475 | if (this.stop) return NULL; |
| 476 | if (this.pausing) await this.pausing.promise; |
| 477 | // irqRateが小数の場合は不等間隔になる |
| 478 | if (this.irqRate !== 0 && this.stepCount % this.irqRate >= this.irqRate - 1) { |
| 479 | await this.irqSleep(); |
| 480 | } |
| 481 | this.stepCount++; |
| 482 | if (this.opts.maxStep && this.stepCount > this.opts.maxStep) { |
| 483 | throw new AiScriptRuntimeError('max step exceeded'); |
| 484 | } |
| 485 | |
| 486 | switch (node.type) { |
| 487 | case 'call': { |
| 488 | const callee = await this._eval(node.target, scope, callStack); |
| 489 | if (isControl(callee)) { |
| 490 | return callee; |
| 491 | } |
| 492 | assertFunction(callee); |
| 493 | const args = []; |
| 494 | for (const expr of node.args) { |
| 495 | const arg = await this._eval(expr, scope, callStack); |
| 496 | if (isControl(arg)) { |
| 497 | return arg; |
| 498 | } |
| 499 | args.push(arg); |
| 500 | } |
| 501 | return this._fn(callee, args, callStack, node.loc.start); |
| 502 | } |
| 503 | |
| 504 | case 'if': { |
| 505 | const cond = await this._eval(node.cond, scope, callStack); |
| 506 | if (isControl(cond)) { |
| 507 | return cond; |
| 508 | } |
| 509 | assertBoolean(cond); |
| 510 | if (cond.value) { |
| 511 | return unWrapLabeledBreak(await this._evalClause(node.then, scope, callStack), node.label); |
| 512 | } |
| 513 | for (const elseif of node.elseif) { |
| 514 | const cond = await this._eval(elseif.cond, scope, callStack); |
| 515 | if (isControl(cond)) { |
| 516 | return cond; |
| 517 | } |
| 518 | assertBoolean(cond); |
| 519 | if (cond.value) { |
| 520 | return unWrapLabeledBreak(await this._evalClause(elseif.then, scope, callStack), node.label); |
| 521 | } |
| 522 | } |
| 523 | if (node.else) { |
| 524 | return unWrapLabeledBreak(await this._evalClause(node.else, scope, callStack), node.label); |
| 525 | } |
| 526 | return NULL; |
| 527 | } |
| 528 | |
| 529 | case 'match': { |
| 530 | const about = await this._eval(node.about, scope, callStack); |
| 531 | if (isControl(about)) { |
no test coverage detected