From: Luca Bruno Date: Thu, 5 Jan 2012 14:33:32 +0000 (+0100) Subject: DOM-like linked list of statements X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4c20c9f7642d04dd1d727d1f59874a284ad27bce;p=thirdparty%2Fvala.git DOM-like linked list of statements --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index a7d867af4..d407b0738 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -2309,7 +2309,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/vala/Makefile.am b/vala/Makefile.am index d341e7659..2c13f48d6 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -35,6 +35,7 @@ libvala_la_VALASOURCES = \ valaassignment.vala \ valaattribute.vala \ valabaseaccess.vala \ + valabasestatement.vala \ valabasicblock.vala \ valabinaryexpression.vala \ valablock.vala \ @@ -146,7 +147,6 @@ libvala_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 000000000..33d2516b8 --- /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 + */ + +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 72e7801e2..44d8f8424 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_list = new ArrayList (); + public Statement first_statement { get; private set; } + + public Statement prev { get; set; } + + public Statement next { get; set; } + + private Statement last_statement; + private List local_variables = new ArrayList (); private List local_constants = new ArrayList (); @@ -54,32 +61,26 @@ 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 get_statements () { - var list = new ArrayList (); - 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; } /** @@ -141,7 +142,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); } } @@ -155,8 +156,8 @@ public class Vala.Block : Symbol, Statement { owner = context.analyzer.get_current_non_local_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 ()) { @@ -172,7 +173,7 @@ public class Vala.Block : Symbol, Statement { public override void get_error_types (Collection collection, SourceReference? source_reference = null) { // 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); } } @@ -182,42 +183,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 e8f2dd8bf..692a077ca 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 f3967a15c..a2325e379 100644 --- a/vala/valacodewriter.vala +++ b/vala/valacodewriter.vala @@ -916,7 +916,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 dc9c93950..a15f90516 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 ab652e906..1fea1cfbb 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 ff3ff6891..426db5df6 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 b65ac2b7f..dfe96102d 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 259574ac4..334b5f628 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 43cebbe62..736c6b7fe 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 b21707e88..3810cffe0 100644 --- a/vala/valaflowanalyzer.vala +++ b/vala/valaflowanalyzer.vala @@ -682,7 +682,7 @@ public class Vala.FlowAnalyzer : CodeVisitor { current_block = new BasicBlock (); all_basic_blocks.add (current_block); 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 f8b3e6cc5..f03102441 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 380effcc5..31c79abfc 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 61c87ba3f..b251ab310 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 be942acee..b6b99c349 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 ce6894633..862ef25a4 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 e4fa6b506..7db428f05 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 a35d27956..ccbee29e4 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/valastatementlist.vala b/vala/valastatementlist.vala deleted file mode 100644 index f773a5ca7..000000000 --- a/vala/valastatementlist.vala +++ /dev/null @@ -1,77 +0,0 @@ -/* valastatementlist.vala - * - * Copyright (C) 2008-2010 Jürg Billeter - * - * 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: - * Jürg Billeter - */ - - -public class Vala.StatementList : CodeNode, Statement { - private List list = new ArrayList (); - - public int length { - get { return list.size; } - } - - public StatementList (SourceReference source_reference) { - this.source_reference = source_reference; - } - - public Statement get (int index) { - return list.get (index); - } - - public void set (int index, Statement stmt) { - list.set (index, stmt); - } - - public void add (Statement stmt) { - list.add (stmt); - } - - public void insert (int index, Statement stmt) { - list.insert (index, stmt); - } - - public override void get_error_types (Collection collection, SourceReference? source_reference = null) { - foreach (var stmt in list) { - stmt.get_error_types (collection, source_reference); - } - } - - public override void accept (CodeVisitor visitor) { - foreach (Statement stmt in list) { - stmt.accept (visitor); - } - } - - public override bool check (CodeContext context) { - foreach (Statement stmt in list) { - if (!stmt.check (context)) { - return false; - } - } - return true; - } - - public override void emit (CodeGenerator codegen) { - foreach (Statement stmt in list) { - stmt.emit (codegen); - } - } -} diff --git a/vala/valaswitchsection.vala b/vala/valaswitchsection.vala index 9e94edea1..3141436cd 100644 --- a/vala/valaswitchsection.vala +++ b/vala/valaswitchsection.vala @@ -80,14 +80,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 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); } } @@ -105,7 +105,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 78cfa3d82..b57154108 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 9349b1818..5061a2c0d 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 fcacfc7fb..d28e6535e 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 e97458ea8..045b0150e 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 963764bb9..ee5b4e43c 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 795de2761..f114b48fb 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 { /** * Creates a new yield statement. *