Esempio n. 1
0
        static NestedText GenTypeTagBody(string typeName, string tagName, Signature tag)
        {
            var modifiedArgs = tag.Args
                               .Map(x => new Arg(
                                        name: x.Name == tagName ? $"{x.Name}Value" : x.Name, // TODO: move to normalizer
                                        type: x.Type,
                                        kind: x.Kind
                                        ))
                               .ToArr();
            var argsWithoutFlags = modifiedArgs
                                   .Filter(x => x.Kind.Match(_: () => true, flags: _ => false))
                                   .ToArr();
            var tagArgs = argsWithoutFlags
                          .Map(x => (
                                   name: x.Name,
                                   lowerName: Helpers.LowerFirst(x.Name),
                                   type: TgTypeConverter.ConvertArgType(x),
                                   isRef: TgTypeConverter.IsRefArgType(x)
                                   )).ToArray();

            return(Scope(
                       Scope(
                           Line($"internal const uint TypeNumber = {Helpers.TypeNumber(tag.TypeNumber)};"),
                           Line("[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]"),
                           Line("uint ITgTypeTag.TypeNumber => TypeNumber;"),
                           Line("")
                           ),
                       tagArgs.Map(arg => Line($"public readonly {arg.type} {arg.name};")).Scope(),
                       Line(""),
                       Scope(
                           Line($"public {tagName}("),
                           IndentedScope(1, $",{Environment.NewLine}",
                                         tagArgs.Map(arg => Line($"{arg.type} {arg.lowerName}"))
                                         ),
                           Line(") {"),
                           IndentedScope(1,
                                         tagArgs.Map(arg => Line(
                                                         $"{arg.name} = {arg.lowerName}" +
                                                         $"{(arg.isRef ? $" ?? throw new ArgumentNullException(nameof({arg.lowerName}))" : "")};"
                                                         ))
                                         ),
                           Line("}")
                           ),
                       Line(""),
                       WithGen.GenWith(argsWithoutFlags, tagName),
                       Line(""),
                       typeName != tagName ? Scope(
                           Line($"public static implicit operator {typeName}({tagName} tag) => new {typeName}(tag);"),
                           Line($"public static implicit operator Some<{typeName}>({tagName} tag) => new {typeName}(tag);"),
                           Line("")
                           ) : EmptyScope(),
                       RelationsGen.GenRelations(tagName, argsWithoutFlags),
                       Line(""),
                       Line(""),
                       SerializerGen.GenSerializer(modifiedArgs, typeNumber: None, "ITgTypeTag.SerializeTag"),
                       Line(""),
                       SerializerGen.GenTypeTagDeserialize(tagName, modifiedArgs)
                       ));
        }
Esempio n. 2
0
        public static NestedText GenSerializer(Arr <Arg> args, Option <int> typeNumber, string funcName)
        {
            Text GenSerializer(TgType type) => type.Match(
                primitive: x => $"Write{x.Type}",
                typeRef: x => "WriteSerializable",
                vector: x => Concat(
                    $"WriteVector<{TgTypeConverter.ConvertType(x.Type)}>(",
                    GenSerializer(x.Type),
                    ")"
                    )
                );

            Option <Text> GenNonFlagArgSerializer(Arg arg) =>
            arg.Kind.Match(
                _: () => throw new Exception("WTF"),
                required: _ => GenSerializer(arg.Type).Apply(Some),
                optional: x => arg.Type == TgType.OfPrimitive(PrimitiveType.True) ? None : Concat(
                    $"WriteOption<{TgTypeConverter.ConvertType(arg.Type)}>(",
                    GenSerializer(arg.Type),
                    ")"
                    ).Apply(Some)
                ).Map(s =>
                      Concat($"Write({arg.Name}, bw, ", s, ");")
                      );

            Text GenMaskSerializer(IEnumerable <(string, int)> maskArgs) =>
            maskArgs.ToArr()
            .Apply(Optional).Filter(xs => xs.Count > 0)
            .Map(xs => xs
                 .Map(x => $"MaskBit({x.Item2}, {x.Item1})").Map(String).Reduce((x, y) => Concat(x, " | ", y))
                 )
            .IfNone("0")
            .Apply(mask => Concat("Write(", mask, ", bw, WriteInt);"));

            Option <Text> GenArgSerializer(Arg arg) => arg.Kind.Match(
                _: () => GenNonFlagArgSerializer(arg),
                flags: _ =>
                args.Choose(x => x.Kind.Match(
                                _: () => None,
                                optional: optional => ($"{x.Name}", optional.Flag.Bit).Apply(Some)
                                )).Apply(GenMaskSerializer)
                );

            var body = args.Choose(GenArgSerializer).Map(Line).Scope().Apply(s => typeNumber
                                                                             .Map(Helpers.TypeNumber).Map(x => Line($"WriteUint(bw, {x});")).Map(typeNumSer => Scope(typeNumSer, s))
                                                                             .IfNone(s)
                                                                             );
            var def = Scope(
                Line($"void {funcName}(BinaryWriter bw)"),
                Line("{"),
                Indent(1, body),
                Line("}")
                );

            return(def);
        }
Esempio n. 3
0
 public static NestedText GenTagYamlifier(Arr <Arg> args, string typeName)
 {
     Text GenYamlifier(bool tagOnly, TgType type) =>
     type.Match(
         primitive: x => $"Yamlifier.Write{x.Type}",
         typeRef: x => $"{TgTypeConverter.ConvertType(type, cmpWrapper: false)}.Yamlify(tagOnly: {(tagOnly ? "true" : "false")})",
         vector: x => Concat(
             $"Yamlifier.StringifyVector<{TgTypeConverter.ConvertType(x.Type, cmpWrapper: false)}>(",
             GenYamlifier(tagOnly, x.Type),
             ")"
             )
         );
Esempio n. 4
0
 public static NestedText GenWith(Arr <Arg> args, string typeName) => Scope(
     Line($"public {typeName} With("),
     IndentedScope(1, "," + Environment.NewLine, args
                   .Map(arg => $"{TgTypeConverter.WrapArgTypeWithNullable(arg)} {Helpers.LowerFirst(arg.Name)} = null")
                   .Map(Line)
                   ),
     Line($") => new {typeName}("),
     IndentedScope(1, "," + Environment.NewLine, args
                   .Map(arg => arg.Name).Map(argName => $"{Helpers.LowerFirst(argName)} ?? {argName}")
                   .Map(Line)
                   ),
     Line(");")
     );
Esempio n. 5
0
        public static NestedText GenRelations(string typeName, Arr <Arg> args)
        {
            var cmpTupleName = String("CmpTuple");


            Text EmPt(Text text) => Concat("(", text, ")");
            Func <Arr <Text>, Text> Tuple(bool type) => xs =>
            xs.Count == 0 ? (type ? "Unit" : "Unit.Default") :
            xs.Count == 1 ? xs[0]
                : Join(", ", xs).Apply(EmPt);

            Text ArgsTuple(bool type, Func <Arg, Text> argStr) => args
            .Map(argStr)
            .Apply(Tuple(type));

            var argsTuple     = ArgsTuple(false, x => x.Name);
            var argsTupleType = ArgsTuple(true, x => TgTypeConverter.ConvertArgType(x));

            var cmpTuple = Scope(
                Line("[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]"),
                Line(Concat(argsTupleType, " ", cmpTupleName, " =>")),
                Indent(1, Line(Concat(argsTuple, ";")))
                );


            var argsInterpolationStr = args
                                       .Map(x => Concat(x.Name, ": ", "{", x.Name, "}"))
                                       .Apply(xs => Join(", ", xs))
                                       .Apply(x => Concat("$\"(", x, ")\""));

            return(Scope(Environment.NewLine + Environment.NewLine,
                         cmpTuple,
                         GenEqRelations(typeName, cmpTupleName),
                         GenCmpRelations(typeName, cmpTupleName),
                         GenGetHashCode(cmpTupleName),
                         GenToString(argsInterpolationStr)
                         ));
        }
Esempio n. 6
0
        static NestedText GenFunc(Signature func, string funcName)
        {
            var argsWithoutFlags = func.Args
                                   .Filter(x => x.Kind.Match(_: () => true, flags: _ => false))
                                   .ToArr();
            var funcArgs = argsWithoutFlags
                           .Map(x => (
                                    name: x.Name,
                                    lowerName: Helpers.LowerFirst(x.Name),
                                    type: TgTypeConverter.ConvertArgType(x),
                                    isRef: TgTypeConverter.IsRefArgType(x)
                                    )).ToArray();

            // usually it is a higher-order function, i am too lazy to modify the scheme just for this case
            var isWrapper        = func.Args.Exists(x => x.Type == TgType.OfTypeRef("X") || x.Type == TgType.OfTypeRef("!X"));
            var resType          = isWrapper ? "TFuncRes" : TgTypeConverter.ConvertType(func.ResultType);
            var classAccess      = isWrapper ? "" : "public ";
            var classTemplates   = isWrapper ? "<TFunc, TFuncRes>" : "";
            var classAnnotations = isWrapper
                ? $": ITgFunc<{resType}> where TFunc : class, ITgFunc<{resType}>"
                : $": ITgFunc<{resType}>, IEquatable<{funcName}>, IComparable<{funcName}>, IComparable";

            var resDes = isWrapper
                ? "Query.DeserializeResult(br);" // it is 'Query' all the time, i am too lazy
                : Concat("Read(br, ", SerializerGen.GenTypeDeserializer(func.ResultType), ");");
            var resultDeserializer = Scope(
                Line($"{resType} ITgFunc<{resType}>.DeserializeResult(BinaryReader br) =>"),
                Indent(1, Line(resDes))
                );

            return(Scope(
                       Line($"{classAccess}sealed class {funcName}{classTemplates} {classAnnotations}"),
                       Line("{"),
                       IndentedScope(1,
                                     funcArgs.Map(arg => Line($"public {arg.type} {arg.name} {{ get; }}")).Scope(),
                                     Scope(
                                         Line(""),
                                         Scope(
                                             Line($"public {funcName}("),
                                             IndentedScope(1, $",{Environment.NewLine}",
                                                           funcArgs.Map(arg => Line($"{arg.type} {arg.lowerName}"))
                                                           ),
                                             Line(") {"),
                                             IndentedScope(1,
                                                           funcArgs.Map(arg => Line(
                                                                            $"{arg.name} = {arg.lowerName}" +
                                                                            $"{(arg.isRef ? $" ?? throw new ArgumentNullException(nameof({arg.lowerName}))" : "")};"
                                                                            ))
                                                           ),
                                             Line("}")
                                             ),
                                         Line(""),
                                         Line(""),
                                         isWrapper ? Scope(new NestedText[0]) : Scope(
                                             WithGen.GenWith(argsWithoutFlags, funcName),
                                             Line(""),
                                             RelationsGen.GenRelations(funcName, argsWithoutFlags),
                                             Line("")
                                             ),
                                         SerializerGen.GenSerializer(func.Args, typeNumber: func.TypeNumber, "ITgSerializable.Serialize"),
                                         Line(""),
                                         resultDeserializer
                                         )
                                     ),
                       Line("}")
                       ));
        }