[vala] Implement coalescing operator ??
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] Implement coalescing operator ??
- Date: Fri, 29 Jan 2010 18:29:39 +0000 (UTC)
commit b319ccfbfd263417ef0724bf3346eb3765cf75a9
Author: Jürg Billeter <j bitron ch>
Date: Wed Jan 27 02:13:24 2010 +0100
Implement coalescing operator ??
Based on patch by Marc-André Lureau, fixes bug 580816.
vala/valabinaryexpression.vala | 38 ++++++++++++++++++++++++++++++++++++--
vala/valacodewriter.vala | 3 +++
vala/valaparser.vala | 13 ++++++++++++-
vala/valascanner.vala | 4 ++++
vala/valatokentype.vala | 1 +
5 files changed, 56 insertions(+), 3 deletions(-)
---
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index 4400f02..01cae0b 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -24,7 +24,7 @@
/**
* Represents an expression with two operands in the source code.
*
- * Supports +, -, *, /, %, <<, >>, <, >, <=, >=, ==, !=, &, |, ^, &&, ||.
+ * Supports +, -, *, /, %, <<, >>, <, >, <=, >=, ==, !=, &, |, ^, &&, ||, ??.
*/
public class Vala.BinaryExpression : Expression {
/**
@@ -118,6 +118,7 @@ public class Vala.BinaryExpression : Expression {
case BinaryOperator.AND: return "&&";
case BinaryOperator.OR: return "||";
case BinaryOperator.IN: return "in";
+ case BinaryOperator.COALESCE: return "??";
}
assert_not_reached ();
@@ -206,6 +207,38 @@ public class Vala.BinaryExpression : Expression {
return true;
}
+ if (operator == BinaryOperator.COALESCE) {
+ var local = new LocalVariable (null, get_temp_name (), left, source_reference);
+ var decl = new DeclarationStatement (local, source_reference);
+ decl.check (analyzer);
+
+ var right_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, right.source_reference), right, AssignmentOperator.SIMPLE, right.source_reference), right.source_reference);
+
+ var true_block = new Block (source_reference);
+
+ true_block.add_statement (right_stmt);
+
+ var cond = new BinaryExpression (BinaryOperator.EQUALITY, new MemberAccess.simple (local.name, left.source_reference), new NullLiteral (source_reference), source_reference);
+
+ var if_stmt = new IfStatement (cond, true_block, null, source_reference);
+
+ insert_statement (analyzer.insert_block, decl);
+ insert_statement (analyzer.insert_block, if_stmt);
+
+ if (!if_stmt.check (analyzer)) {
+ error = true;
+ return false;
+ }
+
+ var ma = new MemberAccess.simple (local.name, source_reference);
+ ma.target_type = target_type;
+ ma.check (analyzer);
+
+ parent_node.replace_expression (this, ma);
+
+ return true;
+ }
+
if (!left.check (analyzer) || !right.check (analyzer)) {
/* if there were any errors in inner expressions, skip type check */
error = true;
@@ -432,5 +465,6 @@ public enum Vala.BinaryOperator {
BITWISE_XOR,
AND,
OR,
- IN
+ IN,
+ COALESCE
}
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index b94f777..89fcab0 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -1586,6 +1586,9 @@ public class Vala.CodeWriter : CodeVisitor {
case BinaryOperator.IN:
write_string (" in ");
break;
+ case BinaryOperator.COALESCE:
+ write_string (" ?? ");
+ break;
default:
assert_not_reached ();
}
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 999976e..b3d3454 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -1217,9 +1217,20 @@ public class Vala.Parser : CodeVisitor {
return left;
}
+ Expression parse_coalescing_expression () throws ParseError {
+ var begin = get_location ();
+ var left = parse_conditional_or_expression ();
+ if (accept (TokenType.OP_COALESCING)) {
+ var right = parse_coalescing_expression ();
+ return new BinaryExpression (BinaryOperator.COALESCE, left, right, get_src (begin));
+ } else {
+ return left;
+ }
+ }
+
Expression parse_conditional_expression () throws ParseError {
var begin = get_location ();
- var condition = parse_conditional_or_expression ();
+ var condition = parse_coalescing_expression ();
if (accept (TokenType.INTERR)) {
var true_expr = parse_expression ();
expect (TokenType.COLON);
diff --git a/vala/valascanner.vala b/vala/valascanner.vala
index 9a1d3ea..40e1975 100644
--- a/vala/valascanner.vala
+++ b/vala/valascanner.vala
@@ -688,6 +688,10 @@ public class Vala.Scanner {
case '?':
type = TokenType.INTERR;
current++;
+ if (current < end && current[0] == '?') {
+ type = TokenType.OP_COALESCING;
+ current++;
+ }
break;
case '|':
type = TokenType.BITWISE_OR;
diff --git a/vala/valatokentype.vala b/vala/valatokentype.vala
index bfacde1..61b4859 100644
--- a/vala/valatokentype.vala
+++ b/vala/valatokentype.vala
@@ -93,6 +93,7 @@ public enum Vala.TokenType {
NULL,
OUT,
OP_AND,
+ OP_COALESCING,
OP_DEC,
OP_EQ,
OP_GE,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]