[vala] dova: Add assert support



commit a445650eea2dae89a9ef259bc825ebaad9c07493
Author: Jürg Billeter <j bitron ch>
Date:   Mon Jun 21 23:03:01 2010 +0200

    dova: Add assert support

 codegen/valadovavaluemodule.vala |   69 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 69 insertions(+), 0 deletions(-)
---
diff --git a/codegen/valadovavaluemodule.vala b/codegen/valadovavaluemodule.vala
index eaa0c25..1b723fe 100644
--- a/codegen/valadovavaluemodule.vala
+++ b/codegen/valadovavaluemodule.vala
@@ -77,6 +77,8 @@ internal class Vala.DovaValueModule : DovaObjectModule {
 			generate_method_declaration ((Method) cl.scope.lookup ("ref"), decl_space);
 			generate_method_declaration ((Method) cl.scope.lookup ("unref"), decl_space);
 		}
+
+		add_value_assert (cl, decl_space);
 	}
 
 	public override void visit_class (Class cl) {
@@ -291,6 +293,25 @@ internal class Vala.DovaValueModule : DovaObjectModule {
 		function.add_parameter (new CCodeFormalParameter ("src_index", "int32_t"));
 
 		decl_space.add_type_member_declaration (function);
+
+		add_value_assert (st, decl_space);
+	}
+
+	void add_value_assert (TypeSymbol sym, CCodeDeclarationSpace decl_space) {
+		string cname = sym.get_cname ();
+		if (sym is Class) {
+			cname += "*";
+		}
+
+		string assert_body;
+		var compare_method = sym.scope.lookup ("compare") as Method;
+		if (compare_method != null) {
+			assert_body = "do { %s __v1 = (v1); %s __v2 = (v2); if (%s (__v1, __v2) cmp 0); else dova_assert_compare (string_create_from_cstring (#v1 \" \" #cmp \" \" #v2), %s_to_string (v1), string_create_from_cstring (#cmp), %s_to_string (v2)); } while (0)".printf (cname, cname, compare_method.get_cname (), sym.get_lower_case_cname (), sym.get_lower_case_cname ());
+		} else {
+			assert_body = "do { %s __v1 = (v1); %s __v2 = (v2); if (__v1 cmp __v2); else dova_assert_compare (string_create_from_cstring (#v1 \" \" #cmp \" \" #v2), %s_to_string (v1), string_create_from_cstring (#cmp), %s_to_string (v2)); } while (0)".printf (cname, cname, sym.get_lower_case_cname (), sym.get_lower_case_cname ());
+		}
+		var assert_macro = new CCodeMacroReplacement ("%s_assert(v1, cmp, v2)".printf (sym.get_lower_case_cname ()), assert_body);
+		decl_space.add_type_member_declaration (assert_macro);
 	}
 
 	public override void visit_struct (Struct st) {
@@ -655,7 +676,55 @@ internal class Vala.DovaValueModule : DovaObjectModule {
 		}
 	}
 
+	bool is_comparison (Expression expr) {
+		var binary_expression = expr as BinaryExpression;
+		if (binary_expression != null) {
+			switch (binary_expression.operator) {
+			case BinaryOperator.LESS_THAN:
+			case BinaryOperator.GREATER_THAN:
+			case BinaryOperator.LESS_THAN_OR_EQUAL:
+			case BinaryOperator.GREATER_THAN_OR_EQUAL:
+			case BinaryOperator.EQUALITY:
+			case BinaryOperator.INEQUALITY:
+				return true;
+			default:
+				return false;
+			}
+		}
+		return false;
+	}
+
+	bool handle_assert (MethodCall expr) {
+		var args = expr.get_argument_list ();
+		var mtype = expr.call.value_type as MethodType;
+		if (mtype == null || mtype.method_symbol.get_cname () != "dova_assert" ||
+		    !(args.get (1) is NullLiteral) ||
+		    !is_comparison (args.get (0))) {
+			return false;
+		}
+
+		expr.accept_children (codegen);
+
+		var binary_expression = (BinaryExpression) args.get (0);
+		var op1 = binary_expression.left;
+		var op2 = binary_expression.right;
+
+		var type = op1.value_type.data_type;
+
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_assert".printf (type.get_lower_case_cname ())));
+		ccall.add_argument ((CCodeExpression) get_ccodenode (op1));
+		ccall.add_argument (new CCodeConstant (binary_expression.get_operator_string ()));
+		ccall.add_argument ((CCodeExpression) get_ccodenode (op2));
+		expr.ccodenode = ccall;
+
+		return true;
+	}
+
 	public override void visit_method_call (MethodCall expr) {
+		if (handle_assert (expr)) {
+			return;
+		}
+
 		var ma = expr.call as MemberAccess;
 		if (ma == null || ma.inner == null || !(ma.inner.value_type is GenericType)) {
 			base.visit_method_call (expr);



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