[vala/wip/transform: 12/43] Code builder
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/transform: 12/43] Code builder
- Date: Thu, 5 Jan 2012 14:59:18 +0000 (UTC)
commit 1e48440c53722124287b7d8f3368ddccdf563870
Author: Luca Bruno <lucabru src gnome org>
Date: Thu Dec 29 19:42:55 2011 +0100
Code builder
codegen/valagvarianttransformer.vala | 84 +++++++------------
vala/Makefile.am | 1 +
vala/valacodebuilder.vala | 154 ++++++++++++++++++++++++++++++++++
vala/valadeletestatement.vala | 2 +-
4 files changed, 185 insertions(+), 56 deletions(-)
---
diff --git a/codegen/valagvarianttransformer.vala b/codegen/valagvarianttransformer.vala
index a0be0e8..af6fa2e 100644
--- a/codegen/valagvarianttransformer.vala
+++ b/codegen/valagvarianttransformer.vala
@@ -45,8 +45,7 @@ public class Vala.GVariantTransformer : CodeTransformer {
{ "g", "signature", true }
};
- Statement current_statement;
- Block current_block;
+ CodeBuilder b;
bool get_basic_type_info (string signature, out BasicTypeInfo basic_type) {
foreach (BasicTypeInfo info in basic_types) {
@@ -59,22 +58,22 @@ public class Vala.GVariantTransformer : CodeTransformer {
return false;
}
- MemberAccess member_access (string symbol_string, CodeNode node) {
+ 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, node.source_reference);
+ ma = new MemberAccess (ma, symbol_string[0].to_string()+s, b.source_reference);
first = false;
} else {
- ma = new MemberAccess (ma, s, node.source_reference);
+ ma = new MemberAccess (ma, s, b.source_reference);
}
}
return ma;
}
Expression serialize_basic (BasicTypeInfo basic_type, Expression expr) {
- var new_call = new ObjectCreationExpression (member_access ("GLib.Variant." + basic_type.type_name, expr), expr.source_reference);
+ var new_call = new ObjectCreationExpression (member_access ("GLib.Variant." + basic_type.type_name), expr.source_reference);
new_call.add_argument (expr);
return new_call;
}
@@ -161,74 +160,53 @@ public class Vala.GVariantTransformer : CodeTransformer {
}
Expression serialize_array (ArrayType array_type, Expression array_expr) {
- LocalVariable temp = new LocalVariable (array_type, array_expr.get_temp_name (), array_expr, array_expr.source_reference);
- var decl = new DeclarationStatement (temp, array_expr.source_reference);
- context.analyzer.get_insert_block (current_statement).insert_before (current_statement, decl);
- check (decl);
+ string temp = b.add_temp_declaration (array_type, null);
- LocalVariable[] indices = new LocalVariable[array_type.rank];
+ string[] indices = new string[array_type.rank];
for (int dim=1; dim <= array_type.rank; dim++) {
- var index = new LocalVariable (null, array_expr.get_temp_name (), new IntegerLiteral ("0"), array_expr.source_reference);
- decl = new DeclarationStatement (index, array_expr.source_reference);
- context.analyzer.get_insert_block (current_statement).insert_before (current_statement, decl);
- check (decl);
- indices[dim-1] = index;
+ indices[dim-1] = b.add_temp_declaration (null, new IntegerLiteral ("0"));
}
return serialize_array_dim (array_type, 1, indices, temp);
}
- Expression serialize_array_dim (ArrayType array_type, int dim, LocalVariable[] indices, LocalVariable array_var) {
- var gvariant_type = new ObjectCreationExpression (member_access ("GLib.VariantType", array_var), array_var.source_reference);
+ 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", array_var), array_var.source_reference);
+ var builderinit = new ObjectCreationExpression (member_access ("GLib.VariantBuilder"), b.source_reference);
builderinit.add_argument (gvariant_type);
- var builder = new LocalVariable (null, array_var.get_temp_name (), builderinit, array_var.source_reference);
- var decl = new DeclarationStatement (builder, array_var.source_reference);
- context.analyzer.get_insert_block (current_statement).insert_before (current_statement, decl);
- check (decl);
+ var builder = b.add_temp_declaration (null, builderinit);
- Expression length = member_access (array_var.name+".length", array_var);
+ Expression length = member_access (array_var+".length");
if (array_type.rank > 1) {
- ElementAccess ea = new ElementAccess (length, array_var.source_reference);
- ea.append_index (new IntegerLiteral ((dim-1).to_string (), array_var.source_reference));
+ ElementAccess ea = new ElementAccess (length, b.source_reference);
+ ea.append_index (new IntegerLiteral ((dim-1).to_string (), b.source_reference));
length = ea;
}
var index = indices[dim-1];
- var forcond = new BinaryExpression (BinaryOperator.LESS_THAN, member_access (index.name, array_var), length, array_var.source_reference);
- var foriter = new PostfixExpression (member_access (index.name, array_var), true, array_var.source_reference);
- var forbody = new Block (array_var.source_reference);
- var old_block = current_block;
- current_block = forbody;
+ 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);
+ 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.name, array_var), array_var.source_reference);
+ var element_expr = new ElementAccess (member_access (array_var), b.source_reference);
for (int i=0; i < dim; i++) {
- element_expr.append_index (member_access (indices[i].name, array_var));
+ element_expr.append_index (member_access (indices[i]));
}
element_variant = serialize_expression (array_type.element_type, element_expr);
}
- current_block = old_block;
- var builder_add = new MethodCall (member_access (builder.name+".add_value", array_var), array_var.source_reference);
+ var builder_add = new MethodCall (member_access (builder+".add_value"), b.source_reference);
builder_add.add_argument (element_variant);
- forbody.add_statement (new ExpressionStatement (builder_add, array_var.source_reference));
+ b.add_expression (builder_add);
+ b.close ();
- var forstmt = new ForStatement (forcond, forbody, array_var.source_reference);
- forstmt.add_iterator (foriter);
- if (dim == 1) {
- context.analyzer.get_current_block (current_statement).insert_before (current_statement, forstmt);
- check (forstmt);
- } else {
- current_block.add_statement (forstmt);
- }
-
- var builder_end = new MethodCall (member_access (builder.name+".end", array_var), array_var.source_reference);
+ var builder_end = new MethodCall (member_access (builder+".end"), b.source_reference);
return builder_end;
}
@@ -251,22 +229,18 @@ public class Vala.GVariantTransformer : CodeTransformer {
return;
}
- current_statement = get_current_statement (expr);
+ b = new CodeBuilder (context, expr.parent_statement, expr.source_reference);
var old_parent_node = expr.parent_node;
var target_type = expr.target_type.copy ();
- current_block = context.analyzer.get_current_block (current_statement);
Expression result = serialize_expression (expr.value_type, expr);
result.target_type = target_type;
+ context.analyzer.replaced_nodes.add (expr);
old_parent_node.replace_expression (expr, result);
- check (result);
- }
-
- Statement get_current_statement (CodeNode node) {
- while (!(node is Statement)) {
- node = node.parent_node;
+ foreach (var node in b.check_nodes) {
+ check (node);
}
- return (Statement) node;
+ check (result);
}
}
diff --git a/vala/Makefile.am b/vala/Makefile.am
index 655bea9..26de52a 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -34,6 +34,7 @@ libvalacore_la_VALASOURCES = \
valacharacterliteral.vala \
valaclass.vala \
valaclasstype.vala \
+ valacodebuilder.vala \
valacodecontext.vala \
valacodegenerator.vala \
valacodenode.vala \
diff --git a/vala/valacodebuilder.vala b/vala/valacodebuilder.vala
new file mode 100644
index 0000000..f08fc92
--- /dev/null
+++ b/vala/valacodebuilder.vala
@@ -0,0 +1,154 @@
+/* valacodebuilder.vala
+ *
+ * Copyright (C) 2011 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;
+
+public class Vala.CodeBuilder {
+ Block current_block;
+ Statement insert_statement;
+ Block insert_block;
+ public SourceReference source_reference;
+ ArrayList<Statement> statement_stack = new ArrayList<Statement> ();
+ public ArrayList<CodeNode> check_nodes = new ArrayList<CodeNode> ();
+
+ public CodeBuilder (CodeContext context, Statement insert_statement, SourceReference source_reference) {
+ this.current_block = new Block (source_reference);
+ this.insert_statement = insert_statement;
+ this.insert_block = context.analyzer.get_insert_block (insert_statement);
+ this.source_reference = source_reference;
+
+ var statement_block = context.analyzer.get_current_block (insert_statement);
+ statement_block.insert_before (insert_statement, current_block);
+ check_nodes.add (current_block);
+ }
+
+ public void open_block () {
+ statement_stack.add (current_block);
+ var parent_block = current_block;
+
+ current_block = new Block (source_reference);
+
+ parent_block.add_statement (current_block);
+ }
+
+ public void open_if (Expression condition) {
+ statement_stack.add (current_block);
+ var parent_block = current_block;
+
+ current_block = new Block (source_reference);
+
+ var stmt = new IfStatement (condition, current_block, null, source_reference);
+ statement_stack.add (stmt);
+
+ parent_block.add_statement (stmt);
+ }
+
+ public void add_else () {
+ current_block = new Block (source_reference);
+
+ var stmt = (IfStatement) statement_stack[statement_stack.size-1];
+ assert (stmt.false_statement == null);
+ stmt.false_statement = current_block;
+ }
+
+ public void else_if (Expression condition) {
+ var parent_if = (IfStatement) statement_stack[statement_stack.size - 1];
+ assert (parent_if.false_statement == null);
+
+ statement_stack.remove_at (statement_stack.size - 1);
+
+ current_block = new Block (source_reference);
+
+ var stmt = new IfStatement (condition, current_block, null, source_reference);
+ var block = new Block (source_reference);
+ block.add_statement (stmt);
+ parent_if.false_statement = block;
+ statement_stack.add (stmt);
+ }
+
+ public void open_while (Expression condition) {
+ statement_stack.add (current_block);
+ var parent_block = current_block;
+
+ current_block = new Block (source_reference);
+
+ var stmt = new WhileStatement (condition, current_block, source_reference);
+ parent_block.add_statement (stmt);
+ }
+
+ public void open_for (Expression? initializer, Expression condition, Expression? iterator) {
+ statement_stack.add (current_block);
+ var parent_block = current_block;
+
+ current_block = new Block (source_reference);
+
+ var stmt = new ForStatement (condition, current_block, source_reference);
+ if (initializer != null) {
+ stmt.add_initializer (initializer);
+ }
+ if (iterator != null) {
+ stmt.add_iterator (iterator);
+ }
+
+ parent_block.add_statement (stmt);
+ }
+
+ public void add_statement (Statement statement) {
+ current_block.add_statement (statement);
+ }
+
+ public void add_expression (Expression expression) {
+ add_statement (new ExpressionStatement (expression, source_reference));
+ }
+
+ public void add_assignment (Expression left, Expression right) {
+ add_expression (new Assignment (left, right, AssignmentOperator.SIMPLE, source_reference));
+ }
+
+ public void add_return (Expression? expression = null) {
+ add_statement (new ReturnStatement (expression, source_reference));
+ }
+
+ public void add_break () {
+ add_statement (new BreakStatement (source_reference));
+ }
+
+ public void add_continue () {
+ add_statement (new ContinueStatement (source_reference));
+ }
+
+ public string add_temp_declaration (DataType? type, Expression? initializer) {
+ var local = new LocalVariable (type, CodeNode.get_temp_name (), initializer, source_reference);
+ var stmt = new DeclarationStatement (local, source_reference);
+ insert_block.insert_before (insert_statement, stmt);
+ check_nodes.insert (0, stmt);
+ return local.name;
+ }
+
+ public void close () {
+ do {
+ var top = statement_stack[statement_stack.size - 1];
+ statement_stack.remove_at (statement_stack.size - 1);
+ current_block = top as Block;
+ } while (current_block == null);
+ }
+}
diff --git a/vala/valadeletestatement.vala b/vala/valadeletestatement.vala
index 5f639d4..ff3ff68 100644
--- a/vala/valadeletestatement.vala
+++ b/vala/valadeletestatement.vala
@@ -51,7 +51,7 @@ public class Vala.DeleteStatement : CodeNode, Statement {
}
public override void replace_expression (Expression old_node, Expression new_node) {
- if (expression = old_node) {
+ if (expression == old_node) {
expression = new_node;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]