private static CsCodeWriter CreateCodeForFractionalResult(OperatorParams p) { var cw = Ext.Create <MultiplyAlgebraGenerator>(); cw.WriteLine("// scenario E"); var args = new CsArguments( $"{p.LeftMethodArgumentName}.Value {p.Oper} {p.RightMethodArgumentName}.Value", $"{p.LeftMethodArgumentName}.Unit", $"{p.RightMethodArgumentName}.Unit" ); var tResult = p.Result.Value; var expression = args.Create(tResult.ValueTypeName); cw.WriteLine($"return {expression};"); return(cw); }
private static bool TryHint(OperatorParams par, CsCodeWriter cw) { if (!(par.OperatorHints is null)) { var builderInput = par.GetBuilder(); if (!(builderInput is null)) { var builder = new OperatorCodeBuilder(builderInput); cw.WriteLine("// scenario with hint"); builder.WriteCode(cw); return(true); } } // Console.WriteLine("args.Input" + par.DebugIs); return(false); }
private static CsCodeWriter CreateCodeForLeftFractionValue(OperatorParams p, [NotNull] FractionUnit leftFraction) { if (leftFraction == null) { throw new ArgumentNullException(nameof(leftFraction)); } var cw = Ext.Create <MultiplyAlgebraGenerator>(); cw.WriteLine("// " + p); var canNormal = leftFraction.DenominatorUnit.Unit == p.Right.Unit && leftFraction.CounterUnit.Unit == p.Result.Unit; if (canNormal) { if (TryHint(p, cw)) { cw.WriteLine("// scenario D1"); return(cw); } } else { if (TryHint(p, cw)) { return(cw); } cw.WriteLine("// scenario D2"); return(cw.WithThrowNotImplementedException()); } var oper = new OperatorCodeBuilderInput(p); var leftUnit = p.LeftMethodArgumentName + "Unit"; oper.ConvertRight(leftUnit + ".DenominatorUnit"); oper.ResultUnit = leftUnit + ".CounterUnit"; oper.AddVariable(leftUnit, p.LeftMethodArgumentName + ".Unit"); cw.WriteLine("// scenario D3"); var builder = new OperatorCodeBuilder(oper); builder.WriteCode(cw); return(cw); }
private static CsCodeWriter CreateCodeForRelatedUnits(OperatorParams p, ref string rightUnit, ref string resultUnit) { var tLeftUnit = p.Left.Unit; var tRightUnit = p.Right.Unit; var tResultUnit = p.Result.Unit; var tResult = p.Result.Value; var cw = Ext.Create <MultiplyAlgebraGenerator>(); cw.WriteLine("// scenario C"); void Add(XUnitTypeName srcUnit, XUnitTypeName targetUnit, string variable) { var line1 = $"var {variable} = GlobalUnitRegistry.Relations.GetOrThrow<{srcUnit}, {targetUnit}>({p.LeftMethodArgumentName}.Unit);"; cw.WriteLine(line1); } if (tRightUnit == tResultUnit) { rightUnit = resultUnit = "newUnit"; Add(tLeftUnit, tResultUnit, resultUnit); } else { Add(tLeftUnit, tRightUnit, rightUnit); Add(tLeftUnit, tResultUnit, resultUnit); } cw.WriteLine( $"var {p.RightMethodArgumentName}Converted = {p.RightMethodArgumentName}.ConvertTo({rightUnit});"); cw.WriteLine( $"var value = {p.LeftMethodArgumentName}.Value {p.Oper} {p.RightMethodArgumentName}Converted.Value;"); cw.WriteLine($"return new {tResult}(value, {resultUnit});"); return(cw); }
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 static CsCodeWriter CreateCodeForRightFractionValue(FractionUnit rightFraction, OperatorParams p) { var cw = Ext.Create <MultiplyAlgebraGenerator>(); Debug.WriteLine(rightFraction); var isCnt = rightFraction.CounterUnit == p.Left; var isResult = rightFraction.CounterUnit == p.Result; if (!(isCnt ^ isResult)) { if (TryHint(p, cw)) { return(cw); } cw.WriteLine("// scenario G"); cw.WithThrowNotImplementedException(); return(cw); } if (isCnt) { cw.WriteLine("// scenario A"); cw.WriteLine( $"// {p.Right.Value.ToLower()} unit will be synchronized with {p.Left.Value.ToLower()} unit"); cw.WriteLine("var unit = new {2}({0}.Unit, {1}.Unit.DenominatorUnit);", p.LeftMethodArgumentName, p.RightMethodArgumentName, p.Right.Unit); cw.WriteLine("var {1}Converted = {1}.WithCounterUnit({0}.Unit);", p.LeftMethodArgumentName, p.RightMethodArgumentName); cw.WriteLine($"var value = {{0}}.Value {p.Oper} {{1}}Converted.Value;", p.LeftMethodArgumentName, p.RightMethodArgumentName); cw.WriteLine("return new {0}(value, {1}.Unit.DenominatorUnit);", p.Result.Value, p.RightMethodArgumentName); } else { cw.WriteLine("// scenario B"); cw.WriteLine("var unit = new {2}({1}.Unit.CounterUnit, {0}.Unit);", p.LeftMethodArgumentName, p.RightMethodArgumentName, p.Right.Unit); cw.WriteLine("var {1}Converted = {1}.WithDenominatorUnit({0}.Unit);", p.LeftMethodArgumentName, p.RightMethodArgumentName); cw.WriteLine($"var value = {{0}}.Value {p.Oper} {{1}}Converted.Value;", p.LeftMethodArgumentName, p.RightMethodArgumentName); cw.WriteLine("return new {0}(value, {1}.Unit.CounterUnit);", p.Result.Value, p.RightMethodArgumentName); } return(cw); }