예제 #1
0
        private void ApplyRuleForBranch(ref bool appliedRule, Core.SegmentFlowBranch flow)
        {
            var destType = Core.TypeStruct.Of(session.PrimitiveBool);
            var srcType  = TypeResolver.GetDataAccessType(session, funct, flow.conditionReg);

            var inferredSrc = TypeInferencer.Try(session, destType, ref srcType);

            if (inferredSrc)
            {
                appliedRule = ApplyToDataAccess(flow.conditionReg, destType);
            }
        }
예제 #2
0
        private void ResolveExprIf(Grammar.ASTNodeExprIf exprIf, ref int curSegment, Core.DataAccess output)
        {
            // Parse condition.
            var conditionReg = Core.DataAccessRegister.ForRegister(
                exprIf.conditionExpr.GetSpan(),
                funct.CreateRegister(Core.TypeStruct.Of(session.PrimitiveBool), false));

            this.ResolveExpr(
                exprIf.conditionExpr,
                ref curSegment,
                conditionReg);

            var flowBranch = new Core.SegmentFlowBranch {
                conditionReg = conditionReg
            };

            funct.SetSegmentFlow(curSegment, flowBranch);

            // Parse true branch.
            var trueSegment = funct.CreateSegment(exprIf.trueBranchExpr.GetSpan().JustBefore());

            flowBranch.destinationSegmentIfTaken = trueSegment;

            ResolveExpr(exprIf.trueBranchExpr, ref trueSegment, output);

            // Parse false branch, if there is one.
            if (exprIf.falseBranchExpr != null)
            {
                var falseSegment = funct.CreateSegment(exprIf.falseBranchExpr.GetSpan().JustBefore());
                flowBranch.destinationSegmentIfNotTaken = falseSegment;

                ResolveExpr(exprIf.falseBranchExpr, ref falseSegment, output);

                var afterSegment = funct.CreateSegment(exprIf.GetSpan().JustAfter());
                funct.SetSegmentFlow(trueSegment, Core.SegmentFlowGoto.To(afterSegment));
                funct.SetSegmentFlow(falseSegment, Core.SegmentFlowGoto.To(afterSegment));
                curSegment = afterSegment;
            }
            // Or else, just route the false segment path to the next segment.
            else
            {
                var afterSegment = funct.CreateSegment(exprIf.GetSpan().JustAfter());
                funct.SetSegmentFlow(trueSegment, Core.SegmentFlowGoto.To(afterSegment));
                flowBranch.destinationSegmentIfNotTaken = afterSegment;
                curSegment = afterSegment;
            }
        }
예제 #3
0
        private void ResolveExprWhile(Grammar.ASTNodeExprWhile exprWhile, ref int curSegment, Core.DataAccess output)
        {
            var registerIndexBefore = funct.registerTypes.Count;

            var conditionSegment = funct.CreateSegment(exprWhile.conditionExpr.GetSpan());

            funct.SetSegmentFlow(curSegment, Core.SegmentFlowGoto.To(conditionSegment));

            // Parse condition.
            var conditionReg = Core.DataAccessRegister.ForRegister(
                exprWhile.conditionExpr.GetSpan(),
                funct.CreateRegister(Core.TypeStruct.Of(session.PrimitiveBool), false));

            this.ResolveExpr(
                exprWhile.conditionExpr,
                ref conditionSegment,
                conditionReg);

            var flowBranch = new Core.SegmentFlowBranch {
                conditionReg = conditionReg
            };

            funct.SetSegmentFlow(conditionSegment, flowBranch);

            // Parse body.
            var bodySegment = funct.CreateSegment(exprWhile.bodyExpr.GetSpan().JustBefore());

            flowBranch.destinationSegmentIfTaken = bodySegment;

            ResolveExpr(exprWhile.bodyExpr, ref bodySegment, output);

            // Deinit inner registers.
            for (var i = funct.registerTypes.Count - 1; i >= registerIndexBefore; i--)
            {
                funct.AddInstruction(bodySegment, Core.InstructionDeinit.ForRegister(i));
            }

            // Route segments.
            var afterSegment = funct.CreateSegment(exprWhile.GetSpan().JustAfter());

            funct.SetSegmentFlow(bodySegment, Core.SegmentFlowGoto.To(conditionSegment));
            flowBranch.destinationSegmentIfNotTaken = afterSegment;
            curSegment = afterSegment;
        }
예제 #4
0
        private void CheckBranch(Core.SegmentFlowBranch flow)
        {
            if (!TypeResolver.ValidateDataAccess(this.session, this.funct, flow.conditionReg))
            {
                this.foundErrors = true;
                return;
            }

            var destType = Core.TypeStruct.Of(session.PrimitiveBool);
            var srcType  = TypeResolver.GetDataAccessType(this.session, this.funct, flow.conditionReg);

            if (!srcType.IsConvertibleTo(destType) &&
                ShouldDiagnose(srcType))
            {
                this.foundErrors = true;
                this.session.AddMessage(
                    Diagnostics.MessageKind.Error,
                    Diagnostics.MessageCode.IncompatibleTypes,
                    "using '" + srcType.GetString(this.session) + "' as condition",
                    flow.conditionReg.span);
            }
        }
예제 #5
0
        private void ResolveExprWhile(Grammar.ASTNodeExprWhile exprWhile, ref int curSegment, Core.DataAccess output)
        {
            var registerIndexBefore = funct.registerTypes.Count;

            var conditionSegment = funct.CreateSegment(exprWhile.conditionExpr.GetSpan());
            funct.SetSegmentFlow(curSegment, Core.SegmentFlowGoto.To(conditionSegment));

            // Parse condition.
            var conditionReg = Core.DataAccessRegister.ForRegister(
                exprWhile.conditionExpr.GetSpan(),
                funct.CreateRegister(Core.TypeStruct.Of(session.PrimitiveBool), false));

            this.ResolveExpr(
                exprWhile.conditionExpr,
                ref conditionSegment,
                conditionReg);

            var flowBranch = new Core.SegmentFlowBranch { conditionReg = conditionReg };
            funct.SetSegmentFlow(conditionSegment, flowBranch);

            // Parse body.
            var bodySegment = funct.CreateSegment(exprWhile.bodyExpr.GetSpan().JustBefore());
            flowBranch.destinationSegmentIfTaken = bodySegment;

            ResolveExpr(exprWhile.bodyExpr, ref bodySegment, output);

            // Deinit inner registers.
            for (var i = funct.registerTypes.Count - 1; i >= registerIndexBefore; i--)
                funct.AddInstruction(bodySegment, Core.InstructionDeinit.ForRegister(i));

            // Route segments.
            var afterSegment = funct.CreateSegment(exprWhile.GetSpan().JustAfter());
            funct.SetSegmentFlow(bodySegment, Core.SegmentFlowGoto.To(conditionSegment));
            flowBranch.destinationSegmentIfNotTaken = afterSegment;
            curSegment = afterSegment;
        }
예제 #6
0
        private void ResolveExprIf(Grammar.ASTNodeExprIf exprIf, ref int curSegment, Core.DataAccess output)
        {
            // Parse condition.
            var conditionReg = Core.DataAccessRegister.ForRegister(
                exprIf.conditionExpr.GetSpan(),
                funct.CreateRegister(Core.TypeStruct.Of(session.PrimitiveBool), false));

            this.ResolveExpr(
                exprIf.conditionExpr,
                ref curSegment,
                conditionReg);

            var flowBranch = new Core.SegmentFlowBranch { conditionReg = conditionReg };
            funct.SetSegmentFlow(curSegment, flowBranch);

            // Parse true branch.
            var trueSegment = funct.CreateSegment(exprIf.trueBranchExpr.GetSpan().JustBefore());
            flowBranch.destinationSegmentIfTaken = trueSegment;

            ResolveExpr(exprIf.trueBranchExpr, ref trueSegment, output);

            // Parse false branch, if there is one.
            if (exprIf.falseBranchExpr != null)
            {
                var falseSegment = funct.CreateSegment(exprIf.falseBranchExpr.GetSpan().JustBefore());
                flowBranch.destinationSegmentIfNotTaken = falseSegment;

                ResolveExpr(exprIf.falseBranchExpr, ref falseSegment, output);

                var afterSegment = funct.CreateSegment(exprIf.GetSpan().JustAfter());
                funct.SetSegmentFlow(trueSegment, Core.SegmentFlowGoto.To(afterSegment));
                funct.SetSegmentFlow(falseSegment, Core.SegmentFlowGoto.To(afterSegment));
                curSegment = afterSegment;
            }
            // Or else, just route the false segment path to the next segment.
            else
            {
                var afterSegment = funct.CreateSegment(exprIf.GetSpan().JustAfter());
                funct.SetSegmentFlow(trueSegment, Core.SegmentFlowGoto.To(afterSegment));
                flowBranch.destinationSegmentIfNotTaken = afterSegment;
                curSegment = afterSegment;
            }
        }
예제 #7
0
 private void CheckBranch(List <InitStatus> statusList, Core.SegmentFlowBranch flow)
 {
     ValidateSource(statusList, flow.conditionReg);
 }