Beispiel #1
0
        public void VerifyMethodExists(string className, string methodName, bool doAssert = true)
        {
            int classIndex = testCore.ClassTable.IndexOf(className);

            if (classIndex == ProtoCore.DSASM.Constants.kInvalidIndex)
            {
                if (doAssert)
                {
                    Assert.Fail(string.Format("\tFailed to find type \"{0}\" \n{1}", className, mErrorMessage));
                }
                return;
            }

            ProtoCore.DSASM.ClassNode thisClass = testCore.ClassTable.ClassNodes[classIndex];
            if (!thisClass.ProcTable.Procedures.Exists(memberFunc => String.Compare(memberFunc.Name, methodName) == 0))
            {
                if (doAssert)
                {
                    Assert.Fail(string.Format("\tMethod \"{0}.{1}\" doesn't exist \n{2}", className, methodName, mErrorMessage));
                }
            }
            else if (!doAssert)
            {
                Assert.Fail(string.Format("\tMethod \"{0}.{1}\" does exist \n{2}", className, methodName, mErrorMessage));
            }
        }
Beispiel #2
0
        public ClassNode(ClassNode rhs)
        {
            IsImportedClass = rhs.IsImportedClass;
            Name = rhs.Name;
            Size = rhs.Size;
            hasCachedDisposeMethod = rhs.hasCachedDisposeMethod;
            disposeMethod = rhs.disposeMethod;
            Rank = rhs.Rank;
            Symbols = new SymbolTable("classscope", 0);
            if (rhs.Symbols != null)
            {
                Symbols = new SymbolTable(rhs.Symbols.ScopeName, rhs.Symbols.RuntimeIndex);
            }
            DefaultArgExprList = new List<AST.AssociativeAST.AssociativeNode>();
            ID = rhs.ID;

            int classRuntimProc = ProtoCore.DSASM.Constants.kInvalidIndex;
            ProcTable = new ProcedureTable(classRuntimProc);
            if (rhs.ProcTable != null)
            {
                ProcTable = new ProcedureTable(rhs.ProcTable);
            }
            Bases = new List<int>(rhs.Bases);
            ExternLib = rhs.ExternLib;
            TypeSystem = rhs.TypeSystem;
            CoerceTypes = new Dictionary<int, int>(rhs.CoerceTypes);
        }
Beispiel #3
0
        public ClassNode(ClassNode rhs)
        {
            IsImportedClass = rhs.IsImportedClass;
            name = rhs.name;
            size = rhs.size;
            hasCachedDisposeMethod = rhs.hasCachedDisposeMethod;
            disposeMethod = rhs.disposeMethod;
            rank = rhs.rank;
            symbols = new SymbolTable("classscope", 0);
            if (rhs.symbols != null)
            {
                symbols = new SymbolTable(rhs.symbols.ScopeName, rhs.symbols.RuntimeIndex);
            }
            defaultArgExprList = new List<AST.AssociativeAST.AssociativeNode>();
            classId = rhs.classId;

            int classRuntimProc = ProtoCore.DSASM.Constants.kInvalidIndex;
            vtable = new ProcedureTable(classRuntimProc);
            if (rhs.vtable != null)
            {
                vtable = new ProcedureTable(rhs.vtable);
            }
            baseList = new List<int>(rhs.baseList);
            ExternLib = rhs.ExternLib;
            typeSystem = rhs.typeSystem;
            coerceTypes = new Dictionary<int, int>(rhs.coerceTypes);
        }
Beispiel #4
0
 internal ClassMirror(ProtoLanguage.CompileStateTracker compileState, ProtoCore.DSASM.ClassNode classNode, LibraryMirror libraryMirror)
 //: base(compileState)
 {
     this.compileState  = compileState;
     ClassName          = classNode.name;
     this.libraryMirror = libraryMirror;
     this.classNode     = classNode;
 }
        private void BuildInteralAttributes()
        {
            Validity.Assert(ClassTable != null);

            ClassNode cnode = null;

            cnode = new ClassNode { Name = kInternalClassName + kAttributeSuffix };
            ClassTable.Append(cnode);
        }
Beispiel #6
0
        /// <summary>
        /// Returns the number of upcasts that need to be performed to turn a class into another class in its upcast chain
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static int GetUpcastCountTo(ClassNode from, ClassNode to, RuntimeCore runtimeCore)
        {
            int toID = runtimeCore.DSExecutable.classTable.ClassNodes.IndexOf(to);

            List<int> upcastChain = GetClassUpcastChain(from, runtimeCore);

            if (!upcastChain.Contains(toID))
                return int.MaxValue;

            return upcastChain.IndexOf(toID);


        }
Beispiel #7
0
        /// <summary>
        /// Get the number of upcasts that need to be performed to turn a class into another class in its upcast chain
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static int GetUpcastCountTo(ClassNode from, ClassNode to, Core core)
        {
            int fromID = core.ClassTable.ClassNodes.IndexOf(from);
            int toID = core.ClassTable.ClassNodes.IndexOf(to);

            List<int> upcastChain = GetClassUpcastChain(from, core);

            //Validity.Assert(upcastChain.Contains(toID), "Asked to upcast a class to a class that wasn't in its upcast chain");

            if (!upcastChain.Contains(toID))
                return int.MaxValue;

            return upcastChain.IndexOf(toID);
        }
Beispiel #8
0
 internal ClassMirror(ProtoCore.Core core, ProtoCore.DSASM.ClassNode classNode,
                      LibraryMirror libraryMirror = null)
     : base(core, classNode.name)
 {
     ClassName = classNode.name;
     if (libraryMirror == null)
     {
         this.libraryMirror = new LibraryMirror(classNode.ExternLib, core);
     }
     else
     {
         this.libraryMirror = libraryMirror;
     }
     this.classNode = classNode;
 }
Beispiel #9
0
        /// <summary>
        /// Returns the list of classes that this can be upcast to
        /// It includes the class itself
        /// </summary>
        /// <param name="cn"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static List<int> GetClassUpcastChain(ClassNode cn, RuntimeCore runtimeCore)
        {
            List<int> ret = new List<int>();

            //@TODO: Replace this with an ID
            ret.Add(runtimeCore.DSExecutable.classTable.ClassNodes.IndexOf(cn));

            ClassNode target = cn;
            while (target.Base != Constants.kInvalidIndex)
            {
                ret.Add(target.Base);
                target = runtimeCore.DSExecutable.classTable.ClassNodes[target.Base];
            }

            if (!ret.Contains((int)(PrimitiveType.Var)))
                ret.Add((int)PrimitiveType.Var);


            return ret;
        }
Beispiel #10
0
        /// <summary>
        /// Get the list of classes that this can be upcast to
        /// It includes the class itself
        /// </summary>
        /// <param name="cn"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static List<int> GetClassUpcastChain(ClassNode cn, Core core)
        {
            List<int> ret = new List<int>();

            //@TODO: Replace this with an ID
            ret.Add(core.ClassTable.ClassNodes.IndexOf(cn));

            ClassNode target = cn;
            while (target.baseList.Count > 0)
            {
                Validity.Assert(target.baseList.Count == 1, "Multiple Inheritence not yet supported, {F5DDC58D-F721-4319-854A-622175AC43F8}");
                ret.Add(target.baseList[0]);

                target = core.ClassTable.ClassNodes[target.baseList[0]];
            }

            if (!ret.Contains((int)(PrimitiveType.kTypeVar)))
                ret.Add((int)PrimitiveType.kTypeVar);

            return ret;
        }
Beispiel #11
0
        public void SetTypeSystem()
        {
            Validity.Assert(null == classTable);
            if (null != classTable)
            {
                return;
            }

            classTable = new DSASM.ClassTable();

            classTable.Reserve((int)PrimitiveType.kMaxPrimitives);

            ClassNode cnode;

            cnode = new ClassNode { name = DSDefinitions.Keyword.Array, rank = 5, typeSystem = this };
            cnode.classId = (int)PrimitiveType.kTypeArray;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeArray);

            cnode = new ClassNode { name = DSDefinitions.Keyword.Double, rank = 4, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceDoubleToIntScore);
            cnode.classId = (int)PrimitiveType.kTypeDouble;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeDouble);

            cnode = new ClassNode { name = DSDefinitions.Keyword.Int, rank = 3, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceIntToDoubleScore);
            cnode.classId = (int)PrimitiveType.kTypeInt;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeInt);

            cnode = new ClassNode { name = DSDefinitions.Keyword.Bool, rank = 2, typeSystem = this };
            cnode.classId = (int)PrimitiveType.kTypeBool;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeBool);

            cnode = new ClassNode { name = DSDefinitions.Keyword.Char, rank = 1, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);

            cnode.classId = (int)PrimitiveType.kTypeChar;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeChar);

            cnode = new ClassNode { name = DSDefinitions.Keyword.String, rank = 0, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeString;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeString);

            cnode = new ClassNode { name = DSDefinitions.Keyword.Var, rank = 0, typeSystem = this };
            cnode.classId = (int)PrimitiveType.kTypeVar;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeVar);

            cnode = new ClassNode { name = DSDefinitions.Keyword.Null, rank = 0, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeNull;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeNull);

            cnode = new ClassNode { name = DSDefinitions.Keyword.Void, rank = 0, typeSystem = this };
            cnode.classId = (int)PrimitiveType.kTypeVoid;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeVoid);

            cnode = new ClassNode { name = DSDefinitions.Keyword.PointerReserved, rank = 0, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypePointer;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypePointer);

            cnode = new ClassNode { name = DSDefinitions.Keyword.FunctionPointer, rank = 0,typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeFunctionPointer;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeFunctionPointer);

            cnode = new ClassNode { name = "return_reserved", rank = 0, typeSystem = this };
            cnode.classId = (int)PrimitiveType.kTypeReturn;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeReturn);
        }
Beispiel #12
0
        // classScope is a global context, it tells we are in which class's scope
        // functionScope is telling us which function we are in. 
        // 
        // 1. Try to find if the target is a member function's local variable
        //        classScope != kInvalidIndex && functionScope != kInvalidIndex;
        // 
        // 2. Try to find if the target is a member variable
        //     2.1 In a member functions classScope != kInvalidIndex && functionScope != kInvalidIndex.
        //         Returns member in derived class, or non-private member in base classes
        // 
        //     2.2 In a global functions classScope == kInvalidIndex && functionScope != kInvalidIndex.
        //         Returns public member in derived class, or public member in base classes
        // 
        //     2.3 Otherwise, classScope == kInvalidIndex && functionScope == kInvalidIndex
        //         Return public member in derived class, or public member in base classes 
        public static int GetSymbolIndex(ClassNode classNode, string name, int classScope, int functionScope, int blockId, List<CodeBlock> codeblockList, out bool hasThisSymbol, out ProtoCore.DSASM.AddressType addressType)
        {
            hasThisSymbol = false;
            addressType = ProtoCore.DSASM.AddressType.Invalid;

            if (classNode.Symbols == null)
            {
                return ProtoCore.DSASM.Constants.kInvalidIndex;
            }

            IEnumerable<SymbolNode> allSymbols = classNode.Symbols.GetNodeForName(name);
            if (allSymbols == null)
            {
                return ProtoCore.DSASM.Constants.kInvalidIndex;
            }

            int myself = classNode.TypeSystem.classTable.IndexOf(classNode.Name);
            bool isInMemberFunctionContext = (classScope == myself) && (functionScope != ProtoCore.DSASM.Constants.kInvalidIndex);
            bool isInStaticFunction = isInMemberFunctionContext && 
                classNode.ProcTable.Procedures.Count > functionScope &&
                classNode.ProcTable.Procedures[functionScope].IsStatic;

            // Try for member function variables
            var blocks = GetAncestorBlockIdsOfBlock(blockId, codeblockList);
            blocks.Insert(0, blockId);

            Dictionary<int, SymbolNode> symbolOfBlockScope = new Dictionary<int, SymbolNode>();
            foreach (var memvar in allSymbols)
            {
                if ((isInMemberFunctionContext) && (memvar.functionIndex == functionScope))
                {
                    symbolOfBlockScope[memvar.codeBlockId] = memvar;
                }
            }
            if (symbolOfBlockScope.Count > 0)
            {
                foreach (var blockid in blocks)
                {
                    if (symbolOfBlockScope.ContainsKey(blockid))
                    {
                        hasThisSymbol = true;
                        addressType = AddressType.VarIndex;
                        return symbolOfBlockScope[blockid].symbolTableIndex;
                    }
                }
            }

            // Try for member variables. 
            var candidates = new List<SymbolNode>();
            foreach (var memvar in allSymbols)
            {
                if (memvar.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                {
                    candidates.Add(memvar);
                }
            }
            // Sort candidates descending based on their class scopes so that
            // we can search member variable in reverse order of hierarchy tree.
            candidates.Sort((lhs, rhs) => rhs.classScope.CompareTo(lhs.classScope));
            hasThisSymbol = candidates.Count > 0;

            foreach (var symbol in candidates)
            {
                bool isAccessible = false;
                if (isInMemberFunctionContext)
                {
                    isAccessible = (symbol.classScope == myself) || (symbol.access != ProtoCore.CompilerDefinitions.AccessModifier.Private);
                    if (isInStaticFunction)
                        isAccessible = isAccessible && symbol.isStatic;
                }
                else
                {
                    isAccessible = symbol.access == ProtoCore.CompilerDefinitions.AccessModifier.Public;
                }

                if (isAccessible)
                {
                    addressType = symbol.isStatic ? AddressType.StaticMemVarIndex : AddressType.MemVarIndex;
                    return symbol.symbolTableIndex;
                }
            }

            return Constants.kInvalidIndex;
        }
Beispiel #13
0
            /// <summary>
            /// Returns the list of constructors defined for the given class
            /// </summary>
            /// <returns></returns>
            public List<MethodMirror> GetConstructors()
            {
                List<MethodMirror> constructors = new List<MethodMirror>();
                
                if(classNode == null)
                {
                    Validity.Assert(staticCore != null);
                    ProtoCore.DSASM.ClassTable classTable = staticCore.ClassTable;
                    int ci = classTable.IndexOf(ClassName);

                    if (ci != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        classNode = classTable.ClassNodes[ci];
                    }
                }
                
                ProcedureTable procedureTable = classNode.vtable;
                List<ProcedureNode> procList = procedureTable.procList;
                foreach (ProcedureNode pNode in procList)
                {
                    if (pNode.isConstructor == true)
                        constructors.Add(new MethodMirror(pNode));
                }
                                
                return constructors;
            }
Beispiel #14
0
 public void SetClassNodeAt(ClassNode node, int index)
 {
     classNodes[index] = node;
     classIndexMap[node.name] = index;
 }
Beispiel #15
0
        //this method compares the values of the stack variables passed
        public static bool CompareStackValues(StackValue sv1, StackValue sv2, RuntimeCore rtCore1, RuntimeCore rtCore2, ProtoCore.Runtime.Context context = null)
        {
            if (sv1.optype != sv2.optype)
            {
                return(false);
            }

            switch (sv1.optype)
            {
            case AddressType.Invalid:
                return(true);

            case AddressType.Int:
                return(sv1.IntegerValue == sv2.IntegerValue);

            case AddressType.Char:
                return(sv1.CharValue == sv2.CharValue);

            case AddressType.Double:
                var value1 = sv1.DoubleValue;
                var value2 = sv2.DoubleValue;

                if (Double.IsInfinity(value1) && Double.IsInfinity(value2))
                {
                    return(true);
                }
                return(MathUtils.Equals(value1, value2));

            case AddressType.Boolean:
                return(sv1.BooleanValue == sv2.BooleanValue);

            case AddressType.ArrayPointer:
                if (Object.ReferenceEquals(rtCore1, rtCore2) && sv1.ArrayPointer == sv2.ArrayPointer)     //if both cores are same and the stack values point to the same heap element, then the stack values are equal
                {
                    return(true);
                }

                DSArray array1 = rtCore1.Heap.ToHeapObject <DSArray>(sv1);
                DSArray array2 = rtCore2.Heap.ToHeapObject <DSArray>(sv2);
                return(DSArray.CompareFromDifferentCore(array1, array2, rtCore1, rtCore2, context));

            case AddressType.String:
                if (Object.ReferenceEquals(rtCore1, rtCore2) && sv1.StringPointer == sv2.StringPointer)     //if both cores are same and the stack values point to the same heap element, then the stack values are equal
                {
                    return(true);
                }
                DSString s1 = rtCore1.Heap.ToHeapObject <DSString>(sv1);
                DSString s2 = rtCore1.Heap.ToHeapObject <DSString>(sv2);
                return(s1.Equals(s2));

            case AddressType.Pointer:
                if (sv1.metaData.type != sv2.metaData.type)     //if the type of class is different, then stack values can never be equal
                {
                    return(false);
                }
                if (Object.ReferenceEquals(rtCore1, rtCore2) && sv1.Pointer == sv2.Pointer)     //if both cores are same and the stack values point to the same heap element, then the stack values are equal
                {
                    return(true);
                }
                ClassNode classnode = rtCore1.DSExecutable.classTable.ClassNodes[sv1.metaData.type];
                if (classnode.IsImportedClass)
                {
                    var helper      = ProtoFFI.DLLFFIHandler.GetModuleHelper(ProtoFFI.FFILanguage.CSharp);
                    var marshaller1 = helper.GetMarshaller(rtCore1);
                    var marshaller2 = helper.GetMarshaller(rtCore2);
                    try
                    {
                        //the interpreter is passed as null as it is not expected to be sued while unmarshalling in this scenario
                        object dsObject1 = marshaller1.UnMarshal(sv1, context, null, typeof(Object));
                        object dsObject2 = marshaller2.UnMarshal(sv2, context, null, typeof(Object));
                        //cores are different in debugger nunit testing only. Most of the imported objects don't have implementation of Object.Equals. It
                        //also does not make sense to compare these objects deeply, as only dummy objects are created in nunit testing, and these dummy objects
                        //might have random values. So we just check whether the object tpye is the same for this testing.
                        if (!object.ReferenceEquals(rtCore1, rtCore2))
                        {
                            return(Object.ReferenceEquals(dsObject1.GetType(), dsObject2.GetType()));
                        }

                        return(Object.Equals(dsObject1, dsObject2));
                    }
                    catch (System.Exception)
                    {
                        return(false);
                    }
                }
                else
                {
                    return(ComparePointerFromHeap(sv1, sv2, rtCore1, rtCore2, context));
                }

            default:
                return(sv1.Equals(sv2));
            }
        }
Beispiel #16
0
            /// <summary>
            /// Constructor to construct ClassMirror from runtime data i.e. StackValue
            /// </summary>
            /// <param name="svData">StackValue</param>
            /// <param name="core">ProtoCore.Core</param>
            internal ClassMirror(StackValue svData, ProtoCore.Core core)
                : base(core)
            {
                Validity.Assert(svData.IsPointer);
                Validity.Assert(null != core.DSExecutable.classTable);

                IList<ClassNode> classNodes = core.DSExecutable.classTable.ClassNodes;
                Validity.Assert(classNodes != null && classNodes.Count > 0);

                this.classNode = classNodes[svData.metaData.type];
                this.ClassName = this.classNode.Name;
                this.Name = this.ClassName;
                libraryMirror = new LibraryMirror(classNode.ExternLib, core);

            }
Beispiel #17
0
            public MethodMirror GetDeclaredMethod(string methodName, List<ProtoCore.Type> argumentTypes)
            {
                if (classNode == null)
                {
                    Validity.Assert(staticCore != null);

                    ProtoCore.DSASM.ClassTable classTable = staticCore.ClassTable;
                    int ci = classTable.IndexOf(ClassName);

                    if (ci != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        classNode = classTable.ClassNodes[ci];
                    }
                }

                ProcedureTable procedureTable = classNode.vtable;
                List<ProcedureNode> procList = procedureTable.procList;
                            
                return StaticMirror.FindMethod(methodName, argumentTypes, procList);
            }
Beispiel #18
0
        //this method compares the values of the stack variables passed
        public static bool CompareStackValues(StackValue sv1, StackValue sv2, Core c1, Core c2, ProtoCore.Runtime.Context context = null)
        {
            if (sv1.optype != sv2.optype)
            {
                return(false);
            }
            switch (sv1.optype)
            {
            case AddressType.Int:
            case AddressType.Char:
                return(sv1.opdata == sv2.opdata);

            case AddressType.Double:
                if (Double.IsInfinity(sv1.opdata_d) && Double.IsInfinity(sv2.opdata_d))
                {
                    return(true);
                }
                return(MathUtils.Equals(sv1.opdata_d, sv2.opdata_d));

            case AddressType.Boolean:
                return((sv1.opdata > 0 && sv2.opdata > 0) || (sv1.opdata == 0 && sv2.opdata == 0));

            case AddressType.ArrayPointer:
            case AddressType.String:
                if (Object.ReferenceEquals(c1, c2) && sv1.opdata == sv2.opdata)    //if both cores are same and the stack values point to the same heap element, then the stack values are equal
                {
                    return(true);
                }
                return(CompareStackValuesFromHeap(sv1, sv2, c1, c2, context));

            case AddressType.Pointer:
                if (sv1.metaData.type != sv2.metaData.type)     //if the type of class is different, then stack values can never be equal
                {
                    return(false);
                }
                if (Object.ReferenceEquals(c1, c2) && sv1.opdata == sv2.opdata)     //if both cores are same and the stack values point to the same heap element, then the stack values are equal
                {
                    return(true);
                }
                ClassNode classnode = c1.DSExecutable.classTable.ClassNodes[(int)sv1.metaData.type];
                if (classnode.IsImportedClass)
                {
                    var helper      = ProtoFFI.DLLFFIHandler.GetModuleHelper(ProtoFFI.FFILanguage.CSharp);
                    var marshaller1 = helper.GetMarshaller(c1);
                    var marshaller2 = helper.GetMarshaller(c2);
                    try
                    {
                        //the interpreter is passed as null as it is not expected to be sued while unmarshalling in this scenario
                        object dsObject1 = marshaller1.UnMarshal(sv1, context, null, typeof(Object));
                        object dsObject2 = marshaller2.UnMarshal(sv2, context, null, typeof(Object));
                        //cores are different in debugger nunit testing only. Most of the imported objects don't have implementation of Object.Equals. It
                        //also does not make sense to compare these objects deeply, as only dummy objects are created in nunit testing, and these dummy objects
                        //might have random values. So we just check whether the object tpye is the same for this testing.
                        if (!object.ReferenceEquals(c1, c2))
                        {
                            return(Object.ReferenceEquals(dsObject1.GetType(), dsObject2.GetType()));
                        }

                        return(Object.Equals(dsObject1, dsObject2));
                    }
                    catch (System.Exception)
                    {
                        return(false);
                    }
                }
                else
                {
                    return(CompareStackValuesFromHeap(sv1, sv2, c1, c2, context));
                }

            default:
                return(sv1.opdata == sv2.opdata);
            }
        }
Beispiel #19
0
        public int Append(ClassNode node)
        {
            Namespace.Symbol symbol = symbolTable.AddSymbol(node.Name);
            if (null == symbol)
            {
                return ProtoCore.DSASM.Constants.kInvalidIndex;
            }

            classNodes.Add(node);
            node.ID = classNodes.Count - 1;
            symbol.Id = node.ID;
            return node.ID;
        }
Beispiel #20
0
        /// <summary>
        /// For a class node using single inheritence, get the chain of inheritences
        /// </summary>
        /// <param name="cn"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static List<int> GetConversionChain(ClassNode cn, Core core)
        {
            List<int> ret = new List<int>();
            List<int> coercableTypes = new List<int>();

            foreach (int typeID in cn.coerceTypes.Keys)
            {
                bool inserted = false;

                for (int i = 0; i < coercableTypes.Count; i++)
                {
                    if (cn.coerceTypes[typeID] < cn.coerceTypes[coercableTypes[i]])
                    {
                        inserted = true;
                        coercableTypes.Insert(typeID, i);
                        break;
                    }
                }
                if (!inserted)
                    coercableTypes.Add(typeID);
            }
            coercableTypes.Add(core.DSExecutable.classTable.ClassNodes.IndexOf(cn));

            ret.AddRange(coercableTypes);
            return ret;
        }
Beispiel #21
0
        public void SetTypeSystem()
        {
            Debug.Assert(null == classTable);
            if (null != classTable)
            {
                return;
            }

            classTable = new DSASM.ClassTable();

            classTable.Reserve((int)PrimitiveType.kMaxPrimitives);

            ProtoCore.DSASM.ClassNode cnode;

            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_array, size = 0, rank = 5, symbols = null, vtable = null, typeSystem = this
            };

            /*cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             * cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             * cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             * cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             * cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             */
            cnode.classId = (int)PrimitiveType.kTypeArray;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeArray);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_double, size = 0, rank = 4, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceDoubleToIntScore);
            cnode.classId = (int)PrimitiveType.kTypeDouble;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeDouble);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_int, size = 0, rank = 3, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceIntToDoubleScore);
            cnode.classId = (int)PrimitiveType.kTypeInt;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeInt);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_bool, size = 0, rank = 2, symbols = null, vtable = null, typeSystem = this
            };
            // if convert operator to method call, without the following statement
            // a = true + 1 will fail, because _add expects two integers
            //cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeBool;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeBool);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_char, size = 0, rank = 1, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);

            cnode.classId = (int)PrimitiveType.kTypeChar;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeChar);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_string, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeString;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeString);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_var, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };

            /*cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            *  cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            *  cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            *  cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            *  cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);*/
            cnode.classId = (int)PrimitiveType.kTypeVar;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeVar);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_null, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeNull;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeNull);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_void, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.classId = (int)PrimitiveType.kTypeVoid;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeVoid);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = "hostentityid", size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.classId = (int)PrimitiveType.kTypeHostEntityID;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeHostEntityID);
            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = "pointer_reserved", size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            // if convert operator to method call, without the following statement,
            // a = b.c + d.e will fail, b.c and d.e are resolved as pointer and _add method requires two integer
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypePointer;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypePointer);
            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = DSDefinitions.Kw.kw_functionpointer, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeFunctionPointer;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeFunctionPointer);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode {
                name = "return_reserved", size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.classId = (int)PrimitiveType.kTypeReturn;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeReturn);
        }
Beispiel #22
0
            /// <summary>
            ///  Returns the list of function properties of the class only
            /// </summary>
            /// <returns> function nodes </returns>
            public List<MethodMirror> GetFunctions()
            {
                List<MethodMirror> methods = new List<MethodMirror>();
                string name = string.Empty;
                
                if(classNode == null)
                {
                    Validity.Assert(staticCore != null);

                    ProtoCore.DSASM.ClassTable classTable = staticCore.ClassTable;
                    int ci = classTable.IndexOf(ClassName);

                    if (ci != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        classNode = classTable.ClassNodes[ci];
                    }
                }
                
                ProcedureTable procedureTable = classNode.vtable;
                List<ProcedureNode> procList = procedureTable.procList;
                    
                foreach (ProcedureNode pNode in procList)
                {
                    name = pNode.name;
                    if (!pNode.isAssocOperator && !pNode.isAutoGenerated && !pNode.isAutoGeneratedThisProc && !pNode.isConstructor)
                    {
                        methods.Add(new MethodMirror(pNode));
                    }
                }
                
                return methods;                
            }
Beispiel #23
0
        /// <summary>
        /// For a class node using single inheritence, get the chain of inheritences
        /// </summary>
        /// <param name="cn"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static List<int> GetConversionChain(ClassNode cn, RuntimeCore runtimeCore)
        {
            List<int> ret = new List<int>();
            /*
            //@TODO: Replace this with an ID
            ret.Add(core.classTable.list.IndexOf(cn));

            ClassNode target = cn;
            while (target.baseList.Count > 0)
            {
                Validity.Assert(target.baseList.Count == 1, "Multiple Inheritence not yet supported, {F5DDC58D-F721-4319-854A-622175AC43F8}");
                ret.Add(cn.baseList[0]);

                target = core.classTable.list[cn.baseList[0]];
            }
            */

            List<int> coercableTypes = new List<int>();

            foreach (int typeID in cn.CoerceTypes.Keys)
            {
                bool inserted = false;

                for (int i = 0; i < coercableTypes.Count; i++)
                {
                    if (cn.CoerceTypes[typeID] < cn.CoerceTypes[coercableTypes[i]])
                    {
                        inserted = true;
                        coercableTypes.Insert(typeID, i);
                        break;
                    }
                }
                if (!inserted)
                    coercableTypes.Add(typeID);
            }
            coercableTypes.Add(runtimeCore.DSExecutable.classTable.ClassNodes.IndexOf(cn));



            ret.AddRange(coercableTypes);
            return ret;

        }
Beispiel #24
0
            /// <summary>
            ///  Returns the list of class properties of this class 
            /// </summary>
            /// <returns> symbol nodes</returns>
            public List<PropertyMirror> GetProperties()
            {
                List<PropertyMirror> properties = new List<PropertyMirror>();
                
                Dictionary<string, ProcedureNode> setterMap = new Dictionary<string, ProcedureNode>();
                string name = string.Empty;

                if (classNode == null)
                {
                    Validity.Assert(staticCore != null);
                
                    ProtoCore.DSASM.ClassTable classTable = staticCore.ClassTable;
                    int ci = classTable.IndexOf(ClassName);

                    
                    if (ci != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        classNode = classTable.ClassNodes[ci];
                    }
                }
                
                ProcedureTable procedureTable = classNode.vtable;
                List<ProcedureNode> procList = procedureTable.procList;
                string getterPrefix = ProtoCore.DSASM.Constants.kGetterPrefix;
                string setterPrefix = ProtoCore.DSASM.Constants.kSetterPrefix;

                foreach (ProcedureNode pNode in procList)
                {
                    name = pNode.name;
                    if (name.Contains(getterPrefix) && pNode.argInfoList.Count == 0 )
                    {
                        properties.Add(new PropertyMirror(pNode));
                    }
                    else if (name.Contains(setterPrefix) && pNode.argInfoList.Count == 1 && !pNode.isAutoGeneratedThisProc)
                    {
                        if (setterMap.ContainsKey(name))
                        {
                            ProcedureNode proc = setterMap[name];
                            if (proc.argTypeList[0].UID == (int)ProtoCore.PrimitiveType.kTypeVar && pNode.argTypeList[0].UID != (int)ProtoCore.PrimitiveType.kTypeVar)
                            {
                                setterMap.Remove(name);
                                setterMap.Add(name, pNode);
                            }
                        }
                        else
                        {
                            setterMap.Add(name, pNode);          
                        }
                    }
                }
                foreach (var kvp in setterMap)
                {
                    properties.Add(new PropertyMirror(kvp.Value, true));
                }
                
                return properties;
                
            }
Beispiel #25
0
        public void SetTypeSystem()
        {
            Debug.Assert(null == classTable);
            if (null != classTable)
            {
                return;
            }

            classTable = new DSASM.ClassTable();

            classTable.Reserve((int)PrimitiveType.kMaxPrimitives);

            ProtoCore.DSASM.ClassNode cnode;

            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.Array, size = 0, rank = 5, symbols = null, vtable = null, typeSystem = this };
            /*cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            */
            cnode.classId = (int)PrimitiveType.kTypeArray;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeArray);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.Double, size = 0, rank = 4, symbols = null, vtable = null, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceDoubleToIntScore);
            cnode.classId = (int)PrimitiveType.kTypeDouble;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeDouble);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.Int, size = 0, rank = 3, symbols = null, vtable = null, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceIntToDoubleScore);
            cnode.classId = (int)PrimitiveType.kTypeInt;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeInt);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.Bool, size = 0, rank = 2, symbols = null, vtable = null, typeSystem = this };
            // if convert operator to method call, without the following statement
            // a = true + 1 will fail, because _add expects two integers
            //cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeBool;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeBool);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.Char, size = 0, rank = 1, symbols = null, vtable = null, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);

            cnode.classId = (int)PrimitiveType.kTypeChar;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeChar);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.String, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeString;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeString);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.Var, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this };
            /*cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);*/
            cnode.classId = (int)PrimitiveType.kTypeVar;
            classTable.SetClassNodeAt(cnode,(int)PrimitiveType.kTypeVar);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.Null, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeNull;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeNull);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.Void, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this };
            cnode.classId = (int)PrimitiveType.kTypeVoid;
            classTable.SetClassNodeAt(cnode,(int)PrimitiveType.kTypeVoid);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = "hostentityid", size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this };
            cnode.classId = (int)PrimitiveType.kTypeHostEntityID;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeHostEntityID);
            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = "pointer_reserved", size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this };
            // if convert operator to method call, without the following statement,
            // a = b.c + d.e will fail, b.c and d.e are resolved as pointer and _add method requires two integer
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypePointer;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypePointer);
            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = DSDefinitions.Keyword.FunctionPointer, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeFunctionPointer;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeFunctionPointer);

            //
            //
            cnode = new ProtoCore.DSASM.ClassNode { name = "return_reserved", size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this };
            cnode.classId = (int)PrimitiveType.kTypeReturn;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeReturn);
        }
Beispiel #26
0
            public List<MethodMirror> GetOverloads(string methodName)
            {
                List<MethodMirror> methods = new List<MethodMirror>();
                string name = string.Empty;

                if(classNode == null)
                {
                    Validity.Assert(staticCore != null);

                    ProtoCore.DSASM.ClassTable classTable = staticCore.ClassTable;
                    int ci = classTable.IndexOf(ClassName);
                    
                    if (ci != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        classNode = classTable.ClassNodes[ci];
                    }
                }
                
                ProcedureTable procedureTable = classNode.vtable;
                List<ProcedureNode> procList = procedureTable.procList;

                foreach (ProcedureNode pNode in procList)
                {
                    name = pNode.name;
                    if (name == methodName)
                    {
                        methods.Add(new MethodMirror(pNode));
                    }
                }
                

                return methods;
            }
Beispiel #27
0
        public void SetClassNodeAt(ClassNode node, int index)
        {
            classNodes[index] = node;
            Namespace.Symbol symbol = null;
            if (!symbolTable.TryGetExactSymbol(node.Name, out symbol))
                symbol = symbolTable.AddSymbol(node.Name);

            symbol.Id = index;
        }
Beispiel #28
0
            public ClassMirror(string className, ProtoCore.Core core)
                : base(core, className)
            {
                ClassName = className;

                if (classNode == null)
                {

                    ProtoCore.DSASM.ClassTable classTable = core.ClassTable;
                    int ci = classTable.IndexOf(ClassName);

                    if (ci != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        classNode = classTable.ClassNodes[ci];
                    }
                    else
                        throw new Exception(String.Format("Class {0} not defined", className));
                }
                libraryMirror = new LibraryMirror(classNode.ExternLib, core);
            }
Beispiel #29
0
            public ClassMirror(int classIndex, ProtoCore.Core core)
            {
                if (classIndex == Constants.kInvalidIndex)
                {
                    throw new ArgumentException("classIndex is invalid");
                }

                ProtoCore.DSASM.ClassTable classTable = core.ClassTable;
                classNode = classTable.ClassNodes[classIndex];
                libraryMirror = new LibraryMirror(classNode.ExternLib, core);
                ClassName = classNode.Name;
            }
Beispiel #30
0
            /// <summary>
            /// Returns the base class hierarchy for the given class
            /// </summary>
            /// <returns></returns>
            public List<ClassMirror> GetClassHierarchy()
            {
                List<ClassMirror> baseClasses = new List<ClassMirror>();
                
                Validity.Assert(!string.IsNullOrEmpty(ClassName));
                Validity.Assert(staticCore != null);

                int ci;
                if (classNode == null)
                {
                    
                    ProtoCore.DSASM.ClassTable classTable = staticCore.ClassTable;
                    ci = classTable.IndexOf(ClassName);

                    if (ci != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        classNode = classTable.ClassNodes[ci];
                    }
                }

                ClassNode cNode = classNode;
                while (cNode.baseList.Count > 0)
                {

                    ci = cNode.baseList[0];
                    Validity.Assert(ci != ProtoCore.DSASM.Constants.kInvalidIndex);

                    baseClasses.Add(new ClassMirror(staticCore, staticCore.ClassTable.ClassNodes[ci], this.libraryMirror));

                    cNode = staticCore.ClassTable.ClassNodes[ci];
                }
                return baseClasses;
            }
Beispiel #31
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;
        }
        private void ProcessClassNode(ClassNode classNode)
        {
            if (null == classNode)
                return;

            // Define class inheritance relationships.
            foreach (int baseClassId in classNode.baseList)
                DefineHierarchy(baseClassId, classNode.classId, true);

            string[] fields =
            {
                "ClassScope",
                "Name",
                "IsImported",
                "Rank",
                "Size"
            };

            string[] values =
            {
                classNode.classId.ToString(),
                GetDatabaseType(classNode.name),
                GetDatabaseType(classNode.IsImportedClass),
                classNode.rank.ToString(),
                classNode.size.ToString()
            };

            try
            {
                string statement = InsertIntoStatement(TableNames.Classes, fields, values);
                SQLiteCommand command = new SQLiteCommand(statement, connection);
                command.ExecuteNonQuery();
            }
            catch (Exception exception)
            {
                HandleException(exception);
            }

            // Now process all the class procedures (class methods), excluding
            // all those that are auto-generated (or temporary). Excluded
            // procedure IDs are placed in 'excludedProcId' list for use later
            // when symbol nodes are processed.
            //
            List<int> excludedProcId = new List<int>();
            if (null != classNode.vtable && (null != classNode.vtable.procList))
            {
                foreach (ProcedureNode procedure in classNode.vtable.procList)
                {
                    // Place generated procedures in a list.
                    if (ProcedureToBeExcluded(procedure))
                    {
                        excludedProcId.Add(procedure.procId);
                        continue;
                    }

                    // Constructors have classScope set to "-1",
                    // so we must be careful not to exclude them.
                    if (procedure.isConstructor && (-1 == procedure.classScope))
                    {
                        procedure.classScope = classNode.classId;
                        ProcessProcedureNode(procedure);
                        procedure.classScope = -1;
                        continue;
                    }

                    // Adding a regular class method.
                    ProcessProcedureNode(procedure);
                }
            }

            // Go through each of the symbol nodes defined in this class node,
            // they can either be class data members or locals defined in class
            // methods. Symbol nodes defined locally in those procedures that
            // were excluded in the previous pass are also present here,
            // therefore it is crucial that they are properly filtered here.
            //
            if (null != classNode.symbols && (null != classNode.symbols.symbolList))
            {
                int verifiedProcId = -1000;
                bool procedureIncluded = false;
                foreach (var symbol in classNode.symbols.symbolList)
                {
                    SymbolNode symbolNode = symbol.Value;
                    if (symbolNode.classScope != classNode.classId)
                        continue; // Data member of base class (processed).

                    // New function index, verify if it needs to be included.
                    if (symbolNode.functionIndex != verifiedProcId)
                    {
                        procedureIncluded = false;
                        verifiedProcId = symbolNode.functionIndex;
                        if (excludedProcId.IndexOf(verifiedProcId) == -1)
                            procedureIncluded = true; // Procedure was included.
                    }

                    if (false != procedureIncluded)
                        ProcessSymbolNode(symbolNode);
                }
            }
        }
Beispiel #33
0
        public void SetTypeSystem()
        {
            Validity.Assert(null == classTable);
            if (null != classTable)
            {
                return;
            }

            classTable = new DSASM.ClassTable();

            classTable.Reserve((int)PrimitiveType.kMaxPrimitives);

            ClassNode cnode;

            cnode = new ClassNode { Name = DSDefinitions.Keyword.Array, Rank = 5, TypeSystem = this };
            cnode.ID = (int)PrimitiveType.kTypeArray;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeArray);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.Double, Rank = 4, TypeSystem = this };
            cnode.ClassAttributes = new AST.AssociativeAST.ClassAttributes("", "num");
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceDoubleToIntScore);
            cnode.ID = (int)PrimitiveType.kTypeDouble;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeDouble);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.Int, Rank = 3, TypeSystem = this };
            cnode.ClassAttributes = new AST.AssociativeAST.ClassAttributes("", "num");
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceIntToDoubleScore);
            cnode.ID = (int)PrimitiveType.kTypeInt;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeInt);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.Bool, Rank = 2, TypeSystem = this };
            cnode.ID = (int)PrimitiveType.kTypeBool;
            cnode.ClassAttributes = new AST.AssociativeAST.ClassAttributes("", "bool");
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeBool);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.Char, Rank = 1, TypeSystem = this };
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);

            cnode.ID = (int)PrimitiveType.kTypeChar;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeChar);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.String, Rank = 0, TypeSystem = this };
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.ID = (int)PrimitiveType.kTypeString;
            cnode.ClassAttributes = new AST.AssociativeAST.ClassAttributes("", "str");
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeString);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.Var, Rank = 0, TypeSystem = this };
            cnode.ID = (int)PrimitiveType.kTypeVar;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeVar);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.Null, Rank = 0, TypeSystem = this };
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.ID = (int)PrimitiveType.kTypeNull;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeNull);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.Void, Rank = 0, TypeSystem = this };
            cnode.ID = (int)PrimitiveType.kTypeVoid;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeVoid);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.PointerReserved, Rank = 0, TypeSystem = this };
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.ID = (int)PrimitiveType.kTypePointer;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypePointer);

            cnode = new ClassNode { Name = DSDefinitions.Keyword.FunctionPointer, Rank = 0,TypeSystem = this };
            cnode.CoerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.ID = (int)PrimitiveType.kTypeFunctionPointer;
            cnode.ClassAttributes = new AST.AssociativeAST.ClassAttributes("", "func");
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeFunctionPointer);

            cnode = new ClassNode { Name = "return_reserved", Rank = 0, TypeSystem = this };
            cnode.ID = (int)PrimitiveType.kTypeReturn;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeReturn);
        }
Beispiel #34
0
            //public ClassMirror(string className)
            //{
            //    ClassName = className;
            //}

            internal ClassMirror(ProtoCore.Core core, ProtoCore.DSASM.ClassNode classNode, LibraryMirror libraryMirror) : base(core)
            {
                ClassName          = classNode.name;
                this.libraryMirror = libraryMirror;
                this.classNode     = classNode;
            }
Beispiel #35
0
 internal ClassMirror(ProtoCore.Core core, ProtoCore.DSASM.ClassNode classNode,
     LibraryMirror libraryMirror = null)
     : base(core, classNode.Name)
 {
     ClassName = classNode.Name;
     if (libraryMirror == null)
         this.libraryMirror = new LibraryMirror(classNode.ExternLib, core);
     else
         this.libraryMirror = libraryMirror;
     this.classNode = classNode;
 }
Beispiel #36
0
        public int Append(ClassNode node)
        {
            if (IndexOf(node.name) != ProtoCore.DSASM.Constants.kInvalidIndex)
            {
                return ProtoCore.DSASM.Constants.kInvalidIndex;
            }

            classNodes.Add(node);
            node.classId = classNodes.Count - 1;
            classIndexMap[node.name] = node.classId;
            return node.classId;
        }
Beispiel #37
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;
        }
Beispiel #38
0
 public void SetClassNodeAt(ClassNode node, int index)
 {
     classNodes[index]        = node;
     classIndexMap[node.name] = index;
 }