From: Jürg Billeter Date: Thu, 30 Jul 2009 17:24:17 +0000 (+0200) Subject: Arrays: Change syntax for fixed-length arrays X-Git-Tag: 0.7.5~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5843b781;p=thirdparty%2Fvala.git Arrays: Change syntax for fixed-length arrays To clarify the difference to normal arrays and allow declaration of inline-allocated arrays of unknown length, the new syntax is: int array[3]; --- diff --git a/vala/valaarraytype.vala b/vala/valaarraytype.vala index 471155562..98f97c664 100644 --- a/vala/valaarraytype.vala +++ b/vala/valaarraytype.vala @@ -37,6 +37,10 @@ public class Vala.ArrayType : ReferenceType { } } + public bool invalid_syntax { get; set; } + + public bool inline_allocated { get; set; } + public bool fixed_length { get; set; } /** @@ -219,4 +223,13 @@ public class Vala.ArrayType : ReferenceType { public override Gee.List get_symbols () { return element_type.get_symbols (); } + + public override bool check (SemanticAnalyzer analyzer) { + if (invalid_syntax) { + Report.error (source_reference, "syntax error, no expression allowed between array brackets"); + error = true; + return false; + } + return element_type.check (analyzer); + } } diff --git a/vala/valaparser.vala b/vala/valaparser.vala index 93e5cbf32..ebf63c52f 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -365,6 +365,7 @@ public class Vala.Parser : CodeVisitor { accept (TokenType.INTERR); while (accept (TokenType.OPEN_BRACKET)) { do { + // required for decision between expression and declaration statement if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET) { parse_expression (); } @@ -422,21 +423,17 @@ public class Vala.Parser : CodeVisitor { // this is more logical, especially when nullable arrays // or pointers are involved while (accept (TokenType.OPEN_BRACKET)) { - int array_length = -1; + bool invalid_array = false; int array_rank = 0; do { array_rank++; - // support for stack-allocated arrays - // also required for decision between expression and declaration statement + // required for decision between expression and declaration statement if (current () != TokenType.COMMA && current () != TokenType.CLOSE_BRACKET) { - var length_expression = parse_expression (); - var length_literal = length_expression as IntegerLiteral; - if (length_literal != null) { - array_length = length_literal.value.to_int (); - } + parse_expression (); + // only used for parsing, reject use as real type + invalid_array = true; } - } - while (accept (TokenType.COMMA)); + } while (accept (TokenType.COMMA)); expect (TokenType.CLOSE_BRACKET); // arrays contain strong references by default @@ -444,12 +441,7 @@ public class Vala.Parser : CodeVisitor { var array_type = new ArrayType (type, array_rank, get_src (begin)); array_type.nullable = accept (TokenType.INTERR); - - if (array_rank == 1 && array_length > 0) { - // fixed length (stack-allocated) array - array_type.fixed_length = true; - array_type.length = array_length; - } + array_type.invalid_syntax = invalid_array; type = array_type; } @@ -472,6 +464,35 @@ public class Vala.Parser : CodeVisitor { return type; } + DataType? parse_inline_array_type (DataType? type) throws ParseError { + var begin = get_location (); + + // inline-allocated array + if (type != null && accept (TokenType.OPEN_BRACKET)) { + int array_length = -1; + + if (current () != TokenType.CLOSE_BRACKET) { + if (current () != TokenType.INTEGER_LITERAL) { + throw new ParseError.SYNTAX (get_error ("expected `]' or integer literal")); + } + + var length_literal = (IntegerLiteral) parse_literal (); + array_length = length_literal.value.to_int (); + } + expect (TokenType.CLOSE_BRACKET); + + var array_type = new ArrayType (type, 1, get_src (begin)); + array_type.inline_allocated = true; + if (array_length > 0) { + array_type.fixed_length = true; + array_type.length = array_length; + } + + return array_type; + } + return type; + } + Gee.List parse_argument_list () throws ParseError { var list = new ArrayList (); if (current () != TokenType.CLOSE_PARENS) { @@ -1431,11 +1452,14 @@ public class Vala.Parser : CodeVisitor { LocalVariable parse_local_variable (DataType? variable_type) throws ParseError { var begin = get_location (); string id = parse_identifier (); + + var type = parse_inline_array_type (variable_type); + Expression initializer = null; if (accept (TokenType.ASSIGN)) { initializer = parse_expression (); } - return new LocalVariable (variable_type, id, initializer, get_src_com (begin)); + return new LocalVariable (type, id, initializer, get_src_com (begin)); } Statement parse_expression_statement () throws ParseError { @@ -2087,6 +2111,9 @@ public class Vala.Parser : CodeVisitor { expect (TokenType.CONST); var type = parse_type (false); string id = parse_identifier (); + + type = parse_inline_array_type (type); + Expression initializer = null; if (accept (TokenType.ASSIGN)) { initializer = parse_expression (); @@ -2117,6 +2144,9 @@ public class Vala.Parser : CodeVisitor { var flags = parse_member_declaration_modifiers (); var type = parse_type (); string id = parse_identifier (); + + type = parse_inline_array_type (type); + var f = new Field (id, type, null, get_src_com (begin)); f.access = access; set_attributes (f, attrs);