Skip to content

Commit 7d4bde2

Browse files
author
Rosnec
committed
Now reporting duplicate classes/methods/vars
1 parent 05515be commit 7d4bde2

7 files changed

Lines changed: 218 additions & 105 deletions

File tree

doc/ClassesDupes.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class ClassesDupes {
2+
public static void main(String[] args) {
3+
System.out.println(new A().run());
4+
}
5+
}
6+
7+
class A {
8+
public int run() {
9+
int x;
10+
int y;
11+
12+
x = 1;
13+
y = 2;
14+
15+
return new B().square(x + y);
16+
}
17+
}
18+
19+
class B {
20+
int foo;
21+
int foo;
22+
int bar;
23+
public int square(int x) {
24+
int x;
25+
int x;
26+
return x * x;
27+
}
28+
public int square(int y) {
29+
return y - y;
30+
}
31+
}
32+
33+
class C extends B {
34+
int baz;
35+
}
36+
37+
class A {}

project.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(defproject mini-java "0.1.1-SNAPSHOT"
1+
(defproject mini-java "0.1.1"
22
:description "A MiniJava compiler implemented in Clojure."
33
:url "https://github.com/dwysocki/mini-java"
44
:license {:name "MIT License"

src/mini_java/ast.clj

Lines changed: 110 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
(:import [org.antlr.v4.runtime.tree TerminalNodeImpl]
55
[mini_java.antlr MiniJavaParser]))
66

7+
(defn- node-line-and-column [node]
8+
(let [token (.getStart node)]
9+
(util/token-line-and-column token)))
10+
11+
(defn- with-line-and-column [node ctx obj]
12+
(let [[line column] (node-line-and-column node)]
13+
(with-meta obj
14+
{:line line
15+
:column column
16+
:context ctx})))
17+
18+
(defn context [node]
19+
(:context (meta node)))
20+
721
(def ^{:private true} parser-inner-classes
822
(.getClasses MiniJavaParser))
923

@@ -24,6 +38,8 @@
2438
(assoc (into {} (map (comp vec reverse typeify) parser-inner-classes))
2539
TerminalNodeImpl :terminal-node))
2640

41+
(def ^{:private true} obj-type-key
42+
(comp type->key type))
2743

2844
(defn- children [node]
2945
(map #(.getChild node %) (range (.getChildCount node))))
@@ -40,7 +56,7 @@
4056
(defn- method-declaration? [[k v]]
4157
(= k :method-declaration))
4258

43-
(defmulti ast (comp type->key type))
59+
(defmulti ast obj-type-key)
4460

4561
(defmethod ast :default [node]
4662
[(type->key (type node)), node])
@@ -54,21 +70,24 @@
5470
(let [children (children node)
5571
main-class (first children)
5672
classes (-> children rest butlast)]
57-
{:main (ast main-class),
58-
:classes (map ast classes)}))
73+
(with-line-and-column node :goal
74+
{:main (ast main-class),
75+
:classes (map ast classes)})))
5976

6077
(defmethod ast :main-class-declaration [node]
61-
{:name (ast (.getChild node 1)),
62-
:body (ast (.getChild node 2))})
78+
(with-line-and-column node :main-class-declaration
79+
{:name (ast (.getChild node 1)),
80+
:body (ast (.getChild node 2))}))
6381

6482
(defmethod ast :class-declaration [node]
6583
(let [child? (= 5 (.getChildCount node))
6684
body-idx (if child? 4 2)
6785
{:keys [vars methods]} (ast (.getChild node body-idx))]
68-
{:name (ast (.getChild node 1)),
69-
:parent (when child? (ast (.getChild node 3))),
70-
:vars (map remove-type vars),
71-
:methods (map remove-type methods)}))
86+
(with-line-and-column node :class-declaration
87+
{:name (ast (.getChild node 1)),
88+
:parent (when child? (ast (.getChild node 3))),
89+
:vars (map remove-type vars),
90+
:methods (map remove-type methods)})))
7291

7392
(defmethod ast :main-class-body [node]
7493
(ast (.getChild node 1)))
@@ -81,85 +100,96 @@
81100
declarations (map ast (remove-braces children))
82101
vars (filter var-declaration? declarations)
83102
methods (filter method-declaration? declarations)]
84-
{:vars vars,
85-
:methods methods}))
103+
(with-line-and-column node :class-body
104+
{:vars vars,
105+
:methods methods})))
86106

87107
(defmethod ast :method-declaration [node]
88108
(let [{:keys [vars statements]} (ast (.getChild node 4))]
89109
[:method-declaration,
90-
{:name (ast (.getChild node 2)),
91-
:type (ast (.getChild node 1)),
92-
:args (ast (.getChild node 3)),
93-
:vars vars,
94-
:statements statements}]))
110+
(with-line-and-column node :method-declaration
111+
{:name (ast (.getChild node 2)),
112+
:type (ast (.getChild node 1)),
113+
:args (ast (.getChild node 3)),
114+
:vars vars,
115+
:statements statements})]))
95116

96117
(defmethod ast :method-body [node]
97118
(let [children (remove-braces (children node))
98119
body-nodes (map ast children)]
99-
{:vars (map remove-type (filter var-declaration? body-nodes))
100-
:statements (filter (comp not var-declaration?) body-nodes)}))
120+
(with-line-and-column node :method-body
121+
{:vars (map remove-type (filter var-declaration? body-nodes))
122+
:statements (filter (comp not var-declaration?) body-nodes)})))
101123

102124
(defmethod ast :var-declaration [node]
103125
[:var-declaration,
104-
{:name (ast (.getChild node 1)),
105-
:type (ast (.getChild node 0))}])
126+
(with-line-and-column node :var-declaration
127+
{:name (ast (.getChild node 1)),
128+
:type (ast (.getChild node 0))})])
106129

107130
(defmethod ast :nested-statement [node]
108131
[:nested-statement,
109-
(->> node
110-
children
111-
remove-braces
112-
(map ast))])
132+
(with-line-and-column node :nested-statement
133+
(->> node
134+
children
135+
remove-braces
136+
(map ast)))])
113137

114138
(defmethod ast :if-else-statement [node]
115139
[:if-else-statement
116-
{:pred (ast (.getChild node 2)),
117-
:then (ast (.getChild node 4)),
118-
:else (ast (.getChild node 6))}])
140+
(with-line-and-column node :if-else-statement
141+
{:pred (ast (.getChild node 2)),
142+
:then (ast (.getChild node 4)),
143+
:else (ast (.getChild node 6))})])
119144

120145
(defmethod ast :while-statement [node]
121146
[:while-statement,
122-
{:pred (ast (.getChild node 2)),
123-
:body (ast (.getChild node 4))}])
147+
(with-line-and-column node :while-statement
148+
{:pred (ast (.getChild node 2)),
149+
:body (ast (.getChild node 4))})])
124150

125151
(defmethod ast :print-statement [node]
126152
[:print-statement,
127-
(ast (.getChild node 2))])
153+
(with-line-and-column node :print-statement
154+
{:arg (ast (.getChild node 2))})])
128155

129156
(defmethod ast :assign-statement [node]
130157
[:assign-statement,
131-
{:target (ast (.getChild node 0)),
132-
:source (ast (.getChild node 2))}])
158+
(with-line-and-column node :assign-statement
159+
{:target (ast (.getChild node 0)),
160+
:source (ast (.getChild node 2))})])
133161

134162
(defmethod ast :array-assign-statement [node]
135163
[:array-assign-statement,
136-
{:target (ast (.getChild node 0)),
137-
:index (ast (.getChild node 2)),
138-
:source (ast (.getChild node 5))}])
164+
(with-line-and-column node :array-assign-statement
165+
{:target (ast (.getChild node 0)),
166+
:index (ast (.getChild node 2)),
167+
:source (ast (.getChild node 5))})])
139168

140169
(defmethod ast :return-statement [node]
141170
[:return-statement,
142-
(ast (.getChild node 1))])
171+
(with-line-and-column node :return-statement
172+
{:return-value (ast (.getChild node 1))})])
143173

144174
(defmethod ast :recur-statement [node]
145175
[:recur-statement,
146-
{:pred (ast (.getChild node 1)),
147-
:args (ast (.getChild node 3)),
148-
:base (ast (.getChild node 5))}])
149-
150-
151-
176+
(with-line-and-column node :recur-statement
177+
{:pred (ast (.getChild node 1)),
178+
:args (ast (.getChild node 3)),
179+
:base (ast (.getChild node 5))})])
152180

153181
(defmethod ast :method-argument-list [node]
154182
(let [children (children node)
155183
args (take-nth 2 (-> children rest butlast))]
156-
(map ast args)))
184+
(with-line-and-column node :method-argument-list
185+
(map ast args))))
157186

158187
(defmethod ast :formal-parameters [node]
159-
(let [length (.getChildCount node)]
160-
(if (= 3 length)
161-
(ast (.getChild node 1))
162-
[])))
188+
(with-line-and-column node :formal-parameters
189+
(let [length (.getChildCount node)]
190+
(if (= 3 length)
191+
(ast (.getChild node 1))
192+
[]))))
163193

164194
(defmethod ast :formal-parameter-list [node]
165195
(->> node
@@ -168,19 +198,22 @@
168198
(map ast)))
169199

170200
(defmethod ast :formal-parameter [node]
171-
{:type (ast (.getChild node 0)),
172-
:name (ast (.getChild node 1))})
201+
(with-line-and-column node :formal-parameter
202+
{:type (ast (.getChild node 0)),
203+
:name (ast (.getChild node 1))}))
173204

174205

175206
(defmethod ast :type [node]
176207
(ast (.getChild node 0)))
177208

178209
(defn- unary-expression [node]
179-
(ast (.getChild node 1)))
210+
(with-line-and-column node (obj-type-key node)
211+
{:operand (ast (.getChild node 1))}))
180212

181213
(defn- binary-expression [node]
182-
{:left (ast (.getChild node 0)),
183-
:right (ast (.getChild node 2))})
214+
(with-line-and-column node (obj-type-key node)
215+
{:left (ast (.getChild node 0)),
216+
:right (ast (.getChild node 2))}))
184217

185218
(defmethod ast :and-expression [node]
186219
[:and-expression,
@@ -204,47 +237,55 @@
204237

205238
(defmethod ast :array-access-expression [node]
206239
[:array-access-expression,
207-
{:array (ast (.getChild node 0)),
208-
:index (ast (.getChild node 2))}])
240+
(with-line-and-column node :array-access-expression
241+
{:array (ast (.getChild node 0)),
242+
:index (ast (.getChild node 2))})])
209243

210244
(defmethod ast :array-length-expression [node]
211245
[:array-length-expression,
212-
(ast (.getChild node 0))])
246+
(with-line-and-column node :array-length-expression
247+
(ast (.getChild node 0)))])
213248

214249
(defmethod ast :method-call-expression [node]
215250
[:method-call-expression,
216-
{:caller (ast (.getChild node 0)),
217-
:method (ast (.getChild node 2)),
218-
:args (ast (.getChild node 3))}])
251+
(with-line-and-column node :method-call-expression
252+
{:caller (ast (.getChild node 0)),
253+
:method (ast (.getChild node 2)),
254+
:args (ast (.getChild node 3))})])
219255

220256
(defmethod ast :int-lit-expression [node]
221257
[:int-lit-expression,
222-
(-> node
223-
(.getChild 0)
224-
ast
225-
Integer.)])
258+
(with-line-and-column node :int-lit-expression
259+
{:value (-> node
260+
(.getChild 0)
261+
ast
262+
Integer.)})])
226263

227264
(defmethod ast :boolean-expression [node]
228265
[:boolean-expression,
229-
(-> node
230-
(.getChild 0)
231-
ast
232-
Boolean.)])
266+
(with-line-and-column node :boolean-expression
267+
{:value (-> node
268+
(.getChild 0)
269+
ast
270+
Boolean.)})])
233271

234272
(defmethod ast :identifier-expression [node]
235273
[:identifier-expression,
236-
(ast (.getChild node 0))])
274+
(with-line-and-column node :identifier-expression
275+
{:id (ast (.getChild node 0))})])
237276

238277
(defmethod ast :this-expression [node]
239278
:this)
240279

241280
(defmethod ast :array-instantiation-expression [node]
242281
[:array-instantiation-expression,
243-
(ast (.getChild node 3))])
282+
(with-line-and-column node :array-instantiation-expression
283+
{:size (ast (.getChild node 3))})])
244284

245285
(defmethod ast :object-instantiation-expression [node]
246286
[:object-instantiation-expression,
247-
(ast (.getChild node 1))])
287+
(with-line-and-column node :object-instantiation-expression
288+
{:type (ast (.getChild node 1))})])
248289

249290
(defmethod ast :not-expression [node]
250291
[:not-expression,

src/mini_java/core.clj

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
(:gen-class))
77

88
(def cli-options
9-
[[nil "--syntax-only"
10-
"Only do syntax checking"]
9+
[[nil "--syntax"
10+
"Stop after syntax checking"]
11+
[nil "--static-semantics"
12+
"Stop after static semantics checking"]
1113
["-h" "--help"]])
1214

1315
(defn usage [options-summary]
@@ -44,20 +46,22 @@
4446

4547
(let [source-file (first arguments)
4648
; parse AST from source file
47-
ast (parser/mini-java source-file)]
49+
[ast parser] (parser/mini-java source-file)]
4850
; exit if there are syntax errors
4951
(when (nil? ast) (exit 1 "Errors occurred."))
5052
; exit if only syntax checking is requested
51-
(when (:syntax-only options) (exit 0))
53+
(when (:syntax options) (exit 0))
5254

5355
; perform static semantics checking
54-
(let [class-table (static-semantics/class-table ast)]
56+
(let [class-table (static-semantics/class-table ast parser)]
5557
; exit if there are semantic errors
5658
(when (nil? class-table) (exit 1 "Errors occurred."))
5759

5860
(println "AST:")
5961
(pprint ast)
6062
(println)
6163
(println "CLASS TABLE:")
62-
(pprint class-table))))
64+
(pprint class-table)
65+
66+
(when (:static-semantics options) (exit 0)))))
6367
nil))

src/mini_java/errors.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@
3838
(defn print-error [parser msg line column]
3939
(let [filename (parser-filename parser)]
4040
(binding [*out* *err*]
41-
(println (str filename ":" line ": " msg))
41+
(println (str filename ":" line ": error: " msg))
4242
(underline-error parser line column))))
4343

0 commit comments

Comments
 (0)