private void PropagateRuleTypes(IRRule rule, IRBinaryCondition condition) { if (condition.LValue.Type == null && condition.LValue is IRVariable) { var lval = condition.LValue as IRVariable; var ruleVariable = rule.Variables[lval.Index]; if (ruleVariable.Type != null) { lval.Type = ruleVariable.Type; } } if (condition.RValue.Type == null && condition.RValue is IRVariable) { var rval = condition.RValue as IRVariable; var ruleVariable = rule.Variables[rval.Index]; if (ruleVariable.Type != null) { rval.Type = ruleVariable.Type; } } // TODO - handle implicit re-typing of rule variables? }
private bool PropagateRuleTypes(IRRule rule, IRBinaryCondition condition) { bool updated = false; if (condition.LValue.Type == null && condition.LValue is IRVariable) { var lval = condition.LValue as IRVariable; var ruleVariable = rule.Variables[lval.Index]; if (ruleVariable.Type != null) { lval.Type = ruleVariable.Type; updated = true; } } if (condition.RValue.Type == null && condition.RValue is IRVariable) { var rval = condition.RValue as IRVariable; var ruleVariable = rule.Variables[rval.Index]; if (ruleVariable.Type != null) { rval.Type = ruleVariable.Type; updated = true; } } // TODO - handle implicit re-typing of rule variables? return(updated); }
private UInt32 ComputeTupleSize(IRRule rule, IRBinaryCondition condition, UInt32 lastTupleSize) { UInt32 tupleSize = lastTupleSize; if (condition.LValue is IRVariable) { var variable = condition.LValue as IRVariable; if (variable.Index >= tupleSize) { tupleSize = (UInt32)variable.Index + 1; } } if (condition.RValue is IRVariable) { var variable = condition.RValue as IRVariable; if (variable.Index >= tupleSize) { tupleSize = (UInt32)variable.Index + 1; } } return tupleSize; }
private void VerifyIRBinaryCondition(IRRule rule, IRBinaryCondition condition, Int32 conditionIndex) { ValueType lhs = condition.LValue.Type, rhs = condition.RValue.Type; // Don't raise compiler errors if the untyped value is a variable, // as we already have a separate rule-level error for untyped variables. if ((lhs == null && condition.LValue is IRVariable) || (rhs == null && condition.RValue is IRVariable)) { return; } if (condition.LValue is IRVariable && condition.RValue is IRVariable && (condition.LValue as IRVariable).Index == (condition.RValue as IRVariable).Index // This bug was fixed in DOS2 DE && Game == TargetGame.DOS2 // There is a known bug in the main campaign that we have to ignore && rule.Goal.Name != "EndGame_PrisonersDilemma") { Context.Log.Error(condition.Location, DiagnosticCode.BinaryOperationSameRhsLhs, "Same variable used on both sides of a binary expression; this will result in an invalid compare in runtime"); return; } VerifyIRBinaryConditionValue(rule, condition.LValue, conditionIndex); VerifyIRBinaryConditionValue(rule, condition.RValue, conditionIndex); if (!AreIntrinsicTypesCompatible(lhs.IntrinsicTypeId, rhs.IntrinsicTypeId)) { Context.Log.Error(condition.Location, DiagnosticCode.LocalTypeMismatch, "Type of left expression ({0}) differs from type of right expression ({1})", TypeToName(lhs.IntrinsicTypeId), TypeToName(rhs.IntrinsicTypeId)); return; } if (IsRiskyComparison(lhs.IntrinsicTypeId, rhs.IntrinsicTypeId)) { Context.Log.Error(condition.Location, DiagnosticCode.RiskyComparison, "Comparison between {0} and {1} may trigger incorrect behavior", TypeToName(lhs.IntrinsicTypeId), TypeToName(rhs.IntrinsicTypeId)); return; } if (IsGuidAliasToAliasCast(lhs, rhs)) { Context.Log.Error(condition.Location, DiagnosticCode.GuidAliasMismatch, "GUID alias type of left expression ({0}) differs from type of right expression ({1})", TypeToName(lhs.TypeId), TypeToName(rhs.TypeId)); return; } // Using greater than/less than operators for strings and GUIDs is probably a mistake. if ((lhs.IntrinsicTypeId == Value.Type.String || lhs.IntrinsicTypeId == Value.Type.GuidString) && (condition.Op == RelOpType.Greater || condition.Op == RelOpType.GreaterOrEqual || condition.Op == RelOpType.Less || condition.Op == RelOpType.LessOrEqual)) { Context.Log.Warn(condition.Location, DiagnosticCode.StringLtGtComparison, "String comparison using operator {0} - probably a mistake?", condition.Op); return; } }