private void EmitIdentifierNode(ImperativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false) { IdentifierNode t = node as IdentifierNode; int dimensions = 0; int runtimeIndex = codeBlock.symbolTable.runtimeIndex; ProtoCore.Type type = new ProtoCore.Type(); type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid; type.IsIndexable = false; ProtoCore.DSASM.SymbolNode symbolnode = null; //bool isAllocated = VerifyAllocation(t.Value, out blockId, out localAllocBlock, out symindex, ref type); //bool allocatedLocally = isAllocated && core.runtimeTableIndex == localAllocBlock; //bool allocatedExternally = isAllocated && core.runtimeTableIndex > localAllocBlock; //bool isVisible = isAllocated && core.runtimeTableIndex >= localAllocBlock; bool isAccessible = false; if (null == t.ArrayDimensions) { //check if it is a function instance ProtoCore.DSASM.ProcedureNode procNode = null; procNode = compileState.GetFirstVisibleProcedure(t.Name, null, codeBlock); if (null != procNode) { if ((int)ProtoCore.DSASM.Constants.kInvalidIndex != procNode.procId) { // A global function inferedType.IsIndexable = false; inferedType.UID = (int)PrimitiveType.kTypeFunctionPointer; int fptr = compileState.FunctionPointerTable.functionPointerDictionary.Count; ProtoCore.DSASM.FunctionPointerNode fptrNode = new ProtoCore.DSASM.FunctionPointerNode(procNode.procId, procNode.runtimeIndex); compileState.FunctionPointerTable.functionPointerDictionary.TryAdd(fptr, fptrNode); compileState.FunctionPointerTable.functionPointerDictionary.TryGetBySecond(fptrNode, out fptr); return; } } } bool isAllocated = VerifyAllocation(t.Value, globalClassIndex, out symbolnode, out isAccessible); if (!isAllocated || !isAccessible) { inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeNull; } else { type = symbolnode.datatype; runtimeIndex = symbolnode.runtimeTableIndex; } if (null != t.ArrayDimensions) { /* Remove static type checking if (!type.IsIndexable && type.UID != (int)PrimitiveType.kTypeArray) buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kWarnMax, string.Format("'{0}' is not indexable at compile time", t.Name)); */ dimensions = DfsEmitArrayIndexHeap(t.ArrayDimensions); } //fix type's rank //fix type's rank if (type.rank >= 0) { type.rank -= dimensions; if (type.rank < 0) { //throw new Exception("Exceed maximum rank!"); type.rank = 0; } } //check whether the value is an array if (type.rank == 0) { type.IsIndexable = false; } if (compileState.TypeSystem.IsHigherRank(type.UID, inferedType.UID)) { inferedType = type; } // We need to get inferedType for boolean variable so that we can perform type check inferedType.UID = (isBooleanOp || (type.UID == (int)PrimitiveType.kTypeBool)) ? (int)PrimitiveType.kTypeBool : inferedType.UID; }
private void EmitIdentifierNode(AssociativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { IdentifierNode t = node as IdentifierNode; int dimensions = 0; ProtoCore.DSASM.SymbolNode symbolnode = null; int runtimeIndex = codeBlock.symbolTable.runtimeIndex; ProtoCore.Type type = new ProtoCore.Type(); type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid; type.IsIndexable = false; bool isAccessible = false; if (null == t.ArrayDimensions) { //check if it is a function instance ProtoCore.DSASM.ProcedureNode procNode = null; procNode = core.GetFirstVisibleProcedure(t.Name, null, codeBlock); if (null != procNode) { if ((int)ProtoCore.DSASM.Constants.kInvalidIndex != procNode.procId) { // A global function inferedType.IsIndexable = false; inferedType.UID = (int)PrimitiveType.kTypeFunctionPointer; if (ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier != subPass) { int fptr = core.FunctionPointerTable.functionPointerDictionary.Count; ProtoCore.DSASM.FunctionPointerNode fptrNode = new ProtoCore.DSASM.FunctionPointerNode(procNode.procId, procNode.runtimeIndex); core.FunctionPointerTable.functionPointerDictionary.TryAdd(fptr, fptrNode); core.FunctionPointerTable.functionPointerDictionary.TryGetBySecond(fptrNode, out fptr); } return; } } } bool isAllocated = VerifyAllocation(t.Name, globalClassIndex, out symbolnode, out isAccessible); if (ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier == subPass) { if (!isAllocated || !isAccessible) { inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeNull; ProtoCore.Type nullType = new ProtoCore.Type(); nullType.UID = (int)PrimitiveType.kTypeNull; nullType.IsIndexable = false; // TODO Jun: Refactor Allocate() to just return the symbol node itself ProtoCore.DSASM.SymbolNode symnode = Allocate(globalClassIndex, globalClassIndex, globalProcIndex, t.Value, nullType); Debug.Assert(symnode != null); IdentLocation.AddEntry(symnode, t.line, t.col, core.CurrentDSFileName); int symbolindex = symnode.symbolTableIndex; if ((int)ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex) { symbolnode = core.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[symbolindex]; } else { symbolnode = codeBlock.symbolTable.symbolList[symbolindex]; } } } else if (isAllocated) { type = symbolnode.datatype; runtimeIndex = symbolnode.runtimeTableIndex; if (null != t.ArrayDimensions) { /* Remove static type checkings. if (type.UID != (int)PrimitiveType.kTypeArray && !type.IsIndexable) buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kWarnMax, string.Format("'{0}' is not indexable at compile time", t.Name)); */ dimensions = DfsEmitArrayIndexHeap(t.ArrayDimensions); } //fix type's rank if (type.rank >= 0) { type.rank -= dimensions; if (type.rank < 0) { //throw new Exception("Exceed maximum rank!"); type.rank = 0; } } //check whether the value is an array if (type.rank == 0) { type.IsIndexable = false; } if (ignoreRankCheck || core.TypeSystem.IsHigherRank(type.UID, inferedType.UID)) { inferedType = type; } // We need to get inferedType for boolean variable so that we can perform type check inferedType.UID = (isBooleanOp || (type.UID == (int)PrimitiveType.kTypeBool)) ? (int)PrimitiveType.kTypeBool : inferedType.UID; } }