Carp/core/core.h

503 lines
9.9 KiB
C
Raw Normal View History

2017-06-26 12:15:03 +03:00
#ifndef PRELUDE_H
#define PRELUDE_H
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>
#include <assert.h>
2017-10-18 14:02:44 +03:00
#include <limits.h>
2017-06-26 12:15:03 +03:00
2017-11-22 18:08:19 +03:00
#define LOG_MEMORY 0
#if LOG_MEMORY
int malloc_balance_counter = 0;
2017-06-30 11:46:40 +03:00
void *logged_malloc(size_t size) {
void *ptr = malloc(size);
printf("MALLOC: %p (%ld bytes)\n", ptr, size);
malloc_balance_counter++;
2017-06-30 11:46:40 +03:00
return ptr;
}
void logged_free(void *ptr) {
printf("FREE: %p\n", ptr);
free(ptr);
malloc_balance_counter--;
if(malloc_balance_counter == 0) {
printf("malloc is balanced! (this should be the last thing you see)\n");
}
else if(malloc_balance_counter < 0) {
printf("malloc is %d, that is bad!\n", malloc_balance_counter);
}
2017-06-30 11:46:40 +03:00
}
#define CARP_MALLOC(size) logged_malloc(size)
#define CARP_FREE(ptr) logged_free(ptr)
#else
#define CARP_MALLOC(size) malloc(size)
#define CARP_FREE(ptr) free(ptr)
#endif
2017-06-26 12:15:03 +03:00
typedef char* string;
2017-10-13 13:48:18 +03:00
// Array
typedef struct {
int len;
void *data;
} Array;
2017-06-26 12:15:03 +03:00
bool not(bool b) {
return !b;
}
2017-10-25 20:17:53 +03:00
int Int__PLUS_(int x, int y) { return x + y; }
int Int__MINUS_(int x, int y) { return x - y; }
int Int__MUL_(int x, int y) { return x * y; }
int Int__DIV_(int x, int y) { return x / y; }
2017-11-16 23:19:39 +03:00
bool Int_safe_MINUS_add(int x, int y, int* res) { return __builtin_sadd_overflow(x, y, res); }
bool Int_safe_MINUS_sub(int x, int y, int* res) { return __builtin_ssub_overflow(x, y, res); }
bool Int_safe_MINUS_mul(int x, int y, int* res) { return __builtin_smul_overflow(x, y, res); }
2017-10-25 20:17:53 +03:00
bool Int__EQ_(int x, int y) { return x == y; }
bool Int__DIV__EQ_(int x, int y) { return x != y; }
bool Int__LT_(int x, int y) { return x < y; }
bool Int__GT_(int x, int y) { return x > y; }
2017-06-26 12:15:03 +03:00
int Int_inc(int x) { return x + 1; }
int Int_dec(int x) { return x - 1; }
2017-11-17 14:26:01 +03:00
int Int_abs(int x) { return abs(x); }
2017-06-26 12:15:03 +03:00
2017-10-25 20:17:53 +03:00
long Long__PLUS_(long x, long y) { return x + y; }
long Long__MINUS_(long x, long y) { return x - y; }
long Long__MUL_(long x, long y) { return x * y; }
long Long__DIV_(long x, long y) { return x / y; }
2017-11-16 23:19:39 +03:00
bool Long_safe_MINUS_add(long x, long y, long* res) { return __builtin_saddl_overflow(x, y, res); }
bool Long_safe_MINUS_sub(long x, long y, long* res) { return __builtin_ssubl_overflow(x, y, res); }
bool Long_safe_MINUS_mul(long x, long y, long* res) { return __builtin_smull_overflow(x, y, res); }
2017-10-25 20:17:53 +03:00
bool Long__EQ_(long x, long y) { return x == y; }
bool Long__LT_(long x, long y) { return x < y; }
bool Long__GT_(long x, long y) { return x > y; }
long Long_inc(long x) { return x + 1; }
long Long_dec(long x) { return x - 1; }
2017-11-17 14:26:01 +03:00
long Long_abs(long x) { return labs(x); }
2017-10-25 20:17:53 +03:00
2017-09-08 13:24:57 +03:00
int Int_copy(int *x) { return *x; }
2017-10-25 20:17:53 +03:00
int Long_copy(long *x) { return *x; }
2017-10-19 19:34:44 +03:00
float Float_copy(float *x) { return *x; }
double Double_copy(double *x) { return *x; }
2017-09-08 13:24:57 +03:00
2017-10-24 14:52:32 +03:00
double Double__PLUS_(double x, double y) { return x + y; }
double Double__MINUS_(double x, double y) { return x - y; }
double Double__MUL_(double x, double y) { return x * y; }
double Double__DIV_(double x, double y) { return x / y; }
bool Double__LT_(double x, double y) { return x < y; }
bool Double__GT_(double x, double y) { return x > y; }
bool Double__EQ_(double x, double y) { return x == y; }
double Double_neg(double x) { return -x; }
2017-10-24 14:52:32 +03:00
float Float__PLUS_(float x, float y) { return x + y; }
float Float__MINUS_(float x, float y) { return x - y; }
float Float__MUL_(float x, float y) { return x * y; }
float Float__DIV_(float x, float y) { return x / y; }
bool Float__LT_(float x, float y) { return x < y; }
bool Float__GT_(float x, float y) { return x > y; }
bool Float__EQ_(float x, float y) { return x == y; }
double Float_neg(float x) { return -x; }
2017-06-26 12:15:03 +03:00
2017-10-24 15:13:45 +03:00
bool and(bool x, bool y) { return x && y; }
bool or(bool x, bool y) { return x || y; }
2017-06-26 12:15:03 +03:00
void IO_println(string *s) { puts(*s); }
void IO_print(string *s) { printf("%s", *s); }
string IO_get_MINUS_line() {
size_t size = 1024;
2017-06-30 12:00:36 +03:00
char *buffer = CARP_MALLOC(size);
2017-06-26 12:15:03 +03:00
getline(&buffer, &size, stdin);
return buffer;
}
int Int_from_MINUS_string(string *s) {
return atoi(*s);
2017-06-26 12:15:03 +03:00
}
int Int_mod(int x, int divider) {
return x % divider;
}
void Int_seed(int seed) {
srand(seed);
}
int Int_random() {
return rand();
}
int Int_random_MINUS_between(int lower, int upper) {
int diff = upper - lower;
return lower + (rand() % diff);
}
string Int_str(int x) {
2017-10-10 21:13:58 +03:00
char *buffer = CARP_MALLOC(64);
snprintf(buffer, 64, "%d", x);
return buffer;
2017-06-26 12:15:03 +03:00
}
bool Int_mask(int a, int b) {
return a & b;
}
2017-10-25 20:17:53 +03:00
long Long_from_MINUS_string(string *s) {
return atol(*s);
}
long Long_mod(long x, long divider) {
return x % divider;
}
void Long_seed(long seed) {
srand(seed);
}
long Long_random() {
return rand();
}
long Long_random_MINUS_between(long lower, long upper) {
long diff = upper - lower;
return lower + (rand() % diff);
}
string Long_str(long x) {
char *buffer = CARP_MALLOC(64);
snprintf(buffer, 64, "%ldl", x);
return buffer;
}
bool Long_mask(long a, long b) {
return a & b;
}
2017-06-26 12:15:03 +03:00
void String_delete(string s) {
2017-06-30 12:00:36 +03:00
CARP_FREE(s);
2017-06-26 12:15:03 +03:00
}
string String_copy(string *s) {
char *ptr = strdup(*s);
#if LOG_MEMORY
printf("STRDUP: %p\n", ptr);
2017-11-22 18:08:19 +03:00
malloc_balance_counter++;
#endif
return ptr;
2017-06-26 12:15:03 +03:00
}
bool String__EQ_(string *a, string *b) {
return strcmp(*a, *b) == 0;
}
2017-10-20 18:00:47 +03:00
bool String__DIV__EQ_(string *a, string *b) {
return strcmp(*a, *b) == 0;
}
2017-06-26 12:15:03 +03:00
string String_append(string a, string b) {
int la = strlen(a);
int lb = strlen(b);
int total = la + lb + 1;
2017-06-30 12:00:36 +03:00
string buffer = CARP_MALLOC(total);
2017-06-26 12:15:03 +03:00
snprintf(buffer, total, "%s%s", a, b);
2017-06-30 12:00:36 +03:00
CARP_FREE(a);
CARP_FREE(b);
2017-06-26 12:15:03 +03:00
return buffer;
}
int String_count(string *s) {
return strlen(*s);
}
// Replace with 'copy' later:
string String_duplicate(string *s) {
return strdup(*s);
}
char* String_cstr(string *s) {
return *s;
}
2017-10-10 21:13:58 +03:00
string String_str(string *s) {
2017-10-12 09:38:53 +03:00
int n = strlen(*s) + 4;
string buffer = CARP_MALLOC(n);
2017-10-12 09:38:53 +03:00
snprintf(buffer, n, "@\"%s\"", *s);
2017-10-10 21:13:58 +03:00
return buffer;
}
2017-10-13 13:48:18 +03:00
Array String_chars(string *s) {
Array chars;
chars.len = strlen(*s);
chars.data = strdup(*s);
return chars;
}
2017-10-20 18:00:47 +03:00
string String_from_MINUS_chars(Array a) {
string s = CARP_MALLOC(a.len+1);
snprintf(s, a.len+1, "%s", a.data);
2017-10-20 18:00:47 +03:00
return s;
}
2017-06-26 12:15:03 +03:00
string Char_str(char c) {
2017-10-10 21:13:58 +03:00
char *buffer = CARP_MALLOC(3);
snprintf(buffer, 3, "\\%c", c);
2017-06-26 12:15:03 +03:00
return buffer;
}
int Char_to_MINUS_int(char c) {
return (int)c;
}
char Char_from_MINUS_int(int i) {
return (char)i;
}
2017-06-26 12:15:03 +03:00
// Double.toInt : Double -> Int
int Double_to_MINUS_int(double x) {
2017-06-26 12:15:03 +03:00
return (int)x;
}
double Double_from_MINUS_int(int x) {
2017-06-26 12:15:03 +03:00
return (double)x;
}
float Double_to_MINUS_float(double x) {
return (float)x;
}
double Double_from_MINUS_float(float x) {
return (double)x;
}
double Double_abs(double x) {
return fabs(x);
}
double Double_acos(double x) {
return acos(x);
}
double Double_asin(double x) {
return asin(x);
}
double Double_atan(double x) {
return atan(x);
}
double Double_atan2(double y, double x) {
return atan2(y, x);
2017-06-26 12:15:03 +03:00
}
double Double_cos(double x) {
return cos(x);
}
double Double_cosh(double x) {
return cosh(x);
}
double Double_sin(double x) {
return sin(x);
}
double Double_sinh(double x) {
return sinh(x);
2017-10-20 01:44:25 +03:00
}
double Double_tanh(double x) {
return tanh(x);
}
double Double_exp(double x) {
return exp(x);
}
double Double_frexp(double x, int* exponent) {
return frexp(x, exponent);
}
double Double_ldexp(double x, int exponent) {
return ldexp(x, exponent);
}
double Double_log(double x) {
return log(x);
}
double Double_log10(double x) {
return log10(x);
}
double Double_modf(double x, double* integer) {
return modf(x, integer);
}
double Double_pow(double x, double y) {
return pow(x, y);
}
double Double_sqrt(double x) {
return sqrt(x);
}
double Double_ceil(double x) {
return ceil(x);
}
2017-11-06 20:08:07 +03:00
double Double_floor(double x) {
return floor(x);
}
double Double_mod(double x, double y) {
return fmod(x, y);
2017-11-07 17:06:47 +03:00
}
2017-10-10 21:13:58 +03:00
string Double_str(double x) {
char *buffer = CARP_MALLOC(32);
2017-10-18 14:02:44 +03:00
snprintf(buffer, 32, "%g", x);
2017-10-10 21:13:58 +03:00
return buffer;
}
int Float_to_MINUS_int(double x) {
2017-06-26 12:15:03 +03:00
return (int)x;
}
2017-10-18 14:02:44 +03:00
float Float_random_MINUS_between(float lower, float upper) {
float diff = upper - lower;
float r = ((float)(rand() % INT_MAX)) / ((float)INT_MAX);
return lower + diff * r;
}
float Float_abs(float x) {
return fabs(x);
}
float Float_acos(float x) {
return acos(x);
}
float Float_asin(float x) {
return asin(x);
}
float Float_atan(float x) {
return atan(x);
}
float Float_atan2(float y, float x) {
return atan2(y, x);
}
float Float_cos(float x) {
return cos(x);
}
float Float_cosh(float x) {
return cosh(x);
}
float Float_sin(float x) {
return sin(x);
}
float Float_sinh(float x) {
return sinh(x);
}
float Float_tanh(float x) {
return tanh(x);
}
float Float_exp(float x) {
return exp(x);
}
float Float_frexp(float x, int* exponent) {
return frexp(x, exponent);
}
float Float_ldexp(float x, int exponent) {
return ldexp(x, exponent);
}
float Float_log(float x) {
return log(x);
}
float Float_log10(float x) {
return log10(x);
}
float Float_modf(float x, float* integer) {
return modf(x, (double*) integer);
}
float Float_pow(float x, float y) {
return pow(x, y);
}
float Float_sqrt(float x) {
return sqrt(x);
}
float Float_ceil(float x) {
return ceil(x);
}
float Float_floor(float x) {
return floor(x);
}
float Float_mod(float x, float y) {
return fmod(x, y);
}
2017-10-10 21:13:58 +03:00
string Float_str(float x) {
char *buffer = CARP_MALLOC(32);
2017-10-18 14:02:44 +03:00
snprintf(buffer, 32, "%gf", x);
2017-10-10 21:13:58 +03:00
return buffer;
}
// Bool
2017-10-20 18:00:47 +03:00
bool Bool__EQ_(bool a, bool b) {
return a == b;
}
bool Bool__DIV__EQ_(bool a, bool b) {
return a != b;
}
string Bool_str(bool b) {
if(b) {
return strdup("true");
} else {
return strdup("false");
}
}
2017-06-26 12:15:03 +03:00
void System_exit(int code) {
exit(code);
}
2017-06-30 12:00:36 +03:00
void System_CARP_FREE__string_MUL_(void *p) {
CARP_FREE(p);
2017-06-26 12:15:03 +03:00
}
int System_time() {
return time(0);
}
2017-10-18 14:02:44 +03:00
void System_srand(int x) {
srand(x);
}
2017-06-26 12:15:03 +03:00
#endif