Last active
February 9, 2024 05:39
-
-
Save srijanpaul-deepsource/f47e334ea62a293c09955e8eef3aeeea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include <math.h> // for NaN | |
#include <assert.h> | |
union BoxedValue_t { | |
uint64_t bits; // to inspect the raw bits | |
double number; // to interpret the value as an IEEE float | |
}; | |
typedef union BoxedValue_t BoxedValue; | |
#define MASK_SIGN 0x8000000000000000UL | |
#define MASK_EXP 0x7ff0000000000000UL | |
#define MASK_QNAN 0x0008000000000000UL | |
#define MASK_TAG 0x0007000000000000UL | |
#define MASK_PTR 0x0000ffffffffffffUL | |
#define TAG_NULL 0x0001000000000000UL | |
#define TAG_TRUE 0x0002000000000000UL | |
#define TAG_FALSE 0x0003000000000000UL | |
#define IS_NUMBER(v) (!isnan(v.number)) | |
#define IS_OBJECT(v) (isnan(v.number) && (MASK_SIGN && (v.bits))) | |
#define AS_NUMBER(v) (v.number) | |
#define AS_OBJECT(v) ((void *)((v.bits) & MASK_PTR)) | |
#define IS_TAGGED(v) (isnan(v.number) && (MASK_TAG & (v.bits))) | |
#define IS_NULL(v) (IS_TAGGED(v) && (TAG_NULL & (v.bits))) | |
#define IS_TRUE(v) (IS_TAGGED(v) && (TAG_TRUE & (v.bits))) | |
#define IS_FALSE(v) (IS_TAGGED(v) && (TAG_FALSE & (v.bits))) | |
#define QNAN 0xfff8000000000000 | |
#define KNULL (QNAN | TAG_NULL) // `NULL` is reserved by C stdlib | |
#define TRUE (QNAN | TAG_TRUE) | |
#define FALSE (QNAN | TAG_FALSE) | |
BoxedValue make_num(double value) { | |
return (BoxedValue){.number = value}; | |
} | |
BoxedValue make_imm(uint64_t value) { | |
return (BoxedValue){.bits = value}; | |
} | |
BoxedValue make_ptr(void *ptr) { | |
BoxedValue value; | |
value.bits = QNAN | (uint64_t)(ptr); | |
return value; | |
} | |
typedef BoxedValue Value; | |
BoxedValue add_numbers(BoxedValue a, BoxedValue b) { | |
if (IS_NUMBER(a) && IS_NUMBER(b)) { | |
double sum = AS_NUMBER(a) + AS_NUMBER(b); | |
return make_num(sum); | |
} | |
return make_imm(KNULL); | |
} | |
int main() { | |
Value null = make_imm(KNULL); | |
assert(IS_NULL(null)); | |
Value vtrue = make_imm(TRUE); | |
assert(IS_TRUE(vtrue)); | |
Value vdbl = make_num(5.564); | |
assert(IS_NUMBER(vdbl) && (AS_NUMBER(vdbl) == 5.564)); | |
Value a = make_num(6), b = make_num(7); | |
assert(AS_NUMBER(add_numbers(a, b)) == 13); | |
const char *sa = "test string"; | |
Value vptr = make_ptr((void *)sa); | |
assert(IS_OBJECT(vptr)); | |
assert(((char *)AS_OBJECT(vptr)) == sa); | |
printf("tests passed.\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment