Ejemplo n.º 1
0
        public static string GenerateCode(string json)
        {
            var discoveredTypes = intrinsicTypes.ToDictionary(type => type.Name, type => type);

            var schemaDefinitions = JsonConvert.DeserializeObject <SchemaTypeDefinitions>(json);

            var cppTypes = schemaDefinitions.Types.Select(t => GenerateType(t));
            var template = new CodeTemplate(cppTypes);

            return(template.TransformText());

            ICppType GenerateType(SchemaType schemaType)
            {
                var topLevelParts = GenerateParts(schemaType);

                var properties = new List <CppProperty>();

                GenerateProperties(topLevelParts);

                var(finalTopLevelParts, topLevelType) = OptimizePartLayout(topLevelParts);

                var namedType = new CppTypeInfo(
                    name: schemaType.Name,
                    alignment: Math.Max(topLevelType.Alignment, schemaType.Alignment),
                    bits: topLevelType.Bits);

                discoveredTypes.Add(namedType.Name, namedType);
                return(new CppClass(namedType, finalTopLevelParts, properties.ToArray()));

                void GenerateProperties(ICppPart[] parts, params CppPropertyCondition[] conditions)
                {
                    foreach (var part in parts)
                    {
                        switch (part)
                        {
                        case CppPropertyPart property:
                            properties.Add(new CppProperty(property.Type, property.Name, conditions));
                            break;

                        case CppUnionHeaderPart unionHeader:
                            var headerFieldType = new CppTypeInfo("", 0, unionHeader.Bits);
                            break;

                        case CppUnionBodyPart unionBody:
                            foreach (var(unionCase, i) in unionBody.Cases.Select((c, i) => (c, i)))
                            {
                                var caseCondition = new CppPropertyCondition(unionBody.ID, i);
                                GenerateProperties(unionCase.Parts, conditions.Concat(new[] { caseCondition }).ToArray());
                            }

                            break;
                        }
                    }
                }

                (ICppPart[] parts, CppTypeInfo type) OptimizePartLayout(ICppPart[] unoptimizedParts)
                {
                    var unoptimizedPartsAndTypes = GetPartsAndTypes(unoptimizedParts);

                    return(ArrangeParts(unoptimizedPartsAndTypes));

                    (ICppPart part, CppTypeInfo type)[] GetPartsAndTypes(ICppPart[] parts)
                    {
                        return(parts.Select <ICppPart, ValueTuple <ICppPart, CppTypeInfo> >(part =>
                        {
                            switch (part)
                            {
                            case CppPropertyPart property:
                                return (property, property.Type);

                            case CppUnionHeaderPart unionHeader:
                                return (unionHeader, new CppTypeInfo("", 0, unionHeader.Bits));

                            case CppUnionBodyPart unionBody:
                                var optimizedCases = new List <CppUnionCase>();
                                var unionBodySize = 8;
                                var unionBodyAlignment = 1;
                                foreach (var unionCase in unionBody.Cases)
                                {
                                    (ICppPart[] caseParts, CppTypeInfo caseType) = OptimizePartLayout(unionCase.Parts);
                                    unionBodySize = Math.Max(caseType.Bits, unionBodySize);
                                    unionBodyAlignment = Math.Max(caseType.Alignment, unionBodyAlignment);
                                    optimizedCases.Add(new CppUnionCase(caseParts));
                                }

                                var unionBodyType = new CppTypeInfo("", unionBodyAlignment, unionBodySize);
                                return (new CppUnionBodyPart(unionBody.ID, optimizedCases.ToArray()), unionBodyType);
                            }

                            throw new ArgumentNullException(nameof(part));
                        }).ToArray());
                    }

                    (ICppPart[] parts, CppTypeInfo type) ArrangeParts((ICppPart part, CppTypeInfo type)[] typesAndParts)
Ejemplo n.º 2
0
 public CppPropertyPart(CppTypeInfo type, string name)
 {
     Type = type;
     Name = name;
 }
Ejemplo n.º 3
0
 public CppEnum(CppTypeInfo typeInfo, string[] cases)
 {
     TypeInfo = typeInfo;
     Cases    = cases;
 }
Ejemplo n.º 4
0
 public CppClass(CppTypeInfo typeInfo, ICppPart[] parts, CppProperty[] properties)
 {
     TypeInfo   = typeInfo;
     Parts      = parts;
     Properties = properties;
 }
Ejemplo n.º 5
0
 public CppProperty(CppTypeInfo type, string name, params CppPropertyCondition[] conditions)
 {
     Type       = type;
     Name       = name;
     Conditions = conditions;
 }
Ejemplo n.º 6
0
 public CppBitFieldPart(CppTypeInfo type, ICppPart[] parts)
 {
     Type  = type;
     Parts = parts;
 }
Ejemplo n.º 7
0
 private string GetParameterType(CppTypeInfo type)
 {
     return(type.Bits <= 64
         ? type.Name
         : $"const {type.Name}&");
 }