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); } }
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; } }
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; }
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); } }
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; }
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; } }
private void CheckBranch(List <InitStatus> statusList, Core.SegmentFlowBranch flow) { ValidateSource(statusList, flow.conditionReg); }