From 5e01fa6d4df6dd23144c50ec6e31ad8319a41518 Mon Sep 17 00:00:00 2001
From: Recolic Keghart <root@recolic.net>
Date: Mon, 8 Apr 2019 20:19:57 -0700
Subject: [PATCH] remove Exception on duplicate id

---
 .../chocopy/common/analysis/SymbolTable.java  |  2 -
 src/main/java/chocopy/pa2/TypeChecker.java    | 49 ++++++++++++++-----
 2 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/src/main/java/chocopy/common/analysis/SymbolTable.java b/src/main/java/chocopy/common/analysis/SymbolTable.java
index e9bc757..e5adcd4 100644
--- a/src/main/java/chocopy/common/analysis/SymbolTable.java
+++ b/src/main/java/chocopy/common/analysis/SymbolTable.java
@@ -1,7 +1,5 @@
 package chocopy.common.analysis;
 
-import org.apache.tools.ant.taskdefs.PathConvert;
-
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
diff --git a/src/main/java/chocopy/pa2/TypeChecker.java b/src/main/java/chocopy/pa2/TypeChecker.java
index 759f177..528121c 100644
--- a/src/main/java/chocopy/pa2/TypeChecker.java
+++ b/src/main/java/chocopy/pa2/TypeChecker.java
@@ -70,9 +70,15 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
                 continue;
             }
 
-            // TODO: DO NOT throw on duplicate id. generate a compiler error.
-            if(isBuildingSym)
-                sym.put(name, type);
+            if(isBuildingSym) {
+                try {
+                    sym.put(name, type);
+                }
+                catch(RuntimeException e) {
+                    // duplicate id
+                    err(decl, e.getMessage());
+                }
+            }
         }
 
         if(isBuildingSym)
@@ -160,18 +166,30 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
         for(TypedVar param : funcDef.params) {
             String name = param.identifier.name;
             ValueType type = resolveTypeAnnotation(param.type);
-            //if(typeIsUserDefinedClass(type))
-            //    type = (ValueType) sym.get(((ClassValueType) type).className());
-            if(isBuildingSym)
-                sym.put(name, type);
+            if(isBuildingSym) {
+                try {
+                    sym.put(name, type);
+                }
+                catch(RuntimeException e) {
+                    // duplicate id
+                    err(param, e.getMessage());
+                }
+            }
             args.add(type);
         }
 
         for(Declaration decl : funcDef.declarations) {
             String name = decl.getIdentifier().name;
             SymbolType type = decl.dispatch(this);
-            if(isBuildingSym)
-                sym.put(name, type);
+            if(isBuildingSym) {
+                try {
+                    sym.put(name, type);
+                }
+                catch(RuntimeException e) {
+                    // duplicate id
+                    err(decl, e.getMessage());
+                }
+            }
         }
 
         if(!isBuildingSym) {
@@ -182,8 +200,17 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
         }
 
         FuncType funcT = new FuncType(args, resolveTypeAnnotation(funcDef.returnType));
-        if(isBuildingSym)
-            sym.put(funcDef.name.name, funcT); // this funcdef should be add to both parentSym and localSym to support recursive func.
+        if(isBuildingSym) {
+            try {
+                // this funcdef should be add to both parentSym and localSym to support recursive func.
+                // stmt will fill the parent sym, and I will fill the local sym.
+                sym.put(funcDef.name.name, funcT);
+            }
+            catch(RuntimeException e) {
+                // duplicate id
+                err(funcDef, e.getMessage());
+            }
+        }
 
         // TA don't like it. OK I won't dispatch this id...
         //funcDef.name.dispatch(this); // dispatch it.
-- 
GitLab