private ClassDeclNode CreateEmptyClassNode(string classname) { ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = new ProtoCore.AST.AssociativeAST.ClassDeclNode(); classnode.className = classname; classnode.Name = null; classnode.IsImportedClass = true; classnode.IsExternLib = true; classnode.ExternLibName = null; //Dummy class. return(classnode); }
private ClassDeclNode ParseEnumType(Type type, string alias) { //TODO: For now Enum can't be suppressed. Validity.Assert(type.IsEnum, "Non enum type is being imported as enum!!"); 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; FieldInfo[] fields = type.GetFields(); foreach (var f in fields) { if (f.FieldType != type) { continue; } VarDeclNode variable = ParseFieldDeclaration(f); if (null == variable) { continue; } variable.IsStatic = true; classnode.varlist.Add(variable); FunctionDefinitionNode func = ParseFieldAccessor(f); if (null != func) { func.IsStatic = true; RegisterFunctionPointer(func.Name, f, null, func.ReturnType); classnode.funclist.Add(func); } } //Get all the attributes on this type and set it to the classnode. FFIClassAttributes cattrs = new FFIClassAttributes(type); classnode.ClassAttributes = cattrs; SetTypeAttributes(type, cattrs); return(classnode); }
private ProtoCore.AST.AssociativeAST.CodeBlockNode MergeCodeBlockNode(ref ProtoCore.AST.AssociativeAST.ImportNode importedNode, ProtoCore.AST.AssociativeAST.CodeBlockNode codeBlockNode) { if (codeBlockNode == null || codeBlockNode.Body == null || importedNode == null) { return(codeBlockNode); } ProtoCore.AST.AssociativeAST.CodeBlockNode importedCodeBlock = importedNode.CodeNode; if (importedCodeBlock == null) { importedNode.CodeNode = codeBlockNode; return(codeBlockNode); } foreach (var item in codeBlockNode.Body) { ProtoCore.AST.AssociativeAST.ClassDeclNode classNode = item as ProtoCore.AST.AssociativeAST.ClassDeclNode; if (classNode != null) { ProtoCore.AST.AssociativeAST.ClassDeclNode importedClass = null; if (TryGetClassNode(importedCodeBlock, classNode.className, out importedClass)) { bool dummyClassNode = IsEmptyClassNode(classNode); bool dummyImportClass = IsEmptyClassNode(importedClass); Validity.Assert(dummyImportClass || dummyClassNode, string.Format("{0} is imported more than once!!", classNode.className)); if (dummyImportClass && !dummyClassNode) { importedNode.CodeNode.Body.Remove(importedClass); importedNode.CodeNode.Body.Add(classNode); } } else { importedNode.CodeNode.Body.Add(classNode); } } else { importedNode.CodeNode.Body.Add(item); //TODO other conflict resolution needs to be done here. } } return(importedNode.CodeNode); }
private ClassDeclNode ParseEnumType(Type type, string alias) { Validity.Assert(type.IsEnum, "Non enum type is being imported as enum!!"); 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; FieldInfo[] fields = type.GetFields(); foreach (var f in fields) { if (f.FieldType != type) { continue; } VarDeclNode variable = ParseFieldDeclaration(f); if (null == variable) { continue; } variable.IsStatic = true; classnode.varlist.Add(variable); FunctionDefinitionNode func = ParseFieldAccessor(f); if (null != func) { func.IsStatic = true; RegisterFunctionPointer(func.Name, f, func.ReturnType); classnode.funclist.Add(func); } } return(classnode); }
public static bool TryGetClassNode(ProtoCore.AST.AssociativeAST.CodeBlockNode node, string typeName, out ProtoCore.AST.AssociativeAST.ClassDeclNode classNode) { classNode = null; //Traverse thru the code block and check if this type is already available if (node == null || node.Body == null) { return(false); } foreach (var item in node.Body) { ProtoCore.AST.AssociativeAST.ClassDeclNode clsnode = item as ProtoCore.AST.AssociativeAST.ClassDeclNode; if (clsnode != null && clsnode.className == typeName) { classNode = clsnode; return(true); } } return(false); }
private void SplitClassDeclarationNode(ClassDeclNode node) { foreach (AssociativeNode procNode in node.Procedures) { if (procNode is FunctionDefinitionNode) { FunctionDefinitionNode fNode = procNode as FunctionDefinitionNode; if (!fNode.IsExternLib) { fNode.FunctionBody.Body = SplitMulitpleAssignment(fNode.FunctionBody.Body); } } else if (procNode is ConstructorDefinitionNode) { ConstructorDefinitionNode cNode = procNode as ConstructorDefinitionNode; if (!cNode.IsExternLib) { cNode.FunctionBody.Body = SplitMulitpleAssignment(cNode.FunctionBody.Body); } } } }
private static bool IsEmptyClassNode(ProtoCore.AST.AssociativeAST.ClassDeclNode classNode) { if (null == classNode) { return(true); } if (classNode.IsExternLib && null == classNode.ExternLibName) { return(true); } if (classNode.funclist.Count > 0) { return(false); } if (classNode.varlist.Count > 0) { return(false); } return(true); }
private static bool IsEmptyClassNode(ProtoCore.AST.AssociativeAST.ClassDeclNode classNode) { if (null == classNode) { return(true); } if (classNode.IsExternLib && null == classNode.ExternLibName) { return(true); } if (classNode.Procedures.Count > 0) { return(false); } if (classNode.Variables.Count > 0) { return(false); } return(true); }
private ClassDeclNode CreateEmptyClassNode(string classname) { ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = new ProtoCore.AST.AssociativeAST.ClassDeclNode(); classnode.className = classname; classnode.Name = null; classnode.IsImportedClass = true; classnode.IsExternLib = true; classnode.ExternLibName = null; //Dummy class. return classnode; }
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); }
void Associative_classdecl(out ProtoCore.AST.AssociativeAST.AssociativeNode node, List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = null) { ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = new ProtoCore.AST.AssociativeAST.ClassDeclNode(); NodeUtils.SetNodeLocation(classnode, la); classnode.Attributes = attrs; Expect(25); Expect(1); classnode.ClassName = t.val; isInClass = true; if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format(Resources.keywordCantBeUsedAsIdentifier, t.val)); } if (la.kind == 28) { Get(); Expect(1); classnode.BaseClasses = new List<string>(); classnode.BaseClasses.Add(t.val); while (la.kind == 1) { Get(); classnode.BaseClasses.Add(t.val); } } Expect(45); while (StartOf(7)) { List<ProtoCore.AST.AssociativeAST.AssociativeNode> attributes = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); if (la.kind == 10) { Associative_AttributeDeclaration(out attributes); } ProtoCore.CompilerDefinitions.AccessModifier access = ProtoCore.CompilerDefinitions.AccessModifier.Public; if (la.kind == 48 || la.kind == 49 || la.kind == 50) { Associative_AccessSpecifier(out access); } if (la.kind == 26) { ProtoCore.AST.AssociativeAST.AssociativeNode constr = null; Associative_constructordecl(out constr, access, attributes); if (String.IsNullOrEmpty(constr.Name)) { constr.Name= classnode.ClassName; } classnode.Procedures.Add(constr); } else if (StartOf(8)) { bool isStatic = false; if (la.kind == 39) { Get(); isStatic = true; } if (la.kind == 27) { ProtoCore.AST.AssociativeAST.AssociativeNode funcnode; Associative_functiondecl(out funcnode, attributes, access, isStatic); classnode.Procedures.Add(funcnode); } else if (la.kind == 1) { ProtoCore.AST.AssociativeAST.AssociativeNode varnode = null; Associative_vardecl(out varnode, access, isStatic, attributes); classnode.Variables.Add(varnode); if (la.val != ";") SynErr(Resources.SemiColonExpected); Expect(23); NodeUtils.SetNodeEndLocation(varnode, t); } else if (la.kind == 23) { Get(); } else SynErr(73); } else SynErr(74); } Expect(46); isInClass = false; classnode.endLine = t.line; classnode.endCol = t.col; node = classnode; }
private void Initialize(ClassDeclNode classDeclNode) { }
void Associative_classdecl(out ProtoCore.AST.AssociativeAST.AssociativeNode node, List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = null) { ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = new ProtoCore.AST.AssociativeAST.ClassDeclNode(); NodeUtils.SetNodeLocation(classnode, la); classnode.Attributes = attrs; Expect(23); Expect(1); classnode.className = t.val; isInClass = true; if (IsKeyWord(t.val, true)) { errors.SemErr(t.line, t.col, String.Format("\"{0}\" is a keyword, identifier expected", t.val)); } if (la.kind == 27) { Get(); Expect(1); classnode.superClass = new List<string>(); classnode.superClass.Add(t.val); while (la.kind == 1) { Get(); classnode.superClass.Add(t.val); } } Expect(44); while (StartOf(7)) { List<ProtoCore.AST.AssociativeAST.AssociativeNode> attributes = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); if (la.kind == 7) { Associative_AttributeDeclaration(out attributes); } ProtoCore.DSASM.AccessSpecifier access = ProtoCore.DSASM.AccessSpecifier.kPublic; if (la.kind == 49 || la.kind == 50 || la.kind == 51) { Associative_AccessSpecifier(out access); } if (la.kind == 24) { ProtoCore.AST.AssociativeAST.AssociativeNode constr = null; Associative_constructordecl(out constr, access, attributes); if (String.IsNullOrEmpty(constr.Name)) { constr.Name= classnode.className; } classnode.funclist.Add(constr); } else if (StartOf(8)) { bool isStatic = false; if (la.kind == 39) { Get(); isStatic = true; } if (la.kind == 25 || la.kind == 26) { ProtoCore.AST.AssociativeAST.AssociativeNode funcnode; Associative_functiondecl(out funcnode, attributes, access, isStatic); classnode.funclist.Add(funcnode); } else if (la.kind == 1) { ProtoCore.AST.AssociativeAST.AssociativeNode varnode = null; Associative_vardecl(out varnode, access, isStatic, attributes); classnode.varlist.Add(varnode); if (la.val != ";") SynErr("';' is expected."); Expect(20); NodeUtils.SetNodeEndLocation(varnode, t); } else if (la.kind == 20) { Get(); } else SynErr(76); } else SynErr(77); } Expect(45); isInClass = false; classnode.endLine = t.line; classnode.endCol = t.col; node = classnode; }
private ClassDeclNode ParseSystemType(Type type, string alias) { Validity.Assert(!SupressesImport(type), "Supressed 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); } // There is no static class in runtime. static class is simply // marked as sealed and abstract. bool isStaticClass = type.IsSealed && type.IsAbstract; if (!isStaticClass) { // If all methods are static, it doesn't make sense to expose // constructor. ConstructorInfo[] ctors = type.GetConstructors(); foreach (var c in ctors) { if (c.IsPublic && !c.IsGenericMethod && !SupressesImport(c)) { ConstructorDefinitionNode node = ParseConstructor(c, type); classnode.funclist.Add(node); List <ProtoCore.Type> argTypes = GetArgumentTypes(node); RegisterFunctionPointer(node.Name, c, argTypes, node.ReturnType); } } } BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static; bool isDerivedClass = (classnode.superClass != null) && classnode.superClass.Count > 0; 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 (SupressesImport(m)) { continue; } if (isStaticClass && m.GetBaseDefinition().DeclaringType == baseType && baseType == typeof(object)) { continue; } //Don't include overriden methods or generic methods if (m.IsPublic && !m.IsGenericMethod && m == m.GetBaseDefinition()) { 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 (SupressesImport(f)) { continue; } //Supress if defined in super-type if (isDerivedClass) { FieldInfo[] supertypeFields = baseType.GetFields(); if (supertypeFields.Any(superF => superF.Name == f.Name)) { continue; } } VarDeclNode variable = ParseFieldDeclaration(f); if (null == variable) { continue; } classnode.varlist.Add(variable); FunctionDefinitionNode func = ParseFieldAccessor(f); if (null != func) { RegisterFunctionPointer(func.Name, f, null, func.ReturnType); } } PropertyInfo[] properties = type.GetProperties(flags); foreach (var p in properties) { AssociativeNode node = ParseProperty(p); if (null != node) { classnode.varlist.Add(node); } } FFIClassAttributes cattrs = new FFIClassAttributes(type); classnode.ClassAttributes = cattrs; SetTypeAttributes(type, cattrs); return(classnode); }
private void EmitMemberVariables(ClassDeclNode classDecl, GraphNode graphNode = null) { // Class member variable pass // Populating each class entry symbols with their respective member variables int thisClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); globalClassIndex = thisClassIndex; if (!unPopulatedClasses.ContainsKey(thisClassIndex)) { return; } ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[thisClassIndex]; // Handle member vars from base class if (!string.IsNullOrEmpty(classDecl.BaseClass)) { int baseClassIndex = core.ClassTable.GetClassId(classDecl.BaseClass); if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClassIndex) { // To handle the case that a base class is defined after // this class. if (unPopulatedClasses.ContainsKey(baseClassIndex)) { EmitMemberVariables(unPopulatedClasses[baseClassIndex], graphNode); globalClassIndex = thisClassIndex; } ClassNode baseClass = core.ClassTable.ClassNodes[baseClassIndex]; // Append the members variables of every class that this class inherits from foreach (ProtoCore.DSASM.SymbolNode symnode in baseClass.Symbols.symbolList.Values) { // It is a member variables if (ProtoCore.DSASM.Constants.kGlobalScope == symnode.functionIndex) { Validity.Assert(!symnode.isArgument); int symbolIndex = AllocateMemberVariable(thisClassIndex, symnode.isStatic ? symnode.classScope : baseClassIndex, symnode.name, symnode.datatype.rank, symnode.access, symnode.isStatic); if (symbolIndex != ProtoCore.DSASM.Constants.kInvalidIndex) thisClass.Size += ProtoCore.DSASM.Constants.kPointerSize; } } } else { Validity.Assert(false, "n-pass compile error, fixme Jun...."); } } foreach (VarDeclNode vardecl in classDecl.Variables) { IdentifierNode varIdent = vardecl.NameNode as IdentifierNode; int symbolIndex = AllocateMemberVariable(thisClassIndex, thisClassIndex, varIdent.Value, vardecl.ArgumentType.rank, vardecl.Access, vardecl.IsStatic); if (symbolIndex != Constants.kInvalidIndex && !classDecl.IsExternLib) { ProtoCore.DSASM.SymbolNode prop = vardecl.IsStatic ? core.CodeBlockList[0].symbolTable.symbolList[symbolIndex] : core.ClassTable.ClassNodes[thisClassIndex].Symbols.symbolList[symbolIndex]; string typeName = vardecl.ArgumentType.Name; if (String.IsNullOrEmpty(typeName)) { prop.datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, Constants.kArbitraryRank); } else { int type = core.TypeSystem.GetType(typeName); if (type == (int)PrimitiveType.InvalidType) { string message = String.Format(ProtoCore.Properties.Resources.kTypeUndefined, typeName); core.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.TypeUndefined, message, core.CurrentDSFileName, vardecl.line, vardecl.col, graphNode); prop.datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0); } else { int rank = vardecl.ArgumentType.rank; prop.datatype = core.TypeSystem.BuildTypeObject(type, rank); } } EmitGetterForProperty(classDecl, prop); EmitSetterForProperty(classDecl, prop); } } classOffset = 0; unPopulatedClasses.Remove(thisClassIndex); }
private void EmitMemberVariables(ClassDeclNode classDecl, GraphNode graphNode = null) { // Class member variable pass // Populating each class entry symbols with their respective member variables int thisClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); globalClassIndex = thisClassIndex; if (!unPopulatedClasses.ContainsKey(thisClassIndex)) { return; } ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[thisClassIndex]; // Handle member vars from base class if (null != classDecl.BaseClasses) { for (int n = 0; n < classDecl.BaseClasses.Count; ++n) { int baseClassIndex = core.ClassTable.GetClassId(classDecl.BaseClasses[n]); if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClassIndex) { // To handle the case that a base class is defined after // this class. if (unPopulatedClasses.ContainsKey(baseClassIndex)) { EmitMemberVariables(unPopulatedClasses[baseClassIndex], graphNode); globalClassIndex = thisClassIndex; } ClassNode baseClass = core.ClassTable.ClassNodes[baseClassIndex]; // Append the members variables of every class that this class inherits from foreach (ProtoCore.DSASM.SymbolNode symnode in baseClass.Symbols.symbolList.Values) { // It is a member variables if (ProtoCore.DSASM.Constants.kGlobalScope == symnode.functionIndex) { Validity.Assert(!symnode.isArgument); int symbolIndex = AllocateMemberVariable(thisClassIndex, symnode.isStatic ? symnode.classScope : baseClassIndex, symnode.name, symnode.datatype.rank, symnode.access, symnode.isStatic); if (symbolIndex != ProtoCore.DSASM.Constants.kInvalidIndex) thisClass.Size += ProtoCore.DSASM.Constants.kPointerSize; } } } else { Validity.Assert(false, "n-pass compile error, fixme Jun...."); } } } // This list will store all static properties initialization // expression (say x = 1). List<BinaryExpressionNode> staticPropertyInitList = new List<BinaryExpressionNode>(); foreach (VarDeclNode vardecl in classDecl.Variables) { IdentifierNode varIdent = null; if (vardecl.NameNode is IdentifierNode) { varIdent = vardecl.NameNode as IdentifierNode; BinaryExpressionNode bNode = new BinaryExpressionNode(); var thisNode =AstFactory.BuildIdentifier(ProtoCore.DSDefinitions.Keyword.This); var propNode =AstFactory.BuildIdentifier(varIdent.Value); bNode.LeftNode = AstFactory.BuildIdentList(thisNode, propNode); NodeUtils.CopyNodeLocation(bNode, vardecl); bNode.Optr = ProtoCore.DSASM.Operator.assign; bool skipInitialization = false; // Initialize it to default value by manually add the right hand side node if (vardecl.ArgumentType.rank == 0) { switch (vardecl.ArgumentType.Name) { case "double": bNode.RightNode = new DoubleNode(0); break; case "int": bNode.RightNode = new IntNode(0); break; case "bool": bNode.RightNode = new BooleanNode(false); break; default: skipInitialization = true; break; } } else if (vardecl.ArgumentType.rank > 0) { if (!vardecl.ArgumentType.Name.Equals("var")) bNode.RightNode = new ExprListNode(); else skipInitialization = true; } else if(vardecl.ArgumentType.rank.Equals(ProtoCore.DSASM.Constants.kArbitraryRank)) { if (!vardecl.ArgumentType.Name.Equals("var")) bNode.RightNode = new NullNode(); else skipInitialization = true; } if (!skipInitialization) { if (vardecl.IsStatic) staticPropertyInitList.Add(bNode); else thisClass.DefaultArgExprList.Add(bNode); } } else if (vardecl.NameNode is BinaryExpressionNode) { BinaryExpressionNode bNode = vardecl.NameNode as BinaryExpressionNode; varIdent = bNode.LeftNode as IdentifierNode; bNode.endCol = vardecl.endCol; bNode.endLine = vardecl.endLine; if (vardecl.IsStatic) staticPropertyInitList.Add(bNode); else thisClass.DefaultArgExprList.Add(bNode); } else { Validity.Assert(false, "Check generated AST"); } // It is possible that fail to allocate variable. In that // case we should remove initializing expression from // cnode's defaultArgExprList int symbolIndex = AllocateMemberVariable(thisClassIndex, thisClassIndex, varIdent.Value, vardecl.ArgumentType.rank, vardecl.Access, vardecl.IsStatic); if (symbolIndex == ProtoCore.DSASM.Constants.kInvalidIndex) { Validity.Assert(thisClass.DefaultArgExprList.Count > 0); thisClass.DefaultArgExprList.RemoveAt(thisClass.DefaultArgExprList.Count - 1); } // Only generate getter/setter for non-ffi class else if (!classDecl.IsExternLib) { ProtoCore.DSASM.SymbolNode prop = vardecl.IsStatic ? core.CodeBlockList[0].symbolTable.symbolList[symbolIndex] : core.ClassTable.ClassNodes[thisClassIndex].Symbols.symbolList[symbolIndex]; string typeName = vardecl.ArgumentType.Name; if (String.IsNullOrEmpty(typeName)) { prop.datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, Constants.kArbitraryRank); } else { int type = core.TypeSystem.GetType(typeName); if (type == (int)PrimitiveType.kInvalidType) { string message = String.Format(ProtoCore.Properties.Resources.kTypeUndefined, typeName); core.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, core.CurrentDSFileName, vardecl.line, vardecl.col, graphNode); prop.datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0); } else { int rank = vardecl.ArgumentType.rank; prop.datatype = core.TypeSystem.BuildTypeObject(type, rank); if (type != (int)PrimitiveType.kTypeVar || prop.datatype.IsIndexable) { prop.staticType = prop.datatype; } } } EmitGetterForProperty(classDecl, prop); EmitSetterForProperty(classDecl, prop); } } classOffset = 0; // Now we are going to create a static function __init_static_properties() // which will initialize all static properties. We will emit a // call to this function after all classes have been compiled. if (staticPropertyInitList.Count > 0 && !classDecl.IsExternLib) { FunctionDefinitionNode initFunc = new FunctionDefinitionNode { Name = ProtoCore.DSASM.Constants.kStaticPropertiesInitializer, Signature = new ArgumentSignatureNode(), Pattern = null, ReturnType = new ProtoCore.Type { Name = core.TypeSystem.GetType((int)PrimitiveType.kTypeNull), UID = (int)PrimitiveType.kTypeNull }, FunctionBody = new CodeBlockNode(), IsExternLib = false, IsDNI = false, ExternLibName = null, Access = ProtoCore.CompilerDefinitions.AccessModifier.kPublic, IsStatic = true }; classDecl.Procedures.Add(initFunc); staticPropertyInitList.ForEach(bNode => initFunc.FunctionBody.Body.Add(bNode)); initFunc.FunctionBody.Body.Add(AstFactory.BuildReturnStatement(new NullNode())); } unPopulatedClasses.Remove(thisClassIndex); }
/// <summary> /// Determines if a class is allowed to be codegened based on certain conditions in the class node /// </summary> /// <param name="classNode"></param> /// <returns></returns> private bool IsClassAllowed(ClassDeclNode classDecl) { // If its an FFI class, it is allowed if (classDecl.IsExternLib) { return true; } // Check the class attributes if (classDecl.Attributes != null) { // If at least one attribute is internal then the class is allowed List<AttributeEntry> attributesList = PopulateAttributes(classDecl.Attributes); if (attributesList.Where(a => a.IsInternalClassAttribute()).Count() > 0) { return true; } } return false; }
public void DFSTraverse(ref AST.AssociativeAST.AssociativeNode node) { if (node is AST.AssociativeAST.IdentifierNode) { EmitIdentifierNode(ref node); } else if (node is ProtoCore.AST.AssociativeAST.IdentifierListNode) { AST.AssociativeAST.IdentifierListNode identList = node as ProtoCore.AST.AssociativeAST.IdentifierListNode; EmitIdentifierListNode(ref identList); } else if (node is ProtoCore.AST.AssociativeAST.IntNode) { AST.AssociativeAST.IntNode intNode = node as ProtoCore.AST.AssociativeAST.IntNode; EmitIntNode(ref intNode); } else if (node is ProtoCore.AST.AssociativeAST.DoubleNode) { AST.AssociativeAST.DoubleNode doubleNode = node as ProtoCore.AST.AssociativeAST.DoubleNode; EmitDoubleNode(ref doubleNode); } else if (node is ProtoCore.AST.AssociativeAST.FunctionCallNode) { AST.AssociativeAST.FunctionCallNode funcCallNode = node as ProtoCore.AST.AssociativeAST.FunctionCallNode; EmitFunctionCallNode(ref funcCallNode); } else if (node is ProtoCore.AST.AssociativeAST.FunctionDotCallNode) { AST.AssociativeAST.FunctionDotCallNode funcDotCall = node as ProtoCore.AST.AssociativeAST.FunctionDotCallNode; EmitFunctionDotCallNode(ref funcDotCall); } else if (node is ProtoCore.AST.AssociativeAST.BinaryExpressionNode) { ProtoCore.AST.AssociativeAST.BinaryExpressionNode binaryExpr = node as ProtoCore.AST.AssociativeAST.BinaryExpressionNode; if (binaryExpr.Optr != DSASM.Operator.assign) { ; } //EmitCode("("); EmitBinaryNode(ref binaryExpr); if (binaryExpr.Optr == DSASM.Operator.assign) { //EmitCode(ProtoCore.DSASM.Constants.termline); } if (binaryExpr.Optr != DSASM.Operator.assign) { ; } //EmitCode(")"); } else if (node is ProtoCore.AST.AssociativeAST.FunctionDefinitionNode) { AST.AssociativeAST.FunctionDefinitionNode funcDefNode = node as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode; EmitFunctionDefNode(ref funcDefNode); } else if (node is ProtoCore.AST.AssociativeAST.ClassDeclNode) { AST.AssociativeAST.ClassDeclNode classDeclNode = node as ProtoCore.AST.AssociativeAST.ClassDeclNode; EmitClassDeclNode(ref classDeclNode); } else if (node is ProtoCore.AST.AssociativeAST.NullNode) { AST.AssociativeAST.NullNode nullNode = node as ProtoCore.AST.AssociativeAST.NullNode; EmitNullNode(ref nullNode); } else if (node is ProtoCore.AST.AssociativeAST.ArrayIndexerNode) { AST.AssociativeAST.ArrayIndexerNode arrIdxNode = node as ProtoCore.AST.AssociativeAST.ArrayIndexerNode; EmitArrayIndexerNode(ref arrIdxNode); } else if (node is ProtoCore.AST.AssociativeAST.ExprListNode) { AST.AssociativeAST.ExprListNode exprListNode = node as ProtoCore.AST.AssociativeAST.ExprListNode; EmitExprListNode(ref exprListNode); } }