Exemplo n.º 1
0
        private void ResolveExprIf(ref int segment, sema.Code.Lvalue destination, syn.Node.If node)
        {
            var conditionRegIndex = this.ResolveIntoNewRegister(
                ref segment, node.condition, new sema.Type.Structure {
                def = ctx.primitiveBool
            });

            var conditionLvalue = new sema.Code.Lvalue.Register {
                index = conditionRegIndex, span = node.condition.span
            };

            this.ResolveExpr(ref segment, conditionLvalue, node.condition);

            var branch = new sema.Code.Terminator.Branch {
                conditionRegisterIndex = conditionRegIndex
            };

            this.code.SetTerminator(segment, branch);

            var trueSegment = this.code.CreateSegment();

            branch.trueSegmentIndex = trueSegment;
            this.ResolveExpr(ref trueSegment, new sema.Code.Lvalue.Discard {
                span = node.trueBlock.span
            }, node.trueBlock);

            if (node.falseBlock != null)
            {
                var falseSegment = this.code.CreateSegment();
                branch.falseSegmentIndex = falseSegment;
                this.ResolveExpr(ref falseSegment, new sema.Code.Lvalue.Discard {
                    span = node.falseBlock.span
                }, node.falseBlock);
                var afterSegment = this.code.CreateSegment();
                this.code.SetTerminator(trueSegment, new sema.Code.Terminator.Goto {
                    segmentIndex = afterSegment
                });
                this.code.SetTerminator(falseSegment, new sema.Code.Terminator.Goto {
                    segmentIndex = afterSegment
                });
                segment = afterSegment;
            }
            else
            {
                var afterSegment = this.code.CreateSegment();
                branch.falseSegmentIndex = afterSegment;
                this.code.SetTerminator(trueSegment, new sema.Code.Terminator.Goto {
                    segmentIndex = afterSegment
                });
                segment = afterSegment;
            }

            this.AddVoidInstruction(segment, destination, node.span);
        }
Exemplo n.º 2
0
        private void ResolveExprWhile(ref int segment, sema.Code.Lvalue destination, syn.Node.While node)
        {
            var conditionSegment    = this.code.CreateSegment();
            var conditionSegmentEnd = conditionSegment;

            this.code.SetTerminator(segment, new sema.Code.Terminator.Goto {
                segmentIndex = conditionSegment
            });

            var conditionRegIndex = this.ResolveIntoNewRegister(
                ref conditionSegmentEnd, node.condition, new sema.Type.Structure {
                def = ctx.primitiveBool
            });

            var conditionLvalue = new sema.Code.Lvalue.Register {
                index = conditionRegIndex, span = node.condition.span
            };

            this.ResolveExpr(ref conditionSegmentEnd, conditionLvalue, node.condition);

            var branch = new sema.Code.Terminator.Branch {
                conditionRegisterIndex = conditionRegIndex
            };

            this.code.SetTerminator(conditionSegmentEnd, branch);

            var bodySegment  = this.code.CreateSegment();
            var afterSegment = this.code.CreateSegment();

            branch.trueSegmentIndex = bodySegment;

            this.breakSegments.Push(afterSegment);
            this.continueSegments.Push(conditionSegment);

            this.ResolveExpr(ref bodySegment, new sema.Code.Lvalue.Discard {
                span = node.block.span
            }, node.block);
            this.code.SetTerminator(bodySegment, new sema.Code.Terminator.Goto {
                segmentIndex = conditionSegment
            });

            this.breakSegments.Pop();
            this.continueSegments.Pop();

            branch.falseSegmentIndex = afterSegment;
            segment = afterSegment;

            this.AddVoidInstruction(segment, destination, node.span);
        }