From: Jamie McCracken Date: Thu, 29 May 2008 02:55:18 +0000 (+0000) Subject: Revamped array syntax X-Git-Tag: VALA_0_3_3~82 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=caae225c4d1a71e9450e10afd202e44bd39eaebf;p=platform%2Fupstream%2Fvala.git Revamped array syntax 2008-05-29 Jamie McCracken * vala/valagenietokentype.vala: * vala/valageniescanner.vala: * vala/valagenieparser.vala: Revamped array syntax svn path=/trunk/; revision=1476 --- diff --git a/ChangeLog b/ChangeLog index d839f12..1c4ccbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-05-29 Jamie McCracken + + * vala/valagenietokentype.vala: + * vala/valageniescanner.vala: + * vala/valagenieparser.vala: + + Revamped array syntax + + 2008-05-29 Jürg Billeter * vala/valainterfacewriter.vala: diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala index 2c8410a..f3bd1b9 100644 --- a/vala/valagenieparser.vala +++ b/vala/valagenieparser.vala @@ -339,7 +339,7 @@ public class Vala.Genie.Parser : CodeVisitor { public void parse_file (SourceFile source_file) { scanner = new Scanner (source_file); - + scanner.indent_spaces = 0; index = -1; size = 0; @@ -395,6 +395,11 @@ public class Vala.Genie.Parser : CodeVisitor { accept (TokenType.DYNAMIC); accept (TokenType.WEAK); + + if (accept (TokenType.ARRAY)) { + accept (TokenType.OF); + } + skip_symbol_name (); skip_type_argument_list (); while (accept (TokenType.OPEN_BRACKET)) { @@ -427,6 +432,14 @@ public class Vala.Genie.Parser : CodeVisitor { value_owned = !accept (TokenType.WEAK); } + /* handle arrays */ + bool is_array = false; + + if (accept (TokenType.ARRAY)) { + expect (TokenType.OF); + is_array = true; + } + var sym = parse_symbol_name (); Gee.List type_arg_list = parse_type_argument_list (false); @@ -445,24 +458,36 @@ public class Vala.Genie.Parser : CodeVisitor { type.nullable = accept (TokenType.INTERR); } - while (accept (TokenType.OPEN_BRACKET)) { - int array_rank = 0; - do { - array_rank++; - // support for stack-allocated arrays - // also required for decision between expression and declaration statement - if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET) { - parse_expression (); + if (is_array) { + + if (!accept (TokenType.OPEN_BRACKET)) { + type.value_owned = true; + type = new ArrayType (type, 1, get_src (begin)); + type.nullable = accept (TokenType.INTERR); + + } else { + prev (); + + while (accept (TokenType.OPEN_BRACKET)) { + int array_rank = 0; + do { + array_rank++; + // support for stack-allocated arrays + // also required for decision between expression and declaration statement + if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET) { + parse_expression (); + } + } + while (accept (TokenType.COMMA)); + expect (TokenType.CLOSE_BRACKET); + + type.value_owned = true; + type = new ArrayType (type, array_rank, get_src (begin)); + type.nullable = accept (TokenType.INTERR); } } - while (accept (TokenType.COMMA)); - expect (TokenType.CLOSE_BRACKET); - - type.value_owned = true; - type = new ArrayType (type, array_rank, get_src (begin)); - type.nullable = accept (TokenType.INTERR); } - + if (!owned_by_default) { value_owned = accept (TokenType.HASH); } @@ -782,13 +807,18 @@ public class Vala.Genie.Parser : CodeVisitor { Expression parse_object_or_array_creation_expression () throws ParseError { var begin = get_location (); expect (TokenType.NEW); + + if (accept (TokenType.ARRAY)) { + expect (TokenType.OF); + var m = parse_member_name (); + var expr = parse_array_creation_expression (begin, m); + return expr; + } + var member = parse_member_name (); if (accept (TokenType.OPEN_PARENS)) { var expr = parse_object_creation_expression (begin, member); return expr; - } else if (accept (TokenType.OPEN_BRACKET)) { - var expr = parse_array_creation_expression (begin, member); - return expr; } else { throw new ParseError.SYNTAX (get_error ("expected ( or [")); } @@ -815,6 +845,9 @@ public class Vala.Genie.Parser : CodeVisitor { Gee.List size_specifier_list; bool first = true; DataType element_type = UnresolvedType.new_from_expression (member); + + var has_bracket = accept (TokenType.OPEN_BRACKET); + do { if (!first) { // array of arrays: new T[][42] @@ -826,17 +859,21 @@ public class Vala.Genie.Parser : CodeVisitor { size_specifier_list = new ArrayList (); do { Expression size = null; - if (current () != TokenType.CLOSE_BRACKET && current () != TokenType.COMMA) { + if (has_bracket && current () != TokenType.CLOSE_BRACKET && current () != TokenType.COMMA) { size = parse_expression (); size_specified = true; } size_specifier_list.add (size); } while (accept (TokenType.COMMA)); - expect (TokenType.CLOSE_BRACKET); + + if (has_bracket) { + expect (TokenType.CLOSE_BRACKET); + } } while (accept (TokenType.OPEN_BRACKET)); InitializerList initializer = null; - if (current () == TokenType.OPEN_BRACE) { + if (accept (TokenType.ASSIGN)) { + initializer = parse_initializer (); } var expr = new ArrayCreationExpression (element_type, size_specifier_list.size, initializer, get_src (begin)); @@ -1615,6 +1652,10 @@ public class Vala.Genie.Parser : CodeVisitor { Expression initializer = null; if (accept (TokenType.ASSIGN)) { initializer = parse_variable_initializer (); + var array_type = variable_type as ArrayType; + if (array_type != null && initializer is InitializerList) { + initializer = new ArrayCreationExpression (array_type.element_type.copy (), array_type.rank, (InitializerList) initializer, initializer.source_reference); + } } return new LocalVariable (variable_type, id, initializer, get_src_com (begin)); } @@ -2227,9 +2268,13 @@ public class Vala.Genie.Parser : CodeVisitor { var type_param_list = parse_type_parameter_list (); var base_types = new ArrayList (); if (accept (TokenType.COLON)) { - do { - base_types.add (parse_type ()); - } while (accept (TokenType.COMMA)); + base_types.add (parse_type ()); + + if (accept (TokenType.IMPLEMENTS)) { + do { + base_types.add (parse_type ()); + } while (accept (TokenType.COMMA)); + } } accept (TokenType.EOL); @@ -2391,19 +2436,45 @@ public class Vala.Genie.Parser : CodeVisitor { InitializerList parse_initializer () throws ParseError { var begin = get_location (); - expect (TokenType.OPEN_BRACE); + if (!accept (TokenType.OPEN_PARENS)) { + expect (TokenType.OPEN_BRACE); + } var initializer = new InitializerList (get_src (begin)); if (current () != TokenType.DEDENT) { do { initializer.append (parse_variable_initializer ()); } while (accept (TokenType.COMMA)); } - expect (TokenType.CLOSE_BRACE); + if (!accept (TokenType.CLOSE_PARENS)) { + expect (TokenType.CLOSE_BRACE); + } return initializer; } + + bool is_initializer () throws ParseError { + if (current () == TokenType.OPEN_BRACE) { + return true; + } + + if (current () == TokenType.OPEN_PARENS) { + var begin = get_location (); + var is_array = false; + + next (); + + var expr = parse_expression (); + is_array = (accept (TokenType.COMMA)); + + rollback (begin); + + return is_array; + } + return false; + } + Expression parse_variable_initializer () throws ParseError { - if (current () == TokenType.OPEN_BRACE) { + if (is_initializer ()) { var expr = parse_initializer (); return expr; } else { diff --git a/vala/valageniescanner.vala b/vala/valageniescanner.vala index d7410bb..a46046f 100644 --- a/vala/valageniescanner.vala +++ b/vala/valageniescanner.vala @@ -210,6 +210,9 @@ public class Vala.Genie.Scanner : Object { break; case 5: switch (begin[0]) { + case 'a': + if (matches (begin, "array")) return TokenType.ARRAY; + break; case 'b': if (matches (begin, "break")) return TokenType.BREAK; break; @@ -401,7 +404,13 @@ public class Vala.Genie.Scanner : Object { break; } break; - + case 10: + switch (begin[0]) { + case 'i': + if (matches (begin, "implements")) return TokenType.IMPLEMENTS; + break; + } + break; } return TokenType.IDENTIFIER; } diff --git a/vala/valagenietokentype.vala b/vala/valagenietokentype.vala index 7f95cf4..ef2c1b5 100644 --- a/vala/valagenietokentype.vala +++ b/vala/valagenietokentype.vala @@ -26,6 +26,7 @@ using GLib; public enum Vala.Genie.TokenType { NONE, ABSTRACT, + ARRAY, AS, ASSERT, ASSIGN, @@ -82,6 +83,7 @@ public enum Vala.Genie.TokenType { HASH, IDENTIFIER, IF, + IMPLEMENTS, IN, INDENT, INIT, @@ -158,6 +160,7 @@ public enum Vala.Genie.TokenType { public weak string to_string () { switch (this) { case ABSTRACT: return "`abstract'"; + case ARRAY: return "`array'"; case AS: return "`as'"; case ASSERT: return "`assert'"; case ASSIGN: return "`='"; @@ -214,6 +217,7 @@ public enum Vala.Genie.TokenType { case HASH: return "`hash'"; case IDENTIFIER: return "identifier"; case IF: return "`if'"; + case IMPLEMENTS: return "`implements'"; case IN: return "`in'"; case INDENT: return "`tab indent'"; case INIT: return "`init'";