// Delegates are really just blessed Types. void CreateProxyType(ISemanticResolver s) { Debug.Assert(m_nodeProxy == null, "only create proxy once"); // The delegate R F(A) (where R is a return type, and A is a parameter list) // Can be converted into the type: // sealed class F : System.MulticastDelegate { // F(object, native int) { } // BeginInvoke() { } // EndInvoke() { } // R Invoke(A) { } // } BlockStatement stmtEmpty = new BlockStatement(null, new Statement[0]); Modifiers modsPublic = new Modifiers(); modsPublic.SetPublic(); Modifiers modsVirtual = modsPublic; modsVirtual.SetVirtual(); //System.Type tNativeInt = typeof(int); System.Type tNativeInt = Type.GetType("System.IntPtr"); TypeEntry t_IAsyncResult = s.ResolveCLRTypeToBlueType(typeof(System.IAsyncResult)); // Create the parameters for the BeginInvoke() ParamVarDecl [] paramBeginInvoke = new ParamVarDecl[m_arParams.Length + 2]; m_arParams.CopyTo(paramBeginInvoke, 0); paramBeginInvoke[m_arParams.Length]= new ParamVarDecl( new Identifier("cb"), new ResolvedTypeSig(typeof(System.AsyncCallback), s), EArgFlow.cIn ); paramBeginInvoke[m_arParams.Length + 1] = new ParamVarDecl( new Identifier("state"), new ResolvedTypeSig(typeof(System.Object), s), EArgFlow.cIn ); m_nodeProxy = new ClassDecl( m_idName, new TypeSig[] { new ResolvedTypeSig(typeof(System.MulticastDelegate), s) }, new MethodDecl[] { // Ctor new MethodDecl( m_idName, null, new ParamVarDecl[] { new ParamVarDecl(new Identifier("instance"), new ResolvedTypeSig(typeof(object), s), EArgFlow.cIn), new ParamVarDecl(new Identifier("func"), new ResolvedTypeSig(tNativeInt, s), EArgFlow.cIn) }, stmtEmpty, modsPublic ), // Invoke, new MethodDecl( new Identifier("Invoke"), this.m_tRetType, this.m_arParams, stmtEmpty, modsVirtual), // Begin Invoke new MethodDecl( new Identifier("BeginInvoke"), new ResolvedTypeSig(t_IAsyncResult), paramBeginInvoke, stmtEmpty, modsVirtual), // End Invoke new MethodDecl( new Identifier("EndInvoke"), this.m_tRetType, new ParamVarDecl[] { new ParamVarDecl(new Identifier("result"), new ResolvedTypeSig(t_IAsyncResult), EArgFlow.cIn) }, stmtEmpty, modsVirtual) }, new PropertyDecl[0], new FieldDecl[0], new EventDecl[0], new TypeDeclBase[0], m_mods, true); // isClass }
//----------------------------------------------------------------------------- // list -> stmt stmt ... //----------------------------------------------------------------------------- protected BlockStatement ParseStatementList() { ArrayList alLocals = new ArrayList(); ArrayList alStatement = new ArrayList(); // Statement block begins with a '{' //ReadExpectedToken(Token.Type.cLCurly); // Read list of statements and local decls Token t = m_lexer.PeekNextToken(); // Keep reading statements until we find a closing '}' //while (t.TokenType != Token.Type.cRCurly) while ( (t.TokenType != Token.Type.cRCurly) && (t.TokenType != Token.Type.cCase) && (t.TokenType != Token.Type.cDefault)) { Statement s; LocalVarDecl v; ParseStatementOrLocal(out s, out v); if (s != null) alStatement.Add(s); if (v != null) alLocals.Add(v); t = m_lexer.PeekNextToken(); } // end while //ReadExpectedToken(Token.Type.cRCurly); LocalVarDecl [] arLocals = LocalVarDeclFromArray(alLocals); Statement[] arStmt = StatementFromArray(alStatement); BlockStatement block = new BlockStatement(arLocals, arStmt); return block; }
//----------------------------------------------------------------------------- // Parse a for-loop // --> 'for' '(' StmtExp:init ';' Exp:test ';' StmtExp:next ')' stmt ';' // --> 'for' '(' Type StmtExp:init '=' exp ';' Exp:test ';' StmtExp:next ')' stmt ';' // // If we declare a var in the initializer, then we return a BlockStatement // else we return a ForStatement //----------------------------------------------------------------------------- protected Statement ParseForStatement() { ReadExpectedToken(Token.Type.cFor); ReadExpectedToken(Token.Type.cLParen); // Initializer - could either be a StmtExp or a var declaration // Note that the var is local to the body statement of the loop, // not to anyone outside the loop //StatementExp seInit = ParseStatementExp(); //ReadExpectedToken(Token.Type.cSemi); Statement sInit; LocalVarDecl vInit; ParseStatementOrLocal(out sInit, out vInit); ExpStatement es = sInit as ExpStatement; if (es == null) ThrowError(E_BadForLoopInit(sInit.Location)); StatementExp seInit = es.StmtExp; // Test expression Exp eTest = ParseExp(); ReadExpectedToken(Token.Type.cSemi); // Update expression StatementExp seNext = ParseStatementExp(); ReadExpectedToken(Token.Type.cRParen); // Get body Statement stmtBody = ParseStatement(); Statement stmt = new ForStatement(seInit, eTest, seNext, stmtBody); // If we have a var decl, then put the for-loop in a block-statement // and add the var to that block statement if (vInit != null) { stmt = new BlockStatement(new LocalVarDecl[] { vInit }, new Statement[] { stmt }); } return stmt; }
//----------------------------------------------------------------------------- // Parse accessors // // *** rules *** // propertyBody -> 'get' block | 'set' block | // 'get' block 'set' block | // 'set' block 'get' block // // For an abstract property: // PropertyBody -> 'get' ';' | 'set' ';' | // 'get' ';' 'set' ';' | // 'set' ';' 'get' ';' //----------------------------------------------------------------------------- protected void ParseAccessors( bool fIsAbstract, Identifier stMemberName, out BlockStatement stmtGet, out bool fHasGet, out BlockStatement stmtSet, out bool fHasSet ) { // We've already parsed everything up until, but not including, the '{' ReadExpectedToken(Token.Type.cLCurly); stmtGet = null; stmtSet = null; fHasGet = false; fHasSet = false; Token t = m_lexer.GetNextToken(); // Parse the get/set accesssors while(t.TokenType != Token.Type.cRCurly) { switch(t.TokenType) { case Token.Type.cGet: if (fHasGet) ThrowError(E_AccessorAlreadyDefined(stMemberName, true)); fHasGet = true; if (fIsAbstract) ReadExpectedToken(Token.Type.cSemi); else stmtGet = ParseStatementBlock(); break; case Token.Type.cSet: if (fHasSet) ThrowError(E_AccessorAlreadyDefined(stMemberName, false)); fHasSet = true; if (fIsAbstract) ReadExpectedToken(Token.Type.cSemi); else stmtSet = ParseStatementBlock(); break; default: // error //this.ThrowError_UnexpectedToken(t, new Token.Type [] { Token.Type.cGet, Token.Type.cSet } ); ThrowError(E_UnexpectedToken(t, Token.Type.cGet, Token.Type.cSet)); break; } t = m_lexer.GetNextToken(); } // Already consumed the closing '}', so we're done. // So just do some error checks & create the ast node if (!fHasGet && !fHasSet) ThrowError(E_MissingAccessor(stMemberName)); }
// Must have a finally or at least one Catch (or both) public TryStatement( BlockStatement stmtTry, // never null CatchHandler [] arCatch, // can be null BlockStatement stmtFinally // can be null ) { Debug.Assert(stmtTry != null); // always have a try block Debug.Assert((arCatch != null && arCatch.Length > 0) || stmtFinally != null); m_stmtTry = stmtTry; m_arCatchHandlers = (arCatch == null) ? new CatchHandler[0] : arCatch; m_stmtFinally = stmtFinally; // @todo - this is wrong m_filerange = stmtTry.Location; }
public CatchHandler( TypeSig type, // type we're catching (must derived from System.Exception) Identifier idName, // optional (can be null) name for local var to store exception BlockStatement stmtBody // handler body (non-null) ) { Debug.Assert(stmtBody != null); // General catch blocks just becomes a System.Exception if (type == null) { m_type = new SimpleTypeSig(new DotObjExp( new SimpleObjExp(new Identifier("System", null)), new Identifier("Exception", null) )); } else { m_type = type; } m_idVarName = idName; m_body = stmtBody; }