KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > asm > jbfc > BFCompiler


1 /***
2  * ASM examples: examples showing how ASM can be used
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package org.objectweb.asm.jbfc;
31
32 import java.io.IOException JavaDoc;
33 import java.io.Reader JavaDoc;
34 import java.util.Stack JavaDoc;
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 /**
42  * A naive implementation of compiler for Brain**** language.
43  * http://www.muppetlabs.com/~breadbox/bf/ *
44  *
45  * @author Eugene Kuleshov
46  */

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 JavaDoc r,
59         String JavaDoc className,
60         String JavaDoc sourceName,
61         ClassVisitor cv) throws IOException JavaDoc
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             // Init local vars for BF environment:
87
// 0 InputStream
88
// 1 OutputStream
89
// 2 Data Pointer
90
// 3 Data Array (int[ 30000])
91

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 JavaDoc labels = new Stack JavaDoc();
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