#include "cxx_codegen.hh"
#include "codegen.hh"
#include "ast.hh"

#include <map>

using namespace ast;
using namespace codegen;
using namespace std;

typedef void (*emitter_t)(ast::DProg *dprog, const char *output_name);

struct EmitterEntry {
    const char *name;
    emitter_t   emitter;
};

static EmitterEntry emitter_table[] = {
    { "C++", cxx_emit_code },
    { 0 }, // sentinel
};


// build list of supported languages
static vector<string> *
init_list()
{
    vector<string> *lang_list = new vector<string>;
    EmitterEntry *i;
    for (i = emitter_table; i->name != 0; ++i)
	lang_list->push_back(i->name);
    return lang_list;
}

// build table mapping languages to emitters
static map<string, emitter_t> *
init_table()
{
    map<string, emitter_t> *table = new map<string, emitter_t>;
    EmitterEntry *i;
    for (i = emitter_table; i->name != 0; ++i)
	(*table)[i->name] = i->emitter;
    return table;
}

static vector<string>         *lang_list = init_list();
static map<string, emitter_t> *emitters  = init_table();

const vector<string> &
codegen::supported()
{
    return *lang_list;
}

bool
codegen::supported(const string &lang)
{
    return (emitters->find(lang) != emitters->end());
}

void
codegen::emit_code(const string &lang, DProg *dprog, const char *output_name)
{
    if (supported(lang))
	(*emitters)[lang](dprog, output_name);
    else
	cerr << "Backend language \"" << lang << "\" not supported.\n";
}


syntax highlighted by Code2HTML, v. 0.9.1