1 /* valagenieparser.vala
3 * Copyright (C) 2008 Jamie McCracken, Jürg Billeter
4 * Based on code by Jürg Billeter
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * Jamie McCracken jamiemcc gnome org
29 * Code visitor parsing all Genie source files.
31 public class Vala
.Genie
.Parser
: CodeVisitor
{
38 // index of current token in buffer
40 // number of tokens in buffer
47 /* hack needed to know if any part of an expression is a lambda one */
48 bool current_expr_is_lambda
;
50 const int BUFFER_SIZE
= 32;
53 public TokenType type
;
54 public SourceLocation begin
;
55 public SourceLocation end
;
71 tokens
= new TokenInfo
[BUFFER_SIZE
];
73 current_expr_is_lambda
= false;
77 * Parses all .gs source files in the specified code context and
80 * @param context a code context
82 public void parse (CodeContext context
) {
83 this
.context
= context
;
84 context
.accept (this
);
87 public override void visit_source_file (SourceFile source_file
) {
88 if (source_file
.filename
.has_suffix (".gs")) {
89 parse_file (source_file
);
94 index
= (index
+ 1) % BUFFER_SIZE
;
97 SourceLocation begin
, end
;
98 TokenType type
= scanner
.read_token (out begin
, out end
);
99 tokens
[index
].type
= type
;
100 tokens
[index
].begin
= begin
;
101 tokens
[index
].end
= end
;
104 return (tokens
[index
].type
!= TokenType
.EOF
);
107 inline
void prev () {
108 index
= (index
- 1 + BUFFER_SIZE
) % BUFFER_SIZE
;
110 assert (size
<= BUFFER_SIZE
);
113 inline TokenType
current () {
114 return tokens
[index
].type
;
117 inline
bool accept (TokenType type
) {
118 if (current () == type
) {
125 inline
bool accept_terminator () {
126 if (current () == TokenType
.SEMICOLON
|| current () == TokenType
.EOL
) {
133 inline
bool accept_block () {
135 bool has_term
= accept_terminator ();
137 if (accept (TokenType
.INDENT
)) {
149 string get_error (string msg
) {
150 var begin
= get_location ();
152 Report
.error (get_src (begin
), "syntax error, " + msg
);
156 inline
bool expect (TokenType type
) throws ParseError
{
161 TokenType cur
= current ();
162 TokenType pre
= tokens
[index
- 1].type
;
164 throw new ParseError
.SYNTAX (get_error ("expected %s but got %s with previous %s".printf (type
.to_string (), cur
.to_string (), pre
.to_string())));
167 inline
bool expect_terminator () throws ParseError
{
168 if (accept_terminator ()) {
172 TokenType cur
= current ();
174 throw new ParseError
.SYNTAX (get_error ("expected line end or semicolon but got %s".printf (cur
.to_string())));
177 inline SourceLocation
get_location () {
178 return tokens
[index
].begin
;
181 string get_last_string () {
182 int last_index
= (index
+ BUFFER_SIZE
- 1) % BUFFER_SIZE
;
183 return ((string) tokens
[last_index
].begin
.pos
).ndup ((tokens
[last_index
].end
.pos
- tokens
[last_index
].begin
.pos
));
186 SourceReference
get_src (SourceLocation begin
) {
187 int last_index
= (index
+ BUFFER_SIZE
- 1) % BUFFER_SIZE
;
189 return new
SourceReference (scanner
.source_file
, begin
.line
, begin
.column
, tokens
[last_index
].end
.line
, tokens
[last_index
].end
.column
);
192 SourceReference
get_src_com (SourceLocation begin
) {
193 int last_index
= (index
+ BUFFER_SIZE
- 1) % BUFFER_SIZE
;
195 var src
= new SourceReference
.with_comment (scanner
.source_file
, begin
.line
, begin
.column
, tokens
[last_index
].end
.line
, tokens
[last_index
].end
.column
, comment
);
200 SourceReference
get_current_src () {
201 return new
SourceReference (scanner
.source_file
, tokens
[index
].begin
.line
, tokens
[index
].begin
.column
, tokens
[index
].end
.line
, tokens
[index
].end
.column
);
204 void rollback (SourceLocation location
) {
205 while (tokens
[index
].begin
.pos
!= location
.pos
) {
210 inline SymbolAccessibility
get_access (string s
) {
212 return SymbolAccessibility
.PRIVATE
;
215 return SymbolAccessibility
.PUBLIC
;
218 void skip_identifier () throws ParseError
{
219 // also accept keywords as identifiers where there is no conflict
220 switch (current ()) {
221 case TokenType
.ABSTRACT
:
223 case TokenType
.ASSERT
:
224 case TokenType
.BREAK
:
225 case TokenType
.CLASS
:
226 case TokenType
.CONST
:
227 case TokenType
.CONTINUE
:
228 case TokenType
.DEDENT
:
230 case TokenType
.DEFAULT
:
231 case TokenType
.DELEGATE
:
232 case TokenType
.DELETE
:
234 case TokenType
.DOWNTO
:
235 case TokenType
.DYNAMIC
:
239 case TokenType
.ENSURES
:
240 case TokenType
.ERRORDOMAIN
:
241 case TokenType
.EVENT
:
242 case TokenType
.EXCEPT
:
243 case TokenType
.EXTERN
:
244 case TokenType
.FALSE
:
245 case TokenType
.FINAL
:
246 case TokenType
.FINALLY
:
249 case TokenType
.IDENTIFIER
:
252 case TokenType
.INDENT
:
254 case TokenType
.INLINE
:
255 case TokenType
.INTERFACE
:
259 case TokenType
.NAMESPACE
:
264 case TokenType
.OVERRIDE
:
266 case TokenType
.PRINT
:
267 case TokenType
.PRIVATE
:
269 case TokenType
.RAISE
:
270 case TokenType
.RAISES
:
272 case TokenType
.REQUIRES
:
273 case TokenType
.RETURN
:
275 case TokenType
.SIZEOF
:
276 case TokenType
.STATIC
:
277 case TokenType
.STRUCT
:
278 case TokenType
.SUPER
:
283 case TokenType
.TYPEOF
:
286 case TokenType
.VIRTUAL
:
288 case TokenType
.VOLATILE
:
291 case TokenType
.WHILE
:
295 throw new ParseError
.SYNTAX (get_error ("expected identifier"));
299 string parse_identifier () throws ParseError
{
301 return get_last_string ();
304 Expression
parse_literal () throws ParseError
{
305 var begin
= get_location ();
307 switch (current ()) {
310 return new
BooleanLiteral (true, get_src (begin
));
311 case TokenType
.FALSE
:
313 return new
BooleanLiteral (false, get_src (begin
));
314 case TokenType
.INTEGER_LITERAL
:
316 return new
IntegerLiteral (get_last_string (), get_src (begin
));
317 case TokenType
.REAL_LITERAL
:
319 return new
RealLiteral (get_last_string (), get_src (begin
));
320 case TokenType
.CHARACTER_LITERAL
:
322 return new
CharacterLiteral (get_last_string (), get_src (begin
));
323 case TokenType
.STRING_LITERAL
:
325 return new
StringLiteral (get_last_string (), get_src (begin
));
328 return new
NullLiteral (get_src (begin
));
330 throw new ParseError
.SYNTAX (get_error ("expected literal"));
334 public void parse_file (SourceFile source_file
) {
335 scanner
= new
Scanner (source_file
);
336 scanner
.indent_spaces
= 0;
343 var begin
= get_location ();
344 /* see if there is an indent attribute */
345 if (accept (TokenType
.OPEN_BRACKET
)) {
346 var id
= parse_identifier ();
347 if (id
== "indent") {
348 expect (TokenType
.ASSIGN
);
349 expect (TokenType
.INTEGER_LITERAL
);
350 scanner
.indent_spaces
= get_last_string().to_int();
351 expect (TokenType
.CLOSE_BRACKET
);
352 expect (TokenType
.EOL
);
358 parse_using_directives ();
359 parse_declarations (context
.root
, true);
360 } catch (ParseError e
) {
367 void skip_symbol_name () throws ParseError
{
370 } while (accept (TokenType
.DOT
));
373 UnresolvedSymbol
parse_symbol_name () throws ParseError
{
374 var begin
= get_location ();
375 UnresolvedSymbol sym
= null;
377 string name
= parse_identifier ();
378 sym
= new
UnresolvedSymbol (sym
, name
, get_src (begin
));
379 } while (accept (TokenType
.DOT
));
383 void skip_type () throws ParseError
{
384 if (accept (TokenType
.VOID
)) {
385 while (accept (TokenType
.STAR
)) {
389 accept (TokenType
.DYNAMIC
);
391 accept (TokenType
.WEAK
);
393 if (accept (TokenType
.ARRAY
) || accept (TokenType
.LIST
) || accept (TokenType
.DICT
)) {
394 accept (TokenType
.OF
);
398 skip_type_argument_list ();
399 while (accept (TokenType
.OPEN_BRACKET
)) {
401 if (current () != TokenType
.COMMA
&& current () != TokenType
.CLOSE_BRACKET
) {
404 } while (accept (TokenType
.COMMA
));
405 expect (TokenType
.CLOSE_BRACKET
);
407 accept (TokenType
.OP_NEG
);
408 accept (TokenType
.INTERR
);
409 accept (TokenType
.HASH
);
412 DataType
parse_type (bool owned_by_default
= true) throws ParseError
{
413 var begin
= get_location ();
415 if (accept (TokenType
.VOID
)) {
416 DataType type
= new
VoidType ();
417 while (accept (TokenType
.STAR
)) {
418 type
= new
PointerType (type
);
423 Gee
.List
<DataType
> type_arg_list
= null;
424 UnresolvedSymbol sym
= null;
426 bool is_dynamic
= accept (TokenType
.DYNAMIC
);
427 bool value_owned
= owned_by_default
;
428 if (owned_by_default
) {
429 value_owned
= !accept (TokenType
.WEAK
);
433 bool is_array
= false;
435 if (accept (TokenType
.ARRAY
)) {
436 expect (TokenType
.OF
);
441 bool is_list
= false;
443 if (accept (TokenType
.LIST
)) {
444 expect (TokenType
.OF
);
450 bool is_dict
= false;
452 if (accept (TokenType
.DICT
)) {
453 expect (TokenType
.OF
);
459 var sym_parent
= new
UnresolvedSymbol (null, "Gee", get_src (begin
));
460 sym
= new
UnresolvedSymbol (sym_parent
, "ArrayList", get_src (begin
));
461 } else if (is_dict
) {
462 var sym_parent
= new
UnresolvedSymbol (null, "Gee", get_src (begin
));
463 sym
= new
UnresolvedSymbol (sym_parent
, "HashMap", get_src (begin
));
465 sym
= parse_symbol_name ();
468 type_arg_list
= parse_type_argument_list (false);
470 DataType type
= new UnresolvedType
.from_symbol (sym
, get_src (begin
));
471 if (type_arg_list
!= null) {
472 foreach (DataType type_arg
in type_arg_list
) {
473 type
.add_type_argument (type_arg
);
477 while (accept (TokenType
.STAR
)) {
478 type
= new
PointerType (type
, get_src (begin
));
481 if (!(type is PointerType
)) {
482 type
.nullable
= accept (TokenType
.INTERR
);
487 if (!accept (TokenType
.OPEN_BRACKET
)) {
488 type
.value_owned
= true;
489 type
= new
ArrayType (type
, 1, get_src (begin
));
490 type
.nullable
= accept (TokenType
.INTERR
);
495 while (accept (TokenType
.OPEN_BRACKET
)) {
499 // support for stack-allocated arrays
500 // also required for decision between expression and declaration statement
501 if (current () != TokenType
.COMMA
&& current () != TokenType
.CLOSE_BRACKET
) {
505 while (accept (TokenType
.COMMA
));
506 expect (TokenType
.CLOSE_BRACKET
);
508 type
.value_owned
= true;
509 type
= new
ArrayType (type
, array_rank
, get_src (begin
));
510 type
.nullable
= accept (TokenType
.INTERR
);
515 if (!owned_by_default
) {
516 value_owned
= accept (TokenType
.HASH
);
519 type
.is_dynamic
= is_dynamic
;
520 type
.value_owned
= value_owned
;
524 Gee
.List
<Expression
> parse_argument_list () throws ParseError
{
525 var list
= new ArrayList
<Expression
> ();
526 if (current () != TokenType
.CLOSE_PARENS
) {
528 list
.add (parse_expression ());
529 } while (accept (TokenType
.COMMA
));
534 Expression
parse_primary_expression () throws ParseError
{
535 var begin
= get_location ();
539 switch (current ()) {
541 case TokenType
.FALSE
:
542 case TokenType
.INTEGER_LITERAL
:
543 case TokenType
.REAL_LITERAL
:
544 case TokenType
.CHARACTER_LITERAL
:
545 case TokenType
.STRING_LITERAL
:
547 expr
= parse_literal ();
549 case TokenType
.ASSERT
:
550 return parse_assert_expression ();
551 case TokenType
.OPEN_PARENS
:
552 expr
= parse_tuple ();
555 expr
= parse_this_access ();
557 case TokenType
.SUPER
:
558 expr
= parse_base_access ();
561 expr
= parse_object_or_array_creation_expression ();
563 case TokenType
.PRINT
:
564 return parse_print_expression ();
565 case TokenType
.SIZEOF
:
566 expr
= parse_sizeof_expression ();
568 case TokenType
.TYPEOF
:
569 expr
= parse_typeof_expression ();
572 expr
= parse_simple_name ();
576 // process primary expressions that start with an inner primary expression
579 switch (current ()) {
581 expr
= parse_member_access (begin
, expr
);
583 case TokenType
.OP_PTR
:
584 expr
= parse_pointer_member_access (begin
, expr
);
586 case TokenType
.OPEN_PARENS
:
587 expr
= parse_method_call (begin
, expr
);
589 case TokenType
.OPEN_BRACKET
:
590 expr
= parse_element_access (begin
, expr
);
592 case TokenType
.OP_INC
:
593 expr
= parse_post_increment_expression (begin
, expr
);
595 case TokenType
.OP_DEC
:
596 expr
= parse_post_decrement_expression (begin
, expr
);
608 Expression
parse_simple_name () throws ParseError
{
609 var begin
= get_location ();
610 string id
= parse_identifier ();
611 Gee
.List
<DataType
> type_arg_list
= parse_type_argument_list (true);
612 var expr
= new
MemberAccess (null, id
, get_src (begin
));
613 if (type_arg_list
!= null) {
614 foreach (DataType type_arg
in type_arg_list
) {
615 expr
.add_type_argument (type_arg
);
621 Expression
parse_tuple () throws ParseError
{
622 var begin
= get_location ();
623 expect (TokenType
.OPEN_PARENS
);
624 var expr_list
= new ArrayList
<Expression
> ();
625 if (current () != TokenType
.CLOSE_PARENS
) {
627 expr_list
.add (parse_expression ());
628 } while (accept (TokenType
.COMMA
));
630 expect (TokenType
.CLOSE_PARENS
);
631 if (expr_list
.size
!= 1) {
632 var tuple
= new
Tuple ();
633 foreach (Expression expr
in expr_list
) {
634 tuple
.add_expression (expr
);
638 return new
ParenthesizedExpression (expr_list
.get (0), get_src (begin
));
641 Expression
parse_member_access (SourceLocation begin
, Expression inner
) throws ParseError
{
642 expect (TokenType
.DOT
);
643 string id
= parse_identifier ();
644 Gee
.List
<DataType
> type_arg_list
= parse_type_argument_list (true);
645 var expr
= new
MemberAccess (inner
, id
, get_src (begin
));
646 if (type_arg_list
!= null) {
647 foreach (DataType type_arg
in type_arg_list
) {
648 expr
.add_type_argument (type_arg
);
654 Expression
parse_pointer_member_access (SourceLocation begin
, Expression inner
) throws ParseError
{
655 expect (TokenType
.OP_PTR
);
656 string id
= parse_identifier ();
657 Gee
.List
<DataType
> type_arg_list
= parse_type_argument_list (true);
658 var expr
= new MemberAccess
.pointer (inner
, id
, get_src (begin
));
659 if (type_arg_list
!= null) {
660 foreach (DataType type_arg
in type_arg_list
) {
661 expr
.add_type_argument (type_arg
);
668 Gee
.List
<Expression
> parse_print_argument_list () throws ParseError
{
669 var list
= new ArrayList
<Expression
> ();
671 var begin
= get_location ();
673 if (current () != TokenType
.CLOSE_PARENS
) {
675 var p_expr
= parse_expression ();
679 if (p_expr
!= null) {
682 if (p_expr is StringLiteral
) {
683 var s_exp
= (StringLiteral
) p_expr
;
684 var len
= s_exp
.value
.size ();
687 var st
= s_exp
.value
.ndup (len
-1);
692 var rhs
= new
StringLiteral (s
, get_src (begin
));
693 p_expr
= new
BinaryExpression (BinaryOperator
.PLUS
, p_expr
, rhs
, get_src (begin
));
700 } while (accept (TokenType
.COMMA
));
705 Expression
parse_print_expression () throws ParseError
{
706 var begin
= get_location ();
708 expect (TokenType
.PRINT
);
709 accept (TokenType
.OPEN_PARENS
);
711 var expr
= new
MemberAccess (null, "print", get_src (begin
));
713 var arg_list
= parse_print_argument_list ();
715 accept (TokenType
.CLOSE_PARENS
);
717 var print_expr
= new
MethodCall (expr
, get_src (begin
));
719 foreach (Expression arg
in arg_list
) {
720 print_expr
.add_argument (arg
);
727 Expression
parse_assert_expression () throws ParseError
{
728 var begin
= get_location ();
730 expect (TokenType
.ASSERT
);
731 accept (TokenType
.OPEN_PARENS
);
733 var expr
= new
MemberAccess (null, "assert", get_src (begin
));
735 var arg_list
= parse_argument_list ();
737 accept (TokenType
.CLOSE_PARENS
);
739 var assert_expr
= new
MethodCall (expr
, get_src (begin
));
741 foreach (Expression arg
in arg_list
) {
742 assert_expr
.add_argument (arg
);
749 Expression
parse_method_call (SourceLocation begin
, Expression inner
) throws ParseError
{
750 expect (TokenType
.OPEN_PARENS
);
751 var arg_list
= parse_argument_list ();
752 expect (TokenType
.CLOSE_PARENS
);
753 var init_list
= parse_object_initializer ();
755 if (init_list
.size
> 0 && inner is MemberAccess
) {
756 // struct creation expression
757 var member
= (MemberAccess
) inner
;
758 member
.creation_member
= true;
760 var expr
= new
ObjectCreationExpression (member
, get_src (begin
));
761 expr
.struct_creation
= true;
762 foreach (Expression arg
in arg_list
) {
763 expr
.add_argument (arg
);
765 foreach (MemberInitializer initializer
in init_list
) {
766 expr
.add_member_initializer (initializer
);
770 var expr
= new
MethodCall (inner
, get_src (begin
));
771 foreach (Expression arg
in arg_list
) {
772 expr
.add_argument (arg
);
778 Expression
parse_element_access (SourceLocation begin
, Expression inner
) throws ParseError
{
779 expect (TokenType
.OPEN_BRACKET
);
780 var index_list
= parse_expression_list ();
781 expect (TokenType
.CLOSE_BRACKET
);
783 var expr
= new
ElementAccess (inner
, get_src (begin
));
784 foreach (Expression index
in index_list
) {
785 expr
.append_index (index
);
790 Gee
.List
<Expression
> parse_expression_list () throws ParseError
{
791 var list
= new ArrayList
<Expression
> ();
793 list
.add (parse_expression ());
794 } while (accept (TokenType
.COMMA
));
798 Expression
parse_this_access () throws ParseError
{
799 var begin
= get_location ();
800 expect (TokenType
.THIS
);
801 return new
MemberAccess (null, "this", get_src (begin
));
804 Expression
parse_base_access () throws ParseError
{
805 var begin
= get_location ();
806 expect (TokenType
.SUPER
);
807 return new
BaseAccess (get_src (begin
));
810 Expression
parse_post_increment_expression (SourceLocation begin
, Expression inner
) throws ParseError
{
811 expect (TokenType
.OP_INC
);
812 return new
PostfixExpression (inner
, true, get_src (begin
));
815 Expression
parse_post_decrement_expression (SourceLocation begin
, Expression inner
) throws ParseError
{
816 expect (TokenType
.OP_DEC
);
817 return new
PostfixExpression (inner
, false, get_src (begin
));
820 Expression
parse_object_or_array_creation_expression () throws ParseError
{
821 var begin
= get_location ();
822 expect (TokenType
.NEW
);
824 if (accept (TokenType
.ARRAY
)) {
825 expect (TokenType
.OF
);
826 var m
= parse_member_name ();
827 var expr
= parse_array_creation_expression (begin
, m
);
831 if (accept (TokenType
.LIST
)) {
832 expect (TokenType
.OF
);
833 var m
= parse_member_name ();
834 var expr
= parse_list_creation_expression (begin
, m
);
838 if (accept (TokenType
.DICT
)) {
839 expect (TokenType
.OF
);
840 var m1
= parse_member_name ();
841 expect (TokenType
.COMMA
);
842 var m2
= parse_member_name ();
843 var expr
= parse_dict_creation_expression (begin
, m1
, m2
);
848 var member
= parse_member_name ();
849 var expr
= parse_object_creation_expression (begin
, member
);
854 Expression
parse_object_creation_expression (SourceLocation begin
, MemberAccess member
) throws ParseError
{
855 member
.creation_member
= true;
856 Gee
.List
<Expression
> arg_list
;
857 if (accept (TokenType
.OPEN_PARENS
)) {
858 arg_list
= parse_argument_list ();
859 expect (TokenType
.CLOSE_PARENS
);
861 arg_list
= new ArrayList
<Expression
> ();
864 var init_list
= parse_object_initializer ();
866 var expr
= new
ObjectCreationExpression (member
, get_src (begin
));
867 foreach (Expression arg
in arg_list
) {
868 expr
.add_argument (arg
);
870 foreach (MemberInitializer initializer
in init_list
) {
871 expr
.add_member_initializer (initializer
);
876 Expression
parse_array_creation_expression (SourceLocation begin
, MemberAccess member
) throws ParseError
{
877 bool size_specified
= false;
878 Gee
.List
<Expression
> size_specifier_list
= null;
880 DataType element_type
= UnresolvedType
.new_from_expression (member
);
882 var has_bracket
= accept (TokenType
.OPEN_BRACKET
);
886 // array of arrays: new T[][42]
887 element_type
= new
ArrayType (element_type
, size_specifier_list
.size
, element_type
.source_reference
);
892 size_specifier_list
= new ArrayList
<Expression
> ();
894 Expression size
= null;
895 if (has_bracket
&& current () != TokenType
.CLOSE_BRACKET
&& current () != TokenType
.COMMA
) {
896 size
= parse_expression ();
897 size_specified
= true;
899 size_specifier_list
.add (size
);
900 } while (accept (TokenType
.COMMA
));
903 expect (TokenType
.CLOSE_BRACKET
);
905 } while (accept (TokenType
.OPEN_BRACKET
));
907 InitializerList initializer
= null;
908 if (accept (TokenType
.ASSIGN
)) {
910 initializer
= parse_initializer ();
912 var expr
= new
ArrayCreationExpression (element_type
, size_specifier_list
.size
, initializer
, get_src (begin
));
913 if (size_specified
) {
914 foreach (Expression size
in size_specifier_list
) {
915 expr
.append_size (size
);
922 Expression
parse_list_creation_expression (SourceLocation begin
, MemberAccess member
) throws ParseError
{
924 DataType element_type
= UnresolvedType
.new_from_expression (member
);
925 MemberAccess list_member
= null, parent_member
= null;
927 parent_member
= new
MemberAccess (null, "Gee", get_src (begin
));
928 list_member
= new
MemberAccess (parent_member
, "ArrayList", get_src (begin
));
929 list_member
.add_type_argument (element_type
);
931 list_member
.creation_member
= true;
933 var expr
= new
ObjectCreationExpression (list_member
, get_src (begin
));
935 if (member
.member_name
== "string") {
936 parent_member
= new
MemberAccess (null, "GLib", get_src (begin
));
937 expr
.add_argument (new
MemberAccess (parent_member
, "str_equal", get_src (begin
)));
939 } else if (member
.member_name
== "int") {
940 parent_member
= new
MemberAccess (null, "GLib", get_src (begin
));
941 expr
.add_argument (new
MemberAccess (parent_member
, "int_equal", get_src (begin
)));
947 Expression
parse_dict_creation_expression (SourceLocation begin
, MemberAccess member_key
, MemberAccess member_value
) throws ParseError
{
949 DataType key_type
= UnresolvedType
.new_from_expression (member_key
);
950 DataType value_type
= UnresolvedType
.new_from_expression (member_value
);
952 MemberAccess dict_member
= null, parent_member
= null, dict_hash
= null, dict_equal
= null;
954 parent_member
= new
MemberAccess (null, "Gee", get_src (begin
));
955 dict_member
= new
MemberAccess (parent_member
, "HashMap", get_src (begin
));
956 dict_member
.add_type_argument (key_type
);
957 dict_member
.add_type_argument (value_type
);
959 if (member_key
.member_name
== "string") {
960 parent_member
= new
MemberAccess (null, "GLib", get_src (begin
));
961 dict_hash
= new
MemberAccess (parent_member
, "str_hash", get_src (begin
));
962 dict_equal
= new
MemberAccess (parent_member
, "str_equal", get_src (begin
));
964 } else if (member_key
.member_name
== "int") {
965 parent_member
= new
MemberAccess (null, "GLib", get_src (begin
));
966 dict_hash
= new
MemberAccess (parent_member
, "int_hash", get_src (begin
));
967 dict_equal
= new
MemberAccess (parent_member
, "int_equal", get_src (begin
));
970 dict_member
.creation_member
= true;
972 var expr
= new
ObjectCreationExpression (dict_member
, get_src (begin
));
974 if (dict_hash
!= null && dict_equal
!= null) {
975 expr
.add_argument (dict_hash
);
976 expr
.add_argument (dict_equal
);
984 Gee
.List
<MemberInitializer
> parse_object_initializer () throws ParseError
{
985 var list
= new ArrayList
<MemberInitializer
> ();
986 if (accept (TokenType
.OPEN_BRACE
)) {
988 list
.add (parse_member_initializer ());
989 } while (accept (TokenType
.COMMA
));
990 expect (TokenType
.CLOSE_BRACE
);
995 MemberInitializer
parse_member_initializer () throws ParseError
{
996 var begin
= get_location ();
997 string id
= parse_identifier ();
998 expect (TokenType
.ASSIGN
);
999 var expr
= parse_expression ();
1001 return new
MemberInitializer (id
, expr
, get_src (begin
));
1004 Expression
parse_sizeof_expression () throws ParseError
{
1005 var begin
= get_location ();
1006 expect (TokenType
.SIZEOF
);
1007 expect (TokenType
.OPEN_PARENS
);
1008 var type
= parse_type ();
1009 expect (TokenType
.CLOSE_PARENS
);
1011 return new
SizeofExpression (type
, get_src (begin
));
1014 Expression
parse_typeof_expression () throws ParseError
{
1015 var begin
= get_location ();
1016 expect (TokenType
.TYPEOF
);
1017 expect (TokenType
.OPEN_PARENS
);
1018 var type
= parse_type ();
1019 expect (TokenType
.CLOSE_PARENS
);
1021 return new
TypeofExpression (type
, get_src (begin
));
1024 UnaryOperator
get_unary_operator (TokenType token_type
) {
1025 switch (token_type
) {
1026 case TokenType
.PLUS
: return UnaryOperator
.PLUS
;
1027 case TokenType
.MINUS
: return UnaryOperator
.MINUS
;
1028 case TokenType
.OP_NEG
: return UnaryOperator
.LOGICAL_NEGATION
;
1029 case TokenType
.TILDE
: return UnaryOperator
.BITWISE_COMPLEMENT
;
1030 case TokenType
.OP_INC
: return UnaryOperator
.INCREMENT
;
1031 case TokenType
.OP_DEC
: return UnaryOperator
.DECREMENT
;
1032 case TokenType
.REF
: return UnaryOperator
.REF
;
1033 case TokenType
.OUT
: return UnaryOperator
.OUT
;
1034 default: return UnaryOperator
.NONE
;
1038 Expression
parse_unary_expression () throws ParseError
{
1039 var begin
= get_location ();
1040 var operator
= get_unary_operator (current ());
1041 if (operator
!= UnaryOperator
.NONE
) {
1043 var op
= parse_unary_expression ();
1044 return new
UnaryExpression (operator
, op
, get_src (begin
));
1046 switch (current ()) {
1047 case TokenType
.HASH
:
1049 var op
= parse_unary_expression ();
1050 return new
ReferenceTransferExpression (op
, get_src (begin
));
1051 case TokenType
.OPEN_PARENS
:
1053 switch (current ()) {
1054 case TokenType
.VOID
:
1055 case TokenType
.DYNAMIC
:
1056 case TokenType
.WEAK
:
1057 case TokenType
.IDENTIFIER
:
1058 var type
= parse_type ();
1059 if (accept (TokenType
.CLOSE_PARENS
)) {
1060 // check follower to decide whether to create cast expression
1061 switch (current ()) {
1062 case TokenType
.OP_NEG
:
1063 case TokenType
.TILDE
:
1064 case TokenType
.OPEN_PARENS
:
1065 case TokenType
.TRUE
:
1066 case TokenType
.FALSE
:
1067 case TokenType
.INTEGER_LITERAL
:
1068 case TokenType
.REAL_LITERAL
:
1069 case TokenType
.CHARACTER_LITERAL
:
1070 case TokenType
.STRING_LITERAL
:
1071 case TokenType
.NULL
:
1072 case TokenType
.THIS
:
1073 case TokenType
.SUPER
:
1075 case TokenType
.SIZEOF
:
1076 case TokenType
.TYPEOF
:
1077 case TokenType
.IDENTIFIER
:
1078 if (!(type is PointerType
) && !type
.value_owned
) {
1079 Report
.warning (get_src (begin
), "obsolete syntax, weak type modifier unused in cast expressions");
1081 var inner
= parse_unary_expression ();
1082 return new
CastExpression (inner
, type
, get_src (begin
), false);
1091 // no cast expression
1094 case TokenType
.STAR
:
1096 var op
= parse_unary_expression ();
1097 return new
PointerIndirection (op
, get_src (begin
));
1098 case TokenType
.BITWISE_AND
:
1100 var op
= parse_unary_expression ();
1101 return new
AddressofExpression (op
, get_src (begin
));
1106 var expr
= parse_primary_expression ();
1110 BinaryOperator
get_binary_operator (TokenType token_type
) {
1111 switch (token_type
) {
1112 case TokenType
.STAR
: return BinaryOperator
.MUL
;
1113 case TokenType
.DIV
: return BinaryOperator
.DIV
;
1114 case TokenType
.PERCENT
: return BinaryOperator
.MOD
;
1115 case TokenType
.PLUS
: return BinaryOperator
.PLUS
;
1116 case TokenType
.MINUS
: return BinaryOperator
.MINUS
;
1117 case TokenType
.OP_LT
: return BinaryOperator
.LESS_THAN
;
1118 case TokenType
.OP_GT
: return BinaryOperator
.GREATER_THAN
;
1119 case TokenType
.OP_LE
: return BinaryOperator
.LESS_THAN_OR_EQUAL
;
1120 case TokenType
.OP_GE
: return BinaryOperator
.GREATER_THAN_OR_EQUAL
;
1121 case TokenType
.OP_EQ
: return BinaryOperator
.EQUALITY
;
1124 if (current () == TokenType
.OP_NEG
) {
1126 return BinaryOperator
.INEQUALITY
;
1129 return BinaryOperator
.EQUALITY
;
1130 case TokenType
.OP_NE
: return BinaryOperator
.INEQUALITY
;
1131 default: return BinaryOperator
.NONE
;
1135 Expression
parse_multiplicative_expression () throws ParseError
{
1136 var begin
= get_location ();
1137 var left
= parse_unary_expression ();
1140 var operator
= get_binary_operator (current ());
1142 case BinaryOperator
.MUL
:
1143 case BinaryOperator
.DIV
:
1144 case BinaryOperator
.MOD
:
1146 var right
= parse_unary_expression ();
1147 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1157 Expression
parse_additive_expression () throws ParseError
{
1158 var begin
= get_location ();
1159 var left
= parse_multiplicative_expression ();
1162 var operator
= get_binary_operator (current ());
1164 case BinaryOperator
.PLUS
:
1165 case BinaryOperator
.MINUS
:
1167 var right
= parse_multiplicative_expression ();
1168 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1178 Expression
parse_shift_expression () throws ParseError
{
1179 var begin
= get_location ();
1180 var left
= parse_additive_expression ();
1183 switch (current ()) {
1184 case TokenType
.OP_SHIFT_LEFT
:
1186 var right
= parse_additive_expression ();
1187 left
= new
BinaryExpression (BinaryOperator
.SHIFT_LEFT
, left
, right
, get_src (begin
));
1189 // don't use OP_SHIFT_RIGHT to support >> for nested generics
1190 case TokenType
.OP_GT
:
1191 char* first_gt_pos
= tokens
[index
].begin
.pos
;
1193 // only accept >> when there is no space between the two > signs
1194 if (current () == TokenType
.OP_GT
&& tokens
[index
].begin
.pos
== first_gt_pos
+ 1) {
1196 var right
= parse_additive_expression ();
1197 left
= new
BinaryExpression (BinaryOperator
.SHIFT_RIGHT
, left
, right
, get_src (begin
));
1211 Expression
parse_relational_expression () throws ParseError
{
1212 var begin
= get_location ();
1213 var left
= parse_shift_expression ();
1216 var operator
= get_binary_operator (current ());
1218 case BinaryOperator
.LESS_THAN
:
1219 case BinaryOperator
.LESS_THAN_OR_EQUAL
:
1220 case BinaryOperator
.GREATER_THAN_OR_EQUAL
:
1222 var right
= parse_shift_expression ();
1223 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1225 case BinaryOperator
.GREATER_THAN
:
1227 // ignore >> and >>= (two tokens due to generics)
1228 if (current () != TokenType
.OP_GT
&& current () != TokenType
.OP_GE
) {
1229 var right
= parse_shift_expression ();
1230 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1237 switch (current ()) {
1240 var type
= parse_type ();
1241 left
= new
TypeCheck (left
, type
, get_src (begin
));
1245 var type
= parse_type ();
1246 left
= new
CastExpression (left
, type
, get_src (begin
), true);
1258 Expression
parse_equality_expression () throws ParseError
{
1259 var begin
= get_location ();
1260 var left
= parse_relational_expression ();
1263 var operator
= get_binary_operator (current ());
1265 case BinaryOperator
.INEQUALITY
:
1266 case BinaryOperator
.EQUALITY
:
1267 if ((operator
== BinaryOperator
.INEQUALITY
) && (current () == TokenType
.IS
)) {
1271 var right
= parse_relational_expression ();
1272 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1282 Expression
parse_and_expression () throws ParseError
{
1283 var begin
= get_location ();
1284 var left
= parse_equality_expression ();
1285 while (accept (TokenType
.BITWISE_AND
)) {
1286 var right
= parse_equality_expression ();
1287 left
= new
BinaryExpression (BinaryOperator
.BITWISE_AND
, left
, right
, get_src (begin
));
1292 Expression
parse_exclusive_or_expression () throws ParseError
{
1293 var begin
= get_location ();
1294 var left
= parse_and_expression ();
1295 while (accept (TokenType
.CARRET
)) {
1296 var right
= parse_and_expression ();
1297 left
= new
BinaryExpression (BinaryOperator
.BITWISE_XOR
, left
, right
, get_src (begin
));
1302 Expression
parse_inclusive_or_expression () throws ParseError
{
1303 var begin
= get_location ();
1304 var left
= parse_exclusive_or_expression ();
1305 while (accept (TokenType
.BITWISE_OR
)) {
1306 var right
= parse_exclusive_or_expression ();
1307 left
= new
BinaryExpression (BinaryOperator
.BITWISE_OR
, left
, right
, get_src (begin
));
1312 Expression
parse_in_expression () throws ParseError
{
1313 var begin
= get_location ();
1314 var left
= parse_inclusive_or_expression ();
1315 while (accept (TokenType
.IN
)) {
1316 var right
= parse_inclusive_or_expression ();
1317 left
= new
BinaryExpression (BinaryOperator
.IN
, left
, right
, get_src (begin
));
1322 Expression
parse_conditional_and_expression () throws ParseError
{
1323 var begin
= get_location ();
1324 var left
= parse_in_expression ();
1325 while (accept (TokenType
.OP_AND
)) {
1326 var right
= parse_in_expression ();
1327 left
= new
BinaryExpression (BinaryOperator
.AND
, left
, right
, get_src (begin
));
1332 Expression
parse_conditional_or_expression () throws ParseError
{
1333 var begin
= get_location ();
1334 var left
= parse_conditional_and_expression ();
1335 while (accept (TokenType
.OP_OR
)) {
1336 var right
= parse_conditional_and_expression ();
1337 left
= new
BinaryExpression (BinaryOperator
.OR
, left
, right
, get_src (begin
));
1342 Expression
parse_conditional_expression () throws ParseError
{
1343 var begin
= get_location ();
1344 var condition
= parse_conditional_or_expression ();
1345 if (accept (TokenType
.INTERR
)) {
1346 var true_expr
= parse_expression ();
1347 expect (TokenType
.COLON
);
1348 var false_expr
= parse_expression ();
1349 return new
ConditionalExpression (condition
, true_expr
, false_expr
, get_src (begin
));
1355 Expression
parse_lambda_expression () throws ParseError
{
1356 var begin
= get_location ();
1357 Gee
.List
<string> params
= new ArrayList
<string> ();
1359 expect (TokenType
.DEF
);
1361 if (accept (TokenType
.OPEN_PARENS
)) {
1362 if (current () != TokenType
.CLOSE_PARENS
) {
1364 params
.add (parse_identifier ());
1365 } while (accept (TokenType
.COMMA
));
1367 expect (TokenType
.CLOSE_PARENS
);
1369 params
.add (parse_identifier ());
1373 LambdaExpression lambda
;
1374 if (accept_block ()) {
1375 var block
= parse_block ();
1376 lambda
= new LambdaExpression
.with_statement_body (block
, get_src (begin
));
1378 var expr
= parse_expression ();
1379 lambda
= new
LambdaExpression (expr
, get_src (begin
));
1380 expect_terminator ();
1385 foreach (string param
in params
) {
1386 lambda
.add_parameter (param
);
1391 AssignmentOperator
get_assignment_operator (TokenType token_type
) {
1392 switch (token_type
) {
1393 case TokenType
.ASSIGN
: return AssignmentOperator
.SIMPLE
;
1394 case TokenType
.ASSIGN_ADD
: return AssignmentOperator
.ADD
;
1395 case TokenType
.ASSIGN_SUB
: return AssignmentOperator
.SUB
;
1396 case TokenType
.ASSIGN_BITWISE_OR
: return AssignmentOperator
.BITWISE_OR
;
1397 case TokenType
.ASSIGN_BITWISE_AND
: return AssignmentOperator
.BITWISE_AND
;
1398 case TokenType
.ASSIGN_BITWISE_XOR
: return AssignmentOperator
.BITWISE_XOR
;
1399 case TokenType
.ASSIGN_DIV
: return AssignmentOperator
.DIV
;
1400 case TokenType
.ASSIGN_MUL
: return AssignmentOperator
.MUL
;
1401 case TokenType
.ASSIGN_PERCENT
: return AssignmentOperator
.PERCENT
;
1402 case TokenType
.ASSIGN_SHIFT_LEFT
: return AssignmentOperator
.SHIFT_LEFT
;
1403 default: return AssignmentOperator
.NONE
;
1407 Expression
parse_expression () throws ParseError
{
1408 if (current () == TokenType
.DEF
) {
1409 var lambda
= parse_lambda_expression ();
1410 current_expr_is_lambda
= true;
1414 var begin
= get_location ();
1415 Expression expr
= parse_conditional_expression ();
1418 var operator
= get_assignment_operator (current ());
1419 if (operator
!= AssignmentOperator
.NONE
) {
1421 var rhs
= parse_expression ();
1422 expr
= new
Assignment (expr
, rhs
, operator
, get_src (begin
));
1423 } else if (current () == TokenType
.OP_GT
) { // >>=
1424 char* first_gt_pos
= tokens
[index
].begin
.pos
;
1426 // only accept >>= when there is no space between the two > signs
1427 if (current () == TokenType
.OP_GE
&& tokens
[index
].begin
.pos
== first_gt_pos
+ 1) {
1429 var rhs
= parse_expression ();
1430 expr
= new
Assignment (expr
, rhs
, AssignmentOperator
.SHIFT_RIGHT
, get_src (begin
));
1444 Statement
get_for_statement_type () throws ParseError
{
1446 var begin
= get_location ();
1447 bool is_foreach
= false;
1449 while (current () != TokenType
.EOL
&& current () != TokenType
.DO
) {
1451 if (accept (TokenType
.IN
)) {
1460 return parse_foreach_statement ();
1462 return parse_for_statement ();
1467 void parse_statements (Block block
) throws ParseError
{
1468 while (current () != TokenType
.DEDENT
1469 && current () != TokenType
.WHEN
1470 && current () != TokenType
.DEFAULT
) {
1472 Statement stmt
= null;
1473 bool is_decl
= false;
1474 comment
= scanner
.pop_comment ();
1475 switch (current ()) {
1477 /* skip over requires and ensures as we handled them in method declaration */
1478 case TokenType
.REQUIRES
:
1479 case TokenType
.ENSURES
:
1480 var begin
= get_location ();
1483 if (accept (TokenType
.EOL
) && accept (TokenType
.INDENT
)) {
1484 while (current () != TokenType
.DEDENT
) {
1488 expect (TokenType
.DEDENT
);
1490 while (current () != TokenType
.EOL
) {
1494 expect (TokenType
.EOL
);
1497 stmt
= new
EmptyStatement (get_src_com (begin
));
1501 case TokenType
.INDENT
:
1502 stmt
= parse_block ();
1504 case TokenType
.SEMICOLON
:
1505 case TokenType
.PASS
:
1506 stmt
= parse_empty_statement ();
1508 case TokenType
.PRINT
:
1509 case TokenType
.ASSERT
:
1510 stmt
= parse_expression_statement ();
1513 stmt
= parse_if_statement ();
1515 case TokenType
.CASE
:
1516 stmt
= parse_switch_statement ();
1518 case TokenType
.WHILE
:
1519 stmt
= parse_while_statement ();
1522 stmt
= parse_do_statement ();
1525 stmt
= get_for_statement_type ();
1527 case TokenType
.BREAK
:
1528 stmt
= parse_break_statement ();
1530 case TokenType
.CONTINUE
:
1531 stmt
= parse_continue_statement ();
1533 case TokenType
.RETURN
:
1534 stmt
= parse_return_statement ();
1536 case TokenType
.RAISE
:
1537 stmt
= parse_throw_statement ();
1540 stmt
= parse_try_statement ();
1542 case TokenType
.LOCK
:
1543 stmt
= parse_lock_statement ();
1545 case TokenType
.DELETE
:
1546 stmt
= parse_delete_statement ();
1550 parse_local_variable_declarations (block
);
1554 case TokenType
.OP_INC
:
1555 case TokenType
.OP_DEC
:
1556 case TokenType
.SUPER
:
1557 case TokenType
.THIS
:
1558 case TokenType
.OPEN_PARENS
:
1559 case TokenType
.STAR
:
1561 stmt
= parse_expression_statement ();
1564 bool is_expr
= is_expression ();
1566 stmt
= parse_expression_statement ();
1569 parse_local_variable_declarations (block
);
1575 block
.add_statement (stmt
);
1577 } catch (ParseError e
) {
1578 if (recover () != RecoveryState
.STATEMENT_BEGIN
) {
1579 // beginning of next declaration or end of file reached
1580 // return what we have so far
1587 bool is_expression () throws ParseError
{
1588 var begin
= get_location ();
1590 // decide between declaration and expression statement
1592 switch (current ()) {
1593 // invocation expression
1594 case TokenType
.OPEN_PARENS
:
1595 // postfix increment
1596 case TokenType
.OP_INC
:
1597 // postfix decrement
1598 case TokenType
.OP_DEC
:
1600 case TokenType
.ASSIGN
:
1601 case TokenType
.ASSIGN_ADD
:
1602 case TokenType
.ASSIGN_BITWISE_AND
:
1603 case TokenType
.ASSIGN_BITWISE_OR
:
1604 case TokenType
.ASSIGN_BITWISE_XOR
:
1605 case TokenType
.ASSIGN_DIV
:
1606 case TokenType
.ASSIGN_MUL
:
1607 case TokenType
.ASSIGN_PERCENT
:
1608 case TokenType
.ASSIGN_SHIFT_LEFT
:
1609 case TokenType
.ASSIGN_SUB
:
1610 case TokenType
.OP_GT
: // >>=
1613 // pointer member access
1614 case TokenType
.OP_PTR
:
1623 Block
parse_embedded_statement () throws ParseError
{
1624 if (current () == TokenType
.INDENT
) {
1625 var block
= parse_block ();
1629 comment
= scanner
.pop_comment ();
1631 var block
= new
Block (get_src_com (get_location ()));
1632 block
.add_statement (parse_embedded_statement_without_block ());
1637 Statement
parse_embedded_statement_without_block () throws ParseError
{
1638 switch (current ()) {
1639 case TokenType
.PASS
:
1640 case TokenType
.SEMICOLON
: return parse_empty_statement ();
1641 case TokenType
.IF
: return parse_if_statement ();
1642 case TokenType
.CASE
: return parse_switch_statement ();
1643 case TokenType
.WHILE
: return parse_while_statement ();
1644 case TokenType
.DO
: return parse_do_statement ();
1645 case TokenType
.FOR
: return get_for_statement_type ();
1646 case TokenType
.BREAK
: return parse_break_statement ();
1647 case TokenType
.CONTINUE
: return parse_continue_statement ();
1648 case TokenType
.RETURN
: return parse_return_statement ();
1649 case TokenType
.RAISE
: return parse_throw_statement ();
1650 case TokenType
.TRY
: return parse_try_statement ();
1651 case TokenType
.LOCK
: return parse_lock_statement ();
1652 case TokenType
.DELETE
: return parse_delete_statement ();
1653 default: return parse_expression_statement ();
1657 Block
parse_block () throws ParseError
{
1658 var begin
= get_location ();
1659 expect (TokenType
.INDENT
);
1660 var block
= new
Block (get_src_com (begin
));
1661 parse_statements (block
);
1662 if (!accept (TokenType
.DEDENT
)) {
1663 // only report error if it's not a secondary error
1664 if (Report
.get_errors () == 0) {
1665 Report
.error (get_current_src (), "tab indentation is incorrect");
1672 Statement
parse_empty_statement () throws ParseError
{
1673 var begin
= get_location ();
1675 accept (TokenType
.PASS
);
1676 accept (TokenType
.SEMICOLON
);
1677 expect_terminator ();
1679 return new
EmptyStatement (get_src_com (begin
));
1682 void add_local_var_variable (Block block
, string id
) throws ParseError
{
1683 DataType type_copy
= null;
1684 var local
= parse_local_variable (type_copy
, id
);
1685 block
.add_statement (new
DeclarationStatement (local
, local
.source_reference
));
1688 void parse_local_variable_declarations (Block block
) throws ParseError
{
1689 if (accept (TokenType
.VAR
)) {
1690 /* support block vars */
1691 if (accept (TokenType
.EOL
) && accept (TokenType
.INDENT
)) {
1692 while (current () != TokenType
.DEDENT
) {
1693 var s
= parse_identifier ();
1694 add_local_var_variable (block
, s
);
1695 accept (TokenType
.EOL
);
1696 accept (TokenType
.SEMICOLON
);
1699 expect (TokenType
.DEDENT
);
1701 var s
= parse_identifier ();
1702 add_local_var_variable (block
, s
);
1703 expect_terminator ();
1709 var id_list
= new ArrayList
<string> ();
1710 DataType variable_type
= null;
1713 id_list
.add (parse_identifier ());
1714 } while (accept (TokenType
.COMMA
));
1716 expect (TokenType
.COLON
);
1718 variable_type
= parse_type ();
1720 foreach (string id
in id_list
) {
1721 DataType type_copy
= null;
1722 if (variable_type
!= null) {
1723 type_copy
= variable_type
.copy ();
1725 var local
= parse_local_variable (type_copy
, id
);
1726 block
.add_statement (new
DeclarationStatement (local
, local
.source_reference
));
1729 expect_terminator ();
1732 LocalVariable
parse_local_variable (DataType? variable_type
, string id
) throws ParseError
{
1733 var begin
= get_location ();
1734 Expression initializer
= null;
1735 if (accept (TokenType
.ASSIGN
)) {
1736 initializer
= parse_variable_initializer ();
1737 var array_type
= variable_type as ArrayType
;
1738 if (array_type
!= null && initializer is InitializerList
) {
1739 initializer
= new
ArrayCreationExpression (array_type
.element_type
.copy (), array_type
.rank
, (InitializerList
) initializer
, initializer
.source_reference
);
1742 return new
LocalVariable (variable_type
, id
, initializer
, get_src_com (begin
));
1745 Statement
parse_expression_statement () throws ParseError
{
1746 var begin
= get_location ();
1747 var expr
= parse_statement_expression ();
1749 if (current_expr_is_lambda
) {
1750 current_expr_is_lambda
= false;
1752 expect_terminator ();
1755 return new
ExpressionStatement (expr
, get_src_com (begin
));
1758 Expression
parse_statement_expression () throws ParseError
{
1759 // invocation expression, assignment,
1760 // or pre/post increment/decrement expression
1761 var expr
= parse_expression ();
1765 Statement
parse_if_statement () throws ParseError
{
1766 var begin
= get_location ();
1768 expect (TokenType
.IF
);
1770 var condition
= parse_expression ();
1772 if (!accept (TokenType
.DO
)) {
1773 expect (TokenType
.EOL
);
1775 accept (TokenType
.EOL
);
1778 var src
= get_src_com (begin
);
1779 var true_stmt
= parse_embedded_statement ();
1780 Block false_stmt
= null;
1781 if (accept (TokenType
.ELSE
)) {
1782 false_stmt
= parse_embedded_statement ();
1784 return new
IfStatement (condition
, true_stmt
, false_stmt
, src
);
1787 Statement
parse_switch_statement () throws ParseError
{
1788 var begin
= get_location ();
1789 expect (TokenType
.CASE
);
1790 var condition
= parse_expression ();
1792 expect (TokenType
.EOL
);
1794 var stmt
= new
SwitchStatement (condition
, get_src_com (begin
));
1795 expect (TokenType
.INDENT
);
1796 while (current () != TokenType
.DEDENT
) {
1797 var section
= new
SwitchSection (get_src_com (begin
));
1799 if (accept (TokenType
.WHEN
)) {
1801 section
.add_label (new
SwitchLabel (parse_expression (), get_src_com (begin
)));
1803 while (accept (TokenType
.COMMA
));
1805 expect (TokenType
.DEFAULT
);
1806 section
.add_label (new SwitchLabel
.with_default (get_src_com (begin
)));
1809 if (!accept (TokenType
.EOL
)) {
1810 expect (TokenType
.DO
);
1813 parse_statements (section
);
1815 /* add break statement for each block */
1816 var break_stmt
= new
BreakStatement (get_src_com (begin
));
1817 section
.add_statement (break_stmt
);
1819 stmt
.add_section (section
);
1821 expect (TokenType
.DEDENT
);
1825 Statement
parse_while_statement () throws ParseError
{
1826 var begin
= get_location ();
1827 expect (TokenType
.WHILE
);
1828 var condition
= parse_expression ();
1830 if (!accept (TokenType
.DO
)) {
1831 expect (TokenType
.EOL
);
1833 accept (TokenType
.EOL
);
1836 var body
= parse_embedded_statement ();
1837 return new
WhileStatement (condition
, body
, get_src_com (begin
));
1840 Statement
parse_do_statement () throws ParseError
{
1841 var begin
= get_location ();
1842 expect (TokenType
.DO
);
1843 expect (TokenType
.EOL
);
1844 var body
= parse_embedded_statement ();
1845 expect (TokenType
.WHILE
);
1847 var condition
= parse_expression ();
1849 expect_terminator ();
1851 return new
DoStatement (body
, condition
, get_src_com (begin
));
1855 Statement
parse_for_statement () throws ParseError
{
1856 var begin
= get_location ();
1858 Expression initializer
= null;
1859 Expression condition
= null;
1860 Expression iterator
= null;
1864 expect (TokenType
.FOR
);
1866 switch (current ()) {
1872 bool local_is_expr
= is_expression ();
1873 is_expr
= local_is_expr
;
1878 var expr_begin
= get_location ();
1879 id
= parse_identifier ();
1880 rollback (expr_begin
);
1881 initializer
= parse_statement_expression ();
1883 block
= new
Block (get_src (begin
));
1884 DataType variable_type
;
1885 if (accept (TokenType
.VAR
)) {
1886 variable_type
= null;
1887 id
= parse_identifier ();
1889 id
= parse_identifier ();
1890 expect (TokenType
.COLON
);
1891 variable_type
= parse_type ();
1894 DataType type_copy
= null;
1895 if (variable_type
!= null) {
1896 type_copy
= variable_type
.copy ();
1898 var local
= parse_local_variable (type_copy
, id
);
1900 block
.add_statement (new
DeclarationStatement (local
, local
.source_reference
));
1905 if (accept (TokenType
.TO
)) {
1906 /* create expression for condition and incrementing iterator */
1907 var to_begin
= get_location ();
1908 var to_src
= get_src (to_begin
);
1909 var left
= new
MemberAccess (null, id
, to_src
);
1910 var right
= parse_primary_expression ();
1912 condition
= new
BinaryExpression (BinaryOperator
.LESS_THAN_OR_EQUAL
, left
, right
, to_src
);
1914 iterator
= new
PostfixExpression (left
, true, to_src
);
1916 expect (TokenType
.DOWNTO
);
1917 var downto_begin
= get_location ();
1918 var downto_src
= get_src (downto_begin
);
1919 /* create expression for condition and decrementing iterator */
1920 var left
= new
MemberAccess (null, id
, downto_src
);
1921 var right
= parse_primary_expression ();
1923 condition
= new
BinaryExpression (BinaryOperator
.GREATER_THAN_OR_EQUAL
, left
, right
, downto_src
);
1925 iterator
= new
PostfixExpression (left
, false, downto_src
);
1928 if (!accept (TokenType
.EOL
)) {
1929 expect (TokenType
.DO
);
1932 var src
= get_src_com (begin
);
1933 var body
= parse_embedded_statement ();
1934 var stmt
= new
ForStatement (condition
, body
, src
);
1936 if (initializer
!= null) stmt
.add_initializer (initializer
);
1938 stmt
.add_iterator (iterator
);
1941 if (block
!= null) {
1942 block
.add_statement (stmt
);
1949 Statement
parse_foreach_statement () throws ParseError
{
1950 var begin
= get_location ();
1951 DataType type
= null;
1954 expect (TokenType
.FOR
);
1956 if (accept (TokenType
.VAR
)) {
1957 id
= parse_identifier ();
1959 id
= parse_identifier ();
1960 if (accept (TokenType
.COLON
)) {
1961 type
= parse_type ();
1965 expect (TokenType
.IN
);
1966 var collection
= parse_expression ();
1967 if (!accept (TokenType
.EOL
)) {
1968 expect (TokenType
.DO
);
1970 var src
= get_src_com (begin
);
1971 var body
= parse_embedded_statement ();
1972 return new
ForeachStatement (type
, id
, collection
, body
, src
);
1975 Statement
parse_break_statement () throws ParseError
{
1976 var begin
= get_location ();
1977 expect (TokenType
.BREAK
);
1978 expect_terminator ();
1979 return new
BreakStatement (get_src_com (begin
));
1982 Statement
parse_continue_statement () throws ParseError
{
1983 var begin
= get_location ();
1984 expect (TokenType
.CONTINUE
);
1985 expect_terminator ();
1986 return new
ContinueStatement (get_src_com (begin
));
1989 Statement
parse_return_statement () throws ParseError
{
1990 var begin
= get_location ();
1991 expect (TokenType
.RETURN
);
1992 Expression expr
= null;
1993 if (current () != TokenType
.SEMICOLON
&& current () != TokenType
.EOL
) {
1994 expr
= parse_expression ();
1996 expect_terminator ();
1997 return new
ReturnStatement (expr
, get_src_com (begin
));
2000 Statement
parse_throw_statement () throws ParseError
{
2001 var begin
= get_location ();
2002 expect (TokenType
.RAISE
);
2003 var expr
= parse_expression ();
2004 expect_terminator ();
2005 return new
ThrowStatement (expr
, get_src_com (begin
));
2008 Statement
parse_try_statement () throws ParseError
{
2009 var begin
= get_location ();
2010 expect (TokenType
.TRY
);
2011 expect (TokenType
.EOL
);
2012 var try_block
= parse_block ();
2013 Block finally_clause
= null;
2014 var catch_clauses
= new ArrayList
<CatchClause
> ();
2015 if (current () == TokenType
.EXCEPT
) {
2016 parse_catch_clauses (catch_clauses
);
2017 if (current () == TokenType
.FINALLY
) {
2018 finally_clause
= parse_finally_clause ();
2021 finally_clause
= parse_finally_clause ();
2023 var stmt
= new
TryStatement (try_block
, finally_clause
, get_src_com (begin
));
2024 foreach (CatchClause clause
in catch_clauses
) {
2025 stmt
.add_catch_clause (clause
);
2030 void parse_catch_clauses (Gee
.List
<CatchClause
> catch_clauses
) throws ParseError
{
2031 while (accept (TokenType
.EXCEPT
)) {
2032 var begin
= get_location ();
2033 DataType type
= null;
2035 if (!accept (TokenType
.EOL
)) {
2036 id
= parse_identifier ();
2037 expect (TokenType
.COLON
);
2038 type
= parse_type ();
2039 expect (TokenType
.EOL
);
2042 var block
= parse_block ();
2043 catch_clauses
.add (new
CatchClause (type
, id
, block
, get_src (begin
)));
2047 Block
parse_finally_clause () throws ParseError
{
2048 expect (TokenType
.FINALLY
);
2050 var block
= parse_block ();
2054 Statement
parse_lock_statement () throws ParseError
{
2055 var begin
= get_location ();
2056 expect (TokenType
.LOCK
);
2057 expect (TokenType
.OPEN_PARENS
);
2058 var expr
= parse_expression ();
2059 expect (TokenType
.CLOSE_PARENS
);
2060 var stmt
= parse_embedded_statement ();
2061 return new
LockStatement (expr
, stmt
, get_src_com (begin
));
2064 Statement
parse_delete_statement () throws ParseError
{
2065 var begin
= get_location ();
2066 expect (TokenType
.DELETE
);
2067 var expr
= parse_expression ();
2068 expect_terminator ();
2069 return new
DeleteStatement (expr
, get_src_com (begin
));
2072 Gee
.List
<Attribute
>?
parse_attributes () throws ParseError
{
2073 if (current () != TokenType
.OPEN_BRACKET
) {
2076 var attrs
= new ArrayList
<Attribute
> ();
2077 while (accept (TokenType
.OPEN_BRACKET
)) {
2079 var begin
= get_location ();
2080 string id
= parse_identifier ();
2081 var attr
= new
Attribute (id
, get_src (begin
));
2082 if (accept (TokenType
.OPEN_PARENS
)) {
2083 if (current () != TokenType
.CLOSE_PARENS
) {
2085 id
= parse_identifier ();
2086 expect (TokenType
.ASSIGN
);
2087 var expr
= parse_expression ();
2088 attr
.add_argument (id
, expr
);
2089 } while (accept (TokenType
.COMMA
));
2091 expect (TokenType
.CLOSE_PARENS
);
2094 } while (accept (TokenType
.COMMA
));
2095 expect (TokenType
.CLOSE_BRACKET
);
2097 expect (TokenType
.EOL
);
2102 void set_attributes (CodeNode node
, Gee
.List
<Attribute
>? attributes
) {
2103 if (attributes
!= null) {
2104 foreach (Attribute attr
in (Gee
.List
<Attribute
>) attributes
) {
2105 node
.attributes
.append (attr
);
2110 Symbol
parse_declaration (bool is_root
= false) throws ParseError
{
2111 comment
= scanner
.pop_comment ();
2112 var attrs
= parse_attributes ();
2114 switch (current ()) {
2115 case TokenType
.CONST
:
2116 return parse_constant_declaration (attrs
);
2117 case TokenType
.CONSTRUCT
:
2118 return parse_creation_method_declaration (attrs
);
2119 case TokenType
.CLASS
:
2120 return parse_class_declaration (attrs
);
2121 case TokenType
.INIT
:
2123 return parse_main_method_declaration (attrs
);
2125 return parse_constructor_declaration (attrs
);
2126 case TokenType
.DELEGATE
:
2127 return parse_delegate_declaration (attrs
);
2129 return parse_method_declaration (attrs
);
2130 case TokenType
.ENUM
:
2131 return parse_enum_declaration (attrs
);
2132 case TokenType
.ERRORDOMAIN
:
2133 return parse_errordomain_declaration (attrs
);
2134 case TokenType
.FINAL
:
2135 return parse_destructor_declaration (attrs
);
2136 case TokenType
.INTERFACE
:
2137 return parse_interface_declaration (attrs
);
2138 case TokenType
.NAMESPACE
:
2139 return parse_namespace_declaration (attrs
);
2140 case TokenType
.PROP
:
2141 return parse_property_declaration (attrs
);
2142 case TokenType
.EVENT
:
2143 return parse_signal_declaration (attrs
);
2144 case TokenType
.STRUCT
:
2145 return parse_struct_declaration (attrs
);
2147 var begin
= get_location ();
2148 while (current () != TokenType
.EOL
&& current () != TokenType
.SEMICOLON
&& current () != TokenType
.EOF
) {
2149 if (current () == TokenType
.COLON
) {
2151 return parse_field_declaration (attrs
);
2161 TokenType cur
= current ();
2162 TokenType pre
= tokens
[index
-1].type
;
2164 throw new ParseError
.SYNTAX (get_error ("expected declaration but got %s with previous %s".printf (cur
.to_string (), pre
.to_string())));
2167 void parse_declarations (Symbol parent
, bool root
= false) throws ParseError
{
2169 expect (TokenType
.INDENT
);
2171 while (current () != TokenType
.DEDENT
&& current () != TokenType
.EOF
) {
2173 if (parent is Namespace
) {
2174 parse_namespace_member ((Namespace
) parent
);
2175 } else if (parent is Class
) {
2176 parse_class_member ((Class
) parent
);
2177 } else if (parent is Struct
) {
2178 parse_struct_member ((Struct
) parent
);
2179 } else if (parent is Interface
) {
2180 parse_interface_member ((Interface
) parent
);
2182 } catch (ParseError e
) {
2186 if (r
== RecoveryState
.STATEMENT_BEGIN
) {
2192 if (r
== RecoveryState
.EOF
) {
2198 if (!accept (TokenType
.DEDENT
)) {
2199 // only report error if it's not a secondary error
2200 if (Report
.get_errors () == 0) {
2201 Report
.error (get_current_src (), "expected dedent");
2207 enum RecoveryState
{
2213 RecoveryState
recover () {
2214 while (current () != TokenType
.EOF
) {
2215 switch (current ()) {
2216 case TokenType
.CLASS
:
2217 case TokenType
.CONST
:
2218 case TokenType
.CONSTRUCT
:
2219 case TokenType
.INIT
:
2221 case TokenType
.DELEGATE
:
2222 case TokenType
.ENUM
:
2223 case TokenType
.ERRORDOMAIN
:
2224 case TokenType
.FINAL
:
2225 case TokenType
.INTERFACE
:
2226 case TokenType
.NAMESPACE
:
2227 case TokenType
.PROP
:
2228 case TokenType
.EVENT
:
2229 case TokenType
.STRUCT
:
2230 return RecoveryState
.DECLARATION_BEGIN
;
2231 case TokenType
.BREAK
:
2232 case TokenType
.CASE
:
2233 case TokenType
.CONTINUE
:
2234 case TokenType
.DELETE
:
2238 case TokenType
.LOCK
:
2239 case TokenType
.RETURN
:
2240 case TokenType
.RAISE
:
2243 case TokenType
.WHILE
:
2244 return RecoveryState
.STATEMENT_BEGIN
;
2250 return RecoveryState
.EOF
;
2253 Namespace
parse_namespace_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2254 var begin
= get_location ();
2255 expect (TokenType
.NAMESPACE
);
2256 var sym
= parse_symbol_name ();
2257 var ns
= new
Namespace (sym
.name
, get_src_com (begin
));
2258 set_attributes (ns
, attrs
);
2259 expect (TokenType
.EOL
);
2260 parse_declarations (ns
);
2264 void parse_namespace_member (Namespace ns
) throws ParseError
{
2266 var sym
= parse_declaration ((ns
== context
.root
));
2267 if (sym is Namespace
) {
2268 ns
.add_namespace ((Namespace
) sym
);
2269 } else if (sym is Class
) {
2270 ns
.add_class ((Class
) sym
);
2271 } else if (sym is Interface
) {
2272 ns
.add_interface ((Interface
) sym
);
2273 } else if (sym is Struct
) {
2274 ns
.add_struct ((Struct
) sym
);
2275 } else if (sym is Enum
) {
2276 ns
.add_enum ((Enum
) sym
);
2277 } else if (sym is ErrorDomain
) {
2278 ns
.add_error_domain ((ErrorDomain
) sym
);
2279 } else if (sym is Delegate
) {
2280 ns
.add_delegate ((Delegate
) sym
);
2281 } else if (sym is Method
) {
2282 var method
= (Method
) sym
;
2283 if (method
.binding
== MemberBinding
.INSTANCE
) {
2284 method
.binding
= MemberBinding
.STATIC
;
2286 ns
.add_method (method
);
2287 } else if (sym is Field
) {
2288 var field
= (Field
) sym
;
2289 if (field
.binding
== MemberBinding
.INSTANCE
) {
2290 field
.binding
= MemberBinding
.STATIC
;
2292 ns
.add_field (field
);
2293 } else if (sym is Constant
) {
2294 ns
.add_constant ((Constant
) sym
);
2296 Report
.error (sym
.source_reference
, "unexpected declaration in namespace");
2298 scanner
.source_file
.add_node (sym
);
2302 void add_uses_clause () throws ParseError
{
2303 var begin
= get_location ();
2304 var sym
= parse_symbol_name ();
2305 var ns_ref
= new
UsingDirective (sym
, get_src (begin
));
2307 scanner
.source_file
.add_using_directive (ns_ref
);
2310 void parse_using_directives () throws ParseError
{
2311 while (accept (TokenType
.USES
)) {
2312 if (accept_block ()) {
2313 expect (TokenType
.INDENT
);
2315 while (current () != TokenType
.DEDENT
&& current () != TokenType
.EOF
) {
2317 expect (TokenType
.EOL
);
2320 expect (TokenType
.DEDENT
);
2324 } while (accept (TokenType
.COMMA
));
2326 expect_terminator ();
2332 Symbol
parse_class_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2333 var begin
= get_location ();
2334 expect (TokenType
.CLASS
);
2336 var flags
= parse_type_declaration_modifiers ();
2338 var sym
= parse_symbol_name ();
2339 var type_param_list
= parse_type_parameter_list ();
2340 var base_types
= new ArrayList
<DataType
> ();
2341 if (accept (TokenType
.COLON
)) {
2342 base_types
.add (parse_type ());
2344 if (accept (TokenType
.IMPLEMENTS
)) {
2346 base_types
.add (parse_type ());
2347 } while (accept (TokenType
.COMMA
));
2351 accept (TokenType
.EOL
);
2353 var cl
= new
Class (sym
.name
, get_src_com (begin
));
2355 if (ModifierFlags
.PRIVATE
in flags
) {
2356 cl
.access
= SymbolAccessibility
.PRIVATE
;
2358 /* class must always be Public unless its name starts wtih underscore */
2359 if (sym
.name
[0] == '_') {
2360 cl
.access
= SymbolAccessibility
.PRIVATE
;
2362 cl
.access
= SymbolAccessibility
.PUBLIC
;
2366 if (ModifierFlags
.ABSTRACT
in flags
) {
2367 cl
.is_abstract
= true;
2369 set_attributes (cl
, attrs
);
2370 foreach (TypeParameter type_param
in type_param_list
) {
2371 cl
.add_type_parameter (type_param
);
2373 foreach (DataType base_type
in base_types
) {
2374 cl
.add_base_type (base_type
);
2377 class_name
= cl
.name
;
2379 parse_declarations (cl
);
2381 // ensure there is always a default construction method
2382 if (!scanner
.source_file
.external_package
2384 && cl
.default_construction_method
== null) {
2385 var m
= new
CreationMethod (cl
.name
, null, cl
.source_reference
);
2386 m
.binding
= MemberBinding
.STATIC
;
2387 m
.access
= SymbolAccessibility
.PUBLIC
;
2388 m
.body
= new
Block (cl
.source_reference
);
2393 while (sym
.inner
!= null) {
2395 var ns
= new
Namespace (sym
.name
, cl
.source_reference
);
2396 if (result is Namespace
) {
2397 ns
.add_namespace ((Namespace
) result
);
2399 ns
.add_class ((Class
) result
);
2400 scanner
.source_file
.add_node (result
);
2407 void parse_class_member (Class cl
) throws ParseError
{
2408 var sym
= parse_declaration ();
2410 cl
.add_class ((Class
) sym
);
2411 } else if (sym is Struct
) {
2412 cl
.add_struct ((Struct
) sym
);
2413 } else if (sym is Enum
) {
2414 cl
.add_enum ((Enum
) sym
);
2415 } else if (sym is Delegate
) {
2416 cl
.add_delegate ((Delegate
) sym
);
2417 } else if (sym is Method
) {
2418 cl
.add_method ((Method
) sym
);
2419 } else if (sym is Vala
.Signal
) {
2420 cl
.add_signal ((Vala
.Signal
) sym
);
2421 } else if (sym is Field
) {
2422 cl
.add_field ((Field
) sym
);
2423 } else if (sym is Constant
) {
2424 cl
.add_constant ((Constant
) sym
);
2425 } else if (sym is Property
) {
2426 cl
.add_property ((Property
) sym
);
2427 } else if (sym is Constructor
) {
2428 var c
= (Constructor
) sym
;
2429 if (c
.binding
== MemberBinding
.INSTANCE
) {
2431 } else if (c
.binding
== MemberBinding
.CLASS
) {
2432 cl
.class_constructor
= c
;
2434 cl
.static_constructor
= c
;
2436 } else if (sym is Destructor
) {
2437 cl
.destructor
= (Destructor
) sym
;
2439 Report
.error (sym
.source_reference
, "unexpected declaration in class");
2443 Constant
parse_constant_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2444 var begin
= get_location ();
2446 expect (TokenType
.CONST
);
2448 parse_member_declaration_modifiers ();
2450 string id
= parse_identifier ();
2451 expect (TokenType
.COLON
);
2452 var type
= parse_type (false);
2454 Expression initializer
= null;
2455 if (accept (TokenType
.ASSIGN
)) {
2456 initializer
= parse_variable_initializer ();
2458 expect_terminator ();
2460 // constant arrays don't own their element
2461 var array_type
= type as ArrayType
;
2462 if (array_type
!= null) {
2463 array_type
.element_type
.value_owned
= false;
2466 var c
= new
Constant (id
, type
, initializer
, get_src_com (begin
));
2467 c
.access
= get_access (id
);
2468 set_attributes (c
, attrs
);
2472 Field
parse_field_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2473 var begin
= get_location ();
2474 string id
= parse_identifier ();
2475 expect (TokenType
.COLON
);
2477 var flags
= parse_member_declaration_modifiers ();
2479 var type
= parse_type ();
2481 var f
= new
Field (id
, type
, null, get_src_com (begin
));
2483 if (ModifierFlags
.ABSTRACT
in flags
|| ModifierFlags
.VIRTUAL
in flags
|| ModifierFlags
.OVERRIDE
in flags
) {
2484 Report
.error (f
.source_reference
, "abstract, virtual, and override modifiers are not applicable to fields");
2487 if (ModifierFlags
.PRIVATE
in flags
) {
2488 f
.access
= SymbolAccessibility
.PRIVATE
;
2490 f
.access
= get_access (id
);
2493 set_attributes (f
, attrs
);
2495 if (accept (TokenType
.ASSIGN
)) {
2496 f
.initializer
= parse_expression ();
2499 if (ModifierFlags
.STATIC
in flags
) {
2500 f
.binding
= MemberBinding
.STATIC
;
2501 } else if (ModifierFlags
.CLASS
in flags
) {
2502 f
.binding
= MemberBinding
.CLASS
;
2505 expect_terminator ();
2510 InitializerList
parse_initializer () throws ParseError
{
2511 var begin
= get_location ();
2512 if (!accept (TokenType
.OPEN_PARENS
)) {
2513 expect (TokenType
.OPEN_BRACE
);
2515 var initializer
= new
InitializerList (get_src (begin
));
2516 if (current () != TokenType
.DEDENT
) {
2518 var init
= parse_variable_initializer ();
2519 initializer
.append (init
);
2520 } while (accept (TokenType
.COMMA
));
2522 if (!accept (TokenType
.CLOSE_PARENS
)) {
2523 expect (TokenType
.CLOSE_BRACE
);
2528 bool is_initializer () throws ParseError
{
2529 if (current () == TokenType
.OPEN_BRACE
) {
2534 if (current () == TokenType.OPEN_PARENS) {
2535 var begin = get_location ();
2536 var is_array = false;
2540 var expr = parse_expression ();
2541 is_array = (accept (TokenType.COMMA));
2553 Expression
parse_variable_initializer () throws ParseError
{
2554 if (is_initializer ()) {
2555 var expr
= parse_initializer ();
2558 var expr
= parse_expression ();
2564 Method
parse_main_method_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2566 var begin
= get_location ();
2567 DataType type
= new
VoidType ();
2568 expect (TokenType
.INIT
);
2570 var method
= new
Method (id
, type
, get_src_com (begin
));
2571 method
.access
= SymbolAccessibility
.PUBLIC
;
2573 set_attributes (method
, attrs
);
2575 method
.binding
= MemberBinding
.STATIC
;
2577 var sym
= new
UnresolvedSymbol (null, "string", get_src (begin
));
2578 type
= new UnresolvedType
.from_symbol (sym
, get_src (begin
));
2579 type
.value_owned
= true;
2580 type
= new
ArrayType (type
, 1, get_src (begin
));
2581 type
.nullable
= false;
2583 var param
= new
FormalParameter ("args", type
, get_src (begin
));
2584 method
.add_parameter (param
);
2587 expect (TokenType
.EOL
);
2589 if (accept_block ()) {
2590 method
.body
= parse_block ();
2596 Method
parse_method_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2597 var begin
= get_location ();
2598 DataType type
= new
VoidType ();
2599 expect (TokenType
.DEF
);
2600 var flags
= parse_member_declaration_modifiers ();
2602 string id
= parse_identifier ();
2604 var params
= new ArrayList
<FormalParameter
> ();
2605 expect (TokenType
.OPEN_PARENS
);
2607 if (current () != TokenType
.CLOSE_PARENS
) {
2609 var param
= parse_parameter ();
2611 } while (accept (TokenType
.COMMA
));
2614 expect (TokenType
.CLOSE_PARENS
);
2617 /* deal with return value */
2618 if (accept (TokenType
.COLON
)) {
2619 type
= parse_type ();
2620 parse_type_parameter_list ();
2624 var method
= new
Method (id
, type
, get_src_com (begin
));
2625 if (ModifierFlags
.PRIVATE
in flags
) {
2626 method
.access
= SymbolAccessibility
.PRIVATE
;
2628 method
.access
= get_access (id
);
2632 set_attributes (method
, attrs
);
2634 foreach (FormalParameter param
in params
) {
2635 method
.add_parameter (param
);
2638 if (accept (TokenType
.RAISES
)) {
2640 method
.add_error_type (parse_type ());
2641 } while (accept (TokenType
.COMMA
));
2645 if (ModifierFlags
.STATIC
in flags
|| id
== "main") {
2646 method
.binding
= MemberBinding
.STATIC
;
2648 if (ModifierFlags
.ABSTRACT
in flags
) {
2649 method
.is_abstract
= true;
2651 if (ModifierFlags
.VIRTUAL
in flags
) {
2652 method
.is_virtual
= true;
2654 if (ModifierFlags
.OVERRIDE
in flags
) {
2655 method
.overrides
= true;
2657 if (ModifierFlags
.INLINE
in flags
) {
2658 method
.is_inline
= true;
2661 expect (TokenType
.EOL
);
2663 var body_location
= get_location ();
2666 /* "requires" and "ensures" if present will be at start of the method body */
2667 if (accept (TokenType
.INDENT
)) {
2668 if (accept (TokenType
.REQUIRES
)) {
2670 if (accept (TokenType
.EOL
) && accept (TokenType
.INDENT
)) {
2671 while (current() != TokenType
.DEDENT
) {
2672 method
.add_precondition (parse_expression ());
2673 expect (TokenType
.EOL
);
2676 expect (TokenType
.DEDENT
);
2677 accept_terminator ();
2680 method
.add_precondition (parse_expression ());
2681 expect_terminator ();
2687 if (accept (TokenType
.ENSURES
)) {
2688 if (accept (TokenType
.EOL
) && accept (TokenType
.INDENT
)) {
2689 while (current() != TokenType
.DEDENT
) {
2690 method
.add_postcondition (parse_expression ());
2691 expect (TokenType
.EOL
);
2694 expect (TokenType
.DEDENT
);
2695 accept_terminator ();
2697 method
.add_postcondition (parse_expression ());
2698 expect_terminator ();
2703 rollback (body_location
);
2706 if (accept_block ()) {
2707 method
.body
= parse_block ();
2712 Property
parse_property_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2713 var begin
= get_location ();
2714 var readonly = false;
2716 expect (TokenType
.PROP
);
2718 var flags
= parse_member_declaration_modifiers ();
2720 readonly = accept (TokenType
.READONLY
);
2722 string id
= parse_identifier ();
2723 expect (TokenType
.COLON
);
2725 bool is_weak
= accept (TokenType
.WEAK
);
2726 var type
= parse_type (false);
2728 var prop
= new
Property (id
, type
, null, null, get_src_com (begin
));
2729 if (ModifierFlags
.PRIVATE
in flags
) {
2730 prop
.access
= SymbolAccessibility
.PRIVATE
;
2732 prop
.access
= get_access (id
);
2735 set_attributes (prop
, attrs
);
2736 if (ModifierFlags
.ABSTRACT
in flags
) {
2737 prop
.is_abstract
= true;
2739 if (ModifierFlags
.VIRTUAL
in flags
) {
2740 prop
.is_virtual
= true;
2742 if (ModifierFlags
.OVERRIDE
in flags
) {
2743 prop
.overrides
= true;
2746 if (accept (TokenType
.ASSIGN
)) {
2747 prop
.default_expression
= parse_expression ();
2751 if (accept_block ()) {
2752 expect (TokenType
.INDENT
);
2753 while (current () != TokenType
.DEDENT
) {
2754 var accessor_begin
= get_location ();
2755 parse_attributes ();
2756 if (accept (TokenType
.GET
)) {
2757 if (prop
.get_accessor
!= null) {
2758 throw new ParseError
.SYNTAX (get_error ("property get accessor already defined"));
2761 if (accept_block ()) {
2762 block
= parse_block ();
2764 prop
.get_accessor
= new
PropertyAccessor (true, false, false, block
, get_src (accessor_begin
));
2765 prop
.get_accessor
.access
= SymbolAccessibility
.PUBLIC
;
2767 bool _construct
= false;
2768 if (accept (TokenType
.SET
)) {
2770 throw new ParseError
.SYNTAX (get_error ("set block not allowed for a read only property"));
2772 _construct
= accept (TokenType
.CONSTRUCT
);
2773 } else if (accept (TokenType
.CONSTRUCT
)) {
2775 } else if (!accept (TokenType
.EOL
)) {
2776 throw new ParseError
.SYNTAX (get_error ("expected get, set, or construct"));
2779 if (prop
.set_accessor
!= null) {
2780 throw new ParseError
.SYNTAX (get_error ("property set accessor already defined"));
2784 if (accept_block ()) {
2785 block
= parse_block ();
2787 prop
.set_accessor
= new
PropertyAccessor (false, !readonly, _construct
, block
, get_src (accessor_begin
));
2788 prop
.set_accessor
.access
= SymbolAccessibility
.PUBLIC
;
2791 accept (TokenType
.EOL
);
2792 expect (TokenType
.DEDENT
);
2794 prop
.get_accessor
= new
PropertyAccessor (true, false, false, null, get_src (begin
));
2795 prop
.get_accessor
.access
= SymbolAccessibility
.PUBLIC
;
2798 prop
.set_accessor
= new
PropertyAccessor (false, true, false, null, get_src (begin
));
2799 prop
.set_accessor
.access
= SymbolAccessibility
.PUBLIC
;
2803 expect_terminator ();
2806 if (!prop
.is_abstract
&& !scanner
.source_file
.external_package
) {
2807 var needs_var
= (readonly && (prop
.get_accessor
!= null && prop
.get_accessor
.body
== null));
2810 needs_var
= (prop
.get_accessor
!= null && prop
.get_accessor
.body
== null) || (prop
.set_accessor
!= null && prop
.set_accessor
.body
== null);
2814 /* automatic property accessor body generation */
2815 var field_type
= prop
.property_type
.copy ();
2816 field_type
.value_owned
= !is_weak
;
2817 prop
.field
= new
Field ("_%s".printf (prop
.name
), field_type
, prop
.default_expression
, prop
.source_reference
);
2818 prop
.field
.access
= SymbolAccessibility
.PRIVATE
;
2825 Vala
.Signal
parse_signal_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2826 var begin
= get_location ();
2829 expect (TokenType
.EVENT
);
2830 var flags
= parse_member_declaration_modifiers ();
2831 string id
= parse_identifier ();
2834 var params
= new ArrayList
<FormalParameter
> ();
2836 expect (TokenType
.OPEN_PARENS
);
2837 if (current () != TokenType
.CLOSE_PARENS
) {
2839 var param
= parse_parameter ();
2841 } while (accept (TokenType
.COMMA
));
2843 expect (TokenType
.CLOSE_PARENS
);
2845 if (accept (TokenType
.COLON
)) {
2846 type
= parse_type ();
2848 type
= new
VoidType ();
2851 var sig
= new Vala
.Signal (id
, type
, get_src_com (begin
));
2852 if (ModifierFlags
.PRIVATE
in flags
) {
2853 sig
.access
= SymbolAccessibility
.PRIVATE
;
2855 sig
.access
= get_access (id
);
2858 if (ModifierFlags
.VIRTUAL
in flags
) {
2859 sig
.is_virtual
= true;
2862 set_attributes (sig
, attrs
);
2864 foreach (FormalParameter formal_param
in params
) {
2865 sig
.add_parameter (formal_param
);
2868 expect_terminator ();
2872 Constructor
parse_constructor_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2873 var begin
= get_location ();
2875 expect (TokenType
.INIT
);
2876 var flags
= parse_member_declaration_modifiers ();
2878 var c
= new
Constructor (get_src_com (begin
));
2879 if (ModifierFlags
.STATIC
in flags
) {
2880 c
.binding
= MemberBinding
.STATIC
;
2881 } else if (ModifierFlags
.CLASS
in flags
) {
2882 c
.binding
= MemberBinding
.CLASS
;
2886 c
.body
= parse_block ();
2890 Destructor
parse_destructor_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2891 var begin
= get_location ();
2892 expect (TokenType
.FINAL
);
2893 var d
= new
Destructor (get_src_com (begin
));
2895 d
.body
= parse_block ();
2899 Symbol
parse_struct_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2900 var begin
= get_location ();
2902 expect (TokenType
.STRUCT
);
2903 var flags
= parse_type_declaration_modifiers ();
2904 var sym
= parse_symbol_name ();
2905 var type_param_list
= parse_type_parameter_list ();
2906 var base_types
= new ArrayList
<DataType
> ();
2907 if (accept (TokenType
.COLON
)) {
2909 base_types
.add (parse_type ());
2910 } while (accept (TokenType
.COMMA
));
2912 var st
= new
Struct (sym
.name
, get_src_com (begin
));
2913 if (ModifierFlags
.PRIVATE
in flags
) {
2914 st
.access
= SymbolAccessibility
.PRIVATE
;
2916 st
.access
= get_access (sym
.name
);
2918 set_attributes (st
, attrs
);
2919 foreach (TypeParameter type_param
in type_param_list
) {
2920 st
.add_type_parameter (type_param
);
2922 foreach (DataType base_type
in base_types
) {
2923 st
.add_base_type (base_type
);
2926 expect (TokenType
.EOL
);
2928 parse_declarations (st
);
2931 while (sym
.inner
!= null) {
2933 var ns
= new
Namespace (sym
.name
, st
.source_reference
);
2934 if (result is Namespace
) {
2935 ns
.add_namespace ((Namespace
) result
);
2937 ns
.add_struct ((Struct
) result
);
2938 scanner
.source_file
.add_node (result
);
2945 void parse_struct_member (Struct st
) throws ParseError
{
2946 var sym
= parse_declaration ();
2947 if (sym is Method
) {
2948 st
.add_method ((Method
) sym
);
2949 } else if (sym is Field
) {
2950 st
.add_field ((Field
) sym
);
2951 } else if (sym is Constant
) {
2952 st
.add_constant ((Constant
) sym
);
2954 Report
.error (sym
.source_reference
, "unexpected declaration in struct");
2958 Symbol
parse_interface_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2959 var begin
= get_location ();
2961 expect (TokenType
.INTERFACE
);
2962 var flags
= parse_type_declaration_modifiers ();
2963 var sym
= parse_symbol_name ();
2964 var type_param_list
= parse_type_parameter_list ();
2965 var base_types
= new ArrayList
<DataType
> ();
2966 if (accept (TokenType
.COLON
)) {
2968 base_types
.add (parse_type ());
2969 } while (accept (TokenType
.COMMA
));
2971 var iface
= new
Interface (sym
.name
, get_src_com (begin
));
2972 if (ModifierFlags
.PRIVATE
in flags
) {
2973 iface
.access
= SymbolAccessibility
.PRIVATE
;
2975 iface
.access
= get_access (sym
.name
);
2978 set_attributes (iface
, attrs
);
2979 foreach (TypeParameter type_param
in type_param_list
) {
2980 iface
.add_type_parameter (type_param
);
2982 foreach (DataType base_type
in base_types
) {
2983 iface
.add_prerequisite (base_type
);
2987 expect (TokenType
.EOL
);
2989 parse_declarations (iface
);
2992 Symbol result
= iface
;
2993 while (sym
.inner
!= null) {
2995 var ns
= new
Namespace (sym
.name
, iface
.source_reference
);
2996 if (result is Namespace
) {
2997 ns
.add_namespace ((Namespace
) result
);
2999 ns
.add_interface ((Interface
) result
);
3000 scanner
.source_file
.add_node (result
);
3007 void parse_interface_member (Interface iface
) throws ParseError
{
3008 var sym
= parse_declaration ();
3010 iface
.add_class ((Class
) sym
);
3011 } else if (sym is Struct
) {
3012 iface
.add_struct ((Struct
) sym
);
3013 } else if (sym is Enum
) {
3014 iface
.add_enum ((Enum
) sym
);
3015 } else if (sym is Delegate
) {
3016 iface
.add_delegate ((Delegate
) sym
);
3017 } else if (sym is Method
) {
3018 iface
.add_method ((Method
) sym
);
3019 } else if (sym is Vala
.Signal
) {
3020 iface
.add_signal ((Vala
.Signal
) sym
);
3021 } else if (sym is Field
) {
3022 iface
.add_field ((Field
) sym
);
3023 } else if (sym is Property
) {
3024 iface
.add_property ((Property
) sym
);
3026 Report
.error (sym
.source_reference
, "unexpected declaration in interface");
3030 Symbol
parse_enum_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
3031 var begin
= get_location ();
3032 expect (TokenType
.ENUM
);
3033 var flags
= parse_type_declaration_modifiers ();
3035 var sym
= parse_symbol_name ();
3036 var en
= new
Enum (sym
.name
, get_src_com (begin
));
3037 if (ModifierFlags
.PRIVATE
in flags
) {
3038 en
.access
= SymbolAccessibility
.PRIVATE
;
3040 en
.access
= get_access (sym
.name
);
3042 set_attributes (en
, attrs
);
3044 expect (TokenType
.EOL
);
3045 expect (TokenType
.INDENT
);
3047 if (current () == TokenType
.DEDENT
) {
3048 // allow trailing comma
3051 var value_attrs
= parse_attributes ();
3052 var value_begin
= get_location ();
3053 string id
= parse_identifier ();
3055 var ev
= new
EnumValue (id
, get_src (value_begin
));
3056 set_attributes (ev
, value_attrs
);
3058 if (accept (TokenType
.ASSIGN
)) {
3059 ev
.value
= parse_expression ();
3062 expect (TokenType
.EOL
);
3065 expect (TokenType
.DEDENT
);
3068 while (sym
.inner
!= null) {
3070 var ns
= new
Namespace (sym
.name
, en
.source_reference
);
3071 if (result is Namespace
) {
3072 ns
.add_namespace ((Namespace
) result
);
3074 ns
.add_enum ((Enum
) result
);
3075 scanner
.source_file
.add_node (result
);
3082 Symbol
parse_errordomain_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
3083 var begin
= get_location ();
3084 expect (TokenType
.ERRORDOMAIN
);
3085 var flags
= parse_type_declaration_modifiers ();
3087 var sym
= parse_symbol_name ();
3088 var ed
= new
ErrorDomain (sym
.name
, get_src_com (begin
));
3089 if (ModifierFlags
.PRIVATE
in flags
) {
3090 ed
.access
= SymbolAccessibility
.PRIVATE
;
3092 ed
.access
= get_access (sym
.name
);
3095 set_attributes (ed
, attrs
);
3097 expect (TokenType
.EOL
);
3098 expect (TokenType
.INDENT
);
3101 if (current () == TokenType
.DEDENT
) {
3102 // allow trailing comma
3105 var code_attrs
= parse_attributes ();
3106 string id
= parse_identifier ();
3108 var ec
= new
ErrorCode (id
);
3109 set_attributes (ec
, code_attrs
);
3110 if (accept (TokenType
.ASSIGN
)) {
3111 ec
.value
= parse_expression ();
3114 accept (TokenType
.EOL
);
3118 expect (TokenType
.DEDENT
);
3121 while (sym
.inner
!= null) {
3123 var ns
= new
Namespace (sym
.name
, ed
.source_reference
);
3125 if (result is Namespace
) {
3126 ns
.add_namespace ((Namespace
) result
);
3128 ns
.add_error_domain ((ErrorDomain
) result
);
3129 scanner
.source_file
.add_node (result
);
3136 ModifierFlags
parse_type_declaration_modifiers () {
3137 ModifierFlags flags
= 0;
3139 switch (current ()) {
3140 case TokenType
.ABSTRACT
:
3142 flags
|= ModifierFlags
.ABSTRACT
;
3145 case TokenType
.EXTERN
:
3147 flags
|= ModifierFlags
.EXTERN
;
3150 case TokenType
.STATIC
:
3152 flags
|= ModifierFlags
.STATIC
;
3155 case TokenType
.PRIVATE
:
3157 flags
|= ModifierFlags
.PRIVATE
;
3166 ModifierFlags
parse_member_declaration_modifiers () {
3167 ModifierFlags flags
= 0;
3169 switch (current ()) {
3170 case TokenType
.ABSTRACT
:
3172 flags
|= ModifierFlags
.ABSTRACT
;
3174 case TokenType
.CLASS
:
3176 flags
|= ModifierFlags
.CLASS
;
3178 case TokenType
.EXTERN
:
3180 flags
|= ModifierFlags
.EXTERN
;
3182 case TokenType
.INLINE
:
3184 flags
|= ModifierFlags
.INLINE
;
3186 case TokenType
.OVERRIDE
:
3188 flags
|= ModifierFlags
.OVERRIDE
;
3190 case TokenType
.STATIC
:
3192 flags
|= ModifierFlags
.STATIC
;
3194 case TokenType
.VIRTUAL
:
3196 flags
|= ModifierFlags
.VIRTUAL
;
3198 case TokenType
.PRIVATE
:
3200 flags
|= ModifierFlags
.PRIVATE
;
3208 FormalParameter
parse_parameter () throws ParseError
{
3209 var attrs
= parse_attributes ();
3210 var begin
= get_location ();
3211 if (accept (TokenType
.ELLIPSIS
)) {
3213 return new FormalParameter
.with_ellipsis (get_src (begin
));
3216 var direction
= ParameterDirection
.IN
;
3217 if (accept (TokenType
.OUT
)) {
3218 direction
= ParameterDirection
.OUT
;
3219 } else if (accept (TokenType
.REF
)) {
3220 direction
= ParameterDirection
.REF
;
3223 string id
= parse_identifier ();
3225 expect (TokenType
.COLON
);
3228 if (direction
== ParameterDirection
.IN
) {
3229 type
= parse_type (false);
3231 type
= parse_type (true);
3234 var param
= new
FormalParameter (id
, type
, get_src (begin
));
3235 set_attributes (param
, attrs
);
3236 param
.direction
= direction
;
3237 param
.construct_parameter
= false;
3238 if (accept (TokenType
.ASSIGN
)) {
3239 param
.default_expression
= parse_expression ();
3244 CreationMethod
parse_creation_method_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
3245 var begin
= get_location ();
3246 CreationMethod method
;
3248 expect (TokenType
.CONSTRUCT
);
3250 parse_member_declaration_modifiers ();
3253 if (accept (TokenType
.OPEN_PARENS
)) {
3254 /* create default name using class name */
3255 method
= new
CreationMethod (class_name
, null, get_src_com (begin
));
3257 var sym
= parse_symbol_name ();
3258 if (sym
.inner
== null) {
3260 if (sym
.name
!= class_name
) {
3261 method
= new
CreationMethod (class_name
, sym
.name
, get_src_com (begin
));
3263 method
= new
CreationMethod (sym
.name
, null, get_src_com (begin
));
3266 method
= new
CreationMethod (sym
.inner
.name
, sym
.name
, get_src_com (begin
));
3268 expect (TokenType
.OPEN_PARENS
);
3272 if (current () != TokenType
.CLOSE_PARENS
) {
3274 var param
= parse_parameter ();
3275 method
.add_parameter (param
);
3276 } while (accept (TokenType
.COMMA
));
3278 expect (TokenType
.CLOSE_PARENS
);
3279 if (accept (TokenType
.RAISES
)) {
3281 method
.add_error_type (parse_type ());
3282 } while (accept (TokenType
.COMMA
));
3284 method
.access
= SymbolAccessibility
.PUBLIC
;
3285 set_attributes (method
, attrs
);
3286 method
.binding
= MemberBinding
.STATIC
;
3288 if (accept_block ()) {
3289 method
.body
= parse_block ();
3295 Symbol
parse_delegate_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
3296 var begin
= get_location ();
3299 expect (TokenType
.DELEGATE
);
3301 var flags
= parse_member_declaration_modifiers ();
3303 var sym
= parse_symbol_name ();
3305 var type_param_list
= parse_type_parameter_list ();
3308 var params
= new ArrayList
<FormalParameter
> ();
3310 expect (TokenType
.OPEN_PARENS
);
3311 if (current () != TokenType
.CLOSE_PARENS
) {
3313 var param
= parse_parameter ();
3315 } while (accept (TokenType
.COMMA
));
3317 expect (TokenType
.CLOSE_PARENS
);
3319 if (accept (TokenType
.COLON
)) {
3320 type
= parse_type ();
3323 type
= new
VoidType ();
3326 if (accept (TokenType
.RAISES
)) {
3329 } while (accept (TokenType
.COMMA
));
3332 expect_terminator ();
3334 var d
= new
Delegate (sym
.name
, type
, get_src_com (begin
));
3335 if (ModifierFlags
.PRIVATE
in flags
) {
3336 d
.access
= SymbolAccessibility
.PRIVATE
;
3338 d
.access
= get_access (sym
.name
);
3341 set_attributes (d
, attrs
);
3343 foreach (TypeParameter type_param
in type_param_list
) {
3344 d
.add_type_parameter (type_param
);
3347 foreach (FormalParameter formal_param
in params
) {
3348 d
.add_parameter (formal_param
);
3351 if (!(ModifierFlags
.STATIC
in flags
)) {
3352 d
.has_target
= true;
3357 while (sym
.inner
!= null) {
3359 var ns
= new
Namespace (sym
.name
, d
.source_reference
);
3361 if (result is Namespace
) {
3362 ns
.add_namespace ((Namespace
) result
);
3364 ns
.add_delegate ((Delegate
) result
);
3365 scanner
.source_file
.add_node (result
);
3372 Gee
.List
<TypeParameter
> parse_type_parameter_list () throws ParseError
{
3373 var list
= new ArrayList
<TypeParameter
> ();
3374 if (accept (TokenType
.OF
)) {
3376 var begin
= get_location ();
3377 string id
= parse_identifier ();
3378 list
.add (new
TypeParameter (id
, get_src (begin
)));
3379 } while (accept (TokenType
.COMMA
));
3385 void skip_type_argument_list () throws ParseError
{
3386 if (accept (TokenType
.OF
)) {
3389 } while (accept (TokenType
.COMMA
));
3393 // try to parse type argument list
3394 Gee
.List
<DataType
>?
parse_type_argument_list (bool maybe_expression
) throws ParseError
{
3395 var begin
= get_location ();
3396 if (accept (TokenType
.OF
)) {
3397 var list
= new ArrayList
<DataType
> ();
3399 switch (current ()) {
3400 case TokenType
.VOID
:
3401 case TokenType
.DYNAMIC
:
3402 case TokenType
.WEAK
:
3403 case TokenType
.IDENTIFIER
:
3404 var type
= parse_type ();
3412 } while (accept (TokenType
.COMMA
));
3419 MemberAccess
parse_member_name () throws ParseError
{
3420 var begin
= get_location ();
3421 MemberAccess expr
= null;
3423 string id
= parse_identifier ();
3424 Gee
.List
<DataType
> type_arg_list
= parse_type_argument_list (false);
3425 expr
= new
MemberAccess (expr
, id
, get_src (begin
));
3426 if (type_arg_list
!= null) {
3427 foreach (DataType type_arg
in type_arg_list
) {
3428 expr
.add_type_argument (type_arg
);
3431 } while (accept (TokenType
.DOT
));