Пример #1
0
        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
            });
        }
Пример #2
0
        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
            });
        }