vala r2009 - in trunk: . vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r2009 - in trunk: . vala
- Date: Mon, 10 Nov 2008 18:56:28 +0000 (UTC)
Author: juergbi
Date: Mon Nov 10 18:56:28 2008
New Revision: 2009
URL: http://svn.gnome.org/viewvc/vala?rev=2009&view=rev
Log:
2008-11-10 JÃrg Billeter <j bitron ch>
* vala/valaaddressofexpression.vala:
* vala/valabaseaccess.vala:
* vala/valabooleanliteral.vala:
* vala/valacastexpression.vala:
* vala/valacharacterliteral.vala:
* vala/valaconditionalexpression.vala:
* vala/valaintegerliteral.vala:
* vala/valalambdaexpression.vala:
* vala/valanullliteral.vala:
* vala/valaobjectcreationexpression.vala:
* vala/valaparenthesizedexpression.vala:
* vala/valapointerindirection.vala:
* vala/valapostfixexpression.vala:
* vala/valarealliteral.vala:
* vala/valareferencetransferexpression.vala:
* vala/valasemanticanalyzer.vala:
* vala/valasizeofexpression.vala:
* vala/valastringliteral.vala:
* vala/valatypecheck.vala:
* vala/valatypeofexpression.vala:
* vala/valaunaryexpression.vala:
Move expression checking to code nodes
Modified:
trunk/ChangeLog
trunk/vala/valaaddressofexpression.vala
trunk/vala/valabaseaccess.vala
trunk/vala/valabooleanliteral.vala
trunk/vala/valacastexpression.vala
trunk/vala/valacharacterliteral.vala
trunk/vala/valaconditionalexpression.vala
trunk/vala/valaintegerliteral.vala
trunk/vala/valalambdaexpression.vala
trunk/vala/valanullliteral.vala
trunk/vala/valaobjectcreationexpression.vala
trunk/vala/valaparenthesizedexpression.vala
trunk/vala/valapointerindirection.vala
trunk/vala/valapostfixexpression.vala
trunk/vala/valarealliteral.vala
trunk/vala/valareferencetransferexpression.vala
trunk/vala/valasemanticanalyzer.vala
trunk/vala/valasizeofexpression.vala
trunk/vala/valastringliteral.vala
trunk/vala/valatypecheck.vala
trunk/vala/valatypeofexpression.vala
trunk/vala/valaunaryexpression.vala
Modified: trunk/vala/valaaddressofexpression.vala
==============================================================================
--- trunk/vala/valaaddressofexpression.vala (original)
+++ trunk/vala/valaaddressofexpression.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valaaddressofexpression.vala
*
- * Copyright (C) 2007 JÃrg Billeter
+ * Copyright (C) 2007-2008 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
@@ -69,4 +69,31 @@
public override bool is_pure () {
return inner.is_pure ();
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ if (inner.error) {
+ return false;
+ }
+ if (!(inner.value_type is ValueType
+ || inner.value_type is ObjectType
+ || inner.value_type is PointerType)) {
+ error = true;
+ Report.error (source_reference, "Address-of operator not supported for this expression");
+ return false;
+ }
+
+ if (inner.value_type.is_reference_type_or_type_parameter ()) {
+ value_type = new PointerType (new PointerType (inner.value_type));
+ } else {
+ value_type = new PointerType (inner.value_type);
+ }
+
+ return !error;
+ }
}
Modified: trunk/vala/valabaseaccess.vala
==============================================================================
--- trunk/vala/valabaseaccess.vala (original)
+++ trunk/vala/valabaseaccess.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valabaseaccess.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 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
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents an access to base class members in the source code.
@@ -49,4 +49,43 @@
public override bool is_pure () {
return true;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ if (!analyzer.is_in_instance_method ()) {
+ error = true;
+ Report.error (source_reference, "Base access invalid outside of instance methods");
+ return false;
+ }
+
+ if (analyzer.current_class == null) {
+ if (analyzer.current_struct == null) {
+ error = true;
+ Report.error (source_reference, "Base access invalid outside of class and struct");
+ return false;
+ } else if (analyzer.current_struct.get_base_types ().size != 1) {
+ error = true;
+ Report.error (source_reference, "Base access invalid without base type %d".printf (analyzer.current_struct.get_base_types ().size));
+ return false;
+ }
+ Iterator<DataType> base_type_it = analyzer.current_struct.get_base_types ().iterator ();
+ base_type_it.next ();
+ value_type = base_type_it.get ();
+ } else if (analyzer.current_class.base_class == null) {
+ error = true;
+ Report.error (source_reference, "Base access invalid without base class");
+ return false;
+ } else {
+ value_type = new ObjectType (analyzer.current_class.base_class);
+ }
+
+ symbol_reference = value_type.data_type;
+
+ return !error;
+ }
}
Modified: trunk/vala/valabooleanliteral.vala
==============================================================================
--- trunk/vala/valabooleanliteral.vala (original)
+++ trunk/vala/valabooleanliteral.vala Mon Nov 10 18:56:28 2008
@@ -60,4 +60,16 @@
public override bool is_pure () {
return true;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ value_type = analyzer.bool_type;
+
+ return !error;
+ }
}
Modified: trunk/vala/valacastexpression.vala
==============================================================================
--- trunk/vala/valacastexpression.vala (original)
+++ trunk/vala/valacastexpression.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valacastexpression.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 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
@@ -97,4 +97,28 @@
type_reference = new_type;
}
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ if (inner.error) {
+ error = true;
+ return false;
+ }
+
+ // FIXME: check whether cast is allowed
+
+ analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE);
+
+ value_type = type_reference;
+ value_type.value_owned = inner.value_type.value_owned;
+
+ inner.target_type = inner.value_type.copy ();
+
+ return !error;
+ }
}
Modified: trunk/vala/valacharacterliteral.vala
==============================================================================
--- trunk/vala/valacharacterliteral.vala (original)
+++ trunk/vala/valacharacterliteral.vala Mon Nov 10 18:56:28 2008
@@ -77,4 +77,16 @@
public override bool is_pure () {
return true;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ value_type = new ValueType ((TypeSymbol) analyzer.root_symbol.scope.lookup ("char"));
+
+ return !error;
+ }
}
Modified: trunk/vala/valaconditionalexpression.vala
==============================================================================
--- trunk/vala/valaconditionalexpression.vala (original)
+++ trunk/vala/valaconditionalexpression.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valaconditionalexpression.vala
*
- * Copyright (C) 2006 JÃrg Billeter
+ * Copyright (C) 2006-2008 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
@@ -69,4 +69,35 @@
public override bool is_pure () {
return condition.is_pure () && true_expression.is_pure () && false_expression.is_pure ();
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ if (condition.error || false_expression.error || true_expression.error) {
+ return false;
+ }
+
+ if (!condition.value_type.compatible (analyzer.bool_type)) {
+ error = true;
+ Report.error (condition.source_reference, "Condition must be boolean");
+ return false;
+ }
+
+ /* FIXME: support memory management */
+ if (false_expression.value_type.compatible (true_expression.value_type)) {
+ value_type = true_expression.value_type.copy ();
+ } else if (true_expression.value_type.compatible (false_expression.value_type)) {
+ value_type = false_expression.value_type.copy ();
+ } else {
+ error = true;
+ Report.error (condition.source_reference, "Incompatible expressions");
+ return false;
+ }
+
+ return !error;
+ }
}
Modified: trunk/vala/valaintegerliteral.vala
==============================================================================
--- trunk/vala/valaintegerliteral.vala (original)
+++ trunk/vala/valaintegerliteral.vala Mon Nov 10 18:56:28 2008
@@ -106,4 +106,16 @@
public override bool is_pure () {
return true;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ value_type = new IntegerType ((TypeSymbol) analyzer.root_symbol.scope.lookup (get_type_name ()), value, get_type_name ());
+
+ return !error;
+ }
}
Modified: trunk/vala/valalambdaexpression.vala
==============================================================================
--- trunk/vala/valalambdaexpression.vala (original)
+++ trunk/vala/valalambdaexpression.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valalambdaexpression.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 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
@@ -111,4 +111,88 @@
public override bool is_pure () {
return false;
}
+
+ string get_lambda_name (SemanticAnalyzer analyzer) {
+ var result = "__lambda%d".printf (analyzer.next_lambda_id);
+
+ analyzer.next_lambda_id++;
+
+ return result;
+ }
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ if (!(target_type is DelegateType)) {
+ error = true;
+ Report.error (source_reference, "lambda expression not allowed in this context");
+ return false;
+ }
+
+ bool in_instance_method = false;
+ var current_method = analyzer.find_current_method ();
+ if (current_method != null) {
+ in_instance_method = (current_method.binding == MemberBinding.INSTANCE);
+ } else {
+ in_instance_method = analyzer.is_in_constructor ();
+ }
+
+ var cb = (Delegate) ((DelegateType) target_type).delegate_symbol;
+ method = new Method (get_lambda_name (analyzer), cb.return_type);
+ if (!cb.has_target || !in_instance_method) {
+ method.binding = MemberBinding.STATIC;
+ }
+ method.owner = analyzer.current_symbol.scope;
+
+ var lambda_params = get_parameters ();
+ Iterator<string> lambda_param_it = lambda_params.iterator ();
+ foreach (FormalParameter cb_param in cb.get_parameters ()) {
+ if (!lambda_param_it.next ()) {
+ /* lambda expressions are allowed to have less parameters */
+ break;
+ }
+
+ string lambda_param = lambda_param_it.get ();
+
+ var param = new FormalParameter (lambda_param, cb_param.parameter_type);
+
+ method.add_parameter (param);
+ }
+
+ if (lambda_param_it.next ()) {
+ /* lambda expressions may not expect more parameters */
+ error = true;
+ Report.error (source_reference, "lambda expression: too many parameters");
+ return false;
+ }
+
+ if (expression_body != null) {
+ var block = new Block (source_reference);
+ block.scope.parent_scope = method.scope;
+
+ if (method.return_type.data_type != null) {
+ block.add_statement (new ReturnStatement (expression_body, source_reference));
+ } else {
+ block.add_statement (new ExpressionStatement (expression_body, source_reference));
+ }
+
+ method.body = block;
+ } else {
+ method.body = statement_body;
+ }
+ method.body.owner = method.scope;
+
+ /* lambda expressions should be usable like MemberAccess of a method */
+ symbol_reference = method;
+
+ accept_children (analyzer);
+
+ value_type = new MethodType (method);
+
+ return !error;
+ }
}
Modified: trunk/vala/valanullliteral.vala
==============================================================================
--- trunk/vala/valanullliteral.vala (original)
+++ trunk/vala/valanullliteral.vala Mon Nov 10 18:56:28 2008
@@ -49,4 +49,16 @@
public override bool is_pure () {
return true;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ value_type = new NullType (source_reference);
+
+ return !error;
+ }
}
Modified: trunk/vala/valaobjectcreationexpression.vala
==============================================================================
--- trunk/vala/valaobjectcreationexpression.vala (original)
+++ trunk/vala/valaobjectcreationexpression.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valaobjectcreationexpression.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 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
Modified: trunk/vala/valaparenthesizedexpression.vala
==============================================================================
--- trunk/vala/valaparenthesizedexpression.vala (original)
+++ trunk/vala/valaparenthesizedexpression.vala Mon Nov 10 18:56:28 2008
@@ -72,4 +72,38 @@
public override bool is_pure () {
return inner.is_pure ();
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ inner.target_type = target_type;
+
+ accept_children (analyzer);
+
+ if (inner.error) {
+ // ignore inner error
+ error = true;
+ return false;
+ }
+
+ if (inner.value_type == null) {
+ // static type may be null for method references
+ error = true;
+ Report.error (inner.source_reference, "Invalid expression type");
+ return false;
+ }
+
+ value_type = inner.value_type.copy ();
+ // don't call g_object_ref_sink on inner and outer expression
+ value_type.floating_reference = false;
+
+ // don't transform expression twice
+ inner.target_type = inner.value_type.copy ();
+
+ return !error;
+ }
}
Modified: trunk/vala/valapointerindirection.vala
==============================================================================
--- trunk/vala/valapointerindirection.vala (original)
+++ trunk/vala/valapointerindirection.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valapointerindirection.vala
*
- * Copyright (C) 2007 JÃrg Billeter
+ * Copyright (C) 2007-2008 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
@@ -69,4 +69,36 @@
public override bool is_pure () {
return inner.is_pure ();
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ if (inner.error) {
+ return false;
+ }
+ if (inner.value_type == null) {
+ error = true;
+ Report.error (source_reference, "internal error: unknown type of inner expression");
+ return false;
+ }
+ if (inner.value_type is PointerType) {
+ var pointer_type = (PointerType) inner.value_type;
+ if (pointer_type.base_type is ReferenceType) {
+ error = true;
+ Report.error (source_reference, "Pointer indirection not supported for this expression");
+ return false;
+ }
+ value_type = pointer_type.base_type;
+ } else {
+ error = true;
+ Report.error (source_reference, "Pointer indirection not supported for this expression");
+ return false;
+ }
+
+ return !error;
+ }
}
Modified: trunk/vala/valapostfixexpression.vala
==============================================================================
--- trunk/vala/valapostfixexpression.vala (original)
+++ trunk/vala/valapostfixexpression.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valapostfixexpression.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 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
@@ -61,4 +61,16 @@
public override bool is_pure () {
return false;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ value_type = inner.value_type;
+
+ return !error;
+ }
}
Modified: trunk/vala/valarealliteral.vala
==============================================================================
--- trunk/vala/valarealliteral.vala (original)
+++ trunk/vala/valarealliteral.vala Mon Nov 10 18:56:28 2008
@@ -69,4 +69,16 @@
public override string to_string () {
return value;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ value_type = new ValueType ((TypeSymbol) analyzer.root_symbol.scope.lookup (get_type_name ()));
+
+ return !error;
+ }
}
Modified: trunk/vala/valareferencetransferexpression.vala
==============================================================================
--- trunk/vala/valareferencetransferexpression.vala (original)
+++ trunk/vala/valareferencetransferexpression.vala Mon Nov 10 18:56:28 2008
@@ -71,4 +71,40 @@
public override bool is_pure () {
return false;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ inner.lvalue = true;
+
+ accept_children (analyzer);
+
+ if (inner.error) {
+ /* if there was an error in the inner expression, skip type check */
+ error = true;
+ return false;
+ }
+
+ if (!(inner is MemberAccess || inner is ElementAccess)) {
+ error = true;
+ Report.error (source_reference, "Reference transfer not supported for this expression");
+ return false;
+ }
+
+ if (!inner.value_type.is_disposable ()
+ && !(inner.value_type is PointerType)) {
+ error = true;
+ Report.error (source_reference, "No reference to be transferred");
+ return false;
+ }
+
+ value_type = inner.value_type.copy ();
+ value_type.value_owned = true;
+
+ return !error;
+ }
}
Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala (original)
+++ trunk/vala/valasemanticanalyzer.vala Mon Nov 10 18:56:28 2008
@@ -63,7 +63,7 @@
public Interface collection_type;
public Interface map_type;
- private int next_lambda_id = 0;
+ public int next_lambda_id = 0;
// keep replaced alive to make sure they remain valid
// for the whole execution of CodeNode.accept
@@ -300,27 +300,27 @@
}
public override void visit_boolean_literal (BooleanLiteral expr) {
- expr.value_type = bool_type;
+ expr.check (this);
}
public override void visit_character_literal (CharacterLiteral expr) {
- expr.value_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("char"));
+ expr.check (this);
}
public override void visit_integer_literal (IntegerLiteral expr) {
- expr.value_type = new IntegerType ((TypeSymbol) root_symbol.scope.lookup (expr.get_type_name ()), expr.value, expr.get_type_name ());
+ expr.check (this);
}
public override void visit_real_literal (RealLiteral expr) {
- expr.value_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup (expr.get_type_name ()));
+ expr.check (this);
}
public override void visit_string_literal (StringLiteral expr) {
- expr.value_type = string_type.copy ();
+ expr.check (this);
}
public override void visit_null_literal (NullLiteral expr) {
- expr.value_type = new NullType (expr.source_reference);
+ expr.check (this);
}
public DataType? get_value_type_for_symbol (Symbol sym, bool lvalue) {
@@ -421,29 +421,7 @@
}
public override void visit_parenthesized_expression (ParenthesizedExpression expr) {
- expr.inner.target_type = expr.target_type;
-
- expr.accept_children (this);
-
- if (expr.inner.error) {
- // ignore inner error
- expr.error = true;
- return;
- }
-
- if (expr.inner.value_type == null) {
- // static type may be null for method references
- expr.error = true;
- Report.error (expr.inner.source_reference, "Invalid expression type");
- return;
- }
-
- expr.value_type = expr.inner.value_type.copy ();
- // don't call g_object_ref_sink on inner and outer expression
- expr.value_type.floating_reference = false;
-
- // don't transform expression twice
- expr.inner.target_type = expr.inner.value_type.copy ();
+ expr.check (this);
}
public override void visit_member_access (MemberAccess expr) {
@@ -799,38 +777,11 @@
}
public override void visit_base_access (BaseAccess expr) {
- if (!is_in_instance_method ()) {
- expr.error = true;
- Report.error (expr.source_reference, "Base access invalid outside of instance methods");
- return;
- }
-
- if (current_class == null) {
- if (current_struct == null) {
- expr.error = true;
- Report.error (expr.source_reference, "Base access invalid outside of class and struct");
- return;
- } else if (current_struct.get_base_types ().size != 1) {
- expr.error = true;
- Report.error (expr.source_reference, "Base access invalid without base type %d".printf (current_struct.get_base_types ().size));
- return;
- }
- Iterator<DataType> base_type_it = current_struct.get_base_types ().iterator ();
- base_type_it.next ();
- expr.value_type = base_type_it.get ();
- } else if (current_class.base_class == null) {
- expr.error = true;
- Report.error (expr.source_reference, "Base access invalid without base class");
- return;
- } else {
- expr.value_type = new ObjectType (current_class.base_class);
- }
-
- expr.symbol_reference = expr.value_type.data_type;
+ expr.check (this);
}
public override void visit_postfix_expression (PostfixExpression expr) {
- expr.value_type = expr.inner.value_type;
+ expr.check (this);
}
public override void visit_object_creation_expression (ObjectCreationExpression expr) {
@@ -872,213 +823,31 @@
}
public override void visit_sizeof_expression (SizeofExpression expr) {
- expr.value_type = ulong_type;
+ expr.check (this);
}
public override void visit_typeof_expression (TypeofExpression expr) {
- expr.value_type = type_type;
- }
-
- private bool is_numeric_type (DataType type) {
- if (!(type.data_type is Struct)) {
- return false;
- }
-
- var st = (Struct) type.data_type;
- return st.is_integer_type () || st.is_floating_type ();
- }
-
- private bool is_integer_type (DataType type) {
- if (!(type.data_type is Struct)) {
- return false;
- }
-
- var st = (Struct) type.data_type;
- return st.is_integer_type ();
+ expr.check (this);
}
public override void visit_unary_expression (UnaryExpression expr) {
- if (expr.operator == UnaryOperator.REF || expr.operator == UnaryOperator.OUT) {
- expr.inner.lvalue = true;
- expr.inner.target_type = expr.target_type;
- }
-
- expr.accept_children (this);
-
- if (expr.inner.error) {
- /* if there was an error in the inner expression, skip type check */
- expr.error = true;
- return;
- }
-
- if (expr.operator == UnaryOperator.PLUS || expr.operator == UnaryOperator.MINUS) {
- // integer or floating point type
- if (!is_numeric_type (expr.inner.value_type)) {
- expr.error = true;
- Report.error (expr.source_reference, "Operator not supported for `%s'".printf (expr.inner.value_type.to_string ()));
- return;
- }
-
- expr.value_type = expr.inner.value_type;
- } else if (expr.operator == UnaryOperator.LOGICAL_NEGATION) {
- // boolean type
- if (!expr.inner.value_type.compatible (bool_type)) {
- expr.error = true;
- Report.error (expr.source_reference, "Operator not supported for `%s'".printf (expr.inner.value_type.to_string ()));
- return;
- }
-
- expr.value_type = expr.inner.value_type;
- } else if (expr.operator == UnaryOperator.BITWISE_COMPLEMENT) {
- // integer type
- if (!is_integer_type (expr.inner.value_type)) {
- expr.error = true;
- Report.error (expr.source_reference, "Operator not supported for `%s'".printf (expr.inner.value_type.to_string ()));
- return;
- }
-
- expr.value_type = expr.inner.value_type;
- } else if (expr.operator == UnaryOperator.INCREMENT ||
- expr.operator == UnaryOperator.DECREMENT) {
- // integer type
- if (!is_integer_type (expr.inner.value_type)) {
- expr.error = true;
- Report.error (expr.source_reference, "Operator not supported for `%s'".printf (expr.inner.value_type.to_string ()));
- return;
- }
-
- var ma = find_member_access (expr.inner);
- if (ma == null) {
- expr.error = true;
- Report.error (expr.source_reference, "Prefix operators not supported for this expression");
- return;
- }
-
- var old_value = new MemberAccess (ma.inner, ma.member_name, expr.inner.source_reference);
- var bin = new BinaryExpression (expr.operator == UnaryOperator.INCREMENT ? BinaryOperator.PLUS : BinaryOperator.MINUS, old_value, new IntegerLiteral ("1"), expr.source_reference);
-
- var assignment = new Assignment (ma, bin, AssignmentOperator.SIMPLE, expr.source_reference);
- var parenthexp = new ParenthesizedExpression (assignment, expr.source_reference);
- parenthexp.target_type = expr.target_type;
- replaced_nodes.add (expr);
- expr.parent_node.replace_expression (expr, parenthexp);
- parenthexp.accept (this);
- return;
- } else if (expr.operator == UnaryOperator.REF || expr.operator == UnaryOperator.OUT) {
- if (expr.inner.symbol_reference is Field || expr.inner.symbol_reference is FormalParameter || expr.inner.symbol_reference is LocalVariable) {
- // ref and out can only be used with fields, parameters, and local variables
- expr.lvalue = true;
- expr.value_type = expr.inner.value_type;
- } else {
- expr.error = true;
- Report.error (expr.source_reference, "ref and out method arguments can only be used with fields, parameters, and local variables");
- return;
- }
- } else {
- expr.error = true;
- Report.error (expr.source_reference, "internal error: unsupported unary operator");
- return;
- }
- }
-
- private MemberAccess? find_member_access (Expression expr) {
- if (expr is ParenthesizedExpression) {
- var pe = (ParenthesizedExpression) expr;
- return find_member_access (pe.inner);
- }
-
- if (expr is MemberAccess) {
- return (MemberAccess) expr;
- }
-
- return null;
+ expr.check (this);
}
public override void visit_cast_expression (CastExpression expr) {
- if (expr.inner.error) {
- expr.error = true;
- return;
- }
-
- // FIXME: check whether cast is allowed
-
- current_source_file.add_type_dependency (expr.type_reference, SourceFileDependencyType.SOURCE);
-
- expr.value_type = expr.type_reference;
- expr.value_type.value_owned = expr.inner.value_type.value_owned;
-
- expr.inner.target_type = expr.inner.value_type.copy ();
+ expr.check (this);
}
public override void visit_pointer_indirection (PointerIndirection expr) {
- if (expr.inner.error) {
- return;
- }
- if (expr.inner.value_type == null) {
- expr.error = true;
- Report.error (expr.source_reference, "internal error: unknown type of inner expression");
- return;
- }
- if (expr.inner.value_type is PointerType) {
- var pointer_type = (PointerType) expr.inner.value_type;
- if (pointer_type.base_type is ReferenceType) {
- expr.error = true;
- Report.error (expr.source_reference, "Pointer indirection not supported for this expression");
- return;
- }
- expr.value_type = pointer_type.base_type;
- } else {
- expr.error = true;
- Report.error (expr.source_reference, "Pointer indirection not supported for this expression");
- return;
- }
+ expr.check (this);
}
public override void visit_addressof_expression (AddressofExpression expr) {
- if (expr.inner.error) {
- return;
- }
- if (!(expr.inner.value_type is ValueType
- || expr.inner.value_type is ObjectType
- || expr.inner.value_type is PointerType)) {
- expr.error = true;
- Report.error (expr.source_reference, "Address-of operator not supported for this expression");
- return;
- }
-
- if (expr.inner.value_type.is_reference_type_or_type_parameter ()) {
- expr.value_type = new PointerType (new PointerType (expr.inner.value_type));
- } else {
- expr.value_type = new PointerType (expr.inner.value_type);
- }
+ expr.check (this);
}
public override void visit_reference_transfer_expression (ReferenceTransferExpression expr) {
- expr.inner.lvalue = true;
-
- expr.accept_children (this);
-
- if (expr.inner.error) {
- /* if there was an error in the inner expression, skip type check */
- expr.error = true;
- return;
- }
-
- if (!(expr.inner is MemberAccess || expr.inner is ElementAccess)) {
- expr.error = true;
- Report.error (expr.source_reference, "Reference transfer not supported for this expression");
- return;
- }
-
- if (!expr.inner.value_type.is_disposable ()
- && !(expr.inner.value_type is PointerType)) {
- expr.error = true;
- Report.error (expr.source_reference, "No reference to be transferred");
- return;
- }
-
- expr.value_type = expr.inner.value_type.copy ();
- expr.value_type.value_owned = true;
+ expr.check (this);
}
public DataType? get_arithmetic_result_type (DataType left_type, DataType right_type) {
@@ -1118,46 +887,11 @@
}
public override void visit_type_check (TypeCheck expr) {
- if (expr.type_reference.data_type == null) {
- /* if type resolving didn't succeed, skip this check */
- expr.error = true;
- return;
- }
-
- current_source_file.add_type_dependency (expr.type_reference, SourceFileDependencyType.SOURCE);
-
- expr.value_type = bool_type;
+ expr.check (this);
}
public override void visit_conditional_expression (ConditionalExpression expr) {
- if (expr.condition.error || expr.false_expression.error || expr.true_expression.error) {
- return;
- }
-
- if (!expr.condition.value_type.compatible (bool_type)) {
- expr.error = true;
- Report.error (expr.condition.source_reference, "Condition must be boolean");
- return;
- }
-
- /* FIXME: support memory management */
- if (expr.false_expression.value_type.compatible (expr.true_expression.value_type)) {
- expr.value_type = expr.true_expression.value_type.copy ();
- } else if (expr.true_expression.value_type.compatible (expr.false_expression.value_type)) {
- expr.value_type = expr.false_expression.value_type.copy ();
- } else {
- expr.error = true;
- Report.error (expr.condition.source_reference, "Incompatible expressions");
- return;
- }
- }
-
- private string get_lambda_name () {
- var result = "__lambda%d".printf (next_lambda_id);
-
- next_lambda_id++;
-
- return result;
+ expr.check (this);
}
public Method? find_current_method () {
@@ -1183,71 +917,7 @@
}
public override void visit_lambda_expression (LambdaExpression l) {
- if (!(l.target_type is DelegateType)) {
- l.error = true;
- Report.error (l.source_reference, "lambda expression not allowed in this context");
- return;
- }
-
- bool in_instance_method = false;
- var current_method = find_current_method ();
- if (current_method != null) {
- in_instance_method = (current_method.binding == MemberBinding.INSTANCE);
- } else {
- in_instance_method = is_in_constructor ();
- }
-
- var cb = (Delegate) ((DelegateType) l.target_type).delegate_symbol;
- l.method = new Method (get_lambda_name (), cb.return_type);
- if (!cb.has_target || !in_instance_method) {
- l.method.binding = MemberBinding.STATIC;
- }
- l.method.owner = current_symbol.scope;
-
- var lambda_params = l.get_parameters ();
- Iterator<string> lambda_param_it = lambda_params.iterator ();
- foreach (FormalParameter cb_param in cb.get_parameters ()) {
- if (!lambda_param_it.next ()) {
- /* lambda expressions are allowed to have less parameters */
- break;
- }
-
- string lambda_param = lambda_param_it.get ();
-
- var param = new FormalParameter (lambda_param, cb_param.parameter_type);
-
- l.method.add_parameter (param);
- }
-
- if (lambda_param_it.next ()) {
- /* lambda expressions may not expect more parameters */
- l.error = true;
- Report.error (l.source_reference, "lambda expression: too many parameters");
- return;
- }
-
- if (l.expression_body != null) {
- var block = new Block (l.source_reference);
- block.scope.parent_scope = l.method.scope;
-
- if (l.method.return_type.data_type != null) {
- block.add_statement (new ReturnStatement (l.expression_body, l.source_reference));
- } else {
- block.add_statement (new ExpressionStatement (l.expression_body, l.source_reference));
- }
-
- l.method.body = block;
- } else {
- l.method.body = l.statement_body;
- }
- l.method.body.owner = l.method.scope;
-
- /* lambda expressions should be usable like MemberAccess of a method */
- l.symbol_reference = l.method;
-
- l.accept_children (this);
-
- l.value_type = new MethodType (l.method);
+ l.check (this);
}
public override void visit_assignment (Assignment a) {
Modified: trunk/vala/valasizeofexpression.vala
==============================================================================
--- trunk/vala/valasizeofexpression.vala (original)
+++ trunk/vala/valasizeofexpression.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valasizeofexpression.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 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
@@ -68,4 +68,16 @@
type_reference = new_type;
}
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ value_type = analyzer.ulong_type;
+
+ return !error;
+ }
}
Modified: trunk/vala/valastringliteral.vala
==============================================================================
--- trunk/vala/valastringliteral.vala (original)
+++ trunk/vala/valastringliteral.vala Mon Nov 10 18:56:28 2008
@@ -76,4 +76,16 @@
public override string to_string () {
return value;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ value_type = analyzer.string_type.copy ();
+
+ return !error;
+ }
}
Modified: trunk/vala/valatypecheck.vala
==============================================================================
--- trunk/vala/valatypecheck.vala (original)
+++ trunk/vala/valatypecheck.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valatypecheck.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 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
@@ -77,4 +77,24 @@
type_reference = new_type;
}
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ if (type_reference.data_type == null) {
+ /* if type resolving didn't succeed, skip this check */
+ error = true;
+ return false;
+ }
+
+ analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE);
+
+ value_type = analyzer.bool_type;
+
+ return !error;
+ }
}
Modified: trunk/vala/valatypeofexpression.vala
==============================================================================
--- trunk/vala/valatypeofexpression.vala (original)
+++ trunk/vala/valatypeofexpression.vala Mon Nov 10 18:56:28 2008
@@ -1,6 +1,6 @@
/* valatypeofexpression.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 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
@@ -68,4 +68,16 @@
type_reference = new_type;
}
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ value_type = analyzer.type_type;
+
+ return !error;
+ }
}
Modified: trunk/vala/valaunaryexpression.vala
==============================================================================
--- trunk/vala/valaunaryexpression.vala (original)
+++ trunk/vala/valaunaryexpression.vala Mon Nov 10 18:56:28 2008
@@ -104,6 +104,129 @@
return inner.is_pure ();
}
+
+ bool is_numeric_type (DataType type) {
+ if (!(type.data_type is Struct)) {
+ return false;
+ }
+
+ var st = (Struct) type.data_type;
+ return st.is_integer_type () || st.is_floating_type ();
+ }
+
+ bool is_integer_type (DataType type) {
+ if (!(type.data_type is Struct)) {
+ return false;
+ }
+
+ var st = (Struct) type.data_type;
+ return st.is_integer_type ();
+ }
+
+ MemberAccess? find_member_access (Expression expr) {
+ if (expr is ParenthesizedExpression) {
+ var pe = (ParenthesizedExpression) expr;
+ return find_member_access (pe.inner);
+ }
+
+ if (expr is MemberAccess) {
+ return (MemberAccess) expr;
+ }
+
+ return null;
+ }
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ if (operator == UnaryOperator.REF || operator == UnaryOperator.OUT) {
+ inner.lvalue = true;
+ inner.target_type = target_type;
+ }
+
+ accept_children (analyzer);
+
+ if (inner.error) {
+ /* if there was an error in the inner expression, skip type check */
+ error = true;
+ return false;
+ }
+
+ if (operator == UnaryOperator.PLUS || operator == UnaryOperator.MINUS) {
+ // integer or floating point type
+ if (!is_numeric_type (inner.value_type)) {
+ error = true;
+ Report.error (source_reference, "Operator not supported for `%s'".printf (inner.value_type.to_string ()));
+ return false;
+ }
+
+ value_type = inner.value_type;
+ } else if (operator == UnaryOperator.LOGICAL_NEGATION) {
+ // boolean type
+ if (!inner.value_type.compatible (analyzer.bool_type)) {
+ error = true;
+ Report.error (source_reference, "Operator not supported for `%s'".printf (inner.value_type.to_string ()));
+ return false;
+ }
+
+ value_type = inner.value_type;
+ } else if (operator == UnaryOperator.BITWISE_COMPLEMENT) {
+ // integer type
+ if (!is_integer_type (inner.value_type)) {
+ error = true;
+ Report.error (source_reference, "Operator not supported for `%s'".printf (inner.value_type.to_string ()));
+ return false;
+ }
+
+ value_type = inner.value_type;
+ } else if (operator == UnaryOperator.INCREMENT ||
+ operator == UnaryOperator.DECREMENT) {
+ // integer type
+ if (!is_integer_type (inner.value_type)) {
+ error = true;
+ Report.error (source_reference, "Operator not supported for `%s'".printf (inner.value_type.to_string ()));
+ return false;
+ }
+
+ var ma = find_member_access (inner);
+ if (ma == null) {
+ error = true;
+ Report.error (source_reference, "Prefix operators not supported for this expression");
+ return false;
+ }
+
+ var old_value = new MemberAccess (ma.inner, ma.member_name, inner.source_reference);
+ var bin = new BinaryExpression (operator == UnaryOperator.INCREMENT ? BinaryOperator.PLUS : BinaryOperator.MINUS, old_value, new IntegerLiteral ("1"), source_reference);
+
+ var assignment = new Assignment (ma, bin, AssignmentOperator.SIMPLE, source_reference);
+ var parenthexp = new ParenthesizedExpression (assignment, source_reference);
+ parenthexp.target_type = target_type;
+ analyzer.replaced_nodes.add (this);
+ parent_node.replace_expression (this, parenthexp);
+ parenthexp.accept (analyzer);
+ return true;
+ } else if (operator == UnaryOperator.REF || operator == UnaryOperator.OUT) {
+ if (inner.symbol_reference is Field || inner.symbol_reference is FormalParameter || inner.symbol_reference is LocalVariable) {
+ // ref and out can only be used with fields, parameters, and local variables
+ lvalue = true;
+ value_type = inner.value_type;
+ } else {
+ error = true;
+ Report.error (source_reference, "ref and out method arguments can only be used with fields, parameters, and local variables");
+ return false;
+ }
+ } else {
+ error = true;
+ Report.error (source_reference, "internal error: unsupported unary operator");
+ return false;
+ }
+
+ return !error;
+ }
}
public enum Vala.UnaryOperator {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]