コード例 #1
0
        public override bool Compile(
            out int blockId,
            ProtoCore.DSASM.CodeBlock parentBlock,
            ProtoCore.LanguageCodeBlock langBlock,
            ProtoCore.CompileTime.Context callContext,
            ProtoCore.DebugServices.EventSink sink         = null,
            ProtoCore.AST.Node codeBlockNode               = null,
            ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            Validity.Assert(langBlock != null);
            bool buildSucceeded = true;

            blockId = 0;

            core.assocCodegen = new ProtoVHDL.CodeGen(core, callContext, parentBlock);

            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, core.builtInsLoaded);
            p.Parse();
            core.builtInsLoaded = true;
            codeBlockNode       = p.root;

            List <ProtoCore.AST.Node> astNodes = ProtoCore.Utils.ParserUtils.GetAstNodes(codeBlockNode);

            core.AstNodeList = astNodes;

            core.assocCodegen.Emit(codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode);

            buildSucceeded = core.BuildStatus.BuildSucceeded;
            return(buildSucceeded);
        }
コード例 #2
0
ファイル: Compiler.cs プロジェクト: rafatahmed/Dynamo
        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;
            bool isLanguageSignValid = isLanguageSignValid = core.Langverify.Verify(langBlock);

            if (isLanguageSignValid)
            {
                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);
        }
コード例 #3
0
ファイル: CodeGen.cs プロジェクト: seasailor/designscript
        public CodeGen(ProtoLanguage.CompileStateTracker coreObj, ProtoCore.DSASM.CodeBlock parentBlock = null)
            : base(coreObj, 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,
                compileStateTracker.CodeBlockIndex,
                new ProtoCore.DSASM.SymbolTable("imperative lang block", compileStateTracker.RuntimeTableIndex),
                new ProtoCore.DSASM.ProcedureTable(compileStateTracker.RuntimeTableIndex),
                false,
                compileStateTracker);

            ++compileStateTracker.CodeBlockIndex;
            ++compileStateTracker.RuntimeTableIndex;

            if (null == parentBlock)
            {
                // This is a top level block
                compileStateTracker.CodeBlockList.Add(codeBlock);
            }
            else
            {
                // This is a nested block
                parentBlock.children.Add(codeBlock);
                codeBlock.parent = parentBlock;
            }
            compileStateTracker.CompleteCodeBlockList.Add(codeBlock);
            blockScope = 0;

            // Bouncing to this language codeblock from a function should immediatlet se the first instruction as the entry point
            if (ProtoCore.DSASM.Constants.kGlobalScope != globalProcIndex)
            {
                isEntrySet = true;
                codeBlock.instrStream.entrypoint = 0;
            }

            backpatchMap = new BackpatchMap();

            nodeBuilder = new NodeBuilder(compileStateTracker);
        }
コード例 #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)
        {
            Validity.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
                }

                buildSucceeded = core.BuildStatus.BuildSucceeded;
            }
            return(buildSucceeded);
        }
コード例 #5
0
ファイル: CodeGen.cs プロジェクト: rafatahmed/Dynamo
        private void EmitForLoopNode(ImperativeNode node, ref ProtoCore.Type inferredType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (core.IsParsingCodeBlockNode || core.IsParsingPreloadedAssembly)
            {
                return;
            }

            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                /*
                x = 0;
                a = {10,20,30,40}
                for(val in a)
                {
                    x = x + val;
                }

                Compiles down to:

                x = 0;
                a = {10,20,30,40};
                val = null;
                %forloop_key = a.key;
                %forloop_expr = a;

                while( %forloop_key != null)
                {
                    val = %forloop_expr[%forloop_key];
                    %forloop_key = %forloop_key + 1;
                    x = x + val;
                }
                */
                DebugProperties.BreakpointOptions oldOptions = core.DebuggerProperties.breakOptions;
                DebugProperties.BreakpointOptions newOptions = oldOptions;
                newOptions |= DebugProperties.BreakpointOptions.EmitCallrForTempBreakpoint;
                core.DebuggerProperties.breakOptions = newOptions;

                // TODO Jun: This compilation unit has many opportunities for optimization 
                //      1. Compiling to while need not be necessary if 'expr' has exactly one element
                //      2. For-loop can have its own semantics without the need to convert to a while node

                ForLoopNode forNode = node as ForLoopNode;
                ++core.ForLoopBlockIndex;   //new forloop beginning. increment loop counter 

                // Insert a dummy block for for-loop so that loopvar is in scope.
                ProtoCore.DSASM.CodeBlock localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                        context.guid,
                        ProtoCore.DSASM.CodeBlockType.kConstruct,
                        Language.kInvalid,
                        core.CodeBlockIndex++,
                        new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("dummy"), core.RuntimeTableIndex++),
                        null,
                        true,
                        core);

                core.CodeBlockIndex++;
                localCodeBlock.instrStream = codeBlock.instrStream;
                localCodeBlock.parent = codeBlock;

                codeBlock.children.Add(localCodeBlock);
                codeBlock = localCodeBlock;
                EmitPushBlockID(localCodeBlock.codeBlockId);


                ProtoCore.Type type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVoid, 0);

                // val = null; 
                IdentifierNode loopvar = nodeBuilder.BuildIdentfier(forNode.loopVar.Name) as IdentifierNode;
                {
                    loopvar.ArrayName = forNode.expression.Name;
                    ProtoCore.Utils.NodeUtils.CopyNodeLocation(loopvar, forNode.loopVar);
                    BinaryExpressionNode loopvarInit = new BinaryExpressionNode();
                    loopvarInit.Optr = ProtoCore.DSASM.Operator.assign;
                    loopvarInit.LeftNode = loopvar;
                    loopvarInit.RightNode = new NullNode();
 
                    ProtoCore.Utils.NodeUtils.CopyNodeLocation(loopvarInit, forNode);
                    loopvarInit.endLine = loopvarInit.line;
                    loopvarInit.endCol = loopvarInit.col + 3;
                    EmitBinaryExpressionNode(loopvarInit, ref type, isBooleanOp, graphNode);
                }

                // %key = null;
                string keyIdent = GetForLoopKeyIdent();
                Allocate(keyIdent, globalProcIndex, TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVoid, 0));
                var key = nodeBuilder.BuildIdentfier(keyIdent);

                // %array = complicated expr in for...in loop, so that we could
                // index into it. 
                string identName = GetForExprIdent();
                var arrayExpr = nodeBuilder.BuildIdentfier(identName);
                NodeUtils.CopyNodeLocation(arrayExpr, forNode.expression);
                BinaryExpressionNode arrayexprAssignment = new BinaryExpressionNode();
                arrayexprAssignment.Optr = ProtoCore.DSASM.Operator.assign;
                arrayexprAssignment.LeftNode = arrayExpr;
                arrayexprAssignment.RightNode = forNode.expression;
                NodeUtils.UpdateBinaryExpressionLocation(arrayexprAssignment);

                switch (forNode.expression.GetType().ToString())
                {
                    case "ProtoCore.AST.ImperativeAST.IdentifierNode":
                    case "ProtoCore.AST.ImperativeAST.ExprListNode":
                        newOptions |= DebugProperties.BreakpointOptions.EmitPopForTempBreakpoint;
                        core.DebuggerProperties.breakOptions = newOptions;
                        break;
                }

                type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                EmitBinaryExpressionNode(arrayexprAssignment, ref type, isBooleanOp, graphNode);
                core.DebuggerProperties.breakOptions = oldOptions; // Restore breakpoint behaviors.

                // Get the size of expr and assign it to the autogen iteration var
                int symbolIndex = Constants.kInvalidIndex;
                SymbolNode symbol = null;
                if (ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex && !IsInLanguageBlockDefinedInFunction())
                {
                    symbolIndex = core.ClassTable.ClassNodes[globalClassIndex].symbols.IndexOf(identName);
                    if (symbolIndex != Constants.kInvalidIndex)
                    {
                        symbol = core.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[symbolIndex];
                    }
                }
                else
                {
                    symbolIndex = codeBlock.symbolTable.IndexOf(identName);
                    if (symbolIndex != Constants.kInvalidIndex)
                    {
                        symbol = codeBlock.symbolTable.symbolList[symbolIndex];
                    }
                }
                EmitInstrConsole(ProtoCore.DSASM.kw.pushvarsize, identName);
                EmitPushArrayKey(symbolIndex, codeBlock.symbolTable.RuntimeIndex, (symbol == null) ? globalClassIndex : symbol.classScope);

                // Push the identifier local block information 
                // Push the array dimensions
                int dimensions = 0;
                EmitPushVarData(dimensions);

                if (ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex && !IsInLanguageBlockDefinedInFunction())
                {
                    symbolIndex = core.ClassTable.ClassNodes[globalClassIndex].symbols.IndexOf(keyIdent);
                    if (symbolIndex != Constants.kInvalidIndex)
                    {
                        symbol = core.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[symbolIndex];
                    }
                }
                else
                {
                    symbolIndex = codeBlock.symbolTable.IndexOf(keyIdent);
                    if (symbolIndex != Constants.kInvalidIndex)
                    {
                        symbol = codeBlock.symbolTable.symbolList[symbolIndex];
                    }
                }
                StackValue opDest = StackValue.BuildVarIndex(symbolIndex);
                EmitInstrConsole(ProtoCore.DSASM.kw.pop, keyIdent);
                EmitPop(opDest, (symbol == null) ? globalClassIndex : symbol.classScope, symbol.runtimeTableIndex);

                // key == null ?
                BinaryExpressionNode condition = new BinaryExpressionNode();
                {
                    condition.Optr = ProtoCore.DSASM.Operator.nq;
                    condition.LeftNode = key;
                    condition.RightNode = new NullNode();
                    condition.line = forNode.KwInLine;
                    condition.col = forNode.KwInCol;
                    condition.endLine = forNode.KwInLine;
                    condition.endCol = forNode.KwInCol + 2; // 2 character for keyword "in".
                }

                // val = array[key];
                BinaryExpressionNode arrayIndexing = new BinaryExpressionNode();
                {
                    arrayIndexing.Optr = ProtoCore.DSASM.Operator.assign;
                    arrayIndexing.LeftNode = loopvar;

                    // Array index into the expr ident
                    ArrayNode arrayIndex = new ArrayNode();
                    arrayIndex.Expr = key;
                    arrayIndex.Type = null;
                    (arrayExpr as IdentifierNode).ArrayDimensions = arrayIndex;
                    arrayIndexing.RightNode = arrayExpr;

                    arrayIndexing.line = loopvar.line;
                    arrayIndexing.col = loopvar.col;
                    arrayIndexing.endLine = loopvar.endLine;
                    arrayIndexing.endCol = loopvar.endCol;
                }

                // key = key + 1;
                BinaryExpressionNode nextKey = new BinaryExpressionNode();
                {
                    nextKey.LeftNode = key;
                    nextKey.Optr = Operator.assign;
                    nextKey.RightNode = nodeBuilder.BuildBinaryExpression(key,
                                                    new IntNode(1),
                                                    Operator.add);
                }

                // Append the array indexing and key increment expressions into 
                // the for-loop body
                forNode.body.Insert(0, arrayIndexing);
                forNode.body.Insert(1, nextKey);

                // Construct and populate the equivalent while node
                WhileStmtNode whileStatement = new WhileStmtNode();
                whileStatement.Expr = condition;
                whileStatement.Body = forNode.body;
                whileStatement.endLine = node.endLine;
                whileStatement.endCol = node.endCol;

                type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                EmitWhileStmtNode(whileStatement, ref type, isBooleanOp, graphNode);

                // As we add a dummy code block around forloop node, RETCN 
                // instruction will get debugging information from 
                // localCodeBlockNode, which is forloop node. We temporarily set
                // lcoalCodeBlockNode to a dummy node so that RETCN won't have 
                // debugging information.
                var dummyCodeBlockNode = new CodeBlockNode();
                var backUpLocalCodeBlockNode = localCodeBlockNode;
                localCodeBlockNode = dummyCodeBlockNode;

                EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                EmitRetcn(localCodeBlock.codeBlockId);

                codeBlock = localCodeBlock.parent;
                localCodeBlockNode = backUpLocalCodeBlockNode;
                //}

                // Comment Jun: The for loop counter must be unique and does not need to reset
                //forloopCounter--;   //for loop ended. decrement counter 
            }
        }
コード例 #6
0
        private void ProcessCodeBlock(CodeBlock codeBlock)
        {
            if (null == codeBlock)
                return;

            int parent = ((null == codeBlock.parent) ? -1 : codeBlock.parent.codeBlockId);
            DefineHierarchy(parent, codeBlock.codeBlockId, false);

            ProcedureTable procTable = codeBlock.procedureTable;
            foreach (ProcedureNode procNode in procTable.procList)
                ProcessProcedureNode(procNode);

            SymbolTable symbolTable = codeBlock.symbolTable;
            foreach (var symbolNode in symbolTable.symbolList)
                ProcessSymbolNode(symbolNode.Value);
        }
コード例 #7
0
ファイル: CodeGen.cs プロジェクト: AutodeskFractal/Dynamo
        private ProtoCore.DSASM.CodeBlock BuildNewCodeBlock(ProcedureTable procTable = null)
        {
            ProcedureTable pTable = procTable == null ? new ProtoCore.DSASM.ProcedureTable(core.RuntimeTableIndex) : procTable;

            // 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
            ProtoCore.DSASM.CodeBlock cb = new ProtoCore.DSASM.CodeBlock(
                context.guid,
                ProtoCore.DSASM.CodeBlockType.kLanguage,
                ProtoCore.Language.Associative,
                core.CodeBlockIndex,
                new ProtoCore.DSASM.SymbolTable("associative lang block", core.RuntimeTableIndex),
                pTable,
                false,
                core);

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

            return cb;
        }
コード例 #8
0
ファイル: CodeGen.cs プロジェクト: seasailor/designscript
        private void EmitIfStmtNode(ImperativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AST.ImperativeAST.BinaryExpressionNode parentNode = null, bool isForInlineCondition = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            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)
                }
                 * */

                int bp = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int L1 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int L2 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                ProtoCore.DSASM.StackValue opCX = new ProtoCore.DSASM.StackValue();

                // If-expr
                IfStmtNode ifnode = node as IfStmtNode;
                DfsTraverse(ifnode.IfExprNode, ref inferedType, false, graphNode, AssociativeSubCompilePass.kNone, parentNode);

                EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regCX);
                opCX.optype = ProtoCore.DSASM.AddressType.Register;
                opCX.opdata = (int)ProtoCore.DSASM.Registers.CX;
                EmitPop(opCX, Constants.kGlobalScope);

                L1 = pc + 1;
                L2 = ProtoCore.DSASM.Constants.kInvalidIndex;
                bp = pc;
                EmitCJmp(L1, L2, ifnode.IfExprNode.line, ifnode.IfExprNode.col, ifnode.IfExprNode.endLine, ifnode.IfExprNode.endCol);

                if (!isForInlineCondition)
                {
                    EmitSetExpressionUID(compileStateTracker.ExpressionUID++);
                }

                // 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,
                    compileStateTracker.CodeBlockIndex++,
                    new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("if"), compileStateTracker.RuntimeTableIndex++),
                    null);

                localCodeBlock.instrStream = codeBlock.instrStream;
                localCodeBlock.parent = codeBlock;
                codeBlock.children.Add(localCodeBlock);
                codeBlock = localCodeBlock;
                compileStateTracker.CompleteCodeBlockList.Add(localCodeBlock);
                EmitPushBlockID(localCodeBlock.codeBlockId);
                // If-body
                foreach (ImperativeNode ifBody in ifnode.IfBody)
                {
                    inferedType = new ProtoCore.Type();
                    inferedType.UID = (int)PrimitiveType.kTypeVar;
                    DfsTraverse(ifBody, ref inferedType, false, graphNode, AssociativeSubCompilePass.kNone, parentNode);
                }

                if (!isForInlineCondition)
                {
                    ProtoCore.AST.Node oldBlockNode = localCodeBlockNode;
                    localCodeBlockNode = ifnode.IfBodyPosition;
                    EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                    EmitRetcn(localCodeBlock.codeBlockId);
                    localCodeBlockNode = oldBlockNode;
                }

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

                L1 = ProtoCore.DSASM.Constants.kInvalidIndex;

                BackpatchTable backpatchTable = new BackpatchTable();
                backpatchTable.Append(pc, L1);
                EmitJmp(L1);
                EmitPopBlockID();

                // Backpatch the L2 destination of the if block
                Backpatch(bp, pc);

                /*
                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, false, graphNode);

                    EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regCX);
                    opCX.optype = ProtoCore.DSASM.AddressType.Register;
                    opCX.opdata = (int)ProtoCore.DSASM.Registers.CX;
                    EmitPop(opCX, Constants.kGlobalScope);

                    L1 = pc + 1;
                    L2 = ProtoCore.DSASM.Constants.kInvalidIndex;
                    bp = pc;
                    EmitCJmp(L1, L2, elseifNode.Expr.line, elseifNode.Expr.col, elseifNode.Expr.endLine, elseifNode.Expr.endCol);

                    EmitSetExpressionUID(compileStateTracker.ExpressionUID++);

                    // 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,
                            compileStateTracker.CodeBlockIndex++,
                            new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("elseif"), compileStateTracker.RuntimeTableIndex++),
                            null);

                        localCodeBlock.instrStream = codeBlock.instrStream;
                        localCodeBlock.parent = codeBlock;
                        codeBlock.children.Add(localCodeBlock);
                        codeBlock = localCodeBlock;
                        compileStateTracker.CompleteCodeBlockList.Add(localCodeBlock);
                        EmitPushBlockID(localCodeBlock.codeBlockId);
                        foreach (ImperativeNode elseifBody in elseifNode.Body)
                        {
                            inferedType = new ProtoCore.Type();
                            inferedType.UID = (int)PrimitiveType.kTypeVar;
                            DfsTraverse(elseifBody, ref inferedType, false, graphNode);
                        }

                        if (!isForInlineCondition)
                        {
                            ProtoCore.AST.Node oldBlockNode = localCodeBlockNode;
                            localCodeBlockNode = elseifNode.ElseIfBodyPosition;
                            EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                            EmitRetcn(localCodeBlock.codeBlockId);
                            localCodeBlockNode = oldBlockNode;
                        }

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

                    L1 = ProtoCore.DSASM.Constants.kInvalidIndex;
                    backpatchTable.Append(pc, L1);
                    EmitJmp(L1);
                    EmitPopBlockID();

                    // Backpatch the L2 destination of the elseif block
                    Backpatch(bp, pc);
                }

                /*
                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,
                        compileStateTracker.CodeBlockIndex++,
                        new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("else"), compileStateTracker.RuntimeTableIndex++),
                        null);

                    localCodeBlock.instrStream = codeBlock.instrStream;
                    localCodeBlock.parent = codeBlock;
                    codeBlock.children.Add(localCodeBlock);
                    codeBlock = localCodeBlock;
                    compileStateTracker.CompleteCodeBlockList.Add(localCodeBlock);
                    EmitPushBlockID(localCodeBlock.codeBlockId);
                    foreach (ImperativeNode elseBody in ifnode.ElseBody)
                    {
                        inferedType = new ProtoCore.Type();
                        inferedType.UID = (int)PrimitiveType.kTypeVar;
                        DfsTraverse(elseBody, ref inferedType, false, graphNode, AssociativeSubCompilePass.kNone, parentNode);
                    }

                    if (!isForInlineCondition)
                    {
                        ProtoCore.AST.Node oldBlockNode = localCodeBlockNode;
                        localCodeBlockNode = ifnode.ElseBodyPosition;
                        EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                        EmitRetcn(localCodeBlock.codeBlockId);
                        localCodeBlockNode = oldBlockNode;
                    }

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

                    L1 = ProtoCore.DSASM.Constants.kInvalidIndex;
                    backpatchTable.Append(pc, L1);
                    EmitJmp(L1);
                    EmitPopBlockID();
                }

                /*
                 *
                          ->	backpatch(bpTable, pc)
                 */
                // ifstmt-exit
                // Backpatch all the previous unconditional jumps
                Backpatch(backpatchTable.backpatchList, pc);
            }
        }
コード例 #9
0
ファイル: Core.cs プロジェクト: limrzx/Dynamo
        private void BfsBuildProcedureTable(CodeBlock codeBlock, ProcedureTable[] procTable)
        {
            if (CodeBlockType.Language == codeBlock.blockType || CodeBlockType.Function == codeBlock.blockType)
            {
                Validity.Assert(codeBlock.procedureTable.RuntimeIndex < RuntimeTableIndex);
                procTable[codeBlock.procedureTable.RuntimeIndex] = codeBlock.procedureTable;
            }

            foreach (CodeBlock child in codeBlock.children)
            {
                BfsBuildProcedureTable(child, procTable);
            }
        }
コード例 #10
0
ファイル: Core.cs プロジェクト: limrzx/Dynamo
 public bool IsFunctionCodeBlock(CodeBlock cblock)
 {
     // Determine if the immediate block is a function block
     // Construct blocks are ignored
     Validity.Assert(null != cblock);
     while (null != cblock)
     {
         if (CodeBlockType.Function == cblock.blockType)
         {
             return true;
         }
         else if (CodeBlockType.Language == cblock.blockType)
         {
             return false;
         }
         cblock = cblock.parent;
     }
     return false;
 }
コード例 #11
0
ファイル: Core.cs プロジェクト: seasailor/designscript
        private void BfsBuildProcedureTable(CodeBlock codeBlock, ProcedureTable[] procTable)
        {
            if (DSASM.CodeBlockType.kLanguage == codeBlock.blockType || DSASM.CodeBlockType.kFunction == codeBlock.blockType)
            {
                Debug.Assert(codeBlock.procedureTable.runtimeIndex < RuntimeTableIndex);
                procTable[codeBlock.procedureTable.runtimeIndex] = codeBlock.procedureTable;
            }

            foreach (DSASM.CodeBlock child in codeBlock.children)
            {
                BfsBuildProcedureTable(child, procTable);
            }
        }
コード例 #12
0
ファイル: Core.cs プロジェクト: seasailor/designscript
        private void BfsBuildInstructionStreams(CodeBlock codeBlock, InstructionStream[] istreamList)
        {
            if (null != codeBlock)
            {
                if (DSASM.CodeBlockType.kLanguage == codeBlock.blockType || DSASM.CodeBlockType.kFunction == codeBlock.blockType)
                {
                    Debug.Assert(codeBlock.codeBlockId < CodeBlockIndex);
                    istreamList[codeBlock.codeBlockId] = codeBlock.instrStream;
                }

                foreach (DSASM.CodeBlock child in codeBlock.children)
                {
                    BfsBuildInstructionStreams(child, istreamList);
                }
            }
        }
コード例 #13
0
ファイル: Core.cs プロジェクト: seasailor/designscript
 public bool IsFunctionCodeBlock(CodeBlock cblock)
 {
     // Determine if the immediate block is a function block
     // Construct blocks are ignored
     Debug.Assert(null != cblock);
     while (null != cblock)
     {
         if (ProtoCore.DSASM.CodeBlockType.kFunction == cblock.blockType)
         {
             return true;
         }
         else if (ProtoCore.DSASM.CodeBlockType.kLanguage == cblock.blockType)
         {
             return false;
         }
         cblock = cblock.parent;
     }
     return false;
 }
コード例 #14
0
ファイル: Core.cs プロジェクト: sh4nnongoh/Dynamo
        public SymbolNode GetFirstVisibleSymbol(string name, int classscope, int function, CodeBlock codeblock)
        {
            Validity.Assert(null != codeblock);
            int symbolIndex = Constants.kInvalidIndex;

            // For variables defined nested language block, their function index
            // is always Constants.kGlobalScope 
            CodeBlock searchBlock = codeblock;
            while (searchBlock != null)
            {
                // For imported node, it is possbile that the block is not the
                // topmost block.
                // 
                // For expression interpreter, as the code has been compiled, the
                // outmost block wouldn't be function block (CodeBlockType.Function).
                // CodeBlockType.Function is a temporary block type which is set when
                // the compile is generating code for function defintion node and will
                // be set back to Associative.
                var isSearchBoundry = searchBlock.blockType == CodeBlockType.Function ||
                    (Options.RunMode == InterpreterMode.Expression && searchBlock.parent == null);

                if (isSearchBoundry)
                {
                    break;
                }

                symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, Constants.kGlobalScope);
                if (symbolIndex == Constants.kInvalidIndex)
                {
                    searchBlock = searchBlock.parent;
                }
                else
                {
                    return searchBlock.symbolTable.symbolList[symbolIndex];
                }
            }

            // Search variable might be defined in function. 
            // If we are not in class defintion, then just stop here, otherwise
            // we should search global block's symbol table.
            if (searchBlock != null && 
                (searchBlock.blockType == CodeBlockType.Function || (Options.RunMode == InterpreterMode.Expression && searchBlock.parent == null)) && 
                classscope == Constants.kGlobalScope)
            {
                symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, function);
            }

            return symbolIndex == Constants.kInvalidIndex ? null : searchBlock.symbolTable.symbolList[symbolIndex];
        }
コード例 #15
0
ファイル: CoreUtils.cs プロジェクト: sh4nnongoh/Dynamo
        public static ProcedureNode GetFunctionByName(string name, CodeBlock codeBlock)
        {
            if (null == codeBlock)
            {
                return null;
            }

            CodeBlock searchBlock = codeBlock;
            while (null != searchBlock)
            {
                if (null == searchBlock.procedureTable)
                {
                    searchBlock = searchBlock.parent;
                    continue;
                }

                // The class table is passed just to check for coercion values
                var procNode = searchBlock.procedureTable.GetFunctionsByName(name).FirstOrDefault();
                if (procNode != null)
                    return procNode;

                searchBlock = searchBlock.parent;
            }
            return null;
        }
コード例 #16
0
ファイル: Core.cs プロジェクト: limrzx/Dynamo
        public SymbolNode GetSymbolInFunction(string name, int classScope, int functionScope, CodeBlock codeBlock)
        {
            Validity.Assert(functionScope != Constants.kGlobalScope);
            if (Constants.kGlobalScope == functionScope)
            {
                return null;
            }

            int symbolIndex = Constants.kInvalidIndex;

            if (classScope != Constants.kGlobalScope)
            {
                //Search local variable for the class member function
                symbolIndex = ClassTable.ClassNodes[classScope].Symbols.IndexOf(name, classScope, functionScope);
                if (symbolIndex != Constants.kInvalidIndex)
                {
                    return ClassTable.ClassNodes[classScope].Symbols.symbolList[symbolIndex];
                }

                //Search class members
                symbolIndex = ClassTable.ClassNodes[classScope].Symbols.IndexOf(name, classScope, Constants.kGlobalScope);
                if (symbolIndex != Constants.kInvalidIndex)
                {
                    return ClassTable.ClassNodes[classScope].Symbols.symbolList[symbolIndex];
                }
            }

            while (symbolIndex == Constants.kInvalidIndex &&
                   codeBlock != null &&
                   codeBlock.blockType != CodeBlockType.Function)
            {
                symbolIndex = codeBlock.symbolTable.IndexOf(name, classScope, functionScope);
                if (symbolIndex != Constants.kInvalidIndex)
                {
                    return codeBlock.symbolTable.symbolList[symbolIndex];
                }
                else
                {
                    codeBlock = codeBlock.parent;
                }
            }

            if (symbolIndex == Constants.kInvalidIndex &&
                codeBlock != null &&
                codeBlock.blockType == CodeBlockType.Function)
            {
                symbolIndex = codeBlock.symbolTable.IndexOf(name, classScope, functionScope);
                if (symbolIndex != Constants.kInvalidIndex)
                {
                    return codeBlock.symbolTable.symbolList[symbolIndex];
                }
            }

            return null;
        }
コード例 #17
0
ファイル: Core.cs プロジェクト: limrzx/Dynamo
        public SymbolNode GetFirstVisibleSymbol(string name, int classscope, int function, CodeBlock codeblock)
        {
            //  
            //

            Validity.Assert(null != codeblock);
            if (null == codeblock)
            {
                return null;
            }

            int symbolIndex = Constants.kInvalidIndex;
            bool stillInsideFunction = function != Constants.kInvalidIndex;
            CodeBlock searchBlock = codeblock;
            // TODO(Jiong): Code Duplication, Consider moving this if else block inside the while loop 
            if (stillInsideFunction)
            {
                symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, function);

                if (function != Constants.kInvalidIndex &&
                    searchBlock.procedureTable != null &&
                    searchBlock.procedureTable.Procedures.Count > function &&   // Note: This check assumes we can not define functions inside a fucntion 
                    symbolIndex == Constants.kInvalidIndex)
                    symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, Constants.kInvalidIndex);
            }
            else
            {
                symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, Constants.kInvalidIndex);
            }
            while (Constants.kInvalidIndex == symbolIndex)
            {
                // if the search block is of type function, it means our search has gone out of the function itself
                // so, we should ignore the given function index and only search its parent block's global variable
                if (searchBlock.blockType == CodeBlockType.Function)
                    stillInsideFunction = false;

                searchBlock = searchBlock.parent;
                if (null == searchBlock)
                {
                    return null;
                }

                // Continue searching
                if (stillInsideFunction)
                {
                    // we are still inside a function, first search the local variable defined in this function 
                    // if not found, then search the enclosing block by specifying the function index as -1
                    symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, function);

                    // this check is to avoid unnecessary search
                    // for example if we have a for loop inside an imperative block which is further inside a function
                    // when we are searching inside the for loop or language block, there is no need to search twice
                    // we need to search twice only when we are searching directly inside the function, 
                    if (function != Constants.kInvalidIndex &&
                        searchBlock.procedureTable != null &&
                        searchBlock.procedureTable.Procedures.Count > function && // Note: This check assumes we can not define functions inside a fucntion 
                        symbolIndex == Constants.kInvalidIndex)

                        symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, Constants.kInvalidIndex);

                }
                else
                {
                    symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, Constants.kInvalidIndex);
                }
            }
            return searchBlock.symbolTable.symbolList[symbolIndex];
        }
コード例 #18
0
ファイル: Core.cs プロジェクト: seasailor/designscript
        private void BfsBuildSequenceTable(CodeBlock codeBlock, SymbolTable[] runtimeSymbols)
        {
            if (DSASM.CodeBlockType.kLanguage == codeBlock.blockType
                || DSASM.CodeBlockType.kFunction == codeBlock.blockType
                || DSASM.CodeBlockType.kConstruct == codeBlock.blockType)
            {
                Debug.Assert(codeBlock.symbolTable.runtimeIndex < RuntimeTableIndex);
                runtimeSymbols[codeBlock.symbolTable.runtimeIndex] = codeBlock.symbolTable;
            }

            foreach (DSASM.CodeBlock child in codeBlock.children)
            {
                BfsBuildSequenceTable(child, runtimeSymbols);
            }
        }
コード例 #19
0
ファイル: Core.cs プロジェクト: limrzx/Dynamo
        private void BfsBuildSequenceTable(CodeBlock codeBlock, SymbolTable[] runtimeSymbols)
        {
            if (CodeBlockType.Language == codeBlock.blockType
                || CodeBlockType.Function == codeBlock.blockType
                || CodeBlockType.Construct == codeBlock.blockType)
            {
                Validity.Assert(codeBlock.symbolTable.RuntimeIndex < RuntimeTableIndex);
                runtimeSymbols[codeBlock.symbolTable.RuntimeIndex] = codeBlock.symbolTable;
            }

            foreach (CodeBlock child in codeBlock.children)
            {
                BfsBuildSequenceTable(child, runtimeSymbols);
            }
        }
コード例 #20
0
ファイル: Core.cs プロジェクト: algobasket/Dynamo
        public SymbolNode GetFirstVisibleSymbol(string name, int classscope, int function, CodeBlock codeblock)
        {
            //  
            //

            Validity.Assert(null != codeblock);
            if (null == codeblock)
            {
                return null;
            }

            int symbolIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
            bool stillInsideFunction = function != ProtoCore.DSASM.Constants.kInvalidIndex;
            DSASM.CodeBlock searchBlock = codeblock;
            // TODO(Jiong): Code Duplication, Consider moving this if else block inside the while loop 
            if (stillInsideFunction)
            {
                symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, function);

                if (function != ProtoCore.DSASM.Constants.kInvalidIndex &&
                    searchBlock.procedureTable != null &&
                    searchBlock.procedureTable.procList.Count > function &&   // Note: This check assumes we can not define functions inside a fucntion 
                    symbolIndex == ProtoCore.DSASM.Constants.kInvalidIndex)
                    symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, ProtoCore.DSASM.Constants.kInvalidIndex);
            }
            else
            {
                symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, ProtoCore.DSASM.Constants.kInvalidIndex);
            }
            while (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
            {
                // if the search block is of type function, it means our search has gone out of the function itself
                // so, we should ignore the given function index and only search its parent block's global variable
                if (searchBlock.blockType == DSASM.CodeBlockType.kFunction)
                    stillInsideFunction = false;

                searchBlock = searchBlock.parent;
                if (null != searchBlock)
                {
                    // Continue searching
                    if (stillInsideFunction)
                    {
                        // we are still inside a function, first search the local variable defined in this function 
                        // if not found, then search the enclosing block by specifying the function index as -1
                        symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, function);

                        // this check is to avoid unnecessary search
                        // for example if we have a for loop inside an imperative block which is further inside a function
                        // when we are searching inside the for loop or language block, there is no need to search twice
                        // we need to search twice only when we are searching directly inside the function, 
                        if (function != ProtoCore.DSASM.Constants.kInvalidIndex &&
                            searchBlock.procedureTable != null &&
                            searchBlock.procedureTable.procList.Count > function && // Note: This check assumes we can not define functions inside a fucntion 
                            symbolIndex == ProtoCore.DSASM.Constants.kInvalidIndex)

                            symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, ProtoCore.DSASM.Constants.kInvalidIndex);

                    }
                    else
                    {
                        symbolIndex = searchBlock.symbolTable.IndexOf(name, classscope, ProtoCore.DSASM.Constants.kInvalidIndex);
                    }
                }
                else
                {
                    // End of nested blocks

                    /*
                    // Not found? Look at the class scope
                    if (ProtoCore.DSASM.Constants.kInvalidIndex != classscope)
                    {
                        // Look at the class members and base class members
                        bool hasSymbol = false;
                        ProtoCore.DSASM.AddressType addrType =  DSASM.AddressType.Invalid;
                        ProtoCore.DSASM.ClassNode cnode = classTable.list[classscope];
                        symbolIndex = cnode.GetFirstVisibleSymbol(name, classscope, function, out hasSymbol, out addrType);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != symbolIndex)
                        {
                            if (addrType == DSASM.AddressType.StaticMemVarIndex)
                            {
                                return codeBlockList[0].symbolTable.symbolList[symbolIndex];
                            }
                            else
                            {
                                return classTable.list[classscope].symbols.symbolList[symbolIndex];
                            }
                        }

                        // Look at the class constructors and functions
                        symbolIndex = classTable.list[classscope].symbols.IndexOf(name, classscope, function);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != symbolIndex)
                        {
                            return classTable.list[classscope].symbols.symbolList[symbolIndex];
                        }
                    }


                    // Not found? Look at the global scope
                    symbolIndex = searchBlock.symbolTable.IndexOf(name, ProtoCore.DSASM.Constants.kInvalidIndex, ProtoCore.DSASM.Constants.kGlobalScope);
                    if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
                    {
                        return null;
                    }
                    break;
                     * */
                    return null;
                }
            }
            return searchBlock.symbolTable.symbolList[symbolIndex];
        }
コード例 #21
0
ファイル: Core.cs プロジェクト: limrzx/Dynamo
        private void BfsBuildInstructionStreams(CodeBlock codeBlock, InstructionStream[] istreamList)
        {
            if (null != codeBlock)
            {
                if (CodeBlockType.Language == codeBlock.blockType || CodeBlockType.Function == codeBlock.blockType)
                {
                    Validity.Assert(codeBlock.codeBlockId < RuntimeTableIndex);
                    istreamList[codeBlock.codeBlockId] = codeBlock.instrStream;
                }

                foreach (CodeBlock child in codeBlock.children)
                {
                    BfsBuildInstructionStreams(child, istreamList);
                }
            }
        }
コード例 #22
0
ファイル: Compiler.cs プロジェクト: jiafeng5513/VisualScript
 public abstract bool Compile(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);
コード例 #23
0
ファイル: CodeGen.cs プロジェクト: seasailor/designscript
        private void EmitWhileStmtNode(ImperativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                /*

                while(E)	->	entry = pc
                                traverse E
                                emit(pop,cx)
                                L1 = pc + 1
                                L2 = null
                                bp = pc
                                emit(jmp, _cx, L1, L2)

                 * */

                int bp = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int L1 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int L2 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int entry = (int)ProtoCore.DSASM.Constants.kInvalidIndex;

                entry = pc;

                WhileStmtNode whileNode = node as WhileStmtNode;
                DfsTraverse(whileNode.Expr, ref inferedType);

                ProtoCore.DSASM.StackValue opCX = new ProtoCore.DSASM.StackValue();
                EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regCX);
                opCX.optype = ProtoCore.DSASM.AddressType.Register;
                opCX.opdata = (int)ProtoCore.DSASM.Registers.CX;
                EmitPop(opCX, Constants.kGlobalScope);

                L1 = pc + 1;
                L2 = ProtoCore.DSASM.Constants.kInvalidIndex;
                bp = pc;
                EmitCJmp(L1, L2, whileNode.Expr.line, whileNode.Expr.col, whileNode.Expr.endLine, whileNode.Expr.endCol);

                EmitSetExpressionUID(compileStateTracker.ExpressionUID++);

                /*
                {
                    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,
                        compileStateTracker.CodeBlockIndex++,
                        new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("while"), compileStateTracker.RuntimeTableIndex++),
                        null,
                        true);

                    localCodeBlock.instrStream = codeBlock.instrStream;
                    localCodeBlock.parent = codeBlock;
                    codeBlock.children.Add(localCodeBlock);
                    codeBlock = localCodeBlock;
                    compileStateTracker.CompleteCodeBlockList.Add(localCodeBlock);
                    backpatchMap.EntryTable[localCodeBlock.codeBlockId] = entry;
                    backpatchMap.BreakTable[localCodeBlock.codeBlockId] = new BackpatchTable();

                    EmitPushBlockID(localCodeBlock.codeBlockId);
                    foreach (ImperativeNode bodyNode in whileNode.Body)
                    {
                        inferedType = new ProtoCore.Type();
                        inferedType.UID = (int)PrimitiveType.kTypeVar;

                        if (bodyNode is LanguageBlockNode)
                        {
                            BinaryExpressionNode langBlockNode = new BinaryExpressionNode();
                            langBlockNode.LeftNode = nodeBuilder.BuildIdentfier(compileStateTracker.GenerateTempLangageVar());
                            langBlockNode.Optr = ProtoCore.DSASM.Operator.assign;
                            langBlockNode.RightNode = bodyNode;
                            DfsTraverse(langBlockNode, ref inferedType, isBooleanOp, graphNode);
                        }
                        else
                        {
                            DfsTraverse(bodyNode, ref inferedType, isBooleanOp, graphNode);
                        }
                    }

                    ProtoCore.AST.Node oldBlockNode = localCodeBlockNode;
                    localCodeBlockNode = node;
                    EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                    EmitRetcn(localCodeBlock.codeBlockId);
                    localCodeBlockNode = oldBlockNode;

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

                    EmitJmp(entry);
                    EmitPopBlockID();
                    Backpatch(backpatchMap.BreakTable[localCodeBlock.codeBlockId].backpatchList, pc);
                }
                Backpatch(bp, pc);
            }
        }
コード例 #24
0
ファイル: CoreUtils.cs プロジェクト: rafatahmed/Dynamo
        public static ProcedureNode GetFirstVisibleProcedure(string name, List<Type> argTypeList, CodeBlock codeblock)
        {
            if (null == codeblock)
            {
                return null;
            }

            CodeBlock searchBlock = codeblock;
            while (null != searchBlock)
            {
                if (null == searchBlock.procedureTable)
                {
                    searchBlock = searchBlock.parent;
                    continue;
                }

                // The class table is passed just to check for coercion values
                int procIndex = searchBlock.procedureTable.IndexOf(name, argTypeList);
                if (Constants.kInvalidIndex != procIndex)
                {
                    return searchBlock.procedureTable.procList[procIndex];
                }
                searchBlock = searchBlock.parent;
            }
            return null;
        }
コード例 #25
0
        public override bool Compile(out int blockId, ProtoCore.DSASM.CodeBlock parentBlock, ProtoCore.LanguageCodeBlock langBlock, ProtoCore.CompileTime.Context callContext, ProtoCore.DebugServices.EventSink sink = null, ProtoCore.AST.Node codeBlockNode = null, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            Validity.Assert(langBlock != null);
            blockId = ProtoCore.DSASM.Constants.kInvalidIndex;

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

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

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

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

                        core.assocCodegen.context = callContext;

                        blockId = core.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)
                        {
                            var p = ParserUtils.CreateParser(langBlock.body, core);
                            p.Parse();

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

                            codeBlockNode = p.root;

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

                        core.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 = core.assocCodegen.codeBlock;
                        if (core.ExecMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
                        {
                            int tempBlockId = core.GetCurrentBlockId();

                            ProtoCore.DSASM.CodeBlock tempCodeBlock = core.GetCodeBlock(core.CodeBlockList, tempBlockId);
                            while (null != tempCodeBlock && tempCodeBlock.blockType != ProtoCore.DSASM.CodeBlockType.kLanguage)
                            {
                                tempCodeBlock = tempCodeBlock.parent;
                            }
                            core.assocCodegen.codeBlock = tempCodeBlock;
                        }
                        core.assocCodegen.codeBlock.EventSink = sink;
                        if (core.BuildStatus.ErrorCount == 0) //if there is syntax error, no build needed
                        {
                            blockId = core.assocCodegen.Emit((codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode), graphNode);
                        }
                        if (core.ExecMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
                        {
                            blockId = core.assocCodegen.codeBlock.codeBlockId;
                            //Restore the code block.
                            core.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 && core.assocCodegen != oldCodegen)
                    {
                        core.assocCodegen = oldCodegen;
                    }
                }
                catch (ProtoCore.BuildHaltException)
                {
#if DEBUG
                    //core.BuildStatus.LogSemanticError(e.errorMsg);
#endif
                }

                buildSucceeded = core.BuildStatus.BuildSucceeded;
            }

            return(buildSucceeded);
        }
コード例 #26
0
ファイル: CodeGen.cs プロジェクト: joespiff/Dynamo
        private ProtoCore.DSASM.CodeBlock BuildNewCodeBlock(ProcedureTable procTable = null)
        {
            ProtoCore.DSASM.CodeBlock cb = new ProtoCore.DSASM.CodeBlock(
                context.guid,
                ProtoCore.DSASM.CodeBlockType.kLanguage,
                ProtoCore.Language.kImperative,
                core.CodeBlockIndex,
                new ProtoCore.DSASM.SymbolTable("imperative lang block", core.RuntimeTableIndex),
                new ProtoCore.DSASM.ProcedureTable(core.RuntimeTableIndex), 
                false, 
                core);

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

            return cb;
        }
コード例 #27
0
ファイル: CodeGen.cs プロジェクト: AutodeskFractal/Dynamo
        private void EmitIfStatementNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            int bp = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
            int L1 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;

            // If-expr
            IfStatementNode ifnode = node as IfStatementNode;
            DfsTraverse(ifnode.ifExprNode, ref inferedType, false, graphNode);
            L1 = ProtoCore.DSASM.Constants.kInvalidIndex;
            bp = pc;
            EmitCJmp(L1);


            // 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(
                context.guid,
                ProtoCore.DSASM.CodeBlockType.kConstruct,
                Language.NotSpecified,
                core.CodeBlockIndex++,
                new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("if"), core.RuntimeTableIndex++),
                null,
                false,
                core);


            localCodeBlock.instrStream = codeBlock.instrStream;
            localCodeBlock.parent = codeBlock;
            codeBlock.children.Add(localCodeBlock);
            codeBlock = localCodeBlock;

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


            L1 = ProtoCore.DSASM.Constants.kInvalidIndex;

            BackpatchTable backpatchTable = new BackpatchTable();
            backpatchTable.Append(pc, L1);
            EmitJmp(L1);

            // Backpatch the L2 destination of the if block
            Backpatch(bp, pc);


            /*		
            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


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

            Validity.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(
                    context.guid,
                    ProtoCore.DSASM.CodeBlockType.kConstruct,
                    Language.NotSpecified,
                    core.CodeBlockIndex++,
                    new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("else"), core.RuntimeTableIndex++),
                    null,
                    false,
                    core);

                localCodeBlock.instrStream = codeBlock.instrStream;
                localCodeBlock.parent = codeBlock;
                codeBlock.children.Add(localCodeBlock);
                codeBlock = localCodeBlock;
                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;

                L1 = ProtoCore.DSASM.Constants.kInvalidIndex;
                backpatchTable.Append(pc, L1);
                EmitJmp(L1);
            }

            /*
             * 
                      ->	backpatch(bpTable, pc) 
             */
            // ifstmt-exit
            // Backpatch all the previous unconditional jumps
            Backpatch(backpatchTable.backpatchList, pc);
        }
コード例 #28
0
ファイル: CodeGen.cs プロジェクト: rafatahmed/Dynamo
        private void EmitWhileStmtNode(ImperativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (core.IsParsingCodeBlockNode || core.IsParsingPreloadedAssembly)
            {
                return;
            }

            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                /*
                   
                while(E)	->	entry = pc
                                traverse E	
                                emit(pop,cx)
                                L1 = pc + 1
                                L2 = null 
                                bp = pc
                                emit(jmp, _cx, L1, L2) 

                 * */

                int bp = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int L1 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int entry = (int)ProtoCore.DSASM.Constants.kInvalidIndex;

                entry = pc;

                WhileStmtNode whileNode = node as WhileStmtNode;
                DfsTraverse(whileNode.Expr, ref inferedType);

                L1 = ProtoCore.DSASM.Constants.kInvalidIndex;
                bp = pc;
                EmitCJmp(L1, whileNode.Expr.line, whileNode.Expr.col, whileNode.Expr.endLine, whileNode.Expr.endCol);

                EmitSetExpressionUID(core.ExpressionUID++);

                /*
                {
                    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(
                        context.guid,
                        ProtoCore.DSASM.CodeBlockType.kConstruct,
                        Language.kInvalid,
                        core.CodeBlockIndex++,
                        new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("while"), core.RuntimeTableIndex++),
                        null,
                        true,
                        core);

                    core.CodeBlockIndex++;

                    localCodeBlock.instrStream = codeBlock.instrStream;
                    localCodeBlock.parent = codeBlock;
                    codeBlock.children.Add(localCodeBlock);
                    codeBlock = localCodeBlock;
                    backpatchMap.EntryTable[localCodeBlock.codeBlockId] = entry;
                    backpatchMap.BreakTable[localCodeBlock.codeBlockId] = new BackpatchTable();
                    
                    EmitPushBlockID(localCodeBlock.codeBlockId);
                    EmitCodeBlock(whileNode.Body, ref inferedType, isBooleanOp, graphNode);

                    ProtoCore.AST.Node oldBlockNode = localCodeBlockNode;
                    localCodeBlockNode = node;
                    EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                    EmitRetcn(localCodeBlock.codeBlockId);
                    localCodeBlockNode = oldBlockNode;


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

                    EmitJmp(entry);
                    Backpatch(backpatchMap.BreakTable[localCodeBlock.codeBlockId].backpatchList, pc);
                }
                Backpatch(bp, pc);
            }
        }