1 /* 2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _OUTPUT_FORMAT_H 8 #define _OUTPUT_FORMAT_H 9 10 #include <vector> 11 #include <map> 12 #include <string> 13 #include <memory> 14 15 typedef unsigned int uint; 16 17 // can't use optional because we want to support older compilers 18 template<typename T> 19 struct simple_optional { 20 T value; 21 T default_value; 22 bool specified; 23 simple_optionalsimple_optional24 simple_optional() : default_value(), specified(false) {} 25 simple_optionalsimple_optional26 simple_optional(const T &value) : value(value), specified(true) {} 27 28 simple_optional<T> &operator=(const T &v) { 29 value = v; 30 specified = true; 31 return *this; 32 } 33 34 operator bool() = delete; // confusing getsimple_optional35 const T &get() const { return specified ? value : default_value; } 36 is_specifiedsimple_optional37 bool is_specified() const { return specified; } 38 with_defaultsimple_optional39 static simple_optional<T> with_default(const T &default_value) { 40 simple_optional<T> rc; 41 rc.default_value = default_value; 42 return rc; 43 } 44 }; 45 46 typedef simple_optional<int> optional_int; 47 typedef simple_optional<bool> optional_bool; 48 49 struct compiled_source { 50 struct symbol { 51 std::string name; 52 int value; 53 bool is_label; 54 symbolcompiled_source::symbol55 symbol(std::string name, int value, bool is_label) : name(std::move(name)), value(value), is_label(is_label) {} 56 }; 57 58 struct program { 59 std::string name; 60 optional_int origin = optional_int::with_default(-1); 61 optional_int sideset_bits_including_opt; 62 bool sideset_opt = false; 63 bool sideset_pindirs = false; 64 int wrap; 65 int wrap_target; 66 std::vector<uint> instructions; 67 std::vector<symbol> symbols; // public only 68 std::map<std::string, std::vector<std::string>> code_blocks; 69 std::map<std::string, std::vector<std::pair<std::string,std::string>>> lang_opts; 70 71 // todo can't have wrap at -1 programcompiled_source::program72 program(std::string name) : name(std::move(name)) {} 73 }; 74 75 std::vector<symbol> global_symbols; // public only 76 std::vector<program> programs; 77 }; 78 79 struct output_format { 80 static std::string default_name; 81 82 std::string name; 83 addoutput_format84 static void add(output_format *lang) { 85 all().push_back(std::shared_ptr<output_format>(lang)); 86 } 87 88 virtual int output(std::string destination, std::vector<std::string> output_options, 89 const compiled_source &source) = 0; 90 91 virtual std::string get_description() = 0; 92 93 FILE *open_single_output(std::string destination); 94 virtual ~output_format() = default; 95 alloutput_format96 static std::vector<std::shared_ptr<output_format>>& all() { 97 static std::vector<std::shared_ptr<output_format>> output_formats; 98 return output_formats; 99 } 100 protected: output_formatoutput_format101 output_format(std::string name) : name(std::move(name)) {} 102 }; 103 104 #endif