// return type is a bit special, first of all you cannot return back an array from C++ to C# // this needs a little massaging // private static Type GetMarshalledReturnType(ProtoCore.Type t) { if (t.IsIndexable && t.rank > 1) { throw new ArgumentException("FFI does not support nested arrays"); } if (t.IsIndexable && (t.Name == "int" || t.Name == "double")) { // now that we have ensured that the array is of rank 1 (1d array) // it is safe to marshall it back at _Array // return(typeof(IntPtr)); } if (t.Name == "int") { return(typeof(Int64)); } else if (t.Name == "double") { return(typeof(double)); } else if (t.Name == "bool") { return(typeof(bool)); } else { throw new ArgumentException(string.Format("FFI: unknown type {0} to marshall", t.Name)); } }
private NumberingState GetNumberingStateForType(ProtoCore.Type type) { NumberingState ns; if (prefixNumberingMap.TryGetValue(type, out ns)) { return(ns); } var shortName = string.Empty; if (namingProvider != null) { shortName = namingProvider.GetTypeDependentName(type); } if (!string.IsNullOrEmpty(shortName)) { ns = new NumberingState(shortName); prefixNumberingMap[type] = ns; return(ns); } return(defaultNS); }
public void DescriptionTest() { var assembly = System.Reflection.Assembly.UnsafeLoadFrom("FFITarget.dll"); var testClass = assembly.GetType("FFITarget.DummyZeroTouchClass"); MethodInfo methodWithDesc = testClass.GetMethod("FunctionWithDescription"); MethodInfo methodWithoutDesc = testClass.GetMethod("FunctionWithoutDescription"); NodeDescriptionAttribute atr = new NodeDescriptionAttribute(""); IEnumerable <TypedParameter> arguments; FunctionDescriptor fucDescriptor; // 1 case. Method with description. var attributes = methodWithDesc.GetCustomAttributes(typeof(NodeDescriptionAttribute), false); Assert.IsNotNull(attributes); Assert.Greater(attributes.Length, 0); atr = attributes[0] as NodeDescriptionAttribute; arguments = methodWithDesc.GetParameters().Select( arg => { var type = new ProtoCore.Type(); type.Name = arg.ParameterType.ToString(); return(new TypedParameter(arg.Name, type)); }); fucDescriptor = new FunctionDescriptor(new FunctionDescriptorParams { FunctionName = methodWithDesc.Name, Summary = atr.ElementDescription, Parameters = arguments }); NodeModel node = new DSFunction(fucDescriptor); Assert.AreEqual(atr.ElementDescription + "\n\n" + fucDescriptor.Signature, node.Description); // 2 case. Method without description. atr = new NodeDescriptionAttribute(""); attributes = methodWithoutDesc.GetCustomAttributes(typeof(NodeDescriptionAttribute), false); Assert.IsNotNull(attributes); Assert.AreEqual(attributes.Length, 0); arguments = methodWithoutDesc.GetParameters().Select( arg => { var type = new ProtoCore.Type(); type.Name = arg.ParameterType.ToString(); return(new TypedParameter(arg.Name, type)); }); fucDescriptor = new FunctionDescriptor(new FunctionDescriptorParams { FunctionName = methodWithDesc.Name, Summary = atr.ElementDescription, Parameters = arguments }); node = new DSFunction(fucDescriptor); Assert.AreEqual(fucDescriptor.Signature, node.Description); }
private ProtoCore.AST.AssociativeAST.VarDeclNode ParseArgumentDeclaration(string parameterName, Type parameterType) { ProtoCore.AST.AssociativeAST.VarDeclNode varDeclNode = new ProtoCore.AST.AssociativeAST.VarDeclNode(); varDeclNode.memregion = ProtoCore.DSASM.MemoryRegion.kMemStack; varDeclNode.access = ProtoCore.DSASM.AccessSpecifier.kPublic; ProtoCore.AST.AssociativeAST.IdentifierNode identifierNode = new ProtoCore.AST.AssociativeAST.IdentifierNode { Value = parameterName, Name = parameterName, datatype = new ProtoCore.Type() { Name = "var", IsIndexable = false, rank = 0, UID = (int)ProtoCore.PrimitiveType.kTypeVar } }; //Lets emit native DS type object ProtoCore.Type argtype = CLRModuleType.GetProtoCoreType(parameterType, Module); varDeclNode.NameNode = identifierNode; varDeclNode.ArgumentType = argtype; return(varDeclNode); }
public string GetTypeDependentName(ProtoCore.Type type) { string prefix = String.Empty; int classIndex = core.ClassTable.IndexOf(type.Name); if (classIndex != Constants.kInvalidIndex) { var classNode = core.ClassTable.ClassNodes[classIndex]; prefix = GetShortName(classNode); // Otherwise change class name to its lower case if (String.IsNullOrEmpty(prefix) && (type.UID > (int)ProtoCore.PrimitiveType.MaxPrimitive)) { prefix = type.Name; if (!string.IsNullOrEmpty(prefix)) { if (prefix.Contains(".")) { prefix = prefix.Split('.').Last(); } prefix = prefix.ToLower(); } } } return(prefix); }
/// <summary> /// Report that the method cannot be found. /// </summary> /// <param name="methodName">The method that cannot be found</param> /// <param name="classScope">The class scope of object</param> /// <param name="arguments">Arguments</param> public void LogFunctionGroupNotFoundWarning(string methodName, int classScope, List <StackValue> arguments) { string className = runtimeCore.DSExecutable.classTable.ClassNodes[classScope].Name; List <string> argumentTypes = new List <string>(); if (arguments == null || arguments.Count == 0) { string propertyName; if (CoreUtils.TryGetPropertyName(methodName, out propertyName)) { string message = string.Format(Resources.kPropertyOfClassNotFound, propertyName, className); LogWarning(WarningID.kMethodResolutionFailure, message); } else { string message = string.Format(Resources.FunctionGroupNotFound, methodName, className); LogWarning(WarningID.kMethodResolutionFailure, message); } } else { foreach (var argument in arguments) { ProtoCore.Type type = runtimeCore.DSExecutable.TypeSystem.BuildTypeObject(argument.metaData.type, 0); argumentTypes.Add(type.ToShortString()); } string message = string.Format(Resources.FunctionGroupWithParameterNotFound, methodName, className, string.Join(",", argumentTypes)); LogWarning(WarningID.kMethodResolutionFailure, message); } }
public TypedParameter(string name = "", string TypeName = "", int TypeRank = -1, string defaultValue = "", string summary = null) { Name = name; Type = new ProtoCore.Type(TypeName, TypeRank); defaultValueString = defaultValue; this.summary = summary; }
public SymbolNode( string name, int index, int functionIndex, Type datatype, bool isArgument, int runtimeIndex, MemoryRegion memregion = MemoryRegion.InvalidRegion, int scope = -1, CompilerDefinitions.AccessModifier access = CompilerDefinitions.AccessModifier.Public, bool isStatic = false, int codeBlockId = Constants.kInvalidIndex) { this.name = name; isTemp = name.StartsWith("%"); isSSATemp = name.StartsWith(Constants.kSSATempPrefix); this.index = index; this.functionIndex = functionIndex; this.absoluteFunctionIndex = functionIndex; this.datatype = datatype; this.isArgument = isArgument; this.memregion = memregion; this.classScope = scope; this.absoluteClassScope = scope; runtimeTableIndex = runtimeIndex; this.access = access; this.isStatic = isStatic; this.codeBlockId = codeBlockId; }
public ProcedureNode(ProcedureNode rhs) { name = rhs.name; pc = rhs.pc; localCount = rhs.localCount; returntype = rhs.returntype; runtimeIndex = rhs.runtimeIndex; isExternal = rhs.isExternal; isAssocOperator = rhs.isAssocOperator; isVarArg = rhs.isVarArg; procId = rhs.procId; classScope = rhs.classScope; argTypeList = new List <Type>(rhs.argTypeList); argInfoList = new List <ArgumentInfo>(rhs.argInfoList); isConstructor = rhs.isConstructor; isStatic = rhs.isStatic; access = rhs.access; isAutoGenerated = rhs.isAutoGenerated; isAutoGeneratedThisProc = rhs.isAutoGeneratedThisProc; isActive = rhs.isActive; ChildCodeBlocks = new List <int>(rhs.ChildCodeBlocks); // Runtime properties are initialized updatedGlobals = new Stack <AssociativeGraph.UpdateNodeRef>(); updatedProperties = new Stack <AssociativeGraph.UpdateNodeRef>(); updatedArgumentProperties = new Dictionary <string, List <AssociativeGraph.UpdateNodeRef> >(); updatedArgumentArrays = new Dictionary <string, List <AssociativeGraph.UpdateNode> >(); GraphNodeList = new List <GraphNode>(); }
public SymbolNode( string name, int index, int functionIndex, Type datatype, Type enforcedType, bool isArgument, int runtimeIndex, MemoryRegion memregion = MemoryRegion.InvalidRegion, int scope = -1, CompilerDefinitions.AccessModifier access = CompilerDefinitions.AccessModifier.Public, bool isStatic = false, int codeBlockId = Constants.kInvalidIndex) { this.name = name; isTemp = name.StartsWith("%"); isSSATemp = name.StartsWith(Constants.kSSATempPrefix); this.index = index; this.functionIndex = functionIndex; this.absoluteFunctionIndex = functionIndex; this.datatype = datatype; this.staticType = enforcedType; this.isArgument = isArgument; this.memregion = memregion; this.classScope = scope; this.absoluteClassScope = scope; runtimeTableIndex = runtimeIndex; this.access = access; this.isStatic = isStatic; this.codeBlockId = codeBlockId; }
void ReturnType(out ProtoCore.Type type) { ProtoCore.Type rtype = new ProtoCore.Type(); Expect(1); rtype.Name = t.val; rtype.rank = 0; if (la.kind == 6) { rtype.IsIndexable = true; Get(); Expect(7); rtype.rank = 1; if (la.kind == 6 || la.kind == 17) { if (la.kind == 17) { Get(); Expect(6); Expect(7); rtype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 6) { Get(); Expect(7); rtype.rank++; } } } } type = rtype; }
/// <summary> /// /// </summary> /// <param name="type"></param> /// <param name="protoCoreType"></param> private static void GetProtoCoreType(Type type, ref ProtoCore.Type protoCoreType) { FFIObjectMarshler marshaler; if (type.IsArray) { Type elemType = type.GetElementType(); GetProtoCoreType(elemType, ref protoCoreType); protoCoreType.rank += type.GetArrayRank(); //set the rank. protoCoreType.IsIndexable = true; } else if (type.IsInterface && (typeof(ICollection).IsAssignableFrom(type) || typeof(IEnumerable).IsAssignableFrom(type))) { protoCoreType.rank += 1; protoCoreType.IsIndexable = true; } else if (type.IsGenericType && (typeof(ICollection).IsAssignableFrom(type) || typeof(IEnumerable).IsAssignableFrom(type))) { Type[] args = type.GetGenericArguments(); int nArgs = args.Length; if (nArgs != 1) { protoCoreType.Name = GetTypeName(type); protoCoreType.UID = (int)ProtoCore.PrimitiveType.kTypePointer; return; } Type elemType = args[0]; //TODO: Ideally we shouldn't be calling this method on CLRModuleType, //but we want to import this elemType, hence we do this. protoCoreType = CLRModuleType.GetProtoCoreType(elemType, null); protoCoreType.rank += 1; protoCoreType.IsIndexable = true; } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { protoCoreType = CLRModuleType.GetProtoCoreType(Nullable.GetUnderlyingType(type), null); } else if (type == typeof(object)) { protoCoreType = PrimitiveMarshler.CreateType(ProtoCore.PrimitiveType.kTypeVar); } else if (type == typeof(void)) { protoCoreType = PrimitiveMarshler.CreateType(ProtoCore.PrimitiveType.kTypeVoid); } else if (protoCoreType.UID == (int)ProtoCore.PrimitiveType.kTypePointer) { protoCoreType.Name = GetTypeName(type); } else if (mPrimitiveMarshalers.TryGetValue(type, out marshaler)) { protoCoreType = marshaler.GetMarshaledType(type); } else { protoCoreType.Name = GetTypeName(type); protoCoreType.UID = (int)ProtoCore.PrimitiveType.kTypePointer; } }
public PInvokeFunctionPointer(PInvokeDLLModule module, String name, ProtoCore.Type returnType) { Module = module; Name = name; mReturnType = returnType; //mFunction = new FFICppFunction(module.Name, name); mFunction = new FFICppFunction(module.ModuleBuilder, module.AssemblyName, module.AssemblyBuilder, name); }
private ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode ParseConstructor(ConstructorInfo c, System.Type type) { //Constructors should always return user defined type object, hence it should be pointer type. ProtoCore.Type selfType = ProtoCoreType; ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = ParsedNamedConstructor(c, type.Name, selfType); return(constr); }
public PInvokeFunctionPointer(PInvokeDLLModule module, String name, List <ProtoCore.Type> argTypes, ProtoCore.Type returnType) { Module = module; Name = name; mReturnType = returnType; mArgTypes = argTypes; mFunction = new FFICppFunction(module.ModuleBuilder, module.AssemblyName, module.AssemblyBuilder, name, GetMarshalledReturnType(returnType)); }
public void DescriptionTest() { var assembly = System.Reflection.Assembly.UnsafeLoadFrom("FFITarget.dll"); var testClass = assembly.GetType("FFITarget.DummyZeroTouchClass"); MethodInfo methodWithDesc = testClass.GetMethod("FunctionWithDescription"); MethodInfo methodWithoutDesc = testClass.GetMethod("FunctionWithoutDescription"); NodeDescriptionAttribute atr = new NodeDescriptionAttribute(""); IEnumerable<TypedParameter> arguments; FunctionDescriptor fucDescriptor; // 1 case. Method with description. var attributes = methodWithDesc.GetCustomAttributes(typeof(NodeDescriptionAttribute), false); Assert.IsNotNull(attributes); Assert.Greater(attributes.Length, 0); atr = attributes[0] as NodeDescriptionAttribute; arguments = methodWithDesc.GetParameters().Select( arg => { var type = new ProtoCore.Type(); type.Name = arg.ParameterType.ToString(); return new TypedParameter(arg.Name, type); }); fucDescriptor = new FunctionDescriptor(new FunctionDescriptorParams { FunctionName = methodWithDesc.Name, Summary = atr.ElementDescription, Parameters = arguments }); NodeModel node = new DSFunction(fucDescriptor); Assert.AreEqual(atr.ElementDescription + "\n\n" + fucDescriptor.Signature, node.Description); // 2 case. Method without description. atr = new NodeDescriptionAttribute(""); attributes = methodWithoutDesc.GetCustomAttributes(typeof(NodeDescriptionAttribute), false); Assert.IsNotNull(attributes); Assert.AreEqual(attributes.Length, 0); arguments = methodWithoutDesc.GetParameters().Select( arg => { var type = new ProtoCore.Type(); type.Name = arg.ParameterType.ToString(); return new TypedParameter(arg.Name, type); }); fucDescriptor = new FunctionDescriptor(new FunctionDescriptorParams { FunctionName = methodWithDesc.Name, Summary = atr.ElementDescription, Parameters = arguments }); node = new DSFunction(fucDescriptor); Assert.AreEqual(fucDescriptor.Signature, node.Description); }
private ProtoCore.AST.AssociativeAST.AssociativeNode ParseMethod(MethodInfo method) { ProtoCore.Type retype = CLRModuleType.GetProtoCoreType(method.ReturnType, Module); bool propaccessor = isPropertyAccessor(method); bool isOperator = isOverloadedOperator(method); FFIMethodAttributes mattrs = new FFIMethodAttributes(method); if (method.IsStatic && method.DeclaringType == method.ReturnType && !propaccessor && !isOperator) { //case for named constructor. Must return a pointer type if (!Object.Equals(method.ReturnType, CLRType)) { throw new InvalidOperationException("Unexpected type for constructor {0D28FC00-F8F4-4049-AD1F-BBC34A68073F}"); } retype = ProtoCoreType; ConstructorDefinitionNode node = ParsedNamedConstructor(method, method.Name, retype); node.MethodAttributes = mattrs; return(node); } //Need to hide property accessor from design script users, prefix with % string prefix = (isOperator || propaccessor) ? "%" : ""; var func = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode(); if (isOperator) { func.Name = string.Format("{0}{1}", prefix, GetDSOperatorName(method.Name)); } else { func.Name = string.Format("{0}{1}", prefix, method.Name); } func.Pattern = null; func.Signature = ParseArgumentSignature(method); if ((retype.IsIndexable && mattrs.AllowRankReduction) || (typeof(object).Equals(method.ReturnType))) { retype.rank = Constants.kArbitraryRank; } func.ReturnType = retype; func.FunctionBody = null; func.access = ProtoCore.Compiler.AccessSpecifier.kPublic; func.IsDNI = false; func.IsExternLib = true; func.ExternLibName = Module.Name; func.IsStatic = method.IsStatic; func.MethodAttributes = mattrs; return(func); }
public CLRFFIFunctionPointer(CLRDLLModule module, string name, MemberInfo info, List <ProtoCore.Type> argTypes, ProtoCore.Type returnType) { Module = module; Name = name; ReflectionInfo = FFIMemberInfo.CreateFrom(info); mArgTypes = argTypes == null?GetArgumentTypes() : argTypes.ToArray(); mReturnType = returnType; }
public IdentifierNode() { ArrayDimensions = null; datatype = new ProtoCore.Type { UID = (int)PrimitiveType.kInvalidType, rank = 0, IsIndexable = false, Name = null }; }
public void SetDataType(string ident, int functionIndex, ProtoCore.Type type) { foreach (SymbolNode node in symbolList.Values) { if (node.functionIndex == functionIndex && node.name == ident) { node.datatype = type; return; } } }
public IdentifierNode(IdentifierNode rhs) : base(rhs) { datatype = new ProtoCore.Type { UID = rhs.datatype.UID, rank = rhs.datatype.rank, Name = rhs.datatype.Name }; Value = rhs.Value; }
public ClassMirror(ProtoCore.Type type, ProtoCore.Core core) : base(core, type.Name) { ClassName = type.Name; if (classNode == null) { ProtoCore.DSASM.ClassTable classTable = core.ClassTable; classNode = classTable.ClassNodes[type.UID]; } libraryMirror = new LibraryMirror(classNode.ExternLib, core); }
private string summary = null; // Indicating that it is not initialized. public TypedParameter(string parameter, ProtoCore.Type type, AssociativeNode defaultValue = null) { if (parameter == null) { throw new ArgumentNullException("parameter"); } Name = parameter; Type = type; DefaultValue = defaultValue; }
private static int GetSymbolType(ProtoCore.DSASM.SymbolNode symbolnode) { ProtoCore.Type staticType = symbolnode.staticType; if (staticType.UID == (int)ProtoCore.PrimitiveType.kTypeVar) { return(symbolnode.datatype.UID); } else { return(staticType.UID); } }
public IdentifierNode(IdentifierNode rhs) : base(rhs) { DataType = new ProtoCore.Type { UID = rhs.DataType.UID, rank = rhs.DataType.rank, Name = rhs.DataType.Name }; Value = rhs.Value; IsLocal = false; }
//public ClassMirror() //{ //} public ClassMirror(ProtoCore.Type type, ProtoLanguage.CompileStateTracker compileState) { if (core != null) { ClassName = type.Name; if (classNode == null) { ProtoCore.DSASM.ClassTable classTable = core.DSExecutable.classTable; classNode = classTable.ClassNodes[type.UID]; } libraryMirror = new LibraryMirror(classNode.ExternLib, compileState); } }
public CLRFFIFunctionPointer(CLRDLLModule module, string name, MemberInfo info, List<ProtoCore.Type> argTypes, ProtoCore.Type returnType) { Module = module; Name = name; ReflectionInfo = FFIMemberInfo.CreateFrom(info); if (argTypes == null) mArgTypes = GetArgumentTypes(ReflectionInfo); else mArgTypes = argTypes.ToArray(); mReturnType = returnType; }
public static bool IsPrimitiveDSType(ProtoCore.Type type) { if (IsPrimitiveRange((ProtoCore.PrimitiveType)type.UID) && type.IsIndexable == false) { return(true); } else if (type.UID == (int)ProtoCore.PrimitiveType.kTypeChar && type.rank == 1) { return(true); } return(false); }
public void SetStaticType(ProtoCore.Type newtype) { if (staticType.Equals(newtype)) { return; } staticType = newtype; if (staticType.UID != (int)PrimitiveType.kTypeVar || staticType.rank != 0) { datatype = staticType; } }
public TypedParameter( FunctionDescriptor function, string name, ProtoCore.Type type, object defaultValue = null) { if (name == null) { throw new ArgumentNullException("name"); } Name = name; Type = type; DefaultValue = defaultValue; Function = function; }
private static bool SameTypes(ProtoCore.Type type1, ProtoCore.Type type2) { if (type1.Name != type2.Name) { return(false); } if (type1.IsIndexable != type2.IsIndexable) { return(false); } if (type1.rank != type2.rank) { return(false); } return(true); }
private static string GetDSTypeName(ProtoCore.Type t) { StringBuilder sb = new StringBuilder(); sb.Append(t.Name); for (int ix = 0; ix < t.rank; ++ix) { sb.Append("[]"); } if (t.rank == ProtoCore.DSASM.Constants.kInvalidIndex) { sb.Append("[]..[]"); } return(sb.ToString()); }
void functiondecl(out Node node) { FunctionDefinitionNode funcDecl = new FunctionDefinitionNode(); ProtoCore.Type rtype = new ProtoCore.Type(); rtype.Name = "var"; rtype.UID = 0; Expect(18); Expect(1); funcDecl.Name = t.val; if (la.kind == 36) { Get(); ReturnType(out rtype); } funcDecl.ReturnType = rtype; Expect(8); if (la.kind == 1 || la.kind == 25) { ArgumentSignatureNode args = new ArgumentSignatureNode(); Node argdecl; ArgDecl(out argdecl); args.AddArgument(argdecl as VarDeclNode); while (la.kind == 30) { Get(); ArgDecl(out argdecl); args.AddArgument(argdecl as VarDeclNode); } funcDecl.Signature = args; } Expect(9); isGlobalScope = false; Expect(32); funcDecl.FunctionBody = new CodeBlockNode(); NodeList body = new NodeList(); stmtlist(out body); Expect(33); funcDecl.localVars = localVarCount; funcDecl.FunctionBody.Body = body; node = funcDecl; isGlobalScope = true; localVarCount = 0; }
public SymbolNode( string name, int index, int heapIndex, int functionIndex, ProtoCore.Type datatype, ProtoCore.Type enforcedType, int size, int datasize, bool isArgument, int runtimeIndex, MemoryRegion memregion = MemoryRegion.kInvalidRegion, bool isArray = false, List<int> arraySizeList = null, int scope = -1, ProtoCore.CompilerDefinitions.AccessModifier access = ProtoCore.CompilerDefinitions.AccessModifier.kPublic, bool isStatic = false, int codeBlockId = ProtoCore.DSASM.Constants.kInvalidIndex) { this.name = name; isTemp = name.StartsWith("%"); this.index = index; this.functionIndex = functionIndex; this.absoluteFunctionIndex = functionIndex; this.datatype = datatype; this.staticType = enforcedType; this.size = size; this.datasize = datasize; this.isArgument = isArgument; this.arraySizeList = arraySizeList; this.memregion = memregion; this.classScope = scope; this.absoluteClassScope = scope; runtimeTableIndex = runtimeIndex; this.access = access; this.isStatic = isStatic; this.codeBlockId = codeBlockId; }
public PInvokeFunctionPointer(PInvokeDLLModule module, String name, List<ProtoCore.Type> argTypes, ProtoCore.Type returnType) { Module = module; Name = name; mReturnType = returnType; mArgTypes = argTypes; mFunction = new FFICppFunction(module.ModuleBuilder, module.AssemblyName, module.AssemblyBuilder, name, GetMarshalledReturnType(returnType)); }
void Associative_DecoratedIdentifier(out ProtoCore.AST.AssociativeAST.AssociativeNode node) { node = null; if (IsTypedVariable()) { Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format("\"{0}\" is a keyword, identifier expected", t.val)); } var typedVar = new ProtoCore.AST.AssociativeAST.TypedIdentifierNode(); typedVar.Name = typedVar.Value = t.val; NodeUtils.SetNodeLocation(typedVar, t); Expect(48); Expect(1); int type = core.TypeSystem.GetType(t.val); if (type == ProtoCore.DSASM.Constants.kInvalidIndex) { var unknownType = new ProtoCore.Type(); unknownType.UID = ProtoCore.DSASM.Constants.kInvalidIndex; unknownType.Name = t.val; typedVar.datatype = unknownType; } else { typedVar.datatype = core.TypeSystem.BuildTypeObject(type, false, 0); } if (la.kind == 7) { var datatype = typedVar.datatype; Get(); Expect(8); datatype.rank = 1; if (la.kind == 7 || la.kind == 21) { if (la.kind == 21) { Get(); Expect(7); Expect(8); datatype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 7) { Get(); Expect(8); datatype.rank++; } } } typedVar.datatype = datatype; } node = typedVar; } else if (la.kind == 1 || la.kind == 9 || la.kind == 44) { Associative_IdentifierList(out node); } else SynErr(94); }
void Associative_DecoratedIdentifier(out ProtoCore.AST.AssociativeAST.AssociativeNode node) { node = null; if (IsLocallyTypedVariable()) { Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } var typedVar = new ProtoCore.AST.AssociativeAST.TypedIdentifierNode(); typedVar.Name = typedVar.Value = t.val; NodeUtils.SetNodeLocation(typedVar, t); Expect(48); Expect(41); typedVar.IsLocal = true; Expect(1); int type = core.TypeSystem.GetType(t.val); if (type == ProtoCore.DSASM.Constants.kInvalidIndex) { var unknownType = new ProtoCore.Type(); unknownType.UID = ProtoCore.DSASM.Constants.kInvalidIndex; unknownType.Name = t.val; typedVar.datatype = unknownType; } else { typedVar.datatype = core.TypeSystem.BuildTypeObject(type, 0); } if (la.kind == 8) { var datatype = typedVar.datatype; Get(); Expect(9); datatype.rank = 1; if (la.kind == 8 || la.kind == 22) { if (la.kind == 22) { Get(); Expect(8); Expect(9); datatype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 8) { Get(); Expect(9); datatype.rank++; } } } typedVar.datatype = datatype; } node = typedVar; } else if (IsLocalVariable()) { Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } var identNode = new ProtoCore.AST.AssociativeAST.IdentifierNode(); identNode.Name = identNode.Value = t.val; NodeUtils.SetNodeLocation(identNode, t); Expect(48); Expect(41); identNode.IsLocal = true; node = identNode; } else if (IsTypedVariable()) { Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } var typedVar = new ProtoCore.AST.AssociativeAST.TypedIdentifierNode(); typedVar.Name = typedVar.Value = t.val; NodeUtils.SetNodeLocation(typedVar, t); Expect(48); string strIdent = string.Empty; int type = ProtoCore.DSASM.Constants.kInvalidIndex; if (IsIdentList()) { TypedIdentifierList(out node); strIdent = node.ToString(); } else if (la.kind == 1) { Get(); strIdent = t.val; } else SynErr(92); type = core.TypeSystem.GetType(strIdent); typedVar.TypeAlias = strIdent; if (type == ProtoCore.DSASM.Constants.kInvalidIndex) { var unknownType = new ProtoCore.Type(); unknownType.UID = ProtoCore.DSASM.Constants.kInvalidIndex; unknownType.Name = strIdent; typedVar.datatype = unknownType; } else { typedVar.datatype = core.TypeSystem.BuildTypeObject(type, 0); } if (la.kind == 8) { var datatype = typedVar.datatype; Get(); Expect(9); datatype.rank = 1; if (la.kind == 8 || la.kind == 22) { if (la.kind == 22) { Get(); Expect(8); Expect(9); datatype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 8) { Get(); Expect(9); datatype.rank++; } } } typedVar.datatype = datatype; } node = typedVar; } else if (la.kind == 1 || la.kind == 10 || la.kind == 46) { Associative_IdentifierList(out node); } else SynErr(93); }
private bool ProcessDynamicFunction(Instruction instr) { int fptr = ProtoCore.DSASM.Constants.kInvalidIndex; int functionDynamicIndex = (int)instr.op1.opdata; int classIndex = (int)instr.op2.opdata; int depth = (int)instr.op3.opdata; bool isDotMemFuncBody = functionDynamicIndex == ProtoCore.DSASM.Constants.kInvalidIndex; bool isFunctionPointerCall = false; if (isDotMemFuncBody) { functionDynamicIndex = (int)rmem.Pop().opdata; } DSASM.DynamicFunctionNode dynamicFunctionNode = core.DynamicFunctionTable.functionTable[functionDynamicIndex]; if (isDotMemFuncBody) { classIndex = dynamicFunctionNode.classIndex; } string procName = dynamicFunctionNode.functionName; List<ProtoCore.Type> arglist = dynamicFunctionNode.argList; if (procName == ProtoCore.DSASM.Constants.kFunctionPointerCall && depth == 0) { isFunctionPointerCall = true; classIndex = ProtoCore.DSASM.Constants.kGlobalScope; StackValue fpSv = rmem.Pop(); if (fpSv.optype != AddressType.FunctionPointer) { rmem.Pop(arglist.Count); //remove the arguments return false; } fptr = (int)fpSv.opdata; } //retrieve the function arguments List<StackValue> argSvList = new List<StackValue>(); if (isDotMemFuncBody) { arglist = new List<Type>(); StackValue argArraySv = rmem.Pop(); for (int i = 0; i < ArrayUtils.GetElementSize(argArraySv, core); ++i) { StackValue sv = core.Heap.Heaplist[(int)argArraySv.opdata].Stack[i]; argSvList.Add(sv); //actual arguments ProtoCore.Type paramType = new ProtoCore.Type(); paramType.UID = (int)sv.metaData.type; paramType.rank = 0; if (sv.optype == AddressType.ArrayPointer) { StackValue paramSv = sv; while (paramSv.optype == AddressType.ArrayPointer) { paramType.rank++; int arrayHeapPtr = (int)paramSv.opdata; if (core.Heap.Heaplist[arrayHeapPtr].VisibleSize > 0) { paramSv = core.Heap.Heaplist[arrayHeapPtr].Stack[0]; paramType.UID = (int)paramSv.metaData.type; } else { paramType.UID = (int)ProtoCore.PrimitiveType.kTypeArray; break; } } } arglist.Add(paramType); //build arglist } argSvList.Reverse(); } else { for (int i = 0; i < arglist.Count; i++) { StackValue argSv = rmem.Pop(); argSvList.Add(argSv); } } int lefttype = DSASM.Constants.kGlobalScope; bool isLeftClass = false; if (isDotMemFuncBody && rmem.Stack.Last().optype == AddressType.Int) //constructor or static function { //in this case, ptr won't be used lefttype = (int)rmem.Pop().opdata; isLeftClass = true; } else if (depth > 0) { //resolve the identifier list StackValue pSv = GetFinalPointer(depth); //push the resolved stack value to stack rmem.Push(pSv); lefttype = (int)pSv.metaData.type; } int type = lefttype; if (depth > 0) { // check whether it is function pointer, this checking is done at runtime to handle the case // when turning on converting dot operator to function call if (!((int)ProtoCore.PrimitiveType.kTypeVoid == type || ProtoCore.DSASM.Constants.kInvalidIndex == type || core.ClassTable.ClassNodes[type].symbols == null)) { bool hasThisSymbol; ProtoCore.DSASM.AddressType addressType; SymbolNode node = null; bool isStatic = false; int symbolIndex = core.ClassTable.ClassNodes[type].GetSymbolIndex(procName, type, DSASM.Constants.kGlobalScope, core.RunningBlock, core, out hasThisSymbol, out addressType); if (ProtoCore.DSASM.Constants.kInvalidIndex != symbolIndex) { if (addressType == AddressType.StaticMemVarIndex) { node = core.CodeBlockList[0].symbolTable.symbolList[symbolIndex]; isStatic = true; } else { node = core.ClassTable.ClassNodes[type].symbols.symbolList[symbolIndex]; } } if (node != null) { isFunctionPointerCall = true; StackValue fpSv = new StackValue(); fpSv.opdata = node.symbolTableIndex; fpSv.optype = isStatic ? AddressType.StaticMemVarIndex : AddressType.Pointer; if (fpSv.optype == AddressType.StaticMemVarIndex) { StackValue op2 = new StackValue(); op2.optype = AddressType.ClassIndex; op2.opdata = Constants.kInvalidIndex; fpSv = GetOperandData(0, fpSv, op2); } else { int ptr = (int)rmem.Stack.Last().opdata; fpSv = core.Heap.Heaplist[ptr].Stack[(int)fpSv.opdata]; } //assuming the dimension is zero, as funtion call with nonzero dimension is not supported yet // Check the last pointer AddressType addrtype = fpSv.optype; if (AddressType.Pointer == addrtype || AddressType.Invalid == addrtype) { /* if lookahead is Not a pointer then move to that pointer and get its value at stack index 0 (or further if array) push that else push the current ptr end */ // Determine if we still need to move one more time on the heap // Peek into the pointed data using nextPtr. // If nextPtr is not a pointer (a primitive) then return the data at nextPtr int nextPtr = (int)fpSv.opdata; bool isActualData = AddressType.Pointer != core.Heap.Heaplist[nextPtr].Stack[0].optype && AddressType.ArrayPointer != core.Heap.Heaplist[nextPtr].Stack[0].optype && AddressType.Invalid != core.Heap.Heaplist[nextPtr].Stack[0].optype; // Invalid is an uninitialized member if (isActualData) { // Move one more and get the value at the first heapstack fpSv = core.Heap.Heaplist[nextPtr].Stack[0]; } } if (fpSv.optype != AddressType.FunctionPointer) { rmem.Pop(); //remove final pointer return false; } fptr = (int)fpSv.opdata; } } } ProtoCore.DSASM.ProcedureNode procNode = null; if (isFunctionPointerCall) { ProtoCore.DSASM.FunctionPointerNode fptrNode; if (core.FunctionPointerTable.functionPointerDictionary.TryGetByFirst(fptr, out fptrNode)) { int blockId = fptrNode.blockId; int procId = fptrNode.procId; int classId = fptrNode.classScope; if (Constants.kGlobalScope == classId) { procName = exe.procedureTable[blockId].procList[procId].name; CodeBlock codeblock = core.GetCodeBlock(core.CodeBlockList, blockId); procNode = core.GetFirstVisibleProcedure(procName, arglist, codeblock); } else { procNode = exe.classTable.ClassNodes[classId].vtable.procList[procId]; } type = classId; } else { procNode = null; } } else { // This is a member function of the previous type if (ProtoCore.DSASM.Constants.kInvalidIndex != type) { int realType; bool isAccessible; ProtoCore.DSASM.ProcedureNode memProcNode = core.ClassTable.ClassNodes[type].GetMemberFunction(procName, arglist, classIndex, out isAccessible, out realType); if (memProcNode == null) { string property; if (CoreUtils.TryGetPropertyName(procName, out property)) { string classname = core.ClassTable.ClassNodes[type].name; string message = String.Format(ProtoCore.RuntimeData.WarningMessage.kPropertyOfClassNotFound, classname, property); core.RuntimeStatus.LogWarning(ProtoCore.RuntimeData.WarningID.kMethodResolutionFailure, message); } else { string message = String.Format(ProtoCore.RuntimeData.WarningMessage.kMethodResolutionFailure, procName); core.RuntimeStatus.LogWarning(ProtoCore.RuntimeData.WarningID.kMethodResolutionFailure, message); } } else { procNode = memProcNode; type = realType; // if the proc node is not accessible, that error will be handled by // callr() later on. } } } if (null != procNode) { if (ProtoCore.DSASM.Constants.kInvalidIndex != procNode.procId) { if (isLeftClass || (isFunctionPointerCall && depth > 0)) //constructor or static function or function pointer call { rmem.Pop(); //remove the array dimension for "isLeftClass" or final pointer for "isFunctionPointerCall" instr.op3.opdata = 0; //depth = 0 } //push back the function arguments for (int i = argSvList.Count - 1; i >= 0; i--) { rmem.Push(argSvList[i]); } //push value-not-provided default argument for (int i = arglist.Count; i < procNode.argInfoList.Count; i++) { rmem.Push(StackValue.BuildDefaultArgument()); } // Push the function declaration block StackValue opblock = StackValue.BuildBlockIndex(procNode.runtimeIndex); rmem.Push(opblock); int dimensions = 0; StackValue opdim = StackValue.BuildArrayDimension(dimensions); rmem.Push(opdim); //Modify the operand data instr.op1.opdata = procNode.procId; instr.op1.optype = AddressType.FunctionIndex; instr.op2.opdata = type; return true; } } if (!(isFunctionPointerCall && depth == 0)) { rmem.Pop(); //remove the array dimension for "isLeftClass" or final pointer } return false; }
protected void BuildRealDependencyForIdentList(AssociativeGraph.GraphNode graphNode) { // Push all dependent pointers ProtoCore.AST.AssociativeAST.IdentifierListNode identList = BuildIdentifierList(ssaPointerList); // Comment Jun: perhaps this can be an assert? if (null != identList) { ProtoCore.Type type = new ProtoCore.Type(); type.UID = globalClassIndex; ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new AssociativeGraph.UpdateNodeRef(); int functionIndex = globalProcIndex; DFSGetSymbolList_Simple(identList, ref type, ref functionIndex, nodeRef); if (null != graphNode && nodeRef.nodeList.Count > 0) { ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode(); dependentNode.updateNodeRefList.Add(nodeRef); graphNode.PushDependent(dependentNode); } } }
protected void BuildRealDependencyForIdentList(AssociativeGraph.GraphNode graphNode) { if (ssaPointerStack.Count == 0) { return; } // Push all dependent pointers ProtoCore.AST.AssociativeAST.IdentifierListNode identList = BuildIdentifierList(ssaPointerStack.Peek()); // Comment Jun: perhaps this can be an assert? if (null != identList) { ProtoCore.Type type = new ProtoCore.Type(); type.UID = globalClassIndex; ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new AssociativeGraph.UpdateNodeRef(); int functionIndex = globalProcIndex; DFSGetSymbolList_Simple(identList, ref type, ref functionIndex, nodeRef); if (null != graphNode && nodeRef.nodeList.Count > 0) { ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode(); dependentNode.updateNodeRefList.Add(nodeRef); graphNode.PushDependent(dependentNode); // If the pointerList is a setter, then it should also be in the lhs of a graphNode // Given: // a.x = 1 // Which was converted to: // tvar = a.set_x(1) // Set a.x as lhs of the graphnode. // This means that statement that depends on a.x can re-execute, such as: // p = a.x; // List<ProtoCore.AST.AssociativeAST.AssociativeNode> topList = ssaPointerStack.Peek(); string propertyName = topList[topList.Count - 1].Name; bool isSetter = propertyName.StartsWith(Constants.kSetterPrefix); if (isSetter) { graphNode.updateNodeRefList.Add(nodeRef); graphNode.IsLHSIdentList = true; AutoGenerateUpdateArgumentReference(nodeRef, graphNode); } } } }
private void BuildSSADependency(Node node, AssociativeGraph.GraphNode graphNode) { // Jun Comment: set the graphNode dependent as this identifier list ProtoCore.Type type = new ProtoCore.Type(); type.UID = globalClassIndex; ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new AssociativeGraph.UpdateNodeRef(); DFSGetSymbolList(node, ref type, nodeRef); if (null != graphNode && nodeRef.nodeList.Count > 0) { ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode(); dependentNode.updateNodeRefList.Add(nodeRef); graphNode.PushDependent(dependentNode); } }
void ArgDecl(out Node node) { IdentifierNode tNode = null; VarDeclNode varDeclNode = new ProtoImperative.AST.VarDeclNode(); varDeclNode.memregion = ProtoCore.DSASM.MemoryRegion.kMemStack; if (la.kind == 25) { Get(); varDeclNode.memregion = ProtoCore.DSASM.MemoryRegion.kMemHeap; } if (isArrayAccess()) { arrayident(out node); tNode = node as IdentifierNode; varDeclNode.NameNode = tNode; } else if (la.kind == 1) { Get(); tNode = new IdentifierNode() { Value = t.val, Name = t.val, type = (int)ProtoCore.PrimitiveType.kTypeVar, datatype = ProtoCore.PrimitiveType.kTypeVar }; varDeclNode.NameNode = tNode; } else SynErr(68); ProtoCore.Type argtype = new ProtoCore.Type(); argtype.Name = "var"; argtype.rank = 0; argtype.UID = 0; if (la.kind == 36) { Get(); Expect(1); argtype.Name = t.val; if (la.kind == 6) { argtype.IsIndexable = true; Get(); Expect(7); argtype.rank = 1; if (la.kind == 6 || la.kind == 17 || la.kind == 31) { if (la.kind == 17) { Get(); Expect(6); Expect(7); argtype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 6) { Get(); Expect(7); argtype.rank++; } } } } } varDeclNode.ArgumentType = argtype; if (la.kind == 31) { Get(); Node rhsNode; expr(out rhsNode); BinaryExpressionNode bNode = new BinaryExpressionNode(); bNode.LeftNode = tNode; bNode.RightNode = rhsNode; bNode.Optr = Operator.assign; varDeclNode.NameNode = bNode; } node = varDeclNode; if(!isGlobalScope) { localVarCount++; } }
public void TestRoundTrip_FunctionDefAndCall_01() { //================================= // 1. Build AST // 2. Execute AST and verify // 3. Convert AST to source // 4. Execute source and verify //================================= int result1 = 20; ExecutionMirror mirror = null; // 1. Build the AST tree // def foo() // { // b = 10; // return = b + 10; // } // // x = foo(); ProtoCore.AST.AssociativeAST.CodeBlockNode cbn = new ProtoCore.AST.AssociativeAST.CodeBlockNode(); // Build the function body ProtoCore.AST.AssociativeAST.BinaryExpressionNode assignment1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), new ProtoCore.AST.AssociativeAST.IntNode(10), ProtoCore.DSASM.Operator.assign); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnExpr = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), new ProtoCore.AST.AssociativeAST.IntNode(10), ProtoCore.DSASM.Operator.add); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnNode = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode(ProtoCore.DSDefinitions.Keyword.Return), returnExpr, ProtoCore.DSASM.Operator.assign); cbn.Body.Add(assignment1); cbn.Body.Add(returnNode); // Build the function definition foo const string functionName = "foo"; ProtoCore.AST.AssociativeAST.FunctionDefinitionNode funcDefNode = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode(); funcDefNode.Name = functionName; funcDefNode.FunctionBody = cbn; // Function Return type ProtoCore.Type returnType = new ProtoCore.Type(); returnType.Initialize(); returnType.UID = (int)ProtoCore.PrimitiveType.Var; returnType.Name = ProtoCore.DSDefinitions.Keyword.Var; funcDefNode.ReturnType = returnType; List<ProtoCore.AST.AssociativeAST.AssociativeNode> astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); astList.Add(funcDefNode); // Build the statement that calls the function foo ProtoCore.AST.AssociativeAST.FunctionCallNode functionCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); functionCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode(functionName); ProtoCore.AST.AssociativeAST.BinaryExpressionNode callstmt = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("x"), functionCall, ProtoCore.DSASM.Operator.assign); astList.Add(callstmt); // 2. Execute AST and verify mirror = thisTest.RunASTSource(astList); Assert.IsTrue((Int64)mirror.GetValue("x").Payload == result1); // 3. Convert AST to source ProtoCore.CodeGenDS codegenDS = new ProtoCore.CodeGenDS(astList); string code = codegenDS.GenerateCode(); Console.WriteLine(code); // 4. Execute source and verify mirror = thisTest.RunScriptSource(code); Assert.IsTrue((Int64)mirror.GetValue("x").Payload == result1); }
public void TestProtoASTExecute_ArrayIndex_RHS_Assign04() { List<ProtoCore.AST.AssociativeAST.AssociativeNode> astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); // a = {1, 2, 3, 4}; int[] input = { 1, 2, 3, 4 }; ProtoCore.AST.AssociativeAST.BinaryExpressionNode declareNodeA = CreateDeclareArrayNode("a", input); astList.Add(declareNodeA); // b = 4; ProtoCore.AST.AssociativeAST.BinaryExpressionNode declareNodeB = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), new ProtoCore.AST.AssociativeAST.IntNode(5), ProtoCore.DSASM.Operator.assign); astList.Add(declareNodeB); // def foo(){ // return = -4; // } ProtoCore.AST.AssociativeAST.CodeBlockNode cbn = new ProtoCore.AST.AssociativeAST.CodeBlockNode(); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnNode = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode(ProtoCore.DSDefinitions.Keyword.Return), new ProtoCore.AST.AssociativeAST.IntNode(-4), ProtoCore.DSASM.Operator.assign); cbn.Body.Add(returnNode); // Build the function definition foo const string functionName = "foo"; ProtoCore.AST.AssociativeAST.FunctionDefinitionNode funcDefNode = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode() { Name = functionName, FunctionBody = cbn }; // Function Return Type ProtoCore.Type returnType = new ProtoCore.Type(); returnType.Initialize(); returnType.UID = (int)ProtoCore.PrimitiveType.Var; returnType.Name = ProtoCore.DSDefinitions.Keyword.Var; funcDefNode.ReturnType = returnType; astList.Add(funcDefNode); // c = a[b + foo()]; ProtoCore.AST.AssociativeAST.FunctionCallNode functionCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); functionCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode(functionName); ProtoCore.AST.AssociativeAST.BinaryExpressionNode operation1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), functionCall, ProtoCore.DSASM.Operator.add); ProtoCore.AST.AssociativeAST.IdentifierNode nodeALHS = new ProtoCore.AST.AssociativeAST.IdentifierNode("a"); nodeALHS.ArrayDimensions = new ProtoCore.AST.AssociativeAST.ArrayNode { Expr = operation1 }; ProtoCore.AST.AssociativeAST.BinaryExpressionNode nodeALHSAssignment = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("c"), nodeALHS, ProtoCore.DSASM.Operator.assign); astList.Add(nodeALHSAssignment); // Verify the results ExecutionMirror mirror = thisTest.RunASTSource(astList); Obj o = mirror.GetValue("c"); Console.WriteLine(o.Payload); // expected: c = 2 Assert.AreEqual(2, Convert.ToInt32(o.Payload)); }
public void TestNameProvider() { var core = CurrentDynamoModel.EngineController.LibraryServices.LibraryManagementCore; var libraryServices = new LibraryCustomizationServices(CurrentDynamoModel.PathManager); var nameProvider = new NamingProvider(core, libraryServices); ProtoCore.Type t; string name = string.Empty; int typeID = -1; t = ProtoCore.TypeSystem.BuildPrimitiveTypeObject(ProtoCore.PrimitiveType.Integer); name = nameProvider.GetTypeDependentName(t); Assert.AreEqual("num", name); t = ProtoCore.TypeSystem.BuildPrimitiveTypeObject(ProtoCore.PrimitiveType.Double); name = nameProvider.GetTypeDependentName(t); Assert.AreEqual("num", name); t = ProtoCore.TypeSystem.BuildPrimitiveTypeObject(ProtoCore.PrimitiveType.String); name = nameProvider.GetTypeDependentName(t); Assert.AreEqual("str", name); typeID = core.TypeSystem.GetType("Autodesk.DesignScript.Geometry.Point"); t = core.TypeSystem.BuildTypeObject(typeID); name = nameProvider.GetTypeDependentName(t); Assert.AreEqual("point", name); typeID = core.TypeSystem.GetType("Autodesk.DesignScript.Geometry.BoundingBox"); t = core.TypeSystem.BuildTypeObject(typeID); name = nameProvider.GetTypeDependentName(t); Assert.AreEqual("boundingBox", name); t = new ProtoCore.Type(); t.Name = "DummyClassForTest"; t.UID = -1; name = nameProvider.GetTypeDependentName(t); Assert.IsTrue(string.IsNullOrEmpty(name)); }
public void TestProtoASTExecute_FunctionDefAndCall_03() { // def add(a : int, b : int) // { // return = a + b; // } // // x = add(2,3); ProtoCore.AST.AssociativeAST.CodeBlockNode cbn = new ProtoCore.AST.AssociativeAST.CodeBlockNode(); // Build the function body ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnExpr = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("a"), new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), ProtoCore.DSASM.Operator.add); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnNode = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode(ProtoCore.DSDefinitions.Keyword.Return), returnExpr, ProtoCore.DSASM.Operator.assign); cbn.Body.Add(returnNode); // Build the function definition foo const string functionName = "foo"; ProtoCore.AST.AssociativeAST.FunctionDefinitionNode funcDefNode = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode(); funcDefNode.Name = functionName; funcDefNode.FunctionBody = cbn; // build the args signature funcDefNode.Signature = new ProtoCore.AST.AssociativeAST.ArgumentSignatureNode(); // Build arg1 ProtoCore.AST.AssociativeAST.VarDeclNode arg1Decl = new ProtoCore.AST.AssociativeAST.VarDeclNode(); arg1Decl.NameNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("a"); // Build the type of arg1 ProtoCore.Type arg1Type = new ProtoCore.Type(); arg1Type.Initialize(); arg1Type.UID = (int)ProtoCore.PrimitiveType.Integer; arg1Type.Name = ProtoCore.DSDefinitions.Keyword.Int; arg1Decl.ArgumentType = arg1Type; funcDefNode.Signature.AddArgument(arg1Decl); // Build arg2 ProtoCore.AST.AssociativeAST.VarDeclNode arg2Decl = new ProtoCore.AST.AssociativeAST.VarDeclNode(); arg2Decl.NameNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("b"); // Build the type of arg2 ProtoCore.Type arg2Type = new ProtoCore.Type(); arg2Type.Initialize(); arg2Type.UID = (int)ProtoCore.PrimitiveType.Integer; arg2Type.Name = ProtoCore.DSDefinitions.Keyword.Int; arg2Decl.ArgumentType = arg2Type; funcDefNode.Signature.AddArgument(arg2Decl); // Function Return type ProtoCore.Type returnType = new ProtoCore.Type(); returnType.Initialize(); returnType.UID = (int)ProtoCore.PrimitiveType.Var; returnType.Name = ProtoCore.DSDefinitions.Keyword.Var; funcDefNode.ReturnType = returnType; // Build the statement that calls the function foo ProtoCore.AST.AssociativeAST.FunctionCallNode functionCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); functionCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode(functionName); List<ProtoCore.AST.AssociativeAST.AssociativeNode> astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); astList.Add(funcDefNode); // Function call // Function args List<ProtoCore.AST.AssociativeAST.AssociativeNode> args = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); args.Add(new ProtoCore.AST.AssociativeAST.IntNode(2)); args.Add(new ProtoCore.AST.AssociativeAST.IntNode(3)); functionCall.FormalArguments = args; // Call the function ProtoCore.AST.AssociativeAST.BinaryExpressionNode callstmt = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("x"), functionCall, ProtoCore.DSASM.Operator.assign); astList.Add(callstmt); ExecutionMirror mirror = thisTest.RunASTSource(astList); Obj o = mirror.GetValue("x"); Assert.IsTrue((Int64)o.Payload == 5); }
void Associative_vardecl(out ProtoCore.AST.AssociativeAST.AssociativeNode node, ProtoCore.CompilerDefinitions.AccessModifier access = ProtoCore.CompilerDefinitions.AccessModifier.Public, bool isStatic = false, List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = null) { ProtoCore.AST.AssociativeAST.IdentifierNode tNode = null; ProtoCore.AST.AssociativeAST.VarDeclNode varDeclNode = new ProtoCore.AST.AssociativeAST.VarDeclNode(); varDeclNode.Access = access; varDeclNode.IsStatic = isStatic; Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } NodeUtils.SetNodeLocation(varDeclNode, t); tNode = AstFactory.BuildIdentifier(t.val); NodeUtils.SetNodeLocation(tNode, t); varDeclNode.NameNode = tNode; if (la.kind == 47) { Get(); Expect(1); ProtoCore.Type argtype = new ProtoCore.Type(); argtype.Name = t.val; argtype.rank = 0; if (la.kind == 10) { Get(); Expect(11); argtype.rank = 1; if (la.kind == 10 || la.kind == 24 || la.kind == 51) { if (la.kind == 24) { Get(); Expect(10); Expect(11); argtype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 10) { Get(); Expect(11); argtype.rank++; } } } } string oldName = tNode.Name; string oldValue = tNode.Value; // Here since the variable has an explicitly specified type // the "IdentifierNode" should really be "TypedIdentifierNode" // (which is used to indicate the identifier that has explicit // type specified). tNode = new ProtoCore.AST.AssociativeAST.TypedIdentifierNode() { Name = oldName, Value = oldValue }; argtype.UID = core.TypeSystem.GetType(argtype.Name); tNode.datatype = argtype; varDeclNode.NameNode = tNode; varDeclNode.ArgumentType = argtype; } if (la.kind == 51) { Get(); ProtoCore.AST.AssociativeAST.AssociativeNode rhsNode; Associative_Expression(out rhsNode); ProtoCore.AST.AssociativeAST.BinaryExpressionNode bNode = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode(); NodeUtils.CopyNodeLocation(bNode, varDeclNode); bNode.LeftNode = tNode; bNode.RightNode = rhsNode; bNode.Optr = Operator.assign; varDeclNode.NameNode = bNode; } node = varDeclNode; //if(!isGlobalScope) { // localVarCount++; //} }
void functiondecl(out Node node) { FunctionDefinitionNode funcDecl = new FunctionDefinitionNode(); ProtoCore.Type rtype = new ProtoCore.Type(); rtype.Name = "var"; rtype.UID = 0; Expect(18); Expect(1); funcDecl.Name = t.val; if (la.kind == 36) { Get(); ReturnType(out rtype); } funcDecl.ReturnType = rtype; Expect(8); if (la.kind == 1 || la.kind == 25) { ArgumentSignatureNode args = new ArgumentSignatureNode(); Node argdecl; ArgDecl(out argdecl); args.AddArgument(argdecl as VarDeclNode); while (la.kind == 30) { Get(); ArgDecl(out argdecl); args.AddArgument(argdecl as VarDeclNode); } funcDecl.Signature = args; } Expect(9); isGlobalScope = false; Expect(32); funcDecl.FunctionBody = new CodeBlockNode(); NodeList body = new NodeList(); stmtlist(out body); Expect(33); funcDecl.localVars = localVarCount; funcDecl.FunctionBody.Body = body; node = funcDecl; isGlobalScope = true; localVarCount= 0; }
void Associative_ArgDecl(out ProtoCore.AST.AssociativeAST.AssociativeNode node, ProtoCore.CompilerDefinitions.AccessModifier access = ProtoCore.CompilerDefinitions.AccessModifier.Public) { ProtoCore.AST.AssociativeAST.IdentifierNode tNode = null; ProtoCore.AST.AssociativeAST.VarDeclNode varDeclNode = new ProtoCore.AST.AssociativeAST.VarDeclNode(); varDeclNode.Access = access; Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } tNode = AstFactory.BuildIdentifier(t.val); NodeUtils.SetNodeLocation(tNode, t); varDeclNode.NameNode = tNode; NodeUtils.CopyNodeLocation(varDeclNode, tNode); ProtoCore.Type argtype = new ProtoCore.Type(); argtype.Name = "var"; argtype.rank = 0; argtype.UID = 0; if (la.kind == 47) { Get(); Expect(1); argtype.Name = t.val; if (la.kind == 10) { Get(); Expect(11); argtype.rank = 1; if (la.kind == 10 || la.kind == 24) { if (la.kind == 24) { Get(); Expect(10); Expect(11); argtype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 10) { Get(); Expect(11); argtype.rank++; } } } } } varDeclNode.ArgumentType = argtype; node = varDeclNode; }
public void TestRoundTrip_ClassDecl_MemFunctionCall_01() { int result1 = 20; ExecutionMirror mirror = null; List<ProtoCore.AST.AssociativeAST.AssociativeNode> astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); // Create an exact copy of the AST list to pass to the source conversion // This needs to be done because the astlist to be run will be SSA'd on the AST execution run List<ProtoCore.AST.AssociativeAST.AssociativeNode> astListcopy = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); // 1. Build AST // class bar // { // f : var // def foo (b:int) // { // b = 10; // return = b + 10; // } // } // // p = bar.bar(); // a = p.foo(); ProtoCore.AST.AssociativeAST.CodeBlockNode cbn = new ProtoCore.AST.AssociativeAST.CodeBlockNode(); // Build the function body ProtoCore.AST.AssociativeAST.BinaryExpressionNode assignment1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), new ProtoCore.AST.AssociativeAST.IntNode(10), ProtoCore.DSASM.Operator.assign); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnExpr = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), new ProtoCore.AST.AssociativeAST.IntNode(10), ProtoCore.DSASM.Operator.add); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnNode = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode(ProtoCore.DSDefinitions.Keyword.Return), returnExpr, ProtoCore.DSASM.Operator.assign); cbn.Body.Add(assignment1); cbn.Body.Add(returnNode); // Build the function definition foo const string functionName = "foo"; ProtoCore.AST.AssociativeAST.FunctionDefinitionNode funcDefNode = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode(); funcDefNode.Name = functionName; funcDefNode.FunctionBody = cbn; // Function Return type ProtoCore.Type returnType = new ProtoCore.Type(); returnType.Initialize(); returnType.UID = (int)ProtoCore.PrimitiveType.Var; returnType.Name = ProtoCore.DSDefinitions.Keyword.Var; funcDefNode.ReturnType = returnType; // Create the class node AST ProtoCore.AST.AssociativeAST.ClassDeclNode classDefNode = new ProtoCore.AST.AssociativeAST.ClassDeclNode(); classDefNode.ClassName = "bar"; // Add the member function 'foo' classDefNode.Procedures.Add(funcDefNode); // Create the property AST ProtoCore.AST.AssociativeAST.VarDeclNode varDeclNode = new ProtoCore.AST.AssociativeAST.VarDeclNode(); varDeclNode.Name = "f"; varDeclNode.NameNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("f"); varDeclNode.ArgumentType = new ProtoCore.Type() { Name = "int", rank = 0, UID = (int)ProtoCore.PrimitiveType.Integer }; classDefNode.Variables.Add(varDeclNode); // Add the constructed class AST astList.Add(classDefNode); astListcopy.Add(new ProtoCore.AST.AssociativeAST.ClassDeclNode(classDefNode)); // p = bar.bar(); ProtoCore.AST.AssociativeAST.FunctionCallNode constructorCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); constructorCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode("bar"); ProtoCore.AST.AssociativeAST.IdentifierListNode identListConstrcctorCall = new ProtoCore.AST.AssociativeAST.IdentifierListNode(); identListConstrcctorCall.LeftNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("bar"); identListConstrcctorCall.RightNode = constructorCall; ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmtInitClass = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("p"), identListConstrcctorCall, ProtoCore.DSASM.Operator.assign); astList.Add(stmtInitClass); astListcopy.Add(new ProtoCore.AST.AssociativeAST.BinaryExpressionNode(stmtInitClass)); // a = p.f; ProtoCore.AST.AssociativeAST.FunctionCallNode functionCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); functionCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode("foo"); ProtoCore.AST.AssociativeAST.IdentifierListNode identListFunctionCall = new ProtoCore.AST.AssociativeAST.IdentifierListNode(); identListFunctionCall.LeftNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("p"); identListFunctionCall.RightNode = functionCall; ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmtPropertyAccess = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("a"), identListFunctionCall, ProtoCore.DSASM.Operator.assign); astList.Add(stmtPropertyAccess); astListcopy.Add(new ProtoCore.AST.AssociativeAST.BinaryExpressionNode(stmtPropertyAccess)); // 2. Execute AST and verify mirror = thisTest.RunASTSource(astList); Assert.IsTrue((Int64)mirror.GetValue("a").Payload == result1); // 3. Convert AST to source ProtoCore.CodeGenDS codegenDS = new ProtoCore.CodeGenDS(astListcopy); string code = codegenDS.GenerateCode(); // 4. Execute source and verify mirror = thisTest.RunScriptSource(code); Assert.IsTrue((Int64)mirror.GetValue("a").Payload == result1); }
void Associative_ClassReference(out ProtoCore.Type type) { type = new ProtoCore.Type(); string name; Expect(1); name = t.val; type.Name = name; type.UID = 0; }
ProtoCore.CodeGenDS codegen = new ProtoCore.CodeGenDS(astList); string code = codegen.GenerateCode(); ExecutionMirror mirror = thisTest.RunScriptSource(code); Assert.IsTrue((Int64)mirror.GetValue("a").Payload == 10); } [Test] [Ignore][Category("DSDefinedClass_Ignored_DSDefinedClassSemantics")] public void TestCodeGenDS_ClassDecl_MemFunctionCall_01() { // class bar // { // f : var // def foo (b:int) // { // b = 10; // return = b + 10; // } // } // // p = bar.bar(); // a = p.foo(); ProtoCore.AST.AssociativeAST.CodeBlockNode cbn = new ProtoCore.AST.AssociativeAST.CodeBlockNode(); // Build the function body ProtoCore.AST.AssociativeAST.BinaryExpressionNode assignment1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), new ProtoCore.AST.AssociativeAST.IntNode(10), ProtoCore.DSASM.Operator.assign); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnExpr = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), new ProtoCore.AST.AssociativeAST.IntNode(10), ProtoCore.DSASM.Operator.add); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnNode = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode(ProtoCore.DSDefinitions.Keyword.Return), returnExpr, ProtoCore.DSASM.Operator.assign); cbn.Body.Add(assignment1); cbn.Body.Add(returnNode); // Build the function definition foo const string functionName = "foo"; ProtoCore.AST.AssociativeAST.FunctionDefinitionNode funcDefNode = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode(); funcDefNode.Name = functionName; funcDefNode.FunctionBody = cbn; // Function Return type ProtoCore.Type returnType = new ProtoCore.Type(); returnType.Initialize(); returnType.UID = (int)ProtoCore.PrimitiveType.Var; returnType.Name = ProtoCore.DSDefinitions.Keyword.Var; funcDefNode.ReturnType = returnType; // Create the class node AST ProtoCore.AST.AssociativeAST.ClassDeclNode classDefNode = new ProtoCore.AST.AssociativeAST.ClassDeclNode(); classDefNode.ClassName = "bar"; // Add the member function 'foo' classDefNode.Procedures.Add(funcDefNode); // Create the property AST ProtoCore.AST.AssociativeAST.VarDeclNode varDeclNode = new ProtoCore.AST.AssociativeAST.VarDeclNode(); varDeclNode.Name = "f"; varDeclNode.NameNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("f"); varDeclNode.ArgumentType = new ProtoCore.Type() { Name = "int", rank = 0, UID = (int)ProtoCore.PrimitiveType.Integer }; classDefNode.Variables.Add(varDeclNode); // Add the constructed class AST List<ProtoCore.AST.AssociativeAST.AssociativeNode> astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); astList.Add(classDefNode); // p = bar.bar(); ProtoCore.AST.AssociativeAST.FunctionCallNode constructorCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); constructorCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode("bar"); ProtoCore.AST.AssociativeAST.IdentifierListNode identListConstrcctorCall = new ProtoCore.AST.AssociativeAST.IdentifierListNode(); identListConstrcctorCall.LeftNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("bar"); identListConstrcctorCall.RightNode = constructorCall; ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmtInitClass = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("p"), identListConstrcctorCall, ProtoCore.DSASM.Operator.assign); astList.Add(stmtInitClass); // a = p.f; ProtoCore.AST.AssociativeAST.FunctionCallNode functionCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); functionCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode("foo"); ProtoCore.AST.AssociativeAST.IdentifierListNode identListFunctionCall = new ProtoCore.AST.AssociativeAST.IdentifierListNode(); identListFunctionCall.LeftNode = new ProtoCore.AST.AssociativeAST.IdentifierNode("p"); identListFunctionCall.RightNode = functionCall; ProtoCore.AST.AssociativeAST.BinaryExpressionNode stmtPropertyAccess = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("a"), identListFunctionCall, ProtoCore.DSASM.Operator.assign);
void Imperative_decoratedIdentifier(out ProtoCore.AST.ImperativeAST.ImperativeNode node) { node = null; if (IsLocallyTypedVariable()) { Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } var typedVar = new ProtoCore.AST.ImperativeAST.TypedIdentifierNode(); typedVar.Name = typedVar.Value = t.val; NodeUtils.SetNodeLocation(typedVar, t); Expect(47); Expect(40); typedVar.IsLocal = true; Expect(1); int type = core.TypeSystem.GetType(t.val); if (type == ProtoCore.DSASM.Constants.kInvalidIndex) { var unknownType = new ProtoCore.Type(); unknownType.UID = ProtoCore.DSASM.Constants.kInvalidIndex; unknownType.Name = t.val; typedVar.DataType = unknownType; } else { typedVar.DataType = core.TypeSystem.BuildTypeObject(type, 0); } if (la.kind == 10) { var datatype = typedVar.DataType; Get(); Expect(11); datatype.rank = 1; if (la.kind == 10 || la.kind == 24) { if (la.kind == 24) { Get(); Expect(10); Expect(11); datatype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 10) { Get(); Expect(11); datatype.rank++; } } } typedVar.DataType = datatype; } node = typedVar; } else if (IsLocalVariable()) { Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } var identNode = new ProtoCore.AST.ImperativeAST.IdentifierNode(); identNode.Name = identNode.Value = t.val; NodeUtils.SetNodeLocation(identNode, t); Expect(47); Expect(40); identNode.IsLocal = true; node = identNode; } else if (IsTypedVariable()) { Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } var typedVar = new ProtoCore.AST.ImperativeAST.TypedIdentifierNode(); typedVar.Name = typedVar.Value = t.val; NodeUtils.SetNodeLocation(typedVar, t); Expect(47); Expect(1); int type = core.TypeSystem.GetType(t.val); if (type == ProtoCore.DSASM.Constants.kInvalidIndex) { var unknownType = new ProtoCore.Type(); unknownType.UID = ProtoCore.DSASM.Constants.kInvalidIndex; unknownType.Name = t.val; typedVar.DataType = unknownType; } else { typedVar.DataType = core.TypeSystem.BuildTypeObject(type, 0); } if (la.kind == 10) { var datatype = typedVar.DataType; Get(); Expect(11); datatype.rank = 1; if (la.kind == 10 || la.kind == 24) { if (la.kind == 24) { Get(); Expect(10); Expect(11); datatype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 10) { Get(); Expect(11); datatype.rank++; } } } typedVar.DataType = datatype; } node = typedVar; } else if (la.kind == 1 || la.kind == 12 || la.kind == 45) { Imperative_IdentifierList(out node); } else SynErr(113); }
public void TestProtoASTExecute_FunctionDefAndCall_01() { // def foo() // { // b = 10; // return = b + 10; // } // // x = foo(); ProtoCore.AST.AssociativeAST.CodeBlockNode cbn = new ProtoCore.AST.AssociativeAST.CodeBlockNode(); // Build the function body ProtoCore.AST.AssociativeAST.BinaryExpressionNode assignment1 = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), new ProtoCore.AST.AssociativeAST.IntNode(10), ProtoCore.DSASM.Operator.assign); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnExpr = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("b"), new ProtoCore.AST.AssociativeAST.IntNode(10), ProtoCore.DSASM.Operator.add); ProtoCore.AST.AssociativeAST.BinaryExpressionNode returnNode = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode(ProtoCore.DSDefinitions.Keyword.Return), returnExpr, ProtoCore.DSASM.Operator.assign); cbn.Body.Add(assignment1); cbn.Body.Add(returnNode); // Build the function definition foo const string functionName = "foo"; ProtoCore.AST.AssociativeAST.FunctionDefinitionNode funcDefNode = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode(); funcDefNode.Name = functionName; funcDefNode.FunctionBody = cbn; // Function Return type ProtoCore.Type returnType = new ProtoCore.Type(); returnType.Initialize(); returnType.UID = (int)ProtoCore.PrimitiveType.Var; returnType.Name = ProtoCore.DSDefinitions.Keyword.Var; funcDefNode.ReturnType = returnType; List<ProtoCore.AST.AssociativeAST.AssociativeNode> astList = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); astList.Add(funcDefNode); // Build the statement that calls the function foo ProtoCore.AST.AssociativeAST.FunctionCallNode functionCall = new ProtoCore.AST.AssociativeAST.FunctionCallNode(); functionCall.Function = new ProtoCore.AST.AssociativeAST.IdentifierNode(functionName); ProtoCore.AST.AssociativeAST.BinaryExpressionNode callstmt = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode( new ProtoCore.AST.AssociativeAST.IdentifierNode("x"), functionCall, ProtoCore.DSASM.Operator.assign); astList.Add(callstmt); ExecutionMirror mirror = thisTest.RunASTSource(astList); Obj o = mirror.GetValue("x"); Assert.IsTrue((Int64)o.Payload == 20); }
void Imperative_ArgDecl(out ProtoCore.AST.ImperativeAST.ImperativeNode node) { ProtoCore.AST.ImperativeAST.IdentifierNode tNode = null; ProtoCore.AST.ImperativeAST.VarDeclNode varDeclNode = new ProtoCore.AST.ImperativeAST.VarDeclNode(); NodeUtils.SetNodeLocation(varDeclNode, la); varDeclNode.memregion = ProtoCore.DSASM.MemoryRegion.MemStack; Expect(1); if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } tNode = BuildImperativeIdentifier(t.val); NodeUtils.SetNodeLocation(tNode, t); varDeclNode.NameNode = tNode; NodeUtils.CopyNodeLocation(varDeclNode, tNode); ProtoCore.Type argtype = new ProtoCore.Type(); argtype.Name = "var"; argtype.rank = 0; argtype.UID = 0; if (la.kind == 47) { Get(); Expect(1); argtype.Name = t.val; if (la.kind == 10) { Get(); Expect(11); argtype.rank = 1; if (la.kind == 10 || la.kind == 24) { if (la.kind == 24) { Get(); Expect(10); Expect(11); argtype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 10) { Get(); Expect(11); argtype.rank++; } } } } } varDeclNode.ArgumentType = argtype; node = varDeclNode; if(!isGlobalScope) { localVarCount++; } }
/// <summary> /// Collapse a set of nodes in a given workspace. /// </summary> /// <param name="selectedNodes"> The function definition for the user-defined node </param> /// <param name="currentWorkspace"> The workspace where</param> /// <param name="isTestMode"></param> /// <param name="args"></param> public CustomNodeWorkspaceModel Collapse( IEnumerable<NodeModel> selectedNodes, WorkspaceModel currentWorkspace, bool isTestMode, FunctionNamePromptEventArgs args) { var selectedNodeSet = new HashSet<NodeModel>(selectedNodes); // Note that undoable actions are only recorded for the "currentWorkspace", // the nodes which get moved into "newNodeWorkspace" are not recorded for undo, // even in the new workspace. Their creations will simply be treated as part of // the opening of that new workspace (i.e. when a user opens a file, she will // not expect the nodes that show up to be undoable). // // After local nodes are moved into "newNodeWorkspace" as the result of // conversion, if user performs an undo, new set of nodes will be created in // "currentWorkspace" (not moving those nodes in the "newNodeWorkspace" back // into "currentWorkspace"). In another word, undo recording is on a per- // workspace basis, it does not work across different workspaces. // UndoRedoRecorder undoRecorder = currentWorkspace.UndoRecorder; CustomNodeWorkspaceModel newWorkspace; using (undoRecorder.BeginActionGroup()) { #region Determine Inputs and Outputs //Step 1: determine which nodes will be inputs to the new node var inputs = new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.InPortData.Count) .Where(node.HasConnectedInput) .Select(data => Tuple.Create(node, data, node.InputNodes[data])) .Where(input => !selectedNodeSet.Contains(input.Item3.Item2)))); var outputs = new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.OutPortData.Count) .Where(node.HasOutput) .SelectMany( data => node.OutputNodes[data].Where( output => !selectedNodeSet.Contains(output.Item2)) .Select(output => Tuple.Create(node, data, output))))); #endregion #region Detect 1-node holes (higher-order function extraction) Log(Properties.Resources.CouldNotRepairOneNodeHoles, WarningLevel.Mild); // http://adsk-oss.myjetbrains.com/youtrack/issue/MAGN-5603 //var curriedNodeArgs = // new HashSet<NodeModel>( // inputs.Select(x => x.Item3.Item2) // .Intersect(outputs.Select(x => x.Item3.Item2))).Select( // outerNode => // { // //var node = new Apply1(); // var node = newNodeWorkspace.AddNode<Apply1>(); // node.SetNickNameFromAttribute(); // node.DisableReporting(); // node.X = outerNode.X; // node.Y = outerNode.Y; // //Fetch all input ports // // in order // // that have inputs // // and whose input comes from an inner node // List<int> inPortsConnected = // Enumerable.Range(0, outerNode.InPortData.Count) // .Where( // x => // outerNode.HasInput(x) // && selectedNodeSet.Contains( // outerNode.Inputs[x].Item2)) // .ToList(); // var nodeInputs = // outputs.Where(output => output.Item3.Item2 == outerNode) // .Select( // output => // new // { // InnerNodeInputSender = output.Item1, // OuterNodeInPortData = output.Item3.Item1 // }) // .ToList(); // nodeInputs.ForEach(_ => node.AddInput()); // node.RegisterAllPorts(); // return // new // { // OuterNode = outerNode, // InnerNode = node, // Outputs = // inputs.Where( // input => input.Item3.Item2 == outerNode) // .Select(input => input.Item3.Item1), // Inputs = nodeInputs, // OuterNodePortDataList = inPortsConnected // }; // }).ToList(); #endregion #region UI Positioning Calculations double avgX = selectedNodeSet.Average(node => node.X); double avgY = selectedNodeSet.Average(node => node.Y); double leftMost = selectedNodeSet.Min(node => node.X); double topMost = selectedNodeSet.Min(node => node.Y); double rightMost = selectedNodeSet.Max(node => node.X + node.Width); double leftShift = leftMost - 250; #endregion #region Handle full selected connectors // Step 2: Determine all the connectors whose start/end owners are // both in the selection set, and then move them from the current // workspace into the new workspace. var fullySelectedConns = new HashSet<ConnectorModel>( currentWorkspace.Connectors.Where( conn => { bool startSelected = selectedNodeSet.Contains(conn.Start.Owner); bool endSelected = selectedNodeSet.Contains(conn.End.Owner); return startSelected && endSelected; })); foreach (var connector in fullySelectedConns) { undoRecorder.RecordDeletionForUndo(connector); connector.Delete(); } #endregion #region Handle partially selected connectors // Step 3: Partially selected connectors (either one of its start // and end owners is in the selection) are to be destroyed. var partiallySelectedConns = currentWorkspace.Connectors.Where( conn => selectedNodeSet.Contains(conn.Start.Owner) || selectedNodeSet.Contains(conn.End.Owner)).ToList(); foreach (var connector in partiallySelectedConns) { undoRecorder.RecordDeletionForUndo(connector); connector.Delete(); } #endregion #region Transfer nodes and connectors to new workspace var newNodes = new List<NodeModel>(); var newAnnotations = new List<AnnotationModel>(); // Step 4: move all nodes to new workspace remove from old // PB: This could be more efficiently handled by a copy paste, but we // are preservering the node foreach (var node in selectedNodeSet) { undoRecorder.RecordDeletionForUndo(node); currentWorkspace.RemoveNode(node); // Assign a new guid to this node, otherwise when node is // compiled to AST, literally it is still in global scope // instead of in function scope. node.GUID = Guid.NewGuid(); node.RenderPackages.Clear(); // shift nodes node.X = node.X - leftShift; node.Y = node.Y - topMost; newNodes.Add(node); } //Copy the group from newNodes foreach (var group in DynamoSelection.Instance.Selection.OfType<AnnotationModel>()) { undoRecorder.RecordDeletionForUndo(group); currentWorkspace.RemoveGroup(group); group.GUID = Guid.NewGuid(); group.SelectedModels = group.DeletedModelBases; newAnnotations.Add(group); } foreach (var conn in fullySelectedConns) { ConnectorModel.Make(conn.Start.Owner, conn.End.Owner, conn.Start.Index, conn.End.Index); } #endregion #region Process inputs var inConnectors = new List<Tuple<NodeModel, int>>(); var uniqueInputSenders = new Dictionary<Tuple<NodeModel, int>, Symbol>(); //Step 3: insert variables (reference step 1) foreach (var input in Enumerable.Range(0, inputs.Count).Zip(inputs, Tuple.Create)) { int inputIndex = input.Item1; NodeModel inputReceiverNode = input.Item2.Item1; int inputReceiverData = input.Item2.Item2; NodeModel inputNode = input.Item2.Item3.Item2; int inputData = input.Item2.Item3.Item1; Symbol node; var key = Tuple.Create(inputNode, inputData); if (uniqueInputSenders.ContainsKey(key)) { node = uniqueInputSenders[key]; } else { inConnectors.Add(Tuple.Create(inputNode, inputData)); node = new Symbol { InputSymbol = inputReceiverNode.InPortData[inputReceiverData].NickName, X = 0 }; // Try to figure out the type of input of custom node // from the type of input of selected node. There are // two kinds of nodes whose input type are available: // function node and custom node. List<Library.TypedParameter> parameters = null; if (inputReceiverNode is Function) { var func = inputReceiverNode as Function; parameters = func.Controller.Definition.Parameters.ToList(); } else if (inputReceiverNode is DSFunctionBase) { var dsFunc = inputReceiverNode as DSFunctionBase; var funcDesc = dsFunc.Controller.Definition; parameters = funcDesc.Parameters.ToList(); if (funcDesc.Type == DSEngine.FunctionType.InstanceMethod || funcDesc.Type == DSEngine.FunctionType.InstanceProperty) { var dummyType = new ProtoCore.Type() { Name = funcDesc.ClassName }; var instanceParam = new TypedParameter(funcDesc.ClassName, dummyType); parameters.Insert(0, instanceParam); } } // so the input of custom node has format // input_var_name : type if (parameters != null && parameters.Count() > inputReceiverData) { var typeName = parameters[inputReceiverData].DisplayTypeName; if (!string.IsNullOrEmpty(typeName)) { node.InputSymbol += " : " + typeName; } } node.SetNickNameFromAttribute(); node.Y = inputIndex*(50 + node.Height); uniqueInputSenders[key] = node; newNodes.Add(node); } //var curriedNode = curriedNodeArgs.FirstOrDefault(x => x.OuterNode == inputNode); //if (curriedNode == null) //{ ConnectorModel.Make(node, inputReceiverNode, 0, inputReceiverData); //} //else //{ // //Connect it to the applier // newNodeWorkspace.AddConnection(node, curriedNode.InnerNode, 0, 0); // //Connect applier to the inner input receive // newNodeWorkspace.AddConnection( // curriedNode.InnerNode, // inputReceiverNode, // 0, // inputReceiverData); //} } #endregion #region Process outputs //List of all inner nodes to connect an output. Unique. var outportList = new List<Tuple<NodeModel, int>>(); var outConnectors = new List<Tuple<NodeModel, int, int>>(); int i = 0; if (outputs.Any()) { foreach (var output in outputs) { if (outportList.All(x => !(x.Item1 == output.Item1 && x.Item2 == output.Item2))) { NodeModel outputSenderNode = output.Item1; int outputSenderData = output.Item2; //NodeModel outputReceiverNode = output.Item3.Item2; //if (curriedNodeArgs.Any(x => x.OuterNode == outputReceiverNode)) // continue; outportList.Add(Tuple.Create(outputSenderNode, outputSenderData)); //Create Symbol Node var node = new Output { Symbol = outputSenderNode.OutPortData[outputSenderData].NickName, X = rightMost + 75 - leftShift }; node.Y = i*(50 + node.Height); node.SetNickNameFromAttribute(); newNodes.Add(node); ConnectorModel.Make(outputSenderNode, node, outputSenderData, 0); i++; } } //Connect outputs to new node outConnectors.AddRange( from output in outputs let outputSenderNode = output.Item1 let outputSenderData = output.Item2 let outputReceiverData = output.Item3.Item1 let outputReceiverNode = output.Item3.Item2 select Tuple.Create( outputReceiverNode, outportList.FindIndex( x => x.Item1 == outputSenderNode && x.Item2 == outputSenderData), outputReceiverData)); } else { foreach (var hanging in selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.OutPortData.Count) .Where(port => !node.HasOutput(port)) .Select(port => new { node, port })).Distinct()) { //Create Symbol Node var node = new Output { Symbol = hanging.node.OutPortData[hanging.port].NickName, X = rightMost + 75 - leftShift }; node.Y = i*(50 + node.Height); node.SetNickNameFromAttribute(); newNodes.Add(node); ConnectorModel.Make(hanging.node, node, hanging.port, 0); i++; } } #endregion var newId = Guid.NewGuid(); newWorkspace = new CustomNodeWorkspaceModel( nodeFactory, newNodes, Enumerable.Empty<NoteModel>(), newAnnotations, Enumerable.Empty<PresetModel>(), new WorkspaceInfo() { X = 0, Y = 0, Name = args.Name, Category = args.Category, Description = args.Description, ID = newId.ToString(), FileName = string.Empty }, currentWorkspace.ElementResolver); newWorkspace.HasUnsavedChanges = true; RegisterCustomNodeWorkspace(newWorkspace); var collapsedNode = CreateCustomNodeInstance(newId, isTestMode: isTestMode); collapsedNode.X = avgX; collapsedNode.Y = avgY; currentWorkspace.AddNode(collapsedNode, centered: false); undoRecorder.RecordCreationForUndo(collapsedNode); foreach (var connector in inConnectors.Select((x, idx) => new { node = x.Item1, from = x.Item2, to = idx }) .Select( nodeTuple => ConnectorModel.Make( nodeTuple.node, collapsedNode, nodeTuple.@from, nodeTuple.to)) .Where(connector => connector != null)) { undoRecorder.RecordCreationForUndo(connector); } foreach (var connector in outConnectors.Select( nodeTuple => ConnectorModel.Make( collapsedNode, nodeTuple.Item1, nodeTuple.Item2, nodeTuple.Item3)).Where(connector => connector != null)) { undoRecorder.RecordCreationForUndo(connector); } } return newWorkspace; }
void Imperative_ReturnType(out ProtoCore.Type type) { ProtoCore.Type rtype = new ProtoCore.Type(); Expect(1); rtype.Name = t.val; rtype.rank = 0; if (la.kind == 10) { Get(); Expect(11); rtype.rank = 1; if (la.kind == 10 || la.kind == 24) { if (la.kind == 24) { Get(); Expect(10); Expect(11); rtype.rank = ProtoCore.DSASM.Constants.nDimensionArrayRank; } else { while (la.kind == 10) { Get(); Expect(11); rtype.rank++; } } } } type = rtype; }