// Allow safe resolving on Statement Exp. Allowed to change to another StmtExp public static void ResolveExpAsRight(ref StatementExp se, ISemanticResolver s) { Exp e = se; Exp.ResolveExpAsRight(ref e, s); if (e is StatementExp) se = (StatementExp) e; else Debug.Assert(false, "Shouldn't have resolved to a non-stmtexp"); Debug.Assert(se != null); }
// <e0, e1, e2 .... en> // e_0 .. e_n-1 are StatementExp, that generate as Statements (to produce side effects) // e_n is a normal expression, generated as an expression, to produce a value public CompoundStmtExp( StatementExp [] eList, Exp eLast ) { Debug.Assert(eList != null); Debug.Assert(eLast != null); m_eList = eList; m_eLast = eLast; }
// Resolve protected override Exp ResolveExpAsRight(ISemanticResolver s) { if (m_symbol != null) return this; // Resolve the type we're allocating m_tFullType.ResolveType(s); Debug.Assert(this.ElemType != null); // Resolve the initializer list if (HasInitializerList) { // If we specified a length, it'd better match the intializer list length. if (DimensionExpList != null) { Debug.Assert(this.DimensionExpList.Length == 1, "@todo -multidimensional arrays"); Exp e = DimensionExpList[0]; // e must be a compile time constant who's value matches the ArrayInit length IntExp eInt = e as IntExp; if (eInt == null) ThrowError(SymbolError.MustBeCompileTimeConstant(e)); if (eInt.Value != m_ArrayInit.Length) ThrowError(SymbolError.NewArrayBoundsMismatch(this)); } m_ArrayInit.Resolve(s, this.ElemType); // The ability to not specifiy a dimension list is just syntactic sugar. // So if we still don't have it, we'd better fill it in based of the array-init list. if (DimensionExpList == null) { m_arExpList = new Exp[] { new IntExp(m_ArrayInit.Length, this.Location) }; } } Debug.Assert(DimensionExpList != null); for(int i = 0; i < this.m_arExpList.Length; i++) { ResolveExpAsRight(ref m_arExpList[i], s); } m_symbol = new ArrayTypeEntry(m_tFullType, s); CalcCLRType(s); // Transform an initializer list into an CompoundExpression: // new T[] { e0, e1, ... en} // <DeclareTemp(x), x = new T[], x[0]=e0, ... x[n]=en, x> if (HasInitializerList) { DeclareLocalStmtExp declare_x = new DeclareLocalStmtExp(this.ArraySymbol); LocalExp x = declare_x.GetLocal(); StatementExp [] list = new StatementExp[m_ArrayInit.Length + 2]; list[0] = declare_x; list[1] = new AssignStmtExp(x, this); for(int i = 0; i < m_ArrayInit.Length; i++) list[i + 2] = new AssignStmtExp( new ArrayAccessExp( x, new IntExp(i, null) ), m_ArrayInit.GetExpAt(i) ); // Strip the ArrayInitializer off this node. m_ArrayInit = null; StatementExp c = new CompoundStmtExp(list, x); StatementExp.ResolveExpAsRight(ref c, s); return c; } // end has Initializer return this; }