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); }
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 = compileState.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 = compileState.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); compileState.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; }