[vala] Add suport for local constants



commit 46fece1d814e59bb1443697fda41132a93bc4978
Author: Jürg Billeter <j bitron ch>
Date:   Wed Oct 13 22:17:41 2010 +0200

    Add suport for local constants
    
    Fixes bug 530623.

 codegen/valaccodebasemodule.vala |   30 ++++++++++++++++++++++++++++++
 vala/valablock.vala              |   20 +++++++++++++++++++-
 vala/valaconstant.vala           |    2 ++
 vala/valaparser.vala             |   29 +++++++++++++++++++++++++++++
 vala/valasymbolresolver.vala     |    3 +++
 5 files changed, 83 insertions(+), 1 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 61eb626..3d8b005 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -719,6 +719,11 @@ public class Vala.CCodeBaseModule : CodeGenerator {
 	}
 
 	public void generate_constant_declaration (Constant c, CCodeFile decl_space, bool definition = false) {
+		if (c.parent_symbol is Block) {
+			// local constant
+			return;
+		}
+
 		if (add_symbol_declaration (decl_space, c, c.get_cname ())) {
 			return;
 		}
@@ -759,6 +764,31 @@ public class Vala.CCodeBaseModule : CodeGenerator {
 	}
 
 	public override void visit_constant (Constant c) {
+		if (c.parent_symbol is Block) {
+			// local constant
+
+			generate_type_declaration (c.type_reference, cfile);
+
+			c.value.emit (this);
+
+			string type_name = c.type_reference.get_const_cname ();
+			string arr = "";
+			if (c.type_reference is ArrayType) {
+				arr = "[]";
+			}
+
+			if (c.type_reference.compatible (string_type)) {
+				type_name = "const char";
+				arr = "[]";
+			}
+
+			var cinitializer = get_cvalue (c.value);
+
+			ccode.add_declaration (type_name, new CCodeVariableDeclarator ("%s%s".printf (c.get_cname (), arr), cinitializer), CCodeModifiers.STATIC);
+
+			return;
+		}
+
 		generate_constant_declaration (c, cfile, true);
 
 		if (!c.is_internal_symbol ()) {
diff --git a/vala/valablock.vala b/vala/valablock.vala
index d7b35f2..c5b044d 100644
--- a/vala/valablock.vala
+++ b/vala/valablock.vala
@@ -36,6 +36,7 @@ public class Vala.Block : Symbol, Statement {
 
 	private List<Statement> statement_list = new ArrayList<Statement> ();
 	private List<LocalVariable> local_variables = new ArrayList<LocalVariable> ();
+	private List<Constant> local_constants = new ArrayList<Constant> ();
 	
 	/**
 	 * Creates a new block.
@@ -90,7 +91,7 @@ public class Vala.Block : Symbol, Statement {
 		var parent_block = parent_symbol;
 		while (parent_block is Block || parent_block is Method || parent_block is PropertyAccessor) {
 			if (parent_block.scope.lookup (local.name) != null) {
-				Report.error (local.source_reference, "Local variable `%s' conflicts with another local variable declared in a parent scope".printf (local.name));
+				Report.error (local.source_reference, "Local variable `%s' conflicts with a local variable or constant declared in a parent scope".printf (local.name));
 				break;
 			}
 			parent_block = parent_block.parent_symbol;
@@ -111,6 +112,19 @@ public class Vala.Block : Symbol, Statement {
 		return local_variables;
 	}
 
+	public void add_local_constant (Constant constant) {
+		var parent_block = parent_symbol;
+		while (parent_block is Block || parent_block is Method || parent_block is PropertyAccessor) {
+			if (parent_block.scope.lookup (constant.name) != null) {
+				Report.error (constant.source_reference, "Local constant `%s' conflicts with a local variable or constant declared in a parent scope".printf (constant.name));
+				break;
+			}
+			parent_block = parent_block.parent_symbol;
+		}
+		local_constants.add (constant);
+		scope.add (constant.name, constant);
+	}
+
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_block (this);
 	}
@@ -143,6 +157,10 @@ public class Vala.Block : Symbol, Statement {
 			local.active = false;
 		}
 
+		foreach (Constant constant in local_constants) {
+			constant.active = false;
+		}
+
 		// use get_statements () instead of statement_list to not miss errors within StatementList objects
 		foreach (Statement stmt in get_statements ()) {
 			add_error_types (stmt.get_error_types ());
diff --git a/vala/valaconstant.vala b/vala/valaconstant.vala
index 02b815f..9860c3a 100644
--- a/vala/valaconstant.vala
+++ b/vala/valaconstant.vala
@@ -217,6 +217,8 @@ public class Vala.Constant : Symbol, Lockable {
 		analyzer.current_source_file = old_source_file;
 		analyzer.current_symbol = old_symbol;
 
+		active = true;
+
 		return !error;
 	}
 
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 44fbd00..43dd8e0 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -1495,6 +1495,10 @@ public class Vala.Parser : CodeVisitor {
 					is_decl = true;
 					parse_local_variable_declarations (block);
 					break;
+				case TokenType.CONST:
+					is_decl = true;
+					parse_local_constant_declarations (block);
+					break;
 				case TokenType.OP_INC:
 				case TokenType.OP_DEC:
 				case TokenType.BASE:
@@ -1709,6 +1713,31 @@ public class Vala.Parser : CodeVisitor {
 		return new LocalVariable (type, id, initializer, get_src (begin));
 	}
 
+	void parse_local_constant_declarations (Block block) throws ParseError {
+		expect (TokenType.CONST);
+		var constant_type = parse_type (false, false);
+		do {
+			DataType type_copy = constant_type.copy ();
+			var local = parse_local_constant (type_copy);
+			block.add_statement (new DeclarationStatement (local, local.source_reference));
+			block.add_local_constant (local);
+			local.active = false;
+		} while (accept (TokenType.COMMA));
+		expect (TokenType.SEMICOLON);
+	}
+
+	Constant parse_local_constant (DataType constant_type) throws ParseError {
+		var begin = get_location ();
+		string id = parse_identifier ();
+
+		var type = parse_inline_array_type (constant_type);
+
+		expect (TokenType.ASSIGN);
+		var initializer = parse_expression ();
+
+		return new Constant (id, type, initializer, get_src (begin));
+	}
+
 	Statement parse_expression_statement () throws ParseError {
 		var begin = get_location ();
 		var expr = parse_statement_expression ();
diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala
index 0afb976..54b3309 100644
--- a/vala/valasymbolresolver.vala
+++ b/vala/valasymbolresolver.vala
@@ -158,9 +158,12 @@ public class Vala.SymbolResolver : CodeVisitor {
 	}
 
 	public override void visit_constant (Constant c) {
+		var old_scope = current_scope;
 		current_scope = c.scope;
 
 		c.accept_children (this);
+
+		current_scope = old_scope;
 	}
 
 	public override void visit_field (Field f) {



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