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); }
private ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode ParsedNamedConstructor(MethodBase method, string constructorName, ProtoCore.Type returnType) { ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = new ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode(); constr.Name = constructorName; constr.Pattern = null; constr.Signature = ParseArgumentSignature(method); constr.ReturnType = returnType; constr.FunctionBody = null; constr.access = ProtoCore.DSASM.AccessSpecifier.kPublic; constr.IsExternLib = true; constr.ExternLibName = Module.Name; return(constr); }
private void EmitClassDeclNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, GraphNode graphNode = null) { ClassDeclNode classDecl = node as ClassDeclNode; // Restrict classes if (!IsClassAllowed(classDecl)) { return; } // Handling n-pass on class declaration if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassName == compilePass) { // Class name pass // Populating the class tables with the class names if (null != codeBlock.parent) { buildStatus.LogSemanticError(Resources.ClassCannotBeDefinedInsideLanguageBlock, core.CurrentDSFileName, classDecl.line, classDecl.col); } ProtoCore.DSASM.ClassNode thisClass = new ProtoCore.DSASM.ClassNode(); thisClass.Name = classDecl.ClassName; thisClass.Size = classDecl.Variables.Count; thisClass.IsImportedClass = classDecl.IsImportedClass; thisClass.TypeSystem = core.TypeSystem; thisClass.ClassAttributes = classDecl.ClassAttributes; if (classDecl.ExternLibName != null) thisClass.ExternLib = classDecl.ExternLibName; else thisClass.ExternLib = Path.GetFileName(core.CurrentDSFileName); globalClassIndex = core.ClassTable.Append(thisClass); if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex) { string message = string.Format("Class redefinition '{0}' (BE1C3285).\n", classDecl.ClassName); buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } unPopulatedClasses.Add(globalClassIndex, classDecl); //Always allow us to convert a class to a bool thisClass.CoerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore); } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassBaseClass == compilePass) { // Base class pass // Populating each class entry with their immediate baseclass globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[globalClassIndex]; // Verify and store the list of classes it inherits from if (null != classDecl.BaseClasses) { for (int n = 0; n < classDecl.BaseClasses.Count; ++n) { int baseClass = core.ClassTable.GetClassId(classDecl.BaseClasses[n]); if (baseClass == globalClassIndex) { string message = string.Format("Class '{0}' cannot derive from itself (DED0A61F).\n", classDecl.ClassName); buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { if (core.ClassTable.ClassNodes[baseClass].IsImportedClass && !thisClass.IsImportedClass) { string message = string.Format("Cannot derive from FFI class {0} (DA87AC4D).\n", core.ClassTable.ClassNodes[baseClass].Name); buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } thisClass.Bases.Add(baseClass); thisClass.CoerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass); } else { string message = string.Format("Unknown base class '{0}' (9E44FFB3).\n", classDecl.BaseClasses[n]); buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } } } } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassHierarchy == compilePass) { // Class hierarchy pass // Populating each class entry with all sub classes in the hierarchy globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[globalClassIndex]; // Verify and store the list of classes it inherits from if (null != classDecl.BaseClasses) { for (int n = 0; n < classDecl.BaseClasses.Count; ++n) { int baseClass = core.ClassTable.GetClassId(classDecl.BaseClasses[n]); // baseClass is already resovled in the previous pass Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != baseClass); // Iterate through all the base classes until the the root class // For every base class, add the coercion score ProtoCore.DSASM.ClassNode tmpCNode = core.ClassTable.ClassNodes[baseClass]; if (tmpCNode.Bases.Count > 0) { baseClass = tmpCNode.Bases[0]; while (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { thisClass.CoerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass); tmpCNode = core.ClassTable.ClassNodes[baseClass]; baseClass = ProtoCore.DSASM.Constants.kInvalidIndex; if (tmpCNode.Bases.Count > 0) { baseClass = tmpCNode.Bases[0]; } } } } } } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemVar == compilePass) { EmitMemberVariables(classDecl, graphNode); } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemFuncSig == compilePass) { // Class member variable pass // Populating each class entry vtables with their respective // member variables signatures globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); List<AssociativeNode> thisPtrOverloadList = new List<AssociativeNode>(); foreach (AssociativeNode funcdecl in classDecl.Procedures) { DfsTraverse(funcdecl, ref inferedType); var funcDef = funcdecl as FunctionDefinitionNode; if (funcDef == null || funcDef.IsStatic || funcDef.Name == ProtoCore.DSDefinitions.Keyword.Dispose) continue; bool isGetterSetter = CoreUtils.IsGetterSetter(funcDef.Name); var thisPtrArgName = Constants.kThisPointerArgName; if (!isGetterSetter) { var classsShortName = classDecl.ClassName.Split('.').Last(); var typeDepName = classsShortName.ToLower(); if (typeDepName != classsShortName && funcDef.Signature.Arguments.All(a => a.NameNode.Name != typeDepName)) thisPtrArgName = typeDepName; } // This is a function, create its parameterized this pointer overload ThisPointerProcOverload thisProc = new ThisPointerProcOverload(); thisProc.classIndex = globalClassIndex; thisProc.procNode = new FunctionDefinitionNode(funcDef); var thisPtrArg = new VarDeclNode() { Access = ProtoCore.CompilerDefinitions.AccessModifier.kPublic, NameNode = AstFactory.BuildIdentifier(thisPtrArgName), ArgumentType = new ProtoCore.Type { Name = classDecl.ClassName, UID = globalClassIndex, rank = 0 } }; thisProc.procNode.Signature.Arguments.Insert(0, thisPtrArg); thisProc.procNode.IsAutoGeneratedThisProc = true; if (CoreUtils.IsGetterSetter(funcDef.Name)) { InsertThisPointerAtBody(thisProc); } else { // Generate a static function for member function f(): // satic def f(a: A) // { // return = a.f() // } thisProc.procNode.IsStatic = true; BuildThisFunctionBody(thisProc); } thisPtrOverloadList.Add(thisProc.procNode); } foreach (var overloadFunc in thisPtrOverloadList) { // Emit the newly defined overloads DfsTraverse(overloadFunc, ref inferedType); } classDecl.Procedures.AddRange(thisPtrOverloadList); if (!classDecl.IsExternLib) { ProtoCore.DSASM.ProcedureTable vtable = core.ClassTable.ClassNodes[globalClassIndex].ProcTable; if (vtable.GetFunctionBySignature(classDecl.ClassName, new List<ProtoCore.Type>()) == null) { ConstructorDefinitionNode defaultConstructor = new ConstructorDefinitionNode(); defaultConstructor.Name = classDecl.ClassName; defaultConstructor.LocalVariableCount = 0; defaultConstructor.Signature = new ArgumentSignatureNode(); defaultConstructor.ReturnType = new ProtoCore.Type { Name = "var", UID = 0 }; defaultConstructor.FunctionBody = new CodeBlockNode(); defaultConstructor.BaseConstructor = null; defaultConstructor.Access = ProtoCore.CompilerDefinitions.AccessModifier.kPublic; defaultConstructor.IsExternLib = false; defaultConstructor.ExternLibName = null; DfsTraverse(defaultConstructor, ref inferedType); classDecl.Procedures.Add(defaultConstructor); } } } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kGlobalScope == compilePass) { // before populate the attributes, we must know the attribute class constructor signatures // in order to check the parameter // populate the attributes for the class and class member variable globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) { ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[globalClassIndex]; // class if (classDecl.Attributes != null) { thisClass.Attributes = PopulateAttributes(classDecl.Attributes); } // member variable int ix = -1; int currentClassScope = -1; foreach (ProtoCore.DSASM.SymbolNode sn in thisClass.Symbols.symbolList.Values) { // only populate the attributes for member variabls if (sn.functionIndex != ProtoCore.DSASM.Constants.kInvalidIndex) continue; if (sn.classScope != globalClassIndex) { if (currentClassScope != sn.classScope) { currentClassScope = sn.classScope; ix = 0; } // copy attribute information from base class sn.Attributes = core.ClassTable.ClassNodes[currentClassScope].Symbols.symbolList[ix++].Attributes; } else { if (currentClassScope != globalClassIndex) { currentClassScope = globalClassIndex; ix = 0; } } } } } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemFuncBody == compilePass) { // Class member variable pass // Populating the function body of each member function defined in the class vtables globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); // Initialize the global function table for this class // 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables int classIndexAtCallsite = globalClassIndex + 1; core.FunctionTable.InitGlobalFunctionEntry(classIndexAtCallsite); foreach (AssociativeNode funcdecl in classDecl.Procedures) { // reset the inferedtype between functions inferedType = new ProtoCore.Type(); DfsTraverse(funcdecl, ref inferedType, false, null, subPass); } } // Reset the class index core.ClassIndex = globalClassIndex = ProtoCore.DSASM.Constants.kGlobalScope; }
private void EmitClassDeclNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { ClassDeclNode classDecl = node as ClassDeclNode; // Handling n-pass on class declaration if (ProtoCore.DSASM.AssociativeCompilePass.kClassName == compilePass) { // Class name pass // Populating the class tables with the class names if (null != codeBlock.parent) { buildStatus.LogSemanticError("A class cannot be defined inside a language block.\n", compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); } if (ProtoCore.DSASM.Constants.kInvalidIndex != compileStateTracker.ClassTable.IndexOf(classDecl.className)) { string message = string.Format("Class redefinition '{0}' (BE1C3285).\n", classDecl.className); buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } ProtoCore.DSASM.ClassNode thisClass = new ProtoCore.DSASM.ClassNode(); thisClass.name = classDecl.className; thisClass.size = classDecl.varlist.Count; thisClass.IsImportedClass = classDecl.IsImportedClass; thisClass.typeSystem = compileStateTracker.TypeSystem; if (classDecl.ExternLibName != null) thisClass.ExternLib = classDecl.ExternLibName; else thisClass.ExternLib = Path.GetFileName(compileStateTracker.CurrentDSFileName); globalClassIndex = compileStateTracker.ClassTable.Append(thisClass); unPopulatedClasses.Add(globalClassIndex, classDecl); //Always allow us to convert a class to a bool thisClass.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore); } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassHeirarchy == compilePass) { // Class heirarchy pass // Populating each class entry with their respective base classes globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className); ProtoCore.DSASM.ClassNode thisClass = compileStateTracker.ClassTable.ClassNodes[globalClassIndex]; // Verify and store the list of classes it inherits from if (null != classDecl.superClass) { for (int n = 0; n < classDecl.superClass.Count; ++n) { int baseClass = compileStateTracker.ClassTable.IndexOf(classDecl.superClass[n]); if (baseClass == globalClassIndex) { string message = string.Format("Class '{0}' cannot derive from itself (DED0A61F).\n", classDecl.className); buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { if (compileStateTracker.ClassTable.ClassNodes[baseClass].IsImportedClass && !thisClass.IsImportedClass) { string message = string.Format("Cannot derive from FFI class {0} (DA87AC4D).\n", compileStateTracker.ClassTable.ClassNodes[baseClass].name); buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } thisClass.baseList.Add(baseClass); thisClass.coerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass); // Iterate through all the base classes until the the root class // For every base class, add the coercion score // TODO Jun: -Integrate this with multiple inheritace when supported // -Cleansify ProtoCore.DSASM.ClassNode tmpCNode = compileStateTracker.ClassTable.ClassNodes[baseClass]; if (tmpCNode.baseList.Count > 0) { baseClass = tmpCNode.baseList[0]; while (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { thisClass.coerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass); tmpCNode = compileStateTracker.ClassTable.ClassNodes[baseClass]; baseClass = ProtoCore.DSASM.Constants.kInvalidIndex; if (tmpCNode.baseList.Count > 0) { baseClass = tmpCNode.baseList[0]; } } } } else { string message = string.Format("Unknown base class '{0}' (9E44FFB3).\n", classDecl.superClass[n]); buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } } } } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemVar == compilePass) { EmitMemberVariables(classDecl); } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncSig == compilePass) { // Class member variable pass // Populating each class entry vtables with their respective member variables signatures globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className); List<AssociativeNode> thisPtrOverloadList = new List<AssociativeNode>(); foreach (AssociativeNode funcdecl in classDecl.funclist) { DfsTraverse(funcdecl, ref inferedType); // If this is a function, create its parameterized this pointer overload if (funcdecl is ProtoCore.AST.AssociativeAST.FunctionDefinitionNode) { string procName = (funcdecl as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode).Name; bool isFunctionExcluded = procName.Equals(ProtoCore.DSASM.Constants.kStaticPropertiesInitializer); // TODO Jun: There is a current limitation of not supporting classes yet at live execution // Fix this soon - the first fix would be in import load and unload for every delta run //if (!core.Options.IsDeltaExecution) if (!compileStateTracker.Options.IsDeltaExecution) { if (!isFunctionExcluded) { ThisPointerProcOverload thisProc = new ThisPointerProcOverload(); thisProc.classIndex = globalClassIndex; thisProc.procNode = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode(funcdecl as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode); thisProc.procNode.IsAutoGeneratedThisProc = true; InsertThisPointerArg(thisProc); //InsertThisPointerAtBody(thisProc); if (ProtoCore.Utils.CoreUtils.IsGetterSetter(procName)) { InsertThisPointerAtBody(thisProc); } else { // This is a normal function // the body thsould be the actaul function called through the this pointer argument // // def f() { return = 1 } // def f(%this : A) { return = %this.f()} // BuildThisFunctionBody(thisProc); } // Emit the newly defined overloads DfsTraverse(thisProc.procNode, ref inferedType); thisPtrOverloadList.Add(thisProc.procNode); } } } } classDecl.funclist.AddRange(thisPtrOverloadList); if (!classDecl.IsExternLib) { ProtoCore.DSASM.ProcedureTable vtable = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable; if (vtable.IndexOfExact(classDecl.className, new List<ProtoCore.Type>()) == ProtoCore.DSASM.Constants.kInvalidIndex) { ConstructorDefinitionNode defaultConstructor = new ConstructorDefinitionNode(); defaultConstructor.Name = classDecl.className; defaultConstructor.localVars = 0; defaultConstructor.Signature = new ArgumentSignatureNode(); defaultConstructor.Pattern = null; defaultConstructor.ReturnType = new ProtoCore.Type { Name = "var", UID = 0 }; defaultConstructor.FunctionBody = new CodeBlockNode(); defaultConstructor.baseConstr = null; defaultConstructor.access = ProtoCore.DSASM.AccessSpecifier.kPublic; defaultConstructor.IsExternLib = false; defaultConstructor.ExternLibName = null; DfsTraverse(defaultConstructor, ref inferedType); classDecl.funclist.Add(defaultConstructor); } } } else if (ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope == compilePass) { // before populate the attributes, we must know the attribute class constructor signatures // in order to check the parameter // populate the attributes for the class and class member variable globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className); if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) { ProtoCore.DSASM.ClassNode thisClass = compileStateTracker.ClassTable.ClassNodes[globalClassIndex]; // class if (classDecl.Attributes != null) { thisClass.Attributes = PopulateAttributes(classDecl.Attributes); } // member variable int ix = -1; int currentClassScope = -1; foreach (ProtoCore.DSASM.SymbolNode sn in thisClass.symbols.symbolList.Values) { // only populate the attributes for member variabls if (sn.functionIndex != ProtoCore.DSASM.Constants.kInvalidIndex) continue; if (sn.classScope != globalClassIndex) { if (currentClassScope != sn.classScope) { currentClassScope = sn.classScope; ix = 0; } // copy attribute information from base class sn.Attributes = compileStateTracker.ClassTable.ClassNodes[currentClassScope].symbols.symbolList[ix++].Attributes; } else { if (currentClassScope != globalClassIndex) { currentClassScope = globalClassIndex; ix = 0; } ProtoCore.AST.AssociativeAST.VarDeclNode varnode = classDecl.varlist[ix++] as ProtoCore.AST.AssociativeAST.VarDeclNode; sn.Attributes = PopulateAttributes((varnode).Attributes); } } } } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncBody == compilePass) { // Class member variable pass // Populating the function body of each member function defined in the class vtables globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className); foreach (AssociativeNode funcdecl in classDecl.funclist) { // reset the inferedtype between functions inferedType = new ProtoCore.Type(); DfsTraverse(funcdecl, ref inferedType, false, null, subPass); } } // Reset the class index compileStateTracker.ClassIndex = globalClassIndex = ProtoCore.DSASM.Constants.kGlobalScope; }
private ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode ParsedNamedConstructor(MethodBase method, string constructorName, ProtoCore.Type returnType) { ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = new ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode(); constr.Name = constructorName; constr.Pattern = null; constr.Signature = ParseArgumentSignature(method); constr.ReturnType = returnType; constr.FunctionBody = null; constr.access = ProtoCore.Compiler.AccessSpecifier.kPublic; constr.IsExternLib = true; constr.ExternLibName = Module.Name; return constr; }
private void EmitClassDeclNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { ClassDeclNode classDecl = node as ClassDeclNode; // Handling n-pass on class declaration if (ProtoCore.DSASM.AssociativeCompilePass.kClassName == compilePass) { ProtoCore.DSASM.ClassNode cnode = new ProtoCore.DSASM.ClassNode(); cnode.name = classDecl.className; cnode.size = classDecl.varlist.Count; cnode.IsImportedClass = classDecl.IsImportedClass; cnode.typeSystem = core.TypeSystem; globalClassIndex = core.ClassTable.Append(cnode); CodeRangeTable.AddClassBlockRangeEntry(globalClassIndex, classDecl.line, classDecl.col, classDecl.endLine, classDecl.endCol, core.CurrentDSFileName); } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassHeirarchy == compilePass) { // Class heirarchy pass // Populating each class entry with their respective base classes globalClassIndex = core.ClassTable.IndexOf(classDecl.className); ProtoCore.DSASM.ClassNode cnode = core.ClassTable.ClassNodes[globalClassIndex]; if (null != classDecl.superClass) { for (int n = 0; n < classDecl.superClass.Count; ++n) { int baseClass = core.ClassTable.IndexOf(classDecl.superClass[n]); if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { cnode.baseList.Add(baseClass); cnode.coerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass); } } } } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemVar == compilePass) { // Class member variable pass // Populating each class entry symbols with their respective member variables globalClassIndex = core.ClassTable.IndexOf(classDecl.className); ProtoCore.DSASM.ClassNode cnode = core.ClassTable.ClassNodes[globalClassIndex]; // Handle member vars from base class if (null != classDecl.superClass) { for (int n = 0; n < classDecl.superClass.Count; ++n) { int baseClass = core.ClassTable.IndexOf(classDecl.superClass[n]); if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { // Append the members variables of every class that this class inherits from foreach (ProtoCore.DSASM.SymbolNode symnode in core.ClassTable.ClassNodes[baseClass].symbols.symbolList.Values) { // It is a member variables if (ProtoCore.DSASM.Constants.kGlobalScope == symnode.functionIndex) { Debug.Assert(!symnode.isArgument); int symbolIndex = AllocateMemberVariable(globalClassIndex, symnode.isStatic ? symnode.classScope : baseClass, symnode.name, symnode.datatype, symnode.access, symnode.isStatic); if (symbolIndex != ProtoCore.DSASM.Constants.kInvalidIndex) cnode.size += ProtoCore.DSASM.Constants.kPointerSize; } } } else { Debug.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.varlist) { IdentifierNode varIdent = null; if (vardecl.NameNode is IdentifierNode) { varIdent = vardecl.NameNode as IdentifierNode; } else if (vardecl.NameNode is BinaryExpressionNode) { BinaryExpressionNode bNode = vardecl.NameNode as BinaryExpressionNode; varIdent = bNode.LeftNode as IdentifierNode; if (vardecl.IsStatic) staticPropertyInitList.Add(bNode); else cnode.defaultArgExprList.Add(bNode); } else { Debug.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 ProtoCore.Type datatype = vardecl.ArgumentType; if (string.IsNullOrEmpty(vardecl.ArgumentType.Name)) datatype.UID = (int)PrimitiveType.kTypeVar; else { datatype.UID = core.TypeSystem.GetType(vardecl.ArgumentType.Name); if (datatype.UID == ProtoCore.DSASM.Constants.kInvalidIndex) datatype.UID = (int)PrimitiveType.kTypeVar; } datatype.Name = core.TypeSystem.GetType(datatype.UID); int symbolIndex = ProtoCore.DSASM.Constants.kInvalidIndex; if (varIdent is ProtoCore.AST.AssociativeAST.TypedIdentifierNode) symbolIndex = AllocateTypedMemberVariable(globalClassIndex, globalClassIndex, varIdent.Value, datatype, vardecl.access, vardecl.IsStatic); else symbolIndex = AllocateMemberVariable(globalClassIndex, globalClassIndex, varIdent.Value, datatype, vardecl.access, vardecl.IsStatic); if (symbolIndex != ProtoCore.DSASM.Constants.kInvalidIndex && !classDecl.IsExternLib) { ProtoCore.DSASM.SymbolNode memVar = vardecl.IsStatic ? core.CodeBlockList[0].symbolTable.symbolList[symbolIndex] : core.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[symbolIndex]; EmitGetterForMemVar(classDecl, memVar); EmitSetterForMemVar(classDecl, memVar); } } 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) { FunctionDefinitionNode initFunc = new FunctionDefinitionNode() { Name = ProtoCore.DSASM.Constants.kStaticPropertiesInitializer, Singnature = 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.DSASM.AccessSpecifier.kPublic, IsStatic = true }; classDecl.funclist.Add(initFunc); staticPropertyInitList.ForEach(bNode => initFunc.FunctionBody.Body.Add(bNode)); initFunc.FunctionBody.Body.Add(new BinaryExpressionNode() { LeftNode = new IdentifierNode() { Value = ProtoCore.DSDefinitions.Kw.kw_return, Name = ProtoCore.DSDefinitions.Kw.kw_return, datatype = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeReturn, false) }, Optr = ProtoCore.DSASM.Operator.assign, RightNode = new NullNode() }); } } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncSig == compilePass) { // Class member variable pass // Populating each class entry vtables with their respective member variables signatures globalClassIndex = core.ClassTable.IndexOf(classDecl.className); foreach (AssociativeNode funcdecl in classDecl.funclist) { DfsTraverse(funcdecl, ref inferedType); } if (!classDecl.IsExternLib) { ProtoCore.DSASM.ProcedureTable vtable = core.ClassTable.ClassNodes[globalClassIndex].vtable; if (vtable.IndexOfExact(classDecl.className, new List<ProtoCore.Type>()) == ProtoCore.DSASM.Constants.kInvalidIndex) { ConstructorDefinitionNode defaultConstructor = new ConstructorDefinitionNode(); defaultConstructor.Name = classDecl.className; defaultConstructor.localVars = 0; defaultConstructor.Signature = new ArgumentSignatureNode(); defaultConstructor.Pattern = null; defaultConstructor.ReturnType = new ProtoCore.Type { Name = "var", UID = 0 }; defaultConstructor.FunctionBody = new CodeBlockNode(); defaultConstructor.baseConstr = null; defaultConstructor.access = ProtoCore.DSASM.AccessSpecifier.kPublic; defaultConstructor.IsExternLib = false; defaultConstructor.ExternLibName = null; DfsTraverse(defaultConstructor, ref inferedType); classDecl.funclist.Add(defaultConstructor); } } } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncBody == compilePass) { // Class member variable pass // Populating the function body of each member function defined in the class vtables globalClassIndex = core.ClassTable.IndexOf(classDecl.className); foreach (AssociativeNode funcdecl in classDecl.funclist) { // reset the inferedtype between functions inferedType = new ProtoCore.Type(); DfsTraverse(funcdecl, ref inferedType, false, null, subPass); } } // Reset the class index core.ClassIndex = globalClassIndex = ProtoCore.DSASM.Constants.kGlobalScope; }
void Associative_constructordecl(out ProtoCore.AST.AssociativeAST.AssociativeNode constrNode, ProtoCore.CompilerDefinitions.AccessModifier access, List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = null) { ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = new ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode(); ; string methodName; ProtoCore.AST.AssociativeAST.AssociativeNode argumentSignature; ProtoCore.AST.AssociativeAST.AssociativeNode pattern; Expect(26); NodeUtils.SetNodeStartLocation(constr, t); Associative_CtorSignature(out methodName, out argumentSignature); var returnType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, Constants.kArbitraryRank); constr.Name = methodName; constr.ReturnType = returnType; constr.Signature = argumentSignature as ProtoCore.AST.AssociativeAST.ArgumentSignatureNode; constr.Access = access; constr.Attributes = attrs; ProtoCore.AST.AssociativeAST.AssociativeNode functionBody = null; if (la.kind == 47) { Get(); ProtoCore.AST.AssociativeAST.AssociativeNode bnode; Associative_BaseConstructorCall(out bnode); constr.BaseConstructor = bnode as ProtoCore.AST.AssociativeAST.FunctionCallNode; } Associative_FunctionalMethodBodyMultiLine(out functionBody); constr.FunctionBody = functionBody as ProtoCore.AST.AssociativeAST.CodeBlockNode; NodeUtils.SetNodeEndLocation(constr, functionBody); constrNode = constr; }
private void SplitConstructorDefinitionNode(ConstructorDefinitionNode node) { if (!node.IsExternLib) { node.FunctionBody.Body = SplitMulitpleAssignment(node.FunctionBody.Body); } }
void Associative_constructordecl(out ProtoCore.AST.AssociativeAST.AssociativeNode constrNode, ProtoCore.DSASM.AccessSpecifier access, List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = null) { ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode constr = new ProtoCore.AST.AssociativeAST.ConstructorDefinitionNode(); ; string methodName; ProtoCore.AST.AssociativeAST.AssociativeNode argumentSignature; ProtoCore.AST.AssociativeAST.AssociativeNode pattern; Expect(24); NodeUtils.SetNodeStartLocation(constr, t); Associative_CtorSignature(out methodName, out argumentSignature); var returnType = new ProtoCore.Type(); returnType.Name = "var"; returnType.UID = 0; returnType.rank = DSASM.Constants.kArbitraryRank; returnType.IsIndexable = true; constr.Name = methodName; constr.Pattern = null; constr.ReturnType = returnType; constr.Signature = argumentSignature as ProtoCore.AST.AssociativeAST.ArgumentSignatureNode; constr.access = access; constr.Attributes = attrs; ProtoCore.AST.AssociativeAST.AssociativeNode functionBody = null; if (la.kind == 48) { Get(); ProtoCore.AST.AssociativeAST.AssociativeNode bnode; Associative_BaseConstructorCall(out bnode); constr.baseConstr = bnode as ProtoCore.AST.AssociativeAST.FunctionCallNode; } Associative_FunctionalMethodBodyMultiLine(out functionBody); constr.FunctionBody = functionBody as ProtoCore.AST.AssociativeAST.CodeBlockNode; NodeUtils.SetNodeEndLocation(constr, functionBody); constrNode = constr; }