ruby: slicc: use default argument value
authorNilay Vaish <nilay@cs.wisc.edu>
Sat, 15 Aug 2015 00:28:43 +0000 (19:28 -0500)
committerNilay Vaish <nilay@cs.wisc.edu>
Sat, 15 Aug 2015 00:28:43 +0000 (19:28 -0500)
Before this patch, while one could declare / define a function with default
argument values, but the actual function call would require one to specify
all the arguments.  This patch changes the check for  function arguments.
Now a function call needs to specify arguments that are at least as much as
those with default values and at most the total number of arguments taken
as input by the function.

12 files changed:
src/mem/ruby/structures/AbstractReplacementPolicy.cc
src/mem/ruby/structures/AbstractReplacementPolicy.hh
src/mem/ruby/structures/LRUPolicy.cc
src/mem/ruby/structures/LRUPolicy.hh
src/mem/ruby/structures/PseudoLRUPolicy.cc
src/mem/ruby/structures/PseudoLRUPolicy.hh
src/mem/slicc/ast/EnumDeclAST.py
src/mem/slicc/ast/FormalParamAST.py
src/mem/slicc/ast/FuncDeclAST.py
src/mem/slicc/ast/InPortDeclAST.py
src/mem/slicc/ast/StateDeclAST.py
src/mem/slicc/symbols/Func.py

index fbcce6e2d422b630dd2a422278a5e96d2fb25e69..d802ecd31f2f44d79455ace412aca1be386e44da 100644 (file)
@@ -66,7 +66,7 @@ AbstractReplacementPolicy::~AbstractReplacementPolicy()
 }
 
 Tick
-AbstractReplacementPolicy::getLastAccess(int64 set, int64 way)
+AbstractReplacementPolicy::getLastAccess(int64_t set, int64_t way)
 {
     return m_last_ref_ptr[set][way];
 }
index 03ef0d2fd122bb7ffee484224676bce4e2c15fa0..c118f3c11f5c8720ae82f8e49b00e7680abc4b3c 100644 (file)
@@ -44,13 +44,13 @@ class AbstractReplacementPolicy : public SimObject
     virtual ~AbstractReplacementPolicy();
 
     /* touch a block. a.k.a. update timestamp */
-    virtual void touch(int64 set, int64 way, Tick time) = 0;
+    virtual void touch(int64_t set, int64_t way, Tick time) = 0;
 
     /* returns the way to replace */
-    virtual int64 getVictim(int64 set) const = 0;
+    virtual int64_t getVictim(int64_t set) const = 0;
 
     /* get the time of the last access */
-    Tick getLastAccess(int64 set, int64 way);
+    Tick getLastAccess(int64_t set, int64_t way);
 
     virtual bool useOccupancy() const { return false; }
 
index a1e3b277e1e5f7b4939caa7a08dac1e0af03ed83..286d197723e92fcbea92f5f3911b8eb9bbc95ce8 100644 (file)
@@ -50,7 +50,7 @@ LRUReplacementPolicyParams::create()
 
 
 void
-LRUPolicy::touch(int64 set, int64 index, Tick time)
+LRUPolicy::touch(int64_t set, int64_t index, Tick time)
 {
     assert(index >= 0 && index < m_assoc);
     assert(set >= 0 && set < m_num_sets);
@@ -58,11 +58,11 @@ LRUPolicy::touch(int64 set, int64 index, Tick time)
     m_last_ref_ptr[set][index] = time;
 }
 
-int64
-LRUPolicy::getVictim(int64 set) const
+int64_t
+LRUPolicy::getVictim(int64_t set) const
 {
     Tick time, smallest_time;
-    int64 smallest_index;
+    int64_t smallest_index;
 
     smallest_index = 0;
     smallest_time = m_last_ref_ptr[set][0];
index 9a9c9e3ebdfdd9909c2a8723a4e96fdccf006d75..388718319996894d9766f1eb89e273da79c976c0 100644 (file)
@@ -41,8 +41,8 @@ class LRUPolicy : public AbstractReplacementPolicy
     LRUPolicy(const Params * p);
     ~LRUPolicy();
 
-    void touch(int64 set, int64 way, Tick time);
-    int64 getVictim(int64 set) const;
+    void touch(int64_t set, int64_t way, Tick time);
+    int64_t getVictim(int64_t set) const;
 };
 
 #endif // __MEM_RUBY_STRUCTURES_LRUPOLICY_HH__
index 8eee0821b4e21a8e34685915c5b1b44a0df3179a..a2b21a6259e378d4d145af29f9e6c814638d65ed 100644 (file)
@@ -38,7 +38,7 @@ PseudoLRUPolicy::PseudoLRUPolicy(const Params * p)
     // associativity cannot exceed capacity of tree representation
     assert(m_num_sets > 0 &&
            m_assoc > 1 &&
-           m_assoc <= (int64) sizeof(uint64)*4);
+           m_assoc <= (int64_t) sizeof(uint64_t)*4);
 
     m_trees = NULL;
     m_num_levels = 0;
@@ -55,7 +55,7 @@ PseudoLRUPolicy::PseudoLRUPolicy(const Params * p)
         m_num_levels++;
     }
     assert(m_num_levels < sizeof(unsigned int)*4);
-    m_trees = new uint64[m_num_sets];
+    m_trees = new uint64_t[m_num_sets];
     for (unsigned i = 0; i < m_num_sets; i++) {
         m_trees[i] = 0;
     }
@@ -75,7 +75,7 @@ PseudoLRUPolicy::~PseudoLRUPolicy()
 }
 
 void
-PseudoLRUPolicy::touch(int64 set, int64 index, Tick time)
+PseudoLRUPolicy::touch(int64_t set, int64_t index, Tick time)
 {
     assert(index >= 0 && index < m_assoc);
     assert(set >= 0 && set < m_num_sets);
@@ -93,10 +93,10 @@ PseudoLRUPolicy::touch(int64 set, int64 index, Tick time)
     m_last_ref_ptr[set][index] = time;
 }
 
-int64
-PseudoLRUPolicy::getVictim(int64 set) const
+int64_t
+PseudoLRUPolicy::getVictim(int64_t set) const
 {
-    int64 index = 0;
+    int64_t index = 0;
 
     int tree_index = 0;
     int node_val;
index fc5add8b129a7da821cb50f12752f313a4d6f411..a4a388cf5225f03c707d1358bdc16369a7186ad0 100644 (file)
@@ -53,13 +53,13 @@ class PseudoLRUPolicy : public AbstractReplacementPolicy
     PseudoLRUPolicy(const Params * p);
     ~PseudoLRUPolicy();
 
-    void touch(int64 set, int64 way, Tick time);
-    int64 getVictim(int64 set) const;
+    void touch(int64_t set, int64_t way, Tick time);
+    int64_t getVictim(int64_t set) const;
 
   private:
     unsigned int m_effective_assoc;    /** nearest (to ceiling) power of 2 */
     unsigned int m_num_levels;         /** number of levels in the tree */
-    uint64m_trees;                   /** bit representation of the
+    uint64_t *m_trees;                   /** bit representation of the
                                         * trees, one for each set */
 };
 
index d97c134831d6f1515f666bbb3e23e4e7f6ab3690..bc0c1c224fce56e9cf0e4d15ed41251f8e8b7966 100644 (file)
@@ -67,6 +67,6 @@ class EnumDeclAST(DeclAST):
         pairs = { "external" : "yes" }
         func = Func(self.symtab, func_id + "_" + t.c_ident,
                     func_id, self.location,
-                    self.symtab.find("std::string", Type), [ t ], [], "",
+                    self.symtab.find("std::string", Type), [ t ], [], [], "",
                     pairs)
         self.symtab.newSymbol(func)
index ce73304f120cc51f48d8f8f2d4d6dd965f959ee2..ef39b40f0e893c84724c223ad33c1c517a7c4fbe 100644 (file)
@@ -46,6 +46,9 @@ class FormalParamAST(AST):
     def generate(self):
         type = self.type_ast.type
         param = "param_%s" % self.ident
+        proto = ""
+        body = ""
+        default = False
 
         # Add to symbol table
         v = Var(self.symtab, self.ident, self.location, type, param,
@@ -56,6 +59,21 @@ class FormalParamAST(AST):
            "interface" in type and (
                type["interface"] == "AbstractCacheEntry" or
                type["interface"] == "AbstractEntry")):
-            return type, "%s* %s" % (type.c_ident, param)
+            proto = "%s* %s" % (type.c_ident, param)
+            body = proto
+        elif self.default != None:
+            value = ""
+            if self.default == True:
+                value = "true"
+            elif self.default == False:
+                value = "false"
+            else:
+                value = "%s" % self.default
+            proto = "const %s& %s = %s" % (type.c_ident, param, value)
+            body = "const %s& %s" % (type.c_ident, param)
+            default = True
         else:
-            return type, "const %s& %s" % (type.c_ident, param)
+            proto = "const %s& %s" % (type.c_ident, param)
+            body = proto
+
+        return type, proto, body, default
index 47ae7076ef3ce74f8b6463854d152f7a1dcb6bad..4e64c0ba5e6417072867cf40cb98ba6a7bdc8c04 100644 (file)
@@ -45,7 +45,9 @@ class FuncDeclAST(DeclAST):
 
     def generate(self, parent = None):
         types = []
-        params = []
+        proto_params = []
+        body_params = []
+        default_count = 0
         void_type = self.symtab.find("void", Type)
 
         # Generate definition code
@@ -58,13 +60,17 @@ class FuncDeclAST(DeclAST):
         for formal in self.formals:
             # Lookup parameter types
             try:
-                type, ident = formal.generate()
+                type, proto, body, default = formal.generate()
                 types.append(type)
-                params.append(ident)
+                proto_params.append(proto)
+                body_params.append(body)
+                if default:
+                    default_count += 1
 
             except AttributeError:
                 types.append(formal.type)
-                params.append(None)
+                proto_params.append(None)
+                body_params.append(None)
 
         body = self.slicc.codeFormatter()
         if self.statements is None:
@@ -87,7 +93,8 @@ class FuncDeclAST(DeclAST):
 
         machine = self.state_machine
         func = Func(self.symtab, func_name_args, self.ident, self.location,
-                    return_type, types, params, str(body), self.pairs)
+                    return_type, types, proto_params,
+                    body_params, str(body), self.pairs, default_count)
 
         if parent is not None:
             if not parent.addFunc(func):
index 7a019a0e07792a3a4e4382fb05bfa0a228f1ac58..2ef0431519ed98f8764380bef3b4661a54b4b14d 100644 (file)
@@ -89,13 +89,13 @@ class InPortDeclAST(DeclAST):
         for param in param_types:
             trigger_func_name += "_" + param.ident
         func = Func(self.symtab, trigger_func_name, "trigger", self.location,
-                    void_type, param_types, [], "", pairs)
+                    void_type, param_types, [], [], "", pairs)
         symtab.newSymbol(func)
 
         # Add the stallPort method - this hacks reschedules the controller
         # for stalled messages that don't trigger events
         func = Func(self.symtab, "stallPort", "stallPort", self.location,
-                    void_type, [], [], "", pairs)
+                    void_type, [], [], [], "", pairs)
         symtab.newSymbol(func)
 
         param_types = []
index f0a0b97d37f08a5fa4ea36f29acc5f1d3f82f7ca..a33ea9245689bb2e23b6fb8c3caad65d8a3ad494 100644 (file)
@@ -66,7 +66,7 @@ class StateDeclAST(DeclAST):
         pairs = { "external" : "yes" }
         func = Func(self.symtab, func_id + "_" +
                     t.ident, func_id, self.location,
-                    self.symtab.find("std::string", Type), [ t ], [], "",
+                    self.symtab.find("std::string", Type), [ t ], [], [], "",
                     pairs)
         self.symtab.newSymbol(func)
 
@@ -76,6 +76,6 @@ class StateDeclAST(DeclAST):
         pairs = { "external" : "yes" }
         func = Func(self.symtab, func_id + "_" +
                     t.ident, func_id, self.location,
-                    self.symtab.find("AccessPermission", Type), [ t ], [], "",
+                    self.symtab.find("AccessPermission", Type), [ t ], [], [], "",
                     pairs)
         self.symtab.newSymbol(func)
index 6da74002a8e48519d54bca1f1bac3b822a7da93f..695450b9c50f0e4138641750b64837d2033b307a 100644 (file)
@@ -30,16 +30,19 @@ from slicc.symbols.Type import Type
 
 class Func(Symbol):
     def __init__(self, table, ident, name, location, return_type, param_types,
-                 param_strings, body, pairs):
+                 proto_param_strings, body_param_strings, body,
+                 pairs, default_count = 0):
         super(Func, self).__init__(table, ident, location, pairs)
         self.return_type = return_type
         self.param_types = param_types
-        self.param_strings = param_strings
+        self.proto_param_strings = proto_param_strings
+        self.body_param_strings = body_param_strings
         self.body = body
         self.isInternalMachineFunc = False
         self.c_ident = ident
         self.c_name = name
         self.class_name = ""
+        self.default_count = default_count
 
     def __repr__(self):
         return ""
@@ -57,16 +60,17 @@ class Func(Symbol):
             return_type += "*"
 
         return "%s %s(%s);" % (return_type, self.c_name,
-                               ", ".join(self.param_strings))
+                               ", ".join(self.proto_param_strings))
 
     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))
+        if len(args) + self.default_count < len(self.param_types) or \
+           len(args) > len(self.param_types):
+            self.error("Wrong number of arguments passed to function: '%s'" + \
+                       " Expected at least: %d, got: %d", self.c_ident,
+                       len(self.param_types) - self.default_count, len(args))
 
         cvec = []
         type_vec = []
@@ -91,14 +95,14 @@ class Func(Symbol):
         code = self.symtab.codeFormatter()
 
         # Generate function header
-        void_type = self.symtab.find("void", Type)
         return_type = self.return_type.c_ident
+        void_type = self.symtab.find("void", Type)
         if "return_by_ref" in self and self.return_type != void_type:
             return_type += "&"
         if "return_by_pointer" in self and self.return_type != void_type:
             return_type += "*"
 
-        params = ', '.join(self.param_strings)
+        params = ', '.join(self.body_param_strings)
 
         code('''
 $return_type