Commit 5e2730eb authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter
Browse files

support casts to generic types support arrays of generic types don't take

2007-04-04  Jürg Billeter  <j@bitron.ch>

	* vala/scanner.l: support casts to generic types
	* vala/valasymbolresolver.vala, vala/valatypereference.vala: support
	  arrays of generic types
	* vala/valasymbolresolver.vala: don't take ownership of elements of weak
	  arrays
	* vala/valasemanticanalyzer.vala: accept uint as index value
	* vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala,
	  vala/valastatement.vala: minor cleanup of creation methods
	* vala/valacodegenerator.vala: support creation methods for structs, fix
	  pointer as return type
	* vapi/glib-2.0.vala: add CLAMP and g_spaced_primes_closest

svn path=/trunk/; revision=277
parent aa78885b
2007-04-04 Jürg Billeter <j@bitron.ch>
* vala/scanner.l: support casts to generic types
* vala/valasymbolresolver.vala, vala/valatypereference.vala: support
arrays of generic types
* vala/valasymbolresolver.vala: don't take ownership of elements of weak
arrays
* vala/valasemanticanalyzer.vala: accept uint as index value
* vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala,
vala/valastatement.vala: minor cleanup of creation methods
* vala/valacodegenerator.vala: support creation methods for structs, fix
pointer as return type
* vapi/glib-2.0.vala: add CLAMP and g_spaced_primes_closest
2007-04-03 Jürg Billeter <j@bitron.ch>
* vapi/math.vala: add mathematical functions, patch by
......
......@@ -73,7 +73,7 @@ literal ({integer_literal}|{real_literal}|{character_literal}|{string_literal
"{" { uploc; return OPEN_BRACE; }
"}" { uploc; return CLOSE_BRACE; }
"("{space}{ident}("."{ident})?("["{space}"]")*{space}")"{space}("("|{ident}|{literal}) { yyless (1); uploc; return OPEN_CAST_PARENS; }
"("{space}{ident}("."{ident})?("<"({ident}".")?{ident}">")?("["{space}"]")*{space}")"{space}("("|{ident}|{literal}) { yyless (1); uploc; return OPEN_CAST_PARENS; }
"(" { uploc; return OPEN_PARENS; }
")" { uploc; return CLOSE_PARENS; }
"[]" { uploc; return BRACKET_PAIR; }
......
......@@ -72,6 +72,7 @@ public class Vala.CodeGenerator : CodeVisitor {
HashTable<string,bool> predefined_marshal_list;
private int next_temp_var_id = 0;
private bool in_creation_method = false;
TypeReference bool_type;
TypeReference char_type;
......@@ -1211,7 +1212,7 @@ public class Vala.CodeGenerator : CodeVisitor {
} else {
ccheck.call = new CCodeIdentifier ("g_return_val_if_fail");
if (ret_type.is_reference_type ()) {
if (ret_type.is_reference_type () || ret_type is Pointer) {
ccheck.add_argument (new CCodeConstant ("NULL"));
} else if (ret_type.get_default_value () != null) {
ccheck.add_argument (new CCodeConstant (ret_type.get_default_value ()));
......@@ -1367,19 +1368,29 @@ public class Vala.CodeGenerator : CodeVisitor {
}
source_type_member_definition.append (function);
if (m is CreationMethod && current_class != null) {
// declare construction parameter array
var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
cparamsinit.add_argument (new CCodeConstant (((CreationMethod)m).n_construction_params.to_string ()));
var cdecl = new CCodeDeclaration ("GParameter *");
cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params", cparamsinit));
cinit.append (cdecl);
cdecl = new CCodeDeclaration ("GParameter *");
cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params_it", new CCodeIdentifier ("__params")));
cinit.append (cdecl);
if (m is CreationMethod) {
if (current_class != null) {
// declare construction parameter array
var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
cparamsinit.add_argument (new CCodeConstant (((CreationMethod)m).n_construction_params.to_string ()));
var cdecl = new CCodeDeclaration ("GParameter *");
cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params", cparamsinit));
cinit.append (cdecl);
cdecl = new CCodeDeclaration ("GParameter *");
cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params_it", new CCodeIdentifier ("__params")));
cinit.append (cdecl);
} else {
var st = (Struct) m.symbol.parent_symbol.node;
var cdecl = new CCodeDeclaration (st.get_cname () + "*");
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
ccall.add_argument (new CCodeConstant (st.get_cname ()));
ccall.add_argument (new CCodeConstant ("1"));
cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
cinit.append (cdecl);
}
}
if (context.module_init_method == m && in_plugin) {
......@@ -1470,9 +1481,16 @@ public class Vala.CodeGenerator : CodeVisitor {
public override void visit_begin_creation_method (CreationMethod! m) {
current_symbol = m.symbol;
current_return_type = m.return_type;
in_creation_method = true;
}
public override void visit_end_creation_method (CreationMethod! m) {
if (current_class != null && m.body != null) {
add_object_creation ((CCodeBlock) m.body.ccodenode);
}
in_creation_method = false;
visit_end_method (m);
}
......@@ -1959,17 +1977,9 @@ public class Vala.CodeGenerator : CodeVisitor {
decl.symbol.active = false;
}
bool in_construction = b.construction;
var cblock = new CCodeBlock ();
foreach (Statement stmt in b.get_statements ()) {
if (in_construction && !stmt.construction) {
// construction part of construction method ends here
add_object_creation (cblock);
in_construction = false;
}
var src = stmt.source_reference;
if (src != null && src.comment != null) {
cblock.add_statement (new CCodeComment (src.comment));
......@@ -1984,11 +1994,6 @@ public class Vala.CodeGenerator : CodeVisitor {
}
}
if (in_construction) {
// construction method doesn't contain non-construction parts
add_object_creation (cblock);
}
if (memory_management) {
foreach (VariableDeclarator decl in local_vars) {
if (decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
......@@ -3714,8 +3719,7 @@ public class Vala.CodeGenerator : CodeVisitor {
if (a.left.symbol_reference != null && a.left.symbol_reference.node is Property) {
var prop = (Property) a.left.symbol_reference.node;
if (ma.inner == null && a.parent_node is Statement &&
((Statement) a.parent_node).construction) {
if (current_class != null && ma.inner == null && in_creation_method) {
// this property is used as a construction parameter
var cpointer = new CCodeIdentifier ("__params_it");
......
......@@ -44,6 +44,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
TypeReference bool_type;
TypeReference string_type;
TypeReference int_type;
TypeReference uint_type;
TypeReference type_type;
DataType pointer_type;
DataType initially_unowned_type;
......@@ -73,6 +74,9 @@ public class Vala.SemanticAnalyzer : 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;
// TODO: don't require GLib namespace in semantic analyzer
var glib_ns = root_symbol.lookup ("GLib");
if (glib_ns != null) {
......@@ -405,10 +409,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
}
if (m.body != null) {
m.body.construction = true;
}
current_symbol = m.symbol;
current_return_type = m.return_type;
}
......@@ -416,17 +416,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
public override void visit_end_creation_method (CreationMethod! m) {
visit_end_method (m);
if (m.body != null) {
if (m.body != null && current_class != null) {
int n_params = 0;
foreach (Statement stmt in m.body.get_statements ()) {
int params = stmt.get_number_of_set_construction_parameters ();
if (params == -1) {
m.error = true;
Report.error (stmt.source_reference, "type creation methods only allow property assignment statements");
Report.error (stmt.source_reference, "class creation methods only allow property assignment statements");
return;
}
n_params += params;
stmt.construction = true;
}
m.n_construction_params = n_params;
}
......@@ -1381,9 +1380,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
/* check if the index is of type integer */
if (e.static_type.data_type != int_type.data_type) {
if (e.static_type.data_type != int_type.data_type && e.static_type.data_type != uint_type.data_type) {
expr.error = true;
Report.error (e.source_reference, "Expression of type `int' expected");
Report.error (e.source_reference, "Expression of type `int' or `uint` expected");
}
}
}
......
/* valastatement.vala
*
* Copyright (C) 2006 Jürg Billeter
* Copyright (C) 2006-2007 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -26,12 +26,6 @@ using GLib;
* Base class for all statement types.
*/
public abstract class Vala.Statement : CodeNode {
/**
* Specifies whether this statement is in the construction part
* of a construction method.
*/
public bool construction { get; set; }
/**
* Returns the number of construction parameters this statement sets in
* maximum or -1 if this statement may not be used in the construction
......
......@@ -220,10 +220,14 @@ public class Vala.SymbolResolver : CodeVisitor {
var element_type = new TypeReference ();
element_type.data_type = type.data_type;
element_type.type_parameter = type.type_parameter;
foreach (TypeReference type_arg in type.get_type_arguments ()) {
element_type.add_type_argument (type_arg);
}
type.remove_all_type_arguments ();
if (type.data_type != null) {
if (type.data_type.is_reference_type ()) {
element_type.takes_ownership = true;
element_type.takes_ownership = type.takes_ownership;
}
type.data_type = element_type.data_type.get_array (type.array_rank);
} else {
......
......@@ -180,7 +180,14 @@ public class Vala.TypeReference : CodeNode {
public ref List<weak TypeReference> get_type_arguments () {
return type_argument_list.copy ();
}
/**
* Removes all generic type arguments.
*/
public void remove_all_type_arguments () {
type_argument_list = null;
}
public override void accept (CodeVisitor! visitor) {
foreach (TypeReference type_arg in type_argument_list) {
type_arg.accept (visitor);
......
......@@ -60,6 +60,9 @@ public struct int {
[InstanceLast ()]
[CCode (cname = "g_strdup_printf")]
public ref string! to_string (string! format = "%i");
[CCode (cname = "CLAMP")]
public int clamp (int low, int high);
}
[CCode (cname = "guint", cheader_filename = "glib.h", type_id = "G_TYPE_UINT", marshaller_type_name = "UINT", get_value_function = "g_value_get_uint", set_value_function = "g_value_set_uint", default_value = "0U")]
......@@ -73,6 +76,9 @@ public struct uint {
[InstanceLast ()]
[CCode (cname = "g_strdup_printf")]
public ref string! to_string (string! format = "%u");
[CCode (cname = "CLAMP")]
public uint clamp (uint low, uint high);
}
[CCode (cname = "gshort", cheader_filename = "glib.h", default_value = "0")]
......@@ -1058,7 +1064,11 @@ namespace GLib {
[CCode (cname = "g_build_filename")]
public static ref string build_filename (string first_element, ...);
}
public static class SpacedPrimes {
public static uint closest (uint num);
}
/* Lexical Scanner */
[ReferenceType (free_function = "g_scanner_destroy")]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment