Example #1
0
        public CoreCodeGen(Core coreObj, ProtoCore.DSASM.CodeBlock parentBlock = null)
        {
            Debug.Assert(coreObj != null);
            this.core        = coreObj;
            argOffset        = 0;
            globalClassIndex = core.ClassIndex;

            if (null == CoreCodeGen.CodeRangeTable)
            {
                CoreCodeGen.CodeRangeTable = new CodeRangeTable();
            }
            if (null == CoreCodeGen.IdentLocation)
            {
                CoreCodeGen.IdentLocation = new IdentLocationTable();
            }
            if (null == CoreCodeGen.ImportTable)
            {
                CoreCodeGen.ImportTable = new ImportTable();
            }

            context  = new ProtoCore.CompileTime.Context();
            opKwData = new ProtoCore.DSASM.OpKeywordData();

            targetLangBlock = ProtoCore.DSASM.Constants.kInvalidIndex;

            enforceTypeCheck = true;

            localProcedure  = core.ProcNode;
            globalProcIndex = null != localProcedure ? localProcedure.procId : ProtoCore.DSASM.Constants.kGlobalScope;

            tryLevel = 0;
        }
Example #2
0
        public ImperativeCodeGen(ProtoLanguage.CompileStateTracker compileState, ProtoCore.DSASM.CodeBlock parentBlock = null)
            : base(compileState, parentBlock)
        {
            //  dumpbytecode is optionally enabled
            //
            astNodes = new List<ImperativeNode>();

            SetCompileOptions();

            // Create a new symboltable for this block
            // Set the new symbol table's parent
            // Set the new table as a child of the parent table

            codeBlock = new ProtoCore.DSASM.CodeBlock(
                ProtoCore.DSASM.CodeBlockType.kLanguage,
                ProtoCore.Language.kImperative,
                compileState.CodeBlockIndex,
                new ProtoCore.DSASM.SymbolTable("imperative lang block", compileState.RuntimeTableIndex),
                new ProtoCore.DSASM.ProcedureTable(compileState.RuntimeTableIndex));

            ++compileState.CodeBlockIndex;
            ++compileState.RuntimeTableIndex;

            compileState.CodeBlockList.Add(codeBlock);
            if (null != parentBlock)
            {
                // This is a nested block
                parentBlock.children.Add(codeBlock);
                codeBlock.parent = parentBlock;
            }

            blockScope = 0;
        }
Example #3
0
        /// <summary>
        /// search global methos by name
        /// </summary>
        /// <param name="si"></param>
        /// <param name="function"></param>
        /// <returns>the key value pair is to keep consistent with the return data type from GetMemberFunctions, GetConstructors</returns>
        private static List <KeyValuePair <int, ProtoCore.DSASM.ProcedureNode> > GetGlobalMethod(ScopeInfo si, string function)
        {
            // in global scope, just search the global functions
            List <KeyValuePair <int, ProtoCore.DSASM.ProcedureNode> > functionList = new List <KeyValuePair <int, ProtoCore.DSASM.ProcedureNode> >();

            if (si.BlockId == ProtoCore.DSASM.Constants.kInvalidIndex)
            {
                return(functionList);
            }

            ProtoCore.DSASM.CodeBlock cb = compileState.CodeBlockList[si.BlockId];
            while (cb != null)
            {
                if (null == cb.procedureTable)
                {
                    cb = cb.parent;
                    continue;
                }

                // search by name
                IEnumerable <ProtoCore.DSASM.ProcedureNode> pns = cb.procedureTable.procList.Where(x => x.name == function);
                if (null == pns || (pns.Count() == 0))
                {
                    cb = cb.parent; // search its parent
                    continue;
                }
                foreach (ProtoCore.DSASM.ProcedureNode pn in pns)
                {
                    functionList.Add(new KeyValuePair <int, ProtoCore.DSASM.ProcedureNode>(ProtoCore.DSASM.Constants.kInvalidIndex, pn));
                }
                break;
            }

            return(functionList);
        }
Example #4
0
        public override bool Compile(out int blockId, ProtoCore.DSASM.CodeBlock parentBlock, ProtoCore.LanguageCodeBlock langBlock, ProtoCore.CompileTime.Context callContext, ProtoCore.DebugServices.EventSink sink, ProtoCore.AST.Node codeBlockNode, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            Debug.Assert(langBlock != null);
            blockId = ProtoCore.DSASM.Constants.kInvalidIndex;

            bool buildSucceeded      = false;
            bool isLanguageSignValid = isLanguageSignValid = core.Langverify.Verify(langBlock);

            if (isLanguageSignValid)
            {
                try
                {
                    ProtoImperative.CodeGen codegen = new ProtoImperative.CodeGen(core, parentBlock);

                    //(Fuqiang, Ayush) : The below code is to parse an Imperative code block. An imoerative code block should
                    // never need to be parsed at this stage, as it would be parsed by the Assoc parser.

                    //System.IO.MemoryStream memstream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(langBlock.body));
                    //ProtoCore.DesignScriptParser.Scanner s = new ProtoCore.DesignScriptParser.Scanner(memstream);
                    //ProtoCore.DesignScriptParser.Parser p = new ProtoCore.DesignScriptParser.Parser(s, core);
                    //System.IO.StringWriter parseErrors = new System.IO.StringWriter();
                    //p.errors.errorStream = parseErrors;
                    //p.Parse();
                    //if (parseErrors.ToString() != String.Empty)
                    //{
                    //    core.BuildStatus.LogSyntaxError(parseErrors.ToString());
                    //}
                    //core.BuildStatus.errorCount += p.errors.count;

                    codegen.context             = callContext;
                    codegen.codeBlock.EventSink = sink;
                    blockId = codegen.Emit(codeBlockNode as ProtoCore.AST.ImperativeAST.CodeBlockNode, graphNode);
                }
                catch (ProtoCore.BuildHaltException e)
                {
#if DEBUG
                    //core.BuildStatus.LogSemanticError(e.errorMsg);
#endif
                }

                int errors   = 0;
                int warnings = 0;
                buildSucceeded = core.BuildStatus.GetBuildResult(out errors, out warnings);
            }
            return(buildSucceeded);
        }
Example #5
0
        public override bool Compile(out int blockId, ProtoCore.DSASM.CodeBlock parentBlock, ProtoCore.LanguageCodeBlock langBlock, ProtoCore.CompileTime.Context callContext, ProtoCore.DebugServices.EventSink sink, ProtoCore.AST.Node codeBlockNode, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            Validity.Assert(langBlock != null);
            blockId = ProtoCore.DSASM.Constants.kInvalidIndex;

            bool buildSucceeded = false;

            try
            {
                ProtoImperative.CodeGen codegen = new ProtoImperative.CodeGen(core, callContext, parentBlock);

                codegen.context             = callContext;
                codegen.codeBlock.EventSink = sink;
                blockId = codegen.Emit(codeBlockNode as ProtoCore.AST.ImperativeAST.CodeBlockNode, graphNode);
            }
            catch (ProtoCore.BuildHaltException)
            {
            }

            buildSucceeded = core.BuildStatus.BuildSucceeded;
            return(buildSucceeded);
        }
        public AssociativeCodeGen(Core coreObj, ProtoCore.DSASM.CodeBlock parentBlock = null)
            : base(coreObj, parentBlock)
        {
            classOffset = 0;

            //  either of these should set the console to flood
            //
            ignoreRankCheck = false;

            astNodes = new List<AssociativeNode>();
            setConstructorStartPC = false;

            // Create a new symboltable for this block
            // Set the new symbol table's parent
            // Set the new table as a child of the parent table

            codeBlock = new ProtoCore.DSASM.CodeBlock(
                ProtoCore.DSASM.CodeBlockType.kLanguage,
                ProtoCore.Language.kAssociative,
                core.CodeBlockIndex,
                new ProtoCore.DSASM.SymbolTable("associative lang block", core.RuntimeTableIndex),
                new ProtoCore.DSASM.ProcedureTable(core.RuntimeTableIndex),
                false,
                core);

            ++core.CodeBlockIndex;
            ++core.RuntimeTableIndex;

            core.CodeBlockList.Add(codeBlock);
            if (null != parentBlock)
            {
                // This is a nested block
                parentBlock.children.Add(codeBlock);
                codeBlock.parent = parentBlock;
            }

            compilePass = ProtoCore.DSASM.AssociativeCompilePass.kClassName;
        }
Example #7
0
        private void EmitWhileStmtNode(ImperativeNode node, ref ProtoCore.Type inferedType)
        {
            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                WhileStmtNode whileNode = node as WhileStmtNode;
                DfsTraverse(whileNode.Expr, ref inferedType);

                /*
                {
                    S		->	traverse S
                                bptable.append(pc)
                                emit(jmp, entry)
                }
                            ->  backpatch(bp, pc)
                */
                if (null != whileNode.Body)
                {
                    // Create a new symboltable for this block
                    // Set the current table as the parent of the new table
                    // Set the new table as a new child of the current table
                    // Set the new table as the current table
                    // Create a new codeblock for this block
                    // Set the current codeblock as the parent of the new codeblock
                    // Set the new codeblock as a new child of the current codeblock
                    // Set the new codeblock as the current codeblock
                    ProtoCore.DSASM.CodeBlock localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                        ProtoCore.DSASM.CodeBlockType.kConstruct,
                        Language.kInvalid,
                        compileState.CodeBlockIndex++,
                        new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("while"), compileState.RuntimeTableIndex++),
                        null,
                        true);

                    localCodeBlock.instrStream = codeBlock.instrStream;
                    localCodeBlock.parent = codeBlock;
                    codeBlock.children.Add(localCodeBlock);
                    codeBlock = localCodeBlock;
                    compileState.CodeBlockList.Add(codeBlock);
                    CodeRangeTable.AddCodeBlockRangeEntry(codeBlock.codeBlockId,
                        whileNode.line,
                        whileNode.col,
                        whileNode.endLine,
                        whileNode.endCol,
                        compileState.CurrentDSFileName);

                    foreach (ImperativeNode bodyNode in whileNode.Body)
                    {
                        inferedType = new ProtoCore.Type();
                        inferedType.UID = (int)PrimitiveType.kTypeVar;
                        DfsTraverse(bodyNode, ref inferedType);
                    }

                    // Restore - Set the local codeblock parent to be the current codeblock
                    codeBlock = localCodeBlock.parent;

                }
            }
        }
Example #8
0
        private void EmitIfStmtNode(ImperativeNode node, ref ProtoCore.Type inferedType)
        {
            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                /*
                                def backpatch(bp, pc)
                                    instr = instrstream[bp]
                                    if instr.opcode is jmp
                                        instr.op1 = pc
                                    elseif instr.opcode is cjmp
                                        instr.op2 = pc
                                    end
                                end

                                def backpatch(table, pc)
                                    foreach node in table
                                        backpatch(node.pc, pc)
                                    end
                                end

                */
                /*
                 if(E)		->	traverse E
                                bpTable = new instance
                                L1 = pc + 1
                                L2 = null
                                bp = pc
                                emit(jmp, _cx, L1, L2)
                {
                    S		->	traverse S
                                L1 = null
                                bpTable.append(pc)
                                emit(jmp,labelEnd)
                                backpatch(bp,pc)
                }
                 * */
                // If-expr
                IfStmtNode ifnode = node as IfStmtNode;
                DfsTraverse(ifnode.IfExprNode, ref inferedType);

                // Create a new codeblock for this block
                // Set the current codeblock as the parent of the new codeblock
                // Set the new codeblock as a new child of the current codeblock
                // Set the new codeblock as the current codeblock
                ProtoCore.DSASM.CodeBlock localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                    ProtoCore.DSASM.CodeBlockType.kConstruct,
                    Language.kInvalid,
                    compileState.CodeBlockIndex++,
                    new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("if"), compileState.RuntimeTableIndex++),
                    null);

                localCodeBlock.instrStream = codeBlock.instrStream;
                localCodeBlock.parent = codeBlock;
                codeBlock.children.Add(localCodeBlock);
                codeBlock = localCodeBlock;
                compileState.CodeBlockList.Add(codeBlock);
                CodeRangeTable.AddCodeBlockRangeEntry(codeBlock.codeBlockId,
                    ifnode.IfBodyPosition.line,
                    ifnode.IfBodyPosition.col,
                    ifnode.IfBodyPosition.endLine,
                    ifnode.IfBodyPosition.endCol,
                    compileState.CurrentDSFileName);

                // If-body
                foreach (ImperativeNode ifBody in ifnode.IfBody)
                {
                    inferedType = new ProtoCore.Type();
                    inferedType.UID = (int)PrimitiveType.kTypeVar;
                    DfsTraverse(ifBody, ref inferedType);
                }

                // Restore - Set the local codeblock parent to be the current codeblock
                codeBlock = localCodeBlock.parent;

                /*
                else if(E)	->	traverse E
                                L1 = pc + 1
                                L2 = null
                                bp = pc
                                emit(jmp, _cx, L1, L2)
                {
                    S		->	traverse S
                                L1 = null
                                bpTable.append(pc)
                                emit(jmp,labelEnd)
                                backpatch(bp,pc)
                }
                 * */

                // Elseif-expr
                foreach (ElseIfBlock elseifNode in ifnode.ElseIfList)
                {
                    DfsTraverse(elseifNode.Expr, ref inferedType);

                    // Elseif-body
                    if (null != elseifNode.Body)
                    {
                        // Create a new codeblock for this block
                        // Set the current codeblock as the parent of the new codeblock
                        // Set the new codeblock as a new child of the current codeblock
                        // Set the new codeblock as the current codeblock
                        localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                            ProtoCore.DSASM.CodeBlockType.kConstruct,
                            Language.kInvalid,
                            compileState.CodeBlockIndex++,
                            new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("elseif"), compileState.RuntimeTableIndex++),
                            null);

                        localCodeBlock.instrStream = codeBlock.instrStream;
                        localCodeBlock.parent = codeBlock;
                        codeBlock.children.Add(localCodeBlock);
                        codeBlock = localCodeBlock;
                        compileState.CodeBlockList.Add(codeBlock);
                        CodeRangeTable.AddCodeBlockRangeEntry(codeBlock.codeBlockId,
                            elseifNode.ElseIfBodyPosition.line,
                            elseifNode.ElseIfBodyPosition.col,
                            elseifNode.ElseIfBodyPosition.endLine,
                            elseifNode.ElseIfBodyPosition.endCol,
                            compileState.CurrentDSFileName);

                        foreach (ImperativeNode elseifBody in elseifNode.Body)
                        {
                            inferedType = new ProtoCore.Type();
                            inferedType.UID = (int)PrimitiveType.kTypeVar;
                            DfsTraverse(elseifBody, ref inferedType);
                        }

                        // Restore - Set the local codeblock parent to be the current codeblock
                        codeBlock = localCodeBlock.parent;
                    }
                }

                /*
                else
                {
                    S		->	traverse S
                                L1 = null
                                bpTable.append(pc)
                                emit(jmp,labelEnd)
                                backpatch(bp,pc)
                }
                 * */
                // Else-body

                Debug.Assert(null != ifnode.ElseBody);
                if (0 != ifnode.ElseBody.Count)
                {
                    // Create a new symboltable for this block
                    // Set the current table as the parent of the new table
                    // Set the new table as a new child of the current table
                    // Set the new table as the current table
                    // Create a new codeblock for this block
                    // Set the current codeblock as the parent of the new codeblock
                    // Set the new codeblock as a new child of the current codeblock
                    // Set the new codeblock as the current codeblock
                    localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                        ProtoCore.DSASM.CodeBlockType.kConstruct,
                        Language.kInvalid,
                        compileState.CodeBlockIndex++,
                        new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("else"), compileState.RuntimeTableIndex++),
                        null);

                    localCodeBlock.instrStream = codeBlock.instrStream;
                    localCodeBlock.parent = codeBlock;
                    codeBlock.children.Add(localCodeBlock);
                    codeBlock = localCodeBlock;
                    compileState.CodeBlockList.Add(codeBlock);
                    CodeRangeTable.AddCodeBlockRangeEntry(codeBlock.codeBlockId,
                        ifnode.ElseBodyPosition.line,
                        ifnode.ElseBodyPosition.col,
                        ifnode.ElseBodyPosition.endLine,
                        ifnode.ElseBodyPosition.endCol,
                        compileState.CurrentDSFileName);

                    foreach (ImperativeNode elseBody in ifnode.ElseBody)
                    {
                        inferedType = new ProtoCore.Type();
                        inferedType.UID = (int)PrimitiveType.kTypeVar;
                        DfsTraverse(elseBody, ref inferedType);
                    }

                    // Restore - Set the local codeblock parent to be the current codeblock
                    codeBlock = localCodeBlock.parent;
                }
            }
        }
        private void EmitIfStatementNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            // If-expr
            IfStatementNode ifnode = node as IfStatementNode;
            DfsTraverse(ifnode.ifExprNode, ref inferedType, false, graphNode);

            // Create a new codeblock for this block
            // Set the current codeblock as the parent of the new codeblock
            // Set the new codeblock as a new child of the current codeblock
            // Set the new codeblock as the current codeblock
            ProtoCore.DSASM.CodeBlock localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                ProtoCore.DSASM.CodeBlockType.kConstruct,
                Language.kInvalid,
                core.CodeBlockIndex++,
                new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("if"), core.RuntimeTableIndex++),
                null);

            localCodeBlock.instrStream = codeBlock.instrStream;
            localCodeBlock.parent = codeBlock;
            codeBlock.children.Add(localCodeBlock);
            codeBlock = localCodeBlock;
            core.CodeBlockList.Add(codeBlock);
            // If-body
            foreach (AssociativeNode ifBody in ifnode.IfBody)
            {
                inferedType = new ProtoCore.Type();
                inferedType.UID = (int)PrimitiveType.kTypeVar;
                DfsTraverse(ifBody, ref inferedType, false, graphNode);
            }

            // Restore - Set the local codeblock parent to be the current codeblock
            codeBlock = localCodeBlock.parent;

            Debug.Assert(null != ifnode.ElseBody);
            if (0 != ifnode.ElseBody.Count)
            {
                // Create a new symboltable for this block
                // Set the current table as the parent of the new table
                // Set the new table as a new child of the current table
                // Set the new table as the current table
                // Create a new codeblock for this block
                // Set the current codeblock as the parent of the new codeblock
                // Set the new codeblock as a new child of the current codeblock
                // Set the new codeblock as the current codeblock
                localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                    ProtoCore.DSASM.CodeBlockType.kConstruct,
                    Language.kInvalid,
                    core.CodeBlockIndex++,
                    new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("else"), core.RuntimeTableIndex++),
                    null);

                localCodeBlock.instrStream = codeBlock.instrStream;
                localCodeBlock.parent = codeBlock;
                codeBlock.children.Add(localCodeBlock);
                codeBlock = localCodeBlock;
                core.CodeBlockList.Add(codeBlock);
                foreach (AssociativeNode elseBody in ifnode.ElseBody)
                {
                    inferedType = new ProtoCore.Type();
                    inferedType.UID = (int)PrimitiveType.kTypeVar;
                    DfsTraverse(elseBody, ref inferedType, false, graphNode);
                }

                // Restore - Set the local codeblock parent to be the current codeblock
                codeBlock = localCodeBlock.parent;
            }
        }
Example #10
0
        /// <summary>
        /// get the type of an identifier based on its location and name
        /// </summary>
        /// <param name="si">where is the ident</param>
        /// <param name="ident">name of the ident</param>
        /// <param name="cp">
        /// where is the ident, not the same usage as parameter "si",
        /// this is used to see if the ident location is before its definition or after its definition
        /// </param>
        /// <returns></returns>
        private static int GetIdentType(ScopeInfo si, string ident, ProtoCore.CodeModel.CodePoint cp)
        {
            if (si.ClassScope == ProtoCore.DSASM.Constants.kInvalidIndex)
            {
                // Not inside any class
                ProtoCore.DSASM.CodeBlock        cb         = null;
                List <ProtoCore.DSASM.CodeBlock> codeBlocks = compileState.CodeBlockList;
                if (null != codeBlocks && (si.BlockId >= 0) && (si.BlockId < codeBlocks.Count))
                {
                    cb = codeBlocks[si.BlockId];
                }

                // loop used to search its parent block
                while (cb != null)
                {
                    // search by matching ident name and function index
                    IEnumerable <ProtoCore.DSASM.SymbolNode> sns = cb.symbolTable.symbolList.Values.Where(x =>
                                                                                                          x.name == ident &&
                                                                                                          x.functionIndex == si.FunctionIndex &&
                                                                                                          x.classScope == ProtoCore.DSASM.Constants.kInvalidIndex);

                    if (sns.Count() > 0) // found something
                    {
                        ProtoCore.DSASM.SymbolNode symbolNode = sns.ElementAt(0);

                        // if it is argument, it is visible every where inside the fucntion
                        if (symbolNode.isArgument == true)
                        {
                            return(GetSymbolType(symbolNode));
                        }

                        // check if the variable definition location is before our searching site
                        if (cp.Before(identLocationTable.Table[symbolNode]))
                        {
                            return(GetSymbolType(symbolNode));
                        }

                        // if not argument, check if it is defined some where in the imported files, if yes, it is visible
                        CodeFile file = identLocationTable.Table[symbolNode].SourceLocation;
                        if (importTable.IsImported(cp.SourceLocation.FilePath, file.FilePath))
                        {
                            return(GetSymbolType(symbolNode));
                        }
                    }

                    if (si.FunctionIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        // no name look up inside a fucntion
                        // TODO: This may need to change, since we are now allowing to access global variables inside a fucntion
                        break;
                    }

                    // update cb to its parent block
                    cb = cb.parent;
                }
            }
            else
            {
                // we are inside a function
                // check if it is this keyword
                if (ident == "this")
                {
                    // the type is the class itself
                    return(si.ClassScope);
                }

                // inside a class scope
                ProtoCore.DSASM.CodeBlock  cb = compileState.CodeBlockList[si.BlockId];
                ProtoCore.DSASM.SymbolNode sn = null;
                while (cb.parent != null)
                {
                    // if it is inside a language block which is inside a function
                    IEnumerable <ProtoCore.DSASM.SymbolNode> sns = cb.symbolTable.symbolList.Values.Where(x => x.name == ident);
                    if (sns.Count() > 0 &&
                        (sns.ElementAt(0).isArgument == true ||
                         importTable.IsImported(cp.SourceLocation.FilePath, identLocationTable.Table[sns.ElementAt(0)].SourceLocation.FilePath) ||
                         cp.Before(identLocationTable.Table[sns.ElementAt(0)])))
                    {
                        sn = sns.ElementAt(0);
                        break;
                    }

                    cb = cb.parent;
                }

                if (sn == null)
                {
                    // search local variables in the funtion
                    IEnumerable <ProtoCore.DSASM.SymbolNode> sns = compileState.ClassTable.ClassNodes[si.ClassScope].symbols.symbolList.Values.Where(x => x.name == ident && x.functionIndex == si.FunctionIndex);
                    if (sns.Count() > 0)
                    {
                        sn = sns.ElementAt(0);
                    }
                    else
                    {
                        // the final search, search the class member variables
                        sn = GetMemberVariable(si.ClassScope, ident, si, false);
                        //sn = GetClassMemberVariable(si.ClassScope, ident);
                    }
                }

                if (sn != null)
                {
                    return(sn.datatype.UID);
                }
            }

            return(ProtoCore.DSASM.Constants.kInvalidIndex);
        }
Example #11
0
 public abstract bool Compile(ProtoLanguage.CompileStateTracker compileState, out int blockId, ProtoCore.DSASM.CodeBlock parentBlock, ProtoCore.LanguageCodeBlock codeblock, ProtoCore.CompileTime.Context callContext, ProtoCore.DebugServices.EventSink sink = null, ProtoCore.AST.Node codeBlockNode = null, ProtoCore.AssociativeGraph.GraphNode graphNode = null);
Example #12
0
        public override bool Compile(ProtoLanguage.CompileStateTracker compileState, out int blockId, ProtoCore.DSASM.CodeBlock parentBlock, ProtoCore.LanguageCodeBlock langBlock, ProtoCore.CompileTime.Context callContext, ProtoCore.DebugServices.EventSink sink, ProtoCore.AST.Node codeBlockNode, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            Debug.Assert(langBlock != null);
            blockId = ProtoCore.DSASM.Constants.kInvalidIndex;

            bool buildSucceeded      = false;
            bool isLanguageSignValid = isLanguageSignValid = compileState.Langverify.Verify(langBlock);

            if (isLanguageSignValid)
            {
                try
                {
                    ProtoImperative.CodeGen codegen = new ProtoImperative.CodeGen(compileState, parentBlock);

                    codegen.context             = callContext;
                    codegen.codeBlock.EventSink = sink;
                    blockId = codegen.Emit(codeBlockNode as ProtoCore.AST.ImperativeAST.CodeBlockNode, graphNode);
                }
                catch (ProtoCore.BuildHaltException e)
                {
#if DEBUG
                    //core.BuildStatus.LogSemanticError(e.errorMsg);
#endif
                }

                int errors   = 0;
                int warnings = 0;
                buildSucceeded = compileState.BuildStatus.GetBuildResult(out errors, out warnings);
            }
            return(buildSucceeded);
        }
Example #13
0
        public override bool Compile(ProtoLanguage.CompileStateTracker compileState, out int blockId, ProtoCore.DSASM.CodeBlock parentBlock, ProtoCore.LanguageCodeBlock langBlock, ProtoCore.CompileTime.Context callContext, ProtoCore.DebugServices.EventSink sink, ProtoCore.AST.Node codeBlockNode, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            Debug.Assert(langBlock != null);
            blockId = ProtoCore.DSASM.Constants.kInvalidIndex;

            bool buildSucceeded  = false;
            bool isLangSignValid = compileState.Langverify.Verify(langBlock);

            if (isLangSignValid)
            {
                try
                {
                    ProtoCore.CodeGen oldCodegen = compileState.assocCodegen;

                    if (ProtoCore.DSASM.InterpreterMode.kNormal == compileState.ExecMode)
                    {
                        if ((compileState.IsParsingPreloadedAssembly || compileState.IsParsingCodeBlockNode) && parentBlock == null)
                        {
                            if (compileState.CodeBlockList.Count == 0)
                            {
                                compileState.assocCodegen = new ProtoAssociative.CodeGen(compileState, parentBlock);
                            }
                            else
                            {
                                // We reuse the existing toplevel CodeBlockList's for the procedureTable's
                                // by calling this overloaded constructor - pratapa
                                compileState.assocCodegen = new ProtoAssociative.CodeGen(compileState);
                            }
                        }
                        else
                        {
                            compileState.assocCodegen = new ProtoAssociative.CodeGen(compileState, parentBlock);
                        }
                    }

                    if (null != compileState.AssocNode)
                    {
                        ProtoCore.AST.AssociativeAST.CodeBlockNode cnode = new ProtoCore.AST.AssociativeAST.CodeBlockNode();
                        cnode.Body.Add(compileState.AssocNode as ProtoCore.AST.AssociativeAST.AssociativeNode);

                        compileState.assocCodegen.context = callContext;

                        blockId = compileState.assocCodegen.Emit((cnode as ProtoCore.AST.AssociativeAST.CodeBlockNode), graphNode);
                    }
                    else
                    {
                        //if not null, Compile has been called from DfsTraverse. No parsing is needed.
                        if (codeBlockNode == null)
                        {
                            System.IO.MemoryStream memstream       = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(langBlock.body));
                            ProtoCore.DesignScriptParser.Scanner s = new ProtoCore.DesignScriptParser.Scanner(memstream);
                            ProtoCore.DesignScriptParser.Parser  p = new ProtoCore.DesignScriptParser.Parser(s, compileState, compileState.builtInsLoaded);
                            p.Parse();

                            // TODO Jun: Set this flag inside a persistent object
                            compileState.builtInsLoaded = true;

                            codeBlockNode = p.root;

                            //compileState.AstNodeList = p.GetParsedASTList(codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode);
                            List <ProtoCore.AST.Node> astNodes = ProtoCore.Utils.ParserUtils.GetAstNodes(codeBlockNode);
                            compileState.AstNodeList = astNodes;
                        }
                        else
                        {
                            if (!compileState.builtInsLoaded)
                            {
                                // Load the built-in methods manually
                                ProtoCore.Utils.CoreUtils.InsertPredefinedAndBuiltinMethods(compileState, codeBlockNode, false);
                                compileState.builtInsLoaded = true;
                            }
                        }

                        compileState.assocCodegen.context = callContext;

                        //Temporarily change the code block for code gen to the current block, in the case it is an imperative block
                        //CodeGen for ProtoImperative is modified to passing in the core object.
                        ProtoCore.DSASM.CodeBlock oldCodeBlock = compileState.assocCodegen.codeBlock;
                        if (compileState.ExecMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
                        {
                            int tempBlockId = compileState.GetCurrentBlockId();

                            ProtoCore.DSASM.CodeBlock tempCodeBlock = compileState.GetCodeBlock(compileState.CodeBlockList, tempBlockId);
                            while (null != tempCodeBlock && tempCodeBlock.blockType != ProtoCore.DSASM.CodeBlockType.kLanguage)
                            {
                                tempCodeBlock = tempCodeBlock.parent;
                            }
                            compileState.assocCodegen.codeBlock = tempCodeBlock;
                        }
                        compileState.assocCodegen.codeBlock.EventSink = sink;
                        if (compileState.BuildStatus.Errors.Count == 0) //if there is syntax error, no build needed
                        {
                            blockId = compileState.assocCodegen.Emit((codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode), graphNode);
                        }
                        if (compileState.ExecMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
                        {
                            blockId = compileState.assocCodegen.codeBlock.codeBlockId;
                            //Restore the code block.
                            compileState.assocCodegen.codeBlock = oldCodeBlock;
                        }
                    }

                    // @keyu: we have to restore asscoCodegen here. It may be
                    // reused later on. Suppose for an inline expression
                    // "x = 1 == 2 ? 3 : 4", we dynamically create assocCodegen
                    // to compile true and false expression in this inline
                    // expression, and if we don't restore assocCodegen, the pc
                    // is totally messed up.
                    //
                    // But if directly replace with old assocCodegen, will it
                    // replace some other useful information? Need to revisit it.
                    //
                    // Also refer to defect IDE-2120.
                    if (oldCodegen != null && compileState.assocCodegen != oldCodegen)
                    {
                        compileState.assocCodegen = oldCodegen;
                    }
                }
                catch (ProtoCore.BuildHaltException e)
                {
#if DEBUG
                    //compileState.BuildStatus.LogSemanticError(e.errorMsg);
#endif
                }

                int errors   = 0;
                int warnings = 0;
                buildSucceeded = compileState.BuildStatus.GetBuildResult(out errors, out warnings);
            }

            return(buildSucceeded);
        }