protected override object?Visit(Expression.If iff) { base.Visit(iff); // Condition must be bool var conditionType = System.TypeOf(iff.Condition); if (!conditionType.Equals(Type.Bool)) { System.Report(new ExpectedTypeError(Type.Bool, conditionType) { Context = "if condition", Place = iff.Condition.ParseTreeNode, }); } // If there is an else branch, body types should match if (iff.Else != null) { var thenType = System.TypeOf(iff.Then); var elseType = System.TypeOf(iff.Else); if (!thenType.Equals(elseType)) { var thenRet = FindDeepestReturnValue(iff.Then)?.ParseTreeNode; var elseRet = FindDeepestReturnValue(iff.Else)?.ParseTreeNode; System.Report(new TypeMismatchError(thenType, elseType) { Context = "if expression", Defined = thenRet, Wrong = elseRet, }); } } return(null); }
public override Expression VisitEXPR_If([NotNull] S_ScriptParser.EXPR_IfContext context) { Expression x = this.Visit(context.expression()[0]); Expression y = this.Visit(context.expression()[1]); Expression z = (context.expression().Length == 2 ? null : this.Visit(context.expression()[2])); Expression if_func = new Expression.If(this._Host, this._Master); if_func.AddChild(x); if_func.AddChild(y); if_func.AddChild(z); this._Master = if_func; return(if_func); }
protected override Value?Visit(Expression.If iff) { if (iff.Else == null) { // No chance for a return value Builder.IfThen( condition: b => VisitNonNull(iff.Condition), then: b => Visit(iff.Then)); return(null); } else { var retType = TypeOf(iff); if (retType.Equals(Semantic.Types.Type.Unit)) { // There is no return value Builder.IfThenElse( condition: b => VisitNonNull(iff.Condition), then: b => Visit(iff.Then), @else: b => Visit(iff.Else)); return(null); } else { // There is a return value we need to take care of // First we allocate space for the return value var retSpace = Builder.Alloc(TranslateToLirType(retType)); // Compile it, storing the results in the respective blocks Builder.IfThenElse( condition: b => VisitNonNull(iff.Condition), then: b => { var result = VisitNonNull(iff.Then); b.Store(retSpace, result); }, @else: b => { var result = VisitNonNull(iff.Else); b.Store(retSpace, result); }); // Load up the result return(Builder.Load(retSpace)); } } }