HolyC usa un sistema de tipos estáticamente tipado con los siguientes tipos numéricos:
| Tipo | Descripción |
|---|---|
U0 |
Equivalente a void, pero con tamaño real de 0 bytes |
I8 / U8 |
Entero con signo/sin signo de 8 bits |
I16 / U16 |
Entero con signo/sin signo de 16 bits |
I32 / U32 |
Entero con signo/sin signo de 32 bits |
I64 / U64 |
Entero con signo/sin signo de 64 bits |
F64 |
Flotante de doble precisión (64 bits) - el único tipo float |
Características clave del sistema de tipos:
typedef (se usa class), no hay bit fields, pero hay rutinas de acceso a bitsF32, auto (inferencia de tipos), y typeof()Estructuras/Clases: HolyC usa class en lugar de struct, soporta herencia:
class Person : SomethingWithAnAge {
U8 name[32];
};
La documentación oficial está integrada dentro de TempleOS (formato DolDoc). Disponible online en:
El proyecto holyc-lang de James Barford es un compilador completo de HolyC que funciona en Linux y macOS:
GitHub: https://github.com/Jamesbarford/holyc-lang
#include <stdint.h>
// HolyC → C equivalente
typedef void U0; // void (pero sizeof(U0) == 0 en HolyC)
typedef int8_t I8; // char / int8_t
typedef uint8_t U8; // unsigned char / uint8_t
typedef int16_t I16; // short / int16_t
typedef uint16_t U16; // unsigned short / uint16_t
typedef int32_t I32; // int / int32_t
typedef uint32_t U32; // unsigned int / uint32_t
typedef int64_t I64; // long long / int64_t
typedef uint64_t U64; // unsigned long long / uint64_t
typedef double F64; // double (el único float en HolyC)
Diferencias clave:
| Aspecto | HolyC | C estándar |
|---|---|---|
U0 |
void real (0 bytes) |
void tiene sizeof = 1 (extensión GCC) |
F64 |
Único tipo flotante | C tiene float y double |
| Extensión | Todo se promueve a 64 bits | No, cada tipo mantiene su tamaño |
I64 = long long |
Sí | Depende de la plataforma |
Sin long ni int genérico |
Solo tipos nombrados por bits | int, long, short sin tamaño fijo |
El compilador holyc-lang para Linux también agrega F32 (equivalente a C float) porque muchas librerías como SDL lo requieren.
#include <stdio.h>
#include <stdint.h>
int main() {
// U0 / void - no guarda valor, solo retorna "nada"
// void no se declara como variable, solo en función
// void MiFunc(void); // función sin retorno y sin args
// I8 / int8_t - (-128 a 127)
int8_t a = -42;
// U8 / uint8_t - (0 a 255) - usado como char o byte
uint8_t b = 255;
uint8_t c = 'A'; // también es un byte
// I16 / int16_t - (-32,768 a 32,767)
int16_t d = -15000;
// U16 / uint16_t - (0 a 65,535)
uint16_t e = 60000;
// I32 / int32_t - (-2,147,483,648 a 2,147,483,647)
int32_t f = 2000000000;
// U32 / uint32_t - (0 a 4,294,967,295)
uint32_t g = 4000000000U;
// I64 / int64_t - (-9.2 quintillones a 9.2 quintillones)
int64_t h = 9000000000000000000LL;
// U64 / uint64_t - (0 a 18.4 quintillones)
uint64_t i = 18000000000000000000ULL;
// F64 / double - (flotante doble precisión, ~15 decimales)
double j = 3.14159265358979;
printf("I8: %d\n", a);
printf("U8: %u\n", b);
printf("U8c: %c\n", c);
printf("I16: %d\n", d);
printf("U16: %u\n", e);
printf("I32: %d\n", f);
printf("U32: %u\n", g);
printf("I64: %lld\n", (long long)h);
printf("U64: %llu\n", (unsigned long long)i);
printf("F64: %f\n", j);
return 0;
}
Salida:
I8: -42
U8: 255
U8c: A
I16: -15000
U16: 60000
I32: 2000000000
U32: 4000000000
I64: 9000000000000000000
U64: 18000000000000000000
F64: 3.141593
Regla práctica:
U8 → bytes, caracteres, booleanosI32/U32 → la mayoría de contadores, índices, tamañosI64/U64 → timestamps, offsets grandes, direcciones de memoriaF64 → cálculos matemáticos, coordenadas