if (!always_false (stmt.condition)) {
b.open_loop ();
if (!always_true (stmt.condition)) {
- var cond = expression (@"!$(stmt.condition)");
+ var cond = expression ("!%?", {stmt.condition});
b.open_if (cond);
b.add_break ();
b.close ();
b.close ();
if (stmt.condition != null && !always_true (stmt.condition)) {
- statements (@"if (!$(stmt.condition)) break;");
+ statements ("if (!%?) break;", {stmt.condition});
}
b.add_statement (stmt.body);
begin_replace_expression (expr);
var result = b.add_temp_declaration (expr.value_type);
- statements (@"if ($(expr.condition)) {
- $result = $(expr.true_expression);
+ statements (@"if (%?) {
+ $result = %?;
} else {
- $result = $(expr.false_expression);
- }");
+ $result = %?;
+ }", {expr.condition, expr.true_expression, expr.false_expression});
replacement = return_temp_access (result, expr.value_type, target_type, formal_target_type);
end_replace_expression (replacement);
if (is_and) {
b.add_assignment (expression (result), expr.right);
} else {
- b.add_expression (expression (@"$result = true"));
+ statements (@"$result = true;");
}
b.add_else ();
if (is_and) {
- b.add_expression (expression (@"$result = false"));
+ statements (@"$result = false;");
} else {
b.add_assignment (expression (result), expr.right);
}
} else if (expr.operator == BinaryOperator.COALESCE) {
var result = b.add_temp_declaration (copy_type (expr.value_type), expr.left);
- b.open_if (expression (@"$result == null"));
- b.add_assignment (expression (result), expr.right);
- b.close ();
+ statements (@"if ($result == null) { $result = %?; }", {expr.right});
replacement = return_temp_access (result, expr.value_type, target_type);
} else if (expr.operator == BinaryOperator.IN && !(expr.left.value_type.compatible (context.analyzer.int_type) && expr.right.value_type.compatible (context.analyzer.int_type)) && !(expr.right.value_type is ArrayType)) {
if (expr.value_type.data_type != null && expr.value_type.data_type.is_subtype_of (context.analyzer.string_type.data_type)) {
return expr;
} else {
- return expression (@"$expr.to_string ()");
+ return expression (@"%?.to_string ()", {expr});
}
}
} else {
replacement = stringify (expression_list[0]);
if (expression_list.size > 1) {
- var concat = (MethodCall) expression (@"$replacement.concat()");
+ var concat = (MethodCall) expression ("%?.concat()", {replacement});
for (int i = 1; i < expression_list.size; i++) {
concat.add_argument (stringify (expression_list[i]));
}
var result = b.add_temp_declaration (copy_type (expr.value_type), expr.inner);
var op = expr.increment ? "+ 1" : "- 1";
- b.add_expression (expression (@"$(expr.inner) = $result $op"));
+ statements (@"$(expr.inner) = $result $op;");
var replacement = return_temp_access (result, expr.value_type, expr.target_type);
m.add_parameter (new Parameter ("variant", data_type ("GLib.Variant", false), b.source_reference));
push_builder (new CodeBuilder.for_subroutine (m));
- var iterator = b.add_temp_declaration (data_type ("GLib.VariantIter"), expression (@"variant.iterator ()"));
+ var iterator = b.add_temp_declaration (data_type ("GLib.VariantIter"), expression ("variant.iterator ()"));
var result = b.add_temp_declaration (type, expression ("{}"));
m.add_parameter (new Parameter ("variant", data_type ("GLib.Variant", false), b.source_reference));
push_builder (new CodeBuilder.for_subroutine (m));
- var iterator = b.add_temp_declaration (data_type ("GLib.VariantIter"), expression (@"variant.iterator ()"));
+ var iterator = b.add_temp_declaration (data_type ("GLib.VariantIter"), expression ("variant.iterator ()"));
var type_args = type.get_type_arguments ();
assert (type_args.size == 2);
/* Utilities for building the code */
- public Expression expression (string str) {
- return new Parser().parse_expression_string (str, source_reference);
+ public Expression expression (string str, owned Expression[]? replacements = null) {
+ return new Parser().parse_expression_string (str, (owned) replacements, source_reference);
}
- public void statements (string str) {
- new Parser().parse_statements_string (str, current_block, source_reference);
+ public void statements (string str, owned Expression[]? replacements = null) {
+ new Parser().parse_statements_string (str, current_block, (owned) replacements, source_reference);
}
// only qualified types, will slightly simplify the work of SymbolResolver
return CodeBuilder.data_type (s, value_owned, nullable);
}
- public Expression expression (string str) {
- return b.expression (str);
+ public Expression expression (string str, Expression[]? replacements = null) {
+ return b.expression (str, replacements);
}
- public void statements (string str) {
- b.statements (str);
+ public void statements (string str, owned Expression[]? replacements = null) {
+ b.statements (str, (owned) replacements);
}
public void check (CodeNode node) {
CodeContext context;
bool compiler_code = false;
SourceReference? from_string_reference = null;
+ Expression[]? replacements = null;
+ int replacement_index = 0;
// token buffer
TokenInfo[] tokens;
}
}
- public Expression? parse_expression_string (string str, SourceReference source_reference) {
+ public Expression? parse_expression_string (string str, owned Expression[]? replacements, SourceReference source_reference) {
compiler_code = true;
context = source_reference.file.context;
from_string_reference = source_reference;
+ this.replacements = (owned) replacements;
+ replacement_index = 0;
scanner = new Scanner.from_string (str, source_reference.file);
index = -1;
return null;
}
- public void parse_statements_string (string str, Block block, SourceReference source_reference) {
+ public void parse_statements_string (string str, Block block, owned Expression[]? replacements, SourceReference source_reference) {
compiler_code = true;
context = source_reference.file.context;
from_string_reference = source_reference;
+ this.replacements = (owned) replacements;
+ replacement_index = 0;
scanner = new Scanner.from_string (str, source_reference.file);
index = -1;
expr = parse_typeof_expression ();
break;
default:
- expr = parse_simple_name ();
+ if (compiler_code && current () == TokenType.PERCENT) {
+ var begin2 = get_location ();
+ next ();
+ if (accept (TokenType.INTERR)) {
+ expr = replacements[replacement_index++];
+ } else {
+ rollback (begin2);
+ expr = parse_simple_name ();
+ }
+ } else {
+ expr = parse_simple_name ();
+ }
break;
}