コード例 #1
0
        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;
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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");
        }