namespace path { char Separator(); String AbsolutePath(String const& path); String Basename(String const& path); String Dirname(String const& path); bool Exists(String const& path); bool LExists(String const& path); String ExpandUser(String const& path); String ExpandVars(String const& path); int64_t GetAccessTime(String const& path); int64_t GetModificationTime(String const& path); int64_t GetCreationTime(String const& path); int64_t GetSize(String const& path); bool IsAbsolute(String const& path); bool IsFile(String const& path); bool IsDirectory(String const& path); bool IsLink(String const& path); bool IsMountPoint(String const& path); template<typename T> String Join(StringBuilder builder, T const& lastItem); template<typename T, typename... Params> String Join(StringBuilder builder, T const& nextItem, Params const&... params); template<typename T, typename... Params> String Join(T const& begin, Params const&... params); String NormCase(String const& path); String NormPath(String const& path); String RealPath(String const& path); String RelativePath(String const& path, String const& relativeTo = StringLiteral("./")); bool SameFile(String const& path1, String const& path2); ///@todo - Split, walk, commonprefix }
/** \brief Load all the initial dictionary words. */ void init_dictionary(int dictsize) { init_compiler(dictsize); memory_words(); compile_primitives(); compile_core_constants(); core_words(); core_extension_words(); compile_dictionary_words(); controlflow_words(); more_core_words(); compile_double(); string_words(); exception_words(); file_words(); format_words(); compile_stack_words(); implementation_words(); vocabulary_words(); interpreter_words(); platform_words(); /* FIX - NEED TO DO THESE */ // Primitive( "d<", &lesser ); /* ( d1 d2 -- f ) */ // Primitive( "d>", &lesser ); /* ( d1 d2 -- f ) */ // Primitive( "u*", &um_star ); /* ( x y -- x*y ) */ // Primitive( "du*", &um_star ); /* ( x y -- x*y ) */ // Primitive( "du/mod", &um_star ); /* ( x y -- x*y ) */ // Primitive( "du<", &um_star ); /* ( x y -- x*y ) */ // Primitive( "m+", &um_star ); /* ( x y -- x*y ) */ // Primitive( "m-", &um_star ); /* ( x y -- x*y ) */ // Primitive( "m*", &um_star ); /* ( x y -- x*y ) */ // Primitive( "m*/", &um_star ); /* ( x y -- x*y ) */ // Primitive( "m/", &um_star ); /* ( x y -- x*y ) */ // Primitive( "m/mod", &um_star ); /* ( x y -- x*y ) */ /* FIX - NEED TO DO THESE */ /* FIX - these two words are no longer used - why are they here ?? */ // Primitive( "um*", &um_star ); /* ( x y -- x*y ) */ // Colon( "udm*" ); /* ( d.lo d.hi n -- d.lo' d.hi' ) */ // c("tuck"); c("um*"); c("drop"); c("-rot"); c("um*"); // c("rot"); c("+"); End(); Colon( ".version" ); DotQuote("Portable ANS Forth - [email protected]"); c("cr"); End(); Colon( "rstrace" ); DotQuote("( R: "); c("rp@"); c("rp0"); c("@"); Do(); c("i"); c("."); c("space"); c("/cell"); PlusLoop(); DotQuote(" )"); c("cr"); End(); Variable( "argument-hook" ); /* To( Tick("ndrop"), "argument-hook" ); */ ACF x = find("unnest"); To( (Cell)x, "argument-hook" ); Colon( "cold" ); c(".version"); c("cold-chain"); /* included may be replaced with path-included which reads FORTH_PATH environment variable to look in selected directories */ c("debug"); c("@"); If(); DotQuote("Loading Forth files..."); Then(); /* StringLiteral("base.fth"); c("included"); */ DotQuote("loading base.fth"); c("cr"); StringLiteral("base.fth"); Tick("included"); c("catch"); c("?aborted"); If(); DotQuote("Failed to load."); c("cr"); Then(); c("debug"); c("@"); If(); DotQuote("done."); c("cr"); Then(); c("hex"); #if 0 c("argument-hook"); c("@"); Tick("execute"); c("catch"); c("?aborted"); If(); DotQuote("argument-hook failed"); c("cr"); Then(); #endif c("read-eval-loop"); End(); Colon( "warm" ); DotQuote( "Warm Started." ); c("cr"); c("rstrace"); c("quit"); End(); /* header */ Colon( "name," ); c("dup"); c("1+"); c("talign"); c("allot"); c("dup"); c("here"); c("1-"); c("c!"); c("here"); c("1-"); c("over"); c("-"); c("swap"); c("cmove"); End(); Colon( "header" ); c("name,"); c("link"); c("do-create"); c(","); End(); Colon( "create" ); c("parse-word"); c("header"); End(); Colon( "codefield" ); /* ( codefield -- ) */ c("lastacf"); c("!"); End(); Colon( ":" ); c("create"); c("hide"); c("do-colon"); c("codefield"); c("]"); End(); Colon( ";" ); c("compile"); c("unnest"); c("["); c("reveal"); End(); immediate(); }
namespace sprawl { String::Holder::Holder() : m_staticData() , m_dynamicData(nullptr) , m_data(nullptr) , m_refCount(1) , m_length(0) , m_hash(0) , m_hashComputed(false) { // } String::Holder::Holder(const char* data) : m_staticData() , m_dynamicData(nullptr) , m_data(nullptr) , m_refCount(1) , m_length(strlen(data)) , m_hash(0) , m_hashComputed(false) { if( m_length < staticDataSize ) { memcpy(m_staticData, data, m_length); m_staticData[m_length] = '\0'; m_data = m_staticData; } else { m_dynamicData = new char[m_length+1]; memcpy(m_dynamicData, data, m_length); m_dynamicData[m_length] = '\0'; m_data = m_dynamicData; } } String::Holder::Holder(const char* data, size_t length) : m_staticData() , m_dynamicData(nullptr) , m_data(nullptr) , m_refCount(1) , m_length(length) , m_hash(0) , m_hashComputed(false) { if( m_length < staticDataSize ) { memcpy(m_staticData, data, m_length); m_staticData[m_length] = '\0'; m_data = m_staticData; } else { m_dynamicData = new char[m_length+1]; memcpy(m_dynamicData, data, m_length); m_dynamicData[m_length] = '\0'; m_data = m_dynamicData; } } String::Holder::Holder(StringLiteral const& literal) : m_staticData() , m_dynamicData(nullptr) , m_data(literal.m_ptr) , m_refCount(1) , m_length(literal.m_length) , m_hash(0) , m_hashComputed(false) { // } void String::Holder::IncRef() { ++m_refCount; } bool String::Holder::DecRef() { return (--m_refCount == 0); } String::Holder* String::Holder::CreateHolder() { typedef memory::PoolAllocator<sizeof(String::Holder)> holderAlloc; String::Holder* ret = (String::Holder*)holderAlloc::alloc(); return ret; } void String::Holder::FreeHolder(Holder* holder) { typedef memory::PoolAllocator<sizeof(String::Holder)> holderAlloc; holder->~Holder(); holderAlloc::free(holder); } String::Holder::~Holder() { if(m_dynamicData) { delete[] m_dynamicData; } } /*static*/ String::Holder String::ms_emptyHolder(StringLiteral("")); String::String() : m_holder(&ms_emptyHolder) { } String::String(const char* const data) : m_holder(Holder::CreateHolder()) { new (m_holder) Holder(data); } String::String(const char* const data, size_t length) : m_holder(Holder::CreateHolder()) { new (m_holder) Holder(data, length); } String::String(String const& other) : m_holder(other.m_holder) { if(m_holder != &ms_emptyHolder) { m_holder->IncRef(); } } String::String(String&& other) : m_holder(other.m_holder) { //Don't change ref count here, it's staying the same because it's being *moved* other.m_holder = &ms_emptyHolder; } String::String(std::string const& stlString) : m_holder(Holder::CreateHolder()) { new (m_holder) Holder(stlString.c_str(), stlString.length()); } String::String(StringLiteral const& stringLiteral) : m_holder(Holder::CreateHolder()) { new (m_holder) Holder(stringLiteral); } String::~String() { if(m_holder != &ms_emptyHolder && m_holder->DecRef()) { Holder::FreeHolder(m_holder); } } sprawl::String String::operator+(sprawl::String const& other) const { sprawl::String ret; ret.m_holder = Holder::CreateHolder(); new (ret.m_holder) Holder(); size_t fullLength = m_holder->m_length + other.m_holder->m_length; if(fullLength < Holder::staticDataSize) { memcpy(ret.m_holder->m_staticData, m_holder->m_data, m_holder->m_length); memcpy(ret.m_holder->m_staticData + m_holder->m_length, other.m_holder->m_data, other.m_holder->m_length); ret.m_holder->m_staticData[fullLength] = '\0'; ret.m_holder->m_data = ret.m_holder->m_staticData; } else { ret.m_holder->m_dynamicData = new char[fullLength+1]; memcpy(ret.m_holder->m_dynamicData, m_holder->m_data, m_holder->m_length); memcpy(ret.m_holder->m_dynamicData + m_holder->m_length, other.m_holder->m_data, other.m_holder->m_length); ret.m_holder->m_dynamicData[fullLength] = '\0'; ret.m_holder->m_data = ret.m_holder->m_dynamicData; } ret.m_holder->m_length = fullLength; return std::move(ret); } sprawl::String String::operator+(const char* other) const { sprawl::String ret; ret.m_holder = Holder::CreateHolder(); new (ret.m_holder) Holder(); size_t length = strlen(other); size_t fullLength = m_holder->m_length + length; if(fullLength < Holder::staticDataSize) { memcpy(ret.m_holder->m_staticData, m_holder->m_data, m_holder->m_length); memcpy(ret.m_holder->m_staticData + m_holder->m_length, other, length); ret.m_holder->m_staticData[fullLength] = '\0'; ret.m_holder->m_data = ret.m_holder->m_staticData; } else { ret.m_holder->m_dynamicData = new char[fullLength+1]; memcpy(ret.m_holder->m_dynamicData, m_holder->m_data, m_holder->m_length); memcpy(ret.m_holder->m_dynamicData + m_holder->m_length, other, length); ret.m_holder->m_dynamicData[fullLength] = '\0'; ret.m_holder->m_data = ret.m_holder->m_dynamicData; } ret.m_holder->m_length = fullLength; return std::move(ret); } sprawl::String& String::operator+=(sprawl::String const& other) { Holder* newHolder = Holder::CreateHolder(); new (newHolder) Holder(); size_t fullLength = m_holder->m_length + other.m_holder->m_length; if(fullLength < Holder::staticDataSize) { memcpy(newHolder->m_staticData, m_holder->m_data, m_holder->m_length); memcpy(newHolder->m_staticData + m_holder->m_length, other.m_holder->m_data, other.m_holder->m_length); newHolder->m_staticData[fullLength] = '\0'; newHolder->m_data = newHolder->m_staticData; } else { newHolder->m_dynamicData = new char[fullLength+1]; memcpy(newHolder->m_dynamicData, m_holder->m_data, m_holder->m_length); memcpy(newHolder->m_dynamicData + m_holder->m_length, other.m_holder->m_data, other.m_holder->m_length); newHolder->m_dynamicData[fullLength] = '\0'; newHolder->m_data = newHolder->m_dynamicData; } newHolder->m_length = fullLength; Holder::FreeHolder(m_holder); m_holder = newHolder; return *this; } sprawl::String& String::operator+=(const char* other) { Holder* newHolder = Holder::CreateHolder(); new (newHolder) Holder(); size_t length = strlen(other); size_t fullLength = m_holder->m_length + length; if(fullLength < Holder::staticDataSize) { memcpy(newHolder->m_staticData, m_holder->m_data, m_holder->m_length); memcpy(newHolder->m_staticData + m_holder->m_length, other, length); newHolder->m_staticData[fullLength] = '\0'; newHolder->m_data = newHolder->m_staticData; } else { newHolder->m_dynamicData = new char[fullLength+1]; memcpy(newHolder->m_dynamicData, m_holder->m_data, m_holder->m_length); memcpy(newHolder->m_dynamicData + m_holder->m_length, other, length); newHolder->m_dynamicData[fullLength] = '\0'; newHolder->m_data = newHolder->m_dynamicData; } newHolder->m_length = fullLength; Holder::FreeHolder(m_holder); m_holder = newHolder; return *this; } String& String::operator=(String const& other) { if(m_holder != &ms_emptyHolder && m_holder->DecRef()) { Holder::FreeHolder(m_holder); } m_holder = other.m_holder; if(m_holder != &ms_emptyHolder) { m_holder->IncRef(); } return *this; } String& String::operator=(String&& other) { if(m_holder != &ms_emptyHolder && m_holder->DecRef()) { Holder::FreeHolder(m_holder); } m_holder = other.m_holder; other.m_holder = &ms_emptyHolder; return *this; } bool String::operator<(String const& other) const { if(m_holder == other.m_holder) { return false; } if(m_holder == &ms_emptyHolder) { return false; } if(other.m_holder == &ms_emptyHolder) { return true; } size_t length = other.m_holder->m_length < m_holder->m_length ? other.m_holder->m_length : m_holder->m_length; const char* const left = m_holder->m_data; const char* const right = other.m_holder->m_data; for(size_t i = 0; i < length; ++i) { if(left[i] == right[i]) continue; return left[i] < right[i]; } return m_holder->m_length < other.m_holder->m_length; } String String::GetOwned() const { if (m_holder->m_data == m_holder->m_dynamicData || m_holder->m_data == m_holder->m_staticData) { return *this; } return String(m_holder->m_data, m_holder->m_length); } std::string String::toStdString() const { if(m_holder == &ms_emptyHolder) { static std::string emptyStr; return emptyStr; } return std::string(m_holder->m_data, m_holder->m_length); } }