From: Luca Bruno Date: Mon, 3 Feb 2014 13:30:02 +0000 (+0100) Subject: Use %? in the parser rather than stringifying expressions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d6d130f766f062602ba36289500e43b8b5e54ca;p=thirdparty%2Fvala.git Use %? in the parser rather than stringifying expressions --- diff --git a/codegen/valaccodetransformer.vala b/codegen/valaccodetransformer.vala index ac938907a..9f67943b6 100644 --- a/codegen/valaccodetransformer.vala +++ b/codegen/valaccodetransformer.vala @@ -68,7 +68,7 @@ public class Vala.CCodeTransformer : CodeTransformer { if (!stmt.condition.is_always_false ()) { b.open_loop (); if (!stmt.condition.is_always_true ()) { - var cond = expression (@"!$(stmt.condition)"); + var cond = expression ("!%?", {stmt.condition}); b.open_if (cond); b.add_break (); b.close (); @@ -125,7 +125,7 @@ public class Vala.CCodeTransformer : CodeTransformer { b.close (); if (stmt.condition != null && !stmt.condition.is_always_true ()) { - statements (@"if (!$(stmt.condition)) break;"); + statements ("if (!%?) break;", {stmt.condition}); } b.add_statement (stmt.body); @@ -237,11 +237,11 @@ public class Vala.CCodeTransformer : CodeTransformer { 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); @@ -266,11 +266,11 @@ public class Vala.CCodeTransformer : CodeTransformer { 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); } @@ -281,9 +281,7 @@ public class Vala.CCodeTransformer : CodeTransformer { result_type.nullable = true; var result = b.add_temp_declaration (result_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, result_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)) { @@ -362,7 +360,7 @@ public class Vala.CCodeTransformer : CodeTransformer { } 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])); } @@ -379,7 +377,7 @@ public class Vala.CCodeTransformer : CodeTransformer { 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); diff --git a/vala/valacodebuilder.vala b/vala/valacodebuilder.vala index 24774e71e..90d3c81d7 100644 --- a/vala/valacodebuilder.vala +++ b/vala/valacodebuilder.vala @@ -267,12 +267,12 @@ public class Vala.CodeBuilder { /* 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 diff --git a/vala/valacodetransformer.vala b/vala/valacodetransformer.vala index 2d6acaccb..e1fed6010 100644 --- a/vala/valacodetransformer.vala +++ b/vala/valacodetransformer.vala @@ -185,12 +185,12 @@ public class Vala.CodeTransformer : CodeVisitor { return CodeBuilder.data_type (s, value_owned, nullable); } - public Expression expression (string str) { - return b.expression (str); + public Expression expression (string str, owned Expression[]? replacements = null) { + return b.expression (str, (owned) 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) { @@ -223,7 +223,7 @@ public class Vala.CodeTransformer : CodeVisitor { if (expr.value_type != null && expr.value_type.type_symbol != null && expr.value_type.type_symbol.is_subtype_of (context.analyzer.string_type.type_symbol)) { return expr; } else { - return expression (@"$expr.to_string ()"); + return expression (@"%?.to_string ()", {expr}); } } diff --git a/vala/valaparser.vala b/vala/valaparser.vala index 17729b86b..1eba3bd9c 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -31,6 +31,8 @@ public class Vala.Parser : CodeVisitor { CodeContext context; bool compiler_code = false; SourceReference? from_string_reference = null; + Expression[]? replacements = null; + int replacement_index = 0; // token buffer TokenInfo[] tokens; @@ -369,12 +371,14 @@ public class Vala.Parser : CodeVisitor { } } - public Expression? parse_expression_string (string str, SourceReference source_reference) { + public Expression? parse_expression_string (string str, owned Expression[]? replacements, SourceReference source_reference) { Expression? result = null; 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; @@ -388,17 +392,25 @@ public class Vala.Parser : CodeVisitor { Report.error (source_reference, "internal error: %s".printf (e.message)); } + if (replacements.length > 0 && ++replacement_index != replacements.length) { + Report.error (source_reference, "internal error: %i replacements for %i placeholders".printf (replacements.length, replacement_index)); + } + scanner = null; + replacement_index = 0; + this.replacements = null; from_string_reference = null; compiler_code = false; return result; } - 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; @@ -412,7 +424,13 @@ public class Vala.Parser : CodeVisitor { Report.error (source_reference, "internal error: %s".printf (e.message)); } + if (replacements.length > 0 && ++replacement_index != replacements.length) { + Report.error (source_reference, "internal error: %i replacements for %i placeholders".printf (replacements.length, replacement_index)); + } + scanner = null; + replacement_index = 0; + this.replacements = null; from_string_reference = null; compiler_code = false; } @@ -756,7 +774,18 @@ public class Vala.Parser : CodeVisitor { expr = parse_typeof_expression (); break; default: - expr = parse_simple_name (); + if (compiler_code && current () == TokenType.PERCENT) { + var inner_begin = get_location (); + next (); + if (accept (TokenType.INTERR)) { + expr = (owned) replacements[replacement_index++]; + } else { + rollback (inner_begin); + expr = parse_simple_name (); + } + } else { + expr = parse_simple_name (); + } break; }