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; }
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; }
/// <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); }
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); }
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; }
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; } } }
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; } }
/// <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); }
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);
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); }
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); }