llvm-mos / llvm-mos-sdk

SDK for developing with the llvm-mos compiler
https://www.llvm-mos.org
Other
279 stars 55 forks source link

Support more of the C++11 library #52

Open dr-m opened 2 years ago

dr-m commented 2 years ago

You may be familiar with the CppCon 2016 talk "Rich Code for Tiny Computers: A Simple Commodore 64 Game in C++17".

The "compiler" implementation was a hack: letting clang translate to IA-32, and then translating a very small subset of IA-32 code to 6502 (while wrongly assuming that IA-32 is an 8-bit processor). Not all registers were supported, nor were function calls, if I remember correctly. The main point was to demonstrate that modern C++ allows zero-overhead abstraction, that is, lots of things can be evaluated at compilation time.

In the video, there was one problem that my very first pull request lefticus/6502-cpp#2 addressed, by implementing constexpr constructors for sprite data.

It would be great if the pong.cpp could be compiled on llvm-mos-sdk with minimal source code modification. Currently, the compilation would fail like this:

pong.cc:2:10: fatal error: 'array' file not found

The std::array is only used for something during compilation time; in the object code, you would only see some immediate loads followed by sta, stx or sty to some VIC-II registers between 0xd020 and 0xd02e.

  vic.border()         = vic.nearest_color<128,128,128>(colors).num; // 50% grey
  vic.background()     = vic.nearest_color<0,0,0>(colors).num;       // black
  vic.sprite_1_color() = vic.nearest_color<255,0,0>(colors).num;     // red
  vic.sprite_2_color() = vic.nearest_color<0,255,0>(colors).num;     // green
pfusik commented 1 year ago

I assume you mean https://github.com/lefticus/6502-cpp/blob/master/examples/pong.cpp

After:

touch array utility algorithm tuple

I get:

C:\0\a8\llvm>"install\bin\mos-c64-clang++.bat" -Os -Wall pong.cpp
pong.cpp:58:19: error: no member named 'make_pair' in namespace 'std'
      return std::make_pair(left?-1:(right?1:0), up?-1:(down?1:0));
             ~~~~~^
pong.cpp:68:26: error: no template named 'pair' in namespace 'std'
    auto operator+=(std::pair<L1&, L2&> lhs, const std::pair<R1, R2> &rhs)
                    ~~~~~^
pong.cpp:68:57: error: no template named 'pair' in namespace 'std'
    auto operator+=(std::pair<L1&, L2&> lhs, const std::pair<R1, R2> &rhs)
                                                   ~~~~~^
pong.cpp:76:36: error: no template named 'pair' in namespace 'std'
    decltype(auto) operator*=(std::pair<L1, L2> &lhs, const std::pair<R1, R2> &rhs)
                              ~~~~~^
pong.cpp:76:66: error: no template named 'pair' in namespace 'std'
    decltype(auto) operator*=(std::pair<L1, L2> &lhs, const std::pair<R1, R2> &rhs)
                                                            ~~~~~^
pong.cpp:94:36: error: no template named 'pair' in namespace 'std'
    Player(const uint8_t num, std::pair<volatile uint8_t &, volatile uint8_t &> sprite_pos,
                              ~~~~~^
pong.cpp:95:42: error: no template named 'pair' in namespace 'std'
                              const std::pair<uint8_t, uint8_t> &start_pos)
                                    ~~~~~^
pong.cpp:112:10: error: no template named 'pair' in namespace 'std'
    std::pair<volatile uint8_t &, volatile uint8_t &> pos;
    ~~~~~^
pong.cpp:276:10: error: no template named 'pair' in namespace 'std'
    std::pair<volatile uint8_t &, volatile uint8_t &>
    ~~~~~^
pong.cpp:168:20: error: no member named 'min_element' in namespace 'std'
      return *std::min_element(std::begin(colors), std::end(colors),
              ~~~~~^
pong.cpp:168:37: error: no member named 'begin' in namespace 'std'
      return *std::min_element(std::begin(colors), std::end(colors),
                               ~~~~~^
pong.cpp:168:57: error: no member named 'end' in namespace 'std'
      return *std::min_element(std::begin(colors), std::end(colors),
                                                   ~~~~~^
pong.cpp:249:17: error: no member named 'ptrdiff_t' in namespace 'std'
        = (std::ptrdiff_t(bitmap.lines) & 0x3fff) / SPRITE_ALIGNMENT;
           ~~~~~^
pong.cpp:260:19: error: no member named 'make_tuple' in namespace 'std'
      return std::make_tuple(
             ~~~~~^
pong.cpp:279:14: error: excess elements in scalar initializer
      return {
             ^
pong.cpp:295:14: error: no template named 'array' in namespace 'std'
  const std::array<Color, 16> colors = {{
        ~~~~~^
pong.cpp:379:8: error: no member named 'pair' in namespace 'std'
  std::pair<int8_t, int8_t> ball_velocity{1,1};
  ~~~~~^
pong.cpp:379:13: error: unexpected type name 'int8_t': expected expression
  std::pair<int8_t, int8_t> ball_velocity{1,1};
            ^
pong.cpp:383:30: error: no member named 'make_pair' in namespace 'std'
    vic.sprite_pos(0) = std::make_pair(255/2, 255/2);
                        ~~~~~^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.