- Fixed baseline aligning calcs
[mono.git] / mcs / mbas / statement.cs
index c5d9ef9ffefdb0cf8597249a2aa1d633063b371d..de580cd2f01c40c5f683eb422f6d8f51f5cb0ee9 100644 (file)
@@ -4,6 +4,7 @@
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
 //   Martin Baulig (martin@gnome.org)
+//      Anirban Bhattacharjee (banirban@novell.com)
 //
 // (C) 2001, 2002 Ximian, Inc.
 //
@@ -936,7 +937,7 @@ namespace Mono.MonoBASIC {
                                if ((t != TypeManager.exception_type) &&
                                    !t.IsSubclassOf (TypeManager.exception_type) &&
                                    !(expr is NullLiteral)) {
-                                       Report.Error (155, loc,
+                                       Report.Error (30665, loc,
                                                      "The type caught or thrown must be derived " +
                                                      "from System.Exception");
                                        return false;
@@ -1032,9 +1033,18 @@ namespace Mono.MonoBASIC {
                {
                        ILGenerator ig = ec.ig;
 
-                       if (type != ExitType.SUB && type != ExitType.FUNCTION && type != ExitType.PROPERTY) {
+                       if (type != ExitType.SUB && type != ExitType.FUNCTION && 
+                               type != ExitType.PROPERTY && type != ExitType.TRY) {
                                if (ec.InLoop == false && ec.Switch == null){
-                                       Report.Error (139, loc, "No enclosing loop or switch to exit from");
+                                       if (type == ExitType.FOR)
+                                               Report.Error (30096, loc, "No enclosing FOR loop to exit from");
+                                       if (type == ExitType.WHILE) \r
+                                               Report.Error (30097, loc, "No enclosing WHILE loop to exit from");
+                                       if (type == ExitType.DO)
+                                               Report.Error (30089, loc, "No enclosing DO loop to exit from");
+                                       if (type == ExitType.SELECT)
+                                               Report.Error (30099, loc, "No enclosing SELECT to exit from");
+
                                        return false;
                                }
 
@@ -1044,7 +1054,8 @@ namespace Mono.MonoBASIC {
                                        ig.Emit (OpCodes.Br, ec.LoopEnd);
                        } else {                        
                                if (ec.InFinally){
-                                       Report.Error (157,loc,"Control can not leave the body of the finally block");
+                                       Report.Error (30393, loc, 
+                                               "Control can not leave the body of the finally block");
                                        return false;
                                }
                        
@@ -4438,16 +4449,19 @@ namespace Mono.MonoBASIC {
        public class Catch {
                public readonly string Name;
                public readonly Block  Block;
+               public Expression Clause;
                public readonly Location Location;
 
                Expression type_expr;
+               //Expression clus_expr;
                Type type;
                
-               public Catch (Expression type, string name, Block block, Location l)
+               public Catch (Expression type, string name, Block block, Expression clause, Location l)
                {
                        type_expr = type;
                        Name = name;
                        Block = block;
+                       Clause = clause;
                        Location = l;
                }
 
@@ -4471,7 +4485,7 @@ namespace Mono.MonoBASIC {
                                        return false;
 
                                if (type != TypeManager.exception_type && !type.IsSubclassOf (TypeManager.exception_type)){
-                                       Report.Error (155, Location,
+                                       Report.Error (30665, Location,
                                                      "The type caught or thrown must be derived " +
                                                      "from System.Exception");
                                        return false;
@@ -4479,6 +4493,13 @@ namespace Mono.MonoBASIC {
                        } else
                                type = null;
 
+                       if (Clause != null)     {
+                               Clause = Statement.ResolveBoolean (ec, Clause, Location);
+                               if (Clause == null) {
+                                       return false;
+                               }
+                       }
+
                        if (!Block.Resolve (ec))
                                return false;
 
@@ -4640,17 +4661,47 @@ namespace Mono.MonoBASIC {
                                        ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
                                } else
                                        ig.Emit (OpCodes.Pop);
-                               
-                               if (!c.Block.Emit (ec))
-                                       returns = false;
+
+                               //
+                               // if when clause is there
+                               //
+                               if (c.Clause != null) {
+                                       if (c.Clause is BoolConstant) {
+                                               bool take = ((BoolConstant) c.Clause).Value;
+
+                                               if (take) 
+                                                       if (!c.Block.Emit (ec))
+                                                               returns = false;
+                                       } else {
+                                               EmitBoolExpression (ec, c.Clause, finish, false);
+                                               if (!c.Block.Emit (ec))
+                                                       returns = false;
+                                       }
+                               } else 
+                                       if (!c.Block.Emit (ec))
+                                               returns = false;
                        }
 
                        if (General != null){
                                ig.BeginCatchBlock (TypeManager.object_type);
                                ig.Emit (OpCodes.Pop);
-                               if (!General.Block.Emit (ec))
-                                       returns = false;
+
+                               if (General.Clause != null) {
+                                       if (General.Clause is BoolConstant) {
+                                               bool take = ((BoolConstant) General.Clause).Value;
+                                               if (take) 
+                                                       if (!General.Block.Emit (ec))
+                                                               returns = false;
+                                       } else {
+                                               EmitBoolExpression (ec, General.Clause, finish, false);
+                                               if (!General.Block.Emit (ec))
+                                                       returns = false;
+                                       }
+                               } else 
+                                       if (!General.Block.Emit (ec))
+                                               returns = false;
                        }
+
                        ec.InCatch = old_in_catch;
 
                        ig.MarkLabel (finish);
@@ -5445,19 +5496,16 @@ namespace Mono.MonoBASIC {
        public class AddHandler : Statement {
                Expression EvtId;
                Expression EvtHandler;
-               Expression EvtTarget;
 
                //
                // keeps track whether EvtId is already resolved
                //
                bool resolved;
 
-               public AddHandler (Expression evt_id, Expression evt_handler, 
-                                                       Expression evt_target, Location l)
+               public AddHandler (Expression evt_id, Expression evt_handler, Location l)
                {
                        EvtId = evt_id;
                        EvtHandler = evt_handler;
-                       EvtTarget = evt_target;
                        loc = l;
                        resolved = false;
                        //Console.WriteLine ("Adding handler '" + evt_handler + "' for Event '" + evt_id +"'");
@@ -5476,7 +5524,6 @@ namespace Mono.MonoBASIC {
 
                        EvtId = EvtId.Resolve(ec);
                        EvtHandler = EvtHandler.Resolve(ec,ResolveFlags.MethodGroup);
-                       EvtTarget = EvtTarget.Resolve (ec,ResolveFlags.VariableOrValue);
                        if (EvtId == null || (!(EvtId is EventExpr))) {
                                Report.Error (30676, "Need an event designator.");
                                return false;
@@ -5487,10 +5534,7 @@ namespace Mono.MonoBASIC {
                                Report.Error (999, "'AddHandler' statement needs an event handler.");
                                return false;
                        }
-                       //EventExpr ee = (EventExpr) EvtId;
-                       //MethodGroupExpr me = (MethodGroupExpr) EvtHandler;
-                       //bool b = EvtId.Type.IsSubclassOf (TypeManager.delegate_type);
-                       //ee.EventInfo.AddEventHandler(EvtTarget, new System.Delegate())
+
                        return true;
                }
 
@@ -5539,14 +5583,11 @@ namespace Mono.MonoBASIC {
        {
                Expression EvtId;
                Expression EvtHandler;
-               Expression EvtTarget;
 
-               public RemoveHandler (Expression evt_id, Expression evt_handler, 
-                       Expression evt_target, Location l)
+               public RemoveHandler (Expression evt_id, Expression evt_handler, Location l)
                {
                        EvtId = evt_id;
                        EvtHandler = evt_handler;
-                       EvtTarget = evt_target;
                        loc = l;
                }
 
@@ -5554,7 +5595,6 @@ namespace Mono.MonoBASIC {
                {
                        EvtId = EvtId.Resolve(ec);
                        EvtHandler = EvtHandler.Resolve(ec,ResolveFlags.MethodGroup);
-                       EvtTarget = EvtTarget.Resolve (ec,ResolveFlags.VariableOrValue);
                        if (EvtId == null || (!(EvtId is EventExpr))) \r
                        {
                                Report.Error (30676, "Need an event designator.");
@@ -5659,10 +5699,8 @@ namespace Mono.MonoBASIC {
                                // TODO: we are in a foreach we probably can't reuse ReDimExpr, must turn it into an array(list)
                                if (Preserve)
                                {
-                                       // TODO: Generate call to copying code, which has to make lots of verifications
-                                       //PreserveExpr = (ExpressionStatement) new Preserve(RedimTarget, acExpr, loc);
-                                       //ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, PreserveExpr, loc), loc);
-                                       ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, acExpr, loc), loc);
+                                       ExpressionStatement PreserveExpr = (ExpressionStatement) new Preserve(RedimTarget, acExpr, loc);
+                                       ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, PreserveExpr, loc), loc);
                                }
                                else
                                        ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, acExpr, loc), loc);