com.judoscript.jamaica.parser.JamaicaDumpVisitor.java Source code

Java tutorial

Introduction

Here is the source code for com.judoscript.jamaica.parser.JamaicaDumpVisitor.java

Source

/* Jamaica, The Java Virtual Machine (JVM) Macro Assembly Language
 * Copyright (C) 2004- James Huang,
 * http://www.judoscript.com/jamaica/index.html
 *
 * This is free software; you can embed, modify and redistribute
 * it under the terms of the GNU Lesser General Public License
 * version 2.1 or up as published by the Free Software Foundation,
 * which you should have received a copy along with this software.
 * In case you did not, please download it from the internet at
 * http://www.gnu.org/copyleft/lesser.html
 *
 * This software 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.
 *
 *************************** CHANGE LOG ***************************
 *
 * Authors: JH  = James Jianbo Huang, judoscript@hotmail.com
 *
 * 03-14-2004  JH   Initial release.
 *
 **********  No tabs. Indent 2 spaces. Follow the style. **********/

package com.judoscript.jamaica.parser;

import java.lang.reflect.Modifier;
import java.io.PrintStream;

import org.apache.commons.lang.StringEscapeUtils;

/**
 * Does nothing but dumping the parse tree.
 * Also serves as a source code template for any other visitors.
 */
public class JamaicaDumpVisitor extends JamaicaVisitorBase {
    static PrintStream out = System.out;

    public Object visit(ASTClassDeclaration node, Object data) throws Exception {
        printAccessFlags(node.getAccessFlags());
        out.print("class " + node.getName());
        String s = node.getSuper();
        if (s != null)
            out.print(" extends " + s);
        String[] sa = node.getInterfaces();
        int i, len = sa == null ? 0 : sa.length;
        if (len > 0)
            out.print(" implements");
        for (i = 0; i < len; ++i) {
            if (i > 0)
                out.print(',');
            out.println(" " + sa[i]);
        }
        out.println("\n{");
        node.childrenAccept(this, data);
        out.println('}');
        return null;
    }

    public Object visit(ASTInterfaceDeclaration node, Object data) throws Exception {
        out.print("interface " + node.getName());
        String[] sa = node.getExtends();
        int i, len = sa == null ? 0 : sa.length;
        if (len > 0)
            out.print(" extends");
        for (i = 0; i < len; ++i) {
            if (i > 0)
                out.print(',');
            out.println(" " + sa[i]);
        }
        out.println();
        out.println('{');
        node.childrenAccept(this, data);
        out.println('}');
        return null;
    }

    public Object visit(ASTDefaultCtor node, Object data) throws Exception {
        out.print("\n  %default_constructor");
        int flags = node.getAccessFlags();
        if (Modifier.isPublic(flags))
            out.print(" <public>");
        else if (Modifier.isProtected(flags))
            out.print(" <protected>");
        else if (Modifier.isPrivate(flags))
            out.print(" <private>");
        out.println();
        return null;
    }

    public Object visit(ASTMethodDeclaration node, Object data) throws Exception {
        boolean abs = Modifier.isAbstract(node.getAccessFlags());
        out.print("\n  ");
        printAccessFlags(node.getAccessFlags());
        out.print(node.getType());
        out.print(' ');
        out.print(node.getName());
        out.print('(');
        ((ASTFormalParameters) node.jjtGetChild(0)).jjtAccept(this, data);
        out.println(')');
        printStringArray("    throws ", node.getExceptions(), !abs);
        if (abs) {
            out.println(";\n");
        } else {
            int bodyLen = node.jjtGetNumChildren();
            out.println("  {");
            int state = 0;
            for (int i = 1; i < bodyLen; ++i) {
                Node n = node.jjtGetChild(i);
                switch (state) {
                case 0:
                    if (n instanceof ASTVariableDeclarator)
                        state = 1;
                    else if (n instanceof ASTVariableDeclarator)
                        state = 2;
                    break;
                case 1:
                    if (!(n instanceof ASTVariableDeclarator)) {
                        state = 2;
                        out.println();
                    }
                case 2:
                    if (n instanceof ASTCatchClause) {
                        state = 3;
                        out.println();
                    }
                    break;
                }
                n.jjtAccept(this, data);
            }
            out.println("  }");
        }
        return null;
    }

    public Object visit(ASTFormalParameters node, Object data) throws Exception {
        int len = node.jjtGetNumChildren();
        for (int i = 0; i < len; ++i) {
            if (i > 0)
                out.print(", ");
            visit((ASTVariableDeclarator) node.jjtGetChild(i), data);
        }
        return null;
    }

    public Object visit(ASTInitializer node, Object data) throws Exception {
        out.println("  {");
        node.childrenAccept(this, data);
        out.println("  }\n");
        return null;
    }

    ////////////////////////////////////////////////////////////////
    // Fields, Variables or Parameters
    ////////////////////////////////////////////////////////////////

    public Object visit(ASTVariableDeclarator node, Object data) throws Exception {
        boolean newline = true;
        Node parent = node.jjtGetParent();
        if (parent instanceof ASTFormalParameters) { // a parameter
            newline = false;
            ;
        } else if (parent instanceof ASTMethodDeclaration) { // a local variable
            out.print("    ");
        } else { // a class field or an interface constant
            out.print("  ");
            printAccessFlags(node.getAccessFlags());
        }
        out.print(node.getType());
        out.print(' ');
        out.print(node.getName());
        if (node.getValue() != null)
            out.print(" = " + node.getValue());
        if (newline)
            out.println(";");
        return null;
    }

    ////////////////////////////////////////////////////////////////
    // Bytecode Instructions
    ////////////////////////////////////////////////////////////////

    public Object visit(ASTCatchClause node, Object data) throws Exception {
        String exception = node.getException();
        out.print("  catch " + exception);
        out.print(" (");
        out.print(node.getStartLabel());
        out.print(", ");
        out.print(node.getEndLabel());
        out.print(") ");
        out.println(node.getActionLabel());
        return null;
    }

    public Object visit(ASTLabel node, Object data) throws Exception {
        out.println(node.getName() + ":");
        return null;
    }

    public Object visit(ASTCodeSimple node, Object data) throws Exception {
        printMnemonic(node, "\n");
        return null;
    }

    public Object visit(ASTCodeWithText node, Object data) throws Exception {
        printMnemonic(node, " ");
        out.println(node.getText());
        return null;
    }

    public Object visit(ASTCodeWithTextInt node, Object data) throws Exception {
        printMnemonic(node, " ");
        String s = node.getText();
        if (s != null)
            out.print(s + ' ');
        out.println(node.getAmount());
        return null;
    }

    public Object visit(ASTCodeWithConstant node, Object data) throws Exception {
        printMnemonic(node, " ");

        Object obj = node.getConstant();
        String s = StringEscapeUtils.escapeJava(obj.toString());
        if (obj instanceof String)
            out.println("\"" + s + '"');
        else if (obj instanceof Character)
            out.println("\'" + s + '\'');
        return null;
    }

    public Object visit(ASTCodeMemberAccess node, Object data) throws Exception {
        printMnemonic(node, " ");
        out.print(node.getClassName());
        out.print(' ');
        out.println(node.getName());
        return null;
    }

    public Object visit(ASTCodeInvoke node, Object data) throws Exception {
        printMnemonic(node, " ");
        out.print(node.getClassName());
        out.print('.');
        out.print(node.getName());
        out.print('(');

        String[] paramTypes = node.getParamTypes();
        int len = paramTypes == null ? 0 : paramTypes.length;
        for (int i = 0; i < len; i++) {
            if (i > 0)
                out.print(", ");
            out.print(paramTypes[i]);
        }

        out.print(')');
        out.println(node.getType());
        return null;
    }

    public Object visit(ASTCodeSwitch node, Object data) throws Exception {
        Object[] cases = node.getCases();
        int[] values = (int[]) cases[0];
        String[] caseLabels = (String[]) cases[1];
        String defaultLabel = node.getDefault();

        out.println("    switch");
        for (int i = 0; i < values.length; ++i)
            out.println("      " + values[i] + ": " + caseLabels[i]);
        if (defaultLabel != null)
            out.println("      default: " + defaultLabel);
        return null;
    }

    public Object visit(ASTMacroSet node, Object data) throws Exception {
        Object t = node.getTarget();
        Object v = node.getValue();
        if (t == null) {
            out.print("    %load ");
        } else if (v == null) {
            out.print("    %store ");
            out.print(t);
        } else {
            out.print("    %set ");
            out.print(t);
            out.print(" = ");
        }
        if (v != null)
            dumpParam(v);
        out.println();
        return null;
    }

    public Object visit(ASTMacroPrint node, Object data) throws Exception {
        out.print("    %");
        out.print(node.getName());
        out.print(" <");
        out.print(node.getTarget());
        out.print("> ");
        dumpParamList(node.getParams(), true);
        return null;
    }

    public Object visit(ASTMacroObject node, Object data) throws Exception {
        if (data == null)
            out.print("    ");
        out.print("%object ");
        out.print(node.getType());
        Object[] params = node.getParams();
        String[] paramTypes = node.getParamTypes();
        int len = params == null ? 0 : params.length;
        if (len > 0) {
            int i;
            out.print('(');
            for (i = 0; i < len; ++i) {
                if (i > 0)
                    out.print(", ");
                out.print(paramTypes[i]);
            }
            out.print(")(");
            for (i = 0; i < len; ++i) {
                if (i > 0)
                    out.print(", ");
                Object o = params[i];
                if (o instanceof String)
                    o = "\"" + StringEscapeUtils.escapeJava(o.toString()) + '"';
                out.print(o);
            }
            out.print(')');
        }
        if (data == null)
            out.println();
        return null;
    }

    public Object visit(ASTMacroArray node, Object data) throws Exception {
        Object[] params = node.getParams();
        int i, len = params == null ? 0 : params.length;

        if (data == null)
            out.print("    ");
        out.print("%array ");
        out.print(node.getType());

        int dim = node.getDim();
        if (dim <= 0 && len > 0) { // single-dim, initialized.
            out.print("[] { ");
            dumpParamList(params, false);
            out.print(" }");
        } else {
            for (i = 0; i < len; ++i) {
                out.print('[');
                dumpParam(params[i]);
                out.print(']');
            }
            for (; i < dim; ++i)
                out.print("[]");
        }
        if (data == null)
            out.println();
        return null;
    }

    public Object visit(ASTMacroStringConcat node, Object data) throws Exception {
        out.print("    %string_concat ");
        dumpParamList(node.getParams(), data == null);
        return null;
    }

    public Object visit(ASTMacroIterate node, Object data) throws Exception {
        if (node.isEnd()) {
            out.println("    %end_iterate");
        } else {
            out.print(node.isArray() ? "    %array_iterate " : "    %iterate ");
            dumpParam(node.getCollection());
            String s = node.getIterateVar();
            if (s != null) {
                out.print(' ');
                out.print(s);
            }
            out.println();
        }
        return null;
    }

    public Object visit(ASTMacroIf node, Object data) throws Exception {
        if (node.isEnd()) {
            out.println("    %end_if");
        } else if (node.isElse()) {
            out.println("    %else");
        } else {
            Object[] params = node.getParams();
            out.print("    %if ");
            dumpParam(params[0]);
            out.print(' ');
            out.print(node.getOperator());
            out.print(' ');
            dumpParam(params[1]);
            out.println();
        }
        return null;
    }

    public Object visit(ASTMacroBase node, Object data) throws Exception {
        if (node instanceof ASTMacroObject)
            return visit((ASTMacroObject) node, data);
        if (node instanceof ASTMacroArray)
            return visit((ASTMacroArray) node, data);
        if (node instanceof ASTMacroStringConcat)
            return visit((ASTMacroStringConcat) node, data);
        if (node instanceof ASTMacroSet)
            return visit((ASTMacroSet) node, data);
        if (node instanceof ASTMacroPrint)
            return visit((ASTMacroPrint) node, data);
        if (node instanceof ASTMacroIterate)
            return visit((ASTMacroIterate) node, data);
        if (node instanceof ASTMacroIf)
            return visit((ASTMacroIf) node, data);
        return data;
    }

    ////////////////////////////////////////////////////////////////
    // Helpers
    ////////////////////////////////////////////////////////////////

    static void printAccessFlags(int flags) {
        if (Modifier.isPublic(flags))
            out.print("public ");
        else if (Modifier.isProtected(flags))
            out.print("protected ");
        else if (Modifier.isPrivate(flags))
            out.print("private ");

        if (Modifier.isAbstract(flags))
            out.print("abstract ");
        if (Modifier.isFinal(flags))
            out.print("final ");
        if (Modifier.isNative(flags))
            out.print("native ");
        if (Modifier.isStatic(flags))
            out.print("static ");
        if (Modifier.isStrict(flags))
            out.print("strict ");
        if (Modifier.isSynchronized(flags))
            out.print("synchronized ");
        if (Modifier.isTransient(flags))
            out.print("transient ");
        if (Modifier.isVolatile(flags))
            out.print("volative ");
    }

    static void printStringArray(String prefix, String[] sa, boolean newline) {
        int len = sa == null ? 0 : sa.length;
        if (len <= 0)
            return;
        out.print(prefix);
        for (int i = 0; i < len; ++i) {
            if (i > 0)
                out.print(", ");
            out.print(sa[i]);
        }
        if (newline)
            out.println();
    }

    static void printMnemonic(ASTCodeSimple code, String postfix) {
        out.print("    ");
        out.print(getMnemonic(code.getOpcode()));
        if (postfix != null)
            out.print(postfix);
    }

    void dumpParam(Object o) {
        if (o instanceof ASTMacroBase) {
            try {
                visit((ASTMacroBase) o, Boolean.TRUE);
                return;
            } catch (Exception e) {
            }
        } else {
            String s = StringEscapeUtils.escapeJava(o.toString());
            if (o instanceof String)
                o = "\"" + s + '"';
            else if (o instanceof Character)
                o = '\'' + s + '\'';
        }
        out.print(o);
    }

    void dumpParamList(Object[] oa, boolean newline) {
        int len = oa == null ? 0 : oa.length;
        for (int i = 0; i < len; ++i) {
            if (i > 0)
                out.print(", ");
            dumpParam(oa[i]);
        }
        if (newline)
            out.println();
    }

    //////////////////////////////////////////////////
    // Constants -- copied from BCEL.

    public static String getMnemonic(int opcode) {
        try {
            return OPCODE_NAMES[opcode];
        } catch (Exception e) {
            return "???";
        }
    }

    public static final String[] OPCODE_NAMES = { "nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1",
            "iconst_2", "iconst_3", "iconst_4", "iconst_5", "lconst_0", "lconst_1", "fconst_0", "fconst_1",
            "fconst_2", "dconst_0", "dconst_1", "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload", "lload",
            "fload", "dload", "aload", "iload_0", "iload_1", "iload_2", "iload_3", "lload_0", "lload_1", "lload_2",
            "lload_3", "fload_0", "fload_1", "fload_2", "fload_3", "dload_0", "dload_1", "dload_2", "dload_3",
            "aload_0", "aload_1", "aload_2", "aload_3", "iaload", "laload", "faload", "daload", "aaload", "baload",
            "caload", "saload", "istore", "lstore", "fstore", "dstore", "astore", "istore_0", "istore_1",
            "istore_2", "istore_3", "lstore_0", "lstore_1", "lstore_2", "lstore_3", "fstore_0", "fstore_1",
            "fstore_2", "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3", "astore_0", "astore_1",
            "astore_2", "astore_3", "iastore", "lastore", "fastore", "dastore", "aastore", "bastore", "castore",
            "sastore", "pop", "pop2", "dup", "dup_x1", "dup_x2", "dup2", "dup2_x1", "dup2_x2", "swap", "iadd",
            "ladd", "fadd", "dadd", "isub", "lsub", "fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", "ldiv",
            "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg", "fneg", "dneg", "ishl", "lshl", "ishr",
            "lshr", "iushr", "lushr", "iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f", "i2d",
            "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f", "i2b", "i2c", "i2s", "lcmp", "fcmpl",
            "fcmpg", "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle", "if_icmpeq", "if_icmpne",
            "if_icmplt", "if_icmpge", "if_icmpgt", "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret",
            "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn", "dreturn", "areturn", "return",
            "getstatic", "putstatic", "getfield", "putfield", "invokevirtual", "invokespecial", "invokestatic",
            "invokeinterface", "???", "new", "newarray", "anewarray", "arraylength", "athrow", "checkcast",
            "instanceof", "monitorenter", "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull", "goto_w",
            "jsr_w", "breakpoint", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???",
            "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???",
            "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???",
            "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "impdep1", "impdep2" };

} // end of class.