protected void EmitDoubleNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { return; } dynamic dNode = node; if (!enforceTypeCheck || compileState.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeDouble, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeDouble; } inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; }
protected void EmitIdentifierListNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.Node bnode = null) { if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { //to process all unbounded parameters if any dynamic iNode = node; while (iNode is ProtoCore.AST.AssociativeAST.IdentifierListNode || iNode is ProtoCore.AST.ImperativeAST.IdentifierListNode) { dynamic rightNode = iNode.RightNode; if (rightNode is ProtoCore.AST.AssociativeAST.FunctionCallNode || rightNode is ProtoCore.AST.ImperativeAST.FunctionCallNode) { foreach (dynamic paramNode in rightNode.FormalArguments) { ProtoCore.Type paramType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0); DfsTraverse(paramNode, ref paramType, false, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier); } } iNode = iNode.LeftNode; } return; } int depth = 0; ProtoCore.Type leftType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kInvalidType, 0); bool isFirstIdent = true; BuildSSADependency(node, graphNode); if (core.Options.GenerateSSA) { BuildRealDependencyForIdentList(graphNode); if (node is ProtoCore.AST.AssociativeAST.IdentifierListNode) { if ((node as ProtoCore.AST.AssociativeAST.IdentifierListNode).IsLastSSAIdentListFactor) { Validity.Assert(null != ssaPointerStack); ssaPointerStack.Pop(); } } } bool isCollapsed; EmitGetterSetterForIdentList(node, ref inferedType, graphNode, subPass, out isCollapsed); if (!isCollapsed) { bool isMethodCallPresent = false; ProtoCore.DSASM.SymbolNode firstSymbol = null; bool isIdentReference = DfsEmitIdentList(node, null, globalClassIndex, ref leftType, ref depth, ref inferedType, false, ref isFirstIdent, ref isMethodCallPresent, ref firstSymbol, graphNode, subPass, bnode); inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; if (isIdentReference && depth > 1) { EmitInstrConsole(ProtoCore.DSASM.kw.pushlist, depth.ToString(), globalClassIndex.ToString()); // TODO Jun: Get blockid int blockId = 0; EmitPushList(depth, globalClassIndex, blockId); } } }
// Deperecate this function after further regression testing and just use DFSGetSymbolList public void DFSGetSymbolList_Simple(Node pNode, ref ProtoCore.Type lefttype, ref int functionindex, ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef) { dynamic node = pNode; if (node is ProtoCore.AST.ImperativeAST.IdentifierListNode || node is ProtoCore.AST.AssociativeAST.IdentifierListNode) { dynamic bnode = node; DFSGetSymbolList_Simple(bnode.LeftNode, ref lefttype, ref functionindex, nodeRef); node = bnode.RightNode; } if (node is ProtoCore.AST.ImperativeAST.IdentifierNode || node is ProtoCore.AST.AssociativeAST.IdentifierNode) { dynamic identnode = node; ProtoCore.DSASM.SymbolNode symbolnode = null; bool isAccessible = false; bool isAllocated = VerifyAllocation(identnode.Value, lefttype.UID, functionindex, out symbolnode, out isAccessible); if (isAllocated) { if (null == symbolnode) { // It is inaccessible from here due to access modifier. // Just attempt to retrieve the symbol int symindex = core.ClassTable.ClassNodes[lefttype.UID].GetFirstVisibleSymbolNoAccessCheck(identnode.Value); if (ProtoCore.DSASM.Constants.kInvalidIndex != symindex) { symbolnode = core.ClassTable.ClassNodes[lefttype.UID].Symbols.symbolList[symindex]; } } // Since the variable was found, all succeeding nodes in the ident list are class members // Class members have a function scope of kGlobalScope as they are only local to the class, not with any member function functionindex = ProtoCore.DSASM.Constants.kGlobalScope; lefttype = symbolnode.datatype; ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode(); updateNode.symbol = symbolnode; updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol; nodeRef.PushUpdateNode(updateNode); } else { // Is it a class? int ci = core.ClassTable.IndexOf(identnode.Value); if (ProtoCore.DSASM.Constants.kInvalidIndex != ci) { lefttype.UID = ci; // Comment Jun: // Create a symbol node that contains information about the class type that contains static properties ProtoCore.DSASM.SymbolNode classSymbol = new DSASM.SymbolNode(); classSymbol.memregion = DSASM.MemoryRegion.kMemStatic; classSymbol.name = identnode.Value; classSymbol.classScope = ci; ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode(); updateNode.symbol = classSymbol; updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol; nodeRef.PushUpdateNode(updateNode); } else { // In this case, the lhs type is undefined // Just attempt to create a symbol node string ident = identnode.Value; if (0 != ident.CompareTo(ProtoCore.DSDefinitions.Keyword.This)) { symbolnode = new SymbolNode(); symbolnode.name = identnode.Value; ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode(); updateNode.symbol = symbolnode; updateNode.nodeType = AssociativeGraph.UpdateNodeType.kSymbol; nodeRef.PushUpdateNode(updateNode); } } } } else if (node is ProtoCore.AST.ImperativeAST.FunctionCallNode || node is ProtoCore.AST.AssociativeAST.FunctionCallNode) { string functionName = node.Function.Value; if (ProtoCore.Utils.CoreUtils.IsGetterSetter(functionName)) { string property; if (CoreUtils.TryGetPropertyName(functionName, out property)) { functionName = property; } ProtoCore.DSASM.SymbolNode symbolnode = null; bool isAccessible = false; bool isAllocated = VerifyAllocation(functionName, lefttype.UID, globalProcIndex, out symbolnode, out isAccessible); if (isAllocated) { if (null == symbolnode) { // It is inaccessible from here due to access modifier. // Just attempt to retrieve the symbol int symindex = core.ClassTable.ClassNodes[lefttype.UID].GetFirstVisibleSymbolNoAccessCheck(functionName); if (ProtoCore.DSASM.Constants.kInvalidIndex != symindex) { symbolnode = core.ClassTable.ClassNodes[lefttype.UID].Symbols.symbolList[symindex]; } } lefttype = symbolnode.datatype; ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode(); updateNode.symbol = symbolnode; updateNode.nodeType = AssociativeGraph.UpdateNodeType.kSymbol; nodeRef.PushUpdateNode(updateNode); } } else { ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode(); ProtoCore.DSASM.ProcedureNode procNodeDummy = new DSASM.ProcedureNode(); procNodeDummy.Name = functionName; updateNode.procNode = procNodeDummy; updateNode.nodeType = AssociativeGraph.UpdateNodeType.kMethod; nodeRef.PushUpdateNode(updateNode); } } }
protected void EmitNullNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone) { if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { return; } dynamic nullNode = node; inferedType.UID = (int)PrimitiveType.kTypeNull; inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; if (core.Options.TempReplicationGuideEmptyFlag) { if (emitReplicationGuide) { int replicationGuides = 0; // Push the number of guides EmitInstrConsole(ProtoCore.DSASM.kw.push, replicationGuides + "[guide]"); StackValue opNumGuides = StackValue.BuildReplicationGuide(replicationGuides); EmitPush(opNumGuides); } } StackValue op = StackValue.Null; if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide) { EmitInstrConsole(ProtoCore.DSASM.kw.pushg, ProtoCore.DSASM.Literal.Null); EmitPushG(op, nullNode.line, nullNode.col); } else { EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.Literal.Null); EmitPush(op, nullNode.line, nullNode.col); } }
protected void EmitReturnStatement(Node node, Type inferedType) { // Check the returned type against the declared return type if (null != localProcedure && localProcedure.IsConstructor && core.IsFunctionCodeBlock(codeBlock)) { buildStatus.LogSemanticError(Resources.ReturnStatementIsNotAllowedInConstructor, core.CurrentDSFileName, node.line, node.col); } EmitReturnToRegister(node.line, node.col, node.endLine, node.endCol); }
protected void EmitCharNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone) { if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { return; } dynamic cNode = node; if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeChar, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeChar; } inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; String value = (String)cNode.Value; if (value.Length > 1) { buildStatus.LogSyntaxError(Resources.TooManyCharacters, null, node.line, node.col); } String strValue = "'" + value + "'"; StackValue op = ProtoCore.DSASM.StackValue.BuildChar(value[0]); if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide) { int replicationGuides = 0; EmitInstrConsole(ProtoCore.DSASM.kw.push, replicationGuides + "[guide]"); StackValue opNumGuides = StackValue.BuildReplicationGuide(replicationGuides); EmitPush(opNumGuides); EmitInstrConsole(ProtoCore.DSASM.kw.pushg, strValue); EmitPushG(op, node.line, node.col); } else { EmitInstrConsole(ProtoCore.DSASM.kw.push, strValue); EmitPush(op, cNode.line, cNode.col); } }
protected void EmitDoubleNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone) { if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { return; } double value; if (node is AST.ImperativeAST.DoubleNode) { value = (node as AST.ImperativeAST.DoubleNode).Value; } else if (node is AST.AssociativeAST.DoubleNode) { value = (node as AST.AssociativeAST.DoubleNode).Value; } else { throw new InvalidDataException("The input node is not DoubleNode"); } if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeDouble, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeDouble; } inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; if (core.Options.TempReplicationGuideEmptyFlag) { if (emitReplicationGuide) { int replicationGuides = 0; // Push the number of guides EmitInstrConsole(ProtoCore.DSASM.kw.push, replicationGuides + "[guide]"); StackValue opNumGuides = StackValue.BuildReplicationGuide(replicationGuides); EmitPush(opNumGuides); } } StackValue op = StackValue.BuildDouble(value); if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide) { EmitInstrConsole(ProtoCore.DSASM.kw.pushg, value.ToString()); EmitPushG(op, node.line, node.col); } else { EmitInstrConsole(ProtoCore.DSASM.kw.push, value.ToString()); EmitPush(op, node.line, node.col); } if (IsAssociativeArrayIndexing) { if (null != graphNode) { // Get the last dependent which is the current identifier being indexed into SymbolNode literalSymbol = new SymbolNode(); literalSymbol.name = value.ToString(); AssociativeGraph.UpdateNode intNode = new AssociativeGraph.UpdateNode(); intNode.symbol = literalSymbol; intNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral; if (graphNode.isIndexingLHS) { graphNode.dimensionNodeList.Add(intNode); } else { int lastDependentIndex = graphNode.dependentList.Count - 1; ProtoCore.AssociativeGraph.UpdateNode currentDependentNode = graphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0]; currentDependentNode.dimensionNodeList.Add(intNode); if (core.Options.GenerateSSA) { if (null != firstSSAGraphNode) { lastDependentIndex = firstSSAGraphNode.dependentList.Count - 1; ProtoCore.AssociativeGraph.UpdateNode firstSSAUpdateNode = firstSSAGraphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0]; firstSSAUpdateNode.dimensionNodeList.Add(intNode); } } } } } }
protected void EmitIdentifierListNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { //to process all unbounded parameters if any dynamic iNode = node; while (iNode is ProtoCore.AST.AssociativeAST.IdentifierListNode || iNode is ProtoCore.AST.ImperativeAST.IdentifierListNode) { dynamic rightNode = iNode.RightNode; if (rightNode is ProtoCore.AST.AssociativeAST.FunctionCallNode || rightNode is ProtoCore.AST.ImperativeAST.FunctionCallNode) { foreach (dynamic paramNode in rightNode.FormalArguments) { ProtoCore.Type paramType = new ProtoCore.Type(); paramType.UID = (int)ProtoCore.PrimitiveType.kTypeVoid; paramType.IsIndexable = false; DfsTraverse(paramNode, ref paramType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier); } } iNode = iNode.LeftNode; } return; } int depth = 0; ProtoCore.Type leftType = new ProtoCore.Type(); leftType.UID = (int)PrimitiveType.kInvalidType; leftType.IsIndexable = false; bool isFirstIdent = true; bool isIdentReference = DfsEmitIdentList(node, null, globalClassIndex, ref leftType, ref depth, ref inferedType, false, ref isFirstIdent, graphNode, subPass); inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; }
protected abstract void DfsTraverse(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone);
protected void EmitExprListNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { int firstType = (int)PrimitiveType.kTypeVoid; dynamic exprlist = node; int rank = 0; if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { //get the rank dynamic ltNode = exprlist; while ((ltNode is ProtoCore.AST.ImperativeAST.ExprListNode || ltNode is ProtoCore.AST.AssociativeAST.ExprListNode) && ltNode.list.Count > 0) { rank++; ltNode = ltNode.list[0]; } } foreach (Node listNode in exprlist.list) { // The infered type is the type of the first element DfsTraverse(listNode, ref inferedType, false, graphNode, subPass); if ((listNode is ProtoCore.AST.AssociativeAST.ExprListNode) == false) { // If 'listNode' was another sub-array, then don't bother adding // it here, as it has added itself in the call to 'DfsTraverse'. if (null != this.arrayElementType) this.arrayElementType.AppendChildType(inferedType); } if ((int)PrimitiveType.kTypeVoid == firstType) { firstType = inferedType.UID; } } inferedType.UID = firstType; inferedType.IsIndexable = true; inferedType.rank = rank; }
protected void EmitReturnStatement(Node node, ProtoCore.Type inferedType) { // Check the returned type against the declared return type if (null != localProcedure && compileState.IsFunctionCodeBlock(codeBlock)) { if (localProcedure.isConstructor) { Debug.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != inferedType.UID); ProtoCore.DSASM.ClassNode typeNode = compileState.ClassTable.ClassNodes[inferedType.UID]; Debug.Assert(null != typeNode); } } }
protected void EmitNullNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { return; } dynamic nullNode = node; inferedType.UID = (int)PrimitiveType.kTypeNull; inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; }
protected void EmitStringNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { return; } dynamic sNode = node; if (!enforceTypeCheck || compileState.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeString; } throw new NotImplementedException(); }
protected void EmitBooleanNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { return; } dynamic bNode = node; // We need to get inferedType for boolean variable so that we can perform type check if (enforceTypeCheck || compileState.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeBool, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeBool; } }
protected int DfsEmitArrayIndexHeap(Node node, AssociativeGraph.GraphNode graphNode = null, ProtoCore.AST.Node parentNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone) { int indexCnt = 0; Validity.Assert(node is ProtoCore.AST.AssociativeAST.ArrayNode || node is ProtoCore.AST.ImperativeAST.ArrayNode); IsAssociativeArrayIndexing = true; dynamic arrayNode = node; while (arrayNode is ProtoCore.AST.AssociativeAST.ArrayNode || arrayNode is ProtoCore.AST.ImperativeAST.ArrayNode) { ++indexCnt; dynamic array = arrayNode; ProtoCore.Type lastType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0); DfsTraverse(array.Expr, ref lastType, false, graphNode, subPass, parentNode); arrayNode = array.Type; } IsAssociativeArrayIndexing = false; return indexCnt; }
protected void EmitReturnStatement(Node node, Type inferedType) { // Check the returned type against the declared return type if (null != localProcedure && core.IsFunctionCodeBlock(codeBlock)) { if (localProcedure.isConstructor) { buildStatus.LogSemanticError("return statements are not allowed in constructors", core.CurrentDSFileName, node.line, node.col); } else { #if STATIC_TYPE_CHECKING if (inferedType.UID == (int)PrimitiveType.kInvalidType) { EmitPushNull(); EmitReturnToRegister(node.line, node.col, node.endLine, node.endCol); return; } ProtoCore.DSASM.ClassNode typeNode = core.classTable.list[inferedType.UID]; Validity.Assert(null != typeNode); bool diableRankCheck = localProcedure.returntype.UID == (int)PrimitiveType.kTypeVar || localProcedure.returntype.rank == -1 || inferedType.UID == (int)PrimitiveType.kTypeVar || inferedType.rank == -1; bool notMatchedRank = diableRankCheck ? false : localProcedure.returntype.rank != inferedType.rank; bool isReturnTypeMatch = (localProcedure.returntype.UID == inferedType.UID) && !notMatchedRank; if (!isReturnTypeMatch) { if (inferedType.UID != (int)PrimitiveType.kTypeVar && (!typeNode.ConvertibleTo(localProcedure.returntype.UID) || notMatchedRank)) { // Log a warning and force conversion to null by popping the result to the LX register and pushing a null ProtoCore.DSASM.ClassNode returnTypeNode = core.classTable.list[localProcedure.returntype.UID]; if (notMatchedRank) { buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kMismatchReturnType, "Function '" + localProcedure.name + "' " + "expects return value to be of type " + returnTypeNode.name + " and of rank " + localProcedure.returntype.rank, core.CurrentDSFileName, node.line, node.col); } else { buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kMismatchReturnType, "Function '" + localProcedure.name + "' " + "expects return value to be of type " + returnTypeNode.name, core.CurrentDSFileName, node.line, node.col); } EmitPushNull(); } else if (localProcedure.returntype.UID < (int)PrimitiveType.kMaxPrimitives && inferedType.UID > (int)PrimitiveType.kTypeNull) { // EmitInstrConsole(ProtoCore.DSASM.kw.cast, localProcedure.returntype.UID.ToString()); // EmitConvert(localProcedure.returntype.UID, localProcedure.returntype.rank); } } } #endif } }
public abstract ProtoCore.DSASM.ProcedureNode TraverseFunctionCall(Node node, Node parentNode, int lefttype, int depth, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.Node bnode = null);
protected void EmitCharNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (subPass == DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { return; } dynamic cNode = node; if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeChar, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeChar; } inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; Byte[] utf8bytes = ProtoCore.Utils.EncodingUtils.UTF8StringToUTF8Bytes((String)cNode.value); String value = Encoding.UTF8.GetString(utf8bytes); if (value.Length > 1) { buildStatus.LogSyntaxError("Too many characters in character literal", null, node.line, node.col); } String strValue = "'" + value + "'"; EmitInstrConsole(ProtoCore.DSASM.kw.push, strValue); StackValue op = ProtoCore.DSASM.StackValue.BuildChar(value[0]); EmitPush(op, cNode.line, cNode.col); }
protected void EmitStringNode( Node node, ref Type inferedType, AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone) { if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { return; } dynamic sNode = node; if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeString; } if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide) { EmitInstrConsole(ProtoCore.DSASM.kw.push, 0 + "[guide]"); StackValue opNumGuides = StackValue.BuildReplicationGuide(0); EmitPush(opNumGuides); } string value = (string)sNode.Value; StackValue svString = core.Heap.AllocateFixedString(value); if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide) { EmitInstrConsole(kw.pushg, "\"" + value + "\""); EmitPushG(svString, node.line, node.col); } else { EmitInstrConsole(kw.push, "\"" + value + "\""); EmitPush(svString, node.line, node.col); } if (IsAssociativeArrayIndexing && graphNode != null && graphNode.isIndexingLHS) { SymbolNode literalSymbol = new SymbolNode(); literalSymbol.name = value; var dimNode = new AssociativeGraph.UpdateNode(); dimNode.symbol = literalSymbol; dimNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral; graphNode.dimensionNodeList.Add(dimNode); } }
protected void EmitStringNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (subPass == DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { return; } dynamic sNode = node; if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeString; } Byte[] utf8bytes = ProtoCore.Utils.EncodingUtils.UTF8StringToUTF8Bytes((String)sNode.value); String value = Encoding.UTF8.GetString(utf8bytes); foreach (char ch in value) { String strValue = "'" + ch + "'"; EmitInstrConsole(ProtoCore.DSASM.kw.push, strValue); StackValue op = ProtoCore.DSASM.StackValue.BuildChar(ch); EmitPush(op, node.line, node.col); } EmitInstrConsole(ProtoCore.DSASM.kw.alloca, value.Length.ToString()); EmitPopString(value.Length); }
protected void EmitBooleanNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone) { if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { return; } bool value; if (node is AST.ImperativeAST.BooleanNode) { value = (node as AST.ImperativeAST.BooleanNode).Value; } else if (node is AST.AssociativeAST.BooleanNode) { value = (node as AST.AssociativeAST.BooleanNode).Value; } else { throw new InvalidDataException("The input node is not a BooleanNode"); } // We need to get inferedType for boolean variable so that we can perform type check if (enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeBool, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeBool; } if (core.Options.TempReplicationGuideEmptyFlag) { if (emitReplicationGuide) { int replicationGuides = 0; // Push the number of guides EmitInstrConsole(ProtoCore.DSASM.kw.push, replicationGuides + "[guide]"); StackValue opNumGuides = StackValue.BuildReplicationGuide(replicationGuides); EmitPush(opNumGuides); } } StackValue op = StackValue.BuildBoolean(value); if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide) { EmitInstrConsole(ProtoCore.DSASM.kw.pushg, value.ToString()); EmitPushG(op, node.line, node.col); } else { EmitInstrConsole(ProtoCore.DSASM.kw.push, value.ToString()); EmitPush(op, node.line, node.col); } }
protected void EmitReturnNode(Node node) { throw new NotImplementedException(); }
protected void EmitExprListNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.Node parentNode = null) { dynamic exprlist = node; int rank = 0; if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { //get the rank dynamic ltNode = exprlist; bool isExprListNode = (ltNode is ProtoCore.AST.ImperativeAST.ExprListNode || ltNode is ProtoCore.AST.AssociativeAST.ExprListNode); bool isStringNode = (ltNode is ProtoCore.AST.ImperativeAST.StringNode || ltNode is ProtoCore.AST.AssociativeAST.StringNode); while ((isExprListNode && ltNode.Exprs.Count > 0) || isStringNode) { rank++; if (isStringNode) break; ltNode = ltNode.Exprs[0]; isExprListNode = (ltNode is ProtoCore.AST.ImperativeAST.ExprListNode || ltNode is ProtoCore.AST.AssociativeAST.ExprListNode); isStringNode = (ltNode is ProtoCore.AST.ImperativeAST.StringNode || ltNode is ProtoCore.AST.AssociativeAST.StringNode); } } int commonType = (int)PrimitiveType.kTypeVoid; foreach (Node listNode in exprlist.Exprs) { bool emitReplicationGuideFlag = emitReplicationGuide; emitReplicationGuide = false; DfsTraverse(listNode, ref inferedType, false, graphNode, subPass, parentNode); if ((int)PrimitiveType.kTypeVoid== commonType) { commonType = inferedType.UID; } else { if (inferedType.UID != commonType) { commonType = (int)PrimitiveType.kTypeVar; } } emitReplicationGuide = emitReplicationGuideFlag; } inferedType.UID = commonType; inferedType.rank = rank; if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { return; } EmitInstrConsole(ProtoCore.DSASM.kw.alloca, exprlist.Exprs.Count.ToString()); EmitPopArray(exprlist.Exprs.Count); if (exprlist.ArrayDimensions != null) { int dimensions = DfsEmitArrayIndexHeap(exprlist.ArrayDimensions, graphNode); EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]"); EmitPushArrayIndex(dimensions); } if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide) { if (node is ProtoCore.AST.AssociativeAST.ExprListNode) { var exprNode = node as ProtoCore.AST.AssociativeAST.ExprListNode; int guides = EmitReplicationGuides(exprNode.ReplicationGuides); EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, guides + "[guide]"); EmitPushReplicationGuide(guides); } } }
void Imperative(out Node codeBlockNode) { ProtoCore.AST.ImperativeAST.ImperativeNode node = null; ProtoCore.AST.ImperativeAST.CodeBlockNode codeblock = new ProtoCore.AST.ImperativeAST.CodeBlockNode(); NodeUtils.SetNodeStartLocation(codeblock, t); while (StartOf(15)) { if (IsNotAttributeFunction()) { Imperative_stmt(out node); } else { List<ProtoCore.AST.ImperativeAST.ImperativeNode> attrs = new List<ProtoCore.AST.ImperativeAST.ImperativeNode>(); if (la.kind == 10) { Imperative_AttributeDeclaration(out attrs); } Imperative_functiondecl(out node, attrs); } if (null != node) codeblock.Body.Add(node); } codeBlockNode = codeblock; // We look ahead (la) here instead of looking at the current token (t) // because when we get here at the end of a language block, "t" would // have been pointing to the ending token of the last statement in the // language block. What we really need here is the closing bracket '}' // character, and that's conveniently residing in the look ahead token. // NodeUtils.SetNodeEndLocation(codeblock, la); }
private void BuildSSADependency(Node node, AssociativeGraph.GraphNode graphNode) { // Jun Comment: set the graphNode dependent as this identifier list ProtoCore.Type type = new ProtoCore.Type(); type.UID = globalClassIndex; ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new AssociativeGraph.UpdateNodeRef(); DFSGetSymbolList(node, ref type, nodeRef); if (null != graphNode && nodeRef.nodeList.Count > 0) { ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode(); dependentNode.updateNodeRefList.Add(nodeRef); graphNode.PushDependent(dependentNode); } }
void Hydrogen(out Node codeBlockNode) { ProtoCore.AST.AssociativeAST.CodeBlockNode codeblock = new ProtoCore.AST.AssociativeAST.CodeBlockNode(); NodeUtils.SetNodeStartLocation(codeblock, t); ProtoCore.AST.AssociativeAST.AssociativeNode node = null; ProtoFFI.ImportModuleHandler imh = null; if (core.IsParsingPreloadedAssembly) { imh = core.ImportHandler; } else { imh = this.ImportModuleHandler; } bool rootImport = (null == imh) ? true : false; while (la.kind == 34) { ProtoCore.AST.AssociativeAST.AssociativeNode importNode = null; Import_Statement(out importNode); if (null != importNode) (codeblock as ProtoCore.AST.AssociativeAST.CodeBlockNode).Body.Add(importNode); } imh = null; if (core.IsParsingPreloadedAssembly) { imh = core.ImportHandler; } else imh = ImportModuleHandler; if(null != core.ContextDataManager) { if (imh == null) imh = new ProtoFFI.ImportModuleHandler(core); ProtoCore.AST.AssociativeAST.AssociativeNode importNode = null; importNode = core.ContextDataManager.Compile(imh); if (null != importNode) (codeblock as ProtoCore.AST.AssociativeAST.CodeBlockNode).Body.Add(importNode); } if (rootImport && null != imh && imh.RootImportNode.CodeNode.Body.Count != 0) (codeblock as ProtoCore.AST.AssociativeAST.CodeBlockNode).Body.Add(imh.RootImportNode); if (rootImport && core.IsParsingPreloadedAssembly && !builtinMethodsLoaded) { CoreUtils.InsertPredefinedAndBuiltinMethods(core, codeblock); core.ImportNodes = codeblock; } while (StartOf(1)) { if (IsNotAttributeFunctionClass()) { Associative_Statement(out node); } else { List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); if (la.kind == 10) { Associative_AttributeDeclaration(out attrs); } if (la.kind == 27) { Associative_functiondecl(out node, attrs); } else if (la.kind == 25) { Associative_classdecl(out node, attrs); } else SynErr(67); } if (null != node) { (codeblock as ProtoCore.AST.AssociativeAST.CodeBlockNode).Body.Add(node); stmtsParsed++; } } if (la.val == "if") SynErr(String.Format(Resources.UseInlineConditional, la.val)); if ((la.val == "for")||(la.val == "while")) SynErr(String.Format(Resources.ValidForImperativeBlockOnly, la.val)); codeBlockNode = codeblock; // We look ahead (la) here instead of looking at the current token (t) // because when we get here at the end of a language block, "t" would // have been pointing to the ending token of the last statement in the // language block. What we really need here is the closing bracket '}' // character, and that's conveniently residing in the look ahead token. // NodeUtils.SetNodeEndLocation(codeblock, la); }
protected abstract void DfsTraverse(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.Node parentNode = null);
protected void EmitIdentifierListNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.Node bnode = null) { if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { //to process all unbounded parameters if any dynamic iNode = node; while (iNode is ProtoCore.AST.AssociativeAST.IdentifierListNode || iNode is ProtoCore.AST.ImperativeAST.IdentifierListNode) { dynamic rightNode = iNode.RightNode; if (rightNode is ProtoCore.AST.AssociativeAST.FunctionCallNode || rightNode is ProtoCore.AST.ImperativeAST.FunctionCallNode) { foreach (dynamic paramNode in rightNode.FormalArguments) { ProtoCore.Type paramType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0); DfsTraverse(paramNode, ref paramType, false, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier); } } iNode = iNode.LeftNode; } return; } int depth = 0; ProtoCore.Type leftType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kInvalidType, 0); bool isFirstIdent = true; BuildSSADependency(node, graphNode); if (core.Options.GenerateSSA) { BuildRealDependencyForIdentList(graphNode); if (node is ProtoCore.AST.AssociativeAST.IdentifierListNode) { if ((node as ProtoCore.AST.AssociativeAST.IdentifierListNode).IsLastSSAIdentListFactor) { Validity.Assert(null != ssaPointerStack); ssaPointerStack.Pop(); } } } bool isCollapsed; EmitGetterSetterForIdentList(node, ref inferedType, graphNode, subPass, out isCollapsed); if (!isCollapsed) { bool isMethodCallPresent = false; ProtoCore.DSASM.SymbolNode firstSymbol = null; bool isIdentReference = DfsEmitIdentList(node, null, globalClassIndex, ref leftType, ref depth, ref inferedType, false, ref isFirstIdent, ref isMethodCallPresent, ref firstSymbol, graphNode, subPass, bnode); inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; if (isIdentReference && depth > 1) { EmitInstrConsole(ProtoCore.DSASM.kw.pushlist, depth.ToString(), globalClassIndex.ToString()); // TODO Jun: Get blockid int blockId = 0; EmitPushList(depth, globalClassIndex, blockId); } #if PROPAGATE_PROPERTY_MODIFY_VIA_METHOD_UPDATE if (isMethodCallPresent) { // Comment Jun: If the first symbol is null, it is a constructor. If you see it isnt, pls tell me if (null != firstSymbol) { StackValue op = StackValue.Null; if (firstSymbol.classScope != ProtoCore.DSASM.Constants.kInvalidIndex && firstSymbol.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope) { // Member var op = firstSymbol.isStatic ? StackValue.BuildStaticMemVarIndex(firstSymbol.symbolTableIndex) : StackValue.BuildMemVarIndex(firstSymbol.symbolTableIndex); } else { op = StackValue.BuildVarIndex(firstSymbol.symbolTableIndex); } EmitPushDependencyData(currentBinaryExprUID, false); EmitInstrConsole(ProtoCore.DSASM.kw.dep, firstSymbol.name); EmitDependency(firstSymbol.runtimeTableIndex, op, 0); } } #endif } }
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, ref bool isMethodCallPresent, ref ProtoCore.DSASM.SymbolNode firstSymbol, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.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, ref isFirstIdent, ref isMethodCallPresent, ref firstSymbol, graphNode, subPass); if (lefttype.rank > 0) { lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull; 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 (ProtoCore.DSASM.Constants.kInvalidIndex != ci) { finalType.UID = lefttype.UID = ci; } else if (identnode.Value == ProtoCore.DSDefinitions.Keyword.This) { finalType.UID = lefttype.UID = contextClassScope; EmitInstrConsole(ProtoCore.DSASM.kw.push, 0 + "[dim]"); StackValue opdim = StackValue.BuildArrayDimension(0); EmitPush(opdim); EmitThisPointerNode(); 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, globalProcIndex, out symbolnode, out isAccessible); } else { isAllocated = VerifyAllocation(identnode.Value, contextClassScope, globalProcIndex, out symbolnode, out isAccessible); Validity.Assert(null == firstSymbol); firstSymbol = symbolnode; } bool callOnClass = false; string leftClassName = ""; int leftci = Constants.kInvalidIndex; 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)) { leftClassName = leftnode.Name; leftci = core.ClassTable.IndexOf(leftClassName); if (leftci != ProtoCore.DSASM.Constants.kInvalidIndex) { callOnClass = true; EmitInstrConsole(ProtoCore.DSASM.kw.push, 0 + "[dim]"); StackValue dynamicOpdim = StackValue.BuildArrayDimension(0); EmitPush(dynamicOpdim); EmitInstrConsole(ProtoCore.DSASM.kw.pushm, leftClassName); StackValue classOp = StackValue.BuildClassIndex(leftci); EmitPushm(classOp, globalClassIndex, codeBlock.codeBlockId); depth = depth + 1; } } } if (null == symbolnode) //unbound identifier { if (isAllocated && !isAccessible) { string message = String.Format(Resources.kPropertyIsInaccessible, identnode.Value); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode); lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull; 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.kTypeNull; 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(ProtoCore.DSASM.kw.push, dim + "[dim]"); StackValue dynamicOpdim = StackValue.BuildArrayDimension(dim); EmitPush(dynamicOpdim); EmitInstrConsole(ProtoCore.DSASM.kw.pushm, identnode.Value + "[dynamic]"); StackValue dynamicOp = StackValue.BuildDynamic(core.DynamicVariableTable.variableTable.Count - 1); EmitPushm(dynamicOp, symbolnode == null ? globalClassIndex : symbolnode.classScope, DSASM.Constants.kInvalidIndex); lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeVar; depth++; return true; } } else { if (callOnClass && !symbolnode.isStatic) { string procName = identnode.Name; string property; ProtoCore.DSASM.ProcedureNode staticProcCallNode = core.ClassTable.ClassNodes[leftci].GetFirstStaticFunctionBy(procName); if (null != staticProcCallNode) { string message = String.Format(Resources.kMethodHasInvalidArguments, procName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode); } else if (CoreUtils.TryGetPropertyName(procName, out property)) { string message = String.Format(Resources.kPropertyIsInaccessible, property); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode); } else { string message = String.Format(Resources.kMethodIsInaccessible, procName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode); } lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull; EmitPushNull(); return false; } } // // The graph node depends on the first identifier in this identifier list // Where: // p = f(1); // px = p.x; // px dependent on p // p = f(2); // if (isFirstIdent && null != graphNode) { isFirstIdent = false; //ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode(); //dependentNode.symbol = symbolnode; //dependentNode.symbolList.Add(symbolnode); //graphNode.PushDependent(dependentNode); } /* 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; ProtoCore.DSASM.AddressType operandType = ProtoCore.DSASM.AddressType.Pointer; if (null != identnode.ArrayDimensions) { dimensions = DfsEmitArrayIndexHeap(identnode.ArrayDimensions, graphNode); operandType = ProtoCore.DSASM.AddressType.ArrayPointer; } if (lefttype.rank >= 0) { lefttype.rank -= dimensions; if (lefttype.rank < 0) { 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; } } StackValue op = new StackValue(); op.optype = operandType; op.opdata = symbolnode.symbolTableIndex; // TODO Jun: Performance. // Is it faster to have a 'push' specific to arrays to prevent pushing dimension for push instruction? EmitInstrConsole(ProtoCore.DSASM.kw.push, dimensions + "[dim]"); StackValue opdim = StackValue.BuildArrayDimension(dimensions); EmitPush(opdim); if (isLeftidentList || depth == 0) { EmitInstrConsole(ProtoCore.DSASM.kw.pushm, identnode.Value); EmitPushm(op, symbolnode == null ? globalClassIndex : symbolnode.classScope, 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); } 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 && !procnode.Name.Equals(ProtoCore.DSASM.Constants.kStaticPropertiesInitializer)) { functionCallStack.Add(procnode); if (null != graphNode) { graphNode.firstProcRefIndex = graphNode.dependentList.Count - 1; } } isMethodCallPresent = !isMethodCallPresent && !procnode.IsAutoGenerated && !procnode.IsConstructor; } //finalType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : finalType.UID; 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; }
protected void EmitCharNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { return; } dynamic cNode = node; if (!enforceTypeCheck || compileState.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeChar, inferedType.UID)) { inferedType.UID = (int)PrimitiveType.kTypeChar; } inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID; throw new NotImplementedException(); }