add exception handling support to the parser update
authorJürg Billeter <j@bitron.ch>
Mon, 5 Mar 2007 21:23:00 +0000 (21:23 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Mon, 5 Mar 2007 21:23:00 +0000 (21:23 +0000)
2007-03-05  Jürg Billeter  <j@bitron.ch>

* vala/scanner.l, vala/parser.y, vala/valacatchclause.vala,
  vala/valathrowstatement.vala, vala/valatrystatement.vala,
  vala/valacodevisitor.vala: add exception handling support to the
  parser
* vala/vala.h, vala/Makefile.am: update

svn path=/trunk/; revision=225

vala/ChangeLog
vala/vala/Makefile.am
vala/vala/parser.y
vala/vala/scanner.l
vala/vala/vala.h
vala/vala/valacatchclause.vala [new file with mode: 0644]
vala/vala/valacodevisitor.vala
vala/vala/valathrowstatement.vala [new file with mode: 0644]
vala/vala/valatrystatement.vala [new file with mode: 0644]

index 5dd80d1..7079662 100644 (file)
@@ -1,3 +1,11 @@
+2007-03-05  Jürg Billeter  <j@bitron.ch>
+
+       * vala/scanner.l, vala/parser.y, vala/valacatchclause.vala,
+         vala/valathrowstatement.vala, vala/valatrystatement.vala,
+         vala/valacodevisitor.vala: add exception handling support to the
+         parser
+       * vala/vala.h, vala/Makefile.am: update
+
 2007-03-05  Raffaele Sandrini  <rasa@gmx.ch>
 
        * vala/valainterfaceregisterfunction.vala: add
index 304ef43..e44686c 100644 (file)
@@ -58,6 +58,9 @@ libvala_la_SOURCES = \
        valacastexpression.c \
        valacastexpression.h \
        valacastexpression.vala \
+       valacatchclause.c \
+       valacatchclause.h \
+       valacatchclause.vala \
        valacharacterliteral.c \
        valacharacterliteral.h \
        valacharacterliteral.vala \
@@ -283,6 +286,12 @@ libvala_la_SOURCES = \
        valasymbolresolver.c \
        valasymbolresolver.h \
        valasymbolresolver.vala \
+       valathrowstatement.c \
+       valathrowstatement.h \
+       valathrowstatement.vala \
+       valatrystatement.c \
+       valatrystatement.h \
+       valatrystatement.vala \
        valatypecheck.c \
        valatypecheck.h \
        valatypecheck.vala \
@@ -325,6 +334,7 @@ valainclude_HEADERS = \
        valabreakstatement.h \
        valacallback.h \
        valacastexpression.h \
+       valacatchclause.h \
        valacharacterliteral.h \
        valaclass.h \
        valaclassregisterfunction.h \
@@ -400,6 +410,8 @@ valainclude_HEADERS = \
        valasymbolbuilder.h \
        valasymbol.h \
        valasymbolresolver.h \
+       valathrowstatement.h \
+       valatrystatement.h \
        valatypecheck.h \
        valatypeofexpression.h \
        valatypeparameter.h \
index 57c5a78..7ba0211 100644 (file)
@@ -93,6 +93,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
        ValaNamedArgument *named_argument;
        ValaSwitchSection *switch_section;
        ValaSwitchLabel *switch_label;
+       ValaCatchClause *catch_clause;
 }
 
 %token OPEN_BRACE "{"
@@ -153,6 +154,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %token BREAK "break"
 %token CALLBACK "callback"
 %token CASE "case"
+%token CATCH "catch"
 %token CLASS "class"
 %token CONST "const"
 %token CONSTRUCT "construct"
@@ -162,6 +164,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %token ELSE "else"
 %token ENUM "enum"
 %token VALA_FALSE "false"
+%token FINALLY "finally"
 %token FLAGS "flags"
 %token FOR "for"
 %token FOREACH "foreach"
@@ -187,7 +190,10 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %token STRUCT "struct"
 %token SWITCH "switch"
 %token THIS "this"
+%token THROW "throw"
+%token THROWS "throws"
 %token VALA_TRUE "true"
+%token TRY "try"
 %token TYPEOF "typeof"
 %token USING "using"
 %token VAR "var"
@@ -284,6 +290,15 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %type <statement> break_statement
 %type <statement> continue_statement
 %type <statement> return_statement
+%type <statement> throw_statement
+%type <statement> try_statement
+%type <list> catch_clauses
+%type <list> specific_catch_clauses
+%type <catch_clause> specific_catch_clause
+%type <catch_clause> opt_general_catch_clause
+%type <catch_clause> general_catch_clause
+%type <statement> opt_finally_clause
+%type <statement> finally_clause
 %type <statement> lock_statement
 %type <namespace> namespace_declaration
 %type <str> opt_name_specifier
@@ -327,6 +342,8 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %type <num> opt_construct
 %type <list> fixed_parameters
 %type <formal_parameter> fixed_parameter
+%type <list> opt_throws_declaration
+%type <list> throws_declaration
 %type <signal> signal_declaration
 %type <constructor> constructor_declaration
 %type <destructor> destructor_declaration
@@ -1231,6 +1248,7 @@ statement
        | selection_statement
        | iteration_statement
        | jump_statement
+       | try_statement
        | lock_statement
        ;
 
@@ -1276,6 +1294,14 @@ embedded_statement
                g_object_unref ($1);
                g_object_unref (src);
          }
+       | try_statement
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = VALA_STATEMENT (vala_block_new (src));
+               vala_block_add_statement (VALA_BLOCK ($$), $1);
+               g_object_unref ($1);
+               g_object_unref (src);
+         }
        | lock_statement
          {
                ValaSourceReference *src = src(@1);
@@ -1716,6 +1742,7 @@ jump_statement
        : break_statement
        | continue_statement
        | return_statement
+       | throw_statement
        ;
 
 break_statement
@@ -1748,6 +1775,117 @@ return_statement
          }
        ;
 
+throw_statement
+       : THROW expression SEMICOLON
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = VALA_STATEMENT (vala_throw_statement_new ($2, src));
+               g_object_unref (src);
+               if ($2 != NULL) {
+                       g_object_unref ($2);
+               }
+         }
+       ;
+
+try_statement
+       : TRY block catch_clauses opt_finally_clause
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = VALA_STATEMENT (vala_try_statement_new (VALA_BLOCK ($2), VALA_BLOCK ($4), src));
+               g_object_unref ($2);
+               if ($4 != NULL) {
+                       g_object_unref ($4);
+               }
+               g_object_unref (src);
+
+               GList *l;
+               for (l = $3; l != NULL; l = l->next) {
+                       vala_try_statement_add_catch_clause (VALA_TRY_STATEMENT ($$), l->data);
+                       g_object_unref (l->data);
+               }
+               g_list_free ($3);
+         }
+       | TRY block finally_clause
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = VALA_STATEMENT (vala_try_statement_new (VALA_BLOCK ($2), VALA_BLOCK ($3), src));
+               g_object_unref ($2);
+               g_object_unref ($3);
+               g_object_unref (src);
+         }
+       ;
+
+catch_clauses
+       : specific_catch_clauses opt_general_catch_clause
+         {
+               if ($2 != NULL) {
+                       $$ = g_list_append ($1, $2);
+               } else {
+                       $$ = $1;
+               }
+         }
+       | general_catch_clause
+         {
+               $$ = g_list_append (NULL, $1);
+         }
+       ;
+
+specific_catch_clauses
+       : specific_catch_clause
+         {
+               $$ = g_list_append (NULL, $1);
+         }
+       | specific_catch_clauses specific_catch_clause
+         {
+               $$ = g_list_append ($1, $2);
+         }
+       ;
+
+specific_catch_clause
+       : CATCH OPEN_PARENS type IDENTIFIER CLOSE_PARENS block
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = vala_catch_clause_new ($3, $4, VALA_BLOCK ($6), src);
+               g_object_unref ($3);
+               g_free ($4);
+               g_object_unref ($6);
+               g_object_unref (src);
+         }
+       ;
+
+opt_general_catch_clause
+       : /* empty */
+         {
+               $$ = NULL;
+         }
+       | general_catch_clause
+       ;
+
+general_catch_clause
+       : CATCH block
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = vala_catch_clause_new (NULL, NULL, VALA_BLOCK ($2), src);
+               g_object_unref ($2);
+               g_object_unref (src);
+         }
+       ;
+opt_finally_clause
+       : /* empty */
+         {
+               $$ = NULL;
+         }
+       | finally_clause
+       ;
+
+
+finally_clause
+       : FINALLY block
+         {
+               $$ = $2;
+         }
+       ;
+
 lock_statement
        : comment LOCK OPEN_PARENS expression CLOSE_PARENS embedded_statement
          {
@@ -2307,7 +2445,7 @@ method_declaration
        ;
 
 method_header
-       : comment opt_attributes opt_access_modifier opt_modifiers type IDENTIFIER OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+       : comment opt_attributes opt_access_modifier opt_modifiers type IDENTIFIER OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_throws_declaration
          {
                GList *l;
                
@@ -2458,6 +2596,21 @@ fixed_parameter
          }
        ;
 
+opt_throws_declaration
+       : /* empty */
+         {
+               $$ = NULL;
+         }
+       | throws_declaration
+       ;
+
+throws_declaration
+       : THROWS type_list
+         {
+               $$ = $2;
+         }
+       ;
+
 property_declaration
        : comment opt_attributes opt_access_modifier opt_modifiers type IDENTIFIER OPEN_BRACE get_accessor_declaration opt_set_accessor_declaration CLOSE_BRACE
          {
@@ -3158,7 +3311,7 @@ static void
 yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg)
 {
        ValaSourceReference *source_reference = vala_source_reference_new (current_source_file, locp->first_line, locp->first_column, locp->last_line, locp->last_column);
-       vala_report_error (source_reference, msg);
+       vala_report_error (source_reference, (char *) msg);
 }
 
 void
index 585f952..1061d57 100644 (file)
@@ -131,6 +131,7 @@ literal                             ({integer_literal}|{real_literal}|{character_literal}|{string_literal
 "break"                { uploc; return BREAK; }
 "callback"     { uploc; return CALLBACK; }
 "case"         { uploc; return CASE; }
+"catch"                { uploc; return CATCH; }
 "class"                { uploc; return CLASS; }
 "const"                { uploc; return CONST; }
 "construct"    { uploc; return CONSTRUCT; }
@@ -140,6 +141,7 @@ literal                             ({integer_literal}|{real_literal}|{character_literal}|{string_literal
 "else"         { uploc; return ELSE; }
 "enum"         { uploc; return ENUM; }
 "false"                { uploc; return VALA_FALSE; }
+"finally"      { uploc; return FINALLY; }
 "flags"                { uploc; return FLAGS; }
 "for"          { uploc; return FOR; }
 "foreach"      { uploc; return FOREACH; }
@@ -165,7 +167,10 @@ literal                            ({integer_literal}|{real_literal}|{character_literal}|{string_literal
 "switch"       { uploc; return SWITCH; }
 "return"       { uploc; return RETURN; }
 "this"         { uploc; return THIS; }
+"throw"                { uploc; return THROW; }
+"throws"       { uploc; return THROWS; }
 "true"         { uploc; return VALA_TRUE; }
+"try"          { uploc; return TRY; }
 "typeof"       { uploc; return TYPEOF; }
 "using"                { uploc; return USING; }
 "var"          { uploc; return VAR; }
index d01ecaa..3909e10 100644 (file)
@@ -8,6 +8,7 @@
 #include <vala/valabreakstatement.h>
 #include <vala/valacallback.h>
 #include <vala/valacastexpression.h>
+#include <vala/valacatchclause.h>
 #include <vala/valacharacterliteral.h>
 #include <vala/valaclass.h>
 #include <vala/valacodecontext.h>
@@ -63,6 +64,8 @@
 #include <vala/valaswitchlabel.h>
 #include <vala/valaswitchsection.h>
 #include <vala/valaswitchstatement.h>
+#include <vala/valathrowstatement.h>
+#include <vala/valatrystatement.h>
 #include <vala/valatypecheck.h>
 #include <vala/valatypeofexpression.h>
 #include <vala/valatypeparameter.h>
diff --git a/vala/vala/valacatchclause.vala b/vala/vala/valacatchclause.vala
new file mode 100644 (file)
index 0000000..3c8af19
--- /dev/null
@@ -0,0 +1,69 @@
+/* valacatchclause.vala
+ *
+ * Copyright (C) 2007  Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Represents a catch clause in a try statement in the source code.
+ */
+public class Vala.CatchClause : CodeNode {
+       /**
+        * Specifies the error type.
+        */
+       public TypeReference type_reference { get; set; }
+       
+       /**
+        * Specifies the error variable name.
+        */
+       public string variable_name { get; set; }
+       
+       /**
+        * Specifies the error handler body.
+        */
+       public Block body { get; set; }
+       
+       /**
+        * Specifies the declarator for the generated error variable.
+        */
+       public VariableDeclarator variable_declarator { get; set; }
+
+       /**
+        * Creates a new catch clause.
+        *
+        * @param type_reference   error type
+        * @param variable_name    error variable name
+        * @param body             error handler body
+        * @param source_reference reference to source code
+        * @return                 newly created catch clause
+        */
+       public CatchClause (construct TypeReference type_reference, construct string variable_name, construct Block body, construct SourceReference source_reference = null) {
+       }
+
+       public override void accept (CodeVisitor! visitor) {
+               visitor.visit_begin_catch_clause (this);
+
+               type_reference.accept (visitor);
+               body.accept (visitor);
+
+               visitor.visit_end_catch_clause (this);
+       }
+}
index 2fc4885..08110f0 100644 (file)
@@ -516,19 +516,67 @@ public abstract class Vala.CodeVisitor {
        }
        
        /**
-        * Visit operation called for lock statements before the body has been visited.
+        * Visit operation called at end of return statements.
         *
-        * @param stmt a lock statement
+        * @param stmt a return statement
         */
-       public virtual void visit_lock_statement (LockStatement! stmt) {
+       public virtual void visit_end_return_statement (ReturnStatement! stmt) {
+       }
+
+       /**
+        * Visit operation called at beginning of throw statements.
+        *
+        * @param stmt a throw statement
+        */
+       public virtual void visit_begin_throw_statement (ThrowStatement! stmt) {
+       }
+
+       /**
+        * Visit operation called at end of throw statements.
+        *
+        * @param stmt a throw statement
+        */
+       public virtual void visit_end_throw_statement (ThrowStatement! stmt) {
+       }
+
+       /**
+        * Visit operation called at beginning of try statements.
+        *
+        * @param stmt a try statement
+        */
+       public virtual void visit_begin_try_statement (TryStatement! stmt) {
+       }
+
+       /**
+        * Visit operation called at end of try statements.
+        *
+        * @param stmt a try statement
+        */
+       public virtual void visit_end_try_statement (TryStatement! stmt) {
+       }
+
+       /**
+        * Visit operation called at beginning of catch clauses.
+        *
+        * @param clause a catch cluase
+        */
+       public virtual void visit_begin_catch_clause (CatchClause! clause) {
+       }
+
+       /**
+        * Visit operation called at end of catch clauses.
+        *
+        * @param clause a catch clause
+        */
+       public virtual void visit_end_catch_clause (CatchClause! clause) {
        }
        
        /**
-        * Visit operation called at end of return statements.
+        * Visit operation called for lock statements before the body has been visited.
         *
-        * @param stmt a return statement
+        * @param stmt a lock statement
         */
-       public virtual void visit_end_return_statement (ReturnStatement! stmt) {
+       public virtual void visit_lock_statement (LockStatement! stmt) {
        }
        
        /**
diff --git a/vala/vala/valathrowstatement.vala b/vala/vala/valathrowstatement.vala
new file mode 100644 (file)
index 0000000..3a69ae5
--- /dev/null
@@ -0,0 +1,73 @@
+/* valathrowstatement.vala
+ *
+ * Copyright (C) 2007  Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Represents a throw statement in the source code.
+ */
+public class Vala.ThrowStatement : Statement {
+       /**
+        * The error expression to throw.
+        */
+       public Expression error_expression {
+               get {
+                       return _error_expression;
+               }
+               set {
+                       _error_expression = value;
+                       if (_error_expression != null) {
+                               _error_expression.parent_node = this;
+                       }
+               }
+       }
+
+       private Expression! _error_expression;
+
+       /**
+        * Creates a new throw statement.
+        *
+        * @param error_expression the error expression
+        * @param source_reference reference to source code
+        * @return                 newly created throw statement
+        */
+       public ThrowStatement (construct Expression! error_expression, construct SourceReference source_reference = null) {
+       }
+       
+       public override void accept (CodeVisitor! visitor) {
+               visitor.visit_begin_throw_statement (this);
+
+               if (error_expression != null) {
+                       error_expression.accept (visitor);
+               
+                       visitor.visit_end_full_expression (error_expression);
+               }
+
+               visitor.visit_end_throw_statement (this);
+       }
+
+       public override void replace (CodeNode! old_node, CodeNode! new_node) {
+               if (error_expression == old_node) {
+                       error_expression = (Expression) new_node;
+               }
+       }
+}
diff --git a/vala/vala/valatrystatement.vala b/vala/vala/valatrystatement.vala
new file mode 100644 (file)
index 0000000..b1a1ccf
--- /dev/null
@@ -0,0 +1,66 @@
+/* valatrystatement.vala
+ *
+ * Copyright (C) 2007  Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Represents a try statement in the source code.
+ */
+public class Vala.TryStatement : Statement {
+       /**
+        * Specifies the body of the try statement.
+        */
+       public Block! body { get; set construct; }
+
+       /**
+        * Specifies the body of the optional finally clause.
+        */
+       public Block finally_body { get; set; }
+
+       private List<CatchClause> catch_clauses;
+
+       /**
+        * Creates a new try statement.
+        *
+        * @param body             body of the try statement
+        * @param finally_body     body of the optional finally clause
+        * @param source_reference reference to source code
+        * @return                 newly created try statement
+        */
+       public TryStatement (construct Block! body, construct Block finally_body, construct SourceReference source_reference = null) {
+       }
+       
+       /**
+        * Appends the specified clause to the list of catch clauses.
+        *
+        * @param clause a catch clause
+        */
+       public void add_catch_clause (CatchClause! clause) {
+               catch_clauses.append (clause);
+       }
+       
+       public override void accept (CodeVisitor! visitor) {
+               visitor.visit_begin_try_statement (this);
+
+               visitor.visit_end_try_statement (this);
+       }
+}