vala r1984 - in trunk: . vala



Author: juergbi
Date: Wed Nov  5 21:33:55 2008
New Revision: 1984
URL: http://svn.gnome.org/viewvc/vala?rev=1984&view=rev

Log:
2008-11-05  JÃrg Billeter  <j bitron ch>

	* vala/valabinaryexpression.vala:
	* vala/valasemanticanalyzer.vala:

	Move binary expression checking to BinaryExpression.check


Modified:
   trunk/ChangeLog
   trunk/vala/valabinaryexpression.vala
   trunk/vala/valasemanticanalyzer.vala

Modified: trunk/vala/valabinaryexpression.vala
==============================================================================
--- trunk/vala/valabinaryexpression.vala	(original)
+++ trunk/vala/valabinaryexpression.vala	Wed Nov  5 21:33:55 2008
@@ -20,7 +20,7 @@
  * 	JÃrg Billeter <j bitron ch>
  */
 
-using GLib;
+using Gee;
 
 /**
  * Represents an expression with two operands in the source code.
@@ -137,6 +137,163 @@
 	public override bool is_non_null () {
 		return left.is_non_null () && right.is_non_null ();
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (left.error || right.error) {
+			/* if there were any errors in inner expressions, skip type check */
+			error = true;
+			return false;
+		}
+
+		if (left.value_type == null) {
+			Report.error (left.source_reference, "invalid left operand");
+			error = true;
+			return false;
+		}
+
+		if (operator != BinaryOperator.IN && right.value_type == null) {
+			Report.error (right.source_reference, "invalid right operand");
+			error = true;
+			return false;
+		}
+
+		if (left.value_type.data_type == analyzer.string_type.data_type
+		    && operator == BinaryOperator.PLUS) {
+			// string concatenation
+
+			if (right.value_type == null || right.value_type.data_type != analyzer.string_type.data_type) {
+				error = true;
+				Report.error (source_reference, "Operands must be strings");
+				return false;
+			}
+
+			value_type = analyzer.string_type.copy ();
+			if (left.is_constant () && right.is_constant ()) {
+				value_type.value_owned = false;
+			} else {
+				value_type.value_owned = true;
+			}
+		} else if (operator == BinaryOperator.PLUS
+			   || operator == BinaryOperator.MINUS
+			   || operator == BinaryOperator.MUL
+			   || operator == BinaryOperator.DIV) {
+			// check for pointer arithmetic
+			if (left.value_type is PointerType) {
+				var offset_type = right.value_type.data_type as Struct;
+				if (offset_type != null && offset_type.is_integer_type ()) {
+					if (operator == BinaryOperator.PLUS
+					    || operator == BinaryOperator.MINUS) {
+						// pointer arithmetic: pointer +/- offset
+						value_type = left.value_type.copy ();
+					}
+				} else if (right.value_type is PointerType) {
+					// pointer arithmetic: pointer - pointer
+					value_type = analyzer.size_t_type;
+				}
+			}
+
+			if (value_type == null) {
+				value_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+			}
+
+			if (value_type == null) {
+				error = true;
+				Report.error (source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
+				return false;
+			}
+		} else if (operator == BinaryOperator.MOD
+			   || operator == BinaryOperator.SHIFT_LEFT
+			   || operator == BinaryOperator.SHIFT_RIGHT
+			   || operator == BinaryOperator.BITWISE_XOR) {
+			value_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+
+			if (value_type == null) {
+				error = true;
+				Report.error (source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
+				return false;
+			}
+		} else if (operator == BinaryOperator.LESS_THAN
+			   || operator == BinaryOperator.GREATER_THAN
+			   || operator == BinaryOperator.LESS_THAN_OR_EQUAL
+			   || operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
+			if (left.value_type.compatible (analyzer.string_type)
+			    && right.value_type.compatible (analyzer.string_type)) {
+				// string comparison
+				} else if (left.value_type is PointerType && right.value_type is PointerType) {
+					// pointer arithmetic
+			} else {
+				var resulting_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+
+				if (resulting_type == null) {
+					error = true;
+					Report.error (source_reference, "Relational operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
+					return false;
+				}
+			}
+
+			value_type = analyzer.bool_type;
+		} else if (operator == BinaryOperator.EQUALITY
+			   || operator == BinaryOperator.INEQUALITY) {
+			/* relational operation */
+
+			if (!right.value_type.compatible (left.value_type)
+			    && !left.value_type.compatible (right.value_type)) {
+				Report.error (source_reference, "Equality operation: `%s' and `%s' are incompatible".printf (right.value_type.to_string (), left.value_type.to_string ()));
+				error = true;
+				return false;
+			}
+
+			if (left.value_type.compatible (analyzer.string_type)
+			    && right.value_type.compatible (analyzer.string_type)) {
+				// string comparison
+			}
+
+			value_type = analyzer.bool_type;
+		} else if (operator == BinaryOperator.BITWISE_AND
+			   || operator == BinaryOperator.BITWISE_OR) {
+			// integer type or flags type
+
+			value_type = left.value_type;
+		} else if (operator == BinaryOperator.AND
+			   || operator == BinaryOperator.OR) {
+			if (!left.value_type.compatible (analyzer.bool_type) || !right.value_type.compatible (analyzer.bool_type)) {
+				error = true;
+				Report.error (source_reference, "Operands must be boolean");
+			}
+
+			value_type = analyzer.bool_type;
+		} else if (operator == BinaryOperator.IN) {
+			// integer type or flags type or collection/map
+
+			/* handle collections and maps */
+			var container_type = right.value_type.data_type;
+			
+			if ((analyzer.collection_type != null && container_type.is_subtype_of (analyzer.collection_type))
+			    || (analyzer.map_type != null && container_type.is_subtype_of (analyzer.map_type))) {
+				Symbol contains_sym = null;
+				if (container_type.is_subtype_of (analyzer.collection_type)) {
+					contains_sym = analyzer.collection_type.scope.lookup ("contains");
+				} else if (container_type.is_subtype_of (analyzer.map_type)) {
+					contains_sym = analyzer.map_type.scope.lookup ("contains");
+				}
+				var contains_method = (Method) contains_sym;
+				Gee.List<FormalParameter> contains_params = contains_method.get_parameters ();
+				Iterator<FormalParameter> contains_params_it = contains_params.iterator ();
+				contains_params_it.next ();
+				var contains_param = contains_params_it.get ();
+
+				var key_type = analyzer.get_actual_type (right.value_type, contains_method, contains_param.parameter_type, this);
+				left.target_type = key_type;
+			}
+			
+			value_type = analyzer.bool_type;
+			
+		} else {
+			assert_not_reached ();
+		}
+
+		return !error;
+	}
 }
 
 public enum Vala.BinaryOperator {

Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala	(original)
+++ trunk/vala/valasemanticanalyzer.vala	Wed Nov  5 21:33:55 2008
@@ -39,8 +39,8 @@
 
 	Gee.List<UsingDirective> current_using_directives;
 
-	DataType bool_type;
-	DataType string_type;
+	public DataType bool_type;
+	public DataType string_type;
 	DataType uchar_type;
 	DataType short_type;
 	DataType ushort_type;
@@ -48,7 +48,7 @@
 	DataType uint_type;
 	DataType long_type;
 	DataType ulong_type;
-	DataType size_t_type;
+	public DataType size_t_type;
 	DataType ssize_t_type;
 	DataType int8_type;
 	DataType unichar_type;
@@ -62,8 +62,8 @@
 	DataType iterable_type;
 	Interface iterator_type;
 	Interface list_type;
-	Interface collection_type;
-	Interface map_type;
+	public Interface collection_type;
+	public Interface map_type;
 
 	private int next_lambda_id = 0;
 
@@ -3084,7 +3084,7 @@
 		expr.value_type.value_owned = true;
 	}
 
-	private DataType? get_arithmetic_result_type (DataType left_type, DataType right_type) {
+	public DataType? get_arithmetic_result_type (DataType left_type, DataType right_type) {
 		 if (!(left_type.data_type is Struct) || !(right_type.data_type is Struct)) {
 			// at least one operand not struct
 		 	return null;
@@ -3117,158 +3117,7 @@
 	}
 
 	public override void visit_binary_expression (BinaryExpression expr) {
-		if (expr.left.error || expr.right.error) {
-			/* if there were any errors in inner expressions, skip type check */
-			expr.error = true;
-			return;
-		}
-
-		if (expr.left.value_type == null) {
-			Report.error (expr.left.source_reference, "invalid left operand");
-			expr.error = true;
-			return;
-		}
-
-		if (expr.operator != BinaryOperator.IN && expr.right.value_type == null) {
-			Report.error (expr.right.source_reference, "invalid right operand");
-			expr.error = true;
-			return;
-		}
-
-		if (expr.left.value_type.data_type == string_type.data_type
-		    && expr.operator == BinaryOperator.PLUS) {
-			// string concatenation
-
-			if (expr.right.value_type == null || expr.right.value_type.data_type != string_type.data_type) {
-				expr.error = true;
-				Report.error (expr.source_reference, "Operands must be strings");
-				return;
-			}
-
-			expr.value_type = string_type.copy ();
-			if (expr.left.is_constant () && expr.right.is_constant ()) {
-				expr.value_type.value_owned = false;
-			} else {
-				expr.value_type.value_owned = true;
-			}
-		} else if (expr.operator == BinaryOperator.PLUS
-			   || expr.operator == BinaryOperator.MINUS
-			   || expr.operator == BinaryOperator.MUL
-			   || expr.operator == BinaryOperator.DIV) {
-			// check for pointer arithmetic
-			if (expr.left.value_type is PointerType) {
-				var offset_type = expr.right.value_type.data_type as Struct;
-				if (offset_type != null && offset_type.is_integer_type ()) {
-					if (expr.operator == BinaryOperator.PLUS
-					    || expr.operator == BinaryOperator.MINUS) {
-						// pointer arithmetic: pointer +/- offset
-						expr.value_type = expr.left.value_type.copy ();
-					}
-				} else if (expr.right.value_type is PointerType) {
-					// pointer arithmetic: pointer - pointer
-					expr.value_type = size_t_type;
-				}
-			}
-
-			if (expr.value_type == null) {
-				expr.value_type = get_arithmetic_result_type (expr.left.value_type, expr.right.value_type);
-			}
-
-			if (expr.value_type == null) {
-				expr.error = true;
-				Report.error (expr.source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (expr.left.value_type.to_string (), expr.right.value_type.to_string ()));
-				return;
-			}
-		} else if (expr.operator == BinaryOperator.MOD
-			   || expr.operator == BinaryOperator.SHIFT_LEFT
-			   || expr.operator == BinaryOperator.SHIFT_RIGHT
-			   || expr.operator == BinaryOperator.BITWISE_XOR) {
-			expr.value_type = get_arithmetic_result_type (expr.left.value_type, expr.right.value_type);
-
-			if (expr.value_type == null) {
-				expr.error = true;
-				Report.error (expr.source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (expr.left.value_type.to_string (), expr.right.value_type.to_string ()));
-				return;
-			}
-		} else if (expr.operator == BinaryOperator.LESS_THAN
-			   || expr.operator == BinaryOperator.GREATER_THAN
-			   || expr.operator == BinaryOperator.LESS_THAN_OR_EQUAL
-			   || expr.operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
-			if (expr.left.value_type.compatible (string_type)
-			    && expr.right.value_type.compatible (string_type)) {
-				// string comparison
-				} else if (expr.left.value_type is PointerType && expr.right.value_type is PointerType) {
-					// pointer arithmetic
-			} else {
-				var resulting_type = get_arithmetic_result_type (expr.left.value_type, expr.right.value_type);
-
-				if (resulting_type == null) {
-					expr.error = true;
-					Report.error (expr.source_reference, "Relational operation not supported for types `%s' and `%s'".printf (expr.left.value_type.to_string (), expr.right.value_type.to_string ()));
-					return;
-				}
-			}
-
-			expr.value_type = bool_type;
-		} else if (expr.operator == BinaryOperator.EQUALITY
-			   || expr.operator == BinaryOperator.INEQUALITY) {
-			/* relational operation */
-
-			if (!expr.right.value_type.compatible (expr.left.value_type)
-			    && !expr.left.value_type.compatible (expr.right.value_type)) {
-				Report.error (expr.source_reference, "Equality operation: `%s' and `%s' are incompatible".printf (expr.right.value_type.to_string (), expr.left.value_type.to_string ()));
-				expr.error = true;
-				return;
-			}
-
-			if (expr.left.value_type.compatible (string_type)
-			    && expr.right.value_type.compatible (string_type)) {
-				// string comparison
-			}
-
-			expr.value_type = bool_type;
-		} else if (expr.operator == BinaryOperator.BITWISE_AND
-			   || expr.operator == BinaryOperator.BITWISE_OR) {
-			// integer type or flags type
-
-			expr.value_type = expr.left.value_type;
-		} else if (expr.operator == BinaryOperator.AND
-			   || expr.operator == BinaryOperator.OR) {
-			if (!expr.left.value_type.compatible (bool_type) || !expr.right.value_type.compatible (bool_type)) {
-				expr.error = true;
-				Report.error (expr.source_reference, "Operands must be boolean");
-			}
-
-			expr.value_type = bool_type;
-		} else if (expr.operator == BinaryOperator.IN) {
-			// integer type or flags type or collection/map
-
-			/* handle collections and maps */
-			var container_type = expr.right.value_type.data_type;
-			
-			if ((collection_type != null && container_type.is_subtype_of (collection_type))
-			    || (map_type != null && container_type.is_subtype_of (map_type))) {
-				Symbol contains_sym = null;
-				if (container_type.is_subtype_of (collection_type)) {
-					contains_sym = collection_type.scope.lookup ("contains");
-				} else if (container_type.is_subtype_of (map_type)) {
-					contains_sym = map_type.scope.lookup ("contains");
-				}
-				var contains_method = (Method) contains_sym;
-				Gee.List<FormalParameter> contains_params = contains_method.get_parameters ();
-				Iterator<FormalParameter> contains_params_it = contains_params.iterator ();
-				contains_params_it.next ();
-				var contains_param = contains_params_it.get ();
-
-				var key_type = get_actual_type (expr.right.value_type, contains_method, contains_param.parameter_type, expr);
-				expr.left.target_type = key_type;
-			}
-			
-			expr.value_type = bool_type;
-			
-		} else {
-			assert_not_reached ();
-		}
+		expr.check (this);
 	}
 
 	public override void visit_type_check (TypeCheck expr) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]