]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
support variable declarators, subtyping, constants, properties, and enums
authorJürg Billeter <j@bitron.ch>
Wed, 17 May 2006 18:40:44 +0000 (18:40 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 17 May 2006 18:40:44 +0000 (18:40 +0000)
2006-05-17  Jürg Billeter  <j@bitron.ch>

* vala/parser.y: support variable declarators, subtyping, constants,
  properties, and enums
* vala/valacodevisitor.vala: support formal parameters, property
  accessors, named arguments, and parenthesized expressions
* vala/valasymbolbuilder.vala: visit enum values, constants, formal
  parameters, properties, and blocks
* vala/valasymbolresolver.vala: save base class, accept void type,
  support type references with namespace name
* vala/valasemanticanalyzer.vala: visitor to find static types of
  expressions
* vala/valacodegenerator.vala: support parenthesized expressions
* vala/valablock.vala: add begin and end visit events
* vala/valaclass.vala: support base types and properties
* vala/valaenum.vala: add values
* vala/valaenumvalue.vala
* vala/valaexpression.vala: add generic symbol reference
* vala/valaforeachstatement.vala: add begin and end visit events
* vala/valaformalparameter.vala: add visit event
* vala/valaliteral.vala: mark class as abstract
* vala/valamethod.vala: add return_type
* vala/valanamedargument.vala: add accept method
* vala/valanamespace.vala: visit fields
* vala/valaobjectcreationexpression.vala: visit arguments
* vala/valaparenthesizedexpression.vala: add visit event
* vala/valaproperty.vala: add accessors
* vala/valapropertyaccessor.vala
* vala/valasimplename.vala: code style update
* vala/valastruct.vala: add constants
* vala/valavariabledeclarator.vala: add type reference
* vala/vala.h: update
* compiler/valacompiler.vala: invoke SemanticAnalyzer
* ccode/valaccodefragment.vala: code style update
* ccode/valaccodeparenthesizedexpression.vala:
* valac/parser.y: support replacement of readonly fields
* valac/context.c: resolve types in operation expressions

svn path=/trunk/; revision=21

31 files changed:
vala/ChangeLog
vala/ccode/valaccodefragment.vala
vala/ccode/valaccodeparenthesizedexpression.vala [new file with mode: 0644]
vala/compiler/valacompiler.vala
vala/vala/parser.y
vala/vala/vala.h
vala/vala/valablock.vala
vala/vala/valaclass.vala
vala/vala/valacodegenerator.vala
vala/vala/valacodevisitor.vala
vala/vala/valaenum.vala
vala/vala/valaenumvalue.vala [new file with mode: 0644]
vala/vala/valaexpression.vala
vala/vala/valaforeachstatement.vala
vala/vala/valaformalparameter.vala
vala/vala/valaliteral.vala
vala/vala/valamethod.vala
vala/vala/valanamedargument.vala
vala/vala/valanamespace.vala
vala/vala/valaobjectcreationexpression.vala
vala/vala/valaparenthesizedexpression.vala
vala/vala/valaproperty.vala
vala/vala/valapropertyaccessor.vala [new file with mode: 0644]
vala/vala/valasemanticanalyzer.vala [new file with mode: 0644]
vala/vala/valasimplename.vala
vala/vala/valastruct.vala
vala/vala/valasymbolbuilder.vala
vala/vala/valasymbolresolver.vala
vala/vala/valavariabledeclarator.vala
vala/valac/context.c
vala/valac/parser.y

index b08cb2ddbe8dd17f56171b311f3f24ed60e516e0..ec5808eb6984ce1fedc223d2a8bc1767412d483d 100644 (file)
@@ -1,3 +1,41 @@
+2006-05-17  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y: support variable declarators, subtyping, constants,
+         properties, and enums
+       * vala/valacodevisitor.vala: support formal parameters, property
+         accessors, named arguments, and parenthesized expressions
+       * vala/valasymbolbuilder.vala: visit enum values, constants, formal
+         parameters, properties, and blocks
+       * vala/valasymbolresolver.vala: save base class, accept void type,
+         support type references with namespace name
+       * vala/valasemanticanalyzer.vala: visitor to find static types of
+         expressions
+       * vala/valacodegenerator.vala: support parenthesized expressions
+       * vala/valablock.vala: add begin and end visit events
+       * vala/valaclass.vala: support base types and properties
+       * vala/valaenum.vala: add values
+       * vala/valaenumvalue.vala
+       * vala/valaexpression.vala: add generic symbol reference
+       * vala/valaforeachstatement.vala: add begin and end visit events
+       * vala/valaformalparameter.vala: add visit event
+       * vala/valaliteral.vala: mark class as abstract
+       * vala/valamethod.vala: add return_type
+       * vala/valanamedargument.vala: add accept method
+       * vala/valanamespace.vala: visit fields
+       * vala/valaobjectcreationexpression.vala: visit arguments
+       * vala/valaparenthesizedexpression.vala: add visit event
+       * vala/valaproperty.vala: add accessors
+       * vala/valapropertyaccessor.vala
+       * vala/valasimplename.vala: code style update
+       * vala/valastruct.vala: add constants
+       * vala/valavariabledeclarator.vala: add type reference
+       * vala/vala.h: update
+       * compiler/valacompiler.vala: invoke SemanticAnalyzer
+       * ccode/valaccodefragment.vala: code style update
+       * ccode/valaccodeparenthesizedexpression.vala: 
+       * valac/parser.y: support replacement of readonly fields
+       * valac/context.c: resolve types in operation expressions
+
 2006-05-16  Jürg Billeter  <j@bitron.ch>
 
        * vala/scanner.l: fix multi-line comments
index ee1b7cda3bf9c7101c087f14b07ecb070ad171e8..f03e48e84dc60bfec4dee1ab2e8ab6a7a96de1b0 100644 (file)
@@ -24,7 +24,7 @@ using GLib;
 
 namespace Vala {
        public class CCodeFragment : CCodeNode {
-               public readonly List<CCodeNode#># children;
+               public ref GLib.List<ref CCodeNode> children { get; construct; }
                
                public void append (CCodeNode node) {
                        _children.append (node);
diff --git a/vala/ccode/valaccodeparenthesizedexpression.vala b/vala/ccode/valaccodeparenthesizedexpression.vala
new file mode 100644 (file)
index 0000000..3e30821
--- /dev/null
@@ -0,0 +1,37 @@
+/* valaccodeparenthesizedexpression.vala
+ *
+ * Copyright (C) 2006  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;
+
+namespace Vala {
+       public class CCodeParenthesizedExpression : CCodeExpression {
+               public readonly ref CCodeExpression inner;
+               
+               public override void write (CCodeWriter writer) {
+                       writer.write_string ("(");
+                       
+                       inner.write (writer);
+
+                       writer.write_string (")");
+               }
+       }
+}
index 6c039b4a75a481b6b7314b46a63456400733611c..3824304b12ddc26c00003589a5ff3325712a0f2b 100644 (file)
@@ -55,6 +55,9 @@ namespace Vala {
                        var attributeprocessor = new AttributeProcessor ();
                        attributeprocessor.process (context);
                        
+                       var analyzer = new SemanticAnalyzer ();
+                       analyzer.analyze (context);
+                       
                        var code_generator = new CodeGenerator ();
                        code_generator.emit (context);
                }
index 6fbc252d18c4b2124db0794d5169e35ffd341000..ae4b1c4d9989ec241157b94cbfd9fae7cc70b53c 100644 (file)
@@ -64,11 +64,13 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
        ValaClass *class;
        ValaStruct *struct_;
        ValaEnum *enum_;
+       ValaEnumValue *enum_value;
        ValaConstant *constant;
        ValaField *field;
        ValaMethod *method;
        ValaFormalParameter *formal_parameter;
        ValaProperty *property;
+       ValaPropertyAccessor *property_accessor;
        ValaLocalVariableDeclaration *local_variable_declaration;
        ValaVariableDeclarator *variable_declarator;
        ValaTypeParameter *type_parameter;
@@ -223,10 +225,20 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %type <statement> return_statement
 %type <namespace> namespace_declaration
 %type <class> class_declaration
+%type <list> opt_class_base
+%type <list> class_base
+%type <list> type_list
 %type <property> property_declaration
+%type <property_accessor> get_accessor_declaration
+%type <property_accessor> opt_set_accessor_declaration
+%type <property_accessor> set_accessor_declaration
 %type <struct_> struct_declaration
 %type <struct_> struct_header
 %type <enum_> enum_declaration
+%type <list> enum_body
+%type <list> opt_enum_member_declarations
+%type <list> enum_member_declarations
+%type <enum_value> enum_member_declaration
 %type <constant> constant_declaration
 %type <variable_declarator> constant_declarator
 %type <field> field_declaration
@@ -703,7 +715,12 @@ declaration_statement
 local_variable_declaration
        : local_variable_type variable_declarators SEMICOLON
          {
+               GList *l;
                $$ = vala_local_variable_declaration_new ($1, $2, src(@2));
+               for (l = $2; l != NULL; l = l->next) {
+                       ValaVariableDeclarator *decl = l->data;
+                       decl->type_reference = g_object_ref ($1);
+               }
          }
        | VAR variable_declarators SEMICOLON
          {
@@ -906,6 +923,9 @@ class_declaration
                for (l = $7; l != NULL; l = l->next) {
                        vala_struct_add_type_parameter (current_struct, l->data);
                }
+               for (l = $8; l != NULL; l = l->next) {
+                       vala_class_add_base_type (VALA_CLASS (current_struct), l->data);
+               }
          }
          class_body
          {
@@ -944,16 +964,28 @@ modifier
 
 opt_class_base
        : /* empty */
+         {
+               $$ = NULL;
+         }
        | class_base
        ;
 
 class_base
        : COLON type_list
+         {
+               $$ = $2;
+         }
        ;
 
 type_list
        : type_name
+         {
+               $$ = g_list_append (NULL, $1);
+         }
        | type_list COMMA type_name
+         {
+               $$ = g_list_append ($1, $3);
+         }
        ;
        
 class_body
@@ -972,6 +1004,9 @@ class_member_declarations
 
 class_member_declaration
        : constant_declaration
+         {
+               vala_struct_add_constant (current_struct, $1);
+         }
        | field_declaration
          {
                vala_struct_add_field (current_struct, $1);
@@ -981,6 +1016,9 @@ class_member_declaration
                vala_struct_add_method (current_struct, $1);
          }
        | property_declaration
+         {
+               vala_class_add_property (VALA_CLASS (current_struct), $1);
+         }
        ;
 
 constant_declaration
@@ -1069,7 +1107,7 @@ method_header
          {
                GList *l;
                
-               $$ = vala_method_new ($7, src_com (@7, $1));
+               $$ = vala_method_new ($7, $6, src_com (@7, $1));
                VALA_CODE_NODE($$)->attributes = $2;
                
                for (l = $9; l != NULL; l = l->next) {
@@ -1127,36 +1165,44 @@ parameter_modifier
        ;
 
 property_declaration
-       : comment opt_attributes opt_access_modifier opt_modifiers opt_ref type IDENTIFIER OPEN_BRACE accessor_declarations CLOSE_BRACE
+       : comment opt_attributes opt_access_modifier opt_modifiers opt_ref type IDENTIFIER OPEN_BRACE get_accessor_declaration opt_set_accessor_declaration CLOSE_BRACE
          {
-               $$ = vala_property_new ($7, $6, src_com (@6, $1));
+               $$ = vala_property_new ($7, $6, $9, $10, src_com (@6, $1));
+         }
+       | comment opt_attributes opt_access_modifier opt_modifiers opt_ref type IDENTIFIER OPEN_BRACE set_accessor_declaration CLOSE_BRACE
+         {
+               $$ = vala_property_new ($7, $6, NULL, $9, src_com (@6, $1));
          }
-       ;
-
-accessor_declarations
-       : get_accessor_declaration opt_set_accessor_declaration
-       | set_accessor_declaration opt_get_accessor_declaration
-       ;
-
-opt_get_accessor_declaration
-       : /* empty */
-       | get_accessor_declaration
        ;
 
 get_accessor_declaration
        : opt_attributes GET method_body
+         {
+               $$ = vala_property_accessor_new (TRUE, FALSE, FALSE, $3, src (@2));
+         }
        ;
 
 opt_set_accessor_declaration
        : /* empty */
+         {
+               $$ = NULL;
+         }
        | set_accessor_declaration
        ;
 
 set_accessor_declaration
        : opt_attributes SET method_body
-       | opt_attributes CONSTRUCT method_body
-       | opt_attributes CONSTRUCT SET method_body
+         {
+               $$ = vala_property_accessor_new (FALSE, TRUE, FALSE, $3, src (@2));
+         }
        | opt_attributes SET CONSTRUCT method_body
+         {
+               $$ = vala_property_accessor_new (FALSE, TRUE, TRUE, $4, src (@2));
+         }
+       | opt_attributes CONSTRUCT method_body
+         {
+               $$ = vala_property_accessor_new (FALSE, FALSE, TRUE, $3, src (@2));
+         }
        ;
 
 struct_declaration
@@ -1233,26 +1279,45 @@ interface_member_declaration
 enum_declaration
        : comment opt_attributes opt_access_modifier ENUM IDENTIFIER enum_body
          {
+               GList *l;
                $$ = vala_enum_new ($5, src_com (@5, $1));
+               for (l = $6; l != NULL; l = l->next) {
+                       vala_enum_add_value ($$, l->data);
+               }
          }
        ;
 
 enum_body
        : OPEN_BRACE opt_enum_member_declarations CLOSE_BRACE
+         {
+               $$ = $2;
+         }
        ;
 
 opt_enum_member_declarations
        : /* empty */
+         {
+               $$ = NULL;
+         }
        | enum_member_declarations
        ;
 
 enum_member_declarations
        : enum_member_declaration
+         {
+               $$ = g_list_append (NULL, $1);
+         }
        | enum_member_declarations COMMA enum_member_declaration
+         {
+               $$ = g_list_append ($1, $3);
+         }
        ;
 
 enum_member_declaration
        : opt_attributes IDENTIFIER
+         {
+               $$ = vala_enum_value_new ($2);
+         }
        ;
 
 flags_declaration
index 63f145dc68b33acc760c69460350c762c5e02408..a4591207e19004319de0227e995355c0ede1a95f 100644 (file)
@@ -12,6 +12,7 @@
 #include <vala/valadeclarationstatement.h>
 #include <vala/valaemptystatement.h>
 #include <vala/valaenum.h>
+#include <vala/valaenumvalue.h>
 #include <vala/valaexpression.h>
 #include <vala/valaexpressionstatement.h>
 #include <vala/valafield.h>
@@ -36,6 +37,7 @@
 #include <vala/valaparser.h>
 #include <vala/valapostfixexpression.h>
 #include <vala/valaproperty.h>
+#include <vala/valapropertyaccessor.h>
 #include <vala/valareturnstatement.h>
 #include <vala/valasimplename.h>
 #include <vala/valasourcefile.h>
index f8d0b192a24f2b3d84a93434ccc2c4aaf54d9f9f..685b860c20e0e34c88757caffb82dfb99d5c3c4e 100644 (file)
@@ -24,19 +24,21 @@ using GLib;
 
 namespace Vala {
        public class Block : Statement {
-               public readonly List<Statement#># statement_list;
-               public readonly SourceReference# source_reference;
+               public readonly ref List<ref Statement> statement_list;
+               public readonly ref SourceReference source_reference;
                
-               public static Block# @new (List<Statement> statement_list, SourceReference source) {
+               public static ref Block new (List<Statement> statement_list, SourceReference source) {
                        return (new Block (statement_list = statement_list, source_reference = source));
                }
                
                public override void accept (CodeVisitor visitor) {
+                       visitor.visit_begin_block (this);
+
                        foreach (Statement stmt in statement_list) {
                                stmt.accept (visitor);
                        }
 
-                       visitor.visit_block (this);
+                       visitor.visit_end_block (this);
                }
        }
 }
index 607e93e481c283696a9d1d4e50d3054c5d607f7d..e773329521eb1378ca59e946370f5534b7f3f2a9 100644 (file)
@@ -24,16 +24,43 @@ using GLib;
 
 namespace Vala {
        public class Class : Struct {
-               public readonly SourceReference# source_reference;
+               public readonly ref SourceReference source_reference;
+               public ref List<ref TypeReference> base_types;
+               public ref Class base_class;
+               
+               ref List<ref Property> properties;
+
+               public void add_base_type (TypeReference type) {
+                       base_types.append (type);
+               }
                
                public static ref Class new (string name, SourceReference source) {
                        return (new Class (name = name, source_reference = source));
                }
                
+               public void add_property (Property prop) {
+                       properties.append (prop);
+                       prop.parent_type = this;
+                       
+                       if (prop.set_accessor != null && prop.set_accessor.body == null) {
+                               /* automatic property accessor body generation */
+                               var f = new Field (name = "_%s".printf (prop.name), type_reference = prop.type_reference, source_reference = source_reference);
+                               add_field (f);
+                       }
+               }
+               
                public override void accept (CodeVisitor visitor) {
                        visitor.visit_begin_class (this);
+                       
+                       foreach (TypeReference type in base_types) {
+                               type.accept (visitor);
+                       }
 
                        visit_children (visitor);                       
+                       
+                       foreach (Property prop in properties) {
+                               prop.accept (visitor);
+                       }
 
                        visitor.visit_end_class (this);
                }
index fee4496e2113d30b7707319499f29a996508b91b..55e557efc203c36d1a6536df1a8009e387edbd05 100644 (file)
@@ -24,17 +24,17 @@ using GLib;
 
 namespace Vala {
        public class CodeGenerator : CodeVisitor {
-               CCodeFragment# header_begin;
-               CCodeFragment# header_type_declaration;
-               CCodeFragment# header_type_definition;
-               CCodeFragment# header_type_member_declaration;
-               CCodeFragment# source_begin;
-               CCodeFragment# source_include_directives;
-               CCodeFragment# source_type_member_declaration;
-               CCodeFragment# source_type_member_definition;
+               ref CCodeFragment header_begin;
+               ref CCodeFragment header_type_declaration;
+               ref CCodeFragment header_type_definition;
+               ref CCodeFragment header_type_member_declaration;
+               ref CCodeFragment source_begin;
+               ref CCodeFragment source_include_directives;
+               ref CCodeFragment source_type_member_declaration;
+               ref CCodeFragment source_type_member_definition;
                
-               CCodeStruct# instance_struct;
-               CCodeStruct# class_struct;
+               ref CCodeStruct instance_struct;
+               ref CCodeStruct class_struct;
                ref CCodeFunction function;
                ref CCodeBlock block;
                
@@ -104,7 +104,7 @@ namespace Vala {
                        header_type_definition.append (instance_struct);
                }
                
-               public override void visit_enum (Enum en) {
+               public override void visit_begin_enum (Enum en) {
                        instance_struct = new CCodeEnum (name = "_%s".printf (en.name));
 
                        if (en.source_reference.comment != null) {
@@ -140,11 +140,17 @@ namespace Vala {
                }
                
 
-               public override void visit_block (Block b) {
+               public override void visit_end_block (Block b) {
                        var cblock = new CCodeBlock ();
                        
                        foreach (Statement stmt in b.statement_list) {
-                               cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+                               if (stmt.ccodenode is CCodeFragment) {
+                                       foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).children) {
+                                               cblock.add_statement (cstmt);
+                                       }
+                               } else {
+                                       cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+                               }
                        }
                        
                        b.ccodenode = cblock;
@@ -155,18 +161,19 @@ namespace Vala {
                }
 
                public override void visit_declaration_statement (DeclarationStatement stmt) {
-                       /* not yet handled var declarations */
-                       if (stmt.declaration.type_reference == null) {
-                               return;
-                       }
-                       
-                       var cdecl = new CCodeDeclarationStatement (type_name = stmt.declaration.type_reference.get_cname ());
+                       /* split declaration statement as var declarators might have different types */
+               
+                       var cfrag = new CCodeFragment ();
                        
                        foreach (VariableDeclarator decl in stmt.declaration.variable_declarators) {
+                               var cdecl = new CCodeDeclarationStatement (type_name = decl.type_reference.get_cname ());
+                       
                                cdecl.add_declarator ((CCodeVariableDeclarator) decl.ccodenode);
+
+                               cfrag.append (cdecl);
                        }
                        
-                       stmt.ccodenode = cdecl;
+                       stmt.ccodenode = cfrag;
                }
 
                public override void visit_variable_declarator (VariableDeclarator decl) {
@@ -244,6 +251,10 @@ namespace Vala {
                        expr.ccodenode = new CCodeIdentifier (name = expr.name);
                }
 
+               public override void visit_parenthesized_expression (ParenthesizedExpression expr) {
+                       expr.ccodenode = new CCodeParenthesizedExpression (inner = (CCodeExpression) expr.inner.ccodenode);
+               }
+
                public override void visit_member_access (MemberAccess expr) {
                        expr.ccodenode = new CCodeIdentifier (name = expr.member_name);
                }
index 98694c89dfb9160d344f2baae159f944bfec8cb3..e3b695a5341834e0166427495a44a132569c9649 100644 (file)
@@ -48,7 +48,13 @@ namespace Vala {
                public virtual void visit_end_struct (Struct st) {
                }
 
-               public virtual void visit_enum (Enum en) {
+               public virtual void visit_begin_enum (Enum en) {
+               }
+
+               public virtual void visit_end_enum (Enum en) {
+               }
+
+               public virtual void visit_enum_value (EnumValue ev) {
                }
 
                public virtual void visit_constant (Constant c) {
@@ -63,7 +69,22 @@ namespace Vala {
                public virtual void visit_end_method (Method m) {
                }
 
-               public virtual void visit_property (Property prop) {
+               public virtual void visit_formal_parameter (FormalParameter p) {
+               }
+
+               public virtual void visit_begin_property (Property prop) {
+               }
+
+               public virtual void visit_end_property (Property prop) {
+               }
+
+               public virtual void visit_begin_property_accessor (PropertyAccessor acc) {
+               }
+
+               public virtual void visit_end_property_accessor (PropertyAccessor acc) {
+               }
+
+               public virtual void visit_named_argument (NamedArgument n) {
                }
 
                public virtual void visit_type_parameter (TypeParameter p) {
@@ -75,7 +96,10 @@ namespace Vala {
                public virtual void visit_type_reference (TypeReference type) {
                }
 
-               public virtual void visit_block (Block b) {
+               public virtual void visit_begin_block (Block b) {
+               }
+
+               public virtual void visit_end_block (Block b) {
                }
 
                public virtual void visit_empty_statement (EmptyStatement stmt) {
@@ -102,7 +126,10 @@ namespace Vala {
                public virtual void visit_for_statement (ForStatement stmt) {
                }
 
-               public virtual void visit_foreach_statement (ForeachStatement stmt) {
+               public virtual void visit_begin_foreach_statement (ForeachStatement stmt) {
+               }
+
+               public virtual void visit_end_foreach_statement (ForeachStatement stmt) {
                }
 
                public virtual void visit_return_statement (ReturnStatement stmt) {
@@ -129,6 +156,9 @@ namespace Vala {
                public virtual void visit_simple_name (SimpleName expr) {
                }
 
+               public virtual void visit_parenthesized_expression (ParenthesizedExpression expr) {
+               }
+
                public virtual void visit_member_access (MemberAccess expr) {
                }
 
index 5746e5514e943a6e68b2d33545228e11315bc9e5..10233007a8f49b6483cce28e1f87535d83b27129 100644 (file)
@@ -24,16 +24,27 @@ using GLib;
 
 namespace Vala {
        public class Enum : Type_ {
-               public readonly string# name;
-               public readonly SourceReference# source_reference;
+               public readonly ref string name;
+               public readonly ref SourceReference source_reference;
                public Namespace @namespace;
+               ref List<ref EnumValue> values;
 
-               public static Enum# @new (string name, SourceReference source) {
+               public static ref Enum new (string name, SourceReference source) {
                        return (new Enum (name = name, source_reference = source));
                }
                
+               public void add_value (EnumValue value) {
+                       values.append (value);
+               }
+               
                public override void accept (CodeVisitor visitor) {
-                       visitor.visit_enum (this);
+                       visitor.visit_begin_enum (this);
+                       
+                       foreach (EnumValue value in values) {
+                               value.accept (visitor);
+                       }
+
+                       visitor.visit_end_enum (this);
                }
                
                public override string get_cname () {
diff --git a/vala/vala/valaenumvalue.vala b/vala/vala/valaenumvalue.vala
new file mode 100644 (file)
index 0000000..0ed01b2
--- /dev/null
@@ -0,0 +1,43 @@
+/* valaenumvalue.vala
+ *
+ * Copyright (C) 2006  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;
+
+namespace Vala {
+       public class EnumValue : CodeNode {
+               public readonly ref string name;
+               public readonly ref IntegerLiteral value;
+               public readonly ref SourceReference source_reference;
+
+               public static ref EnumValue new (string name) {
+                       return (new EnumValue (name = name));
+               }
+
+               public static ref EnumValue new_with_value (string name, int value) {
+                       return (new EnumValue (name = name, value = value));
+               }
+               
+               public override void accept (CodeVisitor visitor) {
+                       visitor.visit_enum_value (this);
+               }
+       }
+}
index 830709e92f26e7f2e6138d9820c5d0f0718efbaa..a183a1616271ba6518271e8a1c45481eb9b2469b 100644 (file)
@@ -24,8 +24,7 @@ using GLib;
 
 namespace Vala {
        public abstract class Expression : CodeNode {
-               TypeReference# static_type;
-               Field field_reference;
-               Method method_reference;
+               public ref TypeReference static_type;
+               public ref Symbol symbol_reference;
        }
 }
index 20dacb0777a06cb8045578d1b3091bc94a1c7819..bad70cb5d231259c70816635bad55c037b60ce08 100644 (file)
@@ -24,22 +24,24 @@ using GLib;
 
 namespace Vala {
        public class ForeachStatement : Statement {
-               public readonly TypeReference# type_reference;
-               public readonly string# variable_name;
-               public readonly Expression# collection;
-               public readonly Statement# body;
-               public readonly SourceReference# source_reference;
+               public readonly ref TypeReference type_reference;
+               public readonly ref string variable_name;
+               public readonly ref Expression collection;
+               public readonly ref Statement body;
+               public readonly ref SourceReference source_reference;
 
-               public static ForeachStatement# @new (TypeReference type, string id, Expression col, Statement body, SourceReference source) {
+               public static ref ForeachStatement new (TypeReference type, string id, Expression col, Statement body, SourceReference source) {
                        return (new ForeachStatement (type_reference = type, variable_name = id, collection = col, body = body, source_reference = source));
                }
                
                public override void accept (CodeVisitor visitor) {
+                       visitor.visit_begin_foreach_statement (this);
+
                        type_reference.accept (visitor);
                        collection.accept (visitor);
                        body.accept (visitor);
 
-                       visitor.visit_foreach_statement (this);
+                       visitor.visit_end_foreach_statement (this);
                }
        }
 }
index 4a455f04466259a60aaac572ea27866c4e657ca1..07dbff1452f3a6707fdef9ca4c0cb6cccce12479 100644 (file)
@@ -34,6 +34,8 @@ namespace Vala {
                
                public override void accept (CodeVisitor visitor) {
                        type_reference.accept (visitor);
+                       
+                       visitor.visit_formal_parameter (this);
                }
        }
 }
index 8d7029134e8e193fb9077067bb5809e86e211fe6..42d3939d83c41f44c4a31a14a2e27a66293a8007 100644 (file)
@@ -23,6 +23,7 @@
 using GLib;
 
 namespace Vala {
-       public class Literal : CodeNode {
+       public abstract class Literal : CodeNode {
+               public ref TypeReference static_type;
        }
 }
index 94f08499e3848f7e3ff8e51e46280129db297495..0559ab0add5b375fe1944340a93a82d81529e9ff 100644 (file)
@@ -25,9 +25,10 @@ using GLib;
 namespace Vala {
        public class Method : CodeNode {
                public readonly ref string name;
-               public readonly SourceReference# source_reference;
+               public readonly ref TypeReference return_type;
+               public readonly ref SourceReference source_reference;
                public CodeNode parent_type;
-               Statement# _body;
+               ref Statement _body;
                public Statement body {
                        get {
                                return _body;
@@ -40,8 +41,8 @@ namespace Vala {
                public bool instance = true;
                ref List<ref FormalParameter> parameters;
                
-               public static Method# @new (string name, SourceReference source) {
-                       return (new Method (name = name, source_reference = source));
+               public static ref Method new (string name, TypeReference return_type, SourceReference source) {
+                       return (new Method (name = name, return_type = return_type, source_reference = source));
                }
                
                public void add_parameter (FormalParameter param) {
@@ -51,6 +52,12 @@ namespace Vala {
                public override void accept (CodeVisitor visitor) {
                        visitor.visit_begin_method (this);
                        
+                       return_type.accept (visitor);
+                       
+                       foreach (FormalParameter param in parameters) {
+                               param.accept (visitor);
+                       }
+                       
                        if (body != null) {
                                body.accept (visitor);
                        }
index a96ec5842bc7ed7370c87480a78e835f6511124b..a2f3ca35f6f174ecae13258afe2c7d6bcf20b23c 100644 (file)
@@ -24,12 +24,18 @@ using GLib;
 
 namespace Vala {
        public class NamedArgument : CodeNode {
-               public readonly string# name;
-               public readonly Expression# argument;
-               public readonly SourceReference# source_reference;
+               public readonly ref string name;
+               public readonly ref Expression argument;
+               public readonly ref SourceReference source_reference;
                
-               public static NamedArgument# @new (string name, Expression arg, SourceReference source) {
+               public static ref NamedArgument new (string name, Expression arg, SourceReference source) {
                        return (new NamedArgument (name = name, argument = arg, source_reference = source));
                }
+               
+               public override void accept (CodeVisitor visitor) {
+                       argument.accept (visitor);
+               
+                       visitor.visit_named_argument (this);
+               }
        }
 }
index 2766b1b834c370d7709302999c5456c3b2c68913..4ac09dfcf270f8e2481feee9338a713d7d65df1e 100644 (file)
@@ -86,6 +86,10 @@ namespace Vala {
                                en.accept (visitor);
                        }
 
+                       foreach (Field f in fields) {
+                               f.accept (visitor);
+                       }
+
                        visitor.visit_end_namespace (this);
                }
 
index e8baace4503a3bb4cac17aa233f5d287b210d2bc..e3e05d608fa6c9ae56d06ee45079bf394871b909 100644 (file)
@@ -24,16 +24,20 @@ using GLib;
 
 namespace Vala {
        public class ObjectCreationExpression : Expression {
-               public readonly TypeReference# type_reference;
-               public readonly List<NamedArgument#># named_argument_list;
-               public readonly SourceReference# source_reference;
+               public readonly ref TypeReference type_reference;
+               public readonly ref List<ref NamedArgument> named_argument_list;
+               public readonly ref SourceReference source_reference;
 
-               public static ObjectCreationExpression# @new (TypeReference type, List<NamedArgument> named_argument_list, SourceReference source) {
+               public static ref ObjectCreationExpression new (TypeReference type, List<NamedArgument> named_argument_list, SourceReference source) {
                        return (new ObjectCreationExpression (type_reference = type, named_argument_list = named_argument_list, source_reference = source));
                }
                
                public override void accept (CodeVisitor visitor) {
                        type_reference.accept (visitor);
+                       
+                       foreach (NamedArgument arg in named_argument_list) {
+                               arg.accept (visitor);
+                       }
                
                        visitor.visit_object_creation_expression (this);
                }
index 2ab1abc82dfaf5ee06c708d9aeaca5d7affff760..a42e54d9fc8a5ca65b80db86b03422f51f59bf80 100644 (file)
@@ -24,15 +24,17 @@ using GLib;
 
 namespace Vala {
        public class ParenthesizedExpression : Expression {
-               public readonly Expression# inner;
-               public readonly SourceReference# source_reference;
+               public readonly ref Expression inner;
+               public readonly ref SourceReference source_reference;
 
-               public static ParenthesizedExpression# @new (Expression inner, SourceReference source) {
+               public static ref ParenthesizedExpression new (Expression inner, SourceReference source) {
                        return (new ParenthesizedExpression (inner = inner, source_reference = source));
                }
                
                public override void accept (CodeVisitor visitor) {
                        inner.accept (visitor);
+                       
+                       visitor.visit_parenthesized_expression (this);
                }
        }
 }
index f3d52674039fb520704e71ad4d3f92d3dcd410ba..fbbc1c3cde5c7ef39479152f40f292af596877ba 100644 (file)
@@ -26,16 +26,29 @@ namespace Vala {
        public class Property : CodeNode {
                public readonly ref string name;
                public readonly ref TypeReference type_reference;
+               public readonly ref PropertyAccessor get_accessor;
+               public readonly ref PropertyAccessor set_accessor;
                public readonly ref SourceReference source_reference;
                public CodeNode parent_type;
                public MemberAccessibility access;
                
-               public static ref Property new (string name, TypeReference type, SourceReference source) {
-                       return (new Property (name = name, type_reference = type, source_reference = source));
+               public static ref Property new (string name, TypeReference type, PropertyAccessor get_accessor, PropertyAccessor set_accessor, SourceReference source) {
+                       return (new Property (name = name, type_reference = type, get_accessor = get_accessor, set_accessor = set_accessor, source_reference = source));
                }
                
                public override void accept (CodeVisitor visitor) {
-                       visitor.visit_property (this);
+                       visitor.visit_begin_property (this);
+
+                       type_reference.accept (visitor);
+                       
+                       if (get_accessor != null) {
+                               get_accessor.accept (visitor);
+                       }
+                       if (set_accessor != null) {
+                               set_accessor.accept (visitor);
+                       }
+               
+                       visitor.visit_end_property (this);
                }
        }
 }
diff --git a/vala/vala/valapropertyaccessor.vala b/vala/vala/valapropertyaccessor.vala
new file mode 100644 (file)
index 0000000..908ad5d
--- /dev/null
@@ -0,0 +1,47 @@
+/* valapropertyaccessor.vala
+ *
+ * Copyright (C) 2006  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;
+
+namespace Vala {
+       public class PropertyAccessor : CodeNode {
+               public readonly ref bool readable;
+               public readonly ref bool writable;
+               public readonly ref bool construct_;
+               public readonly ref Statement body;
+               public readonly ref SourceReference source_reference;
+               
+               public static ref PropertyAccessor new (bool readable, bool writable, bool construct_, Statement body, SourceReference source) {
+                       return (new PropertyAccessor (readable = readable, writable = writable, construct_ = construct_, body = body, source_reference = source));
+               }
+               
+               public override void accept (CodeVisitor visitor) {
+                       visitor.visit_begin_property_accessor (this);
+
+                       if (body != null) {
+                               body.accept (visitor);
+                       }
+               
+                       visitor.visit_end_property_accessor (this);
+               }
+       }
+}
diff --git a/vala/vala/valasemanticanalyzer.vala b/vala/vala/valasemanticanalyzer.vala
new file mode 100644 (file)
index 0000000..6f74ea3
--- /dev/null
@@ -0,0 +1,222 @@
+/* valasemanticanalyzer.vala
+ *
+ * Copyright (C) 2006  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;
+
+namespace Vala {
+       public class SemanticAnalyzer : CodeVisitor {
+               ref Symbol root_symbol;
+               ref Symbol current_symbol;
+               
+               List<NamespaceReference> current_using_directives;
+               TypeReference dummy; // required for broken dependency handlind
+       
+               public void analyze (CodeContext context) {
+                       root_symbol = context.root;
+                       current_symbol = root_symbol;
+                       context.accept (this);
+               }
+               
+               public override void visit_begin_source_file (SourceFile file) {
+                       current_using_directives = file.get_using_directives ();
+               }
+
+               public override void visit_end_source_file (SourceFile file) {
+                       current_using_directives = null;
+               }
+
+               public override void visit_begin_namespace (Namespace ns) {
+                       current_symbol = ns.symbol;
+               }
+
+               public override void visit_end_namespace (Namespace ns) {
+                       current_symbol = current_symbol.parent_symbol;
+               }
+
+               public override void visit_begin_class (Class cl) {
+                       current_symbol = cl.symbol;
+               }
+
+               public override void visit_end_class (Class cl) {
+                       current_symbol = current_symbol.parent_symbol;
+               }
+
+               public override void visit_begin_struct (Struct st) {
+                       current_symbol = st.symbol;
+               }
+
+               public override void visit_end_struct (Struct st) {
+                       current_symbol = current_symbol.parent_symbol;
+               }
+
+               public override void visit_begin_method (Method m) {
+                       current_symbol = m.symbol;
+               }
+
+               public override void visit_end_method (Method m) {
+                       current_symbol = current_symbol.parent_symbol;
+               }
+
+               public override void visit_named_argument (NamedArgument n) {
+               }
+
+               public override void visit_begin_block (Block b) {
+                       current_symbol = b.symbol;
+               }
+
+               public override void visit_end_block (Block b) {
+                       current_symbol = current_symbol.parent_symbol;
+               }
+
+               public override void visit_variable_declarator (VariableDeclarator decl) {
+                       if (decl.type_reference == null) {
+                               /* var type */
+                               decl.type_reference = decl.initializer.static_type;
+                       }
+
+                       decl.symbol = new Symbol (node = decl);
+                       current_symbol.add (decl.name, decl.symbol);
+               }
+
+               public override void visit_begin_foreach_statement (ForeachStatement stmt) {
+                       stmt.symbol = new Symbol (node = stmt.type_reference);
+                       current_symbol.add (stmt.variable_name, stmt.symbol);
+               }
+
+               public override void visit_boolean_literal (BooleanLiteral expr) {
+                       expr.static_type = new TypeReference ();
+                       expr.static_type.type = (Type_) root_symbol.lookup ("bool").node;
+               }
+
+               public override void visit_character_literal (CharacterLiteral expr) {
+                       expr.static_type = new TypeReference ();
+                       expr.static_type.type = (Type_) root_symbol.lookup ("char").node;
+               }
+
+               public override void visit_integer_literal (IntegerLiteral expr) {
+                       expr.static_type = new TypeReference ();
+                       expr.static_type.type = (Type_) root_symbol.lookup ("int").node;
+               }
+
+               public override void visit_string_literal (StringLiteral expr) {
+                       expr.static_type = new TypeReference ();
+                       expr.static_type.type = (Type_) root_symbol.lookup ("string").node;
+               }
+
+               public override void visit_null_literal (NullLiteral expr) {
+               }
+
+               public override void visit_literal_expression (LiteralExpression expr) {
+                       expr.static_type = expr.literal.static_type;
+               }
+               
+               TypeReference get_static_type_for_node (CodeNode node) {
+                       if (node is Field) {
+                               var f = (Field) node;
+                               return f.type_reference;
+                       } else if (node is Property) {
+                               var prop = (Property) node;
+                               return prop.type_reference;
+                       } else if (node is FormalParameter) {
+                               var p = (FormalParameter) node;
+                               return p.type_reference;
+                       } else if (node is TypeReference) {
+                               return (TypeReference) node;
+                       } else if (node is VariableDeclarator) {
+                               var decl = (VariableDeclarator) node;
+                               return decl.type_reference;
+                       }
+                       return null;
+               }
+               
+               Symbol symbol_lookup_inherited (Symbol sym, string name) {
+                       var result = sym.lookup (name);
+                       if (result == null && sym.node is Class) {
+                               var cl = (Class) sym.node;
+                               for (cl = cl.base_class; cl != null && result == null; cl = cl.base_class) {
+                                       result = cl.symbol.lookup (name);
+                               }
+                       }
+                       return result;
+               }
+
+               public override void visit_simple_name (SimpleName expr) {
+                       var sym = current_symbol;
+                       while (sym != null && expr.symbol_reference == null) {
+                               expr.symbol_reference = symbol_lookup_inherited (sym, expr.name);
+                               sym = sym.parent_symbol;
+                       }
+
+                       if (expr.symbol_reference == null) {
+                               foreach (NamespaceReference ns in current_using_directives) {
+                                       var local_sym = ns.namespace_symbol.lookup (expr.name);
+                                       if (expr.symbol_reference != null && local_sym != null) {
+                                               // raise error
+                                               stderr.printf ("ambiguous symbol name %s\n", expr.name);
+                                       }
+                                       expr.symbol_reference = local_sym;
+                               }
+                       }
+
+                       if (expr.symbol_reference == null) {
+                               stderr.printf ("symbol ´%s´ not found\n", expr.name);
+                       }
+
+                       expr.static_type = get_static_type_for_node (expr.symbol_reference.node);
+               }
+
+               public override void visit_parenthesized_expression (ParenthesizedExpression expr) {
+                       expr.static_type = expr.inner.static_type;
+               }
+
+               public override void visit_member_access (MemberAccess expr) {
+                       if (expr.inner.static_type == null) {
+                               if (expr.inner.symbol_reference.node is Type_) {
+                                       expr.symbol_reference = expr.inner.symbol_reference.lookup (expr.member_name);
+                               }
+                       }
+                       
+                       if (expr.symbol_reference == null) {
+                               expr.symbol_reference = symbol_lookup_inherited (expr.inner.static_type.type.symbol, expr.member_name);
+                       }
+                       
+                       if (expr.symbol_reference == null) {
+                               stderr.printf ("%s: member ´%s´ not found\n", expr.source_reference.to_string (), expr.member_name);
+                       }
+                       
+                       expr.static_type = get_static_type_for_node (expr.symbol_reference.node);
+               }
+
+               public override void visit_invocation_expression (InvocationExpression expr) {
+                       var m = (Method) expr.call.symbol_reference.node;
+                       expr.static_type = m.return_type;
+               }
+
+               public override void visit_object_creation_expression (ObjectCreationExpression expr) {
+                       expr.static_type = expr.type_reference;
+               }
+
+               public override void visit_cast_expression (CastExpression expr) {
+                       expr.static_type = expr.type_reference;
+               }
+       }
+}
index a9bfec9cb21f5a5872d8e75377f3bd2405ff4dc6..2c64a13297491d383804ab52ce3c9ba014d7f440 100644 (file)
@@ -24,10 +24,10 @@ using GLib;
 
 namespace Vala {
        public class SimpleName : Expression {
-               public readonly string# name;
-               public readonly SourceReference# source_reference;
+               public readonly ref string name;
+               public readonly ref SourceReference source_reference;
 
-               public static SimpleName# @new (string s, List type_argument_list, SourceReference source) {
+               public static ref SimpleName new (string s, List type_argument_list, SourceReference source) {
                        return (new SimpleName (name = s, source_reference = source));
                }
                
index d08b05b82206f2af26954a32156370e1f56c723d..c612b02611c59afadead7635648d269bd3c62f35 100644 (file)
@@ -29,8 +29,9 @@ namespace Vala {
                public Namespace @namespace;
 
                ref List<ref string> type_parameters;
-               List<Field#># fields;
-               List<Method#># methods;
+               ref List<ref Constant> constants;
+               ref List<ref Field> fields;
+               ref List<ref Method> methods;
                
                public ref string cname;
                public ref string lower_case_csuffix;
@@ -45,6 +46,10 @@ namespace Vala {
                        p.type = this;
                }
                
+               public void add_constant (Constant c) {
+                       constants.append (c);
+               }
+               
                public void add_field (Field f) {
                        fields.append (f);
                        f.parent_type = this;
@@ -68,6 +73,10 @@ namespace Vala {
                                p.accept (visitor);
                        }
                        
+                       foreach (Constant c in constants) {
+                               c.accept (visitor);
+                       }
+                       
                        foreach (Field f in fields) {
                                f.accept (visitor);
                        }
index 77d2eeca35ce21e3d3a07d37487d407a2b0c103c..e29bf21964ef881a2b94cdcf836b10a70954f6e3 100644 (file)
@@ -27,6 +27,7 @@ namespace Vala {
                Symbol root;
                Symbol current_namespace;
                Symbol current_type;
+               Symbol current_symbol;
                
                public void build (CodeContext context) {
                        root = context.root;
@@ -43,6 +44,12 @@ namespace Vala {
                                ns.symbol = new Symbol (node = ns);
                                root.add (ns.name, ns.symbol);
                        }
+                       
+                       current_symbol = ns.symbol;
+               }
+               
+               public override void visit_end_namespace (Namespace ns) {
+                       current_symbol = current_symbol.parent_symbol;
                }
        
                public override void visit_begin_class (Class cl) {
@@ -53,6 +60,12 @@ namespace Vala {
                        }
                        cl.symbol = new Symbol (node = cl);
                        cl.@namespace.symbol.add (cl.name, cl.symbol);
+                       
+                       current_symbol = cl.symbol;
+               }
+               
+               public override void visit_end_class (Class cl) {
+                       current_symbol = current_symbol.parent_symbol;
                }
                
                public override void visit_begin_struct (Struct st) {
@@ -63,9 +76,15 @@ namespace Vala {
                        }
                        st.symbol = new Symbol (node = st);
                        st.@namespace.symbol.add (st.name, st.symbol);
+                       
+                       current_symbol = st.symbol;
+               }
+               
+               public override void visit_end_struct (Struct st) {
+                       current_symbol = current_symbol.parent_symbol;
                }
                
-               public override void visit_enum (Enum en) {
+               public override void visit_begin_enum (Enum en) {
                        if (en.@namespace.symbol.lookup (en.name) != null) {
                                // TODO: raise error
                                stderr.printf ("symbol conflict\n");
@@ -73,26 +92,105 @@ namespace Vala {
                        }
                        en.symbol = new Symbol (node = en);
                        en.@namespace.symbol.add (en.name, en.symbol);
+                       current_symbol = en.symbol;
+               }
+               
+               public override void visit_end_enum (Enum en) {
+                       current_symbol = current_symbol.parent_symbol;
+               }
+
+               public override void visit_enum_value (EnumValue ev) {
+                       ev.symbol = new Symbol (node = ev);
+                       current_symbol.add (ev.name, ev.symbol);
+               }
+
+               public override void visit_constant (Constant c) {
+                       if (current_symbol.lookup (c.name) != null) {
+                               // TODO: raise error
+                               stderr.printf ("symbol conflict\n");
+                               return;
+                       }
+                       c.symbol = new Symbol (node = c);
+                       current_symbol.add (c.name, c.symbol);
                }
                
                public override void visit_field (Field f) {
-                       if (f.parent_type.symbol.lookup (f.name) != null) {
+                       if (current_symbol.lookup (f.name) != null) {
                                // TODO: raise error
                                stderr.printf ("symbol conflict\n");
                                return;
                        }
                        f.symbol = new Symbol (node = f);
-                       f.parent_type.symbol.add (f.name, f.symbol);
+                       current_symbol.add (f.name, f.symbol);
                }
                
                public override void visit_begin_method (Method m) {
-                       if (m.parent_type.symbol.lookup (m.name) != null) {
+                       if (current_symbol.lookup (m.name) != null) {
                                // TODO: raise error
                                stderr.printf ("symbol conflict\n");
                                return;
                        }
                        m.symbol = new Symbol (node = m);
-                       m.parent_type.symbol.add (m.name, m.symbol);
+                       current_symbol.add (m.name, m.symbol);
+                       current_symbol = m.symbol;
+                       
+                       if (m.instance) {
+                               var type = new TypeReference ();
+                               type.type = (Type_) m.symbol.parent_symbol.node;
+                               current_symbol.add ("this", new Symbol (node = type));
+                       }
+               }
+               
+               public override void visit_end_method (Method m) {
+                       current_symbol = current_symbol.parent_symbol;
+               }
+
+               public override void visit_formal_parameter (FormalParameter p) {
+                       p.symbol = new Symbol (node = p);
+                       current_symbol.add (p.name, p.symbol);
+               }
+               
+               public override void visit_begin_property (Property prop) {
+                       if (current_symbol.lookup (prop.name) != null) {
+                               // TODO: raise error
+                               stderr.printf ("symbol conflict\n");
+                               return;
+                       }
+                       prop.symbol = new Symbol (node = prop);
+                       current_symbol.add (prop.name, prop.symbol);
+                       current_symbol = prop.symbol;
+                       
+                       var type = new TypeReference ();
+                       type.type = (Type_) prop.symbol.parent_symbol.node;
+                       current_symbol.add ("this", new Symbol (node = type));
+               }
+               
+               public override void visit_end_property (Property prop) {
+                       current_symbol = current_symbol.parent_symbol;
+               }
+               
+               public override void visit_begin_property_accessor (PropertyAccessor acc) {
+                       acc.symbol = new Symbol (node = acc);
+                       acc.symbol.parent_symbol = current_symbol;
+                       current_symbol = acc.symbol;
+
+                       if (acc.writable || acc.construct_) {
+                               current_symbol.add ("value", new Symbol (node = ((Property) current_symbol.parent_symbol.node).type_reference));
+                       }
+               }
+               
+               public override void visit_end_property_accessor (PropertyAccessor acc) {
+                       current_symbol = current_symbol.parent_symbol;
+               }
+
+               public override void visit_begin_block (Block b) {
+                       b.symbol = new Symbol (node = b);
+                       b.symbol.parent_symbol = current_symbol;
+                       current_symbol = b.symbol;
+               }
+
+               public override void visit_end_block (Block b) {
+                       current_symbol = current_symbol.parent_symbol;
                }
                
                public override void visit_type_parameter (TypeParameter p) {
index e8b27e9a977c4f03a1ed9b3e5c89bb8403ff9fc0..036796169aaa5042552346c54a131e9723f48a7f 100644 (file)
@@ -24,11 +24,13 @@ using GLib;
 
 namespace Vala {
        public class SymbolResolver : CodeVisitor {
+               Symbol root_symbol;
                Symbol current_scope;
                List<NamespaceReference> current_using_directives;
                
                public void resolve (CodeContext context) {
-                       current_scope = context.root;
+                       root_symbol = context.root;
+                       current_scope = root_symbol;
                        context.accept (this);
                }
                
@@ -53,6 +55,15 @@ namespace Vala {
                }
 
                public override void visit_end_class (Class cl) {
+                       foreach (TypeReference type in cl.base_types) {
+                               if (type.type is Class) {
+                                       if (cl.base_class != null) {
+                                               stderr.printf ("error: multiple base classes specified\n");
+                                       }
+                                       cl.base_class = type.type;
+                               }
+                       }
+               
                        current_scope = current_scope.parent_symbol;
                }
 
@@ -73,6 +84,10 @@ namespace Vala {
                }
 
                public override void visit_type_reference (TypeReference type) {
+                       if (type.type_name.cmp ("void") == 0) {
+                               return;
+                       }
+                       
                        if (type.namespace_name == null) {
                                Symbol sym = null;
                                Symbol scope = current_scope;
@@ -85,20 +100,33 @@ namespace Vala {
                                                var local_sym = ns.namespace_symbol.lookup (type.type_name);
                                                if (sym != null && local_sym != null) {
                                                        // raise error
-                                                       stderr.printf ("ambigous type name %s\n", type.type_name);
+                                                       stderr.printf ("error: ambiguous type name %s\n", type.type_name);
                                                }
                                                sym = local_sym;
                                        }
                                }
                                if (sym == null) {
                                        // raise error, type not found
-                                       stderr.printf ("type %s not found\n", type.type_name);
+                                       stderr.printf ("error: type %s not found\n", type.type_name);
                                }
                                if (sym.node is TypeParameter) {
                                        type.type_parameter = sym.node;
                                } else {
                                        type.type = (Type_) sym.node;
                                }
+                       } else {
+                               var ns_symbol = root_symbol.lookup (type.namespace_name);
+                               if (ns_symbol == null) {
+                                       // raise error
+                                       stderr.printf ("error: namespace ´%s´ not found\n", type.namespace_name);
+                               }
+                               
+                               var sym = ns_symbol.lookup (type.type_name);
+                               if (sym == null) {
+                                       // raise error
+                                       stderr.printf ("error: symbol ´%s´ not found in namespace ´%s´\n", type.type_name, type.namespace_name);
+                               }
+                               type.type = (Type_) sym.node;
                        }
                }
        }
index 55cfca6eaa7a9ce6c9ffe0cb7280788d8d1f9405..21fd71553ceb9801007410223ad2cc13f17f7cf1 100644 (file)
@@ -27,6 +27,7 @@ namespace Vala {
                public readonly ref string name;
                public readonly ref Expression initializer;
                public readonly ref SourceReference source_reference;
+               public ref TypeReference type_reference;
        
                public static ref VariableDeclarator new (string name, Expression init, SourceReference source) {
                        return (new VariableDeclarator (name = name, initializer = init, source_reference = source));
@@ -36,6 +37,10 @@ namespace Vala {
                        if (initializer != null) {
                                initializer.accept (visitor);
                        }
+                       
+                       if (type_reference != null) {
+                               type_reference.accept (visitor);
+                       }
                
                        visitor.visit_variable_declarator (this);
                }
index 3af613b7b5e138acf8ab5026b8037c87aba9ed6c..637c9385011bb86116c593dede7a1b6c98b68e71 100644 (file)
@@ -445,6 +445,14 @@ vala_context_resolve_types_in_expression (ValaContext *context, ValaNamespace *n
        case VALA_EXPRESSION_TYPE_MEMBER_ACCESS:
                vala_context_resolve_types_in_expression (context, namespace, expr->member_access.left);
                break;
+       case VALA_EXPRESSION_TYPE_OPERATION:
+               if (expr->op.left != NULL) {
+                       vala_context_resolve_types_in_expression (context, namespace, expr->op.left);
+               }
+               if (expr->op.right != NULL) {
+                       vala_context_resolve_types_in_expression (context, namespace, expr->op.right);
+               }
+               break;
        case VALA_EXPRESSION_TYPE_OBJECT_CREATION:
                vala_context_resolve_type_reference (context, namespace, NULL, expr->object_creation.type);
                for (l = expr->object_creation.named_argument_list; l != NULL; l = l->next) {
index 5843f74fad5bd0d819383484da3287d80b10af01..634041c38120726d5f988b9fa07c6538760a22b4 100644 (file)
@@ -293,6 +293,7 @@ ValaLocation *get_location (int lineno, int colno)
 %type <property> accessor_declarations
 %type <statement> get_accessor_declaration
 %type <statement> set_accessor_declaration
+%type <statement> accessor_body
 %type <named_argument> named_argument
 %type <constant> constant_declaration
 %type <struct_> struct_declaration
@@ -891,18 +892,73 @@ modifier
        ;
        
 property_declaration
-       : opt_attribute_sections opt_modifiers type_name IDENTIFIER OPEN_BRACE accessor_declarations CLOSE_BRACE
+       : opt_attribute_sections opt_modifiers opt_parameter_modifier type_name IDENTIFIER OPEN_BRACE accessor_declarations CLOSE_BRACE
          {
-               $$ = $6;
-               $$->name = g_strdup ($4);
-               $$->location = current_location (@4);
-               $$->return_type = $3;
+               $$ = $7;
+               $$->name = g_strdup ($5);
+               $$->location = current_location (@5);
+               $$->return_type = $4;
                /* default fields to private access */
                if (($2 & VALA_MODIFIER_PUBLIC) == 0) {
                        yyerror (&@2, "Properties must have a public modifier.");
                        YYERROR;
                }
                $$->modifiers = $2;
+
+               if ($$->get_statement == NULL && $$->set_statement == NULL) {
+                       // no property bodies provided => create private field and public construct-only property
+
+                       ValaField *f = g_new0 (ValaField, 1);
+
+                       f->location = current_location (@5);
+                       f->modifiers = VALA_MODIFIER_PRIVATE;
+                       f->declaration_statement = g_new0 (ValaStatement, 1);
+                       f->declaration_statement->type = VALA_STATEMENT_TYPE_VARIABLE_DECLARATION;
+                       f->declaration_statement->location = current_location (@5);
+                       f->declaration_statement->variable_declaration = g_new0 (ValaVariableDeclaration, 1);
+                       f->declaration_statement->variable_declaration->type = $4;
+                       f->declaration_statement->variable_declaration->declarator = g_new0 (ValaVariableDeclarator, 1);
+                       f->declaration_statement->variable_declaration->declarator->name = g_strdup_printf ("_%s", $5);
+                       f->declaration_statement->variable_declaration->declarator->location = current_location (@5);
+                       f->class = current_class;
+
+                       ValaStatement *stmt;
+
+                       $$->get_statement = g_new0 (ValaStatement, 1);
+                       $$->get_statement->type = VALA_STATEMENT_TYPE_BLOCK;
+                       $$->get_statement->location = current_location (@5);
+
+                       stmt = g_new0 (ValaStatement, 1);
+                       stmt->type = VALA_STATEMENT_TYPE_RETURN;
+                       stmt->location = current_location (@5);
+                       stmt->expr = g_new0 (ValaExpression, 1);
+                       stmt->expr->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME;
+                       stmt->expr->location = current_location (@5);
+                       stmt->expr->str = g_strdup_printf ("_%s", $5);
+                       $$->get_statement->block.statements = g_list_append ($$->get_statement->block.statements, stmt);
+
+                       $$->set_statement = g_new0 (ValaStatement, 1);
+                       $$->set_statement->type = VALA_STATEMENT_TYPE_BLOCK;
+                       $$->set_statement->location = current_location (@5);
+
+                       stmt = g_new0 (ValaStatement, 1);
+                       stmt->type = VALA_STATEMENT_TYPE_EXPRESSION;
+                       stmt->location = current_location (@5);
+                       stmt->expr = g_new0 (ValaExpression, 1);
+                       stmt->expr->type = VALA_EXPRESSION_TYPE_ASSIGNMENT;
+                       stmt->expr->location = current_location (@5);
+                       stmt->expr->assignment.left = g_new0 (ValaExpression, 1);
+                       stmt->expr->assignment.left->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME;
+                       stmt->expr->assignment.left->location = current_location (@5);
+                       stmt->expr->assignment.left->str = g_strdup_printf ("_%s", $5);
+                       stmt->expr->assignment.right = g_new0 (ValaExpression, 1);
+                       stmt->expr->assignment.right->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME;
+                       stmt->expr->assignment.right->location = current_location (@5);
+                       stmt->expr->assignment.right->str = "value";
+                       $$->set_statement->block.statements = g_list_append ($$->set_statement->block.statements, stmt);
+
+                       current_class->fields = g_list_append (current_class->fields, f);
+               }
          }
        ;
        
@@ -932,27 +988,35 @@ accessor_declarations
        ;
 
 get_accessor_declaration
-       : GET block
+       : GET accessor_body
          {
                $$ = $2;
          }
        ;
        
 set_accessor_declaration
-       : SET block
+       : SET accessor_body
          {
                $$ = $2;
          }
-       | CONSTRUCT block
+       | CONSTRUCT accessor_body
          {
                $$ = $2;
          }
-       | CONSTRUCT SET block
+       | SET CONSTRUCT accessor_body
          {
                $$ = $3;
          }
        ;
 
+accessor_body
+       : block
+       | SEMICOLON
+         {
+               $$ = NULL;
+         }
+       ;
+
 block
        : OPEN_BRACE opt_statement_list CLOSE_BRACE
          {