breaking changes in type system
This commit is contained in:
@@ -5,12 +5,13 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "std.h"
|
||||
#include "type_system/typedef_macros.h"
|
||||
|
||||
PACK_ENUM(Endian,
|
||||
PACKED_ENUM(Endian,
|
||||
UnknownEndian=0,
|
||||
LittleEndian=1,
|
||||
BigEndian=2
|
||||
);
|
||||
)
|
||||
|
||||
Endian getEndian();
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "std.h"
|
||||
#include "type_system/unitype.h"
|
||||
#include "type_system/type_system.h"
|
||||
|
||||
PACK_ENUM(ErrorId,
|
||||
PACKED_ENUM(ErrorId,
|
||||
SUCCESS, // not an error
|
||||
ERR_MAXLENGTH, ERR_WRONGTYPE, ERR_WRONGINDEX,
|
||||
ERR_NOTIMPLEMENTED, ERR_NULLPTR, ERR_ENDOFSTR,
|
||||
@@ -20,10 +20,10 @@ char* errname(ErrorId err);
|
||||
char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname);
|
||||
char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname);
|
||||
|
||||
typedef struct Maybe{
|
||||
STRUCT(Maybe,
|
||||
Unitype value;
|
||||
char* errmsg;
|
||||
} Maybe;
|
||||
)
|
||||
|
||||
// return it if func doesn't return anything
|
||||
// .value .errmsg
|
||||
@@ -42,47 +42,47 @@ void printMaybe(Maybe e);
|
||||
char* __doNothing(char* a);
|
||||
char* __unknownErr( );
|
||||
|
||||
#define __stringify_err(E) _Generic(\
|
||||
(E),\
|
||||
char*: __doNothing,\
|
||||
int: errname,\
|
||||
default: __unknownErr\
|
||||
#define __stringify_err(E) _Generic( \
|
||||
(E), \
|
||||
char*: __doNothing, \
|
||||
int: errname, \
|
||||
default: __unknownErr \
|
||||
)(E)
|
||||
|
||||
#if __cplusplus
|
||||
#define throw_id(E) __EXIT(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__)))
|
||||
#define throw_msg(E) __EXIT(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__)))
|
||||
|
||||
#define safethrow_id(E, FREEMEM) { FREEMEM;\
|
||||
__RETURN_EXCEPTION(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__)));\
|
||||
#define safethrow_id(E, FREEMEM) { FREEMEM; \
|
||||
__RETURN_EXCEPTION(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__))); \
|
||||
}
|
||||
#define safethrow_msg(E, FREEMEM) { FREEMEM;\
|
||||
__RETURN_EXCEPTION(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__)));\
|
||||
#define safethrow_msg(E, FREEMEM) { FREEMEM; \
|
||||
__RETURN_EXCEPTION(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__))); \
|
||||
}
|
||||
|
||||
#define try_cpp(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){\
|
||||
freeMem;\
|
||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__);\
|
||||
return _rezult;\
|
||||
#define try_cpp(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
|
||||
freeMem; \
|
||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
|
||||
return _rezult; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define throw(E) __EXIT(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__)))
|
||||
|
||||
#define safethrow(E, FREEMEM) { FREEMEM;\
|
||||
__RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__)));\
|
||||
#define safethrow(E, FREEMEM) { FREEMEM; \
|
||||
__RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); \
|
||||
}
|
||||
|
||||
#define try(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){\
|
||||
freeMem;\
|
||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__);\
|
||||
return _rezult;\
|
||||
#define try(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
|
||||
freeMem; \
|
||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
|
||||
return _rezult; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define tryLast(_funcCall, _rezult) Maybe _rezult=_funcCall; if(_rezult.errmsg){\
|
||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__);\
|
||||
__EXIT(_rezult.errmsg);\
|
||||
#define tryLast(_funcCall, _rezult) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
|
||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
|
||||
__EXIT(_rezult.errmsg); \
|
||||
}
|
||||
|
||||
#if __cplusplus
|
||||
|
||||
@@ -2,40 +2,40 @@
|
||||
|
||||
#include "std.h"
|
||||
|
||||
#define __optime_print(opname, t)\
|
||||
char tnames[3][3]={"s\0","ms","us"};\
|
||||
i32 tni=0;\
|
||||
if(t>1000000){\
|
||||
t/=1000000;\
|
||||
tni=0;\
|
||||
} else if(t>1000){\
|
||||
t/=1000;\
|
||||
tni=1;\
|
||||
} else tni=2;\
|
||||
kprintf("\e[93moperation \e[94m%s\e[93m lasted \e[94m%f \e[93m%s\n",\
|
||||
#define __optime_print(opname, t) \
|
||||
char tnames[3][3]={"s\0","ms","us"}; \
|
||||
i32 tni=0; \
|
||||
if(t>1000000){ \
|
||||
t/=1000000; \
|
||||
tni=0; \
|
||||
} else if(t>1000){ \
|
||||
t/=1000; \
|
||||
tni=1; \
|
||||
} else tni=2; \
|
||||
kprintf("\e[93moperation \e[94m%s\e[93m lasted \e[94m%f \e[93m%s\n", \
|
||||
opname, t, tnames[tni]);
|
||||
|
||||
#ifdef CLOCK_REALTIME
|
||||
/// executes codeblock and prints execution time
|
||||
/// u64 op_i is counter of the internal loop
|
||||
/// uses non-standard high-precision clock
|
||||
#define optime(opname,repeats,codeblock) ({\
|
||||
struct timespec start, stop;\
|
||||
clock_gettime(CLOCK_REALTIME, &start);\
|
||||
for(u64 op_i=0;op_i<(u64)repeats;op_i++)\
|
||||
(codeblock);\
|
||||
clock_gettime(CLOCK_REALTIME, &stop);\
|
||||
f64 t=(f64)(stop.tv_sec-start.tv_sec)*1000000+(f64)(stop.tv_nsec-start.tv_nsec)/1000;\
|
||||
__optime_print(opname,t)\
|
||||
#define optime(opname,repeats,codeblock) ({ \
|
||||
struct timespec start, stop; \
|
||||
clock_gettime(CLOCK_REALTIME, &start); \
|
||||
for(u64 op_i=0;op_i<(u64)repeats;op_i++) \
|
||||
(codeblock); \
|
||||
clock_gettime(CLOCK_REALTIME, &stop); \
|
||||
f64 t=(f64)(stop.tv_sec-start.tv_sec)*1000000+(f64)(stop.tv_nsec-start.tv_nsec)/1000; \
|
||||
__optime_print(opname,t) \
|
||||
})
|
||||
#else
|
||||
/// uses standard low precision clock
|
||||
#define optime(opname,repeats,codeblock) ({\
|
||||
clock_t start=clock();\
|
||||
for(u64 op_i=0;op_i<(u64)repeats;op_i++)\
|
||||
(codeblock);\
|
||||
clock_t stop=clock();\
|
||||
f64 t=(f64)(stop-start)/CLOCKS_PER_SEC*1000000;\
|
||||
__optime_print(opname,t)\
|
||||
#define optime(opname,repeats,codeblock) ({ \
|
||||
clock_t start=clock(); \
|
||||
for(u64 op_i=0;op_i<(u64)repeats;op_i++) \
|
||||
(codeblock); \
|
||||
clock_t stop=clock(); \
|
||||
f64 t=(f64)(stop-start)/CLOCKS_PER_SEC*1000000; \
|
||||
__optime_print(opname,t) \
|
||||
})
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@ typedef int64_t i64;
|
||||
typedef uint64_t u64;
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
typedef void* Pointer;
|
||||
|
||||
// Usually bool from stdbool.h is defined as macro,
|
||||
// so in other macros like ktid_##TYPE it will be replaced by _Bool.
|
||||
@@ -72,27 +73,27 @@ typedef u8 bool;
|
||||
#endif
|
||||
|
||||
|
||||
#define __count_args(\
|
||||
a0, a1, a2, a3, a4, a5, a6, a7 ,\
|
||||
a8, a9, a10,a11,a12,a13,a14,a15,\
|
||||
a16,a17,a18,a19,a20,a21,a22,a23,\
|
||||
a24,a25,a26,a27,a28,a29,a30,a31,\
|
||||
a32,a33,a34,a35,a36,a37,a38,a39,\
|
||||
a40,a41,a42,a43,a44,a45,a46,a47,\
|
||||
a48,a49,a50,a51,a52,a53,a54,a55,\
|
||||
a56,a57,a58,a59,a60,a61,a62,a63,\
|
||||
#define __count_args( \
|
||||
a0, a1, a2, a3, a4, a5, a6, a7 , \
|
||||
a8, a9, a10,a11,a12,a13,a14,a15, \
|
||||
a16,a17,a18,a19,a20,a21,a22,a23, \
|
||||
a24,a25,a26,a27,a28,a29,a30,a31, \
|
||||
a32,a33,a34,a35,a36,a37,a38,a39, \
|
||||
a40,a41,a42,a43,a44,a45,a46,a47, \
|
||||
a48,a49,a50,a51,a52,a53,a54,a55, \
|
||||
a56,a57,a58,a59,a60,a61,a62,a63, \
|
||||
a64,...) a64
|
||||
// Macro for counting variadic arguments (max 64)
|
||||
// (see usage in kprint.h)
|
||||
#define count_args(ARGS...) __count_args(\
|
||||
ARGS,\
|
||||
64,63,62,61,60,59,58,57,\
|
||||
56,55,54,53,52,51,50,49,\
|
||||
48,47,46,45,44,43,42,41,\
|
||||
40,39,38,37,36,35,34,33,\
|
||||
32,31,30,29,28,27,26,25,\
|
||||
24,23,22,21,20,19,18,17,\
|
||||
16,15,14,13,12,11,10,9,\
|
||||
#define count_args(ARGS...) __count_args( \
|
||||
ARGS, \
|
||||
64,63,62,61,60,59,58,57, \
|
||||
56,55,54,53,52,51,50,49, \
|
||||
48,47,46,45,44,43,42,41, \
|
||||
40,39,38,37,36,35,34,33, \
|
||||
32,31,30,29,28,27,26,25, \
|
||||
24,23,22,21,20,19,18,17, \
|
||||
16,15,14,13,12,11,10,9, \
|
||||
8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
|
||||
/*
|
||||
@@ -113,16 +114,12 @@ You can even embed it into macro in header (see kprint.h)
|
||||
#define PRAGMA_WARNING_POP _PRAGMA(GCC diagnostic pop)
|
||||
#define W_INT_CONVERSION "-Wint-conversion"
|
||||
#endif
|
||||
#define WARNING_DISABLE(WARNING, CODE)\
|
||||
PRAGMA_WARNING_PUSH\
|
||||
PRAGMA_WARNING_DISABLE(WARNING)\
|
||||
CODE;\
|
||||
#define WARNING_DISABLE(WARNING, CODE) \
|
||||
PRAGMA_WARNING_PUSH \
|
||||
PRAGMA_WARNING_DISABLE(WARNING) \
|
||||
CODE; \
|
||||
PRAGMA_WARNING_POP
|
||||
|
||||
#define PACK_ENUM(ENUM_NAME, ENUM_MEMBERS...) typedef enum ENUM_NAME {\
|
||||
ENUM_MEMBERS\
|
||||
} __attribute__((__packed__)) ENUM_NAME;
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -4,17 +4,21 @@ For using some kerep capabilities, such as generic structs, unitype, and kprint,
|
||||
|
||||
## type id
|
||||
|
||||
Every registered type has its own id (`ktid`), which should be declared in header file and defined in source file.
|
||||
Example:
|
||||
Every registered type has its own `ktDescriptor` and `ktid` is an index of the descriptor in descriptors array.
|
||||
Descriptor should be declared in header file.
|
||||
Following macro declares `typedef struct` and `ktDescriptor`
|
||||
```c
|
||||
//someStruct.h
|
||||
typedef struct { } someStruct;
|
||||
ktid_declare(someStruct);
|
||||
STRUCT(someStruct,
|
||||
i32 i; i32 j; i32 k;
|
||||
);
|
||||
```
|
||||
then you need to define descriptor in a source file
|
||||
```c
|
||||
//someStruct.c
|
||||
ktid_define(someStruct);
|
||||
kt_define(someStruct);
|
||||
```
|
||||
and register it.
|
||||
|
||||
## type descriptors
|
||||
|
||||
|
||||
@@ -2,18 +2,20 @@
|
||||
#include "../base.h"
|
||||
#include "../../kprint/kprint_format.h"
|
||||
|
||||
|
||||
// accepts char* (ptr to char) and char** (ptr to string)
|
||||
char* __toString_char(void* c, u32 fmt) {
|
||||
//*c=char
|
||||
// *c=char*
|
||||
if(kp_fmt_dataFormat(fmt)==kp_s){
|
||||
return cptr_copy(*(char**)c); // to avoid segmentation fault on free() when *c allocalet on stack
|
||||
}
|
||||
// *c=char
|
||||
if(kp_fmt_dataFormat(fmt)==kp_c){
|
||||
char* cc=malloc(2);
|
||||
cc[0]=*(char*)c;
|
||||
cc[1]=0;
|
||||
return cc;
|
||||
}
|
||||
// *c=cstring
|
||||
else if(kp_fmt_dataFormat(fmt)==kp_s){
|
||||
return cptr_copy(*(char**)c);
|
||||
}
|
||||
else throw(ERR_FORMAT);
|
||||
}
|
||||
|
||||
@@ -61,23 +63,23 @@ char* toString_u64(u64 n, bool withPostfix, bool uppercase){
|
||||
return cptr_copy((char*)str+i);
|
||||
}
|
||||
|
||||
#define _toString_float_impl(bufsize, maxPrecision) {\
|
||||
char str[bufsize];\
|
||||
if(precision>maxPrecision)\
|
||||
throw("too big precision");\
|
||||
if(precision==0)\
|
||||
precision=toString_float_default_precision;\
|
||||
i32 cn=IFMSC(\
|
||||
sprintf_s(str, bufsize, "%.*f", precision, n),\
|
||||
sprintf(str, "%.*f", precision, n)\
|
||||
);\
|
||||
/* remove trailing zeroes except .0*/\
|
||||
while(str[cn-1]=='0' && str[cn-2]!='.')\
|
||||
cn--;\
|
||||
if(withPostfix)\
|
||||
str[cn++]= uppercase ? 'F' : 'f';\
|
||||
str[cn]='\0';\
|
||||
return cptr_copy(str);\
|
||||
#define _toString_float_impl(bufsize, maxPrecision) { \
|
||||
char str[bufsize]; \
|
||||
if(precision>maxPrecision) \
|
||||
throw("too big precision"); \
|
||||
if(precision==0) \
|
||||
precision=toString_float_default_precision; \
|
||||
i32 cn=IFMSC( \
|
||||
sprintf_s(str, bufsize, "%.*f", precision, n), \
|
||||
sprintf(str, "%.*f", precision, n) \
|
||||
); \
|
||||
/* remove trailing zeroes except .0*/ \
|
||||
while(str[cn-1]=='0' && str[cn-2]!='.') \
|
||||
cn--; \
|
||||
if(withPostfix) \
|
||||
str[cn++]= uppercase ? 'F' : 'f'; \
|
||||
str[cn]='\0'; \
|
||||
return cptr_copy(str); \
|
||||
}
|
||||
|
||||
char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase)
|
||||
@@ -86,15 +88,15 @@ char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase)
|
||||
char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase)
|
||||
_toString_float_impl(512, toString_f64_max_precision)
|
||||
|
||||
#define byte_to_bits(byte) {\
|
||||
str[cn++]='0' + (u8)((byte>>7)&1); /* 8th bit */\
|
||||
str[cn++]='0' + (u8)((byte>>6)&1); /* 7th bit */\
|
||||
str[cn++]='0' + (u8)((byte>>5)&1); /* 6th bit */\
|
||||
str[cn++]='0' + (u8)((byte>>4)&1); /* 5th bit */\
|
||||
str[cn++]='0' + (u8)((byte>>3)&1); /* 4th bit */\
|
||||
str[cn++]='0' + (u8)((byte>>2)&1); /* 3th bit */\
|
||||
str[cn++]='0' + (u8)((byte>>1)&1); /* 2th bit */\
|
||||
str[cn++]='0' + (u8)((byte>>0)&1); /* 1th bit */\
|
||||
#define byte_to_bits(byte) { \
|
||||
str[cn++]='0' + (u8)((byte>>7)&1); /* 8th bit */ \
|
||||
str[cn++]='0' + (u8)((byte>>6)&1); /* 7th bit */ \
|
||||
str[cn++]='0' + (u8)((byte>>5)&1); /* 6th bit */ \
|
||||
str[cn++]='0' + (u8)((byte>>4)&1); /* 5th bit */ \
|
||||
str[cn++]='0' + (u8)((byte>>3)&1); /* 4th bit */ \
|
||||
str[cn++]='0' + (u8)((byte>>2)&1); /* 3th bit */ \
|
||||
str[cn++]='0' + (u8)((byte>>1)&1); /* 2th bit */ \
|
||||
str[cn++]='0' + (u8)((byte>>0)&1); /* 1th bit */ \
|
||||
}
|
||||
|
||||
char* toString_bin(void* _bytes, u32 size, bool inverse, bool withPrefix){
|
||||
@@ -163,60 +165,72 @@ char* toString_hex(void* _bytes, u32 size, bool inverse, bool withPrefix, bool u
|
||||
}
|
||||
|
||||
|
||||
#define __toString_i32_def(BITS) char* __toString_i##BITS(void* _n, u32 f){\
|
||||
switch(kp_fmt_dataFormat(f)){\
|
||||
case kp_i: ;\
|
||||
i##BITS n=*(i##BITS*)_n;\
|
||||
return toString_i64(n);\
|
||||
case kp_b:\
|
||||
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));\
|
||||
case kp_h:\
|
||||
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));\
|
||||
default:\
|
||||
kprintf("\n%u\n", kp_fmt_dataFormat(f));\
|
||||
throw(ERR_FORMAT);\
|
||||
return NULL;\
|
||||
}\
|
||||
#define __toString_i32_def(BITS) char* __toString_i##BITS(void* _n, u32 f){ \
|
||||
switch(kp_fmt_dataFormat(f)){ \
|
||||
case kp_i: ; \
|
||||
i##BITS n=*(i##BITS*)_n; \
|
||||
return toString_i64(n); \
|
||||
case kp_b: \
|
||||
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
|
||||
case kp_h: \
|
||||
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
|
||||
default: \
|
||||
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
|
||||
throw(ERR_FORMAT); \
|
||||
return NULL; \
|
||||
} \
|
||||
}
|
||||
__toString_i32_def(8)
|
||||
__toString_i32_def(16)
|
||||
__toString_i32_def(32)
|
||||
__toString_i32_def(64)
|
||||
|
||||
#define __toString_u_def(BITS) char* __toString_u##BITS(void* _n, u32 f){\
|
||||
switch(kp_fmt_dataFormat(f)){\
|
||||
case kp_u: ;\
|
||||
u##BITS n=*(u##BITS*)_n;\
|
||||
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));\
|
||||
case kp_b:\
|
||||
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));\
|
||||
case kp_h:\
|
||||
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));\
|
||||
default:\
|
||||
kprintf("\n%u\n", kp_fmt_dataFormat(f));\
|
||||
throw(ERR_FORMAT);\
|
||||
return NULL;\
|
||||
}\
|
||||
#define __toString_u_def(BITS) char* __toString_u##BITS(void* _n, u32 f){ \
|
||||
switch(kp_fmt_dataFormat(f)){ \
|
||||
case kp_u: ; \
|
||||
u##BITS n=*(u##BITS*)_n; \
|
||||
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
|
||||
case kp_b: \
|
||||
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
|
||||
case kp_h: \
|
||||
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
|
||||
default: \
|
||||
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
|
||||
throw(ERR_FORMAT); \
|
||||
return NULL; \
|
||||
} \
|
||||
}
|
||||
__toString_u_def(8)
|
||||
__toString_u_def(16)
|
||||
__toString_u_def(32)
|
||||
__toString_u_def(64)
|
||||
// __toString_u_def(64)
|
||||
char* __toString_u64(void* _n, u32 f){
|
||||
switch(kp_fmt_dataFormat(f)){
|
||||
case kp_u: ;
|
||||
u64 n=*(u64*)_n;
|
||||
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));
|
||||
case kp_b:
|
||||
return toString_bin(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));
|
||||
case kp_h:
|
||||
return toString_hex(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));
|
||||
default:
|
||||
kprintf("\n%u\n", kp_fmt_dataFormat(f)); throw(ERR_FORMAT); return NULL; }
|
||||
}
|
||||
|
||||
#define __toString_float_def(BITS) char* __toString_f##BITS(void* _n, u32 f){\
|
||||
switch(kp_fmt_dataFormat(f)){\
|
||||
case kp_f: ;\
|
||||
f##BITS n=*(f##BITS*)_n;\
|
||||
return toString_f64(n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));\
|
||||
case kp_b:\
|
||||
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));\
|
||||
case kp_h:\
|
||||
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));\
|
||||
default:\
|
||||
kprintf("\n%u\n", kp_fmt_dataFormat(f));\
|
||||
throw(ERR_FORMAT);\
|
||||
return NULL;\
|
||||
}\
|
||||
#define __toString_float_def(BITS) char* __toString_f##BITS(void* _n, u32 f){ \
|
||||
switch(kp_fmt_dataFormat(f)){ \
|
||||
case kp_f: ; \
|
||||
f##BITS n=*(f##BITS*)_n; \
|
||||
return toString_f64(n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
|
||||
case kp_b: \
|
||||
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
|
||||
case kp_h: \
|
||||
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
|
||||
default: \
|
||||
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
|
||||
throw(ERR_FORMAT); \
|
||||
return NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
__toString_float_def(32)
|
||||
|
||||
@@ -6,8 +6,8 @@ extern "C" {
|
||||
|
||||
#include "../errors.h"
|
||||
|
||||
// char and cstring
|
||||
// has different output for fmtChar and fmtString
|
||||
// accepts char* (ptr to char) and char** (ptr to string)
|
||||
// uses format kp_s and kp_c to determine what type is <c> argument
|
||||
char* __toString_char(void* c, u32 fmt);
|
||||
|
||||
// bool
|
||||
|
||||
@@ -4,85 +4,92 @@
|
||||
#include "../../SearchTree/SearchTree.h"
|
||||
#include "../../Hashtable/Hashtable.h"
|
||||
#include "../../String/StringBuilder.h"
|
||||
#include "../../Filesystem/filesystem.h"
|
||||
#include "base_toString.h"
|
||||
|
||||
void ktDescriptors_initKerepTypes(){
|
||||
// null
|
||||
__kt_register("Null", sizeof(NULL), NULL, NULL);
|
||||
ktid_Null=ktid_last;
|
||||
// base types
|
||||
kt_register(char, NULL, __toString_char);
|
||||
kt_register(bool, NULL, __toString_bool);
|
||||
kt_register(f32, NULL, __toString_f32);
|
||||
kt_register(f64, NULL, __toString_f64);
|
||||
kt_register(i8, NULL, __toString_i8);
|
||||
kt_register(u8, NULL, __toString_u8);
|
||||
kt_register(i16, NULL, __toString_i16);
|
||||
kt_register(u16, NULL, __toString_u16);
|
||||
kt_register(i32, NULL, __toString_i32);
|
||||
kt_register(u32, NULL, __toString_u32);
|
||||
kt_register(i64, NULL, __toString_i64);
|
||||
kt_register(u64, NULL, __toString_u64);
|
||||
kt_register(Pointer);
|
||||
if(ktid_Pointer!=0) // this can break UnitypeNull
|
||||
throw("ktid_Pointer!=0, you must init kerep types before any other types");
|
||||
|
||||
kt_register(char);
|
||||
kt_register(bool);
|
||||
kt_register(f32);
|
||||
kt_register(f64);
|
||||
kt_register(i8);
|
||||
kt_register(u8);
|
||||
kt_register(i16);
|
||||
kt_register(u16);
|
||||
kt_register(i32);
|
||||
kt_register(u32);
|
||||
kt_register(i64);
|
||||
kt_register(u64);
|
||||
|
||||
// ktDescriptor
|
||||
kt_register(ktDescriptor, NULL, NULL);
|
||||
|
||||
kt_register(ktDescriptor);
|
||||
|
||||
// base type arrays
|
||||
kt_register(Array_char, (freeMembers_t)Array_char_free, NULL);
|
||||
kt_register(Array_bool, (freeMembers_t)Array_bool_free, NULL);
|
||||
kt_register(Array_f32, (freeMembers_t)Array_f32_free, NULL);
|
||||
kt_register(Array_f64, (freeMembers_t)Array_f64_free, NULL);
|
||||
kt_register(Array_i8, (freeMembers_t)Array_i8_free, NULL);
|
||||
kt_register(Array_u8, (freeMembers_t)Array_u8_free, NULL);
|
||||
kt_register(Array_i16, (freeMembers_t)Array_i16_free, NULL);
|
||||
kt_register(Array_u16, (freeMembers_t)Array_u16_free, NULL);
|
||||
kt_register(Array_i32, (freeMembers_t)Array_i32_free, NULL);
|
||||
kt_register(Array_u32, (freeMembers_t)Array_u32_free, NULL);
|
||||
kt_register(Array_i64, (freeMembers_t)Array_i64_free, NULL);
|
||||
kt_register(Array_u64, (freeMembers_t)Array_u64_free, NULL);
|
||||
kt_register(Array_char);
|
||||
kt_register(Array_bool);
|
||||
kt_register(Array_f32);
|
||||
kt_register(Array_f64);
|
||||
kt_register(Array_i8);
|
||||
kt_register(Array_u8);
|
||||
kt_register(Array_i16);
|
||||
kt_register(Array_u16);
|
||||
kt_register(Array_i32);
|
||||
kt_register(Array_u32);
|
||||
kt_register(Array_i64);
|
||||
kt_register(Array_u64);
|
||||
kt_register(Array_Pointer);
|
||||
|
||||
// base type autoarrs
|
||||
kt_register(Autoarr_char, ____Autoarr_free_char, NULL);
|
||||
kt_register(Autoarr_bool, ____Autoarr_free_bool, NULL);
|
||||
kt_register(Autoarr_f32, ____Autoarr_free_f32, NULL);
|
||||
kt_register(Autoarr_f64, ____Autoarr_free_f64, NULL);
|
||||
kt_register(Autoarr_i8, ____Autoarr_free_i8, NULL);
|
||||
kt_register(Autoarr_u8, ____Autoarr_free_u8, NULL);
|
||||
kt_register(Autoarr_i16, ____Autoarr_free_i16, NULL);
|
||||
kt_register(Autoarr_u16, ____Autoarr_free_u16, NULL);
|
||||
kt_register(Autoarr_i32, ____Autoarr_free_i32, NULL);
|
||||
kt_register(Autoarr_u32, ____Autoarr_free_u32, NULL);
|
||||
kt_register(Autoarr_i64, ____Autoarr_free_i64, NULL);
|
||||
kt_register(Autoarr_u64, ____Autoarr_free_u64, NULL);
|
||||
kt_register(Autoarr_char);
|
||||
kt_register(Autoarr_bool);
|
||||
kt_register(Autoarr_f32);
|
||||
kt_register(Autoarr_f64);
|
||||
kt_register(Autoarr_i8);
|
||||
kt_register(Autoarr_u8);
|
||||
kt_register(Autoarr_i16);
|
||||
kt_register(Autoarr_u16);
|
||||
kt_register(Autoarr_i32);
|
||||
kt_register(Autoarr_u32);
|
||||
kt_register(Autoarr_i64);
|
||||
kt_register(Autoarr_u64);
|
||||
kt_register(Autoarr_Pointer);
|
||||
|
||||
// Unitype
|
||||
kt_register(Unitype, __UnitypePtr_free, NULL);
|
||||
kt_register(Array_Unitype, __Array_Unitype_free_, NULL);
|
||||
kt_register(Autoarr_Unitype, ____Autoarr_free_Unitype_, NULL);
|
||||
kt_register(Unitype);
|
||||
kt_register(Array_Unitype);
|
||||
kt_register(Autoarr_Unitype);
|
||||
// replacing autogenerated freear() function to custom
|
||||
Autoarr_Unitype* _uar=Autoarr_create(Unitype, 1, 1);
|
||||
_uar->functions->freear=__Autoarr_free_Unitype_;
|
||||
Autoarr_free(_uar, true);
|
||||
|
||||
// SearchTreeNode
|
||||
kt_register(STNode, __STNode_free, NULL);
|
||||
// STNode
|
||||
kt_register(STNode);
|
||||
|
||||
// KeyValuePair
|
||||
kt_register(KVPair, __KVPair_free, NULL);
|
||||
kt_register(Autoarr_KVPair, ____Autoarr_free_KVPair_, NULL);
|
||||
kt_register(KVPair);
|
||||
kt_register(Autoarr_KVPair);
|
||||
// replacing autogenerated freear() function to custom
|
||||
Autoarr_KVPair* _kvpar=Autoarr_create(KVPair, 1, 1);
|
||||
_kvpar->functions->freear=__Autoarr_free_KVPair_;
|
||||
Autoarr_free(_kvpar, true);
|
||||
|
||||
// Hashtable
|
||||
kt_register(Hashtable, __Hashtable_free, NULL);
|
||||
kt_register(Hashtable);
|
||||
|
||||
// string
|
||||
kt_register(string, NULL, NULL);
|
||||
kt_register(Array_string, (freeMembers_t)Array_string_free, NULL);
|
||||
kt_register(Autoarr_string, ____Autoarr_free_string, NULL);
|
||||
kt_register(string);
|
||||
kt_register(Array_string);
|
||||
kt_register(Autoarr_string);
|
||||
|
||||
// StringBuilder
|
||||
kt_register(StringBuilder, __StringBuilder_free, NULL);
|
||||
kt_register(StringBuilder);
|
||||
|
||||
//File
|
||||
kt_register(File);
|
||||
}
|
||||
|
||||
@@ -6,16 +6,40 @@ extern "C" {
|
||||
|
||||
#include "../std.h"
|
||||
#include "ktid.h"
|
||||
#include "typedef_macros.h"
|
||||
|
||||
#define kt_declare(TYPE)\
|
||||
ktid_declare(TYPE);\
|
||||
extern ktDescriptor ktDescriptor_##TYPE; \
|
||||
extern ktDescriptor ktDescriptor_##TYPE##_Ptr;
|
||||
|
||||
#define kt_define(TYPE, FREE_FUNC, TOSTRING_FUNC)\
|
||||
ktid_define(TYPE); \
|
||||
ktDescriptor ktDescriptor_##TYPE={ \
|
||||
.name=#TYPE, \
|
||||
.id=ktid_undefined, \
|
||||
.size=sizeof(TYPE), \
|
||||
.freeMembers=FREE_FUNC, \
|
||||
.toString=TOSTRING_FUNC \
|
||||
}; \
|
||||
ktDescriptor ktDescriptor_##TYPE##_Ptr={\
|
||||
.name=#TYPE "_Ptr", \
|
||||
.id=ktid_undefined, \
|
||||
.size=sizeof(TYPE), \
|
||||
.freeMembers=FREE_FUNC, \
|
||||
.toString=TOSTRING_FUNC \
|
||||
};
|
||||
|
||||
typedef void (*freeMembers_t)(void*);
|
||||
typedef char* (*toString_t)(void* obj, u32 fmt);
|
||||
typedef struct ktDescriptor{
|
||||
|
||||
STRUCT(ktDescriptor,
|
||||
char* name;
|
||||
ktid id;
|
||||
u16 size;
|
||||
freeMembers_t freeMembers; // NULL or function which frees all struct members
|
||||
toString_t toString; // NULL or function which generates string representaion of object
|
||||
} ktDescriptor;
|
||||
)
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,62 +1,57 @@
|
||||
#include "../../Autoarr/Autoarr.h"
|
||||
#include "type_system.h"
|
||||
#include "base_toString.h"
|
||||
|
||||
Autoarr_declare(ktDescriptor)
|
||||
Autoarr_define(ktDescriptor)
|
||||
kt_define(Pointer, free, __toString_u64);
|
||||
kt_define(char,NULL, __toString_char);
|
||||
kt_define(bool,NULL, __toString_bool);
|
||||
kt_define(f32, NULL, __toString_f32);
|
||||
kt_define(f64, NULL, __toString_f64);
|
||||
kt_define(i8, NULL, __toString_i8);
|
||||
kt_define(u8, NULL, __toString_u8);
|
||||
kt_define(i16, NULL, __toString_i16);
|
||||
kt_define(u16, NULL, __toString_u16);
|
||||
kt_define(i32, NULL, __toString_i32);
|
||||
kt_define(u32, NULL, __toString_u32);
|
||||
kt_define(i64, NULL, __toString_i64);
|
||||
kt_define(u64, NULL, __toString_u64);
|
||||
|
||||
ktid ktid_Null=-1;
|
||||
kt_define(ktDescriptor, NULL, NULL);
|
||||
|
||||
ktid_define(char);
|
||||
ktid_define(bool);
|
||||
ktid_define(f32);
|
||||
ktid_define(f64);
|
||||
ktid_define(i8);
|
||||
ktid_define(u8);
|
||||
ktid_define(i16);
|
||||
ktid_define(u16);
|
||||
ktid_define(i32);
|
||||
ktid_define(u32);
|
||||
ktid_define(i64);
|
||||
ktid_define(u64);
|
||||
|
||||
ktid_define(ktDescriptor);
|
||||
typedef ktDescriptor* ktDescriptor_Ptr;
|
||||
|
||||
// type descriptors are stored here during initialization
|
||||
Autoarr(ktDescriptor)* __ktDescriptors=NULL;
|
||||
Autoarr(Pointer)* __descriptorPointers=NULL;
|
||||
// here type descriptors are stored when initialization is complited
|
||||
ktDescriptor* typeDescriptors=NULL;
|
||||
ktDescriptor** typeDescriptors=NULL;
|
||||
ktid ktid_last=-1;
|
||||
|
||||
typedef enum{
|
||||
ENUM(ktDescriptorsState,
|
||||
NotInitialized, Initializing, Initialized
|
||||
} ktDescriptorsState;
|
||||
)
|
||||
ktDescriptorsState initState=NotInitialized;
|
||||
|
||||
void ktDescriptors_beginInit(){
|
||||
kprintf("\e[94mtype descriptors initializing...\n");
|
||||
__ktDescriptors=Autoarr_create(ktDescriptor, 256, 256);
|
||||
if(__ktDescriptors==NULL) throw(ERR_NULLPTR);
|
||||
__descriptorPointers=Autoarr_create(Pointer, 256, 256);
|
||||
if(__descriptorPointers==NULL)
|
||||
throw(ERR_NULLPTR);
|
||||
}
|
||||
|
||||
void ktDescriptors_endInit(){
|
||||
typeDescriptors=Autoarr_toArray(__ktDescriptors);
|
||||
Autoarr_free(__ktDescriptors,true);
|
||||
typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers);
|
||||
Autoarr_free(__descriptorPointers,true);
|
||||
if(typeDescriptors==NULL) throw(ERR_NULLPTR);
|
||||
kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
|
||||
}
|
||||
|
||||
void __kt_register(char* name, i16 size, void (*freeMembers)(void*), char* (*toString)(void*, u32)){
|
||||
ktDescriptor typeDesc={
|
||||
.name=name,
|
||||
.size=size,
|
||||
.id=++ktid_last,
|
||||
.freeMembers=freeMembers,
|
||||
.toString=toString
|
||||
};
|
||||
Autoarr_add(__ktDescriptors, typeDesc);
|
||||
void __kt_register(ktDescriptor* descriptor){
|
||||
descriptor->id=++ktid_last;
|
||||
Autoarr_add(__descriptorPointers, descriptor);
|
||||
}
|
||||
|
||||
ktDescriptor ktDescriptor_get(ktid id){
|
||||
if(id>ktid_last) {
|
||||
ktDescriptor* ktDescriptor_get(ktid id){
|
||||
if(id>ktid_last || id==ktid_undefined) {
|
||||
kprintf("\ntype id: %u\n",id);
|
||||
throw("invalid type id");
|
||||
}
|
||||
|
||||
@@ -9,39 +9,38 @@ extern "C" {
|
||||
#include "ktDescriptor.h"
|
||||
|
||||
extern ktid ktid_last;
|
||||
void __kt_register(char* name, i16 size, void (*freeMembers)(void*), char* (*toString)(void*, u32));
|
||||
void __kt_register(ktDescriptor* descriptor);
|
||||
|
||||
#define kt_register(TYPE, FREE_MEMBERS_FUNC, TO_STRING_FUNC)\
|
||||
__kt_register(#TYPE, sizeof(TYPE), FREE_MEMBERS_FUNC, TO_STRING_FUNC);\
|
||||
ktid_##TYPE=ktid_last;\
|
||||
__kt_register(#TYPE "*", sizeof(TYPE), FREE_MEMBERS_FUNC, TO_STRING_FUNC);\
|
||||
#define kt_register(TYPE) \
|
||||
__kt_register(&ktDescriptor_##TYPE); \
|
||||
ktid_##TYPE=ktid_last; \
|
||||
__kt_register(&ktDescriptor_##TYPE##_Ptr); \
|
||||
ktid_##TYPE##_Ptr=ktid_last;
|
||||
|
||||
void ktDescriptors_beginInit();
|
||||
void ktDescriptors_endInit();
|
||||
|
||||
/// @param id id of registered type
|
||||
ktDescriptor ktDescriptor_get(ktid id);
|
||||
ktDescriptor* ktDescriptor_get(ktid id);
|
||||
|
||||
// call it to free heap-allocated ktDescriptors array
|
||||
void ktDescriptors_free();
|
||||
|
||||
extern ktid ktid_Null;
|
||||
kt_declare(Pointer);
|
||||
kt_declare(char);
|
||||
kt_declare(bool);
|
||||
kt_declare(f32);
|
||||
kt_declare(f64);
|
||||
kt_declare(i8);
|
||||
kt_declare(u8);
|
||||
kt_declare(i16);
|
||||
kt_declare(u16);
|
||||
kt_declare(i32);
|
||||
kt_declare(u32);
|
||||
kt_declare(i64);
|
||||
kt_declare(u64);
|
||||
|
||||
ktid_declare(char);
|
||||
ktid_declare(bool);
|
||||
ktid_declare(f32);
|
||||
ktid_declare(f64);
|
||||
ktid_declare(i8);
|
||||
ktid_declare(u8);
|
||||
ktid_declare(i16);
|
||||
ktid_declare(u16);
|
||||
ktid_declare(i32);
|
||||
ktid_declare(u32);
|
||||
ktid_declare(i64);
|
||||
ktid_declare(u64);
|
||||
|
||||
ktid_declare(ktDescriptor);
|
||||
kt_declare(ktDescriptor);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
|
||||
@@ -5,17 +5,20 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../std.h"
|
||||
#include "typedef_macros.h"
|
||||
|
||||
typedef u16 ktid;
|
||||
static const ktid ktid_undefined=-1;
|
||||
|
||||
#define ktid_name(TYPE) ktid_##TYPE
|
||||
#define ktid_ptrName(TYPE) ktid_##TYPE##_Ptr
|
||||
|
||||
#define ktid_declare(TYPE)\
|
||||
extern ktid ktid_##TYPE;\
|
||||
#define ktid_declare(TYPE) \
|
||||
extern ktid ktid_##TYPE; \
|
||||
extern ktid ktid_##TYPE##_Ptr;
|
||||
|
||||
#define ktid_define(TYPE)\
|
||||
ktid ktid_##TYPE=-1;\
|
||||
#define ktid_define(TYPE) \
|
||||
ktid ktid_##TYPE=-1; \
|
||||
ktid ktid_##TYPE##_Ptr=-1;
|
||||
|
||||
#if __cplusplus
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "init.h"
|
||||
#include "ktid.h"
|
||||
#include "ktDescriptor.h"
|
||||
#include "kt_functions.h"
|
||||
#include "unitype.h"
|
||||
#include "typedef_macros.h"
|
||||
|
||||
14
src/base/type_system/typedef_macros.h
Normal file
14
src/base/type_system/typedef_macros.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#define ENUM(ENUM_NAME, ENUM_MEMBERS...) typedef enum ENUM_NAME { \
|
||||
ENUM_MEMBERS \
|
||||
} ENUM_NAME;
|
||||
|
||||
#define PACKED_ENUM(ENUM_NAME, ENUM_MEMBERS...) typedef enum ENUM_NAME { \
|
||||
ENUM_MEMBERS \
|
||||
} __attribute__((__packed__)) ENUM_NAME;
|
||||
|
||||
#define STRUCT(STRUCT_NAME, STRUCT_MEMBERS...) typedef struct STRUCT_NAME { \
|
||||
STRUCT_MEMBERS \
|
||||
} STRUCT_NAME; \
|
||||
kt_declare(STRUCT_NAME);
|
||||
@@ -1,52 +1,90 @@
|
||||
#include "../base.h"
|
||||
#include "../../kprint/kprint_format.h"
|
||||
|
||||
ktid_define(Unitype);
|
||||
|
||||
char* __Unitype_toString(void* _u, u32 fmt){
|
||||
return Unitype_toString(*(Unitype*)_u, fmt);
|
||||
}
|
||||
|
||||
kt_define(Unitype, __UnitypePtr_free, __Unitype_toString);
|
||||
|
||||
void Unitype_free(Unitype u){
|
||||
ktDescriptor type=ktDescriptor_get(u.typeId);
|
||||
if(type.freeMembers)
|
||||
type.freeMembers(u.VoidPtr);
|
||||
if(u.typeId==ktid_undefined){
|
||||
if(u.VoidPtr!=NULL)
|
||||
throw("unitype with undefined typeId has value");
|
||||
return;
|
||||
}
|
||||
|
||||
ktDescriptor* type=ktDescriptor_get(u.typeId);
|
||||
if(type->freeMembers)
|
||||
type->freeMembers(u.VoidPtr);
|
||||
if(u.allocatedInHeap)
|
||||
free(u.VoidPtr);
|
||||
}
|
||||
void __UnitypePtr_free(void* u) { Unitype_free(*(Unitype*)u); }
|
||||
|
||||
char* toString_Unitype(void* _u, u32 fmt){
|
||||
Unitype* u=_u;
|
||||
ktDescriptor type=ktDescriptor_get(u->typeId);
|
||||
char* valuestr=type.toString(_u, fmt);
|
||||
char* rezult=cptr_concat("{ type: ", type.name,
|
||||
", allocated on heap: ", (u->allocatedInHeap ? "true" : "false"),
|
||||
|
||||
char* Unitype_toString(Unitype u, u32 fmt){
|
||||
if(u.typeId==ktid_undefined){
|
||||
if(u.VoidPtr!=NULL)
|
||||
throw("unitype with undefined typeId has value");
|
||||
return cptr_copy("{ERROR_TYPE}");
|
||||
}
|
||||
|
||||
if(fmt==0) {
|
||||
if(u.typeId==ktid_name(bool) ||
|
||||
u.typeId==ktid_name(i8) || u.typeId==ktid_name(i16) ||
|
||||
u.typeId==ktid_name(i32) || u.typeId==ktid_name(i64)){
|
||||
// auto format set
|
||||
fmt=kp_i;
|
||||
// replaces value with pointer to value to pass into toString_i64(void*, u32)
|
||||
i64 value=u.Int64;
|
||||
u.VoidPtr=&value;
|
||||
}
|
||||
else if(u.typeId==ktid_name(u8) || u.typeId==ktid_name(u16) ||
|
||||
u.typeId==ktid_name(u32) || u.typeId==ktid_name(u64)){
|
||||
fmt=kp_u;
|
||||
u64 value=u.UInt64;
|
||||
u.VoidPtr=&value;
|
||||
}
|
||||
else if(u.typeId==ktid_name(f32) || u.typeId==ktid_name(f64)){
|
||||
fmt=kp_f;
|
||||
f64 value=u.Float64;
|
||||
u.VoidPtr=&value;
|
||||
}
|
||||
else if(u.typeId==ktid_name(char)){
|
||||
fmt=kp_c;
|
||||
i64 value=u.Int64;
|
||||
u.VoidPtr=&value;
|
||||
}
|
||||
else if(u.typeId==ktid_ptrName(char)){
|
||||
char* value=u.VoidPtr;
|
||||
u.VoidPtr=&value;
|
||||
fmt=kp_s;
|
||||
}
|
||||
else if(u.typeId==ktid_name(Pointer)){
|
||||
if(u.VoidPtr==NULL)
|
||||
return cptr_copy("{ UniNull }");
|
||||
fmt=kp_h;
|
||||
}
|
||||
}
|
||||
|
||||
ktDescriptor* type=ktDescriptor_get(u.typeId);
|
||||
char* valuestr;
|
||||
if(type->toString)
|
||||
valuestr=type->toString(u.VoidPtr, fmt);
|
||||
else valuestr="ERR_NO_TOSTRING_FUNC";
|
||||
char* rezult=cptr_concat("{ type: ", type->name,
|
||||
", allocated on heap: ", (u.allocatedInHeap ? "true" : "false"),
|
||||
", value:", valuestr, " }");
|
||||
free(valuestr);
|
||||
if(type->toString)
|
||||
free(valuestr);
|
||||
return rezult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define BUFSIZE 64
|
||||
char* sprintuni(Unitype v){
|
||||
char* buf=malloc(BUFSIZE);
|
||||
ktDescriptor type=ktDescriptor_get(v.typeId);
|
||||
if(v.typeId==ktid_Null)
|
||||
sprintf_s(buf, BUFSIZE, "{Null}");
|
||||
else if(v.typeId==ktid_name(f64))
|
||||
sprintf_s(buf, BUFSIZE, "{%s : %lf}", type.name,v.Float64);
|
||||
else if(v.typeId==ktid_name(bool) || v.typeId==ktid_name(u64))
|
||||
sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%llu", "%lu") "}", type.name,v.UInt64);
|
||||
else if(v.typeId==ktid_name(i64))
|
||||
sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%lld", "%ld") "}", type.name,v.Int64);
|
||||
else if(v.typeId==ktid_ptrName(char)){
|
||||
size_t newBUFSIZE=cptr_length(v.VoidPtr) + BUFSIZE/2;
|
||||
buf=realloc(buf, newBUFSIZE);
|
||||
sprintf_s(buf, BUFSIZE, "{%s : \"%s\"}", type.name,(char*)v.VoidPtr);
|
||||
}
|
||||
else sprintf_s(buf, BUFSIZE, "{%s : %p}", type.name,v.VoidPtr);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void printuni(Unitype v){
|
||||
char* s=sprintuni(v);
|
||||
char* s=Unitype_toString(v,0);
|
||||
fputs(s, stdout);
|
||||
fputc('\n',stdout);
|
||||
free(s);
|
||||
}
|
||||
@@ -5,8 +5,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ktid.h"
|
||||
#include "typedef_macros.h"
|
||||
|
||||
typedef struct Unitype{
|
||||
STRUCT(Unitype,
|
||||
union {
|
||||
i64 Int64;
|
||||
u64 UInt64;
|
||||
@@ -17,11 +18,10 @@ typedef struct Unitype{
|
||||
};
|
||||
ktid typeId;
|
||||
bool allocatedInHeap; // should Unitype_free call free() to VoidPtr*
|
||||
} Unitype;
|
||||
ktid_declare(Unitype);
|
||||
)
|
||||
|
||||
|
||||
#define __UniDef(FIELD, TYPE, VAL) (Unitype){\
|
||||
#define __UniDef(FIELD, TYPE, VAL) (Unitype){ \
|
||||
.FIELD=VAL, .typeId=ktid_name(TYPE), .allocatedInHeap=false}
|
||||
|
||||
#define UniInt64(VAL) __UniDef(Int64, i64, VAL)
|
||||
@@ -29,20 +29,23 @@ ktid_declare(Unitype);
|
||||
#define UniFloat64(VAL) __UniDef(Float64, f64, VAL)
|
||||
#define UniBool(VAL) __UniDef(Bool, bool, VAL)
|
||||
|
||||
#define UniStackPtr(TYPE, VAL) (Unitype){\
|
||||
#define UniStackPtr(TYPE, VAL) (Unitype){ \
|
||||
.VoidPtr=VAL, .typeId=ktid_ptrName(TYPE), .allocatedInHeap=false}
|
||||
#define UniHeapPtr(TYPE, VAL) (Unitype){\
|
||||
#define UniHeapPtr(TYPE, VAL) (Unitype){ \
|
||||
.VoidPtr=VAL, .typeId=ktid_ptrName(TYPE), .allocatedInHeap=true}
|
||||
|
||||
#define UniNull (Unitype){.Int64=0, .typeId=ktid_Null, .allocatedInHeap=false}
|
||||
// 0==ktid_Pointer
|
||||
#define UniNull (Unitype){.Int64=0, .typeId=0, .allocatedInHeap=false}
|
||||
#define UniTrue UniBool(true)
|
||||
#define UniFalse UniBool(false)
|
||||
|
||||
#define Unitype_isUniNull(UNI) (UNI.typeId==ktid_Pointer && UNI.VoidPtr==NULL)
|
||||
|
||||
// frees VoidPtr value or does nothing if type isn't pointer
|
||||
void Unitype_free(Unitype u);
|
||||
void __UnitypePtr_free(void* u);
|
||||
char* Unitype_toString(Unitype v, u32 fmt);
|
||||
void printuni(Unitype v);
|
||||
char* sprintuni(Unitype v);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user