Exemplo n.º 1
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);
        }