protected virtual void EmitFunctionDotCallNode(ref ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCall) { Validity.Assert(null != dotCall); //EmitCode(dotCall.lhsName); //EmitCode("."); AST.AssociativeAST.FunctionCallNode funcDotCall = dotCall.FunctionCall; EmitFunctionCallNode(ref funcDotCall); }
private static FunctionDotCallNode CreateFunctionCallNode(string className, string methodName, List<AssociativeNode> args, Core core) { FunctionCallNode fNode = new FunctionCallNode(); fNode.Function = new IdentifierNode(methodName); fNode.FormalArguments = args; IdentifierNode inode = new IdentifierNode(className); return CoreUtils.GenerateCallDotNode(inode, fNode, core); }
private static FunctionDotCallNode CreateEntityNode(long hostInstancePtr, Core core) { FunctionCallNode fNode = new FunctionCallNode(); fNode.Function = new IdentifierNode("FromObject"); List<ProtoCore.AST.AssociativeAST.AssociativeNode> listArgs = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); listArgs.Add(new ProtoCore.AST.AssociativeAST.IntNode(hostInstancePtr)); fNode.FormalArguments = listArgs; string className = "Geometry"; IdentifierNode inode = new ProtoCore.AST.AssociativeAST.IdentifierNode(className); return ProtoCore.Utils.CoreUtils.GenerateCallDotNode(inode, fNode, core); }
public static string GenerateIdentListNameString(ProtoCore.AST.AssociativeAST.AssociativeNode node) { ProtoCore.AST.AssociativeAST.IdentifierListNode iNode; ProtoCore.AST.AssociativeAST.AssociativeNode leftNode = node; List <string> stringList = new List <string>(); while (leftNode is ProtoCore.AST.AssociativeAST.IdentifierListNode) { iNode = leftNode as ProtoCore.AST.AssociativeAST.IdentifierListNode; leftNode = iNode.LeftNode; if (iNode.RightNode is ProtoCore.AST.AssociativeAST.IdentifierNode) { ProtoCore.AST.AssociativeAST.IdentifierNode currentNode = (iNode.RightNode as ProtoCore.AST.AssociativeAST.IdentifierNode); stringList.Add(currentNode.ToString()); } else if (iNode.RightNode is ProtoCore.AST.AssociativeAST.FunctionCallNode) { ProtoCore.AST.AssociativeAST.FunctionCallNode fCall = iNode.RightNode as ProtoCore.AST.AssociativeAST.FunctionCallNode; stringList.Add(fCall.Function.Name); } else { return(string.Empty); } } stringList.Add(leftNode.ToString()); stringList.Reverse(); string retString = string.Empty; foreach (string s in stringList) { retString += s; retString += '.'; } // Remove the last dot retString = retString.Remove(retString.Length - 1); return(retString); }
private AssociativeNode ContextDataMethodCallNode(IContextData data) { string appname = data.ContextProvider.Name; string connectionstring = data.Name; string varname = data.Name; // //Build a functioncall node for expression varname = ImportData(appname, connectionstring); var func = new ProtoCore.AST.AssociativeAST.IdentifierNode(); func.Value = func.Name = ProtoCore.DSASM.Constants.kImportData; var paramAppName = new ProtoCore.AST.AssociativeAST.StringNode(); paramAppName.Value = appname; var paramConnectionString = new ProtoCore.AST.AssociativeAST.StringNode(); paramConnectionString.Value = connectionstring; var funcCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); funcCall.Function = func; funcCall.Name = ProtoCore.DSASM.Constants.kImportData; funcCall.FormalArguments.Add(paramAppName); funcCall.FormalArguments.Add(paramConnectionString); var var = new ProtoCore.AST.AssociativeAST.IdentifierNode(); var.Name = var.Value = varname; var assignExpr = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode(); assignExpr.LeftNode = var; assignExpr.Optr = ProtoCore.DSASM.Operator.assign; assignExpr.RightNode = funcCall; return(assignExpr); }
private AssociativeNode ContextDataMethodCallNode(IContextData data) { string appname = data.ContextProvider.Name; string connectionstring = data.Name; string varname = data.Name; // //Build a functioncall node for expression varname = ImportData(appname, connectionstring); var func = new ProtoCore.AST.AssociativeAST.IdentifierNode(); func.Value = func.Name = ProtoCore.DSASM.Constants.kImportData; var paramAppName = new ProtoCore.AST.AssociativeAST.StringNode(); paramAppName.value = appname; var paramConnectionString = new ProtoCore.AST.AssociativeAST.StringNode(); paramConnectionString.value = connectionstring; var funcCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); funcCall.Function = func; funcCall.Name = ProtoCore.DSASM.Constants.kImportData; funcCall.FormalArguments.Add(paramAppName); funcCall.FormalArguments.Add(paramConnectionString); var var = new ProtoCore.AST.AssociativeAST.IdentifierNode(); var.Name = var.Value = varname; var assignExpr = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode(); assignExpr.LeftNode = var; assignExpr.Optr = ProtoCore.DSASM.Operator.assign; assignExpr.RightNode = funcCall; return assignExpr; }
public void GraphILTest_FFIClassUsage_01() { List<ProtoCore.AST.AssociativeAST.AssociativeNode> astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); //============================================== // Build the import Nodes //============================================== ProtoScript.Runners.ILiveRunner liveRunner = new ProtoScript.Runners.LiveRunner(); List<string> libs = new List<string>(); libs.Add("ProtoGeometry.dll"); liveRunner.ResetVMAndResyncGraph(libs); //============================================== // Build the constructor call nodes // Point.ByCoordinates(10,10,10) //============================================== astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); ProtoCore.AST.AssociativeAST.FunctionCallNode constructorCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); constructorCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode("ByCoordinates"); List<ProtoCore.AST.AssociativeAST.AssociativeNode> listArgs = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(10.0)); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(10.0)); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(10.0)); constructorCall.FormalArguments = listArgs; string className = "Point"; ProtoCore.AST.AssociativeAST.IdentifierNode inode = new ProtoCore.AST.AssociativeAST.IdentifierNode(className); ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(inode, constructorCall, liveRunner.Core); //============================================== // Build the binary expression // p = Point.ByCoordinates(10,10,10) //============================================== ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmt1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("p"), dotCall, ProtoCore.DSASM.Operator.assign); astList.Add(stmt1); //============================================== // Build a binary expression to retirieve the x property // xval = p.X; //============================================== ProtoCore.AST.AssociativeAST.IdentifierListNode identListNode = new ProtoCore.AST.AssociativeAST.IdentifierListNode(); identListNode.LeftNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("p"); identListNode.Optr = ProtoCore.DSASM.Operator.dot; identListNode.RightNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("X"); ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmt2 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("xval"), identListNode, ProtoCore.DSASM.Operator.assign); astList.Add(stmt2); //============================================== // emit the DS code from the AST tree // // import("ProtoGeometry.dll"); // p = Point.Bycoordinates(10.0, 10.0, 10.0); // xval = p.X; // //============================================== // Instantiate GraphSyncData List<Subtree> addedList = new List<Subtree>(); addedList.Add(new Subtree(astList, System.Guid.NewGuid())); GraphSyncData syncData = new GraphSyncData(null, addedList, null); // emit the DS code from the AST tree liveRunner.UpdateGraph(syncData); ProtoCore.Mirror.RuntimeMirror mirror = liveRunner.InspectNodeValue("xval"); Assert.IsTrue((double)mirror.GetData().Data == 10.0); /////////////////////////////////////////////////////////////////////////////// libs = new List<string>(); libs.Add("ProtoGeometry.dll"); liveRunner.ResetVMAndResyncGraph(libs); astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); constructorCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); constructorCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode("ByCoordinates"); listArgs = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(10.0)); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(10.0)); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(10.0)); constructorCall.FormalArguments = listArgs; className = "Point"; inode = new ProtoCore.AST.AssociativeAST.IdentifierNode(className); dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(inode, constructorCall, liveRunner.Core); //============================================== // Build the binary expression // p = Point.ByCoordinates(10,10,10) //============================================== stmt1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("p"), dotCall, ProtoCore.DSASM.Operator.assign); astList.Add(stmt1); //============================================== // Build a binary expression to retirieve the x property // xval = p.X; //============================================== identListNode = new ProtoCore.AST.AssociativeAST.IdentifierListNode(); identListNode.LeftNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("p"); identListNode.Optr = ProtoCore.DSASM.Operator.dot; identListNode.RightNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("X"); stmt2 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("xval"), identListNode, ProtoCore.DSASM.Operator.assign); astList.Add(stmt2); //============================================== // emit the DS code from the AST tree // // import("ProtoGeometry.dll"); // p = Point.Bycoordinates(10.0, 10.0, 10.0); // xval = p.X; // //============================================== // Instantiate GraphSyncData addedList = new List<Subtree>(); addedList.Add(new Subtree(astList, System.Guid.NewGuid())); syncData = new GraphSyncData(null, addedList, null); liveRunner.UpdateGraph(syncData); mirror = liveRunner.InspectNodeValue("xval"); Assert.IsTrue((double)mirror.GetData().Data == 10.0); }
public static ProtoCore.AST.AssociativeAST.FunctionDotCallNode GenerateCallDotNode(ProtoCore.AST.AssociativeAST.AssociativeNode lhs, ProtoCore.AST.AssociativeAST.FunctionCallNode rhsCall, Core core = null) { // The function name to call string rhsName = rhsCall.Function.Name; int argNum = rhsCall.FormalArguments.Count; ProtoCore.AST.AssociativeAST.ExprListNode argList = new ProtoCore.AST.AssociativeAST.ExprListNode(); foreach (ProtoCore.AST.AssociativeAST.AssociativeNode arg in rhsCall.FormalArguments) { // The function arguments argList.list.Add(arg); } FunctionCallNode funCallNode = new FunctionCallNode(); IdentifierNode funcName = new IdentifierNode { Value = Constants.kDotArgMethodName, Name = Constants.kDotArgMethodName }; funCallNode.Function = funcName; funCallNode.Name = Constants.kDotArgMethodName; NodeUtils.CopyNodeLocation(funCallNode, lhs); int rhsIdx = ProtoCore.DSASM.Constants.kInvalidIndex; string lhsName = string.Empty; if (lhs is ProtoCore.AST.AssociativeAST.IdentifierNode) { lhsName = (lhs as ProtoCore.AST.AssociativeAST.IdentifierNode).Name; if (lhsName == ProtoCore.DSDefinitions.Keyword.This) { lhs = new ProtoCore.AST.AssociativeAST.ThisPointerNode(); } } if (core != null) { DynamicFunction func; if (core.DynamicFunctionTable.TryGetFunction(rhsName, 0, Constants.kInvalidIndex, out func)) { rhsIdx = func.Index; } else { func = core.DynamicFunctionTable.AddNewFunction(rhsName, 0, Constants.kInvalidIndex); rhsIdx = func.Index; } } // The first param to the dot arg (the pointer or the class name) funCallNode.FormalArguments.Add(lhs); // The second param which is the dynamic table index of the function to call var rhs = new IntNode(rhsIdx); funCallNode.FormalArguments.Add(rhs); // The array dimensions ProtoCore.AST.AssociativeAST.ExprListNode arrayDimExperList = new ProtoCore.AST.AssociativeAST.ExprListNode(); int dimCount = 0; if (rhsCall.Function is ProtoCore.AST.AssociativeAST.IdentifierNode) { // Number of dimensions ProtoCore.AST.AssociativeAST.IdentifierNode fIdent = rhsCall.Function as ProtoCore.AST.AssociativeAST.IdentifierNode; if (fIdent.ArrayDimensions != null) { arrayDimExperList = ProtoCore.Utils.CoreUtils.BuildArrayExprList(fIdent.ArrayDimensions); dimCount = arrayDimExperList.list.Count; } else if (rhsCall.ArrayDimensions != null) { arrayDimExperList = ProtoCore.Utils.CoreUtils.BuildArrayExprList(rhsCall.ArrayDimensions); dimCount = arrayDimExperList.list.Count; } else { arrayDimExperList = new ProtoCore.AST.AssociativeAST.ExprListNode(); } } funCallNode.FormalArguments.Add(arrayDimExperList); // Number of dimensions var dimNode = new IntNode(dimCount); funCallNode.FormalArguments.Add(dimNode); if (argNum >= 0) { funCallNode.FormalArguments.Add(argList); funCallNode.FormalArguments.Add(new IntNode(argNum)); } var funDotCallNode = new FunctionDotCallNode(rhsCall); funDotCallNode.DotCall = funCallNode; funDotCallNode.FunctionCall.Function = rhsCall.Function; // Consider the case of "myClass.Foo(a, b)", we will have "DotCall" being // equal to "myClass" (in terms of its starting line/column), and "rhsCall" // matching with the location of "Foo(a, b)". For execution cursor to cover // this whole statement, the final "DotCall" function call node should // range from "lhs.col" to "rhs.col". // NodeUtils.SetNodeEndLocation(funDotCallNode.DotCall, rhsCall); NodeUtils.CopyNodeLocation(funDotCallNode, funDotCallNode.DotCall); return(funDotCallNode); }
private void TraverseDotCallArguments(FunctionCallNode funcCall, FunctionDotCallNode dotCall, ProcedureNode procCallNode, List<ProtoCore.Type> arglist, string procName, int classIndex, string className, bool isStaticCall, bool isConstructor, GraphNode graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass, BinaryExpressionNode bnode) { // Update graph dependencies if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier && graphNode != null) { if (isStaticCall) { Validity.Assert(classIndex != Constants.kInvalidIndex); Validity.Assert(!string.IsNullOrEmpty(className)); SymbolNode classSymbol = new SymbolNode(); classSymbol.name = className; classSymbol.classScope = classIndex; PushSymbolAsDependent(classSymbol, graphNode); } } int funtionArgCount = 0; for (int n = 0; n < funcCall.FormalArguments.Count; ++n) { if (isStaticCall || isConstructor) { if (n != Constants.kDotArgIndexArrayArgs) { continue; } } AssociativeNode paramNode = funcCall.FormalArguments[n]; ProtoCore.Type paramType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0); emitReplicationGuide = false; // If it's a binary node then continue type check, otherwise // disable type check and just take the type of paramNode itself enforceTypeCheck = !(paramNode is BinaryExpressionNode); if (ProtoCore.DSASM.Constants.kDotArgIndexPtr == n) { // Traversing the first arg (the LHS pointer/Static instanct/Constructor // Replication guides only allowed on method, e.g., // // x = p<1>.f({1,2}<2>); // // But not on getter, e.g., // // c = a<1>.x<2>; if (!CoreUtils.IsGetterSetter(procName) && !isConstructor) { emitReplicationGuide = true; } DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode); } else if (ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs == n) { // Traversing the actual arguments passed into the function // (not the dot function) int defaultArgNumber = 0; // If its null this is the second call in a chained dot if (null != procCallNode) { defaultArgNumber = procCallNode.ArgumentInfos.Count - dotCall.FunctionCall.FormalArguments.Count; } // Enable graphnode dependencies if its a setter method bool allowDependentState = null != graphNode ? graphNode.allowDependents : false; if (CoreUtils.IsSetter(procName)) { // If the arguments are not temporaries ExprListNode exprList = paramNode as ExprListNode; Validity.Assert(1 == exprList.Exprs.Count); string varname = string.Empty; if (exprList.Exprs[0] is IdentifierNode) { varname = (exprList.Exprs[0] as IdentifierNode).Name; if (!CoreUtils.IsAutoGeneratedVar(varname)) { graphNode.allowDependents = true; } else if (CoreUtils.IsSSATemp(varname) && core.Options.GenerateSSA) { graphNode.allowDependents = true; } } else { graphNode.allowDependents = true; } } emitReplicationGuide = true; if (defaultArgNumber > 0) { ExprListNode exprList = paramNode as ExprListNode; if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { for (int i = 0; i < defaultArgNumber; i++) { exprList.Exprs.Add(new DefaultArgNode()); } } if (!isStaticCall && !isConstructor) { DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); funtionArgCount = exprList.Exprs.Count; } else { foreach (AssociativeNode exprListNode in exprList.Exprs) { bool repGuideState = emitReplicationGuide; if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { emitReplicationGuide = false; } DfsTraverse(exprListNode, ref paramType, false, graphNode, subPass, bnode); emitReplicationGuide = repGuideState; arglist.Add(paramType); } } } else { ExprListNode exprList = paramNode as ExprListNode; // Comment Jun: This is a getter/setter or a an auto-generated thisarg function... // ...add the dynamic sv that will be resolved as a pointer at runtime if (!isStaticCall && !isConstructor) { // TODO Jun: pls get rid of subPass checking outside the core travesal if (ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone == subPass) { exprList.Exprs.Insert(0, new DynamicNode()); } } if (exprList.Exprs.Count > 0) { foreach (AssociativeNode exprListNode in exprList.Exprs) { bool repGuideState = emitReplicationGuide; if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { emitReplicationGuide = false; } DfsTraverse(exprListNode, ref paramType, false, graphNode, subPass, bnode); emitReplicationGuide = repGuideState; arglist.Add(paramType); } if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier && !isStaticCall && !isConstructor) { 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); } } } else { if (!isStaticCall && !isConstructor) { if (exprList != null) { bool emitReplicationGuideState = emitReplicationGuide; emitReplicationGuide = false; DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); emitReplicationGuide = emitReplicationGuideState; } else { DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); } } } funtionArgCount = exprList.Exprs.Count; } emitReplicationGuide = false; // Restore the state only if it is a setter method if (ProtoCore.Utils.CoreUtils.IsSetter(procName)) { graphNode.allowDependents = allowDependentState; } } else if (ProtoCore.DSASM.Constants.kDotArgIndexArgCount == n) { IntNode argNumNode = new IntNode(funtionArgCount); DfsTraverse(argNumNode, ref paramType, false, graphNode, subPass); } else { DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); } emitReplicationGuide = false; enforceTypeCheck = true; if (!isStaticCall || !isConstructor) { arglist.Add(paramType); } } }
public void GraphILTest_FFIClassUsage_02_astInput() { ProtoScript.Runners.ILiveRunner liveRunner = new ProtoScript.Runners.LiveRunner(); List<ProtoCore.AST.AssociativeAST.AssociativeNode> astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); //============================================== // Build the import Nodes //============================================== List<string> libs = new List<string>(); libs.Add("ProtoGeometry.dll"); List<LibraryMirror> libMirrors = liveRunner.ResetVMAndImportLibrary(libs); //============================================== // Build the constructor call nodes // Point.ByCoordinates(10,10,10) //============================================== ProtoCore.AST.AssociativeAST.FunctionCallNode constructorCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); constructorCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode("ByCoordinates"); List<ProtoCore.AST.AssociativeAST.AssociativeNode> listArgs = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(10.0)); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(10.0)); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(10.0)); constructorCall.FormalArguments = listArgs; string className = "Point"; ProtoCore.AST.AssociativeAST.IdentifierNode inode = new ProtoCore.AST.AssociativeAST.IdentifierNode(className); ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(inode, constructorCall, liveRunner.Core); //============================================== // Build the binary expression // p = Point.ByCoordinates(10,10,10) //============================================== ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmt1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("p"), dotCall, ProtoCore.DSASM.Operator.assign); astList.Add(stmt1); //============================================== // Translate the point // newPoint = p.Translate(1,2,3); //============================================== ProtoCore.AST.AssociativeAST.FunctionCallNode functionCallTranslate = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); functionCallTranslate.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode("Translate"); listArgs = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(1.0)); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(2.0)); listArgs.Add(new ProtoCore.AST.AssociativeAST.DoubleNode(3.0)); functionCallTranslate.FormalArguments = listArgs; //ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCallTranslate = new ProtoCore.AST.AssociativeAST.FunctionDotCallNode("p", functionCallTranslate); className = "p"; inode = new ProtoCore.AST.AssociativeAST.IdentifierNode(className); ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCallTranslate = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(inode, functionCallTranslate, liveRunner.Core); //============================================== // Build the binary expression //============================================== ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmt2 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("newPoint"), dotCallTranslate, ProtoCore.DSASM.Operator.assign); astList.Add(stmt2); //============================================== // Build a binary expression to retirieve the x property // xval = newPoint.X //============================================== ProtoCore.AST.AssociativeAST.IdentifierListNode identListNode = new ProtoCore.AST.AssociativeAST.IdentifierListNode(); identListNode.LeftNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("newPoint"); identListNode.Optr = ProtoCore.DSASM.Operator.dot; identListNode.RightNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("X"); ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmt3 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("xval"), identListNode, ProtoCore.DSASM.Operator.assign); astList.Add(stmt3); //============================================== // // import ("ProtoGeometry.dll"); // p = Point.Bycoordinates(10.0, 10.0, 10.0); // newPoint = p.Translate(1.0,2.0,3.0); // xval = newPoint.X; // //============================================== // update graph CodeBlockNode cNode = new CodeBlockNode(); cNode.Body = astList; liveRunner.UpdateGraph(cNode); ProtoCore.Mirror.RuntimeMirror mirror = liveRunner.InspectNodeValue("xval"); Assert.IsTrue((double)mirror.GetData().Data == 11.0); }
public FunctionDotCallNode(FunctionCallNode callNode) { DotCall = new FunctionCallNode(); FunctionCall = callNode; isLastSSAIdentListFactor = false; }
private void BuildThisFunctionBody(ThisPointerProcOverload procOverload) { BinaryExpressionNode thisFunctionBody = new BinaryExpressionNode(); IdentifierNode leftNode = new IdentifierNode(); leftNode.Name = leftNode.Value = ProtoCore.DSDefinitions.Keyword.Return; thisFunctionBody.LeftNode = leftNode; thisFunctionBody.Optr = Operator.assign; // Build the function call and pass it the arguments including the this pointer FunctionCallNode fcall = new FunctionCallNode(); IdentifierNode identNode = new IdentifierNode(); identNode.Name = procOverload.procNode.Name; fcall.Function = identNode; // Set the arguments passed into the function excluding the 'this' argument List<AssociativeNode> args = new List<AssociativeNode>(); for (int n = 1; n < procOverload.procNode.Signature.Arguments.Count; ++n) { VarDeclNode varDecl = procOverload.procNode.Signature.Arguments[n]; args.Add(varDecl.NameNode); } fcall.FormalArguments = args; // Build the dotcall node procOverload.procNode.FunctionBody.Body = new List<AssociativeNode>(); procOverload.procNode.FunctionBody.Body.Add(thisFunctionBody); thisFunctionBody.RightNode = CoreUtils.GenerateCallDotNode(procOverload.procNode.Signature.Arguments[0].NameNode, fcall, core); }
private void EmitInlineConditionalNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone, ProtoCore.AST.AssociativeAST.BinaryExpressionNode parentNode = null) { if (subPass == AssociativeSubCompilePass.kUnboundIdentifier) { return; } bool isInlineConditionalFlag = false; int startPC = pc; bool isReturn = false; if (graphNode != null) { isInlineConditionalFlag = graphNode.isInlineConditional; graphNode.isInlineConditional = true; startPC = graphNode.updateBlock.startpc; isReturn = graphNode.isReturn; } InlineConditionalNode inlineConditionalNode = node as InlineConditionalNode; // TODO: Jun, this 'if' condition needs to be removed as it was the old implementation - pratapa if (inlineConditionalNode.IsAutoGenerated) { // Normal inline conditional IfStatementNode ifNode = new IfStatementNode(); ifNode.ifExprNode = inlineConditionalNode.ConditionExpression; List<AssociativeNode> ifBody = new List<AssociativeNode>(); List<AssociativeNode> elseBody = new List<AssociativeNode>(); ifBody.Add(inlineConditionalNode.TrueExpression); elseBody.Add(inlineConditionalNode.FalseExpression); ifNode.IfBody = ifBody; ifNode.ElseBody = elseBody; EmitIfStatementNode(ifNode, ref inferedType, graphNode); } else { // CPS inline conditional FunctionCallNode inlineCall = new FunctionCallNode(); IdentifierNode identNode = new IdentifierNode(); identNode.Name = ProtoCore.DSASM.Constants.kInlineConditionalMethodName; inlineCall.Function = identNode; DebugProperties.BreakpointOptions oldOptions = compileStateTracker.DebugProps.breakOptions; DebugProperties.BreakpointOptions newOptions = oldOptions; newOptions |= DebugProperties.BreakpointOptions.EmitInlineConditionalBreakpoint; compileStateTracker.DebugProps.breakOptions = newOptions; compileStateTracker.DebugProps.highlightRange = new ProtoCore.CodeModel.CodeRange { StartInclusive = new ProtoCore.CodeModel.CodePoint { LineNo = parentNode.line, CharNo = parentNode.col }, EndExclusive = new ProtoCore.CodeModel.CodePoint { LineNo = parentNode.endLine, CharNo = parentNode.endCol } }; // True condition language block BinaryExpressionNode bExprTrue = new BinaryExpressionNode(); bExprTrue.LeftNode = nodeBuilder.BuildReturn(); bExprTrue.Optr = Operator.assign; bExprTrue.RightNode = inlineConditionalNode.TrueExpression; LanguageBlockNode langblockT = new LanguageBlockNode(); int trueBlockId = ProtoCore.DSASM.Constants.kInvalidIndex; langblockT.codeblock.language = ProtoCore.Language.kAssociative; langblockT.codeblock.fingerprint = ""; langblockT.codeblock.version = ""; compileStateTracker.AssocNode = bExprTrue; EmitDynamicLanguageBlockNode(langblockT, bExprTrue, ref inferedType, ref trueBlockId, graphNode, AssociativeSubCompilePass.kNone); compileStateTracker.AssocNode = null; ProtoCore.AST.AssociativeAST.DynamicBlockNode dynBlockT = new ProtoCore.AST.AssociativeAST.DynamicBlockNode(trueBlockId); // False condition language block BinaryExpressionNode bExprFalse = new BinaryExpressionNode(); bExprFalse.LeftNode = nodeBuilder.BuildReturn(); bExprFalse.Optr = Operator.assign; bExprFalse.RightNode = inlineConditionalNode.FalseExpression; LanguageBlockNode langblockF = new LanguageBlockNode(); int falseBlockId = ProtoCore.DSASM.Constants.kInvalidIndex; langblockF.codeblock.language = ProtoCore.Language.kAssociative; langblockF.codeblock.fingerprint = ""; langblockF.codeblock.version = ""; compileStateTracker.AssocNode = bExprFalse; EmitDynamicLanguageBlockNode(langblockF, bExprFalse, ref inferedType, ref falseBlockId, graphNode, AssociativeSubCompilePass.kNone); compileStateTracker.AssocNode = null; ProtoCore.AST.AssociativeAST.DynamicBlockNode dynBlockF = new ProtoCore.AST.AssociativeAST.DynamicBlockNode(falseBlockId); compileStateTracker.DebugProps.breakOptions = oldOptions; compileStateTracker.DebugProps.highlightRange = new ProtoCore.CodeModel.CodeRange { StartInclusive = new ProtoCore.CodeModel.CodePoint { LineNo = Constants.kInvalidIndex, CharNo = Constants.kInvalidIndex }, EndExclusive = new ProtoCore.CodeModel.CodePoint { LineNo = Constants.kInvalidIndex, CharNo = Constants.kInvalidIndex } }; inlineCall.FormalArguments.Add(inlineConditionalNode.ConditionExpression); inlineCall.FormalArguments.Add(dynBlockT); inlineCall.FormalArguments.Add(dynBlockF); // Save the pc and store it after the call EmitFunctionCallNode(inlineCall, ref inferedType, false, graphNode, AssociativeSubCompilePass.kUnboundIdentifier); EmitFunctionCallNode(inlineCall, ref inferedType, false, graphNode, AssociativeSubCompilePass.kNone, parentNode); // Need to restore those settings. if (graphNode != null) { graphNode.isInlineConditional = isInlineConditionalFlag; graphNode.updateBlock.startpc = startPC; graphNode.isReturn = isReturn; } } }
private void SSAIdentList(AssociativeNode node, ref Stack<AssociativeNode> ssaStack, ref List<AssociativeNode> astlist) { if (node is IdentifierNode) { IdentifierNode ident = node as IdentifierNode; if (null == ident.ArrayDimensions) { // Build the temp pointer BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; bnode.isSSAAssignment = true; bnode.isSSAPointerAssignment = true; bnode.IsFirstIdentListNode = true; // Left node var identNode =AstFactory.BuildIdentifier(ProtoCore.Utils.CoreUtils.BuildSSATemp(core)); identNode.ReplicationGuides = GetReplicationGuides(ident); identNode.AtLevel = ident.AtLevel; bnode.LeftNode = identNode; // Right node bnode.RightNode = ident; astlist.Add(bnode); ssaStack.Push(bnode); } else { EmitSSAArrayIndex(ident, ssaStack, ref astlist, true); (astlist[0] as BinaryExpressionNode).IsFirstIdentListNode = true; } } else if (node is ExprListNode) { //ExprListNode exprList = node as ExprListNode; DFSEmitSSA_AST(node, ssaStack, ref astlist); } else if (node is FunctionCallNode) { FunctionCallNode fcall = node as FunctionCallNode; if (null == fcall.ArrayDimensions) { // Build the temp pointer BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; bnode.isSSAAssignment = true; bnode.isSSAPointerAssignment = true; bnode.IsFirstIdentListNode = true; // Left node var identNode =AstFactory.BuildIdentifier(ProtoCore.Utils.CoreUtils.BuildSSATemp(core)); identNode.ReplicationGuides = fcall.ReplicationGuides; identNode.AtLevel = fcall.AtLevel; bnode.LeftNode = identNode; // Right node bnode.RightNode = fcall; astlist.Add(bnode); ssaStack.Push(bnode); } else { EmitSSAArrayIndex(fcall, ssaStack, ref astlist, true); (astlist[0] as BinaryExpressionNode).IsFirstIdentListNode = true; } } else if (node is IdentifierListNode) { IdentifierListNode identList = node as IdentifierListNode; // Build the rhs identifier list containing the temp pointer IdentifierListNode rhsIdentList = new IdentifierListNode(); rhsIdentList.Optr = Operator.dot; bool isLeftNodeExprList = false; // Check if identlist matches any namesapce bool resolvedCall = false; string[] classNames = ProtoCore.Utils.CoreUtils.GetResolvedClassName(core.ClassTable, identList); if (classNames.Length == 1) { // // The identlist is a class name and should not be SSA'd // such as: // p = Obj.Create() // var leftNode =AstFactory.BuildIdentifier(classNames[0]); rhsIdentList.LeftNode = leftNode; ProtoCore.Utils.CoreUtils.CopyDebugData(leftNode, node); resolvedCall = true; } else if (classNames.Length > 0) { // There is a resolution conflict // identList resolved to multiple classes // TODO Jun: Move this warning handler to after the SSA transform // http://adsk-oss.myjetbrains.com/youtrack/issue/MAGN-5221 buildStatus.LogSymbolConflictWarning(identList.LeftNode.ToString(), classNames); rhsIdentList = identList; resolvedCall = true; } else { // identList unresolved // Continue to transform this identlist into SSA isLeftNodeExprList = identList.LeftNode is ExprListNode; // Recursively traversse the left of the ident list SSAIdentList(identList.LeftNode, ref ssaStack, ref astlist); AssociativeNode lhsNode = ssaStack.Pop(); if (lhsNode is BinaryExpressionNode) { rhsIdentList.LeftNode = (lhsNode as BinaryExpressionNode).LeftNode; } else { rhsIdentList.LeftNode = lhsNode; } } ArrayNode arrayDimension = null; AssociativeNode rnode = null; if (identList.RightNode is IdentifierNode) { IdentifierNode identNode = identList.RightNode as IdentifierNode; arrayDimension = identNode.ArrayDimensions; rnode = identNode; } else if (identList.RightNode is FunctionCallNode) { FunctionCallNode fcNode = new FunctionCallNode(identList.RightNode as FunctionCallNode); arrayDimension = fcNode.ArrayDimensions; List<AssociativeNode> astlistArgs = new List<AssociativeNode>(); for (int idx = 0; idx < fcNode.FormalArguments.Count; idx++) { AssociativeNode arg = fcNode.FormalArguments[idx]; var replicationGuides = GetReplicationGuides(arg); if (replicationGuides == null) { replicationGuides = new List<AssociativeNode> { }; } else { RemoveReplicationGuides(arg); } var atLevel = GetAtLevel(arg); if (atLevel != null) { RemoveAtLevel(arg); } DFSEmitSSA_AST(arg, ssaStack, ref astlistArgs); var argNode = ssaStack.Pop(); var argBinaryExpr = argNode as BinaryExpressionNode; if (argBinaryExpr != null) { var newArgNode = NodeUtils.Clone(argBinaryExpr.LeftNode) as IdentifierNode; newArgNode.ReplicationGuides = replicationGuides; newArgNode.AtLevel = atLevel; fcNode.FormalArguments[idx] = newArgNode; } else { fcNode.FormalArguments[idx] = argNode; } astlist.AddRange(astlistArgs); astlistArgs.Clear(); } astlist.AddRange(astlistArgs); rnode = fcNode; } else { Validity.Assert(false); } Validity.Assert(null != rnode); rhsIdentList.RightNode = rnode; if (null == arrayDimension) { // New SSA expr for the current dot call string ssatemp = ProtoCore.Utils.CoreUtils.BuildSSATemp(core); var tmpIdent =AstFactory.BuildIdentifier(ssatemp); BinaryExpressionNode bnode = new BinaryExpressionNode(tmpIdent, rhsIdentList, Operator.assign); bnode.isSSAPointerAssignment = true; if (resolvedCall || isLeftNodeExprList ) { bnode.IsFirstIdentListNode = true; } astlist.Add(bnode); ssaStack.Push(bnode); } else { List<AssociativeNode> ssaAstList = new List<AssociativeNode>(); EmitSSAArrayIndex(rhsIdentList, ssaStack, ref ssaAstList, true); if (resolvedCall || isLeftNodeExprList) { (ssaAstList[0] as BinaryExpressionNode).IsFirstIdentListNode = true; } astlist.AddRange(ssaAstList); } } }
private ProtoCore.AST.AssociativeAST.AssociativeNode GenerateUnaryOperatorMethodCallNode(UnaryOperator op, ProtoCore.AST.AssociativeAST.AssociativeNode operand) { ProtoCore.AST.AssociativeAST.FunctionCallNode funCallNode = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); ProtoCore.AST.AssociativeAST.IdentifierNode funcName = new ProtoCore.AST.AssociativeAST.IdentifierNode { Value = ProtoCore.DSASM.Constants.kInternalNamePrefix + op.ToString(), Name = ProtoCore.DSASM.Constants.kInternalNamePrefix + op.ToString() }; funCallNode.Function = funcName; funCallNode.Name = ProtoCore.DSASM.Constants.kInternalNamePrefix + op.ToString(); funCallNode.FormalArguments.Add(operand); NodeUtils.CopyNodeLocation(funCallNode, operand); return funCallNode; }
public void GraphILTest_FFIClassUsage_03() { // // a=2; // tSSA_150=1..10; // x= tSSA_150; // tSSA_151=x; // tSSA_152=a; // tSSA_153=( tSSA_151+ tSSA_152); // var_79153f69593b4fde9bb50646a1aaea96= tSSA_153; // tSSA_154=Point.ByCoordinates(var_79153f69593b4fde9bb50646a1aaea96,a,a); // var_347c1113204a4d15a22f7daf83bbe20e= tSSA_154; // // // a=2; // x=1..10; // var_79153f69593b4fde9bb50646a1aaea96=(x+a); // var_347c1113204a4d15a22f7daf83bbe20e=Point.ByCoordinates(var_79153f69593b4fde9bb50646a1aaea96,a,a); // ProtoScript.Runners.ILiveRunner liveRunner = new ProtoScript.Runners.LiveRunner(); List<ProtoCore.AST.AssociativeAST.AssociativeNode> astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); //============================================== // Build the import Nodes //============================================== //ProtoCore.AST.AssociativeAST.ImportNode importNode = new ProtoCore.AST.AssociativeAST.ImportNode(); //importNode.ModuleName = "ProtoGeometry.dll"; //astList.Add(importNode); List<string> libs = new List<string>(); libs.Add("ProtoGeometry.dll"); liveRunner.ResetVMAndResyncGraph(libs); // Build the AST trees // a = 2 ProtoCore.AST.AssociativeAST.BinaryExpressionNode assign1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("a"), new ProtoCore.AST.AssociativeAST.IntNode(2), ProtoCore.DSASM.Operator.assign); astList.Add(assign1); // x = 1..10; ProtoCore.AST.AssociativeAST.RangeExprNode rangeExpr = new ProtoCore.AST.AssociativeAST.RangeExprNode(); rangeExpr.FromNode = new ProtoCore.AST.AssociativeAST.IntNode(1); rangeExpr.ToNode = new ProtoCore.AST.AssociativeAST.IntNode(10); rangeExpr.StepNode = new ProtoCore.AST.AssociativeAST.IntNode(1); ProtoCore.AST.AssociativeAST.BinaryExpressionNode assign2 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("x"), rangeExpr, ProtoCore.DSASM.Operator.assign); astList.Add(assign2); // var_79153f69593b4fde9bb50646a1aaea96 = (x + a); ProtoCore.AST.AssociativeAST.BinaryExpressionNode assign3 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("dude"), new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("x"), new ProtoCore.AST.AssociativeAST.IdentifierNode("a"), ProtoCore.DSASM.Operator.add), ProtoCore.DSASM.Operator.assign); astList.Add(assign3); //============================================== // Build the constructor call nodes // Point.ByCoordinates(10,10,10) //============================================== ProtoCore.AST.AssociativeAST.FunctionCallNode constructorCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); constructorCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode("ByCoordinates"); List<ProtoCore.AST.AssociativeAST.AssociativeNode> listArgs = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); listArgs.Add(new ProtoCore.AST.AssociativeAST.IdentifierNode("dude")); listArgs.Add(new ProtoCore.AST.AssociativeAST.IdentifierNode("a")); listArgs.Add(new ProtoCore.AST.AssociativeAST.IdentifierNode("a")); constructorCall.FormalArguments = listArgs; string className = "Point"; ProtoCore.AST.AssociativeAST.IdentifierNode inode = new ProtoCore.AST.AssociativeAST.IdentifierNode(className); ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(inode, constructorCall, liveRunner.Core); //============================================== // Build the binary expression // p = Point.ByCoordinates(10,10,10) //============================================== ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmt1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("final"), dotCall, ProtoCore.DSASM.Operator.assign); astList.Add(stmt1); //============================================== // emit the DS code from the AST tree //============================================== // Instantiate GraphSyncData List<Subtree> addedList = new List<Subtree>(); addedList.Add(new Subtree(astList, System.Guid.NewGuid())); GraphSyncData syncData = new GraphSyncData(null, addedList, null); // emit the DS code from the AST tree liveRunner.UpdateGraph(syncData); }
// // proc SSAIdentList(node, ssastack, ast) // { // if node is ident // t = SSATemp() // tmpIdent = new Ident(t) // binexpr = new BinaryExpr(tmpIdent, node) // ast.push(binexpr) // ssastack.push(tmpIdent) // else if node is identlist // SSAIdentList(node.left, ssastack, ast) // rhs = new identlist(new Ident(ssastack.pop), node.right) // t = SSATemp() // tmpIdent = new Ident(t) // binexpr = new BinaryExpr(tmpIdent, rhs) // ast.push(binexpr) // ssastack.push(tmpIdent) // end // } // private void SSAIdentList(AssociativeNode node, ref Stack<AssociativeNode> ssaStack, ref List<AssociativeNode> astlist) { if (node is IdentifierNode) { IdentifierNode ident = node as IdentifierNode; if (null == ident.ArrayDimensions) { // Build the temp pointer BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; bnode.isSSAAssignment = true; bnode.isSSAPointerAssignment = true; // Left node var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.BuildSSATemp(core)); (identNode as IdentifierNode).ReplicationGuides = GetReplicationGuides(ident); bnode.LeftNode = identNode; // Right node bnode.RightNode = ident; astlist.Add(bnode); ssaStack.Push(bnode); } else { EmitSSAArrayIndex(ident, ssaStack, ref astlist, true); } } else if (node is ExprListNode) { //ExprListNode exprList = node as ExprListNode; DFSEmitSSA_AST(node, ssaStack, ref astlist); } else if (node is FunctionCallNode) { FunctionCallNode fcall = node as FunctionCallNode; if (null == fcall.ArrayDimensions) { // Build the temp pointer BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; bnode.isSSAAssignment = true; bnode.isSSAPointerAssignment = true; // Left node var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.BuildSSATemp(core)); (identNode as IdentifierNode).ReplicationGuides = fcall.ReplicationGuides; bnode.LeftNode = identNode; // Right node bnode.RightNode = fcall; astlist.Add(bnode); ssaStack.Push(bnode); } else { EmitSSAArrayIndex(fcall, ssaStack, ref astlist, true); } } else if (node is IdentifierListNode) { IdentifierListNode identList = node as IdentifierListNode; //Check if the LeftNode for given IdentifierList represents a class. string[] classNames = this.core.ClassTable.GetAllMatchingClasses(identList.LeftNode.ToString()); if (classNames.Length > 1) { string message = string.Format(WarningMessage.kMultipleSymbolFound, identList.LeftNode.ToString(), classNames[0]); for(int i = 1; i < classNames.Length; ++i) message += ", " + classNames[i]; this.core.BuildStatus.LogWarning(WarningID.kMultipleSymbolFound, message); } if(classNames.Length == 1) { var leftNode = nodeBuilder.BuildIdentfier(classNames[0]); SSAIdentList(leftNode, ref ssaStack, ref astlist); } else { // Recursively traversse the left of the ident list SSAIdentList(identList.LeftNode, ref ssaStack, ref astlist); } // Build the rhs identifier list containing the temp pointer IdentifierListNode rhsIdentList = new IdentifierListNode(); rhsIdentList.Optr = Operator.dot; AssociativeNode lhsNode = ssaStack.Pop(); if (lhsNode is BinaryExpressionNode) { rhsIdentList.LeftNode = (lhsNode as BinaryExpressionNode).LeftNode; } else { rhsIdentList.LeftNode = lhsNode; } ArrayNode arrayDimension = null; AssociativeNode rnode = null; if (identList.RightNode is IdentifierNode) { IdentifierNode identNode = identList.RightNode as IdentifierNode; arrayDimension = identNode.ArrayDimensions; rnode = identNode; } else if (identList.RightNode is FunctionCallNode) { FunctionCallNode fcNode = new FunctionCallNode(identList.RightNode as FunctionCallNode); arrayDimension = fcNode.ArrayDimensions; List<AssociativeNode> astlistArgs = new List<AssociativeNode>(); for (int idx = 0; idx < fcNode.FormalArguments.Count; idx++) { AssociativeNode arg = fcNode.FormalArguments[idx]; var replicationGuides = GetReplicationGuides(arg); if (replicationGuides == null) { replicationGuides = new List<AssociativeNode> { }; } else { RemoveReplicationGuides(arg); } DFSEmitSSA_AST(arg, ssaStack, ref astlistArgs); var argNode = ssaStack.Pop(); var argBinaryExpr = argNode as BinaryExpressionNode; if (argBinaryExpr != null) { var newArgNode = NodeUtils.Clone(argBinaryExpr.LeftNode); (newArgNode as IdentifierNode).ReplicationGuides = replicationGuides; fcNode.FormalArguments[idx] = newArgNode; } else { fcNode.FormalArguments[idx] = argNode; } astlist.AddRange(astlistArgs); astlistArgs.Clear(); } astlist.AddRange(astlistArgs); rnode = fcNode; } else { Validity.Assert(false); } Validity.Assert(null != rnode); rhsIdentList.RightNode = rnode; if (null == arrayDimension) { // New SSA expr for the current dot call string ssatemp = ProtoCore.Utils.CoreUtils.BuildSSATemp(core); var tmpIdent = nodeBuilder.BuildIdentfier(ssatemp); BinaryExpressionNode bnode = new BinaryExpressionNode(tmpIdent, rhsIdentList, Operator.assign); bnode.isSSAPointerAssignment = true; astlist.Add(bnode); //ssaStack.Push(tmpIdent); ssaStack.Push(bnode); } else { EmitSSAArrayIndex(rhsIdentList, ssaStack, ref astlist, true); } } }
public FunctionDotCallNode(FunctionDotCallNode rhs): base(rhs) { DotCall = new FunctionCallNode(rhs.DotCall); FunctionCall = new FunctionCallNode(rhs.FunctionCall); lhsName = rhs.lhsName; isLastSSAIdentListFactor = rhs.isLastSSAIdentListFactor; }
public FunctionDotCallNode(string lhsName, FunctionCallNode callNode) { this.lhsName = lhsName; FunctionCall = callNode; isLastSSAIdentListFactor = false; }
protected FunctionCallNode EmitGetterSetterForIdent(IdentifierNode inode, bool isSetter = false) { if (isSetter) { FunctionCallNode setter = new FunctionCallNode(); setter.Function = inode; IdentifierNode tmpArg = new IdentifierNode(); tmpArg.Name = tmpArg.Value = ProtoCore.DSASM.Constants.kTempArg; tmpArg.datatype = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeVar, false); setter.FormalArguments.Add(tmpArg); return setter; } else { FunctionCallNode getter = new FunctionCallNode(); getter.Function = inode; return getter; } }
/// <summary> /// Converts lhs ident lists to a function call /// a.x = 10 /// -> t = a.%set_x(10) /// /// a.x.y = b + c /// -> a.x.%set_y(b + c) /// /// a.x[0] = 10 /// -> tval = a.%get_x() /// tval[0] = 10 /// tmp = a.%set_x(tval) /// </summary> /// <param name="astList"></param> /// <returns></returns> private List<AssociativeNode> TransformLHSIdentList(List<AssociativeNode> astList) { List<AssociativeNode> newAstList = new List<AssociativeNode>(); foreach (AssociativeNode node in astList) { BinaryExpressionNode bNode = node as BinaryExpressionNode; if (bNode == null) { newAstList.Add(node); } else { bool isLHSIdentList = bNode.LeftNode is IdentifierListNode; if (!isLHSIdentList) { newAstList.Add(node); } else { IdentifierNode lhsTemp = new IdentifierNode(Constants.kTempVar); IdentifierListNode identList = bNode.LeftNode as IdentifierListNode; Validity.Assert(identList != null); AssociativeNode argument = bNode.RightNode; IdentifierNode identFunctionCall = identList.RightNode as IdentifierNode; string setterName = ProtoCore.DSASM.Constants.kSetterPrefix + identList.RightNode.Name; bool isArrayIndexed = identFunctionCall.ArrayDimensions != null; if (isArrayIndexed) { // a.x[0] = 10 // tval = a.%get_x() string getterName = ProtoCore.DSASM.Constants.kGetterPrefix + identList.RightNode.Name; ProtoCore.AST.AssociativeAST.FunctionCallNode fcall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); fcall.Function = new IdentifierNode(identList.RightNode.Name); fcall.Function.Name = getterName; IdentifierListNode identList1 = new IdentifierListNode(); identList1.LeftNode = identList.LeftNode; identList1.RightNode = fcall; BinaryExpressionNode bnodeGet = new BinaryExpressionNode( lhsTemp, identList1, Operator.assign ); newAstList.Add(bnodeGet); // tval[0] = 10 IdentifierNode lhsTempIndexed = new IdentifierNode(Constants.kTempVar); lhsTempIndexed.ArrayDimensions = identFunctionCall.ArrayDimensions; BinaryExpressionNode bnodeAssign = new BinaryExpressionNode( lhsTempIndexed, argument, Operator.assign ); newAstList.Add(bnodeAssign); // tmp = a.%set_x(tval) ProtoCore.AST.AssociativeAST.FunctionCallNode fcallSet = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); fcallSet.Function = identFunctionCall; fcallSet.Function.Name = setterName; List<AssociativeNode> args = new List<AssociativeNode>(); IdentifierNode lhsTempAssignBack = new IdentifierNode(Constants.kTempVar); args.Add(lhsTempAssignBack); fcallSet.FormalArguments = args; IdentifierListNode identList2 = new IdentifierListNode(); identList2.LeftNode = identList.LeftNode; identList2.RightNode = fcallSet; IdentifierNode lhsTempAssign = new IdentifierNode(Constants.kTempPropertyVar); BinaryExpressionNode bnodeSet = new BinaryExpressionNode( lhsTempAssign, identList2, Operator.assign ); newAstList.Add(bnodeSet); } else { List<AssociativeNode> args = new List<AssociativeNode>(); args.Add(argument); ProtoCore.AST.AssociativeAST.FunctionCallNode fcall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); fcall.Function = identFunctionCall; fcall.Function.Name = setterName; fcall.FormalArguments = args; identList.RightNode = fcall; BinaryExpressionNode convertedAssignNode = new BinaryExpressionNode(lhsTemp, identList, Operator.assign); NodeUtils.CopyNodeLocation(convertedAssignNode, bNode); newAstList.Add(convertedAssignNode); } } } } return newAstList; }
private ProtoCore.AST.AssociativeAST.AssociativeNode GenerateBinaryOperatorMethodCallNode(Operator op, ProtoCore.AST.AssociativeAST.AssociativeNode op1, ProtoCore.AST.AssociativeAST.AssociativeNode op2) { ProtoCore.AST.AssociativeAST.FunctionCallNode funCallNode = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); ProtoCore.AST.AssociativeAST.IdentifierNode funcName = new ProtoCore.AST.AssociativeAST.IdentifierNode { Value = ProtoCore.DSASM.Op.GetOpFunction(op), Name = ProtoCore.DSASM.Op.GetOpFunction(op) }; funCallNode.Function = funcName; funCallNode.Name = ProtoCore.DSASM.Op.GetOpFunction(op); funCallNode.FormalArguments.Add(op1); funCallNode.FormalArguments.Add(op2); NodeUtils.SetNodeLocation(funCallNode, op1, op2); return funCallNode; }
public FunctionCallNode(FunctionCallNode rhs) : base(rhs) { Function = NodeUtils.Clone(rhs.Function); FormalArguments = new List<AssociativeNode>(); foreach (AssociativeNode argNode in rhs.FormalArguments) { AssociativeNode tempNode = NodeUtils.Clone(argNode); FormalArguments.Add(tempNode); } DynamicTableIndex = rhs.DynamicTableIndex; }
/* proc DFSEmit_SSA_AST(node, ssastack[], astlist[]) if node is binary expression def bnode if node.optr is assign op bnode.optr = node.optr bnode.left = node.left DFSEmit_SSA_AST(node.right, ssastack, astlist) bnode.right = ssastack.pop() else def tnode tnode.optr = node.optr DFSEmit_SSA_AST(node.left, ssastack, astlist) DFSEmit_SSA_AST(node.right, ssastack, astlist) def lastnode = ssastack.pop() def prevnode = ssastack.pop() if prevnode is binary tnode.left = prevnode.left else tnode.left = prevnode end if lastnode is binary tnode.right = lastnode.left else tnode.right = lastnode end bnode.optr = �=� bnode.left = GetSSATemp() bnode.right = tnode end astlist.append(bnode) ssastack.push(bnode) else if node is identifier def bnode bnode.optr = �=� bnode.left = GetSSATemp() bnode.right = node astlist.append(bnode) ssastack.push(bnode) else ssastack.push(node) end end */ private void DFSEmitSSA_AST(AssociativeNode node, Stack<AssociativeNode> ssaStack, ref List<AssociativeNode> astlist) { Debug.Assert(null != astlist && null != ssaStack); if (node is BinaryExpressionNode) { BinaryExpressionNode astBNode = node as BinaryExpressionNode; BinaryExpressionNode bnode = new BinaryExpressionNode(); if (ProtoCore.DSASM.Operator.assign == astBNode.Optr) { bnode.Optr = ProtoCore.DSASM.Operator.assign; bnode.LeftNode = astBNode.LeftNode; DFSEmitSSA_AST(astBNode.RightNode, ssaStack, ref astlist); AssociativeNode assocNode = ssaStack.Pop(); if (assocNode is BinaryExpressionNode) { bnode.RightNode = (assocNode as BinaryExpressionNode).LeftNode; } else { bnode.RightNode = assocNode; } bnode.isSSAAssignment = false; } else { BinaryExpressionNode tnode = new BinaryExpressionNode(); tnode.Optr = astBNode.Optr; DFSEmitSSA_AST(astBNode.LeftNode, ssaStack, ref astlist); DFSEmitSSA_AST(astBNode.RightNode, ssaStack, ref astlist); AssociativeNode lastnode = ssaStack.Pop(); AssociativeNode prevnode = ssaStack.Pop(); tnode.LeftNode = prevnode is BinaryExpressionNode ? (prevnode as BinaryExpressionNode).LeftNode : prevnode; tnode.RightNode = lastnode is BinaryExpressionNode ? (lastnode as BinaryExpressionNode).LeftNode : lastnode; bnode.Optr = ProtoCore.DSASM.Operator.assign; // Left node var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker)); bnode.LeftNode = identNode; // Right node bnode.RightNode = tnode; bnode.isSSAAssignment = true; } astlist.Add(bnode); ssaStack.Push(bnode); } else if (node is ArrayNode) { ArrayNode arrayNode = node as ArrayNode; DFSEmitSSA_AST(arrayNode.Expr, ssaStack, ref astlist); BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; // Left node AssociativeNode tmpIdent = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker)); Validity.Assert(null != tmpIdent); bnode.LeftNode = tmpIdent; // pop off the dimension AssociativeNode dimensionNode = ssaStack.Pop(); ArrayNode currentDimensionNode = null; if (dimensionNode is BinaryExpressionNode) { currentDimensionNode = new ArrayNode((dimensionNode as BinaryExpressionNode).LeftNode, null); } else { currentDimensionNode = new ArrayNode(dimensionNode, null); } // Pop the prev SSA node where the current dimension will apply AssociativeNode nodePrev = ssaStack.Pop(); if (nodePrev is BinaryExpressionNode) { AssociativeNode rhsIdent = nodeBuilder.BuildIdentfier((nodePrev as BinaryExpressionNode).LeftNode.Name); (rhsIdent as IdentifierNode).ArrayDimensions = currentDimensionNode; bnode.RightNode = rhsIdent; astlist.Add(bnode); ssaStack.Push(bnode); if (null != arrayNode.Type) { DFSEmitSSA_AST(arrayNode.Type, ssaStack, ref astlist); } } else if (nodePrev is IdentifierListNode) { IdentifierNode iNode = (nodePrev as IdentifierListNode).RightNode as IdentifierNode; Validity.Assert(null != iNode); iNode.ArrayDimensions = currentDimensionNode; if (null != arrayNode.Type) { DFSEmitSSA_AST(arrayNode.Type, ssaStack, ref astlist); } } else { Validity.Assert(false); } //bnode.RightNode = rhsIdent; //astlist.Add(bnode); //ssaStack.Push(bnode); } else if (node is IdentifierNode) { IdentifierNode ident = node as IdentifierNode; if (null == ident.ArrayDimensions) { BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; // Left node var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker)); bnode.LeftNode = identNode; // Right node bnode.RightNode = ident; bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else { EmitSSAArrayIndex(ident, ssaStack, ref astlist); } } else if (node is FunctionCallNode || node is FunctionDotCallNode) { FunctionCallNode fcNode = null; if (node is FunctionCallNode) { fcNode = node as FunctionCallNode; for (int idx = 0; idx < fcNode.FormalArguments.Count; idx++) { AssociativeNode arg = fcNode.FormalArguments[idx]; DFSEmitSSA_AST(arg, ssaStack, ref astlist); AssociativeNode argNode = ssaStack.Pop(); if (argNode is BinaryExpressionNode) { BinaryExpressionNode argBinaryExpr = argNode as BinaryExpressionNode; (argBinaryExpr.LeftNode as IdentifierNode).ReplicationGuides = GetReplicationGuidesFromASTNode(argBinaryExpr.RightNode); fcNode.FormalArguments[idx] = argBinaryExpr.LeftNode; } else { fcNode.FormalArguments[idx] = argNode; } } } BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; // Left node var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker)); bnode.LeftNode = identNode; // Store the replication guide from the function call to the temp (identNode as IdentifierNode).ReplicationGuides = GetReplicationGuidesFromASTNode(node); //Right node bnode.RightNode = node; bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else if (node is IdentifierListNode) { SSAIdentList(node, ref ssaStack, ref astlist); AssociativeNode lastNode = null; Validity.Assert(astlist.Count > 0); // Get the last identifierlist node and set its flag // This is required to reset the pointerlist for every identifierlist traversed // i.e. // a = p.x // reset the flag after traversing p.x // // b = p.x + g.y // reset the flag after traversing p.x and p.y // int lastIndex = astlist.Count - 1; for (int n = lastIndex; n >= 0 ; --n) { lastNode = astlist[n]; Validity.Assert(lastNode is BinaryExpressionNode); BinaryExpressionNode bnode = lastNode as BinaryExpressionNode; Validity.Assert(bnode.Optr == Operator.assign); if (bnode.RightNode is IdentifierListNode) { IdentifierListNode identList = bnode.RightNode as IdentifierListNode; identList.isLastSSAIdentListFactor = true; break; } } // // Backtrack and convert all identlist nodes to dot calls // This can potentially be optimized by performing the dotcall transform in SSAIdentList // /////////////////////////// int x = 0; for (int n = lastIndex; n >= 0; --n) { lastNode = astlist[n]; BinaryExpressionNode bnode = lastNode as BinaryExpressionNode; Validity.Assert(bnode.Optr == Operator.assign); if (bnode.RightNode is IdentifierListNode) { IdentifierListNode identList = bnode.RightNode as IdentifierListNode; if (identList.RightNode is IdentifierNode) { IdentifierNode identNode = identList.RightNode as IdentifierNode; ProtoCore.AST.AssociativeAST.FunctionCallNode rcall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); rcall.Function = new IdentifierNode(identNode); rcall.Function.Name = ProtoCore.DSASM.Constants.kGetterPrefix + rcall.Function.Name; FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(identList.LeftNode, rcall, compileStateTracker); dotCall.isLastSSAIdentListFactor = identList.isLastSSAIdentListFactor; bnode.RightNode = dotCall; } else if (identList.RightNode is FunctionCallNode) { FunctionCallNode fCallNode = identList.RightNode as FunctionCallNode; FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(identList.LeftNode, fCallNode, compileStateTracker); dotCall.isLastSSAIdentListFactor = identList.isLastSSAIdentListFactor; bnode.RightNode = dotCall; } else { Validity.Assert(false); } } if (bnode.isSSAFirstAssignment) { break; } } /////////////////////////// } else if (node is ExprListNode) { ExprListNode exprList = node as ExprListNode; for (int n = 0; n < exprList.list.Count; n++) { DFSEmitSSA_AST(exprList.list[n], ssaStack, ref astlist); AssociativeNode argNode = ssaStack.Pop(); exprList.list[n] = argNode is BinaryExpressionNode ? (argNode as BinaryExpressionNode).LeftNode : argNode; } BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; // Left node var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker)); bnode.LeftNode = identNode; //Right node bnode.RightNode = exprList; bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else if (node is InlineConditionalNode) { InlineConditionalNode ilnode = node as InlineConditionalNode; DFSEmitSSA_AST(ilnode.ConditionExpression, ssaStack, ref astlist); AssociativeNode cexpr = ssaStack.Pop(); ilnode.ConditionExpression = cexpr is BinaryExpressionNode ? (cexpr as BinaryExpressionNode).LeftNode : cexpr; DFSEmitSSA_AST(ilnode.TrueExpression, ssaStack, ref astlist); AssociativeNode trueExpr = ssaStack.Pop(); ilnode.TrueExpression = trueExpr is BinaryExpressionNode ? (trueExpr as BinaryExpressionNode).LeftNode : trueExpr; DFSEmitSSA_AST(ilnode.FalseExpression, ssaStack, ref astlist); AssociativeNode falseExpr = ssaStack.Pop(); ilnode.FalseExpression = falseExpr is BinaryExpressionNode ? (falseExpr as BinaryExpressionNode).LeftNode : falseExpr; BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; // Left node var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker)); bnode.LeftNode = identNode; //Right node bnode.RightNode = ilnode; bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else if (node is RangeExprNode) { RangeExprNode rangeNode = node as RangeExprNode; DFSEmitSSA_AST(rangeNode.FromNode, ssaStack, ref astlist); AssociativeNode fromExpr = ssaStack.Pop(); rangeNode.FromNode = fromExpr is BinaryExpressionNode ? (fromExpr as BinaryExpressionNode).LeftNode : fromExpr; DFSEmitSSA_AST(rangeNode.ToNode, ssaStack, ref astlist); AssociativeNode toExpr = ssaStack.Pop(); rangeNode.ToNode = toExpr is BinaryExpressionNode ? (toExpr as BinaryExpressionNode).LeftNode : toExpr; if (rangeNode.StepNode != null) { DFSEmitSSA_AST(rangeNode.StepNode, ssaStack, ref astlist); AssociativeNode stepExpr = ssaStack.Pop(); rangeNode.StepNode = stepExpr is BinaryExpressionNode ? (stepExpr as BinaryExpressionNode).LeftNode : stepExpr; } BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; // Left node var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker)); bnode.LeftNode = identNode; //Right node bnode.RightNode = rangeNode; bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else { ssaStack.Push(node); } }
private void EmitFunctionCallNode(Func node, out AssociativeNode outnode) { Validity.Assert(node != null); FunctionCallNode fNode = new FunctionCallNode(); List<ProtoCore.AST.AssociativeAST.AssociativeNode> args = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); if (node.Name.Contains(".")) { string funcName = (node.Name.Split('.'))[1]; fNode.Function = new IdentifierNode(funcName); } //else if (node.GetChildrenWithIndices().Count != 0) //{ //} else fNode.Function = new IdentifierNode(node.Name); for (int i = 0; i < node.numParameters; i++) args.Add(new NullNode()); if (args.Count > 0) { Dictionary<int, Node> nodes = node.GetChildrenWithIndices(); for (int i = 0; i < nodes.Count; ++i) { AssociativeNode argNode = null; DFSTraverse(nodes[i], out argNode); args.RemoveAt(i); args.Insert(i, argNode); } } fNode.FormalArguments = args; outnode = fNode; }
void Associative_BaseConstructorCall(out ProtoCore.AST.AssociativeAST.AssociativeNode bnode) { ProtoCore.AST.AssociativeAST.FunctionCallNode f = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); List<ProtoCore.AST.AssociativeAST.AssociativeNode> args = null; if (la.val != "base") { SynErr(Resources.BaseIsExpectedToCallBaseConstructor); } else { Get(); NodeUtils.SetNodeLocation(f, t); } if (la.kind == 6) { Get(); Associative_Ident(out bnode); f.Function = bnode; } Associative_Arguments(out args); f.FormalArguments = args; bnode = f; }
void Associative_IdentifierList(out ProtoCore.AST.AssociativeAST.AssociativeNode node) { node = null; if (isInClass && IsIdentList()) { disableKwCheck = true; } Associative_NameReference(out node); disableKwCheck = false; ProtoCore.AST.AssociativeAST.AssociativeNode inode = node; while (la.kind == 6) { Get(); ProtoCore.AST.AssociativeAST.AssociativeNode rnode = null; Associative_NameReference(out rnode); if ((inode is ProtoCore.AST.AssociativeAST.IdentifierNode) && (inode as ProtoCore.AST.AssociativeAST.IdentifierNode).Name == ProtoCore.DSDefinitions.Keyword.This && (rnode is ProtoCore.AST.AssociativeAST.FunctionCallNode)) { node = rnode; return; } ProtoCore.AST.AssociativeAST.IdentifierListNode bnode = new ProtoCore.AST.AssociativeAST.IdentifierListNode(); bnode.LeftNode = node; bnode.Optr = Operator.dot; bnode.RightNode = rnode; node = bnode; NodeUtils.SetNodeLocation(bnode, bnode.LeftNode, bnode.RightNode); if (!core.Options.GenerateSSA) { bool isNeitherIdentOrFunctionCall = !(rnode is ProtoCore.AST.AssociativeAST.IdentifierNode || rnode is ProtoCore.AST.AssociativeAST.FunctionCallNode); if (isLeft || isNeitherIdentOrFunctionCall) { node = inode; } else { if (rnode is ProtoCore.AST.AssociativeAST.IdentifierNode) { ProtoCore.AST.AssociativeAST.FunctionCallNode rcall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); rcall.Function = rnode; rcall.Function.Name = ProtoCore.DSASM.Constants.kGetterPrefix + rcall.Function.Name; bnode.RightNode = rcall; NodeUtils.SetNodeLocation(rcall, rnode, rnode); node = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(bnode.LeftNode, rcall, core); } else { string rhsName = null; ProtoCore.AST.AssociativeAST.ExprListNode dimList = null; int dim = 0; if (rnode is ProtoCore.AST.AssociativeAST.FunctionCallNode) { ProtoCore.AST.AssociativeAST.FunctionCallNode rhsFNode = rnode as ProtoCore.AST.AssociativeAST.FunctionCallNode; node = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(node, rhsFNode, core); } } } } } { if (!isModifier && withinModifierCheckScope) { if (isLeftVarIdentList) { if (inode is ProtoCore.AST.AssociativeAST.IdentifierListNode) { isModifier = false; if (node is ProtoCore.AST.AssociativeAST.FunctionDotCallNode) { ProtoCore.AST.AssociativeAST.FunctionDotCallNode fdotCall = node as ProtoCore.AST.AssociativeAST.FunctionDotCallNode; string checkVar = ProtoCore.Utils.CoreUtils.GenerateIdentListNameString(fdotCall.GetIdentList()); isModifier = (leftVar == checkVar); } } } else if (inode is ProtoCore.AST.AssociativeAST.IdentifierNode) { isModifier = (leftVar == inode.Name); } // The LHS is an identifier else { // It is a modifier if the lhs is: // 1. the same as the current node // 2. the current node starts with the lhs identifier isModifier = (leftVar == inode.Name); if (!isModifier) { string rhsString = ProtoCore.Utils.CoreUtils.GenerateIdentListNameString(inode); isModifier = rhsString.StartsWith(leftVar); } } } } }
private void DFSEmitSSA_AST(AssociativeNode node, Stack<AssociativeNode> ssaStack, ref List<AssociativeNode> astlist) { Validity.Assert(null != astlist && null != ssaStack); if (node is BinaryExpressionNode) { BinaryExpressionNode astBNode = node as BinaryExpressionNode; AssociativeNode leftNode = null; AssociativeNode rightNode = null; bool isSSAAssignment = false; if (ProtoCore.DSASM.Operator.assign == astBNode.Optr) { leftNode = astBNode.LeftNode; DFSEmitSSA_AST(astBNode.RightNode, ssaStack, ref astlist); AssociativeNode assocNode = ssaStack.Pop(); if (assocNode is BinaryExpressionNode) { rightNode = (assocNode as BinaryExpressionNode).LeftNode; } else { rightNode = assocNode; } isSSAAssignment = false; // Handle SSA if the lhs is not an identifier // A non-identifier LHS is any LHS that is not just an identifier name. // i.e. a[0], a.b, f(), f(x) var isSingleIdentifier = (leftNode is IdentifierNode) && (leftNode as IdentifierNode).ArrayDimensions == null; if (!isSingleIdentifier) { EmitSSALHS(ref leftNode, ssaStack, ref astlist); } } else { BinaryExpressionNode tnode = new BinaryExpressionNode(); tnode.Optr = astBNode.Optr; DFSEmitSSA_AST(astBNode.LeftNode, ssaStack, ref astlist); DFSEmitSSA_AST(astBNode.RightNode, ssaStack, ref astlist); AssociativeNode lastnode = ssaStack.Pop(); AssociativeNode prevnode = ssaStack.Pop(); tnode.LeftNode = prevnode is BinaryExpressionNode ? (prevnode as BinaryExpressionNode).LeftNode : prevnode; tnode.RightNode = lastnode is BinaryExpressionNode ? (lastnode as BinaryExpressionNode).LeftNode : lastnode; // Left node leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core)); // Right node rightNode = tnode; isSSAAssignment = true; } var bnode = AstFactory.BuildAssignment(leftNode, rightNode); bnode.isSSAAssignment = isSSAAssignment; bnode.IsInputExpression = astBNode.IsInputExpression; astlist.Add(bnode); ssaStack.Push(bnode); } else if (node is ArrayNode) { var arrayNode = node as ArrayNode; DFSEmitSSA_AST(arrayNode.Expr, ssaStack, ref astlist); var bnode = new BinaryExpressionNode { Optr = Operator.assign }; // Left node var tmpIdent = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core)); Validity.Assert(null != tmpIdent); bnode.LeftNode = tmpIdent; if (arrayNode.Expr == null && arrayNode.Type == null) { // Right node bnode.RightNode = new NullNode(); astlist.Add(bnode); ssaStack.Push(bnode); return; } // pop off the dimension var dimensionNode = ssaStack.Pop(); ArrayNode currentDimensionNode; if (dimensionNode is BinaryExpressionNode) { currentDimensionNode = new ArrayNode((dimensionNode as BinaryExpressionNode).LeftNode, null); } else { currentDimensionNode = new ArrayNode(dimensionNode, null); } // Pop the prev SSA node where the current dimension will apply AssociativeNode nodePrev = ssaStack.Pop(); if (nodePrev is BinaryExpressionNode) { AssociativeNode rhsIdent =AstFactory.BuildIdentifier((nodePrev as BinaryExpressionNode).LeftNode.Name); (rhsIdent as IdentifierNode).ArrayDimensions = currentDimensionNode; bnode.RightNode = rhsIdent; astlist.Add(bnode); ssaStack.Push(bnode); if (null != arrayNode.Type) { DFSEmitSSA_AST(arrayNode.Type, ssaStack, ref astlist); } } else if (nodePrev is IdentifierListNode) { IdentifierNode iNode = (nodePrev as IdentifierListNode).RightNode as IdentifierNode; Validity.Assert(null != iNode); iNode.ArrayDimensions = currentDimensionNode; if (null != arrayNode.Type) { DFSEmitSSA_AST(arrayNode.Type, ssaStack, ref astlist); } } else { Validity.Assert(false); } } else if (node is IdentifierNode) { IdentifierNode ident = node as IdentifierNode; if (core.Options.GenerateSSA) { string ssaTempName = string.Empty; if (null == ident.ArrayDimensions) { BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; // Left node ssaTempName = ProtoCore.Utils.CoreUtils.BuildSSATemp(core); var identNode =AstFactory.BuildIdentifier(ssaTempName); bnode.LeftNode = identNode; // Right node bnode.RightNode = ident; bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); // Associate the first pointer with each SSA temp // It is acceptable to store firstVar even if it is not a pointer as ResolveFinalNodeRefs() will just ignore this entry // if this ssa temp is not treated as a pointer inside the function string firstVar = ident.Name; ssaTempToFirstPointerMap.Add(ssaTempName, firstVar); } else { EmitSSAArrayIndex(ident, ssaStack, ref astlist); } } else { BinaryExpressionNode bnode = new BinaryExpressionNode(); bnode.Optr = ProtoCore.DSASM.Operator.assign; // Left node var identNode =AstFactory.BuildIdentifier(ProtoCore.Utils.CoreUtils.BuildSSATemp(core)); bnode.LeftNode = identNode; // Right node bnode.RightNode = ident; bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } } else if (node is FunctionCallNode || node is FunctionDotCallNode) { FunctionCallNode fcNode = null; if (node is FunctionCallNode) { fcNode = new FunctionCallNode(node as FunctionCallNode); List<AssociativeNode> astlistArgs = new List<AssociativeNode>(); for (int idx = 0; idx < fcNode.FormalArguments.Count; idx++) { AssociativeNode arg = fcNode.FormalArguments[idx]; DFSEmitSSA_AST(arg, ssaStack, ref astlistArgs); AssociativeNode argNode = ssaStack.Pop(); if (argNode is BinaryExpressionNode) { BinaryExpressionNode argBinaryExpr = argNode as BinaryExpressionNode; var argLeftNode = argBinaryExpr.LeftNode as IdentifierNode; argLeftNode.ReplicationGuides = GetReplicationGuides(arg); argLeftNode.AtLevel = GetAtLevel(arg); fcNode.FormalArguments[idx] = argBinaryExpr.LeftNode; } else { fcNode.FormalArguments[idx] = argNode; } astlist.AddRange(astlistArgs); astlistArgs.Clear(); } } // Left node var leftNode =AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core)); if (null != fcNode) { leftNode.ReplicationGuides = GetReplicationGuides(fcNode); leftNode.AtLevel = GetAtLevel(fcNode); } var bnode = AstFactory.BuildAssignment(leftNode, fcNode); bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else if (node is IdentifierListNode) { SSAIdentList(node, ref ssaStack, ref astlist); AssociativeNode lastNode = null; Validity.Assert(astlist.Count > 0); // Get the last identifierlist node and set its flag // This is required to reset the pointerlist for every identifierlist traversed // i.e. // a = p.x // reset the flag after traversing p.x // // b = p.x + g.y // reset the flag after traversing p.x and p.y // int lastIndex = astlist.Count - 1; for (int n = lastIndex; n >= 0 ; --n) { lastNode = astlist[n]; Validity.Assert(lastNode is BinaryExpressionNode); BinaryExpressionNode bnode = lastNode as BinaryExpressionNode; Validity.Assert(bnode.Optr == Operator.assign); if (bnode.RightNode is IdentifierListNode) { IdentifierListNode identList = bnode.RightNode as IdentifierListNode; identList.IsLastSSAIdentListFactor = true; break; } } // Assign the first ssa assignment flag BinaryExpressionNode firstBNode = astlist[0] as BinaryExpressionNode; Validity.Assert(null != firstBNode); Validity.Assert(firstBNode.Optr == Operator.assign); firstBNode.isSSAFirstAssignment = true; // // Get the first pointer // The first pointer is the lhs of the next dotcall // // Given: // a = x.y.z // SSA'd to: // t0 = x -> 'x' is the lhs of the first dotcall (x.y) // t1 = t0.y // t2 = t1.z // a = t2 IdentifierNode lhsIdent = null; if (firstBNode.RightNode is IdentifierNode) { // In this case the rhs of the ident list is an ident // Get the ident name lhsIdent = (firstBNode.RightNode as IdentifierNode); } else if(firstBNode.RightNode is FunctionCallNode) { // In this case the rhs of the ident list is a function // Get the function name lhsIdent = (firstBNode.RightNode as FunctionCallNode).Function as IdentifierNode; } else { lhsIdent = null; } //========================================================= // // 1. Backtrack and convert all identlist nodes to dot calls // This can potentially be optimized by performing the dotcall transform in SSAIdentList // // 2. Associate the first pointer with each SSA temp // //========================================================= AssociativeNode prevNode = null; for (int n = 0; n <= lastIndex; n++) { lastNode = astlist[n]; BinaryExpressionNode bnode = lastNode as BinaryExpressionNode; Validity.Assert(bnode.Optr == Operator.assign); // Get the ssa temp name Validity.Assert(bnode.LeftNode is IdentifierNode); string ssaTempName = (bnode.LeftNode as IdentifierNode).Name; Validity.Assert(CoreUtils.IsSSATemp(ssaTempName)); if (bnode.RightNode is IdentifierListNode) { IdentifierListNode identList = bnode.RightNode as IdentifierListNode; if (identList.RightNode is IdentifierNode) { IdentifierNode identNode = identList.RightNode as IdentifierNode; ProtoCore.AST.AssociativeAST.FunctionCallNode rcall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); rcall.Function = new IdentifierNode(identNode); rcall.Function.Name = ProtoCore.DSASM.Constants.kGetterPrefix + rcall.Function.Name; ProtoCore.Utils.CoreUtils.CopyDebugData(identList.LeftNode, lhsIdent); FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(identList.LeftNode, rcall, core); dotCall.isLastSSAIdentListFactor = identList.IsLastSSAIdentListFactor; bnode.RightNode = dotCall; ProtoCore.Utils.CoreUtils.CopyDebugData(bnode, lhsIdent); // Update the LHS of the next dotcall // a = x.y.z // t0 = x // t1 = t0.y 'y' is the lhs of the next dotcall (y.z) // t2 = t1.z // a = t2 // Validity.Assert(rcall.Function is IdentifierNode); lhsIdent = rcall.Function as IdentifierNode; } else if (identList.RightNode is FunctionCallNode) { FunctionCallNode fCallNode = identList.RightNode as FunctionCallNode; ProtoCore.Utils.CoreUtils.CopyDebugData(identList.LeftNode, lhsIdent); FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(identList.LeftNode, fCallNode, core); dotCall.isLastSSAIdentListFactor = identList.IsLastSSAIdentListFactor; bnode.RightNode = dotCall; ProtoCore.Utils.CoreUtils.CopyDebugData(bnode, lhsIdent); // Update the LHS of the next dotcall // a = x.y.z // t0 = x // t1 = t0.y 'y' is the lhs of the next dotcall (y.z) // t2 = t1.z // a = t2 // Validity.Assert(fCallNode.Function is IdentifierNode); lhsIdent = fCallNode.Function as IdentifierNode; } else { Validity.Assert(false); } } prevNode = bnode.RightNode; } } else if (node is ExprListNode) { ExprListNode exprList = node as ExprListNode; for (int n = 0; n < exprList.Exprs.Count; n++) { List<AssociativeNode> currentElementASTList = new List<AssociativeNode>(); DFSEmitSSA_AST(exprList.Exprs[n], ssaStack, ref currentElementASTList); astlist.AddRange(currentElementASTList); currentElementASTList.Clear(); AssociativeNode argNode = ssaStack.Pop(); exprList.Exprs[n] = argNode is BinaryExpressionNode ? (argNode as BinaryExpressionNode).LeftNode : argNode; } var leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core)); var bnode = AstFactory.BuildAssignment(leftNode, exprList); bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else if (node is InlineConditionalNode) { InlineConditionalNode ilnode = node as InlineConditionalNode; List<AssociativeNode> inlineExpressionASTList = new List<AssociativeNode>(); // Emit the boolean condition DFSEmitSSA_AST(ilnode.ConditionExpression, ssaStack, ref inlineExpressionASTList); AssociativeNode cexpr = ssaStack.Pop(); ilnode.ConditionExpression = cexpr is BinaryExpressionNode ? (cexpr as BinaryExpressionNode).LeftNode : cexpr; var namenode = ilnode.ConditionExpression as ArrayNameNode; if (namenode != null) { var rightNode = (cexpr is BinaryExpressionNode) ? (cexpr as BinaryExpressionNode).RightNode : cexpr; namenode.ReplicationGuides = GetReplicationGuides(rightNode); namenode.AtLevel = GetAtLevel(rightNode); } astlist.AddRange(inlineExpressionASTList); inlineExpressionASTList.Clear(); DFSEmitSSA_AST(ilnode.TrueExpression, ssaStack, ref inlineExpressionASTList); cexpr = ssaStack.Pop(); ilnode.TrueExpression = cexpr is BinaryExpressionNode ? (cexpr as BinaryExpressionNode).LeftNode : cexpr; namenode = ilnode.TrueExpression as ArrayNameNode; if (namenode != null) { var rightNode = (cexpr is BinaryExpressionNode) ? (cexpr as BinaryExpressionNode).RightNode : cexpr; namenode.ReplicationGuides = GetReplicationGuides(rightNode); namenode.AtLevel = GetAtLevel(rightNode); } astlist.AddRange(inlineExpressionASTList); inlineExpressionASTList.Clear(); DFSEmitSSA_AST(ilnode.FalseExpression, ssaStack, ref inlineExpressionASTList); cexpr = ssaStack.Pop(); ilnode.FalseExpression = cexpr is BinaryExpressionNode ? (cexpr as BinaryExpressionNode).LeftNode : cexpr; namenode = ilnode.FalseExpression as ArrayNameNode; if (namenode != null) { var rightNode = (cexpr is BinaryExpressionNode) ? (cexpr as BinaryExpressionNode).RightNode : cexpr; namenode.ReplicationGuides = GetReplicationGuides(rightNode); namenode.AtLevel = GetAtLevel(rightNode); } astlist.AddRange(inlineExpressionASTList); inlineExpressionASTList.Clear(); var leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core)); var bnode = AstFactory.BuildAssignment(leftNode, ilnode); bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else if (node is RangeExprNode) { RangeExprNode rangeNode = node as RangeExprNode; DFSEmitSSA_AST(rangeNode.From, ssaStack, ref astlist); AssociativeNode fromExpr = ssaStack.Pop(); rangeNode.From = fromExpr is BinaryExpressionNode ? (fromExpr as BinaryExpressionNode).LeftNode : fromExpr; DFSEmitSSA_AST(rangeNode.To, ssaStack, ref astlist); AssociativeNode toExpr = ssaStack.Pop(); rangeNode.To = toExpr is BinaryExpressionNode ? (toExpr as BinaryExpressionNode).LeftNode : toExpr; if (rangeNode.Step != null) { DFSEmitSSA_AST(rangeNode.Step, ssaStack, ref astlist); AssociativeNode stepExpr = ssaStack.Pop(); rangeNode.Step = stepExpr is BinaryExpressionNode ? (stepExpr as BinaryExpressionNode).LeftNode : stepExpr; } var leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core)); var bnode = AstFactory.BuildAssignment(leftNode, rangeNode); bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else if (node is GroupExpressionNode) { if (core.Options.GenerateSSA) { GroupExpressionNode groupExpr = node as GroupExpressionNode; if (null == groupExpr.ArrayDimensions) { DFSEmitSSA_AST(groupExpr.Expression, ssaStack, ref astlist); var leftNode =AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core)); AssociativeNode groupExprBinaryStmt = ssaStack.Pop(); var rightNode = (groupExprBinaryStmt as BinaryExpressionNode).LeftNode; var bnode = AstFactory.BuildAssignment(leftNode, rightNode); bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else { EmitSSAArrayIndex(groupExpr, ssaStack, ref astlist); } } else { // We never supported SSA on grouped expressions // Keep it that way if SSA flag is off ssaStack.Push(node); } } // We allow a null to be generated an SSA variable // TODO Jun: Generalize this into genrating SSA temps for all literals else if (node is NullNode) { var leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core)); var bnode = AstFactory.BuildAssignment(leftNode, node); bnode.isSSAAssignment = true; astlist.Add(bnode); ssaStack.Push(bnode); } else { ssaStack.Push(node); } }
void Associative_Attribute(out ProtoCore.AST.AssociativeAST.AssociativeNode node) { ProtoCore.AST.AssociativeAST.FunctionCallNode f = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); Associative_Ident(out node); NodeUtils.SetNodeStartLocation(f, t); List<ProtoCore.AST.AssociativeAST.AssociativeNode> args = null; while (la.kind == 12) { Associative_Arguments(out args); f.FormalArguments = args; } f.Function = node; NodeUtils.SetNodeEndLocation(f, t); node = f; }
private void EmitInlineConditionalNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.AssociativeAST.BinaryExpressionNode parentNode = null) { if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { return; } bool isInlineConditionalFlag = false; int startPC = pc; bool isReturn = false; if (graphNode != null) { isInlineConditionalFlag = graphNode.isInlineConditional; graphNode.isInlineConditional = true; startPC = graphNode.updateBlock.startpc; isReturn = graphNode.isReturn; } InlineConditionalNode inlineConditionalNode = node as InlineConditionalNode; // TODO: Jun, this 'if' condition needs to be removed as it was the old implementation - pratapa if (inlineConditionalNode.IsAutoGenerated) { // Normal inline conditional IfStatementNode ifNode = new IfStatementNode(); ifNode.ifExprNode = inlineConditionalNode.ConditionExpression; List<AssociativeNode> ifBody = new List<AssociativeNode>(); List<AssociativeNode> elseBody = new List<AssociativeNode>(); ifBody.Add(inlineConditionalNode.TrueExpression); elseBody.Add(inlineConditionalNode.FalseExpression); ifNode.IfBody = ifBody; ifNode.ElseBody = elseBody; EmitIfStatementNode(ifNode, ref inferedType, graphNode); } else { // CPS inline conditional FunctionCallNode inlineCall = new FunctionCallNode(); IdentifierNode identNode = new IdentifierNode(); identNode.Name = ProtoCore.DSASM.Constants.kInlineConditionalMethodName; inlineCall.Function = identNode; DebugProperties.BreakpointOptions oldOptions = core.DebuggerProperties.breakOptions; DebugProperties.BreakpointOptions newOptions = oldOptions; newOptions |= DebugProperties.BreakpointOptions.EmitInlineConditionalBreakpoint; core.DebuggerProperties.breakOptions = newOptions; core.DebuggerProperties.highlightRange = new ProtoCore.CodeModel.CodeRange { StartInclusive = new ProtoCore.CodeModel.CodePoint { LineNo = parentNode.line, CharNo = parentNode.col }, EndExclusive = new ProtoCore.CodeModel.CodePoint { LineNo = parentNode.endLine, CharNo = parentNode.endCol } }; // As SSA conversion is enabled, we have got the values of // true and false branch, so it isn't necessary to create // language blocks. if (core.Options.GenerateSSA) { inlineCall.FormalArguments.Add(inlineConditionalNode.ConditionExpression); inlineCall.FormalArguments.Add(inlineConditionalNode.TrueExpression); inlineCall.FormalArguments.Add(inlineConditionalNode.FalseExpression); } else { // True condition language block BinaryExpressionNode bExprTrue = AstFactory.BuildReturnStatement(inlineConditionalNode.TrueExpression); LanguageBlockNode langblockT = new LanguageBlockNode(); int trueBlockId = Constants.kInvalidIndex; langblockT.codeblock.Language = ProtoCore.Language.Associative; core.AssocNode = bExprTrue; core.InlineConditionalBodyGraphNodes.Push(new List<GraphNode>()); EmitDynamicLanguageBlockNode(langblockT, bExprTrue, ref inferedType, ref trueBlockId, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone); List<GraphNode> trueBodyNodes = core.InlineConditionalBodyGraphNodes.Pop(); // Append dependent nodes of the inline conditional foreach (GraphNode gnode in trueBodyNodes) foreach (GraphNode dNode in gnode.dependentList) graphNode.PushDependent(dNode); core.AssocNode = null; DynamicBlockNode dynBlockT = new DynamicBlockNode(trueBlockId); // False condition language block BinaryExpressionNode bExprFalse = AstFactory.BuildReturnStatement(inlineConditionalNode.FalseExpression); LanguageBlockNode langblockF = new LanguageBlockNode(); int falseBlockId = Constants.kInvalidIndex; langblockF.codeblock.Language = ProtoCore.Language.Associative; core.AssocNode = bExprFalse; core.InlineConditionalBodyGraphNodes.Push(new List<GraphNode>()); EmitDynamicLanguageBlockNode(langblockF, bExprFalse, ref inferedType, ref falseBlockId, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone); List<GraphNode> falseBodyNodes = core.InlineConditionalBodyGraphNodes.Pop(); // Append dependent nodes of the inline conditional foreach (GraphNode gnode in falseBodyNodes) foreach (GraphNode dNode in gnode.dependentList) graphNode.PushDependent(dNode); core.AssocNode = null; DynamicBlockNode dynBlockF = new DynamicBlockNode(falseBlockId); inlineCall.FormalArguments.Add(inlineConditionalNode.ConditionExpression); inlineCall.FormalArguments.Add(dynBlockT); inlineCall.FormalArguments.Add(dynBlockF); } core.DebuggerProperties.breakOptions = oldOptions; core.DebuggerProperties.highlightRange = new ProtoCore.CodeModel.CodeRange { StartInclusive = new ProtoCore.CodeModel.CodePoint { LineNo = Constants.kInvalidIndex, CharNo = Constants.kInvalidIndex }, EndExclusive = new ProtoCore.CodeModel.CodePoint { LineNo = Constants.kInvalidIndex, CharNo = Constants.kInvalidIndex } }; // Save the pc and store it after the call EmitFunctionCallNode(inlineCall, ref inferedType, false, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier); EmitFunctionCallNode(inlineCall, ref inferedType, false, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, parentNode); // Need to restore those settings. if (graphNode != null) { graphNode.isInlineConditional = isInlineConditionalFlag; graphNode.updateBlock.startpc = startPC; graphNode.isReturn = isReturn; } } }
private AssociativeNode GenerateUnaryOperatorMethodCallNode(UnaryOperator op, ProtoCore.AST.AssociativeAST.AssociativeNode operand) { FunctionCallNode funCallNode = new FunctionCallNode(); IdentifierNode funcName = new IdentifierNode { Value = ProtoCore.DSASM.Op.GetUnaryOpFunction(op), Name = ProtoCore.DSASM.Op.GetUnaryOpFunction(op) }; funCallNode.Function = funcName; funCallNode.Name = ProtoCore.DSASM.Op.GetUnaryOpFunction(op); funCallNode.FormalArguments.Add(operand); NodeUtils.CopyNodeLocation(funCallNode, operand); return funCallNode; }
private void EmitFunctionCall(int depth, int type, List<ProtoCore.Type> arglist, ProcedureNode procNode, FunctionCallNode funcCall, bool isGetter = false, BinaryExpressionNode parentExpression = null) { int blockId = procNode.RuntimeIndex; //push value-not-provided default argument for (int i = arglist.Count; i < procNode.ArgumentInfos.Count; i++) { EmitDefaultArgNode(); } // Push the function declaration block and indexed array // Jun TODO: Implementeation of indexing into a function call: // x = f()[0][1] int dimensions = 0; EmitPushVarData(dimensions); // Emit depth EmitInstrConsole(kw.push, depth + "[depth]"); EmitPush(StackValue.BuildInt(depth)); // The function call EmitInstrConsole(ProtoCore.DSASM.kw.callr, procNode.Name); if (isGetter) { EmitCall(procNode.ID, blockId, type, Constants.kInvalidIndex, Constants.kInvalidIndex, Constants.kInvalidIndex, Constants.kInvalidIndex, procNode.PC); } // Break at function call inside dynamic lang block created for a 'true' or 'false' expression inside an inline conditional else if (core.DebuggerProperties.breakOptions.HasFlag(DebugProperties.BreakpointOptions.EmitInlineConditionalBreakpoint)) { ProtoCore.CodeModel.CodePoint startInclusive = core.DebuggerProperties.highlightRange.StartInclusive; ProtoCore.CodeModel.CodePoint endExclusive = core.DebuggerProperties.highlightRange.EndExclusive; EmitCall(procNode.ID, blockId, type, startInclusive.LineNo, startInclusive.CharNo, endExclusive.LineNo, endExclusive.CharNo, procNode.PC); } else if (parentExpression != null) { EmitCall(procNode.ID, blockId, type, parentExpression.line, parentExpression.col, parentExpression.endLine, parentExpression.endCol, procNode.PC); } else { EmitCall(procNode.ID, blockId, type, funcCall.line, funcCall.col, funcCall.endLine, funcCall.endCol, procNode.PC); } // The function return value EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX); StackValue opReturn = StackValue.BuildRegister(Registers.RX); EmitPush(opReturn); }
public AssociativeNode BuildFunctionCall(string functionName, List<AssociativeNode> arguments) { var func = new FunctionCallNode(); func.Function = BuildIdentfier(functionName); func.FormalArguments = arguments; return func; }
public static ProtoCore.AST.AssociativeAST.FunctionDotCallNode GenerateCallDotNode(ProtoCore.AST.AssociativeAST.AssociativeNode lhs, ProtoCore.AST.AssociativeAST.FunctionCallNode rhsCall, Core core = null) { // The function name to call string rhsName = rhsCall.Function.Name; int argNum = rhsCall.FormalArguments.Count; ProtoCore.AST.AssociativeAST.ExprListNode argList = new ProtoCore.AST.AssociativeAST.ExprListNode(); foreach (ProtoCore.AST.AssociativeAST.AssociativeNode arg in rhsCall.FormalArguments) { // The function arguments argList.list.Add(arg); } FunctionCallNode funCallNode = new FunctionCallNode(); IdentifierNode funcName = new IdentifierNode { Value = Constants.kDotArgMethodName, Name = Constants.kDotArgMethodName }; funCallNode.Function = funcName; funCallNode.Name = Constants.kDotArgMethodName; NodeUtils.CopyNodeLocation(funCallNode, lhs); int rhsIdx = ProtoCore.DSASM.Constants.kInvalidIndex; string lhsName = string.Empty; if (lhs is ProtoCore.AST.AssociativeAST.IdentifierNode) { lhsName = (lhs as ProtoCore.AST.AssociativeAST.IdentifierNode).Name; if (lhsName == ProtoCore.DSDefinitions.Keyword.This) { lhs = new ProtoCore.AST.AssociativeAST.ThisPointerNode(); } } if (core != null) { DynamicFunction func; if (core.DynamicFunctionTable.TryGetFunction(rhsName, 0, Constants.kInvalidIndex, out func)) { rhsIdx = func.Index; } else { func = core.DynamicFunctionTable.AddNewFunction(rhsName, 0, Constants.kInvalidIndex); rhsIdx = func.Index; } } // The first param to the dot arg (the pointer or the class name) funCallNode.FormalArguments.Add(lhs); // The second param which is the dynamic table index of the function to call var rhs = new IntNode(rhsIdx); funCallNode.FormalArguments.Add(rhs); // The array dimensions ProtoCore.AST.AssociativeAST.ExprListNode arrayDimExperList = new ProtoCore.AST.AssociativeAST.ExprListNode(); int dimCount = 0; if (rhsCall.Function is ProtoCore.AST.AssociativeAST.IdentifierNode) { // Number of dimensions ProtoCore.AST.AssociativeAST.IdentifierNode fIdent = rhsCall.Function as ProtoCore.AST.AssociativeAST.IdentifierNode; if (fIdent.ArrayDimensions != null) { arrayDimExperList = ProtoCore.Utils.CoreUtils.BuildArrayExprList(fIdent.ArrayDimensions); dimCount = arrayDimExperList.list.Count; } else if (rhsCall.ArrayDimensions != null) { arrayDimExperList = ProtoCore.Utils.CoreUtils.BuildArrayExprList(rhsCall.ArrayDimensions); dimCount = arrayDimExperList.list.Count; } else { arrayDimExperList = new ProtoCore.AST.AssociativeAST.ExprListNode(); } } funCallNode.FormalArguments.Add(arrayDimExperList); // Number of dimensions var dimNode = new IntNode(dimCount); funCallNode.FormalArguments.Add(dimNode); if (argNum >= 0) { funCallNode.FormalArguments.Add(argList); funCallNode.FormalArguments.Add(new IntNode(argNum)); } var funDotCallNode = new FunctionDotCallNode(rhsCall); funDotCallNode.DotCall = funCallNode; funDotCallNode.FunctionCall.Function = rhsCall.Function; // Consider the case of "myClass.Foo(a, b)", we will have "DotCall" being // equal to "myClass" (in terms of its starting line/column), and "rhsCall" // matching with the location of "Foo(a, b)". For execution cursor to cover // this whole statement, the final "DotCall" function call node should // range from "lhs.col" to "rhs.col". // NodeUtils.SetNodeEndLocation(funDotCallNode.DotCall, rhsCall); NodeUtils.CopyNodeLocation(funDotCallNode, funDotCallNode.DotCall); return funDotCallNode; }
public void DFSTraverse(ref AST.AssociativeAST.AssociativeNode node) { if (node is AST.AssociativeAST.IdentifierNode) { EmitIdentifierNode(ref node); } else if (node is ProtoCore.AST.AssociativeAST.IdentifierListNode) { AST.AssociativeAST.IdentifierListNode identList = node as ProtoCore.AST.AssociativeAST.IdentifierListNode; EmitIdentifierListNode(ref identList); } else if (node is ProtoCore.AST.AssociativeAST.IntNode) { AST.AssociativeAST.IntNode intNode = node as ProtoCore.AST.AssociativeAST.IntNode; EmitIntNode(ref intNode); } else if (node is ProtoCore.AST.AssociativeAST.DoubleNode) { AST.AssociativeAST.DoubleNode doubleNode = node as ProtoCore.AST.AssociativeAST.DoubleNode; EmitDoubleNode(ref doubleNode); } else if (node is ProtoCore.AST.AssociativeAST.FunctionCallNode) { AST.AssociativeAST.FunctionCallNode funcCallNode = node as ProtoCore.AST.AssociativeAST.FunctionCallNode; EmitFunctionCallNode(ref funcCallNode); } else if (node is ProtoCore.AST.AssociativeAST.FunctionDotCallNode) { AST.AssociativeAST.FunctionDotCallNode funcDotCall = node as ProtoCore.AST.AssociativeAST.FunctionDotCallNode; EmitFunctionDotCallNode(ref funcDotCall); } else if (node is ProtoCore.AST.AssociativeAST.BinaryExpressionNode) { ProtoCore.AST.AssociativeAST.BinaryExpressionNode binaryExpr = node as ProtoCore.AST.AssociativeAST.BinaryExpressionNode; if (binaryExpr.Optr != DSASM.Operator.assign) { ; } //EmitCode("("); EmitBinaryNode(ref binaryExpr); if (binaryExpr.Optr == DSASM.Operator.assign) { //EmitCode(ProtoCore.DSASM.Constants.termline); } if (binaryExpr.Optr != DSASM.Operator.assign) { ; } //EmitCode(")"); } else if (node is ProtoCore.AST.AssociativeAST.FunctionDefinitionNode) { AST.AssociativeAST.FunctionDefinitionNode funcDefNode = node as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode; EmitFunctionDefNode(ref funcDefNode); } else if (node is ProtoCore.AST.AssociativeAST.ClassDeclNode) { AST.AssociativeAST.ClassDeclNode classDeclNode = node as ProtoCore.AST.AssociativeAST.ClassDeclNode; EmitClassDeclNode(ref classDeclNode); } else if (node is ProtoCore.AST.AssociativeAST.NullNode) { AST.AssociativeAST.NullNode nullNode = node as ProtoCore.AST.AssociativeAST.NullNode; EmitNullNode(ref nullNode); } else if (node is ProtoCore.AST.AssociativeAST.ArrayIndexerNode) { AST.AssociativeAST.ArrayIndexerNode arrIdxNode = node as ProtoCore.AST.AssociativeAST.ArrayIndexerNode; EmitArrayIndexerNode(ref arrIdxNode); } else if (node is ProtoCore.AST.AssociativeAST.ExprListNode) { AST.AssociativeAST.ExprListNode exprListNode = node as ProtoCore.AST.AssociativeAST.ExprListNode; EmitExprListNode(ref exprListNode); } }