/// <summary> /// API used by external host to build AST for any function call /// </summary> /// <param name="type"></param> /// <param name="hostInstancePtr"></param> /// <param name="functionName"></param> /// <param name="userDefinedArgs"></param> /// <param name="primitiveArgs"></param> /// <param name="formatString"></param> /// <param name="core"></param> /// <param name="symbolName"></param> /// <param name="code"></param> /// <returns></returns> public static AssociativeNode BuildAST(string type, long hostInstancePtr, string functionName, List <IntPtr> userDefinedArgs, List <string> primitiveArgs, string formatString, ProtoCore.Core core, ref string symbolName, ref string code) { symbolName = string.Empty; List <AssociativeNode> astNodes = new List <AssociativeNode>(); FunctionDotCallNode dotCall = null; BinaryExpressionNode bNode = null; ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCallNode = null; List <AssociativeNode> argNodes = new List <AssociativeNode>(); if (userDefinedArgs != null) { foreach (var arg in userDefinedArgs) { dotCallNode = CreateEntityNode((long)arg, core); bNode = CreateAssignmentNode(dotCallNode); argNodes.Add(bNode); } astNodes.AddRange(argNodes); } List <ProtoCore.AST.AssociativeAST.AssociativeNode> args = CreateArgs(formatString, primitiveArgs, argNodes); if (hostInstancePtr != 0) { dotCallNode = CreateEntityNode(hostInstancePtr, core); bNode = CreateAssignmentNode(dotCallNode); astNodes.Add(bNode); dotCall = CreateFunctionCallNode((bNode.LeftNode as IdentifierNode).Value, functionName, args, core); } else { dotCall = CreateFunctionCallNode(type, functionName, args, core); } bNode = CreateAssignmentNode(dotCall); if (bNode.LeftNode is IdentifierNode) { symbolName = (bNode.LeftNode as IdentifierNode).Value; } astNodes.Add(bNode); CodeBlockNode codeBlockNode = new CodeBlockNode(); codeBlockNode.Body = astNodes; ProtoCore.CodeGenDS codeGen = new ProtoCore.CodeGenDS(astNodes); code = codeGen.GenerateCode(); return(codeBlockNode); }
private VariableSlotInfo GetVariableSlotInfo(FunctionDotCallNode functionDotCallNode) { // @TODO(done): No hard-casting. ProtoCore.AST.AssociativeAST.IdentifierNode idenNode = functionDotCallNode.DotCall.FormalArguments[0] as ProtoCore.AST.AssociativeAST.IdentifierNode; if (idenNode == null) { throw new InvalidOperationException("Unsupported AST Node Type"); } string var = idenNode.Value; int line = functionDotCallNode.line; uint slot = uint.MaxValue; return(new VariableSlotInfo(var, line, slot)); }
private void AddReferencesFromAst(AssociativeNode astNode) { if (IsPrimitiveType(astNode)) { return; } ProtoCore.AST.AssociativeAST.IdentifierNode identNode = astNode as ProtoCore.AST.AssociativeAST.IdentifierNode; if (identNode != null) { this.references.Add(GetVariableSlotInfo(identNode)); return; } FunctionDotCallNode funcDotCallNode = astNode as FunctionDotCallNode; if (funcDotCallNode != null) { // @TODO(done): Avoid hard casting. this.references.Add(GetVariableSlotInfo(funcDotCallNode)); return; } FunctionCallNode functionCallNode = (FunctionCallNode)astNode; if (funcDotCallNode != null) { // @TODO(done): Avoid hard casting. foreach (AssociativeNode node in functionCallNode.FormalArguments) { AddReferencesFromAst(node); } return; } // @TODO(Sean): Print out type info to help yourself. throw new ArgumentException("Unsupported node type (79CCBEA9F50E)", "astNode"); }
private void TraverseToSplit(AssociativeNode node, out AssociativeNode outNode, ref List <AssociativeNode> splitList) { if (node is BinaryExpressionNode) { BinaryExpressionNode ben = node as BinaryExpressionNode; BinaryExpressionNode newNode = new BinaryExpressionNode(); AssociativeNode lNode = null; TraverseToSplit(ben.LeftNode, out lNode, ref splitList); newNode.LeftNode = lNode; newNode.Optr = ben.Optr; AssociativeNode rNode = null; TraverseToSplit(ben.RightNode, out rNode, ref splitList); newNode.RightNode = rNode; if (ben.Optr == ProtoCore.DSASM.Operator.assign) { if (NotEnlisted(splitList, newNode)) { splitList.Add(newNode); } outNode = lNode; } else { outNode = newNode; } } else if (node is FunctionCallNode) { FunctionCallNode funcCallNode = node as FunctionCallNode; AssociativeNode statement = null; foreach (AssociativeNode argNode in funcCallNode.FormalArguments) { TraverseToSplit(argNode, out statement, ref splitList); } for (int i = 0; i < funcCallNode.FormalArguments.Count; i++) { AssociativeNode argNode = funcCallNode.FormalArguments[i]; if (argNode is BinaryExpressionNode) { funcCallNode.FormalArguments[i] = (argNode as BinaryExpressionNode).LeftNode; } } //if (statement is BinaryExpressionNode) //{ // splitList.Add(statement); //} outNode = funcCallNode; } else if (node is FunctionDotCallNode) { FunctionDotCallNode funcDotNode = node as FunctionDotCallNode; AssociativeNode statement = null; TraverseToSplit(funcDotNode.FunctionCall, out statement, ref splitList); funcDotNode.FunctionCall = (statement as FunctionCallNode); TraverseToSplit(funcDotNode.DotCall.FormalArguments[0], out statement, ref splitList); if (statement is BinaryExpressionNode) { funcDotNode.DotCall.FormalArguments[0] = (statement as BinaryExpressionNode).LeftNode; } else { funcDotNode.DotCall.FormalArguments[0] = statement; } outNode = funcDotNode; } else if (node is ProtoCore.AST.AssociativeAST.ImportNode) { outNode = node; splitList.Add(outNode); } else if (node is ProtoCore.AST.AssociativeAST.ArrayIndexerNode) { ArrayIndexerNode arrIdxNode = node as ArrayIndexerNode; AssociativeNode statement = null; TraverseToSplit(arrIdxNode.Array, out statement, ref splitList); arrIdxNode.Array = statement; outNode = arrIdxNode; } else if (node is ProtoCore.AST.AssociativeAST.ExprListNode) { ExprListNode exprListNode = node as ExprListNode; AssociativeNode statement = null; //for (int i=0; i<exprListNode.list.Count; i++) foreach (AssociativeNode listNode in exprListNode.list) { TraverseToSplit(listNode, out statement, ref splitList); } for (int i = 0; i < exprListNode.list.Count; i++) { AssociativeNode argNode = exprListNode.list[i]; if (argNode is BinaryExpressionNode) { exprListNode.list[i] = (argNode as BinaryExpressionNode).LeftNode; } } outNode = exprListNode; } //else if (node is ProtoCore.AST.AssociativeAST.ArrayNode) //{ // k //} else if (node is ProtoCore.AST.AssociativeAST.RangeExprNode) { RangeExprNode rangeExprNode = node as RangeExprNode; AssociativeNode statement = null; TraverseToSplit(rangeExprNode.FromNode, out statement, ref splitList); TraverseToSplit(rangeExprNode.StepNode, out statement, ref splitList); TraverseToSplit(rangeExprNode.ToNode, out statement, ref splitList); if (rangeExprNode.FromNode is BinaryExpressionNode) { rangeExprNode.FromNode = (rangeExprNode.FromNode as BinaryExpressionNode).LeftNode; } if (rangeExprNode.StepNode is BinaryExpressionNode) { rangeExprNode.StepNode = (rangeExprNode.StepNode as BinaryExpressionNode).LeftNode; } if (rangeExprNode.ToNode is BinaryExpressionNode) { rangeExprNode.ToNode = (rangeExprNode.ToNode as BinaryExpressionNode).LeftNode; } outNode = rangeExprNode; } else { outNode = node; } }
public virtual void VisitFunctionDotCallNode(FunctionDotCallNode node) { DefaultVisit(node); }
public virtual TAssociative VisitFunctionDotCallNode(FunctionDotCallNode node) { return(VisitAssociativeNode(node)); }
public virtual bool VisitFunctionDotCallNode(FunctionDotCallNode node) { return(DefaultVisit(node)); }
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 static FunctionDotCallNode GenerateCallDotNode(AssociativeNode lhs, FunctionCallNode rhsCall, Core core = null) { // The function name to call string rhsName = rhsCall.Function.Name; int argNum = rhsCall.FormalArguments.Count; ExprListNode argList = new ExprListNode(); foreach (AssociativeNode arg in rhsCall.FormalArguments) { // The function arguments argList.Exprs.Add(arg); } var arguments = new List <AssociativeNode>(); int rhsIdx = DSASM.Constants.kInvalidIndex; string lhsName = string.Empty; if (lhs is IdentifierNode) { lhsName = (lhs as IdentifierNode).Name; if (lhsName == DSDefinitions.Keyword.This) { lhs = new 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) arguments.Add(lhs); // The second param which is the dynamic table index of the function to call arguments.Add(new IntNode(rhsIdx)); // The array dimensions ExprListNode arrayDimExperList = new ExprListNode(); int dimCount = 0; if (rhsCall.Function is IdentifierNode) { // Number of dimensions IdentifierNode fIdent = rhsCall.Function as IdentifierNode; if (fIdent.ArrayDimensions != null) { arrayDimExperList = CoreUtils.BuildArrayExprList(fIdent.ArrayDimensions); dimCount = arrayDimExperList.Exprs.Count; } else if (rhsCall.ArrayDimensions != null) { arrayDimExperList = CoreUtils.BuildArrayExprList(rhsCall.ArrayDimensions); dimCount = arrayDimExperList.Exprs.Count; } else { arrayDimExperList = new ExprListNode(); } } arguments.Add(arrayDimExperList); // Number of dimensions var dimNode = new IntNode(dimCount); arguments.Add(dimNode); if (argNum >= 0) { arguments.Add(argList); arguments.Add(new IntNode(argNum)); } var funDotCallNode = new FunctionDotCallNode(rhsCall, arguments); // funDotCallNode.FunctionCall.Function = rhsCall.Function; NodeUtils.SetNodeEndLocation(funDotCallNode, rhsCall); return(funDotCallNode); }