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 expect (TokenType
.OPEN_PARENS
);
623 var expr_list
= new ArrayList
<Expression
> ();
624 if (current () != TokenType
.CLOSE_PARENS
) {
626 expr_list
.add (parse_expression ());
627 } while (accept (TokenType
.COMMA
));
629 expect (TokenType
.CLOSE_PARENS
);
630 if (expr_list
.size
!= 1) {
631 var tuple
= new
Tuple ();
632 foreach (Expression expr
in expr_list
) {
633 tuple
.add_expression (expr
);
637 return expr_list
.get (0);
640 Expression
parse_member_access (SourceLocation begin
, Expression inner
) throws ParseError
{
641 expect (TokenType
.DOT
);
642 string id
= parse_identifier ();
643 Gee
.List
<DataType
> type_arg_list
= parse_type_argument_list (true);
644 var expr
= new
MemberAccess (inner
, id
, get_src (begin
));
645 if (type_arg_list
!= null) {
646 foreach (DataType type_arg
in type_arg_list
) {
647 expr
.add_type_argument (type_arg
);
653 Expression
parse_pointer_member_access (SourceLocation begin
, Expression inner
) throws ParseError
{
654 expect (TokenType
.OP_PTR
);
655 string id
= parse_identifier ();
656 Gee
.List
<DataType
> type_arg_list
= parse_type_argument_list (true);
657 var expr
= new MemberAccess
.pointer (inner
, id
, get_src (begin
));
658 if (type_arg_list
!= null) {
659 foreach (DataType type_arg
in type_arg_list
) {
660 expr
.add_type_argument (type_arg
);
667 Gee
.List
<Expression
> parse_print_argument_list () throws ParseError
{
668 var list
= new ArrayList
<Expression
> ();
670 var begin
= get_location ();
672 if (current () != TokenType
.CLOSE_PARENS
) {
674 var p_expr
= parse_expression ();
678 if (p_expr
!= null) {
681 if (p_expr is StringLiteral
) {
682 var s_exp
= (StringLiteral
) p_expr
;
683 var len
= s_exp
.value
.size ();
686 var st
= s_exp
.value
.ndup (len
-1);
691 var rhs
= new
StringLiteral (s
, get_src (begin
));
692 p_expr
= new
BinaryExpression (BinaryOperator
.PLUS
, p_expr
, rhs
, get_src (begin
));
699 } while (accept (TokenType
.COMMA
));
704 Expression
parse_print_expression () throws ParseError
{
705 var begin
= get_location ();
707 expect (TokenType
.PRINT
);
708 accept (TokenType
.OPEN_PARENS
);
710 var expr
= new
MemberAccess (null, "print", get_src (begin
));
712 var arg_list
= parse_print_argument_list ();
714 accept (TokenType
.CLOSE_PARENS
);
716 var print_expr
= new
MethodCall (expr
, get_src (begin
));
718 foreach (Expression arg
in arg_list
) {
719 print_expr
.add_argument (arg
);
726 Expression
parse_assert_expression () throws ParseError
{
727 var begin
= get_location ();
729 expect (TokenType
.ASSERT
);
730 accept (TokenType
.OPEN_PARENS
);
732 var expr
= new
MemberAccess (null, "assert", get_src (begin
));
734 var arg_list
= parse_argument_list ();
736 accept (TokenType
.CLOSE_PARENS
);
738 var assert_expr
= new
MethodCall (expr
, get_src (begin
));
740 foreach (Expression arg
in arg_list
) {
741 assert_expr
.add_argument (arg
);
748 Expression
parse_method_call (SourceLocation begin
, Expression inner
) throws ParseError
{
749 expect (TokenType
.OPEN_PARENS
);
750 var arg_list
= parse_argument_list ();
751 expect (TokenType
.CLOSE_PARENS
);
752 var init_list
= parse_object_initializer ();
754 if (init_list
.size
> 0 && inner is MemberAccess
) {
755 // struct creation expression
756 var member
= (MemberAccess
) inner
;
757 member
.creation_member
= true;
759 var expr
= new
ObjectCreationExpression (member
, get_src (begin
));
760 expr
.struct_creation
= true;
761 foreach (Expression arg
in arg_list
) {
762 expr
.add_argument (arg
);
764 foreach (MemberInitializer initializer
in init_list
) {
765 expr
.add_member_initializer (initializer
);
769 var expr
= new
MethodCall (inner
, get_src (begin
));
770 foreach (Expression arg
in arg_list
) {
771 expr
.add_argument (arg
);
777 Expression
parse_element_access (SourceLocation begin
, Expression inner
) throws ParseError
{
778 expect (TokenType
.OPEN_BRACKET
);
779 var index_list
= parse_expression_list ();
780 expect (TokenType
.CLOSE_BRACKET
);
782 var expr
= new
ElementAccess (inner
, get_src (begin
));
783 foreach (Expression index
in index_list
) {
784 expr
.append_index (index
);
789 Gee
.List
<Expression
> parse_expression_list () throws ParseError
{
790 var list
= new ArrayList
<Expression
> ();
792 list
.add (parse_expression ());
793 } while (accept (TokenType
.COMMA
));
797 Expression
parse_this_access () throws ParseError
{
798 var begin
= get_location ();
799 expect (TokenType
.THIS
);
800 return new
MemberAccess (null, "this", get_src (begin
));
803 Expression
parse_base_access () throws ParseError
{
804 var begin
= get_location ();
805 expect (TokenType
.SUPER
);
806 return new
BaseAccess (get_src (begin
));
809 Expression
parse_post_increment_expression (SourceLocation begin
, Expression inner
) throws ParseError
{
810 expect (TokenType
.OP_INC
);
811 return new
PostfixExpression (inner
, true, get_src (begin
));
814 Expression
parse_post_decrement_expression (SourceLocation begin
, Expression inner
) throws ParseError
{
815 expect (TokenType
.OP_DEC
);
816 return new
PostfixExpression (inner
, false, get_src (begin
));
819 Expression
parse_object_or_array_creation_expression () throws ParseError
{
820 var begin
= get_location ();
821 expect (TokenType
.NEW
);
823 if (accept (TokenType
.ARRAY
)) {
824 expect (TokenType
.OF
);
825 var m
= parse_member_name ();
826 var expr
= parse_array_creation_expression (begin
, m
);
830 if (accept (TokenType
.LIST
)) {
831 expect (TokenType
.OF
);
832 var m
= parse_member_name ();
833 var expr
= parse_list_creation_expression (begin
, m
);
837 if (accept (TokenType
.DICT
)) {
838 expect (TokenType
.OF
);
839 var m1
= parse_member_name ();
840 expect (TokenType
.COMMA
);
841 var m2
= parse_member_name ();
842 var expr
= parse_dict_creation_expression (begin
, m1
, m2
);
847 var member
= parse_member_name ();
848 var expr
= parse_object_creation_expression (begin
, member
);
853 Expression
parse_object_creation_expression (SourceLocation begin
, MemberAccess member
) throws ParseError
{
854 member
.creation_member
= true;
855 Gee
.List
<Expression
> arg_list
;
856 if (accept (TokenType
.OPEN_PARENS
)) {
857 arg_list
= parse_argument_list ();
858 expect (TokenType
.CLOSE_PARENS
);
860 arg_list
= new ArrayList
<Expression
> ();
863 var init_list
= parse_object_initializer ();
865 var expr
= new
ObjectCreationExpression (member
, get_src (begin
));
866 foreach (Expression arg
in arg_list
) {
867 expr
.add_argument (arg
);
869 foreach (MemberInitializer initializer
in init_list
) {
870 expr
.add_member_initializer (initializer
);
875 Expression
parse_array_creation_expression (SourceLocation begin
, MemberAccess member
) throws ParseError
{
876 bool size_specified
= false;
877 Gee
.List
<Expression
> size_specifier_list
= null;
879 DataType element_type
= UnresolvedType
.new_from_expression (member
);
881 var has_bracket
= accept (TokenType
.OPEN_BRACKET
);
885 // array of arrays: new T[][42]
886 element_type
= new
ArrayType (element_type
, size_specifier_list
.size
, element_type
.source_reference
);
891 size_specifier_list
= new ArrayList
<Expression
> ();
893 Expression size
= null;
894 if (has_bracket
&& current () != TokenType
.CLOSE_BRACKET
&& current () != TokenType
.COMMA
) {
895 size
= parse_expression ();
896 size_specified
= true;
898 size_specifier_list
.add (size
);
899 } while (accept (TokenType
.COMMA
));
902 expect (TokenType
.CLOSE_BRACKET
);
904 } while (accept (TokenType
.OPEN_BRACKET
));
906 InitializerList initializer
= null;
907 if (accept (TokenType
.ASSIGN
)) {
909 initializer
= parse_initializer ();
911 var expr
= new
ArrayCreationExpression (element_type
, size_specifier_list
.size
, initializer
, get_src (begin
));
912 if (size_specified
) {
913 foreach (Expression size
in size_specifier_list
) {
914 expr
.append_size (size
);
921 Expression
parse_list_creation_expression (SourceLocation begin
, MemberAccess member
) throws ParseError
{
923 DataType element_type
= UnresolvedType
.new_from_expression (member
);
924 MemberAccess list_member
= null, parent_member
= null;
926 parent_member
= new
MemberAccess (null, "Gee", get_src (begin
));
927 list_member
= new
MemberAccess (parent_member
, "ArrayList", get_src (begin
));
928 list_member
.add_type_argument (element_type
);
930 list_member
.creation_member
= true;
932 var expr
= new
ObjectCreationExpression (list_member
, get_src (begin
));
934 if (member
.member_name
== "string") {
935 parent_member
= new
MemberAccess (null, "GLib", get_src (begin
));
936 expr
.add_argument (new
MemberAccess (parent_member
, "str_equal", get_src (begin
)));
938 } else if (member
.member_name
== "int") {
939 parent_member
= new
MemberAccess (null, "GLib", get_src (begin
));
940 expr
.add_argument (new
MemberAccess (parent_member
, "int_equal", get_src (begin
)));
946 Expression
parse_dict_creation_expression (SourceLocation begin
, MemberAccess member_key
, MemberAccess member_value
) throws ParseError
{
948 DataType key_type
= UnresolvedType
.new_from_expression (member_key
);
949 DataType value_type
= UnresolvedType
.new_from_expression (member_value
);
951 MemberAccess dict_member
= null, parent_member
= null, dict_hash
= null, dict_equal
= null;
953 parent_member
= new
MemberAccess (null, "Gee", get_src (begin
));
954 dict_member
= new
MemberAccess (parent_member
, "HashMap", get_src (begin
));
955 dict_member
.add_type_argument (key_type
);
956 dict_member
.add_type_argument (value_type
);
958 if (member_key
.member_name
== "string") {
959 parent_member
= new
MemberAccess (null, "GLib", get_src (begin
));
960 dict_hash
= new
MemberAccess (parent_member
, "str_hash", get_src (begin
));
961 dict_equal
= new
MemberAccess (parent_member
, "str_equal", get_src (begin
));
963 } else if (member_key
.member_name
== "int") {
964 parent_member
= new
MemberAccess (null, "GLib", get_src (begin
));
965 dict_hash
= new
MemberAccess (parent_member
, "int_hash", get_src (begin
));
966 dict_equal
= new
MemberAccess (parent_member
, "int_equal", get_src (begin
));
969 dict_member
.creation_member
= true;
971 var expr
= new
ObjectCreationExpression (dict_member
, get_src (begin
));
973 if (dict_hash
!= null && dict_equal
!= null) {
974 expr
.add_argument (dict_hash
);
975 expr
.add_argument (dict_equal
);
983 Gee
.List
<MemberInitializer
> parse_object_initializer () throws ParseError
{
984 var list
= new ArrayList
<MemberInitializer
> ();
985 if (accept (TokenType
.OPEN_BRACE
)) {
987 list
.add (parse_member_initializer ());
988 } while (accept (TokenType
.COMMA
));
989 expect (TokenType
.CLOSE_BRACE
);
994 MemberInitializer
parse_member_initializer () throws ParseError
{
995 var begin
= get_location ();
996 string id
= parse_identifier ();
997 expect (TokenType
.ASSIGN
);
998 var expr
= parse_expression ();
1000 return new
MemberInitializer (id
, expr
, get_src (begin
));
1003 Expression
parse_sizeof_expression () throws ParseError
{
1004 var begin
= get_location ();
1005 expect (TokenType
.SIZEOF
);
1006 expect (TokenType
.OPEN_PARENS
);
1007 var type
= parse_type ();
1008 expect (TokenType
.CLOSE_PARENS
);
1010 return new
SizeofExpression (type
, get_src (begin
));
1013 Expression
parse_typeof_expression () throws ParseError
{
1014 var begin
= get_location ();
1015 expect (TokenType
.TYPEOF
);
1016 expect (TokenType
.OPEN_PARENS
);
1017 var type
= parse_type ();
1018 expect (TokenType
.CLOSE_PARENS
);
1020 return new
TypeofExpression (type
, get_src (begin
));
1023 UnaryOperator
get_unary_operator (TokenType token_type
) {
1024 switch (token_type
) {
1025 case TokenType
.PLUS
: return UnaryOperator
.PLUS
;
1026 case TokenType
.MINUS
: return UnaryOperator
.MINUS
;
1027 case TokenType
.OP_NEG
: return UnaryOperator
.LOGICAL_NEGATION
;
1028 case TokenType
.TILDE
: return UnaryOperator
.BITWISE_COMPLEMENT
;
1029 case TokenType
.OP_INC
: return UnaryOperator
.INCREMENT
;
1030 case TokenType
.OP_DEC
: return UnaryOperator
.DECREMENT
;
1031 case TokenType
.REF
: return UnaryOperator
.REF
;
1032 case TokenType
.OUT
: return UnaryOperator
.OUT
;
1033 default: return UnaryOperator
.NONE
;
1037 Expression
parse_unary_expression () throws ParseError
{
1038 var begin
= get_location ();
1039 var operator
= get_unary_operator (current ());
1040 if (operator
!= UnaryOperator
.NONE
) {
1042 var op
= parse_unary_expression ();
1043 return new
UnaryExpression (operator
, op
, get_src (begin
));
1045 switch (current ()) {
1046 case TokenType
.HASH
:
1048 var op
= parse_unary_expression ();
1049 return new
ReferenceTransferExpression (op
, get_src (begin
));
1050 case TokenType
.OPEN_PARENS
:
1052 switch (current ()) {
1053 case TokenType
.VOID
:
1054 case TokenType
.DYNAMIC
:
1055 case TokenType
.WEAK
:
1056 case TokenType
.IDENTIFIER
:
1057 var type
= parse_type ();
1058 if (accept (TokenType
.CLOSE_PARENS
)) {
1059 // check follower to decide whether to create cast expression
1060 switch (current ()) {
1061 case TokenType
.OP_NEG
:
1062 case TokenType
.TILDE
:
1063 case TokenType
.OPEN_PARENS
:
1064 case TokenType
.TRUE
:
1065 case TokenType
.FALSE
:
1066 case TokenType
.INTEGER_LITERAL
:
1067 case TokenType
.REAL_LITERAL
:
1068 case TokenType
.CHARACTER_LITERAL
:
1069 case TokenType
.STRING_LITERAL
:
1070 case TokenType
.NULL
:
1071 case TokenType
.THIS
:
1072 case TokenType
.SUPER
:
1074 case TokenType
.SIZEOF
:
1075 case TokenType
.TYPEOF
:
1076 case TokenType
.IDENTIFIER
:
1077 if (!(type is PointerType
) && !type
.value_owned
) {
1078 Report
.warning (get_src (begin
), "obsolete syntax, weak type modifier unused in cast expressions");
1080 var inner
= parse_unary_expression ();
1081 return new
CastExpression (inner
, type
, get_src (begin
), false);
1090 // no cast expression
1093 case TokenType
.STAR
:
1095 var op
= parse_unary_expression ();
1096 return new
PointerIndirection (op
, get_src (begin
));
1097 case TokenType
.BITWISE_AND
:
1099 var op
= parse_unary_expression ();
1100 return new
AddressofExpression (op
, get_src (begin
));
1105 var expr
= parse_primary_expression ();
1109 BinaryOperator
get_binary_operator (TokenType token_type
) {
1110 switch (token_type
) {
1111 case TokenType
.STAR
: return BinaryOperator
.MUL
;
1112 case TokenType
.DIV
: return BinaryOperator
.DIV
;
1113 case TokenType
.PERCENT
: return BinaryOperator
.MOD
;
1114 case TokenType
.PLUS
: return BinaryOperator
.PLUS
;
1115 case TokenType
.MINUS
: return BinaryOperator
.MINUS
;
1116 case TokenType
.OP_LT
: return BinaryOperator
.LESS_THAN
;
1117 case TokenType
.OP_GT
: return BinaryOperator
.GREATER_THAN
;
1118 case TokenType
.OP_LE
: return BinaryOperator
.LESS_THAN_OR_EQUAL
;
1119 case TokenType
.OP_GE
: return BinaryOperator
.GREATER_THAN_OR_EQUAL
;
1120 case TokenType
.OP_EQ
: return BinaryOperator
.EQUALITY
;
1123 if (current () == TokenType
.OP_NEG
) {
1125 return BinaryOperator
.INEQUALITY
;
1128 return BinaryOperator
.EQUALITY
;
1129 case TokenType
.OP_NE
: return BinaryOperator
.INEQUALITY
;
1130 default: return BinaryOperator
.NONE
;
1134 Expression
parse_multiplicative_expression () throws ParseError
{
1135 var begin
= get_location ();
1136 var left
= parse_unary_expression ();
1139 var operator
= get_binary_operator (current ());
1141 case BinaryOperator
.MUL
:
1142 case BinaryOperator
.DIV
:
1143 case BinaryOperator
.MOD
:
1145 var right
= parse_unary_expression ();
1146 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1156 Expression
parse_additive_expression () throws ParseError
{
1157 var begin
= get_location ();
1158 var left
= parse_multiplicative_expression ();
1161 var operator
= get_binary_operator (current ());
1163 case BinaryOperator
.PLUS
:
1164 case BinaryOperator
.MINUS
:
1166 var right
= parse_multiplicative_expression ();
1167 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1177 Expression
parse_shift_expression () throws ParseError
{
1178 var begin
= get_location ();
1179 var left
= parse_additive_expression ();
1182 switch (current ()) {
1183 case TokenType
.OP_SHIFT_LEFT
:
1185 var right
= parse_additive_expression ();
1186 left
= new
BinaryExpression (BinaryOperator
.SHIFT_LEFT
, left
, right
, get_src (begin
));
1188 // don't use OP_SHIFT_RIGHT to support >> for nested generics
1189 case TokenType
.OP_GT
:
1190 char* first_gt_pos
= tokens
[index
].begin
.pos
;
1192 // only accept >> when there is no space between the two > signs
1193 if (current () == TokenType
.OP_GT
&& tokens
[index
].begin
.pos
== first_gt_pos
+ 1) {
1195 var right
= parse_additive_expression ();
1196 left
= new
BinaryExpression (BinaryOperator
.SHIFT_RIGHT
, left
, right
, get_src (begin
));
1210 Expression
parse_relational_expression () throws ParseError
{
1211 var begin
= get_location ();
1212 var left
= parse_shift_expression ();
1215 var operator
= get_binary_operator (current ());
1217 case BinaryOperator
.LESS_THAN
:
1218 case BinaryOperator
.LESS_THAN_OR_EQUAL
:
1219 case BinaryOperator
.GREATER_THAN_OR_EQUAL
:
1221 var right
= parse_shift_expression ();
1222 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1224 case BinaryOperator
.GREATER_THAN
:
1226 // ignore >> and >>= (two tokens due to generics)
1227 if (current () != TokenType
.OP_GT
&& current () != TokenType
.OP_GE
) {
1228 var right
= parse_shift_expression ();
1229 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1236 switch (current ()) {
1239 var type
= parse_type ();
1240 left
= new
TypeCheck (left
, type
, get_src (begin
));
1244 var type
= parse_type ();
1245 left
= new
CastExpression (left
, type
, get_src (begin
), true);
1257 Expression
parse_equality_expression () throws ParseError
{
1258 var begin
= get_location ();
1259 var left
= parse_relational_expression ();
1262 var operator
= get_binary_operator (current ());
1264 case BinaryOperator
.INEQUALITY
:
1265 case BinaryOperator
.EQUALITY
:
1266 if ((operator
== BinaryOperator
.INEQUALITY
) && (current () == TokenType
.IS
)) {
1270 var right
= parse_relational_expression ();
1271 left
= new
BinaryExpression (operator
, left
, right
, get_src (begin
));
1281 Expression
parse_and_expression () throws ParseError
{
1282 var begin
= get_location ();
1283 var left
= parse_equality_expression ();
1284 while (accept (TokenType
.BITWISE_AND
)) {
1285 var right
= parse_equality_expression ();
1286 left
= new
BinaryExpression (BinaryOperator
.BITWISE_AND
, left
, right
, get_src (begin
));
1291 Expression
parse_exclusive_or_expression () throws ParseError
{
1292 var begin
= get_location ();
1293 var left
= parse_and_expression ();
1294 while (accept (TokenType
.CARRET
)) {
1295 var right
= parse_and_expression ();
1296 left
= new
BinaryExpression (BinaryOperator
.BITWISE_XOR
, left
, right
, get_src (begin
));
1301 Expression
parse_inclusive_or_expression () throws ParseError
{
1302 var begin
= get_location ();
1303 var left
= parse_exclusive_or_expression ();
1304 while (accept (TokenType
.BITWISE_OR
)) {
1305 var right
= parse_exclusive_or_expression ();
1306 left
= new
BinaryExpression (BinaryOperator
.BITWISE_OR
, left
, right
, get_src (begin
));
1311 Expression
parse_in_expression () throws ParseError
{
1312 var begin
= get_location ();
1313 var left
= parse_inclusive_or_expression ();
1314 while (accept (TokenType
.IN
)) {
1315 var right
= parse_inclusive_or_expression ();
1316 left
= new
BinaryExpression (BinaryOperator
.IN
, left
, right
, get_src (begin
));
1321 Expression
parse_conditional_and_expression () throws ParseError
{
1322 var begin
= get_location ();
1323 var left
= parse_in_expression ();
1324 while (accept (TokenType
.OP_AND
)) {
1325 var right
= parse_in_expression ();
1326 left
= new
BinaryExpression (BinaryOperator
.AND
, left
, right
, get_src (begin
));
1331 Expression
parse_conditional_or_expression () throws ParseError
{
1332 var begin
= get_location ();
1333 var left
= parse_conditional_and_expression ();
1334 while (accept (TokenType
.OP_OR
)) {
1335 var right
= parse_conditional_and_expression ();
1336 left
= new
BinaryExpression (BinaryOperator
.OR
, left
, right
, get_src (begin
));
1341 Expression
parse_conditional_expression () throws ParseError
{
1342 var begin
= get_location ();
1343 var condition
= parse_conditional_or_expression ();
1344 if (accept (TokenType
.INTERR
)) {
1345 var true_expr
= parse_expression ();
1346 expect (TokenType
.COLON
);
1347 var false_expr
= parse_expression ();
1348 return new
ConditionalExpression (condition
, true_expr
, false_expr
, get_src (begin
));
1354 Expression
parse_lambda_expression () throws ParseError
{
1355 var begin
= get_location ();
1356 Gee
.List
<string> params
= new ArrayList
<string> ();
1358 expect (TokenType
.DEF
);
1360 if (accept (TokenType
.OPEN_PARENS
)) {
1361 if (current () != TokenType
.CLOSE_PARENS
) {
1363 params
.add (parse_identifier ());
1364 } while (accept (TokenType
.COMMA
));
1366 expect (TokenType
.CLOSE_PARENS
);
1368 params
.add (parse_identifier ());
1372 LambdaExpression lambda
;
1373 if (accept_block ()) {
1374 var block
= parse_block ();
1375 lambda
= new LambdaExpression
.with_statement_body (block
, get_src (begin
));
1377 var expr
= parse_expression ();
1378 lambda
= new
LambdaExpression (expr
, get_src (begin
));
1379 expect_terminator ();
1384 foreach (string param
in params
) {
1385 lambda
.add_parameter (param
);
1390 AssignmentOperator
get_assignment_operator (TokenType token_type
) {
1391 switch (token_type
) {
1392 case TokenType
.ASSIGN
: return AssignmentOperator
.SIMPLE
;
1393 case TokenType
.ASSIGN_ADD
: return AssignmentOperator
.ADD
;
1394 case TokenType
.ASSIGN_SUB
: return AssignmentOperator
.SUB
;
1395 case TokenType
.ASSIGN_BITWISE_OR
: return AssignmentOperator
.BITWISE_OR
;
1396 case TokenType
.ASSIGN_BITWISE_AND
: return AssignmentOperator
.BITWISE_AND
;
1397 case TokenType
.ASSIGN_BITWISE_XOR
: return AssignmentOperator
.BITWISE_XOR
;
1398 case TokenType
.ASSIGN_DIV
: return AssignmentOperator
.DIV
;
1399 case TokenType
.ASSIGN_MUL
: return AssignmentOperator
.MUL
;
1400 case TokenType
.ASSIGN_PERCENT
: return AssignmentOperator
.PERCENT
;
1401 case TokenType
.ASSIGN_SHIFT_LEFT
: return AssignmentOperator
.SHIFT_LEFT
;
1402 default: return AssignmentOperator
.NONE
;
1406 Expression
parse_expression () throws ParseError
{
1407 if (current () == TokenType
.DEF
) {
1408 var lambda
= parse_lambda_expression ();
1409 current_expr_is_lambda
= true;
1413 var begin
= get_location ();
1414 Expression expr
= parse_conditional_expression ();
1417 var operator
= get_assignment_operator (current ());
1418 if (operator
!= AssignmentOperator
.NONE
) {
1420 var rhs
= parse_expression ();
1421 expr
= new
Assignment (expr
, rhs
, operator
, get_src (begin
));
1422 } else if (current () == TokenType
.OP_GT
) { // >>=
1423 char* first_gt_pos
= tokens
[index
].begin
.pos
;
1425 // only accept >>= when there is no space between the two > signs
1426 if (current () == TokenType
.OP_GE
&& tokens
[index
].begin
.pos
== first_gt_pos
+ 1) {
1428 var rhs
= parse_expression ();
1429 expr
= new
Assignment (expr
, rhs
, AssignmentOperator
.SHIFT_RIGHT
, get_src (begin
));
1443 Statement
get_for_statement_type () throws ParseError
{
1445 var begin
= get_location ();
1446 bool is_foreach
= false;
1448 while (current () != TokenType
.EOL
&& current () != TokenType
.DO
) {
1450 if (accept (TokenType
.IN
)) {
1459 return parse_foreach_statement ();
1461 return parse_for_statement ();
1466 void parse_statements (Block block
) throws ParseError
{
1467 while (current () != TokenType
.DEDENT
1468 && current () != TokenType
.WHEN
1469 && current () != TokenType
.DEFAULT
) {
1471 Statement stmt
= null;
1472 bool is_decl
= false;
1473 comment
= scanner
.pop_comment ();
1474 switch (current ()) {
1476 /* skip over requires and ensures as we handled them in method declaration */
1477 case TokenType
.REQUIRES
:
1478 case TokenType
.ENSURES
:
1479 var begin
= get_location ();
1482 if (accept (TokenType
.EOL
) && accept (TokenType
.INDENT
)) {
1483 while (current () != TokenType
.DEDENT
) {
1487 expect (TokenType
.DEDENT
);
1489 while (current () != TokenType
.EOL
) {
1493 expect (TokenType
.EOL
);
1496 stmt
= new
EmptyStatement (get_src_com (begin
));
1500 case TokenType
.INDENT
:
1501 stmt
= parse_block ();
1503 case TokenType
.SEMICOLON
:
1504 case TokenType
.PASS
:
1505 stmt
= parse_empty_statement ();
1507 case TokenType
.PRINT
:
1508 case TokenType
.ASSERT
:
1509 stmt
= parse_expression_statement ();
1512 stmt
= parse_if_statement ();
1514 case TokenType
.CASE
:
1515 stmt
= parse_switch_statement ();
1517 case TokenType
.WHILE
:
1518 stmt
= parse_while_statement ();
1521 stmt
= parse_do_statement ();
1524 stmt
= get_for_statement_type ();
1526 case TokenType
.BREAK
:
1527 stmt
= parse_break_statement ();
1529 case TokenType
.CONTINUE
:
1530 stmt
= parse_continue_statement ();
1532 case TokenType
.RETURN
:
1533 stmt
= parse_return_statement ();
1535 case TokenType
.RAISE
:
1536 stmt
= parse_throw_statement ();
1539 stmt
= parse_try_statement ();
1541 case TokenType
.LOCK
:
1542 stmt
= parse_lock_statement ();
1544 case TokenType
.DELETE
:
1545 stmt
= parse_delete_statement ();
1549 parse_local_variable_declarations (block
);
1553 case TokenType
.OP_INC
:
1554 case TokenType
.OP_DEC
:
1555 case TokenType
.SUPER
:
1556 case TokenType
.THIS
:
1557 case TokenType
.OPEN_PARENS
:
1558 case TokenType
.STAR
:
1560 stmt
= parse_expression_statement ();
1563 bool is_expr
= is_expression ();
1565 stmt
= parse_expression_statement ();
1568 parse_local_variable_declarations (block
);
1574 block
.add_statement (stmt
);
1576 } catch (ParseError e
) {
1577 if (recover () != RecoveryState
.STATEMENT_BEGIN
) {
1578 // beginning of next declaration or end of file reached
1579 // return what we have so far
1586 bool is_expression () throws ParseError
{
1587 var begin
= get_location ();
1589 // decide between declaration and expression statement
1591 switch (current ()) {
1592 // invocation expression
1593 case TokenType
.OPEN_PARENS
:
1594 // postfix increment
1595 case TokenType
.OP_INC
:
1596 // postfix decrement
1597 case TokenType
.OP_DEC
:
1599 case TokenType
.ASSIGN
:
1600 case TokenType
.ASSIGN_ADD
:
1601 case TokenType
.ASSIGN_BITWISE_AND
:
1602 case TokenType
.ASSIGN_BITWISE_OR
:
1603 case TokenType
.ASSIGN_BITWISE_XOR
:
1604 case TokenType
.ASSIGN_DIV
:
1605 case TokenType
.ASSIGN_MUL
:
1606 case TokenType
.ASSIGN_PERCENT
:
1607 case TokenType
.ASSIGN_SHIFT_LEFT
:
1608 case TokenType
.ASSIGN_SUB
:
1609 case TokenType
.OP_GT
: // >>=
1612 // pointer member access
1613 case TokenType
.OP_PTR
:
1622 Block
parse_embedded_statement () throws ParseError
{
1623 if (current () == TokenType
.INDENT
) {
1624 var block
= parse_block ();
1628 comment
= scanner
.pop_comment ();
1630 var block
= new
Block (get_src_com (get_location ()));
1631 block
.add_statement (parse_embedded_statement_without_block ());
1636 Statement
parse_embedded_statement_without_block () throws ParseError
{
1637 switch (current ()) {
1638 case TokenType
.PASS
:
1639 case TokenType
.SEMICOLON
: return parse_empty_statement ();
1640 case TokenType
.IF
: return parse_if_statement ();
1641 case TokenType
.CASE
: return parse_switch_statement ();
1642 case TokenType
.WHILE
: return parse_while_statement ();
1643 case TokenType
.DO
: return parse_do_statement ();
1644 case TokenType
.FOR
: return get_for_statement_type ();
1645 case TokenType
.BREAK
: return parse_break_statement ();
1646 case TokenType
.CONTINUE
: return parse_continue_statement ();
1647 case TokenType
.RETURN
: return parse_return_statement ();
1648 case TokenType
.RAISE
: return parse_throw_statement ();
1649 case TokenType
.TRY
: return parse_try_statement ();
1650 case TokenType
.LOCK
: return parse_lock_statement ();
1651 case TokenType
.DELETE
: return parse_delete_statement ();
1652 default: return parse_expression_statement ();
1656 Block
parse_block () throws ParseError
{
1657 var begin
= get_location ();
1658 expect (TokenType
.INDENT
);
1659 var block
= new
Block (get_src_com (begin
));
1660 parse_statements (block
);
1661 if (!accept (TokenType
.DEDENT
)) {
1662 // only report error if it's not a secondary error
1663 if (context
.report
.get_errors () == 0) {
1664 Report
.error (get_current_src (), "tab indentation is incorrect");
1671 Statement
parse_empty_statement () throws ParseError
{
1672 var begin
= get_location ();
1674 accept (TokenType
.PASS
);
1675 accept (TokenType
.SEMICOLON
);
1676 expect_terminator ();
1678 return new
EmptyStatement (get_src_com (begin
));
1681 void add_local_var_variable (Block block
, string id
) throws ParseError
{
1682 DataType type_copy
= null;
1683 var local
= parse_local_variable (type_copy
, id
);
1684 block
.add_statement (new
DeclarationStatement (local
, local
.source_reference
));
1687 void parse_local_variable_declarations (Block block
) throws ParseError
{
1688 if (accept (TokenType
.VAR
)) {
1689 /* support block vars */
1690 if (accept (TokenType
.EOL
) && accept (TokenType
.INDENT
)) {
1691 while (current () != TokenType
.DEDENT
) {
1692 var s
= parse_identifier ();
1693 add_local_var_variable (block
, s
);
1694 accept (TokenType
.EOL
);
1695 accept (TokenType
.SEMICOLON
);
1698 expect (TokenType
.DEDENT
);
1700 var s
= parse_identifier ();
1701 add_local_var_variable (block
, s
);
1702 expect_terminator ();
1708 var id_list
= new ArrayList
<string> ();
1709 DataType variable_type
= null;
1712 id_list
.add (parse_identifier ());
1713 } while (accept (TokenType
.COMMA
));
1715 expect (TokenType
.COLON
);
1717 variable_type
= parse_type ();
1719 foreach (string id
in id_list
) {
1720 DataType type_copy
= null;
1721 if (variable_type
!= null) {
1722 type_copy
= variable_type
.copy ();
1724 var local
= parse_local_variable (type_copy
, id
);
1725 block
.add_statement (new
DeclarationStatement (local
, local
.source_reference
));
1728 expect_terminator ();
1731 LocalVariable
parse_local_variable (DataType? variable_type
, string id
) throws ParseError
{
1732 var begin
= get_location ();
1733 Expression initializer
= null;
1734 if (accept (TokenType
.ASSIGN
)) {
1735 initializer
= parse_variable_initializer ();
1737 return new
LocalVariable (variable_type
, id
, initializer
, get_src_com (begin
));
1740 Statement
parse_expression_statement () throws ParseError
{
1741 var begin
= get_location ();
1742 var expr
= parse_statement_expression ();
1744 if (current_expr_is_lambda
) {
1745 current_expr_is_lambda
= false;
1747 expect_terminator ();
1750 return new
ExpressionStatement (expr
, get_src_com (begin
));
1753 Expression
parse_statement_expression () throws ParseError
{
1754 // invocation expression, assignment,
1755 // or pre/post increment/decrement expression
1756 var expr
= parse_expression ();
1760 Statement
parse_if_statement () throws ParseError
{
1761 var begin
= get_location ();
1763 expect (TokenType
.IF
);
1765 var condition
= parse_expression ();
1767 if (!accept (TokenType
.DO
)) {
1768 expect (TokenType
.EOL
);
1770 accept (TokenType
.EOL
);
1773 var src
= get_src_com (begin
);
1774 var true_stmt
= parse_embedded_statement ();
1775 Block false_stmt
= null;
1776 if (accept (TokenType
.ELSE
)) {
1777 // allow `else if' on the same line without `do'
1778 if (!accept (TokenType
.DO
) && current () != TokenType
.IF
) {
1779 expect (TokenType
.EOL
);
1781 accept (TokenType
.EOL
);
1784 false_stmt
= parse_embedded_statement ();
1786 return new
IfStatement (condition
, true_stmt
, false_stmt
, src
);
1789 Statement
parse_switch_statement () throws ParseError
{
1790 var begin
= get_location ();
1791 expect (TokenType
.CASE
);
1792 var condition
= parse_expression ();
1794 expect (TokenType
.EOL
);
1796 var stmt
= new
SwitchStatement (condition
, get_src_com (begin
));
1797 expect (TokenType
.INDENT
);
1798 while (current () != TokenType
.DEDENT
) {
1799 var section
= new
SwitchSection (get_src_com (begin
));
1801 if (accept (TokenType
.WHEN
)) {
1803 section
.add_label (new
SwitchLabel (parse_expression (), get_src_com (begin
)));
1805 while (accept (TokenType
.COMMA
));
1807 expect (TokenType
.DEFAULT
);
1808 section
.add_label (new SwitchLabel
.with_default (get_src_com (begin
)));
1811 if (!accept (TokenType
.EOL
)) {
1812 expect (TokenType
.DO
);
1815 parse_statements (section
);
1817 /* add break statement for each block */
1818 var break_stmt
= new
BreakStatement (get_src_com (begin
));
1819 section
.add_statement (break_stmt
);
1821 stmt
.add_section (section
);
1823 expect (TokenType
.DEDENT
);
1827 Statement
parse_while_statement () throws ParseError
{
1828 var begin
= get_location ();
1829 expect (TokenType
.WHILE
);
1830 var condition
= parse_expression ();
1832 if (!accept (TokenType
.DO
)) {
1833 expect (TokenType
.EOL
);
1835 accept (TokenType
.EOL
);
1838 var body
= parse_embedded_statement ();
1839 return new
WhileStatement (condition
, body
, get_src_com (begin
));
1842 Statement
parse_do_statement () throws ParseError
{
1843 var begin
= get_location ();
1844 expect (TokenType
.DO
);
1845 expect (TokenType
.EOL
);
1846 var body
= parse_embedded_statement ();
1847 expect (TokenType
.WHILE
);
1849 var condition
= parse_expression ();
1851 expect_terminator ();
1853 return new
DoStatement (body
, condition
, get_src_com (begin
));
1857 Statement
parse_for_statement () throws ParseError
{
1858 var begin
= get_location ();
1860 Expression initializer
= null;
1861 Expression condition
= null;
1862 Expression iterator
= null;
1866 expect (TokenType
.FOR
);
1868 switch (current ()) {
1874 bool local_is_expr
= is_expression ();
1875 is_expr
= local_is_expr
;
1880 var expr_begin
= get_location ();
1881 id
= parse_identifier ();
1882 rollback (expr_begin
);
1883 initializer
= parse_statement_expression ();
1885 block
= new
Block (get_src (begin
));
1886 DataType variable_type
;
1887 if (accept (TokenType
.VAR
)) {
1888 variable_type
= null;
1889 id
= parse_identifier ();
1891 id
= parse_identifier ();
1892 expect (TokenType
.COLON
);
1893 variable_type
= parse_type ();
1896 DataType type_copy
= null;
1897 if (variable_type
!= null) {
1898 type_copy
= variable_type
.copy ();
1900 var local
= parse_local_variable (type_copy
, id
);
1902 block
.add_statement (new
DeclarationStatement (local
, local
.source_reference
));
1907 if (accept (TokenType
.TO
)) {
1908 /* create expression for condition and incrementing iterator */
1909 var to_begin
= get_location ();
1910 var to_src
= get_src (to_begin
);
1911 var left
= new
MemberAccess (null, id
, to_src
);
1912 var right
= parse_primary_expression ();
1914 condition
= new
BinaryExpression (BinaryOperator
.LESS_THAN_OR_EQUAL
, left
, right
, to_src
);
1916 iterator
= new
PostfixExpression (left
, true, to_src
);
1918 expect (TokenType
.DOWNTO
);
1919 var downto_begin
= get_location ();
1920 var downto_src
= get_src (downto_begin
);
1921 /* create expression for condition and decrementing iterator */
1922 var left
= new
MemberAccess (null, id
, downto_src
);
1923 var right
= parse_primary_expression ();
1925 condition
= new
BinaryExpression (BinaryOperator
.GREATER_THAN_OR_EQUAL
, left
, right
, downto_src
);
1927 iterator
= new
PostfixExpression (left
, false, downto_src
);
1930 if (!accept (TokenType
.EOL
)) {
1931 expect (TokenType
.DO
);
1934 var src
= get_src_com (begin
);
1935 var body
= parse_embedded_statement ();
1936 var stmt
= new
ForStatement (condition
, body
, src
);
1938 if (initializer
!= null) stmt
.add_initializer (initializer
);
1940 stmt
.add_iterator (iterator
);
1943 if (block
!= null) {
1944 block
.add_statement (stmt
);
1951 Statement
parse_foreach_statement () throws ParseError
{
1952 var begin
= get_location ();
1953 DataType type
= null;
1956 expect (TokenType
.FOR
);
1958 if (accept (TokenType
.VAR
)) {
1959 id
= parse_identifier ();
1961 id
= parse_identifier ();
1962 if (accept (TokenType
.COLON
)) {
1963 type
= parse_type ();
1967 expect (TokenType
.IN
);
1968 var collection
= parse_expression ();
1969 if (!accept (TokenType
.EOL
)) {
1970 expect (TokenType
.DO
);
1972 var src
= get_src_com (begin
);
1973 var body
= parse_embedded_statement ();
1974 return new
ForeachStatement (type
, id
, collection
, body
, src
);
1977 Statement
parse_break_statement () throws ParseError
{
1978 var begin
= get_location ();
1979 expect (TokenType
.BREAK
);
1980 expect_terminator ();
1981 return new
BreakStatement (get_src_com (begin
));
1984 Statement
parse_continue_statement () throws ParseError
{
1985 var begin
= get_location ();
1986 expect (TokenType
.CONTINUE
);
1987 expect_terminator ();
1988 return new
ContinueStatement (get_src_com (begin
));
1991 Statement
parse_return_statement () throws ParseError
{
1992 var begin
= get_location ();
1993 expect (TokenType
.RETURN
);
1994 Expression expr
= null;
1995 if (current () != TokenType
.SEMICOLON
&& current () != TokenType
.EOL
) {
1996 expr
= parse_expression ();
1998 expect_terminator ();
1999 return new
ReturnStatement (expr
, get_src_com (begin
));
2002 Statement
parse_throw_statement () throws ParseError
{
2003 var begin
= get_location ();
2004 expect (TokenType
.RAISE
);
2005 var expr
= parse_expression ();
2006 expect_terminator ();
2007 return new
ThrowStatement (expr
, get_src_com (begin
));
2010 Statement
parse_try_statement () throws ParseError
{
2011 var begin
= get_location ();
2012 expect (TokenType
.TRY
);
2013 expect (TokenType
.EOL
);
2014 var try_block
= parse_block ();
2015 Block finally_clause
= null;
2016 var catch_clauses
= new ArrayList
<CatchClause
> ();
2017 if (current () == TokenType
.EXCEPT
) {
2018 parse_catch_clauses (catch_clauses
);
2019 if (current () == TokenType
.FINALLY
) {
2020 finally_clause
= parse_finally_clause ();
2023 finally_clause
= parse_finally_clause ();
2025 var stmt
= new
TryStatement (try_block
, finally_clause
, get_src_com (begin
));
2026 foreach (CatchClause clause
in catch_clauses
) {
2027 stmt
.add_catch_clause (clause
);
2032 void parse_catch_clauses (Gee
.List
<CatchClause
> catch_clauses
) throws ParseError
{
2033 while (accept (TokenType
.EXCEPT
)) {
2034 var begin
= get_location ();
2035 DataType type
= null;
2037 if (!accept (TokenType
.EOL
)) {
2038 id
= parse_identifier ();
2039 expect (TokenType
.COLON
);
2040 type
= parse_type ();
2041 expect (TokenType
.EOL
);
2044 var block
= parse_block ();
2045 catch_clauses
.add (new
CatchClause (type
, id
, block
, get_src (begin
)));
2049 Block
parse_finally_clause () throws ParseError
{
2050 expect (TokenType
.FINALLY
);
2052 var block
= parse_block ();
2056 Statement
parse_lock_statement () throws ParseError
{
2057 var begin
= get_location ();
2058 expect (TokenType
.LOCK
);
2059 expect (TokenType
.OPEN_PARENS
);
2060 var expr
= parse_expression ();
2061 expect (TokenType
.CLOSE_PARENS
);
2062 var stmt
= parse_embedded_statement ();
2063 return new
LockStatement (expr
, stmt
, get_src_com (begin
));
2066 Statement
parse_delete_statement () throws ParseError
{
2067 var begin
= get_location ();
2068 expect (TokenType
.DELETE
);
2069 var expr
= parse_expression ();
2070 expect_terminator ();
2071 return new
DeleteStatement (expr
, get_src_com (begin
));
2074 Gee
.List
<Attribute
>?
parse_attributes () throws ParseError
{
2075 if (current () != TokenType
.OPEN_BRACKET
) {
2078 var attrs
= new ArrayList
<Attribute
> ();
2079 while (accept (TokenType
.OPEN_BRACKET
)) {
2081 var begin
= get_location ();
2082 string id
= parse_identifier ();
2083 var attr
= new
Attribute (id
, get_src (begin
));
2084 if (accept (TokenType
.OPEN_PARENS
)) {
2085 if (current () != TokenType
.CLOSE_PARENS
) {
2087 id
= parse_identifier ();
2088 expect (TokenType
.ASSIGN
);
2089 var expr
= parse_expression ();
2090 attr
.add_argument (id
, expr
);
2091 } while (accept (TokenType
.COMMA
));
2093 expect (TokenType
.CLOSE_PARENS
);
2096 } while (accept (TokenType
.COMMA
));
2097 expect (TokenType
.CLOSE_BRACKET
);
2099 expect (TokenType
.EOL
);
2104 void set_attributes (CodeNode node
, Gee
.List
<Attribute
>? attributes
) {
2105 if (attributes
!= null) {
2106 foreach (Attribute attr
in (Gee
.List
<Attribute
>) attributes
) {
2107 node
.attributes
.append (attr
);
2112 Symbol
parse_declaration (bool is_root
= false) throws ParseError
{
2113 comment
= scanner
.pop_comment ();
2114 var attrs
= parse_attributes ();
2116 switch (current ()) {
2117 case TokenType
.CONST
:
2118 return parse_constant_declaration (attrs
);
2119 case TokenType
.CONSTRUCT
:
2120 return parse_creation_method_declaration (attrs
);
2121 case TokenType
.CLASS
:
2122 return parse_class_declaration (attrs
);
2123 case TokenType
.INIT
:
2125 return parse_main_method_declaration (attrs
);
2127 return parse_constructor_declaration (attrs
);
2128 case TokenType
.DELEGATE
:
2129 return parse_delegate_declaration (attrs
);
2131 return parse_method_declaration (attrs
);
2132 case TokenType
.ENUM
:
2133 return parse_enum_declaration (attrs
);
2134 case TokenType
.ERRORDOMAIN
:
2135 return parse_errordomain_declaration (attrs
);
2136 case TokenType
.FINAL
:
2137 return parse_destructor_declaration (attrs
);
2138 case TokenType
.INTERFACE
:
2139 return parse_interface_declaration (attrs
);
2140 case TokenType
.NAMESPACE
:
2141 return parse_namespace_declaration (attrs
);
2142 case TokenType
.PROP
:
2143 return parse_property_declaration (attrs
);
2144 case TokenType
.EVENT
:
2145 return parse_signal_declaration (attrs
);
2146 case TokenType
.STRUCT
:
2147 return parse_struct_declaration (attrs
);
2149 var begin
= get_location ();
2150 while (current () != TokenType
.EOL
&& current () != TokenType
.SEMICOLON
&& current () != TokenType
.EOF
) {
2151 if (current () == TokenType
.COLON
) {
2153 return parse_field_declaration (attrs
);
2163 TokenType cur
= current ();
2164 TokenType pre
= tokens
[index
-1].type
;
2166 throw new ParseError
.SYNTAX (get_error ("expected declaration but got %s with previous %s".printf (cur
.to_string (), pre
.to_string())));
2169 void parse_declarations (Symbol parent
, bool root
= false) throws ParseError
{
2171 expect (TokenType
.INDENT
);
2173 while (current () != TokenType
.DEDENT
&& current () != TokenType
.EOF
) {
2175 if (parent is Namespace
) {
2176 parse_namespace_member ((Namespace
) parent
);
2177 } else if (parent is Class
) {
2178 parse_class_member ((Class
) parent
);
2179 } else if (parent is Struct
) {
2180 parse_struct_member ((Struct
) parent
);
2181 } else if (parent is Interface
) {
2182 parse_interface_member ((Interface
) parent
);
2184 } catch (ParseError e
) {
2188 if (r
== RecoveryState
.STATEMENT_BEGIN
) {
2194 if (r
== RecoveryState
.EOF
) {
2200 if (!accept (TokenType
.DEDENT
)) {
2201 // only report error if it's not a secondary error
2202 if (context
.report
.get_errors () == 0) {
2203 Report
.error (get_current_src (), "expected dedent");
2209 enum RecoveryState
{
2215 RecoveryState
recover () {
2216 while (current () != TokenType
.EOF
) {
2217 switch (current ()) {
2218 case TokenType
.CLASS
:
2219 case TokenType
.CONST
:
2220 case TokenType
.CONSTRUCT
:
2221 case TokenType
.INIT
:
2223 case TokenType
.DELEGATE
:
2224 case TokenType
.ENUM
:
2225 case TokenType
.ERRORDOMAIN
:
2226 case TokenType
.FINAL
:
2227 case TokenType
.INTERFACE
:
2228 case TokenType
.NAMESPACE
:
2229 case TokenType
.PROP
:
2230 case TokenType
.EVENT
:
2231 case TokenType
.STRUCT
:
2232 return RecoveryState
.DECLARATION_BEGIN
;
2233 case TokenType
.BREAK
:
2234 case TokenType
.CASE
:
2235 case TokenType
.CONTINUE
:
2236 case TokenType
.DELETE
:
2240 case TokenType
.LOCK
:
2241 case TokenType
.RETURN
:
2242 case TokenType
.RAISE
:
2245 case TokenType
.WHILE
:
2246 return RecoveryState
.STATEMENT_BEGIN
;
2252 return RecoveryState
.EOF
;
2255 Namespace
parse_namespace_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2256 var begin
= get_location ();
2257 expect (TokenType
.NAMESPACE
);
2258 var sym
= parse_symbol_name ();
2259 var ns
= new
Namespace (sym
.name
, get_src_com (begin
));
2260 set_attributes (ns
, attrs
);
2261 expect (TokenType
.EOL
);
2262 parse_declarations (ns
);
2266 void parse_namespace_member (Namespace ns
) throws ParseError
{
2268 var sym
= parse_declaration ((ns
== context
.root
));
2269 if (sym is Namespace
) {
2270 ns
.add_namespace ((Namespace
) sym
);
2271 } else if (sym is Class
) {
2272 ns
.add_class ((Class
) sym
);
2273 } else if (sym is Interface
) {
2274 ns
.add_interface ((Interface
) sym
);
2275 } else if (sym is Struct
) {
2276 ns
.add_struct ((Struct
) sym
);
2277 } else if (sym is Enum
) {
2278 ns
.add_enum ((Enum
) sym
);
2279 } else if (sym is ErrorDomain
) {
2280 ns
.add_error_domain ((ErrorDomain
) sym
);
2281 } else if (sym is Delegate
) {
2282 ns
.add_delegate ((Delegate
) sym
);
2283 } else if (sym is Method
) {
2284 var method
= (Method
) sym
;
2285 if (method
.binding
== MemberBinding
.INSTANCE
) {
2286 method
.binding
= MemberBinding
.STATIC
;
2288 ns
.add_method (method
);
2289 } else if (sym is Field
) {
2290 var field
= (Field
) sym
;
2291 if (field
.binding
== MemberBinding
.INSTANCE
) {
2292 field
.binding
= MemberBinding
.STATIC
;
2294 ns
.add_field (field
);
2295 } else if (sym is Constant
) {
2296 ns
.add_constant ((Constant
) sym
);
2298 Report
.error (sym
.source_reference
, "unexpected declaration in namespace");
2300 scanner
.source_file
.add_node (sym
);
2304 void add_uses_clause () throws ParseError
{
2305 var begin
= get_location ();
2306 var sym
= parse_symbol_name ();
2307 var ns_ref
= new
UsingDirective (sym
, get_src (begin
));
2309 scanner
.source_file
.add_using_directive (ns_ref
);
2312 void parse_using_directives () throws ParseError
{
2313 while (accept (TokenType
.USES
)) {
2314 if (accept_block ()) {
2315 expect (TokenType
.INDENT
);
2317 while (current () != TokenType
.DEDENT
&& current () != TokenType
.EOF
) {
2319 expect (TokenType
.EOL
);
2322 expect (TokenType
.DEDENT
);
2326 } while (accept (TokenType
.COMMA
));
2328 expect_terminator ();
2334 Symbol
parse_class_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2335 var begin
= get_location ();
2336 expect (TokenType
.CLASS
);
2338 var flags
= parse_type_declaration_modifiers ();
2340 var sym
= parse_symbol_name ();
2341 var type_param_list
= parse_type_parameter_list ();
2342 var base_types
= new ArrayList
<DataType
> ();
2343 if (accept (TokenType
.COLON
)) {
2344 base_types
.add (parse_type ());
2346 if (accept (TokenType
.IMPLEMENTS
)) {
2348 base_types
.add (parse_type ());
2349 } while (accept (TokenType
.COMMA
));
2353 accept (TokenType
.EOL
);
2355 var cl
= new
Class (sym
.name
, get_src_com (begin
));
2357 if (ModifierFlags
.PRIVATE
in flags
) {
2358 cl
.access
= SymbolAccessibility
.PRIVATE
;
2360 /* class must always be Public unless its name starts wtih underscore */
2361 if (sym
.name
[0] == '_') {
2362 cl
.access
= SymbolAccessibility
.PRIVATE
;
2364 cl
.access
= SymbolAccessibility
.PUBLIC
;
2368 if (ModifierFlags
.ABSTRACT
in flags
) {
2369 cl
.is_abstract
= true;
2371 set_attributes (cl
, attrs
);
2372 foreach (TypeParameter type_param
in type_param_list
) {
2373 cl
.add_type_parameter (type_param
);
2375 foreach (DataType base_type
in base_types
) {
2376 cl
.add_base_type (base_type
);
2379 class_name
= cl
.name
;
2381 parse_declarations (cl
);
2383 // ensure there is always a default construction method
2384 if (!scanner
.source_file
.external_package
2386 && cl
.default_construction_method
== null) {
2387 var m
= new
CreationMethod (cl
.name
, null, cl
.source_reference
);
2388 m
.binding
= MemberBinding
.STATIC
;
2389 m
.access
= SymbolAccessibility
.PUBLIC
;
2390 m
.body
= new
Block (cl
.source_reference
);
2395 while (sym
.inner
!= null) {
2397 var ns
= new
Namespace (sym
.name
, cl
.source_reference
);
2398 if (result is Namespace
) {
2399 ns
.add_namespace ((Namespace
) result
);
2401 ns
.add_class ((Class
) result
);
2402 scanner
.source_file
.add_node (result
);
2409 void parse_class_member (Class cl
) throws ParseError
{
2410 var sym
= parse_declaration ();
2412 cl
.add_class ((Class
) sym
);
2413 } else if (sym is Struct
) {
2414 cl
.add_struct ((Struct
) sym
);
2415 } else if (sym is Enum
) {
2416 cl
.add_enum ((Enum
) sym
);
2417 } else if (sym is Delegate
) {
2418 cl
.add_delegate ((Delegate
) sym
);
2419 } else if (sym is Method
) {
2420 cl
.add_method ((Method
) sym
);
2421 } else if (sym is Vala
.Signal
) {
2422 cl
.add_signal ((Vala
.Signal
) sym
);
2423 } else if (sym is Field
) {
2424 cl
.add_field ((Field
) sym
);
2425 } else if (sym is Constant
) {
2426 cl
.add_constant ((Constant
) sym
);
2427 } else if (sym is Property
) {
2428 cl
.add_property ((Property
) sym
);
2429 } else if (sym is Constructor
) {
2430 var c
= (Constructor
) sym
;
2431 if (c
.binding
== MemberBinding
.INSTANCE
) {
2433 } else if (c
.binding
== MemberBinding
.CLASS
) {
2434 cl
.class_constructor
= c
;
2436 cl
.static_constructor
= c
;
2438 } else if (sym is Destructor
) {
2439 cl
.destructor
= (Destructor
) sym
;
2441 Report
.error (sym
.source_reference
, "unexpected declaration in class");
2445 Constant
parse_constant_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2446 var begin
= get_location ();
2448 expect (TokenType
.CONST
);
2450 parse_member_declaration_modifiers ();
2452 string id
= parse_identifier ();
2453 expect (TokenType
.COLON
);
2454 var type
= parse_type (false);
2456 Expression initializer
= null;
2457 if (accept (TokenType
.ASSIGN
)) {
2458 initializer
= parse_variable_initializer ();
2460 expect_terminator ();
2462 // constant arrays don't own their element
2463 var array_type
= type as ArrayType
;
2464 if (array_type
!= null) {
2465 array_type
.element_type
.value_owned
= false;
2468 var c
= new
Constant (id
, type
, initializer
, get_src_com (begin
));
2469 c
.access
= get_access (id
);
2470 set_attributes (c
, attrs
);
2474 Field
parse_field_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2475 var begin
= get_location ();
2476 string id
= parse_identifier ();
2477 expect (TokenType
.COLON
);
2479 var flags
= parse_member_declaration_modifiers ();
2481 var type
= parse_type ();
2483 var f
= new
Field (id
, type
, null, get_src_com (begin
));
2485 if (ModifierFlags
.ABSTRACT
in flags
|| ModifierFlags
.VIRTUAL
in flags
|| ModifierFlags
.OVERRIDE
in flags
) {
2486 Report
.error (f
.source_reference
, "abstract, virtual, and override modifiers are not applicable to fields");
2489 if (ModifierFlags
.PRIVATE
in flags
) {
2490 f
.access
= SymbolAccessibility
.PRIVATE
;
2492 f
.access
= get_access (id
);
2495 set_attributes (f
, attrs
);
2497 if (accept (TokenType
.ASSIGN
)) {
2498 f
.initializer
= parse_expression ();
2501 if (ModifierFlags
.STATIC
in flags
) {
2502 f
.binding
= MemberBinding
.STATIC
;
2503 } else if (ModifierFlags
.CLASS
in flags
) {
2504 f
.binding
= MemberBinding
.CLASS
;
2507 expect_terminator ();
2512 InitializerList
parse_initializer () throws ParseError
{
2513 var begin
= get_location ();
2514 if (!accept (TokenType
.OPEN_PARENS
)) {
2515 expect (TokenType
.OPEN_BRACE
);
2517 var initializer
= new
InitializerList (get_src (begin
));
2518 if (current () != TokenType
.DEDENT
) {
2520 var init
= parse_variable_initializer ();
2521 initializer
.append (init
);
2522 } while (accept (TokenType
.COMMA
));
2524 if (!accept (TokenType
.CLOSE_PARENS
)) {
2525 expect (TokenType
.CLOSE_BRACE
);
2530 bool is_initializer () throws ParseError
{
2531 if (current () == TokenType
.OPEN_BRACE
) {
2536 if (current () == TokenType.OPEN_PARENS) {
2537 var begin = get_location ();
2538 var is_array = false;
2542 var expr = parse_expression ();
2543 is_array = (accept (TokenType.COMMA));
2555 Expression
parse_variable_initializer () throws ParseError
{
2556 if (is_initializer ()) {
2557 var expr
= parse_initializer ();
2560 var expr
= parse_expression ();
2566 Method
parse_main_method_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2568 var begin
= get_location ();
2569 DataType type
= new
VoidType ();
2570 expect (TokenType
.INIT
);
2572 var method
= new
Method (id
, type
, get_src_com (begin
));
2573 method
.access
= SymbolAccessibility
.PUBLIC
;
2575 set_attributes (method
, attrs
);
2577 method
.binding
= MemberBinding
.STATIC
;
2579 var sym
= new
UnresolvedSymbol (null, "string", get_src (begin
));
2580 type
= new UnresolvedType
.from_symbol (sym
, get_src (begin
));
2581 type
.value_owned
= true;
2582 type
= new
ArrayType (type
, 1, get_src (begin
));
2583 type
.nullable
= false;
2585 var param
= new
FormalParameter ("args", type
, get_src (begin
));
2586 method
.add_parameter (param
);
2589 expect (TokenType
.EOL
);
2591 if (accept_block ()) {
2592 method
.body
= parse_block ();
2598 Method
parse_method_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2599 var begin
= get_location ();
2600 DataType type
= new
VoidType ();
2601 expect (TokenType
.DEF
);
2602 var flags
= parse_member_declaration_modifiers ();
2604 string id
= parse_identifier ();
2606 var params
= new ArrayList
<FormalParameter
> ();
2607 expect (TokenType
.OPEN_PARENS
);
2609 if (current () != TokenType
.CLOSE_PARENS
) {
2611 var param
= parse_parameter ();
2613 } while (accept (TokenType
.COMMA
));
2616 expect (TokenType
.CLOSE_PARENS
);
2619 /* deal with return value */
2620 if (accept (TokenType
.COLON
)) {
2621 type
= parse_type ();
2622 parse_type_parameter_list ();
2626 var method
= new
Method (id
, type
, get_src_com (begin
));
2627 if (ModifierFlags
.PRIVATE
in flags
) {
2628 method
.access
= SymbolAccessibility
.PRIVATE
;
2630 method
.access
= get_access (id
);
2634 set_attributes (method
, attrs
);
2636 foreach (FormalParameter param
in params
) {
2637 method
.add_parameter (param
);
2640 if (accept (TokenType
.RAISES
)) {
2642 method
.add_error_type (parse_type ());
2643 } while (accept (TokenType
.COMMA
));
2647 if (ModifierFlags
.STATIC
in flags
|| id
== "main") {
2648 method
.binding
= MemberBinding
.STATIC
;
2650 if (ModifierFlags
.ABSTRACT
in flags
) {
2651 method
.is_abstract
= true;
2653 if (ModifierFlags
.VIRTUAL
in flags
) {
2654 method
.is_virtual
= true;
2656 if (ModifierFlags
.OVERRIDE
in flags
) {
2657 method
.overrides
= true;
2659 if (ModifierFlags
.INLINE
in flags
) {
2660 method
.is_inline
= true;
2663 expect (TokenType
.EOL
);
2665 var body_location
= get_location ();
2668 /* "requires" and "ensures" if present will be at start of the method body */
2669 if (accept (TokenType
.INDENT
)) {
2670 if (accept (TokenType
.REQUIRES
)) {
2672 if (accept (TokenType
.EOL
) && accept (TokenType
.INDENT
)) {
2673 while (current() != TokenType
.DEDENT
) {
2674 method
.add_precondition (parse_expression ());
2675 expect (TokenType
.EOL
);
2678 expect (TokenType
.DEDENT
);
2679 accept_terminator ();
2682 method
.add_precondition (parse_expression ());
2683 expect_terminator ();
2689 if (accept (TokenType
.ENSURES
)) {
2690 if (accept (TokenType
.EOL
) && accept (TokenType
.INDENT
)) {
2691 while (current() != TokenType
.DEDENT
) {
2692 method
.add_postcondition (parse_expression ());
2693 expect (TokenType
.EOL
);
2696 expect (TokenType
.DEDENT
);
2697 accept_terminator ();
2699 method
.add_postcondition (parse_expression ());
2700 expect_terminator ();
2705 rollback (body_location
);
2708 if (accept_block ()) {
2709 method
.body
= parse_block ();
2714 Property
parse_property_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2715 var begin
= get_location ();
2716 var readonly = false;
2718 expect (TokenType
.PROP
);
2720 var flags
= parse_member_declaration_modifiers ();
2722 readonly = accept (TokenType
.READONLY
);
2724 string id
= parse_identifier ();
2725 expect (TokenType
.COLON
);
2727 bool is_weak
= accept (TokenType
.WEAK
);
2728 var type
= parse_type (false);
2730 var prop
= new
Property (id
, type
, null, null, get_src_com (begin
));
2731 if (ModifierFlags
.PRIVATE
in flags
) {
2732 prop
.access
= SymbolAccessibility
.PRIVATE
;
2734 prop
.access
= get_access (id
);
2737 set_attributes (prop
, attrs
);
2738 if (ModifierFlags
.ABSTRACT
in flags
) {
2739 prop
.is_abstract
= true;
2741 if (ModifierFlags
.VIRTUAL
in flags
) {
2742 prop
.is_virtual
= true;
2744 if (ModifierFlags
.OVERRIDE
in flags
) {
2745 prop
.overrides
= true;
2748 if (accept (TokenType
.ASSIGN
)) {
2749 prop
.default_expression
= parse_expression ();
2753 if (accept_block ()) {
2754 expect (TokenType
.INDENT
);
2755 while (current () != TokenType
.DEDENT
) {
2756 var accessor_begin
= get_location ();
2757 parse_attributes ();
2759 var value_type
= type
.copy ();
2760 value_type
.value_owned
= false;
2762 if (accept (TokenType
.GET
)) {
2763 if (prop
.get_accessor
!= null) {
2764 throw new ParseError
.SYNTAX (get_error ("property get accessor already defined"));
2767 if (accept_block ()) {
2768 block
= parse_block ();
2770 prop
.get_accessor
= new
PropertyAccessor (true, false, false, type
.copy (), block
, get_src (accessor_begin
));
2771 prop
.get_accessor
.access
= SymbolAccessibility
.PUBLIC
;
2773 bool _construct
= false;
2774 if (accept (TokenType
.SET
)) {
2776 throw new ParseError
.SYNTAX (get_error ("set block not allowed for a read only property"));
2778 _construct
= accept (TokenType
.CONSTRUCT
);
2779 } else if (accept (TokenType
.CONSTRUCT
)) {
2781 } else if (!accept (TokenType
.EOL
)) {
2782 throw new ParseError
.SYNTAX (get_error ("expected get, set, or construct"));
2785 if (prop
.set_accessor
!= null) {
2786 throw new ParseError
.SYNTAX (get_error ("property set accessor already defined"));
2790 if (accept_block ()) {
2791 block
= parse_block ();
2793 prop
.set_accessor
= new
PropertyAccessor (false, !readonly, _construct
, value_type
, block
, get_src (accessor_begin
));
2794 prop
.set_accessor
.access
= SymbolAccessibility
.PUBLIC
;
2797 accept (TokenType
.EOL
);
2798 expect (TokenType
.DEDENT
);
2800 var value_type
= type
.copy ();
2801 value_type
.value_owned
= false;
2803 prop
.get_accessor
= new
PropertyAccessor (true, false, false, value_type
, null, get_src (begin
));
2804 prop
.get_accessor
.access
= SymbolAccessibility
.PUBLIC
;
2807 value_type
= type
.copy ();
2808 value_type
.value_owned
= false;
2810 prop
.set_accessor
= new
PropertyAccessor (false, true, false, value_type
, null, get_src (begin
));
2811 prop
.set_accessor
.access
= SymbolAccessibility
.PUBLIC
;
2815 expect_terminator ();
2818 if (!prop
.is_abstract
&& !scanner
.source_file
.external_package
) {
2819 var needs_var
= (readonly && (prop
.get_accessor
!= null && prop
.get_accessor
.body
== null));
2822 needs_var
= (prop
.get_accessor
!= null && prop
.get_accessor
.body
== null) || (prop
.set_accessor
!= null && prop
.set_accessor
.body
== null);
2826 /* automatic property accessor body generation */
2827 var field_type
= prop
.property_type
.copy ();
2828 field_type
.value_owned
= !is_weak
;
2829 prop
.field
= new
Field ("_%s".printf (prop
.name
), field_type
, prop
.default_expression
, prop
.source_reference
);
2830 prop
.field
.access
= SymbolAccessibility
.PRIVATE
;
2837 Vala
.Signal
parse_signal_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2838 var begin
= get_location ();
2841 expect (TokenType
.EVENT
);
2842 var flags
= parse_member_declaration_modifiers ();
2843 string id
= parse_identifier ();
2846 var params
= new ArrayList
<FormalParameter
> ();
2848 expect (TokenType
.OPEN_PARENS
);
2849 if (current () != TokenType
.CLOSE_PARENS
) {
2851 var param
= parse_parameter ();
2853 } while (accept (TokenType
.COMMA
));
2855 expect (TokenType
.CLOSE_PARENS
);
2857 if (accept (TokenType
.COLON
)) {
2858 type
= parse_type ();
2860 type
= new
VoidType ();
2863 var sig
= new Vala
.Signal (id
, type
, get_src_com (begin
));
2864 if (ModifierFlags
.PRIVATE
in flags
) {
2865 sig
.access
= SymbolAccessibility
.PRIVATE
;
2867 sig
.access
= get_access (id
);
2870 if (ModifierFlags
.VIRTUAL
in flags
) {
2871 sig
.is_virtual
= true;
2874 set_attributes (sig
, attrs
);
2876 foreach (FormalParameter formal_param
in params
) {
2877 sig
.add_parameter (formal_param
);
2880 expect_terminator ();
2884 Constructor
parse_constructor_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2885 var begin
= get_location ();
2887 expect (TokenType
.INIT
);
2888 var flags
= parse_member_declaration_modifiers ();
2890 var c
= new
Constructor (get_src_com (begin
));
2891 if (ModifierFlags
.STATIC
in flags
) {
2892 c
.binding
= MemberBinding
.STATIC
;
2893 } else if (ModifierFlags
.CLASS
in flags
) {
2894 c
.binding
= MemberBinding
.CLASS
;
2898 c
.body
= parse_block ();
2902 Destructor
parse_destructor_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2903 var begin
= get_location ();
2904 expect (TokenType
.FINAL
);
2905 var d
= new
Destructor (get_src_com (begin
));
2907 d
.body
= parse_block ();
2911 Symbol
parse_struct_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2912 var begin
= get_location ();
2914 expect (TokenType
.STRUCT
);
2915 var flags
= parse_type_declaration_modifiers ();
2916 var sym
= parse_symbol_name ();
2917 var type_param_list
= parse_type_parameter_list ();
2918 DataType base_type
= null;
2919 if (accept (TokenType
.COLON
)) {
2920 base_type
= parse_type ();
2922 var st
= new
Struct (sym
.name
, get_src_com (begin
));
2923 if (ModifierFlags
.PRIVATE
in flags
) {
2924 st
.access
= SymbolAccessibility
.PRIVATE
;
2926 st
.access
= get_access (sym
.name
);
2928 set_attributes (st
, attrs
);
2929 foreach (TypeParameter type_param
in type_param_list
) {
2930 st
.add_type_parameter (type_param
);
2932 if (base_type
!= null) {
2933 st
.base_type
= base_type
;
2936 expect (TokenType
.EOL
);
2938 parse_declarations (st
);
2941 while (sym
.inner
!= null) {
2943 var ns
= new
Namespace (sym
.name
, st
.source_reference
);
2944 if (result is Namespace
) {
2945 ns
.add_namespace ((Namespace
) result
);
2947 ns
.add_struct ((Struct
) result
);
2948 scanner
.source_file
.add_node (result
);
2955 void parse_struct_member (Struct st
) throws ParseError
{
2956 var sym
= parse_declaration ();
2957 if (sym is Method
) {
2958 st
.add_method ((Method
) sym
);
2959 } else if (sym is Field
) {
2960 st
.add_field ((Field
) sym
);
2961 } else if (sym is Constant
) {
2962 st
.add_constant ((Constant
) sym
);
2964 Report
.error (sym
.source_reference
, "unexpected declaration in struct");
2968 Symbol
parse_interface_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
2969 var begin
= get_location ();
2971 expect (TokenType
.INTERFACE
);
2972 var flags
= parse_type_declaration_modifiers ();
2973 var sym
= parse_symbol_name ();
2974 var type_param_list
= parse_type_parameter_list ();
2975 var base_types
= new ArrayList
<DataType
> ();
2976 if (accept (TokenType
.COLON
)) {
2978 base_types
.add (parse_type ());
2979 } while (accept (TokenType
.COMMA
));
2981 var iface
= new
Interface (sym
.name
, get_src_com (begin
));
2982 if (ModifierFlags
.PRIVATE
in flags
) {
2983 iface
.access
= SymbolAccessibility
.PRIVATE
;
2985 iface
.access
= get_access (sym
.name
);
2988 set_attributes (iface
, attrs
);
2989 foreach (TypeParameter type_param
in type_param_list
) {
2990 iface
.add_type_parameter (type_param
);
2992 foreach (DataType base_type
in base_types
) {
2993 iface
.add_prerequisite (base_type
);
2997 expect (TokenType
.EOL
);
2999 parse_declarations (iface
);
3002 Symbol result
= iface
;
3003 while (sym
.inner
!= null) {
3005 var ns
= new
Namespace (sym
.name
, iface
.source_reference
);
3006 if (result is Namespace
) {
3007 ns
.add_namespace ((Namespace
) result
);
3009 ns
.add_interface ((Interface
) result
);
3010 scanner
.source_file
.add_node (result
);
3017 void parse_interface_member (Interface iface
) throws ParseError
{
3018 var sym
= parse_declaration ();
3020 iface
.add_class ((Class
) sym
);
3021 } else if (sym is Struct
) {
3022 iface
.add_struct ((Struct
) sym
);
3023 } else if (sym is Enum
) {
3024 iface
.add_enum ((Enum
) sym
);
3025 } else if (sym is Delegate
) {
3026 iface
.add_delegate ((Delegate
) sym
);
3027 } else if (sym is Method
) {
3028 iface
.add_method ((Method
) sym
);
3029 } else if (sym is Vala
.Signal
) {
3030 iface
.add_signal ((Vala
.Signal
) sym
);
3031 } else if (sym is Field
) {
3032 iface
.add_field ((Field
) sym
);
3033 } else if (sym is Property
) {
3034 iface
.add_property ((Property
) sym
);
3036 Report
.error (sym
.source_reference
, "unexpected declaration in interface");
3040 Symbol
parse_enum_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
3041 var begin
= get_location ();
3042 expect (TokenType
.ENUM
);
3043 var flags
= parse_type_declaration_modifiers ();
3045 var sym
= parse_symbol_name ();
3046 var en
= new
Enum (sym
.name
, get_src_com (begin
));
3047 if (ModifierFlags
.PRIVATE
in flags
) {
3048 en
.access
= SymbolAccessibility
.PRIVATE
;
3050 en
.access
= get_access (sym
.name
);
3052 set_attributes (en
, attrs
);
3054 expect (TokenType
.EOL
);
3055 expect (TokenType
.INDENT
);
3057 if (current () == TokenType
.DEDENT
) {
3058 // allow trailing comma
3061 var value_attrs
= parse_attributes ();
3062 var value_begin
= get_location ();
3063 string id
= parse_identifier ();
3065 var ev
= new
EnumValue (id
, get_src (value_begin
));
3066 set_attributes (ev
, value_attrs
);
3068 if (accept (TokenType
.ASSIGN
)) {
3069 ev
.value
= parse_expression ();
3072 expect (TokenType
.EOL
);
3075 expect (TokenType
.DEDENT
);
3078 while (sym
.inner
!= null) {
3080 var ns
= new
Namespace (sym
.name
, en
.source_reference
);
3081 if (result is Namespace
) {
3082 ns
.add_namespace ((Namespace
) result
);
3084 ns
.add_enum ((Enum
) result
);
3085 scanner
.source_file
.add_node (result
);
3092 Symbol
parse_errordomain_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
3093 var begin
= get_location ();
3094 expect (TokenType
.ERRORDOMAIN
);
3095 var flags
= parse_type_declaration_modifiers ();
3097 var sym
= parse_symbol_name ();
3098 var ed
= new
ErrorDomain (sym
.name
, get_src_com (begin
));
3099 if (ModifierFlags
.PRIVATE
in flags
) {
3100 ed
.access
= SymbolAccessibility
.PRIVATE
;
3102 ed
.access
= get_access (sym
.name
);
3105 set_attributes (ed
, attrs
);
3107 expect (TokenType
.EOL
);
3108 expect (TokenType
.INDENT
);
3111 if (current () == TokenType
.DEDENT
) {
3112 // allow trailing comma
3115 var code_attrs
= parse_attributes ();
3116 string id
= parse_identifier ();
3118 var ec
= new
ErrorCode (id
);
3119 set_attributes (ec
, code_attrs
);
3120 if (accept (TokenType
.ASSIGN
)) {
3121 ec
.value
= parse_expression ();
3124 accept (TokenType
.EOL
);
3128 expect (TokenType
.DEDENT
);
3131 while (sym
.inner
!= null) {
3133 var ns
= new
Namespace (sym
.name
, ed
.source_reference
);
3135 if (result is Namespace
) {
3136 ns
.add_namespace ((Namespace
) result
);
3138 ns
.add_error_domain ((ErrorDomain
) result
);
3139 scanner
.source_file
.add_node (result
);
3146 ModifierFlags
parse_type_declaration_modifiers () {
3147 ModifierFlags flags
= 0;
3149 switch (current ()) {
3150 case TokenType
.ABSTRACT
:
3152 flags
|= ModifierFlags
.ABSTRACT
;
3155 case TokenType
.EXTERN
:
3157 flags
|= ModifierFlags
.EXTERN
;
3160 case TokenType
.STATIC
:
3162 flags
|= ModifierFlags
.STATIC
;
3165 case TokenType
.PRIVATE
:
3167 flags
|= ModifierFlags
.PRIVATE
;
3176 ModifierFlags
parse_member_declaration_modifiers () {
3177 ModifierFlags flags
= 0;
3179 switch (current ()) {
3180 case TokenType
.ABSTRACT
:
3182 flags
|= ModifierFlags
.ABSTRACT
;
3184 case TokenType
.CLASS
:
3186 flags
|= ModifierFlags
.CLASS
;
3188 case TokenType
.EXTERN
:
3190 flags
|= ModifierFlags
.EXTERN
;
3192 case TokenType
.INLINE
:
3194 flags
|= ModifierFlags
.INLINE
;
3196 case TokenType
.OVERRIDE
:
3198 flags
|= ModifierFlags
.OVERRIDE
;
3200 case TokenType
.STATIC
:
3202 flags
|= ModifierFlags
.STATIC
;
3204 case TokenType
.VIRTUAL
:
3206 flags
|= ModifierFlags
.VIRTUAL
;
3208 case TokenType
.PRIVATE
:
3210 flags
|= ModifierFlags
.PRIVATE
;
3218 FormalParameter
parse_parameter () throws ParseError
{
3219 var attrs
= parse_attributes ();
3220 var begin
= get_location ();
3221 if (accept (TokenType
.ELLIPSIS
)) {
3223 return new FormalParameter
.with_ellipsis (get_src (begin
));
3226 var direction
= ParameterDirection
.IN
;
3227 if (accept (TokenType
.OUT
)) {
3228 direction
= ParameterDirection
.OUT
;
3229 } else if (accept (TokenType
.REF
)) {
3230 direction
= ParameterDirection
.REF
;
3233 string id
= parse_identifier ();
3235 expect (TokenType
.COLON
);
3238 if (direction
== ParameterDirection
.IN
) {
3239 type
= parse_type (false);
3241 type
= parse_type (true);
3244 var param
= new
FormalParameter (id
, type
, get_src (begin
));
3245 set_attributes (param
, attrs
);
3246 param
.direction
= direction
;
3247 if (accept (TokenType
.ASSIGN
)) {
3248 param
.default_expression
= parse_expression ();
3253 CreationMethod
parse_creation_method_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
3254 var begin
= get_location ();
3255 CreationMethod method
;
3257 expect (TokenType
.CONSTRUCT
);
3259 parse_member_declaration_modifiers ();
3262 if (accept (TokenType
.OPEN_PARENS
)) {
3263 /* create default name using class name */
3264 method
= new
CreationMethod (class_name
, null, get_src_com (begin
));
3266 var sym
= parse_symbol_name ();
3267 if (sym
.inner
== null) {
3269 if (sym
.name
!= class_name
) {
3270 method
= new
CreationMethod (class_name
, sym
.name
, get_src_com (begin
));
3272 method
= new
CreationMethod (sym
.name
, null, get_src_com (begin
));
3275 method
= new
CreationMethod (sym
.inner
.name
, sym
.name
, get_src_com (begin
));
3277 expect (TokenType
.OPEN_PARENS
);
3281 if (current () != TokenType
.CLOSE_PARENS
) {
3283 var param
= parse_parameter ();
3284 method
.add_parameter (param
);
3285 } while (accept (TokenType
.COMMA
));
3287 expect (TokenType
.CLOSE_PARENS
);
3288 if (accept (TokenType
.RAISES
)) {
3290 method
.add_error_type (parse_type ());
3291 } while (accept (TokenType
.COMMA
));
3293 method
.access
= SymbolAccessibility
.PUBLIC
;
3294 set_attributes (method
, attrs
);
3295 method
.binding
= MemberBinding
.STATIC
;
3297 if (accept_block ()) {
3298 method
.body
= parse_block ();
3304 Symbol
parse_delegate_declaration (Gee
.List
<Attribute
>? attrs
) throws ParseError
{
3305 var begin
= get_location ();
3308 expect (TokenType
.DELEGATE
);
3310 var flags
= parse_member_declaration_modifiers ();
3312 var sym
= parse_symbol_name ();
3314 var type_param_list
= parse_type_parameter_list ();
3317 var params
= new ArrayList
<FormalParameter
> ();
3319 expect (TokenType
.OPEN_PARENS
);
3320 if (current () != TokenType
.CLOSE_PARENS
) {
3322 var param
= parse_parameter ();
3324 } while (accept (TokenType
.COMMA
));
3326 expect (TokenType
.CLOSE_PARENS
);
3328 if (accept (TokenType
.COLON
)) {
3329 type
= parse_type ();
3332 type
= new
VoidType ();
3335 if (accept (TokenType
.RAISES
)) {
3338 } while (accept (TokenType
.COMMA
));
3341 expect_terminator ();
3343 var d
= new
Delegate (sym
.name
, type
, get_src_com (begin
));
3344 if (ModifierFlags
.PRIVATE
in flags
) {
3345 d
.access
= SymbolAccessibility
.PRIVATE
;
3347 d
.access
= get_access (sym
.name
);
3350 set_attributes (d
, attrs
);
3352 foreach (TypeParameter type_param
in type_param_list
) {
3353 d
.add_type_parameter (type_param
);
3356 foreach (FormalParameter formal_param
in params
) {
3357 d
.add_parameter (formal_param
);
3360 if (!(ModifierFlags
.STATIC
in flags
)) {
3361 d
.has_target
= true;
3366 while (sym
.inner
!= null) {
3368 var ns
= new
Namespace (sym
.name
, d
.source_reference
);
3370 if (result is Namespace
) {
3371 ns
.add_namespace ((Namespace
) result
);
3373 ns
.add_delegate ((Delegate
) result
);
3374 scanner
.source_file
.add_node (result
);
3381 Gee
.List
<TypeParameter
> parse_type_parameter_list () throws ParseError
{
3382 var list
= new ArrayList
<TypeParameter
> ();
3383 if (accept (TokenType
.OF
)) {
3385 var begin
= get_location ();
3386 string id
= parse_identifier ();
3387 list
.add (new
TypeParameter (id
, get_src (begin
)));
3388 } while (accept (TokenType
.COMMA
));
3394 void skip_type_argument_list () throws ParseError
{
3395 if (accept (TokenType
.OF
)) {
3398 } while (accept (TokenType
.COMMA
));
3402 // try to parse type argument list
3403 Gee
.List
<DataType
>?
parse_type_argument_list (bool maybe_expression
) throws ParseError
{
3404 var begin
= get_location ();
3405 if (accept (TokenType
.OF
)) {
3406 var list
= new ArrayList
<DataType
> ();
3408 switch (current ()) {
3409 case TokenType
.VOID
:
3410 case TokenType
.DYNAMIC
:
3411 case TokenType
.WEAK
:
3412 case TokenType
.IDENTIFIER
:
3413 var type
= parse_type ();
3421 } while (accept (TokenType
.COMMA
));
3428 MemberAccess
parse_member_name () throws ParseError
{
3429 var begin
= get_location ();
3430 MemberAccess expr
= null;
3432 string id
= parse_identifier ();
3433 Gee
.List
<DataType
> type_arg_list
= parse_type_argument_list (false);
3434 expr
= new
MemberAccess (expr
, id
, get_src (begin
));
3435 if (type_arg_list
!= null) {
3436 foreach (DataType type_arg
in type_arg_list
) {
3437 expr
.add_type_argument (type_arg
);
3440 } while (accept (TokenType
.DOT
));