private bool TryParseInputSymbol(string inputSymbol, out IdentifierNode identifier, out AssociativeNode defaultValue) { identifier = null; defaultValue = null; var parseString = InputSymbol; parseString += ";"; // During loading of symbol node from file, the elementResolver from the workspace is unavailable // in which case, a local copy of the ER obtained from the symbol node is used var resolver = workspaceElementResolver ?? ElementResolver; var parseParam = new ParseParam(this.GUID, parseString, resolver); if (EngineController.CompilationServices.PreCompileCodeBlock(ref parseParam) && parseParam.ParsedNodes != null && parseParam.ParsedNodes.Any()) { var node = parseParam.ParsedNodes.First() as BinaryExpressionNode; Validity.Assert(node != null); if (node != null) { identifier = node.LeftNode as IdentifierNode; if (inputSymbol.Contains('=')) { defaultValue = node.RightNode; } return(identifier != null); } } return(false); }
public void TestAddedFunction02() { List <string> codes = new List <string>() { "def f(){return = 1;}", "def g(){return = 1;}" }; Guid guid = System.Guid.NewGuid(); List <Subtree> added = new List <Subtree>(); added.Add(ProtoTestFx.TD.TestFrameWork.CreateSubTreeFromCode(guid, codes[0])); var syncData = new GraphSyncData(null, added, null); // Get astlist from ChangeSetComputer ChangeSetComputer changeSetState = new ProtoScript.Runners.ChangeSetComputer(core, runtimeCore); List <AssociativeNode> astList = changeSetState.GetDeltaASTList(syncData); // Get expected ASTList // The list must be in the order that it is expected List <string> expectedCode = new List <string>() { "def f(){return = 1;}", "def g(){return = 1;}" }; List <AssociativeNode> expectedAstList = ProtoCore.Utils.CoreUtils.BuildASTList(core, expectedCode); // Compare ASTs to be equal for (int n = 0; n < astList.Count; ++n) { AssociativeNode node1 = astList[n]; AssociativeNode node2 = expectedAstList[n]; bool isEqual = node1.Equals(node2); Assert.IsTrue(isEqual); } }
public override AssociativeNode VisitIdentifierListNode(IdentifierListNode node) { // First pass attempt to resolve the node before traversing it deeper AssociativeNode newIdentifierListNode = null; if (IsMatchingResolvedName(node, out newIdentifierListNode)) { return(newIdentifierListNode); } var rightNode = node.RightNode; var leftNode = node.LeftNode; rightNode = rightNode.Accept(this); leftNode = leftNode.Accept(this); node = new IdentifierListNode { LeftNode = leftNode, RightNode = rightNode, Optr = Operator.dot }; return(RewriteIdentifierListNode(node)); }
public override IEnumerable <AssociativeNode> BuildOutputAst( List <AssociativeNode> inputAstNodes) { if (!InPorts[0].IsConnected || !InPorts[1].IsConnected) { return(new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) }); } double unitsMM = Conversions.ConversionDictionary[SelectedExportedUnit] * 1000.0; var geometryListNode = inputAstNodes[0]; var filePathNode = inputAstNodes[1]; var unitsMMNode = AstFactory.BuildDoubleNode(unitsMM); AssociativeNode node = null; node = AstFactory.BuildFunctionCall( new Func <IEnumerable <Geometry>, string, double, string>(Geometry.ExportToSAT), new List <AssociativeNode> { geometryListNode, filePathNode, unitsMMNode }); return(new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), node) }); }
public override AssociativeNode VisitIdentifierListNode(IdentifierListNode node) { if (node == null) { return(null); } // If node is a reserved method call, skip rewriting it. if (ReservedMethods.Any(reservedMethod => node.ToString().Contains(reservedMethod))) { return(node); } // First pass attempt to resolve the node before traversing it deeper AssociativeNode newIdentifierListNode = null; if (IsMatchingResolvedName(node, out newIdentifierListNode)) { return(newIdentifierListNode); } var rightNode = node.RightNode; var leftNode = node.LeftNode; rightNode = rightNode.Accept(this); leftNode = leftNode.Accept(this); node = new IdentifierListNode { LeftNode = leftNode, RightNode = rightNode, Optr = Operator.dot }; return(RewriteIdentifierListNode(node)); }
public void TestMethodHasNullCheck() { AssociativeNode foo = new IdentifierNode("foo"); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildAssignment(foo, null)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildAssignment(null, foo)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildBinaryExpression(foo, null, ProtoCore.DSASM.Operator.assign)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildBinaryExpression(null, foo, ProtoCore.DSASM.Operator.assign)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildConditionalNode(null, foo, foo)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildConditionalNode(foo, null, foo)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildConditionalNode(foo, foo, null)); List <AssociativeNode> nullList = null; List <AssociativeNode> fooList = new List <AssociativeNode>(); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildExprList(nullList)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildFunctionCall(() => {}, null)); string nullIdent = null; AssociativeNode nullNode = null; Assert.Throws <ArgumentNullException>(() => AstFactory.BuildFunctionObject(nullNode, 0, new List <int> { }, fooList)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildFunctionObject(foo, 0, null, fooList)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildFunctionObject(nullNode, 0, new List <int> { }, null)); Assert.Throws <ArgumentException>(() => AstFactory.BuildFunctionObject(nullIdent, 0, new List <int> { }, fooList)); Assert.Throws <ArgumentException>(() => AstFactory.BuildFunctionObject(string.Empty, 0, new List <int> { }, fooList)); Assert.Throws <ArgumentException>(() => AstFactory.BuildIdentifier(null)); Assert.Throws <ArgumentException>(() => AstFactory.BuildIdentifier(String.Empty)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildStringNode(null)); Assert.Throws <ArgumentException>(() => AstFactory.BuildParamNode(null)); Assert.Throws <ArgumentException>(() => AstFactory.BuildParamNode(string.Empty)); Assert.Throws <ArgumentNullException>(() => AstFactory.BuildReturnStatement(null)); Assert.Throws <ArgumentNullException>(() => AstFactory.AddReplicationGuide(null, null, false)); }
/// <summary> /// This function creates TypedParameter /// </summary> /// <param name="name">parameter name</param> /// <param name="type">parameter type</param> /// <param name="defaultValue">parameter default value</param> /// <param name="shortArgumentName">short name is used as tooltip</param> /// <param name="summary">parameter description</param> /// <param name="nameIsValid">indicates whether the name can be parsed</param> public TypedParameter(string name, ProtoCore.Type type, AssociativeNode defaultValue, string shortArgumentName, string summary, bool nameIsValid = true) { if (name == null) { throw new ArgumentNullException("parameter"); } Name = name; Type = type; DefaultValue = defaultValue; if (defaultValue != null) { defaultValueString = defaultValue.ToString(); } else { defaultValueString = shortArgumentName; } this.summary = summary; this.NameIsValid = nameIsValid; }
/// <summary> /// AST Implementation /// </summary> /// <param name="inputAstNodes"></param> /// <returns></returns> public override IEnumerable <AssociativeNode> BuildOutputAst(List <AssociativeNode> inputAstNodes) { if (IsPartiallyApplied) { return(new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) }); } AssociativeNode listNode = AstFactory.BuildExprList(inputAstNodes); var functionCall = AstFactory.BuildFunctionCall( new Func <List <object>, D3jsLib.Report>(MandrillTypes.Utilities.CreateGridsterReport), new List <AssociativeNode> { listNode }); return(new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), functionCall), }); }
public override IEnumerable <AssociativeNode> BuildOutputAst(List <AssociativeNode> inputAstNodes) { AssociativeNode node = null; if (PickedSunAndShadowSettings == null) { node = AstFactory.BuildNullNode(); } else { _sunVector = GetSunDirection(PickedSunAndShadowSettings).Normalize(); var xNode = AstFactory.BuildDoubleNode(_sunVector.X); var yNode = AstFactory.BuildDoubleNode(_sunVector.Y); var zNode = AstFactory.BuildDoubleNode(_sunVector.Z); node = AstFactory.BuildFunctionCall( new Func <double, double, double, Autodesk.DesignScript.Geometry.Vector>(Autodesk.DesignScript.Geometry.Vector.ByCoordinates), new List <AssociativeNode> { xNode, yNode, zNode }); } return(new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), node) }); }
private string ResolveClassName(AssociativeNode identifierList) { var identListNode = identifierList as IdentifierListNode; string partialName = identListNode != null? CoreUtils.GetIdentifierExceptMethodName(identListNode) : identifierList.Name; if (string.IsNullOrEmpty(partialName)) { return(String.Empty); } var resolvedName = elementResolver.LookupResolvedName(partialName); if (!string.IsNullOrEmpty(resolvedName)) { return(resolvedName); } // If namespace resolution map does not contain entry for partial name, // back up on compiler to resolve the namespace from partial name var matchingClasses = CoreUtils.GetResolvedClassName(classTable, identifierList); if (matchingClasses.Length == 1) { resolvedName = matchingClasses[0]; var assemblyName = CoreUtils.GetAssemblyFromClassName(classTable, resolvedName); elementResolver.AddToResolutionMap(partialName, resolvedName, assemblyName); } else if (matchingClasses.Length > 1) { OnLogSymbolConflictWarning(partialName, matchingClasses); } return(resolvedName); }
public override IEnumerable <AssociativeNode> BuildOutputAst( List <AssociativeNode> inputAstNodes) { if (null == inputAstNodes || inputAstNodes.Count == 0 || inputAstNodes[0] is ProtoCore.AST.AssociativeAST.NullNode || SelectedToConversion is null || SelectedFromConversion is null) { return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) } } ; var conversionToNode = AstFactory.BuildStringNode(SelectedToConversion?.TypeId); var conversionFromNode = AstFactory.BuildStringNode(SelectedFromConversion?.TypeId); AssociativeNode node = null; node = AstFactory.BuildFunctionCall( new Func <double, string, string, double>(DynamoUnits.Utilities.ConvertByUnitIds), new List <AssociativeNode> { inputAstNodes[0], conversionFromNode, conversionToNode }); return(new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), node) }); }
public override IEnumerable <AssociativeNode> BuildOutputAst(List <AssociativeNode> inputAstNodes) { if (IsPartiallyApplied) { return(new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) }); } if (Input == null) { return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) } } ; var nodes = new List <AssociativeNode>(); foreach (var o in Input) { nodes.Add(AstFactory.BuildStringNode(o.ToString())); } AssociativeNode listNode = AstFactory.BuildExprList(nodes); return(new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), listNode) }); } }
/// <summary> /// Create BinaryExpressionNode /// </summary> /// <param name="node"></param> /// <param name="outnode"></param> private void EmitBlockNode(Block node, out AssociativeNode outnode) { Validity.Assert(node != null); // TODO: Confirm that these children are returned in the order that they // appear in the code Dictionary <int, Node> childNodes = node.GetChildrenWithIndices(); // Parse program statement in node.Name string code = node.Name + ";"; ProtoCore.AST.AssociativeAST.CodeBlockNode commentNode = null; ProtoCore.AST.AssociativeAST.CodeBlockNode codeBlockNode = (ProtoCore.AST.AssociativeAST.CodeBlockNode)GraphUtilities.Parse(code, out commentNode); Validity.Assert(codeBlockNode != null); List <ProtoCore.AST.AssociativeAST.AssociativeNode> astList = codeBlockNode.Body; Validity.Assert(astList.Count == 1); if (astList[0] is ProtoCore.AST.AssociativeAST.IdentifierNode) { ProtoCore.AST.AssociativeAST.BinaryExpressionNode ben = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode(); ben.LeftNode = astList[0]; ben.Optr = ProtoCore.DSASM.Operator.assign; ProtoCore.AST.AssociativeAST.AssociativeNode statement = null; foreach (KeyValuePair <int, Node> kvp in childNodes) { DFSTraverse(kvp.Value, out statement); } ben.RightNode = statement; astList[0] = ben; } //I don't know what I am doing if (astList[0] is BinaryExpressionNode) { BinaryExpressionNode tempBen = astList[0] as BinaryExpressionNode; if (tempBen.LeftNode is IdentifierNode) { IdentifierNode identitiferNode = tempBen.LeftNode as IdentifierNode; if (identitiferNode.ArrayDimensions != null) { ArrayIndexerNode arrIndex = new ArrayIndexerNode(); arrIndex.ArrayDimensions = identitiferNode.ArrayDimensions; arrIndex.Array = identitiferNode; tempBen.LeftNode = arrIndex; } } if (tempBen.RightNode is IdentifierNode) { IdentifierNode identitiferNode = tempBen.RightNode as IdentifierNode; if (identitiferNode.ArrayDimensions != null) { ArrayIndexerNode arrIndex = new ArrayIndexerNode(); arrIndex.ArrayDimensions = identitiferNode.ArrayDimensions; arrIndex.Array = identitiferNode; tempBen.RightNode = arrIndex; } } astList[0] = tempBen; } //it should be correct, if not, debug? ProtoCore.AST.AssociativeAST.BinaryExpressionNode bNode = astList[0] as ProtoCore.AST.AssociativeAST.BinaryExpressionNode; Validity.Assert(bNode != null); bNode.Guid = node.Guid; //bNode.SplitFromUID = node.splitFomUint; // Child nodes are arguments to expression in bNode.RightNode. // Match child nodes with IdentifierNode's in bNode.RightNode - pratapa foreach (Node n in childNodes.Values) { AssociativeNode argNode = null; DFSTraverse(n, out argNode); // DFS traverse the bNode.RightNode and check for IdentifierNode's // and if their names match with the names of argNode, then replace // the IdentifierNode in bNode.RightNode with argNode BinaryExpressionNode ben = argNode as BinaryExpressionNode; Validity.Assert(ben != null); //ProtoCore.CodeGenDS codeGen = new ProtoCore.CodeGenDS(ben); AstCodeBlockTraverse sourceGen = new AstCodeBlockTraverse(ben); ProtoCore.AST.AssociativeAST.AssociativeNode right = bNode.RightNode; sourceGen.DFSTraverse(ref right); bNode.RightNode = right; } //(AstRootNode as CodeBlockNode).Body.Add(expressionNode); Validity.Assert(gc != null); gc.HandleNewNode(bNode); outnode = bNode; }
private void EmitBinaryExpNode(Operator node, out AssociativeNode outnode) { Validity.Assert(node != null); Dictionary <int, Node> nodes = node.GetChildrenWithIndices(); Validity.Assert(nodes.Count <= 2); BinaryExpressionNode expressionNode = new BinaryExpressionNode(); // Create operator from input node switch (node.Name) { case "=": expressionNode.Optr = ProtoCore.DSASM.Operator.assign; break; case "+": expressionNode.Optr = ProtoCore.DSASM.Operator.add; break; case "-": expressionNode.Optr = ProtoCore.DSASM.Operator.sub; break; case "*": expressionNode.Optr = ProtoCore.DSASM.Operator.mul; break; case "/": expressionNode.Optr = ProtoCore.DSASM.Operator.div; break; case "%": expressionNode.Optr = ProtoCore.DSASM.Operator.mod; break; case "==": expressionNode.Optr = ProtoCore.DSASM.Operator.eq; break; case "!=": expressionNode.Optr = ProtoCore.DSASM.Operator.nq; break; case ">=": expressionNode.Optr = ProtoCore.DSASM.Operator.ge; break; case ">": expressionNode.Optr = ProtoCore.DSASM.Operator.gt; break; case "<=": expressionNode.Optr = ProtoCore.DSASM.Operator.le; break; case "<": expressionNode.Optr = ProtoCore.DSASM.Operator.lt; break; case "&&": expressionNode.Optr = ProtoCore.DSASM.Operator.and; break; case "||": expressionNode.Optr = ProtoCore.DSASM.Operator.or; break; case "&": expressionNode.Optr = ProtoCore.DSASM.Operator.bitwiseand; break; case "|": expressionNode.Optr = ProtoCore.DSASM.Operator.bitwiseor; break; case "^": expressionNode.Optr = ProtoCore.DSASM.Operator.bitwisexor; break; default: break; } AssociativeNode identNode1 = new NullNode(); AssociativeNode identNode2 = new NullNode(); if (nodes.Count == 2) { // Create BinaryExpressionNode from identNode1, identNode2 and operator DFSTraverse(nodes[0], out identNode1); DFSTraverse(nodes[1], out identNode2); } else if (nodes.Count == 1) { // Create BinaryExpressionNode from identNode1, null DFSTraverse(nodes[0], out identNode1); } expressionNode.LeftNode = identNode1; expressionNode.RightNode = identNode2; //(AstRootNode as CodeBlockNode).Body.Add(expressionNode); BinaryExpressionNode assignmentNode = new BinaryExpressionNode(); assignmentNode.LeftNode = new IdentifierNode(node.tempName); assignmentNode.Optr = ProtoCore.DSASM.Operator.assign; assignmentNode.RightNode = expressionNode; assignmentNode.Guid = node.Guid; Validity.Assert(gc != null); gc.HandleNewNode(assignmentNode); outnode = assignmentNode; }
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 DefaultVisit(AssociativeNode node) { }
private ClassDeclNode ParseSystemType(Type type, string alias) { Validity.Assert(IsBrowsable(type), "Non browsable type is being imported!!"); string classname = alias; if (classname == null | classname == string.Empty) { classname = CLRObjectMarshler.GetTypeName(type); } ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname); classnode.ExternLibName = Module.Name; classnode.className = classname; classnode.Name = type.Name; Type baseType = GetBaseType(type); if (baseType != null && !CLRObjectMarshler.IsMarshaledAsNativeType(baseType)) { string baseTypeName = CLRObjectMarshler.GetTypeName(baseType); classnode.superClass = new List <string>(); classnode.superClass.Add(baseTypeName); //Make sure that base class is imported properly. CLRModuleType.GetInstance(baseType, Module, string.Empty); } ConstructorInfo[] ctors = type.GetConstructors(); foreach (var c in ctors) { if (c.IsPublic && !c.IsGenericMethod && IsBrowsable(c)) { ConstructorDefinitionNode node = ParseConstructor(c, type); classnode.funclist.Add(node); RegisterFunctionPointer(node.Name, c, node.ReturnType); } } BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static; bool isDerivedClass = classnode.superClass != null; if (isDerivedClass) //has base class { flags |= BindingFlags.DeclaredOnly; //for derived class, parse only class declared methods. } bool isDisposable = typeof(IDisposable).IsAssignableFrom(type); MethodInfo[] methods = type.GetMethods(flags); bool hasDisposeMethod = false; foreach (var m in methods) { if (!IsBrowsable(m)) { continue; } //Don't include overriden methods or generic methods if (m.IsPublic && !m.IsGenericMethod && (m == m.GetBaseDefinition() || (m.GetBaseDefinition().DeclaringType == baseType && baseType == typeof(Object)))) { AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m); classnode.funclist.Add(node); } else if (!hasDisposeMethod && isDisposable && baseType == typeof(Object) && isDisposeMethod(m)) { AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m); classnode.funclist.Add(node); } } if (!hasDisposeMethod && !isDisposable) { AssociativeNode node = ParseAndRegisterFunctionPointer(true, ref hasDisposeMethod, mDisposeMethod); classnode.funclist.Add(node); } FieldInfo[] fields = type.GetFields(); foreach (var f in fields) { if (!IsBrowsable(f)) { continue; } VarDeclNode variable = ParseFieldDeclaration(f); if (null == variable) { continue; } classnode.varlist.Add(variable); FunctionDefinitionNode func = ParseFieldAccessor(f); if (null != func) { RegisterFunctionPointer(func.Name, f, func.ReturnType); } } PropertyInfo[] properties = type.GetProperties(flags); foreach (var p in properties) { AssociativeNode node = ParseProperty(p); if (null != node) { classnode.varlist.Add(node); } } return(classnode); }
/// <summary> /// Compiles a collection of Dynamo nodes into a function definition for a custom node. /// </summary> /// <param name="functionId"></param> /// <param name="returnKeys"></param> /// <param name="functionName"></param> /// <param name="funcBody"></param> /// <param name="outputNodes"></param> /// <param name="parameters"></param> /// <param name="verboseLogging"></param> public void CompileCustomNodeDefinition( Guid functionId, IEnumerable <string> returnKeys, string functionName, IEnumerable <NodeModel> funcBody, IEnumerable <AssociativeNode> outputNodes, IEnumerable <TypedParameter> parameters, bool verboseLogging) { OnAstNodeBuilding(functionId); var functionBody = new CodeBlockNode(); var asts = CompileToAstNodes(funcBody, CompilationContext.None, verboseLogging); functionBody.Body.AddRange(asts.SelectMany(t => t.Item2)); var outputs = outputNodes.ToList(); if (outputs.Count > 1) { /* rtn_array = {}; * rtn_array[key0] = out0; * rtn_array[key1] = out1; * ... * return = rtn_array; */ // return array, holds all outputs string rtnName = "__temp_rtn_" + functionId.ToString().Replace("-", String.Empty); functionBody.Body.Add( AstFactory.BuildAssignment( AstFactory.BuildIdentifier(rtnName), AstFactory.BuildExprList(new List <string>()))); // indexers for each output IEnumerable <AssociativeNode> indexers = returnKeys != null ? returnKeys.Select(AstFactory.BuildStringNode) as IEnumerable <AssociativeNode> : Enumerable.Range(0, outputs.Count).Select(AstFactory.BuildIntNode); functionBody.Body.AddRange( outputs.Zip( indexers, (outputId, indexer) => // for each outputId and return key // pack the output into the return array AstFactory.BuildAssignment(AstFactory.BuildIdentifier(rtnName, indexer), outputId))); // finally, return the return array functionBody.Body.Add(AstFactory.BuildReturnStatement(AstFactory.BuildIdentifier(rtnName))); } else { // For single output, directly return that identifier or null. AssociativeNode returnValue = outputs.Count == 1 ? outputs[0] : new NullNode(); functionBody.Body.Add(AstFactory.BuildReturnStatement(returnValue)); } Type allTypes = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar); //Create a new function definition var functionDef = new FunctionDefinitionNode { Name = functionName.Replace("-", string.Empty), Signature = new ArgumentSignatureNode { Arguments = parameters.Select(param => AstFactory.BuildParamNode(param.Name, param.Type)).ToList() }, FunctionBody = functionBody, ReturnType = allTypes }; OnAstNodeBuilt(functionId, new[] { functionDef }); }
public IdentifierReplacer(string variable, AssociativeNode newValue) { variableName = variable; constantValue = newValue; }
public virtual bool DefaultVisit(AssociativeNode node) { return(false); }
public virtual bool Visit(Node node) { AssociativeNode assocNode = node as AssociativeNode; return((assocNode != null) ? assocNode.Accept(this) : false); }
private AssociativeNode RewriteIdentifierListNode(AssociativeNode identifierList) { var identListNode = identifierList as IdentifierListNode; string partialName = identListNode != null? CoreUtils.GetIdentifierExceptMethodName(identListNode) : identifierList.Name; var resolvedName = elementResolver.LookupResolvedName(partialName); if (string.IsNullOrEmpty(resolvedName)) { // If namespace resolution map does not contain entry for partial name, // back up on compiler to resolve the namespace from partial name var matchingClasses = CoreUtils.GetResolvedClassName(classTable, identifierList); if (matchingClasses.Length == 1) { resolvedName = matchingClasses[0]; var assemblyName = CoreUtils.GetAssemblyFromClassName(classTable, resolvedName); elementResolver.AddToResolutionMap(partialName, resolvedName, assemblyName); } } if (string.IsNullOrEmpty(resolvedName)) { return(identifierList); } var newIdentList = CoreUtils.CreateNodeFromString(resolvedName); Validity.Assert(newIdentList is IdentifierListNode); // If the original input node matches with the resolved name, simply return // the identifier list constructed from the resolved name var symbol = new Symbol(resolvedName); if (symbol.Matches(identifierList.ToString())) { return(newIdentList); } // Remove partialName from identListNode and replace with newIdentList AssociativeNode leftNode = identListNode != null ? identListNode.LeftNode : identifierList; AssociativeNode rightNode = identListNode != null ? identListNode.RightNode : identifierList; var intermediateNodes = new List <AssociativeNode>(); while (leftNode is IdentifierListNode && !symbol.Matches(leftNode.ToString())) { intermediateNodes.Insert(0, ((IdentifierListNode)leftNode).RightNode); leftNode = ((IdentifierListNode)leftNode).LeftNode; } intermediateNodes.Insert(0, newIdentList); var lNode = CoreUtils.CreateNodeByCombiningIdentifiers(intermediateNodes); Validity.Assert(lNode is IdentifierListNode); // The last ident list for the functioncall or identifier rhs var lastIdentList = new IdentifierListNode { LeftNode = lNode, RightNode = rightNode, Optr = Operator.dot }; return(lastIdentList); }
/// <summary> /// Compiles a collection of Dynamo nodes into a function definition for a custom node. /// </summary> /// <param name="functionId"></param> /// <param name="returnKeys"></param> /// <param name="functionName"></param> /// <param name="funcBody"></param> /// <param name="outputNodes"></param> /// <param name="parameters"></param> /// <param name="verboseLogging"></param> internal void CompileCustomNodeDefinition( Guid functionId, IEnumerable <string> returnKeys, string functionName, IEnumerable <NodeModel> funcBody, IEnumerable <AssociativeNode> outputNodes, IEnumerable <TypedParameter> parameters, bool verboseLogging) { OnAstNodeBuilding(functionId); var functionBody = new CodeBlockNode(); var asts = CompileToAstNodes(funcBody, CompilationContext.None, verboseLogging); functionBody.Body.AddRange(asts.SelectMany(t => t.Item2)); var outputs = outputNodes.ToList(); if (outputs.Count > 1) { /* rtn_dict = Dictionary.ByKeysValues({key0, ..., keyn}, {out0, ..., outn}); * return = rtn_dict; */ // return dictionary, holds all outputs string rtnName = "__temp_rtn_" + functionId.ToString().Replace("-", String.Empty); //// indexers for each output var indexers = returnKeys != null ? returnKeys.Select(AstFactory.BuildStringNode) as IEnumerable <AssociativeNode> : Enumerable.Range(0, outputs.Count).Select(AstFactory.BuildIntNode); // Create AST for Dictionary initialization var kvps = outputs.Zip(indexers, (outputId, indexer) => new KeyValuePair <AssociativeNode, AssociativeNode>(indexer, outputId)); var dict = new DictionaryExpressionBuilder(); foreach (var kvp in kvps) { dict.AddKey(kvp.Key); dict.AddValue(kvp.Value); } functionBody.Body.Add(AstFactory.BuildAssignment(AstFactory.BuildIdentifier(rtnName), dict.ToFunctionCall())); // finally, return the return array functionBody.Body.Add(AstFactory.BuildReturnStatement(AstFactory.BuildIdentifier(rtnName))); } else { // For single output, directly return that identifier or null. AssociativeNode returnValue = outputs.Count == 1 && outputs[0] != null ? outputs[0] : new NullNode(); functionBody.Body.Add(AstFactory.BuildReturnStatement(returnValue)); } Type allTypes = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var); //Create a new function definition var functionDef = new FunctionDefinitionNode { Name = functionName.Replace("-", string.Empty), Signature = new ArgumentSignatureNode { Arguments = parameters.Select(param => AstFactory.BuildParamNode(param.Name, param.Type)).ToList() }, FunctionBody = functionBody, ReturnType = allTypes }; OnAstNodeBuilt(functionId, new[] { functionDef }); }
private void CompileToAstNodes( NodeModel node, List <AssociativeNode> resultList, CompilationContext context, bool verboseLogging) { var inputAstNodes = new List <AssociativeNode>(); var inPortsCount = node.InPorts.Count; for (int index = 0; index < inPortsCount; index++) { Tuple <int, NodeModel> inputTuple; if (node.TryGetInput(index, out inputTuple)) { int outputIndexOfInput = inputTuple.Item1; NodeModel inputModel = inputTuple.Item2; AssociativeNode inputNode = inputModel.GetAstIdentifierForOutputIndex(outputIndexOfInput); inputAstNodes.Add(inputNode ?? new NullNode()); } else { if (node.InPorts.Count > index) { var port = node.InPorts[index]; if (port.UsingDefaultValue && port.DefaultValue != null) { inputAstNodes.Add(port.DefaultValue); } else { inputAstNodes.Add(new NullNode()); } } else { Log("Node does not have InPortData at the requested index."); } } } //TODO: This should do something more than just log a generic message. --SJE if (node.State == ElementState.Error) { Log("Error in Node. Not sent for building and compiling"); } if (context == CompilationContext.DeltaExecution) { OnAstNodeBuilding(node.GUID); if (ProfilingSession != null) { ProfilingSession.RegisterNode(node); resultList.Add(ProfilingSession.CreatePreCompilationAstNode(node, inputAstNodes)); } } else if (context == CompilationContext.PreviewGraph) { OnAstNodeBuilding(node.GUID); } #if DEBUG Validity.Assert(inputAstNodes.All(n => n != null), "Shouldn't have null nodes in the AST list"); #endif var scopedNode = node as ScopedNodeModel; IEnumerable <AssociativeNode> astNodes = scopedNode != null ? scopedNode.BuildAstInScope(inputAstNodes, verboseLogging, this) : node.BuildAst(inputAstNodes, context); foreach (var astNode in astNodes) { if (astNode.Kind == AstKind.BinaryExpression) { (astNode as BinaryExpressionNode).guid = node.GUID; } } if (context == CompilationContext.DeltaExecution) { resultList.AddRange(astNodes); if (ProfilingSession != null) { resultList.Add(ProfilingSession.CreatePostCompilationAstNode(node, inputAstNodes)); } OnAstNodeBuilt(node.GUID, resultList); } else if (context == CompilationContext.PreviewGraph) { resultList.AddRange(astNodes); OnAstNodeBuilt(node.GUID, resultList); } else if (context == CompilationContext.NodeToCode) { resultList.AddRange(astNodes); } else { // Inside custom node compilation bool notified = false; foreach (var item in astNodes) { if (item is FunctionDefinitionNode) { if (!notified) { OnAstNodeBuilding(node.GUID); } notified = true; // Register the function node in global scope with Graph Sync data, // so that we don't have a function definition inside the function def // of custom node. OnAstNodeBuilt(node.GUID, new[] { item }); } else { resultList.Add(item); } } if (verboseLogging) { foreach (var n in resultList) { Log(n.ToString()); } } } }
private bool TryParseInputExpression(string inputSymbol, out IdentifierNode identifier, out AssociativeNode defaultValue, out string comment) { identifier = null; defaultValue = null; comment = null; var parseString = InputSymbol; parseString += ";"; // During loading of symbol node from file, the elementResolver from the workspace is unavailable // in which case, a local copy of the ER obtained from the symbol node is used var resolver = workspaceElementResolver ?? ElementResolver; var parseParam = new ParseParam(this.GUID, parseString, resolver); if (EngineController.CompilationServices.PreCompileCodeBlock(ref parseParam) && parseParam.ParsedNodes.Any()) { var parsedComments = parseParam.ParsedComments; if (parsedComments.Any()) { comment = String.Join("\n", parsedComments.Select(c => (c as CommentNode).Value)); } var node = parseParam.ParsedNodes.First() as BinaryExpressionNode; if (node != null) { var leftIdent = node.LeftNode as IdentifierNode; var rightIdent = node.RightNode as IdentifierNode; // "x" will be compiled to "temp_guid = x"; if (leftIdent != null && leftIdent.Value.StartsWith(Constants.kTempVarForNonAssignment)) { identifier = rightIdent; } // "x:int" will be compiled to "x:int = tTypedIdent0"; else if (rightIdent != null && rightIdent.Value.StartsWith(Constants.kTempVarForTypedIdentifier)) { identifier = leftIdent; } else { identifier = leftIdent; } if (inputSymbol.Contains('=')) { defaultValue = node.RightNode; } if (parseParam.Errors.Any()) { this.Error(parseParam.Errors.First().Message); } else if (parseParam.Warnings.Any()) { var warnings = parseParam.Warnings.Where(w => w.ID != WarningID.IdUnboundIdentifier); if (warnings.Any()) { this.Warning(parseParam.Warnings.First().Message); } } return(identifier != null); } } return(false); }
private void EmitFunctionNode(Func node, out AssociativeNode outnode) { Validity.Assert(node != null); AssociativeNode fNode = new NullNode(); string funcQualifier = node.Name; if (node.isRange) { EmitRangeExpNode(node, out fNode); } else if (!funcQualifier.Contains(".")) { if (node.isProperty) { Dictionary <int, Node> nodes = node.GetChildrenWithIndices(); Validity.Assert(nodes.Count == 1); for (int i = 0; i < nodes.Count; ++i) { AssociativeNode instanceNode = null; DFSTraverse(nodes[i], out instanceNode); EmitFunctionCallNode(node, out fNode); ((fNode as FunctionCallNode).Function as IdentifierNode).Value = ProtoCore.DSASM.Constants.kGetterPrefix + ((fNode as FunctionCallNode).Function as IdentifierNode).Value; //string className = (node.Name.Split('.'))[0]; //IdentifierNode inode = new IdentifierNode(className); fNode = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(instanceNode, fNode as FunctionCallNode); } } else if (node.isMemberFunction) { Dictionary <int, Node> nodes = node.GetChildrenWithIndices(); AssociativeNode instanceNode = null; DFSTraverse(nodes[0], out instanceNode); EmitFunctionCallNode(node, out fNode); //string className = (node.Name.Split('.'))[0]; //IdentifierNode inode = new IdentifierNode(className); fNode = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(instanceNode, fNode as FunctionCallNode); } else { // Create AssociativeAST.FunctionCallNode for global and built-in functions EmitFunctionCallNode(node, out fNode); } } else { // Create FunctionDotCallNode for ctors, static and instance methods EmitFunctionDotCallNode(node, out fNode); } BinaryExpressionNode assignmentNode = new BinaryExpressionNode(); assignmentNode.LeftNode = new IdentifierNode(node.tempName); assignmentNode.Optr = ProtoCore.DSASM.Operator.assign; assignmentNode.RightNode = fNode; assignmentNode.Guid = node.Guid; Validity.Assert(gc != null); gc.HandleNewNode(assignmentNode); outnode = assignmentNode; }
public abstract TAssociative VisitAssociativeNode(AssociativeNode node);
public override bool VisitAssociativeNode(AssociativeNode node) { return(VisitAllChildren(node)); }
/// <summary> /// Renumber variables used in astNode. /// </summary> /// <param name="astNode"></param> /// <param name="numberingMap"></param> /// <param name="variableMap"></param> private static void VariableNumbering( ProtoCore.Core core, AssociativeNode astNode, NodeModel node, Dictionary <string, NumberingState> numberingMap, Dictionary <string, string> renamingMap, Dictionary <string, string> inputMap, Dictionary <string, string> outputMap, HashSet <string> mappedVariables) { Action <IdentifierNode> func = n => { var ident = n.Value; // This ident is from other node's output port, it is not necessary to // do renumbering. if (inputMap.ContainsKey(ident)) { return; } NumberingState ns; if (numberingMap.TryGetValue(ident, out ns)) { // ident already defined somewhere else. So we continue to // bump its ID until numbered variable won't conflict with // all existing variables. if (ns.IsNewSession) { ns.BumpID(); while (mappedVariables.Contains(ns.NumberedVariable)) { ns.BumpID(); } ns.IsNewSession = false; } // ident already defined somewhere else, but we already // renumber this variable, so continue to use re-numbered // one. } else { // It is a new variable. But we need to check if some other // variables are renamed to this one because of renumbering. // If there is confliction, continue to bump its ID. ns = new NumberingState(ident); numberingMap[ident] = ns; while (mappedVariables.Contains(ns.NumberedVariable)) { ns.BumpID(); } } if (ns.ID != 0) { var numberedVar = ns.NumberedVariable; n.Name = n.Value = numberedVar; // If this variable is numbered, and it is also output to // other node, we should remap the output variable to // this re-numbered variable. string name = string.Format("{0}%{1}", ident, node.GUID); if (renamingMap.ContainsKey(name)) { var mappedName = renamingMap[name]; renamingMap[mappedName] = numberedVar; // Record in output map. if (outputMap.ContainsKey(mappedName)) { outputMap[mappedName] = numberedVar; } } } // If this one is not the variable that going to be renamed, then // add to mapped variable set if (!renamingMap.ContainsKey(ns.NumberedVariable)) { mappedVariables.Add(ns.NumberedVariable); } }; IdentifierVisitor visitor = new IdentifierVisitor(func, core); astNode.Accept(visitor); }
private void CompileToAstNodes(NodeModel node, List <AssociativeNode> resultList, CompilationContext context, bool verboseLogging) { var inputAstNodes = new List <AssociativeNode>(); foreach (int index in Enumerable.Range(0, node.InPortData.Count)) { Tuple <int, NodeModel> inputTuple; if (node.TryGetInput(index, out inputTuple)) { int outputIndexOfInput = inputTuple.Item1; NodeModel inputModel = inputTuple.Item2; AssociativeNode inputNode = inputModel.GetAstIdentifierForOutputIndex(outputIndexOfInput); #if DEBUG Validity.Assert(inputNode != null, "Shouldn't have null nodes in the AST list"); #endif inputAstNodes.Add(inputNode); } else { PortData port = node.InPortData[index]; inputAstNodes.Add(port.DefaultValue ?? new NullNode()); } } //TODO: This should do something more than just log a generic message. --SJE if (node.State == ElementState.Error) { Log("Error in Node. Not sent for building and compiling"); } if (context == CompilationContext.DeltaExecution) { OnAstNodeBuilding(node.GUID); } #if DEBUG Validity.Assert(inputAstNodes.All(n => n != null), "Shouldn't have null nodes in the AST list"); #endif var scopedNode = node as ScopedNodeModel; IEnumerable <AssociativeNode> astNodes = scopedNode != null ? scopedNode.BuildAstInScope(inputAstNodes, verboseLogging, this) : node.BuildAst(inputAstNodes, context); if (verboseLogging) { foreach (var n in astNodes) { Log(n.ToString()); } } if (null == astNodes) { resultList.AddRange(new AssociativeNode[0]); } else if (context == CompilationContext.DeltaExecution) { OnAstNodeBuilt(node.GUID, astNodes); resultList.AddRange(astNodes); } else if (context == CompilationContext.NodeToCode) { resultList.AddRange(astNodes); } else //Inside custom node compilation. { bool notified = false; foreach (var item in astNodes) { if (item is FunctionDefinitionNode) { if (!notified) { OnAstNodeBuilding(node.GUID); } notified = true; //Register the function node in global scope with Graph Sync data, //so that we don't have a function definition inside the function def //of custom node. OnAstNodeBuilt(node.GUID, new[] { item }); } else { resultList.Add(item); } } } }