Menu

#3407 FATAL Compiler Internal Error in file 'gen.c' line number '5790' : Unimplemented

closed-fixed
None
other
5
2023-01-28
2022-05-31
Under4Mhz
No

The below (rather long) piece of code generates the error:

gen_5790.c:140: error 9: FATAL Compiler Internal Error in file 'gen.c' line number '5790' : Unimplemented
// GPL 2.0
#include <stdint.h>
#include <stdbool.h>

typedef struct { uint8_t x; uint8_t y; } maths_point_u8;
typedef struct { int8_t x; int8_t y; } maths_point_i8;

typedef struct {

    uint8_t id;                              // sprite index
    maths_point_u8 position;            // Current position
    maths_point_i8 direction;           // Direction
    uint8_t delay;                           // speed delay
    uint8_t sprite;                          // sprite direction
    bool active;                        // update
    uint8_t count;                           // change count

} EnemyData;

bool SpriteTurn( maths_point_u8 *position, maths_point_i8 *direction );
bool SpriteTeleport( maths_point_u8 *position, const maths_point_i8 *direction );
uint8_t SpriteDirection( maths_point_i8 *dir );
bool MoveNext( const maths_point_u8 *position, const maths_point_i8 *direction, bool collectPellet );
uint16_t fast_rand();

///< Change enemy direction
void EnemyDirection( EnemyData *enemy ) {

    bool atIntersection = SpriteTurn( &enemy->position, &enemy->direction );
    if ( !atIntersection ) return;

    maths_point_u8 playerPosition;

    maths_point_i8 towardHoraceDelta = { enemy->position.x / 8 - playerPosition.x / 8,
                                         enemy->position.y / 8 - playerPosition.y / 8 };
    maths_point_i8 towardHoraceDir;
    towardHoraceDir.x = towardHoraceDelta.x > 0 ? -1 : 1;
    towardHoraceDir.y = towardHoraceDelta.y > 0 ? -1 : 1;

    maths_point_i8 reverse = { -enemy->direction.x, -enemy->direction.y };
    maths_point_i8 dirx = { towardHoraceDir.x, 0 };
    maths_point_i8 diry = { 0, towardHoraceDir.y };
    maths_point_i8 negdirx = { -towardHoraceDir.x, 0 };
    maths_point_i8 negdiry = { 0, -towardHoraceDir.y };
    maths_point_i8 *directionsy[4] = { &diry, &dirx, &negdiry, &negdirx };
    maths_point_i8 *directionsx[4] = { &dirx, &diry, &negdirx, &negdiry };

    // If level vertically, choose move horiztonally if possible
    //LOG( "towardHoraceDelta %d, %d", towardHoraceDelta.y, towardHoraceDelta.x );
    maths_point_i8 **directions = towardHoraceDelta.y == 0 ? directionsx : directionsy;
    maths_point_i8 *availableList[4];
    uint8_t availableCount = 0;
    uint8_t directionCount = 0;

    // Find a direction
    for( uint8_t index = 0; index < 4; index++ ) {

        maths_point_i8 *dir = directions[index];

        bool blocked = MoveNext( &enemy->position, dir, false );
        if ( blocked ) continue;

        directionCount++;
        bool reversing = reverse.x == dir->x && reverse.y == dir->y;
        if ( reversing ) continue;

        availableList[availableCount++] = dir;
    }

    // Stop enemy turning around in open spaces
    bool blocked = MoveNext( &enemy->position, &enemy->direction, false );
    if ( !blocked && enemy->count && directionCount >= 3 ) {

        //LOG( "Under count" );
        enemy->count--;
        return;
    }

    // Random dir
    if ( availableCount ) {

        bool randomDir = ( fast_rand() & 1 );
        uint8_t dirIndex = randomDir ? fast_rand() % availableCount : 0;
        maths_point_i8 *newDir = availableList[dirIndex];

        // Keep straigh after turning
        bool turning = newDir->x != enemy->direction.x && newDir->y != enemy->direction.y;
        if ( turning )
            enemy->count = directionCount == 3 ? 3 : 2;
        else
            enemy->count = 0;

        enemy->direction = *newDir;
        enemy->sprite = SpriteDirection( &enemy->direction );

        //LOG("Chose %d,%d Random %d", enemy->direction.x, enemy->direction.y, randomDir);
        return;
    }

    // Deadend, check teleport
    bool teleport = SpriteTeleport( &enemy->position, &enemy->direction );
    if ( teleport ) return;

    if ( blocked ) {

        // Reverse if all ways are blocked
        enemy->direction = reverse;
        enemy->sprite = SpriteDirection( &reverse );
        enemy->count = 0;
    }
}

It must be compiled with the following command line with max-allocs-per-node to 10000. Anything under 4194 compiles fine.

sdcc -mz80 --max-allocs-per-node 10000 -c gen_5790.c 

I tried making it smaller, but removing anything tended to make the code compile successfully.

sdcc -v
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502 4.2.2 #13490 (Linux)
published under GNU General Public License (GPL)
1 Attachments

Related

Wiki: NGI0-Entrust-SDCC

Discussion

  • Philipp Klaus Krause

    I can reproduce the issue (only when using an SDCC build configured not to use treedec) on my Debian GNU/Linux testing system.

     
  • Philipp Klaus Krause

    Actually, there are two problem here. Besides getting an error message at all, the error message also has the wrong line number.

     
  • Philipp Klaus Krause

    • status: open --> pending-works-for-me
    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    I cannot reproduce this issue using SDCC from current svn. Could you please check if the bug is still there for you?

     
    • Under4Mhz

      Under4Mhz - 2023-01-28

      It works for me as well. Thanks.

       
  • Philipp Klaus Krause

    • status: pending-works-for-me --> closed-fixed
     
  • Philipp Klaus Krause

    I cannot reproduce this issue using SDCC from current svn. Could you please check if the bug is still there for you?

     

Log in to post a comment.

MongoDB Logo MongoDB