Пример #1
0
        public override int Emit(ProtoCore.AST.Node codeBlockNode, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (core.Options.IsDeltaExecution)
            {
                if (context != null && context.symbolTable != null)
                {
                    Validity.Assert(context.symbolTable.symbolList != null && context.symbolTable.symbolList.Count > 0);
                    codeBlock.symbolTable = context.symbolTable;
                }
            }

            AllocateContextGlobals();

            core.watchStartPC = this.pc;
            if (core.Options.RunMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                return EmitExpressionInterpreter(codeBlockNode);
            }

            this.localCodeBlockNode = codeBlockNode;
            ProtoCore.AST.AssociativeAST.CodeBlockNode codeblock = codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode;
            bool isTopBlock = null == codeBlock.parent;
            if (!isTopBlock)
            {
                // If this is an inner block where there can be no classes, we can start at parsing at the global function state
                compilePass = ProtoCore.CompilerDefinitions.Associative.CompilePass.kGlobalFuncSig;
            }

            codeblock.Body = ApplyTransform(codeblock.Body);
            
            bool hasReturnStatement = false;
            ProtoCore.Type inferedType = new ProtoCore.Type();
            bool ssaTransformed = false;
            while (ProtoCore.CompilerDefinitions.Associative.CompilePass.kDone != compilePass)
            {
                // Emit SSA only after generating the class definitions
                if (core.Options.GenerateSSA)
                {
                    if (compilePass > ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassName && !ssaTransformed)
                    {
                        if (!core.IsParsingCodeBlockNode && !core.Options.IsDeltaExecution)
                        {
                            //Audit class table for multiple symbol definition and emit warning.
                            this.core.ClassTable.AuditMultipleDefinition(this.core.BuildStatus, graphNode);
                        }
                        codeblock.Body = BuildSSA(codeblock.Body, context);              
                        ssaTransformed = true;
                        if (core.Options.DumpIL)
                        {
                            CodeGenDS codegenDS = new CodeGenDS(codeblock.Body);
                            EmitCompileLog(codegenDS.GenerateCode());
                        }
                    }
                }

                inferedType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);
                hasReturnStatement = EmitCodeBlock(codeblock.Body, ref inferedType, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier, false);
                if (compilePass == ProtoCore.CompilerDefinitions.Associative.CompilePass.kGlobalScope && !hasReturnStatement)
                {
                    EmitReturnNull(); 
                }

                compilePass++;

                // We have compiled all classes
                if (compilePass == ProtoCore.CompilerDefinitions.Associative.CompilePass.kGlobalScope && isTopBlock)
                {
                    EmitFunctionCallToInitStaticProperty(codeblock.Body);
                }

            }

            ResolveFinalNodeRefs();
            ResolveSSADependencies();
            
            ProtoCore.AssociativeEngine.Utils.BuildGraphNodeDependencies(
                codeBlock.instrStream.dependencyGraph.GetGraphNodesAtScope(Constants.kInvalidIndex, Constants.kGlobalScope));
        
            
            if (codeBlock.parent == null)  // top-most langauge block
            {
                ResolveFunctionGroups();
            }

            core.InferedType = inferedType;

            if (core.AsmOutput != Console.Out)
            {
                core.AsmOutput.Flush();
            }

            this.localCodeBlockNode = codeBlockNode;

            // Reset the callsite guids in preparation for the next compilation
            core.CallsiteGuidMap = new Dictionary<Guid, int>();

            return codeBlock.codeBlockId;
        }
Пример #2
0
        public override int Emit(ProtoCore.AST.Node codeBlockNode, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (compileStateTracker.Options.IsDeltaExecution)
            {
                if (context != null && context.symbolTable != null)
                {
                    Validity.Assert(context.symbolTable.symbolList != null && context.symbolTable.symbolList.Count > 0);
                    codeBlock.symbolTable = context.symbolTable;
                }
            }

            AllocateContextGlobals();

            compileStateTracker.startPC = this.pc;
            if (compileStateTracker.ExecMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                return EmitExpressionInterpreter(codeBlockNode);
            }

            this.localCodeBlockNode = codeBlockNode;
            ProtoCore.AST.AssociativeAST.CodeBlockNode codeblock = codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode;
            bool isTopBlock = null == codeBlock.parent;
            if (!isTopBlock)
            {
                // If this is an inner block where there can be no classes, we can start at parsing at the global function state
                compilePass = ProtoCore.DSASM.AssociativeCompilePass.kGlobalFuncSig;
            }
            codeblock.Body = SplitMulitpleAssignment(codeblock.Body);
            codeblock.Body = BuildSSA(codeblock.Body, context);

            if (compileStateTracker.Options.DumpIL)
            {
                CodeGenDS codegenDS = new CodeGenDS(codeblock.Body);
                EmitCompileLog(codegenDS.GenerateCode());
            }

            bool hasReturnStatement = false;
            ProtoCore.Type inferedType = new ProtoCore.Type();
            while (ProtoCore.DSASM.AssociativeCompilePass.kDone != compilePass)
            {
                foreach (AssociativeNode node in codeblock.Body)
                {
                    inferedType = new ProtoCore.Type();
                    inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                    inferedType.IsIndexable = false;

                    //
                    // TODO Jun:    Handle stand alone language blocks
                    //              Integrate the subPass into a proper pass
                    //
                    //              **Need to take care of EmitImportNode, in which I used the same code to handle imported language block nodes - Randy
                    //
                    if (node is LanguageBlockNode)
                    {
                        // Build a binaryn node with a temporary lhs for every stand-alone language block
                        var iNode = nodeBuilder.BuildIdentfier(compileStateTracker.GenerateTempLangageVar());
                        var langBlockNode = nodeBuilder.BuildBinaryExpression(iNode, node);

                        DfsTraverse(langBlockNode, ref inferedType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);
                    }
                    else
                    {
                        DfsTraverse(node, ref inferedType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);
                        SetDeltaCompilePC(node);
                    }

                    if (NodeUtils.IsReturnExpressionNode(node))
                        hasReturnStatement = true;
                }
                if (compilePass == ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope && !hasReturnStatement)
                {
                    EmitReturnNull();
                }

                compilePass++;

                // We have compiled all classes
                if (compilePass == ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope && isTopBlock)
                {
                    EmitFunctionCallToInitStaticProperty(codeblock.Body);
                }

            }

            ResolveFinalNodeRefs();

            if (codeBlock.parent == null)  // top-most langauge block
            {
                ResolveFunctionGroups();
            }

            compileStateTracker.InferedType = inferedType;

            if (compileStateTracker.AsmOutput != Console.Out)
            {
                compileStateTracker.AsmOutput.Flush();
            }

            this.localCodeBlockNode = codeBlockNode;

            return codeBlock.codeBlockId;
        }
Пример #3
0
        /// <summary>
        /// Resets the VM whenever a new library is imported and re-imports them
        /// Returns the list of new Library Mirrors for reflection
        /// TODO: It should not be needed once we have language support to insert import statements arbitrarily
        /// </summary>
        /// <param name="libraries"></param>
        /// <returns></returns>
        public List<LibraryMirror> ResetVMAndImportLibrary(List<string> libraries)
        {
            List<LibraryMirror> libs = new List<LibraryMirror>();

            // Reset VM
            ReInitializeLiveRunner();

            // generate import node for each library in input list
            List<AssociativeNode> importNodes = null;
            foreach (string lib in libraries)
            {
                importNodes = new List<AssociativeNode>();

                ProtoCore.AST.AssociativeAST.ImportNode importNode = new ProtoCore.AST.AssociativeAST.ImportNode();
                importNode.ModuleName = lib;

                importNodes.Add(importNode);

                ProtoCore.CodeGenDS codeGen = new ProtoCore.CodeGenDS(importNodes);
                string code = codeGen.GenerateCode();

                int currentCI = runnerCore.ClassTable.ClassNodes.Count;

                UpdateCmdLineInterpreter(code);

                int postCI = runnerCore.ClassTable.ClassNodes.Count;

                IList<ProtoCore.DSASM.ClassNode> classNodes = new List<ProtoCore.DSASM.ClassNode>();
                for (int i = currentCI; i < postCI; ++i)
                {
                    classNodes.Add(runnerCore.ClassTable.ClassNodes[i]);
                }

                ProtoCore.Mirror.LibraryMirror libraryMirror = ProtoCore.Mirror.Reflection.Reflect(lib, classNodes, runnerCore);
                libs.Add(libraryMirror);
            }

            return libs;
        }
Пример #4
0
        /// <summary>
        /// This is called temporarily to reset the VM and recompile the entire graph with new import 
        /// statements whenever a node from a new library is added to the graph.
        /// TODO: It should not be needed once we have language support to insert import statements arbitrarily
        /// </summary>
        /// <param name="libraries"></param>
        /// <param name="syncData"></param>
        public void ResetVMAndResyncGraph(IEnumerable<string> libraries)
        {
            // Reset VM
            ReInitializeLiveRunner();

            if (!libraries.Any())
            {
                return;
            }

            // generate import node for each library in input list
            List<AssociativeNode> importNodes = new List<AssociativeNode>();
            foreach (string lib in libraries)
            {
                ProtoCore.AST.AssociativeAST.ImportNode importNode = new ProtoCore.AST.AssociativeAST.ImportNode();
                importNode.ModuleName = lib;

                importNodes.Add(importNode);
            }
            ProtoCore.CodeGenDS codeGen = new ProtoCore.CodeGenDS(importNodes);
            string code = codeGen.GenerateCode();

            UpdateCmdLineInterpreter(code);
        }
Пример #5
0
 /// <summary>
 /// This is to be used for debugging only to check code emitted from delta AST input
 /// </summary>
 /// <param name="deltaAstList"></param>
 /// <returns></returns>
 private string DebugCodeEmittedForDeltaAst(List<AssociativeNode> deltaAstList)
 {
     var codeGen = new ProtoCore.CodeGenDS(deltaAstList);
     var code = codeGen.GenerateCode();
     return code;
 }
Пример #6
0
        public override int Emit(ProtoCore.AST.Node codeBlockNode, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (core.Options.IsDeltaExecution)
            {
                if (context != null && context.symbolTable != null)
                {
                    Validity.Assert(context.symbolTable.symbolList != null && context.symbolTable.symbolList.Count > 0);
                    codeBlock.symbolTable = context.symbolTable;
                }
            }

            AllocateContextGlobals();

            core.startPC = this.pc;
            if (core.ExecMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                return EmitExpressionInterpreter(codeBlockNode);
            }

            this.localCodeBlockNode = codeBlockNode;
            ProtoCore.AST.AssociativeAST.CodeBlockNode codeblock = codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode;
            bool isTopBlock = null == codeBlock.parent;
            if (!isTopBlock)
            {
                // If this is an inner block where there can be no classes, we can start at parsing at the global function state
                compilePass = ProtoCore.DSASM.AssociativeCompilePass.kGlobalFuncSig;
            }

            codeblock.Body = SplitMulitpleAssignment(codeblock.Body);
            
            bool hasReturnStatement = false;
            ProtoCore.Type inferedType = new ProtoCore.Type();
            bool ssaTransformed = false;
            while (ProtoCore.DSASM.AssociativeCompilePass.kDone != compilePass)
            {
                // Emit SSA only after generating the class definitions
                if (core.Options.GenerateSSA)
                {
                    if (compilePass > AssociativeCompilePass.kClassName && !ssaTransformed)
                    {
                        if (!core.IsParsingCodeBlockNode && !core.Options.IsDeltaExecution)
                        {
                            //Audit class table for multiple symbol definition and emit warning.
                            this.core.ClassTable.AuditMultipleDefinition(this.core.BuildStatus, graphNode == null ? default(Guid) : graphNode.guid);
                        }
                        codeblock.Body = BuildSSA(codeblock.Body, context);
                        core.CachedSSANodes.Clear();
                        core.CachedSSANodes.AddRange(codeblock.Body);
                        ssaTransformed = true;
                        if (core.Options.DumpIL)
                        {
                            CodeGenDS codegenDS = new CodeGenDS(codeblock.Body);
                            EmitCompileLog(codegenDS.GenerateCode());
                        }
                    }
                }

                foreach (AssociativeNode node in codeblock.Body)
                {
                    inferedType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0); 

                    //
                    // TODO Jun:    Handle stand alone language blocks
                    //              Integrate the subPass into a proper pass
                    //              
                    //              **Need to take care of EmitImportNode, in which I used the same code to handle imported language block nodes - Randy
                    //
                    if (node is LanguageBlockNode)
                    {
                        // Build a binaryn node with a temporary lhs for every stand-alone language block
                        var iNode = nodeBuilder.BuildIdentfier(core.GenerateTempLangageVar());
                        var langBlockNode = nodeBuilder.BuildBinaryExpression(iNode, node);

                        DfsTraverse(langBlockNode, ref inferedType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);
                    }
                    else
                    {
                        DfsTraverse(node, ref inferedType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);
                        SetDeltaCompilePC(node);
                    }

                    if (NodeUtils.IsReturnExpressionNode(node))
                        hasReturnStatement = true;
                }

                if (compilePass == ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope && !hasReturnStatement)
                {
                    EmitReturnNull();
                }

                compilePass++;

                // We have compiled all classes
                if (compilePass == ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope && isTopBlock)
                {
                    EmitFunctionCallToInitStaticProperty(codeblock.Body);
                }

            }

            ResolveFinalNodeRefs();
            ResolveSSADependencies();

            if (codeBlock.parent == null)  // top-most langauge block
            {
                ResolveFunctionGroups();
            }

            core.InferedType = inferedType;

            if (core.AsmOutput != Console.Out)
            {
                core.AsmOutput.Flush();
            }

            this.localCodeBlockNode = codeBlockNode;

            // Reset the callsite guids in preparation for the next compilation
            core.CallsiteGuidMap = new Dictionary<Guid, int>();

            return codeBlock.codeBlockId;
        }