/src/core/type.h
https://github.com/jojoin/Def · C Header · 360 lines · 281 code · 54 blank · 25 comment · 28 complexity · 3e7a4f6ae2567b03ecbc470361097b3c MD5 · raw file
- #pragma once
- /**
- * Def ¶ÔÏóÀàÐÍ
- */
- #include <iostream>
- #include <string>
- #include <vector>
- #include <map>
- #include "../global.h"
- #include "./splitfix.h"
- #include "../util/str.h"
- // def µÄÔ×ÓÀàÐÍÁбí
- #define DEF_AOTM_TYPE_LIST(T) \
- T(Nil) \
- T(Bool) \
- T(Int) \
- T(Float) \
- T(Char) \
- T(String) \
- // T(Quote) /* ÒýÓÃ */ \
- namespace def {
- namespace core {
-
- using namespace std;
- using namespace def::util;
- /**
- * Def ¶ÔÏóÀàÐÍ
- */
- struct Type
- {
- virtual string str() = 0; // ×Ö·û´®±íʾ
- virtual void set(Type*) {}; // ÉèÖÃ type
- virtual void add(Type*) {}; // Ôö¼Ó type
- virtual size_t len() { return 1; }; // type ³¤¶È
- virtual Type* copy(const string& n="") { // ¿½±´ type
- return nullptr;
- };
- virtual bool is(Type*t) = 0; // ÅжÏÁ½¸ö¶ÔÏóÊÇ·ñÏàµÈ
- virtual bool isAtomType() = 0; // ÊÇ·ñΪÔ×ÓÀàÐÍ
- virtual string getIdentify(bool strict=true) { // »ñµÃΨһ±êʶ
- return str();
- }
- // static function
- static map<string, Type*> types; // »º´æµÄÔ×ÓÀàÐÍ
- static Type* get(const string &);
- };
- // Ô×ÓÀàÐÍ
- #define ATOM_TYPE(N) \
- struct Type##N : Type \
- { \
- virtual bool isAtomType(){ return true; } \
- virtual string str() { \
- return #N; \
- } \
- virtual bool is(Type*t){ /* Ô×ÓÀàÐͲÉÓÃÔËÐÐʱÅÐ¶Ï */ \
- return dynamic_cast<Type##N*>(t); \
- } \
- };
- #define AT(T) ATOM_TYPE(T)
- DEF_AOTM_TYPE_LIST(AT)
- #undef AT
- #undef AOTM_TYPE
- // À©Õ¹ÀàÐÍ
- #define NOATOM_TYPE(N) \
- struct Type##N : Type \
- { \
- virtual bool isAtomType() { return false; };
- #define TYPE_POND(T) \
- /* Ö¸ÕëÀàÐÍ³Ø */ \
- static map<int, Type##T*> typtrs; \
- static Type##T* get(Type*t) { \
- int adr = (int)t; \
- auto it = typtrs.find(adr); \
- if (it != typtrs.end()) { \
- return it->second; \
- } else { \
- auto tar = new Type##T(t); \
- typtrs.insert(pair<int,Type##T*>(adr,tar)); \
- return tar; \
- } \
- } \
- // Ö¸ÕëÀàÐÍ
- // ½ö¹©ÄÚ²¿±àÒëÆ÷ʵÏÖʹÓÃ
- // ±íÏÖ´Ó¶ÑÉÏ·ÖÅäµÄ¶ÔÏó
- NOATOM_TYPE(Pointer)
- Type* type = nullptr; // ÒýÓÃÖµµÄÀàÐÍ
- TypePointer(Type*t)
- : type(t)
- {}
- virtual string str() {
- return getIdentify();
- }
- virtual string getIdentify(bool strict=true) { // »ñµÃΨһ±êʶ
- return "*" + type->getIdentify(strict);
- }
- virtual bool is(Type*t){
- if (auto *ty = dynamic_cast<TypePointer*>(t)) {
- return type->is(ty->type); // Ö¸ÏòÀàÐÍÒ»ÖÂ
- }
- return false;
- }
- // ÀàÐͳØ
- TYPE_POND(Pointer)
- };
- // ÒýÓÃÀàÐÍ
- NOATOM_TYPE(Refer)
- // size_t len;
- Type* type = nullptr; // ÒýÓÃÖµµÄÀàÐÍ
- TypeRefer(Type*t)
- : type(t)
- {}
- virtual bool is(Type*t){
- if (auto *ty = dynamic_cast<TypeRefer*>(t)) {
- return ty->type->is(type); // ÒýÓÃÀàÐÍÒ»ÖÂ
- }
- return false;
- }
- virtual void set(Type* t) { // Ôö¼Ó type
- type = t;
- }
- virtual string str() {
- return getIdentify();
- }
- virtual string getIdentify(bool strict=true) { // »ñµÃΨһ±êʶ
- return "~" + type->getIdentify(strict);
- }
- // ÀàÐͳØ
- TYPE_POND(Refer)
- };
- // Êý×éÀàÐÍ
- NOATOM_TYPE(Array)
- size_t len;
- Type* type;
- TypeArray(Type*t, size_t l=0)
- : type(t)
- , len(l)
- {}
- virtual string str() {
- return getIdentify();
- }
- virtual string getIdentify(bool strict=true) {
- // »ñµÃΨһ±êʶ£¬strict ±íʾ´óСҲ±ØÐëÏàµÈ
- return "["
- + (strict ? Str::l2s(len) + "x" : "")
- + type->getIdentify(strict)
- + "]";
- }
- virtual void set(Type* t) { // Ôö¼Ó type
- type = t;
- }
- virtual bool is(Type*t){
- if (auto *ty = dynamic_cast<TypeArray*>(t)) {
- return ty->type->is(type); // Êý×éÀàÐÍÒ»ÖÂ
- }
- return false;
- }
- // ÀàÐͳØ
- TYPE_POND(Array)
- };
- // À©Õ¹ÀàÐÍ
- #define EXTEND_TYPE(N,P) \
- struct Type##N : P \
- { \
- virtual bool isAtomType() { return false; };
- // ½á¹¹ÀàÐÍ
- EXTEND_TYPE(Struct, Type)
- long idx = 0;
- static long auto_idx; // ×ÔÔöΨһ±êʶ£¡£¡£¡
- string name; // ÀàÃû³Æ
- vector<string> tabs; // ×ÓÀà±êʶ·û
- vector<Type*> types; // ×ÓÀàÁбí
- TypeStruct(const string&n)
- : name(n) {
- // cout << "TypeStruct(const string&n)"<< n << endl;
- }
- void increment() {
- idx = ++auto_idx;
- }
- virtual bool is(Type*t){ // À©Õ¹ÀàÐÍÖ±½Ó¶Ô±ÈµØÖ·
- if(name!=""){
- return !!( ((int)this)==((int)t) );
- }
- if(auto*sctty=dynamic_cast<TypeStruct*>(t)){
- size_t len = types.size();
- size_t len1 = sctty->types.size();
- if(len!=len1){
- return false;
- }
- while(len--){
- if(!types[len]->is(sctty->types[len])){
- return false;
- }
- }
- return true; // ÔªËظöÊýÏàµÈ£¬Ã¿¸öÔªËØÏàµÈ
- }
- return false;
- }
- virtual string str() {
- string s = name+"{";
- bool f = true;
- for(auto& it : types) {
- if (f) {
- f = false;
- } else {
- s += ",";
- }
- s += it->str();
- }
- return s+"}";
- }
- virtual void add(Type* t, const string&n="") { // Ôö¼Ó type
- tabs.push_back(n);
- types.push_back(t);
- }
- virtual void front(Type* t, const string&n="") { // Ôö¼Ó type
- tabs.insert(tabs.begin(), n);
- types.insert(types.begin(), t);
- }
- virtual size_t len() { // type ³¤¶È
- return types.size();
- };
- virtual Type* copy(const string&n="") { // ¿½±´ type
- TypeStruct* nts = new TypeStruct(n);
- nts->types = types; // ¿½±´½á¹¹
- return nts; // ·µ»Øн¨µÄÀàÐÍ
- };
- int elmpos(const string&n) { // ×ÓÔªËØÆ«ÒÆ
- int i = 0;
- for(auto &it : tabs) {
- if (it==n) {
- return i;
- }
- i++;
- }
- return -1;
- };
- Type* elmget(const string&n) { // ×ÓÔªËØÆ«ÒÆ
- int i = 0;
- for(auto &it : tabs) {
- if (it==n) {
- return types[i];
- }
- i++;
- }
- return nullptr;
- };
- virtual string getIdentify(bool strict=true) { // »ñµÃΨһ±êʶ
- if(name == ""){ // ÄäÃû½á¹¹
- string idf = "";
- for(auto t : types){
- idf += "." + t->getIdentify();
- }
- return idf;
- }
- if(idx == 0){
- return name;
- }
- return name + "." + Str::l2s(idx);
- }
- };
- // º¯ÊýÀàÐÍ
- EXTEND_TYPE(Function,TypeStruct)
- Type* ret; // ·µ»ØÖµÀàÐÍ
- TypeFunction(const string&n, Type*t=nullptr)
- : TypeStruct(n)
- , ret(t)
- {}
- virtual bool is(Type*t){ // À©Õ¹ÀàÐÍÖ±½Ó¶Ô±ÈµØÖ·
- return !!( ((int)this)==((int)t) );
- }
- virtual void set(Type* t) { // ÉèÖ÷µ»ØÖµ type
- ret = t;
- }
- virtual string str() {
- string s(name);
- if (ret) {
- s += ": " + ret->getIdentify();
- }
- s += "(";
- bool fx = false;
- for(auto& it : types) {
- if (fx) s += ",";
- fx = true;
- s += it->getIdentify();
- }
- return s+")";
- }
- virtual string getIdentify(bool strict=true) { // »ñµÃΨһ±êʶ
- string identify(name);
- for(auto& it : types) {
- identify += DEF_SPLITFIX_FUNCARGV+it->getIdentify(strict);
- }
- return identify;
- }
- TypeFunction* clone() { // ¿Ë¡
- auto *clnew = new TypeFunction("", ret);
- size_t len = types.size();
- for(int i = 0; i < len; i++){
- clnew->tabs.push_back(tabs[i]);
- clnew->types.push_back(types[i]);
- }
- return clnew;
- };
- };
- #undef EXTEND_TYPE
- }
- }