Commit 95829c0c authored by Raffaele Sandrini's avatar Raffaele Sandrini Committed by Raffaele Sandrini
Browse files

make those classes ready to process multidimensional arrays. remove

2006-08-11  Raffaele Sandrini  <rasa@gmx.ch>

        * vala/valasymbolresolver.vala, vala/valatypereference.vala,
          vala/valaelementaccess.vala, vala/valadatatype.vala, vala/parser.y,
          vala/valaarray.vala: make those classes ready to process
          multidimensional arrays.
        * vala/scanner.l: remove ARRAY_QUALIFIER token
        * vala/valasemanticanalyzer.vala, vala/parser.y,
          vala/valacodegenerator.vala, vala/valacodegenerator.vala,
          vala/valacodevisitor.vala: add multidimensional array support however
          only one dimensional arrays can be created yet
        * vala/Makefile.am, vala/vala.h: update
        * vala/valatypereference.vala: remove source reference parameter
          when creating from an expression
        * vala/valacodegenerator.vala: add support for uint, long and ulong
          properties


svn path=/trunk/; revision=100
parent 031af2cd
2006-08-11 Raffaele Sandrini <rasa@gmx.ch>
* vala/valasymbolresolver.vala, vala/valatypereference.vala,
vala/valaelementaccess.vala, vala/valadatatype.vala, vala/parser.y,
vala/valaarray.vala: make those classes ready to process
multidimensional arrays.
* vala/scanner.l: remove ARRAY_QUALIFIER token
* vala/valasemanticanalyzer.vala, vala/parser.y,
vala/valacodegenerator.vala, vala/valacodegenerator.vala,
vala/valacodevisitor.vala: add multidimensional array support however
only one dimensional arrays can be created yet
* vala/Makefile.am, vala/vala.h: update
* vala/valatypereference.vala: remove source reference parameter
when creating from an expression
* vala/valacodegenerator.vala: add support for uint, long and ulong
properties
2006-08-10 Jürg Billeter <j@bitron.ch>
* vala/scanner.l: support hexadecimal and octal integer literals,
......
......@@ -19,6 +19,9 @@ libvala_la_SOURCES = \
valaarray.c \
valaarray.h \
valaarray.vala \
valaarraycreationexpression.c \
valaarraycreationexpression.h \
valaarraycreationexpression.vala \
valaassignment.c \
valaassignment.h \
valaassignment.vala \
......@@ -290,6 +293,7 @@ valaincludedir = $(includedir)/vala-1.0/vala
valainclude_HEADERS = \
vala.h \
valaarray.h \
valaarraycreationexpression.h \
valaassignment.h \
valaattribute.h \
valaattributeprocessor.h \
......
......@@ -100,7 +100,6 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%token OPEN_PARENS "("
%token OPEN_CAST_PARENS "cast ("
%token CLOSE_PARENS ")"
%token ARRAY_QUALIFIER "[]"
%token OPEN_BRACKET "["
%token CLOSE_BRACKET "]"
%token ELLIPSIS "..."
......@@ -193,6 +192,8 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%token VIRTUAL "virtual"
%token WEAK "weak"
%token WHILE "while"
%token READ "read"
%token WRITE "write"
%token <str> IDENTIFIER "identifier"
%token <str> INTEGER_LITERAL "integer"
......@@ -210,11 +211,20 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%type <list> argument_list
%type <expression> argument
%type <expression> primary_expression
%type <expression> array_creation_expression
%type <list> size_specifier_list
%type <expression> opt_initializer
%type <num> opt_rank_specifier
%type <num> rank_specifier
%type <num> opt_comma_list
%type <num> comma_list
%type <expression> primary_no_array_creation_expression
%type <expression> simple_name
%type <expression> parenthesized_expression
%type <expression> member_access
%type <expression> invocation_expression
%type <expression> element_access
%type <list> expression_list
%type <expression> this_access
%type <expression> base_access
%type <expression> post_increment_expression
......@@ -303,8 +313,10 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%type <field> field_declaration
%type <list> variable_declarators
%type <variable_declarator> variable_declarator
%type <list> initializer_list
%type <expression> initializer
%type <list> opt_variable_initializer_list
%type <list> variable_initializer_list
%type <expression> variable_initializer
%type <method> method_declaration
%type <method> method_header
%type <statement> method_body
......@@ -443,55 +455,51 @@ type_name
;
type
: type_name opt_op_neg
: type_name opt_rank_specifier opt_op_neg
{
$$ = $1;
if ($2) {
vala_type_reference_set_array_rank ($$, $2);
if ($3) {
vala_type_reference_set_non_null ($$, TRUE);
}
}
| REF type_name opt_op_neg
| REF type_name opt_rank_specifier opt_op_neg
{
$$ = $2;
vala_type_reference_set_is_ref ($$, TRUE);
if ($3) {
vala_type_reference_set_array_rank ($$, $3);
if ($4) {
vala_type_reference_set_non_null ($$, TRUE);
}
}
| WEAK type_name opt_op_neg
| WEAK type_name opt_rank_specifier opt_op_neg
{
$$ = $2;
vala_type_reference_set_is_weak ($$, TRUE);
if ($3) {
vala_type_reference_set_array_rank ($$, $3);
if ($4) {
vala_type_reference_set_non_null ($$, TRUE);
}
}
| OUT type_name opt_op_neg
| OUT type_name opt_rank_specifier opt_op_neg
{
$$ = $2;
vala_type_reference_set_is_out ($$, TRUE);
if ($3) {
vala_type_reference_set_array_rank ($$, $3);
if ($4) {
vala_type_reference_set_non_null ($$, TRUE);
}
}
| OUT REF type_name opt_op_neg
| OUT REF type_name opt_rank_specifier opt_op_neg
{
$$ = $3;
vala_type_reference_set_is_ref ($$, TRUE);
vala_type_reference_set_is_out ($$, TRUE);
if ($4) {
vala_type_reference_set_array_rank ($$, $4);
if ($5) {
vala_type_reference_set_non_null ($$, TRUE);
}
}
| type array_qualifier
{
$$ = $1;
vala_type_reference_set_array ($$, TRUE);
}
;
array_qualifier
: ARRAY_QUALIFIER
;
opt_argument_list
......@@ -518,6 +526,91 @@ argument
;
primary_expression
: primary_no_array_creation_expression
| array_creation_expression
;
array_creation_expression
: NEW member_name size_specifier_list opt_initializer
{
GList *l;
ValaSourceReference *src = src(@2);
ValaTypeReference *t = vala_type_reference_new_from_expression (VALA_EXPRESSION ($2));
$$ = VALA_EXPRESSION (vala_array_creation_expression_new (t, g_list_length ($3), VALA_INITIALIZER_LIST ($4), src));
g_object_unref (t);
for (l = $3; l != NULL; l = l->next) {
vala_array_creation_expression_append_size (VALA_ARRAY_CREATION_EXPRESSION ($$), VALA_EXPRESSION (l->data));
g_object_unref (l->data);
}
g_list_free ($3);
g_object_unref (src);
g_object_unref ($2);
if ($4 != NULL) {
g_object_unref ($4);
}
}
| NEW member_name rank_specifier initializer
{
ValaSourceReference *src = src(@2);
ValaTypeReference *t = vala_type_reference_new_from_expression (VALA_EXPRESSION ($2));
$$ = VALA_EXPRESSION (vala_array_creation_expression_new (t, $3, VALA_INITIALIZER_LIST (4), src));
g_object_unref (t);
g_object_unref (src);
g_object_unref ($2);
g_object_unref ($4);
}
;
size_specifier_list
: OPEN_BRACKET expression_list CLOSE_BRACKET
{
$$ = $2;
}
;
opt_initializer
: /* empty */
{
$$ = NULL;
}
| initializer
;
opt_rank_specifier
: /* empty */
{
$$ = 0;
}
| rank_specifier
;
rank_specifier
: OPEN_BRACKET opt_comma_list CLOSE_BRACKET
{
$$ = $2;
}
;
opt_comma_list
: /* empty */
{
$$ = 1;
}
| comma_list
;
comma_list
: COMMA
{
$$ = 1;
}
| comma_list COMMA
{
$$ = $1 + 1;
}
;
primary_no_array_creation_expression
: literal
{
ValaSourceReference *src = src(@1);
......@@ -607,17 +700,31 @@ invocation_expression
;
element_access
: primary_expression OPEN_BRACKET expression CLOSE_BRACKET
: primary_no_array_creation_expression OPEN_BRACKET expression_list CLOSE_BRACKET
{
GList *l;
ValaSourceReference *src = src(@1);
$$ = VALA_EXPRESSION (vala_element_access_new ($1, $3, src));
g_object_unref ($1);
if ($3 != NULL) {
g_object_unref ($3);
$$ = VALA_EXPRESSION (vala_element_access_new ($1, src));
for (l = $3; l != NULL; l = l->next) {
vala_element_access_append_index (VALA_ELEMENT_ACCESS ($$), VALA_EXPRESSION (l->data));
g_object_unref (l->data);
}
g_list_free ($3);
g_object_unref ($1);
g_object_unref (src);
}
;
expression_list
: expression
{
$$ = g_list_append (NULL, $1);
}
| expression_list COMMA expression
{
$$ = g_list_append ($1, $3);
}
;
this_access
: THIS
......@@ -661,7 +768,7 @@ object_creation_expression
: NEW member_name open_parens opt_argument_list CLOSE_PARENS
{
ValaSourceReference *src = src(@2);
ValaObjectCreationExpression *expr = vala_object_creation_expression_new ($2, src);
ValaObjectCreationExpression *expr = vala_object_creation_expression_new (VALA_MEMBER_ACCESS ($2), src);
g_object_unref ($2);
g_object_unref (src);
......@@ -1210,7 +1317,7 @@ local_variable_type
: primary_expression opt_op_neg
{
ValaSourceReference *src = src(@1);
$$ = vala_type_reference_new_from_expression ($1, src);
$$ = vala_type_reference_new_from_expression ($1);
g_object_unref ($1);
g_object_unref (src);
if ($2) {
......@@ -1220,7 +1327,7 @@ local_variable_type
| REF primary_expression opt_op_neg
{
ValaSourceReference *src = src(@2);
$$ = vala_type_reference_new_from_expression ($2, src);
$$ = vala_type_reference_new_from_expression ($2);
g_object_unref ($2);
g_object_unref (src);
vala_type_reference_set_takes_ownership ($$, TRUE);
......@@ -1228,11 +1335,6 @@ local_variable_type
vala_type_reference_set_non_null ($$, TRUE);
}
}
| local_variable_type array_qualifier
{
$$ = $1;
vala_type_reference_set_array ($$, TRUE);
}
;
opt_op_neg
......@@ -2069,7 +2171,7 @@ variable_declarator
g_object_unref (src);
g_free ($1);
}
| IDENTIFIER ASSIGN initializer
| IDENTIFIER ASSIGN variable_initializer
{
ValaSourceReference *src = src(@1);
$$ = vala_variable_declarator_new ($1, $3, src);
......@@ -2079,20 +2181,8 @@ variable_declarator
}
;
initializer_list
: initializer
{
$$ = g_list_append (NULL, $1);
}
| initializer_list COMMA initializer
{
$$ = g_list_append ($1, $3);
}
;
initializer
: expression
| OPEN_BRACE initializer_list CLOSE_BRACE
: OPEN_BRACE opt_variable_initializer_list CLOSE_BRACE
{
ValaSourceReference *src = src(@1);
$$ = VALA_EXPRESSION (vala_initializer_list_new (src));
......@@ -2108,11 +2198,35 @@ initializer
}
;
opt_variable_initializer_list
: /* empty */
{
$$ = NULL;
}
| variable_initializer_list
;
variable_initializer_list
: variable_initializer
{
$$ = g_list_append (NULL, $1);
}
| variable_initializer_list COMMA variable_initializer
{
$$ = g_list_append ($1, $3);
}
;
variable_initializer
: expression
| initializer
;
method_declaration
: method_header method_body
{
$$ = $1;
vala_method_set_body ($$, $2);
vala_method_set_body ($$, VALA_BLOCK($2));
if ($2 != NULL) {
g_object_unref ($2);
}
......
......@@ -74,7 +74,6 @@ literal ({integer_literal}|{real_literal}|{character_literal}|{string_literal
"("{space}{ident}("."{ident})?("["{space}"]")*{space}")"{space}("("|{ident}|{literal}) { yyless (1); uploc; return OPEN_CAST_PARENS; }
"(" { uploc; return OPEN_PARENS; }
")" { uploc; return CLOSE_PARENS; }
"["{space}"]" { uploc; return ARRAY_QUALIFIER; }
"[" { uploc; return OPEN_BRACKET; }
"]" { uploc; return CLOSE_BRACKET; }
"..." { uploc; return ELLIPSIS; }
......
......@@ -65,3 +65,4 @@
#include <vala/valaunaryexpression.h>
#include <vala/valavariabledeclarator.h>
#include <vala/valawhilestatement.h>
#include <vala/valaarraycreationexpression.h>
......@@ -32,14 +32,41 @@ public class Vala.Array : DataType {
*/
public DataType! element_type { get; set construct; }
/**
* The rank of this array.
*/
public int rank { get; set construct; }
private string cname;
public construct (DataType! type) {
element_type = type;
public construct (DataType _element_type, int _rank) {
rank = _rank;
element_type = _element_type;
if (_rank < 1) {
Report.error (null, "internal: attempt to create an array with rank smaller than 1");
}
}
Array () {
name = "%s[]".printf (element_type.name);
/* FIXME: this implementation raises compiler bugs
string commas = "";
int i = rank - 1;
while (i > 0) {
string += ",";
i--;
}
name = "%s[%s]".printf (element_type.name, commas); */
int i = rank - 1;
name = "%s[".printf (element_type.name);
while (i > 0) {
name = "%s,".printf (name);
i--;
}
name = "%s]".printf (name);
}
/**
......
/* valaarraycreationexpression.vala
*
* Copyright (C) 2006 Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author:
* Raffaele Sandrini <rasa@gmx.ch>
*/
using GLib;
/**
* Represents an array creation expression e.g. "new int[] {1,2,3}".
*/
public class Vala.ArrayCreationExpression : Expression {
/**
* The type of the elements of the array.
*/
public TypeReference element_type { get; set construct; }
/**
* The rank of the array.
*/
public int rank { get; set construct; }
/**
* The size for each dimension ascending from left to right.
*/
private List<Expression> sizes;
/**
* The root array initializer list.
*/
public InitializerList initializer_list { get; set construct; }
/**
* Add a size expression.
*/
public void append_size (Expression! size) {
sizes.append (size);
}
/**
* Get the sizes for all dimensions ascending from left to right.
*/
public ref List<Expression> get_sizes () {
return sizes.copy ();
}
public construct (TypeReference _element_type, int _rank, InitializerList _initializer, SourceReference source) {
element_type = _element_type;
rank = _rank;
initializer_list = _initializer;
source_reference = source;
}
public override void accept (CodeVisitor! visitor) {
if (element_type != null) {
element_type.accept (visitor);
}
if (sizes != null) {
foreach (Expression e in sizes) {
e.accept (visitor);
}
}
visitor.visit_begin_array_creation_expression (this);
if (initializer_list != null) {
initializer_list.accept (visitor);
}
visitor.visit_end_array_creation_expression (this);
}
}
......@@ -64,6 +64,9 @@ public class Vala.CodeGenerator : CodeVisitor {
TypeReference bool_type;
TypeReference int_type;
TypeReference uint_type;
TypeReference long_type;
TypeReference ulong_type;
TypeReference string_type;
TypeReference float_type;
TypeReference double_type;
......@@ -89,6 +92,15 @@ public class Vala.CodeGenerator : CodeVisitor {
int_type = new TypeReference ();
int_type.data_type = (DataType) root_symbol.lookup ("int").node;
uint_type = new TypeReference ();
uint_type.data_type = (DataType) root_symbol.lookup ("uint").node;
long_type = new TypeReference ();
long_type.data_type = (DataType) root_symbol.lookup ("long").node;
ulong_type = new TypeReference ();
ulong_type.data_type = (DataType) root_symbol.lookup ("ulong").node;
float_type = new TypeReference ();
float_type.data_type = (DataType) root_symbol.lookup ("float").node;
......@@ -400,6 +412,21 @@ public class Vala.CodeGenerator : CodeVisitor {
cspec.add_argument (new CCodeConstant ("G_MININT"));
cspec.add_argument (new CCodeConstant ("G_MAXINT"));
cspec.add_argument (new CCodeConstant ("0"));
} else if (prop.type_reference.data_type == uint_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_uint");
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
cspec.add_argument (new CCodeConstant ("0"));
} else if (prop.type_reference.data_type == long_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_long");
cspec.add_argument (new CCodeConstant ("G_MINLONG"));
cspec.add_argument (new CCodeConstant ("G_MAXLONG"));
cspec.add_argument (new CCodeConstant ("0"));
} else if (prop.type_reference.data_type == ulong_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_ulong");
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXULONG"));
cspec.add_argument (new CCodeConstant ("0"));
} else if (prop.type_reference.data_type == bool_type.data_type) {
cspec.call = new CCodeIdentifier ("g_param_spec_boolean");
cspec.add_argument (new CCodeConstant ("FALSE"));
......@@ -621,9 +648,15 @@ public class Vala.CodeGenerator : CodeVisitor {
return new CCodeIdentifier ("g_value_set_object");
} else if (type_reference.data_type == string_type.data_type) {
return new CCodeIdentifier ("g_value_set_string");
} else if (type_reference.type_name == "int"
} else if (type_reference.data_type == int_type.data_type
|| type_reference.data_type is Enum) {
return new CCodeIdentifier ("g_value_set_int");
} else if (type_reference.data_type == uint_type.data_type) {
return new CCodeIdentifier ("g_value_set_uint");
} else if (type_reference.data_type == long_type.data_type) {
return new CCodeIdentifier ("g_value_set_long");
} else if (type_reference.data_type == ulong_type.data_type) {
return new CCodeIdentifier ("g_value_set_ulong");
} else if (type_reference.data_type == bool_type.data_type) {
return new CCodeIdentifier ("g_value_set_boolean");
} else if (type_reference.data_type == float_type.data_type) {
......@@ -707,9 +740,14 @@ public class Vala.CodeGenerator : CodeVisitor {
cgetcall.call = new CCodeIdentifier ("g_value_get_object");
} else if (prop.type_reference.type_name == "string") {
cgetcall.call = new CCodeIdentifier ("g_value_get_string");
} else if (prop.type_reference.type_name == "int"
|| prop.type_reference.data_type is Enum) {
} else if (prop.type_reference.type_name == "int" || prop.type_reference.data_type is Enum) {
cgetcall.call = new CCodeIdentifier ("g_value_get_int");
} else if (prop.type_reference.type_name == "uint") {
cgetcall.call = new CCodeIdentifier ("g_value_get_uint");
} else if (prop.type_reference.type_name == "long") {
cgetcall.call = new CCodeIdentifier ("g_value_get_long");
} else if (prop.type_reference.type_name == "ulong") {
cgetcall.call = new CCodeIdentifier ("g_value_get_ulong");
} else if (prop.type_reference.type_name == "bool") {
cgetcall.call = new CCodeIdentifier ("g_value_get_boolean");
} else if (prop.type_reference.type_name == "float") {
......@@ -895,7 +933,7 @@ public class Vala.CodeGenerator : CodeVisitor {
ccheck.add_argument (new CCodeConstant ("NULL"));
} else if (ret_type.name == "bool") {
ccheck.add_argument (new CCodeConstant ("FALSE"));
} else if (ret_type.name == "int" || ret_type.name == "long" || ret_type.name == "double" || ret_type.name == "float" || ret_type is Enum || ret_type is Flags) {
} else if (ret_type.name == "int" || ret_type.name == "long" || ret_type.name == "double" || ret_type.name == "float" || ret_type.name == "uint" || ret_type.name == "ulong" || ret_type is Enum || ret_type is Flags) {
ccheck.add_argument (new CCodeConstant ("0"));
} else {
Report.error (method_node.source_reference, "not supported return type for runtime type checks");
......@@ -1314,12 +1352,16 @@ public class Vala.CodeGenerator : CodeVisitor {
decl.symbol.active = true;
}
public override void visit_initializer_list (InitializerList! list) {
var clist = new CCodeInitializerList ();
foreach (Expression expr in list.get_initializers ()) {