예제 #1
0
        public override Tree VisitType(TypeContext context)
        {
            TypeTag  type;
            TypeTree tree;
            IToken   token = context.primitive;

            if (token != null)
            {
                switch (token.Type)
                {
                case INT:
                    type = TypeTag.INT;
                    break;

                case LONG:
                    type = TypeTag.LONG;
                    break;

                case FLOAT:
                    type = TypeTag.FLOAT;
                    break;

                case DOUBLE:
                    type = TypeTag.DOUBLE;
                    break;

                case BOOLEAN:
                    type = TypeTag.BOOLEAN;
                    break;

                case CHAR:
                    type = TypeTag.CHAR;
                    break;

                case CSTRING:
                    type = TypeTag.C_STRING;
                    break;

                default:
                    throw new ArgumentException();
                }

                int endCol = token.Column + token.StopIndex - token.StopIndex;
                tree = new PrimitiveTypeNode(token.Line, token.Column, token.Line, endCol, type);
            }
            else
            {
                tree = new DeclaredType(context.Start.Line, context.Start.Column, context.Stop.Line,
                                        context.Stop.Column, context.structName.Text);
            }

            for (int i = 0; i < context.arrays; i++)
            {
                tree = new ArrayTypeTree(context.Start.Line, context.Start.Column, context.Stop.Line,
                                         context.Stop.Column, tree);
            }

            return(tree);
        }
예제 #2
0
        private TypeTree FixTypeTree(TypeTree typeTree, Symbol type, UserTypeFactory factory)
        {
            // Check basic type
            BasicTypeTree basicTypeTree = typeTree as BasicTypeTree;

            if (basicTypeTree != null)
            {
                // Basic type tree is not challenged against template arguments, so try to do that.
                UserType basicUserType;

                if (CreateFactory(factory).GetUserType(type, out basicUserType))
                {
                    TypeTree tree = UserTypeTree.Create(basicUserType, factory);

                    if (tree != null)
                    {
                        return(tree);
                    }
                }

                // Failed to match the type
                // TODO: Look for typedeclared. Class is using different types than in template specialization. We cannot support it right now.
                return(new VariableTypeTree());
            }

            // Check array type
            ArrayTypeTree arrayTypeTree = typeTree as ArrayTypeTree;

            if (arrayTypeTree != null)
            {
                TypeTree elementTypeTree = FixTypeTree(arrayTypeTree.ElementType, type.ElementType, factory);

                if (elementTypeTree != arrayTypeTree.ElementType)
                {
                    return(new ArrayTypeTree(elementTypeTree));
                }

                return(arrayTypeTree);
            }

            // Check pointer type
            PointerTypeTree pointerTypeTree = typeTree as PointerTypeTree;

            if (pointerTypeTree != null)
            {
                TypeTree elementTypeTree = FixTypeTree(pointerTypeTree.ElementType, type.ElementType, factory);

                if (elementTypeTree != pointerTypeTree.ElementType)
                {
                    return(new PointerTypeTree(elementTypeTree));
                }

                return(pointerTypeTree);
            }

            return(typeTree);
        }
예제 #3
0
        /// <summary>
        /// Generates user type field based on the specified symbol field and all other fields that are prepared for this function.
        /// Do not use this function directly, unless you are calling it from overridden function.
        /// </summary>
        /// <param name="field">The symbol field.</param>
        /// <param name="fieldType">The field tree type.</param>
        /// <param name="factory">The user type factory.</param>
        /// <param name="simpleFieldValue">The code foe "simple field value" used when creating transformation.</param>
        /// <param name="gettingField">The code for getting field variable.</param>
        /// <param name="isStatic">if set to <c>true</c> generated field should be static.</param>
        /// <param name="generationFlags">The user type generation flags.</param>
        /// <param name="extractingBaseClass">if set to <c>true</c> user type field is being generated for getting base class.</param>
        protected override UserTypeField ExtractFieldInternal(SymbolField field, TypeTree fieldType, UserTypeFactory factory, string simpleFieldValue, string gettingField, bool isStatic, UserTypeGenerationFlags generationFlags, bool extractingBaseClass)
        {
            // Physical code generation make sense only for non-static fields
            if (!isStatic)
            {
                bool lazyCacheUserTypeFields = generationFlags.HasFlag(UserTypeGenerationFlags.LazyCacheUserTypeFields);

                bool                   cacheUserTypeFields       = generationFlags.HasFlag(UserTypeGenerationFlags.CacheUserTypeFields);
                bool                   cacheStaticUserTypeFields = generationFlags.HasFlag(UserTypeGenerationFlags.CacheStaticUserTypeFields);
                string                 constructorText           = "";
                string                 fieldName          = field.Name;
                string                 fieldTypeString    = fieldType.GetTypeString();
                BasicTypeTree          baseType           = fieldType as BasicTypeTree;
                ArrayTypeTree          codeArrayType      = fieldType as ArrayTypeTree;
                UserTypeTree           userType           = fieldType as UserTypeTree;
                TransformationTypeTree transformationType = fieldType as TransformationTypeTree;
                bool                   isEmbedded         = field.Type.Tag != CodeTypeTag.Pointer;

                // Specialization for basic types
                if (baseType != null)
                {
                    if (baseType.BasicType == "string")
                    {
                        int charSize = field.Type.ElementType.Size;

                        constructorText = string.Format("ReadString(GetCodeType().Module.Process, ReadPointer(memoryBuffer, memoryBufferOffset + {0}, {1}), {2})", field.Offset, field.Type.Size, charSize);
                    }
                    else if (baseType.BasicType != "NakedPointer")
                    {
                        if (field.LocationType == LocationType.BitField)
                        {
                            constructorText = string.Format("Read{0}(memoryBuffer, memoryBufferOffset + {1}, {2}, {3})", baseType.GetTypeString().UppercaseFirst(), field.Offset, field.Size, field.BitPosition);
                        }
                        else
                        {
                            constructorText = string.Format("Read{0}(memoryBuffer, memoryBufferOffset + {1})", baseType.GetTypeString().UppercaseFirst(), field.Offset);
                        }
                    }
                }
                // Specialization for arrays
                else if (codeArrayType != null)
                {
                    if (codeArrayType.ElementType is BasicTypeTree)
                    {
                        baseType = (BasicTypeTree)codeArrayType.ElementType;
                        if (baseType != null && baseType.BasicType != "string" && baseType.BasicType != "NakedPointer")
                        {
                            int arraySize   = field.Type.Size;
                            int elementSize = field.Type.ElementType.Size;

                            if (baseType.BasicType == "char")
                            {
                                constructorText = string.Format("Read{0}Array(memoryBuffer, memoryBufferOffset + {1}, {2}, {3})", baseType.GetTypeString().UppercaseFirst(), field.Offset, arraySize / elementSize, elementSize);
                            }
                            else
                            {
                                constructorText = string.Format("Read{0}Array(memoryBuffer, memoryBufferOffset + {1}, {2})", baseType.GetTypeString().UppercaseFirst(), field.Offset, arraySize / elementSize);
                            }
                            fieldTypeString = baseType.GetTypeString() + "[]";
                        }
                    }
                }
                // Specialization for user types
                else if (userType != null && !extractingBaseClass)
                {
                    if (!(userType.UserType is EnumUserType))
                    {
                        string thisClassCodeType;

                        if (IsTypeUsingStaticCodeType(this))
                        {
                            thisClassCodeType = ClassCodeType;
                        }
                        else
                        {
                            thisClassCodeType = "thisClass.Value.GetCodeType()";
                            usedThisClass     = true;
                        }

                        // Check if type is embedded
                        if (!isEmbedded)
                        {
                            // If user type is not embedded, we do have pointer inside of our memory buffer that we can read directly
                            if (IsTypeUsingStaticCodeType(this))
                            {
                                constructorText = string.Format("ReadPointer<{0}>({4}, \"{1}\", memoryBuffer, memoryBufferOffset + {2}, {3})", fieldTypeString, fieldName, field.Offset, field.Type.Size, ClassCodeType);
                            }
                            else
                            {
                                constructorText = string.Format("ReadPointer<{0}>(thisClass, \"{1}\", memoryBuffer, memoryBufferOffset + {2}, {3})", fieldTypeString, fieldName, field.Offset, field.Type.Size);
                                usedThisClass   = true;
                            }

                            // Do downcasting if field has vtable
                            if (userType.UserType.Symbol.HasVTable() && userType.UserType.DerivedClasses.Count > 0)
                            {
                                constructorText += ".DowncastObject()";
                            }
                        }
                        else
                        {
                            // If user type is embedded, we can reuse memory buffer that we already have in this class
                            string fieldAddress  = string.Format("memoryBufferAddress + (ulong)(memoryBufferOffset + {0})", field.Offset);
                            string fieldCodeType = string.Format("{0}.GetClassFieldType(\"{1}\")", thisClassCodeType, fieldName);

                            if (IsTypeUsingStaticCodeType(userType.UserType))
                            {
                                fieldCodeType = string.Format("{0}.{1}", userType.UserType.FullClassName, ClassCodeType);
                            }
                            else if (IsTypeUsingStaticCodeType(this))
                            {
                                fieldCodeType = AddFieldCodeType(fieldName);
                            }

                            constructorText = string.Format("new {0}(memoryBuffer, memoryBufferOffset + {1}, memoryBufferAddress, {2}, {3}, \"{4}\")", fieldTypeString, field.Offset, fieldCodeType, fieldAddress, fieldName);
                        }
                    }
                    else
                    {
                        // TODO: This is enum. Read how much enum base type is big and just cast to enum type...
                    }
                }
                // Specialization for transformations
                else if (transformationType != null)
                {
                    if (!isEmbedded)
                    {
                        string thisClassCodeType;

                        if (IsTypeUsingStaticCodeType(this))
                        {
                            thisClassCodeType = ClassCodeType;
                        }
                        else
                        {
                            thisClassCodeType = "thisClass.Value.GetCodeType()";
                            usedThisClass     = true;
                        }

                        string fieldAddress  = string.Format("memoryBufferAddress + (ulong)(memoryBufferOffset + {0})", field.Offset);
                        string fieldVariable = string.Format("Variable.CreateNoCast({0}.GetClassFieldType(\"{1}\"), {2}, \"{1}\")", thisClassCodeType, fieldName, fieldAddress);

                        if (transformationType.Transformation.Transformation.HasPhysicalConstructor)
                        {
                            fieldVariable = string.Format("{0}, memoryBuffer, memoryBufferOffset + {1}, memoryBufferAddress", fieldVariable, field.Offset);
                        }

                        simpleFieldValue = fieldVariable;
                        constructorText  = string.Format("new {0}({1})", fieldTypeString, fieldVariable);
                    }
                }

                // If we found suitable physical representation, generate the field
                if (!string.IsNullOrEmpty(constructorText))
                {
                    return new UserTypeField()
                           {
                               ConstructorText      = constructorText,
                               FieldName            = "_" + fieldName,
                               FieldType            = fieldTypeString,
                               FieldTypeInfoComment = string.Format("// {0} {1};", field.Type.Name, fieldName),
                               PropertyName         = UserTypeField.GetPropertyName(field, this),
                               Static           = isStatic,
                               UseUserMember    = lazyCacheUserTypeFields,
                               CacheResult      = cacheUserTypeFields || (isStatic && cacheStaticUserTypeFields),
                               SimpleFieldValue = simpleFieldValue,
                           }
                }
                ;
            }

            return(base.ExtractFieldInternal(field, fieldType, factory, simpleFieldValue, gettingField, isStatic, generationFlags, extractingBaseClass));
        }
예제 #4
0
 public override Type visitArrayType(ArrayTypeTree arrayType, Environment env)
 {
     return(symtab.arrayTypeOf(scan(arrayType.elemTypeTree, env)));
 }
예제 #5
0
파일: AstVisitor.cs 프로젝트: irpbc/mj
 public virtual T visitArrayType(ArrayTypeTree arrayType, A arg) => visit(arrayType, arg);
예제 #6
0
 public override object visitArrayType(ArrayTypeTree arrayType, WritableScope scope)
 {
     return(symtab.arrayTypeOf((Type)scan(arrayType.elemTypeTree, scope)));
 }