[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/rburkholder/daScript/master/src/simulate/debug_info.cpp [Back]  [Original]

#include "daScript/misc/platform.h"

#include "daScript/simulate/debug_info.h"
#include "daScript/ast/ast.h"

#include "daScript/misc/enums.h"
#include "daScript/misc/arraytype.h"
#include "daScript/misc/vectypes.h"
#include "daScript/misc/rangetype.h"

namespace das
{
    Enum g_typeTable = {
        {   Type::autoinfer,    "auto"  },
        {   Type::alias,        "alias"  },
        {   Type::option,       "option"  },
        {   Type::anyArgument,  "any"  },
        {   Type::tVoid,        "void"  },
        {   Type::tBool,        "bool"  },
        {   Type::tInt8,        "int8"  },
        {   Type::tUInt8,       "uint8"  },
        {   Type::tInt16,       "int16"  },
        {   Type::tUInt16,      "uint16"  },
        {   Type::tInt64,       "int64"  },
        {   Type::tUInt64,      "uint64"  },
        {   Type::tString,      "string" },
        {   Type::tPointer,     "pointer" },
        {   Type::tEnumeration, "enumeration" },
        {   Type::tEnumeration8,"enumeration8" },
        {   Type::tEnumeration16, "enumeration16" },
        {   Type::tIterator,    "iterator" },
        {   Type::tArray,       "array" },
        {   Type::tTable,       "table" },
        {   Type::tInt,         "int"   },
        {   Type::tInt2,        "int2"  },
        {   Type::tInt3,        "int3"  },
        {   Type::tInt4,        "int4"  },
        {   Type::tUInt,        "uint"  },
        {   Type::tBitfield,    "bitfield"  },
        {   Type::tUInt2,       "uint2" },
        {   Type::tUInt3,       "uint3" },
        {   Type::tUInt4,       "uint4" },
        {   Type::tFloat,       "float" },
        {   Type::tFloat2,      "float2"},
        {   Type::tFloat3,      "float3"},
        {   Type::tFloat4,      "float4"},
        {   Type::tDouble,      "double" },
        {   Type::tRange,       "range" },
        {   Type::tURange,      "urange"},
        {   Type::tRange64,     "range64" },
        {   Type::tURange64,    "urange64"},
        {   Type::tBlock,       "block"},
        {   Type::tFunction,    "function"},
        {   Type::tLambda,      "lambda"},
        {   Type::tTuple,       "tuple"},
        {   Type::tVariant,     "variant"},
        {   Type::fakeContext,  "__context"},
        {   Type::fakeLineInfo,  "__lineInfo"},
    };

    TypeAnnotation * TypeInfo::getAnnotation() const {
        if ( type != Type::tHandle ) {
            return nullptr;
        }
        return Module::resolveAnnotation(this);
    }

    StructInfo * TypeInfo::getStructType() const {
        if ( type != Type::tStructure ) {
            return nullptr;
        }
        return structType;
    }
    EnumInfo * TypeInfo::getEnumType() const {
        if ( type != Type::tEnumeration && type != Type::tEnumeration8 && type != Type::tEnumeration16 ) {
            return nullptr;
        }
        return enumType;
    }

    void TypeInfo::resolveAnnotation() const {
        if ( daScriptEnvironment::bound->modules ) Module::resolveAnnotation(this);
    }


    string das_to_string ( Type t ) {
        return g_typeTable.find(t);
    }

    Type nameToBasicType(const string & name) {
        return g_typeTable.find(name, Type::none);
    }

    int getTypeBaseSize ( Type type ) {
        switch ( type ) {
            case anyArgument:   return sizeof(vec4f);
            case tPointer:      return sizeof(void *);
            case tIterator:     return sizeof(Sequence);
            case tHandle:       DAS_ASSERTF(0, "we should not be here. if this happens, iterator was somehow placed on stack. how?");
                                return sizeof(void *);
            case tString:       return sizeof(char *);
            case tBool:         return sizeof(bool);            static_assert(sizeof(bool)==1,"4 byte bool");
            case tInt8:         return sizeof(int8_t);
            case tUInt8:        return sizeof(uint8_t);
            case tInt16:        return sizeof(int16_t);
            case tUInt16:       return sizeof(uint16_t);
            case tInt64:        return sizeof(int64_t);
            case tUInt64:       return sizeof(uint64_t);
            case tEnumeration:  return sizeof(int32_t);
            case tEnumeration8: return sizeof(int8_t);
            case tEnumeration16:return sizeof(int16_t);
            case tInt:          return sizeof(int);
            case tInt2:         return sizeof(int2);
            case tInt3:         return sizeof(int3);
            case tInt4:         return sizeof(int4);
            case tUInt:         return sizeof(uint32_t);
            case tBitfield:     return sizeof(uint32_t);
            case tUInt2:        return sizeof(uint2);
            case tUInt3:        return sizeof(uint3);
            case tUInt4:        return sizeof(uint4);
            case tFloat:        return sizeof(float);
            case tFloat2:       return sizeof(float2);
            case tFloat3:       return sizeof(float3);
            case tFloat4:       return sizeof(float4);
            case tDouble:       return sizeof(double);
            case tRange:        return sizeof(range);
            case tURange:       return sizeof(urange);
            case tRange64:      return sizeof(range64);
            case tURange64:     return sizeof(urange64);
            case tArray:        return sizeof(Array);
            case tTable:        return sizeof(Table);
            case tVoid:         return 0;
            case tBlock:        return sizeof(Block);
            case tFunction:     return sizeof(Func);
            case tLambda:       return sizeof(Lambda);
            case tStructure:    return 0;
            case tTuple:        return 0;
            case tVariant:      return 0;
            case fakeContext:   return 0;
            case fakeLineInfo:  return 0;
            default:
                DAS_ASSERTF(0, "not implemented. likely new built-intype been added, and support has not been updated.");
                return 0;
        }
    }

    int getTypeBaseAlign ( Type type ) {
        switch ( type ) {
            case anyArgument:   return alignof(vec4f);
            case tPointer:      return alignof(void *);
            case tIterator:     return alignof(Sequence);
            case tHandle:       DAS_ASSERTF(0, "we should not be here. if this happens iterator was somehow placed on stack. how?");
                                return alignof(void *);
            case tString:       return alignof(char *);
            case tBool:         return alignof(bool);            static_assert(alignof(bool)==1,"4 byte bool");
            case tInt8:         return alignof(int8_t);
            case tUInt8:        return alignof(uint8_t);
            case tInt16:        return alignof(int16_t);
            case tUInt16:       return alignof(uint16_t);
            case tInt64:        return alignof(int64_t);
            case tUInt64:       return alignof(uint64_t);
            case tEnumeration:  return alignof(int32_t);
            case tEnumeration8: return alignof(int8_t);
            case tEnumeration16:return alignof(int16_t);
            case tInt:          return alignof(int32_t);
            case tInt2:         return alignof(int2);
            case tInt3:         return alignof(int3);
            case tInt4:         return alignof(int4);
            case tUInt:         return alignof(uint32_t);
            case tBitfield:     return alignof(uint32_t);
            case tUInt2:        return alignof(uint2);
            case tUInt3:        return alignof(uint3);
            case tUInt4:        return alignof(uint4);
            case tFloat:        return alignof(float);
            case tFloat2:       return alignof(float2);
            case tFloat3:       return alignof(float3);
            case tFloat4:       return alignof(float4);
            case tDouble:       return alignof(double);
            case tRange:        return alignof(range);
            case tURange:       return alignof(urange);
            case tRange64:      return alignof(range64);
            case tURange64:     return alignof(urange64);
            case tArray:        return alignof(Array);
            case tTable:        return alignof(Table);
            case tVoid:         return 1;
            case tBlock:        return alignof(Block);
            case tFunction:     return alignof(Func);
            case tLambda:       return alignof(Lambda);
            case tStructure:    return 1;
            case tTuple:        return 1;
            case tVariant:      return 1;
            case fakeContext:   return 1;
            case fakeLineInfo:  return 1;
            default:
                DAS_ASSERTF(0, "not implemented. likely new built-intype been added, and support has not been updated.");
                return 1;
        }
    }

    int getStructAlign ( StructInfo * info ) {
        int al = 0;
        for ( uint32_t i=0, is=info->count; i!=is; ++i ) {
            al = das::max ( al, getTypeAlign(info->fields[i]) );
        }
        return al;
    }

    int getTupleAlign ( TypeInfo * info ) {
        int al = 0;
        for ( uint32_t i=0, is=info->argCount; i!=is; ++i ) {
            al = das::max ( al, getTypeAlign(info->argTypes[i]) );
        }
        return al;
    }

    int getTupleSize ( TypeInfo * info ) {
        int size = 0;
        for ( uint32_t i=0, is=info->argCount; i!=is; ++i ) {
            int al = getTypeAlign(info->argTypes[i]) - 1;
            size = (size + al) & ~al;
            size += getTypeSize(info->argTypes[i]);
        }
        int al = getTupleAlign(info) - 1;
        size = (size + al) & ~al;
        return size;
    }

    int getVariantAlign ( TypeInfo * info ) {
        int al = getTypeBaseAlign(Type::tInt);
        for ( uint32_t i=0, is=info->argCount; i!=is; ++i ) {
            al = das::max ( al, getTypeAlign(info->argTypes[i]) );
        }
        return al;
    }

    int getVariantSize ( TypeInfo * info ) {
        int maxSize = 0;
        int al = getVariantAlign(info) - 1;
        for ( uint32_t i=0, is=info->argCount; i!=is; ++i ) {
            int size = (getTypeBaseSize(Type::tInt) + al) & ~al;
            size += getTypeSize(info->argTypes[i]);
            maxSize = das::max(size, maxSize);
        }
        maxSize = (maxSize + al) & ~al;
        return maxSize;
    }

    int getTypeBaseSize ( TypeInfo * info ) {
        if ( info->type==Type::tHandle ) {
            return int(info->getAnnotation()->getSizeOf());
        } else if ( info->type==Type::tStructure ) {
            return info->structType->size;
        } else if ( info->type==Type::tTuple ) {
            return getTupleSize(info);
        } else if ( info->type==Type::tVariant ) {
            return getVariantSize(info);
        } else {
            return getTypeBaseSize(info->type);
        }
    }

    int getTypeBaseAlign ( TypeInfo * info ) {
        if ( info->type==Type::tHandle ) {
            return int(info->getAnnotation()->getAlignOf());
        } else if ( info->type==Type::tStructure ) {
            return getStructAlign(info->structType);
        } else if ( info->type==Type::tTuple ) {
            return getTupleAlign(info);
        } else if ( info->type==Type::tVariant ) {
            return getVariantAlign(info);
        } else {
            return getTypeBaseAlign(info->type);
        }
    }

    int getDimSize ( TypeInfo * info ) {
        int size = 1;
        if ( info->dimSize ) {
            for ( uint32_t i=0, is=info->dimSize; i!=is; ++i ) {
                size *= info->dim[i];
            }
        }
        return size;
    }

    int getTypeSize ( TypeInfo * info ) {
        return getDimSize(info) * getTypeBaseSize(info);
    }

    int getTypeAlign ( TypeInfo * info ) {
        return getTypeBaseAlign(info);
    }

    bool isVoid ( const TypeInfo * THIS ) {
        return (THIS->type==Type::tVoid) && (THIS->dimSize==0);
    }

    bool isValidArgumentType ( TypeInfo * argType, TypeInfo * passType ) {
        // passing non-ref to ref, or passing not the same type
        if ( (argType->isRef() && !passType->isRef()) || !isSameType(argType,passType,RefMatters::no, ConstMatters::no, TemporaryMatters::no,false) ) {
            return false;
        }
        // ref or pointer can only add const
        if ( (argType->isRef() || argType->type==Type::tPointer) && !argType->isConst() && passType->isConst() ) {
            return false;
        }
        // all good
        return true;
    }

    bool isSameType ( const TypeInfo * THIS,
                     const TypeInfo * decl,
                     RefMatters refMatters,
                     ConstMatters constMatters,
                     TemporaryMatters temporaryMatters,
                     bool topLevel ) {
        if ( topLevel && THIS->isRef() ) {
            constMatters = ConstMatters::yes;
        }
        if ( THIS->type != decl->type ) {
            return false;
        }
        if ( THIS->type==Type::tHandle && THIS->getAnnotation()!=decl->getAnnotation() ) {
            return false;
        }
        if ( THIS->type==Type::tStructure && THIS->structType!=decl->structType ) {
            return false;
        }
        if ( THIS->type==Type::tPointer || THIS->type==Type::tIterator ) {
            if ( (THIS->firstType && !isVoid(THIS->firstType))
                && (decl->firstType && !isVoid(decl->firstType))
                && !isSameType(THIS->firstType, decl->firstType, RefMatters::yes, ConstMatters::yes, TemporaryMatters::yes, false) ) {
                return false;
            }

        }
        if ( THIS->type==Type::tEnumeration || THIS->type==Type::tEnumeration8 ||
            THIS->type==Type::tEnumeration16 ) {
            if ( THIS->type != decl->type ) {
                return false;
            }
            if ( THIS->enumType && decl->enumType && THIS->enumType!=decl->enumType ) {
                return false;
            }
        }
        if ( THIS->type==Type::tArray ) {
            if ( THIS->firstType && decl->firstType && !isSameType(THIS->firstType, decl->firstType,
                                                                   RefMatters::yes, ConstMatters::yes, TemporaryMatters::yes, false) ) {
                return false;
            }
        }
        if ( THIS->type==Type::tTable ) {
            if ( THIS->firstType && decl->firstType && !isSameType(THIS->firstType, decl->firstType,
                                                                   RefMatters::yes, ConstMatters::yes, TemporaryMatters::yes, false) ) {
                return false;
            }
            if ( THIS->secondType && decl->secondType && !isSameType(THIS->secondType, decl->secondType,
                                                                     RefMatters::yes, ConstMatters::yes, TemporaryMatters::yes, false) ) {
                return false;
            }
        }
        if ( THIS->type==Type::tBlock || THIS->type==Type::tFunction
            || THIS->type==Type::tLambda || THIS->type==Type::tTuple
            || THIS->type==Type::tVariant ) {
            if ( THIS->firstType && decl->firstType && !isSameType(THIS->firstType, decl->firstType,
                                                                   RefMatters::yes, ConstMatters::yes, TemporaryMatters::yes, false) ) {
                return false;
            }
            if ( THIS->firstType || THIS->argCount) {    // if not any block or any function
                if ( THIS->argCount != decl->argCount ) {
                    return false;
                }
                for ( uint32_t i=0, is=THIS->argCount; i!=is; ++i ) {
                    auto arg = THIS->argTypes[i];
                    auto declArg = decl->argTypes[i];
                    if ( !isSameType(arg,declArg,RefMatters::yes, ConstMatters::yes, TemporaryMatters::yes,true) ) {
                        return false;
                    }
                }
            }
        }
        if ( THIS->dimSize != decl->dimSize ) {
            return false;
        } else if ( THIS->dim ) {
            for ( uint32_t i=0,is=THIS->dimSize; i!=is; ++i ) {
                if ( THIS->dim[i] != decl->dim[i] ) {
                    return false;
                }
            }
        }
        if ( refMatters == RefMatters::yes ) {
            if ( THIS->isRef() != decl->isRef() ) {
                return false;
            }
        }
        if ( constMatters == ConstMatters::yes ) {
            if ( THIS->isConst() != decl->isConst() ) {
                return false;
            }
        }
        if ( temporaryMatters == TemporaryMatters::yes ) {
            if ( THIS->isTemp() != decl->isTemp() ) {
                return false;
            }
        }
        return true;
    }

    bool isCompatibleCast ( const StructInfo * THIS, const StructInfo * castS ) {
        if ( castS->count < THIS->count ) {
            return false;
        }
        for ( uint32_t i=0, is=THIS->count; i!=is; ++i ) {
            VarInfo * fd = THIS->fields[i];
            VarInfo * cfd = castS->fields[i];
            if ( strcmp(fd->name,cfd->name)!=0 ) {
                return false;
            }
            if ( !isSameType(fd,cfd,RefMatters::yes, ConstMatters::yes, TemporaryMatters::yes,true) ) {
                return false;
            }
        }
        return true;
    }

    string debug_type ( const TypeInfo * info ) {
        if ( !info ) return "";
        TextWriter stream;
        // its never auto or alias
        if ( info->type==Type::tHandle ) {
            stream getAnnotation()->name;
        } else if ( info->type==Type::tStructure ) {
            stream structType->name;
        } else if ( info->type==Type::tPointer ) {
            stream firstType) type==Type::tEnumeration || info->type==Type::tEnumeration8 || info->type==Type::tEnumeration16 ) {
            stream enumType && info->enumType->name) ? info->enumType->name : "enum");
        } else if ( info->type==Type::tArray ) {
            stream type==Type::tTable ) {
            stream type==Type::tTuple || info->type==Type::tVariant ) {
            stream type) argCount; a!=as; ++a ) {
                if ( a!=0 ) stream argNames ) {
                    stream argNames[a] type==Type::tFunction || info->type==Type::tBlock || info->type==Type::tLambda ) {
            stream type) argCount ) {
                stream argCount; ai!=ais; ++ ai ) {
                    if ( ai!=0 ) stream argTypes[ai]->isConst()) {
                        stream argNames ) {
                        stream argNames[ai] module->name name type==Type::tEnumeration || info->type==Type::tEnumeration8 || info->type==Type::tEnumeration16 ) {
            ss type==Type::tEnumeration8 ) ss type==Type::tEnumeration16 ) ss enumType ) {
                // TODO: add module name to enum info
                ss name type==Type::tPointer ) {
            ss flags & TypeInfo::flag_isSmartPtr ) {
                ss flags & TypeInfo::flag_isSmartPtrNative ? "W" : "M");
            }
        } else {
            switch ( info->type ) {
                case Type::anyArgument:     ss 

Web Proxy Viewer  |  New URL  |  Original Page