2008-04-13 Jürg Billeter <j@bitron.ch>
+ * vala/Makefile.am, vala/valaassignment.vala,
+ vala/valabinaryexpression.vala, vala/valaclass.vala,
+ vala/valanamespace.vala, vala/valaparser.vala,
+ vala/valascanner.vala, vala/valascope.vala,
+ vala/valasourcefile.vala, vala/valasourcelocation.vala,
+ vala/valatokentype.vala, vala/valatuple.vala,
+ vala/valaunaryexpression.vala, vala/valaunresolvedtype.vala:
+
+ Replace generated Vala scanner and parser by handwritten classes
+
+2008-04-13 Jürg Billeter <j@bitron.ch>
+
* vapi/glib-2.0.vapi: add GEnumClass and GEnumValue bindings
2008-04-13 Jürg Billeter <j@bitron.ch>
-DPACKAGE_DATADIR=\"$(pkgdatadir)\" \
$(NULL)
-BUILT_SOURCES = parser.h vala.vala.stamp
-AM_YFLAGS = -d
+BUILT_SOURCES = vala.vala.stamp
noinst_LTLIBRARIES = \
libvalacore.la
valareferencetype.vala \
valareport.vala \
valareturnstatement.vala \
+ valascanner.vala \
valascope.vala \
valasemanticanalyzer.vala \
valasignal.vala \
valasizeofexpression.vala \
valasourcefile.vala \
valasourcefilecycle.vala \
+ valasourcelocation.vala \
valasourcereference.vala \
valastatement.vala \
valastringliteral.vala \
valasymbol.vala \
valasymbolresolver.vala \
valathrowstatement.vala \
+ valatokentype.vala \
valatrystatement.vala \
+ valatuple.vala \
valatypecheck.vala \
valatypeofexpression.vala \
valatypeparameter.vala \
$(NULL)
libvalacore_la_SOURCES = \
- parser.y \
- scanner.l \
vala.h \
vala.vala.stamp \
$(libvalacore_la_VALASOURCES:.vala=.c) \
+++ /dev/null
-/* parser.y
- *
- * Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
- *
- * 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.1 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>
- * Raffaele Sandrini <rasa@gmx.ch>
- */
-
-%{
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "vala.h"
-#include "parser.h"
-
-#define src(l) (vala_source_reference_new (current_source_file, l.first_line, l.first_column, l.last_line, l.last_column))
-
-#define src_com(l,c) (vala_source_reference_new_with_comment (current_source_file, l.first_line, l.first_column, l.last_line, l.last_column, c))
-
-static ValaCodeContext *context;
-static ValaSourceFile *current_source_file;
-static GList *symbol_stack;
-static GList *scope_stack;
-
-typedef enum {
- VALA_MODIFIER_NONE,
- VALA_MODIFIER_ABSTRACT = 1 << 0,
- VALA_MODIFIER_OVERRIDE = 1 << 1,
- VALA_MODIFIER_STATIC = 1 << 2,
- VALA_MODIFIER_VIRTUAL = 1 << 3,
- VALA_MODIFIER_VOLATILE = 1 << 4,
- VALA_MODIFIER_INLINE = 1 << 5
-} ValaModifier;
-
-int yylex (YYSTYPE *yylval_param, YYLTYPE *yylloc_param, ValaParser *parser);
-static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
-
-static void push_symbol (ValaSymbol *symbol);
-static ValaSymbol *pop_symbol (void);
-
-static gboolean check_is_namespace (ValaSymbol *symbol, ValaSourceReference *src);
-static gboolean check_is_class (ValaSymbol *symbol, ValaSourceReference *src);
-static gboolean check_is_struct (ValaSymbol *symbol, ValaSourceReference *src);
-%}
-
-%defines
-%locations
-%pure-parser
-%parse-param {ValaParser *parser}
-%lex-param {ValaParser *parser}
-%error-verbose
-%union {
- int num;
- char *str;
- GList *list;
- ValaUnresolvedSymbol *unresolved_symbol;
- ValaDataType *type_reference;
- ValaExpression *expression;
- ValaStatement *statement;
- ValaBlock *block;
- ValaInterface *interface;
- ValaEnumValue *enum_value;
- ValaErrorCode *error_code;
- ValaConstant *constant;
- ValaField *field;
- ValaMethod *method;
- ValaFormalParameter *formal_parameter;
- ValaProperty *property;
- ValaPropertyAccessor *property_accessor;
- ValaSignal *signal;
- ValaConstructor *constructor;
- ValaDestructor *destructor;
- ValaLocalVariableDeclaration *local_variable_declaration;
- ValaVariableDeclarator *variable_declarator;
- ValaTypeParameter *type_parameter;
- ValaMemberInitializer *member_initializer;
- ValaAttribute *attribute;
- ValaNamedArgument *named_argument;
- ValaSwitchSection *switch_section;
- ValaSwitchLabel *switch_label;
- ValaCatchClause *catch_clause;
-}
-
-%token OPEN_BRACE "{"
-%token CLOSE_BRACE "}"
-%token OPEN_PARENS "("
-%token OPEN_CAST_PARENS "cast ("
-%token CLOSE_PARENS ")"
-%token BRACKET_PAIR "[]"
-%token OPEN_ARRAY_TYPE_BRACKET "array ["
-%token OPEN_BRACKET "["
-%token CLOSE_BRACKET "]"
-%token ELLIPSIS "..."
-%token DOT "."
-%token COLON ":"
-%token COMMA ","
-%token SEMICOLON ";"
-%token HASH "#"
-%token INTERR "?"
-%token NULLABLE_INTERR "nullable ?"
-
-%token ASSIGN_BITWISE_OR "|="
-%token ASSIGN_BITWISE_AND "&="
-%token ASSIGN_BITWISE_XOR "^="
-%token ASSIGN_ADD "+="
-%token ASSIGN_SUB "-="
-%token ASSIGN_MUL "*="
-%token ASSIGN_DIV "/="
-%token ASSIGN_PERCENT "%="
-%token ASSIGN_SHIFT_LEFT "<<="
-%token ASSIGN_SHIFT_RIGHT ">>="
-
-%token OP_INC "++"
-%token OP_DEC "--"
-%token OP_EQ "=="
-%token OP_NE "!="
-%token OP_SHIFT_LEFT "<<"
-%token OP_SHIFT_RIGHT ">>"
-%token OP_LE "<="
-%token OP_GE ">="
-%token LAMBDA "=>"
-%token GENERIC_LT "generic <"
-%token OP_LT "<"
-%token OP_GT ">"
-%token OP_NEG "!"
-%token CARRET "^"
-%token BITWISE_OR "|"
-%token BITWISE_AND "&"
-%token OP_OR "||"
-%token OP_AND "&&"
-%token TILDE "~"
-
-%token OP_PTR "->"
-
-%token ASSIGN "="
-%token PLUS "+"
-%token MINUS "-"
-%token STAR "*"
-%token DIV "/"
-%token PERCENT "%"
-
-%token ABSTRACT "abstract"
-%token AS "as"
-%token BASE "base"
-%token BREAK "break"
-%token CASE "case"
-%token CATCH "catch"
-%token CLASS "class"
-%token CONST "const"
-%token CONSTRUCT "construct"
-%token CONTINUE "continue"
-%token DEFAULT "default"
-%token DELEGATE "delegate"
-%token DELETE "delete"
-%token DO "do"
-%token ELSE "else"
-%token ENSURES "ensures"
-%token ENUM "enum"
-%token ERRORDOMAIN "errordomain"
-%token VALA_FALSE "false"
-%token FINALLY "finally"
-%token FOR "for"
-%token FOREACH "foreach"
-%token GET "get"
-%token IF "if"
-%token IN "in"
-%token INLINE "inline"
-%token INTERFACE "interface"
-%token IS "is"
-%token LOCK "lock"
-%token NAMESPACE "namespace"
-%token NEW "new"
-%token VALA_NULL "null"
-%token OUT "out"
-%token OVERRIDE "override"
-%token PRIVATE "private"
-%token PROTECTED "protected"
-%token PUBLIC "public"
-%token REF "ref"
-%token REQUIRES "requires"
-%token RETURN "return"
-%token SET "set"
-%token SIGNAL "signal"
-%token SIZEOF "sizeof"
-%token STATIC "static"
-%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"
-%token VIRTUAL "virtual"
-%token VOID "void"
-%token VOLATILE "volatile"
-%token WEAK "weak"
-%token WHILE "while"
-
-%token <str> IDENTIFIER "identifier"
-%token <str> INTEGER_LITERAL "integer"
-%token <str> REAL_LITERAL "real"
-%token <str> CHARACTER_LITERAL "character"
-%token <str> STRING_LITERAL "string"
-
-%type <str> comment
-%type <str> identifier
-%type <str> identifier_or_keyword
-%type <expression> literal
-%type <expression> boolean_literal
-%type <num> stars
-%type <unresolved_symbol> symbol_name
-%type <type_reference> type_name
-%type <type_reference> type
-%type <list> opt_argument_list
-%type <list> argument_list
-%type <expression> argument
-%type <expression> primary_expression
-%type <expression> array_creation_expression
-%type <list> size_specifier_list
-%type <expression> opt_initializer
-%type <num> opt_rank_specifier
-%type <num> rank_specifier
-%type <num> opt_bracket_pair
-%type <num> bracket_pair
-%type <num> opt_comma_list
-%type <num> comma_list
-%type <expression> primary_no_array_creation_expression
-%type <expression> simple_name
-%type <expression> parenthesized_expression
-%type <expression> member_access
-%type <expression> pointer_member_access
-%type <expression> invocation_expression
-%type <expression> element_access
-%type <list> expression_list
-%type <expression> this_access
-%type <expression> base_access
-%type <expression> post_increment_expression
-%type <expression> post_decrement_expression
-%type <expression> object_creation_expression
-%type <list> opt_object_initializer
-%type <list> object_initializer
-%type <list> member_initializer_list
-%type <member_initializer> member_initializer
-%type <expression> sizeof_expression
-%type <expression> typeof_expression
-%type <expression> unary_expression
-%type <expression> pre_increment_expression
-%type <expression> pre_decrement_expression
-%type <expression> cast_expression
-%type <expression> pointer_indirection_expression
-%type <expression> addressof_expression
-%type <expression> multiplicative_expression
-%type <expression> additive_expression
-%type <expression> shift_expression
-%type <expression> relational_expression
-%type <expression> equality_expression
-%type <expression> and_expression
-%type <expression> exclusive_or_expression
-%type <expression> inclusive_or_expression
-%type <expression> in_expression
-%type <expression> conditional_and_expression
-%type <expression> conditional_or_expression
-%type <expression> conditional_expression
-%type <expression> lambda_expression
-%type <list> opt_lambda_parameter_list
-%type <list> lambda_parameter_list
-%type <expression> assignment
-%type <num> assignment_operator
-%type <expression> opt_expression
-%type <expression> expression
-%type <statement> statement
-%type <block> embedded_statement
-%type <block> block
-%type <list> opt_statement_list
-%type <list> statement_list
-%type <statement> empty_statement
-%type <statement> declaration_statement
-%type <local_variable_declaration> local_variable_declaration
-%type <type_reference> local_variable_type
-%type <num> opt_op_neg
-%type <num> opt_any_interr
-%type <num> opt_nullable_interr
-%type <statement> expression_statement
-%type <expression> statement_expression
-%type <statement> selection_statement
-%type <statement> if_statement
-%type <statement> switch_statement
-%type <list> switch_block
-%type <list> opt_switch_sections
-%type <list> switch_sections
-%type <switch_section> switch_section
-%type <list> switch_labels
-%type <switch_label> switch_label
-%type <statement> iteration_statement
-%type <statement> while_statement
-%type <statement> do_statement
-%type <statement> for_statement
-%type <list> opt_statement_expression_list
-%type <list> statement_expression_list
-%type <statement> foreach_statement
-%type <statement> jump_statement
-%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 <block> opt_finally_clause
-%type <block> finally_clause
-%type <statement> lock_statement
-%type <statement> delete_statement
-%type <str> opt_name_specifier
-%type <str> name_specifier
-%type <num> opt_access_modifier
-%type <num> access_modifier
-%type <num> opt_modifiers
-%type <num> modifiers
-%type <num> modifier
-%type <list> opt_class_base
-%type <list> class_base
-%type <list> type_list
-%type <property> property_declaration
-%type <property_accessor> opt_get_accessor_declaration
-%type <property_accessor> get_accessor_declaration
-%type <property_accessor> opt_set_accessor_declaration
-%type <property_accessor> set_accessor_declaration
-%type <expression> opt_default_value
-%type <expression> default_value
-%type <constant> constant_declaration
-%type <field> field_declaration
-%type <list> variable_declarators
-%type <variable_declarator> variable_declarator
-%type <expression> initializer
-%type <list> opt_variable_initializer_list
-%type <list> variable_initializer_list
-%type <expression> variable_initializer
-%type <method> method_declaration
-%type <method> method_header
-%type <block> method_body
-%type <list> opt_formal_parameter_list
-%type <list> formal_parameter_list
-%type <num> opt_construct
-%type <list> fixed_parameters
-%type <formal_parameter> fixed_parameter
-%type <list> opt_throws_declaration
-%type <list> throws_declaration
-%type <list> opt_requires_declarations
-%type <list> requires_declarations
-%type <expression> requires_declaration
-%type <list> opt_ensures_declarations
-%type <list> ensures_declarations
-%type <expression> ensures_declaration
-%type <signal> signal_declaration
-%type <constructor> constructor_declaration
-%type <destructor> destructor_declaration
-%type <list> opt_attributes
-%type <list> attributes
-%type <list> attribute_sections
-%type <list> attribute_section
-%type <list> attribute_list
-%type <attribute> attribute
-%type <str> attribute_name
-%type <list> opt_named_argument_list
-%type <list> named_argument_list
-%type <named_argument> named_argument
-%type <list> opt_type_parameter_list
-%type <list> type_parameter_list
-%type <list> type_parameters
-%type <type_parameter> type_parameter
-%type <list> opt_type_argument_list
-%type <list> type_argument_list
-%type <list> type_arguments
-%type <type_reference> type_argument
-%type <expression> member_name
-
-/* expect shift/reduce conflict on if/else */
-%expect 1
-
-%start compilation_unit
-
-%%
-
-opt_comma
- : /* empty */
- | COMMA
- ;
-
-/* identifiers never conflict with context-specific keywords get, set, requires, or ensures */
-identifier
- : IDENTIFIER
- | GET { $$ = g_strdup ("get"); }
- | SET { $$ = g_strdup ("set"); }
- | REQUIRES { $$ = g_strdup ("requires"); }
- | ENSURES { $$ = g_strdup ("ensures"); }
- ;
-
-/* identifiers never conflict with context-specific keywords get, set, requires, or ensures */
-identifier_or_keyword
- : IDENTIFIER
- | ABSTRACT { $$ = g_strdup ("abstract"); }
- | AS { $$ = g_strdup ("as"); }
- | BASE { $$ = g_strdup ("base"); }
- | BREAK { $$ = g_strdup ("break"); }
- | CASE { $$ = g_strdup ("case"); }
- | CATCH { $$ = g_strdup ("catch"); }
- | CLASS { $$ = g_strdup ("class"); }
- | CONST { $$ = g_strdup ("const"); }
- | CONSTRUCT { $$ = g_strdup ("construct"); }
- | CONTINUE { $$ = g_strdup ("continue"); }
- | DEFAULT { $$ = g_strdup ("default"); }
- | DELEGATE { $$ = g_strdup ("delegate"); }
- | DELETE { $$ = g_strdup ("delete"); }
- | DO { $$ = g_strdup ("do"); }
- | ELSE { $$ = g_strdup ("else"); }
- | ENSURES { $$ = g_strdup ("ensures"); }
- | ENUM { $$ = g_strdup ("enum"); }
- | ERRORDOMAIN { $$ = g_strdup ("errordomain"); }
- | VALA_FALSE { $$ = g_strdup ("false"); }
- | FINALLY { $$ = g_strdup ("finally"); }
- | FOR { $$ = g_strdup ("for"); }
- | FOREACH { $$ = g_strdup ("foreach"); }
- | GET { $$ = g_strdup ("get"); }
- | IF { $$ = g_strdup ("if"); }
- | IN { $$ = g_strdup ("in"); }
- | INLINE { $$ = g_strdup ("inline"); }
- | INTERFACE { $$ = g_strdup ("interface"); }
- | IS { $$ = g_strdup ("is"); }
- | LOCK { $$ = g_strdup ("lock"); }
- | NAMESPACE { $$ = g_strdup ("namespace"); }
- | NEW { $$ = g_strdup ("new"); }
- | VALA_NULL { $$ = g_strdup ("null"); }
- | OUT { $$ = g_strdup ("out"); }
- | OVERRIDE { $$ = g_strdup ("override"); }
- | PRIVATE { $$ = g_strdup ("private"); }
- | PROTECTED { $$ = g_strdup ("protected"); }
- | PUBLIC { $$ = g_strdup ("public"); }
- | REF { $$ = g_strdup ("ref"); }
- | REQUIRES { $$ = g_strdup ("requires"); }
- | RETURN { $$ = g_strdup ("return"); }
- | SET { $$ = g_strdup ("set"); }
- | SIGNAL { $$ = g_strdup ("signal"); }
- | SIZEOF { $$ = g_strdup ("sizeof"); }
- | STATIC { $$ = g_strdup ("static"); }
- | STRUCT { $$ = g_strdup ("struct"); }
- | SWITCH { $$ = g_strdup ("switch"); }
- | THIS { $$ = g_strdup ("this"); }
- | THROW { $$ = g_strdup ("throw"); }
- | THROWS { $$ = g_strdup ("throws"); }
- | VALA_TRUE { $$ = g_strdup ("true"); }
- | TRY { $$ = g_strdup ("try"); }
- | TYPEOF { $$ = g_strdup ("typeof"); }
- | USING { $$ = g_strdup ("using"); }
- | VAR { $$ = g_strdup ("var"); }
- | VIRTUAL { $$ = g_strdup ("virtual"); }
- | VOID { $$ = g_strdup ("void"); }
- | VOLATILE { $$ = g_strdup ("volatile"); }
- | WEAK { $$ = g_strdup ("weak"); }
- | WHILE { $$ = g_strdup ("while"); }
- ;
-
-literal
- : boolean_literal
- | INTEGER_LITERAL
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_integer_literal (context, $1, src));
- g_object_unref (src);
- g_free ($1);
- }
- | REAL_LITERAL
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_real_literal (context, $1, src));
- g_free ($1);
- g_object_unref (src);
- }
- | CHARACTER_LITERAL
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_character_literal (context, $1, src));
- g_object_unref (src);
- g_free ($1);
- }
- | STRING_LITERAL
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_string_literal (context, $1, src));
- g_object_unref (src);
- g_free ($1);
- }
- | VALA_NULL
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_null_literal (context, src));
- g_object_unref (src);
- }
- ;
-
-boolean_literal
- : VALA_TRUE
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_boolean_literal (context, TRUE, src));
- g_object_unref (src);
- }
- | VALA_FALSE
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_boolean_literal (context, FALSE, src));
- g_object_unref (src);
- }
- ;
-
-compilation_unit
- : opt_using_directives opt_outer_declarations
- ;
-
-symbol_name
- : identifier
- {
- ValaSourceReference *src = src(@1);
- $$ = vala_unresolved_symbol_new (NULL, $1, src);
- g_free ($1);
- g_object_unref (src);
- }
- | symbol_name DOT identifier
- {
- ValaSourceReference *src = src(@1);
- $$ = vala_unresolved_symbol_new ($1, $3, src);
- g_free ($3);
- g_object_unref (src);
- }
- ;
-
-type_name
- : symbol_name opt_type_argument_list
- {
- GList *l;
- ValaSourceReference *src = src(@1);
- $$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_symbol ($1, src));
- g_object_unref ($1);
- g_object_unref (src);
- for (l = $2; l != NULL; l = l->next) {
- vala_data_type_add_type_argument (VALA_DATA_TYPE ($$), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($2);
- }
- ;
-
-stars
- : STAR
- {
- $$ = 1;
- }
- | stars STAR
- {
- $$ = $1 + 1;
- }
- ;
-
-type
- : type_name opt_rank_specifier opt_op_neg opt_any_interr
- {
- $$ = $1;
- vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $2);
- if ($4) {
- vala_data_type_set_nullable ($$, TRUE);
- vala_data_type_set_requires_null_check ($$, TRUE);
- }
- }
- | WEAK type_name opt_rank_specifier opt_op_neg opt_any_interr
- {
- $$ = $2;
- vala_unresolved_type_set_is_weak (VALA_UNRESOLVED_TYPE ($$), TRUE);
- vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
- if ($5) {
- vala_data_type_set_nullable ($$, TRUE);
- vala_data_type_set_requires_null_check ($$, TRUE);
- }
- }
- | type_name opt_rank_specifier opt_op_neg opt_any_interr HASH
- {
- $$ = $1;
- vala_data_type_set_transfers_ownership ($$, TRUE);
- vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $2);
- if ($4) {
- vala_data_type_set_nullable ($$, TRUE);
- vala_data_type_set_requires_null_check ($$, TRUE);
- }
- }
- | REF type_name opt_rank_specifier opt_op_neg opt_any_interr
- {
- $$ = $2;
- vala_data_type_set_is_ref ($$, TRUE);
- vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
- if ($5) {
- vala_data_type_set_nullable ($$, TRUE);
- vala_data_type_set_requires_null_check ($$, TRUE);
- }
- }
- | OUT type_name opt_rank_specifier opt_op_neg opt_any_interr
- {
- $$ = $2;
- vala_data_type_set_is_out ($$, TRUE);
- vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
- if ($5) {
- vala_data_type_set_nullable ($$, TRUE);
- vala_data_type_set_requires_null_check ($$, TRUE);
- }
- }
- | OUT WEAK type_name opt_rank_specifier opt_op_neg opt_any_interr
- {
- $$ = $3;
- vala_unresolved_type_set_is_weak (VALA_UNRESOLVED_TYPE ($$), TRUE);
- vala_data_type_set_is_out ($$, TRUE);
- vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $4);
- if ($6) {
- vala_data_type_set_nullable ($$, TRUE);
- vala_data_type_set_requires_null_check ($$, TRUE);
- }
- }
- | type_name stars opt_rank_specifier
- {
- $$ = $1;
- vala_unresolved_type_set_pointer_level (VALA_UNRESOLVED_TYPE ($$), $2);
- vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
- }
- | VOID
- {
- $$ = VALA_DATA_TYPE (vala_void_type_new ());
- }
- | VOID stars
- {
- int pointer_level;
-
- $$ = VALA_DATA_TYPE (vala_void_type_new ());
-
- for (pointer_level = $2; pointer_level > 0; pointer_level--) {
- ValaDataType *base_type = $$;
- $$ = VALA_DATA_TYPE (vala_pointer_type_new (base_type));
- g_object_unref (base_type);
- }
- }
- ;
-
-opt_argument_list
- : /* empty */
- {
- $$ = NULL;
- }
- | argument_list
- ;
-
-argument_list
- : argument
- {
- $$ = g_list_append (NULL, $1);
- }
- | argument_list COMMA argument
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-argument
- : expression
- ;
-
-primary_expression
- : primary_no_array_creation_expression
- | array_creation_expression
- ;
-
-array_creation_expression
- : NEW member_name size_specifier_list opt_initializer
- {
- GList *l;
- ValaSourceReference *src = src(@2);
- ValaDataType *t = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression (VALA_EXPRESSION ($2)));
- $$ = VALA_EXPRESSION (vala_code_context_create_array_creation_expression (context, t, g_list_length ($3), VALA_INITIALIZER_LIST ($4), src));
- g_object_unref (t);
- for (l = $3; l != NULL; l = l->next) {
- vala_array_creation_expression_append_size (VALA_ARRAY_CREATION_EXPRESSION ($$), VALA_EXPRESSION (l->data));
- g_object_unref (l->data);
- }
- g_list_free ($3);
- g_object_unref (src);
- g_object_unref ($2);
- if ($4 != NULL) {
- g_object_unref ($4);
- }
- }
- | NEW member_name rank_specifier initializer
- {
- ValaSourceReference *src = src(@2);
- ValaDataType *t = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression (VALA_EXPRESSION ($2)));
- $$ = VALA_EXPRESSION (vala_code_context_create_array_creation_expression (context, t, $3, VALA_INITIALIZER_LIST ($4), src));
- g_object_unref (t);
- g_object_unref (src);
- g_object_unref ($2);
- g_object_unref ($4);
- }
- ;
-
-size_specifier_list
- : OPEN_BRACKET expression_list CLOSE_BRACKET
- {
- $$ = $2;
- }
- ;
-
-opt_initializer
- : /* empty */
- {
- $$ = NULL;
- }
- | initializer
- ;
-
-opt_rank_specifier
- : /* empty */
- {
- $$ = 0;
- }
- | rank_specifier
- ;
-
-rank_specifier
- : OPEN_BRACKET opt_comma_list CLOSE_BRACKET
- {
- $$ = $2;
- }
- | bracket_pair
- ;
-
-opt_bracket_pair
- : /* empty */
- {
- $$ = 0;
- }
- | bracket_pair
- ;
-
-bracket_pair
- : OPEN_ARRAY_TYPE_BRACKET opt_comma_list CLOSE_BRACKET
- {
- $$ = $2;
- }
- ;
-
-opt_comma_list
- : /* empty */
- {
- $$ = 1;
- }
- | comma_list
- ;
-
-comma_list
- : COMMA
- {
- $$ = 2;
- }
- | comma_list COMMA
- {
- $$ = $1 + 1;
- }
- ;
-
-primary_no_array_creation_expression
- : literal
- | simple_name
- | parenthesized_expression
- | member_access
- | pointer_member_access
- | invocation_expression
- | element_access
- | this_access
- | base_access
- | post_increment_expression
- | post_decrement_expression
- | object_creation_expression
- | sizeof_expression
- | typeof_expression
- ;
-
-simple_name
- : identifier opt_type_argument_list
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_member_access (context, NULL, $1, src));
- g_free ($1);
- g_object_unref (src);
-
- if ($2 != NULL) {
- GList *l;
- for (l = $2; l != NULL; l = l->next) {
- vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($2);
- }
- }
- ;
-
-parenthesized_expression
- : OPEN_PARENS expression CLOSE_PARENS
- {
- ValaSourceReference *src = src(@2);
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- $$ = VALA_EXPRESSION (vala_code_context_create_parenthesized_expression (context, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- ;
-
-member_access
- : primary_expression DOT identifier_or_keyword opt_type_argument_list
- {
- ValaSourceReference *src = src(@3);
- $$ = VALA_EXPRESSION (vala_code_context_create_member_access (context, $1, $3, src));
- g_object_unref ($1);
- g_free ($3);
- g_object_unref (src);
-
- if ($4 != NULL) {
- GList *l;
- for (l = $4; l != NULL; l = l->next) {
- vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($4);
- }
- }
- ;
-
-pointer_member_access
- : primary_expression OP_PTR identifier opt_type_argument_list
- {
- ValaSourceReference *src = src(@3);
- $$ = VALA_EXPRESSION (vala_code_context_create_member_access_pointer (context, $1, $3, src));
- g_object_unref ($1);
- g_free ($3);
- g_object_unref (src);
-
- if ($4 != NULL) {
- GList *l;
- for (l = $4; l != NULL; l = l->next) {
- vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($4);
- }
- }
- ;
-
-invocation_expression
- : primary_expression open_parens opt_argument_list CLOSE_PARENS
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_invocation_expression (context, $1, src));
- g_object_unref ($1);
- g_object_unref (src);
-
- if ($3 != NULL) {
- GList *l;
- for (l = $3; l != NULL; l = l->next) {
- if (l->data == NULL) {
- // error in subexpression
- } else {
- vala_invocation_expression_add_argument (VALA_INVOCATION_EXPRESSION ($$), l->data);
- g_object_unref (l->data);
- }
- }
- g_list_free ($3);
- }
- }
- ;
-
-element_access
- : primary_no_array_creation_expression OPEN_BRACKET expression_list CLOSE_BRACKET
- {
- GList *l;
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_element_access (context, $1, src));
- for (l = $3; l != NULL; l = l->next) {
- if (l->data == NULL) {
- // error in subexpression
- } else {
- vala_element_access_append_index (VALA_ELEMENT_ACCESS ($$), VALA_EXPRESSION (l->data));
- g_object_unref (l->data);
- }
- }
- g_list_free ($3);
- g_object_unref ($1);
- g_object_unref (src);
- }
- ;
-
-expression_list
- : expression
- {
- $$ = g_list_append (NULL, $1);
- }
- | expression_list COMMA expression
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-this_access
- : THIS
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_member_access (context, NULL, "this", src));
- g_object_unref (src);
- }
- ;
-
-base_access
- : BASE
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_base_access (context, src));
- g_object_unref (src);
- }
- ;
-
-post_increment_expression
- : primary_expression OP_INC
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_postfix_expression (context, $1, TRUE, src));
- g_object_unref (src);
- g_object_unref ($1);
- }
- ;
-
-post_decrement_expression
- : primary_expression OP_DEC
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_postfix_expression (context, $1, FALSE, src));
- g_object_unref (src);
- g_object_unref ($1);
- }
- ;
-
-object_creation_expression
- : NEW member_name open_parens opt_argument_list CLOSE_PARENS opt_object_initializer
- {
- ValaSourceReference *src = src(@2);
- ValaObjectCreationExpression *expr;
- vala_member_access_set_creation_member (VALA_MEMBER_ACCESS ($2), TRUE);
- expr = vala_code_context_create_object_creation_expression (context, VALA_MEMBER_ACCESS ($2), src);
- g_object_unref ($2);
- g_object_unref (src);
-
- if ($4 != NULL) {
- GList *l;
- for (l = $4; l != NULL; l = l->next) {
- vala_object_creation_expression_add_argument (expr, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($4);
- }
-
- if ($6 != NULL) {
- GList *l;
- for (l = $6; l != NULL; l = l->next) {
- vala_object_creation_expression_add_member_initializer (expr, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($6);
- }
-
- $$ = VALA_EXPRESSION (expr);
- }
- ;
-
-opt_object_initializer
- : /* empty */
- {
- $$ = NULL;
- }
- | object_initializer
- ;
-
-object_initializer
- : OPEN_BRACE member_initializer_list CLOSE_BRACE
- {
- $$ = $2;
- }
- ;
-
-member_initializer_list
- : member_initializer
- {
- $$ = g_list_append (NULL, $1);
- }
- | member_initializer_list COMMA member_initializer
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-member_initializer
- : IDENTIFIER ASSIGN expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = vala_member_initializer_new ($1, $3, src);
- g_object_unref (src);
- g_free ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-sizeof_expression
- : SIZEOF open_parens type_name CLOSE_PARENS
- {
- if ($3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_sizeof_expression (context, $3, src));
- g_object_unref ($3);
- g_object_unref (src);
- }
- }
-
-typeof_expression
- : TYPEOF open_parens type CLOSE_PARENS
- {
- if ($3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_typeof_expression (context, $3, src));
- g_object_unref ($3);
- g_object_unref (src);
- }
- }
-
-unary_expression
- : primary_expression
- | PLUS unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_unary_expression (context, VALA_UNARY_OPERATOR_PLUS, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- | MINUS unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_unary_expression (context, VALA_UNARY_OPERATOR_MINUS, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- | OP_NEG unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_unary_expression (context, VALA_UNARY_OPERATOR_LOGICAL_NEGATION, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- | TILDE unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_unary_expression (context, VALA_UNARY_OPERATOR_BITWISE_COMPLEMENT, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- | pre_increment_expression
- | pre_decrement_expression
- | REF unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_unary_expression (context, VALA_UNARY_OPERATOR_REF, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- | OUT unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_unary_expression (context, VALA_UNARY_OPERATOR_OUT, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- | HASH unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_reference_transfer_expression (context, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- | cast_expression
- | pointer_indirection_expression
- | addressof_expression
- ;
-
-pre_increment_expression
- : OP_INC unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_unary_expression (context, VALA_UNARY_OPERATOR_INCREMENT, $2, src));
- g_object_unref ($2);
- g_object_unref (src);
- }
- }
- ;
-
-pre_decrement_expression
- : OP_DEC unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_unary_expression (context, VALA_UNARY_OPERATOR_DECREMENT, $2, src));
- g_object_unref ($2);
- g_object_unref (src);
- }
- }
- ;
-
-cast_expression
- : OPEN_CAST_PARENS type CLOSE_PARENS unary_expression
- {
- if ($2 == NULL || $4 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_cast_expression (context, $4, $2, src, FALSE));
- g_object_unref (src);
- g_object_unref ($2);
- g_object_unref ($4);
- }
- }
- ;
-
-pointer_indirection_expression
- : STAR unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_pointer_indirection (context, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- ;
-
-addressof_expression
- : BITWISE_AND unary_expression
- {
- if ($2 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_addressof_expression (context, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- }
- ;
-
-multiplicative_expression
- : unary_expression
- | multiplicative_expression STAR unary_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_MUL, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- | multiplicative_expression DIV unary_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_DIV, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- | multiplicative_expression PERCENT unary_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_MOD, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-additive_expression
- : multiplicative_expression
- | additive_expression PLUS multiplicative_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_PLUS, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- | additive_expression MINUS multiplicative_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_MINUS, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-shift_expression
- : additive_expression
- | shift_expression OP_SHIFT_LEFT additive_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_SHIFT_LEFT, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- /* don't use two OP_GT to resolve parse conflicts
- * stacked generics won't be that common in vala */
- | shift_expression OP_SHIFT_RIGHT additive_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_SHIFT_RIGHT, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-relational_expression
- : shift_expression
- | relational_expression OP_LT shift_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_LESS_THAN, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- | relational_expression OP_GT shift_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_GREATER_THAN, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- | relational_expression OP_LE shift_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_LESS_THAN_OR_EQUAL, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- | relational_expression OP_GE shift_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_GREATER_THAN_OR_EQUAL, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- | relational_expression IS type_name
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_type_check (context, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- | relational_expression AS type_name
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_cast_expression (context, $1, $3, src, TRUE));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-equality_expression
- : relational_expression
- | equality_expression OP_EQ relational_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_EQUALITY, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- | equality_expression OP_NE relational_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_INEQUALITY, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-and_expression
- : equality_expression
- | and_expression BITWISE_AND equality_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_BITWISE_AND, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-exclusive_or_expression
- : and_expression
- | exclusive_or_expression CARRET and_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_BITWISE_XOR, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-inclusive_or_expression
- : exclusive_or_expression
- | inclusive_or_expression BITWISE_OR exclusive_or_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_BITWISE_OR, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-in_expression
- : inclusive_or_expression
- | in_expression IN inclusive_or_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_IN, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-
-conditional_and_expression
- : in_expression
- | conditional_and_expression OP_AND in_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_AND, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-conditional_or_expression
- : conditional_and_expression
- | conditional_or_expression OP_OR conditional_and_expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_binary_expression (context, VALA_BINARY_OPERATOR_OR, $1, $3, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-conditional_expression
- : conditional_or_expression
- | conditional_or_expression INTERR expression COLON expression
- {
- if ($1 == NULL || $3 == NULL || $5 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_conditional_expression (context, $1, $3, $5, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- g_object_unref ($5);
- }
- }
- ;
-
-lambda_expression
- : OPEN_PARENS opt_lambda_parameter_list CLOSE_PARENS LAMBDA expression
- {
- if ($5 == NULL) {
- // error in lambda expression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@4);
- $$ = VALA_EXPRESSION (vala_code_context_create_lambda_expression (context, $5, src));
- if ($2 != NULL) {
- GList *l;
- for (l = $2; l != NULL; l = l->next) {
- vala_lambda_expression_add_parameter (VALA_LAMBDA_EXPRESSION ($$), l->data);
- g_free (l->data);
- }
- g_list_free ($2);
- }
- g_object_unref ($5);
- g_object_unref (src);
- }
- }
- | identifier LAMBDA expression
- {
- if ($3 == NULL) {
- // error in lambda expression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_lambda_expression (context, $3, src));
- g_object_unref ($3);
- g_object_unref (src);
- vala_lambda_expression_add_parameter (VALA_LAMBDA_EXPRESSION ($$), $1);
- g_free ($1);
- }
- }
- | OPEN_PARENS opt_lambda_parameter_list CLOSE_PARENS LAMBDA block
- {
- if ($5 == NULL) {
- // error in lambda block
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@4);
- $$ = VALA_EXPRESSION (vala_code_context_create_lambda_expression_with_statement_body (context, VALA_BLOCK ($5), src));
- if ($2 != NULL) {
- GList *l;
- for (l = $2; l != NULL; l = l->next) {
- vala_lambda_expression_add_parameter (VALA_LAMBDA_EXPRESSION ($$), l->data);
- g_free (l->data);
- }
- g_list_free ($2);
- }
- g_object_unref ($5);
- g_object_unref (src);
- }
- }
- | identifier LAMBDA block
- {
- if ($3 == NULL) {
- // error in lambda block
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_lambda_expression_with_statement_body (context, VALA_BLOCK ($3), src));
- g_object_unref ($3);
- g_object_unref (src);
- vala_lambda_expression_add_parameter (VALA_LAMBDA_EXPRESSION ($$), $1);
- g_free ($1);
- }
- }
- ;
-
-opt_lambda_parameter_list
- : /* empty */
- {
- $$ = NULL;
- }
- | lambda_parameter_list
- ;
-
-lambda_parameter_list
- : identifier COMMA identifier
- {
- $$ = g_list_append (NULL, $1);
- $$ = g_list_append ($$, $3);
- }
- | lambda_parameter_list COMMA identifier
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-assignment
- : unary_expression assignment_operator expression
- {
- if ($1 == NULL || $3 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- ValaSourceReference *src = src(@2);
- $$ = VALA_EXPRESSION (vala_code_context_create_assignment (context, $1, $3, $2, src));
- g_object_unref (src);
- g_object_unref ($1);
- g_object_unref ($3);
- }
- }
- ;
-
-assignment_operator
- : ASSIGN
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_SIMPLE;
- }
- | ASSIGN_BITWISE_OR
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_BITWISE_OR;
- }
- | ASSIGN_BITWISE_AND
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_BITWISE_AND;
- }
- | ASSIGN_BITWISE_XOR
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_BITWISE_XOR;
- }
- | ASSIGN_ADD
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_ADD;
- }
- | ASSIGN_SUB
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_SUB;
- }
- | ASSIGN_MUL
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_MUL;
- }
- | ASSIGN_DIV
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_DIV;
- }
- | ASSIGN_PERCENT
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_PERCENT;
- }
- | ASSIGN_SHIFT_LEFT
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_SHIFT_LEFT;
- }
- | ASSIGN_SHIFT_RIGHT
- {
- $$ = VALA_ASSIGNMENT_OPERATOR_SHIFT_RIGHT;
- }
- ;
-
-opt_expression
- : /* empty */
- {
- $$ = NULL;
- }
- | expression
- ;
-
-expression
- : conditional_expression
- | lambda_expression
- | assignment
- | error
- {
- $$ = NULL;
- }
- ;
-
-statement
- : declaration_statement
- | block
- {
- $$ = VALA_STATEMENT ($1);
- }
- | empty_statement
- | expression_statement
- | selection_statement
- | iteration_statement
- | jump_statement
- | try_statement
- | lock_statement
- | delete_statement
- ;
-
-embedded_statement
- : block
- | empty_statement
- {
- ValaSourceReference *src = src(@1);
- if ($1 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- $$ = vala_code_context_create_block (context, src);
- vala_block_add_statement ($$, $1);
- g_object_unref ($1);
- g_object_unref (src);
- }
- }
- | expression_statement
- {
- ValaSourceReference *src = src(@1);
- if ($1 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- $$ = vala_code_context_create_block (context, src);
- vala_block_add_statement ($$, $1);
- g_object_unref ($1);
- g_object_unref (src);
- }
- }
- | selection_statement
- {
- ValaSourceReference *src = src(@1);
- if ($1 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- $$ = vala_code_context_create_block (context, src);
- vala_block_add_statement ($$, $1);
- g_object_unref ($1);
- g_object_unref (src);
- }
- }
- | iteration_statement
- {
- ValaSourceReference *src = src(@1);
- if ($1 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- $$ = vala_code_context_create_block (context, src);
- vala_block_add_statement ($$, $1);
- g_object_unref ($1);
- g_object_unref (src);
- }
- }
- | jump_statement
- {
- ValaSourceReference *src = src(@1);
- if ($1 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- $$ = vala_code_context_create_block (context, src);
- vala_block_add_statement ($$, $1);
- g_object_unref ($1);
- g_object_unref (src);
- }
- }
- | try_statement
- {
- ValaSourceReference *src = src(@1);
- if ($1 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- $$ = vala_code_context_create_block (context, src);
- vala_block_add_statement ($$, $1);
- g_object_unref ($1);
- g_object_unref (src);
- }
- }
- | lock_statement
- {
- ValaSourceReference *src = src(@1);
- if ($1 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- $$ = vala_code_context_create_block (context, src);
- vala_block_add_statement ($$, $1);
- g_object_unref ($1);
- g_object_unref (src);
- }
- }
- | delete_statement
- {
- ValaSourceReference *src = src(@1);
- if ($1 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- $$ = vala_code_context_create_block (context, src);
- vala_block_add_statement ($$, $1);
- g_object_unref ($1);
- g_object_unref (src);
- }
- }
- ;
-
-block
- : OPEN_BRACE opt_statement_list CLOSE_BRACE
- {
- ValaSourceReference *src = src(@1);
- $$ = vala_code_context_create_block (context, src);
- if ($2 != NULL) {
- GList *l;
- for (l = $2; l != NULL; l = l->next) {
- if (l->data == NULL) {
- // error in subexpression
- } else {
- vala_block_add_statement ($$, l->data);
- g_object_unref (l->data);
- }
- }
- g_list_free ($2);
- }
- g_object_unref (src);
- }
- ;
-
-opt_statement_list
- : /* empty */
- {
- $$ = NULL;
- }
- | statement_list
- ;
-
-statement_list
- : statement
- {
- $$ = g_list_append (NULL, $1);
- }
- | statement_list statement
- {
- $$ = g_list_append ($1, $2);
- }
- ;
-
-empty_statement
- : SEMICOLON
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_STATEMENT (vala_code_context_create_empty_statement (context, src));
- g_object_unref (src);
- }
- ;
-
-declaration_statement
- : comment local_variable_declaration SEMICOLON
- {
- ValaSourceReference *src = src_com(@2, $1);
- $$ = VALA_STATEMENT (vala_code_context_create_declaration_statement (context, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- ;
-
-local_variable_declaration
- : local_variable_type variable_declarators
- {
- GList *l;
- ValaSourceReference *src = src(@2);
- $$ = vala_code_context_create_local_variable_declaration (context, $1, src);
- g_object_unref (src);
- for (l = $2; l != NULL; l = l->next) {
- ValaVariableDeclarator *decl = l->data;
- ValaDataType *type = vala_data_type_copy ($1);
- vala_variable_declarator_set_type_reference (decl, type);
- g_object_unref (type);
- vala_local_variable_declaration_add_declarator ($$, decl);
- g_object_unref (decl);
- }
- g_list_free ($2);
- g_object_unref ($1);
- }
- | VAR variable_declarators
- {
- GList *l;
- ValaSourceReference *src = src(@2);
- $$ = vala_code_context_create_local_variable_declaration_var_type (context, src);
- g_object_unref (src);
- for (l = $2; l != NULL; l = l->next) {
- vala_local_variable_declaration_add_declarator ($$, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($2);
- }
- ;
-
-/* don't use type to prevent reduce/reduce conflict */
-local_variable_type
- : primary_expression opt_bracket_pair opt_op_neg opt_nullable_interr
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression ($1));
- g_object_unref ($1);
- g_object_unref (src);
- vala_data_type_set_takes_ownership ($$, TRUE);
- vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $2);
- vala_data_type_set_nullable ($$, TRUE);
- }
- | primary_expression stars
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression ($1));
- g_object_unref ($1);
- g_object_unref (src);
- vala_unresolved_type_set_pointer_level (VALA_UNRESOLVED_TYPE ($$), $2);
- }
- | WEAK primary_expression opt_bracket_pair opt_op_neg opt_nullable_interr
- {
- ValaSourceReference *src = src(@2);
- $$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression ($2));
- g_object_unref ($2);
- g_object_unref (src);
- vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
- vala_data_type_set_nullable ($$, TRUE);
- }
- | VOID
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_DATA_TYPE (vala_void_type_new ());
- g_object_unref (src);
- }
- | VOID stars
- {
- int pointer_level;
- ValaSourceReference *src = src(@1);
- $$ = VALA_DATA_TYPE (vala_void_type_new ());
- g_object_unref (src);
-
- for (pointer_level = $2; pointer_level > 0; pointer_level--) {
- ValaDataType *base_type = $$;
- $$ = VALA_DATA_TYPE (vala_pointer_type_new (base_type));
- g_object_unref (base_type);
- }
- }
- ;
-
-opt_op_neg
- : /* empty */
- {
- $$ = FALSE;
- }
- | OP_NEG
- {
- $$ = TRUE;
- }
- ;
-
-opt_any_interr
- : /* empty */
- {
- $$ = FALSE;
- }
- | INTERR
- {
- $$ = TRUE;
- }
- | NULLABLE_INTERR
- {
- $$ = TRUE;
- }
- ;
-
-opt_nullable_interr
- : /* empty */
- {
- $$ = FALSE;
- }
- | NULLABLE_INTERR
- {
- $$ = TRUE;
- }
- ;
-
-expression_statement
- : comment statement_expression SEMICOLON
- {
- ValaSourceReference *src = src_com(@2, $1);
- $$ = VALA_STATEMENT (vala_code_context_create_expression_statement (context, $2, src));
- g_object_unref (src);
- g_object_unref ($2);
- }
- ;
-
-statement_expression
- : invocation_expression
- | object_creation_expression
- | assignment
- | post_increment_expression
- | post_decrement_expression
- | pre_increment_expression
- | pre_decrement_expression
- ;
-
-selection_statement
- : if_statement
- | switch_statement
- ;
-
-if_statement
- : comment IF open_parens expression CLOSE_PARENS embedded_statement
- {
- ValaSourceReference *src;
-
- if ($4 == NULL || $6 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- src = src_com(@4, $1);
- $$ = VALA_STATEMENT (vala_code_context_create_if_statement (context, $4, $6, NULL, src));
- g_object_unref (src);
- g_object_unref ($4);
- g_object_unref ($6);
- }
- }
- | comment IF open_parens expression CLOSE_PARENS embedded_statement ELSE embedded_statement
- {
- ValaSourceReference *src;
-
- if ($4 == NULL || $6 == NULL || $8 == NULL) {
- // error in subexpression
- $$ = NULL;
- } else {
- src = src_com(@4, $1);
- $$ = VALA_STATEMENT (vala_code_context_create_if_statement (context, $4, $6, $8, src));
- g_object_unref (src);
- g_object_unref ($4);
- g_object_unref ($6);
- g_object_unref ($8);
- }
- }
- ;
-
-switch_statement
- : comment SWITCH open_parens expression CLOSE_PARENS switch_block
- {
- ValaSourceReference *src = src_com(@4, $1);
- $$ = VALA_STATEMENT (vala_code_context_create_switch_statement (context, $4, src));
- g_object_unref ($4);
- g_object_unref (src);
-
- if ($6 != NULL) {
- GList *l;
- for (l = $6; l != NULL; l = l->next) {
- vala_switch_statement_add_section (VALA_SWITCH_STATEMENT ($$), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($6);
- }
- }
- ;
-
-switch_block
- : OPEN_BRACE opt_switch_sections CLOSE_BRACE
- {
- $$ = $2;
- }
- ;
-
-opt_switch_sections
- : /* empty */
- {
- $$ = NULL;
- }
- | switch_sections
- ;
-
-switch_sections
- : switch_section
- {
- $$ = g_list_append (NULL, $1);
- }
- | switch_sections switch_section
- {
- $$ = g_list_append ($1, $2);
- }
- ;
-
-switch_section
- : comment switch_labels statement_list
- {
- GList *l;
- ValaSourceReference *src = src_com(@2, $1);
- $$ = vala_code_context_create_switch_section (context, src);
- g_object_unref (src);
-
- for (l = $2; l != NULL; l = l->next) {
- vala_switch_section_add_label ($$, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($2);
- for (l = $3; l != NULL; l = l->next) {
- vala_switch_section_add_statement ($$, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($3);
- }
- ;
-
-switch_labels
- : switch_label
- {
- $$ = g_list_append (NULL, $1);
- }
- | switch_labels switch_label
- {
- $$ = g_list_append ($1, $2);
- }
- ;
-
-switch_label
- : CASE expression COLON
- {
- ValaSourceReference *src = src(@2);
- $$ = vala_code_context_create_switch_label (context, $2, src);
- g_object_unref ($2);
- g_object_unref (src);
- }
- | DEFAULT COLON
- {
- ValaSourceReference *src = src(@1);
- $$ = vala_code_context_create_switch_label_with_default (context, src);
- g_object_unref (src);
- }
- ;
-
-iteration_statement
- : while_statement
- | do_statement
- | for_statement
- | foreach_statement
- ;
-
-while_statement
- : WHILE open_parens expression CLOSE_PARENS embedded_statement
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_STATEMENT (vala_code_context_create_while_statement (context, $3, $5, src));
- g_object_unref (src);
- g_object_unref ($3);
- g_object_unref ($5);
- }
- ;
-
-do_statement
- : DO embedded_statement WHILE open_parens expression CLOSE_PARENS SEMICOLON
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_STATEMENT (vala_code_context_create_do_statement (context, $2, $5, src));
- g_object_unref ($2);
- g_object_unref ($5);
- g_object_unref (src);
- }
- ;
-
-for_statement
- : FOR OPEN_PARENS opt_statement_expression_list SEMICOLON opt_expression SEMICOLON opt_statement_expression_list CLOSE_PARENS embedded_statement
- {
- GList *l;
- ValaSourceReference *src = src(@1);
- $$ = VALA_STATEMENT (vala_code_context_create_for_statement (context, $5, $9, src));
- if ($5 != NULL) {
- g_object_unref ($5);
- }
- g_object_unref ($9);
- g_object_unref (src);
-
- if ($3 != NULL) {
- for (l = $3; l != NULL; l = l->next) {
- vala_for_statement_add_initializer (VALA_FOR_STATEMENT ($$), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($3);
- }
- if ($7 != NULL) {
- for (l = $7; l != NULL; l = l->next) {
- vala_for_statement_add_iterator (VALA_FOR_STATEMENT ($$), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($7);
- }
- }
- | FOR OPEN_PARENS local_variable_declaration SEMICOLON opt_expression SEMICOLON opt_statement_expression_list CLOSE_PARENS embedded_statement
- {
- GeeCollection *decls;
- GeeIterator *decls_it;
-
- ValaDeclarationStatement *decl_statement;
-
- ValaSourceReference *src = src(@1);
-
- ValaBlock *block = vala_code_context_create_block (context, src);
-
- ValaForStatement *for_statement = vala_code_context_create_for_statement (context, $5, $9, src);
- if ($5 != NULL) {
- g_object_unref ($5);
- }
- g_object_unref ($9);
-
-
- decls = vala_local_variable_declaration_get_variable_declarators ($3);
- decls_it = gee_iterable_iterator (GEE_ITERABLE (decls));
- g_object_unref (decls);
- while (gee_iterator_next (decls_it)) {
- ValaVariableDeclarator *decl = gee_iterator_get (decls_it);
- ValaExpression *init = vala_variable_declarator_get_initializer (decl);
-
- if (init != NULL) {
- ValaSourceReference *decl_src = vala_code_node_get_source_reference (VALA_CODE_NODE (decl));
- ValaMemberAccess *lhs = vala_code_context_create_member_access (context, NULL, vala_symbol_get_name (VALA_SYMBOL (decl)), decl_src);
- ValaAssignment *assign = vala_code_context_create_assignment (context, VALA_EXPRESSION (lhs), init, VALA_ASSIGNMENT_OPERATOR_SIMPLE, decl_src);
- g_object_unref (lhs);
- vala_for_statement_add_initializer (for_statement, VALA_EXPRESSION (assign));
- g_object_unref (assign);
-
- vala_variable_declarator_set_initializer (decl, NULL);
- }
- }
- g_object_unref (decls_it);
-
- decl_statement = vala_code_context_create_declaration_statement (context, $3, src);
- g_object_unref ($3);
- g_object_unref (src);
- vala_block_add_statement (block, VALA_STATEMENT (decl_statement));
- g_object_unref (decl_statement);
-
- if ($7 != NULL) {
- GList *l;
- for (l = $7; l != NULL; l = l->next) {
- vala_for_statement_add_iterator (for_statement, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($7);
- }
-
- vala_block_add_statement (block, VALA_STATEMENT (for_statement));
-
- $$ = VALA_STATEMENT (block);
- }
- ;
-
-opt_statement_expression_list
- : /* empty */
- {
- $$ = NULL;
- }
- | statement_expression_list
- ;
-
-statement_expression_list
- : statement_expression
- {
- $$ = g_list_append (NULL, $1);
- }
- | statement_expression_list COMMA statement_expression
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-foreach_statement
- : FOREACH OPEN_PARENS type identifier IN expression CLOSE_PARENS embedded_statement
- {
- ValaSourceReference *src = src(@3);
- if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($3))) {
- vala_data_type_set_takes_ownership ($3, TRUE);
- }
- $$ = VALA_STATEMENT (vala_code_context_create_foreach_statement (context, $3, $4, $6, $8, src));
- g_object_unref ($3);
- g_free ($4);
- g_object_unref ($6);
- g_object_unref ($8);
- g_object_unref (src);
- }
- ;
-
-jump_statement
- : break_statement
- | continue_statement
- | return_statement
- | throw_statement
- ;
-
-break_statement
- : BREAK SEMICOLON
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_STATEMENT (vala_code_context_create_break_statement (context, src));
- g_object_unref (src);
- }
- ;
-
-continue_statement
- : CONTINUE SEMICOLON
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_STATEMENT (vala_code_context_create_continue_statement (context, src));
- g_object_unref (src);
- }
- ;
-
-return_statement
- : RETURN opt_expression SEMICOLON
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_STATEMENT (vala_code_context_create_return_statement (context, $2, src));
- g_object_unref (src);
- if ($2 != NULL) {
- g_object_unref ($2);
- }
- }
- ;
-
-throw_statement
- : THROW expression SEMICOLON
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_STATEMENT (vala_code_context_create_throw_statement (context, $2, src));
- g_object_unref (src);
- if ($2 != NULL) {
- g_object_unref ($2);
- }
- }
- ;
-
-try_statement
- : TRY block catch_clauses opt_finally_clause
- {
- GList *l;
- ValaSourceReference *src = src(@1);
- $$ = VALA_STATEMENT (vala_code_context_create_try_statement (context, $2, $4, src));
- g_object_unref ($2);
- if ($4 != NULL) {
- g_object_unref ($4);
- }
- g_object_unref (src);
-
- 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_code_context_create_try_statement (context, $2, $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_code_context_create_catch_clause (context, $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_code_context_create_catch_clause (context, 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
- {
- ValaSourceReference *src = src_com(@4, $1);
- $$ = VALA_STATEMENT (vala_code_context_create_lock_statement (context, $4, $6, src));
- g_object_unref (src);
- g_object_unref ($4);
- g_object_unref ($6);
- }
- ;
-
-delete_statement
- : comment DELETE expression SEMICOLON
- {
- ValaSourceReference *src = src_com(@2, $1);
- $$ = VALA_STATEMENT (vala_code_context_create_delete_statement (context, $3, src));
- g_object_unref (src);
- g_object_unref ($3);
- }
- ;
-
-namespace_declaration
- : comment opt_attributes NAMESPACE identifier
- {
- ValaSourceReference *src = src_com(@4, $1);
- ValaSymbol *current_symbol = vala_scope_lookup (scope_stack->data, $4);
- if (current_symbol != NULL) {
- if (check_is_namespace (current_symbol, src)) {
- // merge namespace declarations
- if (!vala_source_file_get_pkg (current_source_file)) {
- vala_namespace_set_pkg (VALA_NAMESPACE (current_symbol), FALSE);
- }
- VALA_CODE_NODE (current_symbol)->attributes = $2;
- }
- } else {
- current_symbol = VALA_SYMBOL (vala_code_context_create_namespace (context, $4, src));
- vala_namespace_set_pkg (VALA_NAMESPACE (current_symbol), vala_source_file_get_pkg (current_source_file));
- VALA_CODE_NODE (current_symbol)->attributes = g_list_concat (VALA_CODE_NODE (current_symbol)->attributes, $2);
- vala_namespace_add_namespace (VALA_NAMESPACE (symbol_stack->data), VALA_NAMESPACE (current_symbol));
- }
- g_object_unref (src);
- g_free ($4);
-
- push_symbol (current_symbol);
- }
- namespace_body
- {
- g_object_unref (pop_symbol ());
- }
- ;
-
-namespace_body
- : OPEN_BRACE opt_namespace_member_declarations CLOSE_BRACE
- | OPEN_BRACE error CLOSE_BRACE
- ;
-
-opt_name_specifier
- : /* empty */
- {
- $$ = NULL;
- }
- | name_specifier
- ;
-
-name_specifier
- : DOT identifier
- {
- $$ = $2;
- }
- ;
-
-opt_using_directives
- : /* empty */
- | using_directives
- ;
-
-using_directives
- : using_directive
- | using_directives using_directive
- ;
-
-using_directive
- : USING using_list SEMICOLON
- ;
-
-using_list
- : using_list COMMA namespace_identifier
- | namespace_identifier
- ;
-
-namespace_identifier
- : identifier
- {
- ValaSourceReference *src = src(@1);
- ValaNamespaceReference *ns_ref = vala_namespace_reference_new ($1, src);
- g_object_unref (src);
- g_free ($1);
- vala_source_file_add_using_directive (current_source_file, ns_ref);
- g_object_unref (ns_ref);
- }
- ;
-
-opt_outer_declarations
- : /* empty */
- | outer_declarations
- ;
-
-outer_declarations
- : outer_declaration
- | outer_declarations outer_declaration
- ;
-
-outer_declaration
- : namespace_member_declaration
- ;
-
-opt_namespace_member_declarations
- : /* empty */
- | namespace_member_declarations
- ;
-
-namespace_member_declarations
- : namespace_member_declaration
- | namespace_member_declarations namespace_member_declaration
- ;
-
-namespace_member_declaration
- : namespace_declaration
- | class_declaration
- | struct_declaration
- | interface_declaration
- | enum_declaration
- | errordomain_declaration
- | delegate_declaration
- | constant_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_namespace_add_constant (VALA_NAMESPACE (symbol_stack->data), $1);
- vala_source_file_add_node (current_source_file, VALA_CODE_NODE ($1));
- g_object_unref ($1);
- }
- }
- | field_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- /* field must be static, don't require developer
- * to explicitly state it */
- vala_field_set_instance ($1, FALSE);
-
- vala_namespace_add_field (VALA_NAMESPACE (symbol_stack->data), $1);
- vala_source_file_add_node (current_source_file, VALA_CODE_NODE ($1));
- g_object_unref ($1);
- }
- }
- | method_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- /* method must be static, don't require developer
- * to explicitly state it */
- vala_method_set_instance ($1, FALSE);
-
- vala_namespace_add_method (VALA_NAMESPACE (symbol_stack->data), $1);
- vala_source_file_add_node (current_source_file, VALA_CODE_NODE ($1));
- g_object_unref ($1);
- }
- }
- ;
-
-class_declaration
- : comment opt_attributes opt_access_modifier opt_modifiers CLASS identifier opt_name_specifier opt_type_parameter_list opt_class_base
- {
- ValaSourceReference *src;
-
- char *name = $6;
-
- ValaSymbol *parent_symbol = VALA_SYMBOL (g_object_ref (symbol_stack->data));
- ValaScope *parent_scope = VALA_SCOPE (scope_stack->data);
- ValaSymbol *current_symbol;
-
- if ($7 != NULL) {
- ValaSourceReference *ns_src = src(@6);
- g_object_unref (parent_symbol);
- parent_symbol = vala_scope_lookup (parent_scope, $6);
- if (parent_symbol != NULL) {
- if (check_is_namespace (parent_symbol, ns_src)) {
- if (!vala_source_file_get_pkg (current_source_file)) {
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), FALSE);
- }
- }
- } else {
- parent_symbol = VALA_SYMBOL (vala_code_context_create_namespace (context, $6, ns_src));
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), vala_source_file_get_pkg (current_source_file));
- vala_namespace_add_namespace (VALA_NAMESPACE (symbol_stack->data), VALA_NAMESPACE (parent_symbol));
- }
- parent_scope = vala_symbol_get_scope (parent_symbol);
- g_free ($6);
- g_object_unref (ns_src);
-
- name = $7;
- }
-
- src = src_com(@6, $1);
- current_symbol = vala_scope_lookup (parent_scope, name);
- if (current_symbol != NULL) {
- if (check_is_class (current_symbol, src)) {
- // merge class declarations
- }
- } else {
- current_symbol = VALA_SYMBOL (vala_code_context_create_class (context, name, src));
- g_free (name);
- g_object_unref (src);
-
- if (VALA_IS_CLASS (parent_symbol)) {
- vala_class_add_class (VALA_CLASS (parent_symbol), VALA_CLASS (current_symbol));
- } else if (VALA_IS_INTERFACE (parent_symbol)) {
- vala_interface_add_class (VALA_INTERFACE (parent_symbol), VALA_CLASS (current_symbol));
- } else if (VALA_IS_NAMESPACE (parent_symbol)) {
- vala_namespace_add_class (VALA_NAMESPACE (parent_symbol), VALA_CLASS (current_symbol));
- vala_source_file_add_node (current_source_file, VALA_CODE_NODE (current_symbol));
- } else {
- g_assert_not_reached ();
- }
-
- VALA_CODE_NODE (current_symbol)->attributes = $2;
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL (current_symbol), $3);
- }
- if (($4 & VALA_MODIFIER_ABSTRACT) == VALA_MODIFIER_ABSTRACT) {
- vala_class_set_is_abstract (VALA_CLASS (current_symbol), TRUE);
- }
- if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
- vala_class_set_is_static (VALA_CLASS (current_symbol), TRUE);
- }
- if ($8 != NULL) {
- GList *l;
- for (l = $8; l != NULL; l = l->next) {
- vala_class_add_type_parameter (VALA_CLASS (current_symbol), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($8);
- }
- if ($9 != NULL) {
- GList *l;
- for (l = $9; l != NULL; l = l->next) {
- vala_class_add_base_type (VALA_CLASS (current_symbol), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($9);
- }
- }
-
- g_object_unref (parent_symbol);
- push_symbol (current_symbol);
- }
- class_body
- {
- /* ensure there is always a default construction method */
- ValaClass *cl = VALA_CLASS (symbol_stack->data);
- if (!vala_source_file_get_pkg (current_source_file) &&
- !vala_class_get_is_abstract (cl) &&
- !vala_class_get_is_static (cl) &&
- vala_class_get_default_construction_method (cl) == NULL) {
- ValaSourceReference *src;
- ValaMethod *m;
- ValaBlock *block;
- src = vala_code_node_get_source_reference (VALA_CODE_NODE (cl));
- m = VALA_METHOD (vala_code_context_create_creation_method (context, vala_symbol_get_name (VALA_SYMBOL (cl)), NULL, src));
- vala_method_set_instance (m, FALSE);
- vala_symbol_set_access (VALA_SYMBOL (m), VALA_SYMBOL_ACCESSIBILITY_PUBLIC);
- block = vala_code_context_create_block (context, src);
- vala_method_set_body (m, block);
- g_object_unref (block);
- vala_class_add_method (cl, m);
- g_object_unref (m);
- }
- g_object_unref (pop_symbol ());
- }
- ;
-
-opt_access_modifier
- : /* empty */
- {
- $$ = -1;
- }
- | access_modifier
- ;
-
-access_modifier
- : PUBLIC
- {
- $$ = VALA_SYMBOL_ACCESSIBILITY_PUBLIC;
- }
- | PROTECTED
- {
- $$ = VALA_SYMBOL_ACCESSIBILITY_PROTECTED;
- }
- | PRIVATE
- {
- $$ = VALA_SYMBOL_ACCESSIBILITY_PRIVATE;
- }
- ;
-
-opt_modifiers
- : /* empty */
- {
- $$ = VALA_MODIFIER_NONE;
- }
- | modifiers
- ;
-
-modifiers
- : modifier
- | modifiers modifier
- {
- if (($1 & $2) == $2) {
- ValaSourceReference *src = src(@2);
- vala_report_error (src, "Modifier may only be specified once.");
- g_object_unref (src);
- }
- $$ = $1 | $2;
- }
- ;
-
-modifier
- : ABSTRACT
- {
- $$ = VALA_MODIFIER_ABSTRACT;
- }
- | OVERRIDE
- {
- $$ = VALA_MODIFIER_OVERRIDE;
- }
- | STATIC
- {
- $$ = VALA_MODIFIER_STATIC;
- }
- | VIRTUAL
- {
- $$ = VALA_MODIFIER_VIRTUAL;
- }
- | VOLATILE
- {
- $$ = VALA_MODIFIER_VOLATILE;
- }
- | INLINE
- {
- $$ = VALA_MODIFIER_INLINE;
- }
- ;
-
-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
- : OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
- ;
-
-opt_class_member_declarations
- : /* empty */
- | class_member_declarations
- ;
-
-class_member_declarations
- : class_member_declaration
- | class_member_declarations class_member_declaration
- ;
-
-class_member_declaration
- : constant_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_class_add_constant (VALA_CLASS (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | field_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_class_add_field (VALA_CLASS (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | method_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_class_add_method (VALA_CLASS (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | property_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_class_add_property (VALA_CLASS (symbol_stack->data), $1, FALSE);
- g_object_unref ($1);
- }
- }
- | signal_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_class_add_signal (VALA_CLASS (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | constructor_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- if (vala_constructor_get_instance ($1)) {
- vala_class_set_constructor (VALA_CLASS (symbol_stack->data), $1);
- } else {
- vala_class_set_static_constructor (VALA_CLASS (symbol_stack->data), $1);
- }
- g_object_unref ($1);
- }
- }
- | destructor_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_class_set_destructor (VALA_CLASS (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | class_declaration
- | struct_declaration
- | enum_declaration
- | delegate_declaration
- ;
-
-constant_declaration
- : comment opt_attributes opt_access_modifier CONST type variable_declarator SEMICOLON
- {
- ValaSourceReference *src = src_com(@5, $1);
- $$ = vala_code_context_create_constant (context, vala_symbol_get_name (VALA_SYMBOL ($6)), $5, vala_variable_declarator_get_initializer ($6), src);
- g_object_unref (src);
- g_object_unref ($5);
- g_object_unref ($6);
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL ($$), $3);
- }
- VALA_CODE_NODE($$)->attributes = $2;
- }
- ;
-
-field_declaration
- : comment opt_attributes opt_access_modifier opt_modifiers type variable_declarator SEMICOLON
- {
- ValaSourceReference *src;
-
- src = src_com(@6, $1);
-
- if (VALA_IS_UNRESOLVED_TYPE ($5)) {
- if (vala_data_type_get_is_ref ($5) || vala_data_type_get_is_out ($5)) {
- vala_report_error (src, "`ref' and `out' may only be used for parameters.");
- }
- if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
- vala_data_type_set_takes_ownership ($5, TRUE);
- }
- }
-
- $$ = vala_code_context_create_field (context, vala_symbol_get_name (VALA_SYMBOL ($6)), $5, vala_variable_declarator_get_initializer ($6), src);
- g_object_unref (src);
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL ($$), $3);
- }
- if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
- vala_field_set_instance ($$, FALSE);
- }
- if (($4 & VALA_MODIFIER_VOLATILE) == VALA_MODIFIER_VOLATILE) {
- vala_field_set_is_volatile ($$, TRUE);
- }
- VALA_CODE_NODE($$)->attributes = $2;
- g_object_unref ($5);
- g_object_unref ($6);
- }
- ;
-
-comment
- :
- {
- $$ = vala_parser_pop_comment (parser);
- }
- ;
-
-variable_declarators
- : variable_declarator
- {
- $$ = g_list_append (NULL, $1);
- }
- | variable_declarators COMMA variable_declarator
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-variable_declarator
- : identifier
- {
- ValaSourceReference *src = src(@1);
- $$ = vala_code_context_create_variable_declarator (context, $1, NULL, src);
- g_object_unref (src);
- g_free ($1);
- }
- | identifier ASSIGN variable_initializer
- {
- ValaSourceReference *src = src(@1);
- $$ = vala_code_context_create_variable_declarator (context, $1, $3, src);
- g_object_unref (src);
- g_free ($1);
- g_object_unref ($3);
- }
- ;
-
-initializer
- : OPEN_BRACE opt_variable_initializer_list CLOSE_BRACE
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_initializer_list (context, src));
- g_object_unref (src);
-
- if ($2 != NULL) {
- GList *l;
- for (l = $2; l != NULL; l = l->next) {
- vala_initializer_list_append (VALA_INITIALIZER_LIST ($$), l->data);
- g_object_unref (l->data);
- }
- }
- }
- ;
-
-opt_variable_initializer_list
- : /* empty */
- {
- $$ = NULL;
- }
- | variable_initializer_list
- ;
-
-variable_initializer_list
- : variable_initializer
- {
- $$ = g_list_append (NULL, $1);
- }
- | variable_initializer_list COMMA variable_initializer
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-variable_initializer
- : expression
- | initializer
- ;
-
-method_declaration
- : method_header method_body
- {
- ValaCodeNode *n = VALA_CODE_NODE ($1);
- if (n != NULL) {
- ValaAttribute *a = vala_code_node_get_attribute (n, "Import");
- gboolean imported;
- if (a != NULL) {
- imported = TRUE;
- g_object_unref (a);
- } else {
- imported = FALSE;
- }
- $$ = $1;
- vala_method_set_body ($$, $2);
-
- if ($2 != NULL) {
- g_object_unref ($2);
- /* method must not be imported, abstract or from a VAPI file */
- if (imported || vala_method_get_is_abstract ($1) || vala_source_file_get_pkg (current_source_file)) {
- ValaSourceReference *sr = vala_code_node_get_source_reference (n);
- vala_report_error (sr, "unexpected method body found");
- g_object_unref (sr);
- }
- } else {
- /* only imported, abstract and VAPI methods are allowed to have no body */
- if (!imported && !vala_method_get_is_abstract ($1) && !vala_source_file_get_pkg (current_source_file)) {
- ValaSourceReference *sr = vala_code_node_get_source_reference (n);
- vala_report_error (sr, "expected method body got `;'");
- g_object_unref (sr);
- }
- }
- }
- }
- | error method_body
- {
- $$ = NULL;
- }
- ;
-
-method_header
- : comment opt_attributes opt_access_modifier opt_modifiers type identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_throws_declaration opt_requires_declarations opt_ensures_declarations
- {
- GList *l;
- ValaSourceReference *src;
- ValaModifier vmodifiers;
-
- src = src_com(@6, $1);
-
- if (VALA_IS_UNRESOLVED_TYPE ($5)) {
- if (vala_data_type_get_is_ref ($5) || vala_data_type_get_is_out ($5)) {
- vala_report_error (src, "`ref' and `out' may only be used for parameters.");
- }
- if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
- vala_data_type_set_transfers_ownership ($5, TRUE);
- }
- }
-
- $$ = vala_code_context_create_method (context, $6, $5, src);
- g_object_unref (src);
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL ($$), $3);
- }
- if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
- vala_method_set_instance ($$, FALSE);
- }
- vmodifiers = $4 & (VALA_MODIFIER_ABSTRACT | VALA_MODIFIER_VIRTUAL | VALA_MODIFIER_OVERRIDE);
- if (vmodifiers == 0) {
- } else if (vmodifiers == VALA_MODIFIER_ABSTRACT) {
- vala_method_set_is_abstract ($$, TRUE);
- } else if (vmodifiers == VALA_MODIFIER_VIRTUAL) {
- vala_method_set_is_virtual ($$, TRUE);
- } else if (vmodifiers == VALA_MODIFIER_OVERRIDE) {
- vala_method_set_overrides ($$, TRUE);
- } else {
- vala_report_error (vala_code_node_get_source_reference (VALA_CODE_NODE ($$)), "Only one of `abstract', `virtual', and `override' may be specified.");
- vala_code_node_set_error (VALA_CODE_NODE ($$), TRUE);
- }
- if (($4 & VALA_MODIFIER_INLINE) == VALA_MODIFIER_INLINE) {
- vala_method_set_is_inline ($$, TRUE);
- }
- VALA_CODE_NODE($$)->attributes = $2;
-
- for (l = $8; l != NULL; l = l->next) {
- vala_method_add_parameter ($$, l->data);
- g_object_unref (l->data);
- }
- if ($8 != NULL) {
- g_list_free ($8);
- }
-
- for (l = $10; l != NULL; l = l->next) {
- vala_method_add_error_domain ($$, l->data);
- g_object_unref (l->data);
- }
- if ($10 != NULL) {
- g_list_free ($10);
- }
-
- if ($11 != NULL) {
- for (l = $11; l != NULL; l = l->next) {
- vala_method_add_precondition ($$, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($11);
- }
-
- if ($12 != NULL) {
- for (l = $12; l != NULL; l = l->next) {
- vala_method_add_postcondition ($$, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($12);
- }
-
- g_object_unref ($5);
- g_free ($6);
-
- if (vala_code_context_ignore_node (context, VALA_CODE_NODE ($$))) {
- g_object_unref ($$);
- $$ = NULL;
- }
- }
- | comment opt_attributes opt_access_modifier opt_modifiers symbol_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_throws_declaration
- {
- GList *l;
-
- ValaSourceReference *src = src_com(@5, $1);
- if (vala_unresolved_symbol_get_inner ($5) == NULL) {
- $$ = VALA_METHOD (vala_code_context_create_creation_method (context, vala_unresolved_symbol_get_name ($5), NULL, src)); } else {
- $$ = VALA_METHOD (vala_code_context_create_creation_method (context, vala_unresolved_symbol_get_name (vala_unresolved_symbol_get_inner ($5)), vala_unresolved_symbol_get_name ($5), src));
- }
- g_object_unref ($5);
- g_object_unref (src);
- vala_method_set_instance ($$, FALSE);
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL ($$), $3);
- }
- VALA_CODE_NODE($$)->attributes = $2;
-
- if ($7 != NULL) {
- for (l = $7; l != NULL; l = l->next) {
- vala_method_add_parameter ($$, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($7);
- }
-
- for (l = $9; l != NULL; l = l->next) {
- vala_method_add_error_domain ($$, l->data);
- g_object_unref (l->data);
- }
- if ($9 != NULL) {
- g_list_free ($9);
- }
- }
- ;
-
-method_body
- : block
- | SEMICOLON
- {
- $$ = NULL;
- }
- ;
-
-opt_formal_parameter_list
- : /* empty */
- {
- $$ = NULL;
- }
- | formal_parameter_list
- ;
-
-formal_parameter_list
- : fixed_parameters
- | fixed_parameters COMMA ELLIPSIS
- {
- ValaSourceReference *src = src(@3);
- $$ = g_list_append ($1, vala_code_context_create_formal_parameter_with_ellipsis (context, src));
- g_object_unref (src);
- }
- | ELLIPSIS
- {
- ValaSourceReference *src = src(@1);
- $$ = g_list_append (NULL, vala_code_context_create_formal_parameter_with_ellipsis (context, src));
- g_object_unref (src);
- }
- ;
-
-fixed_parameters
- : fixed_parameter
- {
- $$ = g_list_append (NULL, $1);
- }
- | fixed_parameters COMMA fixed_parameter
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-opt_construct
- : /* empty */
- {
- $$ = FALSE;
- }
- | CONSTRUCT
- {
- $$ = TRUE;
- }
- ;
-
-fixed_parameter
- : opt_attributes opt_construct type identifier
- {
- ValaSourceReference *src;
-
- src = src(@3);
- if (VALA_IS_UNRESOLVED_TYPE ($3)) {
- if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($3))) {
- vala_data_type_set_takes_ownership ($3, TRUE);
- }
-
- if (!vala_data_type_get_is_ref ($3)
- && !vala_data_type_get_is_out ($3)
- && !vala_data_type_get_transfers_ownership ($3)) {
- /* take_ownership for in parameters that don't transfer ownership is not supported */
- vala_data_type_set_takes_ownership ($3, FALSE);
- }
- }
-
- $$ = vala_code_context_create_formal_parameter (context, $4, $3, src);
- g_object_unref (src);
- vala_formal_parameter_set_construct_parameter ($$, $2);
- g_object_unref ($3);
- g_free ($4);
-
- VALA_CODE_NODE($$)->attributes = $1;
- }
- | opt_attributes opt_construct type identifier ASSIGN expression
- {
- ValaSourceReference *src;
-
- src = src(@3);
- if (VALA_IS_UNRESOLVED_TYPE ($3)) {
- if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($3))) {
- vala_data_type_set_takes_ownership ($3, TRUE);
- }
-
- if (!vala_data_type_get_is_ref ($3)
- && !vala_data_type_get_is_out ($3)
- && !vala_data_type_get_transfers_ownership ($3)) {
- /* take_ownership for in parameters that don't transfer ownership is not supported */
- vala_data_type_set_takes_ownership ($3, FALSE);
- }
- }
-
- $$ = vala_code_context_create_formal_parameter (context, $4, $3, src);
- g_object_unref (src);
- vala_formal_parameter_set_default_expression ($$, $6);
- vala_formal_parameter_set_construct_parameter ($$, $2);
- g_object_unref ($3);
- g_free ($4);
- g_object_unref ($6);
-
- VALA_CODE_NODE($$)->attributes = $1;
- }
- ;
-
-opt_throws_declaration
- : /* empty */
- {
- $$ = NULL;
- }
- | throws_declaration
- ;
-
-throws_declaration
- : THROWS type_list
- {
- $$ = $2;
- }
- ;
-
-opt_requires_declarations
- : /* empty */
- {
- $$ = NULL;
- }
- | requires_declarations
- ;
-
-requires_declarations
- : requires_declaration
- {
- $$ = g_list_append (NULL, $1);
- }
- | requires_declarations requires_declaration
- {
- $$ = g_list_append ($1, $2);
- }
- ;
-
-requires_declaration
- : REQUIRES open_parens expression CLOSE_PARENS
- {
- $$ = $3;
- }
- ;
-
-opt_ensures_declarations
- : /* empty */
- {
- $$ = NULL;
- }
- | ensures_declarations
- ;
-
-ensures_declarations
- : ensures_declaration
- {
- $$ = g_list_append (NULL, $1);
- }
- | ensures_declarations ensures_declaration
- {
- $$ = g_list_append ($1, $2);
- }
- ;
-
-ensures_declaration
- : ENSURES open_parens expression CLOSE_PARENS
- {
- $$ = $3;
- }
- ;
-
-property_declaration
- : comment opt_attributes opt_access_modifier opt_modifiers type identifier OPEN_BRACE get_accessor_declaration opt_set_accessor_declaration opt_default_value CLOSE_BRACE
- {
- ValaSourceReference *src;
-
- if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
- vala_data_type_set_takes_ownership ($5, TRUE);
- }
-
- src = src_com(@5, $1);
- $$ = vala_code_context_create_property (context, $6, $5, $8, $9, src);
- g_object_unref (src);
-
- VALA_CODE_NODE($$)->attributes = $2;
-
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL ($$), $3);
- }
-
- g_object_unref ($5);
- g_free ($6);
- g_object_unref ($8);
- if ($9 != NULL) {
- g_object_unref ($9);
- }
-
- if ($10 != NULL) {
- vala_property_set_default_expression ($$, $10);
- g_object_unref ($10);
- }
-
- if (($4 & VALA_MODIFIER_ABSTRACT) == VALA_MODIFIER_ABSTRACT) {
- vala_property_set_is_abstract ($$, TRUE);
- }
- if (($4 & VALA_MODIFIER_VIRTUAL) == VALA_MODIFIER_VIRTUAL) {
- vala_property_set_is_virtual ($$, TRUE);
- }
- if (($4 & VALA_MODIFIER_OVERRIDE) == VALA_MODIFIER_OVERRIDE) {
- vala_property_set_overrides ($$, TRUE);
- }
- if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
- vala_property_set_instance ($$, FALSE);
- }
- }
- | comment opt_attributes opt_access_modifier opt_modifiers type identifier OPEN_BRACE set_accessor_declaration opt_get_accessor_declaration opt_default_value CLOSE_BRACE
- {
- ValaSourceReference *src;
-
- if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
- vala_data_type_set_takes_ownership ($5, TRUE);
- }
-
- src = src_com(@5, $1);
- $$ = vala_code_context_create_property (context, $6, $5, $9, $8, src);
- g_object_unref (src);
-
- VALA_CODE_NODE($$)->attributes = $2;
-
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL ($$), $3);
- }
-
- g_object_unref ($5);
- g_free ($6);
- g_object_unref ($8);
- if ($9 != NULL) {
- g_object_unref ($9);
- }
-
- if ($10 != NULL) {
- vala_property_set_default_expression ($$, $10);
- g_object_unref ($10);
- }
-
- if (($4 & VALA_MODIFIER_ABSTRACT) == VALA_MODIFIER_ABSTRACT) {
- vala_property_set_is_abstract ($$, TRUE);
- }
- if (($4 & VALA_MODIFIER_VIRTUAL) == VALA_MODIFIER_VIRTUAL) {
- vala_property_set_is_virtual ($$, TRUE);
- }
- if (($4 & VALA_MODIFIER_OVERRIDE) == VALA_MODIFIER_OVERRIDE) {
- vala_property_set_overrides ($$, TRUE);
- }
- if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
- vala_property_set_instance ($$, FALSE);
- }
- }
- ;
-
-opt_get_accessor_declaration
- : /* empty */
- {
- $$ = NULL;
- }
- | get_accessor_declaration
- ;
-
-get_accessor_declaration
- : opt_attributes opt_access_modifier GET method_body
- {
- ValaSourceReference *src = src(@3);
- $$ = vala_code_context_create_property_accessor (context, TRUE, FALSE, FALSE, $4, src);
- g_object_unref (src);
- if ($4 != NULL) {
- g_object_unref ($4);
- }
-
- if ($2 != -1) {
- vala_property_accessor_set_access ($$, $2);
- } else {
- vala_property_accessor_set_access ($$, VALA_SYMBOL_ACCESSIBILITY_PUBLIC);
- }
- }
- ;
-
-opt_set_accessor_declaration
- : /* empty */
- {
- $$ = NULL;
- }
- | set_accessor_declaration
- ;
-
-set_accessor_declaration
- : opt_attributes opt_access_modifier SET method_body
- {
- ValaSourceReference *src = src(@3);
- $$ = vala_code_context_create_property_accessor (context, FALSE, TRUE, FALSE, $4, src);
- g_object_unref (src);
- if ($4 != NULL) {
- g_object_unref ($4);
- }
-
- if ($2 != -1) {
- vala_property_accessor_set_access ($$, $2);
- } else {
- vala_property_accessor_set_access ($$, VALA_SYMBOL_ACCESSIBILITY_PUBLIC);
- }
- }
- | opt_attributes opt_access_modifier SET CONSTRUCT method_body
- {
- ValaSourceReference *src = src(@3);
- $$ = vala_code_context_create_property_accessor (context, FALSE, TRUE, TRUE, $5, src);
- g_object_unref (src);
- if ($5 != NULL) {
- g_object_unref ($5);
- }
-
- if ($2 != -1) {
- vala_property_accessor_set_access ($$, $2);
- } else {
- vala_property_accessor_set_access ($$, VALA_SYMBOL_ACCESSIBILITY_PUBLIC);
- }
- }
- | opt_attributes opt_access_modifier CONSTRUCT method_body
- {
- ValaSourceReference *src = src(@3);
- $$ = vala_code_context_create_property_accessor (context, FALSE, FALSE, TRUE, $4, src);
- g_object_unref (src);
- if ($4 != NULL) {
- g_object_unref ($4);
- }
-
- if ($2 != -1) {
- vala_property_accessor_set_access ($$, $2);
- } else {
- vala_property_accessor_set_access ($$, VALA_SYMBOL_ACCESSIBILITY_PUBLIC);
- }
- }
- | opt_attributes opt_access_modifier CONSTRUCT SET method_body
- {
- ValaSourceReference *src = src(@3);
- $$ = vala_code_context_create_property_accessor (context, FALSE, TRUE, TRUE, $5, src);
- g_object_unref (src);
- if ($5 != NULL) {
- g_object_unref ($5);
- }
-
- if ($2 != -1) {
- vala_property_accessor_set_access ($$, $2);
- } else {
- vala_property_accessor_set_access ($$, VALA_SYMBOL_ACCESSIBILITY_PUBLIC);
- }
- }
- ;
-
-opt_default_value
- : /* empty */
- {
- $$ = NULL;
- }
- | default_value
- ;
-
-default_value
- : DEFAULT OPEN_PARENS expression CLOSE_PARENS SEMICOLON
- {
- $$ = $3;
- }
- | DEFAULT ASSIGN expression SEMICOLON
- {
- $$ = $3;
- }
- ;
-
-signal_declaration
- : comment opt_attributes opt_access_modifier SIGNAL type identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON
- {
- GList *l;
-
- ValaSourceReference *src = src_com(@6, $1);
- $$ = vala_code_context_create_signal (context, $6, $5, src);
- g_object_unref (src);
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL ($$), $3);
- }
- VALA_CODE_NODE($$)->attributes = $2;
-
- for (l = $8; l != NULL; l = l->next) {
- vala_signal_add_parameter ($$, l->data);
- g_object_unref (l->data);
- }
- if ($8 != NULL) {
- g_list_free ($8);
- }
-
- g_object_unref ($5);
- g_free ($6);
- }
- ;
-
-constructor_declaration
- : comment opt_attributes opt_access_modifier opt_modifiers CONSTRUCT block
- {
- ValaSourceReference *src = src_com(@5, $1);
- $$ = vala_code_context_create_constructor (context, src);
- g_object_unref (src);
- vala_constructor_set_body ($$, $6);
- g_object_unref ($6);
-
- if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
- vala_constructor_set_instance ($$, FALSE);
- }
- }
- ;
-
-destructor_declaration
- : comment opt_attributes opt_access_modifier opt_modifiers TILDE identifier OPEN_PARENS CLOSE_PARENS block
- {
- ValaSourceReference *src = src_com(@6, $1);
- $$ = vala_code_context_create_destructor (context, src);
- g_object_unref (src);
- vala_destructor_set_body ($$, $9);
-
- g_free ($6);
- g_object_unref ($9);
- }
- ;
-
-struct_declaration
- : comment opt_attributes opt_access_modifier STRUCT identifier opt_name_specifier opt_type_parameter_list opt_class_base
- {
- GList *l;
- ValaSourceReference *src;
-
- char *name = $5;
-
- ValaSymbol *parent_symbol = VALA_SYMBOL (g_object_ref (symbol_stack->data));
- ValaScope *parent_scope = VALA_SCOPE (scope_stack->data);
- ValaSymbol *current_symbol;
-
- if ($6 != NULL) {
- ValaSourceReference *ns_src = src(@5);
- g_object_unref (parent_symbol);
- parent_symbol = vala_scope_lookup (parent_scope, $5);
- if (parent_symbol != NULL) {
- if (check_is_namespace (parent_symbol, ns_src)) {
- if (!vala_source_file_get_pkg (current_source_file)) {
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), FALSE);
- }
- }
- } else {
- parent_symbol = VALA_SYMBOL (vala_code_context_create_namespace (context, $5, ns_src));
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), vala_source_file_get_pkg (current_source_file));
- vala_namespace_add_namespace (VALA_NAMESPACE (symbol_stack->data), VALA_NAMESPACE (parent_symbol));
- }
- parent_scope = vala_symbol_get_scope (parent_symbol);
- g_free ($5);
- g_object_unref (ns_src);
-
- name = $6;
- }
-
- src = src_com(@5, $1);
- current_symbol = vala_scope_lookup (parent_scope, name);
- if (current_symbol != NULL) {
- if (check_is_struct (current_symbol, src)) {
- // merge class declarations
- }
- } else {
- current_symbol = VALA_SYMBOL (vala_code_context_create_struct (context, name, src));
- g_free (name);
- g_object_unref (src);
-
- if (VALA_IS_CLASS (parent_symbol)) {
- vala_class_add_struct (VALA_CLASS (parent_symbol), VALA_STRUCT (current_symbol));
- } else if (VALA_IS_INTERFACE (parent_symbol)) {
- vala_interface_add_struct (VALA_INTERFACE (parent_symbol), VALA_STRUCT (current_symbol));
- } else if (VALA_IS_NAMESPACE (parent_symbol)) {
- vala_namespace_add_struct (VALA_NAMESPACE (parent_symbol), VALA_STRUCT (current_symbol));
- vala_source_file_add_node (current_source_file, VALA_CODE_NODE (current_symbol));
- } else {
- g_assert_not_reached ();
- }
-
- for (l = $7; l != NULL; l = l->next) {
- vala_struct_add_type_parameter (VALA_STRUCT (current_symbol), l->data);
- }
- VALA_CODE_NODE(current_symbol)->attributes = $2;
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL (current_symbol), $3);
- }
- if ($8 != NULL) {
- for (l = $8; l != NULL; l = l->next) {
- vala_struct_add_base_type (VALA_STRUCT (current_symbol), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($8);
- }
- }
-
- g_object_unref (parent_symbol);
- push_symbol (current_symbol);
- }
- struct_body
- {
- g_object_unref (pop_symbol ());
- }
- ;
-
-struct_body
- : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE
- ;
-
-opt_struct_member_declarations
- : /* empty */
- | struct_member_declarations
- ;
-
-struct_member_declarations
- : struct_member_declaration
- | struct_member_declarations struct_member_declaration
- ;
-
-struct_member_declaration
- : constant_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_struct_add_constant (VALA_STRUCT (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | field_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- /* struct fields must not have initializers */
- ValaExpression *init = vala_field_get_initializer ($1);
- if (init != NULL) {
- ValaSourceReference *src = src(@1);
- vala_report_error (src, "Unexpected field initializer found");
- g_object_unref (src);
- }
- vala_struct_add_field (VALA_STRUCT (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | method_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_struct_add_method (VALA_STRUCT (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- ;
-
-interface_declaration
- : comment opt_attributes opt_access_modifier opt_modifiers INTERFACE identifier opt_name_specifier opt_type_parameter_list opt_class_base
- {
- ValaSourceReference *src;
- char *name = $6;
-
- ValaSymbol *parent_symbol = VALA_SYMBOL (g_object_ref (symbol_stack->data));
- ValaScope *parent_scope = VALA_SCOPE (scope_stack->data);
- ValaInterface *iface;
-
- if ($7 != NULL) {
- ValaSourceReference *ns_src = src(@6);
- g_object_unref (parent_symbol);
- parent_symbol = vala_scope_lookup (parent_scope, $6);
- if (parent_symbol != NULL) {
- if (check_is_namespace (parent_symbol, ns_src)) {
- if (!vala_source_file_get_pkg (current_source_file)) {
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), FALSE);
- }
- }
- } else {
- parent_symbol = VALA_SYMBOL (vala_code_context_create_namespace (context, $6, ns_src));
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), vala_source_file_get_pkg (current_source_file));
- vala_namespace_add_namespace (VALA_NAMESPACE (symbol_stack->data), VALA_NAMESPACE (parent_symbol));
- }
- parent_scope = vala_symbol_get_scope (parent_symbol);
- g_free ($6);
- g_object_unref (ns_src);
-
- name = $7;
- }
-
- src = src_com(@6, $1);
- iface = vala_code_context_create_interface (context, name, src);
- g_free (name);
- g_object_unref (src);
-
- vala_namespace_add_interface (VALA_NAMESPACE (parent_symbol), iface);
- vala_source_file_add_node (current_source_file, VALA_CODE_NODE (iface));
- g_object_unref (parent_symbol);
-
- VALA_CODE_NODE (iface)->attributes = $2;
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL (iface), $3);
- }
- if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
- vala_interface_set_is_static (iface, TRUE);
- }
- if ($8 != NULL) {
- GList *l;
- for (l = $8; l != NULL; l = l->next) {
- vala_interface_add_type_parameter (iface, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($8);
- }
- if ($9 != NULL) {
- GList *l;
- for (l = $9; l != NULL; l = l->next) {
- vala_interface_add_prerequisite (iface, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($9);
- }
-
- push_symbol (VALA_SYMBOL (iface));
- }
- interface_body
- {
- g_object_unref (pop_symbol ());
- }
- ;
-
-interface_body
- : OPEN_BRACE opt_interface_member_declarations CLOSE_BRACE
- | SEMICOLON
- {
- vala_symbol_set_is_imported (symbol_stack->data, TRUE);
- vala_interface_set_declaration_only (VALA_INTERFACE (symbol_stack->data), TRUE);
- }
- ;
-
-opt_interface_member_declarations
- : /* empty */
- | interface_member_declarations
- ;
-
-interface_member_declarations
- : interface_member_declaration
- | interface_member_declarations interface_member_declaration
- ;
-
-interface_member_declaration
- : method_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_interface_add_method (VALA_INTERFACE (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | field_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_interface_add_field (VALA_INTERFACE (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | property_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_interface_add_property (VALA_INTERFACE (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | signal_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_interface_add_signal (VALA_INTERFACE (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- | class_declaration
- | struct_declaration
- | enum_declaration
- | delegate_declaration
- ;
-
-enum_declaration
- : comment opt_attributes opt_access_modifier ENUM identifier opt_name_specifier
- {
- ValaSourceReference *src;
-
- char *name = $5;
-
- ValaSymbol *parent_symbol = VALA_SYMBOL (g_object_ref (symbol_stack->data));
- ValaScope *parent_scope = VALA_SCOPE (scope_stack->data);
- ValaEnum *en;
-
- if ($6 != NULL) {
- ValaSourceReference *ns_src = src(@5);
- g_object_unref (parent_symbol);
- parent_symbol = vala_scope_lookup (parent_scope, $5);
- if (parent_symbol != NULL) {
- if (check_is_namespace (parent_symbol, ns_src)) {
- if (!vala_source_file_get_pkg (current_source_file)) {
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), FALSE);
- }
- }
- } else {
- parent_symbol = VALA_SYMBOL (vala_code_context_create_namespace (context, $5, ns_src));
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), vala_source_file_get_pkg (current_source_file));
- vala_namespace_add_namespace (VALA_NAMESPACE (symbol_stack->data), VALA_NAMESPACE (parent_symbol));
- }
- parent_scope = vala_symbol_get_scope (parent_symbol);
- g_free ($5);
- g_object_unref (ns_src);
-
- name = $6;
- }
-
- src = src_com(@5, $1);
- en = vala_code_context_create_enum (context, name, src);
- g_free (name);
- g_object_unref (src);
-
- if (VALA_IS_CLASS (parent_symbol)) {
- vala_class_add_enum (VALA_CLASS (parent_symbol), en);
- } else if (VALA_IS_INTERFACE (parent_symbol)) {
- vala_interface_add_enum (VALA_INTERFACE (parent_symbol), en);
- } else if (VALA_IS_NAMESPACE (parent_symbol)) {
- vala_namespace_add_enum (VALA_NAMESPACE (parent_symbol), en);
- vala_source_file_add_node (current_source_file, VALA_CODE_NODE (en));
- } else {
- g_assert_not_reached ();
- }
- g_object_unref (parent_symbol);
-
- VALA_CODE_NODE (en)->attributes = $2;
-
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL (en), $3);
- }
-
- push_symbol (VALA_SYMBOL (en));
- }
- enum_body
- {
- g_object_unref (pop_symbol ());
- }
- ;
-
-enum_body
- : OPEN_BRACE opt_enum_member_declarations opt_enum_method_declarations CLOSE_BRACE
- ;
-
-opt_enum_member_declarations
- : /* empty */
- | enum_member_declarations opt_comma
- ;
-
-enum_member_declarations
- : enum_member_declaration
- | enum_member_declarations COMMA enum_member_declaration
- ;
-
-enum_member_declaration
- : comment opt_attributes identifier
- {
- ValaSourceReference *src;
- ValaEnumValue *ev;
-
- src = src_com(@3, $1);
- ev = vala_code_context_create_enum_value (context, $3, src);
- g_free ($3);
- vala_enum_add_value (VALA_ENUM (symbol_stack->data), ev);
- g_object_unref (ev);
- }
- | comment opt_attributes identifier ASSIGN expression
- {
- ValaSourceReference *src;
- ValaEnumValue *ev;
-
- src = src_com(@3, $1);
- ev = vala_code_context_create_enum_value_with_value (context, $3, $5, src);
- g_free ($3);
- g_object_unref ($5);
- vala_enum_add_value (VALA_ENUM (symbol_stack->data), ev);
- g_object_unref (ev);
- }
- ;
-
-opt_enum_method_declarations
- : /* empty */
- | enum_method_declarations
- ;
-
-enum_method_declarations
- : SEMICOLON enum_method_declaration
- | enum_method_declarations enum_method_declaration
- ;
-
-enum_method_declaration
- : method_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_enum_add_method (VALA_ENUM (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- ;
-
-errordomain_declaration
- : comment opt_attributes opt_access_modifier ERRORDOMAIN identifier opt_name_specifier
- {
- ValaSourceReference *src;
-
- char *name = $5;
-
- ValaSymbol *parent_symbol = VALA_SYMBOL (g_object_ref (symbol_stack->data));
- ValaScope *parent_scope = VALA_SCOPE (scope_stack->data);
- ValaErrorDomain *edomain;
-
- if ($6 != NULL) {
- ValaSourceReference *ns_src = src(@5);
- g_object_unref (parent_symbol);
- parent_symbol = vala_scope_lookup (parent_scope, $5);
- if (parent_symbol != NULL) {
- if (check_is_namespace (parent_symbol, ns_src)) {
- if (!vala_source_file_get_pkg (current_source_file)) {
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), FALSE);
- }
- }
- } else {
- parent_symbol = VALA_SYMBOL (vala_code_context_create_namespace (context, $5, ns_src));
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), vala_source_file_get_pkg (current_source_file));
- vala_namespace_add_namespace (VALA_NAMESPACE (symbol_stack->data), VALA_NAMESPACE (parent_symbol));
- }
- parent_scope = vala_symbol_get_scope (parent_symbol);
- g_free ($5);
- g_object_unref (ns_src);
-
- name = $6;
- }
-
- src = src_com(@5, $1);
- edomain = vala_code_context_create_error_domain (context, name, src);
- g_free (name);
- g_object_unref (src);
-
- vala_namespace_add_error_domain (VALA_NAMESPACE (parent_symbol), edomain);
- vala_source_file_add_node (current_source_file, VALA_CODE_NODE (edomain));
- g_object_unref (parent_symbol);
-
- VALA_CODE_NODE (edomain)->attributes = $2;
-
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL (edomain), $3);
- }
-
- push_symbol (VALA_SYMBOL (edomain));
- }
- errordomain_body
- {
- g_object_unref (pop_symbol ());
- }
- ;
-
-errordomain_body
- : OPEN_BRACE opt_errordomain_member_declarations opt_errordomain_method_declarations CLOSE_BRACE
- ;
-
-opt_errordomain_member_declarations
- : /* empty */
- | errordomain_member_declarations opt_comma
- ;
-
-errordomain_member_declarations
- : errordomain_member_declaration
- | errordomain_member_declarations COMMA errordomain_member_declaration
- ;
-
-errordomain_member_declaration
- : opt_attributes identifier
- {
- ValaErrorCode *ec = vala_code_context_create_error_code (context, $2);
- g_free ($2);
- vala_error_domain_add_code (VALA_ERROR_DOMAIN (symbol_stack->data), ec);
- g_object_unref (ec);
- }
- | opt_attributes identifier ASSIGN expression
- {
- ValaErrorCode *ec = vala_code_context_create_error_code_with_value (context, $2, $4);
- g_free ($2);
- g_object_unref ($4);
- vala_error_domain_add_code (VALA_ERROR_DOMAIN (symbol_stack->data), ec);
- g_object_unref (ec);
- }
- ;
-
-opt_errordomain_method_declarations
- : /* empty */
- | errordomain_method_declarations
- ;
-
-errordomain_method_declarations
- : SEMICOLON errordomain_method_declaration
- | errordomain_method_declarations errordomain_method_declaration
- ;
-
-errordomain_method_declaration
- : method_declaration
- {
- /* skip declarations with errors */
- if ($1 != NULL) {
- vala_error_domain_add_method (VALA_ERROR_DOMAIN (symbol_stack->data), $1);
- g_object_unref ($1);
- }
- }
- ;
-
-delegate_declaration
- : comment opt_attributes opt_access_modifier opt_modifiers DELEGATE type identifier opt_name_specifier opt_type_parameter_list OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_throws_declaration SEMICOLON
- {
- ValaSourceReference *src;
- GList *l;
- char *name = $7;
-
- ValaSymbol *parent_symbol = VALA_SYMBOL (g_object_ref (symbol_stack->data));
- ValaScope *parent_scope = VALA_SCOPE (scope_stack->data);
- ValaDelegate *cb;
-
- if ($8 != NULL) {
- ValaSourceReference *ns_src = src(@7);
- g_object_unref (parent_symbol);
- parent_symbol = vala_scope_lookup (parent_scope, $7);
- if (parent_symbol != NULL) {
- if (check_is_namespace (parent_symbol, ns_src)) {
- if (!vala_source_file_get_pkg (current_source_file)) {
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), FALSE);
- }
- }
- } else {
- parent_symbol = VALA_SYMBOL (vala_code_context_create_namespace (context, $7, ns_src));
- vala_namespace_set_pkg (VALA_NAMESPACE (parent_symbol), vala_source_file_get_pkg (current_source_file));
- vala_namespace_add_namespace (VALA_NAMESPACE (symbol_stack->data), VALA_NAMESPACE (parent_symbol));
- }
- parent_scope = vala_symbol_get_scope (parent_symbol);
- g_free ($7);
- g_object_unref (ns_src);
-
- name = $8;
- }
-
- src = src_com(@7, $1);
- cb = vala_code_context_create_delegate (context, name, $6, src);
- g_free (name);
- g_object_unref ($6);
- g_object_unref (src);
-
- if (VALA_IS_CLASS (parent_symbol)) {
- vala_class_add_delegate (VALA_CLASS (parent_symbol), cb);
- } else if (VALA_IS_INTERFACE (parent_symbol)) {
- vala_interface_add_delegate (VALA_INTERFACE (parent_symbol), cb);
- } else if (VALA_IS_NAMESPACE (parent_symbol)) {
- vala_namespace_add_delegate (VALA_NAMESPACE (parent_symbol), cb);
- vala_source_file_add_node (current_source_file, VALA_CODE_NODE (cb));
- } else {
- g_assert_not_reached ();
- }
- g_object_unref (parent_symbol);
-
- if ($3 != -1) {
- vala_symbol_set_access (VALA_SYMBOL (cb), $3);
- }
- VALA_CODE_NODE (cb)->attributes = $2;
- if (($4 & VALA_MODIFIER_STATIC) == 0) {
- vala_delegate_set_instance (cb, TRUE);
- }
-
- if ($9 != NULL) {
- for (l = $9; l != NULL; l = l->next) {
- vala_delegate_add_type_parameter (cb, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($9);
- }
- if ($11 != NULL) {
- for (l = $11; l != NULL; l = l->next) {
- vala_delegate_add_parameter (cb, l->data);
- g_object_unref (l->data);
- }
- g_list_free ($11);
- }
-
- g_object_unref (cb);
- }
- ;
-
-opt_attributes
- : /* empty */
- {
- $$ = NULL;
- }
- | attributes
- ;
-
-attributes
- : attribute_sections
- ;
-
-attribute_sections
- : attribute_section
- | attribute_sections attribute_section
- {
- $$ = g_list_concat ($1, $2);
- }
- ;
-
-attribute_section
- : OPEN_BRACKET attribute_list CLOSE_BRACKET
- {
- $$ = $2;
- }
- | OPEN_BRACKET error CLOSE_BRACKET
- {
- $$ = NULL;
- }
- ;
-
-attribute_list
- : attribute
- {
- $$ = g_list_append (NULL, $1);
- }
- | attribute_list COMMA attribute
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-attribute
- : attribute_name
- {
- ValaSourceReference *src = src(@1);
- $$ = vala_attribute_new ($1, src);
- g_free ($1);
- g_object_unref (src);
- }
- | attribute_name OPEN_PARENS opt_named_argument_list CLOSE_PARENS
- {
- GList *l;
-
- ValaSourceReference *src = src(@1);
- $$ = vala_attribute_new ($1, src);
- g_object_unref (src);
-
- for (l = $3; l != NULL; l = l->next) {
- vala_attribute_add_argument ($$, l->data);
- g_object_unref (l->data);
- }
- if ($3 != NULL) {
- g_list_free ($3);
- }
-
- g_free ($1);
- }
- ;
-
-attribute_name
- : identifier
- ;
-
-opt_named_argument_list
- : /* empty */
- {
- $$ = NULL;
- }
- | named_argument_list
- ;
-
-named_argument_list
- : named_argument
- {
- $$ = g_list_append (NULL, $1);
- }
- | named_argument_list COMMA named_argument
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-named_argument
- : identifier ASSIGN expression
- {
- ValaSourceReference *src = src(@1);
- $$ = vala_named_argument_new ($1, $3, src);
- g_object_unref (src);
-
- g_free ($1);
- g_object_unref ($3);
- }
- ;
-
-opt_type_parameter_list
- : /* empty */
- {
- $$ = NULL;
- }
- | type_parameter_list
- ;
-
-type_parameter_list
- : GENERIC_LT type_parameters OP_GT
- {
- $$ = $2;
- }
- ;
-
-type_parameters
- : type_parameter
- {
- $$ = g_list_append (NULL, $1);
- }
- | type_parameters COMMA type_parameter
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-type_parameter
- : identifier
- {
- ValaSourceReference *src = src(@1);
- $$ = vala_code_context_create_type_parameter (context, $1, src);
- g_object_unref (src);
- g_free ($1);
- }
- ;
-
-opt_type_argument_list
- : /* empty */
- {
- $$ = NULL;
- }
- | type_argument_list
- ;
-
-type_argument_list
- : GENERIC_LT type_arguments OP_GT
- {
- $$ = $2;
- }
- ;
-
-type_arguments
- : type_argument
- {
- $$ = g_list_append (NULL, $1);
- }
- | type_arguments COMMA type_argument
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-type_argument
- : type
- {
- $$ = $1;
- if (VALA_IS_UNRESOLVED_TYPE ($$)) {
- if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($$))) {
- vala_data_type_set_takes_ownership ($$, TRUE);
- }
- }
- }
- ;
-
-open_parens
- : OPEN_PARENS
- | OPEN_CAST_PARENS
- ;
-
-member_name
- : identifier opt_type_argument_list
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_member_access (context, NULL, $1, src));
- g_free ($1);
- g_object_unref (src);
-
- if ($2 != NULL) {
- GList *l;
- for (l = $2; l != NULL; l = l->next) {
- vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($2);
- }
- }
- | member_name DOT identifier opt_type_argument_list
- {
- ValaSourceReference *src = src(@1);
- $$ = VALA_EXPRESSION (vala_code_context_create_member_access (context, $1, $3, src));
- g_object_unref ($1);
- g_free ($3);
- g_object_unref (src);
-
- if ($4 != NULL) {
- GList *l;
- for (l = $4; l != NULL; l = l->next) {
- vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
- g_object_unref (l->data);
- }
- g_list_free ($4);
- }
- }
- ;
-
-%%
-
-extern FILE *yyin;
-extern int yylineno;
-
-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, (char *) msg);
-}
-
-void
-vala_parser_parse_file (ValaParser *parser, ValaSourceFile *source_file)
-{
- current_source_file = source_file;
- context = vala_source_file_get_context (current_source_file);
- push_symbol (VALA_SYMBOL (vala_code_context_get_root (context)));
- yyin = fopen (vala_source_file_get_filename (current_source_file), "r");
- if (yyin == NULL) {
- printf ("Couldn't open source file: %s.\n", vala_source_file_get_filename (current_source_file));
- return;
- }
-
- /* restart line counter on each file */
- yylineno = 1;
-
- yyparse (parser);
- fclose (yyin);
- yyin = NULL;
-}
-
-static void push_symbol (ValaSymbol *symbol) {
- symbol_stack = g_list_prepend (symbol_stack, symbol);
- scope_stack = g_list_prepend (scope_stack, vala_symbol_get_scope (symbol));
-}
-
-static ValaSymbol *pop_symbol (void) {
- ValaSymbol *sym = VALA_SYMBOL (symbol_stack->data);
- symbol_stack = g_list_delete_link (symbol_stack, symbol_stack);
- scope_stack = g_list_delete_link (scope_stack, scope_stack);
- return sym;
-}
-
-static gboolean check_is_namespace (ValaSymbol *symbol, ValaSourceReference *src) {
- if (!VALA_IS_NAMESPACE (symbol)) {
- char *sym_name = vala_symbol_get_full_name (symbol);
- char *error_msg = g_strdup_printf ("`%s` already exists but is not a namespace", sym_name);
- g_free (sym_name);
- vala_report_error (src, error_msg);
- g_free (error_msg);
- return FALSE;
- }
- return TRUE;
-}
-
-static gboolean check_is_class (ValaSymbol *symbol, ValaSourceReference *src) {
- if (!VALA_IS_CLASS (symbol)) {
- char *sym_name = vala_symbol_get_full_name (symbol);
- char *error_msg = g_strdup_printf ("`%s` already exists but is not a class", sym_name);
- g_free (sym_name);
- vala_report_error (src, error_msg);
- g_free (error_msg);
- return FALSE;
- }
- return TRUE;
-}
-
-static gboolean check_is_struct (ValaSymbol *symbol, ValaSourceReference *src) {
- if (!VALA_IS_STRUCT (symbol)) {
- char *sym_name = vala_symbol_get_full_name (symbol);
- char *error_msg = g_strdup_printf ("`%s` already exists but is not a struct", sym_name);
- g_free (sym_name);
- vala_report_error (src, error_msg);
- g_free (error_msg);
- return FALSE;
- }
- return TRUE;
-}
+++ /dev/null
-/* scanner.l
- *
- * Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
- *
- * 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.1 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>
- * Raffaele Sandrini <rasa@gmx.ch>
- */
-
-%{
-#include "vala.h"
-#include "parser.h"
-
-#define YY_DECL int yylex (YYSTYPE *yylval_param, YYLTYPE *yylloc_param, ValaParser *parser)
-
-#define uploc { yylloc->first_column = yylloc->last_column + 1; yylloc->last_column += yyleng; }
-
-static gboolean file_comment = FALSE;
-%}
-
-%option yylineno
-%option bison-bridge
-%option bison-locations
-%option noyywrap
-%option nounput
-
-%x IN_COMMENT
-
-space [ \t\n]*
-ident [[:alnum:]_]+
-decimal_integer_literal (0|[1-9][[:digit:]]*)
-real_literal [[:digit:]]+"."[[:digit:]]*{exponent_part}?{real_suffix}?
-hex_digit [[:digit:]A-Fa-f]
-octal_digit [0-7]
-octal_integer_literal 0{octal_digit}+
-hexadecimal_integer_literal 0x{hex_digit}+
-exponent_part (e|E){sign}?[[:digit:]]+
-sign "+"|"-"
-integer_suffix L|LL|U|UL|ULL
-real_suffix F
-single_character [^\'\\]
-single_string_literal_character [^\"\\]
-simple_escape_sequence \\[\'\"\?\\abfnrtv0]
-hexadecimal_escape_sequence \\x{hex_digit}{hex_digit}?{hex_digit}?{hex_digit}?
-character ({single_character}|{simple_escape_sequence})
-string_literal_character ({single_string_literal_character}|{simple_escape_sequence})
-character_literal \'{character}+\'
-string_literal \"{string_literal_character}*\"
-integer_literal ({decimal_integer_literal}|{hexadecimal_integer_literal}|{octal_integer_literal}){integer_suffix}?
-literal ({integer_literal}|{real_literal}|{character_literal}|{string_literal})
-
-type_name ("weak"{space})?({ident}".")?{ident}
-generic_type {type_name}("<"{space}{type_name}("?"|"*"+)?(","{space}{type_name}("?"|"*"+)?)*">")?("?"|"*"+)?
-
-%%
-
-"/*" { uploc; file_comment = (yylineno == 1); BEGIN (IN_COMMENT); }
-<IN_COMMENT>"*/" { uploc; BEGIN (INITIAL); yytext[yyleng - 2] = '\0'; vala_parser_push_comment (parser, yytext, file_comment); }
-<IN_COMMENT>[^*\n]+ { uploc; yymore (); }
-<IN_COMMENT>"*" { uploc; yymore (); }
-<IN_COMMENT>\n { yylloc->first_line = yylloc->last_line = yylineno; yylloc->first_column = 1; yylloc->last_column = 0; yymore (); }
-
-"//".* { uploc; vala_parser_push_comment (parser, g_strdup (yytext + 2), FALSE); }
-
-"{" { uploc; return OPEN_BRACE; }
-"}" { uploc; return CLOSE_BRACE; }
-"("({space}"weak")?{space}{ident}("."{ident})?("<"({ident}".")?{ident}(","({ident}".")?{ident})*">")?("["{space}"]")*{space}")"{space}("("|{ident}|{literal}) { yyless (1); uploc; return OPEN_CAST_PARENS; }
-"(" { uploc; return OPEN_PARENS; }
-")" { uploc; return CLOSE_PARENS; }
-"["{space}(","{space})*"]" { yyless (1); uploc; return OPEN_ARRAY_TYPE_BRACKET; }
-"[" { uploc; return OPEN_BRACKET; }
-"]" { uploc; return CLOSE_BRACKET; }
-"..." { uploc; return ELLIPSIS; }
-"." { uploc; return DOT; }
-":" { uploc; return COLON; }
-"," { uploc; return COMMA; }
-";" { uploc; return SEMICOLON; }
-"#" { uploc; return HASH; }
-"?"{space}({ident}{space}("="|";")|"[") { yyless (1); uploc; return NULLABLE_INTERR; }
-"?" { uploc; return INTERR; }
-
-"|=" { uploc; return ASSIGN_BITWISE_OR; }
-"&=" { uploc; return ASSIGN_BITWISE_AND; }
-"^=" { uploc; return ASSIGN_BITWISE_XOR; }
-"+=" { uploc; return ASSIGN_ADD; }
-"-=" { uploc; return ASSIGN_SUB; }
-"*=" { uploc; return ASSIGN_MUL; }
-"/=" { uploc; return ASSIGN_DIV; }
-"%=" { uploc; return ASSIGN_PERCENT; }
-"<<=" { uploc; return ASSIGN_SHIFT_LEFT; }
-">>=" { uploc; return ASSIGN_SHIFT_RIGHT; }
-
-"++" { uploc; return OP_INC; }
-"--" { uploc; return OP_DEC; }
-"==" { uploc; return OP_EQ; }
-"!=" { uploc; return OP_NE; }
-"<<" { uploc; return OP_SHIFT_LEFT; }
-">>" { uploc; return OP_SHIFT_RIGHT; }
-"<=" { uploc; return OP_LE; }
-">=" { uploc; return OP_GE; }
-"=>" { uploc; return LAMBDA; }
-"<"{space}{generic_type}{space}(","{space}{generic_type}{space})*">" { yyless (1); uploc; return GENERIC_LT; }
-"<" { uploc; return OP_LT; }
-">" { uploc; return OP_GT; }
-"!" { uploc; return OP_NEG; }
-"||" { uploc; return OP_OR; }
-"|" { uploc; return BITWISE_OR; }
-"&&" { uploc; return OP_AND; }
-"&" { uploc; return BITWISE_AND; }
-"^" { uploc; return CARRET; }
-"~" { uploc; return TILDE; }
-
-"->" { uploc; return OP_PTR; }
-
-"=" { uploc; return ASSIGN; }
-"+" { uploc; return PLUS; }
-"-" { uploc; return MINUS; }
-"*" { uploc; return STAR; }
-"/" { uploc; return DIV; }
-"%" { uploc; return PERCENT; }
-
-"@"[[:alnum:]_]+ { uploc; yylval->str = g_strdup (yytext + 1); return IDENTIFIER; }
-
-"abstract" { uploc; return ABSTRACT; }
-"as" { uploc; return AS; }
-"base" { uploc; return BASE; }
-"break" { uploc; return BREAK; }
-"case" { uploc; return CASE; }
-"catch" { uploc; return CATCH; }
-"class" { uploc; return CLASS; }
-"const" { uploc; return CONST; }
-"construct" { uploc; return CONSTRUCT; }
-"continue" { uploc; return CONTINUE; }
-"default" { uploc; return DEFAULT; }
-"delegate" { uploc; return DELEGATE; }
-"delete" { uploc; return DELETE; }
-"do" { uploc; return DO; }
-"else" { uploc; return ELSE; }
-"ensures" { uploc; return ENSURES; }
-"enum" { uploc; return ENUM; }
-"errordomain" { uploc; return ERRORDOMAIN; }
-"false" { uploc; return VALA_FALSE; }
-"finally" { uploc; return FINALLY; }
-"for" { uploc; return FOR; }
-"foreach" { uploc; return FOREACH; }
-"get" { uploc; return GET; }
-"if" { uploc; return IF; }
-"in" { uploc; return IN; }
-"inline" { uploc; return INLINE; }
-"interface" { uploc; return INTERFACE; }
-"is" { uploc; return IS; }
-"lock" { uploc; return LOCK; }
-"namespace" { uploc; return NAMESPACE; }
-"new" { uploc; return NEW; }
-"null" { uploc; return VALA_NULL; }
-"out" { uploc; return OUT; }
-"override" { uploc; return OVERRIDE; }
-"private" { uploc; return PRIVATE; }
-"protected" { uploc; return PROTECTED; }
-"public" { uploc; return PUBLIC; }
-"ref" { uploc; return REF; }
-"requires" { uploc; return REQUIRES; }
-"set" { uploc; return SET; }
-"signal" { uploc; return SIGNAL; }
-"sizeof" { uploc; return SIZEOF; }
-"static" { uploc; return STATIC; }
-"struct" { uploc; return STRUCT; }
-"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; }
-"virtual" { uploc; return VIRTUAL; }
-"void" { uploc; return VOID; }
-"volatile" { uploc; return VOLATILE; }
-"weak" { uploc; return WEAK; }
-"while" { uploc; return WHILE; }
-
-{real_literal} { uploc; yylval->str = g_strdup (yytext); return REAL_LITERAL; }
-{integer_literal} { uploc; yylval->str = g_strdup (yytext); return INTEGER_LITERAL; }
-
-{character_literal} { uploc; yylval->str = g_strdup (yytext); return CHARACTER_LITERAL; }
-{string_literal} { uploc; yylval->str = g_strdup (yytext); return STRING_LITERAL; }
-
-{ident} { uploc; yylval->str = g_strdup (yytext); return IDENTIFIER; }
-
-[ \t\r]+ { uploc; /* eat up whitespace */ }
-[\n]+ { yylloc->first_line = yylloc->last_line = yylineno; yylloc->first_column = 1; yylloc->last_column = 0; }
-
-. { uploc; fprintf (stderr, "%d: syntax error: unexpected character ´%s´\n", yylloc->first_line, yytext); }
}
public enum Vala.AssignmentOperator {
+ NONE,
SIMPLE,
BITWISE_OR,
BITWISE_AND,
}
public enum Vala.BinaryOperator {
+ NONE,
PLUS,
MINUS,
MUL,
*/
public void add_method (Method! m) {
if (m.instance || m is CreationMethod) {
+ if (m.this_parameter != null) {
+ m.scope.remove (m.this_parameter.name);
+ }
m.this_parameter = new FormalParameter ("this", new ClassType (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
+ if (m.result_var != null) {
+ m.scope.remove (m.result_var.name);
+ }
m.result_var = new VariableDeclarator ("result");
m.result_var.type_reference = m.return_type.copy ();
m.scope.add (m.result_var.name, m.result_var);
}
/**
+ * Returns a copy of the list of enums.
+ *
+ * @return enum list
+ */
+ public Collection<Enum> get_enums () {
+ return new ReadOnlyCollection<Enum> (enums);
+ }
+
+ /**
+ * Returns a copy of the list of error domains.
+ *
+ * @return error domain list
+ */
+ public Collection<ErrorDomain> get_error_domains () {
+ return new ReadOnlyCollection<ErrorDomain> (error_domains);
+ }
+
+ /**
+ * Returns a copy of the list of fields.
+ *
+ * @return field list
+ */
+ public Collection<Field> get_fields () {
+ return new ReadOnlyCollection<Field> (fields);
+ }
+
+ /**
+ * Returns a copy of the list of constants.
+ *
+ * @return constant list
+ */
+ public Collection<Constant> get_constants () {
+ return new ReadOnlyCollection<Constant> (constants);
+ }
+
+ /**
+ * Returns a copy of the list of delegates.
+ *
+ * @return delegate list
+ */
+ public Collection<Delegate> get_delegates () {
+ return new ReadOnlyCollection<Delegate> (delegates);
+ }
+
+ /**
+ * Returns a copy of the list of methods.
+ *
+ * @return method list
+ */
+ public Collection<Method> get_methods () {
+ return new ReadOnlyCollection<Method> (methods);
+ }
+
+ /**
* Adds the specified constant to this namespace.
*
* @param constant a constant
/* valaparser.vala
*
- * Copyright (C) 2006-2007 Jürg Billeter
+ * Copyright (C) 2006-2008 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
*/
using GLib;
+using Gee;
/**
* Code visitor parsing all Vala source files.
*/
public class Vala.Parser : CodeVisitor {
- private string comment;
- private string _file_comment;
-
+ Scanner scanner;
+
+ CodeContext context;
+
+ // token buffer
+ TokenInfo[] tokens;
+ // index of current token in buffer
+ int index;
+ // number of tokens in buffer
+ int size;
+
+ string comment;
+
+ const int BUFFER_SIZE = 32;
+
+ struct TokenInfo {
+ public TokenType type;
+ public SourceLocation begin;
+ public SourceLocation end;
+ }
+
+ enum ModifierFlags {
+ NONE,
+ ABSTRACT = 1 << 0,
+ CLASS = 1 << 1,
+ INLINE = 1 << 2,
+ OVERRIDE = 1 << 3,
+ STATIC = 1 << 4,
+ VIRTUAL = 1 << 5
+ }
+
+ construct {
+ tokens = new TokenInfo[BUFFER_SIZE];
+ }
+
/**
* Parse all source files in the specified code context and build a
* code tree.
* @param context a code context
*/
public void parse (CodeContext! context) {
+ this.context = context;
context.accept (this);
}
public override void visit_source_file (SourceFile! source_file) {
if (source_file.filename.has_suffix (".vala") || source_file.filename.has_suffix (".vapi")) {
parse_file (source_file);
- source_file.comment = _file_comment;
}
+ }
- _file_comment = null;
+ inline bool next () {
+ index = (index + 1) % BUFFER_SIZE;
+ size--;
+ if (size <= 0) {
+ SourceLocation begin, end;
+ TokenType type = scanner.read_token (out begin, out end);
+ tokens[index].type = type;
+ tokens[index].begin = begin;
+ tokens[index].end = end;
+ size = 1;
+ }
+ return (tokens[index].type != TokenType.EOF);
}
- /**
- * Adds the specified comment to the comment stack.
- *
- * @param comment_item a comment string
- * @param file_comment true if file header comment, false otherwise
- */
- public void push_comment (string! comment_item, bool file_comment) {
- if (comment == null) {
- comment = comment_item;
+ inline void prev () {
+ index = (index - 1 + BUFFER_SIZE) % BUFFER_SIZE;
+ size++;
+ assert (size <= BUFFER_SIZE);
+ }
+
+ inline TokenType current () {
+ return tokens[index].type;
+ }
+
+ inline bool accept (TokenType type) {
+ if (current () == type) {
+ next ();
+ return true;
+ }
+ return false;
+ }
+
+ string get_error (string msg) {
+ var begin = get_location ();
+ next ();
+ Report.error (get_src (begin), "syntax error, " + msg);
+ return msg;
+ }
+
+ inline bool expect (TokenType type) throws ParseError {
+ if (accept (type)) {
+ return true;
+ }
+
+ throw new ParseError.SYNTAX (get_error ("expected %s".printf (type.to_string ())));
+ }
+
+ inline SourceLocation get_location () {
+ return tokens[index].begin;
+ }
+
+ string get_last_string () {
+ int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
+ return ((string) tokens[last_index].begin.pos).ndup ((tokens[last_index].end.pos - tokens[last_index].begin.pos));
+ }
+
+ SourceReference get_src (SourceLocation begin) {
+ int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
+
+ return new SourceReference (scanner.source_file, begin.line, begin.column, tokens[last_index].end.line, tokens[last_index].end.column);
+ }
+
+ SourceReference get_src_com (SourceLocation begin) {
+ int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
+
+ var src = new SourceReference.with_comment (scanner.source_file, begin.line, begin.column, tokens[last_index].end.line, tokens[last_index].end.column, comment);
+ comment = null;
+ return src;
+ }
+
+ void rollback (SourceLocation location) {
+ while (tokens[index].begin.pos != location.pos) {
+ prev ();
+ }
+ }
+
+ void skip_identifier () throws ParseError {
+ // also accept keywords as identifiers where there is no conflict
+ switch (current ()) {
+ case TokenType.ABSTRACT:
+ case TokenType.AS:
+ case TokenType.BASE:
+ case TokenType.BREAK:
+ case TokenType.CASE:
+ case TokenType.CATCH:
+ case TokenType.CLASS:
+ case TokenType.CONST:
+ case TokenType.CONSTRUCT:
+ case TokenType.CONTINUE:
+ case TokenType.DEFAULT:
+ case TokenType.DELEGATE:
+ case TokenType.DELETE:
+ case TokenType.DO:
+ case TokenType.ELSE:
+ case TokenType.ENUM:
+ case TokenType.ENSURES:
+ case TokenType.ERRORDOMAIN:
+ case TokenType.FALSE:
+ case TokenType.FINALLY:
+ case TokenType.FOR:
+ case TokenType.FOREACH:
+ case TokenType.GET:
+ case TokenType.IDENTIFIER:
+ case TokenType.IF:
+ case TokenType.IN:
+ case TokenType.INLINE:
+ case TokenType.INTERFACE:
+ case TokenType.IS:
+ case TokenType.LOCK:
+ case TokenType.NAMESPACE:
+ case TokenType.NEW:
+ case TokenType.NULL:
+ case TokenType.OUT:
+ case TokenType.OVERRIDE:
+ case TokenType.PRIVATE:
+ case TokenType.PROTECTED:
+ case TokenType.PUBLIC:
+ case TokenType.REF:
+ case TokenType.REQUIRES:
+ case TokenType.RETURN:
+ case TokenType.SET:
+ case TokenType.SIGNAL:
+ case TokenType.SIZEOF:
+ case TokenType.STATIC:
+ case TokenType.STRUCT:
+ case TokenType.SWITCH:
+ case TokenType.THIS:
+ case TokenType.THROW:
+ case TokenType.THROWS:
+ case TokenType.TRUE:
+ case TokenType.TRY:
+ case TokenType.TYPEOF:
+ case TokenType.USING:
+ case TokenType.VAR:
+ case TokenType.VIRTUAL:
+ case TokenType.VOID:
+ case TokenType.VOLATILE:
+ case TokenType.WEAK:
+ case TokenType.WHILE:
+ next ();
+ return;
+ }
+
+ throw new ParseError.SYNTAX (get_error ("expected identifier"));
+ }
+
+ string parse_identifier () throws ParseError {
+ skip_identifier ();
+ return get_last_string ();
+ }
+
+ Expression parse_literal () throws ParseError {
+ var begin = get_location ();
+
+ switch (current ()) {
+ case TokenType.TRUE:
+ next ();
+ return context.create_boolean_literal (true, get_src (begin));
+ case TokenType.FALSE:
+ next ();
+ return context.create_boolean_literal (false, get_src (begin));
+ case TokenType.INTEGER_LITERAL:
+ next ();
+ return context.create_integer_literal (get_last_string (), get_src (begin));
+ case TokenType.REAL_LITERAL:
+ next ();
+ return context.create_real_literal (get_last_string (), get_src (begin));
+ case TokenType.CHARACTER_LITERAL:
+ next ();
+ return context.create_character_literal (get_last_string (), get_src (begin));
+ case TokenType.STRING_LITERAL:
+ next ();
+ return context.create_string_literal (get_last_string (), get_src (begin));
+ case TokenType.NULL:
+ next ();
+ return context.create_null_literal (get_src (begin));
+ }
+
+ throw new ParseError.SYNTAX (get_error ("expected literal"));
+ }
+
+ public void parse_file (SourceFile source_file) {
+ scanner = new Scanner (source_file);
+
+ index = -1;
+ size = 0;
+
+ next ();
+
+ try {
+ parse_using_directives ();
+ parse_declarations (context.root, true);
+ } catch (ParseError e) {
+ // already reported
+ }
+
+ scanner = null;
+ }
+
+ void skip_symbol_name () throws ParseError {
+ do {
+ skip_identifier ();
+ } while (accept (TokenType.DOT));
+ }
+
+ UnresolvedSymbol parse_symbol_name () throws ParseError {
+ var begin = get_location ();
+ UnresolvedSymbol sym = null;
+ do {
+ string name = parse_identifier ();
+ sym = new UnresolvedSymbol (sym, name, get_src (begin));
+ } while (accept (TokenType.DOT));
+ return sym;
+ }
+
+ void skip_type () throws ParseError {
+ if (accept (TokenType.VOID)) {
+ while (accept (TokenType.STAR)) {
+ }
+ return;
+ }
+ accept (TokenType.REF);
+ accept (TokenType.OUT);
+ accept (TokenType.WEAK);
+ skip_symbol_name ();
+ skip_type_argument_list ();
+ while (accept (TokenType.STAR)) {
+ }
+ if (accept (TokenType.OPEN_BRACKET)) {
+ do {
+ if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET) {
+ parse_expression ();
+ }
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.CLOSE_BRACKET);
+ }
+ accept (TokenType.OP_NEG);
+ accept (TokenType.INTERR);
+ accept (TokenType.HASH);
+ }
+
+ DataType parse_type () throws ParseError {
+ var begin = get_location ();
+
+ if (accept (TokenType.VOID)) {
+ DataType type = new VoidType ();
+ while (accept (TokenType.STAR)) {
+ type = new PointerType (type);
+ }
+ return type;
+ }
+
+ bool is_ref = accept (TokenType.REF);
+ bool is_out = !is_ref && accept (TokenType.OUT);
+
+ bool is_weak = accept (TokenType.WEAK);
+
+ var sym = parse_symbol_name ();
+ var type_arg_list = parse_type_argument_list (false);
+
+ int stars = 0;
+ while (accept (TokenType.STAR)) {
+ stars++;
+ }
+
+ int array_rank = 0;
+ if (accept (TokenType.OPEN_BRACKET)) {
+ do {
+ array_rank++;
+ // support for stack-allocated arrays
+ // also required for decision between expression and declaration statement
+ if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET) {
+ parse_expression ();
+ }
+ }
+ while (accept (TokenType.COMMA));
+ expect (TokenType.CLOSE_BRACKET);
+ }
+
+ // deprecated
+ accept (TokenType.OP_NEG);
+
+ bool nullable = accept (TokenType.INTERR);
+
+ bool transfers_ownership = accept (TokenType.HASH);
+
+ var type = new UnresolvedType.from_symbol (sym, get_src (begin));
+ if (type_arg_list != null) {
+ foreach (DataType type_arg in type_arg_list) {
+ type.add_type_argument (type_arg);
+ }
+ }
+ type.is_ref = is_ref;
+ type.is_out = is_out;
+ type.is_weak = is_weak;
+ type.pointer_level = stars;
+ type.array_rank = array_rank;
+ type.nullable = nullable;
+ type.requires_null_check = nullable;
+ type.transfers_ownership = transfers_ownership;
+ return type;
+ }
+
+ Gee.List<Expression> parse_argument_list () throws ParseError {
+ var list = new ArrayList<Expression> ();
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ list.add (parse_expression ());
+ } while (accept (TokenType.COMMA));
+ }
+ return list;
+ }
+
+ Expression parse_primary_expression () throws ParseError {
+ var begin = get_location ();
+
+ Expression expr;
+
+ switch (current ()) {
+ case TokenType.TRUE:
+ case TokenType.FALSE:
+ case TokenType.INTEGER_LITERAL:
+ case TokenType.REAL_LITERAL:
+ case TokenType.CHARACTER_LITERAL:
+ case TokenType.STRING_LITERAL:
+ case TokenType.NULL:
+ expr = parse_literal ();
+ break;
+ case TokenType.OPEN_PARENS:
+ expr = parse_tuple ();
+ break;
+ case TokenType.THIS:
+ expr = parse_this_access ();
+ break;
+ case TokenType.BASE:
+ expr = parse_base_access ();
+ break;
+ case TokenType.NEW:
+ expr = parse_object_or_array_creation_expression ();
+ break;
+ case TokenType.SIZEOF:
+ expr = parse_sizeof_expression ();
+ break;
+ case TokenType.TYPEOF:
+ expr = parse_typeof_expression ();
+ break;
+ default:
+ expr = parse_simple_name ();
+ break;
+ }
+
+ // process primary expressions that start with an inner primary expression
+ bool found = true;
+ while (found) {
+ switch (current ()) {
+ case TokenType.DOT:
+ expr = parse_member_access (begin, expr);
+ break;
+ case TokenType.OP_PTR:
+ expr = parse_pointer_member_access (begin, expr);
+ break;
+ case TokenType.OPEN_PARENS:
+ expr = parse_invocation_expression (begin, expr);
+ break;
+ case TokenType.OPEN_BRACKET:
+ expr = parse_element_access (begin, expr);
+ break;
+ case TokenType.OP_INC:
+ expr = parse_post_increment_expression (begin, expr);
+ break;
+ case TokenType.OP_DEC:
+ expr = parse_post_decrement_expression (begin, expr);
+ break;
+ default:
+ found = false;
+ break;
+ }
+ }
+
+ return expr;
+ }
+
+ Expression parse_simple_name () throws ParseError {
+ var begin = get_location ();
+ string id = parse_identifier ();
+ var type_arg_list = parse_type_argument_list (true);
+ var expr = context.create_member_access (null, id, get_src (begin));
+ if (type_arg_list != null) {
+ foreach (DataType type_arg in type_arg_list) {
+ expr.add_type_argument (type_arg);
+ }
+ }
+ return expr;
+ }
+
+ Expression parse_tuple () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.OPEN_PARENS);
+ var expr_list = new ArrayList<Expression> ();
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ expr_list.add (parse_expression ());
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.CLOSE_PARENS);
+ if (expr_list.size != 1) {
+ var tuple = new Tuple ();
+ foreach (Expression expr in expr_list) {
+ tuple.add_expression (expr);
+ }
+ return tuple;
+ }
+ return context.create_parenthesized_expression (expr_list.get (0), get_src (begin));
+ }
+
+ Expression parse_member_access (SourceLocation begin, Expression inner) throws ParseError {
+ expect (TokenType.DOT);
+ string id = parse_identifier ();
+ var type_arg_list = parse_type_argument_list (true);
+ var expr = context.create_member_access (inner, id, get_src (begin));
+ if (type_arg_list != null) {
+ foreach (DataType type_arg in type_arg_list) {
+ expr.add_type_argument (type_arg);
+ }
+ }
+ return expr;
+ }
+
+ Expression parse_pointer_member_access (SourceLocation begin, Expression inner) throws ParseError {
+ expect (TokenType.OP_PTR);
+ string id = parse_identifier ();
+ var type_arg_list = parse_type_argument_list (true);
+ var expr = context.create_member_access_pointer (inner, id, get_src (begin));
+ if (type_arg_list != null) {
+ foreach (DataType type_arg in type_arg_list) {
+ expr.add_type_argument (type_arg);
+ }
+ }
+ return expr;
+ }
+
+ Expression parse_invocation_expression (SourceLocation begin, Expression inner) throws ParseError {
+ expect (TokenType.OPEN_PARENS);
+ var arg_list = parse_argument_list ();
+ expect (TokenType.CLOSE_PARENS);
+
+ var expr = context.create_invocation_expression (inner, get_src (begin));
+ foreach (Expression arg in arg_list) {
+ expr.add_argument (arg);
+ }
+ return expr;
+ }
+
+ Expression parse_element_access (SourceLocation begin, Expression inner) throws ParseError {
+ expect (TokenType.OPEN_BRACKET);
+ var index_list = parse_expression_list ();
+ expect (TokenType.CLOSE_BRACKET);
+
+ var expr = context.create_element_access (inner, get_src (begin));
+ foreach (Expression index in index_list) {
+ expr.append_index (index);
+ }
+ return expr;
+ }
+
+ Gee.List<Expression> parse_expression_list () throws ParseError {
+ var list = new ArrayList<Expression> ();
+ do {
+ list.add (parse_expression ());
+ } while (accept (TokenType.COMMA));
+ return list;
+ }
+
+ Expression parse_this_access () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.THIS);
+ return context.create_member_access (null, "this", get_src (begin));
+ }
+
+ Expression parse_base_access () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.BASE);
+ return context.create_base_access (get_src (begin));
+ }
+
+ Expression parse_post_increment_expression (SourceLocation begin, Expression inner) throws ParseError {
+ expect (TokenType.OP_INC);
+ return context.create_postfix_expression (inner, true, get_src (begin));
+ }
+
+ Expression parse_post_decrement_expression (SourceLocation begin, Expression inner) throws ParseError {
+ expect (TokenType.OP_DEC);
+ return context.create_postfix_expression (inner, false, get_src (begin));
+ }
+
+ Expression parse_object_or_array_creation_expression () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.NEW);
+ var member = parse_member_name ();
+ if (accept (TokenType.OPEN_PARENS)) {
+ return parse_object_creation_expression (begin, member);
+ } else if (accept (TokenType.OPEN_BRACKET)) {
+ return parse_array_creation_expression (begin, member);
} else {
- comment = "%s\n%s".printf (comment, comment_item);
+ throw new ParseError.SYNTAX (get_error ("expected ( or ["));
}
- if (file_comment) {
- _file_comment = comment;
- comment = null;
+ }
+
+ Expression parse_object_creation_expression (SourceLocation begin, MemberAccess member) throws ParseError {
+ member.creation_member = true;
+ var arg_list = parse_argument_list ();
+ expect (TokenType.CLOSE_PARENS);
+ var init_list = parse_object_initializer ();
+
+ var expr = context.create_object_creation_expression (member, get_src (begin));
+ foreach (Expression arg in arg_list) {
+ expr.add_argument (arg);
}
+ foreach (MemberInitializer initializer in init_list) {
+ expr.add_member_initializer (initializer);
+ }
+ return expr;
}
-
- /**
- * Clears and returns the content of the comment stack.
- *
- * @return saved comment
- */
- public string pop_comment () {
- if (comment == null) {
+
+ Expression parse_array_creation_expression (SourceLocation begin, MemberAccess member) throws ParseError {
+ bool size_specified = false;
+ var size_specifier_list = new ArrayList<Expression> ();
+ do {
+ Expression size = null;
+ if (current () != TokenType.CLOSE_BRACKET && current () != TokenType.COMMA) {
+ size = parse_expression ();
+ size_specified = true;
+ }
+ size_specifier_list.add (size);
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.CLOSE_BRACKET);
+ InitializerList initializer = null;
+ if (current () == TokenType.OPEN_BRACE) {
+ initializer = parse_initializer ();
+ }
+ var expr = context.create_array_creation_expression (UnresolvedType.new_from_expression (member), size_specifier_list.size, initializer, get_src (begin));
+ if (size_specified) {
+ foreach (Expression size in size_specifier_list) {
+ expr.append_size (size);
+ }
+ }
+ return expr;
+ }
+
+ Gee.List<MemberInitializer> parse_object_initializer () throws ParseError {
+ var list = new ArrayList<MemberInitializer> ();
+ if (accept (TokenType.OPEN_BRACE)) {
+ do {
+ list.add (parse_member_initializer ());
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.CLOSE_BRACE);
+ }
+ return list;
+ }
+
+ MemberInitializer parse_member_initializer () throws ParseError {
+ var begin = get_location ();
+ string id = parse_identifier ();
+ expect (TokenType.ASSIGN);
+ var expr = parse_expression ();
+
+ return new MemberInitializer (id, expr, get_src (begin));
+ }
+
+ Expression parse_sizeof_expression () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.SIZEOF);
+ expect (TokenType.OPEN_PARENS);
+ var type = parse_type ();
+ expect (TokenType.CLOSE_PARENS);
+
+ return context.create_sizeof_expression (type, get_src (begin));
+ }
+
+ Expression parse_typeof_expression () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.TYPEOF);
+ expect (TokenType.OPEN_PARENS);
+ var type = parse_type ();
+ expect (TokenType.CLOSE_PARENS);
+
+ return context.create_typeof_expression (type, get_src (begin));
+ }
+
+ UnaryOperator get_unary_operator (TokenType token_type) {
+ switch (token_type) {
+ case TokenType.PLUS: return UnaryOperator.PLUS;
+ case TokenType.MINUS: return UnaryOperator.MINUS;
+ case TokenType.OP_NEG: return UnaryOperator.LOGICAL_NEGATION;
+ case TokenType.TILDE: return UnaryOperator.BITWISE_COMPLEMENT;
+ case TokenType.OP_INC: return UnaryOperator.INCREMENT;
+ case TokenType.OP_DEC: return UnaryOperator.DECREMENT;
+ case TokenType.REF: return UnaryOperator.REF;
+ case TokenType.OUT: return UnaryOperator.OUT;
+ default: return UnaryOperator.NONE;
+ }
+ }
+
+ Expression parse_unary_expression () throws ParseError {
+ var begin = get_location ();
+ var operator = get_unary_operator (current ());
+ if (operator != UnaryOperator.NONE) {
+ next ();
+ var op = parse_unary_expression ();
+ return context.create_unary_expression (operator, op, get_src (begin));
+ }
+ switch (current ()) {
+ case TokenType.HASH:
+ next ();
+ var op = parse_unary_expression ();
+ return context.create_reference_transfer_expression (op, get_src (begin));
+ case TokenType.OPEN_PARENS:
+ next ();
+ switch (current ()) {
+ case TokenType.VOID:
+ case TokenType.IDENTIFIER:
+ var type = parse_type ();
+ if (accept (TokenType.CLOSE_PARENS)) {
+ // check follower to decide whether to create cast expression
+ switch (current ()) {
+ case TokenType.OP_NEG:
+ case TokenType.TILDE:
+ case TokenType.OPEN_PARENS:
+ case TokenType.TRUE:
+ case TokenType.FALSE:
+ case TokenType.INTEGER_LITERAL:
+ case TokenType.REAL_LITERAL:
+ case TokenType.CHARACTER_LITERAL:
+ case TokenType.STRING_LITERAL:
+ case TokenType.NULL:
+ case TokenType.THIS:
+ case TokenType.BASE:
+ case TokenType.NEW:
+ case TokenType.SIZEOF:
+ case TokenType.TYPEOF:
+ case TokenType.IDENTIFIER:
+ var inner = parse_unary_expression ();
+ return context.create_cast_expression (inner, type, get_src (begin), false);
+ }
+ }
+ break;
+ }
+ // no cast expression
+ rollback (begin);
+ break;
+ case TokenType.STAR:
+ next ();
+ var op = parse_unary_expression ();
+ return context.create_pointer_indirection (op, get_src (begin));
+ case TokenType.BITWISE_AND:
+ next ();
+ var op = parse_unary_expression ();
+ return context.create_addressof_expression (op, get_src (begin));
+ }
+
+ return parse_primary_expression ();
+ }
+
+ BinaryOperator get_binary_operator (TokenType token_type) {
+ switch (token_type) {
+ case TokenType.STAR: return BinaryOperator.MUL;
+ case TokenType.DIV: return BinaryOperator.DIV;
+ case TokenType.PERCENT: return BinaryOperator.MOD;
+ case TokenType.PLUS: return BinaryOperator.PLUS;
+ case TokenType.MINUS: return BinaryOperator.MINUS;
+ case TokenType.OP_LT: return BinaryOperator.LESS_THAN;
+ case TokenType.OP_GT: return BinaryOperator.GREATER_THAN;
+ case TokenType.OP_LE: return BinaryOperator.LESS_THAN_OR_EQUAL;
+ case TokenType.OP_GE: return BinaryOperator.GREATER_THAN_OR_EQUAL;
+ case TokenType.OP_EQ: return BinaryOperator.EQUALITY;
+ case TokenType.OP_NE: return BinaryOperator.INEQUALITY;
+ default: return BinaryOperator.NONE;
+ }
+ }
+
+ Expression parse_multiplicative_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_unary_expression ();
+ bool found = true;
+ while (found) {
+ var operator = get_binary_operator (current ());
+ switch (operator) {
+ case BinaryOperator.MUL:
+ case BinaryOperator.DIV:
+ case BinaryOperator.MOD:
+ next ();
+ var right = parse_unary_expression ();
+ left = context.create_binary_expression (operator, left, right, get_src (begin));
+ break;
+ default:
+ found = false;
+ break;
+ }
+ }
+ return left;
+ }
+
+ Expression parse_additive_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_multiplicative_expression ();
+ bool found = true;
+ while (found) {
+ var operator = get_binary_operator (current ());
+ switch (operator) {
+ case BinaryOperator.PLUS:
+ case BinaryOperator.MINUS:
+ next ();
+ var right = parse_multiplicative_expression ();
+ left = context.create_binary_expression (operator, left, right, get_src (begin));
+ break;
+ default:
+ found = false;
+ break;
+ }
+ }
+ return left;
+ }
+
+ Expression parse_shift_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_additive_expression ();
+ bool found = true;
+ while (found) {
+ switch (current ()) {
+ case TokenType.OP_SHIFT_LEFT:
+ next ();
+ var right = parse_additive_expression ();
+ left = context.create_binary_expression (BinaryOperator.SHIFT_LEFT, left, right, get_src (begin));
+ break;
+ // don't use OP_SHIFT_RIGHT to support >> for nested generics
+ case TokenType.OP_GT:
+ char* first_gt_pos = tokens[index].begin.pos;
+ next ();
+ // only accept >> when there is no space between the two > signs
+ if (current () == TokenType.OP_GT && tokens[index].begin.pos == first_gt_pos + 1) {
+ next ();
+ var right = parse_additive_expression ();
+ left = context.create_binary_expression (BinaryOperator.SHIFT_RIGHT, left, right, get_src (begin));
+ } else {
+ prev ();
+ found = false;
+ }
+ break;
+ default:
+ found = false;
+ break;
+ }
+ }
+ return left;
+ }
+
+ Expression parse_relational_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_shift_expression ();
+ bool found = true;
+ while (found) {
+ var operator = get_binary_operator (current ());
+ switch (operator) {
+ case BinaryOperator.LESS_THAN:
+ case BinaryOperator.LESS_THAN_OR_EQUAL:
+ case BinaryOperator.GREATER_THAN_OR_EQUAL:
+ next ();
+ var right = parse_shift_expression ();
+ left = context.create_binary_expression (operator, left, right, get_src (begin));
+ break;
+ case BinaryOperator.GREATER_THAN:
+ next ();
+ // ignore >> and >>= (two tokens due to generics)
+ if (current () != TokenType.OP_GT && current () != TokenType.OP_GE) {
+ var right = parse_shift_expression ();
+ left = context.create_binary_expression (operator, left, right, get_src (begin));
+ } else {
+ prev ();
+ found = false;
+ }
+ break;
+ default:
+ switch (current ()) {
+ case TokenType.IS:
+ next ();
+ var type = parse_type ();
+ left = context.create_type_check (left, type, get_src (begin));
+ break;
+ case TokenType.AS:
+ next ();
+ var type = parse_type ();
+ left = context.create_cast_expression (left, type, get_src (begin), true);
+ break;
+ default:
+ found = false;
+ break;
+ }
+ break;
+ }
+ }
+ return left;
+ }
+
+ Expression parse_equality_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_relational_expression ();
+ bool found = true;
+ while (found) {
+ var operator = get_binary_operator (current ());
+ switch (operator) {
+ case BinaryOperator.EQUALITY:
+ case BinaryOperator.INEQUALITY:
+ next ();
+ var right = parse_relational_expression ();
+ left = context.create_binary_expression (operator, left, right, get_src (begin));
+ break;
+ default:
+ found = false;
+ break;
+ }
+ }
+ return left;
+ }
+
+ Expression parse_and_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_equality_expression ();
+ while (accept (TokenType.BITWISE_AND)) {
+ var right = parse_equality_expression ();
+ left = context.create_binary_expression (BinaryOperator.BITWISE_AND, left, right, get_src (begin));
+ }
+ return left;
+ }
+
+ Expression parse_exclusive_or_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_and_expression ();
+ while (accept (TokenType.CARRET)) {
+ var right = parse_and_expression ();
+ left = context.create_binary_expression (BinaryOperator.BITWISE_XOR, left, right, get_src (begin));
+ }
+ return left;
+ }
+
+ Expression parse_inclusive_or_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_exclusive_or_expression ();
+ while (accept (TokenType.BITWISE_OR)) {
+ var right = parse_exclusive_or_expression ();
+ left = context.create_binary_expression (BinaryOperator.BITWISE_OR, left, right, get_src (begin));
+ }
+ return left;
+ }
+
+ Expression parse_in_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_inclusive_or_expression ();
+ while (accept (TokenType.IN)) {
+ var right = parse_inclusive_or_expression ();
+ left = context.create_binary_expression (BinaryOperator.IN, left, right, get_src (begin));
+ }
+ return left;
+ }
+
+ Expression parse_conditional_and_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_in_expression ();
+ while (accept (TokenType.OP_AND)) {
+ var right = parse_in_expression ();
+ left = context.create_binary_expression (BinaryOperator.AND, left, right, get_src (begin));
+ }
+ return left;
+ }
+
+ Expression parse_conditional_or_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_conditional_and_expression ();
+ while (accept (TokenType.OP_OR)) {
+ var right = parse_conditional_and_expression ();
+ left = context.create_binary_expression (BinaryOperator.OR, left, right, get_src (begin));
+ }
+ return left;
+ }
+
+ Expression parse_conditional_expression () throws ParseError {
+ var begin = get_location ();
+ var condition = parse_conditional_or_expression ();
+ if (accept (TokenType.INTERR)) {
+ var true_expr = parse_expression ();
+ expect (TokenType.COLON);
+ var false_expr = parse_expression ();
+ return context.create_conditional_expression (condition, true_expr, false_expr, get_src (begin));
+ } else {
+ return condition;
+ }
+ }
+
+ Expression parse_lambda_expression () throws ParseError {
+ var begin = get_location ();
+ Gee.List<string> params = new ArrayList<string> ();
+ if (accept (TokenType.OPEN_PARENS)) {
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ params.add (parse_identifier ());
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.CLOSE_PARENS);
+ } else {
+ params.add (parse_identifier ());
+ }
+ expect (TokenType.LAMBDA);
+
+ LambdaExpression lambda;
+ if (current () == TokenType.OPEN_BRACE) {
+ var block = parse_block ();
+ lambda = context.create_lambda_expression_with_statement_body (block, get_src (begin));
+ } else {
+ var expr = parse_expression ();
+ lambda = context.create_lambda_expression (expr, get_src (begin));
+ }
+ foreach (string param in params) {
+ lambda.add_parameter (param);
+ }
+ return lambda;
+ }
+
+ AssignmentOperator get_assignment_operator (TokenType token_type) {
+ switch (token_type) {
+ case TokenType.ASSIGN: return AssignmentOperator.SIMPLE;
+ case TokenType.ASSIGN_ADD: return AssignmentOperator.ADD;
+ case TokenType.ASSIGN_SUB: return AssignmentOperator.SUB;
+ case TokenType.ASSIGN_BITWISE_OR: return AssignmentOperator.BITWISE_OR;
+ case TokenType.ASSIGN_BITWISE_AND: return AssignmentOperator.BITWISE_AND;
+ case TokenType.ASSIGN_BITWISE_XOR: return AssignmentOperator.BITWISE_XOR;
+ case TokenType.ASSIGN_DIV: return AssignmentOperator.DIV;
+ case TokenType.ASSIGN_MUL: return AssignmentOperator.MUL;
+ case TokenType.ASSIGN_PERCENT: return AssignmentOperator.PERCENT;
+ case TokenType.ASSIGN_SHIFT_LEFT: return AssignmentOperator.SHIFT_LEFT;
+ default: return AssignmentOperator.NONE;
+ }
+ }
+
+ Expression parse_expression () throws ParseError {
+ var begin = get_location ();
+ Expression expr = parse_conditional_expression ();
+
+ if (current () == TokenType.LAMBDA) {
+ rollback (begin);
+ return parse_lambda_expression ();
+ }
+
+ while (true) {
+ var operator = get_assignment_operator (current ());
+ if (operator != AssignmentOperator.NONE) {
+ next ();
+ var rhs = parse_expression ();
+ expr = context.create_assignment (expr, rhs, operator);
+ } else if (current () == TokenType.OP_GT) { // >>=
+ char* first_gt_pos = tokens[index].begin.pos;
+ next ();
+ // only accept >>= when there is no space between the two > signs
+ if (current () == TokenType.OP_GE && tokens[index].begin.pos == first_gt_pos + 1) {
+ next ();
+ var rhs = parse_expression ();
+ expr = context.create_assignment (expr, rhs, AssignmentOperator.SHIFT_RIGHT);
+ } else {
+ prev ();
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ return expr;
+ }
+
+ Statement parse_statement () throws ParseError {
+ comment = scanner.pop_comment ();
+ switch (current ()) {
+ case TokenType.OPEN_BRACE:
+ return parse_block ();
+ case TokenType.SEMICOLON:
+ return parse_empty_statement ();
+ case TokenType.IF:
+ return parse_if_statement ();
+ case TokenType.SWITCH:
+ return parse_switch_statement ();
+ case TokenType.WHILE:
+ return parse_while_statement ();
+ case TokenType.DO:
+ return parse_do_statement ();
+ case TokenType.FOR:
+ return parse_for_statement ();
+ case TokenType.FOREACH:
+ return parse_foreach_statement ();
+ case TokenType.BREAK:
+ return parse_break_statement ();
+ case TokenType.CONTINUE:
+ return parse_continue_statement ();
+ case TokenType.RETURN:
+ return parse_return_statement ();
+ case TokenType.THROW:
+ return parse_throw_statement ();
+ case TokenType.TRY:
+ return parse_try_statement ();
+ case TokenType.LOCK:
+ return parse_lock_statement ();
+ case TokenType.DELETE:
+ return parse_delete_statement ();
+ case TokenType.VAR:
+ return parse_declaration_statement ();
+ case TokenType.OP_INC:
+ case TokenType.OP_DEC:
+ case TokenType.BASE:
+ case TokenType.THIS:
+ case TokenType.OPEN_PARENS:
+ case TokenType.STAR:
+ return parse_expression_statement ();
+ }
+
+ if (is_expression ()) {
+ return parse_expression_statement ();
+ } else {
+ return parse_declaration_statement ();
+ }
+ }
+
+ bool is_expression () throws ParseError {
+ var begin = get_location ();
+
+ // decide between declaration and expression statement
+ skip_type ();
+ switch (current ()) {
+ // invocation expression
+ case TokenType.OPEN_PARENS:
+ // postfix increment
+ case TokenType.OP_INC:
+ // postfix decrement
+ case TokenType.OP_DEC:
+ // assignments
+ case TokenType.ASSIGN:
+ case TokenType.ASSIGN_ADD:
+ case TokenType.ASSIGN_BITWISE_AND:
+ case TokenType.ASSIGN_BITWISE_OR:
+ case TokenType.ASSIGN_BITWISE_XOR:
+ case TokenType.ASSIGN_DIV:
+ case TokenType.ASSIGN_MUL:
+ case TokenType.ASSIGN_PERCENT:
+ case TokenType.ASSIGN_SHIFT_LEFT:
+ case TokenType.ASSIGN_SUB:
+ case TokenType.OP_GT: // >>=
+ // member access
+ case TokenType.DOT:
+ // pointer member access
+ case TokenType.OP_PTR:
+ rollback (begin);
+ return true;
+ }
+
+ rollback (begin);
+ return false;
+ }
+
+ Block parse_embedded_statement () throws ParseError {
+ if (current () == TokenType.OPEN_BRACE) {
+ return parse_block ();
+ }
+
+ comment = scanner.pop_comment ();
+
+ var block = context.create_block ();
+ block.add_statement (parse_embedded_statement_without_block ());
+ return block;
+
+ }
+
+ Statement parse_embedded_statement_without_block () throws ParseError {
+ switch (current ()) {
+ case TokenType.SEMICOLON: return parse_empty_statement ();
+ case TokenType.IF: return parse_if_statement ();
+ case TokenType.SWITCH: return parse_switch_statement ();
+ case TokenType.WHILE: return parse_while_statement ();
+ case TokenType.DO: return parse_do_statement ();
+ case TokenType.FOR: return parse_for_statement ();
+ case TokenType.FOREACH: return parse_foreach_statement ();
+ case TokenType.BREAK: return parse_break_statement ();
+ case TokenType.CONTINUE: return parse_continue_statement ();
+ case TokenType.RETURN: return parse_return_statement ();
+ case TokenType.THROW: return parse_throw_statement ();
+ case TokenType.TRY: return parse_try_statement ();
+ case TokenType.LOCK: return parse_lock_statement ();
+ case TokenType.DELETE: return parse_delete_statement ();
+ default: return parse_expression_statement ();
+ }
+ }
+
+ Block parse_block () throws ParseError {
+ var begin = get_location ();
+ Gee.List<Statement> list = new ArrayList<Statement> ();
+ expect (TokenType.OPEN_BRACE);
+ var block = context.create_block (get_src_com (begin));
+ while (current () != TokenType.CLOSE_BRACE) {
+ try {
+ var stmt = parse_statement ();
+ if (stmt == null) {
+ // workaround for current limitation of exception handling
+ throw new ParseError.SYNTAX ("syntax error in statement");
+ }
+ block.add_statement (stmt);
+ } catch (ParseError e) {
+ if (recover () != RecoveryState.STATEMENT_BEGIN) {
+ // beginning of next declaration or end of file reached
+ // return what we have so far
+ return block;
+ }
+ }
+ }
+ if (!accept (TokenType.CLOSE_BRACE)) {
+ Report.error (new SourceReference (scanner.source_file, tokens[index].begin.line, tokens[index].begin.column, tokens[index].end.line, tokens[index].end.column), "expected `}'");
+ }
+
+ return block;
+ }
+
+ Statement parse_empty_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.SEMICOLON);
+ return context.create_empty_statement (get_src_com (begin));
+ }
+
+ Statement parse_declaration_statement () throws ParseError {
+ var begin = get_location ();
+ var decl = parse_local_variable_declaration ();
+ expect (TokenType.SEMICOLON);
+ return context.create_declaration_statement (decl, get_src_com (begin));
+ }
+
+ LocalVariableDeclaration parse_local_variable_declaration () throws ParseError {
+ var begin = get_location ();
+ LocalVariableDeclaration decl;
+ if (accept (TokenType.VAR)) {
+ var declarators = parse_variable_declarators ();
+ decl = context.create_local_variable_declaration_var_type (get_src (begin));
+ foreach (VariableDeclarator var_decl in declarators) {
+ decl.add_declarator (var_decl);
+ }
+ } else {
+ var type = parse_type ();
+ var declarators = parse_variable_declarators ();
+ if (!((UnresolvedType) type).is_weak) {
+ type.takes_ownership = true;
+ }
+ type.requires_null_check = false;
+ type.nullable = true;
+ decl = context.create_local_variable_declaration (type, get_src (begin));
+ foreach (VariableDeclarator var_decl in declarators) {
+ var_decl.type_reference = type.copy ();
+ decl.add_declarator (var_decl);
+ }
+ }
+ return decl;
+ }
+
+ Statement parse_expression_statement () throws ParseError {
+ var begin = get_location ();
+ var expr = parse_statement_expression ();
+ expect (TokenType.SEMICOLON);
+ return context.create_expression_statement (expr, get_src_com (begin));
+ }
+
+ Expression parse_statement_expression () throws ParseError {
+ // invocation expression, assignment,
+ // or pre/post increment/decrement expression
+ return parse_expression ();
+ }
+
+ Statement parse_if_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.IF);
+ expect (TokenType.OPEN_PARENS);
+ var condition = parse_expression ();
+ expect (TokenType.CLOSE_PARENS);
+ var src = get_src_com (begin);
+ var true_stmt = parse_embedded_statement ();
+ Block false_stmt = null;
+ if (accept (TokenType.ELSE)) {
+ false_stmt = parse_embedded_statement ();
+ }
+ return context.create_if_statement (condition, true_stmt, false_stmt, src);
+ }
+
+ Statement parse_switch_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.SWITCH);
+ expect (TokenType.OPEN_PARENS);
+ var condition = parse_expression ();
+ expect (TokenType.CLOSE_PARENS);
+ var stmt = context.create_switch_statement (condition, get_src_com (begin));
+ expect (TokenType.OPEN_BRACE);
+ while (current () != TokenType.CLOSE_BRACE) {
+ var section = context.create_switch_section (get_src_com (begin));
+ do {
+ if (accept (TokenType.CASE)) {
+ section.add_label (context.create_switch_label (parse_expression (), get_src_com (begin)));
+ } else {
+ expect (TokenType.DEFAULT);
+ section.add_label (context.create_switch_label_with_default (get_src_com (begin)));
+ }
+ expect (TokenType.COLON);
+ } while (current () == TokenType.CASE || current () == TokenType.DEFAULT);
+ while (current () != TokenType.CLOSE_BRACE
+ && current () != TokenType.CASE
+ && current () != TokenType.DEFAULT) {
+ section.add_statement (parse_statement ());
+ }
+ stmt.add_section (section);
+ }
+ expect (TokenType.CLOSE_BRACE);
+ return stmt;
+ }
+
+ Statement parse_while_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.WHILE);
+ expect (TokenType.OPEN_PARENS);
+ var condition = parse_expression ();
+ expect (TokenType.CLOSE_PARENS);
+ var body = parse_embedded_statement ();
+ return context.create_while_statement (condition, body, get_src_com (begin));
+ }
+
+ Statement parse_do_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.DO);
+ var body = parse_embedded_statement ();
+ expect (TokenType.WHILE);
+ expect (TokenType.OPEN_PARENS);
+ var condition = parse_expression ();
+ expect (TokenType.CLOSE_PARENS);
+ expect (TokenType.SEMICOLON);
+ return context.create_do_statement (body, condition, get_src_com (begin));
+ }
+
+ Statement parse_for_statement () throws ParseError {
+ var begin = get_location ();
+ Block block = null;
+ expect (TokenType.FOR);
+ expect (TokenType.OPEN_PARENS);
+ var initializer_list = new ArrayList<Expression> ();
+ if (!accept (TokenType.SEMICOLON)) {
+ bool is_expr;
+ switch (current ()) {
+ case TokenType.VAR:
+ is_expr = false;
+ break;
+ case TokenType.OP_INC:
+ case TokenType.OP_DEC:
+ is_expr = true;
+ break;
+ default:
+ is_expr = is_expression ();
+ break;
+ }
+
+ if (is_expr) {
+ do {
+ initializer_list.add (parse_statement_expression ());
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.SEMICOLON);
+ } else {
+ block = context.create_block (get_src (begin));
+ block.add_statement (parse_declaration_statement ());
+ }
+ }
+ Expression condition = null;
+ if (current () != TokenType.SEMICOLON) {
+ condition = parse_expression ();
+ }
+ expect (TokenType.SEMICOLON);
+ var iterator_list = new ArrayList<Expression> ();
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ iterator_list.add (parse_statement_expression ());
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.CLOSE_PARENS);
+ var src = get_src_com (begin);
+ var body = parse_embedded_statement ();
+ var stmt = context.create_for_statement (condition, body, src);
+ foreach (Expression init in initializer_list) {
+ stmt.add_initializer (init);
+ }
+ foreach (Expression iter in iterator_list) {
+ stmt.add_iterator (iter);
+ }
+ if (block != null) {
+ block.add_statement (stmt);
+ return block;
+ } else {
+ return stmt;
+ }
+ }
+
+ Statement parse_foreach_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.FOREACH);
+ expect (TokenType.OPEN_PARENS);
+ var type = parse_type ();
+ var unresolved_type = type as UnresolvedType;
+ if (unresolved_type != null && !unresolved_type.is_weak) {
+ unresolved_type.takes_ownership = true;
+ }
+ string id = parse_identifier ();
+ expect (TokenType.IN);
+ var collection = parse_expression ();
+ expect (TokenType.CLOSE_PARENS);
+ var src = get_src_com (begin);
+ var body = parse_embedded_statement ();
+ return context.create_foreach_statement (type, id, collection, body, src);
+ }
+
+ Statement parse_break_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.BREAK);
+ expect (TokenType.SEMICOLON);
+ return context.create_break_statement (get_src_com (begin));
+ }
+
+ Statement parse_continue_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.CONTINUE);
+ expect (TokenType.SEMICOLON);
+ return context.create_continue_statement (get_src_com (begin));
+ }
+
+ Statement parse_return_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.RETURN);
+ Expression expr = null;
+ if (current () != TokenType.SEMICOLON) {
+ expr = parse_expression ();
+ }
+ expect (TokenType.SEMICOLON);
+ return context.create_return_statement (expr, get_src_com (begin));
+ }
+
+ Statement parse_throw_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.THROW);
+ var expr = parse_expression ();
+ expect (TokenType.SEMICOLON);
+ return context.create_throw_statement (expr, get_src_com (begin));
+ }
+
+ Statement parse_try_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.TRY);
+ var try_block = parse_block ();
+ Block finally_clause = null;
+ var catch_clauses = new ArrayList<CatchClause> ();
+ if (current () == TokenType.CATCH) {
+ parse_catch_clauses (catch_clauses);
+ if (current () == TokenType.FINALLY) {
+ finally_clause = parse_finally_clause ();
+ }
+ } else {
+ finally_clause = parse_finally_clause ();
+ }
+ var stmt = context.create_try_statement (try_block, finally_clause, get_src_com (begin));
+ foreach (CatchClause clause in catch_clauses) {
+ stmt.add_catch_clause (clause);
+ }
+ return stmt;
+ }
+
+ void parse_catch_clauses (Gee.List<CatchClause> catch_clauses) throws ParseError {
+ while (accept (TokenType.CATCH)) {
+ var begin = get_location ();
+ DataType type = null;
+ string id = null;
+ if (accept (TokenType.OPEN_PARENS)) {
+ type = parse_type ();
+ id = parse_identifier ();
+ expect (TokenType.CLOSE_PARENS);
+ }
+ var block = parse_block ();
+ catch_clauses.add (context.create_catch_clause (type, id, block, get_src (begin)));
+ }
+ }
+
+ Block parse_finally_clause () throws ParseError {
+ expect (TokenType.FINALLY);
+ return parse_block ();
+ }
+
+ Statement parse_lock_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.LOCK);
+ expect (TokenType.OPEN_PARENS);
+ var expr = parse_expression ();
+ expect (TokenType.CLOSE_PARENS);
+ var stmt = parse_embedded_statement ();
+ return context.create_lock_statement (expr, stmt, get_src_com (begin));
+ }
+
+ Statement parse_delete_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.DELETE);
+ var expr = parse_expression ();
+ expect (TokenType.SEMICOLON);
+ return context.create_delete_statement (expr, get_src_com (begin));
+ }
+
+ Gee.List<Attribute> parse_attributes () throws ParseError {
+ if (current () != TokenType.OPEN_BRACKET) {
return null;
}
+ var attrs = new ArrayList<Attribute> ();
+ while (accept (TokenType.OPEN_BRACKET)) {
+ do {
+ var begin = get_location ();
+ string id = parse_identifier ();
+ var attr = new Attribute (id, get_src (begin));
+ if (accept (TokenType.OPEN_PARENS)) {
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ begin = get_location ();
+ string id = parse_identifier ();
+ expect (TokenType.ASSIGN);
+ var expr = parse_expression ();
+ attr.add_argument (new NamedArgument (id, expr, get_src (begin)));
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.CLOSE_PARENS);
+ }
+ attrs.add (attr);
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.CLOSE_BRACKET);
+ }
+ return attrs;
+ }
+
+ void set_attributes (CodeNode node, Gee.List<Attribute> attributes) {
+ if (attributes != null) {
+ foreach (Attribute attr in attributes) {
+ node.attributes.append (attr);
+ }
+ }
+ }
+
+ Symbol parse_declaration () throws ParseError {
+ comment = scanner.pop_comment ();
+ var attrs = parse_attributes ();
- String result = new String (comment);
- comment = null;
+ var begin = get_location ();
- weak string index;
- while ((index = result.str.chr (-1, '\t')) != null) {
- result.erase (result.str.pointer_to_offset (index), 1);
- }
+ TokenType last_keyword = current ();
- return result.str;
- }
+ while (is_declaration_keyword (current ())) {
+ last_keyword = current ();
+ next ();
+ }
- [Import ()]
- public void parse_file (SourceFile! source_file);
+ switch (current ()) {
+ case TokenType.CONSTRUCT:
+ rollback (begin);
+ return parse_constructor_declaration (attrs);
+ case TokenType.TILDE:
+ rollback (begin);
+ return parse_destructor_declaration (attrs);
+ default:
+ skip_type ();
+ switch (current ()) {
+ case TokenType.OPEN_BRACE:
+ case TokenType.SEMICOLON:
+ case TokenType.COLON:
+ rollback (begin);
+ switch (last_keyword) {
+ case TokenType.CLASS: return parse_class_declaration (attrs);
+ case TokenType.ENUM: return parse_enum_declaration (attrs);
+ case TokenType.ERRORDOMAIN: return parse_errordomain_declaration (attrs);
+ case TokenType.INTERFACE: return parse_interface_declaration (attrs);
+ case TokenType.NAMESPACE: return parse_namespace_declaration (attrs);
+ case TokenType.STRUCT: return parse_struct_declaration (attrs);
+ }
+ break;
+ case TokenType.OPEN_PARENS:
+ rollback (begin);
+ return parse_creation_method_declaration (attrs);
+ default:
+ skip_type (); // might contain type parameter list
+ switch (current ()) {
+ case TokenType.OPEN_PARENS:
+ rollback (begin);
+ switch (last_keyword) {
+ case TokenType.DELEGATE: return parse_delegate_declaration (attrs);
+ case TokenType.SIGNAL: return parse_signal_declaration (attrs);
+ default: return parse_method_declaration (attrs);
+ }
+ case TokenType.ASSIGN:
+ case TokenType.SEMICOLON:
+ rollback (begin);
+ switch (last_keyword) {
+ case TokenType.CONST: return parse_constant_declaration (attrs);
+ default: return parse_field_declaration (attrs);
+ }
+ case TokenType.OPEN_BRACE:
+ rollback (begin);
+ return parse_property_declaration (attrs);
+ }
+ break;
+ }
+ break;
+ }
+
+ throw new ParseError.SYNTAX (get_error ("expected declaration"));
+ }
+
+ void parse_declarations (Symbol parent, bool root = false) throws ParseError {
+ if (!root) {
+ expect (TokenType.OPEN_BRACE);
+ }
+ while (current () != TokenType.CLOSE_BRACE && current () != TokenType.EOF) {
+ try {
+ if (parent is Namespace) {
+ parse_namespace_member ((Namespace) parent);
+ } else if (parent is Class) {
+ parse_class_member ((Class) parent);
+ } else if (parent is Struct) {
+ parse_struct_member ((Struct) parent);
+ } else if (parent is Interface) {
+ parse_interface_member ((Interface) parent);
+ }
+ } catch (ParseError e) {
+ int r;
+ do {
+ r = recover ();
+ } while (r == RecoveryState.STATEMENT_BEGIN);
+ if (r == RecoveryState.EOF) {
+ return;
+ }
+ }
+ }
+ if (!root) {
+ if (!accept (TokenType.CLOSE_BRACE)) {
+ Report.error (new SourceReference (scanner.source_file, tokens[index].begin.line, tokens[index].begin.column, tokens[index].end.line, tokens[index].end.column), "expected `}'");
+ }
+ }
+ }
+
+ enum RecoveryState {
+ EOF,
+ DECLARATION_BEGIN,
+ STATEMENT_BEGIN
+ }
+
+ RecoveryState recover () {
+ while (current () != TokenType.EOF) {
+ switch (current ()) {
+ case TokenType.ABSTRACT:
+ case TokenType.CLASS:
+ case TokenType.CONST:
+ case TokenType.CONSTRUCT:
+ case TokenType.DELEGATE:
+ case TokenType.ENUM:
+ case TokenType.ERRORDOMAIN:
+ case TokenType.INLINE:
+ case TokenType.INTERFACE:
+ case TokenType.NAMESPACE:
+ case TokenType.OVERRIDE:
+ case TokenType.PRIVATE:
+ case TokenType.PROTECTED:
+ case TokenType.PUBLIC:
+ case TokenType.SIGNAL:
+ case TokenType.STATIC:
+ case TokenType.STRUCT:
+ case TokenType.VIRTUAL:
+ case TokenType.VOLATILE:
+ return RecoveryState.DECLARATION_BEGIN;
+ case TokenType.BREAK:
+ case TokenType.CONTINUE:
+ case TokenType.DELETE:
+ case TokenType.DO:
+ case TokenType.FOR:
+ case TokenType.FOREACH:
+ case TokenType.IF:
+ case TokenType.LOCK:
+ case TokenType.RETURN:
+ case TokenType.SWITCH:
+ case TokenType.THROW:
+ case TokenType.TRY:
+ case TokenType.VAR:
+ case TokenType.WHILE:
+ return RecoveryState.STATEMENT_BEGIN;
+ default:
+ next ();
+ break;
+ }
+ }
+ return RecoveryState.EOF;
+ }
+
+ Namespace parse_namespace_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.NAMESPACE);
+ var sym = parse_symbol_name ();
+ var ns = context.create_namespace (sym.name, get_src_com (begin));
+ ns.pkg = scanner.source_file.pkg;
+ set_attributes (ns, attrs);
+ parse_declarations (ns);
+ return ns;
+ }
+
+ void parse_namespace_member (Namespace ns) throws ParseError {
+ var sym = parse_declaration ();
+ if (sym is Namespace) {
+ if (ns.scope.lookup (sym.name) is Namespace) {
+ // merge if namespace already exists
+ var old_ns = (Namespace) ns.scope.lookup (sym.name);
+ var new_ns = (Namespace) sym;
+ if (!new_ns.pkg) {
+ old_ns.pkg = false;
+ }
+ foreach (Class cl in new_ns.get_classes ()) {
+ if (old_ns.scope.lookup (cl.name) is Class) {
+ // merge
+ var old_class = (Class) old_ns.scope.lookup (cl.name);
+ foreach (DataType base_type in cl.get_base_types ()) {
+ old_class.add_base_type (base_type);
+ }
+ foreach (Field f in cl.get_fields ()) {
+ old_class.add_field (f);
+ }
+ foreach (Method m in cl.get_methods ()) {
+ if (m == cl.default_construction_method && old_class.default_construction_method != null) {
+ // ignore secondary default creation method
+ continue;
+ }
+ old_class.add_method (m);
+ }
+ if (cl.constructor != null) {
+ old_class.constructor = cl.constructor;
+ }
+ scanner.source_file.remove_node (cl);
+ } else {
+ old_ns.add_class (cl);
+ }
+ }
+ foreach (Struct st in new_ns.get_structs ()) {
+ old_ns.add_struct (st);
+ }
+ foreach (Interface iface in new_ns.get_interfaces ()) {
+ old_ns.add_interface (iface);
+ }
+ foreach (Delegate d in new_ns.get_delegates ()) {
+ old_ns.add_delegate (d);
+ }
+ foreach (Enum en in new_ns.get_enums ()) {
+ old_ns.add_enum (en);
+ }
+ foreach (ErrorDomain ed in new_ns.get_error_domains ()) {
+ old_ns.add_error_domain (ed);
+ }
+ foreach (Constant c in new_ns.get_constants ()) {
+ old_ns.add_constant (c);
+ }
+ foreach (Field f in new_ns.get_fields ()) {
+ old_ns.add_field (f);
+ }
+ foreach (Method m in new_ns.get_methods ()) {
+ old_ns.add_method (m);
+ }
+ } else {
+ context.root.add_namespace ((Namespace) sym);
+ }
+ } else if (sym is Class) {
+ ns.add_class ((Class) sym);
+ } else if (sym is Interface) {
+ ns.add_interface ((Interface) sym);
+ } else if (sym is Struct) {
+ ns.add_struct ((Struct) sym);
+ } else if (sym is Enum) {
+ ns.add_enum ((Enum) sym);
+ } else if (sym is ErrorDomain) {
+ ns.add_error_domain ((ErrorDomain) sym);
+ } else if (sym is Delegate) {
+ ns.add_delegate ((Delegate) sym);
+ } else if (sym is Method) {
+ var method = (Method) sym;
+ method.instance = false;
+ ns.add_method (method);
+ } else if (sym is Field) {
+ var field = (Field) sym;
+ field.instance = false;
+ ns.add_field (field);
+ } else if (sym is Constant) {
+ ns.add_constant ((Constant) sym);
+ } else if (sym == null) {
+ // workaround for current limitation of exception handling
+ throw new ParseError.SYNTAX ("syntax error in declaration");
+ } else {
+ Report.error (sym.source_reference, "unexpected declaration in namespace");
+ }
+ scanner.source_file.add_node (sym);
+ }
+
+ void parse_using_directives () throws ParseError {
+ while (accept (TokenType.USING)) {
+ var begin = get_location ();
+
+ do {
+ var begin = get_location ();
+ var sym = parse_symbol_name ();
+ var ns_ref = new NamespaceReference (sym.name, get_src (begin));
+ scanner.source_file.add_using_directive (ns_ref);
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.SEMICOLON);
+ }
+ }
+
+ Symbol parse_class_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ var flags = parse_type_declaration_modifiers ();
+ expect (TokenType.CLASS);
+ var sym = parse_symbol_name ();
+ var type_param_list = parse_type_parameter_list ();
+ var base_types = new ArrayList<DataType> ();
+ if (accept (TokenType.COLON)) {
+ do {
+ base_types.add (parse_type ());
+ } while (accept (TokenType.COMMA));
+ }
+
+ var cl = context.create_class (sym.name, get_src_com (begin));
+ cl.access = access;
+ if (ModifierFlags.ABSTRACT in flags) {
+ cl.is_abstract = true;
+ }
+ if (ModifierFlags.STATIC in flags) {
+ cl.is_static = true;
+ }
+ set_attributes (cl, attrs);
+ foreach (TypeParameter type_param in type_param_list) {
+ cl.add_type_parameter (type_param);
+ }
+ foreach (DataType base_type in base_types) {
+ cl.add_base_type (base_type);
+ }
+
+ parse_declarations (cl);
+
+ // ensure there is always a default construction method
+ if (!scanner.source_file.pkg
+ && !cl.is_abstract
+ && !cl.is_static
+ && cl.default_construction_method == null) {
+ var m = context.create_creation_method (cl.name, null, cl.source_reference);
+ m.instance = false;
+ m.access = SymbolAccessibility.PUBLIC;
+ m.body = context.create_block (cl.source_reference);
+ cl.add_method (m);
+ }
+
+ Symbol result = cl;
+ while (sym.inner != null) {
+ sym = sym.inner;
+ var ns = context.create_namespace (sym.name, cl.source_reference);
+ ns.pkg = scanner.source_file.pkg;
+ if (result is Namespace) {
+ ns.add_namespace ((Namespace) result);
+ } else {
+ ns.add_class ((Class) result);
+ scanner.source_file.add_node (result);
+ }
+ result = ns;
+ }
+ return result;
+ }
+
+ void parse_class_member (Class cl) throws ParseError {
+ var sym = parse_declaration ();
+ if (sym is Class) {
+ cl.add_class ((Class) sym);
+ } else if (sym is Struct) {
+ cl.add_struct ((Struct) sym);
+ } else if (sym is Enum) {
+ cl.add_enum ((Enum) sym);
+ } else if (sym is Delegate) {
+ cl.add_delegate ((Delegate) sym);
+ } else if (sym is Method) {
+ cl.add_method ((Method) sym);
+ } else if (sym is Signal) {
+ cl.add_signal ((Signal) sym);
+ } else if (sym is Field) {
+ cl.add_field ((Field) sym);
+ } else if (sym is Constant) {
+ cl.add_constant ((Constant) sym);
+ } else if (sym is Property) {
+ cl.add_property ((Property) sym);
+ } else if (sym is Constructor) {
+ var c = (Constructor) sym;
+ if (c.instance) {
+ cl.constructor = c;
+ } else {
+ cl.static_constructor = c;
+ }
+ } else if (sym is Destructor) {
+ cl.destructor = (Destructor) sym;
+ } else if (sym == null) {
+ // workaround for current limitation of exception handling
+ throw new ParseError.SYNTAX ("syntax error in declaration");
+ } else {
+ Report.error (sym.source_reference, "unexpected declaration in class");
+ }
+ }
+
+ Constant parse_constant_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ parse_member_declaration_modifiers ();
+ expect (TokenType.CONST);
+ var type = parse_type ();
+ string id = parse_identifier ();
+ Expression initializer = null;
+ if (accept (TokenType.ASSIGN)) {
+ initializer = parse_variable_initializer ();
+ }
+ expect (TokenType.SEMICOLON);
+ var c = context.create_constant (id, type, initializer, get_src_com (begin));
+ c.access = access;
+ set_attributes (c, attrs);
+ return c;
+ }
+
+ Field parse_field_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ var flags = parse_member_declaration_modifiers ();
+ var type = parse_type ();
+ var unresolved_type = type as UnresolvedType;
+ if (unresolved_type != null && !unresolved_type.is_weak) {
+ unresolved_type.takes_ownership = true;
+ }
+ string id = parse_identifier ();
+ var f = context.create_field (id, type, null, get_src_com (begin));
+ f.access = access;
+ set_attributes (f, attrs);
+ if (ModifierFlags.STATIC in flags) {
+ f.instance = false;
+ }
+ if (accept (TokenType.ASSIGN)) {
+ f.initializer = parse_expression ();
+ }
+ expect (TokenType.SEMICOLON);
+ return f;
+ }
+
+ Gee.List<VariableDeclarator> parse_variable_declarators () throws ParseError {
+ var list = new ArrayList<VariableDeclarator> ();
+ do {
+ var var_decl = parse_variable_declarator ();
+ list.add (var_decl);
+ } while (accept (TokenType.COMMA));
+ return list;
+ }
+
+ VariableDeclarator parse_variable_declarator () throws ParseError {
+ var begin = get_location ();
+ string id = parse_identifier ();
+ Expression initializer = null;
+ if (accept (TokenType.ASSIGN)) {
+ initializer = parse_variable_initializer ();
+ }
+ return context.create_variable_declarator (id, initializer, get_src (begin));
+ }
+
+ InitializerList parse_initializer () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.OPEN_BRACE);
+ var initializer = context.create_initializer_list (get_src (begin));
+ if (current () != TokenType.CLOSE_BRACE) {
+ do {
+ initializer.append (parse_variable_initializer ());
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.CLOSE_BRACE);
+ return initializer;
+ }
+
+ Expression parse_variable_initializer () throws ParseError {
+ if (current () == TokenType.OPEN_BRACE) {
+ return parse_initializer ();
+ } else {
+ return parse_expression ();
+ }
+ }
+
+ Method parse_method_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ var flags = parse_member_declaration_modifiers ();
+ var type = parse_type ();
+ var unresolved_type = type as UnresolvedType;
+ if (unresolved_type != null && !unresolved_type.is_weak) {
+ unresolved_type.transfers_ownership = true;
+ }
+ string id = parse_identifier ();
+ parse_type_parameter_list ();
+ var method = context.create_method (id, type, get_src_com (begin));
+ method.access = access;
+ set_attributes (method, attrs);
+ if (ModifierFlags.STATIC in flags) {
+ method.instance = false;
+ }
+ if (ModifierFlags.ABSTRACT in flags) {
+ method.is_abstract = true;
+ }
+ if (ModifierFlags.VIRTUAL in flags) {
+ method.is_virtual = true;
+ }
+ if (ModifierFlags.OVERRIDE in flags) {
+ method.overrides = true;
+ }
+ if (ModifierFlags.INLINE in flags) {
+ method.is_inline = true;
+ }
+ expect (TokenType.OPEN_PARENS);
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ method.add_parameter (parse_parameter ());
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.CLOSE_PARENS);
+ if (accept (TokenType.THROWS)) {
+ do {
+ method.add_error_domain (parse_type ());
+ } while (accept (TokenType.COMMA));
+ }
+ if (!accept (TokenType.SEMICOLON)) {
+ method.body = parse_block ();
+ }
+ return method;
+ }
+
+ Property parse_property_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ var flags = parse_member_declaration_modifiers ();
+ var type = parse_type ();
+ if (!((UnresolvedType) type).is_weak) {
+ type.takes_ownership = true;
+ }
+ string id = parse_identifier ();
+ var prop = context.create_property (id, type, null, null, get_src_com (begin));
+ prop.access = access;
+ set_attributes (prop, attrs);
+ if (ModifierFlags.ABSTRACT in flags) {
+ prop.is_abstract = true;
+ }
+ if (ModifierFlags.VIRTUAL in flags) {
+ prop.is_virtual = true;
+ }
+ if (ModifierFlags.OVERRIDE in flags) {
+ prop.overrides = true;
+ }
+ expect (TokenType.OPEN_BRACE);
+ while (current () != TokenType.CLOSE_BRACE) {
+ if (accept (TokenType.DEFAULT)) {
+ if (prop.default_expression != null) {
+ throw new ParseError.SYNTAX (get_error ("property default value already defined"));
+ }
+ if (accept (TokenType.OPEN_PARENS)) {
+ // deprecated
+ prop.default_expression = parse_expression ();
+ expect (TokenType.CLOSE_PARENS);
+ } else {
+ expect (TokenType.ASSIGN);
+ prop.default_expression = parse_expression ();
+ }
+ expect (TokenType.SEMICOLON);
+ } else {
+ parse_attributes ();
+ var accessor_access = parse_access_modifier (SymbolAccessibility.PUBLIC);
+ if (accept (TokenType.GET)) {
+ if (prop.get_accessor != null) {
+ throw new ParseError.SYNTAX (get_error ("property get accessor already defined"));
+ }
+ Block block = null;
+ if (!accept (TokenType.SEMICOLON)) {
+ block = parse_block ();
+ }
+ prop.get_accessor = context.create_property_accessor (true, false, false, block, get_src (begin));
+ prop.get_accessor.access = accessor_access;
+ } else {
+ bool writable, _construct;
+ if (accept (TokenType.SET)) {
+ writable = true;
+ _construct = accept (TokenType.CONSTRUCT);
+ } else if (accept (TokenType.CONSTRUCT)) {
+ _construct = true;
+ writable = accept (TokenType.SET);
+ } else {
+ throw new ParseError.SYNTAX (get_error ("expected get, set, or construct"));
+ }
+ if (prop.set_accessor != null) {
+ throw new ParseError.SYNTAX (get_error ("property set accessor already defined"));
+ }
+ Block block = null;
+ if (!accept (TokenType.SEMICOLON)) {
+ block = parse_block ();
+ }
+ prop.set_accessor = context.create_property_accessor (false, writable, _construct, block, get_src (begin));
+ prop.set_accessor.access = accessor_access;
+ }
+ }
+ }
+ expect (TokenType.CLOSE_BRACE);
+ return prop;
+ }
+
+ Signal parse_signal_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ parse_access_modifier ();
+ parse_member_declaration_modifiers ();
+ expect (TokenType.SIGNAL);
+ var type = parse_type ();
+ string id = parse_identifier ();
+ var sig = context.create_signal (id, type, get_src_com (begin));
+ set_attributes (sig, attrs);
+ expect (TokenType.OPEN_PARENS);
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ var param = parse_parameter ();
+ sig.add_parameter (param);
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.CLOSE_PARENS);
+ expect (TokenType.SEMICOLON);
+ return sig;
+ }
+
+ Constructor parse_constructor_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var flags = parse_member_declaration_modifiers ();
+ expect (TokenType.CONSTRUCT);
+ var c = context.create_constructor (get_src_com (begin));
+ if (ModifierFlags.STATIC in flags) {
+ c.instance = false;
+ }
+ c.body = parse_block ();
+ return c;
+ }
+
+ Destructor parse_destructor_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.TILDE);
+ parse_identifier ();
+ expect (TokenType.OPEN_PARENS);
+ expect (TokenType.CLOSE_PARENS);
+ var d = context.create_destructor (get_src_com (begin));
+ d.body = parse_block ();
+ return d;
+ }
+
+ Symbol parse_struct_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ parse_type_declaration_modifiers ();
+ expect (TokenType.STRUCT);
+ var sym = parse_symbol_name ();
+ var base_types = new ArrayList<DataType> ();
+ if (accept (TokenType.COLON)) {
+ do {
+ base_types.add (parse_type ());
+ } while (accept (TokenType.COMMA));
+ }
+ var st = context.create_struct (sym.name, get_src_com (begin));
+ st.access = access;
+ set_attributes (st, attrs);
+ foreach (DataType base_type in base_types) {
+ st.add_base_type (base_type);
+ }
+
+ parse_declarations (st);
+
+ Symbol result = st;
+ while (sym.inner != null) {
+ sym = sym.inner;
+ var ns = context.create_namespace (sym.name, st.source_reference);
+ ns.pkg = scanner.source_file.pkg;
+ if (result is Namespace) {
+ ns.add_namespace ((Namespace) result);
+ } else {
+ ns.add_struct ((Struct) result);
+ scanner.source_file.add_node (result);
+ }
+ result = ns;
+ }
+ return result;
+ }
+
+ void parse_struct_member (Struct st) throws ParseError {
+ var sym = parse_declaration ();
+ if (sym is Method) {
+ st.add_method ((Method) sym);
+ } else if (sym is Field) {
+ st.add_field ((Field) sym);
+ } else if (sym is Constant) {
+ st.add_constant ((Constant) sym);
+ } else if (sym == null) {
+ // workaround for current limitation of exception handling
+ throw new ParseError.SYNTAX ("syntax error in declaration");
+ } else {
+ Report.error (sym.source_reference, "unexpected declaration in struct");
+ }
+ }
+
+ Symbol parse_interface_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ parse_type_declaration_modifiers ();
+ expect (TokenType.INTERFACE);
+ var sym = parse_symbol_name ();
+ var type_param_list = parse_type_parameter_list ();
+ var base_types = new ArrayList<DataType> ();
+ if (accept (TokenType.COLON)) {
+ do {
+ base_types.add (parse_type ());
+ } while (accept (TokenType.COMMA));
+ }
+ var iface = context.create_interface (sym.name, get_src_com (begin));
+ iface.access = access;
+ set_attributes (iface, attrs);
+ foreach (TypeParameter type_param in type_param_list) {
+ iface.add_type_parameter (type_param);
+ }
+ foreach (DataType base_type in base_types) {
+ iface.add_prerequisite (base_type);
+ }
+
+ parse_declarations (iface);
+
+ Symbol result = iface;
+ while (sym.inner != null) {
+ sym = sym.inner;
+ var ns = context.create_namespace (sym.name, iface.source_reference);
+ ns.pkg = scanner.source_file.pkg;
+ if (result is Namespace) {
+ ns.add_namespace ((Namespace) result);
+ } else {
+ ns.add_interface ((Interface) result);
+ scanner.source_file.add_node (result);
+ }
+ result = ns;
+ }
+ return result;
+ }
+
+ void parse_interface_member (Interface iface) throws ParseError {
+ var sym = parse_declaration ();
+ if (sym is Class) {
+ iface.add_class ((Class) sym);
+ } else if (sym is Struct) {
+ iface.add_struct ((Struct) sym);
+ } else if (sym is Enum) {
+ iface.add_enum ((Enum) sym);
+ } else if (sym is Delegate) {
+ iface.add_delegate ((Delegate) sym);
+ } else if (sym is Method) {
+ iface.add_method ((Method) sym);
+ } else if (sym is Signal) {
+ iface.add_signal ((Signal) sym);
+ } else if (sym is Field) {
+ iface.add_field ((Field) sym);
+ } else if (sym is Property) {
+ iface.add_property ((Property) sym);
+ } else if (sym == null) {
+ // workaround for current limitation of exception handling
+ throw new ParseError.SYNTAX ("syntax error in declaration");
+ } else {
+ Report.error (sym.source_reference, "unexpected declaration in interface");
+ }
+ }
+
+ Symbol parse_enum_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ parse_type_declaration_modifiers ();
+ expect (TokenType.ENUM);
+ var sym = parse_symbol_name ();
+ var en = context.create_enum (sym.name, get_src_com (begin));
+ en.access = access;
+ set_attributes (en, attrs);
+
+ expect (TokenType.OPEN_BRACE);
+ do {
+ if (current () == TokenType.CLOSE_BRACE) {
+ // allow trailing comma
+ break;
+ }
+ string id = parse_identifier ();
+ var ev = context.create_enum_value (id, get_src (begin));
+ if (accept (TokenType.ASSIGN)) {
+ ev.value = parse_expression ();
+ }
+ en.add_value (ev);
+ } while (accept (TokenType.COMMA));
+ if (accept (TokenType.SEMICOLON)) {
+ // enum methods
+ while (current () != TokenType.CLOSE_BRACE) {
+ var sym = parse_declaration ();
+ if (sym is Method) {
+ en.add_method ((Method) sym);
+ } else if (sym == null) {
+ // workaround for current limitation of exception handling
+ throw new ParseError.SYNTAX ("syntax error in declaration");
+ } else {
+ Report.error (sym.source_reference, "unexpected declaration in enum");
+ }
+ }
+ }
+ expect (TokenType.CLOSE_BRACE);
+
+ Symbol result = en;
+ while (sym.inner != null) {
+ sym = sym.inner;
+ var ns = context.create_namespace (sym.name, en.source_reference);
+ ns.pkg = scanner.source_file.pkg;
+ if (result is Namespace) {
+ ns.add_namespace ((Namespace) result);
+ } else {
+ ns.add_enum ((Enum) result);
+ scanner.source_file.add_node (result);
+ }
+ result = ns;
+ }
+ return result;
+ }
+
+ Symbol parse_errordomain_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ parse_type_declaration_modifiers ();
+ expect (TokenType.ERRORDOMAIN);
+ var sym = parse_symbol_name ();
+ var ed = context.create_error_domain (sym.name, get_src_com (begin));
+ ed.access = access;
+ set_attributes (ed, attrs);
+
+ expect (TokenType.OPEN_BRACE);
+ do {
+ if (current () == TokenType.CLOSE_BRACE) {
+ // allow trailing comma
+ break;
+ }
+ string id = parse_identifier ();
+ var ec = context.create_error_code (id);
+ if (accept (TokenType.ASSIGN)) {
+ ec.value = parse_expression ();
+ }
+ ed.add_code (ec);
+ } while (accept (TokenType.COMMA));
+ if (accept (TokenType.SEMICOLON)) {
+ // errordomain methods
+ while (current () != TokenType.CLOSE_BRACE) {
+ var sym = parse_declaration ();
+ if (sym is Method) {
+ ed.add_method ((Method) sym);
+ } else if (sym == null) {
+ // workaround for current limitation of exception handling
+ throw new ParseError.SYNTAX ("syntax error in declaration");
+ } else {
+ Report.error (sym.source_reference, "unexpected declaration in errordomain");
+ }
+ }
+ }
+ expect (TokenType.CLOSE_BRACE);
+
+ Symbol result = ed;
+ while (sym.inner != null) {
+ sym = sym.inner;
+ var ns = context.create_namespace (sym.name, ed.source_reference);
+ ns.pkg = scanner.source_file.pkg;
+ if (result is Namespace) {
+ ns.add_namespace ((Namespace) result);
+ } else {
+ ns.add_error_domain ((ErrorDomain) result);
+ scanner.source_file.add_node (result);
+ }
+ result = ns;
+ }
+ return result;
+ }
+
+ SymbolAccessibility parse_access_modifier (SymbolAccessibility default_access = SymbolAccessibility.PRIVATE) {
+ switch (current ()) {
+ case TokenType.PRIVATE:
+ next ();
+ return SymbolAccessibility.PRIVATE;
+ case TokenType.PROTECTED:
+ next ();
+ return SymbolAccessibility.PROTECTED;
+ case TokenType.PUBLIC:
+ next ();
+ return SymbolAccessibility.PUBLIC;
+ default:
+ return default_access;
+ }
+ }
+
+ ModifierFlags parse_type_declaration_modifiers () {
+ ModifierFlags flags = 0;
+ while (true) {
+ switch (current ()) {
+ case TokenType.ABSTRACT:
+ next ();
+ flags |= ModifierFlags.ABSTRACT;
+ break;
+ case TokenType.STATIC:
+ next ();
+ flags |= ModifierFlags.STATIC;
+ break;
+ default:
+ return flags;
+ }
+ }
+ return flags;
+ }
+
+ ModifierFlags parse_member_declaration_modifiers () {
+ ModifierFlags flags = 0;
+ while (true) {
+ switch (current ()) {
+ case TokenType.ABSTRACT:
+ next ();
+ flags |= ModifierFlags.ABSTRACT;
+ break;
+ case TokenType.CLASS:
+ next ();
+ flags |= ModifierFlags.CLASS;
+ break;
+ case TokenType.INLINE:
+ next ();
+ flags |= ModifierFlags.INLINE;
+ break;
+ case TokenType.OVERRIDE:
+ next ();
+ flags |= ModifierFlags.OVERRIDE;
+ break;
+ case TokenType.STATIC:
+ next ();
+ flags |= ModifierFlags.STATIC;
+ break;
+ case TokenType.VIRTUAL:
+ next ();
+ flags |= ModifierFlags.VIRTUAL;
+ break;
+ default:
+ return flags;
+ }
+ }
+ return flags;
+ }
+
+ FormalParameter parse_parameter () throws ParseError {
+ var attrs = parse_attributes ();
+ var begin = get_location ();
+ if (accept (TokenType.ELLIPSIS)) {
+ // varargs
+ return context.create_formal_parameter_with_ellipsis (get_src (begin));
+ }
+ bool construct_param = accept (TokenType.CONSTRUCT);
+ var type = parse_type ();
+ var ut = type as UnresolvedType;
+ if (ut != null) {
+ if (!ut.is_weak) {
+ ut.takes_ownership = true;
+ }
+ if (!ut.is_ref && !ut.is_out && !ut.transfers_ownership) {
+ // take_ownership for in parameters that don't transfer ownership is not supported
+ ut.takes_ownership = false;
+ }
+ }
+ string id = parse_identifier ();
+ var param = context.create_formal_parameter (id, type, get_src (begin));
+ set_attributes (param, attrs);
+ param.construct_parameter = construct_param;
+ if (accept (TokenType.ASSIGN)) {
+ param.default_expression = parse_expression ();
+ }
+ return param;
+ }
+
+ CreationMethod parse_creation_method_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ parse_member_declaration_modifiers ();
+ var sym = parse_symbol_name ();
+ CreationMethod method;
+ if (sym.inner == null) {
+ method = context.create_creation_method (sym.name, null, get_src_com (begin));
+ } else {
+ method = context.create_creation_method (sym.inner.name, sym.name, get_src_com (begin));
+ }
+ expect (TokenType.OPEN_PARENS);
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ method.add_parameter (parse_parameter ());
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.CLOSE_PARENS);
+ if (accept (TokenType.THROWS)) {
+ do {
+ method.add_error_domain (parse_type ());
+ } while (accept (TokenType.COMMA));
+ }
+ method.access = access;
+ set_attributes (method, attrs);
+ method.instance = false;
+ if (!accept (TokenType.SEMICOLON)) {
+ method.body = parse_block ();
+ }
+ return method;
+ }
+
+ Symbol parse_delegate_declaration (Gee.List<Attribute> attrs) throws ParseError {
+ var begin = get_location ();
+ var access = parse_access_modifier ();
+ var flags = parse_member_declaration_modifiers ();
+ expect (TokenType.DELEGATE);
+ var type = parse_type ();
+ var sym = parse_symbol_name ();
+ var type_param_list = parse_type_parameter_list ();
+ var d = context.create_delegate (sym.name, type, get_src_com (begin));
+ d.access = access;
+ set_attributes (d, attrs);
+ if (!(ModifierFlags.STATIC in flags)) {
+ d.instance = true;
+ }
+ foreach (TypeParameter type_param in type_param_list) {
+ d.add_type_parameter (type_param);
+ }
+ expect (TokenType.OPEN_PARENS);
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ d.add_parameter (parse_parameter ());
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.CLOSE_PARENS);
+ if (accept (TokenType.THROWS)) {
+ do {
+ parse_type ();
+ } while (accept (TokenType.COMMA));
+ }
+ expect (TokenType.SEMICOLON);
+
+ Symbol result = d;
+ while (sym.inner != null) {
+ sym = sym.inner;
+ var ns = context.create_namespace (sym.name, d.source_reference);
+ ns.pkg = scanner.source_file.pkg;
+ if (result is Namespace) {
+ ns.add_namespace ((Namespace) result);
+ } else {
+ ns.add_delegate ((Delegate) result);
+ scanner.source_file.add_node (result);
+ }
+ result = ns;
+ }
+ return result;
+ }
+
+ Gee.List<TypeParameter> parse_type_parameter_list () throws ParseError {
+ var list = new ArrayList<TypeParameter> ();
+ if (accept (TokenType.OP_LT)) {
+ do {
+ var begin = get_location ();
+ string id = parse_identifier ();
+ list.add (context.create_type_parameter (id, get_src (begin)));
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.OP_GT);
+ }
+ return list;
+ }
+
+ void skip_type_argument_list () throws ParseError {
+ if (accept (TokenType.OP_LT)) {
+ do {
+ skip_type ();
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.OP_GT);
+ }
+ }
+
+ // try to parse type argument list
+ Gee.List<DataType> parse_type_argument_list (bool maybe_expression) throws ParseError {
+ var begin = get_location ();
+ if (accept (TokenType.OP_LT)) {
+ var list = new ArrayList<DataType> ();
+ do {
+ switch (current ()) {
+ case TokenType.VOID:
+ case TokenType.WEAK:
+ case TokenType.IDENTIFIER:
+ var type = parse_type ();
+ if (!((UnresolvedType) type).is_weak) {
+ type.takes_ownership = true;
+ }
+ list.add (type);
+ break;
+ default:
+ rollback (begin);
+ return null;
+ }
+ } while (accept (TokenType.COMMA));
+ if (!accept (TokenType.OP_GT)) {
+ rollback (begin);
+ return null;
+ }
+ if (maybe_expression) {
+ // check follower to decide whether to keep type argument list
+ switch (current ()) {
+ case TokenType.OPEN_PARENS:
+ case TokenType.CLOSE_PARENS:
+ case TokenType.CLOSE_BRACKET:
+ case TokenType.COLON:
+ case TokenType.SEMICOLON:
+ case TokenType.COMMA:
+ case TokenType.DOT:
+ case TokenType.INTERR:
+ case TokenType.OP_EQ:
+ case TokenType.OP_NE:
+ // keep type argument list
+ break;
+ default:
+ // interpret tokens as expression
+ rollback (begin);
+ return null;
+ }
+ }
+ return list;
+ }
+ return null;
+ }
+
+ MemberAccess parse_member_name () throws ParseError {
+ var begin = get_location ();
+ MemberAccess expr = null;
+ do {
+ string id = parse_identifier ();
+ var type_arg_list = parse_type_argument_list (false);
+ expr = context.create_member_access (expr, id, get_src (begin));
+ if (type_arg_list != null) {
+ foreach (DataType type_arg in type_arg_list) {
+ expr.add_type_argument (type_arg);
+ }
+ }
+ } while (accept (TokenType.DOT));
+ return expr;
+ }
+
+ bool is_declaration_keyword (TokenType type) {
+ switch (type) {
+ case TokenType.ABSTRACT:
+ case TokenType.CLASS:
+ case TokenType.CONST:
+ case TokenType.DELEGATE:
+ case TokenType.ENUM:
+ case TokenType.ERRORDOMAIN:
+ case TokenType.INLINE:
+ case TokenType.INTERFACE:
+ case TokenType.NAMESPACE:
+ case TokenType.OVERRIDE:
+ case TokenType.PRIVATE:
+ case TokenType.PROTECTED:
+ case TokenType.PUBLIC:
+ case TokenType.SIGNAL:
+ case TokenType.STATIC:
+ case TokenType.STRUCT:
+ case TokenType.VIRTUAL:
+ case TokenType.VOLATILE:
+ return true;
+ default:
+ return false;
+ }
+ }
}
+
+public errordomain Vala.ParseError {
+ FAILED,
+ SYNTAX
+}
+
--- /dev/null
+/* valascanner.vala
+ *
+ * Copyright (C) 2008 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.1 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;
+using Gee;
+
+/**
+ * Lexical scanner for Vala source files.
+ */
+public class Vala.Scanner : Object {
+ public SourceFile source_file { get; construct; }
+
+ char* begin;
+ char* current;
+ char* end;
+
+ int line;
+ int column;
+
+ string _comment;
+
+ public Scanner (SourceFile source_file) {
+ this.source_file = source_file;
+ }
+
+ construct {
+ begin = source_file.get_mapped_contents ();
+ end = begin + source_file.get_mapped_length ();
+
+ current = begin;
+
+ line = 1;
+ column = 1;
+ }
+
+ bool is_ident_char (char c) {
+ return (c.isalnum () || c == '_');
+ }
+
+ TokenType get_identifier_or_keyword (char* begin, int len) {
+ switch (len) {
+ case 2:
+ switch (begin[0]) {
+ case 'a':
+ if (matches (begin, "as")) return TokenType.AS;
+ break;
+ case 'd':
+ if (matches (begin, "do")) return TokenType.DO;
+ break;
+ case 'i':
+ switch (begin[1]) {
+ case 'f':
+ return TokenType.IF;
+ case 'n':
+ return TokenType.IN;
+ case 's':
+ return TokenType.IS;
+ }
+ break;
+ }
+ break;
+ case 3:
+ switch (begin[0]) {
+ case 'f':
+ if (matches (begin, "for")) return TokenType.FOR;
+ break;
+ case 'g':
+ if (matches (begin, "get")) return TokenType.GET;
+ break;
+ case 'n':
+ if (matches (begin, "new")) return TokenType.NEW;
+ break;
+ case 'o':
+ if (matches (begin, "out")) return TokenType.OUT;
+ break;
+ case 'r':
+ if (matches (begin, "ref")) return TokenType.REF;
+ break;
+ case 's':
+ if (matches (begin, "set")) return TokenType.SET;
+ break;
+ case 't':
+ if (matches (begin, "try")) return TokenType.TRY;
+ break;
+ case 'v':
+ if (matches (begin, "var")) return TokenType.VAR;
+ break;
+ }
+ break;
+ case 4:
+ switch (begin[0]) {
+ case 'b':
+ if (matches (begin, "base")) return TokenType.BASE;
+ break;
+ case 'c':
+ if (matches (begin, "case")) return TokenType.CASE;
+ break;
+ case 'e':
+ switch (begin[1]) {
+ case 'l':
+ if (matches (begin, "else")) return TokenType.ELSE;
+ break;
+ case 'n':
+ if (matches (begin, "enum")) return TokenType.ENUM;
+ break;
+ }
+ break;
+ case 'l':
+ if (matches (begin, "lock")) return TokenType.LOCK;
+ break;
+ case 'n':
+ if (matches (begin, "null")) return TokenType.NULL;
+ break;
+ case 't':
+ switch (begin[1]) {
+ case 'h':
+ if (matches (begin, "this")) return TokenType.THIS;
+ break;
+ case 'r':
+ if (matches (begin, "true")) return TokenType.TRUE;
+ break;
+ }
+ break;
+ case 'v':
+ if (matches (begin, "void")) return TokenType.VOID;
+ break;
+ case 'w':
+ if (matches (begin, "weak")) return TokenType.WEAK;
+ break;
+ }
+ break;
+ case 5:
+ switch (begin[0]) {
+ case 'b':
+ if (matches (begin, "break")) return TokenType.BREAK;
+ break;
+ case 'c':
+ switch (begin[1]) {
+ case 'a':
+ if (matches (begin, "catch")) return TokenType.CATCH;
+ break;
+ case 'l':
+ if (matches (begin, "class")) return TokenType.CLASS;
+ break;
+ case 'o':
+ if (matches (begin, "const")) return TokenType.CONST;
+ break;
+ }
+ break;
+ case 'f':
+ if (matches (begin, "false")) return TokenType.FALSE;
+ break;
+ case 't':
+ if (matches (begin, "throw")) return TokenType.THROW;
+ break;
+ case 'u':
+ if (matches (begin, "using")) return TokenType.USING;
+ break;
+ case 'w':
+ if (matches (begin, "while")) return TokenType.WHILE;
+ break;
+ }
+ break;
+ case 6:
+ switch (begin[0]) {
+ case 'd':
+ if (matches (begin, "delete")) return TokenType.DELETE;
+ break;
+ case 'i':
+ if (matches (begin, "inline")) return TokenType.INLINE;
+ break;
+ case 'p':
+ if (matches (begin, "public")) return TokenType.PUBLIC;
+ break;
+ case 'r':
+ if (matches (begin, "return")) return TokenType.RETURN;
+ break;
+ case 's':
+ switch (begin[1]) {
+ case 'i':
+ switch (begin[2]) {
+ case 'g':
+ if (matches (begin, "signal")) return TokenType.SIGNAL;
+ break;
+ case 'z':
+ if (matches (begin, "sizeof")) return TokenType.SIZEOF;
+ break;
+ }
+ break;
+ case 't':
+ switch (begin[2]) {
+ case 'a':
+ if (matches (begin, "static")) return TokenType.STATIC;
+ break;
+ case 'r':
+ if (matches (begin, "struct")) return TokenType.STRUCT;
+ break;
+ }
+ break;
+ case 'w':
+ if (matches (begin, "switch")) return TokenType.SWITCH;
+ break;
+ }
+ break;
+ case 't':
+ switch (begin[1]) {
+ case 'h':
+ if (matches (begin, "throws")) return TokenType.THROWS;
+ break;
+ case 'y':
+ if (matches (begin, "typeof")) return TokenType.TYPEOF;
+ break;
+ }
+ break;
+ }
+ break;
+ case 7:
+ switch (begin[0]) {
+ case 'd':
+ if (matches (begin, "default")) return TokenType.DEFAULT;
+ break;
+ case 'e':
+ if (matches (begin, "ensures")) return TokenType.ENSURES;
+ break;
+ case 'f':
+ switch (begin[1]) {
+ case 'i':
+ if (matches (begin, "finally")) return TokenType.FINALLY;
+ break;
+ case 'o':
+ if (matches (begin, "foreach")) return TokenType.FOREACH;
+ break;
+ }
+ break;
+ case 'p':
+ if (matches (begin, "private")) return TokenType.PRIVATE;
+ break;
+ case 'v':
+ if (matches (begin, "virtual")) return TokenType.VIRTUAL;
+ break;
+ }
+ break;
+ case 8:
+ switch (begin[0]) {
+ case 'a':
+ if (matches (begin, "abstract")) return TokenType.ABSTRACT;
+ break;
+ case 'c':
+ if (matches (begin, "continue")) return TokenType.CONTINUE;
+ break;
+ case 'd':
+ if (matches (begin, "delegate")) return TokenType.DELEGATE;
+ break;
+ case 'o':
+ if (matches (begin, "override")) return TokenType.OVERRIDE;
+ break;
+ case 'r':
+ if (matches (begin, "requires")) return TokenType.REQUIRES;
+ break;
+ case 'v':
+ if (matches (begin, "volatile")) return TokenType.VOLATILE;
+ break;
+ }
+ break;
+ case 9:
+ switch (begin[0]) {
+ case 'c':
+ if (matches (begin, "construct")) return TokenType.CONSTRUCT;
+ break;
+ case 'i':
+ if (matches (begin, "interface")) return TokenType.INTERFACE;
+ break;
+ case 'n':
+ if (matches (begin, "namespace")) return TokenType.NAMESPACE;
+ break;
+ case 'p':
+ if (matches (begin, "protected")) return TokenType.PROTECTED;
+ break;
+ }
+ break;
+ case 11:
+ if (matches (begin, "errordomain")) return TokenType.ERRORDOMAIN;
+ break;
+ }
+ return TokenType.IDENTIFIER;
+ }
+
+ public TokenType read_token (out SourceLocation token_begin, out SourceLocation token_end) {
+ space ();
+
+ TokenType type;
+ char* begin = current;
+ token_begin.pos = begin;
+ token_begin.line = line;
+ token_begin.column = column;
+
+ int token_length_in_chars = -1;
+
+ if (current >= end) {
+ type = TokenType.EOF;
+ } else if (current[0].isalpha () || current[0] == '_') {
+ int len = 0;
+ while (current < end && is_ident_char (current[0])) {
+ current++;
+ len++;
+ }
+ type = get_identifier_or_keyword (begin, len);
+ } else if (current[0] == '@') {
+ token_begin.pos++; // @ is not part of the identifier
+ current++;
+ int len = 0;
+ while (current < end && is_ident_char (current[0])) {
+ current++;
+ len++;
+ }
+ type = TokenType.IDENTIFIER;
+ } else if (current[0].isdigit ()) {
+ while (current < end && current[0].isdigit ()) {
+ current++;
+ }
+ type = TokenType.INTEGER_LITERAL;
+ if (current < end && current[0].tolower () == 'l') {
+ current++;
+ if (current < end && current[0].tolower () == 'l') {
+ current++;
+ }
+ } else if (current < end && current[0].tolower () == 'u') {
+ current++;
+ if (current < end && current[0].tolower () == 'l') {
+ current++;
+ if (current < end && current[0].tolower () == 'l') {
+ current++;
+ }
+ }
+ } else if (current < end && current[0] == '.') {
+ current++;
+ while (current < end && current[0].isdigit ()) {
+ current++;
+ }
+ if (current < end && current[0].tolower () == 'e') {
+ current++;
+ if (current < end && (current[0] == '+' || current[0] == '-')) {
+ current++;
+ }
+ while (current < end && current[0].isdigit ()) {
+ current++;
+ }
+ }
+ if (current < end && current[0].tolower () == 'f') {
+ current++;
+ }
+ type = TokenType.REAL_LITERAL;
+ } else if (current < end && current == begin + 1
+ && begin[0] == '0' && begin[1] == 'x' && begin[2].isxdigit ()) {
+ // hexadecimal integer literal
+ current++;
+ while (current < end && current[0].isxdigit ()) {
+ current++;
+ }
+ } else if (current < end && is_ident_char (current[0])) {
+ // allow identifiers to start with a digit
+ // as long as they contain at least one char
+ while (current < end && is_ident_char (current[0])) {
+ current++;
+ }
+ type = TokenType.IDENTIFIER;
+ }
+ } else {
+ switch (current[0]) {
+ case '{':
+ type = TokenType.OPEN_BRACE;
+ current++;
+ break;
+ case '}':
+ type = TokenType.CLOSE_BRACE;
+ current++;
+ break;
+ case '(':
+ type = TokenType.OPEN_PARENS;
+ current++;
+ break;
+ case ')':
+ type = TokenType.CLOSE_PARENS;
+ current++;
+ break;
+ case '[':
+ type = TokenType.OPEN_BRACKET;
+ current++;
+ break;
+ case ']':
+ type = TokenType.CLOSE_BRACKET;
+ current++;
+ break;
+ case '.':
+ type = TokenType.DOT;
+ current++;
+ if (current < end - 1) {
+ if (current[0] == '.' && current[1] == '.') {
+ type = TokenType.ELLIPSIS;
+ current += 2;
+ }
+ }
+ break;
+ case ':':
+ type = TokenType.COLON;
+ current++;
+ break;
+ case ',':
+ type = TokenType.COMMA;
+ current++;
+ break;
+ case ';':
+ type = TokenType.SEMICOLON;
+ current++;
+ break;
+ case '#':
+ type = TokenType.HASH;
+ current++;
+ break;
+ case '?':
+ type = TokenType.INTERR;
+ current++;
+ break;
+ case '|':
+ type = TokenType.BITWISE_OR;
+ current++;
+ if (current < end) {
+ switch (current[0]) {
+ case '=':
+ type = TokenType.ASSIGN_BITWISE_OR;
+ current++;
+ break;
+ case '|':
+ type = TokenType.OP_OR;
+ current++;
+ break;
+ }
+ }
+ break;
+ case '&':
+ type = TokenType.BITWISE_AND;
+ current++;
+ if (current < end) {
+ switch (current[0]) {
+ case '=':
+ type = TokenType.ASSIGN_BITWISE_AND;
+ current++;
+ break;
+ case '&':
+ type = TokenType.OP_AND;
+ current++;
+ break;
+ }
+ }
+ break;
+ case '^':
+ type = TokenType.CARRET;
+ current++;
+ if (current < end && current[0] == '=') {
+ type = TokenType.ASSIGN_BITWISE_XOR;
+ current++;
+ }
+ break;
+ case '~':
+ type = TokenType.TILDE;
+ current++;
+ break;
+ case '=':
+ type = TokenType.ASSIGN;
+ current++;
+ if (current < end) {
+ switch (current[0]) {
+ case '=':
+ type = TokenType.OP_EQ;
+ current++;
+ break;
+ case '>':
+ type = TokenType.LAMBDA;
+ current++;
+ break;
+ }
+ }
+ break;
+ case '<':
+ type = TokenType.OP_LT;
+ current++;
+ if (current < end) {
+ switch (current[0]) {
+ case '=':
+ type = TokenType.OP_LE;
+ current++;
+ break;
+ case '<':
+ type = TokenType.OP_SHIFT_LEFT;
+ current++;
+ if (current < end && current[0] == '=') {
+ type = TokenType.ASSIGN_SHIFT_LEFT;
+ current++;
+ }
+ break;
+ }
+ }
+ break;
+ case '>':
+ type = TokenType.OP_GT;
+ current++;
+ if (current < end && current[0] == '=') {
+ type = TokenType.OP_GE;
+ current++;
+ }
+ break;
+ case '!':
+ type = TokenType.OP_NEG;
+ current++;
+ if (current < end && current[0] == '=') {
+ type = TokenType.OP_NE;
+ current++;
+ }
+ break;
+ case '+':
+ type = TokenType.PLUS;
+ current++;
+ if (current < end) {
+ switch (current[0]) {
+ case '=':
+ type = TokenType.ASSIGN_ADD;
+ current++;
+ break;
+ case '+':
+ type = TokenType.OP_INC;
+ current++;
+ break;
+ }
+ }
+ break;
+ case '-':
+ type = TokenType.MINUS;
+ current++;
+ if (current < end) {
+ switch (current[0]) {
+ case '=':
+ type = TokenType.ASSIGN_SUB;
+ current++;
+ break;
+ case '-':
+ type = TokenType.OP_DEC;
+ current++;
+ break;
+ case '>':
+ type = TokenType.OP_PTR;
+ current++;
+ break;
+ }
+ }
+ break;
+ case '*':
+ type = TokenType.STAR;
+ current++;
+ if (current < end && current[0] == '=') {
+ type = TokenType.ASSIGN_MUL;
+ current++;
+ }
+ break;
+ case '/':
+ type = TokenType.DIV;
+ current++;
+ if (current < end && current[0] == '=') {
+ type = TokenType.ASSIGN_DIV;
+ current++;
+ }
+ break;
+ case '%':
+ type = TokenType.PERCENT;
+ current++;
+ if (current < end && current[0] == '=') {
+ type = TokenType.ASSIGN_PERCENT;
+ current++;
+ }
+ break;
+ case '\'':
+ case '"':
+ if (begin[0] == '\'') {
+ type = TokenType.CHARACTER_LITERAL;
+ } else {
+ type = TokenType.STRING_LITERAL;
+ }
+ token_length_in_chars = 2;
+ current++;
+ while (current < end && current[0] != begin[0]) {
+ if (current[0] == '\\') {
+ current++;
+ token_length_in_chars++;
+ if (current < end && current[0] == 'x') {
+ // hexadecimal escape character
+ current++;
+ token_length_in_chars++;
+ while (current < end && current[0].isxdigit ()) {
+ current++;
+ token_length_in_chars++;
+ }
+ } else {
+ current++;
+ token_length_in_chars++;
+ }
+ } else if (current[0] == '\n') {
+ break;
+ } else {
+ unichar u = ((string) current).get_char_validated ((long) (end - current));
+ if (u != (unichar) (-1)) {
+ current += u.to_utf8 (null);
+ token_length_in_chars++;
+ } else {
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "invalid UTF-8 character");
+ }
+ }
+ }
+ if (current < end && current[0] != '\n') {
+ current++;
+ } else {
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "syntax error, expected %c".printf (begin[0]));
+ }
+ break;
+ default:
+ unichar u = ((string) current).get_char_validated ((long) (end - current));
+ if (u != (unichar) (-1)) {
+ current += u.to_utf8 (null);
+ Report.error (new SourceReference (source_file, line, column, line, column), "syntax error, unexpected character");
+ } else {
+ current++;
+ Report.error (new SourceReference (source_file, line, column, line, column), "invalid UTF-8 character");
+ }
+ column++;
+ return read_token (out token_begin, out token_end);
+ }
+ }
+
+ if (token_length_in_chars < 0) {
+ column += (int) (current - begin);
+ } else {
+ column += token_length_in_chars;
+ }
+
+ token_end.pos = current;
+ token_end.line = line;
+ token_end.column = column - 1;
+
+ return type;
+ }
+
+ bool matches (char* begin, string keyword) {
+ char* keyword_array = keyword;
+ long len = keyword.len ();
+ for (int i = 0; i < len; i++) {
+ if (begin[i] != keyword_array[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool whitespace () {
+ bool found = false;
+ while (current < end && current[0].isspace ()) {
+ if (current[0] == '\n') {
+ line++;
+ column = 0;
+ }
+ found = true;
+ current++;
+ column++;
+ }
+ return found;
+ }
+
+ bool comment () {
+ if (current > end - 2
+ || current[0] != '/'
+ || (current[1] != '/' && current[1] != '*')) {
+ return false;
+ }
+
+ if (current[1] == '/') {
+ // single-line comment
+ current += 2;
+ char* begin = current;
+ // skip until end of line or end of file
+ while (current < end && current[0] != '\n') {
+ current++;
+ }
+ push_comment (((string) begin).ndup ((long) (current - begin)), line == 1);
+ } else {
+ // delimited comment
+ current += 2;
+ char* begin = current;
+ int begin_line = line;
+ while (current < end - 1
+ && (current[0] != '*' || current[1] != '/')) {
+ if (current[0] == '\n') {
+ line++;
+ column = 0;
+ }
+ current++;
+ column++;
+ }
+ if (current == end - 1) {
+ Report.error (new SourceReference (source_file, line, column, line, column), "syntax error, expected */");
+ return true;
+ }
+ push_comment (((string) begin).ndup ((long) (current - begin)), begin_line == 1);
+ current += 2;
+ column += 2;
+ }
+
+ return true;
+ }
+
+ void space () {
+ while (whitespace () || comment ()) {
+ }
+ }
+
+ void push_comment (string! comment_item, bool file_comment) {
+ if (_comment == null) {
+ _comment = comment_item;
+ } else {
+ _comment = "%s\n%s".printf (_comment, comment_item);
+ }
+ if (file_comment) {
+ source_file.comment = _comment;
+ _comment = null;
+ }
+ }
+
+ /**
+ * Clears and returns the content of the comment stack.
+ *
+ * @return saved comment
+ */
+ public string pop_comment () {
+ if (_comment == null) {
+ return null;
+ }
+
+ var result = new StringBuilder (_comment);
+ _comment = null;
+
+ weak string index;
+ while ((index = result.str.chr (-1, '\t')) != null) {
+ result.erase (result.str.pointer_to_offset (index), 1);
+ }
+
+ return result.str;
+ }
+}
+
symbol_table = new HashMap<string,Symbol> (str_hash, str_equal);
} else if (lookup (name) != null) {
owner.error = true;
- Report.error (owner.source_reference, "`%s' already contains a definition for `%s'".printf (owner.get_full_name (), name));
+ Report.error (sym.source_reference, "`%s' already contains a definition for `%s'".printf (owner.get_full_name (), name));
return;
}
}
sym.owner = this;
}
-
+
+ public void remove (string name) {
+ symbol_table.remove (name);
+ }
+
/**
* Returns the symbol stored in the symbol table with the specified
* name.
private Gee.ArrayList<string> source_array = null;
+ private MappedFile mapped_file = null;
+
/**
* Creates a new source file.
*
nodes.add (node);
}
+ public void remove_node (CodeNode! node) {
+ nodes.remove (node);
+ }
+
/**
* Returns a copy of the list of code nodes.
*
}
}
+ public char* get_mapped_contents () {
+ if (mapped_file == null) {
+ mapped_file = new MappedFile (filename, false);
+ }
+
+ return mapped_file.get_contents ();
+ }
+
+ public size_t get_mapped_length () {
+ return mapped_file.get_length ();
+ }
}
public enum Vala.SourceFileDependencyType {
--- /dev/null
+/* valasourcelocation.vala
+ *
+ * Copyright (C) 2008 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.1 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 position in a source file.
+ */
+public struct Vala.SourceLocation {
+ public char* pos;
+ public int line;
+ public int column;
+
+ public SourceLocation (char* _pos, int _line, int _column) {
+ pos = _pos;
+ line = _line;
+ column = _column;
+ }
+}
+
--- /dev/null
+/* valatokentype.vala
+ *
+ * Copyright (C) 2008 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.1 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;
+
+public enum Vala.TokenType {
+ NONE,
+ ABSTRACT,
+ AS,
+ ASSIGN,
+ ASSIGN_ADD,
+ ASSIGN_BITWISE_AND,
+ ASSIGN_BITWISE_OR,
+ ASSIGN_BITWISE_XOR,
+ ASSIGN_DIV,
+ ASSIGN_MUL,
+ ASSIGN_PERCENT,
+ ASSIGN_SHIFT_LEFT,
+ ASSIGN_SUB,
+ BASE,
+ BITWISE_AND,
+ BITWISE_OR,
+ BREAK,
+ CARRET,
+ CASE,
+ CATCH,
+ CHARACTER_LITERAL,
+ CLASS,
+ CLOSE_BRACE,
+ CLOSE_BRACKET,
+ CLOSE_PARENS,
+ COLON,
+ COMMA,
+ CONST,
+ CONSTRUCT,
+ CONTINUE,
+ DEFAULT,
+ DELEGATE,
+ DELETE,
+ DIV,
+ DO,
+ DOT,
+ ELLIPSIS,
+ ELSE,
+ ENUM,
+ ENSURES,
+ ERRORDOMAIN,
+ EOF,
+ FALSE,
+ FINALLY,
+ FOR,
+ FOREACH,
+ GET,
+ HASH,
+ IDENTIFIER,
+ IF,
+ IN,
+ INLINE,
+ INTEGER_LITERAL,
+ INTERFACE,
+ INTERR,
+ IS,
+ LAMBDA,
+ LOCK,
+ MINUS,
+ NAMESPACE,
+ NEW,
+ NULL,
+ OUT,
+ OP_AND,
+ OP_DEC,
+ OP_EQ,
+ OP_GE,
+ OP_GT,
+ OP_INC,
+ OP_LE,
+ OP_LT,
+ OP_NE,
+ OP_NEG,
+ OP_OR,
+ OP_PTR,
+ OP_SHIFT_LEFT,
+ OPEN_BRACE,
+ OPEN_BRACKET,
+ OPEN_PARENS,
+ OVERRIDE,
+ PERCENT,
+ PLUS,
+ PRIVATE,
+ PROTECTED,
+ PUBLIC,
+ REAL_LITERAL,
+ REF,
+ REQUIRES,
+ RETURN,
+ SEMICOLON,
+ SET,
+ SIGNAL,
+ SIZEOF,
+ STAR,
+ STATIC,
+ STRING_LITERAL,
+ STRUCT,
+ SWITCH,
+ THIS,
+ THROW,
+ THROWS,
+ TILDE,
+ TRUE,
+ TRY,
+ TYPEOF,
+ USING,
+ VAR,
+ VIRTUAL,
+ VOID,
+ VOLATILE,
+ WEAK,
+ WHILE;
+
+ public weak string to_string () {
+ switch (this) {
+ case ABSTRACT: return "`abstract'";
+ case AS: return "`as'";
+ case ASSIGN: return "`='";
+ case ASSIGN_ADD: return "`+='";
+ case ASSIGN_BITWISE_AND: return "`&='";
+ case ASSIGN_BITWISE_OR: return "`|='";
+ case ASSIGN_BITWISE_XOR: return "`^='";
+ case ASSIGN_DIV: return "`/='";
+ case ASSIGN_MUL: return "`*='";
+ case ASSIGN_PERCENT: return "`%='";
+ case ASSIGN_SHIFT_LEFT: return "`<<='";
+ case ASSIGN_SUB: return "`-='";
+ case BASE: return "`base'";
+ case BITWISE_AND: return "`&'";
+ case BITWISE_OR: return "`|'";
+ case BREAK: return "`break'";
+ case CARRET: return "`^'";
+ case CASE: return "`case'";
+ case CATCH: return "`catch'";
+ case CHARACTER_LITERAL: return "character literal";
+ case CLASS: return "`class'";
+ case CLOSE_BRACE: return "`}'";
+ case CLOSE_BRACKET: return "`]'";
+ case CLOSE_PARENS: return "`)'";
+ case COLON: return "`:'";
+ case COMMA: return "`,'";
+ case CONST: return "`const'";
+ case CONSTRUCT: return "`construct'";
+ case CONTINUE: return "`continue'";
+ case DEFAULT: return "`default'";
+ case DELEGATE: return "`delegate'";
+ case DELETE: return "`delete'";
+ case DIV: return "`/'";
+ case DO: return "`do'";
+ case DOT: return "`.'";
+ case ELLIPSIS: return "`...'";
+ case ELSE: return "`else'";
+ case ENUM: return "`enum'";
+ case ENSURES: return "`ensures'";
+ case ERRORDOMAIN: return "`errordomain'";
+ case EOF: return "end of file";
+ case FALSE: return "`false'";
+ case FINALLY: return "`finally'";
+ case FOR: return "`for'";
+ case FOREACH: return "`foreach'";
+ case GET: return "`get'";
+ case HASH: return "`hash'";
+ case IDENTIFIER: return "identifier";
+ case IF: return "`if'";
+ case IN: return "`in'";
+ case INLINE: return "`inline'";
+ case INTEGER_LITERAL: return "integer literal";
+ case INTERFACE: return "`interface'";
+ case INTERR: return "`?'";
+ case IS: return "`is'";
+ case LAMBDA: return "`=>'";
+ case LOCK: return "`lock'";
+ case MINUS: return "`-'";
+ case NAMESPACE: return "`namespace'";
+ case NEW: return "`new'";
+ case NULL: return "`null'";
+ case OUT: return "`out'";
+ case OP_AND: return "`&&'";
+ case OP_DEC: return "`--'";
+ case OP_EQ: return "`=='";
+ case OP_GE: return "`>='";
+ case OP_GT: return "`>'";
+ case OP_INC: return "`++'";
+ case OP_LE: return "`<='";
+ case OP_LT: return "`<'";
+ case OP_NE: return "`!='";
+ case OP_NEG: return "`!'";
+ case OP_OR: return "`||'";
+ case OP_PTR: return "`->'";
+ case OP_SHIFT_LEFT: return "`<<'";
+ case OPEN_BRACE: return "`{'";
+ case OPEN_BRACKET: return "`['";
+ case OPEN_PARENS: return "`('";
+ case OVERRIDE: return "`override'";
+ case PERCENT: return "`%'";
+ case PLUS: return "`+'";
+ case PRIVATE: return "`private'";
+ case PROTECTED: return "`protected'";
+ case PUBLIC: return "`public'";
+ case REAL_LITERAL: return "real literal";
+ case REF: return "`ref'";
+ case REQUIRES: return "`requires'";
+ case RETURN: return "`return'";
+ case SEMICOLON: return "`;'";
+ case SET: return "`set'";
+ case SIGNAL: return "`signal'";
+ case SIZEOF: return "`sizeof'";
+ case STAR: return "`*'";
+ case STATIC: return "`static'";
+ case STRING_LITERAL: return "string literal";
+ case STRUCT: return "`struct'";
+ case SWITCH: return "`switch'";
+ case THIS: return "`this'";
+ case THROW: return "`throw'";
+ case THROWS: return "`throws'";
+ case TILDE: return "`~'";
+ case TRUE: return "`true'";
+ case TRY: return "`try'";
+ case TYPEOF: return "`typeof'";
+ case USING: return "`using'";
+ case VAR: return "`var'";
+ case VIRTUAL: return "`virtual'";
+ case VOID: return "`void'";
+ case VOLATILE: return "`volatile'";
+ case WEAK: return "`weak'";
+ case WHILE: return "`while'";
+ default: return "unknown token";
+ }
+ }
+}
+
--- /dev/null
+/* valatuple.vala
+ *
+ * Copyright (C) 2006-2008 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.1 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;
+using Gee;
+
+/**
+ * Represents a fixed-length sequence of expressions in the source code.
+ */
+public class Vala.Tuple : Expression {
+ private Gee.List<Expression> expression_list = new ArrayList<Expression> ();
+
+ public Tuple () {
+ }
+
+ public void add_expression (Expression expr) {
+ expression_list.add (expr);
+ }
+
+ public Gee.List<Expression> get_expressions () {
+ return expression_list;
+ }
+
+ public override bool is_pure () {
+ return false;
+ }
+}
+
}
public enum Vala.UnaryOperator {
+ NONE,
PLUS,
MINUS,
LOGICAL_NEGATION,
return result;
}
+
+ public override string to_string () {
+ return unresolved_symbol.to_string ();
+ }
}