public static FunctionDotCallNode GenerateCallDotNode(AssociativeNode lhs,
                                                              FunctionCallNode rhsCall, Core core = null)
        {
            // The function name to call
            string       rhsName = rhsCall.Function.Name;
            int          argNum  = rhsCall.FormalArguments.Count;
            ExprListNode argList = new ExprListNode();

            foreach (AssociativeNode arg in rhsCall.FormalArguments)
            {
                // The function arguments
                argList.Exprs.Add(arg);
            }

            var arguments = new List <AssociativeNode>();

            int    rhsIdx  = DSASM.Constants.kInvalidIndex;
            string lhsName = string.Empty;

            if (lhs is IdentifierNode)
            {
                lhsName = (lhs as IdentifierNode).Name;
                if (lhsName == DSDefinitions.Keyword.This)
                {
                    lhs = new ThisPointerNode();
                }
            }

            if (core != null)
            {
                DynamicFunction func;
                if (core.DynamicFunctionTable.TryGetFunction(rhsName, 0, Constants.kInvalidIndex, out func))
                {
                    rhsIdx = func.Index;
                }
                else
                {
                    func   = core.DynamicFunctionTable.AddNewFunction(rhsName, 0, Constants.kInvalidIndex);
                    rhsIdx = func.Index;
                }
            }

            // The first param to the dot arg (the pointer or the class name)
            arguments.Add(lhs);

            // The second param which is the dynamic table index of the function to call
            arguments.Add(new IntNode(rhsIdx));

            // The array dimensions
            ExprListNode arrayDimExperList = new ExprListNode();
            int          dimCount          = 0;

            if (rhsCall.Function is IdentifierNode)
            {
                // Number of dimensions
                IdentifierNode fIdent = rhsCall.Function as IdentifierNode;
                if (fIdent.ArrayDimensions != null)
                {
                    arrayDimExperList = CoreUtils.BuildArrayExprList(fIdent.ArrayDimensions);
                    dimCount          = arrayDimExperList.Exprs.Count;
                }
                else if (rhsCall.ArrayDimensions != null)
                {
                    arrayDimExperList = CoreUtils.BuildArrayExprList(rhsCall.ArrayDimensions);
                    dimCount          = arrayDimExperList.Exprs.Count;
                }
                else
                {
                    arrayDimExperList = new ExprListNode();
                }
            }

            arguments.Add(arrayDimExperList);

            // Number of dimensions
            var dimNode = new IntNode(dimCount);

            arguments.Add(dimNode);

            if (argNum >= 0)
            {
                arguments.Add(argList);
                arguments.Add(new IntNode(argNum));
            }

            var funDotCallNode = new FunctionDotCallNode(rhsCall, arguments);

            // funDotCallNode.FunctionCall.Function = rhsCall.Function;
            NodeUtils.SetNodeEndLocation(funDotCallNode, rhsCall);
            return(funDotCallNode);
        }
Example #2
0
        public static ProtoCore.AST.AssociativeAST.FunctionDotCallNode GenerateCallDotNode(ProtoCore.AST.AssociativeAST.AssociativeNode lhs,
                                                                                           ProtoCore.AST.AssociativeAST.FunctionCallNode rhsCall, Core core = null)
        {
            // The function name to call
            string rhsName = rhsCall.Function.Name;
            int    argNum  = rhsCall.FormalArguments.Count;

            ProtoCore.AST.AssociativeAST.ExprListNode argList = new ProtoCore.AST.AssociativeAST.ExprListNode();
            foreach (ProtoCore.AST.AssociativeAST.AssociativeNode arg in rhsCall.FormalArguments)
            {
                // The function arguments
                argList.list.Add(arg);
            }


            FunctionCallNode funCallNode = new FunctionCallNode();
            IdentifierNode   funcName    = new IdentifierNode {
                Value = Constants.kDotArgMethodName, Name = Constants.kDotArgMethodName
            };

            funCallNode.Function = funcName;
            funCallNode.Name     = Constants.kDotArgMethodName;

            NodeUtils.CopyNodeLocation(funCallNode, lhs);
            int    rhsIdx  = ProtoCore.DSASM.Constants.kInvalidIndex;
            string lhsName = string.Empty;

            if (lhs is ProtoCore.AST.AssociativeAST.IdentifierNode)
            {
                lhsName = (lhs as ProtoCore.AST.AssociativeAST.IdentifierNode).Name;
                if (lhsName == ProtoCore.DSDefinitions.Keyword.This)
                {
                    lhs = new ProtoCore.AST.AssociativeAST.ThisPointerNode();
                }
            }

            if (core != null)
            {
                DynamicFunction func;
                if (core.DynamicFunctionTable.TryGetFunction(rhsName, 0, Constants.kInvalidIndex, out func))
                {
                    rhsIdx = func.Index;
                }
                else
                {
                    func   = core.DynamicFunctionTable.AddNewFunction(rhsName, 0, Constants.kInvalidIndex);
                    rhsIdx = func.Index;
                }
            }

            // The first param to the dot arg (the pointer or the class name)
            funCallNode.FormalArguments.Add(lhs);

            // The second param which is the dynamic table index of the function to call
            var rhs = new IntNode(rhsIdx);

            funCallNode.FormalArguments.Add(rhs);

            // The array dimensions
            ProtoCore.AST.AssociativeAST.ExprListNode arrayDimExperList = new ProtoCore.AST.AssociativeAST.ExprListNode();
            int dimCount = 0;

            if (rhsCall.Function is ProtoCore.AST.AssociativeAST.IdentifierNode)
            {
                // Number of dimensions
                ProtoCore.AST.AssociativeAST.IdentifierNode fIdent = rhsCall.Function as ProtoCore.AST.AssociativeAST.IdentifierNode;
                if (fIdent.ArrayDimensions != null)
                {
                    arrayDimExperList = ProtoCore.Utils.CoreUtils.BuildArrayExprList(fIdent.ArrayDimensions);
                    dimCount          = arrayDimExperList.list.Count;
                }
                else if (rhsCall.ArrayDimensions != null)
                {
                    arrayDimExperList = ProtoCore.Utils.CoreUtils.BuildArrayExprList(rhsCall.ArrayDimensions);
                    dimCount          = arrayDimExperList.list.Count;
                }
                else
                {
                    arrayDimExperList = new ProtoCore.AST.AssociativeAST.ExprListNode();
                }
            }

            funCallNode.FormalArguments.Add(arrayDimExperList);

            // Number of dimensions
            var dimNode = new IntNode(dimCount);

            funCallNode.FormalArguments.Add(dimNode);

            if (argNum >= 0)
            {
                funCallNode.FormalArguments.Add(argList);
                funCallNode.FormalArguments.Add(new IntNode(argNum));
            }

            var funDotCallNode = new FunctionDotCallNode(rhsCall);

            funDotCallNode.DotCall = funCallNode;
            funDotCallNode.FunctionCall.Function = rhsCall.Function;

            // Consider the case of "myClass.Foo(a, b)", we will have "DotCall" being
            // equal to "myClass" (in terms of its starting line/column), and "rhsCall"
            // matching with the location of "Foo(a, b)". For execution cursor to cover
            // this whole statement, the final "DotCall" function call node should
            // range from "lhs.col" to "rhs.col".
            //
            NodeUtils.SetNodeEndLocation(funDotCallNode.DotCall, rhsCall);
            NodeUtils.CopyNodeLocation(funDotCallNode, funDotCallNode.DotCall);


            return(funDotCallNode);
        }
Example #3
0
        private static void ParseUserCodeCore(Core core, string expression, out List <AssociativeNode> astNodes, out List <AssociativeNode> commentNodes)
        {
            astNodes = new List <AssociativeNode>();

            core.ResetForPrecompilation();
            core.IsParsingCodeBlockNode = true;
            core.ParsingMode            = ParseMode.AllowNonAssignment;

            ParseResult parseResult = ParserUtils.ParseWithCore(expression, core);

            commentNodes = ParserUtils.GetAstNodes(parseResult.CommentBlockNode);
            var nodes = ParserUtils.GetAstNodes(parseResult.CodeBlockNode);

            Validity.Assert(nodes != null);

            int index           = 0;
            int typedIdentIndex = 0;

            foreach (var node in nodes)
            {
                var n = node as AssociativeNode;
                Validity.Assert(n != null);

                // Append the temporaries only if it is not a function def or class decl
                bool isFunctionOrClassDef = n is FunctionDefinitionNode || n is ClassDeclNode;

                // Handle non Binary expression nodes separately
                if (n is ModifierStackNode)
                {
                    core.BuildStatus.LogSemanticError(Resources.ModifierBlockNotSupported);
                }
                else if (n is ImportNode)
                {
                    core.BuildStatus.LogSemanticError(Resources.ImportStatementNotSupported);
                }
                else if (isFunctionOrClassDef)
                {
                    // Add node as it is
                    astNodes.Add(node);
                }
                else
                {
                    // Handle temporary naming for temporary Binary exp. nodes and non-assignment nodes
                    var ben = node as BinaryExpressionNode;
                    if (ben != null && ben.Optr == Operator.assign)
                    {
                        var mNode = ben.RightNode as ModifierStackNode;
                        if (mNode != null)
                        {
                            core.BuildStatus.LogSemanticError(Resources.ModifierBlockNotSupported);
                        }
                        var lNode = ben.LeftNode as IdentifierNode;
                        if (lNode != null && lNode.Value == Constants.kTempProcLeftVar)
                        {
                            string name    = Constants.kTempVarForNonAssignment + index;
                            var    newNode = new BinaryExpressionNode(new IdentifierNode(name), ben.RightNode);
                            astNodes.Add(newNode);
                            index++;
                        }
                        else
                        {
                            // Add node as it is
                            astNodes.Add(node);
                            index++;
                        }
                    }
                    else
                    {
                        if (node is TypedIdentifierNode)
                        {
                            // e.g. a : int = %tTypedIdent_<Index>;
                            var ident = new IdentifierNode(Constants.kTempVarForTypedIdentifier + typedIdentIndex);
                            NodeUtils.CopyNodeLocation(ident, node);
                            var typedNode = new BinaryExpressionNode(node as TypedIdentifierNode, ident, Operator.assign);
                            NodeUtils.CopyNodeLocation(typedNode, node);
                            astNodes.Add(typedNode);
                            typedIdentIndex++;
                        }
                        else
                        {
                            string name    = Constants.kTempVarForNonAssignment + index;
                            var    newNode = new BinaryExpressionNode(new IdentifierNode(name), n);
                            astNodes.Add(newNode);
                            index++;
                        }
                    }
                }
            }
        }