[vala/wip/transform: 13/49] Parse expressions from string



commit 803a7333da5c8ce8760bc96e4d61648c201141a8
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                 |   43 +++++++++++++++++++++++++++++++--
 vala/valascanner.vala                |   14 +++++++++++
 3 files changed, 65 insertions(+), 28 deletions(-)
---
diff --git a/codegen/valagvarianttransformer.vala b/codegen/valagvarianttransformer.vala
index af6fa2e..2e0158e 100644
--- a/codegen/valagvarianttransformer.vala
+++ b/codegen/valagvarianttransformer.vala
@@ -58,22 +58,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;
 	}
@@ -170,15 +160,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));
@@ -186,27 +172,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 487a3ee..8e300b2 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,11 +149,19 @@ 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.line, begin.column, tokens[last_index].end.line, tokens[last_index].end.column);
+		if (from_string_reference == null) {
+			return new SourceReference (scanner.source_file, begin.line, begin.column, tokens[last_index].end.line, tokens[last_index].end.column);
+		} else {
+			return from_string_reference;
+		}
 	}
 
 	SourceReference get_current_src () {
-		return new SourceReference (scanner.source_file, tokens[index].begin.line, tokens[index].begin.column, tokens[index].end.line, tokens[index].end.column);
+		if (from_string_reference == null) {
+			return new SourceReference (scanner.source_file, tokens[index].begin.line, tokens[index].begin.column, tokens[index].end.line, tokens[index].end.column);
+		} else {
+			return from_string_reference;
+		}
 	}
 
 	SourceReference get_last_src () {
@@ -320,6 +330,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) {
 		scanner = new Scanner (source_file);
 		parse_file_comments ();
@@ -669,7 +699,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 624c77d..77445ca 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]