Commit 078c5edd authored by Mathias Hasselmann's avatar Mathias Hasselmann Committed by Mathias Hasselmann
Browse files

support C# like as operator test the as operator

2007-08-20  Mathias Hasselmann  <mathias.hasselmann@gmx.de>

	* vala/valacastexpression.vala, gobject/valacodegenerator.vala,
	vala/parser.y, vala/scanner.l: support C# like as operator
	* tests/Makefile.am, tests/test-034.*: test the as operator

svn path=/trunk/; revision=489
parent ffc0bc9c
2007-08-20 Mathias Hasselmann <mathias.hasselmann@gmx.de>
* vala/valacastexpression.vala, gobject/valacodegenerator.vala,
vala/parser.y, vala/scanner.l: support C# like as operator
* tests/Makefile.am, tests/test-034.*: test the as operator
2007-08-20 Jürg Billeter <j@bitron.ch>
* vala/valafield.vala: support cheader_filename attribute,
......
......@@ -2453,7 +2453,25 @@ public class Vala.CodeGenerator : CodeVisitor {
public override void visit_cast_expression (CastExpression! expr) {
if (expr.type_reference.data_type is Class || expr.type_reference.data_type is Interface) {
// GObject cast
expr.ccodenode = new InstanceCast ((CCodeExpression) expr.inner.ccodenode, expr.type_reference.data_type);
if (expr.is_silent_cast) {
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable_declarator (expr.inner.static_type);
temp_vars.add (temp_decl);
var ctemp = new CCodeIdentifier (temp_decl.name);
var cinit = new CCodeAssignment (ctemp, (CCodeExpression) expr.inner.ccodenode);
var ccheck = create_type_check (ctemp, expr.type_reference.data_type);
var ccast = new CCodeCastExpression (ctemp, expr.type_reference.get_cname ());
var cnull = new CCodeConstant ("NULL");
ccomma.append_expression (cinit);
ccomma.append_expression (new CCodeConditionalExpression (ccheck, ccast, cnull));
expr.ccodenode = ccomma;
} else {
expr.ccodenode = new InstanceCast ((CCodeExpression) expr.inner.ccodenode, expr.type_reference.data_type);
}
} else {
expr.ccodenode = new CCodeCastExpression ((CCodeExpression) expr.inner.ccodenode, expr.type_reference.get_cname ());
}
......@@ -2549,10 +2567,14 @@ public class Vala.CodeGenerator : CodeVisitor {
visit_expression (expr);
}
static CCodeFunctionCall create_type_check (CCodeNode! ccodenode, DataType! type) {
var ccheck = new CCodeFunctionCall (new CCodeIdentifier (type.get_upper_case_cname ("IS_")));
ccheck.add_argument ((CCodeExpression) ccodenode);
return ccheck;
}
public override void visit_type_check (TypeCheck! expr) {
var ccheck = new CCodeFunctionCall (new CCodeIdentifier (expr.type_reference.data_type.get_upper_case_cname ("IS_")));
ccheck.add_argument ((CCodeExpression) expr.expression.ccodenode);
expr.ccodenode = ccheck;
expr.ccodenode = create_type_check (expr.expression.ccodenode, expr.type_reference.data_type);
}
public override void visit_conditional_expression (ConditionalExpression! expr) {
......
......@@ -66,6 +66,7 @@ TESTS = \
test-031.vala \
test-032.vala \
test-033.vala \
test-034.vala \
$(NULL)
EXTRA_DIST = \
......@@ -103,6 +104,7 @@ EXTRA_DIST = \
test-031.vala \
test-032.vala \
test-033.vala \
test-034.vala \
test-001.out \
test-002.out \
test-003.out \
......@@ -136,6 +138,7 @@ EXTRA_DIST = \
test-031.out \
test-032.out \
test-033.out \
test-034.out \
\
testenchant.stamp \
testenchant.vala \
......
init: 1 1 1
is A: 1 1 0
is B: 0 1 0
is C: 0 0 1
as A: 1 1 0
as B: 0 1 0
as C: 0 0 1
using GLib;
class Maman.A {
}
class Maman.B : A {
}
class Maman.C {
}
class Maman.Bar {
static void main () {
var a = new A ();
var b = new B ();
var c = new C ();
stdout.printf ("init: %d %d %d\n", null != a, null != b, null != c);
stdout.printf ("is A: %d %d %d\n", a is A, b is A, c is A);
stdout.printf ("is B: %d %d %d\n", a is B, b is B, c is B);
stdout.printf ("is C: %d %d %d\n", a is C, b is C, c is C);
stdout.printf ("as A: %d %d %d\n", null != (a as A), null != (b as A), null != (c as A));
stdout.printf ("as B: %d %d %d\n", null != (a as B), null != (b as B), null != (c as B));
stdout.printf ("as C: %d %d %d\n", null != (a as C), null != (b as C), null != (c as C));
}
}
......@@ -149,6 +149,7 @@ static gboolean check_is_class (ValaSymbol *symbol, ValaSourceReference *src);
%token PERCENT "%"
%token ABSTRACT "abstract"
%token AS "as"
%token BASE "base"
%token BREAK "break"
%token CASE "case"
......@@ -951,7 +952,7 @@ cast_expression
: OPEN_CAST_PARENS type CLOSE_PARENS unary_expression
{
ValaSourceReference *src = src(@1);
$$ = VALA_EXPRESSION (vala_cast_expression_new ($4, $2, src));
$$ = VALA_EXPRESSION (vala_cast_expression_new ($4, $2, src, FALSE));
g_object_unref (src);
g_object_unref ($2);
g_object_unref ($4);
......@@ -1090,6 +1091,14 @@ relational_expression
g_object_unref ($1);
g_object_unref ($3);
}
| relational_expression AS type
{
ValaSourceReference *src = src(@2);
$$ = VALA_EXPRESSION (vala_cast_expression_new ($1, $3, src, TRUE));
g_object_unref (src);
g_object_unref ($1);
g_object_unref ($3);
}
;
equality_expression
......
......@@ -128,6 +128,7 @@ literal ({integer_literal}|{real_literal}|{character_literal}|{string_literal
"@"[[:alnum:]_]+ { uploc; yylval->str = g_strdup (yytext + 1); return IDENTIFIER; }
"abstract" { uploc; return ABSTRACT; }
"as" { uploc; return AS; }
"base" { uploc; return BASE; }
"break" { uploc; return BREAK; }
"case" { uploc; return CASE; }
......
......@@ -44,6 +44,11 @@ public class Vala.CastExpression : Expression {
*/
public TypeReference! type_reference { get; set construct; }
/**
* Checked casts return NULL instead of raising an error.
*/
public bool is_silent_cast { get; set construct; }
private Expression! _inner;
/**
......@@ -53,10 +58,7 @@ public class Vala.CastExpression : Expression {
* @param type target type
* @return newly created cast expression
*/
public CastExpression (Expression! _inner, TypeReference! type, SourceReference source) {
inner = _inner;
type_reference = type;
source_reference = source;
public CastExpression (construct Expression! inner, construct TypeReference! type_reference, construct SourceReference source_reference, construct bool is_silent_cast) {
}
public override void accept (CodeVisitor! visitor) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment