diff options
author | Daniel Friesel <daniel.friesel@uos.de> | 2019-08-30 13:53:53 +0200 |
---|---|---|
committer | Daniel Friesel <daniel.friesel@uos.de> | 2019-08-30 13:53:53 +0200 |
commit | 855bc77bcf3a39859e590abc4b95311b317c1b49 (patch) | |
tree | ea4a95cb6d7a9ba30707ca2c4f4b27a3fe2ff182 /lib | |
parent | 65491fab964b69416aa7f0bc96eff98a38b45fd9 (diff) |
add codegen MVP for online model overhead analysis
Diffstat (limited to 'lib')
-rw-r--r-- | lib/aspectc.py | 2 | ||||
-rw-r--r-- | lib/codegen.py | 80 |
2 files changed, 81 insertions, 1 deletions
diff --git a/lib/aspectc.py b/lib/aspectc.py index 919c93d..3229057 100644 --- a/lib/aspectc.py +++ b/lib/aspectc.py @@ -7,7 +7,7 @@ class AspectCClass: :attr name: class name (str) :attr class_id: internal AspectC++ class ID (str/int) :attr functions: functions implemented by this class (list of :class:`AspectCFunction`) - :attr function: dict mapping function name to :class:`AspectCFunction` + :attr function: dict mapping function name to :class:`AspectCFunction`. Only sensible for classes which do not overload functions. """ def __init__(self, name, class_id, functions): diff --git a/lib/codegen.py b/lib/codegen.py new file mode 100644 index 0000000..d6dfe6e --- /dev/null +++ b/lib/codegen.py @@ -0,0 +1,80 @@ +"""Code generators for multipass dummy drivers for online model evaluation.""" + +header_template = """ +#ifndef DFATOOL_{name}_H +#define DFATOOL_{name}_H + +class {name} +{{ +private: +{name}(const {name} ©); + +public: +{enums} +{functions} +}}; + +extern {name} {name_lower}; + +#endif +""" + +implementation_template = """ +#include "driver/dummy.h" + +{functions} + +{name} {name_lower}; +""" + +class MultipassDriver: + """Generate C++ header and no-op implementation for a multipass driver based on a DFA model.""" + + def __init__(self, name, pta, class_info, enum = dict()): + self.impl = '' + self.header = '' + self.name = name + self.pta = pta + self.class_info = class_info + self.enum = enum + + function_definitions = list() + function_bodies = list() + + function_definitions.append('{}() {{}}'.format(self.name)) + seen_transitions = set() + + for transition in self.pta.transitions: + if transition.name in seen_transitions: + continue + seen_transitions.add(transition.name) + + # XXX right now we only verify whether both functions have the + # same number of arguments. This breaks in many overloading cases. + function_info = self.class_info.function[transition.name] + function_arguments = list() + + if len(transition.arguments) != len(function_info.argument_types): + # polymorphic function variant, TODO + pass + + for i in range(len(transition.arguments)): + function_arguments.append('{} {}'.format(function_info.argument_types[i], transition.arguments[i])) + + function_definition = '{} {}({})'.format(function_info.return_type, transition.name, ', '.join(function_arguments)) + function_head = '{} {}::{}({})'.format(function_info.return_type, self.name, transition.name, ', '.join(function_arguments)) + + function_body = str() + + if function_info.return_type != 'void': + function_body = 'return 0;\n' + + function_definitions.append(function_definition + ';') + function_bodies.append('{} {{\n{}}}'.format(function_head, function_body)) + + enums = list() + for enum_name in self.enum.keys(): + enums.append('enum {} {{ {} }};'.format(enum_name, ', '.join(self.enum[enum_name]))) + + self.header = header_template.format(name = self.name, name_lower = self.name.lower(), functions = '\n'.join(function_definitions), enums = '\n'.join(enums)) + self.impl = implementation_template.format(name = self.name, name_lower = self.name.lower(), functions = '\n\n'.join(function_bodies)) |