void ASTVisitor.Accept(NodeTry value) { Accept(value); }
internal void Accept(NodeTry t) { // Disable scopes, we'll do them ourselves if (t.body is NodeBlock) (t.body as NodeBlock).createScope = false; if (t.handler is NodeBlock) (t.handler as NodeBlock).createScope = false; uint stackSize = builder.StackCount; // Start the exception handler uint handler = builder.OpPushExH(0); // Do things! t.body.isResultRequired = t.isResultRequired; t.body.inTailPosition = t.inTailPosition; builder.StartScope(); t.body.Visit(this); builder.EndScope(); // When we're done, skip the exception handling code uint pass = builder.OpJump(0); // This is where we'll go if we fail builder.SetOpC(handler, builder.InsnCount); // Begin our exception handling, which clears the stack to a certain point for us builder.OpBeginExH(stackSize); // Here, we have an exception! If we want it, assign it to our local var builder.StartScope(); if (t.exceptionName != null) { uint local; if (!builder.AddLocal(t.exceptionName, out local)) log.Error(t.location, "Duplicate local variable '{0}'.", t.exceptionName); builder.OpStoreEx(local); } // Start the exception handling code t.handler.isResultRequired = t.isResultRequired; t.handler.inTailPosition = t.inTailPosition; t.handler.Visit(this); builder.EndScope(); // Here's where we jump if we pass everything builder.SetOpC(pass, builder.InsnCount); }
private Node ParseTry() { var expr = new NodeTry(Location); Advance(); // what we're trying if (!TokensRemain) { log.Error(expr.location, "Expected an expression for 'try' block, but the end of the file was reached."); return expr; } expr.body = Expression(); Expect(CATCH, "Expected 'catch' block after try body."); if (Check(OPEN_BRACE)) { Advance(); string name; ExpectIdentifier(out name, "Identifier expected as exception variable name."); expr.exceptionName = name; Expect(CLOSE_BRACE, "A close brace (')') is expected to surround exception variable name."); } // what we're using to handle issues if (!TokensRemain) { log.Error(expr.location, "Expected an expression for 'catch' block, but the end of the file was reached."); return expr; } expr.handler = Expression(); return expr; }