output_format.h 2.8 KB

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