private void CompileWhile(Node node) { var conditionIndex = this.CurrentIndex(); this.CompileExpr(node.children[0]); var branch = new Instruction.Branch { span = node.span }; this.Emit(branch); var prevContinues = this.continues; var prevBreaks = this.breaks; this.continues = new List <Instruction.Goto>(); this.breaks = new List <Instruction.Goto>(); var trueIndex = this.CurrentIndex(); this.CompileExpr(node.children[1]); this.Emit(new Instruction.Discard { span = node.children[1].span.JustAfter }); this.Emit(new Instruction.Goto { span = node.children[1].span.JustAfter, destination = conditionIndex }); var afterIndex = this.CurrentIndex(); branch.destinationIfTrue = trueIndex; branch.destinationIfFalse = afterIndex; foreach (var cont in this.continues) { cont.destination = conditionIndex; } foreach (var br in this.breaks) { br.destination = afterIndex; } this.continues = prevContinues; this.breaks = prevBreaks; this.Emit(new Instruction.PushLiteral { span = node.span.JustAfter, literal = null }); }
private void CompileIf(Node node) { this.CompileExpr(node.children[0]); var branch = new Instruction.Branch { span = node.span }; this.Emit(branch); var trueIndex = this.CurrentIndex(); this.CompileExpr(node.children[1]); this.Emit(new Instruction.Discard { span = node.children[1].span.JustAfter }); var gotoAfter = new Instruction.Goto { span = node.children[1].span.JustAfter }; this.Emit(gotoAfter); var afterIndex = this.CurrentIndex(); var falseIndex = afterIndex; if (node.children.Count == 3) { this.CompileExpr(node.children[2]); this.Emit(new Instruction.Discard { span = node.children[2].span.JustAfter }); afterIndex = this.CurrentIndex(); } branch.destinationIfTrue = trueIndex; branch.destinationIfFalse = falseIndex; gotoAfter.destination = afterIndex; this.Emit(new Instruction.PushLiteral { span = node.span.JustAfter, literal = null }); }