Exemplo n.º 1
0
        private ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode ParseConstructor(ConstructorInfo c, System.Type type)
        {
            //Constructors should always return user defined type object, hence it should be pointer type.
            ProtoCore.Type selfType = ProtoCoreType;

            ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = ParsedNamedConstructor(c, type.Name, selfType);
            return(constr);
        }
Exemplo n.º 2
0
        private ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode ParsedNamedConstructor(MethodBase method, string constructorName, ProtoCore.Type returnType)
        {
            ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = new ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode();
            constr.Name          = constructorName;
            constr.Pattern       = null;
            constr.Signature     = ParseArgumentSignature(method);
            constr.ReturnType    = returnType;
            constr.FunctionBody  = null;
            constr.access        = ProtoCore.DSASM.AccessSpecifier.kPublic;
            constr.IsExternLib   = true;
            constr.ExternLibName = Module.Name;

            return(constr);
        }
Exemplo n.º 3
0
        private void EmitClassDeclNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone,
            GraphNode graphNode = null)
        {
            ClassDeclNode classDecl = node as ClassDeclNode;
            
            // Restrict classes 
            if (!IsClassAllowed(classDecl))
            {
                return;
            }
            // Handling n-pass on class declaration
            if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassName == compilePass)
            {
                // Class name pass
                // Populating the class tables with the class names
                if (null != codeBlock.parent)
                {
                    buildStatus.LogSemanticError(Resources.ClassCannotBeDefinedInsideLanguageBlock, core.CurrentDSFileName, classDecl.line, classDecl.col);
                }


                ProtoCore.DSASM.ClassNode thisClass = new ProtoCore.DSASM.ClassNode();
                thisClass.Name = classDecl.ClassName;
                thisClass.Size = classDecl.Variables.Count;
                thisClass.IsImportedClass = classDecl.IsImportedClass;
                thisClass.TypeSystem = core.TypeSystem;
                thisClass.ClassAttributes = classDecl.ClassAttributes;
                
                if (classDecl.ExternLibName != null)
                    thisClass.ExternLib = classDecl.ExternLibName;
                else
                    thisClass.ExternLib = Path.GetFileName(core.CurrentDSFileName);

                globalClassIndex = core.ClassTable.Append(thisClass);
                if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex)
                {
                    string message = string.Format("Class redefinition '{0}' (BE1C3285).\n", classDecl.ClassName);
                    buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col);
                    throw new BuildHaltException(message);
                }

                unPopulatedClasses.Add(globalClassIndex, classDecl);

                //Always allow us to convert a class to a bool
                thisClass.CoerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            }
            else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassBaseClass == compilePass)
            { 
                // Base class pass
                // Populating each class entry with their immediate baseclass
                globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName);

                ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[globalClassIndex];

                // Verify and store the list of classes it inherits from 
                if (null != classDecl.BaseClasses)
                {
                    for (int n = 0; n < classDecl.BaseClasses.Count; ++n)
                    {
                        int baseClass = core.ClassTable.GetClassId(classDecl.BaseClasses[n]);
                        if (baseClass == globalClassIndex)
                        {
                            string message = string.Format("Class '{0}' cannot derive from itself (DED0A61F).\n", classDecl.ClassName);
                            buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col);
                            throw new BuildHaltException(message);
                        }

                        if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass)
                        {
                            if (core.ClassTable.ClassNodes[baseClass].IsImportedClass && !thisClass.IsImportedClass)
                            {
                                string message = string.Format("Cannot derive from FFI class {0} (DA87AC4D).\n",
                                    core.ClassTable.ClassNodes[baseClass].Name);

                                buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col);
                                throw new BuildHaltException(message);
                            }

                            thisClass.Bases.Add(baseClass);
                            thisClass.CoerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass);
                        }
                        else
                        {
                            string message = string.Format("Unknown base class '{0}' (9E44FFB3).\n", classDecl.BaseClasses[n]);
                            buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col);
                            throw new BuildHaltException(message);
                        }
                    }
                }
            }
            else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassHierarchy == compilePass)
            {
                // Class hierarchy pass
                // Populating each class entry with all sub classes in the hierarchy
                globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName);

                ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[globalClassIndex];

                // Verify and store the list of classes it inherits from 
                if (null != classDecl.BaseClasses)
                {
                    for (int n = 0; n < classDecl.BaseClasses.Count; ++n)
                    {
                        int baseClass = core.ClassTable.GetClassId(classDecl.BaseClasses[n]);

                        // baseClass is already resovled in the previous pass
                        Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != baseClass);

                            
                        // Iterate through all the base classes until the the root class
                        // For every base class, add the coercion score
                        ProtoCore.DSASM.ClassNode tmpCNode = core.ClassTable.ClassNodes[baseClass];
                        if (tmpCNode.Bases.Count > 0)
                        {
                            baseClass = tmpCNode.Bases[0];
                            while (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass)
                            {
                                thisClass.CoerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass);
                                tmpCNode = core.ClassTable.ClassNodes[baseClass];

                                baseClass = ProtoCore.DSASM.Constants.kInvalidIndex;
                                if (tmpCNode.Bases.Count > 0)
                                {
                                    baseClass = tmpCNode.Bases[0];
                                }
                            }
                        }
                    }
                }
            }
            else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemVar == compilePass)
            {
                EmitMemberVariables(classDecl, graphNode);
            }
            else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemFuncSig == compilePass)
            {
                // Class member variable pass
                // Populating each class entry vtables with their respective
                // member variables signatures
                globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName);

                List<AssociativeNode> thisPtrOverloadList = new List<AssociativeNode>();
                foreach (AssociativeNode funcdecl in classDecl.Procedures)
                {
                    DfsTraverse(funcdecl, ref inferedType);

                    var funcDef = funcdecl as FunctionDefinitionNode;
                    if (funcDef == null || funcDef.IsStatic || funcDef.Name == ProtoCore.DSDefinitions.Keyword.Dispose)
                        continue;

                    bool isGetterSetter = CoreUtils.IsGetterSetter(funcDef.Name);

                    var thisPtrArgName = Constants.kThisPointerArgName;
                    if (!isGetterSetter)
                    {
                        var classsShortName = classDecl.ClassName.Split('.').Last();
                        var typeDepName = classsShortName.ToLower();
                        if (typeDepName != classsShortName && funcDef.Signature.Arguments.All(a => a.NameNode.Name != typeDepName))
                            thisPtrArgName = typeDepName;
                    }

                    // This is a function, create its parameterized this pointer overload
                    ThisPointerProcOverload thisProc = new ThisPointerProcOverload();
                    thisProc.classIndex = globalClassIndex;
                    thisProc.procNode = new FunctionDefinitionNode(funcDef);
                    var thisPtrArg = new VarDeclNode()
                    {
                        Access = ProtoCore.CompilerDefinitions.AccessModifier.kPublic,
                        NameNode = AstFactory.BuildIdentifier(thisPtrArgName),
                        ArgumentType = new ProtoCore.Type { Name = classDecl.ClassName, UID = globalClassIndex, rank = 0 }
                    };
                    thisProc.procNode.Signature.Arguments.Insert(0, thisPtrArg);
                    thisProc.procNode.IsAutoGeneratedThisProc = true;

                    if (CoreUtils.IsGetterSetter(funcDef.Name))
                    {
                        InsertThisPointerAtBody(thisProc);
                    }
                    else
                    {
                        // Generate a static function for member function f():
                        //     satic def f(a: A)
                        //     { 
                        //        return = a.f()
                        //     }
                        thisProc.procNode.IsStatic = true;
                        BuildThisFunctionBody(thisProc);
                    }

                    thisPtrOverloadList.Add(thisProc.procNode);
                }

                foreach (var overloadFunc in thisPtrOverloadList)
                {
                    // Emit the newly defined overloads
                    DfsTraverse(overloadFunc, ref inferedType);
                }

                classDecl.Procedures.AddRange(thisPtrOverloadList);

                if (!classDecl.IsExternLib)
                {
                    ProtoCore.DSASM.ProcedureTable vtable = core.ClassTable.ClassNodes[globalClassIndex].ProcTable;
                    if (vtable.GetFunctionBySignature(classDecl.ClassName, new List<ProtoCore.Type>()) == null)
                    {
                        ConstructorDefinitionNode defaultConstructor = new ConstructorDefinitionNode();
                        defaultConstructor.Name = classDecl.ClassName;
                        defaultConstructor.LocalVariableCount = 0;
                        defaultConstructor.Signature = new ArgumentSignatureNode();
                        defaultConstructor.ReturnType = new ProtoCore.Type { Name = "var", UID = 0 };
                        defaultConstructor.FunctionBody = new CodeBlockNode();
                        defaultConstructor.BaseConstructor = null;
                        defaultConstructor.Access = ProtoCore.CompilerDefinitions.AccessModifier.kPublic;
                        defaultConstructor.IsExternLib = false;
                        defaultConstructor.ExternLibName = null;
                        DfsTraverse(defaultConstructor, ref inferedType);
                        classDecl.Procedures.Add(defaultConstructor);
                    }
                }
            }
            else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kGlobalScope == compilePass)
            {
                // before populate the attributes, we must know the attribute class constructor signatures
                // in order to check the parameter 
                // populate the attributes for the class and class member variable 
                globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName);
                if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[globalClassIndex];
                    // class
                    if (classDecl.Attributes != null)
                    {
                        thisClass.Attributes = PopulateAttributes(classDecl.Attributes);
                    }

                    // member variable
                    int ix = -1;
                    int currentClassScope = -1;
                    foreach (ProtoCore.DSASM.SymbolNode sn in thisClass.Symbols.symbolList.Values)
                    {
                        // only populate the attributes for member variabls
                        if (sn.functionIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                            continue;
                        if (sn.classScope != globalClassIndex)
                        {
                            if (currentClassScope != sn.classScope)
                            {
                                currentClassScope = sn.classScope;
                                ix = 0;
                            }
                            // copy attribute information from base class
                            sn.Attributes = core.ClassTable.ClassNodes[currentClassScope].Symbols.symbolList[ix++].Attributes;
                        }
                        else
                        {
                            if (currentClassScope != globalClassIndex)
                            {
                                currentClassScope = globalClassIndex;
                                ix = 0;
                            }
                        }
                    }
                }
            }
            else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemFuncBody == compilePass)
            {
                // Class member variable pass
                // Populating the function body of each member function defined in the class vtables

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

                // Initialize the global function table for this class
                // 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables
                int classIndexAtCallsite = globalClassIndex + 1;
                core.FunctionTable.InitGlobalFunctionEntry(classIndexAtCallsite);

                foreach (AssociativeNode funcdecl in classDecl.Procedures)
                {
                    // reset the inferedtype between functions
                    inferedType = new ProtoCore.Type();
                    DfsTraverse(funcdecl, ref inferedType, false, null, subPass);
                }
            }

            // Reset the class index
            core.ClassIndex = globalClassIndex = ProtoCore.DSASM.Constants.kGlobalScope;
        }
Exemplo n.º 4
0
        private void EmitClassDeclNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            ClassDeclNode classDecl = node as ClassDeclNode;

            // Handling n-pass on class declaration
            if (ProtoCore.DSASM.AssociativeCompilePass.kClassName == compilePass)
            {
                // Class name pass
                // Populating the class tables with the class names
                if (null != codeBlock.parent)
                {
                    buildStatus.LogSemanticError("A class cannot be defined inside a language block.\n", compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col);
                }

                if (ProtoCore.DSASM.Constants.kInvalidIndex != compileStateTracker.ClassTable.IndexOf(classDecl.className))
                {
                    string message = string.Format("Class redefinition '{0}' (BE1C3285).\n", classDecl.className);
                    buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col);
                    throw new BuildHaltException(message);
                }

                ProtoCore.DSASM.ClassNode thisClass = new ProtoCore.DSASM.ClassNode();
                thisClass.name = classDecl.className;
                thisClass.size = classDecl.varlist.Count;
                thisClass.IsImportedClass = classDecl.IsImportedClass;
                thisClass.typeSystem = compileStateTracker.TypeSystem;

                if (classDecl.ExternLibName != null)
                    thisClass.ExternLib = classDecl.ExternLibName;
                else
                    thisClass.ExternLib = Path.GetFileName(compileStateTracker.CurrentDSFileName);

                globalClassIndex = compileStateTracker.ClassTable.Append(thisClass);
                unPopulatedClasses.Add(globalClassIndex, classDecl);

                //Always allow us to convert a class to a bool
                thisClass.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            }
            else if (ProtoCore.DSASM.AssociativeCompilePass.kClassHeirarchy == compilePass)
            {
                // Class heirarchy pass
                // Populating each class entry with their respective base classes
                globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className);

                ProtoCore.DSASM.ClassNode thisClass = compileStateTracker.ClassTable.ClassNodes[globalClassIndex];

                // Verify and store the list of classes it inherits from
                if (null != classDecl.superClass)
                {
                    for (int n = 0; n < classDecl.superClass.Count; ++n)
                    {
                        int baseClass = compileStateTracker.ClassTable.IndexOf(classDecl.superClass[n]);
                        if (baseClass == globalClassIndex)
                        {
                            string message = string.Format("Class '{0}' cannot derive from itself (DED0A61F).\n", classDecl.className);
                            buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col);
                            throw new BuildHaltException(message);
                        }

                        if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass)
                        {
                            if (compileStateTracker.ClassTable.ClassNodes[baseClass].IsImportedClass && !thisClass.IsImportedClass)
                            {
                                string message = string.Format("Cannot derive from FFI class {0} (DA87AC4D).\n",
                                    compileStateTracker.ClassTable.ClassNodes[baseClass].name);

                                buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col);
                                throw new BuildHaltException(message);
                            }

                            thisClass.baseList.Add(baseClass);
                            thisClass.coerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass);

                            // Iterate through all the base classes until the the root class
                            // For every base class, add the coercion score

                            // TODO Jun: -Integrate this with multiple inheritace when supported
                            //           -Cleansify
                            ProtoCore.DSASM.ClassNode tmpCNode = compileStateTracker.ClassTable.ClassNodes[baseClass];
                            if (tmpCNode.baseList.Count > 0)
                            {
                                baseClass = tmpCNode.baseList[0];
                                while (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass)
                                {
                                    thisClass.coerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass);
                                    tmpCNode = compileStateTracker.ClassTable.ClassNodes[baseClass];

                                    baseClass = ProtoCore.DSASM.Constants.kInvalidIndex;
                                    if (tmpCNode.baseList.Count > 0)
                                    {
                                        baseClass = tmpCNode.baseList[0];
                                    }
                                }
                            }
                        }
                        else
                        {
                            string message = string.Format("Unknown base class '{0}' (9E44FFB3).\n", classDecl.superClass[n]);
                            buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col);
                            throw new BuildHaltException(message);
                        }
                    }
                }
            }
            else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemVar == compilePass)
            {
                EmitMemberVariables(classDecl);
            }
            else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncSig == compilePass)
            {
                // Class member variable pass
                // Populating each class entry vtables with their respective member variables signatures

                globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className);
                List<AssociativeNode> thisPtrOverloadList = new List<AssociativeNode>();
                foreach (AssociativeNode funcdecl in classDecl.funclist)
                {
                    DfsTraverse(funcdecl, ref inferedType);

                    // If this is a function, create its parameterized this pointer overload
                    if (funcdecl is ProtoCore.AST.AssociativeAST.FunctionDefinitionNode)
                    {
                        string procName = (funcdecl as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode).Name;

                        bool isFunctionExcluded = procName.Equals(ProtoCore.DSASM.Constants.kStaticPropertiesInitializer);

                        // TODO Jun: There is a current limitation of not supporting classes yet at live execution
                        // Fix this soon - the first fix would be in import load and unload for every delta run
                        //if (!core.Options.IsDeltaExecution)
                        if (!compileStateTracker.Options.IsDeltaExecution)
                        {
                            if (!isFunctionExcluded)
                            {
                                ThisPointerProcOverload thisProc = new ThisPointerProcOverload();
                                thisProc.classIndex = globalClassIndex;

                                thisProc.procNode = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode(funcdecl as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode);
                                thisProc.procNode.IsAutoGeneratedThisProc = true;

                                InsertThisPointerArg(thisProc);
                                //InsertThisPointerAtBody(thisProc);

                                if (ProtoCore.Utils.CoreUtils.IsGetterSetter(procName))
                                {
                                    InsertThisPointerAtBody(thisProc);
                                }
                                else
                                {
                                    // This is a normal function
                                    // the body thsould be the actaul function called through the this pointer argument
                                    //
                                    // def f() { return = 1 }
                                    // def f(%this : A) { return = %this.f()}
                                    //
                                    BuildThisFunctionBody(thisProc);
                                }

                                // Emit the newly defined overloads
                                DfsTraverse(thisProc.procNode, ref inferedType);

                                thisPtrOverloadList.Add(thisProc.procNode);
                            }
                        }
                    }

                }
                classDecl.funclist.AddRange(thisPtrOverloadList);

                if (!classDecl.IsExternLib)
                {
                    ProtoCore.DSASM.ProcedureTable vtable = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable;
                    if (vtable.IndexOfExact(classDecl.className, new List<ProtoCore.Type>()) == ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        ConstructorDefinitionNode defaultConstructor = new ConstructorDefinitionNode();
                        defaultConstructor.Name = classDecl.className;
                        defaultConstructor.localVars = 0;
                        defaultConstructor.Signature = new ArgumentSignatureNode();
                        defaultConstructor.Pattern = null;
                        defaultConstructor.ReturnType = new ProtoCore.Type { Name = "var", UID = 0 };
                        defaultConstructor.FunctionBody = new CodeBlockNode();
                        defaultConstructor.baseConstr = null;
                        defaultConstructor.access = ProtoCore.DSASM.AccessSpecifier.kPublic;
                        defaultConstructor.IsExternLib = false;
                        defaultConstructor.ExternLibName = null;
                        DfsTraverse(defaultConstructor, ref inferedType);
                        classDecl.funclist.Add(defaultConstructor);
                    }
                }
            }
            else if (ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope == compilePass)
            {
                // before populate the attributes, we must know the attribute class constructor signatures
                // in order to check the parameter
                // populate the attributes for the class and class member variable
                globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className);
                if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    ProtoCore.DSASM.ClassNode thisClass = compileStateTracker.ClassTable.ClassNodes[globalClassIndex];
                    // class
                    if (classDecl.Attributes != null)
                    {
                        thisClass.Attributes = PopulateAttributes(classDecl.Attributes);
                    }
                    // member variable
                    int ix = -1;
                    int currentClassScope = -1;
                    foreach (ProtoCore.DSASM.SymbolNode sn in thisClass.symbols.symbolList.Values)
                    {
                        // only populate the attributes for member variabls
                        if (sn.functionIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                            continue;
                        if (sn.classScope != globalClassIndex)
                        {
                            if (currentClassScope != sn.classScope)
                            {
                                currentClassScope = sn.classScope;
                                ix = 0;
                            }
                            // copy attribute information from base class
                            sn.Attributes = compileStateTracker.ClassTable.ClassNodes[currentClassScope].symbols.symbolList[ix++].Attributes;
                        }
                        else
                        {
                            if (currentClassScope != globalClassIndex)
                            {
                                currentClassScope = globalClassIndex;
                                ix = 0;
                            }
                            ProtoCore.AST.AssociativeAST.VarDeclNode varnode = classDecl.varlist[ix++] as ProtoCore.AST.AssociativeAST.VarDeclNode;
                            sn.Attributes = PopulateAttributes((varnode).Attributes);
                        }
                    }
                }
            }
            else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncBody == compilePass)
            {
                // Class member variable pass
                // Populating the function body of each member function defined in the class vtables

                globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className);

                foreach (AssociativeNode funcdecl in classDecl.funclist)
                {
                    // reset the inferedtype between functions
                    inferedType = new ProtoCore.Type();
                    DfsTraverse(funcdecl, ref inferedType, false, null, subPass);
                }
            }

            // Reset the class index
            compileStateTracker.ClassIndex = globalClassIndex = ProtoCore.DSASM.Constants.kGlobalScope;
        }
Exemplo n.º 5
0
        private ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode ParsedNamedConstructor(MethodBase method, string constructorName, ProtoCore.Type returnType)
        {
            ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = new ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode();
            constr.Name = constructorName;
            constr.Pattern = null;
            constr.Signature = ParseArgumentSignature(method);
            constr.ReturnType = returnType;
            constr.FunctionBody = null;
            constr.access = ProtoCore.Compiler.AccessSpecifier.kPublic;
            constr.IsExternLib = true;
            constr.ExternLibName = Module.Name;

            return constr;
        }
Exemplo n.º 6
0
        private void EmitClassDeclNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            ClassDeclNode classDecl = node as ClassDeclNode;

            // Handling n-pass on class declaration
            if (ProtoCore.DSASM.AssociativeCompilePass.kClassName == compilePass)
            {
                ProtoCore.DSASM.ClassNode cnode = new ProtoCore.DSASM.ClassNode();
                cnode.name = classDecl.className;
                cnode.size = classDecl.varlist.Count;
                cnode.IsImportedClass = classDecl.IsImportedClass;
                cnode.typeSystem = core.TypeSystem;
                globalClassIndex = core.ClassTable.Append(cnode);
                CodeRangeTable.AddClassBlockRangeEntry(globalClassIndex,
                    classDecl.line,
                    classDecl.col,
                    classDecl.endLine,
                    classDecl.endCol,
                    core.CurrentDSFileName);
            }
            else if (ProtoCore.DSASM.AssociativeCompilePass.kClassHeirarchy == compilePass)
            {
                // Class heirarchy pass
                // Populating each class entry with their respective base classes
                globalClassIndex = core.ClassTable.IndexOf(classDecl.className);

                ProtoCore.DSASM.ClassNode cnode = core.ClassTable.ClassNodes[globalClassIndex];

                if (null != classDecl.superClass)
                {
                    for (int n = 0; n < classDecl.superClass.Count; ++n)
                    {
                        int baseClass = core.ClassTable.IndexOf(classDecl.superClass[n]);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass)
                        {
                            cnode.baseList.Add(baseClass);
                            cnode.coerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass);
                        }
                    }
                }

            }
            else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemVar == compilePass)
            {
                // Class member variable pass
                // Populating each class entry symbols with their respective member variables

                globalClassIndex = core.ClassTable.IndexOf(classDecl.className);
                ProtoCore.DSASM.ClassNode cnode = core.ClassTable.ClassNodes[globalClassIndex];

                // Handle member vars from base class
                if (null != classDecl.superClass)
                {
                    for (int n = 0; n < classDecl.superClass.Count; ++n)
                    {
                        int baseClass = core.ClassTable.IndexOf(classDecl.superClass[n]);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass)
                        {
                            // Append the members variables of every class that this class inherits from
                            foreach (ProtoCore.DSASM.SymbolNode symnode in core.ClassTable.ClassNodes[baseClass].symbols.symbolList.Values)
                            {
                                // It is a member variables
                                if (ProtoCore.DSASM.Constants.kGlobalScope == symnode.functionIndex)
                                {
                                    Debug.Assert(!symnode.isArgument);
                                    int symbolIndex = AllocateMemberVariable(globalClassIndex, symnode.isStatic ? symnode.classScope : baseClass, symnode.name, symnode.datatype, symnode.access, symnode.isStatic);

                                    if (symbolIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                                        cnode.size += ProtoCore.DSASM.Constants.kPointerSize;
                                }
                            }
                        }
                        else
                        {
                            Debug.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.varlist)
                {
                    IdentifierNode varIdent = null;
                    if (vardecl.NameNode is IdentifierNode)
                    {
                        varIdent = vardecl.NameNode as IdentifierNode;
                    }
                    else if (vardecl.NameNode is BinaryExpressionNode)
                    {
                        BinaryExpressionNode bNode = vardecl.NameNode as BinaryExpressionNode;
                        varIdent = bNode.LeftNode as IdentifierNode;
                        if (vardecl.IsStatic)
                            staticPropertyInitList.Add(bNode);
                        else
                            cnode.defaultArgExprList.Add(bNode);
                    }
                    else
                    {
                        Debug.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
                    ProtoCore.Type datatype = vardecl.ArgumentType;
                    if (string.IsNullOrEmpty(vardecl.ArgumentType.Name))
                        datatype.UID = (int)PrimitiveType.kTypeVar;
                    else
                    {
                        datatype.UID = core.TypeSystem.GetType(vardecl.ArgumentType.Name);
                        if (datatype.UID == ProtoCore.DSASM.Constants.kInvalidIndex)
                            datatype.UID = (int)PrimitiveType.kTypeVar;
                    }
                    datatype.Name = core.TypeSystem.GetType(datatype.UID);
                    int symbolIndex = ProtoCore.DSASM.Constants.kInvalidIndex;

                    if (varIdent is ProtoCore.AST.AssociativeAST.TypedIdentifierNode)
                        symbolIndex = AllocateTypedMemberVariable(globalClassIndex, globalClassIndex, varIdent.Value, datatype, vardecl.access, vardecl.IsStatic);
                    else
                        symbolIndex = AllocateMemberVariable(globalClassIndex, globalClassIndex, varIdent.Value, datatype, vardecl.access, vardecl.IsStatic);

                    if (symbolIndex != ProtoCore.DSASM.Constants.kInvalidIndex &&
                        !classDecl.IsExternLib)
                    {
                        ProtoCore.DSASM.SymbolNode memVar =
                            vardecl.IsStatic
                            ? core.CodeBlockList[0].symbolTable.symbolList[symbolIndex]
                            : core.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[symbolIndex];

                        EmitGetterForMemVar(classDecl, memVar);
                        EmitSetterForMemVar(classDecl, memVar);
                    }
                }
                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)
                {
                    FunctionDefinitionNode initFunc = new FunctionDefinitionNode()
                    {
                        Name = ProtoCore.DSASM.Constants.kStaticPropertiesInitializer,
                        Singnature = 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.DSASM.AccessSpecifier.kPublic,
                        IsStatic = true
                    };
                    classDecl.funclist.Add(initFunc);

                    staticPropertyInitList.ForEach(bNode => initFunc.FunctionBody.Body.Add(bNode));
                    initFunc.FunctionBody.Body.Add(new BinaryExpressionNode()
                    {
                        LeftNode = new IdentifierNode()
                        {
                            Value = ProtoCore.DSDefinitions.Kw.kw_return,
                            Name = ProtoCore.DSDefinitions.Kw.kw_return,
                            datatype = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeReturn, false)
                        },
                        Optr = ProtoCore.DSASM.Operator.assign,
                        RightNode = new NullNode()
                    });
                }
            }
            else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncSig == compilePass)
            {
                // Class member variable pass
                // Populating each class entry vtables with their respective member variables signatures

                globalClassIndex = core.ClassTable.IndexOf(classDecl.className);
                foreach (AssociativeNode funcdecl in classDecl.funclist)
                {
                    DfsTraverse(funcdecl, ref inferedType);
                }

                if (!classDecl.IsExternLib)
                {
                    ProtoCore.DSASM.ProcedureTable vtable = core.ClassTable.ClassNodes[globalClassIndex].vtable;
                    if (vtable.IndexOfExact(classDecl.className, new List<ProtoCore.Type>()) == ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        ConstructorDefinitionNode defaultConstructor = new ConstructorDefinitionNode();
                        defaultConstructor.Name = classDecl.className;
                        defaultConstructor.localVars = 0;
                        defaultConstructor.Signature = new ArgumentSignatureNode();
                        defaultConstructor.Pattern = null;
                        defaultConstructor.ReturnType = new ProtoCore.Type { Name = "var", UID = 0 };
                        defaultConstructor.FunctionBody = new CodeBlockNode();
                        defaultConstructor.baseConstr = null;
                        defaultConstructor.access = ProtoCore.DSASM.AccessSpecifier.kPublic;
                        defaultConstructor.IsExternLib = false;
                        defaultConstructor.ExternLibName = null;
                        DfsTraverse(defaultConstructor, ref inferedType);
                        classDecl.funclist.Add(defaultConstructor);
                    }
                }
            }
            else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncBody == compilePass)
            {
                // Class member variable pass
                // Populating the function body of each member function defined in the class vtables

                globalClassIndex = core.ClassTable.IndexOf(classDecl.className);

                foreach (AssociativeNode funcdecl in classDecl.funclist)
                {
                    // reset the inferedtype between functions
                    inferedType = new ProtoCore.Type();
                    DfsTraverse(funcdecl, ref inferedType, false, null, subPass);
                }
            }

            // Reset the class index
            core.ClassIndex = globalClassIndex = ProtoCore.DSASM.Constants.kGlobalScope;
        }
Exemplo n.º 7
0
	void Associative_constructordecl(out ProtoCore.AST.AssociativeAST.AssociativeNode constrNode, ProtoCore.CompilerDefinitions.AccessModifier access, List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = null) {
		ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = new ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode(); ;                                 
		string methodName;  
		ProtoCore.AST.AssociativeAST.AssociativeNode argumentSignature; 
		ProtoCore.AST.AssociativeAST.AssociativeNode pattern;                               
		
		Expect(26);
		NodeUtils.SetNodeStartLocation(constr, t); 
		Associative_CtorSignature(out methodName, out argumentSignature);
		var returnType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, Constants.kArbitraryRank);
		
		constr.Name = methodName; 
		constr.ReturnType = returnType;
		constr.Signature = argumentSignature as ProtoCore.AST.AssociativeAST.ArgumentSignatureNode;
		constr.Access = access; 
		constr.Attributes = attrs;
		ProtoCore.AST.AssociativeAST.AssociativeNode functionBody = null; 
		
		if (la.kind == 47) {
			Get();
			ProtoCore.AST.AssociativeAST.AssociativeNode bnode; 
			Associative_BaseConstructorCall(out bnode);
			constr.BaseConstructor = bnode as ProtoCore.AST.AssociativeAST.FunctionCallNode; 
		}
		Associative_FunctionalMethodBodyMultiLine(out functionBody);
		constr.FunctionBody = functionBody as ProtoCore.AST.AssociativeAST.CodeBlockNode; 
		NodeUtils.SetNodeEndLocation(constr, functionBody); 
		constrNode = constr; 
	}
Exemplo n.º 8
0
 private void SplitConstructorDefinitionNode(ConstructorDefinitionNode node)
 {
     if (!node.IsExternLib)
     {
         node.FunctionBody.Body = SplitMulitpleAssignment(node.FunctionBody.Body);
     }
 }
Exemplo n.º 9
0
        void Associative_constructordecl(out ProtoCore.AST.AssociativeAST.AssociativeNode constrNode, ProtoCore.DSASM.AccessSpecifier access, List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = null)
        {
            ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = new ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode(); ;
            string methodName;
            ProtoCore.AST.AssociativeAST.AssociativeNode argumentSignature;
            ProtoCore.AST.AssociativeAST.AssociativeNode pattern;

            Expect(24);
            NodeUtils.SetNodeStartLocation(constr, t);
            Associative_CtorSignature(out methodName, out argumentSignature);
            var returnType = new ProtoCore.Type();
            returnType.Name = "var";
            returnType.UID = 0;
            returnType.rank = DSASM.Constants.kArbitraryRank;
            returnType.IsIndexable = true;

            constr.Name = methodName;
            constr.Pattern = null;
            constr.ReturnType = returnType;
            constr.Signature = argumentSignature as ProtoCore.AST.AssociativeAST.ArgumentSignatureNode;
            constr.access = access;
            constr.Attributes = attrs;
            ProtoCore.AST.AssociativeAST.AssociativeNode functionBody = null;

            if (la.kind == 48) {
            Get();
            ProtoCore.AST.AssociativeAST.AssociativeNode bnode;
            Associative_BaseConstructorCall(out bnode);
            constr.baseConstr = bnode as ProtoCore.AST.AssociativeAST.FunctionCallNode;
            }
            Associative_FunctionalMethodBodyMultiLine(out functionBody);
            constr.FunctionBody = functionBody as ProtoCore.AST.AssociativeAST.CodeBlockNode;
            NodeUtils.SetNodeEndLocation(constr, functionBody);
            constrNode = constr;
        }