Пример #1
0
        private ClassDeclNode CreateEmptyClassNode(string classname)
        {
            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = new ProtoCore.AST.AssociativeAST.ClassDeclNode();
            classnode.className       = classname;
            classnode.Name            = null;
            classnode.IsImportedClass = true;

            classnode.IsExternLib   = true;
            classnode.ExternLibName = null; //Dummy class.

            return(classnode);
        }
Пример #2
0
        private ClassDeclNode ParseEnumType(Type type, string alias)
        {
            //TODO: For now Enum can't be suppressed.
            Validity.Assert(type.IsEnum, "Non enum type is being imported as enum!!");

            string classname = alias;

            if (classname == null | classname == string.Empty)
            {
                classname = CLRObjectMarshler.GetTypeName(type);
            }

            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname);
            classnode.ExternLibName = Module.Name;
            classnode.className     = classname;
            classnode.Name          = type.Name;

            FieldInfo[] fields = type.GetFields();
            foreach (var f in fields)
            {
                if (f.FieldType != type)
                {
                    continue;
                }

                VarDeclNode variable = ParseFieldDeclaration(f);
                if (null == variable)
                {
                    continue;
                }
                variable.IsStatic = true;
                classnode.varlist.Add(variable);
                FunctionDefinitionNode func = ParseFieldAccessor(f);
                if (null != func)
                {
                    func.IsStatic = true;
                    RegisterFunctionPointer(func.Name, f, null, func.ReturnType);
                    classnode.funclist.Add(func);
                }
            }

            //Get all the attributes on this type and set it to the classnode.
            FFIClassAttributes cattrs = new FFIClassAttributes(type);

            classnode.ClassAttributes = cattrs;
            SetTypeAttributes(type, cattrs);

            return(classnode);
        }
Пример #3
0
        private ProtoCore.AST.AssociativeAST.CodeBlockNode MergeCodeBlockNode(ref ProtoCore.AST.AssociativeAST.ImportNode importedNode,
                                                                              ProtoCore.AST.AssociativeAST.CodeBlockNode codeBlockNode)
        {
            if (codeBlockNode == null || codeBlockNode.Body == null || importedNode == null)
            {
                return(codeBlockNode);
            }

            ProtoCore.AST.AssociativeAST.CodeBlockNode importedCodeBlock = importedNode.CodeNode;
            if (importedCodeBlock == null)
            {
                importedNode.CodeNode = codeBlockNode;
                return(codeBlockNode);
            }

            foreach (var item in codeBlockNode.Body)
            {
                ProtoCore.AST.AssociativeAST.ClassDeclNode classNode = item as ProtoCore.AST.AssociativeAST.ClassDeclNode;
                if (classNode != null)
                {
                    ProtoCore.AST.AssociativeAST.ClassDeclNode importedClass = null;
                    if (TryGetClassNode(importedCodeBlock, classNode.className, out importedClass))
                    {
                        bool dummyClassNode   = IsEmptyClassNode(classNode);
                        bool dummyImportClass = IsEmptyClassNode(importedClass);

                        Validity.Assert(dummyImportClass || dummyClassNode, string.Format("{0} is imported more than once!!", classNode.className));
                        if (dummyImportClass && !dummyClassNode)
                        {
                            importedNode.CodeNode.Body.Remove(importedClass);
                            importedNode.CodeNode.Body.Add(classNode);
                        }
                    }
                    else
                    {
                        importedNode.CodeNode.Body.Add(classNode);
                    }
                }
                else
                {
                    importedNode.CodeNode.Body.Add(item); //TODO other conflict resolution needs to be done here.
                }
            }
            return(importedNode.CodeNode);
        }
Пример #4
0
        private ClassDeclNode ParseEnumType(Type type, string alias)
        {
            Validity.Assert(type.IsEnum, "Non enum type is being imported as enum!!");

            string classname = alias;

            if (classname == null | classname == string.Empty)
            {
                classname = CLRObjectMarshler.GetTypeName(type);
            }

            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname);
            classnode.ExternLibName = Module.Name;
            classnode.className     = classname;
            classnode.Name          = type.Name;

            FieldInfo[] fields = type.GetFields();
            foreach (var f in fields)
            {
                if (f.FieldType != type)
                {
                    continue;
                }

                VarDeclNode variable = ParseFieldDeclaration(f);
                if (null == variable)
                {
                    continue;
                }
                variable.IsStatic = true;
                classnode.varlist.Add(variable);
                FunctionDefinitionNode func = ParseFieldAccessor(f);
                if (null != func)
                {
                    func.IsStatic = true;
                    RegisterFunctionPointer(func.Name, f, func.ReturnType);
                    classnode.funclist.Add(func);
                }
            }

            return(classnode);
        }
Пример #5
0
        public static bool TryGetClassNode(ProtoCore.AST.AssociativeAST.CodeBlockNode node, string typeName, out ProtoCore.AST.AssociativeAST.ClassDeclNode classNode)
        {
            classNode = null;
            //Traverse thru the code block and check if this type is already available
            if (node == null || node.Body == null)
            {
                return(false);
            }

            foreach (var item in node.Body)
            {
                ProtoCore.AST.AssociativeAST.ClassDeclNode clsnode = item as ProtoCore.AST.AssociativeAST.ClassDeclNode;
                if (clsnode != null && clsnode.className == typeName)
                {
                    classNode = clsnode;
                    return(true);
                }
            }
            return(false);
        }
Пример #6
0
 private void SplitClassDeclarationNode(ClassDeclNode node)
 {
     foreach (AssociativeNode procNode in node.Procedures)
     {
         if (procNode is FunctionDefinitionNode)
         {
             FunctionDefinitionNode fNode = procNode as FunctionDefinitionNode;
             if (!fNode.IsExternLib)
             {
                 fNode.FunctionBody.Body = SplitMulitpleAssignment(fNode.FunctionBody.Body);
             }
         }
         else if (procNode is ConstructorDefinitionNode)
         {
             ConstructorDefinitionNode cNode = procNode as ConstructorDefinitionNode;
             if (!cNode.IsExternLib)
             {
                 cNode.FunctionBody.Body = SplitMulitpleAssignment(cNode.FunctionBody.Body);
             }
         }
     }
 }
Пример #7
0
        private static bool IsEmptyClassNode(ProtoCore.AST.AssociativeAST.ClassDeclNode classNode)
        {
            if (null == classNode)
            {
                return(true);
            }

            if (classNode.IsExternLib && null == classNode.ExternLibName)
            {
                return(true);
            }

            if (classNode.funclist.Count > 0)
            {
                return(false);
            }

            if (classNode.varlist.Count > 0)
            {
                return(false);
            }

            return(true);
        }
Пример #8
0
        private static bool IsEmptyClassNode(ProtoCore.AST.AssociativeAST.ClassDeclNode classNode)
        {
            if (null == classNode)
            {
                return(true);
            }

            if (classNode.IsExternLib && null == classNode.ExternLibName)
            {
                return(true);
            }

            if (classNode.Procedures.Count > 0)
            {
                return(false);
            }

            if (classNode.Variables.Count > 0)
            {
                return(false);
            }

            return(true);
        }
Пример #9
0
        private ClassDeclNode CreateEmptyClassNode(string classname)
        {
            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = new ProtoCore.AST.AssociativeAST.ClassDeclNode();
            classnode.className = classname;
            classnode.Name = null;
            classnode.IsImportedClass = true;

            classnode.IsExternLib = true;
            classnode.ExternLibName = null; //Dummy class.

            return classnode;
        }
Пример #10
0
        private ClassDeclNode ParseSystemType(Type type, string alias)
        {
            Validity.Assert(IsBrowsable(type), "Non browsable type is being imported!!");

            string classname = alias;

            if (classname == null | classname == string.Empty)
            {
                classname = CLRObjectMarshler.GetTypeName(type);
            }

            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname);
            classnode.ExternLibName = Module.Name;
            classnode.className     = classname;
            classnode.Name          = type.Name;
            Type baseType = GetBaseType(type);

            if (baseType != null && !CLRObjectMarshler.IsMarshaledAsNativeType(baseType))
            {
                string baseTypeName = CLRObjectMarshler.GetTypeName(baseType);

                classnode.superClass = new List <string>();
                classnode.superClass.Add(baseTypeName);
                //Make sure that base class is imported properly.
                CLRModuleType.GetInstance(baseType, Module, string.Empty);
            }

            ConstructorInfo[] ctors = type.GetConstructors();
            foreach (var c in ctors)
            {
                if (c.IsPublic && !c.IsGenericMethod && IsBrowsable(c))
                {
                    ConstructorDefinitionNode node = ParseConstructor(c, type);
                    classnode.funclist.Add(node);
                    RegisterFunctionPointer(node.Name, c, node.ReturnType);
                }
            }

            BindingFlags flags          = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static;
            bool         isDerivedClass = classnode.superClass != null;

            if (isDerivedClass)                     //has base class
            {
                flags |= BindingFlags.DeclaredOnly; //for derived class, parse only class declared methods.
            }
            bool isDisposable = typeof(IDisposable).IsAssignableFrom(type);

            MethodInfo[] methods          = type.GetMethods(flags);
            bool         hasDisposeMethod = false;

            foreach (var m in methods)
            {
                if (!IsBrowsable(m))
                {
                    continue;
                }

                //Don't include overriden methods or generic methods
                if (m.IsPublic && !m.IsGenericMethod && (m == m.GetBaseDefinition() || (m.GetBaseDefinition().DeclaringType == baseType && baseType == typeof(Object))))
                {
                    AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m);
                    classnode.funclist.Add(node);
                }
                else if (!hasDisposeMethod && isDisposable && baseType == typeof(Object) && isDisposeMethod(m))
                {
                    AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m);
                    classnode.funclist.Add(node);
                }
            }
            if (!hasDisposeMethod && !isDisposable)
            {
                AssociativeNode node = ParseAndRegisterFunctionPointer(true, ref hasDisposeMethod, mDisposeMethod);
                classnode.funclist.Add(node);
            }

            FieldInfo[] fields = type.GetFields();
            foreach (var f in fields)
            {
                if (!IsBrowsable(f))
                {
                    continue;
                }

                VarDeclNode variable = ParseFieldDeclaration(f);
                if (null == variable)
                {
                    continue;
                }
                classnode.varlist.Add(variable);
                FunctionDefinitionNode func = ParseFieldAccessor(f);
                if (null != func)
                {
                    RegisterFunctionPointer(func.Name, f, func.ReturnType);
                }
            }

            PropertyInfo[] properties = type.GetProperties(flags);
            foreach (var p in properties)
            {
                AssociativeNode node = ParseProperty(p);
                if (null != node)
                {
                    classnode.varlist.Add(node);
                }
            }

            return(classnode);
        }
Пример #11
0
	void Associative_classdecl(out ProtoCore.AST.AssociativeAST.AssociativeNode node, List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = null) {
		ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = new ProtoCore.AST.AssociativeAST.ClassDeclNode(); 
		NodeUtils.SetNodeLocation(classnode, la); classnode.Attributes = attrs; 
		Expect(25);
		Expect(1);
		classnode.ClassName = t.val; 
		isInClass = true;
		if (IsKeyWord(t.val, true))
		{
		    errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val));
		}
		
		if (la.kind == 28) {
			Get();
			Expect(1);
			classnode.BaseClasses = new List<string>();
			classnode.BaseClasses.Add(t.val); 
			
			while (la.kind == 1) {
				Get();
				classnode.BaseClasses.Add(t.val); 
			}
		}
		Expect(45);
		while (StartOf(7)) {
			List<ProtoCore.AST.AssociativeAST.AssociativeNode> attributes = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); 
			if (la.kind == 10) {
				Associative_AttributeDeclaration(out attributes);
			}
			ProtoCore.CompilerDefinitions.AccessModifier access = ProtoCore.CompilerDefinitions.AccessModifier.Public; 
			if (la.kind == 48 || la.kind == 49 || la.kind == 50) {
				Associative_AccessSpecifier(out access);
			}
			if (la.kind == 26) {
				ProtoCore.AST.AssociativeAST.AssociativeNode constr = null; 
				Associative_constructordecl(out constr, access, attributes);
				if (String.IsNullOrEmpty(constr.Name))
				{
				   constr.Name= classnode.ClassName;
				}
				classnode.Procedures.Add(constr); 
				
			} else if (StartOf(8)) {
				bool isStatic = false; 
				if (la.kind == 39) {
					Get();
					isStatic = true; 
				}
				if (la.kind == 27) {
					ProtoCore.AST.AssociativeAST.AssociativeNode funcnode; 
					Associative_functiondecl(out funcnode, attributes, access, isStatic);
					classnode.Procedures.Add(funcnode); 
				} else if (la.kind == 1) {
					ProtoCore.AST.AssociativeAST.AssociativeNode varnode = null; 
					Associative_vardecl(out varnode, access, isStatic, attributes);
					classnode.Variables.Add(varnode); 
					if (la.val != ";")
					   SynErr(Resources.SemiColonExpected);  
					
					Expect(23);
					NodeUtils.SetNodeEndLocation(varnode, t); 
				} else if (la.kind == 23) {
					Get();
				} else SynErr(73);
			} else SynErr(74);
		}
		Expect(46);
		isInClass = false; classnode.endLine = t.line; classnode.endCol = t.col; 
		node = classnode; 
	}
Пример #12
0
 private void Initialize(ClassDeclNode classDeclNode)
 {
 }
Пример #13
0
        void Associative_classdecl(out ProtoCore.AST.AssociativeAST.AssociativeNode node, List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = null)
        {
            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = new ProtoCore.AST.AssociativeAST.ClassDeclNode();
            NodeUtils.SetNodeLocation(classnode, la); classnode.Attributes = attrs;
            Expect(23);
            Expect(1);
            classnode.className = t.val;
            isInClass = true;
            if (IsKeyWord(t.val, true))
            {
            errors.SemErr(t.line, t.col, String.Format("\"{0}\" is a keyword, identifier expected", t.val));
            }

            if (la.kind == 27) {
            Get();
            Expect(1);
            classnode.superClass = new List<string>();
            classnode.superClass.Add(t.val);

            while (la.kind == 1) {
                Get();
                classnode.superClass.Add(t.val);
            }
            }
            Expect(44);
            while (StartOf(7)) {
            List<ProtoCore.AST.AssociativeAST.AssociativeNode> attributes = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>();
            if (la.kind == 7) {
                Associative_AttributeDeclaration(out attributes);
            }
            ProtoCore.DSASM.AccessSpecifier access = ProtoCore.DSASM.AccessSpecifier.kPublic;
            if (la.kind == 49 || la.kind == 50 || la.kind == 51) {
                Associative_AccessSpecifier(out access);
            }
            if (la.kind == 24) {
                ProtoCore.AST.AssociativeAST.AssociativeNode constr = null;
                Associative_constructordecl(out constr, access, attributes);
                if (String.IsNullOrEmpty(constr.Name))
                {
                   constr.Name= classnode.className;
                }
                classnode.funclist.Add(constr);

            } else if (StartOf(8)) {
                bool isStatic = false;
                if (la.kind == 39) {
                    Get();
                    isStatic = true;
                }
                if (la.kind == 25 || la.kind == 26) {
                    ProtoCore.AST.AssociativeAST.AssociativeNode funcnode;
                    Associative_functiondecl(out funcnode, attributes, access, isStatic);
                    classnode.funclist.Add(funcnode);
                } else if (la.kind == 1) {
                    ProtoCore.AST.AssociativeAST.AssociativeNode varnode = null;
                    Associative_vardecl(out varnode, access, isStatic, attributes);
                    classnode.varlist.Add(varnode);
                    if (la.val != ";")
                       SynErr("';' is expected.");

                    Expect(20);
                    NodeUtils.SetNodeEndLocation(varnode, t);
                } else if (la.kind == 20) {
                    Get();
                } else SynErr(76);
            } else SynErr(77);
            }
            Expect(45);
            isInClass = false; classnode.endLine = t.line; classnode.endCol = t.col;
            node = classnode;
        }
Пример #14
0
        private ClassDeclNode ParseSystemType(Type type, string alias)
        {
            Validity.Assert(!SupressesImport(type), "Supressed type is being imported!!");

            string classname = alias;

            if (classname == null | classname == string.Empty)
            {
                classname = CLRObjectMarshler.GetTypeName(type);
            }

            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname);
            classnode.ExternLibName = Module.Name;
            classnode.className     = classname;
            classnode.Name          = type.Name;
            Type baseType = GetBaseType(type);

            if (baseType != null && !CLRObjectMarshler.IsMarshaledAsNativeType(baseType))
            {
                string baseTypeName = CLRObjectMarshler.GetTypeName(baseType);

                classnode.superClass = new List <string>();
                classnode.superClass.Add(baseTypeName);
                //Make sure that base class is imported properly.
                CLRModuleType.GetInstance(baseType, Module, string.Empty);
            }

            // There is no static class in runtime. static class is simply
            // marked as sealed and abstract.
            bool isStaticClass = type.IsSealed && type.IsAbstract;

            if (!isStaticClass)
            {
                // If all methods are static, it doesn't make sense to expose
                // constructor.
                ConstructorInfo[] ctors = type.GetConstructors();
                foreach (var c in ctors)
                {
                    if (c.IsPublic && !c.IsGenericMethod && !SupressesImport(c))
                    {
                        ConstructorDefinitionNode node = ParseConstructor(c, type);
                        classnode.funclist.Add(node);

                        List <ProtoCore.Type> argTypes = GetArgumentTypes(node);
                        RegisterFunctionPointer(node.Name, c, argTypes, node.ReturnType);
                    }
                }
            }

            BindingFlags flags          = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static;
            bool         isDerivedClass = (classnode.superClass != null) && classnode.superClass.Count > 0;

            if (isDerivedClass)                     //has base class
            {
                flags |= BindingFlags.DeclaredOnly; //for derived class, parse only class declared methods.
            }
            bool isDisposable = typeof(IDisposable).IsAssignableFrom(type);

            MethodInfo[] methods          = type.GetMethods(flags);
            bool         hasDisposeMethod = false;

            foreach (var m in methods)
            {
                if (SupressesImport(m))
                {
                    continue;
                }

                if (isStaticClass && m.GetBaseDefinition().DeclaringType == baseType && baseType == typeof(object))
                {
                    continue;
                }

                //Don't include overriden methods or generic methods
                if (m.IsPublic && !m.IsGenericMethod && m == m.GetBaseDefinition())
                {
                    AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m);
                    classnode.funclist.Add(node);
                }
                else if (!hasDisposeMethod && isDisposable && baseType == typeof(Object) && isDisposeMethod(m))
                {
                    AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m);
                    classnode.funclist.Add(node);
                }
            }
            if (!hasDisposeMethod && !isDisposable)
            {
                AssociativeNode node = ParseAndRegisterFunctionPointer(true, ref hasDisposeMethod, mDisposeMethod);
                classnode.funclist.Add(node);
            }

            FieldInfo[] fields = type.GetFields();
            foreach (var f in fields)
            {
                if (SupressesImport(f))
                {
                    continue;
                }

                //Supress if defined in super-type
                if (isDerivedClass)
                {
                    FieldInfo[] supertypeFields = baseType.GetFields();

                    if (supertypeFields.Any(superF => superF.Name == f.Name))
                    {
                        continue;
                    }
                }


                VarDeclNode variable = ParseFieldDeclaration(f);
                if (null == variable)
                {
                    continue;
                }
                classnode.varlist.Add(variable);
                FunctionDefinitionNode func = ParseFieldAccessor(f);
                if (null != func)
                {
                    RegisterFunctionPointer(func.Name, f, null, func.ReturnType);
                }
            }

            PropertyInfo[] properties = type.GetProperties(flags);
            foreach (var p in properties)
            {
                AssociativeNode node = ParseProperty(p);
                if (null != node)
                {
                    classnode.varlist.Add(node);
                }
            }

            FFIClassAttributes cattrs = new FFIClassAttributes(type);

            classnode.ClassAttributes = cattrs;
            SetTypeAttributes(type, cattrs);

            return(classnode);
        }
Пример #15
0
        private void EmitMemberVariables(ClassDeclNode classDecl, GraphNode graphNode = null)
        {
            // Class member variable pass
            // Populating each class entry symbols with their respective member variables

            int thisClassIndex = core.ClassTable.GetClassId(classDecl.ClassName);
            globalClassIndex = thisClassIndex;

            if (!unPopulatedClasses.ContainsKey(thisClassIndex))
            {
                return;
            }
            ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[thisClassIndex];

            // Handle member vars from base class
            if (!string.IsNullOrEmpty(classDecl.BaseClass))
            {
                int baseClassIndex = core.ClassTable.GetClassId(classDecl.BaseClass);
                if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClassIndex)
                {
                    // To handle the case that a base class is defined after
                    // this class.
                    if (unPopulatedClasses.ContainsKey(baseClassIndex))
                    {
                        EmitMemberVariables(unPopulatedClasses[baseClassIndex], graphNode);
                        globalClassIndex = thisClassIndex;
                    }

                    ClassNode baseClass = core.ClassTable.ClassNodes[baseClassIndex];
                    // Append the members variables of every class that this class inherits from
                    foreach (ProtoCore.DSASM.SymbolNode symnode in baseClass.Symbols.symbolList.Values)
                    {
                        // It is a member variables
                        if (ProtoCore.DSASM.Constants.kGlobalScope == symnode.functionIndex)
                        {
                            Validity.Assert(!symnode.isArgument);
                            int symbolIndex = AllocateMemberVariable(thisClassIndex, symnode.isStatic ? symnode.classScope : baseClassIndex, symnode.name, symnode.datatype.rank, symnode.access, symnode.isStatic);

                            if (symbolIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                                thisClass.Size += ProtoCore.DSASM.Constants.kPointerSize;
                        }
                    }
                }
                else
                {
                    Validity.Assert(false, "n-pass compile error, fixme Jun....");
                }
            }

            foreach (VarDeclNode vardecl in classDecl.Variables)
            {
                IdentifierNode varIdent = vardecl.NameNode as IdentifierNode;
                int symbolIndex = AllocateMemberVariable(thisClassIndex, thisClassIndex, varIdent.Value, vardecl.ArgumentType.rank, vardecl.Access, vardecl.IsStatic);
                if (symbolIndex != Constants.kInvalidIndex && !classDecl.IsExternLib)
                {
                    ProtoCore.DSASM.SymbolNode prop =
                        vardecl.IsStatic
                        ? core.CodeBlockList[0].symbolTable.symbolList[symbolIndex]
                        : core.ClassTable.ClassNodes[thisClassIndex].Symbols.symbolList[symbolIndex];
                    string typeName = vardecl.ArgumentType.Name;
                    if (String.IsNullOrEmpty(typeName))
                    {
                        prop.datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, Constants.kArbitraryRank);
                    }
                    else
                    {
                        int type = core.TypeSystem.GetType(typeName);
                        if (type == (int)PrimitiveType.InvalidType)
                        {
                            string message = String.Format(ProtoCore.Properties.Resources.kTypeUndefined, typeName);
                            core.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.TypeUndefined, message, core.CurrentDSFileName, vardecl.line, vardecl.col, graphNode);
                            prop.datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0);
                        }
                        else
                        {
                            int rank = vardecl.ArgumentType.rank;
                            prop.datatype = core.TypeSystem.BuildTypeObject(type, rank);
                        }
                    }

                    EmitGetterForProperty(classDecl, prop);
                    EmitSetterForProperty(classDecl, prop);
                }
            }
            classOffset = 0;

            unPopulatedClasses.Remove(thisClassIndex);
        }
Пример #16
0
        private void EmitMemberVariables(ClassDeclNode classDecl, GraphNode graphNode = null)
        {
            // Class member variable pass
            // Populating each class entry symbols with their respective member variables

            int thisClassIndex = core.ClassTable.GetClassId(classDecl.ClassName);
            globalClassIndex = thisClassIndex;

            if (!unPopulatedClasses.ContainsKey(thisClassIndex))
            {
                return;
            }
            ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[thisClassIndex];

            // Handle member vars from base class
            if (null != classDecl.BaseClasses)
            {
                for (int n = 0; n < classDecl.BaseClasses.Count; ++n)
                {
                    int baseClassIndex = core.ClassTable.GetClassId(classDecl.BaseClasses[n]);
                    if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClassIndex)
                    {
                        // To handle the case that a base class is defined after
                        // this class.
                        if (unPopulatedClasses.ContainsKey(baseClassIndex))
                        {
                            EmitMemberVariables(unPopulatedClasses[baseClassIndex], graphNode);
                            globalClassIndex = thisClassIndex;
                        }

                        ClassNode baseClass = core.ClassTable.ClassNodes[baseClassIndex];
                        // Append the members variables of every class that this class inherits from
                        foreach (ProtoCore.DSASM.SymbolNode symnode in baseClass.Symbols.symbolList.Values)
                        {
                            // It is a member variables
                            if (ProtoCore.DSASM.Constants.kGlobalScope == symnode.functionIndex)
                            {
                                Validity.Assert(!symnode.isArgument);
                                int symbolIndex = AllocateMemberVariable(thisClassIndex, symnode.isStatic ? symnode.classScope : baseClassIndex, symnode.name, symnode.datatype.rank, symnode.access, symnode.isStatic);

                                if (symbolIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                                    thisClass.Size += ProtoCore.DSASM.Constants.kPointerSize;
                            }
                        }
                    }
                    else
                    {
                        Validity.Assert(false, "n-pass compile error, fixme Jun....");
                    }
                }
            }

            // This list will store all static properties initialization
            // expression (say x = 1).
            List<BinaryExpressionNode> staticPropertyInitList = new List<BinaryExpressionNode>();

            foreach (VarDeclNode vardecl in classDecl.Variables)
            {
                IdentifierNode varIdent = null;
                if (vardecl.NameNode is IdentifierNode)
                {   
                    varIdent = vardecl.NameNode as IdentifierNode;

                    BinaryExpressionNode bNode = new BinaryExpressionNode();

                    var thisNode =AstFactory.BuildIdentifier(ProtoCore.DSDefinitions.Keyword.This);
                    var propNode =AstFactory.BuildIdentifier(varIdent.Value);
                    bNode.LeftNode = AstFactory.BuildIdentList(thisNode, propNode);

                    NodeUtils.CopyNodeLocation(bNode, vardecl);
                    bNode.Optr = ProtoCore.DSASM.Operator.assign;

                    bool skipInitialization = false;

                    // Initialize it to default value by manually add the right hand side node
                    if (vardecl.ArgumentType.rank == 0)
                    {
                        switch (vardecl.ArgumentType.Name)
                        {
                            case "double": bNode.RightNode = new DoubleNode(0); break;
                            case "int": bNode.RightNode = new IntNode(0); break;
                            case "bool": bNode.RightNode = new BooleanNode(false); break;
                            default: skipInitialization = true; break;
                        }
                    }
                    else if (vardecl.ArgumentType.rank > 0)
                    {
                        if (!vardecl.ArgumentType.Name.Equals("var"))
                            bNode.RightNode = new ExprListNode();
                        else
                            skipInitialization = true;
                    }
                    else if(vardecl.ArgumentType.rank.Equals(ProtoCore.DSASM.Constants.kArbitraryRank))
                    {
                        if (!vardecl.ArgumentType.Name.Equals("var"))
                            bNode.RightNode = new NullNode();
                        else
                            skipInitialization = true;
                    }

                    if (!skipInitialization)
                    {
                        if (vardecl.IsStatic)
                            staticPropertyInitList.Add(bNode);
                        else
                            thisClass.DefaultArgExprList.Add(bNode);
                    }
                }
                else if (vardecl.NameNode is BinaryExpressionNode)
                {
                    BinaryExpressionNode bNode = vardecl.NameNode as BinaryExpressionNode;
                    varIdent = bNode.LeftNode as IdentifierNode;

                    bNode.endCol = vardecl.endCol;
                    bNode.endLine = vardecl.endLine;

                    if (vardecl.IsStatic)
                        staticPropertyInitList.Add(bNode);
                    else
                        thisClass.DefaultArgExprList.Add(bNode);
                }
                else
                {
                    Validity.Assert(false, "Check generated AST");
                }

                // It is possible that fail to allocate variable. In that 
                // case we should remove initializing expression from 
                // cnode's defaultArgExprList
                int symbolIndex = AllocateMemberVariable(thisClassIndex, thisClassIndex, varIdent.Value, vardecl.ArgumentType.rank, vardecl.Access, vardecl.IsStatic);
                if (symbolIndex == ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    Validity.Assert(thisClass.DefaultArgExprList.Count > 0);
                    thisClass.DefaultArgExprList.RemoveAt(thisClass.DefaultArgExprList.Count - 1);
                }
                // Only generate getter/setter for non-ffi class
                else if (!classDecl.IsExternLib)
                {
                    ProtoCore.DSASM.SymbolNode prop =
                        vardecl.IsStatic
                        ? core.CodeBlockList[0].symbolTable.symbolList[symbolIndex]
                        : core.ClassTable.ClassNodes[thisClassIndex].Symbols.symbolList[symbolIndex];
                    string typeName = vardecl.ArgumentType.Name;
                    if (String.IsNullOrEmpty(typeName))
                    {
                        prop.datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, Constants.kArbitraryRank);
                    }
                    else
                    {
                        int type = core.TypeSystem.GetType(typeName);
                        if (type == (int)PrimitiveType.kInvalidType)
                        {
                            string message = String.Format(ProtoCore.Properties.Resources.kTypeUndefined, typeName);
                            core.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, core.CurrentDSFileName, vardecl.line, vardecl.col, graphNode);
                            prop.datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);
                        }
                        else
                        {
                            int rank = vardecl.ArgumentType.rank;
                            prop.datatype = core.TypeSystem.BuildTypeObject(type, rank);
                            if (type != (int)PrimitiveType.kTypeVar || prop.datatype.IsIndexable)
                            {
                                prop.staticType = prop.datatype;
                            }
                        }
                    }

                    EmitGetterForProperty(classDecl, prop);
                    EmitSetterForProperty(classDecl, prop);
                }
            }
            classOffset = 0;

            // Now we are going to create a static function __init_static_properties()
            // which will initialize all static properties. We will emit a 
            // call to this function after all classes have been compiled.
            if (staticPropertyInitList.Count > 0 && !classDecl.IsExternLib)
            {
                FunctionDefinitionNode initFunc = new FunctionDefinitionNode
                {
                    Name = ProtoCore.DSASM.Constants.kStaticPropertiesInitializer,
                    Signature = new ArgumentSignatureNode(),
                    Pattern = null,
                    ReturnType = new ProtoCore.Type { Name = core.TypeSystem.GetType((int)PrimitiveType.kTypeNull), UID = (int)PrimitiveType.kTypeNull },
                    FunctionBody = new CodeBlockNode(),
                    IsExternLib = false,
                    IsDNI = false,
                    ExternLibName = null,
                    Access = ProtoCore.CompilerDefinitions.AccessModifier.kPublic,
                    IsStatic = true
                };
                classDecl.Procedures.Add(initFunc);

                staticPropertyInitList.ForEach(bNode => initFunc.FunctionBody.Body.Add(bNode));
                initFunc.FunctionBody.Body.Add(AstFactory.BuildReturnStatement(new NullNode()));
            }

            unPopulatedClasses.Remove(thisClassIndex);
        }
Пример #17
0
        /// <summary>
        /// Determines if a class is allowed to be codegened based on certain conditions in the class node
        /// </summary>
        /// <param name="classNode"></param>
        /// <returns></returns>
        private bool IsClassAllowed(ClassDeclNode classDecl)
        {
            // If its an FFI class, it is allowed
            if (classDecl.IsExternLib)
            {
                return true;
            }

            // Check the class attributes
            if (classDecl.Attributes != null)
            {
                // If at least one attribute is internal then the class is allowed
                List<AttributeEntry> attributesList = PopulateAttributes(classDecl.Attributes);
                if (attributesList.Where(a => a.IsInternalClassAttribute()).Count() > 0)
                {
                    return true;
                }
            }
            return false;
        }
Пример #18
0
 public void DFSTraverse(ref AST.AssociativeAST.AssociativeNode node)
 {
     if (node is AST.AssociativeAST.IdentifierNode)
     {
         EmitIdentifierNode(ref node);
     }
     else if (node is ProtoCore.AST.AssociativeAST.IdentifierListNode)
     {
         AST.AssociativeAST.IdentifierListNode identList = node as ProtoCore.AST.AssociativeAST.IdentifierListNode;
         EmitIdentifierListNode(ref identList);
     }
     else if (node is ProtoCore.AST.AssociativeAST.IntNode)
     {
         AST.AssociativeAST.IntNode intNode = node as ProtoCore.AST.AssociativeAST.IntNode;
         EmitIntNode(ref intNode);
     }
     else if (node is ProtoCore.AST.AssociativeAST.DoubleNode)
     {
         AST.AssociativeAST.DoubleNode doubleNode = node as ProtoCore.AST.AssociativeAST.DoubleNode;
         EmitDoubleNode(ref doubleNode);
     }
     else if (node is ProtoCore.AST.AssociativeAST.FunctionCallNode)
     {
         AST.AssociativeAST.FunctionCallNode funcCallNode = node as ProtoCore.AST.AssociativeAST.FunctionCallNode;
         EmitFunctionCallNode(ref funcCallNode);
     }
     else if (node is ProtoCore.AST.AssociativeAST.FunctionDotCallNode)
     {
         AST.AssociativeAST.FunctionDotCallNode funcDotCall = node as ProtoCore.AST.AssociativeAST.FunctionDotCallNode;
         EmitFunctionDotCallNode(ref funcDotCall);
     }
     else if (node is ProtoCore.AST.AssociativeAST.BinaryExpressionNode)
     {
         ProtoCore.AST.AssociativeAST.BinaryExpressionNode binaryExpr = node as ProtoCore.AST.AssociativeAST.BinaryExpressionNode;
         if (binaryExpr.Optr != DSASM.Operator.assign)
         {
             ;
         }
         //EmitCode("(");
         EmitBinaryNode(ref binaryExpr);
         if (binaryExpr.Optr == DSASM.Operator.assign)
         {
             //EmitCode(ProtoCore.DSASM.Constants.termline);
         }
         if (binaryExpr.Optr != DSASM.Operator.assign)
         {
             ;
         }
         //EmitCode(")");
     }
     else if (node is ProtoCore.AST.AssociativeAST.FunctionDefinitionNode)
     {
         AST.AssociativeAST.FunctionDefinitionNode funcDefNode = node as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode;
         EmitFunctionDefNode(ref funcDefNode);
     }
     else if (node is ProtoCore.AST.AssociativeAST.ClassDeclNode)
     {
         AST.AssociativeAST.ClassDeclNode classDeclNode = node as ProtoCore.AST.AssociativeAST.ClassDeclNode;
         EmitClassDeclNode(ref classDeclNode);
     }
     else if (node is ProtoCore.AST.AssociativeAST.NullNode)
     {
         AST.AssociativeAST.NullNode nullNode = node as ProtoCore.AST.AssociativeAST.NullNode;
         EmitNullNode(ref nullNode);
     }
     else if (node is ProtoCore.AST.AssociativeAST.ArrayIndexerNode)
     {
         AST.AssociativeAST.ArrayIndexerNode arrIdxNode = node as ProtoCore.AST.AssociativeAST.ArrayIndexerNode;
         EmitArrayIndexerNode(ref arrIdxNode);
     }
     else if (node is ProtoCore.AST.AssociativeAST.ExprListNode)
     {
         AST.AssociativeAST.ExprListNode exprListNode = node as ProtoCore.AST.AssociativeAST.ExprListNode;
         EmitExprListNode(ref exprListNode);
     }
 }