/src/util/type.c
https://gitlab.com/CoyoteLang/compiler · C · 333 lines · 305 code · 16 blank · 12 comment · 39 complexity · c35c9f1821fe6e5b7725ef64caa057fe MD5 · raw file
- #include <util/type.h>
- #include <assert.h>
- // for type_get_by_name
- #include <string.h>
- // <DEBUG ONLY>
- #include <stdio.h>
- // </DEBUG ONLY>
- Type Tvoid = { TF_VOID };
- Type Tbool = { TF_BOOLEAN, { .uboolean = { 1, 1 } } };
- Type Tbyte = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 1, COY_TRUE } } },
- Tubyte = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 1, COY_FALSE } } };
- Type Tshort = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 2, COY_TRUE } } },
- Tushort = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 2, COY_FALSE } } };
- Type Tint = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 4, COY_TRUE } } },
- Tuint = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 4, COY_FALSE } } };
- Type Tlong = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 8, COY_TRUE } } },
- Tulong = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 8, COY_FALSE } } };
- //Type Tcent = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 16, COY_TRUE } } },
- // Tucent = { TF_INTEGER, { .uinteger = { 1, 1, COMPLEX_REAL, 16, COY_FALSE } } };
- Type Tfloat = { TF_REAL, { .ureal = { 1, 1, COMPLEX_REAL, 4 } } },
- Tdouble = { TF_REAL, { .ureal = { 1, 1, COMPLEX_REAL, 8 } } },
- Treal = { TF_REAL, { .ureal = { 1, 1, COMPLEX_REAL, 255 } } };
- Type Tchar = { TF_CHARACTER, { .ucharacter = { 1 } } },
- Twchar = { TF_CHARACTER, { .ucharacter = { 2 } } },
- Tdchar = { TF_CHARACTER, { .ucharacter = { 4 } } };
- Type Tstring = { TF_STRING, { .ustring = { &Tchar } } },
- Twstring = { TF_STRING, { .ustring = { &Twchar } } },
- Tdstring = { TF_STRING, { .ustring = { &Tdchar } } };
- Type Tmixed = { TF_MIXED };
- // unknowns
- Type TstringU = { TF_STRING, { .ustring = { NULL } } };
- // internals
- Type Ttype = { TF_TYPE };
- Type* type_get_by_name(const char* name)
- {
- #define GET(NAME) if(!strcmp(name, #NAME)) return &T##NAME
- GET(void);
- GET(bool);
- GET(byte); GET(ubyte);
- GET(short); GET(ushort);
- GET(int); GET(uint);
- GET(long); GET(ulong);
- //GET(cent); GET(ucent);
- GET(float); GET(double); GET(real);
- GET(char); GET(wchar); GET(dchar);
- GET(mixed);
- return NULL;
- }
- static COYusize type__complex_multiplier(TypeComplex com)
- {
- switch(com)
- {
- case COMPLEX_REAL:
- case COMPLEX_IMAG: return 1;
- case COMPLEX_COMPLEX: return 2;
- case COMPLEX_QUATERNION: return 4;
- }
- assert(0 && "Internal error: invalid type__complex_multiplier()");
- return 0;
- }
- COYusize type_sizeof(const Type* type)
- {
- switch(type->family)
- {
- case TF_VOID: return 0;
- case TF_BOOLEAN: return type->u.uboolean.dimx * type->u.uboolean.dimy;
- case TF_INTEGER: return type->u.uinteger.dimx * type->u.uinteger.dimy * type__complex_multiplier(type->u.uinteger.com) * type->u.uinteger.width;
- case TF_REAL: return type->u.ureal.dimx * type->u.ureal.dimy * type__complex_multiplier(type->u.ureal.com) * (type->u.ureal.width == Treal.u.ureal.width ? sizeof(COYreal) : type->u.ureal.width);
- case TF_CHARACTER: return type->u.ucharacter.width;
- case TF_STRUCT: assert(0 && "TODO: struct.sizeof"); return 0;
- case TF_CLASS:
- case TF_ARRAY:
- case TF_STRING:
- case TF_DICT:
- case TF_SET:
- case TF_OPTION:
- case TF_DELEGATE: return sizeof(void*);
- case TF_MIXED:
- case TF_TYPE: assert(0 && "Internal error: illegal type_sizeof() type"); return 0;
- }
- assert(0 && "Internal error: invalid type_sizeof()");
- return 0;
- }
- COYbool type_isnum(const Type* type)
- {
- switch(type->family)
- {
- case TF_BOOLEAN:
- case TF_INTEGER:
- case TF_REAL:
- case TF_CHARACTER:
- return COY_TRUE;
- case TF_VOID:
- case TF_STRUCT:
- case TF_CLASS:
- case TF_ARRAY:
- case TF_STRING:
- case TF_DICT:
- case TF_SET:
- case TF_DELEGATE:
- case TF_OPTION:
- case TF_MIXED:
- return COY_FALSE;
- case TF_TYPE:
- assert(0 && "Attempted to use isnum() on a type");
- }
- assert(0);
- return COY_FALSE;
- }
- COYbool type_isref(const Type* type)
- {
- switch(type->family)
- {
- case TF_VOID:
- case TF_BOOLEAN:
- case TF_INTEGER:
- case TF_REAL:
- case TF_CHARACTER:
- case TF_STRUCT:
- return COY_FALSE;
- case TF_CLASS:
- /*case TF_ARRAY:
- case TF_STRING:
- case TF_DICT:
- case TF_SET:*/
- case TF_DELEGATE:
- case TF_OPTION:
- case TF_MIXED:
- return COY_TRUE;
- case TF_ARRAY:
- case TF_STRING:
- case TF_DICT:
- case TF_SET:
- assert(0 && "TODO isref for ARRAY|STRING|DICT|SET");
- case TF_TYPE:
- assert(0 && "Attempted to use isref() on a type");
- }
- assert(0);
- return COY_FALSE;
- }
- static void type_dumpDBG_complex(TypeComplex com);
- static void type_dumpDBG_dim(COYubyte dimx, COYubyte dimy);
- static void type_dumpDBG_list(Type* const* items, COYuint nitems, const char* sep);
- static void type_dumpDBG_name(const Type* type);
- static void type_dumpDBG_complex(TypeComplex com)
- {
- switch(com)
- {
- case COMPLEX_REAL: break;
- case COMPLEX_IMAG: printf("i"); break;
- case COMPLEX_COMPLEX: printf("c"); break;
- case COMPLEX_QUATERNION: printf("q"); break;
- }
- }
- static void type_dumpDBG_dim(COYubyte dimx, COYubyte dimy)
- {
- if(dimx) printf("%u", dimx);
- if(dimy) printf("x%u", dimy);
- }
- static void type_dumpDBG_list(Type* const* items, COYuint nitems, const char* sep)
- {
- if(!sep) sep = "";
- COYuint i;
- for(i = 0; i < nitems; i++)
- {
- if(i) printf("%s", sep);
- type_dumpDBG_name(items[i]);
- }
- }
- static void type_dumpDBG_name(const Type* type)
- {
- if(!type)
- {
- printf("<null>");
- return;
- }
- switch(type->family)
- {
- case TF_VOID:
- printf("void");
- return;
- case TF_BOOLEAN:
- printf("bool");
- type_dumpDBG_dim(type->u.uboolean.dimx, type->u.uboolean.dimy);
- return;
- case TF_INTEGER:
- type_dumpDBG_complex(type->u.uinteger.com);
- if(!type->u.uinteger.is_signed) printf("u");
- switch(type->u.uinteger.width)
- {
- case 1: printf("byte"); break;
- case 2: printf("short"); break;
- case 4: printf("int"); break;
- case 8: printf("long"); break;
- default: assert(0);
- }
- type_dumpDBG_dim(type->u.uinteger.dimx, type->u.uinteger.dimy);
- return;
- case TF_REAL:
- type_dumpDBG_complex(type->u.ureal.com);
- switch(type->u.ureal.width)
- {
- case 4: printf("float"); break;
- case 8: printf("double"); break;
- case 16: printf("real"); break;
- default: assert(0);
- }
- type_dumpDBG_dim(type->u.ureal.dimx, type->u.ureal.dimy);
- return;
- case TF_CHARACTER:
- switch(type->u.ucharacter.width)
- {
- case 1: printf("char"); break;
- case 2: printf("wchar"); break;
- case 4: printf("dchar"); break;
- default: assert(0);
- }
- return;
- case TF_STRUCT:
- printf("struct %.*s", (int)type->u.ustruct.name->len, type->u.ustruct.name->ptr);
- return;
- case TF_CLASS:
- printf("class %.*s", (int)type->u.ustruct.name->len, type->u.ustruct.name->ptr);
- return;
- case TF_ARRAY:
- type_dumpDBG_name(type->u.uarray.val);
- printf("[]");
- return;
- case TF_STRING:
- if(type->u.ustring.val == &Tchar)
- printf("c");
- else if(type->u.ustring.val == &Twchar)
- printf("w");
- else if(type->u.ustring.val == &Tdchar)
- printf("d");
- else if(!type->u.ustring.val)
- printf("_");
- else
- assert(0);
- printf("string");
- return;
- case TF_DICT:
- type_dumpDBG_name(type->u.udict.val);
- printf("[");
- type_dumpDBG_name(type->u.udict.key);
- printf("]");
- return;
- case TF_SET:
- printf("set[");
- type_dumpDBG_name(type->u.uset.key);
- printf("]");
- return;
- case TF_DELEGATE:
- printf("delegate ");
- type_dumpDBG_name(type->u.udelegate.ret);
- printf("(");
- type_dumpDBG_list(type->u.udelegate.params, type->u.udelegate.nparams, ",");
- if(type->u.udelegate.has_varargs) printf("...");
- printf(")");
- return;
- case TF_OPTION:
- type_dumpDBG_name(type->u.uoption.base);
- printf("?");
- return;
- case TF_MIXED:
- printf("mixed");
- return;
- case TF_TYPE:
- printf("<type>");
- return;
- }
- assert(0);
- }
- void type_dumpDBG(const Type* type)
- {
- if(!type)
- {
- printf("<null>");
- return;
- }
- switch(type->family)
- {
- case TF_VOID:
- case TF_BOOLEAN:
- case TF_INTEGER:
- case TF_REAL:
- case TF_CHARACTER:
- case TF_ARRAY:
- case TF_STRING:
- case TF_DICT:
- case TF_SET:
- case TF_DELEGATE:
- case TF_OPTION:
- case TF_MIXED:
- case TF_TYPE:
- type_dumpDBG_name(type);
- return;
- case TF_STRUCT:
- type_dumpDBG_name(type);
- printf("{");
- type_dumpDBG_list(type->u.ustruct.fields, type->u.ustruct.nfields, ";");
- printf("}");
- return;
- case TF_CLASS:
- type_dumpDBG_name(type);
- if(type->u.uclass.ninherits)
- {
- printf(":");
- type_dumpDBG_list(type->u.uclass.inherits, type->u.uclass.ninherits, ",");
- }
- printf("{");
- type_dumpDBG_list(type->u.uclass.fields, type->u.uclass.nfields, ";");
- printf("}");
- return;
- }
- assert(0);
- }