/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.java; import java.util.ArrayList; /** * A statement. */ public interface Statement { void setMethod(MethodObj method); boolean isEnd(); /** * Get the C++ code. * * @return the C++ code */ String asString(); } /** * The base class for statements. */ abstract class StatementBase implements Statement { public boolean isEnd() { return false; } } /** * A "return" statement. */ class ReturnStatement extends StatementBase { /** * The return expression. */ Expr expr; private MethodObj method; public void setMethod(MethodObj method) { this.method = method; } public String asString() { if (expr == null) { return "return;"; } Type returnType = method.returnType; expr.setType(returnType); if (!expr.getType().isObject()) { return "return " + expr.asString() + ";"; } if (returnType.refCount) { return "return " + expr.getType().asString() + "(" + expr.asString() + ");"; } return "return " + expr.asString() + ";"; } } /** * A "do .. while" statement. */ class DoWhileStatement extends StatementBase { /** * The condition. */ Expr condition; /** * The execution block. */ Statement block; public void setMethod(MethodObj method) { block.setMethod(method); } public String asString() { return "do {\n" + block + "} while (" + condition.asString() + ");"; } } /** * A "continue" statement. */ class ContinueStatement extends StatementBase { public void setMethod(MethodObj method) { // ignore } public String asString() { return "continue;"; } } /** * A "break" statement. */ class BreakStatement extends StatementBase { public void setMethod(MethodObj method) { // ignore } public String asString() { return "break;"; } } /** * An empty statement. */ class EmptyStatement extends StatementBase { public void setMethod(MethodObj method) { // ignore } public String asString() { return ";"; } } /** * A "switch" statement. */ class SwitchStatement extends StatementBase { private StatementBlock defaultBlock; private final ArrayList<Expr> cases = new ArrayList<Expr>(); private final ArrayList<StatementBlock> blocks = new ArrayList<StatementBlock>(); private final Expr expr; public SwitchStatement(Expr expr) { this.expr = expr; } public void setMethod(MethodObj method) { defaultBlock.setMethod(method); for (StatementBlock b : blocks) { b.setMethod(method); } } public String asString() { StringBuilder buff = new StringBuilder(); buff.append("switch (").append(expr.asString()).append(") {\n"); for (int i = 0; i < cases.size(); i++) { buff.append("case " + cases.get(i).asString() + ":\n"); buff.append(blocks.get(i).toString()); } if (defaultBlock != null) { buff.append("default:\n"); buff.append(defaultBlock.toString()); } buff.append("}"); return buff.toString(); } public void setDefaultBlock(StatementBlock block) { this.defaultBlock = block; } /** * Add a case. * * @param expr the case expression * @param block the execution block */ public void addCase(Expr expr, StatementBlock block) { cases.add(expr); blocks.add(block); } } /** * An expression statement. */ class ExprStatement extends StatementBase { private final Expr expr; public ExprStatement(Expr expr) { this.expr = expr; } public void setMethod(MethodObj method) { // ignore } public String asString() { return expr.asString() + ";"; } } /** * A "while" statement. */ class WhileStatement extends StatementBase { /** * The condition. */ Expr condition; /** * The execution block. */ Statement block; public void setMethod(MethodObj method) { block.setMethod(method); } public String asString() { String w = "while (" + condition.asString() + ")"; String s = block.toString(); return w + "\n" + s; } } /** * An "if" statement. */ class IfStatement extends StatementBase { /** * The condition. */ Expr condition; /** * The execution block. */ Statement block; /** * The else block. */ Statement elseBlock; public void setMethod(MethodObj method) { block.setMethod(method); if (elseBlock != null) { elseBlock.setMethod(method); } } public String asString() { String w = "if (" + condition.asString() + ") {\n"; String s = block.asString(); if (elseBlock != null) { s += "} else {\n" + elseBlock.asString(); } return w + s + "}"; } } /** * A "for" statement. */ class ForStatement extends StatementBase { /** * The init block. */ Statement init; /** * The condition. */ Expr condition; /** * The main loop block. */ Statement block; /** * The update list. */ ArrayList<Expr> updates = new ArrayList<Expr>(); /** * The type of the iterable. */ Type iterableType; /** * The iterable variable name. */ String iterableVariable; /** * The iterable expression. */ Expr iterable; public void setMethod(MethodObj method) { block.setMethod(method); } public String asString() { StringBuffer buff = new StringBuffer(); buff.append("for ("); if (iterableType != null) { Type it = iterable.getType(); if (it != null && it.arrayLevel > 0) { String idx = "i_" + iterableVariable; buff.append("int " + idx + " = 0; " + idx + " < " + iterable.asString() + "->length(); " + idx + "++"); buff.append(") {\n"); buff.append(JavaParser.indent(iterableType + " " + iterableVariable + " = " + iterable.asString() + "->at("+ idx +");\n")); buff.append(block.toString()).append("}"); } else { // TODO iterate over a collection buff.append(iterableType).append(' '); buff.append(iterableVariable).append(": "); buff.append(iterable); buff.append(") {\n"); buff.append(block.toString()).append("}"); } } else { buff.append(init.asString()); buff.append(" ").append(condition.asString()).append("; "); for (int i = 0; i < updates.size(); i++) { if (i > 0) { buff.append(", "); } buff.append(updates.get(i).asString()); } buff.append(") {\n"); buff.append(block.asString()).append("}"); } return buff.toString(); } } /** * A statement block. */ class StatementBlock extends StatementBase { /** * The list of instructions. */ final ArrayList<Statement> instructions = new ArrayList<Statement>(); public void setMethod(MethodObj method) { for (Statement s : instructions) { s.setMethod(method); } } public String asString() { StringBuilder buff = new StringBuilder(); for (Statement s : instructions) { if (s.isEnd()) { break; } buff.append(JavaParser.indent(s.asString())); } return buff.toString(); } } /** * A variable declaration. */ class VarDecStatement extends StatementBase { /** * The type. */ Type type; private ArrayList<String> variables = new ArrayList<String>(); private ArrayList<Expr> values = new ArrayList<Expr>(); public void setMethod(MethodObj method) { // ignore } public String asString() { StringBuilder buff = new StringBuilder(); buff.append(type.asString()).append(' '); StringBuilder assign = new StringBuilder(); for (int i = 0; i < variables.size(); i++) { if (i > 0) { buff.append(", "); } String varName = variables.get(i); buff.append(varName); Expr value = values.get(i); if (value != null) { if (!value.getType().isObject()) { buff.append(" = ").append(value.asString()); } else { value.setType(type); assign.append(varName).append(" = ").append(value.asString()).append(";\n"); } } } buff.append(";"); if (assign.length() > 0) { buff.append("\n"); buff.append(assign); } return buff.toString(); } /** * Add a variable. * * @param name the variable name * @param value the init value */ public void addVariable(String name, Expr value) { variables.add(name); values.add(value); } } /** * A native statement. */ class StatementNative extends StatementBase { private final String code; StatementNative(String code) { this.code = code; } public void setMethod(MethodObj method) { // ignore } public String asString() { return code; } public boolean isEnd() { return code.equals("return;"); } }