1 30 package org.objectweb.asm.jbfc; 31 32 import java.io.IOException ; 33 import java.io.Reader ; 34 import java.util.Stack ; 35 36 import org.objectweb.asm.ClassVisitor; 37 import org.objectweb.asm.Label; 38 import org.objectweb.asm.MethodVisitor; 39 import org.objectweb.asm.Opcodes; 40 41 47 public class BFCompiler implements Opcodes { 48 49 private static final int V_IS = 0; 50 51 private static final int V_OS = 1; 52 53 private static final int V_P = 2; 54 55 private static final int V_D = 3; 56 57 public void compile( 58 Reader r, 59 String className, 60 String sourceName, 61 ClassVisitor cv) throws IOException 62 { 63 cv.visit(Opcodes.V1_3, 64 ACC_PUBLIC, 65 className.replace('.', '/'), 66 null, 67 "java/lang/Object", 68 null); 69 cv.visitSource(sourceName, null); 70 71 MethodVisitor mv; 72 { 73 mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 74 mv.visitCode(); 75 mv.visitVarInsn(ALOAD, 0); 76 mv.visitMethodInsn(INVOKESPECIAL, 77 "java/lang/Object", 78 "<init>", 79 "()V"); 80 mv.visitInsn(RETURN); 81 mv.visitMaxs(1, 1); 82 mv.visitEnd(); 83 } 84 85 { 86 92 mv = cv.visitMethod(ACC_PUBLIC + ACC_STATIC, 93 "main", 94 "([Ljava/lang/String;)V", 95 null, 96 null); 97 mv.visitCode(); 98 99 mv.visitFieldInsn(GETSTATIC, 100 "java/lang/System", 101 "in", 102 "Ljava/io/InputStream;"); 103 mv.visitVarInsn(ASTORE, V_IS); 104 105 mv.visitFieldInsn(GETSTATIC, 106 "java/lang/System", 107 "out", 108 "Ljava/io/PrintStream;"); 109 mv.visitVarInsn(ASTORE, V_OS); 110 111 mv.visitInsn(ICONST_0); 112 mv.visitVarInsn(ISTORE, V_P); 113 114 mv.visitIntInsn(SIPUSH, 30000); 115 mv.visitIntInsn(NEWARRAY, T_INT); 116 mv.visitVarInsn(ASTORE, V_D); 117 118 Stack labels = new Stack (); 119 120 int d = 0; 121 int p = 0; 122 123 int c; 124 while ((c = r.read()) != -1) { 125 switch (c) { 126 case '>': 127 d = storeD(mv, d); 128 p++; 129 break; 130 131 case '<': 132 d = storeD(mv, d); 133 p--; 134 break; 135 136 case '+': 137 p = storeP(mv, p); 138 d++; 139 break; 140 141 case '-': 142 p = storeP(mv, p); 143 d--; 144 break; 145 146 case '.': 147 p = storeP(mv, p); 148 d = storeD(mv, d); 149 150 mv.visitVarInsn(ALOAD, V_OS); 151 mv.visitVarInsn(ALOAD, V_D); 152 mv.visitVarInsn(ILOAD, V_P); 153 mv.visitInsn(IALOAD); 154 mv.visitMethodInsn(INVOKEVIRTUAL, 155 "java/io/OutputStream", 156 "write", 157 "(I)V"); 158 break; 159 160 case ',': 161 p = storeP(mv, p); 162 d = storeD(mv, d); 163 164 mv.visitVarInsn(ALOAD, V_D); 165 mv.visitVarInsn(ILOAD, V_P); 166 mv.visitVarInsn(ALOAD, V_IS); 167 mv.visitMethodInsn(INVOKEVIRTUAL, 168 "java/io/InputStream", 169 "read", 170 "()I"); 171 mv.visitInsn(IASTORE); 172 break; 173 174 case '[': 175 p = storeP(mv, p); 176 d = storeD(mv, d); 177 178 Label ls = new Label(); 179 Label le = new Label(); 180 labels.push(ls); 181 labels.push(le); 182 mv.visitJumpInsn(GOTO, le); 183 mv.visitLabel(ls); 184 break; 185 186 case ']': 187 p = storeP(mv, p); 188 d = storeD(mv, d); 189 190 mv.visitLabel((Label) labels.pop()); 191 mv.visitVarInsn(ALOAD, V_D); 192 mv.visitVarInsn(ILOAD, V_P); 193 mv.visitInsn(IALOAD); 194 mv.visitJumpInsn(IFNE, (Label) labels.pop()); 195 break; 196 } 197 } 198 199 mv.visitInsn(RETURN); 200 201 mv.visitMaxs(1, 1); 202 mv.visitEnd(); 203 } 204 205 } 206 207 private int storeD(MethodVisitor mv, int d) { 208 if (d != 0) { 209 mv.visitVarInsn(ALOAD, V_D); 210 mv.visitVarInsn(ILOAD, V_P); 211 mv.visitInsn(DUP2); 212 mv.visitInsn(IALOAD); 213 mv.visitIntInsn(SIPUSH, d); 214 mv.visitInsn(IADD); 215 mv.visitInsn(IASTORE); 216 } 217 return 0; 218 } 219 220 private int storeP(MethodVisitor mv, int p) { 221 if (p != 0) { 222 mv.visitIincInsn(V_P, p); 223 } 224 return 0; 225 } 226 227 } 228 | Popular Tags |