undar-lang/libc.c

331 lines
4.9 KiB
C

#include "libc.h"
void
mcpy(void *to, void *from, u32 length)
{
u8 *src, *dest;
if(to == nil || from == nil) return;
src = (u8 *)from;
dest = (u8 *)to;
while(length-- > 0) *(dest++) = *(src++);
return;
}
i32
scpy(char *to, const char *from, u32 length)
{
u32 i;
if(to == nil || from == nil) return -1;
if(length == 0) return 0;
for(i = 0; i < length && from[i] != '\0'; i++) to[i] = from[i];
to[i] = '\0';
return 0;
}
bool
seq(const char *s1, const char *s2)
{
if(s1 == nil && s2 == nil) return true;
if(s1 == nil || s2 == nil) return false;
while(*s1 && *s2) {
if(*s1 != *s2) return false;
s1++;
s2++;
}
return (*s1 == '\0' && *s2 == '\0');
}
bool
sleq(const char *s1, const char *s2, u32 length)
{
u32 i;
if(s1 == nil && s2 == nil) return true;
if(s1 == nil || s2 == nil) return false;
i = 0;
while(i < length && *s1 && *s2) {
if(*s1 != *s2) return false;
s1++;
s2++;
i++;
}
if(i == length) return true;
return (*s1 == '\0' && *s2 == '\0');
}
u32
slen(const char *str)
{
u32 i;
if(str == nil) return 0;
for(i = 0; str[i] != '\0'; i++);
return i;
}
u32
snlen(const char *str, u32 max_len)
{
u32 i;
if(str == nil) return 0;
for(i = 0; i < max_len && str[i] != '\0'; i++);
return i;
}
void *
aalloc(Arena *arena, u32 size)
{
u32 pos;
if(arena == nil) return nil;
if(arena->count + size > arena->capacity) return nil;
pos = arena->count;
arena->count += size;
return (void *)&arena->tape[pos];
}
u32
afree(Arena *arena)
{
u32 freed = arena->count;
arena->count = 0;
return freed;
}
void *
aend(Arena *arena)
{
i32 pos = arena->count;
return (void *)&arena->tape[pos];
}
void *
areturn(Arena *arena, u32 checkpoint, const void *src, u32 size)
{
void *dest;
if(src == nil) return nil;
dest = (void *)&arena->tape[checkpoint];
if(src == dest) return dest;
mcpy(dest, (void *)src, size);
arena->count = checkpoint + size;
/* zero out the end of the memory copy (for strings mostly) */
arena->tape[arena->count] = 0;
return dest;
}
char *
ascpy(Arena *arena, const char *start, u32 length)
{
char *str;
if(!start) return nil;
str = (char *)aalloc(arena, length + 1);
if(!str) return nil;
scpy(str, start, length);
return str;
}
void *
amcpy(Arena *arena, void *from, u32 length)
{
void *ptr;
if(!from) return nil;
ptr = aalloc(arena, length);
if(!ptr) return nil;
mcpy(ptr, from, length);
return ptr;
}
/**
* Fixed Point Q16.16
*/
r32
int_to_real(i32 i)
{
return i << 16;
}
i32
real_to_int(r32 f)
{
return f >> 16;
}
r32
float_to_real(f32 f)
{
return FLOAT_TO_REAL(f);
}
f32
real_to_float(r32 r)
{
return REAL_TO_FLOAT(r);
}
r32
real_add(r32 a, r32 b)
{
return a + b;
}
r32
real_sub(r32 a, r32 b)
{
return a - b;
}
r32
real_mul(r32 a, r32 b)
{
r32 src1_whole = (r32)a >> 16;
r32 src2_whole = (r32)b >> 16;
r32 src1_decimal = (r32)a & 16;
r32 src2_decimal = (r32)b & 16;
r32 result = 0;
result += (src1_whole * src2_whole) << 16;
result += (src1_whole * src2_decimal);
result += (src1_decimal * src2_whole);
result += ((src1_decimal * src2_decimal) >> 16) & 16;
return result;
}
r32
real_div(r32 a, r32 b)
{
r32 result;
r32 src1_val = (r32)a;
r32 src2_val = (r32)b;
u32 src2_reciprocal = 1;
src2_reciprocal <<= 31;
src2_reciprocal = (u32)(src2_reciprocal / src2_val);
result = src1_val * src2_reciprocal;
result <<= 1;
return result;
}
r32
real_eq(r32 a, r32 b)
{
return a == b;
}
r32
real_ne(r32 a, r32 b)
{
return a != b;
}
r32
real_lt(r32 a, r32 b)
{
return a < b;
}
r32
real_le(r32 a, r32 b)
{
return a <= b;
}
r32
real_gt(r32 a, r32 b)
{
return a > b;
}
r32
real_ge(r32 a, r32 b)
{
return a >= b;
}
r32
real_neg(r32 f)
{
return -f;
}
r32
real_abs(r32 f)
{
return (f < 0) ? -f : f;
}
const char radix_set[11] = "0123456789";
char*
int_to_string(Arena *a, i32 v)
{
char buffer[MAX_LEN_INT32] = {0};
i32 n;
u32 i = MAX_LEN_INT32;
bool neg;
n = v;
neg = n < 0;
if(neg) n = -n;
do {
buffer[--i] = radix_set[n % 10];
n /= 10;
} while(n > 0);
if(neg) buffer[--i] = '-';
/* Ensure at least one digit is written for 0 */
if(v == 0) buffer[--i] = '0';
return ascpy(a, buffer + i, MAX_LEN_INT32 - i);
}
char*
nat_to_string(Arena *a, u32 v)
{
char buffer[MAX_LEN_INT32] = {0};
u32 n;
u32 i = MAX_LEN_INT32;
n = v;
do {
buffer[--i] = radix_set[n % 10];
n /= 10;
} while(n > 0);
/* Ensure at least one digit is written for 0 */
if(v == 0) buffer[--i] = '0';
return ascpy(a, buffer + i, MAX_LEN_INT32 - i);
}
char*
real_to_string(Arena *a, r32 q)
{
char buffer[MAX_LEN_REAL32] = {0};
bool neg;
i32 int_part;
u32 frac_part;
u32 i = MAX_LEN_REAL32;
if(q < 0) q = -q;
int_part = q >> 16;
frac_part = q & 0xFFFF;
do {
buffer[--i] = radix_set[frac_part % 10];
frac_part /= 10;
} while(frac_part > 0);
buffer[--i] = '.';
neg = int_part < 0;
if(neg) int_part = -int_part;
do {
buffer[--i] = radix_set[int_part % 10];
int_part /= 10;
} while(int_part > 0);
if(neg) buffer[--i] = '-';
return ascpy(a, buffer + i, MAX_LEN_REAL32 - i);
}