@@ -21,13 +21,15 @@ class MiniJavaPrintListener(MinijavaListener):
21
21
def __init__ (self , symbolTable ):
22
22
super ().__init__ ()
23
23
self .currentClass = ""
24
- self .currentMethodType = ""
24
+ self .currentMethod = ""
25
25
self .lastExpressionType = ""
26
26
self .codeStore = {}
27
27
self .code = ""
28
28
self .isInitialized = False
29
29
30
30
self .symbolTable = symbolTable
31
+ self .lables = []
32
+ self .lableCounter = 0
31
33
32
34
self .block_number = 0
33
35
self .variables = {}
@@ -40,17 +42,49 @@ def get_bytecode(self):
40
42
def get_representation (s_type ):
41
43
if s_type == 'int' :
42
44
return 'I'
43
- if s_type == 'boolean' :
45
+ elif s_type == 'boolean' :
44
46
return 'Z'
47
+ else :
48
+ print ("type UNKNOWN" , s_type )
49
+
50
+ def get_new_lable (self ):
51
+ lable = 'LABLE_' + str (self .lableCounter )
52
+ self .lableCounter = self .lableCounter + 1
53
+ self .lables .append (lable )
54
+ return lable
55
+
56
+ def get_last_lable (self ):
57
+ return self .lables [- 1 ]
58
+
59
+ def remove_last_lable (self ):
60
+ self .lables = self .lables [:- 1 ]
45
61
46
62
@staticmethod
47
63
def get_return_by_type (s_type ):
48
64
#todo implement array
49
65
if s_type == 'int' :
50
66
return 'ireturn'
51
- if s_type == 'boolean' :
67
+ elif s_type == 'boolean' :
52
68
return 'ireturn'
53
69
70
+
71
+ def get_method_type (self , method_name ):
72
+ prop = self .symbolTable [self .currentClass ][method_name ]
73
+ return_type = prop ['return_type' ]
74
+ return return_type
75
+
76
+ def get_method_inp_type (self , method_name , lookup_class = None ):
77
+ if lookup_class is None :
78
+ lookup_class = self .currentClass
79
+ print (lookup_class , "PPPPPPPPP" )
80
+ print (self .symbolTable [lookup_class ])
81
+ prop = self .symbolTable [lookup_class ][method_name ]
82
+ inputs = prop ["inputs" ]
83
+ str_types = ""
84
+ for inp in inputs :
85
+ str_types += self .get_representation (inp [0 ]) + ','
86
+ return str_types [:- 1 ]
87
+
54
88
def enterMainClass (self , ctx :MinijavaParser .MainClassContext ):
55
89
self .currentClass = ctx .getChild (1 ).getText ()
56
90
self .code += '.class public %s' % self .currentClass + '\n '
@@ -96,32 +130,39 @@ def enterMethodDeclaration(self, ctx:MinijavaParser.MethodDeclarationContext):
96
130
self .code += 'invokenonvirtual java/lang/Object/<init>()V' + '\n '
97
131
self .code += 'return' + '\n '
98
132
self .code += '.end method' + '\n '
99
- self .currentMethodType = ctx .getChild (1 ).getText ()
100
- method_name = ctx .getChild (2 ).getText ()
101
-
102
- self .code += '.method public %s' % method_name
133
+ method_type = ctx .getChild (1 ).getText ()
134
+ self .currentMethod = ctx .getChild (2 ).getText ()
135
+ self .code += '.method public %s' % self .currentMethod
103
136
104
137
if ctx .getChild (4 ).getText () == ')' :
105
- return_type_representation = self .get_representation (self . currentMethodType )
138
+ return_type_representation = self .get_representation (method_type )
106
139
self .code += '()%s' % return_type_representation + '\n '
107
140
108
141
def exitMethodDeclaration (self , ctx : MinijavaParser .MethodDeclarationContext ):
109
142
self .code += '.end method' + '\n '
110
143
111
144
def enterParameterList (self , ctx :MinijavaParser .ParameterListContext ):
112
145
self .code += '('
146
+ self .code += self .get_method_inp_type (self .currentMethod )
113
147
114
148
def exitParameterList (self , ctx : MinijavaParser .ParameterListContext ):
115
- return_type_representation = self .get_representation (self .currentMethodType )
149
+ method_type = self .get_method_type (self .currentMethod )
150
+ return_type_representation = self .get_representation (method_type )
116
151
self .code += ')%s' % return_type_representation + '\n '
117
152
118
153
def enterMethodBody (self , ctx :MinijavaParser .MethodBodyContext ):
119
154
self .code += '.limit stack 10000' + '\n '
155
+ self .code += '.limit locals 1000' + '\n '
120
156
#todo implement .limit locals
121
157
self .code += ''
122
158
123
159
def exitMethodBody (self , ctx :MinijavaParser .MethodBodyContext ):
124
- self .code += self .get_return_by_type (self .currentMethodType ) + '\n '
160
+ method_type = self .get_method_type (self .currentMethod )
161
+ self .code += self .get_return_by_type (method_type ) + '\n '
162
+
163
+ def exitNotExpression (self , ctx :MinijavaParser .NotExpressionContext ):
164
+ self .code += 'ldc 1' + '\n '
165
+ self .code += 'ixor' + '\n '
125
166
126
167
def enterObjectInstantiationExpression (self , ctx :MinijavaParser .ObjectInstantiationExpressionContext ):
127
168
object_class_name = ctx .getChild (1 ).getText ()
@@ -136,20 +177,19 @@ def exitObjectInstantiationExpression(self, ctx:MinijavaParser.ObjectInstantiati
136
177
def exitMethodCallExpression (self , ctx : MinijavaParser .MethodCallExpressionContext ):
137
178
#todo implement method inputs
138
179
method_name = ctx .getChild (2 ).getText ()
139
- print ("gi" )
140
- print (self .lastExpressionType )
141
- print (method_name )
142
180
class_properties = self .symbolTable [self .lastExpressionType ][method_name ]
181
+ input_types = self .get_method_inp_type (method_name , self .lastExpressionType )
143
182
return_type_representation = self .get_representation (class_properties ["return_type" ])
144
- self .code += 'invokevirtual %s/%s(%s)%s' % (self .lastExpressionType , method_name , '' , return_type_representation ) + '\n '
183
+ self .code += 'invokevirtual %s/%s(%s)%s' % (self .lastExpressionType , method_name , input_types , return_type_representation ) + '\n '
145
184
146
185
def enterLocalDeclaration (self , ctx :MinijavaParser .LocalDeclarationContext ):
147
186
#todo
148
- var_name = ctx .getChild (1 ).getText ()
187
+ var_name = ctx .getChild (0 ). getChild ( 1 ).getText ()
149
188
var_properties = self .symbolTable [self .currentClass ][var_name ]
189
+ var_id = var_properties ['id' ]
150
190
if var_properties ['return_type' ] == 'int' :
151
191
self .code += 'bipush 0' + '\n '
152
- self .code += 'istore' + '\n '
192
+ self .code += 'istore %s' % var_id + '\n '
153
193
154
194
def enterVariableAssignmentStatement (self , ctx :MinijavaParser .VariableAssignmentStatementContext ):
155
195
name = ctx .getChild (0 ).getText ()
@@ -158,6 +198,10 @@ def enterVariableAssignmentStatement(self, ctx:MinijavaParser.VariableAssignment
158
198
if type == 'field' :
159
199
self .code += 'aload 0 ; push this' + '\n '
160
200
201
+ def enterIfElseStatement (self , ctx :MinijavaParser .IfElseStatementContext ):
202
+ lable = self .get_new_lable ()
203
+ self .code += ''
204
+
161
205
#todo var type
162
206
def exitVariableAssignmentStatement (self , ctx :MinijavaParser .VariableAssignmentStatementContext ):
163
207
name = ctx .getChild (0 ).getText ()
@@ -187,6 +231,23 @@ def exitBasicMathExpression(self, ctx:MinijavaParser.BasicMathExpressionContext)
187
231
elif type == '-' :
188
232
self .code += "isub" + '\n '
189
233
234
+ def exitLtExpression (self , ctx :MinijavaParser .LtExpressionContext ):
235
+ l1 = self .get_new_lable ()
236
+ l2 = self .get_new_lable ()
237
+ print ()
238
+ print ("enterLtExpression" )
239
+ self .code += 'isub' + '\n '
240
+ self .code += 'ifle %s' % l1 + '\n '
241
+ self .code += 'ldc 0' + '\n '
242
+ self .code += 'goto %s' % l2 + '\n '
243
+ self .code += '%s:' % l1 + '\n '
244
+ self .code += 'ldc 1' + '\n '
245
+ self .code += '%s:' % l2 + '\n '
246
+
247
+ self .remove_last_lable ()
248
+ self .remove_last_lable ()
249
+
250
+
190
251
def enterIntLitExpression (self , ctx :MinijavaParser .IntLitExpressionContext ):
191
252
literal = ctx .getChild (0 ).getText ()
192
253
print ("enterIntLitExpression %s" % literal )
@@ -201,6 +262,11 @@ def enterIdentifierExpression(self, ctx:MinijavaParser.IdentifierExpressionConte
201
262
representation = self .get_representation (return_type )
202
263
self .code += 'aload 0 ; push this' + '\n '
203
264
self .code += 'getfield %s/%s %s' % (self .currentClass , name , representation ) + '\n '
265
+ elif type == 'var' :
266
+ var_id = properties ['id' ] - 1
267
+ return_type = properties ['return_type' ]
268
+ upcode = self .get_representation (return_type ).lower () + 'load'
269
+ self .code += '%s %d' % (upcode , var_id ) + '\n '
204
270
205
271
def enterPrintStatement (self , ctx : MinijavaParser .PrintStatementContext ):
206
272
self .code += "getstatic java/lang/System/out Ljava/io/PrintStream;" + '\n '
@@ -209,10 +275,6 @@ def exitPrintStatement(self, ctx:MinijavaParser.PrintStatementContext):
209
275
self .code += "invokevirtual java/io/PrintStream/println(I)V" + '\n '
210
276
211
277
212
- def enterLtExpression (self , ctx :MinijavaParser .LtExpressionContext ):
213
- print ()
214
- print ("enterLtExpression" )
215
- self .code += ""
216
278
217
279
def enterAndExpression (self , ctx :MinijavaParser .AndExpressionContext ):
218
280
print ()
0 commit comments