[vala/staging] Use %? in the parser rather than stringifying expressions



commit 5061f69d4b938b14e73874a996713a9c56929b8c
Author: Luca Bruno <luca bruno immobiliare it>
Date:   Mon Feb 3 14:30:02 2014 +0100

    Use %? in the parser rather than stringifying expressions

 codegen/valaccodetransformer.vala | 49 ++++++++++++---------------------------
 vala/valacodebuilder.vala         |  8 +++----
 vala/valacodetransformer.vala     | 10 ++++----
 vala/valaparser.vala              | 35 +++++++++++++++++++++++++---
 4 files changed, 56 insertions(+), 46 deletions(-)
---
diff --git a/codegen/valaccodetransformer.vala b/codegen/valaccodetransformer.vala
index 82d260df6..26316734f 100644
--- a/codegen/valaccodetransformer.vala
+++ b/codegen/valaccodetransformer.vala
@@ -68,10 +68,7 @@ public class Vala.CCodeTransformer : CodeTransformer {
                if (!always_false (stmt.condition)) {
                        b.open_loop ();
                        if (!always_true (stmt.condition)) {
-                               var cond = expression (@"!$(stmt.condition)");
-                               b.open_if (cond);
-                               b.add_break ();
-                               b.close ();
+                               statements ("if (!%?) { break; }", {stmt.condition});
                        }
                        b.add_statement (stmt.body);
                        b.close ();
@@ -89,13 +86,7 @@ public class Vala.CCodeTransformer : CodeTransformer {
                // do not generate variable and if block if condition is always true
                if (!always_true (stmt.condition)) {
                        var notfirst = b.add_temp_declaration (null, expression ("false"));
-                       b.open_if (expression (notfirst));
-                       b.open_if (new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, stmt.condition, 
stmt.source_reference));
-                       b.add_break ();
-                       b.close ();
-                       b.add_else ();
-                       b.add_assignment (expression (notfirst), expression ("true"));
-                       b.close ();
+                       statements (@"if ($notfirst) { if (!%?) { break; } } else { $notfirst = true; }", 
{stmt.condition});
                }
                stmt.body.checked = false;
                b.add_statement (stmt.body);
@@ -125,7 +116,7 @@ public class Vala.CCodeTransformer : CodeTransformer {
                        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);
 
@@ -236,11 +227,7 @@ 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);
-                                       } else {
-                                       $result = $(expr.false_expression);
-                                       }");
+               statements (@"if (%?) { $result = %?; } else { $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);
@@ -261,26 +248,18 @@ public class Vala.CCodeTransformer : CodeTransformer {
                    && (expr.operator == BinaryOperator.AND || expr.operator == BinaryOperator.OR)) {
                        var is_and = expr.operator == BinaryOperator.AND;
                        var result = b.add_temp_declaration (data_type ("bool"));
-                       b.open_if (expr.left);
-                       if (is_and) {
-                               b.add_assignment (expression (result), expr.right);
-                       } else {
-                               b.add_expression (expression (@"$result = true"));
-                       }
-                       b.add_else ();
+
                        if (is_and) {
-                               b.add_expression (expression (@"$result = false"));
+                               statements (@"if (%?) { $result = %?; } else { $result = false; }", 
{expr.left, expr.right});
                        } else {
-                               b.add_assignment (expression (result), expr.right);
+                               statements (@"if (%?) { $result = true; } else { $result = %?; }", 
{expr.left, expr.right});
                        }
-                       b.close ();
+
                        replacement = expression (result);
                } else if (expr.operator == BinaryOperator.COALESCE) {
                        var result = b.add_temp_declaration (copy_type (expr.value_type, null, true), 
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)) {
@@ -359,7 +338,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]));
                                }
@@ -375,9 +354,11 @@ public class Vala.CCodeTransformer : CodeTransformer {
                begin_replace_expression (expr);
 
                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"));
-
+               if (expr.increment) {
+                       statements (@"$(expr.inner) = $result + 1;");
+               } else {
+                       statements (@"$(expr.inner) = $result - 1;");
+               }
                var replacement = return_temp_access (result, expr.value_type, expr.target_type);
 
                end_replace_expression (replacement);
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 a22842c68..ef811eb42 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) {
@@ -233,7 +233,7 @@ public class Vala.CodeTransformer : CodeVisitor {
                if (expr.value_type != null && 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});
                }
        }
 
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index ee1907d36..93eeeec5e 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;
@@ -340,12 +342,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;
@@ -359,17 +363,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;
@@ -383,7 +395,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;
        }
@@ -714,7 +732,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;
                }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]