[vala/wip/transform: 42/47] DOM-like linked list of statements



commit 8fb338d112b9f163a2ff7c243a8894d62020422c
Author: Luca Bruno <lucabru src gnome org>
Date:   Thu Jan 5 15:33:32 2012 +0100

    DOM-like linked list of statements

 codegen/valaccodebasemodule.vala   |    2 +-
 codegen/valadovabasemodule.vala    |    2 +-
 vala/Makefile.am                   |    2 +-
 vala/valabasestatement.vala        |   32 +++++++++
 vala/valablock.vala                |  134 ++++++++++++++++++++----------------
 vala/valabreakstatement.vala       |    2 +-
 vala/valacodewriter.vala           |    2 +-
 vala/valacontinuestatement.vala    |    2 +-
 vala/valadeclarationstatement.vala |    2 +-
 vala/valadeletestatement.vala      |    2 +-
 vala/valadostatement.vala          |    2 +-
 vala/valaemptystatement.vala       |    2 +-
 vala/valaexpressionstatement.vala  |    2 +-
 vala/valaflowanalyzer.vala         |    2 +-
 vala/valaforeachstatement.vala     |    2 +-
 vala/valaforstatement.vala         |    2 +-
 vala/valaifstatement.vala          |    2 +-
 vala/valalockstatement.vala        |    2 +-
 vala/valaloop.vala                 |    2 +-
 vala/valareturnstatement.vala      |    2 +-
 vala/valastatement.vala            |    2 +
 vala/valastatementlist.vala        |   77 ---------------------
 vala/valaswitchsection.vala        |    6 +-
 vala/valaswitchstatement.vala      |    2 +-
 vala/valathrowstatement.vala       |    2 +-
 vala/valatrystatement.vala         |    2 +-
 vala/valaunlockstatement.vala      |    2 +-
 vala/valawhilestatement.vala       |    2 +-
 vala/valayieldstatement.vala       |    2 +-
 29 files changed, 135 insertions(+), 164 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index a39c558..cf7f058 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2044,7 +2044,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 			cfile.add_function (unref_fun);
 		}
 
-		foreach (Statement stmt in b.get_statements ()) {
+		foreach (Statement stmt in b) {
 			push_line (stmt.source_reference);
 			stmt.emit (this);
 			pop_line ();
diff --git a/codegen/valadovabasemodule.vala b/codegen/valadovabasemodule.vala
index bb85873..f969801 100644
--- a/codegen/valadovabasemodule.vala
+++ b/codegen/valadovabasemodule.vala
@@ -782,7 +782,7 @@ public abstract class Vala.DovaBaseModule : CodeGenerator {
 			cfile.add_function (unref_fun);
 		}
 
-		foreach (Statement stmt in b.get_statements ()) {
+		foreach (Statement stmt in b) {
 			stmt.emit (this);
 		}
 
diff --git a/vala/Makefile.am b/vala/Makefile.am
index d0eb485..5a2a2ab 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -23,6 +23,7 @@ libvalacore_la_VALASOURCES = \
 	valaassignment.vala \
 	valaattribute.vala \
 	valabaseaccess.vala \
+	valabasestatement.vala \
 	valabasicblock.vala \
 	valabinaryexpression.vala \
 	valablock.vala \
@@ -134,7 +135,6 @@ libvalacore_la_VALASOURCES = \
 	valasourcelocation.vala \
 	valasourcereference.vala \
 	valastatement.vala \
-	valastatementlist.vala \
 	valastringliteral.vala \
 	valastruct.vala \
 	valastructvaluetype.vala \
diff --git a/vala/valabasestatement.vala b/vala/valabasestatement.vala
new file mode 100644
index 0000000..33d2516
--- /dev/null
+++ b/vala/valabasestatement.vala
@@ -0,0 +1,32 @@
+/* valabasestatement.vala
+ *
+ * Copyright (C) 2012  Luca Bruno
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ * 	Luca Bruno <lucabru src gnome org>
+ */
+
+using GLib;
+
+/**
+ * Simple class implementing Statement.
+ */
+public class Vala.BaseStatement : CodeNode, Statement {
+	public Statement prev { get; set; }
+
+	public Statement next { get; set; }
+}
diff --git a/vala/valablock.vala b/vala/valablock.vala
index df2f1eb..81e9d35 100644
--- a/vala/valablock.vala
+++ b/vala/valablock.vala
@@ -34,7 +34,14 @@ public class Vala.Block : Symbol, Statement {
 
 	public bool captured { get; set; }
 
-	private List<Statement> statement_list = new ArrayList<Statement> ();
+	public Statement first_statement { get; private set; }
+
+	public Statement prev { get; set; }
+
+	public Statement next { get; set; }
+
+	private Statement last_statement;
+
 	private List<LocalVariable> local_variables = new ArrayList<LocalVariable> ();
 	private List<Constant> local_constants = new ArrayList<Constant> ();
 	
@@ -54,34 +61,28 @@ public class Vala.Block : Symbol, Statement {
 	 */
 	public void add_statement (Statement stmt) {
 		stmt.parent_node = this;
-		statement_list.add (stmt);
+		if (last_statement == null) {
+			first_statement = last_statement = stmt;
+		} else {
+			last_statement.next = stmt;
+			stmt.prev = last_statement;
+			last_statement = stmt;
+		}
 	}
 
 	public void insert_statement (int index, Statement stmt) {
-		stmt.parent_node = this;
-		statement_list.insert (index, stmt);
-	}
-
-	/**
-	 * Returns a copy of the list of statements.
-	 *
-	 * @return statement list
-	 */
-	public List<Statement> get_statements () {
-		var list = new ArrayList<Statement> ();
-		foreach (Statement stmt in statement_list) {
-			var stmt_list = stmt as StatementList;
-			if (stmt_list != null) {
-				for (int i = 0; i < stmt_list.length; i++) {
-					list.add (stmt_list.get (i));
-				}
-			} else {
-				list.add (stmt);
-			}
+		Statement iter = first_statement;
+		while (iter != null && index > 0) {
+			index--;
+			iter = iter.next;
+		}
+		if (iter == null) {
+			add_statement (stmt);
+		} else {
+			insert_before (iter, stmt);
 		}
-		return list;
 	}
-	
+
 	/**
 	 * Add a local variable to this block.
 	 *
@@ -132,7 +133,7 @@ public class Vala.Block : Symbol, Statement {
 	}
 
 	public override void accept_children (CodeVisitor visitor) {
-		foreach (Statement stmt in statement_list) {
+		foreach (Statement stmt in this) {
 			stmt.accept (visitor);
 		}
 	}
@@ -146,8 +147,8 @@ public class Vala.Block : Symbol, Statement {
 
 		owner = context.analyzer.get_current_symbol (parent_node).scope;
 
-		for (int i = 0; i < statement_list.size; i++) {
-			statement_list[i].check (context);
+		foreach (var stmt in this) {
+			stmt.check (context);
 		}
 
 		foreach (LocalVariable local in get_local_variables ()) {
@@ -166,7 +167,7 @@ public class Vala.Block : Symbol, Statement {
 			source_reference = this.source_reference;
 		}
 		// use get_statements () instead of statement_list to not miss errors within StatementList objects
-		foreach (Statement stmt in get_statements ()) {
+		foreach (Statement stmt in this) {
 			stmt.get_error_types (collection, source_reference);
 		}
 	}
@@ -176,42 +177,55 @@ public class Vala.Block : Symbol, Statement {
 	}
 
 	public void insert_before (Statement stmt, Statement new_stmt) {
-		for (int i = 0; i < statement_list.size; i++) {
-			var stmt_list = statement_list[i] as StatementList;
-			if (stmt_list != null) {
-				for (int j = 0; j < stmt_list.length; j++) {
-					if (stmt_list.get (j) == stmt) {
-						stmt_list.insert (j, new_stmt);
-						new_stmt.parent_node = this;
-						break;
-					}
-				}
-			} else if (statement_list[i] == stmt) {
-				stmt_list = new StatementList (source_reference);
-				stmt_list.add (new_stmt);
-				stmt_list.add (stmt);
-				statement_list[i] = stmt_list;
-				new_stmt.parent_node = this;
-			}
+		new_stmt.parent_node = this;
+		new_stmt.prev = stmt.prev;
+		new_stmt.next = stmt;
+
+		if (stmt.prev == null) {
+			first_statement = new_stmt;
+		} else {
+			stmt.prev.next = new_stmt;
 		}
+		stmt.prev = new_stmt;
 	}
 
 	public void replace_statement (Statement old_stmt, Statement new_stmt) {
-		for (int i = 0; i < statement_list.size; i++) {
-			var stmt_list = statement_list[i] as StatementList;
-			if (stmt_list != null) {
-				for (int j = 0; j < stmt_list.length; j++) {
-					if (stmt_list.get (j) == old_stmt) {
-						stmt_list.set (j, new_stmt);
-						new_stmt.parent_node = this;
-						break;
-					}
-				}
-			} else if (statement_list[i] == old_stmt) {
-				statement_list[i] = new_stmt;
-				new_stmt.parent_node = this;
-				break;
-			}
+		new_stmt.parent_node = this;
+		new_stmt.prev = old_stmt.prev;
+		new_stmt.next = old_stmt.next;
+
+		if (old_stmt.prev == null) {
+			first_statement = new_stmt;
+		} else {
+			old_stmt.prev.next = new_stmt;
+		}
+
+		if (old_stmt.next == null) {
+			last_statement = new_stmt;
+		} else {
+			old_stmt.next.prev = new_stmt;
+		}
+	}
+
+	public StatementIterator iterator () {
+		return new StatementIterator (this);
+	}
+}
+
+public class Vala.StatementIterator {
+	private Block block;
+	private Statement next;
+
+	public StatementIterator (Block block) {
+		this.block = block;
+		this.next = block.first_statement;
+	}
+
+	public Statement? next_value () {
+		var ret = next;
+		if (ret != null) {
+			next = ret.next;
 		}
+		return ret;
 	}
 }
diff --git a/vala/valabreakstatement.vala b/vala/valabreakstatement.vala
index 3f69c85..6545b2d 100644
--- a/vala/valabreakstatement.vala
+++ b/vala/valabreakstatement.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * Represents a break statement in the source code.
  */
-public class Vala.BreakStatement : CodeNode, Statement {
+public class Vala.BreakStatement : BaseStatement {
 	/**
 	 * Creates a new break statement.
 	 *
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index ddd7e3b..2c77654 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -815,7 +815,7 @@ public class Vala.CodeWriter : CodeVisitor {
 	public override void visit_block (Block b) {
 		write_begin_block ();
 
-		foreach (Statement stmt in b.get_statements ()) {
+		foreach (Statement stmt in b) {
 			stmt.accept (this);
 		}
 
diff --git a/vala/valacontinuestatement.vala b/vala/valacontinuestatement.vala
index 1de109d..083d746 100644
--- a/vala/valacontinuestatement.vala
+++ b/vala/valacontinuestatement.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * Represents a continue statement in the source code.
  */
-public class Vala.ContinueStatement : CodeNode, Statement {
+public class Vala.ContinueStatement : BaseStatement {
 	/**
 	 * Creates a new continue statement.
 	 *
diff --git a/vala/valadeclarationstatement.vala b/vala/valadeclarationstatement.vala
index 12303cd..8b3ce75 100644
--- a/vala/valadeclarationstatement.vala
+++ b/vala/valadeclarationstatement.vala
@@ -24,7 +24,7 @@
 /**
  * Represents a local variable or constant declaration statement in the source code.
  */
-public class Vala.DeclarationStatement : CodeNode, Statement {
+public class Vala.DeclarationStatement : BaseStatement {
 	/**
 	 * The local variable or constant declaration.
 	 */
diff --git a/vala/valadeletestatement.vala b/vala/valadeletestatement.vala
index ff3ff68..426db5d 100644
--- a/vala/valadeletestatement.vala
+++ b/vala/valadeletestatement.vala
@@ -23,7 +23,7 @@
 /**
  * Represents a delete statement e.g. "delete a".
  */
-public class Vala.DeleteStatement : CodeNode, Statement {
+public class Vala.DeleteStatement : BaseStatement {
 	/**
 	 * Expression representing the instance to be freed.
 	 */
diff --git a/vala/valadostatement.vala b/vala/valadostatement.vala
index 940e61f..b43ace1 100644
--- a/vala/valadostatement.vala
+++ b/vala/valadostatement.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * Represents a do iteration statement in the source code.
  */
-public class Vala.DoStatement : CodeNode, Statement {
+public class Vala.DoStatement : BaseStatement {
 	/**
 	 * Specifies the loop body.
 	 */
diff --git a/vala/valaemptystatement.vala b/vala/valaemptystatement.vala
index 1cc6ae0..81bcd3b 100644
--- a/vala/valaemptystatement.vala
+++ b/vala/valaemptystatement.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * An empty statement.
  */
-public class Vala.EmptyStatement : CodeNode, Statement {
+public class Vala.EmptyStatement : BaseStatement {
 	/**
 	 * Creates a new empty statement.
 	 *
diff --git a/vala/valaexpressionstatement.vala b/vala/valaexpressionstatement.vala
index c0c55f3..7dc1534 100644
--- a/vala/valaexpressionstatement.vala
+++ b/vala/valaexpressionstatement.vala
@@ -25,7 +25,7 @@
  * A code statement that evaluates a given expression. The value computed by the
  * expression, if any, is discarded.
  */
-public class Vala.ExpressionStatement : CodeNode, Statement {
+public class Vala.ExpressionStatement : BaseStatement {
 	/**
 	 * Specifies the expression to evaluate.
 	 */
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index bd6001b..1f2720b 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -667,7 +667,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 		foreach (SwitchSection section in stmt.get_sections ()) {
 			current_block = new BasicBlock ();
 			condition_block.connect (current_block);
-			foreach (Statement section_stmt in section.get_statements ()) {
+			foreach (Statement section_stmt in section) {
 				section_stmt.accept (this);
 			}
 
diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala
index d2a0984..5764064 100644
--- a/vala/valaforeachstatement.vala
+++ b/vala/valaforeachstatement.vala
@@ -25,7 +25,7 @@
  * Represents a foreach statement in the source code. Foreach statements iterate
  * over the elements of a collection.
  */
-public class Vala.ForeachStatement : CodeNode, Statement {
+public class Vala.ForeachStatement : BaseStatement {
 	/**
 	 * Specifies the element type.
 	 */
diff --git a/vala/valaforstatement.vala b/vala/valaforstatement.vala
index d2f644c..c79a6d1 100644
--- a/vala/valaforstatement.vala
+++ b/vala/valaforstatement.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * Represents a for iteration statement in the source code.
  */
-public class Vala.ForStatement : CodeNode, Statement {
+public class Vala.ForStatement : BaseStatement {
 	/**
 	 * Specifies the loop condition.
 	 */
diff --git a/vala/valaifstatement.vala b/vala/valaifstatement.vala
index f2d22e7..04c0372 100644
--- a/vala/valaifstatement.vala
+++ b/vala/valaifstatement.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * Represents an if selection statement in the source code.
  */
-public class Vala.IfStatement : CodeNode, Statement {
+public class Vala.IfStatement : BaseStatement {
 	/**
 	 * The boolean condition to evaluate.
 	 */
diff --git a/vala/valalockstatement.vala b/vala/valalockstatement.vala
index 6f7912e..6f0f443 100644
--- a/vala/valalockstatement.vala
+++ b/vala/valalockstatement.vala
@@ -32,7 +32,7 @@ using GLib;
  * occurs. Otherwise it's translated into a try/finally statement which unlocks the mutex
  * after the block is finished.
  */
-public class Vala.LockStatement : CodeNode, Statement {
+public class Vala.LockStatement : BaseStatement {
 	/**
 	 * Expression representing the resource to be locked.
 	 */
diff --git a/vala/valaloop.vala b/vala/valaloop.vala
index bf44a9c..065acc4 100644
--- a/vala/valaloop.vala
+++ b/vala/valaloop.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * Represents an endless loop.
  */
-public class Vala.Loop : CodeNode, Statement {
+public class Vala.Loop : BaseStatement {
 	/**
 	 * Specifies the loop body.
 	 */
diff --git a/vala/valareturnstatement.vala b/vala/valareturnstatement.vala
index 6760aff..8c1caf8 100644
--- a/vala/valareturnstatement.vala
+++ b/vala/valareturnstatement.vala
@@ -24,7 +24,7 @@
 /**
  * Represents a return statement in the source code.
  */
-public class Vala.ReturnStatement : CodeNode, Statement {
+public class Vala.ReturnStatement : BaseStatement {
 	/**
 	 * The optional expression to return.
 	 */
diff --git a/vala/valastatement.vala b/vala/valastatement.vala
index a35d279..ccbee29 100644
--- a/vala/valastatement.vala
+++ b/vala/valastatement.vala
@@ -26,4 +26,6 @@ using GLib;
  * Interface for all statement types.
  */
 public interface Vala.Statement : CodeNode {
+	public abstract Statement prev { get; set; }
+	public abstract Statement next { get; set; }
 }
diff --git a/vala/valaswitchsection.vala b/vala/valaswitchsection.vala
index 5580ac6..3ba0824 100644
--- a/vala/valaswitchsection.vala
+++ b/vala/valaswitchsection.vala
@@ -76,14 +76,14 @@ public class Vala.SwitchSection : Block {
 			label.accept (visitor);
 		}
 
-		foreach (Statement st in get_statements ()) {
+		foreach (Statement st in this) {
 			st.accept (visitor);
 		}
 	}
 
 	public override void get_error_types (Collection<DataType> collection, SourceReference? source_reference = null) {
 		// use get_statements () instead of statement_list to not miss errors within StatementList objects
-		foreach (var stmt in get_statements ()) {
+		foreach (var stmt in this) {
 			stmt.get_error_types (collection, source_reference);
 		}
 	}
@@ -101,7 +101,7 @@ public class Vala.SwitchSection : Block {
 			label.check (context);
 		}
 
-		foreach (Statement st in get_statements ()) {
+		foreach (Statement st in this) {
 			st.check (context);
 		}
 
diff --git a/vala/valaswitchstatement.vala b/vala/valaswitchstatement.vala
index d6d2999..1e7051b 100644
--- a/vala/valaswitchstatement.vala
+++ b/vala/valaswitchstatement.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * Represents a switch selection statement in the source code.
  */
-public class Vala.SwitchStatement : CodeNode, Statement {
+public class Vala.SwitchStatement : BaseStatement {
 	/**
 	 * Specifies the switch expression.
 	 */
diff --git a/vala/valathrowstatement.vala b/vala/valathrowstatement.vala
index 5de6447..3018bba 100644
--- a/vala/valathrowstatement.vala
+++ b/vala/valathrowstatement.vala
@@ -24,7 +24,7 @@
 /**
  * Represents a throw statement in the source code.
  */
-public class Vala.ThrowStatement : CodeNode, Statement {
+public class Vala.ThrowStatement : BaseStatement {
 	/**
 	 * The error expression to throw.
 	 */
diff --git a/vala/valatrystatement.vala b/vala/valatrystatement.vala
index 3ae8924..1a0aaf8 100644
--- a/vala/valatrystatement.vala
+++ b/vala/valatrystatement.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * Represents a try statement in the source code.
  */
-public class Vala.TryStatement : CodeNode, Statement {
+public class Vala.TryStatement : BaseStatement {
 	/**
 	 * Specifies the body of the try statement.
 	 */
diff --git a/vala/valaunlockstatement.vala b/vala/valaunlockstatement.vala
index e73e363..7da272b 100644
--- a/vala/valaunlockstatement.vala
+++ b/vala/valaunlockstatement.vala
@@ -24,7 +24,7 @@
 /**
  * Represents an unlock statement e.g. {{{ unlock (a); }}}.
  */
-public class Vala.UnlockStatement : CodeNode, Statement {
+public class Vala.UnlockStatement : BaseStatement {
 	/**
 	 * Expression representing the resource to be unlocked.
 	 */
diff --git a/vala/valawhilestatement.vala b/vala/valawhilestatement.vala
index 84b66b5..448dfd5 100644
--- a/vala/valawhilestatement.vala
+++ b/vala/valawhilestatement.vala
@@ -25,7 +25,7 @@ using GLib;
 /**
  * Represents a while iteration statement in the source code.
  */
-public class Vala.WhileStatement : CodeNode, Statement {
+public class Vala.WhileStatement : BaseStatement {
 	/**
 	 * Specifies the loop condition.
 	 */
diff --git a/vala/valayieldstatement.vala b/vala/valayieldstatement.vala
index 084ae26..18b49de 100644
--- a/vala/valayieldstatement.vala
+++ b/vala/valayieldstatement.vala
@@ -23,7 +23,7 @@
 /**
  * Represents a yield statement in the source code.
  */
-public class Vala.YieldStatement : CodeNode, Statement {
+public class Vala.YieldStatement : BaseStatement {
 	/**
 	 * The expression to yield or the method call to yield to.
 	 */



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