ruby: slicc: avoid duplicate code for function argument check
authorNilay Vaish <nilay@cs.wisc.edu>
Sun, 30 Aug 2015 15:52:58 +0000 (10:52 -0500)
committerNilay Vaish <nilay@cs.wisc.edu>
Sun, 30 Aug 2015 15:52:58 +0000 (10:52 -0500)
Both FuncCallExprAST and MethodCallExprAST had code for checking the arguments
with which a function is being called.  The patch does away with this
duplication.  Now the code for checking function call arguments resides in the
Func class.

src/mem/slicc/ast/FuncCallExprAST.py
src/mem/slicc/ast/MethodCallExprAST.py
src/mem/slicc/parser.py
src/mem/slicc/symbols/Func.py

index 9336a22977ee232178652ec4e0cbe46afd50a2c2..0c9880d6dd1bfb4407d5493458492b135e318c42 100644 (file)
@@ -93,22 +93,7 @@ class FuncCallExprAST(ExprAST):
         if func is None:
             self.error("Unrecognized function name: '%s'", func_name_args)
 
-        if len(self.exprs) != len(func.param_types):
-            self.error("Wrong number of arguments passed to function : '%s'" +\
-                       " Expected %d, got %d", self.proc_name,
-                       len(func.param_types), len(self.exprs))
-
-        cvec = []
-        type_vec = []
-        for expr,expected_type in zip(self.exprs, func.param_types):
-            # Check the types of the parameter
-            actual_type,param_code = expr.inline(True)
-            if str(actual_type) != 'OOD' and \
-            str(actual_type) != str(expected_type):
-                expr.error("Type mismatch: expected: %s actual: %s" % \
-                           (expected_type, actual_type))
-            cvec.append(param_code)
-            type_vec.append(expected_type)
+        cvec, type_vec = func.checkArguments(self.exprs)
 
         # OK, the semantics of "trigger" here is that, ports in the
         # machine have different priorities. We always check the first
index 8be319a40d0a0a26eaf9fc998c565008d1b8a730..104d6f8df4a6b8b77e48722020d0528bcfa6b5ad 100644 (file)
@@ -56,20 +56,8 @@ class MethodCallExprAST(ExprAST):
             self.error("Invalid method call: Type '%s' does not have a method '%s'",
                        obj_type, methodId)
 
-        if len(self.expr_ast_vec) != \
-               len(obj_type.methods[methodId].param_types):
-            # Right number of parameters
-            self.error("Wrong number of parameters for function name: '%s', " + \
-                       "expected: , actual: ", proc_name,
-                  len(obj_type.methods[methodId].param_types),
-                  len(self.expr_ast_vec))
-
-        for actual_type, expected_type in \
-                zip(paramTypes, obj_type.methods[methodId].param_types):
-            if actual_type != expected_type and \
-                   str(actual_type["interface"]) != str(expected_type):
-                self.error("Type mismatch: expected: %s actual: %s",
-                           expected_type, actual_type)
+        func = obj_type.methods[methodId]
+        func.checkArguments(self.expr_ast_vec)
 
         # Return the return type of the method
         return obj_type.methods[methodId].return_type
@@ -78,10 +66,9 @@ class MethodCallExprAST(ExprAST):
         pass
 
 class MemberMethodCallExprAST(MethodCallExprAST):
-    def __init__(self, slicc, obj_expr_ast, proc_name, expr_ast_vec):
+    def __init__(self, slicc, obj_expr_ast, func_call):
         s = super(MemberMethodCallExprAST, self)
-        s.__init__(slicc, proc_name, expr_ast_vec)
-
+        s.__init__(slicc, func_call.proc_name, func_call.exprs)
         self.obj_expr_ast = obj_expr_ast
 
     def __repr__(self):
index 0cbe9ea6388e49a658cace0667b14a49ef626e3e..49177345d1cc3cf782b145ff5eef5e0797d1bfd9 100644 (file)
@@ -669,15 +669,18 @@ class SLICC(Grammar):
 
     def p_expr__member_method_call(self, p):
         "aexpr : aexpr DOT ident '(' exprs ')'"
-        p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5])
+        p[0] = ast.MemberMethodCallExprAST(self, p[1],
+                    ast.FuncCallExprAST(self, p[3], p[5]))
 
     def p_expr__member_method_call_lookup(self, p):
         "aexpr : aexpr '[' exprs ']'"
-        p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3])
+        p[0] = ast.MemberMethodCallExprAST(self, p[1],
+                    ast.FuncCallExprAST(self, "lookup", p[3]))
 
     def p_expr__class_method_call(self, p):
         "aexpr : type DOUBLE_COLON ident '(' exprs ')'"
-        p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5])
+        p[0] = ast.ClassMethodCallExprAST(self, p[1],
+                    ast.FuncCallExprAST(self, p[3], p[5]))
 
     def p_expr__aexpr(self, p):
         "expr : aexpr"
index d50d0309fdaa11412509818fe592832235624c9d..6da74002a8e48519d54bca1f1bac3b822a7da93f 100644 (file)
@@ -62,6 +62,27 @@ class Func(Symbol):
     def writeCodeFiles(self, path, includes):
         return
 
+    def checkArguments(self, args):
+        if len(args) != len(self.param_types):
+            self.error("Wrong number of arguments passed to function : '%s'" +\
+                       " Expected %d, got %d", self.c_ident,
+                       len(self.param_types), len(args))
+
+        cvec = []
+        type_vec = []
+        for expr,expected_type in zip(args, self.param_types):
+            # Check the types of the parameter
+            actual_type,param_code = expr.inline(True)
+            if str(actual_type) != 'OOD' and \
+               str(actual_type) != str(expected_type) and \
+               str(actual_type["interface"]) != str(expected_type):
+                expr.error("Type mismatch: expected: %s actual: %s" % \
+                           (expected_type, actual_type))
+            cvec.append(param_code)
+            type_vec.append(expected_type)
+
+        return cvec, type_vec
+
     def generateCode(self):
         '''This write a function of object Chip'''
         if "external" in self: