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.
This commit is contained in:
Brad Beckmann 2015-07-20 09:15:18 -05:00
parent 0d00cbc97b
commit 8a54adc2a5
8 changed files with 42 additions and 16 deletions

View file

@ -30,6 +30,8 @@
// Mapping functions // Mapping functions
int machineCount(MachineType machType); int machineCount(MachineType machType);
MachineID mapAddressToRange(Address addr, MachineType type,
int low, int high);
MachineID mapAddressToRange(Address addr, MachineType type, MachineID mapAddressToRange(Address addr, MachineType type,
int low, int high, NodeID n); int low, int high, NodeID n);
NetDest broadcast(MachineType type); NetDest broadcast(MachineType type);

View file

@ -65,7 +65,8 @@ class EnumDeclAST(DeclAST):
func_id = "%s_to_string" % t.c_ident func_id = "%s_to_string" % t.c_ident
pairs = { "external" : "yes" } 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 ], [], "", self.symtab.find("std::string", Type), [ t ], [], "",
pairs) pairs)
self.symtab.newSymbol(func) self.symtab.newSymbol(func)

View file

@ -80,12 +80,18 @@ class FuncCallExprAST(ExprAST):
code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline()) code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline())
return self.symtab.find("void", Type) 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 # 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 # Check the types and get the code for the parameters
if func is None: 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): if len(self.exprs) != len(func.param_types):
self.error("Wrong number of arguments passed to function : '%s'" +\ self.error("Wrong number of arguments passed to function : '%s'" +\
@ -193,7 +199,7 @@ if (!(${{cvec[0]}})) {
params += str(param_code); params += str(param_code);
fix = code.nofix() fix = code.nofix()
code('(${{func.c_ident}}($params))') code('(${{func.c_name}}($params))')
code.fix(fix) code.fix(fix)
return func.return_type return func.return_type

View file

@ -74,9 +74,20 @@ class FuncDeclAST(DeclAST):
self.symtab.popFrame() 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 machine = self.state_machine
func = Func(self.symtab, self.ident, self.location, return_type, func = Func(self.symtab, func_name_args, self.ident, self.location,
types, params, str(body), self.pairs) return_type, types, params, str(body), self.pairs)
if parent is not None: if parent is not None:
if not parent.addFunc(func): if not parent.addFunc(func):

View file

@ -85,14 +85,17 @@ class InPortDeclAST(DeclAST):
# Add the trigger method - FIXME, this is a bit dirty # Add the trigger method - FIXME, this is a bit dirty
pairs = { "external" : "yes" } pairs = { "external" : "yes" }
func = Func(self.symtab, "trigger", self.location, void_type, trigger_func_name = "trigger"
param_types, [], "", pairs) 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) symtab.newSymbol(func)
# Add the stallPort method - this hacks reschedules the controller # Add the stallPort method - this hacks reschedules the controller
# for stalled messages that don't trigger events # for stalled messages that don't trigger events
func = Func(self.symtab, "stallPort", self.location, void_type, [], func = Func(self.symtab, "stallPort", "stallPort", self.location,
[], "", pairs) void_type, [], [], "", pairs)
symtab.newSymbol(func) symtab.newSymbol(func)
param_types = [] param_types = []

View file

@ -64,7 +64,8 @@ class StateDeclAST(DeclAST):
func_id = "%s_to_string" % t.c_ident func_id = "%s_to_string" % t.c_ident
pairs = { "external" : "yes" } 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 ], [], "", self.symtab.find("std::string", Type), [ t ], [], "",
pairs) pairs)
self.symtab.newSymbol(func) self.symtab.newSymbol(func)
@ -73,7 +74,8 @@ class StateDeclAST(DeclAST):
func_id = "%s_to_permission" % t.c_ident func_id = "%s_to_permission" % t.c_ident
pairs = { "external" : "yes" } 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 ], [], "", self.symtab.find("AccessPermission", Type), [ t ], [], "",
pairs) pairs)
self.symtab.newSymbol(func) self.symtab.newSymbol(func)

View file

@ -29,7 +29,7 @@ from slicc.symbols.Symbol import Symbol
from slicc.symbols.Type import Type from slicc.symbols.Type import Type
class Func(Symbol): 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): param_strings, body, pairs):
super(Func, self).__init__(table, ident, location, pairs) super(Func, self).__init__(table, ident, location, pairs)
self.return_type = return_type self.return_type = return_type
@ -38,6 +38,7 @@ class Func(Symbol):
self.body = body self.body = body
self.isInternalMachineFunc = False self.isInternalMachineFunc = False
self.c_ident = ident self.c_ident = ident
self.c_name = name
self.class_name = "" self.class_name = ""
def __repr__(self): def __repr__(self):
@ -55,7 +56,7 @@ class Func(Symbol):
elif "return_by_pointer" in self and self.return_type != void_type: elif "return_by_pointer" in self and self.return_type != void_type:
return_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)) ", ".join(self.param_strings))
def writeCodeFiles(self, path, includes): def writeCodeFiles(self, path, includes):
@ -80,7 +81,7 @@ class Func(Symbol):
code(''' code('''
$return_type $return_type
${{self.class_name}}::${{self.c_ident}}($params) ${{self.class_name}}::${{self.c_name}}($params)
{ {
${{self.body}} ${{self.body}}
} }

View file

@ -40,7 +40,7 @@ class Transition(Symbol):
# check to make sure there is a getNextState function declared # check to make sure there is a getNextState function declared
found = False found = False
for func in machine.functions: for func in machine.functions:
if func.c_ident == 'getNextState': if func.c_ident == 'getNextState_Address':
found = True found = True
break break
if found == False: if found == False: