Add timespan

This commit is contained in:
2025-12-01 05:34:04 -06:00
parent d5c57ae018
commit e409970ae4
15 changed files with 759 additions and 467 deletions

View File

@@ -25,7 +25,7 @@ jobs:
name: Build Docker Image
dockerfile: Dockerfile.run
output: !RegistryOutput
tags: onedev.site.tesses.net/crosslang/crosslang:latest
tags: onedev.site.tesses.net/crosslang/crosslang:latest onedev.site.tesses.net/crosslang/crosslang:@commit_hash@
registryLogins:
- registryUrl: '@server_url@'
userName: '@job_token@'
@@ -86,6 +86,8 @@ jobs:
envVars:
- name: GITEA_AUTH
value: '@secret:GITEA_AUTH@'
- name: BUILD_NO
value: '@build_number@'
useTTY: true
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
- !CommandStep
@@ -109,6 +111,8 @@ jobs:
value: '@secret:GITEA_AUTH@'
- name: CPKG_KEY
value: '@secret:CPKG_KEY@'
- name: BUILD_NO
value: '@build_number@'
useTTY: true
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
- !SCPCommandStep
@@ -125,6 +129,7 @@ jobs:
privateKeySecret: TRUENAS_SSH
commands: |
cd /mnt/storage24tb/Files/Public/CrossLang
rm -f latest
ln -s @build_number@ latest
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
triggers:

View File

@@ -157,7 +157,6 @@ src/runtime_methods/helpers.cpp
src/types/async.cpp
src/types/associativearray.cpp
src/types/any.cpp
src/types/datetime.cpp
src/types/ittr.cpp
src/types/closure.cpp
src/types/dictionary.cpp
@@ -445,7 +444,11 @@ set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/winicon.ico")
set(CPACK_NSIS_MODIFY_PATH ON)
set(CPACK_PACKAGE_VENDOR "Tesses")
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$DESKTOP\\\\CrossLang Interperter.lnk' '$INSTDIR\\\\bin\\\\crossint.exe'")
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\CrossLang Interperter.lnk' '$INSTDIR\\\\bin\\\\crossint.exe'")
include(CPack)
add_subdirectory(pkgconfig)

View File

@@ -1 +1,2 @@
export DEB_VERSION=1.0.0
export BUILD=$(($BUILD_NO-142))
export DEB_VERSION=1.0.0-$BUILD

View File

@@ -591,14 +591,7 @@ typedef enum {
*/
int Lex(std::string filename, std::istream& strm, std::vector<LexToken>& tokens);
/**
* @brief Undefined type
*
*/
class Undefined
{
};
using Undefined = std::monostate;
class AdvancedSyntaxNode;
/**
* @brief Bytecode instruction enumeration
@@ -802,7 +795,7 @@ class CharInstruction : public ByteCodeInstruction {
void Write(std::vector<uint8_t>& data);
};
using SyntaxNode = std::variant<int64_t, double, std::string, char, bool, std::nullptr_t, Undefined,std::vector<uint8_t>, AdvancedSyntaxNode,std::shared_ptr<Tesses::Framework::Streams::Stream>,std::shared_ptr<Tesses::Framework::Filesystem::VFSPath>>;
using SyntaxNode = std::variant<Undefined,int64_t, double, std::string, char, bool, std::nullptr_t,std::vector<uint8_t>, AdvancedSyntaxNode,std::shared_ptr<Tesses::Framework::Streams::Stream>,std::shared_ptr<Tesses::Framework::Filesystem::VFSPath>>;
@@ -1383,15 +1376,6 @@ class Parser {
};
class TDateTime {
Tesses::Framework::Date::DateTime* dt;
public:
TDateTime();
TDateTime(Tesses::Framework::Date::DateTime t);
TDateTime(const TDateTime& dt);
Tesses::Framework::Date::DateTime& GetDate();
~TDateTime();
};
class TBreak {
};
@@ -1403,7 +1387,7 @@ class TContinue {
*
*/
using TObject = std::variant<int64_t,double,char,bool,std::string,std::regex,Tesses::Framework::Filesystem::VFSPath,std::nullptr_t,Undefined,MethodInvoker,THeapObjectHolder,TVMVersion,TDateTime,TBreak,TContinue,std::shared_ptr<Tesses::Framework::Streams::Stream>,std::shared_ptr<Tesses::Framework::Filesystem::VFS>,std::shared_ptr<Tesses::Framework::Http::IHttpServer>,std::shared_ptr<Tesses::Framework::Http::HttpRequestBody>,std::shared_ptr<Tesses::Framework::TextStreams::TextReader>,std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>;
using TObject = std::variant<int64_t,double,char,bool,std::string,std::regex,Tesses::Framework::Filesystem::VFSPath,std::nullptr_t,Undefined,MethodInvoker,THeapObjectHolder,TVMVersion,std::shared_ptr<Tesses::Framework::Date::DateTime>,std::shared_ptr<Tesses::Framework::Date::TimeSpan>,TBreak,TContinue,std::shared_ptr<Tesses::Framework::Streams::Stream>,std::shared_ptr<Tesses::Framework::Filesystem::VFS>,std::shared_ptr<Tesses::Framework::Http::IHttpServer>,std::shared_ptr<Tesses::Framework::Http::HttpRequestBody>,std::shared_ptr<Tesses::Framework::TextStreams::TextReader>,std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>;
class TRootEnvironment;
class GC;

25
pkgconfig/CMakeLists.txt Normal file
View File

@@ -0,0 +1,25 @@
set(PKGCONFIG_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
set(PKGCONFIG_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
set(PKGCONFIG_PROJECT_DESCRIPTION "A programming language")
set(PKGCONFIG_PROJECT_HOMEPAGE_URL "https://onedev.site.tesses.net/crosslang")
if(CROSSLANG_ENABLE_FFI)
set(PKGCONFIG_DEPS "Requires: libffi")
else()
set(PKGCONFIG_DEPS "")
endif()
if(CROSSLANG_ENABLE_STATIC)
configure_file(crosslang_static.pc.in crosslang_static.pc @ONLY)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/crosslang_static.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
if(CROSSLANG_ENABLE_SHARED)
configure_file(crosslang.pc.in crosslang.pc @ONLY)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/crosslang.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()

13
pkgconfig/crosslang.pc.in Normal file
View File

@@ -0,0 +1,13 @@
prefix=@CMAKE_INSTALL_PREFIX@
includedir=@PKGCONFIG_INCLUDEDIR@
libdir=@PKGCONFIG_LIBDIR@
Name: @PROJECT_NAME@
Description: @PKGCONFIG_PROJECT_DESCRIPTION@
URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
@PKGCONFIG_DEPS@
Cflags: -I"${includedir}"
Libs: -L"${libdir}" -lcrosslang_shared

View File

@@ -0,0 +1,13 @@
prefix=@CMAKE_INSTALL_PREFIX@
includedir=@PKGCONFIG_INCLUDEDIR@
libdir=@PKGCONFIG_LIBDIR@
Name: @PROJECT_NAME@
Description: @PKGCONFIG_PROJECT_DESCRIPTION@
URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
@PKGCONFIG_DEPS@
Cflags: -I"${includedir}"
Libs: -L"${libdir}" -lcrosslang_static

View File

@@ -578,7 +578,6 @@ namespace Tesses::CrossLang
}
break;
case '<':
case '>':
case '?':
if(peek == read)
{
@@ -645,6 +644,7 @@ namespace Tesses::CrossLang
case '^':
case '~':
case '!':
case '>':
case '*':
case '%':
//*

View File

@@ -114,11 +114,18 @@ namespace Tesses::CrossLang
bool Parser::IsAnySymbol(std::initializer_list<std::string> idents, bool pop)
{
if(i < tokens.size())
{
if(tokens[i].type != LexTokenType::Symbol) return false;
for(auto item : idents)
{
if(item == ">")
{
if(i+1<tokens.size())
{
if((tokens[i+1].text == ">" || tokens[i+1].text == ">=") && tokens[i+1].type == LexTokenType::Symbol) continue;
}
if(item == tokens[i].text)
{
tkn = tokens[i];
@@ -126,6 +133,42 @@ namespace Tesses::CrossLang
return true;
}
}
else if(item == ">>=")
{
if(i+1 < tokens.size())
{
if(tokens[i].text == ">" && tokens[i+1].text == ">=" && tokens[i].type == LexTokenType::Symbol && tokens[i+1].type == LexTokenType::Symbol)
{
tkn = tokens[i];
tkn.text = ">>=";
if(pop) i+=2;
return true;
}
}
}
else if(item == ">>")
{
if(i+1 < tokens.size())
{
if(tokens[i].text == ">" && tokens[i+1].text == ">" && tokens[i].type == LexTokenType::Symbol && tokens[i+1].type == LexTokenType::Symbol)
{
tkn = tokens[i];
tkn.text = ">>";
if(pop) i+=2;
return true;
}
}
}
else {
if(item == tokens[i].text)
{
tkn = tokens[i];
if(pop) i++;
return true;
}
}
}
}
return false;
}
@@ -134,7 +177,48 @@ namespace Tesses::CrossLang
if(i < tokens.size())
{
if(tokens[i].type != LexTokenType::Symbol) return false;
if(tokens[i].text == txt)
if(txt == ">")
{
if(i+1<tokens.size())
{
if((tokens[i+1].text == ">" || tokens[i+1].text == ">=") && tokens[i+1].type == LexTokenType::Symbol) return false;
}
if(txt == tokens[i].text)
{
tkn = tokens[i];
if(pop) i++;
return true;
}
}
else if(txt == ">>=")
{
if(i+1 < tokens.size())
{
if(tokens[i].text == ">" && tokens[i+1].text == ">=" && tokens[i].type == LexTokenType::Symbol && tokens[i+1].type == LexTokenType::Symbol)
{
tkn = tokens[i];
tkn.text = ">>=";
if(pop) i+=2;
return true;
}
}
}
else if(txt == ">>")
{
if(i+1 < tokens.size())
{
if(tokens[i].text == ">" && tokens[i+1].text == ">" && tokens[i].type == LexTokenType::Symbol && tokens[i+1].type == LexTokenType::Symbol)
{
tkn = tokens[i];
tkn.text = ">>";
if(pop) i+=2;
return true;
}
}
}
else if(tokens[i].text == txt)
{
tkn = tokens[i];
if(pop) i++;
@@ -147,11 +231,53 @@ namespace Tesses::CrossLang
{
if(i < tokens.size())
{
if(tokens[i].type != LexTokenType::Symbol)
{
throw SyntaxException(tokens[i].lineInfo, "expected the symbol \"" + txt + "\" but got the " + LexTokenType_ToString(tokens[i].type) + " \"" + tokens[i].text + "\" which is not a symbol at all.");
}
if(tokens[i].text != txt)
if(txt == ">")
{
if(i+1<tokens.size())
{
if((tokens[i+1].text == ">" || tokens[i+1].text == ">=") && tokens[i+1].type == LexTokenType::Symbol)
throw SyntaxException(tokens[i].lineInfo, "expected the symbol \"" + txt + "\" but got the symbol \"" + tokens[i].text + tokens[i+1].text + "\"");;
}
if(txt == tokens[i].text)
{
return;
}
}
if(txt == ">>=")
{
if(i+1 < tokens.size())
{
if(tokens[i].text == ">" && tokens[i+1].text == ">=" && tokens[i].type == LexTokenType::Symbol && tokens[i+1].type == LexTokenType::Symbol)
{
return;
}
throw SyntaxException(tokens[i].lineInfo, "expected the symbol \"" + txt + "\" but got the symbol \"" + tokens[i].text + tokens[i+1].text + "\"");
}
throw SyntaxException(tokens[i].lineInfo, "expected the symbol \"" + txt + "\" but got the symbol \"" + tokens[i].text + "\"");
}
else if(txt == ">>")
{
if(i+1 < tokens.size())
{
if(tokens[i].text == ">" && tokens[i+1].text == ">" && tokens[i].type == LexTokenType::Symbol && tokens[i+1].type == LexTokenType::Symbol)
{
i+=2;
return;
}
throw SyntaxException(tokens[i].lineInfo, "expected the symbol \"" + txt + "\" but got the symbol \"" + tokens[i].text + tokens[i+1].text + "\"");
}
throw SyntaxException(tokens[i].lineInfo, "expected the symbol \"" + txt + "\" but got the symbol \"" + tokens[i].text + "\"");
}
else if(tokens[i].text != txt)
{
throw SyntaxException(tokens[i].lineInfo, "expected the symbol \"" + txt + "\" but got the symbol \"" + tokens[i].text + "\"");

View File

@@ -70,13 +70,32 @@ namespace Tesses::CrossLang
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
{
auto txtFile = vfs->OpenFile(path,"rb");
if(txtFile == nullptr) return "";
Tesses::Framework::TextStreams::StreamReader reader(txtFile);
return reader.ReadToEnd();
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs,path);
}
return "";
}
static TObject FS_ReadAllLines(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
{
std::vector<std::string> lines;
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs,path,lines);
ls.GetGC()->BarrierBegin();
auto items = TList::Create(ls);
for(auto& l : lines) { items->Add(l);}
ls.GetGC()->BarrierEnd();
return items;
}
return nullptr;
}
static TObject FS_ReadAllBytes(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
@@ -84,15 +103,8 @@ namespace Tesses::CrossLang
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
{
auto txtFile = vfs->OpenFile(path,"rb");
if(txtFile == nullptr) return nullptr;
auto res = TByteArray::Create(ls);
std::array<uint8_t,1024> data;
size_t read;
do {
read = txtFile->ReadBlock(data.data(),data.size());
res->data.insert(res->data.end(),data.begin(),data.begin()+read);
} while(read != 0);
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs,path,res->data);
return res;
}
@@ -100,6 +112,27 @@ namespace Tesses::CrossLang
}
static TObject FS_WriteAllLines(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TList* lines;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,lines))
{
std::vector<std::string> content;
ls.GetGC()->BarrierBegin();
for(auto& item : lines->items)
{
if(std::holds_alternative<std::string>(item))
content.push_back(std::get<std::string>(item));
}
ls.GetGC()->BarrierEnd();
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs,path,content);
}
return nullptr;
}
static TObject FS_WriteAllText(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
@@ -109,10 +142,7 @@ namespace Tesses::CrossLang
std::string content;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content))
{
auto txtFile = vfs->OpenFile(path,"wb");
if(txtFile == nullptr) return nullptr;
Tesses::Framework::TextStreams::StreamWriter writer(txtFile);
writer.Write(content);
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs,path,content);
}
return nullptr;
}
@@ -125,10 +155,7 @@ namespace Tesses::CrossLang
TByteArray* bArray;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,bArray))
{
auto txtFile = vfs->OpenFile(path,"wb");
if(txtFile == nullptr) return nullptr;
txtFile->WriteBlock(bArray->data.data(),bArray->data.size());
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs,path,bArray->data);
}
return nullptr;
}
@@ -167,6 +194,9 @@ namespace Tesses::CrossLang
dict->DeclareFunction(gc, "ReadAllText","Read all text from file", {"fs","filename"},FS_ReadAllText);
dict->DeclareFunction(gc, "WriteAllText","Write all text to file", {"fs","filename","content"},FS_WriteAllText);
dict->DeclareFunction(gc, "ReadAllLines","Read all lines from file", {"fs","filename"},FS_ReadAllLines);
dict->DeclareFunction(gc, "WriteAllLines","Write all lines to file", {"fs","filename","lines"},FS_WriteAllLines);
dict->DeclareFunction(gc, "ReadAllBytes","Read all bytes from file", {"fs","filename"},FS_ReadAllBytes);
dict->DeclareFunction(gc, "WriteAllBytes","Write all bytes to file", {"fs","filename","content"},FS_WriteAllBytes);

View File

@@ -99,7 +99,7 @@ namespace Tesses::CrossLang
std::string value;
int64_t i64;
double d64;
TDateTime da;
std::shared_ptr<Tesses::Framework::Date::DateTime> da;
if(GetArgument(args,0,key) )
{
if(GetArgument(args,1,value))
@@ -109,7 +109,7 @@ namespace Tesses::CrossLang
else if(GetArgument(args,1,d64))
this->dict->AddValue(key, d64);
else if(GetArgument(args,1,da))
this->dict->AddValue(key, da.GetDate());
this->dict->AddValue(key, *da);
}
}
else if(key == "SetValue")
@@ -118,7 +118,7 @@ namespace Tesses::CrossLang
std::string value;
int64_t i64;
double d64;
TDateTime da;
std::shared_ptr<Tesses::Framework::Date::DateTime> da;
if(GetArgument(args,0,key) )
{
if(GetArgument(args,1,value))
@@ -128,7 +128,7 @@ namespace Tesses::CrossLang
else if(GetArgument(args,1,d64))
this->dict->SetValue(key, d64);
else if(GetArgument(args,1,da))
this->dict->SetValue(key, da.GetDate());
this->dict->SetValue(key, *da);
}
}
else if(key == "Clear")
@@ -185,7 +185,7 @@ namespace Tesses::CrossLang
Tesses::Framework::Date::DateTime value;
if(GetArgument(args,0,key) && dict->TryGetFirstDate(key,value))
{
return value;
return std::make_shared<Tesses::Framework::Date::DateTime>(value);
}
return nullptr;
}
@@ -373,9 +373,9 @@ namespace Tesses::CrossLang
}
else if(key == "WithLastModified")
{
TDateTime da;
std::shared_ptr<Tesses::Framework::Date::DateTime> da;
if(GetArgument(args,0,da))
ctx->WithLastModified(da.GetDate());
ctx->WithLastModified(*da);
return this;
}
else if(key == "WithContentDisposition")

View File

@@ -29,8 +29,19 @@
namespace Tesses::CrossLang
{
#if defined(_WIN32)
std::string SharedExtension = ".dll";
#elif defined(__APPLE__)
std::string SharedExtension = ".dylib";
#else
std::string SharedExtension = ".so";
#endif
class TMuxex : public TNativeObject
{
public:
@@ -60,330 +71,9 @@ namespace Tesses::CrossLang
}
};
class DocumentationParser : public TNativeObject
{
public:
std::vector<std::pair<std::string,TObject>> items;
DocumentationParser(std::string doc)
{
size_t i=0;
int state=-1;
std::string key={};
std::string value={};
auto add = [&]()->void{
if(value == "true") {
items.push_back(std::pair<std::string,TObject>(key,true));
} else if(value == "false") {
items.push_back(std::pair<std::string,TObject>(key,false));
} else if(value == "null") {
items.push_back(std::pair<std::string,TObject>(key,nullptr));
} else {
if(value[0] >= '0' && value[0] <= '9')
{
try {
if(value.find('.') != std::string::npos)
{
items.push_back(std::pair<std::string,TObject>(key,std::stod(value)));
}
else {
items.push_back(std::pair<std::string,TObject>(key,std::stoll(value)));
}
}catch(...) {}
}
else {
items.push_back(std::pair<std::string,TObject>(key,value));
}
}
};
auto ReadChr = [&]() -> std::pair<int,bool> {
int read=i < doc.size() ? (int)doc[i++] : -1;
if(read == -1)
{
return std::pair<int,bool>(-1,false);
}
if(read == '\\')
{
read = i < doc.size() ? (int)doc[i++] : -1;
if(read == -1)
{
return std::pair<int,bool>(-1,true);
}
else if(read == 'n')
{
return std::pair<int,bool>('\n',true);
}
else if(read == 'r')
{
return std::pair<int,bool>('\r',true);
}
else if(read == 'f')
{
return std::pair<int,bool>('\f',true);
}
else if(read == 'b')
{
return std::pair<int,bool>('\b',true);
}
else if(read == 'a')
{
return std::pair<int,bool>('\a',true);
}
else if(read == '0')
{
return std::pair<int,bool>('\0',true);
}
else if(read == 'v')
{
return std::pair<int,bool>('\v',true);
}
else if(read == 'e')
{
return std::pair<int,bool>('\x1B',true);
}
else if(read == 't')
{
return std::pair<int,bool>('\t',true);
}
else if(read == 'x')
{
int r1 = i < doc.size() ? (int)doc[i++] : -1;
if(r1 == -1)
{
return std::pair<int,bool>(-1,true);
}
int r2 = i < doc.size() ? (int)doc[i++] : -1;
if(r2 == -1)
{
return std::pair<int,bool>(-1,true);
}
uint8_t c = (uint8_t)std::stoi(std::string{(char)r1,(char)r2},nullptr,16);
return std::pair<int,bool>(c,true);
}
else
{
return std::pair<int,bool>(read,true);
}
}
else
{
return std::pair<int,bool>(read,false);
}
};
for(; i < doc.size(); i++)
{
if(doc[i] == '@')
{
state = 0;
key={};
value={};
if(i + 1 < doc.size())
{
if(doc[i+1] == '@')
{
i++;
continue;
}
else {
i++;
for(; i < doc.size(); i++)
{
switch(doc[i])
{
case '\'':
{
i++;
auto c = ReadChr();
i++;
if(c.first != -1)
{
if(state == 0)
key+={(char)c.first};
else {
this->items.push_back(std::pair<std::string,TObject>(key,(char)c.first));
state = -1;
goto outer;
}
}
}
break;
case '\"':
{
if(state == 0)
{
i++;
auto rChr = ReadChr();
while(rChr.first != '\"' || rChr.second)
{
if(rChr.first == -1) break;
key += (char)rChr.first;
rChr = ReadChr();
}
i--;
}
else {
i++;
auto rChr = ReadChr();
while(rChr.first != '\"' || rChr.second)
{
if(rChr.first == -1) break;
value += (char)rChr.first;
rChr = ReadChr();
}
this->items.push_back(std::pair<std::string,TObject>(key,value));
state = -1;
goto outer;
}
}
break;
case ' ':
case '\n':
case '\t':
case '\r':
if(state == 0 && !key.empty())
state=1;
else
if(state == 1 && !value.empty())
{
add();
state = -1;
goto outer;
}
break;
default:
if(state == 0) key += doc[i];
else value += doc[i];
break;
}
}
}
outer:;
}
}
}
if(state == 1 && !value.empty())
{
add();
}
}
TObject CallMethod(GCList& ls, std::string key, std::vector<TObject> args);
std::string TypeName()
{
return "DocumentationParser";
}
};
class DocumentationParserEnumerator : public TEnumerator
{
int index;
DocumentationParser* dict;
public:
static DocumentationParserEnumerator* Create(GCList& ls, DocumentationParser* dict)
{
auto dpe=new DocumentationParserEnumerator();
auto gc = ls.GetGC();
ls.Add(dpe);
gc->Watch(dpe);
dpe->dict = dict;
dpe->index=-1;
return dpe;
}
bool MoveNext(GC* ls)
{
ls->BarrierBegin();
bool r = ++index < this->dict->items.size();
ls->BarrierEnd();
return r;
}
TObject GetCurrent(GCList& ls)
{
std::pair<std::string,TObject> item;
ls.GetGC()->BarrierBegin();
if(this->index > -1 && this->index < this->dict->items.size())
{
item = this->dict->items[(size_t)this->index];
}
ls.GetGC()->BarrierEnd();
return TDictionary::Create(ls,{
TDItem("Key", item.first),
TDItem("Value", item.second)
});
}
void Mark()
{
if(this->marked) return;
this->marked=true;
dict->Mark();
}
};
TObject DocumentationParser::CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
{
std::string myKey;
if(key == "GetAt" && GetArgument(args,0,myKey))
{
for(auto item : this->items)
if(item.first == myKey) return item.second;
}
if(key == "ToString")
{
std::string n={};
for(auto item : this->items)
{
n.push_back('@');
n.append(item.first);
n.push_back(' ');
std::string str;
if(GetObject(item.second,str))
{
n.append(EscapeString(str,true));
}
else n.append(ToString(ls.GetGC(), item.second));
n.push_back('\n');
}
return n;
}
if(key == "GetEnumerator")
{
return DocumentationParserEnumerator::Create(ls,this);
}
return Undefined();
}
TObject New_DocumentationParser(GCList& ls, std::vector<TObject> args)
{
std::string doc;
if(GetArgument(args,0,doc))
{
return TNativeObject::Create<DocumentationParser>(ls, doc);
}
return Undefined();
}
#if defined(CROSSLANG_ENABLE_SHARED)
class DL {
@@ -771,10 +461,29 @@ namespace Tesses::CrossLang
}
#endif
Tesses::Framework::Filesystem::VFSPath GetPluginPath(Tesses::Framework::Filesystem::VFSPath path)
{
using namespace Tesses::Framework::Filesystem;
if(!path.relative) return path;
auto pluginConfigDir = GetCrossLangConfigDir() / "Plugins";
if(LocalFS->DirectoryExists(pluginConfigDir))
{
if(LocalFS->FileExists(pluginConfigDir / path + SharedExtension))
return pluginConfigDir / path + SharedExtension;
auto path2 = pluginConfigDir / path.GetParent() / "lib" + path.GetFileName() + SharedExtension;
if(LocalFS->FileExists(path2)) return path2;
}
return path;
}
void LoadPlugin(GC* gc, TRootEnvironment* env, Tesses::Framework::Filesystem::VFSPath sharedObjectPath)
{
#if defined(CROSSLANG_ENABLE_SHARED)
auto ptr = std::make_shared<DL>(sharedObjectPath);
auto ptr = std::make_shared<DL>(GetPluginPath(sharedObjectPath));
auto cb = ptr->Resolve<PluginFunction>("CrossLangPluginInit");
if(cb == nullptr) return;
gc->RegisterEverythingCallback([ptr,cb](GC* gc, TRootEnvironment* env)-> void{
@@ -857,8 +566,14 @@ namespace Tesses::CrossLang
static TObject TypeIsDateTime(GCList& ls, std::vector<TObject> args)
{
if(args.empty()) return nullptr;
TDateTime* dt;
return GetArgumentHeap(args,0,dt);
std::shared_ptr<Tesses::Framework::Date::DateTime> dt;
return GetArgument(args,0,dt);
}
static TObject TypeIsTimeSpan(GCList& ls, std::vector<TObject> args)
{
if(args.empty()) return nullptr;
std::shared_ptr<Tesses::Framework::Date::TimeSpan> dt;
return GetArgument(args,0,dt);
}
static TObject New_SubdirFilesystem(GCList& ls, std::vector<TObject> args)
{
@@ -905,6 +620,25 @@ namespace Tesses::CrossLang
}
return nullptr;
}
static TObject New_TempFS(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0,vfs))
{
bool deleteOnDispose=true;
GetArgument(args,1,deleteOnDispose);
return std::make_shared<Tesses::Framework::Filesystem::TempFS>(vfs,deleteOnDispose);
}
else {
bool deleteOnDispose;
if(GetArgument(args,0,deleteOnDispose))
{
return std::make_shared<Tesses::Framework::Filesystem::TempFS>(deleteOnDispose);
}
}
return std::make_shared<Tesses::Framework::Filesystem::TempFS>();
}
static TObject New_Stream(GCList& ls, std::vector<TObject> args)
{
TDictionary* dict;
@@ -921,8 +655,8 @@ namespace Tesses::CrossLang
{
if(args.size()==1)
{
Tesses::Framework::Date::DateTime dt(year);
return dt;
return std::make_shared<Tesses::Framework::Date::DateTime>(year);
}
else
{
@@ -940,12 +674,45 @@ namespace Tesses::CrossLang
GetArgument(args,6,isLocal);
Tesses::Framework::Date::DateTime dt((int)year,(int)month,(int)day,(int)hour,(int)minute,(int)second,isLocal);
return dt;
return std::make_shared<Tesses::Framework::Date::DateTime>((int)year,(int)month,(int)day,(int)hour,(int)minute,(int)second,isLocal);
}
}
return nullptr;
}
static TObject New_TimeSpan(GCList& ls, std::vector<TObject> args)
{
int64_t arg1;
if(GetArgument(args,0,arg1))
{
if(args.size()==1)
{
return std::make_shared<Tesses::Framework::Date::TimeSpan>(arg1);
}
else if(args.size() >= 3)
{
int64_t arg2;
int64_t arg3;
if(GetArgument(args,1,arg2) && GetArgument(args,2,arg3))
{
int64_t arg4;
if(GetArgument(args,3,arg4))
{
return std::make_shared<Tesses::Framework::Date::TimeSpan>((int)arg1,(int)arg2,(int)arg3,(int)arg4);
}
else
{
return std::make_shared<Tesses::Framework::Date::TimeSpan>((int)arg1,(int)arg2,(int)arg3);;
}
}
}
}
return nullptr;
}
std::string GetObjectTypeString(TObject _obj)
{
if(std::holds_alternative<std::regex>(_obj)) return "Regex";
@@ -960,7 +727,8 @@ namespace Tesses::CrossLang
if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(_obj)) return "Path";
if(std::holds_alternative<TVMVersion>(_obj)) return "Version";
if(std::holds_alternative<TDateTime>(_obj)) return "DateTime";
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(_obj)) return "DateTime";
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(_obj)) return "TimeSpan";
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::Stream>>(_obj))
{
auto strm = std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(_obj);
@@ -1003,15 +771,14 @@ namespace Tesses::CrossLang
if(vfs != nullptr)
{
auto localVFS = std::dynamic_pointer_cast<Tesses::Framework::Filesystem::LocalFilesystem>(vfs);
auto mountableVFS = std::dynamic_pointer_cast<Tesses::Framework::Filesystem::MountableFilesystem>(vfs);
auto subFS = std::dynamic_pointer_cast<Tesses::Framework::Filesystem::SubdirFilesystem>(vfs);
auto tempFS = std::dynamic_pointer_cast<Tesses::Framework::Filesystem::TempFS>(vfs);
if(localVFS != nullptr) return "LocalFilesystem";
if(subFS != nullptr) return "SubdirFilesystem";
if(mountableVFS != nullptr) return "MountableFilesystem";
if(tempFS != nullptr) return "TempFS";
}
@@ -1209,11 +976,11 @@ namespace Tesses::CrossLang
static TObject DateTime_getNow(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Date::DateTime::Now();
return std::make_shared<Tesses::Framework::Date::DateTime>(Tesses::Framework::Date::DateTime::Now());
}
static TObject DateTime_getNowUTC(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Date::DateTime::NowUTC();
return std::make_shared<Tesses::Framework::Date::DateTime>(Tesses::Framework::Date::DateTime::NowUTC());
}
static TObject DateTime_getNowEpoch(GCList& ls, std::vector<TObject> args)
{
@@ -1226,7 +993,7 @@ namespace Tesses::CrossLang
Tesses::Framework::Date::DateTime dt;
if(GetArgument(args,0,d) && Tesses::Framework::Date::DateTime::TryParseHttpDate(d,dt))
{
return dt;
return std::make_shared<Tesses::Framework::Date::DateTime>(dt);
}
return nullptr;
}
@@ -1234,6 +1001,56 @@ namespace Tesses::CrossLang
{
return TTask::Create(ls);
}
static TObject TimeSpan_Parse(GCList& ls, std::vector<TObject> args)
{
std::string t;
Tesses::Framework::Date::TimeSpan ts;
if(GetArgument(args,0,t) && Tesses::Framework::Date::TimeSpan::TryParse(t,ts))
{
return std::make_shared<Tesses::Framework::Date::TimeSpan>(ts);
}
return nullptr;
}
static TObject TimeSpan_FromSeconds(GCList& ls, std::vector<TObject> args)
{
int64_t n;
if(GetArgument(args,0,n))
{
return std::make_shared<Tesses::Framework::Date::TimeSpan>(n);
}
return nullptr;
}
static TObject TimeSpan_FromMinutes(GCList& ls, std::vector<TObject> args)
{
int64_t n;
if(GetArgument(args,0,n))
{
return std::make_shared<Tesses::Framework::Date::TimeSpan>(n*60);
}
return nullptr;
}
static TObject TimeSpan_FromHours(GCList& ls, std::vector<TObject> args)
{
int64_t n;
if(GetArgument(args,0,n))
{
return std::make_shared<Tesses::Framework::Date::TimeSpan>(n*3600);
}
return nullptr;
}
static TObject TimeSpan_FromDays(GCList& ls, std::vector<TObject> args)
{
int64_t n;
if(GetArgument(args,0,n))
{
return std::make_shared<Tesses::Framework::Date::TimeSpan>(n*86400);
}
return nullptr;
}
void TStd::RegisterRoot(GC* gc, TRootEnvironment* env)
{
GCList ls(gc);
@@ -1251,10 +1068,18 @@ namespace Tesses::CrossLang
date->DeclareFunction(gc, "TryParseHttpDate","Parse the http date",{},DateTime_TryParseHttpDate);
date->SetValue("Zone", (int64_t)Tesses::Framework::Date::GetTimeZone());
date->SetValue("SupportsDaylightSavings",Tesses::Framework::Date::TimeZoneSupportDST());
auto ts = env->EnsureDictionary(gc, "TimeSpan");
ts->DeclareFunction(gc, "Parse", "Parse timespan",{"tsStr"}, TimeSpan_Parse);
ts->DeclareFunction(gc,"FromSeconds","Create timespan from seconds", {"seconds"}, TimeSpan_FromSeconds);
ts->DeclareFunction(gc,"FromMinutes","Create timespan from minutes", {"minutes"}, TimeSpan_FromMinutes);
ts->DeclareFunction(gc,"FromHours","Create timespan from hours", {"hours"}, TimeSpan_FromHours);
ts->DeclareFunction(gc,"FromDays","Create timespan from days", {"days"}, TimeSpan_FromDays);
auto task = env->EnsureDictionary(gc,"Task");
task->DeclareFunction(gc,"AsyncClosure","Create async closure (internal for compiler to generate calls to)",{"closure"},[](GCList& ls, std::vector<TObject> args)->TObject {
@@ -1275,11 +1100,13 @@ namespace Tesses::CrossLang
TDictionary* newTypes = env->EnsureDictionary(gc, "New");
newTypes->DeclareFunction(gc, "DateTime","Create a DateTime object, if only one arg is provided year is epoch, isLocal defaults to true unless epoch",{"year","$month","$day","$hour","$minute","$second","$isLocal"},New_DateTime);
newTypes->DeclareFunction(gc, "TimeSpan","Create a DateTime object, if only one arg is provided days is totalSeconds, if there are only three arguments days will be hours, hours will be minutes, minutes will be seconds (according to the argument documentation)",{"days","$hours","$minutes","$seconds"},New_TimeSpan);
newTypes->DeclareFunction(gc, "MountableFilesystem","Create a mountable filesystem",{"root"}, New_MountableFilesystem);
newTypes->DeclareFunction(gc, "SubdirFilesystem","Create a subdir filesystem",{"fs","subdir"}, New_SubdirFilesystem);
newTypes->DeclareFunction(gc, "MemoryStream","Create a memory stream",{"writable"}, New_MemoryStream);
newTypes->DeclareFunction(gc, "Filesystem","Create filesystem", {"fs"},New_Filesystem);
newTypes->DeclareFunction(gc, "TempFS","Create a temp directory",{"",""}, New_TempFS);
newTypes->DeclareFunction(gc, "Stream","Create stream", {"strm"},New_Stream);
newTypes->DeclareFunction(gc, "MemoryFilesystem","Create in memory filesystem", {},New_MemoryFilesystem);
@@ -1326,7 +1153,7 @@ namespace Tesses::CrossLang
env->DeclareFunction(gc, "TypeIsStream","Get whether object is a stream",{"object"},TypeIsStream);
env->DeclareFunction(gc, "TypeIsVFS","Get whether object is a virtual filesystem",{"object"},TypeIsVFS);
env->DeclareFunction(gc, "TypeIsDateTime","Get whether object is a DateTime",{"object"},TypeIsDateTime);
env->DeclareFunction(gc, "TypeIsTimeSpan","Get whether object is a TimeSpan",{"object"},TypeIsTimeSpan);
newTypes->DeclareFunction(gc, "Regex", "Create regex object",{"regex"},[](GCList& ls,std::vector<TObject> args)->TObject {
@@ -1372,7 +1199,6 @@ namespace Tesses::CrossLang
newTypes->DeclareFunction(gc,"AArray","alias for new AssociativeArray",{},[](GCList& ls, std::vector<TObject> args)->TObject {
return TAssociativeArray::Create(ls);
});
newTypes->DeclareFunction(gc,"DocumentationParser","Parse documentation blocks",{"documentationString"},New_DocumentationParser);
newTypes->DeclareFunction(gc,"ByteArray","Create bytearray, with optional either size (to size it) or string argument (to fill byte array)",{"$data"},ByteArray);
newTypes->DeclareFunction(gc,"Task","Create a task for async, to manually create an async object",{},New_Task);

View File

@@ -1,23 +0,0 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TDateTime::TDateTime()
{
this->dt=new Tesses::Framework::Date::DateTime();
}
TDateTime::TDateTime(Tesses::Framework::Date::DateTime t)
{
this->dt = new Tesses::Framework::Date::DateTime(t);
}
TDateTime::TDateTime(const TDateTime& dt)
{
this->dt = new Tesses::Framework::Date::DateTime(*dt.dt);
}
Tesses::Framework::Date::DateTime& TDateTime::GetDate()
{
return *this->dt;
}
TDateTime::~TDateTime()
{
delete this->dt;
}
}

View File

@@ -476,14 +476,14 @@ namespace Tesses::CrossLang {
{
this->ls->GetGC()->BarrierBegin();
res = dict->GetValue("LastWrite");
TDateTime d;
std::shared_ptr<Tesses::Framework::Date::DateTime> d;
if(GetObject(res,d))
lastWrite =d.GetDate();
lastWrite =*d;
res = dict->GetValue("LastAccess");
if(GetObject(res,d))
lastWrite =d.GetDate();
lastWrite = *d;
this->ls->GetGC()->BarrierEnd();
}
@@ -497,7 +497,7 @@ namespace Tesses::CrossLang {
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "SetDate",{path,lastWrite,lastAccess});
dict->CallMethod(ls, "SetDate",{path,std::make_shared<Tesses::Framework::Date::DateTime>(lastWrite),std::make_shared<Tesses::Framework::Date::DateTime>(lastAccess)});
}
}

View File

@@ -45,12 +45,16 @@ namespace Tesses::CrossLang {
{
return std::get<char>(obj) != 0;
}
else if(std::holds_alternative<TDateTime>(obj))
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(obj))
{
auto& dt = std::get<TDateTime>(obj).GetDate();
return !(dt.Year() == 1970 && dt.Month() == 1 && dt.Day() == 1 && dt.Hour() == 0 && dt.Minute() == 0 && dt.Second() == 0 && !dt.IsLocal());
auto& dt = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(obj);
return !(dt->Year() == 1970 && dt->Month() == 1 && dt->Day() == 1 && dt->Hour() == 0 && dt->Minute() == 0 && dt->Second() == 0 && !dt->IsLocal());
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(obj))
{
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(obj)->TotalSeconds() != 0;
}
else if(std::holds_alternative<THeapObjectHolder>(obj))
{
auto o = std::get<THeapObjectHolder>(obj).obj;
@@ -60,7 +64,6 @@ namespace Tesses::CrossLang {
auto ba = dynamic_cast<TByteArray*>(o);
auto nat = dynamic_cast<TNative*>(o);
auto thrd = dynamic_cast<ThreadHandle*>(o);
auto dt = dynamic_cast<TDateTime*>(o);
auto natObj = dynamic_cast<TNativeObject*>(o);
auto any = dynamic_cast<TAny*>(o);
@@ -153,9 +156,13 @@ namespace Tesses::CrossLang {
{
return std::get<int64_t>(left) == std::get<char>(right);
}
else if(std::holds_alternative<TDateTime>(left) && std::holds_alternative<TDateTime>(right))
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
return std::get<TDateTime>(left).GetDate().ToEpoch() == std::get<TDateTime>(right).GetDate().ToEpoch();
return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left)->ToEpoch() == std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)->ToEpoch();
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left)->TotalSeconds() == std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)->TotalSeconds();
}
else if(std::holds_alternative<TVMVersion>(left) && std::holds_alternative<TVMVersion>(right))
{
@@ -457,6 +464,18 @@ namespace Tesses::CrossLang {
{
cse.back()->Push(gc, (int64_t)(std::get<int64_t>(left) - std::get<char>(right)));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::TimeSpan>((*l) - (*r)));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::DateTime>((*l) - (*r)));
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
auto obj = std::get<THeapObjectHolder>(left).obj;
@@ -1083,9 +1102,18 @@ namespace Tesses::CrossLang {
{
cse.back()->Push(gc, std::get<std::string>(left) < std::get<std::string>(right));
}
else if(std::holds_alternative<TDateTime>(left) && std::holds_alternative<TDateTime>(right))
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
cse.back()->Push(gc, std::get<TDateTime>(left).GetDate().ToEpoch() < std::get<TDateTime>(right).GetDate().ToEpoch());
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,l->ToEpoch() < r->ToEpoch());
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,l->TotalSeconds() < r->TotalSeconds());
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
@@ -1194,9 +1222,18 @@ namespace Tesses::CrossLang {
{
cse.back()->Push(gc, std::get<std::string>(left) > std::get<std::string>(right));
}
else if(std::holds_alternative<TDateTime>(left) && std::holds_alternative<TDateTime>(right))
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
cse.back()->Push(gc, std::get<TDateTime>(left).GetDate().ToEpoch() > std::get<TDateTime>(right).GetDate().ToEpoch());
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,l->ToEpoch() > r->ToEpoch());
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,l->TotalSeconds() > r->TotalSeconds());
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
@@ -1305,9 +1342,18 @@ namespace Tesses::CrossLang {
{
cse.back()->Push(gc, std::get<std::string>(left) <= std::get<std::string>(right));
}
else if(std::holds_alternative<TDateTime>(left) && std::holds_alternative<TDateTime>(right))
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
cse.back()->Push(gc, std::get<TDateTime>(left).GetDate().ToEpoch() <= std::get<TDateTime>(right).GetDate().ToEpoch());
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,l->ToEpoch() <= r->ToEpoch());
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,l->TotalSeconds() <= r->TotalSeconds());
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
@@ -1418,9 +1464,18 @@ namespace Tesses::CrossLang {
{
cse.back()->Push(gc, std::get<std::string>(left) >= std::get<std::string>(right));
}
else if(std::holds_alternative<TDateTime>(left) && std::holds_alternative<TDateTime>(right))
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
cse.back()->Push(gc, std::get<TDateTime>(left).GetDate().ToEpoch() >= std::get<TDateTime>(right).GetDate().ToEpoch());
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,l->ToEpoch() >= r->ToEpoch());
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,l->TotalSeconds() >= r->TotalSeconds());
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
@@ -1549,9 +1604,18 @@ namespace Tesses::CrossLang {
auto r = lver.CompareTo(rver);
cse.back()->Push(gc, r == 0);
}
else if(std::holds_alternative<TDateTime>(left) && std::holds_alternative<TDateTime>(right))
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
cse.back()->Push(gc, std::get<TDateTime>(left).GetDate().ToEpoch() == std::get<TDateTime>(right).GetDate().ToEpoch());
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,(l->ToEpoch() == r->ToEpoch()) && (l->IsLocal() == r->IsLocal()));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,l->TotalSeconds() == r->TotalSeconds());
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
@@ -1714,9 +1778,18 @@ namespace Tesses::CrossLang {
auto r = lver.CompareTo(rver);
cse.back()->Push(gc, r != 0);
}
else if(std::holds_alternative<TDateTime>(left) && std::holds_alternative<TDateTime>(right))
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
cse.back()->Push(gc, std::get<TDateTime>(left).GetDate().ToEpoch() != std::get<TDateTime>(right).GetDate().ToEpoch());
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,!((l->ToEpoch() == r->ToEpoch()) && (l->IsLocal() == r->IsLocal())));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,l->TotalSeconds() != r->TotalSeconds());
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
@@ -2262,6 +2335,24 @@ namespace Tesses::CrossLang {
{
cse.back()->Push(gc,std::get<int64_t>(left) + std::get<double>(right));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::TimeSpan>((*l) + (*r)));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
{
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
}
else if(std::holds_alternative<std::string>(left) && std::holds_alternative<std::string>(right))
{
std::string str={};
@@ -3224,9 +3315,24 @@ namespace Tesses::CrossLang {
cse.back()->Push(gc, Undefined());
return false;
}
else if(std::holds_alternative<TDateTime>(instance))
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(instance))
{
auto& date = std::get<TDateTime>(instance).GetDate();
auto& time = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(instance);
if(key == "ToString")
{
bool slim = false;
GetArgument(args,0,slim);
cse.back()->Push(gc, time->ToString(slim));
return false;
}
cse.back()->Push(gc, Undefined());
return false;
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(instance))
{
auto& date = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(instance);
if(key == "ToString")
@@ -3234,38 +3340,129 @@ namespace Tesses::CrossLang {
std::string fmt;
if(GetArgument(args,0,fmt))
{
cse.back()->Push(gc, date.ToString(fmt));
cse.back()->Push(gc, date->ToString(fmt));
}
else
{
cse.back()->Push(gc, date.ToString());
cse.back()->Push(gc, date->ToString());
}
return false;
}
if(key == "ToHttpDate")
{
cse.back()->Push(gc, date.ToHttpDate());
cse.back()->Push(gc, date->ToHttpDate());
return false;
}
if(key == "ToEpoch")
{
cse.back()->Push(gc, date.ToEpoch());
cse.back()->Push(gc, date->ToEpoch());
return false;
}
if(key == "ToLocal")
{
cse.back()->Push(gc, date.ToLocal());
cse.back()->Push(gc, std::make_shared<Tesses::Framework::Date::DateTime>(date->ToLocal()));
return false;
}
if(key == "ToUTC")
{
cse.back()->Push(gc, date.ToUTC());
cse.back()->Push(gc, std::make_shared<Tesses::Framework::Date::DateTime>(date->ToUTC()));
return false;
}
cse.back()->Push(gc, nullptr);
return false;
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::TextStreams::TextReader>>(instance))
{
auto textReader = std::get<std::shared_ptr<Tesses::Framework::TextStreams::TextReader>>(instance);
if(key == "Rewind")
{
cse.back()->Push(gc,textReader->Rewind());
return false;
}
if(key == "ReadBlock")
{
int64_t sz;
if(GetArgument(args,0,sz))
{
std::string block;
if(textReader->ReadBlock(block,(size_t)sz))
{
cse.back()->Push(gc, block);
return false;
}
}
cse.back()->Push(gc, nullptr);
return false;
}
if(key == "ReadChar")
{
cse.back()->Push(gc,(int64_t)textReader->ReadChar());
return false;
}
if(key == "ReadLine")
{
std::string line;
if(textReader->ReadLine(line))
{
cse.back()->Push(gc, line);
return false;
}
cse.back()->Push(gc, nullptr);
return false;
}
if(key == "ReadAllLines")
{
std::vector<std::string> lines;
textReader->ReadAllLines(lines);
gc->BarrierBegin();
TList* list = TList::Create(ls);
for(auto& item : lines) list->Add(item);
gc->BarrierEnd();
return list;
}
if(key == "ReadToEnd")
{
std::string text;
textReader->ReadToEnd(text);
cse.back()->Push(gc,text);
return false;
}
if(key == "CopyTo")
{
std::shared_ptr<Tesses::Framework::TextStreams::TextWriter> writer;
if(GetArgument(args,0,writer))
{
textReader->CopyTo(*writer);
}
}
cse.back()->Push(gc, Undefined());
return false;
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance))
{
auto textWriter=std::get<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance);
if(key == "Write")
{
if(args.size()>0)
textWriter->Write(ToString(gc,args[0]));
}
if(key == "WriteLine")
{
if(args.size()>0)
textWriter->WriteLine(ToString(gc,args[0]));
}
if(key == "WriteData")
{
if(args.size()>0)
{
auto s=ToString(gc,args[0]);
textWriter->WriteData(s.c_str(),s.size());
}
}
cse.back()->Push(gc, nullptr);
return false;
}
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance))
{
auto strm = std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance);
@@ -3697,11 +3894,11 @@ namespace Tesses::CrossLang {
if(key == "SetDate")
{
Tesses::Framework::Filesystem::VFSPath path;
TDateTime lastWrite;
TDateTime lastAccess;
std::shared_ptr<Tesses::Framework::Date::DateTime> lastWrite;
std::shared_ptr<Tesses::Framework::Date::DateTime> lastAccess;
if(GetArgumentAsPath(args,0,path) && GetArgument(args,1,lastWrite) && GetArgument(args,2,lastAccess))
{
vfs->SetDate(path,lastWrite.GetDate(), lastAccess.GetDate());
vfs->SetDate(path,*lastWrite, *lastAccess);
}
cse.back()->Push(gc, nullptr);
return false;
@@ -3718,8 +3915,8 @@ namespace Tesses::CrossLang {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("LastWrite", TDateTime(lastWrite));
dict->SetValue("LastAccess", TDateTime(lastAccess));
dict->SetValue("LastWrite", std::make_shared<Tesses::Framework::Date::DateTime>(lastWrite));
dict->SetValue("LastAccess", std::make_shared<Tesses::Framework::Date::DateTime>(lastAccess));
ls.GetGC()->BarrierEnd();
cse.back()->Push(gc, dict);
@@ -5364,6 +5561,33 @@ namespace Tesses::CrossLang {
cse.back()->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Filesystem::VFS>>(instance))
{
auto vfs = std::get<std::shared_ptr<Tesses::Framework::Filesystem::VFS>>(instance);
auto tmpFS=std::dynamic_pointer_cast<Tesses::Framework::Filesystem::TempFS>(vfs);
if(tmpFS)
{
if(key == "TempDirectoryName")
{
cse.back()->Push(gc,tmpFS->TempDirectoryName());
return false;
}
}
cse.back()->Push(gc,Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance))
{
auto writer = std::get<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance);
if(key == "NewLine")
{
cse.back()->Push(gc,writer->newline);
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance))
{
auto strm = std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance);
@@ -5373,7 +5597,7 @@ namespace Tesses::CrossLang {
if(key == "CanRead")
{
;
cse.back()->Push(gc, strm->CanRead());
return false;
@@ -5476,47 +5700,93 @@ namespace Tesses::CrossLang {
stk->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<TDateTime>(instance))
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(instance))
{
auto& date = std::get<TDateTime>(instance).GetDate();
auto time = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(instance);
if(key == "Days")
{
stk->Push(gc, (int64_t)time->Days());
return false;
}
if(key == "Hours")
{
stk->Push(gc, (int64_t)time->Hours());
return false;
}
if(key == "Minutes")
{
stk->Push(gc, (int64_t)time->Minutes());
return false;
}
if(key == "Seconds")
{
stk->Push(gc, (int64_t)time->Seconds());
return false;
}
if(key == "TotalHours")
{
stk->Push(gc, time->TotalHours());
return false;
}
if(key == "TotalMinutes")
{
stk->Push(gc, time->TotalMinutes());
return false;
}
if(key == "TotalSeconds")
{
stk->Push(gc, time->TotalSeconds());
return false;
}
stk->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(instance))
{
auto& date = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(instance);
if(key == "IsLocal")
{
stk->Push(gc, date.IsLocal());
stk->Push(gc, date->IsLocal());
return false;
}
if(key == "Year")
{
stk->Push(gc, (int64_t)date.Year());
stk->Push(gc, (int64_t)date->Year());
return false;
}
if(key == "Month")
{
stk->Push(gc, (int64_t)date.Month());
stk->Push(gc, (int64_t)date->Month());
return false;
}
if(key == "Day")
{
stk->Push(gc, (int64_t)date.Day());
stk->Push(gc, (int64_t)date->Day());
return false;
}
if(key == "Hour")
{
stk->Push(gc, (int64_t)date.Hour());
stk->Push(gc, (int64_t)date->Hour());
return false;
}
if(key == "Minute")
{
stk->Push(gc, (int64_t)date.Minute());
stk->Push(gc, (int64_t)date->Minute());
return false;
}
if(key == "Second")
{
stk->Push(gc, (int64_t)date.Second());
stk->Push(gc, (int64_t)date->Second());
return false;
}
if(key == "DayOfWeek")
{
stk->Push(gc, (int64_t)date.DayOfWeek());
stk->Push(gc, (int64_t)date->DayOfWeek());
return false;
}
@@ -5971,6 +6241,21 @@ namespace Tesses::CrossLang {
}
std::string key = std::get<std::string>(_key);
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance))
{
auto writer = std::get<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance);
if(key == "NewLine")
{
if(std::holds_alternative<std::string>(value))
{
writer->newline = std::get<std::string>(value);
}
cse.back()->Push(gc,writer->newline);
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance))
{
auto strm = std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance);
@@ -7604,9 +7889,13 @@ namespace Tesses::CrossLang {
{
return std::get<bool>(o) ? "true" : "false";
}
if(std::holds_alternative<TDateTime>(o))
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(o))
{
return std::get<TDateTime>(o).GetDate().ToString();
return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(o)->ToString();
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(o))
{
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(o)->ToString(false);
}
if(std::holds_alternative<THeapObjectHolder>(o))
{