Exemplo n.º 1
0
        //------------------------------------------------------------
        // CParser.ParseObjectInitializer
        //
        /// <summary></summary>
        /// <param name="newNode"></param>
        //------------------------------------------------------------
        internal void ParseObjectInitializer(NEWNODE newNode)
        {
            DebugUtil.Assert(CurrentTokenID() == TOKENID.OPENCURLY);
            NextToken();

            DECLSTMTNODE stmtNode = AllocNode(NODEKIND.DECLSTMT, newNode) as DECLSTMTNODE;

            CListMaker list  = new CListMaker(this);
            int        comma = -1;

            while (
                CurrentTokenID() != TOKENID.CLOSECURLY &&
                CurrentTokenID() != TOKENID.ENDFILE)
            {
                if (CurrentTokenID() == TOKENID.IDENTIFIER &&
                    PeekToken(1) == TOKENID.EQUAL)
                {
                    list.Add(
                        ParseVariableDeclarator(
                            stmtNode,
                            stmtNode,
                            (uint)PARSEDECLFLAGS.LOCAL,
                            false,  // isFirst,
                            -1),
                        comma);
                }
                else
                {
                    Error(CSCERRID.ERR_InvalidInitializerDeclarator);

                    TOKENID tid = CurrentTokenID();
                    while (
                        tid != TOKENID.COMMA &&
                        tid != TOKENID.CLOSECURLY &&
                        tid != TOKENID.ENDFILE)
                    {
                        NextToken();
                        tid = CurrentTokenID();
                    }
                }

                if (CurrentTokenID() != TOKENID.COMMA)
                {
                    break;
                }
                comma = CurrentTokenIndex();
                NextToken();
            }
            Eat(TOKENID.CLOSECURLY);

            stmtNode.VariablesNode = list.GetList(stmtNode);
            newNode.InitialNode    = stmtNode;
            newNode.Flags         |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER;

            if (newNode.ParentNode != null &&
                newNode.ParentNode.Kind == NODEKIND.VARDECL)
            {
                VARDECLNODE vdNode = newNode.ParentNode as VARDECLNODE;
                if (vdNode != null)
                {
                    newNode.Flags   |= NODEFLAGS.NEW_IN_VARDECL;
                    vdNode.NewFlags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER;
                }
            }
            else if (newNode.ParentNode != null &&
                     newNode.ParentNode.Kind == NODEKIND.BINOP &&
                     newNode.Operator == OPERATOR.ASSIGN)
            {
                VARDECLNODE vdNode = newNode.ParentNode.ParentNode as VARDECLNODE;
                if (vdNode != null)
                {
                    newNode.Flags   |= NODEFLAGS.NEW_IN_VARDECL;
                    vdNode.NewFlags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER;
                }
            }

            BASENODE node = newNode.ParentNode;

            while (node != null && !node.IsStatement)
            {
                node = node.ParentNode;
            }
            if (node != null)
            {
                (node as STATEMENTNODE).NewFlags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER;
            }
        }
Exemplo n.º 2
0
        //------------------------------------------------------------
        // FUNCBREC.BindObjectInitializer
        //
        /// <summary></summary>
        /// <param name="newNode"></param>
        /// <param name="typeSym"></param>
        /// <param name="locVarSym"></param>
        /// <param name="objectExpr"></param>
        /// <param name="builder"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        internal EXPR BindObjectInitializer(
            NEWNODE newNode,
            TYPESYM typeSym,
            LOCVARSYM locVarSym,
            EXPR objectExpr,
            StatementListBuilder builder)
        {
            DebugUtil.Assert(newNode != null && typeSym != null && builder != null);
            DebugUtil.Assert(
                (locVarSym != null && objectExpr == null) ||
                (locVarSym == null && objectExpr != null));

            BindFlagsEnum bindFlags   = BindFlagsEnum.RValueRequired;
            string        localFormat = "<{0}><{1}>__local";

            //--------------------------------------------------------
            // Bind the local variable.
            //--------------------------------------------------------
            if (locVarSym == null)
            {
                string typeName = typeSym.IsAGGTYPESYM ?
                                  (typeSym as AGGTYPESYM).GetAggregate().Name :
                                  typeSym.Name;
                string locName = String.Format(localFormat, typeName, (this.localCount)++);

                locVarSym = Compiler.LocalSymbolManager.CreateLocalSym(
                    SYMKIND.LOCVARSYM,
                    locName,
                    this.currentScopeSym) as LOCVARSYM;
                locVarSym.TypeSym             = typeSym;
                locVarSym.LocSlotInfo.HasInit = true;
                locVarSym.DeclTreeNode        = newNode;

                StoreInCache(newNode, locName, locVarSym, null, true);
            }

            EXPR locVarExpr = BindToLocal(
                newNode,
                locVarSym,
                bindFlags | BindFlagsEnum.MemberSet);

            //--------------------------------------------------------
            // If objectExpr is not null, assign it to the local variable.
            //--------------------------------------------------------
            if (objectExpr != null)
            {
                EXPR assignLocExpr = BindAssignment(
                    newNode,
                    locVarExpr,
                    objectExpr,
                    false);

                builder.Add(SetNodeStmt(newNode, MakeStmt(newNode, assignLocExpr, 0)));
            }

            //--------------------------------------------------------
            // Assign each value.
            //--------------------------------------------------------
            DECLSTMTNODE decNode = newNode.InitialNode as DECLSTMTNODE;

            DebugUtil.Assert(decNode != null);
            BASENODE node = decNode.VariablesNode;

            while (node != null)
            {
                VARDECLNODE varDecl;
                if (node.Kind == NODEKIND.LIST)
                {
                    varDecl = node.AsLIST.Operand1 as VARDECLNODE;
                    node    = node.AsLIST.Operand2;
                }
                else
                {
                    varDecl = node as VARDECLNODE;
                    node    = null;
                }

                BINOPNODE assignNode = varDecl.ArgumentsNode as BINOPNODE;
                if (assignNode == null ||
                    assignNode.Operator != OPERATOR.ASSIGN ||
                    assignNode.Operand1 == null ||
                    assignNode.Operand1.Kind != NODEKIND.NAME ||
                    assignNode.Operand2 == null)
                {
                    continue;
                }

                //----------------------------------------------------
                // LHS
                //----------------------------------------------------
                NAMENODE nameNode = assignNode.Operand1 as NAMENODE;
                DebugUtil.Assert(nameNode != null);

                bindFlags = BindFlagsEnum.MemberSet;
                MemberLookup mem = new MemberLookup();

                EXPR leftExpr = null;
                if (mem.Lookup(
                        Compiler,
                        typeSym,
                        locVarExpr,
                        this.parentDeclSym,
                        nameNode.Name,
                        0,
                        MemLookFlagsEnum.UserCallable))
                {
                    SymWithType swt = mem.FirstSymWithType;
                    DebugUtil.Assert(swt != null && swt.IsNotNull);

                    switch (swt.Sym.Kind)
                    {
                    case SYMKIND.MEMBVARSYM:
                        leftExpr = BindToField(
                            assignNode,
                            locVarExpr,
                            FieldWithType.Convert(swt),
                            bindFlags);
                        break;

                    case SYMKIND.PROPSYM:
                        leftExpr = BindToProperty(
                            assignNode,
                            locVarExpr,
                            PropWithType.Convert(swt),
                            bindFlags,
                            null,
                            null);
                        break;

                    default:
                        leftExpr = NewError(nameNode, null);
                        break;
                    }
                }
                else
                {
                    mem.ReportErrors(nameNode);
                    leftExpr = NewError(nameNode, null);
                }

                //----------------------------------------------------
                // Collection initializer
                //----------------------------------------------------
                if (assignNode.Operand2.Kind == NODEKIND.ARRAYINIT)
                {
                    if (!leftExpr.TypeSym.IsARRAYSYM)
                    {
                        BindCollectionInitializer(
                            newNode,
                            (assignNode.Operand2 as UNOPNODE).Operand,
                            leftExpr.TypeSym, //typeSym,
                            null,             //locVarSym,
                            leftExpr,
                            null,
                            builder);
                        continue;
                    }
                }

                //----------------------------------------------------
                // RHS
                //----------------------------------------------------
                EXPR rightExpr = BindExpr(
                    assignNode.Operand2,
                    BindFlagsEnum.RValueRequired);

                //----------------------------------------------------
                // Assign
                //----------------------------------------------------
                EXPR assignExpr = BindAssignment(
                    assignNode,
                    leftExpr,
                    rightExpr,
                    false);

                builder.Add(SetNodeStmt(decNode, MakeStmt(decNode, assignExpr, 0)));
            }

            return(locVarExpr);
        }