Skip to content

Add support for unsigned integer types #278

@jserv

Description

@jserv

Description

The compiler lacks support for unsigned integer types, which are fundamental for systems programming, bit manipulation, and proper C99 compliance. Currently only signed int and char are supported.

Current Behavior

  • unsigned keyword is not recognized
  • All integers are treated as signed
  • No unsigned char, unsigned int, unsigned long, etc.
  • Bit manipulation operations may have unexpected behavior
  • Cannot represent values > INT_MAX correctly

Expected Behavior

Full support for unsigned integer types:

  • unsigned char (0 to 255)
  • unsigned short (0 to 65535)
  • unsigned int (0 to 4294967295 on 32-bit)
  • unsigned long and unsigned long long
  • Proper arithmetic and conversion rules
  • Correct overflow behavior (wrapping)

Implementation Requirements

1. Lexer/Parser Changes

  • Recognize unsigned and signed keywords
  • Parse type specifier combinations correctly
  • Handle unsigned alone (means unsigned int)

2. Type System Extension

  • Add unsigned variants to type representation
  • Track signedness in type information
  • Implement type compatibility rules

3. Code Generation

  • Different instructions for signed vs unsigned operations
    • Division and modulo
    • Right shift (arithmetic vs logical)
    • Comparisons (signed vs unsigned)
  • Proper sign/zero extension for conversions

4. Literal Parsing

  • Support U and u suffixes for literals
  • Handle large unsigned constants correctly

Test Cases

// Basic unsigned types
unsigned int a = 4294967295U;  // Max 32-bit unsigned
unsigned char b = 255;
unsigned short c = 65535;

// Arithmetic differences
int signed_div = -10 / 3;      // -3
unsigned int unsigned_div = (unsigned)-10 / 3;  // Large positive

// Right shift differences  
int signed_shift = -1 >> 1;    // Implementation defined (usually -1)
unsigned int unsigned_shift = (unsigned)-1 >> 1;  // 0x7FFFFFFF

// Comparison differences
int x = -1;
unsigned int y = 1;
if (x < y)  // true (signed comparison)
    printf("Signed comparison\n");
if ((unsigned)x > y)  // true (unsigned comparison, -1 becomes large)
    printf("Unsigned comparison\n");

// Overflow behavior
unsigned char uc = 255;
uc++;  // Should wrap to 0

// Mixed arithmetic (usual arithmetic conversions)
unsigned int u = 1;
int s = -2;
unsigned int result = u + s;  // Should be 4294967295 (unsigned)

Implementation Strategy

  1. Start with unsigned int only
  2. Add other unsigned types (char, short, long)
  3. Implement proper arithmetic conversions
  4. Add literal suffix support
  5. Ensure correct code generation for all operations

Impact

  • CRITICAL for systems programming
  • Required for proper bit manipulation
  • Enables handling of memory addresses
  • Essential for C99 compliance

Challenges

  • Affects entire compilation pipeline
  • Requires careful handling of type conversions
  • Architecture-specific code generation changes
  • Testing all edge cases

References

  • C99 Standard Section 6.2.5 (Types)
  • C99 Standard Section 6.3.1.8 (Usual arithmetic conversions)
  • C99 Standard Section 6.7.2 (Type specifiers)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions