protected ProtoCore.DSASM.AddressType GetOpType(ProtoCore.PrimitiveType type) { ProtoCore.DSASM.AddressType optype = ProtoCore.DSASM.AddressType.Int; // Data coercion for the prototype // The JIL executive handles int primitives if (ProtoCore.PrimitiveType.kTypeInt == type || ProtoCore.PrimitiveType.kTypeBool == type || ProtoCore.PrimitiveType.kTypeChar == type || ProtoCore.PrimitiveType.kTypeString == type) { optype = ProtoCore.DSASM.AddressType.Int; } else if (ProtoCore.PrimitiveType.kTypeDouble == type) { optype = ProtoCore.DSASM.AddressType.Double; } else if (ProtoCore.PrimitiveType.kTypeVar == type) { optype = ProtoCore.DSASM.AddressType.VarIndex; } else if (ProtoCore.PrimitiveType.kTypeReturn == type) { optype = ProtoCore.DSASM.AddressType.Register; } else { Debug.Assert(false); } return(optype); }
// 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 int GetSymbolIndex(string name, int classScope, int functionScope, int blockId, Core core, out bool hasThisSymbol, out ProtoCore.DSASM.AddressType addressType) { hasThisSymbol = false; addressType = ProtoCore.DSASM.AddressType.Invalid; if (symbols == null) { return(ProtoCore.DSASM.Constants.kInvalidIndex); } IEnumerable <SymbolNode> allSymbols = symbols.GetNodeForName(name); if (allSymbols == null) { return(ProtoCore.DSASM.Constants.kInvalidIndex); } int myself = typeSystem.classTable.IndexOf(this.name); bool isInMemberFunctionContext = (classScope == myself) && (functionScope != ProtoCore.DSASM.Constants.kInvalidIndex); bool isInStaticFunction = isInMemberFunctionContext && (vtable.procList[functionScope].isStatic); // Try for member function variables var blocks = core.GetAncestorBlockIdsOfBlock(blockId); 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.AccessSpecifier.kPrivate); if (isInStaticFunction) { isAccessible = isAccessible && symbol.isStatic; } } else { isAccessible = symbol.access == ProtoCore.CompilerDefinitions.AccessSpecifier.kPublic; } if (isAccessible) { addressType = symbol.isStatic ? AddressType.StaticMemVarIndex : AddressType.MemVarIndex; return(symbol.symbolTableIndex); } } return(Constants.kInvalidIndex); }
protected bool DfsEmitIdentList(Node pNode, Node parentNode, int contextClassScope, ref ProtoCore.Type lefttype, ref int depth, ref ProtoCore.Type finalType, bool isLeftidentList, ref bool isFirstIdent, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { bool isRefFromIdentifier = false; dynamic node = pNode; if (node is ProtoCore.AST.ImperativeAST.IdentifierListNode || node is ProtoCore.AST.AssociativeAST.IdentifierListNode) { dynamic bnode = node; if (ProtoCore.DSASM.Operator.dot != bnode.Optr) { throw new BuildHaltException(); } isRefFromIdentifier = DfsEmitIdentList(bnode.LeftNode, bnode, contextClassScope, ref lefttype, ref depth, ref finalType, isLeftidentList, ref isFirstIdent, graphNode, subPass); if (lefttype.rank > 0) { lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull; return(false); } node = bnode.RightNode; } if (node is ProtoCore.AST.ImperativeAST.IdentifierNode || node is ProtoCore.AST.AssociativeAST.IdentifierNode) { dynamic identnode = node; int ci = core.ClassTable.IndexOf(identnode.Value); if (ProtoCore.DSASM.Constants.kInvalidIndex != ci) { finalType.UID = lefttype.UID = ci; } else if (identnode.Value == ProtoCore.DSDefinitions.Kw.kw_this) { finalType.UID = lefttype.UID = contextClassScope; depth++; return(true); } else { ProtoCore.DSASM.SymbolNode symbolnode = null; bool isAllocated = false; bool isAccessible = false; if (lefttype.UID != -1) { isAllocated = VerifyAllocation(identnode.Value, lefttype.UID, out symbolnode, out isAccessible); } else { isAllocated = VerifyAllocation(identnode.Value, contextClassScope, out symbolnode, out isAccessible); } bool callOnClass = false; if (pNode is ProtoCore.AST.ImperativeAST.IdentifierListNode || pNode is ProtoCore.AST.AssociativeAST.IdentifierListNode) { dynamic leftnode = ((dynamic)pNode).LeftNode; if (leftnode != null && (leftnode is ProtoCore.AST.ImperativeAST.IdentifierNode || leftnode is ProtoCore.AST.AssociativeAST.IdentifierNode)) { string leftClassName = leftnode.Name; int leftci = core.ClassTable.IndexOf(leftClassName); if (leftci != ProtoCore.DSASM.Constants.kInvalidIndex) { callOnClass = true; depth = depth + 1; } } } if (null == symbolnode) //unbound identifier { if (isAllocated && !isAccessible) { lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull; return(false); } if (depth == 0) { lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull; return(false); } else { ProtoCore.DSASM.DyanmicVariableNode dynamicVariableNode = new ProtoCore.DSASM.DyanmicVariableNode(identnode.Value, globalProcIndex, globalClassIndex); core.DynamicVariableTable.variableTable.Add(dynamicVariableNode); int dim = 0; if (null != identnode.ArrayDimensions) { dim = DfsEmitArrayIndexHeap(identnode.ArrayDimensions); } lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeVar; depth++; return(true); } } else { if (callOnClass && !symbolnode.isStatic) { lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull; return(false); } } lefttype = symbolnode.datatype; int dimensions = 0; // Get the symbols' table index int runtimeIndex = symbolnode.runtimeTableIndex; ProtoCore.DSASM.AddressType operandType = ProtoCore.DSASM.AddressType.Pointer; if (null != identnode.ArrayDimensions) { /* Remove static type checking * if (lefttype.UID != (int)PrimitiveType.kTypeArray && !lefttype.IsIndexable) * buildStatus.LogWarning(BuildData.WarningID.kWarnMax, string.Format("'{0}' is not indexable at compile time", identnode.Name)); */ dimensions = DfsEmitArrayIndexHeap(identnode.ArrayDimensions); operandType = ProtoCore.DSASM.AddressType.ArrayPointer; } //update the rank if (lefttype.rank >= 0) { lefttype.rank -= dimensions; if (lefttype.rank < 0) { //throw new Exception("Exceed maximum rank!"); lefttype.rank = 0; } } if (0 == depth || (symbolnode != null && symbolnode.isStatic)) { if (ProtoCore.DSASM.Constants.kGlobalScope == symbolnode.functionIndex && ProtoCore.DSASM.Constants.kInvalidIndex != symbolnode.classScope) { // member var operandType = symbolnode.isStatic ? ProtoCore.DSASM.AddressType.StaticMemVarIndex : ProtoCore.DSASM.AddressType.MemVarIndex; } else { operandType = ProtoCore.DSASM.AddressType.VarIndex; } } depth = depth + 1; finalType = lefttype; } return(true); } else if (node is ProtoCore.AST.ImperativeAST.FunctionCallNode || node is ProtoCore.AST.AssociativeAST.FunctionCallNode) { TraverseFunctionCall(node, pNode, lefttype.UID, depth, ref finalType, graphNode, subPass); //finalType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : finalType.UID; lefttype = finalType; depth = 1; } //else //{ // throw new BuildHaltException(); //} return(false); }