104 lines
2.8 KiB
C
104 lines
2.8 KiB
C
|
/*
|
||
|
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||
|
*
|
||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
#ifndef _OUTPUT_FORMAT_H
|
||
|
#define _OUTPUT_FORMAT_H
|
||
|
|
||
|
#include <vector>
|
||
|
#include <map>
|
||
|
#include <string>
|
||
|
#include <memory>
|
||
|
|
||
|
typedef unsigned int uint;
|
||
|
|
||
|
// can't use optional because we want to support older compilers
|
||
|
template<typename T>
|
||
|
struct simple_optional {
|
||
|
T value;
|
||
|
T default_value;
|
||
|
bool specified;
|
||
|
|
||
|
simple_optional() : default_value(), specified(false) {}
|
||
|
|
||
|
simple_optional(const T &value) : value(value), specified(true) {}
|
||
|
|
||
|
simple_optional<T> &operator=(const T &v) {
|
||
|
value = v;
|
||
|
specified = true;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
operator bool() = delete; // confusing
|
||
|
const T &get() const { return specified ? value : default_value; }
|
||
|
|
||
|
bool is_specified() const { return specified; }
|
||
|
|
||
|
static simple_optional<T> with_default(const T &default_value) {
|
||
|
simple_optional<T> rc;
|
||
|
rc.default_value = default_value;
|
||
|
return rc;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
typedef simple_optional<int> optional_int;
|
||
|
typedef simple_optional<bool> optional_bool;
|
||
|
|
||
|
struct compiled_source {
|
||
|
struct symbol {
|
||
|
std::string name;
|
||
|
int value;
|
||
|
bool is_label;
|
||
|
|
||
|
symbol(std::string name, int value, bool is_label) : name(std::move(name)), value(value), is_label(is_label) {}
|
||
|
};
|
||
|
|
||
|
struct program {
|
||
|
std::string name;
|
||
|
optional_int origin = optional_int::with_default(-1);
|
||
|
optional_int sideset_bits_including_opt;
|
||
|
bool sideset_opt = false;
|
||
|
bool sideset_pindirs = false;
|
||
|
int wrap;
|
||
|
int wrap_target;
|
||
|
std::vector<uint> instructions;
|
||
|
std::vector<symbol> symbols; // public only
|
||
|
std::map<std::string, std::vector<std::string>> code_blocks;
|
||
|
std::map<std::string, std::vector<std::pair<std::string,std::string>>> lang_opts;
|
||
|
|
||
|
// todo can't have wrap at -1
|
||
|
program(std::string name) : name(std::move(name)) {}
|
||
|
};
|
||
|
|
||
|
std::vector<symbol> global_symbols; // public only
|
||
|
std::vector<program> programs;
|
||
|
};
|
||
|
|
||
|
struct output_format {
|
||
|
static std::string default_name;
|
||
|
|
||
|
std::string name;
|
||
|
|
||
|
static void add(output_format *lang) {
|
||
|
all().push_back(std::shared_ptr<output_format>(lang));
|
||
|
}
|
||
|
|
||
|
virtual int output(std::string destination, std::vector<std::string> output_options,
|
||
|
const compiled_source &source) = 0;
|
||
|
|
||
|
virtual std::string get_description() = 0;
|
||
|
|
||
|
FILE *open_single_output(std::string destination);
|
||
|
virtual ~output_format() = default;
|
||
|
|
||
|
static std::vector<std::shared_ptr<output_format>>& all() {
|
||
|
static std::vector<std::shared_ptr<output_format>> output_formats;
|
||
|
return output_formats;
|
||
|
}
|
||
|
protected:
|
||
|
output_format(std::string name) : name(std::move(name)) {}
|
||
|
};
|
||
|
|
||
|
#endif
|