/*

This is the program that writes the file INT.h that is included in all the C
sections that consistitue the BCPL Cintcode system.  INT.h contains C #define
statements for macros such as BCPLINT32 and BCPLINT64 for the architecture that
this program is running on.  If the current (not the target) architecture uses 64
bit pointers, it adds a #define for PTR64.

*/

#include <stdio.h>

int main() {
  printf("/* This file was generated by mkint-h */\n\n");

  if (sizeof(int)==4) {
    printf("#define BCPLINT32 int\n");
    printf("#define BCPLUINT32 unsigned int\n");
    printf("#define FormD32 \"d\"\n");
    printf("#define FormX32 \"X\"\n");
    } else if (sizeof(long)==4) {
    printf("#define BCPLINT32 long\n");
    printf("#define BCPLUINT32 unsigned long\n");
    printf("#define FormD32 \"ld\"\n");
    printf("#define FormX32 \"lX\"\n");
  }

  if (sizeof(int)==8){
    printf("#define BCPLINT64 int\n");
    printf("#define BCPLUINT64 unsigned int\n");
    printf("#define FormD64 \"d\"\n");
    printf("#define FormX64 \"X\"\n");
  } else if (sizeof(long)==8) {
    printf("#define BCPLINT64 long\n");
    printf("#define BCPLUINT64 unsigned long\n");
    printf("#define FormD64 \"ld\"\n");
    printf("#define FormX64 \"lX\"\n");
  } else if (sizeof(long long)==8) {
    printf("#define BCPLINT64 long long\n");
    printf("#define BCPLUINT64 unsigned long long\n");
    printf("#define FormD64 \"lld\"\n");
    printf("#define FormX64 \"llX\"\n");
  }

  // Conditionally define CURRENT64
  if (sizeof(void*)==8){
    printf("#define CURRENT64\n");
  }

  // Define FLOAT32 and FLOAT64
  printf("#define FLOAT32 float\n");
  printf("#define FLOAT64 double\n");

  if(sizeof(float)!=4) printf("SYSTEM ERROR: sizeof(float) in not 4\n");
  if(sizeof(double)!=8) printf("SYSTEM ERROR: sizeof(double) in not 8\n");

  // TARGET64 is conditionally defined elsewhere depending on the BCPL word
  // length of the target system. BCPLFLOAT will be defined as FLOAT64 or
  // FLOAT32 depending on whether TARGET64 is defined or not. Thus BCPL
  // floating point numbers have the same size as the BCPL word.

  // Discover whether char is signed or unsigned in this implementation
  { char ch = 0xFF;
    if(ch<0) {
      printf("#define BCPLCHAR char\n");
      printf("#define UBCPLCHAR unsigned char\n");
    } else {
      printf("#define BCPLCHAR signed char\n");
      printf("#define UBCPLCHAR char\n");
    }
  }
  return 0;
}
