private void CreateOperator(TypesGroup left, TypesGroup right, TypesGroup result, string op, bool areRelatedUnits, NullableArguments nullableArguments, OperatorHints operatorHints) { var leftValue = left.Value.ValueTypeName; var rightValue = right.Value.ValueTypeName; if ((nullableArguments & NullableArguments.Left) != 0) { leftValue += "?"; } if ((nullableArguments & NullableArguments.Right) != 0) { rightValue += "?"; } var operatorGenerationKey = new OperatorGenerationKey(leftValue, rightValue, op); var tResult = result.Value; if (_done.TryGetValue(operatorGenerationKey, out var resultType)) { if (resultType != tResult.ValueTypeName) { throw new NotSupportedException(); } return; } _done[operatorGenerationKey] = tResult.ValueTypeName; var info = op == "/" ? OperatorInfo.Div : OperatorInfo.Mul; var leftName = info.Left.Name; var rightName = info.Right.Name; if (left.Value != right.Value) { leftName = left.Value.FirstLower(); rightName = right.Value.FirstLower(); } var cl = GetClass(operatorGenerationKey.GetOperatorTargetType()); cl.Kind = CsNamespaceMemberKind.Struct; // cw.WriteLine("// " + key + " " + areRelatedUnits); var rightFraction = FractionUnitDefs.IsFraction(right); var leftFraction = FractionUnitDefs.IsFraction(left); var rightUnit = "rightUnit"; var resultUnit = "resultUnit"; CsCodeWriter PrepareCode() { if (nullableArguments == NullableArguments.None) { var ppp = new OperatorParams(left, right, result, leftName, rightName, op, operatorHints); if (areRelatedUnits) { return(CreateCodeForRelatedUnits(ppp, ref rightUnit, ref resultUnit)); } if (leftFraction != null) { if (rightFraction == null) { return(CreateCodeForLeftFractionValue(ppp, leftFraction)); } { var cw = Ext.Create <Self>(); if (TryHint(ppp, cw)) { cw.WriteLine("// scenario F1"); return(cw); } cw.WriteLine("// scenario F2"); cw.WithThrowNotImplementedException(); return(cw); } } if (rightFraction != null) { return(CreateCodeForRightFractionValue(rightFraction, ppp)); } { var cw = Ext.Create <Self>(); if (TryHint(ppp, cw)) { cw.WriteLine("// scenario F3"); return(cw); } } return(CreateCodeForFractionalResult(ppp)); } return(NullableArgument.CreateCode(leftName, rightName, op, nullableArguments)); } var cw1 = PrepareCode(); var method = cl.AddMethod(op, tResult + (nullableArguments == NullableArguments.None ? "" : "?"), info.Description) .WithBody(cw1); var p = method.AddParam(leftName, leftValue); p.Description = info.Left.Desctiption; p = method.AddParam(rightName, rightValue); p.Description = info.Right.Desctiption; }
private void Add_Algebra_PlusMinus() { const string right = "right"; const string left = "left"; var delta = BasicUnitDefs.All.GetDeltaByUnit(Cfg.UnitTypes.Unit); if (delta != null) { if (delta.UnitTypes.Value == Cfg.UnitTypes.Value) { delta = null; } } void AddPlusOrMinus(string op, XValueTypeName lt, XValueTypeName rt) { var resultType = Cfg.UnitTypes.Value; if (delta != null && op == "-") { resultType = delta.UnitTypes.Value; } string CreateResultFromVariable(string varName, XValueTypeName srcType, bool addMinus = false) { var result = addMinus ? "-" + varName : varName; if (delta is null || srcType == resultType) { return(result); } var unitSource = varName; if (lt != rt) { if (lt == resultType) { unitSource = left; } else if (rt == resultType) { unitSource = right; } else { throw new NotSupportedException(); } } result = new CsArguments(result + ".Value", unitSource + ".Unit").Create(resultType.ValueTypeName); return(result); } var cw = Ext.Create <BasicUnitValuesGenerator>(); var result1 = CreateResultFromVariable(right, rt, op == "-"); var condition = $"{left}.Value.Equals({ValuePropertyType}.Zero) && string.IsNullOrEmpty({left}.Unit?.UnitName)"; cw.SingleLineIf(condition, ReturnValue(result1)); result1 = CreateResultFromVariable(left, lt); condition = $"{right}.Value.Equals({ValuePropertyType}.Zero) && string.IsNullOrEmpty({right}.Unit?.UnitName)"; cw.SingleLineIf(condition, ReturnValue(result1)); cw.WriteLine($"{right} = {right}.ConvertTo({left}.Unit);"); var returnExpression = new CsArguments($"{left}.Value {op} {right}.Value", $"{left}.Unit") .Create(resultType.ValueTypeName); cw.WriteLine(ReturnValue(returnExpression)); Target.AddMethod(op, resultType.ValueTypeName) .WithLeftRightArguments(lt.ValueTypeName, rt.ValueTypeName) .WithBody(cw); } var targetName = new XValueTypeName(Target.Name); AddPlusOrMinus("-", targetName, targetName); if (delta != null) { AddPlusOrMinus("+", targetName, delta.UnitTypes.Value); AddPlusOrMinus("+", delta.UnitTypes.Value, targetName); } else { AddPlusOrMinus("+", targetName, targetName); } }
protected void Add_Parse(string splitMethodName) { string ArrayItemCode(ref int columnIndex) { return($"units[{(columnIndex++).CsEncode()}]"); } CsArguments GetConstructorArguments(TypesGroup tg, ref int columnIndex) { var aa = ProductUnitDefs.All; var a4 = aa.ByValueTypeName(tg.Value); var arguments = ArrayItemCode(ref columnIndex); if (a4 is null) { return(new CsArguments(arguments)); } return(new CsArguments( new CsArguments(arguments).Create(a4.CounterUnit.Unit.TypeName), new CsArguments(ArrayItemCode(ref columnIndex)).Create(a4.DenominatorUnit.Unit.TypeName) )); } CsArguments licznik, mianownik; { var columnIndex = 0; if (Cfg is FractionUnit fu) { licznik = GetConstructorArguments(fu.CounterUnit, ref columnIndex); mianownik = GetConstructorArguments(fu.DenominatorUnit, ref columnIndex); } else { licznik = new CsArguments(ArrayItemCode(ref columnIndex)); mianownik = new CsArguments(ArrayItemCode(ref columnIndex)); } } var cw = Ext.Create(GetType()); if (string.IsNullOrEmpty(splitMethodName)) { cw.WithThrowNotImplementedException("Not implemented due to unknown split method name."); } else { cw.SingleLineIf("string.IsNullOrEmpty(value)", "throw new ArgumentNullException(nameof(value));"); cw.WriteLine("var r = CommonParse.Parse(value, typeof(" + Target.Name + "));"); cw.WriteLine("var units = " + splitMethodName + "(r.UnitName);"); var sum = mianownik.Arguments.Length + licznik.Arguments.Length; cw.SingleLineIf("units.Length != " + sum.CsEncode(), "throw new Exception($\"{r.UnitName} is not valid " + Target.Name + " unit\");"); cw.WriteAssign("counterUnit", new CsArguments("units[0]").Create(GenInfo.First.Unit), true); //cw.WriteLine("var counterUnit = new " + GenInfo.First.Unit + "(units[0]);"); cw.WriteAssign("denominatorUnit", mianownik.Create(GenInfo.Second.Unit), true); // cw.WriteLine("var denominatorUnit = new " + GenInfo.Second.Unit + "(units[1]);"); cw.WriteLine(ReturnValue($"new {Target.Name}(r.Value, counterUnit, denominatorUnit)")); } var m = Target.AddMethod("Parse", GenInfo.Result.Value.ValueTypeName) .WithStatic() .WithBody(cw); m.AddParam("value", "string"); }