public SymbolNode( string name, int index, int functionIndex, Type datatype, bool isArgument, int runtimeIndex, MemoryRegion memregion = MemoryRegion.InvalidRegion, int scope = -1, CompilerDefinitions.AccessModifier access = CompilerDefinitions.AccessModifier.Public, bool isStatic = false, int codeBlockId = Constants.kInvalidIndex) { this.name = name; isTemp = name.StartsWith("%"); isSSATemp = name.StartsWith(Constants.kSSATempPrefix); this.index = index; this.functionIndex = functionIndex; this.absoluteFunctionIndex = functionIndex; this.datatype = datatype; this.isArgument = isArgument; this.memregion = memregion; this.classScope = scope; this.absoluteClassScope = scope; runtimeTableIndex = runtimeIndex; this.access = access; this.isStatic = isStatic; this.codeBlockId = codeBlockId; }
protected bool DfsEmitIdentList( Node pNode, Node parentNode, int contextClassScope, ref Type lefttype, ref int depth, ref Type finalType, bool isLeftidentList, AssociativeGraph.GraphNode graphNode = null, CompilerDefinitions.SubCompilePass subPass = CompilerDefinitions.SubCompilePass.None, Node binaryExpNode = null) { 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) { string message = "The left hand side of an operation can only contain an indirection operator '.' (48D67B9B)"; buildStatus.LogSemanticError(message, core.CurrentDSFileName, bnode.line, bnode.col); throw new BuildHaltException(message); } DfsEmitIdentList(bnode.LeftNode, bnode, contextClassScope, ref lefttype, ref depth, ref finalType, isLeftidentList, graphNode, subPass); if (lefttype.rank > 0) { lefttype.UID = finalType.UID = (int)PrimitiveType.Null; EmitPushNull(); return false; } node = bnode.RightNode; } if (node is ProtoCore.AST.ImperativeAST.GroupExpressionNode) { ProtoCore.AST.ImperativeAST.ArrayNode array = node.ArrayDimensions; node = node.Expression; node.ArrayDimensions = array; } else if (node is ProtoCore.AST.AssociativeAST.GroupExpressionNode) { ProtoCore.AST.AssociativeAST.ArrayNode array = node.ArrayDimensions; List<ProtoCore.AST.AssociativeAST.AssociativeNode> replicationGuides = node.ReplicationGuides; node = node.Expression; node.ArrayDimensions = array; node.ReplicationGuides = replicationGuides; } if (node is ProtoCore.AST.ImperativeAST.IdentifierNode || node is ProtoCore.AST.AssociativeAST.IdentifierNode) { dynamic identnode = node; int ci = core.ClassTable.IndexOf(identnode.Value); if (Constants.kInvalidIndex != ci) { finalType.UID = lefttype.UID = ci; } else if (identnode.Value == DSDefinitions.Keyword.This) { finalType.UID = lefttype.UID = contextClassScope; EmitThisPointerNode(); depth++; return true; } else { SymbolNode symbolnode = null; bool isAllocated = false; bool isAccessible = false; if (lefttype.UID != -1) { isAllocated = VerifyAllocation(identnode.Value, lefttype.UID, globalProcIndex, out symbolnode, out isAccessible); } else { isAllocated = VerifyAllocation(identnode.Value, contextClassScope, globalProcIndex, out symbolnode, out isAccessible); } if (null == symbolnode) //unbound identifier { if (isAllocated && !isAccessible) { string message = String.Format(Resources.kPropertyIsInaccessible, identnode.Value); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.AccessViolation, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode); lefttype.UID = finalType.UID = (int)PrimitiveType.Null; EmitPushNull(); return false; } else { string message = String.Format(Resources.kUnboundIdentifierMsg, identnode.Value); var unboundSymbol = new SymbolNode { name = identnode.Value }; buildStatus.LogUnboundVariableWarning(unboundSymbol, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode); } if (depth == 0) { lefttype.UID = finalType.UID = (int)PrimitiveType.Null; EmitPushNull(); depth = 1; return false; } else { DSASM.DyanmicVariableNode dynamicVariableNode = new DSASM.DyanmicVariableNode(identnode.Value, globalProcIndex, globalClassIndex); core.DynamicVariableTable.variableTable.Add(dynamicVariableNode); int dim = 0; if (null != identnode.ArrayDimensions) { dim = DfsEmitArrayIndexHeap(identnode.ArrayDimensions, graphNode); } EmitInstrConsole(kw.pushm, identnode.Value + "[dynamic]"); StackValue dynamicOp = StackValue.BuildDynamic(core.DynamicVariableTable.variableTable.Count - 1); EmitPushm(dynamicOp, symbolnode == null ? globalClassIndex : symbolnode.classScope, DSASM.Constants.kInvalidIndex); if (dim > 0) { EmitPushDimensions(dim); EmitLoadElement(null, Constants.kInvalidIndex); } lefttype.UID = finalType.UID = (int)PrimitiveType.Var; depth++; return true; } } /* Dont try to figure out the type at compile time if it is * an array, it is just not reliable because each element in * an array can have different types */ if (!symbolnode.datatype.IsIndexable || symbolnode.datatype.rank < 0) lefttype = symbolnode.datatype; int dimensions = 0; // Get the symbols' table index int runtimeIndex = symbolnode.runtimeTableIndex; if (lefttype.rank >= 0) { lefttype.rank -= dimensions; if (lefttype.rank < 0) { lefttype.rank = 0; } } StackValue op = StackValue.Null; if (0 == depth || (symbolnode != null && symbolnode.isStatic)) { if (ProtoCore.DSASM.Constants.kGlobalScope == symbolnode.functionIndex && ProtoCore.DSASM.Constants.kInvalidIndex != symbolnode.classScope) { // member var if (symbolnode.isStatic) op = StackValue.BuildStaticMemVarIndex(symbolnode.symbolTableIndex); else op = StackValue.BuildMemVarIndex(symbolnode.symbolTableIndex); } else { op = StackValue.BuildVarIndex(symbolnode.symbolTableIndex); } } if (isLeftidentList || depth == 0) { EmitInstrConsole(kw.pushm, identnode.Value); EmitPushm(op, symbolnode == null ? globalClassIndex : symbolnode.classScope, runtimeIndex); if (null != identnode.ArrayDimensions) { dimensions = DfsEmitArrayIndexHeap(identnode.ArrayDimensions, graphNode); } if (dimensions > 0) { EmitPushDimensions(dimensions); EmitLoadElement(symbolnode, runtimeIndex); } } else { // change to dynamic call to facilitate update mechanism DSASM.DyanmicVariableNode dynamicVariableNode = new DSASM.DyanmicVariableNode(identnode.Name, globalProcIndex, globalClassIndex); core.DynamicVariableTable.variableTable.Add(dynamicVariableNode); StackValue dynamicOp = StackValue.BuildDynamic(core.DynamicVariableTable.variableTable.Count - 1); EmitInstrConsole(ProtoCore.DSASM.kw.pushm, identnode.Value + "[dynamic]"); EmitPushm(dynamicOp, symbolnode == null ? globalClassIndex : symbolnode.classScope, runtimeIndex); if (null != identnode.ArrayDimensions) { dimensions = DfsEmitArrayIndexHeap(identnode.ArrayDimensions, graphNode); } if (dimensions > 0) { EmitPushDimensions(dimensions); EmitLoadElement(null, Constants.kInvalidIndex); } } depth = depth + 1; finalType = lefttype; } return true; } else if (node is ProtoCore.AST.ImperativeAST.FunctionCallNode || node is ProtoCore.AST.AssociativeAST.FunctionCallNode) { // A function call must always track dependents bool allowDependents = true; if (null != graphNode) { allowDependents = graphNode.allowDependents; graphNode.allowDependents = true; } if (binaryExpNode != null) { ProtoCore.Utils.NodeUtils.SetNodeLocation(node, binaryExpNode, binaryExpNode); } ProtoCore.DSASM.ProcedureNode procnode = TraverseFunctionCall(node, pNode, lefttype.UID, depth, ref finalType, graphNode, subPass, binaryExpNode); // Restore the graphNode dependent state if (null != graphNode) { graphNode.allowDependents = allowDependents; } // This is the first non-auto generated procedure found in the identifier list if (null != procnode) { if (!procnode.IsConstructor) { functionCallStack.Add(procnode); } } lefttype = finalType; depth = 1; } else { string message = "The left side of operator '.' must be an identifier. (B9AEA3A6)"; buildStatus.LogSemanticError(message, core.CurrentDSFileName, node.line, node.col); throw new BuildHaltException(message); } return false; }