diff --git a/.vscode/launch.json b/.vscode/launch.json index 076c6ce..1b95120 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,8 +8,8 @@ "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/build/crossint", - "args": ["/home/mike/crossint.tcross"], + "program": "${workspaceFolder}/builds/linux/crosslang", + "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], diff --git a/CMakeLists.txt b/CMakeLists.txt index 797eaf4..ee9a096 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,14 @@ cmake_minimum_required(VERSION 3.20) -project(TessesCrossLang) +project(TessesCrossLang VERSION 1.0) set(CMAKE_CXX_STANDARD 20) + set(ENABLE_TESTING OFF) option(CROSSLANG_ENABLE_STATIC "Enable Tesses CrossLang static libraries" ON) option(CROSSLANG_ENABLE_SHARED "Enable Tesses CrossLang shared libraries" ON) option(CROSSLANG_ENABLE_BINARIES "Enable Tesses CrossLang binaries" ON) +option(CROSSLANG_INSTALL_DEVELOPMENT "Enable Tesses CrossLang development files" ON) option(CROSSLANG_ENABLE_THREADING "Enable Tesses CrossLang threading" ON) option(CROSSLANG_ENABLE_SQLITE "Enable sqlite (Embedded database, supports Wii)" ON) option(CROSSLANG_ENABLE_JSON "Enable JSON" ON) @@ -16,10 +18,9 @@ option(CROSSLANG_ENABLE_TERMIOS "Enable termios (For changing terminal options)" -set(JANSSON_DIR "Directory for Jansson" CACHE PATH "Jansson directory") +set(JANSSON_DIR "" CACHE PATH "Directory for Jansson") find_package(TessesFramework REQUIRED) - function(CROSSLANG_LINK_DEPS CROSSLANG_TARGET_NAME) if(CROSSLANG_ENABLE_PROCESS) target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_PROCESS) @@ -67,12 +68,13 @@ endif() if("${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoWii") target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC wiisocket) endif() - -target_include_directories(${CROSSLANG_TARGET_NAME} PUBLIC include) -target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC TessesFramework::tessesframework) +target_include_directories(${CROSSLANG_TARGET_NAME} + PUBLIC + "$" + "$" +) endfunction() - list(APPEND CROSSLANG_SOURCE src/compiler/codegen.cpp src/compiler/lexer.cpp @@ -114,23 +116,68 @@ list(APPEND CROSSLANG_SOURCE src/sqlite/sqlite3.c src/sqlite/vfs.c) endif() + +include(GNUInstallDirs) + if(CROSSLANG_ENABLE_STATIC) + add_library(crosslang_static STATIC ${CROSSLANG_SOURCE}) +target_link_libraries(crosslang_static PUBLIC TessesFramework::tessesframework) CROSSLANG_LINK_DEPS(crosslang_static) -install(TARGETS crosslang_static DESTINATION lib) +list(APPEND TessesCrossLangLibs crosslang_static) endif() -#if(CROSSLANG_ENABLE_SHARED) -#add_library(crosslang_shared SHARED ${CROSSLANG_SOURCE}) -#CROSSLANG_LINK_DEPS(crosslang_shared) -#install(TARGETS crosslang_shared DESTINATION lib) -#endif() +if(CROSSLANG_ENABLE_SHARED) +add_library(crosslang_shared SHARED ${CROSSLANG_SOURCE}) +CROSSLANG_LINK_DEPS(crosslang_shared) +target_link_libraries(crosslang_shared PUBLIC TessesFramework::tessesframework_shared) +list(APPEND TessesCrossLangLibs crosslang_shared) +endif() + + + + +if(CROSSLANG_INSTALL_DEVELOPMENT) +install(TARGETS ${TessesCrossLangLibs} + EXPORT TessesCrossLangTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +install(FILES include/CrossLang.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +install(EXPORT TessesCrossLangTargets + FILE TessesCrossLangTargets.cmake + NAMESPACE TessesCrossLang:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang +) + + +include(CMakePackageConfigHelpers) +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake" +INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang) + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake" +DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang) +endif() if(CROSSLANG_ENABLE_BINARIES) +if(CROSSLANG_ENABLE_SHARED) +add_executable(crossc src/crosslangcompiler.cpp) +add_executable(crossvm src/crosslangvm.cpp) +add_executable(crossint src/crosslanginterperter.cpp) +add_executable(crossdump src/crosslangdump.cpp) +add_executable(crosslang src/crosslang.cpp) +target_link_libraries(crossc PUBLIC crosslang_shared) +target_link_libraries(crossvm PUBLIC crosslang_shared) +target_link_libraries(crossint PUBLIC crosslang_shared) +target_link_libraries(crossdump PUBLIC crosslang_shared) +target_link_libraries(crosslang PUBLIC crosslang_shared) +elseif(CROSSLANG_ENABLE_STATIC) - -if(CROSSLANG_ENABLE_STATIC) add_executable(crossc src/crosslangcompiler.cpp) add_executable(crossvm src/crosslangvm.cpp) add_executable(crossint src/crosslanginterperter.cpp) @@ -141,25 +188,17 @@ target_link_libraries(crossvm PUBLIC crosslang_static) target_link_libraries(crossint PUBLIC crosslang_static) target_link_libraries(crossdump PUBLIC crosslang_static) target_link_libraries(crosslang PUBLIC crosslang_static) -#elseif(CROSSLANG_ENABLE_SHARED) -#add_executable(crossc src/crosslangcompiler.cpp) -#add_executable(crossvm src/crosslangvm.cpp) -#add_executable(crossint src/crosslanginterperter.cpp) -#target_link_libraries(crossc PUBLIC crosslang_shared) -#target_link_libraries(crossvm PUBLIC crosslang_shared) -#target_link_libraries(crossint PUBLIC crosslang_shared) else() add_executable(crossc src/crosslangcompiler.cpp ${CROSSLANG_SOURCE}) add_executable(crossvm src/crosslangvm.cpp ${CROSSLANG_SOURCE}) add_executable(crossint src/crosslanginterperter.cpp ${CROSSLANG_SOURCE}) add_executable(crossdump src/crosslangdump.cpp ${CROSSLANG_SOURCE}) add_executable(crosslang src/crosslang.cpp ${CROSSLANG_SOURCE}) - CROSSLANG_LINK_DEPS(crossc) CROSSLANG_LINK_DEPS(crossvm) CROSSLANG_LINK_DEPS(crossint) CROSSLANG_LINK_DEPS(crosslang) - +CROSSLANG_LINK_DEPS(crossdump) endif() install(TARGETS crossc DESTINATION bin) install(TARGETS crossvm DESTINATION bin) @@ -167,12 +206,9 @@ install(TARGETS crossint DESTINATION bin) install(TARGETS crossdump DESTINATION bin) install(TARGETS crosslang DESTINATION bin) endif() - -install(FILES ${PROJECT_SOURCE_DIR}/include/CrossLang.hpp DESTINATION include) - include(InstallRequiredSystemLibraries) set(CPACK_PACKAGE_CONTACT "Mike Nolan ") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md") set(CPACK_PACKAGE_VERSION_MAJOR "${TessesCrossLang_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${TessesCrossLang_VERSION_MINOR}") -include(CPack) +include(CPack) \ No newline at end of file diff --git a/Config.cmake.in b/Config.cmake.in new file mode 100644 index 0000000..e3b6488 --- /dev/null +++ b/Config.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/TessesCrossLangTargets.cmake") + +check_required_components(TessesCrossLang) diff --git a/Dockerfile b/Dockerfile index 8b2cf28..f7ca659 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ RUN apt update -y && \ apt clean -y && \ rm -rf /var/lib/apt/lists/* WORKDIR /tmp -RUN git clone https://gitea.site.tesses.net/tesses50/tesses-framework && cd tesses-framework && mkdir build && cd build && cmake -S .. -B . && make -j4 && make install && cd /tmp && rm -r /tmp/tesses-framework +RUN git clone https://gitea.site.tesses.net/tesses50/tesses-framework && cd tesses-framework && mkdir build && cd build && cmake -S .. -B . && make -j4 && make install && cd /tmp && rm -r /tmp/tesses-framework COPY . /src WORKDIR /src RUN mkdir build && cd build && cmake -S .. -B . && make -j4 && make install && cd / && rm -r /src diff --git a/src/crosslang.cpp b/src/crosslang.cpp index f92c10f..3e6326e 100644 --- a/src/crosslang.cpp +++ b/src/crosslang.cpp @@ -17,8 +17,9 @@ int main(int argc, char** argv) Tesses::Framework::Filesystem::LocalFilesystem fs; GC gc; gc.Start(); - GCList ls(gc); + tryAgain: + GCList ls(gc); TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); @@ -29,13 +30,13 @@ int main(int argc, char** argv) else { tryAgainFast: - std::cout << "File " << filename.ToString() << " not found, do you want to download the installer from: https://crosslang.tesseslanguage.com/crosslang-shell-install.tcross (this will install other stuff as well) (Y/n)? "; + std::cout << "File " << filename.ToString() << " not found, do you want to download the installer from: https://gitea.site.tesses.net/tesses50/crosslang-libs/raw/branch/master/crosslang-shell-install.tcross (this may install other stuff as well) (Y/n)? "; std::string line; std::getline(std::cin,line); if(line == "Y" || line == "y") { HttpRequest req; - req.url = "https://crosslang.tesseslanguage.com/crosslang-shell-install.tcross"; + req.url = "https://gitea.site.tesses.net/tesses50/crosslang-libs/raw/branch/master/crosslang-shell-install.tcross"; req.method = "GET"; HttpResponse resp(req); if(resp.statusCode == StatusCode::OK) @@ -74,4 +75,4 @@ int main(int argc, char** argv) if(GetObject(res,iresult)) return (int)iresult; return 0; -} \ No newline at end of file +} diff --git a/src/runtime_methods/io.cpp b/src/runtime_methods/io.cpp index d3e1fb9..602b521 100644 --- a/src/runtime_methods/io.cpp +++ b/src/runtime_methods/io.cpp @@ -54,6 +54,23 @@ namespace Tesses::CrossLang } return nullptr; } + static TObject FS_MakeFull(GCList& ls, std::vector args) + { + Tesses::Framework::Filesystem::VFSPath path; + if(GetArgumentAsPath(args,0,path)) + { + if(path.relative) + { + Tesses::Framework::Filesystem::LocalFilesystem lfs; + auto curDir = std::filesystem::current_path(); + auto myPath = lfs.SystemToVFSPath(curDir.string()) / path; + myPath = myPath.CollapseRelativeParents(); + return myPath; + } + return path.CollapseRelativeParents(); + } + return nullptr; + } void TStd::RegisterIO(GC* gc,TRootEnvironment* env,bool enableLocalFilesystem) { @@ -68,6 +85,7 @@ namespace Tesses::CrossLang TVFSHeapObject* vfs = TVFSHeapObject::Create(ls, new Tesses::Framework::Filesystem::LocalFilesystem()); dict->SetValue("Local", vfs); + dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},FS_MakeFull); } dict->DeclareFunction(gc, "MountableFilesystem","Create a mountable filesystem",{"root"}, FS_MountableFilesystem); diff --git a/src/types/rootenvironment.cpp b/src/types/rootenvironment.cpp index d4063ac..ebe21f2 100644 --- a/src/types/rootenvironment.cpp +++ b/src/types/rootenvironment.cpp @@ -1,5 +1,5 @@ #include "CrossLang.hpp" - +#include namespace Tesses::CrossLang { void TRootEnvironment::LoadDependency(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, std::pair dep) { @@ -14,7 +14,6 @@ namespace Tesses::CrossLang { Tesses::Framework::Streams::Stream* file; - if(vfs->RegularFileExists(filename) && (file = vfs->OpenFile(filename,"rb")) != nullptr) { @@ -159,7 +158,7 @@ namespace Tesses::CrossLang { TFile* f = TFile::Create(ls); f->Load(gc, file); Tesses::Framework::Filesystem::SubdirFilesystem dir(vfs,path.GetParent(),false); - LoadFileWithDependencies(gc,vfs,f); + LoadFileWithDependencies(gc,&dir,f); } else throw VMException("Could not open file: \"" + path.GetFileName() + "\"."); diff --git a/src/types/vfsheapobject.cpp b/src/types/vfsheapobject.cpp index 9e05aeb..a32ad1d 100644 --- a/src/types/vfsheapobject.cpp +++ b/src/types/vfsheapobject.cpp @@ -201,7 +201,9 @@ namespace Tesses::CrossLang { return out; } } + return false; } + bool TObjectVFS::SymlinkExists(Tesses::Framework::Filesystem::VFSPath path) { TVFSHeapObject* vfs; @@ -220,6 +222,7 @@ namespace Tesses::CrossLang { return out; } } + return false; } bool TObjectVFS::CharacterDeviceExists(Tesses::Framework::Filesystem::VFSPath path) { @@ -239,6 +242,7 @@ namespace Tesses::CrossLang { return out; } } + return false; } bool TObjectVFS::BlockDeviceExists(Tesses::Framework::Filesystem::VFSPath path) { @@ -258,6 +262,7 @@ namespace Tesses::CrossLang { return out; } } + return false; } bool TObjectVFS::SocketFileExists(Tesses::Framework::Filesystem::VFSPath path) { @@ -277,6 +282,7 @@ namespace Tesses::CrossLang { return out; } } + return false; } bool TObjectVFS::FIFOFileExists(Tesses::Framework::Filesystem::VFSPath path) { @@ -296,6 +302,7 @@ namespace Tesses::CrossLang { return out; } } + return false; } bool TObjectVFS::FileExists(Tesses::Framework::Filesystem::VFSPath path) { @@ -315,6 +322,7 @@ namespace Tesses::CrossLang { return out; } } + return false; } bool TObjectVFS::SpecialFileExists(Tesses::Framework::Filesystem::VFSPath path) { @@ -334,6 +342,7 @@ namespace Tesses::CrossLang { return out; } } + return false; } void TObjectVFS::CreateSymlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath symlinkFile) { @@ -383,6 +392,7 @@ namespace Tesses::CrossLang { return out; } } + return false; } void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path) { @@ -450,6 +460,7 @@ namespace Tesses::CrossLang { delete ls; }); } + return Tesses::Framework::Filesystem::VFSPathEnumerator(); } void TObjectVFS::MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest) { diff --git a/src/vm/vm.cpp b/src/vm/vm.cpp index f76962b..f6fe302 100644 --- a/src/vm/vm.cpp +++ b/src/vm/vm.cpp @@ -1535,6 +1535,42 @@ namespace Tesses::CrossLang { else if(std::holds_alternative(instance)) { std::string str = std::get(instance); + if(key == "IndexOf") + { + char c; + if(GetArgument(args,0,c)) + { + int64_t index = 0; + GetArgument(args,1,index); + + auto res = str.find_first_of(c,(std::size_t)index); + if(res == std::string::npos) + cse.back()->Push(gc, (int64_t)-1); + else + cse.back()->Push(gc, (int64_t)res); + return false; + } + cse.back()->Push(gc,nullptr); + return false; + } + if(key == "LastIndexOf") + { + char c; + if(GetArgument(args,0,c)) + { + int64_t index = str.size(); + GetArgument(args,1,index); + + auto res = str.find_last_of(c,(std::size_t)index); + if(res == std::string::npos) + cse.back()->Push(gc, (int64_t)-1); + else + cse.back()->Push(gc, (int64_t)res); + return false; + } + cse.back()->Push(gc,nullptr); + return false; + } if(key == "GetEnumerator") { cse.back()->Push(gc, TStringEnumerator::Create(ls,str)); @@ -1721,7 +1757,51 @@ namespace Tesses::CrossLang { //TStd::RegisterSqlite //TStd::RegisterVM auto myEnv = cse.back()->env->GetRootEnvironment(); + if(key == "RegisterEverything") + { + if(myEnv->permissions.canRegisterConsole && !rootEnv->permissions.locked) + TStd::RegisterConsole(gc, rootEnv); + + if(myEnv->permissions.canRegisterCrypto && !rootEnv->permissions.locked) + TStd::RegisterCrypto(gc, rootEnv); + + if(myEnv->permissions.canRegisterDictionary && !rootEnv->permissions.locked) + TStd::RegisterDictionary(gc, rootEnv); + + if(myEnv->permissions.canRegisterEnv && !rootEnv->permissions.locked) + TStd::RegisterDictionary(gc, rootEnv); + + + if(myEnv->permissions.canRegisterIO && !rootEnv->permissions.locked) + TStd::RegisterIO(gc, rootEnv, myEnv->permissions.canRegisterLocalFS); + if(myEnv->permissions.canRegisterJSON && !rootEnv->permissions.locked) + TStd::RegisterJson(gc, rootEnv); + + if(myEnv->permissions.canRegisterNet && !rootEnv->permissions.locked) + TStd::RegisterNet(gc, rootEnv); + + if(myEnv->permissions.canRegisterOGC && !rootEnv->permissions.locked) + TStd::RegisterOGC(gc, rootEnv); + + if(myEnv->permissions.canRegisterPath && !rootEnv->permissions.locked) + TStd::RegisterPath(gc, rootEnv); + + if(myEnv->permissions.canRegisterRoot && !rootEnv->permissions.locked) + TStd::RegisterRoot(gc, rootEnv); + + if(myEnv->permissions.canRegisterSDL2 && !rootEnv->permissions.locked) + TStd::RegisterSDL2(gc, rootEnv); + + if(myEnv->permissions.canRegisterSqlite && !rootEnv->permissions.locked) + TStd::RegisterSqlite(gc, rootEnv); + + if(myEnv->permissions.canRegisterVM && !rootEnv->permissions.locked) + TStd::RegisterVM(gc, rootEnv); + + cse.back()->Push(gc,nullptr); + return false; + } if(key == "RegisterConsole") { if(myEnv->permissions.canRegisterConsole && !rootEnv->permissions.locked) @@ -1779,7 +1859,7 @@ namespace Tesses::CrossLang { if(key == "RegisterOGC") { if(myEnv->permissions.canRegisterOGC && !rootEnv->permissions.locked) - TStd::RegisterNet(gc, rootEnv); + TStd::RegisterOGC(gc, rootEnv); cse.back()->Push(gc,nullptr); return false; } @@ -2623,7 +2703,7 @@ namespace Tesses::CrossLang { } - if(key == "GetAt") + if(key == "SetAt") { if(args.size() != 2) {