Fixes bug 622570.
methods/bug599892.vala \
methods/bug613483.vala \
methods/bug620673.vala \
+ methods/bug622570.vala \
methods/bug642899.vala \
methods/bug646345.vala \
methods/bug648320.vala \
--- /dev/null
+delegate int Deleg1 (ref int foo);
+delegate void Deleg2 (out Value foo, ref int bar);
+
+void main () {
+ int a = 3, b = 4;
+ Value c;
+ Deleg1 d1 = ref foo => foo + 5;
+ Deleg2 d2 = (out foo, ref bar) => { foo = 10; bar = 3; };
+ assert (d1 (ref a) == 8);
+ d2 (out c, ref b);
+ assert (c == 10);
+ assert (b == 3);
+}
public override void visit_lambda_expression (LambdaExpression expr) {
write_string ("(");
var params = expr.get_parameters ();
- if (params.size != 0) {
- for (var i = 0; i < params.size - 1; ++ i) {
- write_string (params[i]);
+ int i = 1;
+ foreach (var param in params) {
+ if (i > 1) {
write_string (", ");
}
- write_string (params[params.size - 1]);
+
+ if (param.direction == ParameterDirection.REF) {
+ write_string ("ref ");
+ } else if (param.direction == ParameterDirection.OUT) {
+ write_string ("out ");
+ }
+
+ write_identifier (param.name);
+
+ i++;
}
write_string (") =>");
if (expr.statement_body != null) {
Expression parse_lambda_expression () throws ParseError {
var begin = get_location ();
- List<string> params = new ArrayList<string> ();
+ List<Parameter> params = new ArrayList<Parameter> ();
expect (TokenType.DEF);
if (accept (TokenType.OPEN_PARENS)) {
if (current () != TokenType.CLOSE_PARENS) {
do {
- params.add (parse_identifier ());
+ var param = new Parameter (parse_identifier (), null, get_src (get_location ()));
+ params.add (param);
} while (accept (TokenType.COMMA));
}
expect (TokenType.CLOSE_PARENS);
} else {
- params.add (parse_identifier ());
+ var param = new Parameter (parse_identifier (), null, get_src (get_location ()));
+ params.add (param);
}
}
- foreach (string param in params) {
+ foreach (var param in params) {
lambda.add_parameter (param);
}
return lambda;
*/
public Method method { get; set; }
- private List<string> parameters = new ArrayList<string> ();
+ private List<Parameter> parameters = new ArrayList<Parameter> ();
/**
* Creates a new lambda expression.
*
* @param param parameter name
*/
- public void add_parameter (string param) {
+ public void add_parameter (Parameter param) {
parameters.add (param);
}
*
* @return parameter list
*/
- public List<string> get_parameters () {
+ public List<Parameter> get_parameters () {
return parameters;
}
}
var lambda_params = get_parameters ();
- Iterator<string> lambda_param_it = lambda_params.iterator ();
+ Iterator<Parameter> lambda_param_it = lambda_params.iterator ();
if (cb.sender_type != null && lambda_params.size == cb.get_parameters ().size + 1) {
// lambda expression has sender parameter
lambda_param_it.next ();
- string lambda_param = lambda_param_it.get ();
- var param = new Parameter (lambda_param, cb.sender_type);
- method.add_parameter (param);
+ Parameter lambda_param = lambda_param_it.get ();
+ lambda_param.variable_type = cb.sender_type;
+ method.add_parameter (lambda_param);
}
foreach (Parameter cb_param in cb.get_parameters ()) {
break;
}
- string lambda_param = lambda_param_it.get ();
- var param_type = cb_param.variable_type.get_actual_type (target_type, null, this);
- var param = new Parameter (lambda_param, param_type);
- method.add_parameter (param);
+ Parameter lambda_param = lambda_param_it.get ();
+ lambda_param.variable_type = cb_param.variable_type.get_actual_type (target_type, null, this);
+ method.add_parameter (lambda_param);
}
if (lambda_param_it.next ()) {
* @param source reference to source code
* @return newly created formal parameter
*/
- public Parameter (string name, DataType variable_type, SourceReference? source_reference = null) {
+ public Parameter (string name, DataType? variable_type, SourceReference? source_reference = null) {
base (variable_type, name, null, source_reference);
access = SymbolAccessibility.PUBLIC;
}
}
+ Parameter parse_lambda_parameter () throws ParseError {
+ var begin = get_location ();
+ var direction = ParameterDirection.IN;
+ if (accept (TokenType.OUT)) {
+ direction = ParameterDirection.OUT;
+ } else if (accept (TokenType.REF)) {
+ direction = ParameterDirection.REF;
+ }
+
+ string id = parse_identifier ();
+
+ var param = new Parameter (id, null, get_src (begin));
+ param.direction = direction;
+ return param;
+ }
+
Expression parse_lambda_expression () throws ParseError {
var begin = get_location ();
- List<string> params = new ArrayList<string> ();
+ List<Parameter> params = new ArrayList<Parameter> ();
if (accept (TokenType.OPEN_PARENS)) {
if (current () != TokenType.CLOSE_PARENS) {
do {
- params.add (parse_identifier ());
+ params.add (parse_lambda_parameter ());
} while (accept (TokenType.COMMA));
}
expect (TokenType.CLOSE_PARENS);
} else {
- params.add (parse_identifier ());
+ params.add (parse_lambda_parameter ());
}
expect (TokenType.LAMBDA);
var expr = parse_expression ();
lambda = new LambdaExpression (expr, get_src (begin));
}
- foreach (string param in params) {
+ foreach (var param in params) {
lambda.add_parameter (param);
}
return lambda;
}
Expression parse_expression () throws ParseError {
+ if (is_lambda_expression ()) {
+ return parse_lambda_expression ();
+ }
+
var begin = get_location ();
- Expression expr = parse_conditional_expression ();
- if (current () == TokenType.LAMBDA) {
- rollback (begin);
- var lambda = parse_lambda_expression ();
- return lambda;
- }
+ Expression expr = parse_conditional_expression ();
while (true) {
var operator = get_assignment_operator (current ());
}
}
+ bool is_lambda_expression () {
+ var begin = get_location ();
+
+ switch (current ()) {
+ case TokenType.OUT:
+ case TokenType.REF:
+ next ();
+ if (accept (TokenType.IDENTIFIER) && accept (TokenType.LAMBDA)) {
+ rollback (begin);
+ return true;
+ }
+ break;
+ case TokenType.IDENTIFIER:
+ next ();
+ if (accept (TokenType.LAMBDA)) {
+ rollback (begin);
+ return true;
+ }
+ break;
+ case TokenType.OPEN_PARENS:
+ next ();
+ if (current () != TokenType.CLOSE_PARENS) {
+ do {
+ if (current () == TokenType.OUT || current () == TokenType.REF) {
+ next ();
+ }
+ if (!accept (TokenType.IDENTIFIER)) {
+ rollback (begin);
+ return false;
+ }
+ } while (accept (TokenType.COMMA));
+ }
+ if (accept (TokenType.CLOSE_PARENS) && accept (TokenType.LAMBDA)) {
+ rollback (begin);
+ return true;
+ }
+ break;
+ }
+
+ rollback (begin);
+ return false;
+ }
+
Block parse_embedded_statement () throws ParseError {
if (current () == TokenType.OPEN_BRACE) {
var block = parse_block ();