--- /dev/null
+#include <map>
+#include <vector>
+#include <iostream>
+#include <cassert>
+
+#include "PluginInstance.h"
+#include "PluginException.h"
+#include "ConfigException.h"
+#include "PluginType.h"
+
+using namespace std;
+using namespace nncc::contrib;
+using namespace nncc::contrib::config;
+using namespace nncc::contrib::plugin;
+
+namespace
+{
+const string pluginName = "soft backend";
+const string pluginVersion = "0.01";
+const string pluginDesc = "Generates source code for selected programming language from IR";
+const PluginType pluginType = typeBackEnd;
+
+// Helpers
+enum class OPT_ID
+{
+ INVALID,
+ TARGET_LANG,
+ OUT_HEADER,
+ OUT_CODE,
+ OUT_MODEL
+};
+
+const char *targetLangOpt = "emit-source";
+const char *outCodeOpt = "out-code";
+const char *outHeaderOpt = "out-header";
+const char *outModelOpt = "out-model";
+
+// general options with some expected value
+const map<string, OPT_ID> opts = {{targetLangOpt, OPT_ID::TARGET_LANG},
+ {outCodeOpt, OPT_ID::OUT_CODE},
+ {outHeaderOpt, OPT_ID::OUT_HEADER},
+ {outModelOpt, OPT_ID::OUT_MODEL}};
+
+// flag options
+const map<string, OPT_ID> flags;
+
+enum class LANG_ID
+{
+ INVALID,
+ C,
+ CPP
+};
+
+const map<string, LANG_ID> langs = {{"c", LANG_ID::C},
+ {"c++", LANG_ID::CPP}};
+
+// Plugin implementation
+class SoftBackendInstance : public AbstractPluginInstance
+{
+public:
+ SoftBackendInstance &operator=(const SoftBackendInstance &) = delete;
+ SoftBackendInstance(const SoftBackendInstance &) = delete;
+
+ static AbstractPluginInstance &getInstance();
+ void fillSession() override;
+ void checkConfig() override;
+ void *execute(void *data) override;
+
+ void setParam(const string &name) override;
+ void setParam(const string &name, const string &value) override;
+
+private:
+ LANG_ID _target;
+ string _outHeaderFile;
+ string _outCodeFile;
+ string _outModelFile;
+
+ SoftBackendInstance();
+ ~SoftBackendInstance() override = default;
+};
+
+SoftBackendInstance::SoftBackendInstance(): _target(LANG_ID::INVALID)
+{
+ // EMPTY
+}
+
+AbstractPluginInstance &SoftBackendInstance::getInstance()
+{
+ static SoftBackendInstance instance;
+ return instance;
+}
+
+void SoftBackendInstance::fillSession()
+{
+ const static map<string, string> info = {{"module description", pluginDesc}};
+ const static vector<PluginParam> moduleParams = {{targetLangOpt, "language to emit: c,c++", false},
+ {outCodeOpt, "output file for code", true},
+ {outHeaderOpt, "output file for header", true},
+ {outModelOpt, "output file for model parameters", true}};
+
+ AbstractPluginInstance::fillSessionBase(pluginType, pluginVersion, pluginName);
+
+ for (auto &i : info)
+ getSession()->addInfo(i.first, i.second);
+
+ for (const auto &p: moduleParams)
+ getSession()->registerParam(p);
+}
+
+void SoftBackendInstance::checkConfig()
+{
+ assert(_target != LANG_ID::INVALID && "No target language selected");
+}
+
+void *SoftBackendInstance::execute(void *data)
+{
+ assert(_target != LANG_ID::INVALID);
+ // TODO Implementation here
+ cout << "\n[" << pluginName << "] Plugin executed" << endl;
+ return data;
+}
+
+void SoftBackendInstance::setParam(const string &name)
+{
+ auto optionIt = flags.find(name);
+ (void) optionIt;
+ // plugin do not have flag arguments for now - throw exception
+ throw ConfigException("[" + pluginName + "] Unsupported flag parameter <" + name + ">");
+}
+
+void SoftBackendInstance::setParam(const string &name, const string &value)
+{
+ auto optionIt = opts.find(name);
+ assert(optionIt != opts.end());
+ switch (optionIt->second)
+ {
+ case OPT_ID::TARGET_LANG:
+ {
+ auto langId = langs.find(value);
+ if (langId == langs.end())
+ {
+ string info = "[" + pluginName + "] Unsupported target language <" + value + ">";
+ throw ConfigException(info);
+ }
+ _target = langId->second;
+ break;
+ }
+ case OPT_ID::OUT_HEADER:
+ {
+ _outHeaderFile = value;
+ break;
+ }
+ case OPT_ID::OUT_CODE:
+ {
+ _outCodeFile = value;
+ break;
+ }
+ case OPT_ID::OUT_MODEL:
+ {
+ _outModelFile = value;
+ break;
+ }
+ default:
+ throw ConfigException("[" + pluginName + "] Unsupported parameter <" + name + ">");
+ }
+}
+
+} // unnamed namespace
+
+extern "C" AbstractPluginInstance *get_instance()
+{
+ return &SoftBackendInstance::getInstance();
+}