[vala/wip/transform-ast: 4/24] parser: Allow to parse expressions/statements from string



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

    parser: Allow to parse expressions/statements from string

 vala/valaparser.vala  | 95 +++++++++++++++++++++++++++++++++++++++++++++++----
 vala/valascanner.vala | 14 ++++++++
 2 files changed, 102 insertions(+), 7 deletions(-)
---
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index f1b49352d..17729b86b 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;
@@ -165,18 +167,30 @@ 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 () {
-               int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
-               var token = tokens[last_index];
-               return new SourceReference (scanner.source_file, token.begin, token.end);
+               if (from_string_reference == null) {
+                       int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
+                       var token = tokens[last_index];
+                       return new SourceReference (scanner.source_file, token.begin, token.end);
+               } else {
+                       return from_string_reference;
+               }
        }
 
        void rollback (SourceLocation location) {
@@ -281,6 +295,11 @@ public class Vala.Parser : CodeVisitor {
                        }
                        break;
                default:
+                       if (compiler_code && current () == TokenType.DOT) {
+                               next();
+                               next();
+                               return;
+                       }
                        throw new ParseError.SYNTAX ("expected identifier");
                }
        }
@@ -350,6 +369,54 @@ public class Vala.Parser : CodeVisitor {
                }
        }
 
+       public Expression? parse_expression_string (string str, SourceReference source_reference) {
+               Expression? result = null;
+
+               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 {
+                       result = parse_expression ();
+               } catch (Error e) {
+                       Report.error (source_reference, "internal error: %s".printf (e.message));
+               }
+
+               scanner = null;
+               from_string_reference = null;
+               compiler_code = false;
+
+               return result;
+       }
+
+       public void parse_statements_string (string str, Block block, 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 {
+                       parse_statements (block);
+               } catch (Error e) {
+                       Report.error (source_reference, "internal error: %s".printf (e.message));
+               }
+
+               scanner = null;
+               from_string_reference = null;
+               compiler_code = false;
+       }
+
        public void parse_file (SourceFile source_file) {
                var has_global_context = (context != null);
                if (!has_global_context) {
@@ -389,6 +456,9 @@ public class Vala.Parser : CodeVisitor {
        }
 
        void skip_symbol_name () throws ParseError {
+               if (compiler_code && accept (TokenType.DOT)) {
+                       // temporary variable
+               }
                do {
                        skip_identifier ();
                } while (accept (TokenType.DOT) || accept (TokenType.DOUBLE_COLON));
@@ -723,7 +793,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 ();
@@ -1634,6 +1711,10 @@ public class Vala.Parser : CodeVisitor {
                                        break;
                                default:
                                        bool is_expr = is_expression ();
+                                       if (!is_expr && compiler_code && current () == TokenType.DOT) {
+                                               // compiler variable assignment
+                                               is_expr = true;
+                                       }
                                        if (is_expr) {
                                                stmt = parse_expression_statement ();
                                        } else {
diff --git a/vala/valascanner.vala b/vala/valascanner.vala
index a2e76b4d5..89fc5dbb5 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]