[vala/wip/transform: 21/102] Parse expressions from string



commit 48ef51534d0abdfd7d5889a2a57560a431f4008a
Author: Luca Bruno <lucabru src gnome org>
Date:   Fri Dec 30 09:26:26 2011 +0100

    Parse expressions from string

 codegen/valagvarianttransformer.vala | 36 +++++++++--------------------
 vala/valaparser.vala                 | 45 ++++++++++++++++++++++++++++++++----
 vala/valascanner.vala                | 14 +++++++++++
 3 files changed, 66 insertions(+), 29 deletions(-)
---
diff --git a/codegen/valagvarianttransformer.vala b/codegen/valagvarianttransformer.vala
index 239f8488e..d1f337a54 100644
--- a/codegen/valagvarianttransformer.vala
+++ b/codegen/valagvarianttransformer.vala
@@ -60,22 +60,12 @@ public class Vala.GVariantTransformer : CodeTransformer {
                return false;
        }
 
-       MemberAccess member_access (string symbol_string) {
-               MemberAccess? ma = null;
-               bool first = true;
-               foreach (unowned string s in symbol_string.substring(1).split (".")) {
-                       if (first) {
-                               ma = new MemberAccess (ma, symbol_string[0].to_string()+s, 
b.source_reference);
-                               first = false;
-                       } else {
-                               ma = new MemberAccess (ma, s, b.source_reference);
-                       }
-               }
-               return ma;
+       Expression expression (string str) {
+               return new Parser().parse_expression_string (str, b.source_reference);
        }
 
        Expression serialize_basic (BasicTypeInfo basic_type, Expression expr) {
-               var new_call = new ObjectCreationExpression (member_access ("GLib.Variant." + 
basic_type.type_name), expr.source_reference);
+               var new_call = (ObjectCreationExpression) expression (@"new 
GLib.Variant.$(basic_type.type_name)()");
                new_call.add_argument (expr);
                return new_call;
        }
@@ -172,15 +162,11 @@ public class Vala.GVariantTransformer : CodeTransformer {
        }
 
        Expression serialize_array_dim (ArrayType array_type, int dim, string[] indices, string array_var) {
-               var gvariant_type = new ObjectCreationExpression (member_access ("GLib.VariantType"), 
b.source_reference);
-               gvariant_type.add_argument (new StringLiteral ("\""+get_type_signature (array_type)+"\""));
-
-               var builderinit = new ObjectCreationExpression (member_access ("GLib.VariantBuilder"), 
b.source_reference);
-               builderinit.add_argument (gvariant_type);
+               var builderinit = expression (@"new GLib.VariantBuilder (new GLib.VariantType 
(\"$(get_type_signature (array_type))\"))");
 
                var builder = b.add_temp_declaration (null, builderinit);
 
-               Expression length = member_access (array_var+".length");
+               Expression length = expression (array_var+".length");
                if (array_type.rank > 1) {
                        ElementAccess ea = new ElementAccess (length, b.source_reference);
                        ea.append_index (new IntegerLiteral ((dim-1).to_string (), b.source_reference));
@@ -188,27 +174,27 @@ public class Vala.GVariantTransformer : CodeTransformer {
                }
 
                var index = indices[dim-1];
-               var forcond = new BinaryExpression (BinaryOperator.LESS_THAN, member_access (index), length, 
b.source_reference);
-               var foriter = new PostfixExpression (member_access (index), true, b.source_reference);
+               var forcond = new BinaryExpression (BinaryOperator.LESS_THAN, expression (index), length, 
b.source_reference);
+               var foriter = new PostfixExpression (expression (index), true, b.source_reference);
                b.open_for (null, forcond, foriter);
 
                Expression element_variant;
                if (dim < array_type.rank) {
                        element_variant = serialize_array_dim (array_type, dim + 1, indices, array_var);
                } else {
-                       var element_expr = new ElementAccess (member_access (array_var), b.source_reference);
+                       var element_expr = new ElementAccess (expression (array_var), b.source_reference);
                        for (int i=0; i < dim; i++) {
-                               element_expr.append_index (member_access (indices[i]));
+                               element_expr.append_index (expression (indices[i]));
                        }
                        element_variant = serialize_expression (array_type.element_type, element_expr);
                }
 
-               var builder_add = new MethodCall (member_access (builder+".add_value"), b.source_reference);
+               var builder_add = new MethodCall (expression (builder+".add_value"), b.source_reference);
                builder_add.add_argument (element_variant);
                b.add_expression (builder_add);
                b.close ();
 
-               var builder_end = new MethodCall (member_access (builder+".end"), b.source_reference);
+               var builder_end = new MethodCall (expression (builder+".end"), b.source_reference);
                return builder_end;
        }
 
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index f52fba893..ab86256a2 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -29,6 +29,8 @@ public class Vala.Parser : CodeVisitor {
        Scanner scanner;
 
        CodeContext context;
+       bool compiler_code = false;
+       SourceReference? from_string_reference = null;
 
        // token buffer
        TokenInfo[] tokens;
@@ -147,12 +149,20 @@ public class Vala.Parser : CodeVisitor {
        SourceReference get_src (SourceLocation begin) {
                int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
 
-               return new SourceReference (scanner.source_file, begin, tokens[last_index].end);
+               if (from_string_reference == null) {
+                       return new SourceReference (scanner.source_file, begin, tokens[last_index].end);
+               } else {
+                       return from_string_reference;
+               }
        }
 
        SourceReference get_current_src () {
-               var token = tokens[index];
-               return new SourceReference (scanner.source_file, token.begin, token.end);
+               if (from_string_reference == null) {
+                       var token = tokens[index];
+                       return new SourceReference (scanner.source_file, token.begin, token.end);
+               } else {
+                       return from_string_reference;
+               }
        }
 
        SourceReference get_last_src () {
@@ -322,6 +332,26 @@ public class Vala.Parser : CodeVisitor {
                }
        }
 
+       public Expression? parse_expression_string (string str, SourceReference source_reference) {
+               compiler_code = true;
+               context = source_reference.file.context;
+               from_string_reference = source_reference;
+
+               scanner = new Scanner.from_string (str, source_reference.file);
+               index = -1;
+               size = 0;
+
+               next ();
+
+               try {
+                       return parse_expression ();
+               } catch (Error e) {
+               }
+
+               scanner = null;
+               return null;
+       }
+
        public void parse_file (SourceFile source_file) {
                var has_global_context = (context != null);
                if (!has_global_context) {
@@ -682,7 +712,14 @@ public class Vala.Parser : CodeVisitor {
 
        Expression parse_simple_name () throws ParseError {
                var begin = get_location ();
-               string id = parse_identifier ();
+               string id;
+               if (compiler_code && accept (TokenType.DOT)) {
+                       // temporary variable
+                       next ();
+                       id = "."+get_last_string ();
+               } else {
+                       id = parse_identifier ();
+               }
                bool qualified = false;
                if (id == "global" && accept (TokenType.DOUBLE_COLON)) {
                        id = parse_identifier ();
diff --git a/vala/valascanner.vala b/vala/valascanner.vala
index 718b65471..6a5a38624 100644
--- a/vala/valascanner.vala
+++ b/vala/valascanner.vala
@@ -28,6 +28,7 @@ using GLib;
  */
 public class Vala.Scanner {
        public SourceFile source_file { get; private set; }
+       string buffer;
 
        TokenType previous;
        char* current;
@@ -69,6 +70,19 @@ public class Vala.Scanner {
                column = 1;
        }
 
+       public Scanner.from_string (string str, SourceFile source_file) {
+               this.source_file = source_file;
+               buffer = str; // keep alive
+
+               char* begin = str;
+               end = begin + str.length;
+
+               current = begin;
+
+               line = 1;
+               column = 1;
+       }
+
        public void seek (SourceLocation location) {
                current = location.pos;
                line = location.line;


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