From 8a54adc2a55c9858cb536fac3a9cd92bc47ce778 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Mon, 20 Jul 2015 09:15:18 -0500 Subject: [PATCH] slicc: enable overloading in functions not in classes For many years the slicc symbol table has supported overloaded functions in external classes. This patch extends that support to functions that are not part of classes (a.k.a. no parent). For example, this support allows slicc to understand that mapAddressToRange is overloaded and the NodeID is an optional parameter. --- src/mem/protocol/RubySlicc_ComponentMapping.sm | 2 ++ src/mem/slicc/ast/EnumDeclAST.py | 3 ++- src/mem/slicc/ast/FuncCallExprAST.py | 12 +++++++++--- src/mem/slicc/ast/FuncDeclAST.py | 15 +++++++++++++-- src/mem/slicc/ast/InPortDeclAST.py | 11 +++++++---- src/mem/slicc/ast/StateDeclAST.py | 6 ++++-- src/mem/slicc/symbols/Func.py | 7 ++++--- src/mem/slicc/symbols/Transition.py | 2 +- 8 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/mem/protocol/RubySlicc_ComponentMapping.sm b/src/mem/protocol/RubySlicc_ComponentMapping.sm index 37b2c3ef4e..afb758b681 100644 --- a/src/mem/protocol/RubySlicc_ComponentMapping.sm +++ b/src/mem/protocol/RubySlicc_ComponentMapping.sm @@ -30,6 +30,8 @@ // Mapping functions int machineCount(MachineType machType); +MachineID mapAddressToRange(Address addr, MachineType type, + int low, int high); MachineID mapAddressToRange(Address addr, MachineType type, int low, int high, NodeID n); NetDest broadcast(MachineType type); diff --git a/src/mem/slicc/ast/EnumDeclAST.py b/src/mem/slicc/ast/EnumDeclAST.py index acddcb91f4..d97c134831 100644 --- a/src/mem/slicc/ast/EnumDeclAST.py +++ b/src/mem/slicc/ast/EnumDeclAST.py @@ -65,7 +65,8 @@ class EnumDeclAST(DeclAST): func_id = "%s_to_string" % t.c_ident pairs = { "external" : "yes" } - func = Func(self.symtab, func_id, self.location, + func = Func(self.symtab, func_id + "_" + t.c_ident, + func_id, self.location, self.symtab.find("std::string", Type), [ t ], [], "", pairs) self.symtab.newSymbol(func) diff --git a/src/mem/slicc/ast/FuncCallExprAST.py b/src/mem/slicc/ast/FuncCallExprAST.py index 8aebad336f..9336a22977 100644 --- a/src/mem/slicc/ast/FuncCallExprAST.py +++ b/src/mem/slicc/ast/FuncCallExprAST.py @@ -80,12 +80,18 @@ class FuncCallExprAST(ExprAST): code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline()) return self.symtab.find("void", Type) + func_name_args = self.proc_name + + for expr in self.exprs: + actual_type,param_code = expr.inline(True) + func_name_args += "_" + str(actual_type.ident) + # Look up the function in the symbol table - func = self.symtab.find(self.proc_name, Func) + func = self.symtab.find(func_name_args, Func) # Check the types and get the code for the parameters if func is None: - self.error("Unrecognized function name: '%s'", self.proc_name) + 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'" +\ @@ -193,7 +199,7 @@ if (!(${{cvec[0]}})) { params += str(param_code); fix = code.nofix() - code('(${{func.c_ident}}($params))') + code('(${{func.c_name}}($params))') code.fix(fix) return func.return_type diff --git a/src/mem/slicc/ast/FuncDeclAST.py b/src/mem/slicc/ast/FuncDeclAST.py index 052d9f05e7..47ae7076ef 100644 --- a/src/mem/slicc/ast/FuncDeclAST.py +++ b/src/mem/slicc/ast/FuncDeclAST.py @@ -74,9 +74,20 @@ class FuncDeclAST(DeclAST): self.symtab.popFrame() + func_name_args = self.ident + + if parent is None: + for arg in self.formals: + from slicc.ast import FormalParamAST + if isinstance(arg, FormalParamAST): + arg_name = arg.type_ast.ident + else: + arg_name = arg + func_name_args += "_" + str(arg_name) + machine = self.state_machine - func = Func(self.symtab, self.ident, self.location, return_type, - types, params, str(body), self.pairs) + func = Func(self.symtab, func_name_args, self.ident, self.location, + return_type, types, params, str(body), self.pairs) if parent is not None: if not parent.addFunc(func): diff --git a/src/mem/slicc/ast/InPortDeclAST.py b/src/mem/slicc/ast/InPortDeclAST.py index c5a1435eb1..da7357580d 100644 --- a/src/mem/slicc/ast/InPortDeclAST.py +++ b/src/mem/slicc/ast/InPortDeclAST.py @@ -85,14 +85,17 @@ class InPortDeclAST(DeclAST): # Add the trigger method - FIXME, this is a bit dirty pairs = { "external" : "yes" } - func = Func(self.symtab, "trigger", self.location, void_type, - param_types, [], "", pairs) + trigger_func_name = "trigger" + 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) 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", self.location, void_type, [], - [], "", pairs) + func = Func(self.symtab, "stallPort", "stallPort", self.location, + void_type, [], [], "", pairs) symtab.newSymbol(func) param_types = [] diff --git a/src/mem/slicc/ast/StateDeclAST.py b/src/mem/slicc/ast/StateDeclAST.py index 2bca54d092..f0a0b97d37 100644 --- a/src/mem/slicc/ast/StateDeclAST.py +++ b/src/mem/slicc/ast/StateDeclAST.py @@ -64,7 +64,8 @@ class StateDeclAST(DeclAST): func_id = "%s_to_string" % t.c_ident pairs = { "external" : "yes" } - func = Func(self.symtab, func_id, self.location, + func = Func(self.symtab, func_id + "_" + + t.ident, func_id, self.location, self.symtab.find("std::string", Type), [ t ], [], "", pairs) self.symtab.newSymbol(func) @@ -73,7 +74,8 @@ class StateDeclAST(DeclAST): func_id = "%s_to_permission" % t.c_ident pairs = { "external" : "yes" } - func = Func(self.symtab, func_id, self.location, + func = Func(self.symtab, func_id + "_" + + t.ident, func_id, self.location, self.symtab.find("AccessPermission", Type), [ t ], [], "", pairs) self.symtab.newSymbol(func) diff --git a/src/mem/slicc/symbols/Func.py b/src/mem/slicc/symbols/Func.py index a52b6bbcc1..d50d0309fd 100644 --- a/src/mem/slicc/symbols/Func.py +++ b/src/mem/slicc/symbols/Func.py @@ -29,7 +29,7 @@ from slicc.symbols.Symbol import Symbol from slicc.symbols.Type import Type class Func(Symbol): - def __init__(self, table, ident, location, return_type, param_types, + def __init__(self, table, ident, name, location, return_type, param_types, param_strings, body, pairs): super(Func, self).__init__(table, ident, location, pairs) self.return_type = return_type @@ -38,6 +38,7 @@ class Func(Symbol): self.body = body self.isInternalMachineFunc = False self.c_ident = ident + self.c_name = name self.class_name = "" def __repr__(self): @@ -55,7 +56,7 @@ class Func(Symbol): elif "return_by_pointer" in self and self.return_type != void_type: return_type += "*" - return "%s %s(%s);" % (return_type, self.c_ident, + return "%s %s(%s);" % (return_type, self.c_name, ", ".join(self.param_strings)) def writeCodeFiles(self, path, includes): @@ -80,7 +81,7 @@ class Func(Symbol): code(''' $return_type -${{self.class_name}}::${{self.c_ident}}($params) +${{self.class_name}}::${{self.c_name}}($params) { ${{self.body}} } diff --git a/src/mem/slicc/symbols/Transition.py b/src/mem/slicc/symbols/Transition.py index 9ecd6c54bd..856d3f4b00 100644 --- a/src/mem/slicc/symbols/Transition.py +++ b/src/mem/slicc/symbols/Transition.py @@ -40,7 +40,7 @@ class Transition(Symbol): # check to make sure there is a getNextState function declared found = False for func in machine.functions: - if func.c_ident == 'getNextState': + if func.c_ident == 'getNextState_Address': found = True break if found == False: