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)); } }
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); }
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); }
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); }
/// <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); }
/// <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); }
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; }
/// <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; }
/// <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; }
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); }
// 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; }
/// <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; }
public void SetClassNodeAt(ClassNode node, int index) { classNodes[index] = node; classIndexMap[node.name] = index; }
//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)); } }
/// <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); }
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); }
//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); } }
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; }
/// <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; }
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); }
/// <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; }
/// <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; }
/// <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; }
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); }
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; }
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; }
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); }
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; }
/// <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; }
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); } } }
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); }
//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; }
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; }
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; }
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; }