vala r1984 - in trunk: . vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r1984 - in trunk: . vala
- Date: Wed, 5 Nov 2008 21:33:56 +0000 (UTC)
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]