9 Commits

Author SHA1 Message Date
bdbdfde646 Fix a security vulerability in crossdump that is supposed to use uint32_t but accidently used uint8_t, set to tessesframework=0.0.5
All checks were successful
Build and Deploy on Tag / build-arch (push) Successful in 1m18s
Build and Deploy on Tag / update-tap (push) Successful in 4m8s
2026-06-01 06:49:08 -05:00
62e316b022 Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
All checks were successful
Build and Deploy on Tag / build-arch (push) Successful in 1m22s
Build and Deploy on Tag / update-tap (push) Successful in 4m16s
2026-05-29 21:13:21 -05:00
17e4ca9410 Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
Some checks failed
Build and Deploy on Tag / build-arch (push) Failing after 16s
Build and Deploy on Tag / update-tap (push) Has been cancelled
2026-05-29 21:04:56 -05:00
dcbc58481e Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
Some checks failed
Build and Deploy on Tag / build-arch (push) Failing after 55s
Build and Deploy on Tag / update-tap (push) Has been cancelled
2026-05-29 20:58:44 -05:00
abea319ea0 Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs 2026-05-29 20:52:26 -05:00
d26e357448 Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable
All checks were successful
Build and Deploy on Tag / update-tap (push) Successful in 7m1s
Build and Deploy on Tag / build-arch (push) Successful in 22m2s
2026-05-08 23:48:24 -05:00
2608e94192 Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable
Some checks failed
Build and Deploy on Tag / update-tap (push) Has been cancelled
Build and Deploy on Tag / build-arch (push) Has been cancelled
2026-05-08 23:24:57 -05:00
0f0e47003c Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable
Some checks failed
Build and Deploy on Tag / build-arch (push) Failing after 2m10s
Build and Deploy on Tag / update-tap (push) Has been cancelled
2026-05-08 23:14:10 -05:00
7008a6ae61 Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable 2026-05-08 23:10:20 -05:00
111 changed files with 25773 additions and 30144 deletions

321
.clang-format Normal file
View File

@@ -0,0 +1,321 @@
---
Language: Cpp
AlignAfterOpenBracket: true
AccessModifierOffset: -2
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: true
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
AlignPPAndNotPP: true
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowBreakBeforeQtProperty: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AllowShortNamespacesOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AttributeMacros:
- __capability
BinPackArguments: true
BinPackLongBracedList: true
BinPackParameters: BinPack
BitFieldColonSpacing: Both
BracedInitializerIndentWidth: -1
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterOpenBracketBracedList: false
BreakAfterOpenBracketFunction: false
BreakAfterOpenBracketIf: false
BreakAfterOpenBracketLoop: false
BreakAfterOpenBracketSwitch: false
BreakAfterReturnType: None
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeCloseBracketBracedList: false
BreakBeforeCloseBracketFunction: false
BreakBeforeCloseBracketIf: false
BreakBeforeCloseBracketLoop: false
BreakBeforeCloseBracketSwitch: false
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTemplateCloser: false
BreakBeforeTernaryOperators: true
BreakBinaryOperations: Never
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
BreakTemplateDeclarations: MultiLine
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: AlignFirstComment
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
EnumTrailingComma: Leave
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExportBlock: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigitsInsert: 0
BinaryMaxDigitsRemove: 0
Decimal: 0
DecimalMinDigitsInsert: 0
DecimalMaxDigitsRemove: 0
Hex: 0
HexMinDigitsInsert: 0
HexMaxDigitsRemove: 0
BinaryMinDigits: 0
DecimalMinDigits: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: true
AtStartOfFile: true
KeepFormFeed: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
NumericLiteralCase:
ExponentLetter: Leave
HexDigit: Leave
Prefix: Leave
Suffix: Leave
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
OneLineFormatOffRegex: ''
PackConstructorInitializers: BinPack
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakBeforeMemberAccess: 150
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
PPIndentWidth: -1
QualifierAlignment: Leave
ReferenceAlignment: Pointer
ReflowComments: Always
RemoveBracesLLVM: false
RemoveEmptyLinesInUnwrappedLines: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes:
Enabled: true
IgnoreCase: false
IgnoreExtension: false
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterOperatorKeyword: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterNot: false
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBraces: Never
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
WrapNamespaceBodyWithEmptyLines: Leave
...

View File

@@ -21,7 +21,7 @@ jobs:
- run: pacman-key --config /opt/cross/ppc/pacman.conf --add /root/repository.key
- run: printf "[tesses50.git.tesses.org]\nSigLevel = Optional TrustAll\nServer = https://git.tesses.org/api/packages/tesses50/arch/core/\$arch\n" >> /etc/pacman.conf
- run: printf "[tesses50.git.tesses.org]\nSigLevel = Optional TrustAll\nServer = https://git.tesses.org/api/packages/tesses50/arch/core/\$arch\n" >> /opt/cross/ppc/pacman.conf
- run: pacman --noconfirm -Sy mbedtls curl tessesframework zip zig ninja
- run: pacman --noconfirm -Sy mbedtls tessesframework zip zig ninja
- run: pacman --config /opt/cross/ppc/pacman.conf --noconfirm -Sy mbedtls tessesframework
- run: cp Packaging/Linux/PKGBUILD /home/build/PKGBUILD
- run: cp Packaging/Linux/build-arch.sh /home/build/build-arch.sh
@@ -29,7 +29,6 @@ jobs:
- run: chown build:build /home/build/PKGBUILD
- run: chown build:build /home/build/build-arch.sh
- run: su build -c /home/build/build-arch.sh
- run: env -C Packaging/Slim bash build.sh
- uses: akkuman/gitea-release-action@v1
env:
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
@@ -39,9 +38,20 @@ jobs:
artifacts/**
update-tap:
runs-on: ubuntu-latest
runs-on: global-container-mingw
steps:
- uses: actions/checkout@v4
- run: |
mkdir -p artifacts
env -C Packaging/Windows bash build.sh
- uses: akkuman/gitea-release-action@v1
env:
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
with:
prerelease: true
files: |-
artifacts/**
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to registry

6
.vscode/launch.json vendored
View File

@@ -8,10 +8,10 @@
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/builds/linux/crosslang",
"args": ["token"],
"program": "${workspaceFolder}/builds/l/crossint",
"args": ["queryable.tcross"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"cwd": "${workspaceFolder}/builds/l",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",

View File

@@ -88,7 +88,8 @@
"clangd.fallbackFlags": [
"-I${workspaceFolder}/include",
"-I/home/mike/tmp-crosslang/usr/local/include/"
]
],
"editor.formatOnSave": true
}

View File

@@ -1,188 +1,35 @@
cmake_minimum_required(VERSION 3.16)
include(cmake/version.cmake)
include(cmake/options.cmake)
project(TessesCrossLang VERSION ${CROSSLANG_MAJOR_VERSION}.${CROSSLANG_MINOR_VERSION}.${CROSSLANG_PATCH_VERSION})
set(CMAKE_CXX_STANDARD 17)
include(CMakePackageConfigHelpers)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if(CROSSLANG_CUSTOM_CONSOLE)
set(CROSSLANG_ENABLE_BINARIES OFF)
set(CROSSLANG_ENABLE_SHARED OFF)
endif()
if(CROSSLANG_FETCHCONTENT)
set(TESSESFRAMEWORK_ENABLE_EXAMPLES OFF)
set(TESSESFRAMEWORK_ENABLE_APPS OFF)
if(NOT TESSESFRAMEWORK_ENABLE_SHARED)
set(CROSSLANG_ENABLE_SHARED OFF)
endif()
if(NOT TESSESFRAMEWORK_ENABLE_STATIC)
set(CROSSLANG_ENABLE_STATIC OFF)
endif()
if(NOT TESSESFRAMEWORK_ENABLE_RPATH)
set(CROSSLANG_ENABLE_RPATH OFF)
endif()
#set(CROSSLANG_ENABLE_SHARED OFF)
#set(TESSESFRAMEWORK_ENABLE_SHARED OFF)
#set(CROSSLANG_SHARED_EXECUTABLES OFF)
include(GNUInstallDirs)
include(CheckLibraryExists)
include(FetchContent)
FetchContent_Declare(
TessesFramework
GIT_REPOSITORY https://git.tesses.org/tesses50/tessesframework.git
)
FetchContent_MakeAvailable(TessesFramework)
list(APPEND TessesCrossLangLibs ${TessesFrameworkTargets})
else()
find_package(TessesFramework REQUIRED)
endif()
include(cmake/sources.cmake)
include(cmake/options.cmake)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if(CROSSLANG_ENABLE_FFI)
find_package(PkgConfig)
endif()
include(cmake/linkdeps.cmake)
if(CROSSLANG_ENABLE_FFI AND CROSSLANG_ENABLE_SHARED)
pkg_check_modules(LIBFFI REQUIRED IMPORTED_TARGET libffi)
endif()
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/CrossLangVersion.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h"
INSTALL_DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/CrossLangVersion.h)
include(cmake/findtf.cmake)
include(cmake/sources.cmake)
if(CROSSLANG_OFFLINE_SHELL_PACKAGE STREQUAL "")
include(cmake/cpack.cmake)
if(CROSSLANG_STATIC)
include(cmake/staticlib.cmake)
else()
install(FILES ${CROSSLANG_OFFLINE_SHELL_PACKAGE} DESTINATION share/Tesses/CrossLang)
include(cmake/sharedlib.cmake)
endif()
if(MINGW)
list(APPEND CROSSLANG_WIN32_EXE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/winicon.rc")
if(MINGW)
ENABLE_LANGUAGE(RC)
endif(MINGW)
endif()
include(cmake/install-dev.cmake)
include(cmake/app.cmake)
include(GNUInstallDirs)
if(CROSSLANG_ENABLE_STATIC)
add_library(crosslang_static STATIC ${CROSSLANG_SOURCE})
CROSSLANG_LINK_DEPS(crosslang_static)
if(CROSSLANG_FETCHCONTENT)
target_link_libraries(crosslang_static PUBLIC tessesframework)
else()
target_link_libraries(crosslang_static PUBLIC TessesFramework::tessesframework)
endif()
list(APPEND TessesCrossLangLibs crosslang_static)
endif()
if(CROSSLANG_ENABLE_SHARED)
add_library(crosslang_shared SHARED ${CROSSLANG_SOURCE})
CROSSLANG_LINK_DEPS(crosslang_shared)
if(CROSSLANG_FETCHCONTENT)
target_link_libraries(crosslang_shared PUBLIC tessesframework_shared)
else()
target_link_libraries(crosslang_shared PUBLIC TessesFramework::tessesframework_shared)
endif()
list(APPEND TessesCrossLangLibs crosslang_shared)
endif()
if(CROSSLANG_ENABLE_SUPERSLIM)
include(cmake/slim.cmake)
else()
include(cmake/shared.cmake)
if(CROSSLANG_ENABLE_BINARIES)
if(CROSSLANG_ENABLE_SHARED AND CROSSLANG_SHARED_EXECUTABLES)
include(cmake/shared_exec.cmake)
elseif(CROSSLANG_ENABLE_STATIC)
include(cmake/static_exec.cmake)
else()
include(cmake/exec.cmake)
endif()
install(TARGETS crossc DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS crossvm DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS crossint DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS crossdump DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS crosslang DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS crossarchiveextract DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS crossarchivecreate DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS crossasm DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS crossdisasm DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS crossmerge DESTINATION "${CMAKE_INSTALL_BINDIR}")
if(NOT WIN32)
install(TARGETS crossthumbnailer DESTINATION "${CMAKE_INSTALL_BINDIR}")
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/crossvm-binfmt.conf.in "${CMAKE_CURRENT_BINARY_DIR}/crossvm-binfmt.conf"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/binfmt.d)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/crossvm-binfmt.conf"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/binfmt.d)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/crosslang.xml"
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mime/packages)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/crosslang.png"
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/crosslang.thumbnailer"
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/thumbnailers)
endif()
endif()
endif()
include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_CONTACT "Mike Nolan <tesses@tesses.net>")
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}")
set(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS
"!include \\\"FileFunc.nsh\\\"\n!include \\\"${CMAKE_CURRENT_SOURCE_DIR}/FileAssociation.nsh\\\"")
# Create association on install
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
"\\\${RegisterExtension} '$INSTDIR\\\\bin\\\\crossvm.exe' '.crvm' 'CrossLang Executable'\n\
\\\${RefreshShellIcons}")
# Remove association on uninstall
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
"\\\${RegisterExtension} '$INSTDIR\\\\bin\\\\crossint.exe' '.tcross' 'CrossLang Script'\n\
\\\${RefreshShellIcons}\n\
\\\${UnRegisterExtension} '.crvm' 'CrossLang Executable'\n\
\\\${RefreshShellIcons}")
# Remove association on uninstall
set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
"\\\${UnRegisterExtension} '.tcross' 'CrossLang Script'\n\
\\\${RefreshShellIcons}\n\
\\\${UnRegisterExtension} '.crvm' 'CrossLang Executable'\n\
\\\${RefreshShellIcons}")
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)
if(CROSSLANG_INSTALL_DEVELOPMENT)
add_subdirectory(pkgconfig)
endif()
endif()

View File

@@ -6,7 +6,7 @@ RUN apk add --no-cache cmake g++ make git
COPY ./ /src
RUN cd /src && mkdir build && cd build && cmake -S .. -B . -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_APPS=ON -DCMAKE_BUILD_TYPE=Release ; make -j`nproc` && make install DESTDIR=/out
RUN cd /src && mkdir build && cd build && cmake -S .. -B . -DTESSESFRAMEWORK_STATIC=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_APPS=ON -DCMAKE_BUILD_TYPE=Release ; make -j`nproc` && make install DESTDIR=/out
FROM alpine:latest
RUN apk update
@@ -14,4 +14,4 @@ RUN apk add --no-cache libstdc++
COPY --from=build /out/usr /usr
ENV CROSSLANG_CONTAINER=1
ENTRYPOINT ["/usr/local/bin/crossint"]
ENTRYPOINT ["/usr/local/bin/crosslang","int"]

View File

@@ -1,16 +1,16 @@
# Maintainer: Mike Nolan <tesses@tesses.net>
pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn'
pkgver=0.0.4
pkgver=0.0.7
pkgrel=1
pkgdesc=""
arch=('x86_64' 'powerpc')
url="https://git.tesses.org/tesses50/crosslang"
license=('GPLv3')
groups=()
depends=('mbedtls' 'tessesframework=0.0.3')
depends=('mbedtls' 'tessesframework=0.0.5')
makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
install=
source=('crosslang::git+https://git.tesses.org/tesses50/crosslang')
source=('crosslang::git+https://git.tesses.org/tesses50/crosslang#tag=v0.0.7')
noextract=()
sha256sums=('SKIP')
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
@@ -30,14 +30,14 @@ prepare() {
build() {
cd "$srcdir/${pkgname}"
mkdir build
cd build
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release
cmake -S .. -B . -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release
else
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN"
cmake -S .. -B . -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN"
fi
cd build
make -j`nproc`
}

View File

@@ -7,7 +7,7 @@ git clone --depth 1 https://git.tesses.org/tesses50/zig-cross builds/zig-cross
for tripple in x86_64-linux-musl x86-linux-musl aarch64-linux-musl arm-linux-musleabi riscv64-linux-musl powerpc-linux-musleabihf; do
export BUILDDIR=builds/$tripple
mkdir -p $BUILDDIR
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -GNinja
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -D -DTESSESFRAMEWORK_STATIC=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -GNinja
cmake --build $BUILDDIR || exit 1
cmake --install $BUILDDIR --prefix $BUILDDIR/out
mv $BUILDDIR/out/bin/crosslang ../../artifacts/crosslang-slim-$tripple
@@ -16,7 +16,7 @@ done
for tripple in x86_64-windows-gnu x86-windows-gnu aarch64-windows-gnu; do
export BUILDDIR=builds/$tripple
mkdir -p $BUILDDIR
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -GNinja
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -D -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -GNinja
cmake --build $BUILDDIR || exit 1
cmake --install $BUILDDIR --prefix $BUILDDIR/out
@@ -26,7 +26,7 @@ done
for tripple in x86_64-macos-none aarch64-macos-none; do
export BUILDDIR=builds/$tripple
mkdir -p $BUILDDIR
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -GNinja -DCMAKE_EXE_LINKER_FLAGS="-Wl,--strip-all"
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -D -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -GNinja -DCMAKE_EXE_LINKER_FLAGS="-Wl,--strip-all"
cmake --build $BUILDDIR || exit 1
cmake --install $BUILDDIR --prefix $BUILDDIR/out

View File

@@ -1,16 +1,15 @@
#!/bin/bash
cmake -S ../.. -B build-x86 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x86.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DCMAKE_INSTALL_PREFIX=tmp-x86 -DCMAKE_BUILD_TYPE=Release
mkdir -p ../../artifacts
cmake -S ../.. -B build-x86 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x86.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_INSTALL_PREFIX=tmp-x86 -DCMAKE_BUILD_TYPE=Release
cd build-x86
make -j`nproc`
cpack -G NSIS
cpack -G ZIP
mv TessesCrossLang-*-win32.exe ../../../artifacts/crosslang-win32.exe
mv TessesCrossLang-*-win32.zip ../../../artifacts/crosslang-win32.zip
mv TessesCrossLang-*-win32.exe ../../../artifacts/crosslang-win32-setup.exe
mv crosslang.exe ../../../artifacts/crosslang-win32-portable.exe
cd ..
cmake -S ../.. -B build-x64 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x64.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DCMAKE_INSTALL_PREFIX=tmp-x64 -DCMAKE_BUILD_TYPE=Release
cmake -S ../.. -B build-x64 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x64.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_INSTALL_PREFIX=tmp-x64 -DCMAKE_BUILD_TYPE=Release
cd build-x64
make -j`nproc`
cpack -G NSIS
cpack -G ZIP
mv TessesCrossLang-*-win64.exe ../../../artifacts/crosslang-win64.exe
mv TessesCrossLang-*-win64.zip ../../../artifacts/crosslang-win64.zip
mv TessesCrossLang-*-win64.exe ../../../artifacts/crosslang-win64-setup.exe
mv crosslang.exe ../../../artifacts/crosslang-win64-portable.exe

View File

@@ -47,7 +47,7 @@ sudo make install
## Build with shared libs only (self contained dependencies)
```bash
cmake -S ../.. -B . -DTESSESFRAMEWORK_ENABLE_STATIC=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=ON
cmake -S ../.. -B .
make -j`nproc`
sudo make install
```

View File

@@ -1,280 +0,0 @@
var cpus = [
{
uname = "ppc",
name = "powerpc",
compiler = "powerpc-linux-musl-cross",
cc = "powerpc-linux-musl-gcc",
cxx = "powerpc-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "ppc64",
name = "powerpc64",
compiler = "powerpc64-linux-musl-cross",
cc = "powerpc64-linux-musl-gcc",
cxx = "powerpc64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "x86_64",
name = "x86_64",
compiler = "x86_64-linux-musl-cross",
cc = "x86_64-linux-musl-gcc",
cxx = "x86_64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname="i686",
name = "i686",
compiler = "i686-linux-musl-cross",
cc = "i686-linux-musl-gcc",
cxx = "i686-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "aarch64",
name = "aarch64",
compiler = "aarch64-linux-musl-cross",
cc = "aarch64-linux-musl-gcc",
cxx = "aarch64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "arm",
name = "arm",
compiler = "arm-linux-musleabi-cross",
cc = "arm-linux-musleabi-gcc",
cxx = "arm-linux-musleabi-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "armv7l",
name = "armv7l",
compiler = "arm-linux-musleabihf-cross",
cc = "arm-linux-musleabihf-gcc",
cxx = "arm-linux-musleabihf-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "mips",
name = "mips",
compiler = "mips-linux-musl-cross",
cc = "mips-linux-musl-gcc",
cxx = "mips-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "mips64",
name = "mips64",
compiler = "mips64-linux-musl-cross",
cc = "mips64-linux-musl-gcc",
cxx = "mips64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "riscv32",
name = "riscv32",
compiler = "riscv32-linux-musl-cross",
cc = "riscv32-linux-musl-gcc",
cxx = "riscv32-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "riscv64",
name = "riscv64",
compiler = "riscv64-linux-musl-cross",
cc = "riscv64-linux-musl-gcc",
cxx = "riscv64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
}
];
var mbedversion="mbedtls-2.28.9";
func main(args)
{
var working = FS.CurrentPath / "Working";
FS.Local.CreateDirectory(working / "Toolchains");
FS.Local.CreateDirectory(working / "CMakeToolchains");
FS.Local.CreateDirectory(working / "Source");
FS.Local.CreateDirectory(working / "DvdFiles" / "Linux");
FS.Local.CreateDirectory(working / "DvdFiles" / "Common");
FS.Local.CreateDirectory(working / "Output");
var install = "#!/bin/bash
export CPU=`uname -m`
";
var file = $"cd {working / \"Source\"}
if [ ! -d \"{mbedversion}\" ]; then
wget -O ../DvdFiles/crosslang-license.txt https://downloads.tesses.net/gpl-3.0.txt
cp ../DvdFiles/crosslang-license.txt ../Output/crosslang-license.txt
wget -O {mbedversion}.tar.bz2 https://downloads.tesses.net/cache/libraries/source/{mbedversion}.tar.bz2
tar xf {mbedversion}.tar.bz2
rm {mbedversion}.tar.bz2
fi
git clone --depth=1 https://git.tesses.org/tesses50/tessesframework
git clone --depth=1 https://git.tesses.org/tesses50/crosslang
zip -r \"{working / \"DvdFiles\" / \"crosslang-source.zip\"}\" ./*
cp ../DvdFiles/crosslang-source.zip ../Output/crosslang-source.zip
wget -O \"{working / \"DvdFiles\" / \"Common\" / \"ShellPackage.crvm\"}\" https://redirect.tesses.net/crosslang-shell
";
var w32_toolchain = $"
set(CMAKE_C_COMPILER \"/usr/bin/i686-w64-mingw32-gcc\")
set(CMAKE_CXX_COMPILER \"/usr/bin/i686-w64-mingw32-g++\")
set(CMAKE_C_FLAGS \"-static-libgcc -static-libstdc++ -static\")
set(CMAKE_CXX_FLAGS \"-static-libgcc -static-libstdc++ -static\")
set(CMAKE_EXE_LINKER_FLAGS \"-static-libgcc -static-libstdc++ -static\")
set(CMAKE_SYSROOT \"{working}/Sysroot/windows\")
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR i686)
";
FS.Local.CreateDirectory(working / "Build" / "windows");
FS.Local.CreateDirectory(working / "Sysroot" / "windows");
FS.WriteAllText(FS.Local,working / "CMakeToolchains" / "windows.cmake", w32_toolchain);
file += $"#windows
cd \"{working / \"Build\" / \"windows\"}\"
mkdir -p mbedtls
cd mbedtls
cmake -S \"{working / \"Source\" / mbedversion}\" -B . -DCMAKE_TOOLCHAIN_FILE=\"{working / \"CMakeToolchains\" / \"windows\"}.cmake\" -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF
make -j16
make install DESTDIR=\"{working / \"Sysroot\" / \"windows\"}\"
cd ..
mkdir -p tesses-framework
cd tesses-framework
cmake -S \"{working / \"Source\" / \"tesses-framework\"}\" -DMBEDTLS_DIR=\"{working / \"Sysroot\" / \"windows\"/\"usr\"/\"local\"}\" -B . -DCMAKE_TOOLCHAIN_FILE=\"{working / \"CMakeToolchains\" / \"windows\"}.cmake\" -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF
make -j16
make install DESTDIR=\"{working / \"Sysroot\" / \"windows\"}\"
cd ..
mkdir -p crosslang
cd crosslang
cmake -S \"{working / \"Source\" / \"crosslang\"}\" -B . -DCMAKE_TOOLCHAIN_FILE=\"{working / \"CMakeToolchains\" / \"windows\"}.cmake\" -DCROSSLANG_ENABLE_SHARED=OFF -DCROSSLANG_FETCHCONTENT=OFF -DCROSSLANG_SHARED_EXECUTABLES=OFF
make -j16
cpack -G NSIS
cpack -G ZIP
cp TessesCrossLang-*-win32.exe \"{working/\"DvdFiles\"/\"setup.exe\"}\"
cp TessesCrossLang-*-win32.zip \"{working/\"DvdFiles\"/\"crosslang-win32.zip\"}\"
cp TessesCrossLang-*-win32.exe \"{working/\"Output\"/\"crosslang-win32.exe\"}\"
cp TessesCrossLang-*-win32.zip \"{working/\"Output\"/\"crosslang-win32.zip\"}\"
";
each(var item : cpus)
{
FS.Local.CreateDirectory(working / "Build" / item.name);
FS.Local.CreateDirectory(working / "Sysroot" / item.name);
var toolchain = $"
set(CMAKE_C_COMPILER \"{working}/Toolchains/{item.compiler}/bin/{item.cc}\")
set(CMAKE_CXX_COMPILER \"{working}/Toolchains/{item.compiler}/bin/{item.cxx}\")
set(CMAKE_C_FLAGS \"{item.flags}\")
set(CMAKE_CXX_FLAGS \"{item.flags}\")
set(CMAKE_EXE_LINKER_FLAGS \"{item.flags}\")
set(CMAKE_SYSROOT \"{working}/Sysroot/{item.name}\")
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR powerpc)
";
if(item.name == "riscv32" || item.name == "riscv64")
{
toolchain += "set(CMAKE_POSITION_INDEPENDENT_CODE ON)\n";
}
FS.WriteAllText(FS.Local,working / "CMakeToolchains" / $"{item.name}.cmake", toolchain);
var tar = working / "Output" / $"crosslang-{item.name}.tar.gz";
var dvdDir = working / "DvdFiles" / "Linux" / item.name;
file += $"#{item.name}
cd \"{working / \"Toolchains\"}\"
if [ ! -d \"{item.compiler}\" ]; then
wget -O {item.compiler}.tgz https://downloads.tesses.net/cache/compilers/{item.compiler}.tgz
tar xzf {item.compiler}.tgz
rm {item.compiler}.tgz
fi
cd \"{working / \"Build\" / item.name}\"
mkdir -p mbedtls
cd mbedtls
cmake -S \"{working / \"Source\" / mbedversion}\" -B . -DCMAKE_TOOLCHAIN_FILE=\"{working / \"CMakeToolchains\" / item.name}.cmake\" -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF
make -j16
make install DESTDIR=\"{working / \"Sysroot\" / item.name}\"
cd ..
mkdir -p tesses-framework
cd tesses-framework
cmake -S \"{working / \"Source\" / \"tesses-framework\"}\" -DMBEDTLS_DIR=\"{working / \"Sysroot\" / item.name/\"usr\"/\"local\"}\" -B . -DCMAKE_TOOLCHAIN_FILE=\"{working / \"CMakeToolchains\" / item.name}.cmake\" -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF
make -j16
make install DESTDIR=\"{working / \"Sysroot\" / item.name}\"
cd ..
mkdir -p crosslang
cd crosslang
cmake -S \"{working / \"Source\" / \"crosslang\"}\" -B . -DCMAKE_TOOLCHAIN_FILE=\"{working / \"CMakeToolchains\" / item.name}.cmake\" -DCROSSLANG_ENABLE_SHARED=OFF -DCROSSLANG_FETCHCONTENT=OFF -DCROSSLANG_SHARED_EXECUTABLES=OFF
make -j16
make install DESTDIR=\"{working / \"Sysroot\" / item.name}\"
cd \"{working/\"Sysroot\"/item.name/\"usr\"/\"local\"}\"
tar czf \"{tar}\" bin share lib/binfmt.d
mv bin \"{dvdDir}\"
";
install += $"
if [[ \"$CPU\" == \"{item.uname}\" ]]; then
install -D -m 755 -o root ./Linux/{item.name}/crossarchivecreate /usr/local/bin/crossarchivecreate
install -D -m 755 -o root ./Linux/{item.name}/crossarchiveextract /usr/local/bin/crossarchiveextract
install -D -m 755 -o root ./Linux/{item.name}/crossc /usr/local/bin/crossc
install -D -m 755 -o root ./Linux/{item.name}/crossdump /usr/local/bin/crossdump
install -D -m 755 -o root ./Linux/{item.name}/crossint /usr/local/bin/crossint
install -D -m 755 -o root ./Linux/{item.name}/crosslang /usr/local/bin/crosslang
install -D -m 755 -o root ./Linux/{item.name}/crossthumbnailer /usr/local/bin/crossthumbnailer
install -D -m 755 -o root ./Linux/{item.name}/crossvm /usr/local/bin/crossvm
install -D -m 644 -o root ./Linux/crosslang.thumbnailer /usr/local/share/thumbnailers/crosslang.thumbnailer
install -D -m 644 -o root ./Linux/crosslang.xml /usr/local/share/mime/crosslang.xml
install -D -m 644 -o root ./Linux/crossvm-binfmt.conf /usr/local/lib/binfmt.d/crossvm-binfmt.conf
install -D -m 644 -o root ./Linux/crosslang.png /usr/local/share/icons/crosslang.png
install -D -m 644 -o root ./Common/ShellPackage.crvm /usr/local/share/Tesses/CrossLang/Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm
fi
";
}
file += $"
cd \"{working.GetParent()}\"
cd \"{working}\"
chmod 755 DvdFiles/install.sh
cp Source/crosslang/crosslang.png DvdFiles/Linux/crosslang.png
cp Source/crosslang/winicon.ico DvdFiles/cross.ico
cd DvdFiles
xorriso -outdev ../Output/crosslang.iso -add *
";
FS.WriteAllText(FS.Local,"script.sh", file);
FS.WriteAllText(FS.Local,./"Working"/"DvdFiles"/"install.sh", install);
FS.WriteAllText(FS.Local,./"Working"/"DvdFiles"/"Linux"/"crossvm-binfmt.conf",":CrossVM:M::TCROSSVM::/usr/local/bin/crossvm:\n");
FS.WriteAllText(FS.Local,./"Working"/"DvdFiles"/"Linux"/"crosslang.thumbnailer","[Thumbnailer Entry]
TryExec=crossthumbnailer
Exec=crossthumbnailer %i %o
MimeType=application/crvm;
");
FS.WriteAllText(FS.Local,"Working"/"DvdFiles"/"ReadmeWindows.txt", "When installing make sure to enable path\nRun ShellInstaller.bat from each user (if offline)");
FS.WriteAllText(FS.Local,"Working"/"DvdFiles"/"ShellInstaller.bat", "@echo off\r\ncrossarchiveextract Common\\ShellPackage.crvm %APPDATA%\\Tesses\\CrossLang");
FS.WriteAllText(FS.Local,./"Working"/"DvdFiles"/"autorun.inf","[autorun]\r\nicon=cross.ico\r\nopen=setup.exe\r\nlabel=CrossLang");
FS.WriteAllText(FS.Local,./"Working"/"DvdFiles"/"Linux"/"crosslang.xml","<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<mime-info xmlns=\"http://www.freedesktop.org/standards/shared-mime-info\">
<mime-type type=\"application/crvm\">
<sub-class-of type=\"application/octet-stream\"/>
<comment>CrossLang Executable</comment>
<comment xml:lang=\"en\">CrossLang Executable</comment>
<glob pattern=\"*.crvm\"/>
<icon name=\"crosslang\"/>
</mime-type>
<mime-type type=\"text/tcross\">
<sub-class-of type=\"text/plain\"/>
<comment>CrossLang Source</comment>
<comment xml:lang=\"en\">CrossLang Source</comment>
<glob pattern=\"*.tcross\"/>
<icon name=\"crosslang\"/>
</mime-type>
</mime-info>"
);
}

View File

@@ -1,5 +1,14 @@
# Changelog
## 0.0.7
Fix a security vulerability in crossdump that is supposed to use uint32_t but accidently used uint8_t, set to tessesframework=0.0.5
## 0.0.6
Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
## 0.0.5
Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable
## 0.0.4
Rework for git.tesses.org, GC* is std::shared_ptr maybe will fix crash during exit

25
cmake/app.cmake Normal file
View File

@@ -0,0 +1,25 @@
if(CROSSLANG_ENABLE_BINARIES)
if(MINGW)
list(APPEND CROSSLANG_WIN32_EXE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/winicon.rc")
if(MINGW)
ENABLE_LANGUAGE(RC)
endif(MINGW)
endif()
add_executable(crosslang_app src/programs/slim.cpp "${CROSSLANG_WIN32_EXE_SRC}")
target_link_libraries(crosslang_app PUBLIC crosslang)
set_target_properties(crosslang_app PROPERTIES OUTPUT_NAME crosslang)
install(TARGETS crosslang_app DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
if(NOT WIN32 AND NOT APPLE)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/crossvm-binfmt.conf.in "${CMAKE_CURRENT_BINARY_DIR}/crossvm-binfmt.conf"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/binfmt.d)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/crossvm-binfmt.conf"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/binfmt.d)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/crosslang.xml"
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mime/packages)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/crosslang.png"
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/crosslang.thumbnailer"
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/thumbnailers)
endif()

39
cmake/cpack.cmake Normal file
View File

@@ -0,0 +1,39 @@
include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_CONTACT "Mike Nolan <tesses@tesses.net>")
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}")
set(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS
"!include \\\"FileFunc.nsh\\\"\n!include \\\"${CMAKE_CURRENT_SOURCE_DIR}/FileAssociation.nsh\\\"")
# Create association on install
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
"\\\${RegisterExtension} '$INSTDIR\\\\bin\\\\crossvm.exe' '.crvm' 'CrossLang Executable'\n\
\\\${RefreshShellIcons}")
# Remove association on uninstall
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
"\\\${RegisterExtension} '$INSTDIR\\\\bin\\\\crosslang.exe int' '.tcross' 'CrossLang Script'\n\
\\\${RefreshShellIcons}\n\
\\\${UnRegisterExtension} '.crvm' 'CrossLang Executable'\n\
\\\${RefreshShellIcons}")
# Remove association on uninstall
set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
"\\\${UnRegisterExtension} '.tcross' 'CrossLang Script'\n\
\\\${RefreshShellIcons}\n\
\\\${UnRegisterExtension} '.crvm' 'CrossLang Executable'\n\
\\\${RefreshShellIcons}")
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)

View File

@@ -1,57 +0,0 @@
add_executable(crossc src/programs/crosslangcompiler.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossvm src/programs/crosslangvm.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossint src/programs/crosslanginterperter.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossdump src/programs/crosslangdump.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crosslang src/programs/crosslang.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossarchiveextract src/programs/crossarchiveextract.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossarchivecreate src/programs/crossarchivecreate.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossasm src/crossasmcli.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossdisasm src/crossdisasmcli.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossmerge src/crossmergecli.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
if(NOT WIN32)
add_executable(crossthumbnailer src/crossthumbnailer.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
endif()
CROSSLANG_LINK_DEPS(crossc)
CROSSLANG_LINK_DEPS(crossvm)
CROSSLANG_LINK_DEPS(crossint)
CROSSLANG_LINK_DEPS(crosslang)
CROSSLANG_LINK_DEPS(crossdump)
CROSSLANG_LINK_DEPS(crossarchiveextract)
CROSSLANG_LINK_DEPS(crossarchivecreate)
CROSSLANG_LINK_DEPS(crossmerge)
CROSSLANG_LINK_DEPS(crossdisasm)
CROSSLANG_LINK_DEPS(crossasm)
if(NOT WIN32)
CROSSLANG_LINK_DEPS(crossthumbnailer)
endif()
if(CROSSLANG_FETCHCONTENT)
target_link_libraries(crossc PUBLIC tessesframework)
target_link_libraries(crossvm PUBLIC tessesframework)
target_link_libraries(crossint PUBLIC tessesframework)
target_link_libraries(crosslang PUBLIC tessesframework)
target_link_libraries(crossdump PUBLIC tessesframework)
target_link_libraries(crossarchiveextract PUBLIC tessesframework)
target_link_libraries(crossarchivecreate PUBLIC tessesframework)
target_link_libraries(crossasm PUBLIC tessesframework)
target_link_libraries(crossdisasm PUBLIC tessesframework)
target_link_libraries(crossmerge PUBLIC tessesframework)
if(NOT WIN32)
target_link_libraries(crossthumbnailer PUBLIC tessesframework)
endif()
else()
target_link_libraries(crossc PUBLIC TessesFramework::tessesframework)
target_link_libraries(crossvm PUBLIC TessesFramework::tessesframework)
target_link_libraries(crossint PUBLIC TessesFramework::tessesframework)
target_link_libraries(crosslang PUBLIC TessesFramework::tessesframework)
target_link_libraries(crossdump PUBLIC TessesFramework::tessesframework)
target_link_libraries(crossarchiveextract PUBLIC TessesFramework::tessesframework)
target_link_libraries(crossarchivecreate PUBLIC TessesFramework::tessesframework)
target_link_libraries(crossasm PUBLIC TessesFramework::tessesframework)
target_link_libraries(crossdisasm PUBLIC TessesFramework::tessesframework)
target_link_libraries(crossmerge PUBLIC TessesFramework::tessesframework)
if(NOT WIN32)
target_link_libraries(crossthumbnailer PUBLIC TessesFramework::tessesframework)
endif()
endif()

14
cmake/findtf.cmake Normal file
View File

@@ -0,0 +1,14 @@
if(CROSSLANG_FETCHCONTENT)
set(CROSSLANG_STATIC ${TESSESFRAMEWORK_STATIC} CACHE INTERNAL "For CrossLang" FORCE)
FetchContent_Declare(
TessesFramework
GIT_REPOSITORY https://git.tesses.org/tesses50/tessesframework.git
GIT_TAG 41d503cfb535eca95068b0265418ab2f580264d6
)
set(TESSESFRAMEWORK_ENABLE_EXAMPLES OFF)
FetchContent_MakeAvailable(TessesFramework)
else()
find_package(TessesFramework REQUIRED)
endif()

38
cmake/helpers.cmake Normal file
View File

@@ -0,0 +1,38 @@
if(CROSSLANG_ENABLE_FFI)
if(NOT CROSSLANG_STATIC)
pkg_check_modules(LIBFFI REQUIRED IMPORTED_TARGET libffi)
target_compile_definitions(crosslang PUBLIC CROSSLANG_ENABLE_FFI)
target_link_libraries(crosslang PUBLIC PkgConfig::LIBFFI)
endif()
endif()
if(CROSSLANG_CUSTOM_CONSOLE)
target_compile_definitions(crosslang PRIVATE CROSSLANG_CUSTOM_CONSOLE)
endif()
if(CROSSLANG_STATIC)
target_compile_definitions(crosslang PRIVATE CROSSLANG_STATIC)
endif()
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/CrossLangVersion.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h"
INSTALL_DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/CrossLangVersion.h)
target_include_directories(crosslang
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
target_include_directories(crosslang
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
if(TESSESFRAMEWORK_FETCHCONTENT)
target_link_libraries(crosslang PUBLIC tessesframework)
else()
target_link_libraries(crosslang PUBLIC TessesFramework::tessesframework)
endif()

View File

@@ -1,34 +1,28 @@
if(CROSSLANG_INSTALL_DEVELOPMENT)
install(TARGETS ${TessesCrossLangLibs}
EXPORT TessesCrossLangTargets
install(TARGETS ${CrossLangLibs}
EXPORT CrossLangTargets
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(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT TessesCrossLangTargets
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/CrossLang.hpp" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(EXPORT CrossLangTargets
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)
else()
if(CROSSLANG_ENABLE_SHARED)
install(TARGETS crosslang_shared
EXPORT TessesCrossLangTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif()
endif()

View File

@@ -1,62 +0,0 @@
function(CROSSLANG_LINK_DEPS CROSSLANG_TARGET_NAME)
target_include_directories(${CROSSLANG_TARGET_NAME}
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
if(CROSSLANG_ENABLE_FFI AND CROSSLANG_ENABLE_SHARED)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_FFI)
target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC PkgConfig::LIBFFI)
endif()
if(CROSSLANG_ENABLE_SUPERSLIM)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_SUPERSLIM)
endif()
if(CROSSLANG_ENABLE_TIME)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_TIME)
endif()
if(CROSSLANG_ENABLE_CONFIG_ENVVAR)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_CONFIG_ENVVAR)
endif()
if(CROSSLANG_ENABLE_PROCESS)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_PROCESS)
endif()
if(CROSSLANG_ENABLE_THREADING)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_THREADING)
endif()
if(CROSSLANG_ENABLE_TERMIOS)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_TERMIOS)
endif()
if(CROSSLANG_ENABLE_SQLITE)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_SQLITE)
endif()
if(CROSSLANG_CUSTOM_CONSOLE)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_CUSTOM_CONSOLE)
endif()
if(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_PLATFORM_FOLDERS)
endif()
if(CROSSLANG_ENABLE_SHARED)
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_SHARED)
endif()
if("${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoWii" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoGameCube")
target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC fat)
endif()
if("${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoWii")
target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC wiisocket)
endif()
if(CROSSLANG_ENABLE_SHARED AND NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows"))
target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC dl)
endif()
target_include_directories(${CROSSLANG_TARGET_NAME}
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
endfunction()

View File

@@ -1,18 +1,7 @@
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_TERMIOS "Enable termios (For changing terminal options)" ON)
option(CROSSLANG_SHARED_EXECUTABLES "Link with libcrosslang_shared" ON)
option(CROSSLANG_FETCHCONTENT "Use fetchcontent" ON)
option(CROSSLANG_ENABLE_CONFIG_ENVVAR "Allow setting config directory via the environment variable CROSSLANG_CONFIG" ON)
option(CROSSLANG_ENABLE_FFI "Enable libffi" OFF)
option(CROSSLANG_ENABLE_RPATH "Enable RPATH" ON)
option(CROSSLANG_ENABLE_SUPERSLIM "Enable crosslang superslim, one binary" OFF)
option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF)
set(CROSSLANG_OFFLINE_SHELL_PACKAGE "" CACHE FILEPATH "Path to the shell package generated from https://git.tesses.org/crosslangextras")
option(CROSSLANG_STATIC "Build with static libraries instead of shared" OFF)

View File

@@ -1,37 +0,0 @@
if(CROSSLANG_ENABLE_RPATH)
set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE)
if (APPLE)
set(CMAKE_INSTALL_RPATH "@executable_path/../${CMAKE_INSTALL_LIBDIR}")
else()
set(CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
endif()
endif()
add_executable(crossmerge src/crossmergecli.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossasm src/crossasmcli.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossdisasm src/crossdisasmcli.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossc src/programs/crosslangcompiler.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossvm src/programs/crosslangvm.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossint src/programs/crosslanginterperter.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossdump src/programs/crosslangdump.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crosslang src/programs/crosslang.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossarchiveextract src/programs/crossarchiveextract.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossarchivecreate src/programs/crossarchivecreate.cpp ${CROSSLANG_WIN32_EXE_SRC})
if(NOT WIN32)
add_executable(crossthumbnailer src/crossthumbnailer.cpp ${CROSSLANG_WIN32_EXE_SRC})
endif()
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)
target_link_libraries(crossarchiveextract PUBLIC crosslang_shared)
target_link_libraries(crossarchivecreate PUBLIC crosslang_shared)
target_link_libraries(crossasm PUBLIC crosslang_shared)
target_link_libraries(crossdisasm PUBLIC crosslang_shared)
target_link_libraries(crossmerge PUBLIC crosslang_shared)
if(NOT WIN32)
target_link_libraries(crossthumbnailer PUBLIC crosslang_shared)
endif()

20
cmake/sharedlib.cmake Normal file
View File

@@ -0,0 +1,20 @@
if(TESSESFRAMEWORK_ENABLE_RPATH)
set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE)
if (APPLE)
set(CMAKE_INSTALL_RPATH "@executable_path/../${CMAKE_INSTALL_LIBDIR}")
else()
set(CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
endif()
endif()
add_library(crosslang SHARED ${CROSSLANG_SOURCE})
set_target_properties(crosslang PROPERTIES
VERSION ${CROSSLANG_MAJOR_VERSION}.${CROSSLANG_MINOR_VERSION}.${CROSSLANG_PATCH_VERSION}
SOVERSION ${CROSSLANG_MAJOR_VERSION}
)
include(${CMAKE_CURRENT_LIST_DIR}/helpers.cmake)
list(APPEND CrossLangLibs crosslang)

View File

@@ -1,21 +0,0 @@
add_executable(crosslang WIN32 src/programs/slim.cpp ${CROSSLANG_WIN32_EXE_SRC})
if(CROSSLANG_ENABLE_STATIC)
target_link_libraries(crosslang PUBLIC crosslang_static)
elseif(CROSSLANG_ENABLE_SHARED)
target_link_libraries(crosslang PUBLIC crosslang_shared)
endif()
if(CROSSLANG_ENABLE_SHARED)
install(TARGETS crosslang_shared
EXPORT TessesCrossLangTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif()
install(TARGETS crosslang DESTINATION "${CMAKE_INSTALL_BINDIR}")

View File

@@ -9,9 +9,6 @@ src/vm/bc/invokemethod.cpp
src/vm/bc/executemethod2.cpp
src/vm/bc/invoketwo.cpp
src/vm/bc/tobool.cpp
src/assembler/asm.cpp
src/assembler/disasm.cpp
src/assembler/merge.cpp
src/compiler/codegen.cpp
src/compiler/lexer.cpp
src/compiler/parser.cpp
@@ -49,6 +46,7 @@ src/types/streamheapobject.cpp
src/types/class.cpp
src/types/classenvironment.cpp
src/types/random.cpp
src/types/queryable.cpp
src/vm/filereader.cpp
src/vm/gc.cpp
src/vm/gclist.cpp

View File

@@ -1,28 +0,0 @@
add_executable(crossc src/programs/crosslangcompiler.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossvm src/programs/crosslangvm.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossint src/programs/crosslanginterperter.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossdump src/programs/crosslangdump.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crosslang src/programs/crosslang.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossarchiveextract src/programs/crossarchiveextract.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossarchivecreate src/programs/crossarchivecreate.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossasm src/crossasmcli.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossdisasm src/crossdisasmcli.cpp ${CROSSLANG_WIN32_EXE_SRC})
add_executable(crossmerge src/crossmergecli.cpp ${CROSSLANG_WIN32_EXE_SRC})
if(NOT WIN32)
add_executable(crossthumbnailer src/crossthumbnailer.cpp ${CROSSLANG_WIN32_EXE_SRC})
endif()
target_link_libraries(crossc PUBLIC crosslang_static)
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)
target_link_libraries(crossarchiveextract PUBLIC crosslang_static)
target_link_libraries(crossarchivecreate PUBLIC crosslang_static)
target_link_libraries(crossmerge PUBLIC crosslang_static)
target_link_libraries(crossasm PUBLIC crosslang_static)
target_link_libraries(crossdisasm PUBLIC crosslang_static)
if(NOT WIN32)
target_link_libraries(crossthumbnailer PUBLIC crosslang_static)
endif()

6
cmake/staticlib.cmake Normal file
View File

@@ -0,0 +1,6 @@
add_library(crosslang STATIC ${CROSSLANG_SOURCE})
include(${CMAKE_CURRENT_LIST_DIR}/helpers.cmake)
list(APPEND CrossLangLibs crosslang)

View File

@@ -1,3 +1,3 @@
set(CROSSLANG_MAJOR_VERSION 0)
set(CROSSLANG_MINOR_VERSION 0)
set(CROSSLANG_PATCH_VERSION 4)
set(CROSSLANG_PATCH_VERSION 7)

View File

@@ -1,4 +1,4 @@
[Thumbnailer Entry]
TryExec=crossthumbnailer
Exec=crossthumbnailer %i %o
TryExec=crosslang
Exec=crosslang thumbnailer %i %o
MimeType=application/crvm;

File diff suppressed because it is too large Load Diff

View File

@@ -10,16 +10,8 @@ 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()

View File

@@ -8,6 +8,7 @@ URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
@PKGCONFIG_DEPS@
Requires: tessesframework
Cflags: -I"${includedir}"
Libs: -L"${libdir}" -lcrosslang_shared
Libs: -L"${libdir}" -lcrosslang

View File

@@ -1,13 +0,0 @@
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

@@ -1,324 +1,306 @@
#include "CrossLang.hpp"
#include <iostream>
namespace Tesses::CrossLang
{
void CrossArchiveCreate(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::string name, TVMVersion version, std::string info, std::string icon)
{
std::vector<std::string> ignored_files;
std::string file = "/.crossarchiveignore";
if(vfs->FileExists(file))
{
auto strm = vfs->OpenFile(file,"rb");
if(strm != nullptr)
{
Tesses::Framework::TextStreams::StreamReader reader(strm);
std::string ignores;
while(reader.ReadLine(ignores))
{
if(!ignores.empty() && ignores[0] != '#')
{
ignored_files.push_back(ignores);
}
ignores.clear();
namespace Tesses::CrossLang {
void CrossArchiveCreate(
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
std::shared_ptr<Tesses::Framework::Streams::Stream> strm, std::string name,
TVMVersion version, std::string info, std::string icon) {
std::vector<std::string> ignored_files;
std::string file = "/.crossarchiveignore";
if (vfs->FileExists(file)) {
auto strm = vfs->OpenFile(file, "rb");
if (strm != nullptr) {
Tesses::Framework::TextStreams::StreamReader reader(strm);
std::string ignores;
while (reader.ReadLine(ignores)) {
if (!ignores.empty() && ignores[0] != '#') {
ignored_files.push_back(ignores);
}
ignores.clear();
}
}
static std::vector<uint8_t> error_message_byte_code = {
PUSHSTRING,
0,
0,
0,
2,
GETVARIABLE,
PUSHSTRING,
0,
0,
0,
3,
PUSHSTRING,
0,
0,
0,
4,
PUSHLONG,
0,
0,
0,
0,
0,
0,
0,
1,
CALLMETHOD,
RET
};
auto writeInt = [](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,uint32_t number)->void{
uint8_t buff[4];
BitConverter::FromUint32BE(buff[0],number);
strm->WriteBlock(buff,4);
};
auto writeStr = [&writeInt](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::string text)->void {
writeInt(strm,(uint32_t)text.size());
strm->WriteBlock((const uint8_t*)text.c_str(),text.size());
};
std::vector<std::string> strs;
strs.push_back(name);
strs.push_back(info);
strs.push_back("Console");
strs.push_back("WriteLine");
strs.push_back("You are trying to run a crvm archive, stop it you won't get anywhere!\nUse crossarchiveextract instead.");
std::vector<std::string> resources;
auto ensureResource = [&resources](std::string path)->uint32_t {
for(uint32_t i = 0; i < (uint32_t)resources.size(); i++)
{
if(resources[i] == path) return i;
}
uint32_t index = (uint32_t)resources.size();
resources.push_back(path);
return index;
};
auto ensureString = [&strs](std::string str)->uint32_t {
for(uint32_t i = 0; i < (uint32_t)strs.size(); i++)
{
if(strs[i] == str) return i;
}
uint32_t index = (uint32_t)strs.size();
strs.push_back(str);
return index;
};
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkFS = [&ignored_files,vfs,&ensureString,&ensureResource,&ms,&walkFS,&writeInt](Tesses::Framework::Filesystem::VFSPath path)->void {
if(vfs->DirectoryExists(path))
{
ms->WriteByte(1);
std::vector<std::string> paths;
for(auto item : vfs->EnumeratePaths(path))
{
if(!item.relative && item.path.size() == 1 && item.path[0] == "__resdir_tmp") continue;
if(!item.relative && item.path.size() == 1 && item.path[0] == ".crossarchiveignore") continue;
std::string filename = item.GetFileName();
bool shallIgnore=false;
for(auto ign : ignored_files) if(ign == filename) {shallIgnore=true; break;}
if(shallIgnore) continue;
if(vfs->DirectoryExists(item) || vfs->RegularFileExists(item))
paths.push_back(item.GetFileName());
}
writeInt(ms,(uint32_t)paths.size());
for(auto item : paths)
{
writeInt(ms,ensureString(item));
walkFS(path / item);
}
}
else if(vfs->RegularFileExists(path))
{
ms->WriteByte(0);
writeInt(ms,ensureResource(path.ToString()));
}
};
walkFS(std::string("/"));
if(!icon.empty())
ensureResource(icon);
uint8_t main_header[18];
memcpy(main_header,"TCROSSVM",8);
TVMVersion rtVersion(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
rtVersion.ToArray(main_header+8);
version.ToArray(main_header+13);
strm->WriteBlock(main_header,sizeof(main_header));
writeInt(strm,(uint32_t)((icon.empty() ? 5 : 6)+resources.size()));
strm->WriteBlock((const uint8_t*)"STRS",4);
uint32_t sz=4;
for(auto str : strs)
sz += (uint32_t)(4 + str.size());
writeInt(strm,sz);
writeInt(strm,(uint32_t)strs.size());
for(auto str : strs)
{
writeStr(strm,str);
}
strm->WriteBlock((const uint8_t*)"NAME",4);
writeInt(strm,4);
writeInt(strm,0);
strm->WriteBlock((const uint8_t*)"INFO",4);
writeInt(strm,4);
writeInt(strm,1);
if(!icon.empty())
{
strm->WriteBlock((const uint8_t*)"ICON",4);
writeInt(strm,4);
writeInt(strm,ensureResource(icon));
}
strm->WriteBlock((const uint8_t*)"CHKS",4);
writeInt(strm,(uint32_t)(12+error_message_byte_code.size()));
writeInt(strm,1);
writeInt(strm,0);
writeInt(strm,(uint32_t)error_message_byte_code.size());
strm->WriteBlock(error_message_byte_code.data(),error_message_byte_code.size());
for(auto res : resources)
{
strm->WriteBlock((const uint8_t*)"RESO",4);
auto strm2 = vfs->OpenFile(res,"rb");
writeInt(strm,(uint32_t)strm2->GetLength());
strm2->CopyTo(strm);
}
strm->WriteBlock((const uint8_t*)"ARCV",4);
writeInt(strm,(uint32_t)ms->GetLength());
ms->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
ms->CopyTo(strm);
}
std::pair<std::pair<std::string,TVMVersion>,std::string> CrossArchiveExtract(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs)
{
auto ensure = [strm](uint8_t* buffer,size_t count)->void{
static std::vector<uint8_t> error_message_byte_code = {
PUSHSTRING, 0, 0, 0, 2, GETVARIABLE, PUSHSTRING, 0, 0, 0,
3, PUSHSTRING, 0, 0, 0, 4, PUSHLONG, 0, 0, 0,
0, 0, 0, 0, 1, CALLMETHOD, RET};
auto writeInt = [](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
uint32_t number) -> void {
uint8_t buff[4];
BitConverter::FromUint32BE(buff[0], number);
strm->WriteBlock(buff, 4);
};
auto writeStr =
[&writeInt](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
std::string text) -> void {
writeInt(strm, (uint32_t)text.size());
strm->WriteBlock((const uint8_t *)text.c_str(), text.size());
};
size_t read = strm->ReadBlock(buffer, count);
if(read < count) throw VMException("End of file, could not read " + std::to_string((int64_t)count) + " byte(s)., offset=" + std::to_string(strm->GetLength()));
};
auto ensureInt = [&ensure]()->uint32_t {
uint8_t buffer[4];
ensure(buffer,4);
return BitConverter::ToUint32BE(buffer[0]);
};
auto ensureStr = [&ensure,&ensureInt]()-> std::string {
auto len = ensureInt();
if(len == 0) return {};
std::string str={};
str.resize((size_t)len);
ensure((uint8_t*)str.data(),str.size());
return str;
};
std::vector<std::string> strs;
auto getStr = [&ensure,&ensureInt,&strs]()-> std::string {
auto index = ensureInt();
if(index > strs.size()) throw VMException("String does not exist in TCrossVM file, expected string index: " + std::to_string(index) + ", total strings: " + std::to_string(strs.size()));
return strs[index];
};
uint8_t main_header[18];
ensure(main_header,sizeof(main_header));
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image.");
TVMVersion version(main_header+8);
if(version.CompareToRuntime() == 1)
{
throw VMException("Runtime is too old.");
std::vector<std::string> strs;
strs.push_back(name);
strs.push_back(info);
strs.push_back("Console");
strs.push_back("WriteLine");
strs.push_back("You are trying to run a crvm archive, stop it you won't "
"get anywhere!\nUse crossarchiveextract instead.");
std::vector<std::string> resources;
auto ensureResource = [&resources](std::string path) -> uint32_t {
for (uint32_t i = 0; i < (uint32_t)resources.size(); i++) {
if (resources[i] == path)
return i;
}
TVMVersion v2(main_header+13);
std::string name;
std::string info;
uint32_t index = (uint32_t)resources.size();
resources.push_back(path);
return index;
};
auto ensureString = [&strs](std::string str) -> uint32_t {
for (uint32_t i = 0; i < (uint32_t)strs.size(); i++) {
if (strs[i] == str)
return i;
}
uint32_t index = (uint32_t)strs.size();
strs.push_back(str);
return index;
};
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
size_t _len = (size_t)ensureInt();
std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkFS =
[&ignored_files, vfs, &ensureString, &ensureResource, &ms, &walkFS,
&writeInt](Tesses::Framework::Filesystem::VFSPath path) -> void {
if (vfs->DirectoryExists(path)) {
char table_name[4];
uint32_t resource_id = 0;
Tesses::Framework::Filesystem::VFSPath tmpDir("/__resdir_tmp");
vfs->CreateDirectory(tmpDir);
for(size_t i = 0;i < _len; i++)
{
ensure((uint8_t*)table_name,sizeof(table_name));
size_t tableLen = (size_t)ensureInt();
if(strncmp(table_name,"NAME",4) == 0)
{
name = getStr();
}
else if(strncmp(table_name,"INFO",4) == 0)
{
info = getStr();
}
else if(strncmp(table_name,"RESO",4) == 0) //resources (using embed)
{
auto path = tmpDir /std::to_string(resource_id);
auto strm2 = vfs->OpenFile(path,"wb");
size_t read = 0;
size_t offset = 0;
uint8_t buff[1024];
do {
read = std::min(std::min(tableLen-offset,tableLen), sizeof(buff));
read = strm->Read(buff,read);
if(read > 0)
strm2->WriteBlock(buff,read);
offset+=read;
} while(read > 0);
resource_id++;
}
else if(strncmp(table_name,"STRS",4) == 0) //strings
{
size_t strsLen = (size_t)ensureInt();
for(size_t j = 0;j < strsLen;j++)
{
strs.push_back(ensureStr());
}
}
else if(strncmp(table_name,"ARCV",4) == 0)
{
size_t offset = 0;
std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkEntry = [strm,vfs,&getStr,&ensureInt,&tmpDir,&tableLen,&offset,&walkEntry](Tesses::Framework::Filesystem::VFSPath path)->void {
if(offset + 1 > tableLen) return;
uint8_t type = strm->ReadByte();
offset++;
if(type == 1)
{
//ISDIR
vfs->CreateDirectory(path);
if(offset + 4 > tableLen) return;
uint32_t count = ensureInt();
offset +=4;
for(uint32_t i = 0; i < count; i++)
{
if(offset + 4 > tableLen) return;
std::string name = getStr();
offset +=4;
walkEntry(path / name);
}
}
else if(type == 0)
{
if(offset + 4 > tableLen) return;
uint32_t index = ensureInt();
auto fSrc = tmpDir /std::to_string(index);
vfs->MoveFile(fSrc, path);
ms->WriteByte(1);
std::vector<std::string> paths;
for (auto item : vfs->EnumeratePaths(path)) {
if (!item.relative && item.path.size() == 1 &&
item.path[0] == "__resdir_tmp")
continue;
if (!item.relative && item.path.size() == 1 &&
item.path[0] == ".crossarchiveignore")
continue;
std::string filename = item.GetFileName();
bool shallIgnore = false;
for (auto ign : ignored_files)
if (ign == filename) {
shallIgnore = true;
break;
}
};
walkEntry(std::string("/"));
if (shallIgnore)
continue;
if (vfs->DirectoryExists(item) || vfs->RegularFileExists(item))
paths.push_back(item.GetFileName());
}
else
{
if(strm->CanSeek())
{
strm->Seek((int64_t)tableLen,Tesses::Framework::Streams::SeekOrigin::Current);
}
else{
uint8_t* buffer=new uint8_t[tableLen];
ensure(buffer,tableLen);
delete[] buffer;
}
writeInt(ms, (uint32_t)paths.size());
for (auto item : paths) {
writeInt(ms, ensureString(item));
walkFS(path / item);
}
} else if (vfs->RegularFileExists(path)) {
ms->WriteByte(0);
writeInt(ms, ensureResource(path.ToString()));
}
vfs->DeleteDirectoryRecurse(tmpDir);
return std::pair<std::pair<std::string,TVMVersion>,std::string>(std::pair<std::string,TVMVersion>(name,v2),info);
};
walkFS(std::string("/"));
if (!icon.empty())
ensureResource(icon);
uint8_t main_header[18];
memcpy(main_header, "TCROSSVM", 8);
TVMVersion rtVersion(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
CROSSLANG_BYTECODE_VERSIONSTAGE);
rtVersion.ToArray(main_header + 8);
version.ToArray(main_header + 13);
strm->WriteBlock(main_header, sizeof(main_header));
writeInt(strm, (uint32_t)((icon.empty() ? 5 : 6) + resources.size()));
strm->WriteBlock((const uint8_t *)"STRS", 4);
uint32_t sz = 4;
for (auto str : strs)
sz += (uint32_t)(4 + str.size());
writeInt(strm, sz);
writeInt(strm, (uint32_t)strs.size());
for (auto str : strs) {
writeStr(strm, str);
}
strm->WriteBlock((const uint8_t *)"NAME", 4);
writeInt(strm, 4);
writeInt(strm, 0);
strm->WriteBlock((const uint8_t *)"INFO", 4);
writeInt(strm, 4);
writeInt(strm, 1);
if (!icon.empty()) {
strm->WriteBlock((const uint8_t *)"ICON", 4);
writeInt(strm, 4);
writeInt(strm, ensureResource(icon));
}
strm->WriteBlock((const uint8_t *)"CHKS", 4);
writeInt(strm, (uint32_t)(12 + error_message_byte_code.size()));
writeInt(strm, 1);
writeInt(strm, 0);
writeInt(strm, (uint32_t)error_message_byte_code.size());
strm->WriteBlock(error_message_byte_code.data(),
error_message_byte_code.size());
for (auto res : resources) {
strm->WriteBlock((const uint8_t *)"RESO", 4);
auto strm2 = vfs->OpenFile(res, "rb");
writeInt(strm, (uint32_t)strm2->GetLength());
strm2->CopyTo(strm);
}
strm->WriteBlock((const uint8_t *)"ARCV", 4);
writeInt(strm, (uint32_t)ms->GetLength());
ms->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
ms->CopyTo(strm);
}
std::pair<std::pair<std::string, TVMVersion>, std::string>
CrossArchiveExtract(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs) {
auto ensure = [strm](uint8_t *buffer, size_t count) -> void {
size_t read = strm->ReadBlock(buffer, count);
if (read < count)
throw VMException(
"End of file, could not read " +
std::to_string((int64_t)count) +
" byte(s)., offset=" + std::to_string(strm->GetLength()));
};
auto ensureInt = [&ensure]() -> uint32_t {
uint8_t buffer[4];
ensure(buffer, 4);
return BitConverter::ToUint32BE(buffer[0]);
};
auto ensureStr = [&ensure, &ensureInt]() -> std::string {
auto len = ensureInt();
if (len == 0)
return {};
std::string str = {};
str.resize((size_t)len);
ensure((uint8_t *)str.data(), str.size());
return str;
};
std::vector<std::string> strs;
auto getStr = [&ensure, &ensureInt, &strs]() -> std::string {
auto index = ensureInt();
if (index > strs.size())
throw VMException("String does not exist in TCrossVM file, "
"expected string index: " +
std::to_string(index) + ", total strings: " +
std::to_string(strs.size()));
return strs[index];
};
uint8_t main_header[18];
ensure(main_header, sizeof(main_header));
if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
throw VMException("Invalid TCrossVM image.");
TVMVersion version(main_header + 8);
if (version.CompareToRuntime() == 1) {
throw VMException("Runtime is too old.");
}
TVMVersion v2(main_header + 13);
std::string name;
std::string info;
size_t _len = (size_t)ensureInt();
char table_name[4];
uint32_t resource_id = 0;
Tesses::Framework::Filesystem::VFSPath tmpDir("/__resdir_tmp");
vfs->CreateDirectory(tmpDir);
for (size_t i = 0; i < _len; i++) {
ensure((uint8_t *)table_name, sizeof(table_name));
size_t tableLen = (size_t)ensureInt();
if (strncmp(table_name, "NAME", 4) == 0) {
name = getStr();
} else if (strncmp(table_name, "INFO", 4) == 0) {
info = getStr();
}
else if (strncmp(table_name, "RESO", 4) == 0) // resources (using embed)
{
auto path = tmpDir / std::to_string(resource_id);
auto strm2 = vfs->OpenFile(path, "wb");
size_t read = 0;
size_t offset = 0;
uint8_t buff[1024];
do {
read = std::min(std::min(tableLen - offset, tableLen),
sizeof(buff));
read = strm->Read(buff, read);
if (read > 0)
strm2->WriteBlock(buff, read);
offset += read;
} while (read > 0);
resource_id++;
}
else if (strncmp(table_name, "STRS", 4) == 0) // strings
{
size_t strsLen = (size_t)ensureInt();
for (size_t j = 0; j < strsLen; j++) {
strs.push_back(ensureStr());
}
} else if (strncmp(table_name, "ARCV", 4) == 0) {
size_t offset = 0;
std::function<void(Tesses::Framework::Filesystem::VFSPath)>
walkEntry =
[strm, vfs, &getStr, &ensureInt, &tmpDir, &tableLen,
&offset, &walkEntry](
Tesses::Framework::Filesystem::VFSPath path) -> void {
if (offset + 1 > tableLen)
return;
uint8_t type = strm->ReadByte();
offset++;
if (type == 1) {
// ISDIR
vfs->CreateDirectory(path);
if (offset + 4 > tableLen)
return;
uint32_t count = ensureInt();
offset += 4;
for (uint32_t i = 0; i < count; i++) {
if (offset + 4 > tableLen)
return;
std::string name = getStr();
offset += 4;
walkEntry(path / name);
}
} else if (type == 0) {
if (offset + 4 > tableLen)
return;
uint32_t index = ensureInt();
auto fSrc = tmpDir / std::to_string(index);
vfs->MoveFile(fSrc, path);
}
};
walkEntry(std::string("/"));
} else {
if (strm->CanSeek()) {
strm->Seek((int64_t)tableLen,
Tesses::Framework::Streams::SeekOrigin::Current);
} else {
uint8_t *buffer = new uint8_t[tableLen];
ensure(buffer, tableLen);
delete[] buffer;
}
}
}
vfs->DeleteDirectoryRecurse(tmpDir);
return std::pair<std::pair<std::string, TVMVersion>, std::string>(
std::pair<std::string, TVMVersion>(name, v2), info);
}
} // namespace Tesses::CrossLang

File diff suppressed because it is too large Load Diff

View File

@@ -1,917 +0,0 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
class CrossLangFileReader {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
void Ensure(uint8_t* buffer, size_t len)
{
auto read = this->strm->ReadBlock(buffer, len);
if(read < len) throw VMException("End of file, could not read " + std::to_string((int64_t)len) + " byte(s)., offset=" + std::to_string(strm->GetLength()));
}
uint32_t ReadInt()
{
uint8_t buffer[4];
Ensure(buffer,4);
return BitConverter::ToUint32BE(buffer[0]);
}
std::string ReadString()
{
auto len = ReadInt();
if(len == 0) return {};
std::string str={};
str.resize((size_t)len);
Ensure((uint8_t*)str.data(),str.size());
return str;
}
std::string GetString()
{
uint32_t index=ReadInt();
if(index >= this->strings.size()) throw VMException("String does not exist in TCrossVM file, expected string index: " + std::to_string(index) + ", total strings: " + std::to_string(this->strings.size()));
return this->strings[index];
}
public:
CrossLangFileReader(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
{
this->strm = strm;
uint8_t main_header[18];
Ensure(main_header,sizeof(main_header));
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image.");
TVMVersion version(main_header+8);
if(version.CompareToRuntime() == 1)
{
throw VMException("Runtime is too old.");
}
TVMVersion v2(main_header+13);
this->version = v2;
size_t _len = (size_t)ReadInt();
char table_name[4];
for(size_t i = 0;i < _len; i++)
{
Ensure((uint8_t*)table_name,sizeof(table_name));
size_t tableLen = (size_t)ReadInt();
if(strncmp(table_name,"NAME",4) == 0)
{
this->name = GetString();
}
else if(strncmp(table_name,"INFO",4) == 0)
{
this->info = GetString();
}
else if(strncmp(table_name,"DEPS",4) == 0) //dependencies
{
std::string name = GetString();
uint8_t version_bytes[5];
Ensure(version_bytes,sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
this->dependencies.push_back(std::pair<std::string,TVMVersion>(name, depVersion));
}
else if(strncmp(table_name,"TOOL",4) == 0) //compile tools (for package manager)
{
std::string name = GetString();
uint8_t version_bytes[5];
Ensure(version_bytes,sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
this->tools.push_back(std::pair<std::string,TVMVersion>(name, depVersion));
}
else if(strncmp(table_name,"RESO",4) == 0) //resources (using embed)
{
std::vector<uint8_t> data;
data.resize(tableLen);
Ensure(data.data(), tableLen);
this->resources.push_back(data);
}
else if(strncmp(table_name,"CHKS",4) == 0) //chunks
{
size_t chunkCount = (size_t)ReadInt();
for(size_t j = 0; j < chunkCount; j++)
{
std::vector<std::string> args;
size_t argCount = (size_t)ReadInt();
for(size_t k = 0; k < argCount; k++)
{
args.push_back(GetString());
}
std::vector<uint8_t> code;
size_t len = (size_t)ReadInt();
code.resize(len);
Ensure(code.data(),len);
//reader.ReadIntoBuffer(chunk->code);
this->chunks.emplace(this->chunks.end(),args,code);
}
}
else if(strncmp(table_name,"FUNS",4) == 0) //functions
{
size_t funLength = (size_t)ReadInt();
for(size_t j = 0; j < funLength;j++)
{
std::vector<std::string> fnParts;
uint32_t fnPartsC = ReadInt();
for(uint32_t k = 0; k < fnPartsC; k++)
{
fnParts.push_back(GetString());
}
uint32_t fnNumber = ReadInt();
this->functions.push_back(std::pair<std::vector<std::string>,uint32_t>(fnParts,fnNumber));
}
}
else if(strncmp(table_name,"STRS",4) == 0) //strings
{
size_t strsLen = (size_t)ReadInt();
for(size_t j = 0;j < strsLen;j++)
{
this->strings.push_back(ReadString());
}
}
else if(strncmp(table_name,"ICON",4) == 0) //icon
{
this->icon = (int32_t)ReadInt();
}
else if(strncmp(table_name,"MACH",4) == 0) //machine
{
std::string name = GetString();
std::string howToGet = GetString();
this->vms.push_back(std::pair<std::string,std::string>(name,howToGet));
}
else if(strncmp(table_name,"CLSS",4) == 0) //classes
{
uint32_t clsCnt = ReadInt();
for(uint32_t j = 0; j < clsCnt; j++)
{
TClass cls;
cls.documentation= GetString();
uint32_t name_cnt = ReadInt();
for(uint32_t k = 0; k < name_cnt; k++)
{
cls.name.push_back(GetString());
}
name_cnt = ReadInt();
for(uint32_t k = 0; k < name_cnt; k++)
{
cls.inherits.push_back(GetString());
}
name_cnt = ReadInt();
for(uint32_t k = 0; k < name_cnt; k++)
{
TClassEntry ent;
Ensure(main_header,1);
uint8_t sig = main_header[0];
ent.isAbstract = (sig & 0b00001000) != 0;
ent.isFunction = (sig & 0b00000100) == 0;
ent.modifier = (TClassModifier)(sig & 3);
ent.documentation = GetString();
ent.name = GetString();
uint32_t arglen = ReadInt();
for(uint32_t l = 0; l < arglen; l++)
ent.args.push_back(GetString());
ent.chunkId = ReadInt();
cls.entry.push_back(ent);
}
this->classes.push_back(cls);
}
}
else
{
std::vector<uint8_t> data;
data.resize(tableLen);
Ensure(data.data(), tableLen);
std::string key(std::string(table_name), 4);
this->sections.push_back(std::pair<std::string,std::vector<uint8_t>>(key,data));
}
}
}
std::vector<std::string> strings;
std::vector<std::pair<std::vector<std::string>,std::vector<uint8_t>>> chunks;
std::vector<std::pair<std::string,std::string>> vms;
std::vector<std::pair<std::vector<std::string>, uint32_t>> functions;
std::vector<std::pair<std::string,TVMVersion>> dependencies;
std::vector<std::pair<std::string,TVMVersion>> tools;
std::vector<std::pair<std::string,std::vector<uint8_t>>> sections;
std::vector<std::vector<uint8_t>> resources;
std::vector<TClass> classes;
std::string name;
TVMVersion version;
std::string info;
int32_t icon;
std::string Chunk2String(size_t chunkId,size_t tab)
{
if(chunkId >= this->chunks.size()) return {};
auto& code = this->chunks[chunkId].second;
std::string buffer = {};
std::vector<uint32_t> labels;
size_t i = 0;
while(i < code.size())
{
switch(code[i++])
{
case PUSHRESOURCESTREAM:
case PUSHRESOURCE:
case PUSHSTRING:
case SCOPEENDTIMES:
case PUSHCLOSURE:
case PUSHSCOPELESSCLOSURE:
i+=4;
break;
case PUSHLONG:
case PUSHDOUBLE:
i+=8;
break;
case PUSHCHAR:
i+=1;
break;
case JMP:
case JMPC:
case JMPIFBREAK:
case JMPIFCONTINUE:
case JMPIFDEFINED:
case JMPUNDEFINED:
{
bool already = false;
for(auto item : labels)
{
if(item == i) {
already=true;
break;
}
}
if(!already)
labels.push_back(BitConverter::ToUint32BE(code[i]));
i+=4;
}
break;
default:
break;
}
}
i=0;
while(i < code.size())
{
for(size_t j = 0; j < labels.size(); j++)
{
if(labels[j] == i)
{
buffer.append(tab,'\t');
buffer.append("lbl l" + std::to_string((uint32_t)j) + "\n");
break;
}
}
buffer.append(tab,'\t');
switch(code[i++])
{
case ADD:
buffer.append("add");
break;
case SUB:
buffer.append("sub");
break;
case TIMES:
buffer.append("mul");
break;
case DIVIDE:
buffer.append("div");
break;
case MODULO:
buffer.append("mod");
break;
case LEFTSHIFT:
buffer.append("lsh");
break;
case RIGHTSHIFT:
buffer.append("rsh");
break;
case BITWISEOR:
buffer.append("bor");
break;
case BITWISEAND:
buffer.append("band");
break;
case BITWISENOT:
buffer.append("bnot");
break;
case LESSTHAN:
buffer.append("lt");
break;
case GREATERTHAN:
buffer.append("gt");
break;
case LESSTHANEQ:
buffer.append("lte");
break;
case GREATERTHANEQ:
buffer.append("gte");
break;
case EQ:
buffer.append("eq");
break;
case NEQ:
buffer.append("neq");
break;
case NOT:
buffer.append("not");
break;
case NEGATIVE:
buffer.append("neg");
break;
case XOR:
buffer.append("xor");
break;
case POP:
buffer.append("pop");
break;
case DUP:
buffer.append("dup");
break;
case PUSHCLOSURE:
{
uint32_t clId = (uint32_t)code[i++] << 24;
clId |= (uint32_t)code[i++] << 16;
clId |= (uint32_t)code[i++] << 8;
clId |= (uint32_t)code[i++];
buffer.append("pushclosure (");
bool first=true;
for(auto item : this->chunks.at(clId).first)
{
if(!first)
buffer.append(", ");
buffer.append(item);
first=false;
}
buffer.append(") {\n");
buffer.append(Chunk2String((size_t)clId,tab+1));
buffer.append(tab,'\t');
buffer.append("}");
}
break;
case CREATEDICTIONARY:
buffer.append("createdict");
break;
case CREATEARRAY:
buffer.append("createarray");
break;
case APPENDLIST:
buffer.append("appendlist");
break;
case APPENDDICT:
buffer.append("appenddict");
break;
case PUSHRESOUURCEDIR:
buffer.append("embeddir");
break;
case PUSHRESOURCE:
{
uint32_t clId = (uint32_t)code[i++] << 24;
clId |= (uint32_t)code[i++] << 16;
clId |= (uint32_t)code[i++] << 8;
clId |= (uint32_t)code[i++];
buffer.append("embed ");
buffer.append(EscapeString(name + "-" + version.ToString()+"_"+ std::to_string(clId) + ".bin",true));
}
break;
case PUSHRESOURCESTREAM:
{
uint32_t clId = (uint32_t)code[i++] << 24;
clId |= (uint32_t)code[i++] << 16;
clId |= (uint32_t)code[i++] << 8;
clId |= (uint32_t)code[i++];
buffer.append("embedstrm ");
buffer.append(EscapeString(name + "-" + version.ToString()+"_"+ std::to_string(clId) + ".bin",true));
}
break;
case PUSHLONG:
{
uint64_t number = (uint64_t)code[i++] << 56;
number |= (uint64_t)code[i++] << 48;
number |= (uint64_t)code[i++] << 40;
number |= (uint64_t)code[i++] << 32;
number |= (uint64_t)code[i++] << 24;
number |= (uint64_t)code[i++] << 16;
number |= (uint64_t)code[i++] << 8;
number |= (uint64_t)code[i++];
buffer.append("push " + std::to_string(number));
}
break;
case PUSHCHAR:
{
buffer.append("push '" + EscapeString(std::string({(char)code[i++]}),false) + "'");
}
break;
case PUSHDOUBLE:
{
auto res = BitConverter::ToDoubleBE(code[i]);
i+=8;
buffer.append("push " + std::to_string(res));
}
break;
case PUSHSTRING:
{
auto res = BitConverter::ToUint32BE(code[i]);
i+=4;
buffer.append("push " + EscapeString(strings[res],true));
}
break;
case PUSHNULL:
buffer.append("push null");
break;
case PUSHUNDEFINED:
buffer.append("push undefined");
break;
case SCOPEBEGIN:
buffer.append("scopebegin");
break;
case SCOPEEND:
buffer.append("scopeend");
break;
case SCOPEENDTIMES:
{
auto res = BitConverter::ToUint32BE(code[i]);
i+=4;
buffer.append("scopeendtimes " + std::to_string(res));
}
break;
case PUSHFALSE:
buffer.append("push false");
break;
case PUSHTRUE:
buffer.append("push true");
break;
case SETVARIABLE:
buffer.append("setvariable");
break;
case GETVARIABLE:
buffer.append("getvariable");
break;
case DECLAREVARIABLE:
buffer.append("declarevariable");
break;
case DECLARECONSTVARIABLE:
buffer.append("declareconstvariable");
break;
case SETFIELD:
buffer.append("setfield");
break;
case GETFIELD:
buffer.append("getfield");
break;
case CALLFUNCTION:
buffer.append("callfunction");
break;
case CALLMETHOD:
buffer.append("callmethod");
break;
case RET:
buffer.append("ret");
break;
case JMPC:
{
auto res = BitConverter::ToUint32BE(code[i]);
i+=4;
buffer.append("jmpc l");
for(size_t j = 0; j < labels.size(); j++)
{
if(labels[j] == res)
{
buffer.append(std::to_string((uint32_t)j));
break;
}
}
}
break;
case JMP:
{
auto res = BitConverter::ToUint32BE(code[i]);
i+=4;
buffer.append("jmp l");
for(size_t j = 0; j < labels.size(); j++)
{
if(labels[j] == res)
{
buffer.append(std::to_string((uint32_t)j));
break;
}
}
}
break;
case JMPUNDEFINED:
{
auto res = BitConverter::ToUint32BE(code[i]);
i+=4;
buffer.append("jmpundefined l");
for(size_t j = 0; j < labels.size(); j++)
{
if(labels[j] == res)
{
buffer.append(std::to_string((uint32_t)j));
break;
}
}
}
break;
case DEFER:
buffer.append("defer");
break;
case TRYCATCH:
buffer.append("trycatch");
break;
case THROW:
buffer.append("throw");
break;
case PUSHSCOPELESSCLOSURE:
{
uint32_t clId = (uint32_t)code[i++] << 24;
clId |= (uint32_t)code[i++] << 16;
clId |= (uint32_t)code[i++] << 8;
clId |= (uint32_t)code[i++];
buffer.append("pushscopelessclosure (");
bool first=true;
for(auto item : this->chunks.at(clId).first)
{
if(!first)
buffer.append(", ");
buffer.append(item);
first=false;
}
buffer.append(") {\n");
buffer.append(Chunk2String((size_t)clId,tab+1));
buffer.append(tab,'\t');
buffer.append("}");
}
break;
case YIELD:
buffer.append("yield");
break;
case PUSHROOTPATH:
buffer.append("push /");
break;
case PUSHRELATIVEPATH:
buffer.append("push .");
break;
case BREAKPOINT:
buffer.append("breakpoint");
break;
case LINEINFO:
buffer.append("lineinfo");
break;
case PUSHBREAK:
buffer.append("push break");
break;
case PUSHCONTINUE:
buffer.append("push continue");
break;
case JMPIFBREAK:
{
auto res = BitConverter::ToUint32BE(code[i]);
i+=4;
buffer.append("jmpifbreak l");
for(size_t j = 0; j < labels.size(); j++)
{
if(labels[j] == res)
{
buffer.append(std::to_string((uint32_t)j));
break;
}
}
}
break;
case JMPIFCONTINUE:
{
auto res = BitConverter::ToUint32BE(code[i]);
i+=4;
buffer.append("jmpifcontinue l");
for(size_t j = 0; j < labels.size(); j++)
{
if(labels[j] == res)
{
buffer.append(std::to_string((uint32_t)j));
break;
}
}
}
break;
case JMPIFDEFINED:
{
auto res = BitConverter::ToUint32BE(code[i]);
i+=4;
buffer.append("jmpifdefined l");
for(size_t j = 0; j < labels.size(); j++)
{
if(labels[j] == res)
{
buffer.append(std::to_string((uint32_t)j));
break;
}
}
}
break;
default:
printf("ILL: %i\n", (int)code[i-1]);
break;
}
buffer.push_back('\n');
}
if(code.empty()) buffer.push_back('\n');
return buffer;
}
};
void Disassemble(std::shared_ptr<Tesses::Framework::Streams::Stream> src,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, bool generateJSON,bool extractResources)
{
using namespace Tesses::Framework::Filesystem;
CrossLangFileReader file(src);
if(extractResources)
{
std::string resdir = "res";
VFSPath path=resdir;
vfs->CreateDirectory(path);
for(size_t i = 0; i < file.resources.size(); i++)
{
auto path2 = path / file.name + "-" + file.version.ToString()+"_"+ std::to_string((uint32_t)i) + ".bin";
auto strm = vfs->OpenFile(path2,"wb");
strm->WriteBlock(file.resources[i].data(),file.resources[i].size());
}
std::string secdir = "sections";
VFSPath secpath=secdir;
vfs->CreateDirectory(secpath);
for(size_t i = 0; i < file.sections.size(); i++)
{
auto path2 = secpath / file.name + "-" + file.version.ToString()+"_"+ std::to_string((uint32_t)i) + ".tsec";
if(file.sections[i].first.size() != 4) {
throw std::runtime_error("Chunk name is not 4 bytes");
}
auto strm = vfs->OpenFile(path2,"wb");
strm->WriteBlock((const uint8_t*)file.sections[i].first.data(), 4);
strm->WriteBlock(file.sections[i].second.data(),file.sections[i].second.size());
}
}
std::string srcFile = {};
srcFile.append("root {\n");
srcFile.append(file.Chunk2String(0,1));
srcFile.append("}\n");
for(auto& item : file.functions)
{
if(!item.first[0].empty())
{
srcFile.append("/^" + Tesses::Framework::Http::HttpUtils::Replace(item.first[0],"^","^^") +"^/\n");
}
srcFile.append("func ");
for(size_t i = 1; i < item.first.size(); i++)
{
if(i > 1)
{
srcFile.push_back('.');
}
srcFile.append(item.first[i]);
}
srcFile.append("(");
auto& chunk = file.chunks.at(item.second);
for(size_t i = 0; i < chunk.first.size(); i++)
{
if(i > 0)
{
srcFile.append(", ");
}
srcFile.append(chunk.first[i]);
}
srcFile.append(") {\n");
srcFile.append(file.Chunk2String((size_t)item.second,1));
srcFile.append("}\n");
}
for(auto& cls : file.classes)
{
if(!cls.documentation.empty())
{
srcFile.append("/^" + Tesses::Framework::Http::HttpUtils::Replace(cls.documentation,"^","^^") +"^/\n");
}
srcFile.append("class ");
for(size_t i = 0; i < cls.name.size(); i++)
{
if(i > 0)
{
srcFile.push_back('.');
}
srcFile.append(cls.name[i]);
}
if(!(cls.inherits.size() == 1 && cls.inherits[0] == "ClassObject"))
{
srcFile.append(" : ");
for(size_t i = 0; i < cls.inherits.size(); i++)
{
if(i > 0)
{
srcFile.push_back('.');
}
srcFile.append(cls.inherits[i]);
}
}
srcFile.append(" {\n");
for(auto& item : cls.entry)
{
if(!item.documentation.empty())
srcFile.append("\t/^"+Tesses::Framework::Http::HttpUtils::Replace(item.documentation,"^","^^")+"^/\n");
switch(item.modifier)
{
case TClassModifier::Private:
srcFile.append("\tprivate ");
break;
case TClassModifier::Protected:
srcFile.append("\tprotected ");
break;
case TClassModifier::Public:
srcFile.append("\tpublic ");
break;
case TClassModifier::Static:
srcFile.append("\tstatic ");
default:
break;
}
if(item.isFunction)
{
if(item.isAbstract)
{
srcFile.append("abstract " + item.name);
srcFile.append("(");
for(size_t i = 0; i < item.args.size(); i++)
{
if(i > 0)
{
srcFile.append(", ");
}
srcFile.append(item.args[i]);
}
srcFile.append(");\n");
}
else {
srcFile.append(item.name);
srcFile.append("(");
for(size_t i = 0; i < item.args.size(); i++)
{
if(i > 0)
{
srcFile.append(", ");
}
srcFile.append(item.args[i]);
}
srcFile.append(") {\n");
srcFile.append(file.Chunk2String(item.chunkId,2));
srcFile.append("\t}\n");
}
}
else {
srcFile.append(item.name);
if(item.isAbstract)
{
srcFile.append(";\n");
}
else {
srcFile.append(" {\n");
srcFile.append(file.Chunk2String(item.chunkId,2));
srcFile.append("\t}\n");
}
}
}
srcFile.append("}\n");
}
std::string srcdirs = "src";
VFSPath srcdir=srcdirs;
vfs->CreateDirectory(srcdir);
Tesses::Framework::TextStreams::StreamWriter writer(vfs->OpenFile(srcdir / file.name + "-" + file.version.ToString() + ".tcasm","wb"));
writer.Write(srcFile);
if(generateJSON)
{
using namespace Tesses::Framework::Serialization::Json;
JObject json_data {
JOItem{"name", file.name},
JOItem{"version",file.version.ToString()}
};
if(!file.info.empty())
{
json_data.SetValue("info",Json::Decode(file.info));
}
if(file.icon > -1 && file.icon < file.resources.size())
{
json_data.SetValue("icon",file.name + "-" + file.version.ToString()+"_"+ std::to_string(file.icon) + ".bin");
}
if(!file.dependencies.empty())
{
JArray array;
for(auto& item : file.dependencies)
{
array.Add(JObject {
JOItem {
"name",
item.first
},
JOItem {
"version",
item.second.ToString()
}
});
}
json_data.SetValue("dependencies", array);
}
if(!file.tools.empty())
{
JArray array;
for(auto& item : file.tools)
{
array.Add(JObject {
JOItem {
"name",
item.first
},
JOItem {
"version",
item.second.ToString()
}
});
}
json_data.SetValue("tools", array);
}
if(!file.vms.empty())
{
JArray array;
for(auto& item : file.vms)
{
array.Add(JObject {
JOItem {
"name",
item.first
},
JOItem {
"how_to_get",
item.second
}
});
}
json_data.SetValue("vms", array);
}
Tesses::Framework::TextStreams::StreamWriter json_writer(vfs->OpenFile(VFSPath() / "crossapp.json","wb" ));
json_writer.WriteLine(Json::Encode(json_data,true));
}
}
}

View File

@@ -1,169 +0,0 @@
#include "CrossLang.hpp"
using namespace Tesses::Framework::Serialization::Json;
namespace Tesses::CrossLang {
static void LoadDependency(std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir, std::pair<std::string,TVMVersion> dep, std::vector<std::pair<std::string, TVMVersion>>& files, std::vector<std::pair<std::string, TVMVersion>>& tools);
static void LoadDependencies(std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir,TFile* file, std::vector<std::pair<std::string, TVMVersion>>& files, std::vector<std::pair<std::string, TVMVersion>>& tools);
static void LoadDependency(std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir, std::pair<std::string,TVMVersion> dep, std::vector<std::pair<std::string, TVMVersion>>& files, std::vector<std::pair<std::string, TVMVersion>>& tools)
{
for(auto index = files.begin(); index != files.end(); index++)
{
if(index->first == dep.first)
{
if(index->second.CompareTo(dep.second) >= 0) return;
files.erase(index);
break;
}
}
std::string name = {};
name.append(dep.first);
name.push_back('-');
name.append(dep.second.ToString());
name.append(".crvm");
auto filename= sourceDir / name;
if(srcFS->RegularFileExists(filename))
{
auto file = srcFS->OpenFile(filename,"rb");
TFile f;
f.Load(nullptr, file);
LoadDependencies(srcFS,sourceDir,&f,files,tools);
}
else throw VMException("Could not open file: \"" + name + "\".");
}
static void LoadDependencies(std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir,TFile* file, std::vector<std::pair<std::string, TVMVersion>>& files, std::vector<std::pair<std::string, TVMVersion>>& tools)
{
files.push_back(std::pair<std::string,TVMVersion>(file->name,file->version));
for(auto item : file->tools)
{
bool exists = false;
for(auto& itm2 : tools)
{
if(itm2.first == item.first)
{
exists=true;
if(itm2.second.CompareTo(item.second) < 0) {
itm2.second = item.second;
}
break;
}
}
if(!exists)
tools.push_back(item);
}
for(auto item : file->dependencies)
{
LoadDependency(srcFS,sourceDir,item,files,tools);
}
}
static void EnumerateCRVM(std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir,std::string filename, std::vector<std::pair<std::string, TVMVersion>>& files, std::shared_ptr<Tesses::Framework::Filesystem::VFS> destFS)
{
TFile file;
auto strm = srcFS->OpenFile(sourceDir / filename,"rb");
if(strm->EndOfStream()) {
throw std::runtime_error("File does not exist: " + (sourceDir / filename).ToString() );
}
file.Load(nullptr,strm);
std::vector<std::pair<std::string, TVMVersion>> tools;
LoadDependencies(srcFS,sourceDir,&file,files,tools);
JObject json_data {
JOItem{"name", file.name},
JOItem{"version",file.version.ToString()}
};
if(!file.info.empty())
{
json_data.SetValue("info",Json::Decode(file.info));
}
if(file.icon > -1 && file.icon < file.resources.size())
{
json_data.SetValue("icon",file.name + "-" + file.version.ToString()+"_"+ std::to_string(file.icon) + ".bin");
}
if(!file.tools.empty())
{
JArray array;
for(auto& item : file.tools)
{
array.Add(JObject {
JOItem {
"name",
item.first
},
JOItem {
"version",
item.second.ToString()
}
});
}
json_data.SetValue("tools", array);
}
if(!file.vms.empty())
{
JArray array;
for(auto& item : file.vms)
{
array.Add(JObject {
JOItem {
"name",
item.first
},
JOItem {
"how_to_get",
item.second
}
});
}
json_data.SetValue("vms", array);
}
Tesses::Framework::TextStreams::StreamWriter json_writer(destFS->OpenFile(Tesses::Framework::Filesystem::VFSPath() / "crossapp.json","wb" ));
json_writer.WriteLine(Json::Encode(json_data,true));
}
Tesses::Framework::Filesystem::VFSPath Merge(std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcFS, Tesses::Framework::Filesystem::VFSPath sourcePath, std::shared_ptr<Tesses::Framework::Filesystem::VFS> destFS)
{
std::vector<std::pair<std::string, TVMVersion>> files;
for(auto ent : destFS->EnumeratePaths(Tesses::Framework::Filesystem::VFSPath()))
{
if(destFS->DirectoryExists(ent))
{
destFS->DeleteDirectoryRecurse(ent);
}
else {
destFS->DeleteFile(ent);
}
}
EnumerateCRVM(srcFS,sourcePath.GetParent(), sourcePath.GetFileName(),files,destFS);
for(auto item : files)
{
auto filePath = sourcePath.GetParent() / item.first + "-" + item.second.ToString() + ".crvm";
if(srcFS->RegularFileExists(filePath))
{
auto strm = srcFS->OpenFile(filePath,"rb");
Disassemble(strm,destFS,false);
}
}
return Assemble(destFS);
}
}

View File

@@ -2,10 +2,10 @@
#if defined(CROSSLANG_ENABLE_JSON)
#include <jansson.h>
#endif
namespace Tesses::CrossLang
{
AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,bool isExpression, std::vector<SyntaxNode> nodes)
{
namespace Tesses::CrossLang {
AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,
bool isExpression,
std::vector<SyntaxNode> nodes) {
AdvancedSyntaxNode asn;
asn.nodeName = std::string(nodeName);
asn.isExpression = isExpression;
@@ -14,45 +14,43 @@ AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,bool isE
}
#if defined(CROSSLANG_ENABLE_JSON)
static SyntaxNode Deserialize2(json_t* json)
{
if(json_is_null(json)) return nullptr;
if(json_is_true(json)) return true;
if(json_is_false(json)) return false;
if(json_is_integer(json)) return (int64_t)json_integer_value(json);
if(json_is_real(json)) return json_real_value(json);
if(json_is_string(json)) return std::string(json_string_value(json),json_string_length(json));
if(json_is_object(json))
{
json_t* typ = json_object_get(json, "type");
if(json_is_string(typ))
{
std::string type(json_string_value(typ),json_string_length(typ));
if(type == CharExpression)
{
json_t* chrData = json_object_get(json,"value");
if(json_is_integer(chrData))
{
static SyntaxNode Deserialize2(json_t *json) {
if (json_is_null(json))
return nullptr;
if (json_is_true(json))
return true;
if (json_is_false(json))
return false;
if (json_is_integer(json))
return (int64_t)json_integer_value(json);
if (json_is_real(json))
return json_real_value(json);
if (json_is_string(json))
return std::string(json_string_value(json), json_string_length(json));
if (json_is_object(json)) {
json_t *typ = json_object_get(json, "type");
if (json_is_string(typ)) {
std::string type(json_string_value(typ), json_string_length(typ));
if (type == CharExpression) {
json_t *chrData = json_object_get(json, "value");
if (json_is_integer(chrData)) {
return (char)(uint8_t)json_integer_value(chrData);
}
}
if(type == UndefinedExpression)
{
if (type == UndefinedExpression) {
return Undefined();
}
json_t* isExpr = json_object_get(json,"isExpression");
json_t *isExpr = json_object_get(json, "isExpression");
bool isExprB = json_is_true(isExpr);
AdvancedSyntaxNode asn;
AdvancedSyntaxNode asn;
asn.nodeName = type;
asn.isExpression = isExprB;
json_t* args = json_object_get(json, "args");
if(json_is_array(args))
{
json_t *args = json_object_get(json, "args");
if (json_is_array(args)) {
size_t index;
json_t* value;
json_array_foreach(args, index, value)
{
json_t *value;
json_array_foreach(args, index, value) {
asn.nodes.push_back(Deserialize2(value));
}
}
@@ -63,89 +61,79 @@ static SyntaxNode Deserialize2(json_t* json)
}
#endif
SyntaxNode Deserialize(std::string astData)
{
#if defined(CROSSLANG_ENABLE_JSON)
json_t* json = json_loadb(astData.c_str(),astData.size(), 0, NULL);
SyntaxNode Deserialize(std::string astData) {
#if defined(CROSSLANG_ENABLE_JSON)
json_t *json = json_loadb(astData.c_str(), astData.size(), 0, NULL);
auto r = Deserialize2(json);
json_decref(json);
return r;
#endif
#endif
return nullptr;
}
#if defined(CROSSLANG_ENABLE_JSON)
static json_t* Serialize2(SyntaxNode node)
{
if(std::holds_alternative<std::nullptr_t>(node))
static json_t *Serialize2(SyntaxNode node) {
if (std::holds_alternative<std::nullptr_t>(node))
return json_null();
if(std::holds_alternative<int64_t>(node))
{
if (std::holds_alternative<int64_t>(node)) {
return json_integer(std::get<int64_t>(node));
}
if(std::holds_alternative<double>(node))
{
if (std::holds_alternative<double>(node)) {
return json_real(std::get<double>(node));
}
if(std::holds_alternative<bool>(node))
{
if (std::holds_alternative<bool>(node)) {
return json_boolean(std::get<bool>(node));
}
if(std::holds_alternative<std::string>(node))
{
if (std::holds_alternative<std::string>(node)) {
std::string str = std::get<std::string>(node);
return json_stringn(str.c_str(),str.size());
return json_stringn(str.c_str(), str.size());
}
if(std::holds_alternative<char>(node))
{
if (std::holds_alternative<char>(node)) {
char c = std::get<char>(node);
json_t* json = json_object();
json_object_set_new(json,"type",json_string((const char*)CharExpression.data()));
json_t *json = json_object();
json_object_set_new(json, "type",
json_string((const char *)CharExpression.data()));
json_object_set_new(json, "value", json_integer((uint8_t)c));
return json;
}
if(std::holds_alternative<Undefined>(node))
{
json_t* json = json_object();
json_object_set_new(json,"type",json_string((const char*)UndefinedExpression.data()));
if (std::holds_alternative<Undefined>(node)) {
json_t *json = json_object();
json_object_set_new(
json, "type",
json_string((const char *)UndefinedExpression.data()));
return json;
}
if(std::holds_alternative<AdvancedSyntaxNode>(node))
{
if (std::holds_alternative<AdvancedSyntaxNode>(node)) {
auto asn = std::get<AdvancedSyntaxNode>(node);
json_t* j = json_object();
json_t *j = json_object();
json_object_set_new(j, "type", json_string(asn.nodeName.c_str()));
json_object_set_new(j, "isExpression",json_boolean(asn.isExpression));
json_t* arr=json_array();
for(auto item : asn.nodes)
{
json_array_append_new(arr,Serialize2(item));
json_object_set_new(j, "isExpression", json_boolean(asn.isExpression));
json_t *arr = json_array();
for (auto item : asn.nodes) {
json_array_append_new(arr, Serialize2(item));
}
json_object_set_new(j, "args", arr);
return j;
}
return json_null();
}
#endif
std::string Serialize(SyntaxNode node)
{
std::string Serialize(SyntaxNode node) {
#if defined(CROSSLANG_ENABLE_JSON)
json_t* json = Serialize2(node);
char* txt = json_dumps(json,0);
std::string str(txt);
free(json);
json_decref(json);
return str;
json_t *json = Serialize2(node);
char *txt = json_dumps(json, 0);
std::string str(txt);
free(json);
json_decref(json);
return str;
#endif
return "";
return "";
}
}
} // namespace Tesses::CrossLang

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +0,0 @@
#include "CrossLang.hpp"
int main(int argc, char** argv)
{
using namespace Tesses::Framework;
using namespace Tesses::Framework::Streams;
using namespace Tesses::Framework::Filesystem;
using namespace Tesses::CrossLang;
TF_Init();
if(argc > 1 && strcmp(argv[1],"--help"))
{
std::cout << "Run this command in directory you want to assemble (with the crossasm.json)" << std::endl;
return 0;
}
auto curdir = VFSPath::GetAbsoluteCurrentDirectory();
auto sdfs=std::make_shared<SubdirFilesystem>(LocalFS,curdir);
auto path = Assemble(sdfs);
path.relative = true;
std::cout << "Output: " << (curdir / path).ToString() << std::endl;
return 0;
}

View File

@@ -1,63 +0,0 @@
#include "CrossLang.hpp"
void help(char* program)
{
std::cout << "USAGE: " << program << " [flags] FILE.CRVM" << std::endl;
std::cout << "USAGE: " << program << " [flags] FILE.CRVM DIR" << std::endl;
std::cout << "Flags:" << std::endl;
std::cout << "--no-json\tNo json" << std::endl;
std::cout << "--no-resources\nNo resources" << std::endl;
exit(0);
}
int main(int argc, char** argv)
{
using namespace Tesses::Framework;
using namespace Tesses::Framework::Streams;
using namespace Tesses::Framework::Filesystem;
using namespace Tesses::CrossLang;
TF_Init();
std::string file;
Tesses::Framework::Filesystem::VFSPath path = VFSPath::GetAbsoluteCurrentDirectory();
int curPos = 0;
bool json=true;
bool resources = true;
for(int i = 1; i < argc; i++)
{
if(strcmp(argv[i],"--no-json") == 0)
{
json = false;
}
else if(strcmp(argv[i],"--no-resources") == 0)
{
resources = false;
}
else if(strcmp(argv[i],"--help") == 0)
{
help(argv[0]);
}
else {
if(curPos == 0)
{
file = argv[i];
curPos++;
}
else if(curPos == 1)
{
path = LocalFS->SystemToVFSPath(argv[i]);
}
}
}
if(file.empty())
{
help(argv[0]);
}
auto strm = LocalFS->OpenFile(file,"rb");
auto sdir = std::make_shared<SubdirFilesystem>(LocalFS,path);
if(strm->CanRead())
Disassemble(strm, sdir,json,resources);
return 0;
}

View File

@@ -1,285 +0,0 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
using namespace Tesses::CrossLang;
using namespace Tesses::Framework;
using namespace Tesses::Framework::Filesystem;
void Help(const char* filename)
{
printf("USAGE: %s [OPTIONS] source_file1 source_file2 source_file_n \n", filename);
printf("OPTIONS:\n");
printf(" -o: Output directory (OUTDIR, defaults to ./bin)\n");
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": \"https://example.com/\", \"homepage\": \"https://example.com/\",\"license\":\"MIT\"})\n");
printf(" -I: Set icon resource name (in the resource folder), should be a 128x128 png\n");
printf(" -v: Set version (1.0.0.0-prod defaults to 1.0.0.0-dev)\n");
printf(" -d: Add dependency (DependencyName-1.0.0.0-prod)\n");
printf(" -D: enable debug)\n");
printf(" -t: Declare a tool (ToolName-1.0.0.0-prod)\n");
printf(" -n: Set name (MyAppOrLibName defaults to out)\n");
printf(" -r: Set resource directory (RESDIR defaults to res)\n");
printf(" -h, --help: Prints help\n");
printf(" -e: Set comptime permissions defaults to none, none for no support, \"secure\" for sane without file access, \"secure_file\" for sane with file access to current directory and sub directories, \"full\" has full runtime.\n");
printf("Options except for help have flag with arg like this: -F ARG\n");
exit(1);
}
int main(int argc, char** argv)
{
/*std::ifstream strm(argv[1],std::ios_base::in|std::ios_base::binary);
std::vector<LexToken> tokens;
Lex(argv[1],strm,tokens);
Parser parser(tokens);
CodeGen gen;
gen.GenRoot(parser.ParseRoot());
std::vector<uint8_t> data;
ByteCodeVectorWriter w(data);
gen.Save(std::filesystem::current_path(),w);
*/
TF_InitWithConsole();
std::filesystem::path outputDir = std::filesystem::current_path() / "bin";
std::vector<std::filesystem::path> source;
std::filesystem::path resourceDir = std::filesystem::current_path() / "res";
std::vector<std::pair<std::string, TVMVersion>> dependencies;
std::vector<std::pair<std::string, TVMVersion>> tools;
std::string name="out";
std::string info="{}";
std::string icon="";
std::string comptime="none";
TVMVersion version;
bool debug=false;
for(int i = 1; i < argc; i++)
{
if(strcmp(argv[i],"--help") == 0 || strcmp(argv[i],"-h")==0)
{
Help(argv[0]);
}
else if(strcmp(argv[i], "-o") == 0)
{
i++;
if(i < argc)
{
outputDir = argv[i];
}
}
else if(strcmp(argv[i], "-r") == 0)
{
i++;
if(i < argc)
{
resourceDir = argv[i];
}
}
else if(strcmp(argv[i], "-e") == 0)
{
i++;
if(i < argc)
{
comptime = argv[i];
}
}
else if(strcmp(argv[i], "-i") == 0)
{
i++;
if(i < argc)
{
info = argv[i];
}
}
else if(strcmp(argv[i],"-I") == 0)
{
i++;
if(i < argc)
{
icon = argv[i];
}
}
else if(strcmp(argv[i], "-d") == 0)
{
i++;
if(i < argc)
{
std::string str = argv[i];
auto lastDash = str.find_last_of('-');
if(lastDash < str.size())
{
std::string str2 = str.substr(lastDash+1);
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod")
{
lastDash = str.find_last_of('-',lastDash-1);
}
std::string str1 = str.substr(0,lastDash);
str2 = str.substr(lastDash+1);
TVMVersion v2;
if(!TVMVersion::TryParse(str2,v2))
{
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
exit(1);
}
dependencies.push_back(std::pair<std::string,TVMVersion>(str1,v2));
}
else
{
printf("ERROR: Dependency must have version\n");
exit(1);
}
}
}
else if(strcmp(argv[i], "-t") == 0)
{
i++;
if(i < argc)
{
std::string str = argv[i];
auto lastDash = str.find_last_of('-');
if(lastDash < str.size())
{
std::string str2 = str.substr(lastDash+1);
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod")
{
lastDash = str.find_last_of('-',lastDash-1);
}
std::string str1 = str.substr(0,lastDash);
str2 = str.substr(lastDash+1);
TVMVersion v2;
if(!TVMVersion::TryParse(str2,v2))
{
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
exit(1);
}
tools.push_back(std::pair<std::string,TVMVersion>(str1,v2));
}
else
{
printf("ERROR: Tool must have version\n");
exit(1);
}
}
}
else if(strcmp(argv[i], "-n") == 0)
{
i++;
if(i < argc)
{
name = argv[i];
}
}
else if(strcmp(argv[i], "-v") == 0)
{
i++;
if(i < argc)
{
if(!TVMVersion::TryParse(argv[i],version))
{
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
exit(1);
}
}
}
else if(strcmp(argv[i],"-D") == 0)
{
debug = true;
}
else {
source.push_back(argv[i]);
}
}
if(source.empty())
{
Help(argv[0]);
}
std::vector<LexToken> tokens;
for(auto src : source)
{
std::ifstream strm(src,std::ios_base::in|std::ios_base::binary);
int res = Lex(std::filesystem::absolute(src).string(),strm,tokens);
}
std::shared_ptr<GC> gc;
std::shared_ptr<GCList> ls;
TRootEnvironment* env=nullptr;
if(comptime != "none")
{
gc = std::make_shared<GC>();
gc->Start();
ls = std::make_shared<GCList>(gc);
env = TRootEnvironment::Create(*ls,TDictionary::Create(*ls));
if(comptime == "secure")
{
TStd::RegisterConsole(gc,env);
TStd::RegisterClass(gc,env);
TStd::RegisterCrypto(gc,env);
TStd::RegisterDictionary(gc,env);
TStd::RegisterJson(gc,env);
TStd::RegisterRoot(gc,env);
TStd::RegisterIO(gc,env,false);
env->permissions.locked=true;
}
else if(comptime == "secure_file")
{
TStd::RegisterConsole(gc,env);
TStd::RegisterClass(gc,env);
TStd::RegisterCrypto(gc,env);
TStd::RegisterDictionary(gc,env);
TStd::RegisterJson(gc,env);
TStd::RegisterRoot(gc,env);
TStd::RegisterIO(gc,env,false);
env->permissions.locked=true;
auto fs = env->EnsureDictionary(gc,"FS");
fs->SetValue("Local", std::make_shared<SubdirFilesystem>(LocalFS,Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory()));
}
else if(comptime == "full")
{
TStd::RegisterStd(gc,env);
env->permissions.locked=true;
}
}
Parser parser(tokens,gc,env);
parser.debug = debug;
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,LocalFS->SystemToVFSPath(resourceDir.string()));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
gen.name = name;
gen.version = version;
gen.info = info;
gen.icon = icon;
for(auto deps : dependencies)
{
gen.dependencies.push_back(deps);
}
for(auto tool : tools)
{
gen.tools.push_back(tool);
}
std::filesystem::create_directory(outputDir);
{
auto strm = std::make_shared<Tesses::Framework::Streams::FileStream>(outputDir / (name + "-" + version.ToString() + ".crvm"),"wb");
gen.Save(strm);
}
return 0;
}

View File

@@ -1,44 +0,0 @@
#include "CrossLang.hpp"
void help(char* program)
{
std::cout << "USAGE: " << program << " FILE.CRVM DEST.CRVM" << std::endl;
exit(0);
}
int main(int argc, char** argv)
{
using namespace Tesses::Framework;
using namespace Tesses::Framework::Streams;
using namespace Tesses::Framework::Filesystem;
using namespace Tesses::CrossLang;
TF_Init();
if(argc < 3)
{
help(argv[0]);
}
std::string src=argv[1];
std::string dest=argv[2];
VFSPath srcF = src;
VFSPath destF = dest;
srcF.MakeAbsolute();
destF.MakeAbsolute();
auto sdir = std::make_shared<SubdirFilesystem>(LocalFS,srcF.GetParent());
auto ddir = std::make_shared<SubdirFilesystem>(LocalFS,destF+"_tmp");
auto outpath = Merge(sdir,"/"+srcF.GetFileName(), ddir);
outpath.relative=true;
outpath = (destF+"_tmp") / outpath;
LocalFS->MoveFile(outpath,destF);
LocalFS->DeleteDirectoryRecurse(destF+"_tmp");
return 0;
}

View File

@@ -3,57 +3,49 @@
#include <TessesFramework/Filesystem/LocalFS.hpp>
#include <TessesFramework/Filesystem/VFS.hpp>
#include <TessesFramework/Streams/Stream.hpp>
#include <fstream>
#include <ios>
#include <iostream>
#include <fstream>
int main(int argc,char** argv)
{
int main(int argc, char **argv) {
Tesses::Framework::TF_Init();
std::string p = argv[0];
auto emptyThumb =Tesses::Framework::Platform::Environment::GetRealExecutablePath(p).GetParent().GetParent() / "share" / "icons" / "crosslang.png";
if(argc < 3)
{
auto emptyThumb =
Tesses::Framework::Platform::Environment::GetRealExecutablePath(p)
.GetParent()
.GetParent() /
"share" / "icons" / "crosslang.png";
if (argc < 3) {
std::cout << "USAGE: " << argv[0] << " CRVMFILE NEWPNG" << std::endl;
return 1;
}
std::string crvm = argv[1];
std::string png = argv[2];
if(Tesses::Framework::Filesystem::LocalFS->FileExists(crvm))
{
Tesses::CrossLang::TFile file;
auto f = Tesses::Framework::Filesystem::LocalFS->OpenFile(crvm, "rb");
file.Load(nullptr,f);
if (Tesses::Framework::Filesystem::LocalFS->FileExists(crvm)) {
Tesses::CrossLang::TFile file;
auto f = Tesses::Framework::Filesystem::LocalFS->OpenFile(crvm, "rb");
if(file.icon >= 0 && file.icon < file.resources.size())
{
auto f2 = Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
if(f2 != nullptr)
{
auto& icon = file.resources[file.icon];
f2->WriteBlock(icon.data(),icon.size());
}
return 0;
file.Load(nullptr, f);
if (file.icon >= 0 && file.icon < file.resources.size()) {
auto f2 =
Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
if (f2 != nullptr) {
auto &icon = file.resources[file.icon];
f2->WriteBlock(icon.data(), icon.size());
}
return 0;
}
}
if(Tesses::Framework::Filesystem::LocalFS->FileExists(emptyThumb))
{
auto src = Tesses::Framework::Filesystem::LocalFS->OpenFile(emptyThumb,"rb");
auto dest = Tesses::Framework::Filesystem::LocalFS->OpenFile(png,"wb");
if(src != nullptr && dest != nullptr)
{
if (Tesses::Framework::Filesystem::LocalFS->FileExists(emptyThumb)) {
auto src =
Tesses::Framework::Filesystem::LocalFS->OpenFile(emptyThumb, "rb");
auto dest = Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
if (src != nullptr && dest != nullptr) {
src->CopyTo(dest);
}
}
return 0;
}

View File

@@ -1,37 +1,25 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
SharedPtrTObject::SharedPtrTObject(std::shared_ptr<GC> gc, TObject o)
{
this->ls = new GCList(gc);
this->ls->Add(o);
this->o = o;
}
TObject& SharedPtrTObject::GetObject()
{
return this->o;
}
SharedPtrTObject::~SharedPtrTObject()
{
if(this->ls)
namespace Tesses::CrossLang {
SharedPtrTObject::SharedPtrTObject(std::shared_ptr<GC> gc, TObject o) {
this->ls = new GCList(gc);
this->ls->Add(o);
this->o = o;
}
TObject &SharedPtrTObject::GetObject() { return this->o; }
SharedPtrTObject::~SharedPtrTObject() {
if (this->ls)
delete this->ls;
}
std::shared_ptr<GC> SharedPtrTObject::GetGC()
{
return this->ls->GetGC();
}
MarkedTObject CreateMarkedTObject(std::shared_ptr<GC> gc, TObject o)
{
return std::make_shared<SharedPtrTObject>(gc,o);
}
MarkedTObject CreateMarkedTObject(GCList* gc, TObject o)
{
return CreateMarkedTObject(gc->GetGC(),o);
}
MarkedTObject CreateMarkedTObject(GCList& gc, TObject o)
{
return CreateMarkedTObject(gc.GetGC(),o);
}
}
}
std::shared_ptr<GC> SharedPtrTObject::GetGC() { return this->ls->GetGC(); }
MarkedTObject CreateMarkedTObject(std::shared_ptr<GC> gc, TObject o) {
return std::make_shared<SharedPtrTObject>(gc, o);
}
MarkedTObject CreateMarkedTObject(GCList *gc, TObject o) {
return CreateMarkedTObject(gc->GetGC(), o);
}
MarkedTObject CreateMarkedTObject(GCList &gc, TObject o) {
return CreateMarkedTObject(gc.GetGC(), o);
}
} // namespace Tesses::CrossLang

View File

@@ -3,12 +3,15 @@
namespace Tesses::CrossLang::Programs {
using namespace Tesses::Framework::Filesystem;
using namespace Tesses::Framework::Streams;
static void Help(std::string& filename)
{
std::cout << "USAGE: " << filename << " [OPTIONS] <dirasroot> <archive.crvm>" << std::endl;
static void Help(std::string &filename) {
std::cout << "USAGE: " << filename
<< " [OPTIONS] <dirasroot> <archive.crvm>" << std::endl;
printf("OPTIONS:\n");
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": \"https://example.com/\", \"homepage\": \"https://example.com/\",\"license\":\"MIT\"})\n");
printf(" -I: Set icon name (relative to dirasroot), should be a 128x128 png\n");
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": "
"\"https://example.com/\", \"homepage\": "
"\"https://example.com/\",\"license\":\"MIT\"})\n");
printf(" -I: Set icon name (relative to dirasroot), should be a 128x128 "
"png\n");
printf(" -v: Set version (1.0.0.0-prod defaults to 1.0.0.0-dev)\n");
printf(" -n: Set name (MyAppOrLibName defaults to out)\n");
printf(" -h, --help: Prints help\n");
@@ -16,80 +19,66 @@ static void Help(std::string& filename)
exit(1);
}
int64_t CrossArchiveCreate(std::vector<std::string>& argv)
{
int64_t CrossArchiveCreate(std::vector<std::string> &argv) {
Tesses::Framework::TF_Init();
std::string name="out";
std::string info="{}";
TVMVersion version;
std::string icon="";
std::vector<std::string> args;
for(int i = 1; i < argv.size(); i++)
{
if(argv[i] == "--help" || argv[i] == "-h")
{
std::string name = "out";
std::string info = "{}";
TVMVersion version;
std::string icon = "";
std::vector<std::string> args;
for (int i = 1; i < argv.size(); i++) {
if (argv[i] == "--help" || argv[i] == "-h") {
Help(argv[0]);
}
else if(argv[i] == "-i")
{
} else if (argv[i] == "-i") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
info = argv[i];
}
}
else if(argv[i] == "-I")
{
} else if (argv[i] == "-I") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
icon = argv[i];
}
}
else if(argv[i] == "-n")
{
} else if (argv[i] == "-n") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
name = argv[i];
}
}
else if(argv[i] == "-v")
{
} else if (argv[i] == "-v") {
i++;
if(i < argv.size())
{
if(!TVMVersion::TryParse(argv[i],version))
{
if (i < argv.size()) {
if (!TVMVersion::TryParse(argv[i], version)) {
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
"]]]\n");
exit(1);
}
}
}
else {
} else {
args.push_back(argv[i]);
}
}
}
if(args.size() < 2) Help(argv[0]);
auto path = Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(args[0]);
if (args.size() < 2)
Help(argv[0]);
auto path =
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(args[0]);
Tesses::Framework::Filesystem::LocalFS->CreateDirectory(path);
auto sdfs = std::make_shared<SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,path);
auto sdfs = std::make_shared<SubdirFilesystem>(
Tesses::Framework::Filesystem::LocalFS, path);
FILE* f = fopen(args[1].c_str(),"wb");
if(f == NULL)
{
FILE *f = fopen(args[1].c_str(), "wb");
if (f == NULL) {
printf("ERROR: could not open %s\n", args[1].c_str());
return 1;
}
auto strm = std::make_shared<FileStream>(f,true,"wb",true);
CrossArchiveCreate(sdfs,strm,name,version,info,icon);
auto strm = std::make_shared<FileStream>(f, true, "wb", true);
CrossArchiveCreate(sdfs, strm, name, version, info, icon);
return 0;
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -5,25 +5,23 @@ namespace Tesses::CrossLang::Programs {
using namespace Tesses::Framework::Filesystem;
using namespace Tesses::Framework::Streams;
int64_t CrossArchiveExtract(std::vector<std::string>& argv)
{
int64_t CrossArchiveExtract(std::vector<std::string> &argv) {
Tesses::Framework::TF_Init();
if(argv.size() < 3)
{
std::cout << "USAGE: " << argv[0] << " <archive.crvm> <dirasroot>" << std::endl;
if (argv.size() < 3) {
std::cout << "USAGE: " << argv[0] << " <archive.crvm> <dirasroot>"
<< std::endl;
return 1;
}
auto sdfs= std::make_shared<SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,std::string(argv[2]));
auto strm= LocalFS->OpenFile(argv[1], "rb");
if(strm->CanRead())
{
auto sdfs = std::make_shared<SubdirFilesystem>(
Tesses::Framework::Filesystem::LocalFS, std::string(argv[2]));
auto strm = LocalFS->OpenFile(argv[1], "rb");
if (!strm->CanRead()) {
std::cout << "ERROR: could not open " << argv[1] << std::endl;
return 1;
}
auto res = Tesses::CrossLang::CrossArchiveExtract(strm,sdfs);
auto res = Tesses::CrossLang::CrossArchiveExtract(strm, sdfs);
std::cout << "Crvm Name: " << res.first.first << std::endl;
std::cout << "Crvm Version: " << res.first.second.ToString() << std::endl;
@@ -31,4 +29,4 @@ int64_t CrossArchiveExtract(std::vector<std::string>& argv)
return 0;
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -1,38 +1,37 @@
#include "CrossLang.hpp"
#include <iostream>
namespace Tesses::CrossLang::Programs {
static void Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,uint8_t* buffer, size_t len)
{
if(strm->ReadBlock(buffer,len) != len)
{
throw VMException("Could not read " + std::to_string(len) + " byte(s).");
static void Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
uint8_t *buffer, size_t len) {
if (strm->ReadBlock(buffer, len) != len) {
throw VMException("Could not read " + std::to_string(len) +
" byte(s).");
}
}
static uint32_t EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
{
static uint32_t
EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
uint8_t buff[4];
Ensure(strm,buff,sizeof(buff));
Ensure(strm, buff, sizeof(buff));
return BitConverter::ToUint32BE(buff[0]);
}
static std::string EnsureString(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
{
static std::string
EnsureString(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
size_t len = (size_t)EnsureInt(strm);
std::string myStr={};
std::string myStr = {};
myStr.resize(len);
Ensure(strm,(uint8_t*)myStr.data(), len);
Ensure(strm, (uint8_t *)myStr.data(), len);
return myStr;
}
void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
{
void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
uint8_t main_header[18];
Ensure(strm,main_header,sizeof(main_header));
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image.");
TVMVersion version(main_header+8);
if(version.CompareToRuntime() == 1)
{
Ensure(strm, main_header, sizeof(main_header));
if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
throw VMException("Invalid TCrossVM image.");
TVMVersion version(main_header + 8);
if (version.CompareToRuntime() == 1) {
throw VMException("Runtime is too old.");
}
TVMVersion v2(main_header+13);
TVMVersion v2(main_header + 13);
std::cout << "Version: " << v2.ToString() << std::endl;
size_t _len = (size_t)EnsureInt(strm);
@@ -41,215 +40,188 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
std::vector<std::string> strs;
std::unordered_map<uint32_t, std::vector<std::string>> funs;
std::vector<std::vector<std::string>> closures;
std::unordered_map<uint32_t, std::vector<std::string>> funs;
std::vector<std::vector<std::string>> closures;
char table_name[4];
bool hasIcon = false;
char table_name[4];
bool hasIcon=false;
for (size_t i = 0; i < _len; i++) {
Ensure(strm, (uint8_t *)table_name, sizeof(table_name));
size_t tableLen = (size_t)EnsureInt(strm);
std::string tableName(table_name, 4);
if (tableName == "ICON") {
hasIcon = true;
} else if (tableName == "STRS") {
size_t strsLen = (size_t)EnsureInt(strm);
for (size_t j = 0; j < strsLen; j++) {
strs.push_back(EnsureString(strm));
}
} else if (tableName == "DEPS") {
for(size_t i = 0; i < _len; i++)
{
Ensure(strm,(uint8_t*)table_name,sizeof(table_name));
size_t tableLen = (size_t)EnsureInt(strm);
std::string tableName(table_name,4);
if(tableName == "ICON")
{
hasIcon=true;
std::string name = strs.at((size_t)EnsureInt(strm));
uint8_t version_bytes[5];
Ensure(strm, version_bytes, sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
std::cout << "Dependency: " << name << "-" << depVersion.ToString()
<< std::endl;
} else if (tableName == "NAME") {
std::cout << "Name: " << strs.at((size_t)EnsureInt(strm))
<< std::endl;
} else if (tableName == "CLSS") {
std::cout << "Classes:\n";
uint32_t clss_cnt = EnsureInt(strm);
for (uint32_t j = 0; j < clss_cnt; j++) {
std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/"
<< std::endl;
uint32_t fnPartsC = EnsureInt(strm);
std::cout << "\tName: ";
for (uint32_t k = 0; k < fnPartsC; k++) {
if (k > 0)
std::cout << ".";
std::cout << strs.at(EnsureInt(strm));
}
else if(tableName == "STRS")
{
size_t strsLen = (size_t)EnsureInt(strm);
for(size_t j = 0;j < strsLen;j++)
{
strs.push_back(EnsureString(strm));
std::cout << std::endl;
fnPartsC = EnsureInt(strm);
std::cout << "\tInherits: ";
for (uint32_t k = 0; k < fnPartsC; k++) {
if (k > 0)
std::cout << ".";
std::cout << strs.at(EnsureInt(strm));
}
std::cout << std::endl;
uint32_t ents = EnsureInt(strm);
for (uint32_t k = 0; k < ents; k++) {
Ensure(strm, main_header, 1);
uint8_t flags = main_header[0];
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/"
<< std::endl;
std::string fnname = strs.at(EnsureInt(strm));
std::string fnargs;
uint32_t argParts = EnsureInt(strm);
for (uint32_t l = 0; l < argParts; l++) {
if (l > 0)
fnargs += ", ";
fnargs += strs.at(EnsureInt(strm));
}
}
else if(tableName == "DEPS")
{
std::string name = strs.at((size_t)EnsureInt(strm));
uint8_t version_bytes[5];
Ensure(strm,version_bytes,sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
std::cout << "Dependency: " << name << "-" << depVersion.ToString() << std::endl;
}
else if(tableName == "NAME")
{
std::cout << "Name: " << strs.at((size_t)EnsureInt(strm)) << std::endl;
}
else if(tableName == "CLSS")
{
std::cout << "Classes:\n";
uint32_t clss_cnt= EnsureInt(strm);
for(uint32_t j = 0; j < clss_cnt; j++)
{
std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl;
uint32_t fnPartsC = EnsureInt(strm);
std::cout << "\tName: ";
for(uint32_t k = 0; k < fnPartsC; k++)
{
if(k > 0) std::cout << ".";
std::cout << strs.at(EnsureInt(strm));
}
std::cout << std::endl;
fnPartsC = EnsureInt(strm);
std::cout << "\tInherits: ";
for(uint32_t k = 0; k < fnPartsC; k++)
{
if(k > 0) std::cout << ".";
std::cout << strs.at(EnsureInt(strm));
}
std::cout << std::endl;
uint32_t ents = EnsureInt(strm);
for(uint8_t k = 0; k < ents; k++)
{
Ensure(strm,main_header,1);
uint8_t flags = main_header[0];
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl;
std::string fnname = strs.at(EnsureInt(strm));
std::string fnargs;
uint32_t argParts = EnsureInt(strm);
for(uint32_t l = 0; l < argParts; l++)
{
if(l > 0) fnargs += ", ";
fnargs += strs.at(EnsureInt(strm));
}
uint32_t fnchunk = EnsureInt(strm);
switch(flags & 3)
{
case 0:
std::cout << "\t\tprivate ";
break;
case 1:
std::cout << "\t\tprotected ";
break;
case 2:
std::cout << "\t\tpublic ";
break;
case 3:
std::cout << "\t\tstatic ";
break;
}
switch((flags >> 2) & 3)
{
case 0:
std::cout << "func " << fnname << "(" << fnargs << "), chunk = " << fnchunk << std::endl;
break;
case 1:
std::cout << "field " << fnname << ", chunk = " << fnchunk << std::endl;
break;
case 2:
std::cout << "abstract " << fnname << "(" << fnargs << ")" << std::endl;
break;
case 3:
std::cout << "unset_field " << fnname << std::endl;
break;
}
std::cout << std::endl;
}
}
}
else if(tableName == "CHKS")
{
size_t chunkCount = (size_t)EnsureInt(strm);
for(size_t j = 0; j < chunkCount; j++)
{
std::vector<std::string> args;
size_t argCount = (size_t)EnsureInt(strm);
for(size_t k = 0; k < argCount; k++)
{
args.push_back(strs.at(EnsureInt(strm)));
}
auto len = EnsureInt(strm);
strm->Seek(len,Tesses::Framework::Streams::SeekOrigin::Current);
closures.push_back(args);
}
}
else if(tableName == "FUNS")
{
size_t funLength = (size_t)EnsureInt(strm);
for(size_t j = 0; j < funLength;j++)
{
std::vector<std::string> fnParts;
uint32_t fnPartsC = EnsureInt(strm);
for(uint32_t k = 0; k < fnPartsC; k++)
{
fnParts.push_back(strs.at(EnsureInt(strm)));
uint32_t fnchunk = EnsureInt(strm);
switch (flags & 3) {
case 0:
std::cout << "\t\tprivate ";
break;
case 1:
std::cout << "\t\tprotected ";
break;
case 2:
std::cout << "\t\tpublic ";
break;
case 3:
std::cout << "\t\tstatic ";
break;
}
uint32_t fnNumber = EnsureInt(strm);
funs[fnNumber] = fnParts;
}
}
else if(tableName == "INFO")
{
switch ((flags >> 2) & 3) {
case 0:
std::cout << "func " << fnname << "(" << fnargs
<< "), chunk = " << fnchunk << std::endl;
std::cout << "Info: " << strs.at((size_t)EnsureInt(strm)) << std::endl;
}
else
{
strm->Seek((int64_t)tableLen,Tesses::Framework::Streams::SeekOrigin::Current);
break;
case 1:
std::cout << "field " << fnname
<< ", chunk = " << fnchunk << std::endl;
break;
case 2:
std::cout << "abstract " << fnname << "(" << fnargs
<< ")" << std::endl;
break;
case 3:
std::cout << "unset_field " << fnname << std::endl;
break;
}
std::cout << std::endl;
}
}
if(hasIcon)
std::cout << "Has Icon: yes" << std::endl;
else
std::cout << "Has Icon: no" << std::endl;
} else if (tableName == "CHKS") {
size_t chunkCount = (size_t)EnsureInt(strm);
for(size_t i = 1; i < closures.size(); i++)
{
if(funs.count((uint32_t)i) > 0)
{
std::cout << "Func: ";
auto res = funs[(uint32_t)i];
if(!res.empty()) {
std::cout << "/^" << res[0] << "^/ ";
}
for(size_t i = 1; i < res.size(); i++)
{
if(i > 1) std::cout << ".";
std::cout << res[i];
}
for (size_t j = 0; j < chunkCount; j++) {
std::vector<std::string> args;
size_t argCount = (size_t)EnsureInt(strm);
for (size_t k = 0; k < argCount; k++) {
args.push_back(strs.at(EnsureInt(strm)));
}
else
{
std::cout << "Closure: ";
}
std::cout << "(";
bool first=true;
for(auto arg : closures[i])
{
if(!first) std::cout << ", ";
std::cout << arg;
auto len = EnsureInt(strm);
if(first) first=false;
}
std::cout << ")" << std::endl;
strm->Seek(len,
Tesses::Framework::Streams::SeekOrigin::Current);
closures.push_back(args);
}
std::cout << std::endl;
std::cout << "String Table:" << std::endl;
} else if (tableName == "FUNS") {
size_t funLength = (size_t)EnsureInt(strm);
for(auto str : strs) {
std::cout << EscapeString(str, true) << std::endl;
for (size_t j = 0; j < funLength; j++) {
std::vector<std::string> fnParts;
uint32_t fnPartsC = EnsureInt(strm);
for (uint32_t k = 0; k < fnPartsC; k++) {
fnParts.push_back(strs.at(EnsureInt(strm)));
}
uint32_t fnNumber = EnsureInt(strm);
funs[fnNumber] = fnParts;
}
} else if (tableName == "INFO") {
std::cout << "Info: " << strs.at((size_t)EnsureInt(strm))
<< std::endl;
} else {
strm->Seek((int64_t)tableLen,
Tesses::Framework::Streams::SeekOrigin::Current);
}
}
if (hasIcon)
std::cout << "Has Icon: yes" << std::endl;
else
std::cout << "Has Icon: no" << std::endl;
for (size_t i = 1; i < closures.size(); i++) {
if (funs.count((uint32_t)i) > 0) {
std::cout << "Func: ";
auto res = funs[(uint32_t)i];
if (!res.empty()) {
std::cout << "/^" << res[0] << "^/ ";
}
for (size_t i = 1; i < res.size(); i++) {
if (i > 1)
std::cout << ".";
std::cout << res[i];
}
} else {
std::cout << "Closure: ";
}
std::cout << "(";
bool first = true;
for (auto arg : closures[i]) {
if (!first)
std::cout << ", ";
std::cout << arg;
if (first)
first = false;
}
std::cout << ")" << std::endl;
}
std::cout << std::endl;
std::cout << "String Table:" << std::endl;
for (auto str : strs) {
std::cout << EscapeString(str, true) << std::endl;
}
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -6,153 +6,150 @@
using namespace Tesses::Framework;
using namespace Tesses::Framework::Http;
namespace Tesses::CrossLang::Programs
{
namespace Tesses::CrossLang::Programs {
static bool Download(Tesses::Framework::Filesystem::VFSPath filename,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs)
{
auto inContainer=Platform::Environment::GetVariable("CROSSLANG_CONTAINER");
if(inContainer && (*inContainer=="1" || *inContainer=="y" || *inContainer=="Y"))
{
static bool Download(Tesses::Framework::Filesystem::VFSPath filename,
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs) {
auto inContainer =
Platform::Environment::GetVariable("CROSSLANG_CONTAINER");
if (inContainer &&
(*inContainer == "1" || *inContainer == "y" || *inContainer == "Y")) {
HttpRequest req;
req.followRedirects=true;
req.followRedirects = true;
req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET";
HttpResponse resp(req);
if(resp.statusCode == StatusCode::OK)
{
if (resp.statusCode == StatusCode::OK) {
auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, vfs);
return true;
}
else
{
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
} else {
std::cout << "Error when fetching the script error: "
<< std::to_string(resp.statusCode) << " "
<< HttpUtils::StatusCodeString(resp.statusCode)
<< std::endl;
return false;
}
}
while(true)
{
std::cout << "File " << filename.ToString() << " not found, do you want to download the installer from: https://redirect.tesses.net/crosslang-shell (this may install other stuff as well) (Y/n)? ";
while (true) {
std::cout << "File " << filename.ToString()
<< " not found, do you want to download the installer from: "
"https://redirect.tesses.net/crosslang-shell (this may "
"install other stuff as well) (Y/n)? ";
std::string line;
std::getline(std::cin,line);
if(line == "Y" || line == "y")
{
std::getline(std::cin, line);
if (line == "Y" || line == "y") {
HttpRequest req;
req.followRedirects = true;
req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET";
HttpResponse resp(req);
if(resp.statusCode == StatusCode::OK)
{
if (resp.statusCode == StatusCode::OK) {
auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, vfs);
return true;
}
else
{
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
} else {
std::cout << "Error when fetching the script error: "
<< std::to_string(resp.statusCode) << " "
<< HttpUtils::StatusCodeString(resp.statusCode)
<< std::endl;
return false;
}
}
else if(line == "N" || line == "n")
{
std::cout << "Looks like you will need to install manually" << std::endl;
} else if (line == "N" || line == "n") {
std::cout << "Looks like you will need to install manually"
<< std::endl;
return false;
}
else
{
} else {
std::cout << "Please use Y or N (case insensitive)" << std::endl;
}
}
return false;
}
TObject CrossLangShell(GCList& ls, std::vector<std::string>& argv)
{
TObject CrossLangShell(GCList &ls, std::vector<std::string> &argv) {
Tesses::Framework::Filesystem::VFSPath dir = GetCrossLangConfigDir();
Tesses::Framework::Filesystem::VFSPath filename = dir / "Shell" / "Shell.crvm";
Tesses::Framework::Filesystem::VFSPath filename =
dir / "Shell" / "Shell.crvm";
auto p = Tesses::Framework::Platform::Environment::GetRealExecutablePath(Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[0])).GetParent().GetParent() / "share" / "Tesses" / "CrossLang" / "Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm";
if(argv.size() == 2 && argv[1] == "configdir")
{
auto p =
Tesses::Framework::Platform::Environment::GetRealExecutablePath(
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[0]))
.GetParent()
.GetParent() /
"share" / "Tesses" / "CrossLang" /
"Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm";
if (argv.size() == 2 && argv[1] == "configdir") {
std::cout << dir.ToString() << std::endl;
return 0;
}
if(argv.size() > 1 && argv[1] == "update-shell")
{
if (argv.size() > 1 && argv[1] == "update-shell") {
auto subdir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,dir);
auto subdir =
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
Tesses::Framework::Filesystem::LocalFS, dir);
HttpRequest req;
req.followRedirects=true;
req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET";
HttpResponse resp(req);
if(resp.statusCode == StatusCode::OK)
{
auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, subdir);
req.followRedirects = true;
req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET";
HttpResponse resp(req);
if (resp.statusCode == StatusCode::OK) {
auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, subdir);
return 0;
}
else
{
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
return 1;
}
return 0;
} else {
std::cout << "Error when fetching the script error: "
<< std::to_string(resp.statusCode) << " "
<< HttpUtils::StatusCodeString(resp.statusCode)
<< std::endl;
return 1;
}
return 0;
}
if(!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename))
{
auto subdir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,dir);
if(Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p))
{
std::cout << "Installing " << p.ToString() << " -> " << dir.ToString() << std::endl;
auto strm = Tesses::Framework::Filesystem::LocalFS->OpenFile(p,"rb");
if(strm != nullptr)
{
if (!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename)) {
auto subdir =
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
Tesses::Framework::Filesystem::LocalFS, dir);
if (Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p)) {
std::cout << "Installing " << p.ToString() << " -> "
<< dir.ToString() << std::endl;
auto strm =
Tesses::Framework::Filesystem::LocalFS->OpenFile(p, "rb");
if (strm != nullptr) {
CrossLang::CrossArchiveExtract(strm, subdir);
}
else
{
} else {
return 1;
}
}
else
{
if(!Download(filename,subdir)) return 1;
} else {
if (!Download(filename, subdir))
return 1;
return 0;
}
}
TRootEnvironment *env =
TRootEnvironment::Create(ls, TDictionary::Create(ls));
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(ls.GetGC(), env);
env->LoadFileWithDependencies(
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
TStd::RegisterStd(ls.GetGC(),env);
env->LoadFileWithDependencies(ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
TList* args = TList::Create(ls);
TList *args = TList::Create(ls);
args->Add(filename.ToString());
for(size_t arg=1;arg<argv.size();arg++)
for (size_t arg = 1; arg < argv.size(); arg++)
args->Add(std::string(argv[arg]));
return env->CallFunctionWithFatalError(ls,"main",{args});
return env->CallFunctionWithFatalError(ls, "main", {args});
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -1,16 +1,20 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <iostream>
using namespace Tesses::Framework;
using namespace Tesses::Framework::Filesystem;
namespace Tesses::CrossLang::Programs {
static void Help(std::string filename)
{
std::cout << "USAGE: " << filename << " [OPTIONS] source_file1 source_file2 source_file_n" << std::endl;
static void Help(std::string filename) {
std::cout << "USAGE: " << filename
<< " [OPTIONS] source_file1 source_file2 source_file_n"
<< std::endl;
printf("OPTIONS:\n");
printf(" -o: Output directory (OUTDIR, defaults to ./bin)\n");
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": \"https://example.com/\", \"homepage\": \"https://example.com/\",\"license\":\"MIT\"})\n");
printf(" -I: Set icon resource name (in the resource folder), should be a 128x128 png\n");
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": "
"\"https://example.com/\", \"homepage\": "
"\"https://example.com/\",\"license\":\"MIT\"})\n");
printf(" -I: Set icon resource name (in the resource folder), should be "
"a 128x128 png\n");
printf(" -v: Set version (1.0.0.0-prod defaults to 1.0.0.0-dev)\n");
printf(" -d: Add dependency (DependencyName-1.0.0.0-prod)\n");
printf(" -D: enable debug)\n");
@@ -18,12 +22,14 @@ static void Help(std::string filename)
printf(" -n: Set name (MyAppOrLibName defaults to out)\n");
printf(" -r: Set resource directory (RESDIR defaults to res)\n");
printf(" -h, --help: Prints help\n");
printf(" -e: Set comptime permissions defaults to none, none for no support, \"secure\" for sane without file access, \"secure_file\" for sane with file access to current directory and sub directories, \"full\" has full runtime.\n");
printf(" -e: Set comptime permissions defaults to none, none for no "
"support, \"secure\" for sane without file access, \"secure_file\" "
"for sane with file access to current directory and sub "
"directories, \"full\" has full runtime.\n");
printf("Options except for help have flag with arg like this: -F ARG\n");
exit(1);
}
void CrossLangCompiler(std::vector<std::string>& argv)
{
void CrossLangCompiler(std::vector<std::string> &argv) {
/*std::ifstream strm(argv[1],std::ios_base::in|std::ios_base::binary);
std::vector<LexToken> tokens;
Lex(argv[1],strm,tokens);
@@ -36,228 +42,189 @@ void CrossLangCompiler(std::vector<std::string>& argv)
ByteCodeVectorWriter w(data);
gen.Save(std::filesystem::current_path(),w);
*/
TF_InitWithConsole();
std::filesystem::path outputDir = std::filesystem::current_path() / "bin";
std::vector<std::filesystem::path> source;
std::filesystem::path resourceDir = std::filesystem::current_path() / "res";
std::vector<std::pair<std::string, TVMVersion>> dependencies;
std::vector<std::pair<std::string, TVMVersion>> tools;
std::string name="out";
std::string info="{}";
std::string icon="";
std::string comptime="none";
TVMVersion version;
bool debug=false;
TF_InitWithConsole();
std::filesystem::path outputDir = std::filesystem::current_path() / "bin";
std::vector<std::filesystem::path> source;
std::filesystem::path resourceDir = std::filesystem::current_path() / "res";
std::vector<std::pair<std::string, TVMVersion>> dependencies;
std::vector<std::pair<std::string, TVMVersion>> tools;
std::string name = "out";
std::string info = "{}";
std::string icon = "";
std::string comptime = "none";
TVMVersion version;
bool debug = false;
for(size_t i = 1; i < argv.size(); i++)
{
if(argv[i] == "--help" || argv[i] == "-h")
{
for (size_t i = 1; i < argv.size(); i++) {
if (argv[i] == "--help" || argv[i] == "-h") {
Help(argv[0]);
}
else if(argv[i] == "-o")
{
else if (argv[i] == "-o") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
outputDir = argv[i];
}
}
else if(argv[i] == "-r")
{
} else if (argv[i] == "-r") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
resourceDir = argv[i];
}
}
else if(argv[i] == "-e")
{
} else if (argv[i] == "-e") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
comptime = argv[i];
}
}
else if(argv[i] == "-i")
{
else if (argv[i] == "-i") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
info = argv[i];
}
}
else if(argv[i] == "-I")
{
} else if (argv[i] == "-I") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
icon = argv[i];
}
}
else if(argv[i] == "-d")
{
} else if (argv[i] == "-d") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
std::string str = argv[i];
auto lastDash = str.find_last_of('-');
if(lastDash < str.size())
{
std::string str2 = str.substr(lastDash+1);
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod")
{
lastDash = str.find_last_of('-',lastDash-1);
if (lastDash < str.size()) {
std::string str2 = str.substr(lastDash + 1);
if (str2 == "dev" || str2 == "alpha" || str2 == "beta" ||
str2 == "prod") {
lastDash = str.find_last_of('-', lastDash - 1);
}
std::string str1 = str.substr(0,lastDash);
str2 = str.substr(lastDash+1);
std::string str1 = str.substr(0, lastDash);
str2 = str.substr(lastDash + 1);
TVMVersion v2;
if(!TVMVersion::TryParse(str2,v2))
{
if (!TVMVersion::TryParse(str2, v2)) {
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-"
"prod]]]]\n");
exit(1);
}
dependencies.push_back(std::pair<std::string,TVMVersion>(str1,v2));
}
else
{
dependencies.push_back(
std::pair<std::string, TVMVersion>(str1, v2));
} else {
printf("ERROR: Dependency must have version\n");
exit(1);
}
}
}
else if(argv[i] == "-t")
{
} else if (argv[i] == "-t") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
std::string str = argv[i];
auto lastDash = str.find_last_of('-');
if(lastDash < str.size())
{
std::string str2 = str.substr(lastDash+1);
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod")
{
lastDash = str.find_last_of('-',lastDash-1);
if (lastDash < str.size()) {
std::string str2 = str.substr(lastDash + 1);
if (str2 == "dev" || str2 == "alpha" || str2 == "beta" ||
str2 == "prod") {
lastDash = str.find_last_of('-', lastDash - 1);
}
std::string str1 = str.substr(0,lastDash);
str2 = str.substr(lastDash+1);
std::string str1 = str.substr(0, lastDash);
str2 = str.substr(lastDash + 1);
TVMVersion v2;
if(!TVMVersion::TryParse(str2,v2))
{
if (!TVMVersion::TryParse(str2, v2)) {
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-"
"prod]]]]\n");
exit(1);
}
tools.push_back(std::pair<std::string,TVMVersion>(str1,v2));
}
else
{
tools.push_back(
std::pair<std::string, TVMVersion>(str1, v2));
} else {
printf("ERROR: Tool must have version\n");
exit(1);
}
}
}
else if(argv[i] == "-n")
{
} else if (argv[i] == "-n") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
name = argv[i];
}
}
else if(argv[i] == "-v")
{
} else if (argv[i] == "-v") {
i++;
if(i < argv.size())
{
if(!TVMVersion::TryParse(argv[i],version))
{
if (i < argv.size()) {
if (!TVMVersion::TryParse(argv[i], version)) {
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
"]]]\n");
exit(1);
}
}
}
else if(argv[i] == "-D" || argv[i] == "--debug")
{
} else if (argv[i] == "-D" || argv[i] == "--debug") {
debug = true;
}
else {
} else {
source.push_back(argv[i]);
}
}
if(source.empty())
{
}
if (source.empty()) {
Help(argv[0]);
}
}
std::vector<LexToken> tokens;
for(auto src : source)
{
std::ifstream strm(src,std::ios_base::in|std::ios_base::binary);
int res = Lex(std::filesystem::absolute(src).string(),strm,tokens);
for (auto src : source) {
std::ifstream strm(src, std::ios_base::in | std::ios_base::binary);
int res = Lex(std::filesystem::absolute(src).string(), strm, tokens);
}
std::shared_ptr<GC> gc;
std::shared_ptr<GCList> ls;
TRootEnvironment* env=nullptr;
if(comptime != "none")
{
std::shared_ptr<GC> gc= std::make_shared<GC>();
TRootEnvironment *env = nullptr;
if (comptime != "none") {
std::shared_ptr<GC> gc = std::make_shared<GC>();
gc->Start();
ls = std::make_shared<GCList>(gc);
env = TRootEnvironment::Create(*ls,TDictionary::Create(*ls));
env = TRootEnvironment::Create(*ls, TDictionary::Create(*ls));
if(comptime == "secure")
{
TStd::RegisterConsole(gc,env);
TStd::RegisterClass(gc,env);
TStd::RegisterCrypto(gc,env);
TStd::RegisterDictionary(gc,env);
TStd::RegisterJson(gc,env);
TStd::RegisterRoot(gc,env);
TStd::RegisterIO(gc,env,false);
env->permissions.locked=true;
}
else if(comptime == "secure_file")
{
TStd::RegisterConsole(gc,env);
TStd::RegisterClass(gc,env);
TStd::RegisterCrypto(gc,env);
TStd::RegisterDictionary(gc,env);
TStd::RegisterJson(gc,env);
TStd::RegisterRoot(gc,env);
TStd::RegisterIO(gc,env,false);
env->permissions.locked=true;
auto fs = env->EnsureDictionary(gc,"FS");
fs->SetValue("Local", std::make_shared<SubdirFilesystem>(LocalFS,Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory()));
}
else if(comptime == "full")
{
TStd::RegisterStd(gc,env);
env->permissions.locked=true;
if (comptime == "secure") {
TStd::RegisterConsole(gc, env);
TStd::RegisterClass(gc, env);
TStd::RegisterCrypto(gc, env);
TStd::RegisterDictionary(gc, env);
TStd::RegisterJson(gc, env);
TStd::RegisterRoot(gc, env);
TStd::RegisterIO(gc, env, false);
env->permissions.locked = true;
} else if (comptime == "secure_file") {
TStd::RegisterConsole(gc, env);
TStd::RegisterClass(gc, env);
TStd::RegisterCrypto(gc, env);
TStd::RegisterDictionary(gc, env);
TStd::RegisterJson(gc, env);
TStd::RegisterRoot(gc, env);
TStd::RegisterIO(gc, env, false);
env->permissions.locked = true;
auto fs = env->EnsureDictionary(gc, "FS");
fs->SetValue("Local",
std::make_shared<SubdirFilesystem>(
LocalFS, Tesses::Framework::Filesystem::VFSPath::
GetAbsoluteCurrentDirectory()));
} else if (comptime == "full") {
TStd::RegisterStd(gc, env);
env->permissions.locked = true;
}
}
Parser parser(tokens,gc,env);
Parser parser(tokens, gc, env);
parser.debug = debug;
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,LocalFS->SystemToVFSPath(resourceDir.string()));
auto sfs = std::make_shared<SubdirFilesystem>(
LocalFS, LocalFS->SystemToVFSPath(resourceDir.string()));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
@@ -265,21 +232,20 @@ void CrossLangCompiler(std::vector<std::string>& argv)
gen.version = version;
gen.info = info;
gen.icon = icon;
for(auto deps : dependencies)
{
for (auto deps : dependencies) {
gen.dependencies.push_back(deps);
}
for(auto tool : tools)
{
for (auto tool : tools) {
gen.tools.push_back(tool);
}
std::filesystem::create_directory(outputDir);
{
auto strm = std::make_shared<Tesses::Framework::Streams::FileStream>(outputDir / (name + "-" + version.ToString() + ".crvm"),"wb");
auto strm = std::make_shared<Tesses::Framework::Streams::FileStream>(
outputDir / (name + "-" + version.ToString() + ".crvm"), "wb");
gen.Save(strm);
}
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -1,124 +1,114 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
using namespace Tesses::Framework;
using namespace Tesses::Framework::Filesystem;
namespace Tesses::CrossLang::Programs {
TObject CrossLangInterperter(GCList& ls,TRootEnvironment* env,std::vector<std::string>& argv)
{
std::shared_ptr<GC> gc = ls.GetGC();
if(argv.size() > 1)
{
std::ifstream strm(argv[1],std::ios_base::in|std::ios_base::binary);
TObject CrossLangInterperter(GCList &ls, TRootEnvironment *env,
std::vector<std::string> &argv) {
std::shared_ptr<GC> gc = ls.GetGC();
if (argv.size() > 1) {
std::ifstream strm(argv[1], std::ios_base::in | std::ios_base::binary);
std::vector<LexToken> tokens;
Lex(argv[1],strm,tokens);
Lex(argv[1], strm, tokens);
Parser parser(tokens);
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
std::vector<uint8_t> data;
{
auto strm2 = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
auto strm2 =
std::make_shared<Tesses::Framework::Streams::MemoryStream>(
true);
gen.Save(strm2);
{
TFile* file = TFile::Create(ls);
TFile *file = TFile::Create(ls);
strm2->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
file->Load(gc, strm2);
strm2->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
file->Load(gc,strm2);
env->LoadFile(gc, file);
}
}
TList* args = TList::Create(ls);
for(int arg=1;arg<argv.size();arg++)
TList *args = TList::Create(ls);
for (int arg = 1; arg < argv.size(); arg++)
args->Add(std::string(argv[arg]));
return env->CallFunctionWithFatalError(ls,"main",{args});
}
else
{
while(true)
{
return env->CallFunctionWithFatalError(ls, "main", {args});
} else {
while (true) {
std::cout << "> ";
std::string source;
std::getline(std::cin,source);
std::getline(std::cin, source);
auto strm2 = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
auto strm2 =
std::make_shared<Tesses::Framework::Streams::MemoryStream>(
true);
if(source.find("loadfile ") == 0)
{
if (source.find("loadfile ") == 0) {
std::string filename = source.substr(9);
std::ifstream strm(filename,std::ios_base::in|std::ios_base::binary);
std::ifstream strm(filename,
std::ios_base::in | std::ios_base::binary);
std::vector<LexToken> tokens;
Lex(filename,strm,tokens);
Lex(filename, strm, tokens);
Parser parser(tokens);
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
auto sfs =
std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
gen.Save(strm2);
}
else if(source == "exit")
{
} else if (source == "exit") {
return (int64_t)0;
}
else
{
} else {
std::vector<LexToken> tokens;
std::stringstream strm(source,std::ios_base::in | std::ios_base::binary);
Lex("lexed.tcross",strm,tokens);
std::stringstream strm(source, std::ios_base::in |
std::ios_base::binary);
Lex("lexed.tcross", strm, tokens);
Parser parser(tokens);
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
auto sfs =
std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
gen.Save(strm2);
}
{
TFile* file = TFile::Create(ls);
strm2->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
file->Load(gc,strm2);
env->LoadFile(gc, file);
TFile *file = TFile::Create(ls);
}
strm2->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
file->Load(gc, strm2);
env->LoadFile(gc, file);
}
}
}
return (int64_t)0;
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -1,61 +1,58 @@
#include "CrossLang.hpp"
using namespace Tesses::Framework;
namespace Tesses::CrossLang::Programs {
TObject CrossLangVM(GCList& ls,TRootEnvironment* env, std::vector<std::string>& argv)
{
if(argv.size() < 2)
{
std::cout << "USAGE: " << (argv.empty() ? (std::string)"crossvm" : argv[0]) << " <filename.crvm> <args...>" << std::endl;
return 1;
}
env->LoadFileWithDependencies(ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1]));
if(env->HasVariable("WebAppMain"))
{
Args args(argv);
int port = 4206;
for(auto& item : args.options)
{
if(item.first == "port")
{
port = std::stoi(item.second);
}
}
env->EnsureDictionary(ls.GetGC(),"Net")->SetValue("WebServerPort", (int64_t)port);
TList* args2 = TList::Create(ls);
for(auto& item : args.positional)
{
args2->Add(item);
}
auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2});
auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(),res);
if(svr2 == nullptr) return 1;
Tesses::Framework::Http::HttpServer svr(port,svr2);
svr.StartAccepting();
TF_RunEventLoop();
TDictionary* _dict;
TClassObject* _co;
if(GetObjectHeap(res,_dict))
{
_dict->CallMethod(ls,"Close",{});
}
if(GetObjectHeap(res,_co))
{
_co->CallMethod(ls,"","Close",{});
}
TF_Quit();
return 0;
}
else {
TList* args = TList::Create(ls);
for(size_t arg=1;arg<argv.size();arg++)
args->Add(std::string(argv[arg]));
return env->CallFunctionWithFatalError(ls,"main",{args});
}
TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
std::vector<std::string> &argv) {
if (argv.size() < 2) {
std::cout << "USAGE: "
<< (argv.empty() ? (std::string) "crossvm" : argv[0])
<< " <filename.crvm> <args...>" << std::endl;
return 1;
}
}
env->LoadFileWithDependencies(
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS,
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1]));
if (env->HasVariable("WebAppMain")) {
Args args(argv);
int port = 4206;
for (auto &item : args.options) {
if (item.first == "port") {
port = std::stoi(item.second);
}
}
env->EnsureDictionary(ls.GetGC(), "Net")
->SetValue("WebServerPort", (int64_t)port);
TList *args2 = TList::Create(ls);
for (auto &item : args.positional) {
args2->Add(item);
}
auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2});
auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(), res);
if (svr2 == nullptr)
return 1;
Tesses::Framework::Http::HttpServer svr(port, svr2);
svr.StartAccepting();
TF_RunEventLoop();
TDictionary *_dict;
TClassObject *_co;
if (GetObjectHeap(res, _dict)) {
_dict->CallMethod(ls, "Close", {});
}
if (GetObjectHeap(res, _co)) {
_co->CallMethod(ls, "", "Close", {});
}
TF_Quit();
return 0;
} else {
TList *args = TList::Create(ls);
for (size_t arg = 1; arg < argv.size(); arg++)
args->Add(std::string(argv[arg]));
return env->CallFunctionWithFatalError(ls, "main", {args});
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -1,9 +0,0 @@
#include "CrossLang.hpp"
int main(int argc, char** argv)
{
std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
args[i] = argv[i];
return (int)Tesses::CrossLang::Programs::CrossArchiveCreate(args);
}

View File

@@ -1,9 +0,0 @@
#include "CrossLang.hpp"
int main(int argc, char** argv)
{
std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
args[i] = argv[i];
return (int)Tesses::CrossLang::Programs::CrossArchiveExtract(args);
}

View File

@@ -1,25 +0,0 @@
#include "CrossLang.hpp"
using namespace Tesses::Framework;
using namespace Tesses::CrossLang;
using namespace Tesses::Framework::Filesystem;
int main(int argc, char** argv)
{
TF_InitWithConsole();
if(argc > 0)
TF_AllowPortable(argv[0]);
std::shared_ptr<GC> gc= std::make_shared<GC>();
gc->Start();
GCList ls(gc);
std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
args[i] = argv[i];
auto res = Programs::CrossLangShell(ls, args);
int64_t myi64;
if(GetObject(res,myi64))
return (int)myi64;
return 0;
}

View File

@@ -1,23 +0,0 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace Tesses::Framework;
using namespace Tesses::CrossLang;
using namespace Tesses::Framework::Filesystem;
int main(int argc, char** argv)
{
TF_InitWithConsole();
if(argc > 0)
TF_AllowPortable(argv[0]);
std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
args[i] = argv[i];
Programs::CrossLangCompiler(args);
return 0;
}

View File

@@ -1,28 +0,0 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace Tesses::Framework;
using namespace Tesses::CrossLang;
using namespace Tesses::Framework::Filesystem;
int main(int argc, char** argv)
{
TF_InitWithConsole();
if(argc > 0)
TF_AllowPortable(argv[0]);
for(int i = 1; i < argc; i++)
{
VFSPath path(argv[i]);
if(LocalFS->FileExists(path))
{
std::cout << "File: " << path.ToString() << std::endl;
auto strm = LocalFS->OpenFile(path, "rb");
Programs::CrossLangDump(strm);
}
else {
std::cout << "File: " << path.ToString() << " does not exist." << std::endl;
}
}
}

View File

@@ -1,30 +0,0 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace Tesses::Framework;
using namespace Tesses::CrossLang;
using namespace Tesses::Framework::Filesystem;
int main(int argc, char** argv)
{
TF_InitWithConsole();
if(argc > 0)
TF_AllowPortable(argv[0]);
std::shared_ptr<GC> gc= std::make_shared<GC>();
gc->Start();
GCList ls(gc);
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(gc,env);
std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
args[i] = argv[i];
auto res = Programs::CrossLangInterperter(ls, env, args);
int64_t myi64;
if(GetObject(res,myi64))
return (int)myi64;
return 0;
}

View File

@@ -1,30 +0,0 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace Tesses::Framework;
using namespace Tesses::CrossLang;
using namespace Tesses::Framework::Filesystem;
int main(int argc, char** argv)
{
TF_InitWithConsole();
if(argc > 0)
TF_AllowPortable(argv[0]);
std::shared_ptr<GC> gc= std::make_shared<GC>();
gc->Start();
GCList ls(gc);
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(gc,env);
std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
args[i] = argv[i];
auto res = Programs::CrossLangVM(ls, env, args);
int64_t myi64;
if(GetObject(res,myi64))
return (int)myi64;
return 0;
}

View File

@@ -4,173 +4,189 @@ using namespace Tesses::Framework;
using namespace Tesses::CrossLang;
using namespace Tesses::Framework::Filesystem;
int main(int argc, char** argv)
{
//crosslang crossint
//crosslang
//crosslang ...
std::string programName = "crosslang";
int main(int argc, char **argv) {
TF_InitWithConsole();
if(argc > 0)
{
TF_AllowPortable(argv[0]);
Tesses::Framework::Filesystem::VFSPath path=(std::string)argv[0];
path.RemoveExtension();
programName = path.GetFileName();
}
TF_AllowPortable();
std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
for (int i = 0; i < argc; i++)
args[i] = argv[i];
if(programName == "crossint")
{
int64_t myi64=0;
std::shared_ptr<GC> gc= std::make_shared<GC>();
auto execName = TF_GetExecutableName();
if (!execName.empty()) {
Tesses::Framework::Filesystem::VFSPath execPath = execName;
if (execPath.HasExtension()) {
execPath.RemoveExtension();
}
if (Tesses::Framework::Filesystem::LocalFS->FileExists(execPath +
".crvm")) {
if (args.empty())
args.push_back(execPath.GetFileName());
auto crvmFile = execPath + ".crvm";
args.insert(args.begin() + 1, crvmFile.ToString());
int64_t myi64 = 0;
std::shared_ptr<GC> gc = std::make_shared<GC>();
gc->Start();
GCList ls(gc);
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(gc,env);
auto res= Programs::CrossLangInterperter(ls, env, args);
GetObject(res,myi64);
TRootEnvironment *env =
TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(gc, env);
auto res = Programs::CrossLangVM(ls, env, args);
GetObject(res, myi64);
return (int)myi64;
}
else if(programName == "crossc")
{
Programs::CrossLangCompiler(args);
return 0;
}
else if(programName == "crossarchivecreate")
{
Programs::CrossArchiveCreate(args);
return 0;
}
else if(programName == "crossarchiveextract")
{
Programs::CrossArchiveExtract(args);
return 0;
}
else if(programName == "crossdump")
{
for(size_t i = 1; i < args.size(); i++)
{
VFSPath path = args[i];
if(LocalFS->FileExists(path))
{
std::cout << "File: " << path.ToString() << std::endl;
auto strm = LocalFS->OpenFile(path, "rb");
Programs::CrossLangDump(strm);
}
else {
std::cout << "File: " << path.ToString() << " does not exist." << std::endl;
}
}
return 0;
}
else if(programName == "crossvm")
{
std::shared_ptr<GC> gc= std::make_shared<GC>();
gc->Start();
int64_t myi64=0;
GCList ls(gc);
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(gc,env);
auto res= Programs::CrossLangVM(ls, env, args);
GetObject(res,myi64);
return (int)myi64;
}
else if(args.size() > 1)
{
if(args[1] == "crossint")
{
int64_t myi64=0;
if (args.size() > 1) {
if (args[1] == "--help") {
if (!Tesses::Framework::Filesystem::LocalFS->FileExists(
GetCrossLangConfigDir() / "Shell" / "Shell.crvm")) {
Console::WriteLine(args[0] + " COMMAND");
Console::WriteLine("COMMANDS:");
Console::WriteLine(
"int: interperter, used to be crossint");
Console::WriteLine(
"c: the compiler, used to be crossc");
Console::WriteLine("archivecreate: create archives, used to "
"be crossarchivecreate");
Console::WriteLine("archiveextract: extract archives, used to "
"be crossarchiveextract");
Console::WriteLine("thumbnailer: create thumbnails on "
"freedesktop, used to be crossthumbnailer");
Console::WriteLine("dump: dump metadata about crvm "
"file, used to be crossdump");
Console::WriteLine("vm: interpert bytecode file, "
"used to be crossvm");
Console::WriteLine("update-shell: update the shell");
Console::WriteLine(
"configdir: print the config directory");
Console::WriteLine("");
Console::WriteLine("NOTE: As you don't have the shell, these "
"commands are limited");
Console::WriteLine(
"NOTE: You can put this binary in a folder with a crvm "
"file, as long as filename matches (ignoring extension) it "
"will directly launch the crvm file");
return 1;
}
}
if (args[1] == "int") {
int64_t myi64 = 0;
args.erase(args.begin());
std::shared_ptr<GC> gc= std::make_shared<GC>();
std::shared_ptr<GC> gc = std::make_shared<GC>();
gc->Start();
GCList ls(gc);
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(gc,env);
auto res= Programs::CrossLangInterperter(ls, env, args);
TRootEnvironment *env =
TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(gc, env);
auto res = Programs::CrossLangInterperter(ls, env, args);
GetObject(res, myi64);
GetObject(res,myi64);
return (int)myi64;
}
else if(args[1] == "crossc")
{
} else if (args[1] == "c") {
args.erase(args.begin());
Programs::CrossLangCompiler(args);
return 0;
}
else if(args[1] == "crossarchivecreate")
{
} else if (args[1] == "archivecreate") {
args.erase(args.begin());
Programs::CrossArchiveCreate(args);
return 0;
}
else if(args[1] == "crossarchiveextract")
{
} else if (args[1] == "archiveextract") {
args.erase(args.begin());
Programs::CrossArchiveExtract(args);
return 0;
}
else if(args[1] == "crossdump")
{
for(size_t i = 2; i < args.size(); i++)
{
VFSPath path = args[i];
if(LocalFS->FileExists(path))
{
std::cout << "File: " << path.ToString() << std::endl;
auto strm = LocalFS->OpenFile(path, "rb");
Programs::CrossLangDump(strm);
} else if (args[1] == "thumbnailer") {
Tesses::Framework::Filesystem::VFSPath execPath =
TF_GetExecutableName();
auto emptyThumb = execPath.GetParent().GetParent() / "share" /
"icons" / "crosslang.png";
if (argc < 4) {
std::cout << "USAGE: " << argv[0]
<< " thumbnailer CRVMFILE NEWPNG" << std::endl;
return 1;
}
std::string crvm = argv[2];
std::string png = argv[3];
if (Tesses::Framework::Filesystem::LocalFS->FileExists(crvm)) {
Tesses::CrossLang::TFile file;
auto f = Tesses::Framework::Filesystem::LocalFS->OpenFile(crvm,
"rb");
file.Load(nullptr, f);
if (file.icon >= 0 && file.icon < file.resources.size()) {
auto f2 = Tesses::Framework::Filesystem::LocalFS->OpenFile(
png, "wb");
if (f2 != nullptr) {
auto &icon = file.resources[file.icon];
f2->WriteBlock(icon.data(), icon.size());
}
return 0;
}
else {
std::cout << "File: " << path.ToString() << " does not exist." << std::endl;
}
if (Tesses::Framework::Filesystem::LocalFS->FileExists(
emptyThumb)) {
auto src = Tesses::Framework::Filesystem::LocalFS->OpenFile(
emptyThumb, "rb");
auto dest =
Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
if (src != nullptr && dest != nullptr) {
src->CopyTo(dest);
}
}
return 0;
}
else if(args[1] == "crossvm")
{
int64_t myi64=0;
} else if (args[1] == "dump") {
for (size_t i = 2; i < args.size(); i++) {
VFSPath path = args[i];
if (LocalFS->FileExists(path)) {
std::cout << "File: " << path.ToString() << std::endl;
auto strm = LocalFS->OpenFile(path, "rb");
Programs::CrossLangDump(strm);
} else {
std::cout << "File: " << path.ToString()
<< " does not exist." << std::endl;
}
}
return 0;
} else if (args[1] == "vm") {
int64_t myi64 = 0;
args.erase(args.begin());
std::shared_ptr<GC> gc= std::make_shared<GC>();
std::shared_ptr<GC> gc = std::make_shared<GC>();
gc->Start();
GCList ls(gc);
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(gc,env);
auto res= Programs::CrossLangVM(ls, env, args);
GetObject(res,myi64);
TRootEnvironment *env =
TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(gc, env);
auto res = Programs::CrossLangVM(ls, env, args);
GetObject(res, myi64);
return (int)myi64;
}
}
{
int64_t myi64=0;
std::shared_ptr<GC> gc= std::make_shared<GC>();
int64_t myi64 = 0;
std::shared_ptr<GC> gc = std::make_shared<GC>();
gc->Start();
GCList ls(gc);
auto res= Programs::CrossLangShell(ls, args);
GCList ls(gc);
auto res = Programs::CrossLangShell(ls, args);
GetObject(res,myi64);
GetObject(res, myi64);
return (int)myi64;
}
}

View File

@@ -1,287 +1,255 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
static TList *VectorOfStringToList(GCList &ls, std::vector<std::string> &strs) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto &item : strs)
list->Add(item);
ls.GetGC()->BarrierEnd();
return list;
}
static TList *EntriesToList(GCList &ls, std::vector<TClassEntry> &ents) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto &item : ents) {
std::string modifier = "public";
switch (item.modifier) {
case TClassModifier::Public:
modifier = "public";
break;
case TClassModifier::Private:
modifier = "private";
break;
case TClassModifier::Protected:
modifier = "protected";
break;
case TClassModifier::Static:
modifier = "static";
break;
}
namespace Tesses::CrossLang
{
static TList* VectorOfStringToList(GCList& ls, std::vector<std::string>& strs)
{
TList* list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto& item : strs)
list->Add(item);
ls.GetGC()->BarrierEnd();
return list;
list->Add(TDictionary::Create(
ls,
{TDItem("Name", item.name), TDItem("IsAbstract", item.isAbstract),
TDItem("IsFunction", item.isFunction),
TDItem("Documentation", item.documentation),
TDItem("ChunkId", (int64_t)item.chunkId),
TDItem("Arguments", VectorOfStringToList(ls, item.args)),
TDItem("Modifier", modifier)}));
}
static TList* EntriesToList(GCList& ls, std::vector<TClassEntry>& ents)
{
TList* list=TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto& item : ents)
{
std::string modifier = "public";
switch(item.modifier)
{
case TClassModifier::Public:
modifier = "public";
break;
case TClassModifier::Private:
modifier = "private";
break;
case TClassModifier::Protected:
modifier = "protected";
break;
case TClassModifier::Static:
modifier = "static";
break;
}
list->Add(TDictionary::Create(ls,{
TDItem("Name",item.name),
TDItem("IsAbstract",item.isAbstract),
TDItem("IsFunction",item.isFunction),
TDItem("Documentation",item.documentation),
TDItem("ChunkId",(int64_t)item.chunkId),
TDItem("Arguments",VectorOfStringToList(ls,item.args)),
TDItem("Modifier",modifier)
}));
ls.GetGC()->BarrierEnd();
return list;
}
static TList *ClassInstanceToList(GCList &ls, TClassObject *co) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto &item : co->entries) {
if (item.modifier == TClassModifier::Public) {
list->Add(TDictionary::Create(
ls,
{TDItem("Name", item.name), TDItem("IsFunction", !item.canSet),
TDItem("Owner", item.owner), TDItem("Value", item.value)}));
}
ls.GetGC()->BarrierEnd();
return list;
}
static TList* ClassInstanceToList(GCList& ls, TClassObject* co)
{
TList* list=TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto& item : co->entries)
{
if(item.modifier == TClassModifier::Public)
{
list->Add(TDictionary::Create(ls, {
TDItem(
"Name", item.name
),
TDItem(
"IsFunction", !item.canSet
),
TDItem(
"Owner", item.owner
),
TDItem(
"Value", item.value
)
}));
}
}
ls.GetGC()->BarrierEnd();
return list;
}
TObject GetClassInfo(GCList& ls,TFile* f, uint32_t index)
{
return TDictionary::Create(ls,{
TDItem("Name", JoinPeriod(f->classes.at(index).name)),
TDItem("NameParts",VectorOfStringToList(ls,f->classes.at(index).name)),
TDItem("Inherits", JoinPeriod(f->classes.at(index).inherits)),
TDItem("InheritsParts",VectorOfStringToList(ls,f->classes.at(index).inherits)),
TDItem("Documentation",f->classes.at(index).documentation),
TDItem("Entries",EntriesToList(ls,f->classes.at(index).entry))
});
}
static TObject Class_CreateInstance(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
{
TList* args_ls;
if(!GetArgumentHeap(args,1,args_ls)) return nullptr;
TList* list;
TClassObject* obj;
std::string str;
if(GetArgumentHeap(args,0,list))
{
std::vector<std::string> clsName;
for(int64_t i = 0; i < list->Count(); i++)
{
auto o = list->Get(i);
if(GetObject(o,str)) clsName.push_back(str);
}
for(auto& item : env->classes)
{
auto& f=item.first->classes.at(item.second);
if(f.name.size() != clsName.size()) continue;
bool found=true;
for(size_t i = 0; i < f.name.size(); i++)
if(f.name[i] != clsName[i])
{
found=false;
break;
}
if(found)
{
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
}
else
continue;
}
}
else if(GetArgument(args,0,str))
{
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
for(auto& item : env->classes)
{
auto& f=item.first->classes.at(item.second);
if(f.name.size() != clsName.size()) continue;
bool found=true;
for(size_t i = 0; i < f.name.size(); i++)
if(f.name[i] != clsName[i])
{
found=false;
break;
}
if(found)
{
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
}
else
continue;
}
}
ls.GetGC()->BarrierEnd();
return list;
}
TObject GetClassInfo(GCList &ls, TFile *f, uint32_t index) {
return TDictionary::Create(
ls, {TDItem("Name", JoinPeriod(f->classes.at(index).name)),
TDItem("NameParts",
VectorOfStringToList(ls, f->classes.at(index).name)),
TDItem("Inherits", JoinPeriod(f->classes.at(index).inherits)),
TDItem("InheritsParts",
VectorOfStringToList(ls, f->classes.at(index).inherits)),
TDItem("Documentation", f->classes.at(index).documentation),
TDItem("Entries", EntriesToList(ls, f->classes.at(index).entry))});
}
static TObject Class_CreateInstance(TRootEnvironment *env, GCList &ls,
std::vector<TObject> args) {
TList *args_ls;
if (!GetArgumentHeap(args, 1, args_ls))
return nullptr;
}
static TObject Class_GetClassNames(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
{
TList* list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto& item : env->classes)
{
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
TList *list;
TClassObject *obj;
std::string str;
if (GetArgumentHeap(args, 0, list)) {
std::vector<std::string> clsName;
for (int64_t i = 0; i < list->Count(); i++) {
auto o = list->Get(i);
if (GetObject(o, str))
clsName.push_back(str);
}
ls.GetGC()->BarrierEnd();
return list;
}
static TObject Class_GetInfo(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
{
TList* list;
TClassObject* obj;
std::string str;
if(GetArgumentHeap(args,0,list))
{
std::vector<std::string> clsName;
for(int64_t i = 0; i < list->Count(); i++)
{
auto o = list->Get(i);
if(GetObject(o,str)) clsName.push_back(str);
}
for(auto& item : env->classes)
{
auto& f=item.first->classes.at(item.second);
if(f.name.size() != clsName.size()) continue;
bool found=true;
for(size_t i = 0; i < f.name.size(); i++)
if(f.name[i] != clsName[i])
{
found=false;
break;
}
if(found)
{
return GetClassInfo(ls,item.first,item.second);
for (auto &item : env->classes) {
auto &f = item.first->classes.at(item.second);
if (f.name.size() != clsName.size())
continue;
bool found = true;
for (size_t i = 0; i < f.name.size(); i++)
if (f.name[i] != clsName[i]) {
found = false;
break;
}
else
continue;
}
if (found) {
return TClassObject::Create(ls, item.first, item.second, env,
args_ls->items);
} else
continue;
}
else if(GetArgument(args,0,str))
{
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
for(auto& item : env->classes)
{
auto& f=item.first->classes.at(item.second);
if(f.name.size() != clsName.size()) continue;
bool found=true;
for(size_t i = 0; i < f.name.size(); i++)
if(f.name[i] != clsName[i])
{
found=false;
break;
}
if(found)
{
return GetClassInfo(ls,item.first,item.second);
} else if (GetArgument(args, 0, str)) {
std::vector<std::string> clsName =
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
for (auto &item : env->classes) {
auto &f = item.first->classes.at(item.second);
if (f.name.size() != clsName.size())
continue;
bool found = true;
for (size_t i = 0; i < f.name.size(); i++)
if (f.name[i] != clsName[i]) {
found = false;
break;
}
else
continue;
}
}
else if(GetArgumentHeap(args,0,obj))
{
return GetClassInfo(ls,obj->file,obj->classIndex);
}
if (found) {
return TClassObject::Create(ls, item.first, item.second, env,
args_ls->items);
return nullptr;
} else
continue;
}
}
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
GCList ls(gc);
env->permissions.canRegisterClass=true;
TDictionary* cls= env->EnsureDictionary(gc, "Class");
gc->BarrierBegin();
TExternalMethod* ext = TExternalMethod::Create(ls ,"Get the class info",{"classInstanceOrClassName"},[env](GCList& ls, std::vector<TObject> args)->TObject {
return Class_GetInfo(env,ls,args);
});
ext->watch.push_back(env);
cls->SetValue("GetInfo",ext);
return nullptr;
}
static TObject Class_GetClassNames(TRootEnvironment *env, GCList &ls,
std::vector<TObject> args) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto &item : env->classes) {
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
}
ls.GetGC()->BarrierEnd();
return list;
}
static TObject Class_GetInfo(TRootEnvironment *env, GCList &ls,
std::vector<TObject> args) {
ext = TExternalMethod::Create(ls ,"Get the class names",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
return Class_GetClassNames(env,ls,args);
});
ext->watch.push_back(env);
cls->SetValue("GetClassNames",ext);
ext = TExternalMethod::Create(ls ,"Create an instance of class",{"name","args"},[env](GCList& ls, std::vector<TObject> args)->TObject {
return Class_CreateInstance(env,ls,args);
});
ext->watch.push_back(env);
cls->SetValue("CreateInstance",ext);
cls->DeclareFunction(gc,"Name","Get class name via instance",{"instance"},[](GCList& ls, std::vector<TObject> args)->TObject {
TClassObject* cls;
if(GetArgumentHeap(args,0,cls))
{
return cls->name;
}
return "";
});
TList *list;
TClassObject *obj;
std::string str;
if (GetArgumentHeap(args, 0, list)) {
std::vector<std::string> clsName;
for (int64_t i = 0; i < list->Count(); i++) {
auto o = list->Get(i);
if (GetObject(o, str))
clsName.push_back(str);
}
for (auto &item : env->classes) {
auto &f = item.first->classes.at(item.second);
if (f.name.size() != clsName.size())
continue;
cls->DeclareFunction(gc, "GetInstanceInfo", "Get the instance specific info, including current values", {}, [](GCList& ls, std::vector<TObject> args)->TObject {
TClassObject* co;
if(GetArgumentHeap(args, 0, co))
{
bool found = true;
for (size_t i = 0; i < f.name.size(); i++)
if (f.name[i] != clsName[i]) {
found = false;
break;
}
if (found) {
return GetClassInfo(ls, item.first, item.second);
} else
continue;
}
} else if (GetArgument(args, 0, str)) {
std::vector<std::string> clsName =
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
for (auto &item : env->classes) {
auto &f = item.first->classes.at(item.second);
if (f.name.size() != clsName.size())
continue;
bool found = true;
for (size_t i = 0; i < f.name.size(); i++)
if (f.name[i] != clsName[i]) {
found = false;
break;
}
if (found) {
return GetClassInfo(ls, item.first, item.second);
} else
continue;
}
} else if (GetArgumentHeap(args, 0, obj)) {
return GetClassInfo(ls, obj->file, obj->classIndex);
}
return nullptr;
}
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment *env) {
GCList ls(gc);
env->permissions.canRegisterClass = true;
TDictionary *cls = env->EnsureDictionary(gc, "Class");
gc->BarrierBegin();
TExternalMethod *ext = TExternalMethod::Create(
ls, "Get the class info", {"classInstanceOrClassName"},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return Class_GetInfo(env, ls, args);
});
ext->watch.push_back(env);
cls->SetValue("GetInfo", ext);
ext = TExternalMethod::Create(
ls, "Get the class names", {},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return Class_GetClassNames(env, ls, args);
});
ext->watch.push_back(env);
cls->SetValue("GetClassNames", ext);
ext = TExternalMethod::Create(
ls, "Create an instance of class", {"name", "args"},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return Class_CreateInstance(env, ls, args);
});
ext->watch.push_back(env);
cls->SetValue("CreateInstance", ext);
cls->DeclareFunction(gc, "Name", "Get class name via instance",
{"instance"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
TClassObject *cls;
if (GetArgumentHeap(args, 0, cls)) {
return cls->name;
}
return "";
});
cls->DeclareFunction(
gc, "GetInstanceInfo",
"Get the instance specific info, including current values", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
TClassObject *co;
if (GetArgumentHeap(args, 0, co)) {
ls.GetGC()->BarrierBegin();
auto res= TDictionary::Create(ls,
{
TDItem("Name", co->name),
TDItem("File", co->file),
TDItem("ClassIndex", (int64_t)co->classIndex),
TDItem("InheritList", VectorOfStringToList(ls, co->inherit_tree)),
TDItem("Entries", ClassInstanceToList(ls,co))
}
);
auto res = TDictionary::Create(
ls, {TDItem("Name", co->name), TDItem("File", co->file),
TDItem("ClassIndex", (int64_t)co->classIndex),
TDItem("InheritList",
VectorOfStringToList(ls, co->inherit_tree)),
TDItem("Entries", ClassInstanceToList(ls, co))});
ls.GetGC()->BarrierEnd();
return res;
}
return nullptr;
});
gc->BarrierEnd();
}
}
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -2,334 +2,247 @@
#include "CrossLang.hpp"
#include <iostream>
#if defined(GEKKO) || defined(__SWITCH__) || defined(_WIN32)
#undef CROSSLANG_ENABLE_TERMIOS
#endif
#ifdef CROSSLANG_ENABLE_TERMIOS
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>
#endif
namespace Tesses::CrossLang {
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios orig_termios;
static void disableRawMode()
{
tcsetattr(0, TCSAFLUSH, &orig_termios);
TObject Console_setInvertedColors(GCList &ls, std::vector<TObject> args) {
bool inverted;
if (GetArgument(args, 0, inverted)) {
Tesses::Framework::Console::SetInvertedColors(inverted);
}
#endif
TObject Console_getEcho(GCList& ls, std::vector<TObject> args)
{
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
return (raw.c_lflag & ECHO) > 0;
#endif
return false;
}
TObject Console_setEcho(GCList& ls, std::vector<TObject> args)
{
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
{
bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ECHO;
}
else
{
raw.c_lflag &= ~(ECHO);
}
tcsetattr(0, TCSAFLUSH, &raw);
return Undefined();
}
TObject Console_Reset(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Console::Reset();
return Undefined();
}
TObject Console_getIsTTY(GCList &ls, std::vector<TObject> args) {
#endif
return cooked;
}
return Tesses::Framework::Console::IsTTY();
}
TObject Console_getEcho(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::GetEcho();
}
TObject Console_setEcho(GCList &ls, std::vector<TObject> args) {
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
bool cooked = std::get<bool>(args[0]);
Tesses::Framework::Console::SetEcho(cooked);
return cooked;
}
return Undefined();
}
TObject Console_getCanonical(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::GetCanonical();
}
TObject Console_setCanonical(GCList &ls, std::vector<TObject> args) {
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
bool cooked = std::get<bool>(args[0]);
Tesses::Framework::Console::SetCanonical(cooked);
return cooked;
}
return Undefined();
}
TObject Console_getSignals(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::GetSignals();
}
TObject Console_setSignals(GCList &ls, std::vector<TObject> args) {
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
bool cooked = std::get<bool>(args[0]);
Tesses::Framework::Console::SetSignals(cooked);
return cooked;
}
return Undefined();
}
TObject Console_Read(GCList &ls, std::vector<TObject> args) {
return (int64_t)Tesses::Framework::Console::Read();
}
TObject Console_ReadLine(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::ReadLine();
}
TObject Console_ReadPassword(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::ReadPassword();
}
TObject Console_Write(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
return Undefined();
}
TObject Console_getCanonical(GCList& ls, std::vector<TObject> args)
{
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
return (raw.c_lflag & ICANON) > 0;
#endif
return false;
}
TObject Console_setCanonical(GCList& ls, std::vector<TObject> args)
{
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
{
bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ICANON;
}
else
{
raw.c_lflag &= ~(ICANON);
}
tcsetattr(0, TCSAFLUSH, &raw);
#endif
return cooked;
}
return Undefined();
}
TObject Console_getSignals(GCList& ls, std::vector<TObject> args)
{
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
return (raw.c_lflag & ISIG) > 0;
#endif
return false;
}
TObject Console_setSignals(GCList& ls, std::vector<TObject> args)
{
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
{
bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ISIG;
}
else
{
raw.c_lflag &= ~(ISIG);
}
tcsetattr(0, TCSAFLUSH, &raw);
#endif
return cooked;
}
return Undefined();
}
TObject Console_Read(GCList& ls, std::vector<TObject> args)
{
uint8_t byte;
std::cin.read((char*)&byte,1);
return std::cin.eof() ? (int64_t)-1 : (int64_t)byte;
}
TObject Console_ReadLine(GCList& ls, std::vector<TObject> args)
{
std::string str;
std::getline(std::cin,str);
return str;
}
TObject Console_Write(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
return Undefined();
}
std::cout << ToString(ls.GetGC(),args[0]);
return Undefined();
}
TObject Console_Fatal(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
std::cout << "FATAL: <NO MESSAGE>" << std::endl;
exit(1);
}
std::cout << "FATAL: " << ToString(ls.GetGC(),args[0]) << std::endl;
Tesses::Framework::Console::Write(ToString(ls.GetGC(), args[0]));
return Undefined();
}
TObject Console_Fatal(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
Tesses::Framework::Console::ErrorLine("FATAL: <NO MESSAGE>");
exit(1);
}
TObject Console_WriteLine(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
std::cout << "\n";
return Undefined();
}
std::cout << ToString(ls.GetGC(),args[0]) << "\n";
return Undefined();
}
TObject Console_Error(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
return Undefined();
}
std::cerr << ToString(ls.GetGC(),args[0]);
return Undefined();
}
TObject Console_ErrorLine(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
std::cout << "\n";
return Undefined();
}
std::cerr << ToString(ls.GetGC(),args[0]) << "\n";
return Undefined();
}
TObject Console_getIn(GCList& ls, std::vector<TObject> args)
{
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdin,false,"r",false);
}
TObject Console_getOut(GCList& ls, std::vector<TObject> args)
{
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdout,false,"w",false);
}
TObject Console_getError(GCList& ls, std::vector<TObject> args)
{
return std::make_shared<Tesses::Framework::Streams::FileStream>(stderr,false,"w",false);
}
TObject Console_Clear(GCList& ls, std::vector<TObject> args)
{
//because I just really want a clear function
#if defined(_WIN32)
system("cls");
#else
std::cout << "\x1b[2J\x1b[H" << std::flush; //because of wii and stuff (dont want to rely on clear command)
#endif
return Undefined();
}
static void con_sz(int& w, int& h)
{
w = 0;
h = 0;
#if defined(_WIN32)
#elif defined(CROSSLANG_ENABLE_TERMIOS)
if(!isatty(STDOUT_FILENO))
return;
struct winsize ws;
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0)
{
w = ws.ws_col;
h = ws.ws_row;
}
#endif
}
TObject Console_ProgressBar(GCList& ls, std::vector<TObject> args)
{
//[=== ] 50%
bool showBar = true;
#if defined(CROSSLANG_ENABLE_TERMIOS)
if(!isatty(STDOUT_FILENO)) showBar=false;
#endif
int64_t progress = 0;
double pdbl = 0;
GetArgument(args,0,pdbl);
if(GetArgument(args,0,progress)) pdbl = progress / 100.0;
if(pdbl < 0) pdbl=0;
if(pdbl > 1) pdbl=1;
std::cout << "\r";
if(showBar)
{
int w,h;
con_sz(w,h);
int totalBlocks = w - 10;
if(totalBlocks > 0)
{
std::cout << "[\033[0;32m";
int i;
int off = pdbl * totalBlocks;
for(int i = 0; i < totalBlocks; i++)
{
if(i < off)
std::cout << "=";
else
std::cout << " ";
}
std::cout << "\033[0m] ";
}
}
std::cout << std::setw(3) << (int)(pdbl*100) << "%" << std::flush;
return Undefined();
}
TObject Console_getSize(GCList& ls, std::vector<TObject> args)
{
#if defined(CROSSLANG_ENABLE_TERMIOS)
if(!isatty(STDOUT_FILENO)) return nullptr;
#endif
int w, h;
con_sz(w,h);
TDictionary* dict = TDictionary::Create(ls,{
TDItem("Width", (int64_t)w),
TDItem("Height",(int64_t)h)
});
return dict;
}
void TStd::RegisterConsole(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterConsole=true;
if(env->permissions.customConsole != nullptr)
{
gc->BarrierBegin();
env->DeclareVariable("Console", env->permissions.customConsole );
gc->BarrierEnd();
return;
}
#ifdef CROSSLANG_ENABLE_TERMIOS
tcgetattr(0, &orig_termios);
atexit(disableRawMode);
#endif
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc,"getEcho","Get whether terminal is echoing characters read",{},Console_getEcho);
dict->DeclareFunction(gc,"setEcho","Set whether terminal is echoing characters read",{"flag"},Console_setEcho);
dict->DeclareFunction(gc,"getCanonical","Get whether terminal is buffering line by line (true) or byte by byte (false)",{},Console_getCanonical);
dict->DeclareFunction(gc,"setCanonical","Set whether terminal is buffering line by line (true) or byte by byte (false)",{"flag"},Console_setCanonical);
dict->DeclareFunction(gc,"getSignals","Get whether terminal is sending signals for CTRL+C (true) or via read (false)",{},Console_getSignals);
dict->DeclareFunction(gc,"setSignals","Set whether terminal is sending signals for CTRL+C (true) or via read (false)",{"flag"},Console_setSignals);
dict->DeclareFunction(gc,"Clear", "Clear the console",{},Console_Clear);
dict->DeclareFunction(gc,"Read", "Reads a byte from stdin",{},Console_Read);
dict->DeclareFunction(gc,"ReadLine","Reads line from stdin",{},Console_ReadLine);
dict->DeclareFunction(gc,"Write","Write text \"text\" to stdout",{"text"},Console_Write);
dict->DeclareFunction(gc,"WriteLine","Write text \"text\" to stdout with new line",{"$text"},Console_WriteLine);
dict->DeclareFunction(gc,"Error", "Write text \"error\" to stderr",{"error"},Console_Error);
dict->DeclareFunction(gc,"ErrorLine","Write text \"error\" to stderr",{"$error"},Console_ErrorLine);
dict->DeclareFunction(gc,"ProgressBar","Draw progressbar", {}, Console_ProgressBar);
if(env->permissions.canRegisterEverything)
dict->DeclareFunction(gc,"Fatal","Stop the program with an optional error message",{"$text"},Console_Fatal);
dict->DeclareFunction(gc,"getIn","Get stdin Stream",{},Console_getIn);
dict->DeclareFunction(gc,"getOut","Get stdout Stream",{},Console_getOut);
dict->DeclareFunction(gc,"getError", "Get stderr Stream",{},Console_getError);
dict->DeclareFunction(gc, "getSize", "Get console size",{},Console_getSize);
gc->BarrierBegin();
env->DeclareVariable("Console", dict);
auto _new = env->EnsureDictionary(gc,"New");
_new->DeclareFunction(gc,"ConsoleReader","Read from console",{},[](GCList& ls,std::vector<TObject> args)->TObject {
return std::make_shared<Tesses::Framework::TextStreams::ConsoleReader>();
});
_new->DeclareFunction(gc,"ConsoleWriter","Write to console",{"$isStderr"},[](GCList& ls,std::vector<TObject> args)->TObject {
bool err;
if(GetArgument(args,0,err)) return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>(err);
return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>();
});
gc->BarrierEnd();
}
Tesses::Framework::Console::ErrorLine("FATAL: " +
ToString(ls.GetGC(), args[0]));
exit(1);
}
TObject Console_WriteLine(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
Tesses::Framework::Console::WriteLineView("");
return Undefined();
}
Tesses::Framework::Console::WriteLine(ToString(ls.GetGC(), args[0]));
return Undefined();
}
TObject Console_Error(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
return Undefined();
}
Tesses::Framework::Console::Error(ToString(ls.GetGC(), args[0]));
return Undefined();
}
TObject Console_ErrorLine(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
Tesses::Framework::Console::ErrorLine("");
return Undefined();
}
Tesses::Framework::Console::ErrorLine(ToString(ls.GetGC(), args[0]));
return Undefined();
}
TObject Console_getIn(GCList &ls, std::vector<TObject> args) {
return std::make_shared<Tesses::Framework::Streams::FileStream>(
stdin, false, "r", false);
}
TObject Console_getOut(GCList &ls, std::vector<TObject> args) {
return std::make_shared<Tesses::Framework::Streams::FileStream>(
stdout, false, "w", false);
}
TObject Console_getError(GCList &ls, std::vector<TObject> args) {
return std::make_shared<Tesses::Framework::Streams::FileStream>(
stderr, false, "w", false);
}
TObject Console_Clear(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Console::Clear();
return Undefined();
}
TObject Console_ProgressBar(GCList &ls, std::vector<TObject> args) {
double dbl;
int64_t i64;
if (GetArgument(args, 0, i64)) {
Tesses::Framework::Console::ProgressBar((int)i64);
} else if (GetArgument(args, 0, dbl)) {
Tesses::Framework::Console::ProgressBar(dbl);
}
return Undefined();
}
TObject Console_getSize(GCList &ls, std::vector<TObject> args) {
auto sz = Tesses::Framework::Console::GetSize();
TDictionary *dict =
TDictionary::Create(ls, {TDItem("Width", (int64_t)sz.first),
TDItem("Height", (int64_t)sz.second)});
return dict;
}
TObject Console_List(GCList &ls, std::vector<TObject> args) {
if (!args.empty()) {
GCList ls2(ls.GetGC());
auto enumerator = TEnumerator::CreateFromObject(ls2, args[0]);
std::vector<std::string> items;
while (enumerator->MoveNext(ls2.GetGC())) {
auto item = enumerator->GetCurrent(ls2);
items.push_back(ToString(ls2.GetGC(), item));
}
return (int64_t)Tesses::Framework::Console::List(items);
}
return 0;
}
void TStd::RegisterConsole(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterConsole = true;
if (env->permissions.customConsole != nullptr) {
gc->BarrierBegin();
env->DeclareVariable("Console", env->permissions.customConsole);
gc->BarrierEnd();
return;
}
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(
gc, "getIsTTY",
"Get whether terminal is a terminal or just piped to file", {},
Console_getIsTTY);
dict->DeclareFunction(gc, "getEcho",
"Get whether terminal is echoing characters read", {},
Console_getEcho);
dict->DeclareFunction(gc, "setEcho",
"Set whether terminal is echoing characters read",
{"flag"}, Console_setEcho);
dict->DeclareFunction(gc, "getCanonical",
"Get whether terminal is buffering line by line "
"(true) or byte by byte (false)",
{}, Console_getCanonical);
dict->DeclareFunction(gc, "setCanonical",
"Set whether terminal is buffering line by line "
"(true) or byte by byte (false)",
{"flag"}, Console_setCanonical);
dict->DeclareFunction(gc, "getSignals",
"Get whether terminal is sending signals for CTRL+C "
"(true) or via read (false)",
{}, Console_getSignals);
dict->DeclareFunction(gc, "setSignals",
"Set whether terminal is sending signals for CTRL+C "
"(true) or via read (false)",
{"flag"}, Console_setSignals);
dict->DeclareFunction(gc, "Clear", "Clear the console", {}, Console_Clear);
dict->DeclareFunction(gc, "Read", "Reads a byte from stdin", {},
Console_Read);
dict->DeclareFunction(gc, "ReadLine", "Reads line from stdin", {},
Console_ReadLine);
dict->DeclareFunction(gc, "ReadPassword", "Reads password from stdin", {},
Console_ReadPassword);
dict->DeclareFunction(gc, "Write", "Write text \"text\" to stdout",
{"text"}, Console_Write);
dict->DeclareFunction(gc, "WriteLine",
"Write text \"text\" to stdout with new line",
{"$text"}, Console_WriteLine);
dict->DeclareFunction(gc, "Error", "Write text \"error\" to stderr",
{"error"}, Console_Error);
dict->DeclareFunction(gc, "ErrorLine", "Write text \"error\" to stderr",
{"$error"}, Console_ErrorLine);
dict->DeclareFunction(gc, "ProgressBar", "Draw progressbar", {},
Console_ProgressBar);
dict->DeclareFunction(gc, "List", "Draw list", {"itemsitterator"},
Console_List);
if (env->permissions.canRegisterEverything)
dict->DeclareFunction(gc, "Fatal",
"Stop the program with an optional error message",
{"$text"}, Console_Fatal);
dict->DeclareFunction(gc, "getIn", "Get stdin Stream", {}, Console_getIn);
dict->DeclareFunction(gc, "getOut", "Get stdout Stream", {},
Console_getOut);
dict->DeclareFunction(gc, "getError", "Get stderr Stream", {},
Console_getError);
dict->DeclareFunction(gc, "getSize", "Get console size", {},
Console_getSize);
gc->BarrierBegin();
env->DeclareVariable("Console", dict);
auto _new = env->EnsureDictionary(gc, "New");
_new->DeclareFunction(
gc, "ConsoleReader", "Read from console", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return std::make_shared<
Tesses::Framework::TextStreams::ConsoleReader>();
});
_new->DeclareFunction(
gc, "ConsoleWriter", "Write to console", {"$isStderr"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
bool err;
if (GetArgument(args, 0, err))
return std::make_shared<
Tesses::Framework::TextStreams::ConsoleWriter>(err);
return std::make_shared<
Tesses::Framework::TextStreams::ConsoleWriter>();
});
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang
#endif

View File

@@ -2,183 +2,173 @@
using namespace Tesses::Framework::Crypto;
namespace Tesses::CrossLang
{
static TObject Crypto_RandomBytes(GCList& ls, std::vector<TObject> args)
{
int64_t size;
std::string personalStr;
if(GetArgument(args,0,size) && GetArgument(args,1,personalStr))
{
namespace Tesses::CrossLang {
static TObject Crypto_RandomBytes(GCList &ls, std::vector<TObject> args) {
std::vector<uint8_t> bytes;
bytes.resize((size_t)size);
if(RandomBytes(bytes,personalStr))
{
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return nullptr;
int64_t size;
std::string personalStr;
if (GetArgument(args, 0, size) && GetArgument(args, 1, personalStr)) {
std::vector<uint8_t> bytes;
bytes.resize((size_t)size);
if (RandomBytes(bytes, personalStr)) {
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return nullptr;
}
static TObject Crypto_PBKDF2(GCList& ls, std::vector<TObject> args)
{
std::string pass;
TByteArray* bArraySalt;
int64_t itterations;
int64_t keylength;
int64_t shanum;
if(GetArgument(args,0,pass) && GetArgumentHeap(args,1, bArraySalt) && GetArgument(args,2, itterations) && GetArgument(args,3,keylength) && GetArgument(args,4,shanum))
{
ShaVersion version = VERSION_SHA384;
switch(shanum)
{
case 1:
version = VERSION_SHA1;
break;
case 224:
version = VERSION_SHA224;
break;
case 256:
version = VERSION_SHA256;
break;
default:
case 384:
version = VERSION_SHA384;
break;
case 512:
version = VERSION_SHA512;
break;
}
return nullptr;
}
static TObject Crypto_PBKDF2(GCList &ls, std::vector<TObject> args) {
std::string pass;
TByteArray *bArraySalt;
int64_t itterations;
int64_t keylength;
int64_t shanum;
if (GetArgument(args, 0, pass) && GetArgumentHeap(args, 1, bArraySalt) &&
GetArgument(args, 2, itterations) && GetArgument(args, 3, keylength) &&
GetArgument(args, 4, shanum)) {
ShaVersion version = VERSION_SHA384;
std::vector<uint8_t> key;
key.resize((size_t)keylength);
if(PBKDF2(key,pass,bArraySalt->data,(long)itterations,version))
{
TByteArray* ba = TByteArray::Create(ls);
ba->data = key;
return ba;
}
switch (shanum) {
case 1:
version = VERSION_SHA1;
break;
case 224:
version = VERSION_SHA224;
break;
case 256:
version = VERSION_SHA256;
break;
default:
case 384:
version = VERSION_SHA384;
break;
case 512:
version = VERSION_SHA512;
break;
}
std::vector<uint8_t> key;
key.resize((size_t)keylength);
if (PBKDF2(key, pass, bArraySalt->data, (long)itterations, version)) {
TByteArray *ba = TByteArray::Create(ls);
ba->data = key;
return ba;
}
return nullptr;
}
return nullptr;
}
static TObject Crypto_Base64Encode(GCList &ls, std::vector<TObject> args) {
TByteArray *byteArray;
static TObject Crypto_Base64Encode(GCList& ls, std::vector<TObject> args)
{
TByteArray* byteArray;
if(GetArgumentHeap(args,0,byteArray))
{
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
if (GetArgumentHeap(args, 0, byteArray)) {
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
}
return "";
}
static TObject Crypto_Base64Decode(GCList &ls, std::vector<TObject> args) {
std::string str;
if (GetArgument(args, 0, str)) {
TByteArray *bArray = TByteArray::Create(ls);
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
}
return "";
}
static TObject Crypto_Base64Decode(GCList& ls, std::vector<TObject> args)
{
std::string str;
if(GetArgument(args,0,str))
{
TByteArray* bArray = TByteArray::Create(ls);
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
return bArray;
}
return nullptr;
}
void TStd::RegisterCrypto(std::shared_ptr<GC> gc, TRootEnvironment *env) {
return bArray;
}
return nullptr;
}
void TStd::RegisterCrypto(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterCrypto = true;
if (!HaveCrypto())
return;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "PBKDF2", "Hash passwords with PBKDF2",
{"pass", "salt", "itterations", "keylen", "shanum"},
Crypto_PBKDF2);
dict->DeclareFunction(gc, "RandomBytes",
"Create bytearray but with random bytes in it "
"instead of zeros (this uses mbedtls by the way)",
{"byteCount", "personalString"}, Crypto_RandomBytes);
env->permissions.canRegisterCrypto=true;
if(!HaveCrypto()) return;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "PBKDF2","Hash passwords with PBKDF2",{"pass","salt","itterations","keylen","shanum"},Crypto_PBKDF2);
dict->DeclareFunction(gc, "RandomBytes","Create bytearray but with random bytes in it instead of zeros (this uses mbedtls by the way)",{"byteCount","personalString"},Crypto_RandomBytes);
dict->DeclareFunction(gc, "Base64Encode","Base64 encode",{"data"},Crypto_Base64Encode);
dict->DeclareFunction(gc, "Base64Decode","Base64 decode",{"str"},Crypto_Base64Decode);
dict->DeclareFunction(gc, "Sha1", "Hash with sha1 algorithm (please don't use sha1 unless you need to)",{"strm"}, [](GCList& ls, std::vector<TObject> args)->TObject {
TByteArray* baSrc;
dict->DeclareFunction(gc, "Base64Encode", "Base64 encode", {"data"},
Crypto_Base64Encode);
dict->DeclareFunction(gc, "Base64Decode", "Base64 decode", {"str"},
Crypto_Base64Decode);
dict->DeclareFunction(
gc, "Sha1",
"Hash with sha1 algorithm (please don't use sha1 unless you need to)",
{"strm"}, [](GCList &ls, std::vector<TObject> args) -> TObject {
TByteArray *baSrc;
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
if(GetArgument(args, 0, sho))
{
if (GetArgument(args, 0, sho)) {
auto bytes = Sha1::ComputeHash(sho);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
if(GetArgumentHeap(args,0,baSrc))
{
auto bytes = Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
if (GetArgumentHeap(args, 0, baSrc)) {
auto bytes =
Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return Undefined();
});
dict->DeclareFunction(gc, "Sha256", "Hash with sha256 algorithm",{"strm","$is224"}, [](GCList& ls, std::vector<TObject> args)->TObject {
TByteArray* baSrc;
dict->DeclareFunction(
gc, "Sha256", "Hash with sha256 algorithm", {"strm", "$is224"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
TByteArray *baSrc;
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
bool is224=false;
GetArgument(args,1,is224);
bool is224 = false;
GetArgument(args, 1, is224);
if(GetArgument(args, 0, sho))
{
auto bytes = Sha256::ComputeHash(sho,is224);
if (GetArgument(args, 0, sho)) {
auto bytes = Sha256::ComputeHash(sho, is224);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
if(GetArgumentHeap(args,0,baSrc))
{
auto bytes = Sha256::ComputeHash(baSrc->data.data(), baSrc->data.size(), is224);
if (GetArgumentHeap(args, 0, baSrc)) {
auto bytes = Sha256::ComputeHash(baSrc->data.data(),
baSrc->data.size(), is224);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return Undefined();
});
dict->DeclareFunction(gc, "Sha512", "Hash with sha512 algorithm",{"strm","$is384"}, [](GCList& ls, std::vector<TObject> args)->TObject {
TByteArray* baSrc;
dict->DeclareFunction(
gc, "Sha512", "Hash with sha512 algorithm", {"strm", "$is384"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
TByteArray *baSrc;
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
bool is384=false;
GetArgument(args,1,is384);
bool is384 = false;
GetArgument(args, 1, is384);
if(GetArgument(args, 0, sho))
{
auto bytes = Sha512::ComputeHash(sho,is384);
if (GetArgument(args, 0, sho)) {
auto bytes = Sha512::ComputeHash(sho, is384);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
if(GetArgumentHeap(args,0,baSrc))
{
auto bytes = Sha512::ComputeHash(baSrc->data.data(), baSrc->data.size(), is384);
if (GetArgumentHeap(args, 0, baSrc)) {
auto bytes = Sha512::ComputeHash(baSrc->data.data(),
baSrc->data.size(), is384);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return Undefined();
});
gc->BarrierBegin();
env->DeclareVariable("Crypto", dict);
gc->BarrierEnd();
}
gc->BarrierBegin();
env->DeclareVariable("Crypto", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -1,149 +1,137 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
TObject Dictionary_FindByKey(GCList& ls, std::vector<TObject> args)
{
TList* dest = TList::Create(ls);
ls.GetGC()->BarrierBegin();
std::string key;
if(GetArgument(args,1,key))
{
namespace Tesses::CrossLang {
TObject Dictionary_FindByKey(GCList &ls, std::vector<TObject> args) {
TList *dest = TList::Create(ls);
ls.GetGC()->BarrierBegin();
std::string key;
if (GetArgument(args, 1, key)) {
std::function<void(TObject)> crawl;
crawl = [&](TObject o) -> void {
TDictionary* dict;
TList* list;
TAssociativeArray* aa;
if(GetObjectHeap(o,aa))
{
std::string k0;
for(auto& item : aa->items)
{
if(GetObject(item.first,k0) && k0 == key) dest->Add(item.second);
crawl(item.second);
}
std::function<void(TObject)> crawl;
crawl = [&](TObject o) -> void {
TDictionary *dict;
TList *list;
TAssociativeArray *aa;
if (GetObjectHeap(o, aa)) {
std::string k0;
for (auto &item : aa->items) {
if (GetObject(item.first, k0) && k0 == key)
dest->Add(item.second);
crawl(item.second);
}
if(GetObjectHeap(o,dict))
{
for(auto& item : dict->items)
{
if(item.first == key) dest->Add(item.second);
crawl(item.second);
}
}
if (GetObjectHeap(o, dict)) {
for (auto &item : dict->items) {
if (item.first == key)
dest->Add(item.second);
crawl(item.second);
}
if(GetObjectHeap(o,list))
{
for(auto& item : list->items)
{
crawl(item);
}
}
if (GetObjectHeap(o, list)) {
for (auto &item : list->items) {
crawl(item);
}
};
crawl(args[0]);
}
ls.GetGC()->BarrierEnd();
return dest;
}
};
crawl(args[0]);
}
TObject Dictionary_Items(GCList& ls, std::vector<TObject> args)
{
TDictionary* dict;
TDynamicDictionary* dynDict;
if(GetArgumentHeap(args,0,dynDict))
{
TDictionary* enumerableItem = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
ls.GetGC()->BarrierEnd();
return dest;
}
TObject Dictionary_Items(GCList &ls, std::vector<TObject> args) {
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{},[dynDict](GCList& ls2, std::vector<TObject> args)->TObject {
TDictionary *dict;
TDynamicDictionary *dynDict;
if (GetArgumentHeap(args, 0, dynDict)) {
TDictionary *enumerableItem = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
auto fn = TExternalMethod::Create(
ls, "Get Enumerator for Dictionary", {},
[dynDict](GCList &ls2, std::vector<TObject> args) -> TObject {
return dynDict->GetEnumerator(ls2);
});
fn->watch.push_back(dynDict);
enumerableItem->SetValue("GetEnumerator", fn);
ls.GetGC()->BarrierEnd();
fn->watch.push_back(dynDict);
return enumerableItem;
}
if(GetArgumentHeap(args,0,dict))
{
TDictionary* enumerableItem = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
enumerableItem->SetValue("GetEnumerator", fn);
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{"dict"},[dict](GCList& ls2, std::vector<TObject> args)->TObject {
return TDictionaryEnumerator::Create(ls2,dict);
ls.GetGC()->BarrierEnd();
return enumerableItem;
}
if (GetArgumentHeap(args, 0, dict)) {
TDictionary *enumerableItem = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
auto fn = TExternalMethod::Create(
ls, "Get Enumerator for Dictionary", {"dict"},
[dict](GCList &ls2, std::vector<TObject> args) -> TObject {
return TDictionaryEnumerator::Create(ls2, dict);
});
fn->watch.push_back(dict);
enumerableItem->SetValue("GetEnumerator", fn);
fn->watch.push_back(dict);
enumerableItem->SetValue("GetEnumerator", fn);
ls.GetGC()->BarrierEnd();
return enumerableItem;
}
return Undefined();
}
TObject Dictionary_GetField(GCList &ls, std::vector<TObject> args) {
TDictionary *dict;
TDynamicDictionary *dynDict;
std::string key;
if (GetArgument(args, 1, key)) {
if (GetArgumentHeap(args, 0, dict)) {
ls.GetGC()->BarrierBegin();
auto res = dict->GetValue(key);
ls.GetGC()->BarrierEnd();
return enumerableItem;
return res;
} else if (GetArgumentHeap(args, 0, dynDict)) {
return dynDict->GetField(ls, key);
}
return Undefined();
}
TObject Dictionary_GetField(GCList& ls, std::vector<TObject> args)
{
TDictionary* dict;
TDynamicDictionary* dynDict;
std::string key;
if(GetArgument(args,1,key))
{
if(GetArgumentHeap(args,0,dict))
{
ls.GetGC()->BarrierBegin();
auto res = dict->GetValue(key);
ls.GetGC()->BarrierEnd();
return res;
}
else if(GetArgumentHeap(args,0,dynDict))
{
return dynDict->GetField(ls,key);
}
return nullptr;
}
TObject Dictionary_SetField(GCList &ls, std::vector<TObject> args) {
TDictionary *dict;
TDynamicDictionary *dynDict;
std::string key;
if (args.size() == 3 && GetArgument(args, 1, key)) {
if (GetArgumentHeap(args, 0, dict)) {
ls.GetGC()->BarrierBegin();
dict->SetValue(key, args[2]);
ls.GetGC()->BarrierEnd();
} else if (GetArgumentHeap(args, 0, dynDict)) {
dynDict->SetField(ls, key, args[2]);
}
return nullptr;
}
TObject Dictionary_SetField(GCList& ls, std::vector<TObject> args)
{
TDictionary* dict;
TDynamicDictionary* dynDict;
std::string key;
if(args.size() == 3 && GetArgument(args,1,key))
{
if(GetArgumentHeap(args,0,dict))
{
ls.GetGC()->BarrierBegin();
dict->SetValue(key,args[2]);
ls.GetGC()->BarrierEnd();
}
else if(GetArgumentHeap(args,0,dynDict))
{
dynDict->SetField(ls,key,args[2]);
}
}
return nullptr;
}
void TStd::RegisterDictionary(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
return nullptr;
}
void TStd::RegisterDictionary(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterDictionary=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
env->permissions.canRegisterDictionary = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
gc->BarrierBegin();
dict->DeclareFunction(gc, "FindByKey","Scan object recursively, return list of items with key",{"obj","key"}, Dictionary_FindByKey);
dict->DeclareFunction(gc, "Items","Get Dictionary Item Enumerable, for the each(item : Dictionary.Items(myDict)){item.Key; item.Value;}",{"dictionary"},Dictionary_Items);
dict->DeclareFunction(gc, "SetField","Set a field in dictionary",{"dict","key","value"},Dictionary_SetField);
dict->DeclareFunction(gc, "GetField","Get a field in dictionary",{"dict","key"},Dictionary_GetField);
gc->BarrierBegin();
dict->DeclareFunction(
gc, "FindByKey",
"Scan object recursively, return list of items with key",
{"obj", "key"}, Dictionary_FindByKey);
dict->DeclareFunction(gc, "Items",
"Get Dictionary Item Enumerable, for the each(item : "
"Dictionary.Items(myDict)){item.Key; item.Value;}",
{"dictionary"}, Dictionary_Items);
dict->DeclareFunction(gc, "SetField", "Set a field in dictionary",
{"dict", "key", "value"}, Dictionary_SetField);
dict->DeclareFunction(gc, "GetField", "Get a field in dictionary",
{"dict", "key"}, Dictionary_GetField);
env->DeclareVariable("Dictionary", dict);
gc->BarrierEnd();
}
}
env->DeclareVariable("Dictionary", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -5,165 +5,152 @@
#include <windows.h>
#endif
namespace Tesses::CrossLang
{
using namespace Tesses::Framework::Platform::Environment;
#if defined(_WIN32)
static char EnvPathSeperator=';';
#else
static char EnvPathSeperator=':';
#endif
namespace Tesses::CrossLang {
using namespace Tesses::Framework::Platform::Environment;
#if defined(_WIN32)
static char EnvPathSeperator = ';';
#else
static char EnvPathSeperator = ':';
#endif
Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath("");
Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath("");
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir()
{
if(!CrossLangConfigPath.path.empty())
return CrossLangConfigPath;
return SpecialFolders::GetConfig() / "Tesses" / "CrossLang";
}
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir() {
if (!CrossLangConfigPath.path.empty())
return CrossLangConfigPath;
static TObject Env_getCrossLangConfig(GCList& ls, std::vector<TObject> args)
{
return GetCrossLangConfigDir();
}
static TObject Env_getPlatform(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Platform::Environment::GetPlatform();
}
static TObject Env_GetAt(GCList& ls, std::vector<TObject> args)
{
std::string key;
if(GetArgument(args,0,key))
{
auto v = GetVariable(key);
if(v) return v.value();
}
return nullptr;
}
static TObject Env_SetAt(GCList& ls, std::vector<TObject> args)
{
std::string key;
std::string value;
if(GetArgument(args,0,key))
{
if(GetArgument(args,1,value))
{
SetVariable(key,value);
return value;
}
else
{
SetVariable(key,std::nullopt);
}
}
return nullptr;
}
static TObject Env_getDownloads(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetDownloads();
}
static TObject Env_getMusic(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetMusic();
}
static TObject Env_getPictures(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetPictures();
}
static TObject Env_getVideos(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetVideos();
}
static TObject Env_getDocuments(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetDocuments();
}
static TObject Env_getConfig(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetConfig();
}
static TObject Env_getDesktop(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetDesktop();
}
static TObject Env_getState(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetState();
}
static TObject Env_getCache(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetCache();
}
static TObject Env_getData(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetData();
}
static TObject Env_getUser(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetHomeFolder();
}
static TObject Env_GetRealExecutablePath(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath p;
if(GetArgumentAsPath(args,0,p))
{
return GetRealExecutablePath(p);
}
return Tesses::Framework::Filesystem::VFSPath();
}
static TObject Env_GetAll(GCList& ls, std::vector<TObject> args)
{
ls.GetGC()->BarrierBegin();
TList* list = TList::Create(ls);
std::vector<std::pair<std::string, std::string>> env;
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
for(auto& item : env)
{
list->Add(TDictionary::Create(ls,{TDItem("Key",item.first),TDItem("Value",item.second)}));
}
ls.GetGC()->BarrierEnd();
return list;
}
static TObject Env_getLittleEndian(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Serialization::BitConverter::IsLittleEndian();
}
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
env->permissions.canRegisterEnv=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc,"GetAt","Get environment variable", {"key"}, Env_GetAt);
dict->DeclareFunction(gc,"SetAt","Set environment variable", {"key","value"}, Env_SetAt);
dict->DeclareFunction(gc,"GetAll","Get all of the environment variables",{},Env_GetAll);
dict->DeclareFunction(gc,"getDesktop","Get desktop folder",{},Env_getDesktop);
dict->DeclareFunction(gc,"getDownloads","Get downloads folder",{},Env_getDownloads);
dict->DeclareFunction(gc,"getDocuments","Get documents folder",{},Env_getDocuments);
dict->DeclareFunction(gc,"getMusic","Get music folder",{},Env_getMusic);
dict->DeclareFunction(gc,"getPictures","Get pictures folder",{},Env_getPictures);
dict->DeclareFunction(gc,"getVideos","Get videos folder",{},Env_getVideos);
dict->DeclareFunction(gc,"getState","Get state folder",{},Env_getState);
dict->DeclareFunction(gc,"getCache","Get cache folder",{},Env_getCache);
dict->DeclareFunction(gc,"getConfig","Get config folder",{},Env_getConfig);
dict->DeclareFunction(gc,"getCrossLangConfig","Get crosslang configuration folder",{}, Env_getCrossLangConfig);
dict->DeclareFunction(gc,"getData","Get data folder",{},Env_getData);
dict->DeclareFunction(gc,"getUser","Get user folder",{},Env_getUser);
dict->DeclareFunction(gc,"getPlatform","Get platform name",{},Env_getPlatform);
dict->DeclareFunction(gc,"GetRealExecutablePath", "Get the absolute path for executable", {"path"},Env_GetRealExecutablePath);
dict->DeclareFunction(gc, "getLittleEndian", "Is the platform little endian", {},Env_getLittleEndian);
gc->BarrierBegin();
dict->SetValue("EnvPathSeperator",EnvPathSeperator);
env->SetVariable("Env", dict);
gc->BarrierEnd();
}
return SpecialFolders::GetConfig() / "Tesses" / "CrossLang";
}
static TObject Env_getCrossLangConfig(GCList &ls, std::vector<TObject> args) {
return GetCrossLangConfigDir();
}
static TObject Env_getPlatform(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Platform::Environment::GetPlatform();
}
static TObject Env_GetAt(GCList &ls, std::vector<TObject> args) {
std::string key;
if (GetArgument(args, 0, key)) {
auto v = GetVariable(key);
if (v)
return v.value();
}
return nullptr;
}
static TObject Env_SetAt(GCList &ls, std::vector<TObject> args) {
std::string key;
std::string value;
if (GetArgument(args, 0, key)) {
if (GetArgument(args, 1, value)) {
SetVariable(key, value);
return value;
} else {
SetVariable(key, std::nullopt);
}
}
return nullptr;
}
static TObject Env_getDownloads(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetDownloads();
}
static TObject Env_getMusic(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetMusic();
}
static TObject Env_getPictures(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetPictures();
}
static TObject Env_getVideos(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetVideos();
}
static TObject Env_getDocuments(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetDocuments();
}
static TObject Env_getConfig(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetConfig();
}
static TObject Env_getDesktop(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetDesktop();
}
static TObject Env_getState(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetState();
}
static TObject Env_getCache(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetCache();
}
static TObject Env_getData(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetData();
}
static TObject Env_getUser(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetHomeFolder();
}
static TObject Env_GetRealExecutablePath(GCList &ls,
std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath p;
if (GetArgumentAsPath(args, 0, p)) {
return GetRealExecutablePath(p);
}
return Tesses::Framework::Filesystem::VFSPath();
}
static TObject Env_GetAll(GCList &ls, std::vector<TObject> args) {
ls.GetGC()->BarrierBegin();
TList *list = TList::Create(ls);
std::vector<std::pair<std::string, std::string>> env;
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
for (auto &item : env) {
list->Add(TDictionary::Create(
ls, {TDItem("Key", item.first), TDItem("Value", item.second)}));
}
ls.GetGC()->BarrierEnd();
return list;
}
static TObject Env_getLittleEndian(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Serialization::BitConverter::IsLittleEndian();
}
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterEnv = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "GetAt", "Get environment variable", {"key"},
Env_GetAt);
dict->DeclareFunction(gc, "SetAt", "Set environment variable",
{"key", "value"}, Env_SetAt);
dict->DeclareFunction(gc, "GetAll", "Get all of the environment variables",
{}, Env_GetAll);
dict->DeclareFunction(gc, "getDesktop", "Get desktop folder", {},
Env_getDesktop);
dict->DeclareFunction(gc, "getDownloads", "Get downloads folder", {},
Env_getDownloads);
dict->DeclareFunction(gc, "getDocuments", "Get documents folder", {},
Env_getDocuments);
dict->DeclareFunction(gc, "getMusic", "Get music folder", {}, Env_getMusic);
dict->DeclareFunction(gc, "getPictures", "Get pictures folder", {},
Env_getPictures);
dict->DeclareFunction(gc, "getVideos", "Get videos folder", {},
Env_getVideos);
dict->DeclareFunction(gc, "getState", "Get state folder", {}, Env_getState);
dict->DeclareFunction(gc, "getCache", "Get cache folder", {}, Env_getCache);
dict->DeclareFunction(gc, "getConfig", "Get config folder", {},
Env_getConfig);
dict->DeclareFunction(gc, "getCrossLangConfig",
"Get crosslang configuration folder", {},
Env_getCrossLangConfig);
dict->DeclareFunction(gc, "getData", "Get data folder", {}, Env_getData);
dict->DeclareFunction(gc, "getUser", "Get user folder", {}, Env_getUser);
dict->DeclareFunction(gc, "getPlatform", "Get platform name", {},
Env_getPlatform);
dict->DeclareFunction(gc, "GetRealExecutablePath",
"Get the absolute path for executable", {"path"},
Env_GetRealExecutablePath);
dict->DeclareFunction(gc, "getLittleEndian",
"Is the platform little endian", {},
Env_getLittleEndian);
gc->BarrierBegin();
dict->SetValue("EnvPathSeperator", EnvPathSeperator);
env->SetVariable("Env", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -1,57 +1,53 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
static TObject Helpers_CopyToProgress(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Streams::Stream> src;
std::shared_ptr<Tesses::Framework::Streams::Stream> dest;
double precision=1000.0;
TCallable* callable;
if(GetArgument(args,0,src) && GetArgument(args,1,dest) && GetArgumentHeap(args,2,callable))
{
GetArgument(args,3,precision);
auto len = src->GetLength();
callable->Call(ls,{0.0});
if(len > 0)
{
std::vector<uint8_t> buff(1024);
int64_t pos=0;
int curPercent=0;
int lastPercent=0;
size_t read = 0;
do {
read = src->ReadBlock(buff.data(),buff.size());
dest->WriteBlock(buff.data(),read);
static TObject Helpers_CopyToProgress(GCList &ls, std::vector<TObject> args) {
std::shared_ptr<Tesses::Framework::Streams::Stream> src;
std::shared_ptr<Tesses::Framework::Streams::Stream> dest;
double precision = 1000.0;
TCallable *callable;
if (GetArgument(args, 0, src) && GetArgument(args, 1, dest) &&
GetArgumentHeap(args, 2, callable)) {
GetArgument(args, 3, precision);
auto len = src->GetLength();
callable->Call(ls, {0.0});
if (len > 0) {
std::vector<uint8_t> buff(1024);
int64_t pos = 0;
int curPercent = 0;
int lastPercent = 0;
size_t read = 0;
do {
read = src->ReadBlock(buff.data(), buff.size());
dest->WriteBlock(buff.data(), read);
if(read == 0) break;
pos += (int64_t)read;
if (read == 0)
break;
pos += (int64_t)read;
double percent = ((double)pos / len);
percent *= precision;
curPercent = (int)percent;
double percent = ((double)pos / len);
percent *= precision;
if(curPercent > lastPercent)
{
lastPercent = curPercent;
callable->Call(ls,{curPercent/precision});
}
curPercent = (int)percent;
if (curPercent > lastPercent) {
lastPercent = curPercent;
callable->Call(ls, {curPercent / precision});
}
} while(read != 0);
}
else {
src->CopyTo(dest);
}
callable->Call(ls,{1.0});
} while (read != 0);
} else {
src->CopyTo(dest);
}
return Undefined();
callable->Call(ls, {1.0});
}
void TStd::RegisterHelpers(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
auto helpers=env->EnsureDictionary(gc,"Helpers");
helpers->DeclareFunction(gc,"CopyToProgress","Copy Stream to another (but with progress event)",{"src","dest","progressCB","$precision"},Helpers_CopyToProgress);
}
}
return Undefined();
}
void TStd::RegisterHelpers(std::shared_ptr<GC> gc, TRootEnvironment *env) {
auto helpers = env->EnsureDictionary(gc, "Helpers");
helpers->DeclareFunction(gc, "CopyToProgress",
"Copy Stream to another (but with progress event)",
{"src", "dest", "progressCB", "$precision"},
Helpers_CopyToProgress);
}
} // namespace Tesses::CrossLang

View File

@@ -1,322 +1,341 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
static TObject FS_CreateArchive(GCList &ls, std::vector<TObject> args) {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
namespace Tesses::CrossLang
{
static TObject FS_CreateArchive(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
std::string name;
std::string version;
std::string info;
std::string icon="";
TVMVersion version2;
std::string name;
std::string version;
std::string info;
std::string icon = "";
TVMVersion version2;
if(GetArgument(args,0,vfs) && GetArgument(args,1,strm) && GetArgument(args,2,name) && GetArgument(args,4,info) && ((GetArgument(args,3,version) && TVMVersion::TryParse(version,version2)) || GetArgument(args,3,version2)))
{
GetArgument(args,5,icon);
CrossArchiveCreate(vfs,strm,name,version2,info,icon);
}
return nullptr;
if (GetArgument(args, 0, vfs) && GetArgument(args, 1, strm) &&
GetArgument(args, 2, name) && GetArgument(args, 4, info) &&
((GetArgument(args, 3, version) &&
TVMVersion::TryParse(version, version2)) ||
GetArgument(args, 3, version2))) {
GetArgument(args, 5, icon);
CrossArchiveCreate(vfs, strm, name, version2, info, icon);
}
static TObject FS_ExtractArchive(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetArgument(args,0,strm) && GetArgument(args,1,vfs))
{
auto res = CrossArchiveExtract(strm,vfs);
return nullptr;
}
static TObject FS_ExtractArchive(GCList &ls, std::vector<TObject> args) {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Name",res.first.first);
dict->SetValue("Version",res.first.second.ToString());
dict->SetValue("Info",res.second);
ls.GetGC()->BarrierEnd();
return dict;
}
return nullptr;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if (GetArgument(args, 0, strm) && GetArgument(args, 1, vfs)) {
auto res = CrossArchiveExtract(strm, vfs);
TDictionary *dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Name", res.first.first);
dict->SetValue("Version", res.first.second.ToString());
dict->SetValue("Info", res.second);
ls.GetGC()->BarrierEnd();
return dict;
}
return nullptr;
}
static TObject FS_ReadAllText(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
static TObject FS_ReadAllText(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))
{
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs,path);
}
return "";
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs, path);
}
return "";
}
static TObject FS_ReadAllLines(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
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;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs,path,lines);
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
std::vector<std::string> lines;
ls.GetGC()->BarrierBegin();
auto items = TList::Create(ls);
for(auto& l : lines) { items->Add(l);}
ls.GetGC()->BarrierEnd();
return items;
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs, path, lines);
ls.GetGC()->BarrierBegin();
auto items = TList::Create(ls);
for (auto &l : lines) {
items->Add(l);
}
return nullptr;
ls.GetGC()->BarrierEnd();
return items;
}
return nullptr;
}
static TObject FS_ReadAllBytes(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))
{
auto res = TByteArray::Create(ls);
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs,path,res->data);
return res;
}
return nullptr;
static TObject FS_ReadAllBytes(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)) {
auto res = TByteArray::Create(ls);
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs, path,
res->data);
return res;
}
return nullptr;
}
static TObject FS_WriteAllLines(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
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))
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;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::string content;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
GetArgument(args, 2, content)) {
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs, path,
content);
}
return nullptr;
}
static TObject FS_WriteAllBytes(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TByteArray *bArray;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
GetArgumentHeap(args, 2, bArray)) {
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs, path,
bArray->data);
}
return nullptr;
}
class FS_Watcher : public TNativeObject {
public:
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
FS_Watcher(
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher)
: watcher(watcher) {}
TObject CallMethod(GCList &ls, std::string name,
std::vector<TObject> args) {
if (name == "getPath") {
return watcher->GetPath();
}
if (name == "getFilesystem") {
return watcher->GetFilesystem();
}
if (name == "setEnabled") {
bool enabled;
if (GetArgument(args, 0, enabled)) {
watcher->SetEnabled(enabled);
return enabled;
}
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;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::string content;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content))
{
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs,path,content);
if (name == "getEnabled") {
return watcher->GetEnabled();
}
return nullptr;
}
static TObject FS_WriteAllBytes(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TByteArray* bArray;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,bArray))
{
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs,path,bArray->data);
if (name == "setEvents") {
int64_t evts;
if (GetArgument(args, 0, evts)) {
watcher->events =
(Tesses::Framework::Filesystem::FSWatcherEventType)evts;
return evts;
}
}
return nullptr;
}
class FS_Watcher : public TNativeObject {
public:
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
FS_Watcher(std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher): watcher(watcher)
{}
TObject CallMethod(GCList& ls, std::string name, std::vector<TObject> args)
{
if(name == "getPath")
{
return watcher->GetPath();
}
if(name == "getFilesystem")
{
return watcher->GetFilesystem();
}
if(name == "setEnabled")
{
bool enabled;
if(GetArgument(args,0,enabled))
{
watcher->SetEnabled(enabled);
return enabled;
}
}
if(name == "getEnabled")
{
return watcher->GetEnabled();
}
if(name == "setEvents")
{
int64_t evts;
if(GetArgument(args,0,evts))
{
watcher->events = (Tesses::Framework::Filesystem::FSWatcherEventType)evts;
return evts;
}
}
if(name == "getEvents")
{
return (int64_t)watcher->events;
}
if(name == "setCallback")
{
TCallable* callable=nullptr;
if(GetArgumentHeap(args,0,callable))
{
auto markedT = CreateMarkedTObject(ls,callable);
watcher->event = [markedT](Tesses::Framework::Filesystem::FSWatcherEvent& evt) -> void {
GCList ls(markedT->GetGC());
TObject o = markedT->GetObject();
TCallable* callable;
if(GetObjectHeap(o,callable))
{
auto isEvent = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
{
if (name == "getEvents") {
return (int64_t)watcher->events;
}
if (name == "setCallback") {
TCallable *callable = nullptr;
if (GetArgumentHeap(args, 0, callable)) {
auto markedT = CreateMarkedTObject(ls, callable);
watcher->event =
[markedT](
Tesses::Framework::Filesystem::FSWatcherEvent &evt)
-> void {
GCList ls(markedT->GetGC());
TObject o = markedT->GetObject();
TCallable *callable;
if (GetObjectHeap(o, callable)) {
auto isEvent = TExternalMethod::Create(
ls, "", {},
[evt](GCList &ls,
std::vector<TObject> args) -> TObject {
int64_t n;
if(GetArgument(args,0,n))
{
if (GetArgument(args, 0, n)) {
auto myevt = evt;
return myevt.IsEvent((Tesses::Framework::Filesystem::FSWatcherEventType)n);
return myevt.IsEvent(
(Tesses::Framework::Filesystem::
FSWatcherEventType)n);
}
return false;
});
auto toString = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
{
auto toString = TExternalMethod::Create(
ls, "", {},
[evt](GCList &ls,
std::vector<TObject> args) -> TObject {
auto myevt = evt;
return myevt.ToString();
});
auto dict = TDictionary::Create(ls, {TDItem("IsDirectory",evt.isDir),TDItem("Type",(int64_t)evt.type),TDItem("Source",evt.src), TDItem("Destination",evt.dest),TDItem("ToString",toString),TDItem("IsEvent",isEvent)});
callable->Call(ls,{dict});
}
};
auto dict = TDictionary::Create(
ls, {TDItem("IsDirectory", evt.isDir),
TDItem("Type", (int64_t)evt.type),
TDItem("Source", evt.src),
TDItem("Destination", evt.dest),
TDItem("ToString", toString),
TDItem("IsEvent", isEvent)});
callable->Call(ls, {dict});
}
else {
watcher->event=nullptr;
}
return nullptr;
}
if(name == "Start")
{
watcher->SetEnabled(true);
}
if(name == "Stop")
{
watcher->SetEnabled(false);
}
if(name == "ToString")
{
return "FSWatcher";
}
return Undefined();
};
} else {
watcher->event = nullptr;
}
std::string TypeName() {
return "FSWatcher";
}
};
TObject New_FSWatcher(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
{
return TNativeObject::Create<FS_Watcher>(ls,Tesses::Framework::Filesystem::FSWatcher::Create(vfs,path));
return nullptr;
}
return nullptr;
if (name == "Start") {
watcher->SetEnabled(true);
}
if (name == "Stop") {
watcher->SetEnabled(false);
}
if (name == "ToString") {
return "FSWatcher";
}
return Undefined();
}
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env, bool enable)
{
if(enable)
{
RegisterIO(gc,env,std::make_shared<Tesses::Framework::Filesystem::RelativeFilesystem>(Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory()));
}
else
{
RegisterIO(gc,env,nullptr);
}
std::string TypeName() { return "FSWatcher"; }
};
TObject New_FSWatcher(GCList &ls, std::vector<TObject> args) {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
return TNativeObject::Create<FS_Watcher>(
ls, Tesses::Framework::Filesystem::FSWatcher::Create(vfs, path));
}
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env,std::shared_ptr<Tesses::Framework::Filesystem::RelativeFilesystem> fs)
{
return nullptr;
}
void TStd::RegisterIO(std::shared_ptr<GC> gc, TRootEnvironment *env,
bool enable) {
if (enable) {
RegisterIO(
gc, env,
std::make_shared<Tesses::Framework::Filesystem::RelativeFilesystem>(
Tesses::Framework::Filesystem::LocalFS,
Tesses::Framework::Filesystem::VFSPath::
GetAbsoluteCurrentDirectory()));
} else {
RegisterIO(gc, env, nullptr);
}
}
void TStd::RegisterIO(
std::shared_ptr<GC> gc, TRootEnvironment *env,
std::shared_ptr<Tesses::Framework::Filesystem::RelativeFilesystem> fs) {
env->permissions.canRegisterIO=true;
env->permissions.localfs = fs;
GCList ls(gc);
gc->BarrierBegin();
auto newDict = env->EnsureDictionary(gc, "New");
newDict->DeclareFunction(gc,"FSWatcher","Watch a file/directory",{"vfs","path"}, New_FSWatcher);
auto dict = env->EnsureDictionary(gc,"FS");
dict->SetValue("SEEK_SET",(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
dict->SetValue("SEEK_CUR",(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
dict->SetValue("SEEK_END",(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
dict->SetValue("FSWatcherEvents",TDictionary::Create(ls,
{
TDItem("None", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::None),
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Accessed),
TDItem("AttributeChanged", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::AttributeChanged),
TDItem("Writen", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
TDItem("Read", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Read),
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Created),
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Deleted),
TDItem("WatchEntryDeleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryDeleted),
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Modified),
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryMoved),
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveOld),
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveNew),
TDItem("Opened", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
TDItem("Closed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
TDItem("Moved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
TDItem("All", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::All)
}
));
env->permissions.canRegisterIO = true;
env->permissions.localfs = fs;
GCList ls(gc);
if(fs)
{
dict->SetValue("Local", fs);
dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},[fs](GCList& ls, std::vector<TObject> args)->TObject{
gc->BarrierBegin();
auto newDict = env->EnsureDictionary(gc, "New");
newDict->DeclareFunction(gc, "FSWatcher", "Watch a file/directory",
{"vfs", "path"}, New_FSWatcher);
auto dict = env->EnsureDictionary(gc, "FS");
dict->SetValue("SEEK_SET",
(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
dict->SetValue("SEEK_CUR",
(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
dict->SetValue("SEEK_END",
(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
dict->SetValue(
"FSWatcherEvents",
TDictionary::Create(
ls,
{TDItem(
"None",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::None),
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::Accessed),
TDItem("AttributeChanged",
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
AttributeChanged),
TDItem(
"Writen",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
TDItem(
"Read",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Read),
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::Created),
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::Deleted),
TDItem("WatchEntryDeleted",
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
WatchEntryDeleted),
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::Modified),
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::WatchEntryMoved),
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::MoveOld),
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::MoveNew),
TDItem(
"Opened",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
TDItem(
"Closed",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
TDItem(
"Moved",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
TDItem(
"All",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::All)}));
if (fs) {
dict->SetValue("Local", fs);
dict->DeclareFunction(
gc, "MakeFull", "Make absolute path from relative path", {"path"},
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
if(path.relative)
{
if (GetArgumentAsPath(args, 0, path)) {
if (path.relative) {
auto myPath = fs->GetWorking() / path;
myPath = myPath.CollapseRelativeParents();
return myPath;
@@ -325,37 +344,47 @@ namespace Tesses::CrossLang
}
return nullptr;
});
dict->DeclareFunction(gc,"getCurrentPath","Get current path",{},[fs](GCList& ls, std::vector<TObject> args)->TObject{
dict->DeclareFunction(
gc, "getCurrentPath", "Get current path", {},
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
return fs->GetWorking();
});
dict->DeclareFunction(gc,"setCurrentPath","Set the current path",{"path"}, [fs](GCList& ls, std::vector<TObject> args)->TObject {
dict->DeclareFunction(
gc, "setCurrentPath", "Set the current path", {"path"},
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
if(path.relative)
{
fs->SetWorking(path.MakeAbsolute(fs->GetWorking()));
}
else {
fs->SetWorking(path);
}
if (GetArgumentAsPath(args, 0, path)) {
if (path.relative) {
fs->SetWorking(path.MakeAbsolute(fs->GetWorking()));
} else {
fs->SetWorking(path);
}
}
return path;
});
}
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);
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",{"fs","strm","name","version","info"},FS_CreateArchive);
dict->DeclareFunction(gc,"ExtractArchive", "Extract a crvm archive",{"strm","vfs"},FS_ExtractArchive);
gc->BarrierEnd();
}
}
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);
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",
{"fs", "strm", "name", "version", "info"},
FS_CreateArchive);
dict->DeclareFunction(gc, "ExtractArchive", "Extract a crvm archive",
{"strm", "vfs"}, FS_ExtractArchive);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -2,206 +2,193 @@
#include "CrossLang.hpp"
using namespace Tesses::Framework::Serialization::Json;
namespace Tesses::CrossLang
{
namespace Tesses::CrossLang {
static bool IsValidForJson(TObject v)
{
if(std::holds_alternative<std::nullptr_t>(v)) return true;
static bool IsValidForJson(TObject v) {
if (std::holds_alternative<std::nullptr_t>(v))
return true;
if(std::holds_alternative<int64_t>(v)) return true;
if (std::holds_alternative<int64_t>(v))
return true;
if(std::holds_alternative<double>(v)) return true;
if (std::holds_alternative<double>(v))
return true;
if (std::holds_alternative<bool>(v))
return true;
if(std::holds_alternative<bool>(v)) return true;
if (std::holds_alternative<std::string>(v))
return true;
if(std::holds_alternative<std::string>(v)) return true;
if(std::holds_alternative<THeapObjectHolder>(v))
{
auto res = std::get<THeapObjectHolder>(v);
auto ls = dynamic_cast<TList*>(res.obj);
auto dict = dynamic_cast<TDictionary*>(res.obj);
if(ls != nullptr) return true;
if(dict != nullptr) return true;
}
return false;
if (std::holds_alternative<THeapObjectHolder>(v)) {
auto res = std::get<THeapObjectHolder>(v);
auto ls = dynamic_cast<TList *>(res.obj);
auto dict = dynamic_cast<TDictionary *>(res.obj);
if (ls != nullptr)
return true;
if (dict != nullptr)
return true;
}
static JToken JsonSerialize(TObject v)
{
if(std::holds_alternative<std::nullptr_t>(v)) return nullptr;
if(std::holds_alternative<int64_t>(v)) return std::get<int64_t>(v);
if(std::holds_alternative<double>(v)) return std::get<double>(v);
if(std::holds_alternative<bool>(v)) return std::get<bool>(v);
if(std::holds_alternative<std::string>(v)) return std::get<std::string>(v);
if(std::holds_alternative<THeapObjectHolder>(v))
{
auto obj = std::get<THeapObjectHolder>(v).obj;
auto ls = dynamic_cast<TList*>(obj);
auto dict = dynamic_cast<TDictionary*>(obj);
if(ls != nullptr)
{
JArray items;
for(int64_t i = 0; i < ls->Count(); i++)
{
auto val = ls->Get(i);
if(IsValidForJson(val))
items.Add(JsonSerialize(val));
}
return items;
}
if(dict != nullptr)
{
JObject obj;
for(auto item : dict->items)
{
if(IsValidForJson(item.second))
obj.SetValue(item.first,JsonSerialize(item.second));
}
return obj;
}
}
return false;
}
static JToken JsonSerialize(TObject v) {
if (std::holds_alternative<std::nullptr_t>(v))
return nullptr;
}
static TObject JsonEncode(GCList& ls2, std::vector<TObject> args)
{
if(args.size() >= 1)
{
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
auto json = JsonSerialize(args[0]);
if (std::holds_alternative<int64_t>(v))
return std::get<int64_t>(v);
if (std::holds_alternative<double>(v))
return std::get<double>(v);
if (std::holds_alternative<bool>(v))
return std::get<bool>(v);
if (std::holds_alternative<std::string>(v))
return std::get<std::string>(v);
if (std::holds_alternative<THeapObjectHolder>(v)) {
auto obj = std::get<THeapObjectHolder>(v).obj;
auto ls = dynamic_cast<TList *>(obj);
auto dict = dynamic_cast<TDictionary *>(obj);
return Json::Encode(json,indent);
}
return "null";
}
static TObject JsonDocEncode(GCList& ls2, std::vector<TObject> args)
{
if(args.size() >= 1)
{
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
auto json = JsonSerialize(args[0]);
JArray ar;
if(TryGetJToken(json,ar))
return Json::DocEncode(ar,indent);
}
return "";
}
static TObject JsonDeserialize(GCList& ls2,JToken json)
{
if(std::holds_alternative<JUndefined>(json)) return nullptr;
if(std::holds_alternative<std::nullptr_t>(json)) return nullptr;
bool b;
int64_t _i64;
double _f64;
std::string str;
JArray arr;
JObject obj;
if(TryGetJToken(json,b)) return b;
if(TryGetJToken(json,_i64)) return _i64;
if(TryGetJToken(json,_f64)) return _f64;
if(TryGetJToken(json,str)) return str;
if(TryGetJToken(json,arr))
{
TList* ls = TList::Create(ls2);
for(auto& item : arr)
{
auto itemRes = JsonDeserialize(ls2,item);
ls2.GetGC()->BarrierBegin();
ls->Add(itemRes);
ls2.GetGC()->BarrierEnd();
if (ls != nullptr) {
JArray items;
for (int64_t i = 0; i < ls->Count(); i++) {
auto val = ls->Get(i);
if (IsValidForJson(val))
items.Add(JsonSerialize(val));
}
return ls;
return items;
}
if(TryGetJToken(json,obj))
{
TDictionary* dict = TDictionary::Create(ls2);
for(auto& item : obj)
{
auto itemRes = JsonDeserialize(ls2,item.second);
ls2.GetGC()->BarrierBegin();
dict->SetValue(item.first,itemRes);
ls2.GetGC()->BarrierEnd();
if (dict != nullptr) {
JObject obj;
for (auto item : dict->items) {
if (IsValidForJson(item.second))
obj.SetValue(item.first, JsonSerialize(item.second));
}
return dict;
return obj;
}
return Undefined();
}
static TObject JsonDecode(GCList& ls2,std::vector<TObject> args)
{
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
{
return JsonDeserialize(ls2, Json::Decode(std::get<std::string>(args[0])));
}
return Undefined();
}
static TObject JsonDocDecode(GCList& ls2,std::vector<TObject> args)
{
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
{
return JsonDeserialize(ls2, Json::DocDecode(std::get<std::string>(args[0])));
}
return Undefined();
}
std::string Json_Encode(TObject o,bool indent)
{
return Json::Encode(JsonSerialize(o),indent);
}
TObject Json_Decode(GCList ls,std::string str)
{
return JsonDeserialize(ls,Json::Decode(str));
}
std::string Json_DocEncode(TObject o,bool indent)
{
auto obj = JsonSerialize(o);
JArray ls;
if(TryGetJToken(obj,ls))
return Json::DocEncode(ls,indent);
return "";
}
TObject Json_DocDecode(GCList ls,std::string str)
{
return JsonDeserialize(ls,Json::DocDecode(str));
}
void TStd::RegisterJson(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
return nullptr;
}
static TObject JsonEncode(GCList &ls2, std::vector<TObject> args) {
if (args.size() >= 1) {
bool indent =
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
std::get<bool>(args[1]));
env->permissions.canRegisterJSON=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "Decode","Deserialize Json",{"jsonString"},JsonDecode);
dict->DeclareFunction(gc, "Encode","Serialize Json",{"any","$indent"},JsonEncode);
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc", {"jsonDocString"},JsonDocDecode);
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc", {"ls","$indent"},JsonDocEncode);
gc->BarrierBegin();
env->DeclareVariable("Json", dict);
gc->BarrierEnd();
auto json = JsonSerialize(args[0]);
return Json::Encode(json, indent);
}
}
return "null";
}
static TObject JsonDocEncode(GCList &ls2, std::vector<TObject> args) {
if (args.size() >= 1) {
bool indent =
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
std::get<bool>(args[1]));
auto json = JsonSerialize(args[0]);
JArray ar;
if (TryGetJToken(json, ar))
return Json::DocEncode(ar, indent);
}
return "";
}
static TObject JsonDeserialize(GCList &ls2, JToken json) {
if (std::holds_alternative<JUndefined>(json))
return nullptr;
if (std::holds_alternative<std::nullptr_t>(json))
return nullptr;
bool b;
int64_t _i64;
double _f64;
std::string str;
JArray arr;
JObject obj;
if (TryGetJToken(json, b))
return b;
if (TryGetJToken(json, _i64))
return _i64;
if (TryGetJToken(json, _f64))
return _f64;
if (TryGetJToken(json, str))
return str;
if (TryGetJToken(json, arr)) {
TList *ls = TList::Create(ls2);
for (auto &item : arr) {
auto itemRes = JsonDeserialize(ls2, item);
ls2.GetGC()->BarrierBegin();
ls->Add(itemRes);
ls2.GetGC()->BarrierEnd();
}
return ls;
}
if (TryGetJToken(json, obj)) {
TDictionary *dict = TDictionary::Create(ls2);
for (auto &item : obj) {
auto itemRes = JsonDeserialize(ls2, item.second);
ls2.GetGC()->BarrierBegin();
dict->SetValue(item.first, itemRes);
ls2.GetGC()->BarrierEnd();
}
return dict;
}
return Undefined();
}
static TObject JsonDecode(GCList &ls2, std::vector<TObject> args) {
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
return JsonDeserialize(ls2,
Json::Decode(std::get<std::string>(args[0])));
}
return Undefined();
}
static TObject JsonDocDecode(GCList &ls2, std::vector<TObject> args) {
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
return JsonDeserialize(ls2,
Json::DocDecode(std::get<std::string>(args[0])));
}
return Undefined();
}
std::string Json_Encode(TObject o, bool indent) {
return Json::Encode(JsonSerialize(o), indent);
}
TObject Json_Decode(GCList ls, std::string str) {
return JsonDeserialize(ls, Json::Decode(str));
}
std::string Json_DocEncode(TObject o, bool indent) {
auto obj = JsonSerialize(o);
JArray ls;
if (TryGetJToken(obj, ls))
return Json::DocEncode(ls, indent);
return "";
}
TObject Json_DocDecode(GCList ls, std::string str) {
return JsonDeserialize(ls, Json::DocDecode(str));
}
void TStd::RegisterJson(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterJSON = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "Decode", "Deserialize Json", {"jsonString"},
JsonDecode);
dict->DeclareFunction(gc, "Encode", "Serialize Json", {"any", "$indent"},
JsonEncode);
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc",
{"jsonDocString"}, JsonDocDecode);
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc",
{"ls", "$indent"}, JsonDocEncode);
gc->BarrierBegin();
env->DeclareVariable("Json", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

File diff suppressed because it is too large Load Diff

View File

@@ -1,84 +1,75 @@
#include "CrossLang.hpp"
#if defined(GEKKO)
#include <ogcsys.h>
#include <gccore.h>
#include <ogc/pad.h>
#include <ogcsys.h>
#if defined(HW_RVL)
#include <wiiuse/wpad.h>
#endif
#endif
namespace Tesses::CrossLang
{
#if defined(GEKKO)
#if defined(HW_RVL)
static TObject OGC_WPAD_ScanPads(GCList& ls, std::vector<TObject> args)
{
return (int64_t)WPAD_ScanPads();
}
static TObject OGC_WPAD_ButtonsUp(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
namespace Tesses::CrossLang {
#if defined(GEKKO)
#if defined(HW_RVL)
static TObject OGC_WPAD_ScanPads(GCList &ls, std::vector<TObject> args) {
return (int64_t)WPAD_ScanPads();
}
static TObject OGC_WPAD_ButtonsUp(GCList &ls, std::vector<TObject> args) {
int64_t chan;
if (GetArgument(args, 0, chan))
return (int64_t)WPAD_ButtonsUp((int)chan);
return 0;
}
static TObject OGC_WPAD_ButtonsDown(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return 0;
}
static TObject OGC_WPAD_ButtonsDown(GCList &ls, std::vector<TObject> args) {
int64_t chan;
if (GetArgument(args, 0, chan))
return (int64_t)WPAD_ButtonsDown((int)chan);
return 0;
}
static TObject OGC_WPAD_ButtonsHeld(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return 0;
}
static TObject OGC_WPAD_ButtonsHeld(GCList &ls, std::vector<TObject> args) {
int64_t chan;
if (GetArgument(args, 0, chan))
return (int64_t)WPAD_ButtonsDown((int)chan);
return 0;
}
static TObject OGC_WPAD_BatteryLevel(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return 0;
}
static TObject OGC_WPAD_BatteryLevel(GCList &ls, std::vector<TObject> args) {
int64_t chan;
if (GetArgument(args, 0, chan))
return (int64_t)WPAD_BatteryLevel((int)chan);
return 0;
}
#endif
#endif
void TStd::RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
GCList ls(gc);
#if defined(GEKKO)
gc->BarrierBegin();
return 0;
}
#endif
#endif
void TStd::RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment *env) {
GCList ls(gc);
#if defined(GEKKO)
TDictionary* dict_ogc_pad = TDictionary::Create(ls);
#if defined(HW_RVL)
TDictionary* dict_rvl_wpad = TDictionary::Create(ls);
dict_rvl_wpad->DeclareFunction(gc, "ScanPads","Scan wiimotes",{},OGC_WPAD_ScanPads);
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown","Is button down",{"pad"},OGC_WPAD_ButtonsDown);
dict_rvl_wpad->SetValue("BUTTON_A",(int64_t)WPAD_BUTTON_A);
dict_rvl_wpad->SetValue("BUTTON_B",(int64_t)WPAD_BUTTON_B);
dict_rvl_wpad->SetValue("BUTTON_HOME",(int64_t)WPAD_BUTTON_HOME);
dict_rvl_wpad->SetValue("BUTTON_UP",(int64_t)WPAD_BUTTON_UP);
dict_rvl_wpad->SetValue("BUTTON_DOWN",(int64_t)WPAD_BUTTON_DOWN);
dict_rvl_wpad->SetValue("BUTTON_LEFT",(int64_t)WPAD_BUTTON_LEFT);
dict_rvl_wpad->SetValue("BUTTON_RIGHT",(int64_t)WPAD_BUTTON_RIGHT);
dict_rvl_wpad->SetValue("BUTTON_1",(int64_t)WPAD_BUTTON_1);
dict_rvl_wpad->SetValue("BUTTON_2",(int64_t)WPAD_BUTTON_2);
dict_rvl_wpad->SetValue("BUTTON_PLUS",(int64_t)WPAD_BUTTON_PLUS);
dict_rvl_wpad->SetValue("BUTTON_MINUS",(int64_t)WPAD_BUTTON_MINUS);
env->DeclareVariable("WPAD", dict_rvl_wpad);
#endif
env->DeclareVariable("PAD", dict_ogc_pad);
gc->BarrierEnd();
#endif
env->permissions.canRegisterOGC=true;
gc->BarrierBegin();
}
}
TDictionary *dict_ogc_pad = TDictionary::Create(ls);
#if defined(HW_RVL)
TDictionary *dict_rvl_wpad = TDictionary::Create(ls);
dict_rvl_wpad->DeclareFunction(gc, "ScanPads", "Scan wiimotes", {},
OGC_WPAD_ScanPads);
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown", "Is button down", {"pad"},
OGC_WPAD_ButtonsDown);
dict_rvl_wpad->SetValue("BUTTON_A", (int64_t)WPAD_BUTTON_A);
dict_rvl_wpad->SetValue("BUTTON_B", (int64_t)WPAD_BUTTON_B);
dict_rvl_wpad->SetValue("BUTTON_HOME", (int64_t)WPAD_BUTTON_HOME);
dict_rvl_wpad->SetValue("BUTTON_UP", (int64_t)WPAD_BUTTON_UP);
dict_rvl_wpad->SetValue("BUTTON_DOWN", (int64_t)WPAD_BUTTON_DOWN);
dict_rvl_wpad->SetValue("BUTTON_LEFT", (int64_t)WPAD_BUTTON_LEFT);
dict_rvl_wpad->SetValue("BUTTON_RIGHT", (int64_t)WPAD_BUTTON_RIGHT);
dict_rvl_wpad->SetValue("BUTTON_1", (int64_t)WPAD_BUTTON_1);
dict_rvl_wpad->SetValue("BUTTON_2", (int64_t)WPAD_BUTTON_2);
dict_rvl_wpad->SetValue("BUTTON_PLUS", (int64_t)WPAD_BUTTON_PLUS);
dict_rvl_wpad->SetValue("BUTTON_MINUS", (int64_t)WPAD_BUTTON_MINUS);
env->DeclareVariable("WPAD", dict_rvl_wpad);
#endif
env->DeclareVariable("PAD", dict_ogc_pad);
gc->BarrierEnd();
#endif
env->permissions.canRegisterOGC = true;
}
} // namespace Tesses::CrossLang

View File

@@ -1,83 +1,76 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
bool GetObjectAsPath(TObject& obj, Tesses::Framework::Filesystem::VFSPath& path, bool allowString)
{
if(GetObject(obj,path)) return true;
std::string str;
if(allowString && GetObject<std::string>(obj,str))
{
path = Tesses::Framework::Filesystem::VFSPath(str);
return true;
}
return false;
namespace Tesses::CrossLang {
bool GetObjectAsPath(TObject &obj, Tesses::Framework::Filesystem::VFSPath &path,
bool allowString) {
if (GetObject(obj, path))
return true;
std::string str;
if (allowString && GetObject<std::string>(obj, str)) {
path = Tesses::Framework::Filesystem::VFSPath(str);
return true;
}
bool GetArgumentAsPath(std::vector<TObject>& args, size_t index, Tesses::Framework::Filesystem::VFSPath& path,bool allowString)
{
if(GetArgument(args,index,path)) return true;
std::string str;
if(allowString && GetArgument<std::string>(args,index,str))
{
path = Tesses::Framework::Filesystem::VFSPath(str);
return true;
}
return false;
return false;
}
bool GetArgumentAsPath(std::vector<TObject> &args, size_t index,
Tesses::Framework::Filesystem::VFSPath &path,
bool allowString) {
if (GetArgument(args, index, path))
return true;
std::string str;
if (allowString && GetArgument<std::string>(args, index, str)) {
path = Tesses::Framework::Filesystem::VFSPath(str);
return true;
}
static TObject Path_Root(GCList& ls, std::vector<TObject> args)
{
auto res = Tesses::Framework::Filesystem::VFSPath();\
res.relative=false;
return false;
}
static TObject Path_Root(GCList &ls, std::vector<TObject> args) {
auto res = Tesses::Framework::Filesystem::VFSPath();
res.relative = false;
return res;
}
static TObject Path_FromString(GCList &ls, std::vector<TObject> args) {
std::string str;
if (GetArgument(args, 0, str)) {
return Tesses::Framework::Filesystem::VFSPath(str);
}
return nullptr;
}
static TObject Path_Create(GCList &ls, std::vector<TObject> args) {
TList *myls;
bool relative;
if (GetArgument(args, 0, relative) && GetArgumentHeap(args, 1, myls)) {
std::vector<std::string> items;
for (int64_t i = 0; i < myls->Count(); i++) {
std::string str;
TObject o = myls->Get(i);
if (GetObject<std::string>(o, str)) {
items.push_back(str);
}
}
auto res = Tesses::Framework::Filesystem::VFSPath(items);
res.relative = relative;
return res;
}
static TObject Path_FromString(GCList& ls, std::vector<TObject> args)
{
std::string str;
if(GetArgument(args,0,str))
{
return Tesses::Framework::Filesystem::VFSPath(str);
}
return nullptr;
}
static TObject Path_Create(GCList& ls, std::vector<TObject> args)
{
TList* myls;
bool relative;
if(GetArgument(args,0,relative) && GetArgumentHeap(args,1,myls))
{
std::vector<std::string> items;
for(int64_t i = 0; i < myls->Count(); i++)
{
std::string str;
TObject o =myls->Get(i);
if(GetObject<std::string>(o,str))
{
items.push_back(str);
}
}
auto res = Tesses::Framework::Filesystem::VFSPath(items);
res.relative = relative;
return res;
}
return nullptr;
}
void TStd::RegisterPath(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
return nullptr;
}
void TStd::RegisterPath(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterPath=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
gc->BarrierBegin();
dict->DeclareFunction(gc,"FromString","Create a Path from string",{"path"},Path_FromString);
dict->DeclareFunction(gc,"Create","Create a Path from parts",{"relative","parts"},Path_Create);
dict->DeclareFunction(gc,"Root","Create Absolute Root Path",{}, Path_Root);
env->DeclareVariable("Path", dict);
gc->BarrierEnd();
}
}
env->permissions.canRegisterPath = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
gc->BarrierBegin();
dict->DeclareFunction(gc, "FromString", "Create a Path from string",
{"path"}, Path_FromString);
dict->DeclareFunction(gc, "Create", "Create a Path from parts",
{"relative", "parts"}, Path_Create);
dict->DeclareFunction(gc, "Root", "Create Absolute Root Path", {},
Path_Root);
env->DeclareVariable("Path", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -1,321 +1,295 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
class ProcessObject : public TNativeObject {
public:
ProcessObject() {
arguments = nullptr;
environment = nullptr;
}
ProcessObject(GCList &ls) {
arguments = TList::Create(ls);
environment = TList::Create(ls);
process.includeThisEnv = true;
process.redirectStdIn = false;
process.redirectStdOut = false;
namespace Tesses::CrossLang
{
class ProcessObject : public TNativeObject {
public:
ProcessObject()
{
arguments=nullptr;
environment=nullptr;
}
ProcessObject(GCList& ls)
{
arguments = TList::Create(ls);
environment = TList::Create(ls);
process.includeThisEnv=true;
process.redirectStdIn=false;
process.redirectStdOut=false;
process.redirectStdErr=false;
}
TList* arguments;
TList* environment;
Tesses::Framework::Platform::Process process;
std::string TypeName()
{
return "Process";
}
void Mark()
{
if(this->marked) return;
this->marked=true;
if(arguments != nullptr) arguments->Mark();
if(environment != nullptr) environment->Mark();
}
TObject CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
{
if(key == "setFileName" && GetArgument(args,0,process.name))
{
return process.name;
}
if(key == "getFileName")
{
return process.name;
}
if(key == "setRedirectStandardInput" && GetArgument(args,0,process.redirectStdIn))
{
return process.redirectStdIn;
}
if(key == "getRedirectStandardInput")
{
return process.redirectStdIn;
}
if(key == "setRedirectStandardOutput" && GetArgument(args,0,process.redirectStdOut))
{
return process.redirectStdOut;
}
if(key == "getRedirectStandardOutput")
{
return process.redirectStdOut;
}
if(key == "setRedirectStandardError" && GetArgument(args,0,process.redirectStdErr))
{
return process.redirectStdErr;
}
if(key == "getRedirectStandardError")
{
return process.redirectStdErr;
}
if(key == "setWorkingDirectory" && GetArgument(args,0,process.workingDirectory))
{
return process.workingDirectory;
}
if(key == "getWorkingDirectory")
{
return process.workingDirectory;
}
if(key == "setInheritParentEnvironment" && GetArgument(args,0,process.includeThisEnv))
{
return process.includeThisEnv;
}
if(key == "getInheritParentEnvironment")
{
return process.includeThisEnv;
}
if(key == "getArguments")
{
if(arguments == nullptr) return nullptr;
return arguments;
}
if(key == "setArguments")
{
if(GetArgumentHeap(args,0,arguments))
{
return arguments;
}
}
if(key == "getEnvironment")
{
if(environment == nullptr) return nullptr;
return environment;
}
if(key == "getEnvironment")
{
if(GetArgumentHeap(args,0,environment))
{
return environment;
}
}
if(key == "Start")
{
this->process.args.push_back(process.name);
if(arguments != nullptr)
{
for(int64_t i = 0; i < arguments->Count(); i++)
{
TObject argVal=arguments->Get(i);
std::string argValStr;
if(GetObject(argVal,argValStr))
this->process.args.push_back(argValStr);
}
}
if(environment != nullptr)
{
for(int64_t i = 0; i < environment->Count(); i++)
{
TObject arg = environment->Get(i);
std::string argstr;
if(GetObject(arg,argstr))
{
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
if(kvp.size()==2)
{
process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
}
else if(kvp.size()==1)
{
process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
}
}
}
}
return process.Start();
}
if(key == "Join" || key == "WaitForExit")
{
return (int64_t)process.WaitForExit();
}
if(key == "getHasExited")
{
return process.HasExited();
}
if(key == "Terminate")
{
process.Kill(SIGTERM);
}
if(key == "CloseStdInNow")
{
process.CloseStdInNow();
}
int64_t k;
if(key == "Kill" && GetArgument(args,0,k))
{
process.Kill((int)k);
}
if(key == "getStandardInput")
{
return process.GetStdinStream();
}
if(key == "getStandardOutput")
{
return process.GetStdoutStream();
}
if(key == "getStandardError")
{
return process.GetStderrStream();
}
return Undefined();
}
};
static TObject Process_Start(GCList& ls, std::vector<TObject> args, TRootEnvironment* env)
{
//Process.Start({
// FileName = "git",
// Arguments = ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
// Environment = [],
// InheritParentEnvironment=true
//})
TDictionary* dict;
if(GetArgumentHeap(args,0,dict))
{
auto process = TNativeObject::Create<ProcessObject>(ls);
auto name = dict->GetValue("FileName");
auto inh = dict->GetValue("InheritParentEnvironment");
auto rStdIn = dict->GetValue("RedirectStandardInput");
auto rStdOut = dict->GetValue("RedirectStandardOutput");
auto rStdErr = dict->GetValue("RedirectStandardError");
auto workingDirectory = dict->GetValue("WorkingDirectory");
process->process.includeThisEnv=true;
process->process.redirectStdIn=false;
process->process.redirectStdOut=false;
process->process.redirectStdErr=false;
GetObject(inh,process->process.includeThisEnv);
GetObject(rStdIn,process->process.redirectStdIn);
GetObject(rStdOut,process->process.redirectStdOut);
GetObject(rStdErr,process->process.redirectStdErr);
GetObject(name,process->process.name);
Tesses::Framework::Filesystem::VFSPath wdPath;
if(env->permissions.localfs)
{
process->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
}
if(GetObject(workingDirectory,wdPath))
{
process->process.workingDirectory= wdPath.MakeAbsolute().ToString();
}
GetObject(workingDirectory,process->process.workingDirectory);
process->process.args.push_back(process->process.name);
auto argumentsO = dict->GetValue("Arguments");
TList* arguments;
if(GetObjectHeap(argumentsO,arguments))
{
for(int64_t i = 0; i < arguments->Count(); i++)
{
TObject arg = arguments->Get(i);
std::string argstr;
if(GetObject(arg,argstr))
{
process->process.args.push_back(argstr);
}
}
}
argumentsO = dict->GetValue("Environment");
if(GetObjectHeap(argumentsO,arguments))
{
for(int64_t i = 0; i < arguments->Count(); i++)
{
TObject arg = arguments->Get(i);
std::string argstr;
if(GetObject(arg,argstr))
{
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
if(kvp.size()==2)
{
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
}
else if(kvp.size()==1)
{
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
}
}
}
}
if(process->process.Start())
{
return process;
}
process.redirectStdErr = false;
}
TList *arguments;
TList *environment;
Tesses::Framework::Platform::Process process;
std::string TypeName() { return "Process"; }
void Mark() {
if (this->marked)
return;
this->marked = true;
if (arguments != nullptr)
arguments->Mark();
if (environment != nullptr)
environment->Mark();
}
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args) {
if (key == "setFileName" && GetArgument(args, 0, process.name)) {
return process.name;
}
if (key == "getFileName") {
return process.name;
}
return nullptr;
}
void TStd::RegisterProcess(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterProcess=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
gc->BarrierBegin();
auto processStart = TExternalMethod::Create(ls,"Start a process",{"process_object"},[env](GCList& ls, std::vector<TObject> args)->TObject{
return Process_Start(ls,args,env);
});
processStart->watch.push_back(env);
dict->SetValue("Start",processStart);
env->SetVariable("Process",dict);
auto process = env->EnsureDictionary(gc,"New");
auto newProcess = TExternalMethod::Create(ls, "Create process",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
auto obj= TNativeObject::Create<ProcessObject>(ls,ls);
if(env->permissions.localfs)
{
obj->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
if (key == "setRedirectStandardInput" &&
GetArgument(args, 0, process.redirectStdIn)) {
return process.redirectStdIn;
}
if (key == "getRedirectStandardInput") {
return process.redirectStdIn;
}
if (key == "setRedirectStandardOutput" &&
GetArgument(args, 0, process.redirectStdOut)) {
return process.redirectStdOut;
}
if (key == "getRedirectStandardOutput") {
return process.redirectStdOut;
}
if (key == "setRedirectStandardError" &&
GetArgument(args, 0, process.redirectStdErr)) {
return process.redirectStdErr;
}
if (key == "getRedirectStandardError") {
return process.redirectStdErr;
}
if (key == "setWorkingDirectory" &&
GetArgument(args, 0, process.workingDirectory)) {
return process.workingDirectory;
}
if (key == "getWorkingDirectory") {
return process.workingDirectory;
}
if (key == "setInheritParentEnvironment" &&
GetArgument(args, 0, process.includeThisEnv)) {
return process.includeThisEnv;
}
if (key == "getInheritParentEnvironment") {
return process.includeThisEnv;
}
if (key == "getArguments") {
if (arguments == nullptr)
return nullptr;
return arguments;
}
if (key == "setArguments") {
if (GetArgumentHeap(args, 0, arguments)) {
return arguments;
}
return obj;
}
if (key == "getEnvironment") {
if (environment == nullptr)
return nullptr;
return environment;
}
if (key == "getEnvironment") {
if (GetArgumentHeap(args, 0, environment)) {
return environment;
}
}
if (key == "Start") {
this->process.args.push_back(process.name);
if (arguments != nullptr) {
for (int64_t i = 0; i < arguments->Count(); i++) {
TObject argVal = arguments->Get(i);
std::string argValStr;
if (GetObject(argVal, argValStr))
this->process.args.push_back(argValStr);
}
}
if (environment != nullptr) {
for (int64_t i = 0; i < environment->Count(); i++) {
TObject arg = environment->Get(i);
std::string argstr;
if (GetObject(arg, argstr)) {
auto kvp =
Tesses::Framework::Http::HttpUtils::SplitString(
argstr, "=", 2);
if (kvp.size() == 2) {
process.env.push_back(
std::pair<std::string, std::string>(kvp[0],
kvp[1]));
} else if (kvp.size() == 1) {
process.env.push_back(
std::pair<std::string, std::string>(kvp[0],
""));
}
}
}
}
return process.Start();
}
if (key == "Join" || key == "WaitForExit") {
return (int64_t)process.WaitForExit();
}
if (key == "getHasExited") {
return process.HasExited();
}
if (key == "Terminate") {
process.Kill(SIGTERM);
}
if (key == "CloseStdInNow") {
process.CloseStdInNow();
}
int64_t k;
if (key == "Kill" && GetArgument(args, 0, k)) {
process.Kill((int)k);
}
if (key == "getStandardInput") {
return process.GetStdinStream();
}
if (key == "getStandardOutput") {
return process.GetStdoutStream();
}
if (key == "getStandardError") {
return process.GetStderrStream();
}
return Undefined();
}
};
static TObject Process_Start(GCList &ls, std::vector<TObject> args,
TRootEnvironment *env) {
// Process.Start({
// FileName = "git",
// Arguments =
// ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
// Environment = [],
// InheritParentEnvironment=true
// })
TDictionary *dict;
if (GetArgumentHeap(args, 0, dict)) {
auto process = TNativeObject::Create<ProcessObject>(ls);
auto name = dict->GetValue("FileName");
auto inh = dict->GetValue("InheritParentEnvironment");
auto rStdIn = dict->GetValue("RedirectStandardInput");
auto rStdOut = dict->GetValue("RedirectStandardOutput");
auto rStdErr = dict->GetValue("RedirectStandardError");
auto workingDirectory = dict->GetValue("WorkingDirectory");
process->process.includeThisEnv = true;
process->process.redirectStdIn = false;
process->process.redirectStdOut = false;
process->process.redirectStdErr = false;
GetObject(inh, process->process.includeThisEnv);
GetObject(rStdIn, process->process.redirectStdIn);
GetObject(rStdOut, process->process.redirectStdOut);
GetObject(rStdErr, process->process.redirectStdErr);
GetObject(name, process->process.name);
Tesses::Framework::Filesystem::VFSPath wdPath;
if (env->permissions.localfs) {
process->process.workingDirectory =
env->permissions.localfs->GetWorking().ToString();
}
if (GetObject(workingDirectory, wdPath)) {
process->process.workingDirectory =
wdPath.MakeAbsolute().ToString();
}
GetObject(workingDirectory, process->process.workingDirectory);
process->process.args.push_back(process->process.name);
auto argumentsO = dict->GetValue("Arguments");
TList *arguments;
if (GetObjectHeap(argumentsO, arguments)) {
for (int64_t i = 0; i < arguments->Count(); i++) {
TObject arg = arguments->Get(i);
std::string argstr;
if (GetObject(arg, argstr)) {
process->process.args.push_back(argstr);
}
}
}
argumentsO = dict->GetValue("Environment");
if (GetObjectHeap(argumentsO, arguments)) {
for (int64_t i = 0; i < arguments->Count(); i++) {
TObject arg = arguments->Get(i);
std::string argstr;
if (GetObject(arg, argstr)) {
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(
argstr, "=", 2);
if (kvp.size() == 2) {
process->process.env.push_back(
std::pair<std::string, std::string>(kvp[0],
kvp[1]));
} else if (kvp.size() == 1) {
process->process.env.push_back(
std::pair<std::string, std::string>(kvp[0], ""));
}
}
}
}
if (process->process.Start()) {
return process;
}
}
return nullptr;
}
void TStd::RegisterProcess(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterProcess = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
gc->BarrierBegin();
auto processStart = TExternalMethod::Create(
ls, "Start a process", {"process_object"},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return Process_Start(ls, args, env);
});
newProcess->watch.push_back(env);
process->SetValue("Process",newProcess);
//process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
process->DeclareFunction(gc, "CGIServer", "Create a CGI Server",{"path"},[](GCList& ls, std::vector<TObject> args)->TObject{
processStart->watch.push_back(env);
dict->SetValue("Start", processStart);
env->SetVariable("Process", dict);
auto process = env->EnsureDictionary(gc, "New");
auto newProcess = TExternalMethod::Create(
ls, "Create process", {},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
auto obj = TNativeObject::Create<ProcessObject>(ls, ls);
if (env->permissions.localfs) {
obj->process.workingDirectory =
env->permissions.localfs->GetWorking().ToString();
}
return obj;
});
newProcess->watch.push_back(env);
process->SetValue("Process", newProcess);
// process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
process->DeclareFunction(
gc, "CGIServer", "Create a CGI Server", {"path"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
return std::make_shared<Tesses::Framework::Http::CGIServer>(path);
if (GetArgumentAsPath(args, 0, path)) {
return std::make_shared<Tesses::Framework::Http::CGIServer>(
path);
}
return Undefined();
});
gc->BarrierEnd();
}
process->DeclareFunction(
gc, "ShellFileOrUrl", "Launch file or url in shell", {"urlOrFilename"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
std::string fileOrUrl;
if (GetArgument(args, 0, fileOrUrl))
Tesses::Framework::Platform::ShellFileOrUrl(fileOrUrl);
return Undefined();
});
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -3,170 +3,192 @@
#include <iostream>
namespace Tesses::CrossLang {
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
using namespace Tesses::Framework::Serialization;
TObject Sqlite_Escape(GCList& ls, std::vector<TObject> args)
{
int64_t n;
double d;
bool b;
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
using namespace Tesses::Framework::Serialization;
TObject Sqlite_Escape(GCList &ls, std::vector<TObject> args) {
int64_t n;
double d;
bool b;
std::string str;
if(GetArgument(args,0,str))
{
return SQLiteDatabase::Escape(str);
}
if(GetArgument(args,0,n))
{
return std::to_string(n);
}
if(GetArgument(args,0,b))
{
return b ? "1" : "0";
}
if(GetArgument(args,0,d))
{
return std::to_string(d);
}
return "NULL";
std::string str;
if (GetArgument(args, 0, str)) {
return SQLiteDatabase::Escape(str);
}
class SQLiteObject : public TNativeObject
{
public:
SQLiteDatabase* db;
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path)
{
db=new SQLiteDatabase(path);
}
std::string TypeName()
{
return "SQLiteDatabase";
}
void Close()
{
if(this->db == nullptr) return;
delete this->db;
this->db = nullptr;
}
bool ToBool()
{
return this->db != nullptr;
}
TObject CallMethod(GCList& ls,std::string name, std::vector<TObject> args)
{
if(name == "Close") this->Close();
if(name == "Escape") {
return Sqlite_Escape(ls,args);
}
if(name == "Exec")
{
std::string arg;
if(GetArgument(args,0,arg))
{
if(this->db == nullptr) return nullptr;
std::vector<std::vector<std::pair<std::string, std::optional<std::string>>>> res;
this->db->Exec(arg,res);
TList* list = TList::Create(ls);
for(auto& item : res)
{
TDictionary* dict = TDictionary::Create(ls);
for(auto& item2 : item)
{
if(item2.second)
dict->SetValue(item2.first,item2.second.value());
else
dict->SetValue(item2.first,nullptr);
}
list->Add(dict);
}
return list;
}
}
return Undefined();
}
~SQLiteObject()
{
if(this->db != nullptr)
delete this->db;
}
};
TObject Sqlite_Open(GCList& ls, std::vector<TObject> args,TRootEnvironment* env)
{
Tesses::Framework::Filesystem::VFSPath p;
if(GetArgumentAsPath(args,0,p))
{
if(env->permissions.sqlite3Scoped)
{
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
}
return TNativeObject::Create<SQLiteObject>(ls,p);
}
return Undefined();
if (GetArgument(args, 0, n)) {
return std::to_string(n);
}
TObject Sqlite_Exec(GCList& ls, std::vector<TObject> args)
{
SQLiteObject* sql;
std::string cmd;
if(GetArgumentHeap(args,0,sql) && GetArgument(args,1,cmd))
{
try {
return sql->CallMethod(ls,"Exec",{cmd});
} catch(std::runtime_error& ex)
{
return (std::string)ex.what();
}
}
return Undefined();
if (GetArgument(args, 0, b)) {
return b ? "1" : "0";
}
if (GetArgument(args, 0, d)) {
return std::to_string(d);
}
TObject Sqlite_Close(GCList& ls, std::vector<TObject> args)
{
SQLiteObject* sql;
if(GetArgumentHeap(args,0,sql))
{
sql->Close();
}
return Undefined();
}
#endif
void TStd::RegisterSqlite(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterSqlite=true;
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc,"Open","Opens the database (returns database handle or an error message as string or undefined)",{"filename"},[env](GCList& ls, std::vector<TObject> args)->TObject {
return Sqlite_Open(ls,args,env);
});
dict->DeclareFunction(gc,"Exec","Execute sql (returns dictionary of columns key=value, an error message as string or undefined)",{"handle","sql"},Sqlite_Exec);
dict->DeclareFunction(gc,"Close","Close sql database",{"handle"},Sqlite_Close);
dict->DeclareFunction(gc,"Escape","Escape sql text",{"text"},Sqlite_Escape);
gc->BarrierBegin();
env->DeclareVariable("Sqlite", dict);
gc->BarrierEnd();
#endif
}
return "NULL";
}
TObject Sqlite_Prepare(GCList &ls, std::vector<TObject> args) {
std::string str;
TList *list;
std::string newStr = "";
if (GetArgument(args, 0, str) && GetArgumentHeap(args, 1, list)) {
int64_t item = 0;
for (size_t i = 0; i < str.size(); i++) {
if (str[i] == '@' && (i + 1 >= str.size() || str[i + 1] != '@')) {
auto v = list->Get(item);
int64_t n;
double d;
bool b;
std::string str;
if (GetObject(v, str)) {
newStr += SQLiteDatabase::Escape(str);
} else if (GetObject(v, n)) {
newStr += std::to_string(n);
} else if (GetObject(v, b)) {
newStr += (b ? "1" : "0");
} else if (GetObject(v, d)) {
newStr += std::to_string(d);
} else {
newStr += "NULL";
}
} else {
newStr += str[i];
}
}
}
return newStr;
}
class SQLiteObject : public TNativeObject {
public:
SQLiteDatabase *db;
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path) {
db = new SQLiteDatabase(path);
}
std::string TypeName() { return "SQLiteDatabase"; }
void Close() {
if (this->db == nullptr)
return;
delete this->db;
this->db = nullptr;
}
bool ToBool() { return this->db != nullptr; }
TObject CallMethod(GCList &ls, std::string name,
std::vector<TObject> args) {
if (name == "Close")
this->Close();
if (name == "Escape") {
return Sqlite_Escape(ls, args);
}
if (name == "Prepare") {
return Sqlite_Prepare(ls, args);
}
if (name == "Exec") {
std::string arg;
if (GetArgument(args, 0, arg)) {
if (this->db == nullptr)
return nullptr;
std::vector<std::vector<
std::pair<std::string, std::optional<std::string>>>>
res;
this->db->Exec(arg, res);
TList *list = TList::Create(ls);
for (auto &item : res) {
TDictionary *dict = TDictionary::Create(ls);
for (auto &item2 : item) {
if (item2.second)
dict->SetValue(item2.first, item2.second.value());
else
dict->SetValue(item2.first, nullptr);
}
list->Add(dict);
}
return list;
}
}
return Undefined();
}
~SQLiteObject() {
if (this->db != nullptr)
delete this->db;
}
};
TObject Sqlite_Open(GCList &ls, std::vector<TObject> args,
TRootEnvironment *env) {
Tesses::Framework::Filesystem::VFSPath p;
if (GetArgumentAsPath(args, 0, p)) {
if (env->permissions.sqlite3Scoped) {
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
}
return TNativeObject::Create<SQLiteObject>(ls, p);
}
return Undefined();
}
TObject Sqlite_Exec(GCList &ls, std::vector<TObject> args) {
SQLiteObject *sql;
std::string cmd;
if (GetArgumentHeap(args, 0, sql) && GetArgument(args, 1, cmd)) {
try {
return sql->CallMethod(ls, "Exec", {cmd});
} catch (std::runtime_error &ex) {
return (std::string)ex.what();
}
}
return Undefined();
}
TObject Sqlite_Close(GCList &ls, std::vector<TObject> args) {
SQLiteObject *sql;
if (GetArgumentHeap(args, 0, sql)) {
sql->Close();
}
return Undefined();
}
#endif
void TStd::RegisterSqlite(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterSqlite = true;
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(
gc, "Open",
"Opens the database (returns database handle or an error message as "
"string or undefined)",
{"filename"}, [env](GCList &ls, std::vector<TObject> args) -> TObject {
return Sqlite_Open(ls, args, env);
});
dict->DeclareFunction(gc, "Exec",
"Execute sql (returns dictionary of columns "
"key=value, an error message as string or undefined)",
{"handle", "sql"}, Sqlite_Exec);
dict->DeclareFunction(gc, "Close", "Close sql database", {"handle"},
Sqlite_Close);
dict->DeclareFunction(gc, "Escape", "Escape sql text", {"text"},
Sqlite_Escape);
dict->DeclareFunction(gc, "Prepare", "Prepare sql", {"sql", "items"},
Sqlite_Prepare);
gc->BarrierBegin();
env->DeclareVariable("Sqlite", dict);
gc->BarrierEnd();
#endif
}
} // namespace Tesses::CrossLang

File diff suppressed because it is too large Load Diff

View File

@@ -1,40 +1,42 @@
#include "TessesFramework/Uuid.hpp"
#include "CrossLang.hpp"
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Uuid.hpp"
namespace Tesses::CrossLang {
static TObject Uuid_NewUuid(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Uuid::Generate();
static TObject Uuid_NewUuid(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Uuid::Generate();
}
static TObject Uuid_TryParse(GCList &ls, std::vector<TObject> args) {
std::string str;
Tesses::Framework::Uuid uuid;
if (GetArgument(args, 0, str) &&
Tesses::Framework::Uuid::TryParse(str, uuid))
return uuid;
return nullptr;
}
static TObject Uuid_FromBytes(GCList &ls, std::vector<TObject> args) {
TByteArray *ba;
int64_t index;
if (GetArgumentHeap(args, 0, ba) && GetArgument(args, 1, index) &&
(size_t)index < ba->data.size() &&
(size_t)index + 16 <= ba->data.size()) {
return Tesses::Framework::Serialization::BitConverter::ToUuid(
ba->data[(size_t)index]);
}
static TObject Uuid_TryParse(GCList& ls, std::vector<TObject> args)
{
std::string str;
Tesses::Framework::Uuid uuid;
if(GetArgument(args, 0, str) && Tesses::Framework::Uuid::TryParse(str,uuid))
return uuid;
return nullptr;
}
static TObject Uuid_FromBytes(GCList& ls, std::vector<TObject> args)
{
TByteArray* ba;
int64_t index;
if(GetArgumentHeap(args,0,ba) && GetArgument(args, 1, index) && (size_t)index < ba->data.size() && (size_t)index + 16 <= ba->data.size())
{
return Tesses::Framework::Serialization::BitConverter::ToUuid(ba->data[(size_t)index]);
}
return nullptr;
}
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
gc->BarrierBegin();
TDictionary* guid = env->EnsureDictionary(gc, "Uuid");
guid->DeclareFunction(gc,"NewUuid","Create random uuid",{},Uuid_NewUuid);
guid->DeclareFunction(gc, "TryParse","Try to parse",{"str"}, Uuid_TryParse);
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",{"byteArray","offset"}, Uuid_FromBytes);
gc->BarrierEnd();
}
}
return nullptr;
}
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment *env) {
gc->BarrierBegin();
TDictionary *guid = env->EnsureDictionary(gc, "Uuid");
guid->DeclareFunction(gc, "NewUuid", "Create random uuid", {},
Uuid_NewUuid);
guid->DeclareFunction(gc, "TryParse", "Try to parse", {"str"},
Uuid_TryParse);
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",
{"byteArray", "offset"}, Uuid_FromBytes);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -1,123 +1,104 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <iostream>
#include <sstream>
namespace Tesses::CrossLang
{
namespace Tesses::CrossLang {
static TObject AstToTObject(GCList& ls,SyntaxNode node)
{
if(std::holds_alternative<std::nullptr_t>(node))
static TObject AstToTObject(GCList &ls, SyntaxNode node) {
if (std::holds_alternative<std::nullptr_t>(node))
return nullptr;
if(std::holds_alternative<int64_t>(node))
{
if (std::holds_alternative<int64_t>(node)) {
return std::get<int64_t>(node);
}
if(std::holds_alternative<double>(node))
{
if (std::holds_alternative<double>(node)) {
return std::get<double>(node);
}
if(std::holds_alternative<bool>(node))
{
if (std::holds_alternative<bool>(node)) {
return std::get<bool>(node);
}
if(std::holds_alternative<std::string>(node))
{
if (std::holds_alternative<std::string>(node)) {
std::string str = std::get<std::string>(node);
return str;
}
if(std::holds_alternative<char>(node))
{
if (std::holds_alternative<char>(node)) {
char c = std::get<char>(node);
return c;
}
if(std::holds_alternative<Undefined>(node))
{
if (std::holds_alternative<Undefined>(node)) {
auto r = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
r->SetValue("Type",std::string(UndefinedExpression));
r->SetValue("Type", std::string(UndefinedExpression));
ls.GetGC()->BarrierEnd();
return r;
}
if(std::holds_alternative<AdvancedSyntaxNode>(node))
{
if (std::holds_alternative<AdvancedSyntaxNode>(node)) {
auto asn = std::get<AdvancedSyntaxNode>(node);
auto r = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
r->SetValue("Type",asn.nodeName);
r->SetValue("IsExpression",asn.isExpression);
TList* ls2 = TList::Create(ls);
for(auto item : asn.nodes)
{
ls2->Add(AstToTObject(ls,item));
r->SetValue("Type", asn.nodeName);
r->SetValue("IsExpression", asn.isExpression);
TList *ls2 = TList::Create(ls);
for (auto item : asn.nodes) {
ls2->Add(AstToTObject(ls, item));
}
r->SetValue("Arguments", ls2);
ls.GetGC()->BarrierEnd();
return r;
}
return nullptr;
}
static TObject VM_SourceToAst(GCList& ls, std::vector<TObject> args)
{
std::string str;
if(GetArgument(args,0,str))
{
std::stringstream strm(str);
std::vector<LexToken> tokens;
int res = Lex("memory.tcross",strm,tokens);
if(res != 0)
{
throw VMException("Lex error at line: " + std::to_string(res));
}
Parser p(tokens);
auto res2 =p.ParseRoot();
return AstToTObject(ls,res2);
return nullptr;
}
static TObject VM_SourceToAst(GCList &ls, std::vector<TObject> args) {
std::string str;
if (GetArgument(args, 0, str)) {
std::stringstream strm(str);
std::vector<LexToken> tokens;
int res = Lex("memory.tcross", strm, tokens);
if (res != 0) {
throw VMException("Lex error at line: " + std::to_string(res));
}
return nullptr;
Parser p(tokens);
auto res2 = p.ParseRoot();
return AstToTObject(ls, res2);
}
static TObject VM_Eval(GCList& ls, std::vector<TObject> args)
{
std::string str;
if(GetArgument(args,0,str))
{
if(current_function != nullptr)
{
return current_function->env->Eval(ls,str);
}
return nullptr;
}
static TObject VM_Eval(GCList &ls, std::vector<TObject> args) {
std::string str;
if (GetArgument(args, 0, str)) {
if (current_function != nullptr) {
return current_function->env->Eval(ls, str);
}
return nullptr;
}
static TObject Failure(GCList& ls, std::string reason)
{
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Success",false);
dict->SetValue("Reason", reason);
ls.GetGC()->BarrierEnd();
return dict;
}
static TObject Success(GCList& ls)
{
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Success",true);
ls.GetGC()->BarrierEnd();
return dict;
}
static TObject VM_getCurrentEnvironment(GCList& ls2,std::vector<TObject> args)
{
if(current_function != nullptr) return current_function->env;
return Undefined();
}
static TObject VM_Compile(GCList& ls, std::vector<TObject> args)
{
try {
TDictionary* dict;
if(!GetArgumentHeap<TDictionary*>(args,0,dict)) return Undefined();
return nullptr;
}
static TObject Failure(GCList &ls, std::string reason) {
TDictionary *dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Success", false);
dict->SetValue("Reason", reason);
ls.GetGC()->BarrierEnd();
return dict;
}
static TObject Success(GCList &ls) {
TDictionary *dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Success", true);
ls.GetGC()->BarrierEnd();
return dict;
}
static TObject VM_getCurrentEnvironment(GCList &ls2,
std::vector<TObject> args) {
if (current_function != nullptr)
return current_function->env;
return Undefined();
}
static TObject VM_Compile(GCList &ls, std::vector<TObject> args) {
try {
TDictionary *dict;
if (!GetArgumentHeap<TDictionary *>(args, 0, dict))
return Undefined();
/*
VM.Compile
{
@@ -127,18 +108,20 @@ namespace Tesses::CrossLang
Version = "",
Dependencies = [{Name="Name", Version}],
ResourceDirectory = "",
}
}
*/
std::string name = "Out";
std::vector<std::pair<std::string,std::string>> sources;
TVMVersion version(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
std::vector<std::pair<std::string,TVMVersion>> dependencies;
std::vector<std::pair<std::string,TVMVersion>> tools;
std::vector<std::pair<std::string, std::string>> sources;
TVMVersion version(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
CROSSLANG_BYTECODE_VERSIONSTAGE);
std::vector<std::pair<std::string, TVMVersion>> dependencies;
std::vector<std::pair<std::string, TVMVersion>> tools;
std::string info;
std::string icon;
bool debug=false;
bool debug = false;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
ls.GetGC()->BarrierBegin();
@@ -151,116 +134,110 @@ namespace Tesses::CrossLang
TObject _icon = dict->GetValue("Icon");
TObject _comptime = dict->GetValue("CompTime");
TObject _resourceFileSystem = dict->GetValue("ResourceFileSystem");
TObject _out = dict->GetValue("Output");
TObject _dbg = dict->GetValue("Debug");
TList* _toolList;
TList* _depList; TList* srcLst;
TRootEnvironment* comptimeEnv=nullptr;
GetObject<std::string>(_name,name);
GetObject<std::string>(_info,info);
GetObject<std::string>(_icon,icon);
TList *_toolList;
TList *_depList;
TList *srcLst;
TRootEnvironment *comptimeEnv = nullptr;
GetObject<std::string>(_name, name);
GetObject<std::string>(_info, info);
GetObject<std::string>(_icon, icon);
GetObject(_resourceFileSystem, vfs);
GetObjectHeap(_comptime,comptimeEnv);
GetObject(_dbg,debug);
GetObjectHeap(_comptime, comptimeEnv);
GetObject(_dbg, debug);
std::string v2;
if(GetObject<std::string>(_version,v2))
if (GetObject<std::string>(_version, v2))
TVMVersion::TryParse(v2, version);
else
GetObject(_version,version);
GetObject(_version, version);
if(GetObjectHeap<TList*>(_dependencies,_depList))
{
for(int64_t i = 0; i < _depList->Count(); i++)
{
if (GetObjectHeap<TList *>(_dependencies, _depList)) {
for (int64_t i = 0; i < _depList->Count(); i++) {
TObject _dep = _depList->Get(i);
TDictionary* _depD;
if(GetObjectHeap<TDictionary*>(_dep, _depD))
{
TDictionary *_depD;
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
TObject _name2 = _depD->GetValue("Name");
TObject _version2 = _depD->GetValue("Version");
std::string name2;
std::string version2;
TVMVersion version02;
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
{
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
}
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
{
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
if (GetObject<std::string>(_name2, name2) &&
GetObject<std::string>(_version2, version2) &&
TVMVersion::TryParse(version2, version02)) {
dependencies.push_back(
std::pair<std::string, TVMVersion>(name2,
version02));
} else if (GetObject<std::string>(_name2, name2) &&
GetObject(_version2, version02)) {
dependencies.push_back(
std::pair<std::string, TVMVersion>(name2,
version02));
}
}
}
}
if(GetObjectHeap<TList*>(_tools,_toolList))
{
for(int64_t i = 0; i < _toolList->Count(); i++)
{
if (GetObjectHeap<TList *>(_tools, _toolList)) {
for (int64_t i = 0; i < _toolList->Count(); i++) {
TObject _dep = _toolList->Get(i);
TDictionary* _depD;
if(GetObjectHeap<TDictionary*>(_dep, _depD))
{
TDictionary *_depD;
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
TObject _name2 = _depD->GetValue("Name");
TObject _version2 = _depD->GetValue("Version");
std::string name2;
std::string version2;
TVMVersion version02;
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
{
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
}
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
{
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
if (GetObject<std::string>(_name2, name2) &&
GetObject<std::string>(_version2, version2) &&
TVMVersion::TryParse(version2, version02)) {
tools.push_back(std::pair<std::string, TVMVersion>(
name2, version02));
} else if (GetObject<std::string>(_name2, name2) &&
GetObject(_version2, version02)) {
tools.push_back(std::pair<std::string, TVMVersion>(
name2, version02));
}
}
}
}
if(GetObjectHeap<TList*>(_sources,srcLst))
{
for(int64_t i = 0; i < srcLst->Count(); i++)
{
if (GetObjectHeap<TList *>(_sources, srcLst)) {
for (int64_t i = 0; i < srcLst->Count(); i++) {
TObject _src = srcLst->Get(i);
TDictionary* _srcD;
if(GetObjectHeap<TDictionary*>(_src, _srcD))
{
TDictionary *_srcD;
if (GetObjectHeap<TDictionary *>(_src, _srcD)) {
TObject _sourceTxt = _srcD->GetValue("Source");
TObject _filename = _srcD->GetValue("FileName");
std::string srctxt = "";
std::string filename = "memory_" + std::to_string(i) + ".tcross";
std::string filename =
"memory_" + std::to_string(i) + ".tcross";
bool fromFile = false;
GetObject<std::string>(_sourceTxt,srctxt);
GetObject<std::string>(_filename,filename);
sources.push_back(std::pair<std::string,std::string>(srctxt,filename));
GetObject<std::string>(_sourceTxt, srctxt);
GetObject<std::string>(_filename, filename);
sources.push_back(
std::pair<std::string, std::string>(srctxt, filename));
}
}
}
ls.GetGC()->BarrierEnd();
std::vector<LexToken> tokens;
for(auto source : sources)
{
for (auto source : sources) {
std::stringstream strm(source.first);
int res = Lex(source.second, strm, tokens);
if(res != 0)
{
return Failure(ls, "Lex error in file \"" + source.second + "\":" + std::to_string(res));
if (res != 0) {
return Failure(ls, "Lex error in file \"" + source.second +
"\":" + std::to_string(res));
}
}
Parser parser(tokens,ls.GetGC(),comptimeEnv);
Parser parser(tokens, ls.GetGC(), comptimeEnv);
parser.debug = debug;
SyntaxNode n = parser.ParseRoot();
CodeGen gen;
@@ -274,147 +251,136 @@ namespace Tesses::CrossLang
gen.icon = icon;
std::string outpath;
std::shared_ptr<Tesses::Framework::Streams::Stream> stream;
if(GetObject(_out, stream))
{
if (GetObject(_out, stream)) {
gen.Save(stream);
}
return Success(ls);
} catch(std::exception& ex)
{
return Failure(ls, ex.what());
}
} catch (std::exception &ex) {
return Failure(ls, ex.what());
}
static TObject VM_GetStacktrace(GCList& ls, std::vector<TObject> args)
{
if(current_function != nullptr)
{
if(current_function->thread != nullptr)
{
TList* list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto item : current_function->thread->call_stack_entries)
{
auto dict = TDictionary::Create(ls);
if(item->callable->closure->name)
dict->SetValue("Name", *item->callable->closure->name);
dict->SetValue("Closure", item->callable->closure);
dict->SetValue("FileName", item->callable->file->name + "-" + item->callable->file->version.ToString() + ".crvm");
dict->SetValue("IP",(int64_t)item->ip);
if(item->srcline >= 1)
{
dict->SetValue("SourceFile", item->srcfile);
dict->SetValue("SourceLine",item->srcline);
}
list->Add(dict);
}
ls.GetGC()->BarrierEnd();
return list;
}
}
return nullptr;
}
void TStd::RegisterVM(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterVM=true;
GCList ls(gc);
}
static TObject VM_GetStacktrace(GCList &ls, std::vector<TObject> args) {
if (current_function != nullptr) {
if (current_function->thread != nullptr) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto item : current_function->thread->call_stack_entries) {
auto dict = TDictionary::Create(ls);
if (item->callable->closure->name)
dict->SetValue("Name", *item->callable->closure->name);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "GetStacktrace","Get the current stack trace", {}, VM_GetStacktrace);
dict->DeclareFunction(gc, "getRootEnvironmentAsDictionary","Get root environment as a dictionary",{},[env](GCList& ls, std::vector<TObject> args)-> TObject{
dict->SetValue("Closure", item->callable->closure);
dict->SetValue("FileName",
item->callable->file->name + "-" +
item->callable->file->version.ToString() +
".crvm");
dict->SetValue("IP", (int64_t)item->ip);
if (item->srcline >= 1) {
dict->SetValue("SourceFile", item->srcfile);
dict->SetValue("SourceLine", item->srcline);
}
list->Add(dict);
}
ls.GetGC()->BarrierEnd();
return list;
}
}
return nullptr;
}
void TStd::RegisterVM(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterVM = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "GetStacktrace", "Get the current stack trace",
{}, VM_GetStacktrace);
dict->DeclareFunction(
gc, "getRootEnvironmentAsDictionary",
"Get root environment as a dictionary", {},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return env->GetDictionary();
});
dict->DeclareFunction(gc, "getRootEnvironment","Get root environment, for reflection purposes",{},[env](GCList& ls2,std::vector<TObject> args)->TObject {return env;});
dict->DeclareFunction(gc, "getCurrentEnvironment","Get current environment, for reflection purposes",{},VM_getCurrentEnvironment);
dict->DeclareFunction(gc, "CreateEnvironment","Create root environment",{"$dict"},[env](GCList& ls,std::vector<TObject> args)->TObject{
TDictionary* dict;
if(GetArgumentHeap(args,0,dict))
{
auto renv = TRootEnvironment::Create(ls,dict);
renv->permissions.customConsole = env->permissions.customConsole;
dict->DeclareFunction(
gc, "getRootEnvironment",
"Get root environment, for reflection purposes", {},
[env](GCList &ls2, std::vector<TObject> args) -> TObject {
return env;
});
dict->DeclareFunction(gc, "getCurrentEnvironment",
"Get current environment, for reflection purposes",
{}, VM_getCurrentEnvironment);
dict->DeclareFunction(
gc, "CreateEnvironment", "Create root environment", {"$dict"},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
TDictionary *dict;
if (GetArgumentHeap(args, 0, dict)) {
auto renv = TRootEnvironment::Create(ls, dict);
renv->permissions.customConsole =
env->permissions.customConsole;
return renv;
}
else
{
auto renv = TRootEnvironment::Create(ls,TDictionary::Create(ls));
renv->permissions.customConsole = env->permissions.customConsole;
} else {
auto renv =
TRootEnvironment::Create(ls, TDictionary::Create(ls));
renv->permissions.customConsole =
env->permissions.customConsole;
return renv;
}
});
dict->DeclareFunction(gc, "LoadExecutable", "Load a crossvm executable",{"stream"},[](GCList& ls,std::vector<TObject> args)->TObject{
dict->DeclareFunction(
gc, "LoadExecutable", "Load a crossvm executable", {"stream"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetArgument(args,0,strm))
{
TFile* f =TFile::Create(ls);
f->Load(ls.GetGC(),strm);
if (GetArgument(args, 0, strm)) {
TFile *f = TFile::Create(ls);
f->Load(ls.GetGC(), strm);
return f;
}
return nullptr;
});
#if defined(CROSSLANG_ENABLE_SUPERSLIM)
dict->SetValue("SuperSlim", true);
#else
dict->SetValue("SuperSlim", false);
#endif
dict->DeclareFunction(gc, "Eval", "Eval source code",{"source"}, VM_Eval);
dict->DeclareFunction(gc, "Compile", "Compile Source",{"dict"},VM_Compile);
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast", {"source"}, VM_SourceToAst);
dict->DeclareFunction(gc, "getRuntimeVersion","Get the runtime version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
return TVMVersion(CROSSLANG_MAJOR,CROSSLANG_MINOR,CROSSLANG_PATCH,0,TVMVersionStage::DevVersion);
});
dict->DeclareFunction(gc, "getBytecodeVersion","Get the bytecode version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
return TVMVersion(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
});
dict->DeclareFunction(gc, "getIsRunning","Is the program still running",{},[](GCList& ls, std::vector<TObject> args)->TObject {
return Tesses::Framework::TF_IsRunning();
});
dict->DeclareFunction(gc, "RunEventLoopItteration","Run Event Loop Itteration",{},[](GCList& ls, std::vector<TObject> args)->TObject {
Tesses::Framework::TF_RunEventLoopItteration();
return Undefined();
});
dict->DeclareFunction(gc, "RunEventLoop","Run Event Loop",{},[](GCList& ls, std::vector<TObject> args)->TObject {
Tesses::Framework::TF_RunEventLoop();
return Undefined();
});
dict->DeclareFunction(gc, "Merge", "Merge crvm files", {"srcVFS","sourcePath","destVFS"},[](GCList& ls, std::vector<TObject> args)->TObject {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcVFS;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> destVFS;
Tesses::Framework::Filesystem::VFSPath sourcePath;
if(GetArgument(args,0, srcVFS) && GetArgumentAsPath(args,1,sourcePath) && GetArgument(args,2,destVFS))
return Merge(srcVFS, sourcePath, destVFS);
return Undefined();
});
dict->DeclareFunction(gc, "Disassemble","Disassemble crvm file",{"strm","vfs","$generateJSON","$extractResources"},[](GCList& ls, std::vector<TObject> args)->TObject {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
bool generateJSON=true;
bool extractResources=true;
if(GetArgument(args,0,strm) && GetArgument(args,1, vfs))
{
GetArgument(args,2,generateJSON);
GetArgument(args,3,extractResources);
Disassemble(strm,vfs, generateJSON, extractResources);
}
return Undefined();
});
dict->DeclareFunction(gc, "Assemble", "Assemble crvm file",{"vfs"},[](GCList& ls, std::vector<TObject> args)->TObject {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0, vfs))
return Assemble(vfs);
return Undefined();
});
gc->BarrierBegin();
env->DeclareVariable("VM", dict);
gc->BarrierEnd();
}
}
dict->DeclareFunction(gc, "Eval", "Eval source code", {"source"}, VM_Eval);
dict->DeclareFunction(gc, "Compile", "Compile Source", {"dict"},
VM_Compile);
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast",
{"source"}, VM_SourceToAst);
dict->DeclareFunction(
gc, "getRuntimeVersion", "Get the runtime version", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return TVMVersion(CROSSLANG_MAJOR, CROSSLANG_MINOR, CROSSLANG_PATCH,
0, TVMVersionStage::DevVersion);
});
dict->DeclareFunction(
gc, "getBytecodeVersion", "Get the bytecode version", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return TVMVersion(
CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
CROSSLANG_BYTECODE_VERSIONSTAGE);
});
dict->DeclareFunction(gc, "getIsRunning", "Is the program still running",
{},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return Tesses::Framework::TF_IsRunning();
});
dict->DeclareFunction(gc, "RunEventLoopItteration",
"Run Event Loop Itteration", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::TF_RunEventLoopItteration();
return Undefined();
});
dict->DeclareFunction(gc, "RunEventLoop", "Run Event Loop", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::TF_RunEventLoop();
return Undefined();
});
gc->BarrierBegin();
env->DeclareVariable("VM", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -1,28 +1,26 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TAny* TAny::Create(GCList& ls)
{
TAny* anyObj = new TAny();
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(anyObj);
gc->Watch(anyObj);
return anyObj;
}
TAny* TAny::Create(GCList* ls)
{
TAny* anyObj = new TAny();
std::shared_ptr<GC> gc = ls->GetGC();
ls->Add(anyObj);
gc->Watch(anyObj);
return anyObj;
}
void TAny::Mark()
{
if(this->marked) return;
this->marked=true;
GC::Mark(this->other);
}
}
TAny *TAny::Create(GCList &ls) {
TAny *anyObj = new TAny();
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(anyObj);
gc->Watch(anyObj);
return anyObj;
}
TAny *TAny::Create(GCList *ls) {
TAny *anyObj = new TAny();
std::shared_ptr<GC> gc = ls->GetGC();
ls->Add(anyObj);
gc->Watch(anyObj);
return anyObj;
}
void TAny::Mark() {
if (this->marked)
return;
this->marked = true;
GC::Mark(this->other);
}
} // namespace Tesses::CrossLang

View File

@@ -1,116 +1,96 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
TAssociativeArray* TAssociativeArray::Create(GCList& ls)
{
TAssociativeArray* list=new TAssociativeArray();
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(list);
_gc->Watch(list);
return list;
}
TAssociativeArray* TAssociativeArray::Create(GCList* ls)
{
TAssociativeArray* list=new TAssociativeArray();
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(list);
_gc->Watch(list);
return list;
}
void TAssociativeArray::Set(std::shared_ptr<GC> gc, TObject key, TObject value)
{
if(std::holds_alternative<Undefined>(key)) return;
gc->BarrierBegin();
for(auto index = this->items.begin(); index < this->items.end(); index++)
{
auto first= index->first;
gc->BarrierEnd();
auto eq = Equals(gc,key,first);
gc->BarrierBegin();
if(eq)
{
if(std::holds_alternative<Undefined>(value))
{
this->items.erase(index);
}
else
{
index->second = value;
}
gc->BarrierEnd();
return;
}
}
this->items.push_back(std::pair<TObject,TObject>(key,value));
gc->BarrierEnd();
}
TObject TAssociativeArray::Get(std::shared_ptr<GC> gc, TObject key)
{
if(std::holds_alternative<Undefined>(key)) return Undefined();
gc->BarrierBegin();
for(auto& item : this->items)
{
auto first= item.first;
gc->BarrierEnd();
auto eq = Equals(gc,key,first);
gc->BarrierBegin();
if(eq)
{
gc->BarrierEnd();
return item.second;
}
}
gc->BarrierEnd();
return Undefined();
}
TObject TAssociativeArray::GetKey(int64_t index)
{
if(index >= 0 && index < (int64_t)this->items.size())
{
return this->items[index].first;
}
return Undefined();
}
TObject TAssociativeArray::GetValue(int64_t index)
{
if(index >= 0 && index < (int64_t)this->items.size())
{
return this->items[index].second;
}
return Undefined();
}
void TAssociativeArray::SetKey(int64_t index, TObject key)
{
namespace Tesses::CrossLang {
if(std::holds_alternative<Undefined>(key)) return;
if(index >= 0 && index < (int64_t)this->items.size())
{
this->items[index].first=key;
}
}
void TAssociativeArray::SetValue(int64_t index,TObject value)
{
if(std::holds_alternative<Undefined>(value)) return;
if(index >= 0 && index < (int64_t)this->items.size())
{
this->items[index].first=value;
TAssociativeArray *TAssociativeArray::Create(GCList &ls) {
TAssociativeArray *list = new TAssociativeArray();
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(list);
_gc->Watch(list);
return list;
}
TAssociativeArray *TAssociativeArray::Create(GCList *ls) {
TAssociativeArray *list = new TAssociativeArray();
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(list);
_gc->Watch(list);
return list;
}
void TAssociativeArray::Set(std::shared_ptr<GC> gc, TObject key,
TObject value) {
if (std::holds_alternative<Undefined>(key))
return;
gc->BarrierBegin();
for (auto index = this->items.begin(); index < this->items.end(); index++) {
auto first = index->first;
gc->BarrierEnd();
auto eq = Equals(gc, key, first);
gc->BarrierBegin();
if (eq) {
if (std::holds_alternative<Undefined>(value)) {
this->items.erase(index);
} else {
index->second = value;
}
gc->BarrierEnd();
return;
}
}
int64_t TAssociativeArray::Count()
{
return (int64_t)this->items.size();
}
void TAssociativeArray::Mark()
{
if(this->marked) return;
this->marked=true;
for(auto& item : this->items)
{
GC::Mark(item.first);
GC::Mark(item.second);
this->items.push_back(std::pair<TObject, TObject>(key, value));
gc->BarrierEnd();
}
TObject TAssociativeArray::Get(std::shared_ptr<GC> gc, TObject key) {
if (std::holds_alternative<Undefined>(key))
return Undefined();
gc->BarrierBegin();
for (auto &item : this->items) {
auto first = item.first;
gc->BarrierEnd();
auto eq = Equals(gc, key, first);
gc->BarrierBegin();
if (eq) {
gc->BarrierEnd();
return item.second;
}
}
}
gc->BarrierEnd();
return Undefined();
}
TObject TAssociativeArray::GetKey(int64_t index) {
if (index >= 0 && index < (int64_t)this->items.size()) {
return this->items[index].first;
}
return Undefined();
}
TObject TAssociativeArray::GetValue(int64_t index) {
if (index >= 0 && index < (int64_t)this->items.size()) {
return this->items[index].second;
}
return Undefined();
}
void TAssociativeArray::SetKey(int64_t index, TObject key) {
if (std::holds_alternative<Undefined>(key))
return;
if (index >= 0 && index < (int64_t)this->items.size()) {
this->items[index].first = key;
}
}
void TAssociativeArray::SetValue(int64_t index, TObject value) {
if (std::holds_alternative<Undefined>(value))
return;
if (index >= 0 && index < (int64_t)this->items.size()) {
this->items[index].first = value;
}
}
int64_t TAssociativeArray::Count() { return (int64_t)this->items.size(); }
void TAssociativeArray::Mark() {
if (this->marked)
return;
this->marked = true;
for (auto &item : this->items) {
GC::Mark(item.first);
GC::Mark(item.second);
}
}
} // namespace Tesses::CrossLang

View File

@@ -1,261 +1,228 @@
#include "CrossLang.hpp"
//THANKS TO https://www.youtube.com/watch?v=R-z2Hv-7nxk
// THANKS TO https://www.youtube.com/watch?v=R-z2Hv-7nxk
namespace Tesses::CrossLang {
TTask::TTask(std::shared_ptr<GC> gc)
{
this->gc = gc;
}
TTask* TTask::Create(GCList& ls)
{
TTask* task = new TTask(ls.GetGC());
ls.Add(task);
task->gc->Watch(task);
return task;
}
bool TTask::IsCompleted()
{
gc->BarrierBegin();
bool r = this->isCompleted;
gc->BarrierEnd();
TTask::TTask(std::shared_ptr<GC> gc) { this->gc = gc; }
TTask *TTask::Create(GCList &ls) {
TTask *task = new TTask(ls.GetGC());
ls.Add(task);
task->gc->Watch(task);
return task;
}
bool TTask::IsCompleted() {
gc->BarrierBegin();
bool r = this->isCompleted;
gc->BarrierEnd();
return r;
}
TTask* TTask::ContinueWith(GCList& ls, TCallable* callable)
{
TTask* task = TTask::Create(ls);
return r;
}
TTask *TTask::ContinueWith(GCList &ls, TCallable *callable) {
TTask *task = TTask::Create(ls);
TExternalMethod* em = TExternalMethod::Create(ls,"Internal async thing",{"_asyncObj"},[callable,task](GCList& ls,std::vector<TObject> args)->TObject{
TExternalMethod *em = TExternalMethod::Create(
ls, "Internal async thing", {"_asyncObj"},
[callable, task](GCList &ls, std::vector<TObject> args) -> TObject {
try {
task->SetSucceeded(callable->Call(ls,args));
} catch(...) {
task->SetSucceeded(callable->Call(ls, args));
} catch (...) {
task->SetFailed(std::current_exception());
}
return nullptr;
});
em->watch = {callable,task};
this->gc->BarrierBegin();
if(this->isCompleted)
{
this->gc->BarrierEnd();
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
auto cobj = this->obj;
ls->Add(cobj);
ls->Add(em);
this->gc->GetPool()->Schedule([ls,em,cobj](size_t s)->void {
em->Call(*ls,{cobj});
});
return task;
}
else
{
this->cont = em;
}
em->watch = {callable, task};
this->gc->BarrierBegin();
if (this->isCompleted) {
this->gc->BarrierEnd();
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
auto cobj = this->obj;
ls->Add(cobj);
ls->Add(em);
this->gc->GetPool()->Schedule(
[ls, em, cobj](size_t s) -> void { em->Call(*ls, {cobj}); });
return task;
} else {
this->cont = em;
}
void TTask::ContinueWith(TCallable* callable)
{
this->gc->BarrierBegin();
if(this->isCompleted)
{
this->gc->BarrierEnd();
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
auto cobj = this->obj;
ls->Add(cobj);
ls->Add(callable);
this->gc->GetPool()->Schedule([ls,callable,cobj](size_t s)->void {
callable->Call(*ls,{cobj});
});
return;
}
else
{
this->cont = callable;
}
this->gc->BarrierEnd();
return task;
}
void TTask::ContinueWith(TCallable *callable) {
this->gc->BarrierBegin();
if (this->isCompleted) {
this->gc->BarrierEnd();
}
void TTask::SetFailed(std::exception_ptr ex)
{
this->ex = ex;
this->SetSucceeded(nullptr);
}
void TTask::SetSucceeded(TObject v)
{
gc->BarrierBegin();
if(this->isCompleted)
{
gc->BarrierEnd();
return;
}
this->isCompleted=true;
this->obj = v;
auto cont = this->cont;
gc->BarrierEnd();
if(cont != nullptr)
{
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
auto callable = cont;
ls->Add(v);
ls->Add(callable);
this->gc->GetPool()->Schedule([ls,callable,v](size_t s)->void {
callable->Call(*ls,{v});
});
}
}
TObject TTask::Wait()
{
while(true)
{
gc->BarrierBegin();
if(this->isCompleted)
{
if(this->ex)
{
auto error = this->ex;
gc->BarrierEnd();
std::rethrow_exception(error);
}
auto o = this->obj;
gc->BarrierEnd();
return o;
}
gc->BarrierEnd();
}
}
void TTask::Mark()
{
if(this->marked) return;
this->marked=true;
GC::Mark(this->obj);
if(this->cont != nullptr)
this->cont->Mark();
}
TTask* TTask::Run(GCList& ls, TCallable* callable)
{
TTask* task = TTask::Create(ls);
std::shared_ptr<GCList> ls2=std::make_shared<GCList>(ls.GetGC());
ls2->Add(callable);
ls2->Add(task);
ls.GetGC()->GetPool()->Schedule([ls2,callable,task](size_t s)->void {
try
{
task->SetSucceeded(callable->Call(*ls2,{}));
}
catch(...)
{
task->SetFailed(std::current_exception());
}
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
auto cobj = this->obj;
ls->Add(cobj);
ls->Add(callable);
this->gc->GetPool()->Schedule([ls, callable, cobj](size_t s) -> void {
callable->Call(*ls, {cobj});
});
return task;
return;
} else {
this->cont = callable;
}
TTask* TTask::FromResult(GCList& ls, TObject v)
{
TTask* task = TTask::Create(ls);
task->SetSucceeded(v);
return task;
}
this->gc->BarrierEnd();
}
class TTaskCseObj {
std::shared_ptr<GC> gc;
TTask* task;
public:
TTaskCseObj(std::shared_ptr<GC> gc, TTask* task)
{
this->gc = gc;
this->task = task;
void TTask::SetFailed(std::exception_ptr ex) {
this->ex = ex;
this->SetSucceeded(nullptr);
}
void TTask::SetSucceeded(TObject v) {
gc->BarrierBegin();
if (this->isCompleted) {
gc->BarrierEnd();
return;
}
this->isCompleted = true;
this->obj = v;
auto cont = this->cont;
gc->BarrierEnd();
if (cont != nullptr) {
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
auto callable = cont;
ls->Add(v);
ls->Add(callable);
this->gc->GetPool()->Schedule(
[ls, callable, v](size_t s) -> void { callable->Call(*ls, {v}); });
}
}
TObject TTask::Wait() {
while (true) {
gc->BarrierBegin();
if (this->isCompleted) {
if (this->ex) {
auto error = this->ex;
gc->BarrierEnd();
std::rethrow_exception(error);
}
void Invoke(std::shared_ptr<TTaskCseObj> shared_o,CallStackEntry* cse, TObject o)
{
try {
GCList ls(gc);
cse->Push(gc,o);
auto res = cse->Resume(ls);
CallStackEntry* cse2;
if(GetObjectHeap(res,cse2))
{
auto taskPiece=cse2->Pop(ls);
TTask* task;
if(GetObjectHeap(taskPiece,task))
{
auto em = TExternalMethod::Create(ls,"",{"obj"},[cse2,task,shared_o](GCList& ls, std::vector<TObject> args)->TObject {
shared_o->Invoke(shared_o,cse2,args.empty() ? (TObject)Undefined():args[0]);
auto o = this->obj;
gc->BarrierEnd();
return o;
}
gc->BarrierEnd();
}
}
void TTask::Mark() {
if (this->marked)
return;
this->marked = true;
GC::Mark(this->obj);
if (this->cont != nullptr)
this->cont->Mark();
}
TTask *TTask::Run(GCList &ls, TCallable *callable) {
TTask *task = TTask::Create(ls);
std::shared_ptr<GCList> ls2 = std::make_shared<GCList>(ls.GetGC());
ls2->Add(callable);
ls2->Add(task);
ls.GetGC()->GetPool()->Schedule([ls2, callable, task](size_t s) -> void {
try {
task->SetSucceeded(callable->Call(*ls2, {}));
} catch (...) {
task->SetFailed(std::current_exception());
}
});
return task;
}
TTask *TTask::FromResult(GCList &ls, TObject v) {
TTask *task = TTask::Create(ls);
task->SetSucceeded(v);
return task;
}
class TTaskCseObj {
std::shared_ptr<GC> gc;
TTask *task;
public:
TTaskCseObj(std::shared_ptr<GC> gc, TTask *task) {
this->gc = gc;
this->task = task;
}
void Invoke(std::shared_ptr<TTaskCseObj> shared_o, CallStackEntry *cse,
TObject o) {
try {
GCList ls(gc);
cse->Push(gc, o);
auto res = cse->Resume(ls);
CallStackEntry *cse2;
if (GetObjectHeap(res, cse2)) {
auto taskPiece = cse2->Pop(ls);
TTask *task;
if (GetObjectHeap(taskPiece, task)) {
auto em = TExternalMethod::Create(
ls, "", {"obj"},
[cse2, task, shared_o](
GCList &ls, std::vector<TObject> args) -> TObject {
shared_o->Invoke(shared_o, cse2,
args.empty() ? (TObject)Undefined()
: args[0]);
return nullptr;
});
em->watch.push_back(task);
em->watch.push_back(cse2);
task->ContinueWith(em);
}
}
else {
this->task->SetSucceeded(res);
}
} catch(...) {
this->task->SetFailed(std::current_exception());
em->watch.push_back(task);
em->watch.push_back(cse2);
task->ContinueWith(em);
}
} else {
this->task->SetSucceeded(res);
}
};
TTask* TTask::FromClosure(GCList& ls, TClosure* closure)
{
auto res = closure->Call(ls,{});
CallStackEntry* ent;
if(GetObjectHeap(res,ent))
{
return FromCallStackEntry(ls,ent);
} catch (...) {
this->task->SetFailed(std::current_exception());
}
return FromResult(ls,res);
}
TTask* TTask::FromCallStackEntry(GCList& ls, CallStackEntry* ent)
{
TTask* task = TTask::Create(ls);
//try {
GCList ls2(ls.GetGC());
std::shared_ptr<GC> gc = ls.GetGC();
std::shared_ptr<TTaskCseObj> obj = std::make_shared<TTaskCseObj>(gc,task);
ls2.Add(task);
auto res = ent->Pop(ls2);
TTask* task2;
if(GetObjectHeap(res,task2))
{
auto em = TExternalMethod::Create(ls2,"",{},[ent,task,obj](GCList& ls, std::vector<TObject> args)->TObject {
obj->Invoke(obj,ent,args.empty() ? (TObject)Undefined():args[0]);
return nullptr;
});
em->watch.push_back(task);
em->watch.push_back(ent);
task2->ContinueWith(em);
}
/*} catch(...) {
task->SetFailed(std::current_exception());
}*/
return task;
};
TTask *TTask::FromClosure(GCList &ls, TClosure *closure) {
auto res = closure->Call(ls, {});
CallStackEntry *ent;
if (GetObjectHeap(res, ent)) {
return FromCallStackEntry(ls, ent);
}
}
return FromResult(ls, res);
}
TTask *TTask::FromCallStackEntry(GCList &ls, CallStackEntry *ent) {
TTask *task = TTask::Create(ls);
// try {
GCList ls2(ls.GetGC());
std::shared_ptr<GC> gc = ls.GetGC();
std::shared_ptr<TTaskCseObj> obj = std::make_shared<TTaskCseObj>(gc, task);
ls2.Add(task);
auto res = ent->Pop(ls2);
TTask *task2;
if (GetObjectHeap(res, task2)) {
auto em = TExternalMethod::Create(
ls2, "", {},
[ent, task, obj](GCList &ls, std::vector<TObject> args) -> TObject {
obj->Invoke(obj, ent,
args.empty() ? (TObject)Undefined() : args[0]);
return nullptr;
});
em->watch.push_back(task);
em->watch.push_back(ent);
task2->ContinueWith(em);
}
/*} catch(...) {
task->SetFailed(std::current_exception());
}*/
return task;
}
} // namespace Tesses::CrossLang

View File

@@ -1,247 +1,248 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
std::string TClassObject::TypeName()
{
std::string type = "class ";
type += this->name;
for(auto& item : this->inherit_tree) type += " : " + item;
return type;
namespace Tesses::CrossLang {
std::string TClassObject::TypeName() {
std::string type = "class ";
type += this->name;
for (auto &item : this->inherit_tree)
type += " : " + item;
return type;
}
TObject TClassObject::CallMethod(GCList &ls, std::string className,
std::string name, std::vector<TObject> args) {
auto value = this->GetValue(className, name);
TCallable *callable;
if (GetObjectHeap(value, callable)) {
return callable->Call(ls, args);
}
TObject TClassObject::CallMethod(GCList& ls, std::string className, std::string name,std::vector<TObject> args)
{
auto value = this->GetValue(className,name);
TCallable* callable;
if(GetObjectHeap(value, callable))
{
return callable->Call(ls,args);
}
return Undefined();
}
TClassObjectEntry* TClassObject::GetEntry(std::string classN, std::string key)
{
for(auto& item : this->entries)
{
if(item.name == key)
{
switch(item.modifier)
{
case TClassModifier::Private:
if(classN != item.owner) return nullptr;
break;
case TClassModifier::Protected:
if(classN.empty()) return nullptr;
if(classN != item.owner)
{
for(auto inh : this->inherit_tree)
{
if(inh == classN) {
return &item;
}
}
return nullptr;
}
break;
default:
//DO NOTHING
break;
}
return &item;
}
}
return nullptr;
}
TClassObject* TClassObject::Create(GCList& ls, TFile* f, uint32_t classIndex, TEnvironment* env, std::vector<TObject> args)
{
return Create(&ls,f,classIndex,env,args);
}
std::string JoinPeriod(std::vector<std::string>& p)
{
std::string newStr = "";
for(size_t i = 0; i < p.size(); i++)
{
if(i > 0) newStr.push_back('.');
newStr += p[i];
}
return newStr;
}
TClassObject* TClassObject::Create(GCList* ls, TFile* f, uint32_t classIndex, TEnvironment* env, std::vector<TObject> args)
{
if(ls == nullptr) return nullptr;
TClassObject* obj = new TClassObject();
obj->file = f;
obj->classIndex = classIndex;
obj->ogEnv=env;
obj->env = TClassEnvironment::Create(ls,env,obj);
obj->name = JoinPeriod(f->classes[classIndex].name);
bool hasToString=false;
for(auto entry : f->classes[classIndex].entry)
{
if(entry.modifier == TClassModifier::Static) continue;
TClassObjectEntry ent;
ent.name = entry.name;
ent.modifier = entry.modifier;
ent.canSet = !entry.isFunction;
ent.owner = obj->name;
if(entry.isFunction)
{
if(ent.name == "ToString") hasToString=true;
if(entry.isAbstract)
{
delete obj;
throw VMException("Method " + ent.name + " in " + ent.owner + " is abstract.");
}
else
{
auto clos = TClosure::Create(ls,obj->env,obj->file,entry.chunkId);
clos->documentation = entry.documentation;
clos->className = ent.owner;
ent.value = clos;
}
}
else {
if(entry.isAbstract) ent.value = Undefined();
else {
auto clos = TClosure::Create(ls,obj->env,obj->file,entry.chunkId);
clos->className=ent.owner;
ent.value = clos->Call(*ls,{});
}
}
obj->entries.push_back(ent);
}
TClass* clsCur = &f->classes[classIndex];
TRootEnvironment* rEnv = env->GetRootEnvironment();
while(!clsCur->inherits.empty() && !(clsCur->inherits.size() == 1 && clsCur->inherits[0] == "ClassObject"))
{
obj->inherit_tree.push_back(JoinPeriod(clsCur->inherits));
size_t idx;
if(rEnv->TryFindClass(clsCur->inherits,idx))
{
auto file = rEnv->classes[idx].first;
clsCur = &rEnv->classes[idx].first->classes.at(rEnv->classes[idx].second);
auto ownerNow = JoinPeriod(clsCur->name);
for(auto entry : clsCur->entry)
{
if(entry.modifier == TClassModifier::Static) continue;
bool cont=false;
for(auto e : obj->entries)
if(e.name == entry.name)
{
cont=true;
break;
}
if(cont) continue;
return Undefined();
}
TClassObjectEntry *TClassObject::GetEntry(std::string classN, std::string key) {
for (auto &item : this->entries) {
if (item.name == key) {
switch (item.modifier) {
case TClassModifier::Private:
if (classN != item.owner)
return nullptr;
break;
case TClassModifier::Protected:
if (classN.empty())
return nullptr;
if (classN != item.owner) {
for (auto inh : this->inherit_tree) {
if (inh == classN) {
TClassObjectEntry ent;
ent.name = entry.name;
ent.modifier = entry.modifier;
ent.canSet = !entry.isFunction;
ent.owner = ownerNow;
if(entry.isFunction)
{
if(ent.name == "ToString") hasToString=true;
if(entry.isAbstract)
{
delete obj;
throw VMException("Method " + ent.name + " in " + ownerNow + " is abstract.");
return &item;
}
}
else
{
auto clos = TClosure::Create(ls,obj->env,file,entry.chunkId);
return nullptr;
}
break;
default:
// DO NOTHING
break;
}
return &item;
}
}
return nullptr;
}
TClassObject *TClassObject::Create(GCList &ls, TFile *f, uint32_t classIndex,
TEnvironment *env,
std::vector<TObject> args) {
return Create(&ls, f, classIndex, env, args);
}
std::string JoinPeriod(std::vector<std::string> &p) {
std::string newStr = "";
for (size_t i = 0; i < p.size(); i++) {
if (i > 0)
newStr.push_back('.');
newStr += p[i];
}
return newStr;
}
TClassObject *TClassObject::Create(GCList *ls, TFile *f, uint32_t classIndex,
TEnvironment *env,
std::vector<TObject> args) {
if (ls == nullptr)
return nullptr;
TClassObject *obj = new TClassObject();
obj->file = f;
obj->classIndex = classIndex;
obj->ogEnv = env;
obj->env = TClassEnvironment::Create(ls, env, obj);
obj->name = JoinPeriod(f->classes[classIndex].name);
bool hasToString = false;
for (auto &entry : f->classes[classIndex].entry) {
if (entry.modifier == TClassModifier::Static)
continue;
TClassObjectEntry ent;
ent.name = entry.name;
ent.modifier = entry.modifier;
ent.canSet = !entry.isFunction;
ent.owner = obj->name;
if (entry.isFunction) {
if (entry.name == "ToString")
hasToString = true;
if (entry.isAbstract) {
delete obj;
throw VMException("Method " + ent.name + " in " + ent.owner +
" is abstract.");
} else {
auto clos =
TClosure::Create(ls, obj->env, obj->file, entry.chunkId);
clos->documentation = entry.documentation;
clos->className = ent.owner;
ent.value = clos;
}
} else {
if (entry.isAbstract)
ent.value = Undefined();
else {
auto clos =
TClosure::Create(ls, obj->env, obj->file, entry.chunkId);
clos->className = ent.owner;
ent.value = clos->Call(*ls, {});
}
}
obj->entries.push_back(ent);
}
TClass *clsCur = &f->classes[classIndex];
TRootEnvironment *rEnv = env->GetRootEnvironment();
while (!clsCur->inherits.empty() &&
!(clsCur->inherits.size() == 1 &&
clsCur->inherits[0] == "ClassObject")) {
obj->inherit_tree.push_back(JoinPeriod(clsCur->inherits));
size_t idx;
if (rEnv->TryFindClass(clsCur->inherits, idx)) {
auto file = rEnv->classes[idx].first;
clsCur = &rEnv->classes[idx].first->classes.at(
rEnv->classes[idx].second);
auto ownerNow = JoinPeriod(clsCur->name);
for (auto &entry : clsCur->entry) {
if (entry.modifier == TClassModifier::Static)
continue;
bool cont = false;
for (auto e : obj->entries)
if (e.name == entry.name) {
cont = true;
break;
}
if (cont)
continue;
TClassObjectEntry ent;
ent.name = entry.name;
ent.modifier = entry.modifier;
ent.canSet = !entry.isFunction;
ent.owner = ownerNow;
if (entry.isFunction) {
if (entry.name == "ToString")
hasToString = true;
if (entry.isAbstract) {
delete obj;
throw VMException("Method " + ent.name + " in " +
ownerNow + " is abstract.");
} else {
auto clos =
TClosure::Create(ls, obj->env, file, entry.chunkId);
clos->closure->name = obj->name + "::" + ent.name;
clos->className = ownerNow;
clos->documentation = entry.documentation;
ent.value = clos;
}
}
else {
if(entry.isAbstract) ent.value = Undefined();
} else {
if (entry.isAbstract)
ent.value = Undefined();
else {
auto clos = TClosure::Create(ls,obj->env,file,entry.chunkId);
auto clos =
TClosure::Create(ls, obj->env, file, entry.chunkId);
clos->closure->name = obj->name + "::" + ent.name;
clos->className = ownerNow;
ent.value = clos->Call(*ls,{});
ent.value = clos->Call(*ls, {});
}
}
}
obj->entries.push_back(ent);
}
}
}
if(!hasToString)
{
TClassObjectEntry ent;
ent.canSet=false;
ent.modifier = TClassModifier::Public;
ent.name = "ToString";
ent.owner = obj->name;
ent.value = TExternalMethod::Create(ls,"The ToString",{},[obj](GCList& ls,std::vector<TObject> args)->TObject { return obj->TypeName();});
obj->entries.push_back(ent);
}
TCallable* call=nullptr;
std::string fnName = f->classes[classIndex].name[f->classes[classIndex].name.size()-1];
for(auto& item : obj->entries)
if(item.name == fnName)
{
GetObjectHeap(item.value,call);
break;
}
ls->Add(obj);
ls->GetGC()->Watch(obj);
if(call != nullptr) call->Call(*ls,args);
return obj;
}
if (!hasToString) {
TClassObjectEntry ent;
ent.canSet = false;
ent.modifier = TClassModifier::Public;
ent.name = "ToString";
ent.owner = obj->name;
ent.value = TExternalMethod::Create(
ls, "The ToString", {},
[obj](GCList &ls, std::vector<TObject> args) -> TObject {
return obj->TypeName();
});
obj->entries.push_back(ent);
}
TCallable *call = nullptr;
std::string fnName =
f->classes[classIndex].name[f->classes[classIndex].name.size() - 1];
for (auto &item : obj->entries)
if (item.name == fnName) {
GetObjectHeap(item.value, call);
break;
}
ls->Add(obj);
ls->GetGC()->Watch(obj);
TObject TClassObject::GetValue(std::string className, std::string key)
{
auto ent = GetEntry(className,key);
if(ent == nullptr) return Undefined();
return ent->value;
}
void TClassObject::SetValue(std::string className, std::string key,TObject value)
{
auto ent = GetEntry(className,key);
if(ent == nullptr) return;
if(ent->canSet) ent->value = value;
}
bool TClassObject::HasValue(std::string className,std::string key)
{
auto ent = GetEntry(className,key);
return ent != nullptr;
}
bool TClassObject::HasField(std::string className,std::string key)
{
auto ent = GetEntry(className,key);
if(ent == nullptr) return false;
return ent->canSet;
}
bool TClassObject::HasMethod(std::string className,std::string key)
{
auto ent = GetEntry(className,key);
if(ent == nullptr) return false;
TCallable* call;
return GetObjectHeap(ent->value,call);
}
void TClassObject::Mark()
{
if(this->marked) return;
this->marked=true;
this->env->Mark();
this->file->Mark();
this->ogEnv->Mark();
for(auto& item : this->entries) GC::Mark(item.value);
}
}
if (call != nullptr)
call->Call(*ls, args);
return obj;
}
TObject TClassObject::GetValue(std::string className, std::string key) {
auto ent = GetEntry(className, key);
if (ent == nullptr)
return Undefined();
return ent->value;
}
void TClassObject::SetValue(std::string className, std::string key,
TObject value) {
auto ent = GetEntry(className, key);
if (ent == nullptr)
return;
if (ent->canSet)
ent->value = value;
}
bool TClassObject::HasValue(std::string className, std::string key) {
auto ent = GetEntry(className, key);
return ent != nullptr;
}
bool TClassObject::HasField(std::string className, std::string key) {
auto ent = GetEntry(className, key);
if (ent == nullptr)
return false;
return ent->canSet;
}
bool TClassObject::HasMethod(std::string className, std::string key) {
auto ent = GetEntry(className, key);
if (ent == nullptr)
return false;
TCallable *call;
return GetObjectHeap(ent->value, call);
}
void TClassObject::Mark() {
if (this->marked)
return;
this->marked = true;
this->env->Mark();
this->file->Mark();
this->ogEnv->Mark();
for (auto &item : this->entries)
GC::Mark(item.value);
}
} // namespace Tesses::CrossLang

View File

@@ -1,130 +1,142 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
bool TClassEnvironment::HasConstForSet(std::string key)
{
if(this->env->HasVariableRecurse(key))
{
return this->env->HasConstForSet(key);
}
return false;
bool TClassEnvironment::HasConstForSet(std::string key) {
if (this->env->HasVariableRecurse(key)) {
return this->env->HasConstForSet(key);
}
TClassEnvironment* TClassEnvironment::Create(GCList* gc,TEnvironment* env,TClassObject* obj)
{
TClassEnvironment* env2=new TClassEnvironment(env,obj);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(env2);
_gc->Watch(env2);
return env2;
}
TClassEnvironment* TClassEnvironment::Create(GCList& gc,TEnvironment* env,TClassObject* obj)
{
return false;
}
TClassEnvironment *TClassEnvironment::Create(GCList *gc, TEnvironment *env,
TClassObject *obj) {
TClassEnvironment* env2=new TClassEnvironment(env,obj);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(env2);
_gc->Watch(env2);
return env2;
}
TClassEnvironment::TClassEnvironment(TEnvironment* env,TClassObject* obj)
{
this->env = env;
this->clsObj=obj;
}
bool TClassEnvironment::HasVariable(std::string key)
{
if(key == "this") return true;
if(this->clsObj->HasValue(current_function == nullptr ? "" : current_function->callable->className,key)) return true;
return false;
}
bool TClassEnvironment::HasVariableRecurse(std::string key)
{
if(HasVariable(key)) return true;
return this->env->HasVariableRecurse(key);
}
bool TClassEnvironment::HasVariableOrFieldRecurse(std::string key, bool setting)
{
if(key == "this") return true;
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
if(clsObj->HasMethod(clsName,(setting ? "set" : "get")+key)) return true;
if(clsObj->HasValue(clsName,key)) return true;
return env->HasVariableOrFieldRecurse(key,setting);
}
TObject TClassEnvironment::GetVariable(std::string key)
{
if(key == "this") return this->clsObj;
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
if(clsObj->HasValue(clsName,key)) return this->clsObj->GetValue(clsName,key);
return env->GetVariable(key);
}
void TClassEnvironment::SetVariable(std::string key, TObject value)
{
if(key == "this") return;
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
if(clsObj->HasValue(clsName,key))
{
this->clsObj->SetValue(clsName,key,value);
return;
}
this->env->SetVariable(key,value);
TClassEnvironment *env2 = new TClassEnvironment(env, obj);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(env2);
_gc->Watch(env2);
return env2;
}
TClassEnvironment *TClassEnvironment::Create(GCList &gc, TEnvironment *env,
TClassObject *obj) {
TClassEnvironment *env2 = new TClassEnvironment(env, obj);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(env2);
_gc->Watch(env2);
return env2;
}
TClassEnvironment::TClassEnvironment(TEnvironment *env, TClassObject *obj) {
this->env = env;
this->clsObj = obj;
}
bool TClassEnvironment::HasVariable(std::string key) {
if (key == "this")
return true;
if (this->clsObj->HasValue(current_function == nullptr
? ""
: current_function->callable->className,
key))
return true;
return false;
}
bool TClassEnvironment::HasVariableRecurse(std::string key) {
if (HasVariable(key))
return true;
return this->env->HasVariableRecurse(key);
}
bool TClassEnvironment::HasVariableOrFieldRecurse(std::string key,
bool setting) {
if (key == "this")
return true;
std::string clsName = current_function == nullptr
? ""
: current_function->callable->className;
if (clsObj->HasMethod(clsName, (setting ? "set" : "get") + key))
return true;
if (clsObj->HasValue(clsName, key))
return true;
return env->HasVariableOrFieldRecurse(key, setting);
}
TObject TClassEnvironment::GetVariable(std::string key) {
if (key == "this")
return this->clsObj;
std::string clsName = current_function == nullptr
? ""
: current_function->callable->className;
if (clsObj->HasValue(clsName, key))
return this->clsObj->GetValue(clsName, key);
return env->GetVariable(key);
}
void TClassEnvironment::SetVariable(std::string key, TObject value) {
if (key == "this")
return;
std::string clsName = current_function == nullptr
? ""
: current_function->callable->className;
if (clsObj->HasValue(clsName, key)) {
this->clsObj->SetValue(clsName, key, value);
return;
}
TObject TClassEnvironment::GetVariable(GCList& ls, std::string key)
{
if(key == "this") return this->clsObj;
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
if(this->clsObj->HasMethod(clsName,"get"+key))
{
auto res=this->clsObj->GetValue(clsName,"get"+key);
TCallable* call;
if(GetObjectHeap(res,call)) return call->Call(ls,{});
}
if(this->clsObj->HasValue(clsName,key)) return this->clsObj->GetValue(clsName,key);
return this->env->GetVariable(ls,key);
}
TObject TClassEnvironment::SetVariable(GCList& ls, std::string key, TObject v)
{
if(key == "this") return this->clsObj;
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
if(this->clsObj->HasMethod(clsName,"set"+key))
{
auto res=this->clsObj->GetValue(clsName,"set"+key);
TCallable* call;
if(GetObjectHeap(res,call)) return call->Call(ls,{v});
}
if(this->clsObj->HasValue(clsName,key)) { this->clsObj->SetValue(clsName,key,v); return v;}
return this->env->SetVariable(ls,key,v);
}
void TClassEnvironment::DeclareVariable(std::string key, TObject value)
{
this->env->SetVariable(key, value);
return;
}
TObject TClassEnvironment::GetVariable(GCList &ls, std::string key) {
if (key == "this")
return this->clsObj;
std::string clsName = current_function == nullptr
? ""
: current_function->callable->className;
if (this->clsObj->HasMethod(clsName, "get" + key)) {
auto res = this->clsObj->GetValue(clsName, "get" + key);
TCallable *call;
if (GetObjectHeap(res, call))
return call->Call(ls, {});
}
TRootEnvironment* TClassEnvironment::GetRootEnvironment()
{
return this->env->GetRootEnvironment();
if (this->clsObj->HasValue(clsName, key))
return this->clsObj->GetValue(clsName, key);
return this->env->GetVariable(ls, key);
}
TObject TClassEnvironment::SetVariable(GCList &ls, std::string key, TObject v) {
if (key == "this")
return this->clsObj;
std::string clsName = current_function == nullptr
? ""
: current_function->callable->className;
if (this->clsObj->HasMethod(clsName, "set" + key)) {
auto res = this->clsObj->GetValue(clsName, "set" + key);
TCallable *call;
if (GetObjectHeap(res, call))
return call->Call(ls, {v});
}
TEnvironment* TClassEnvironment::GetParentEnvironment()
{
return this->env;
if (this->clsObj->HasValue(clsName, key)) {
this->clsObj->SetValue(clsName, key, v);
return v;
}
void TClassEnvironment::Mark()
{
if(this->marked) return;
this->marked=true;
this->clsObj->Mark();
this->env->Mark();
for(auto item : this->defers) item->Mark();
}
}
return this->env->SetVariable(ls, key, v);
}
void TClassEnvironment::DeclareVariable(std::string key, TObject value) {}
TRootEnvironment *TClassEnvironment::GetRootEnvironment() {
return this->env->GetRootEnvironment();
}
TEnvironment *TClassEnvironment::GetParentEnvironment() { return this->env; }
void TClassEnvironment::Mark() {
if (this->marked)
return;
this->marked = true;
this->clsObj->Mark();
this->env->Mark();
for (auto item : this->defers)
item->Mark();
}
} // namespace Tesses::CrossLang

View File

@@ -1,99 +1,97 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TArgWrapper* TArgWrapper::Create(GCList& ls, TCallable* callable)
{
TArgWrapper* argWrapper = new TArgWrapper();
argWrapper->callable = callable;
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
}
TArgWrapper* TArgWrapper::Create(GCList* ls, TCallable* callable)
{
TArgWrapper* argWrapper = new TArgWrapper();
argWrapper->callable = callable;
std::shared_ptr<GC> gc = ls->GetGC();
ls->Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
}
TObject TArgWrapper::Call(GCList& ls,std::vector<TObject> args)
{
auto cse = current_function;
TList* argList = TList::Create(ls);
argList->items = args;
TObject v=this->callable->Call(ls,{argList});
current_function = cse;
return v;
}
void TArgWrapper::Mark()
{
if(this->marked) return;
this->marked = true;
this->callable->Mark();
GC::Mark(this->tag);
}
void TCallable::Mark()
{
if(this->marked) return;
this->marked=true;
GC::Mark(this->tag);
}
void TClosure::Mark()
{
if(this->marked) return;
this->marked=true;
this->file->Mark();
this->env->Mark();
this->closure->Mark();
GC::Mark(this->tag);
}
TClosure* TClosure::Create(GCList& ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
{
TClosure* closure = new TClosure();
closure->className="";
closure->ownScope=ownScope;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if(chunkId < file->chunks.size())
TArgWrapper *TArgWrapper::Create(GCList &ls, TCallable *callable) {
TArgWrapper *argWrapper = new TArgWrapper();
argWrapper->callable = callable;
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
}
TArgWrapper *TArgWrapper::Create(GCList *ls, TCallable *callable) {
TArgWrapper *argWrapper = new TArgWrapper();
argWrapper->callable = callable;
std::shared_ptr<GC> gc = ls->GetGC();
ls->Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
}
TObject TArgWrapper::Call(GCList &ls, std::vector<TObject> args) {
auto cse = current_function;
TList *argList = TList::Create(ls);
argList->items = args;
TObject v = this->callable->Call(ls, {argList});
current_function = cse;
return v;
}
void TArgWrapper::Mark() {
if (this->marked)
return;
this->marked = true;
this->callable->Mark();
GC::Mark(this->tag);
}
void TCallable::Mark() {
if (this->marked)
return;
this->marked = true;
GC::Mark(this->tag);
}
void TClosure::Mark() {
if (this->marked)
return;
this->marked = true;
this->file->Mark();
this->env->Mark();
this->closure->Mark();
GC::Mark(this->tag);
}
TClosure *TClosure::Create(GCList &ls, TEnvironment *env, TFile *file,
uint32_t chunkId, bool ownScope) {
TClosure *closure = new TClosure();
closure->className = "";
closure->ownScope = ownScope;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if (chunkId < file->chunks.size())
closure->closure = file->chunks[chunkId];
else throw VMException("ChunkId out of bounds.");
closure->env = env;
closure->file = file;
return closure;
}
TClosure* TClosure::Create(GCList* ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
{
TClosure* closure = new TClosure();
closure->className="";
closure->ownScope=ownScope;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if(chunkId < file->chunks.size())
else
throw VMException("ChunkId out of bounds.");
closure->env = env;
closure->file = file;
return closure;
}
TClosure *TClosure::Create(GCList *ls, TEnvironment *env, TFile *file,
uint32_t chunkId, bool ownScope) {
TClosure *closure = new TClosure();
closure->className = "";
closure->ownScope = ownScope;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if (chunkId < file->chunks.size())
closure->closure = file->chunks[chunkId];
else throw VMException("ChunkId out of bounds.");
closure->env = env;
closure->file = file;
return closure;
}
TObject TClosure::Call(GCList& ls,std::vector<TObject> args)
{
auto cse = current_function;
InterperterThread* thrd=InterperterThread::Create(ls);
thrd->AddCallStackEntry(ls,this, args);
else
throw VMException("ChunkId out of bounds.");
closure->env = env;
closure->file = file;
thrd->Execute(ls.GetGC());
return closure;
}
TObject v= thrd->call_stack_entries[0]->Pop(ls);
current_function = cse;
return v;
}
}
TObject TClosure::Call(GCList &ls, std::vector<TObject> args) {
auto cse = current_function;
InterperterThread *thrd = InterperterThread::Create(ls);
thrd->AddCallStackEntry(ls, this, args);
thrd->Execute(ls.GetGC());
TObject v = thrd->call_stack_entries[0]->Pop(ls);
current_function = cse;
return v;
}
} // namespace Tesses::CrossLang

View File

@@ -1,221 +1,206 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TDynamicDictionary* TDynamicDictionary::Create(GCList& ls,TCallable* callable)
{
namespace Tesses::CrossLang {
TDynamicDictionary *TDynamicDictionary::Create(GCList &ls,
TCallable *callable) {
TDynamicDictionary* dict=new TDynamicDictionary();
dict->cb = callable;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(dict);
_gc->Watch(dict);
return dict;
}
TDynamicDictionary* TDynamicDictionary::Create(GCList* ls,TCallable* callable)
{
TDynamicDictionary* dict=new TDynamicDictionary();
dict->cb = callable;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(dict);
_gc->Watch(dict);
return dict;
}
TDynamicDictionary *dict = new TDynamicDictionary();
dict->cb = callable;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(dict);
_gc->Watch(dict);
return dict;
}
TDynamicDictionary *TDynamicDictionary::Create(GCList *ls,
TCallable *callable) {
TDynamicDictionary *dict = new TDynamicDictionary();
dict->cb = callable;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(dict);
_gc->Watch(dict);
return dict;
}
void TDynamicDictionary::Mark()
{
if(this->marked) return;
this->marked=true;
this->cb->Mark();
}
void TDynamicDictionary::Mark() {
if (this->marked)
return;
this->marked = true;
this->cb->Mark();
}
TObject TDynamicDictionary::GetField(GCList& ls, std::string key)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "GetField");
dict->SetValue("Key", key);
ls.GetGC()->BarrierEnd();
return this->cb->Call(ls,{dict});
}
TObject TDynamicDictionary::GetField(GCList &ls, std::string key) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "GetField");
dict->SetValue("Key", key);
ls.GetGC()->BarrierEnd();
return this->cb->Call(ls, {dict});
}
TObject TDynamicDictionary::SetField(GCList& ls, std::string key, TObject value)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "SetField");
dict->SetValue("Key", key);
dict->SetValue("Value", value);
ls.GetGC()->BarrierEnd();
return this->cb->Call(ls,{dict});
}
TObject TDynamicDictionary::SetField(GCList &ls, std::string key,
TObject value) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "SetField");
dict->SetValue("Key", key);
dict->SetValue("Value", value);
ls.GetGC()->BarrierEnd();
return this->cb->Call(ls, {dict});
}
TObject TDynamicDictionary::CallMethod(GCList& ls, std::string name, std::vector<TObject> args)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "CallMethod");
dict->SetValue("Name", name);
auto argVal = TList::Create(ls);
argVal->items = args;
dict->SetValue("Arguments", argVal);
ls.GetGC()->BarrierEnd();
return this->cb->Call(ls,{dict});
}
TObject TDynamicDictionary::CallMethod(GCList &ls, std::string name,
std::vector<TObject> args) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "CallMethod");
dict->SetValue("Name", name);
auto argVal = TList::Create(ls);
argVal->items = args;
dict->SetValue("Arguments", argVal);
ls.GetGC()->BarrierEnd();
return this->cb->Call(ls, {dict});
}
TEnumerator* TDynamicDictionary::GetEnumerator(GCList& ls)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "GetEnumerator");
TEnumerator *TDynamicDictionary::GetEnumerator(GCList &ls) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "GetEnumerator");
ls.GetGC()->BarrierEnd();
ls.GetGC()->BarrierEnd();
return TEnumerator::CreateFromObject(ls,this->cb->Call(ls,{dict}));
}
bool TDictionary::MethodExists(GCList& ls,std::string method)
{
ls.GetGC()->BarrierBegin();
auto r = this->GetValue(method);
TCallable* callable;
bool res = GetObjectHeap(r,callable);
ls.GetGC()->BarrierEnd();
return res;
}
bool TDynamicDictionary::MethodExists(GCList& ls,std::string name)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "MethodExists");
dict->SetValue("Name", name);
return TEnumerator::CreateFromObject(ls, this->cb->Call(ls, {dict}));
}
bool TDictionary::MethodExists(GCList &ls, std::string method) {
ls.GetGC()->BarrierBegin();
auto r = this->GetValue(method);
TCallable *callable;
bool res = GetObjectHeap(r, callable);
ls.GetGC()->BarrierEnd();
return res;
}
bool TDynamicDictionary::MethodExists(GCList &ls, std::string name) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "MethodExists");
dict->SetValue("Name", name);
ls.GetGC()->BarrierEnd();
ls.GetGC()->BarrierEnd();
auto res = this->cb->Call(ls,{dict});
bool r2;
if(GetObject(res,r2)) return r2;
return false;
}
auto res = this->cb->Call(ls, {dict});
bool r2;
if (GetObject(res, r2))
return r2;
return false;
}
TDynamicDictionary::~TDynamicDictionary()
{
TDynamicDictionary::~TDynamicDictionary() {}
TObject TDictionary::CallMethod(GCList &ls, std::string key,
std::vector<TObject> args) {
ls.GetGC()->BarrierBegin();
auto res = this->GetValue(key);
ls.GetGC()->BarrierEnd();
TCallable *callable;
}
TObject TDictionary::CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
{
ls.GetGC()->BarrierBegin();
auto res = this->GetValue(key);
ls.GetGC()->BarrierEnd();
TCallable* callable;
if (GetObjectHeap(res, callable)) {
auto closure = dynamic_cast<TClosure *>(callable);
if (closure != nullptr && !closure->closure->args.empty() &&
closure->closure->args.front() == "this") {
std::vector<TObject> args2;
args2.push_back(this);
args2.insert(args2.end(), args.begin(), args.end());
return closure->Call(ls, args2);
if(GetObjectHeap(res,callable))
{
auto closure = dynamic_cast<TClosure*>(callable);
if(closure != nullptr && !closure->closure->args.empty() && closure->closure->args.front() == "this")
{
std::vector<TObject> args2;
args2.push_back(this);
args2.insert(args2.end(), args.begin(),args.end());
return closure->Call(ls,args2);
}
else
{
return callable->Call(ls,args);
}
}
return Undefined();
}
TObject TDictionary::CallMethodWithFatalError(GCList& ls, std::string key, std::vector<TObject> args)
{
ls.GetGC()->BarrierBegin();
auto res = this->GetValue(key);
ls.GetGC()->BarrierEnd();
TCallable* callable;
if(GetObjectHeap(res,callable))
{
auto closure = dynamic_cast<TClosure*>(callable);
if(closure != nullptr && !closure->closure->args.empty() && closure->closure->args.front() == "this")
{
std::vector<TObject> args2;
args2.push_back(this);
args2.insert(args2.end(), args.begin(),args.end());
return closure->CallWithFatalError(ls,args2);
}
else
{
return callable->CallWithFatalError(ls,args);
}
}
return Undefined();
}
void TDictionary::DeclareFunction(std::shared_ptr<GC> gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
gc->BarrierBegin();
GCList ls(gc);
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb));
gc->BarrierEnd();
}
void TDictionary::DeclareFunction(std::shared_ptr<GC> gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
gc->BarrierBegin();
GCList ls(gc);
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
gc->BarrierEnd();
}
TObject TDictionary::GetValue(std::string key)
{
if(this->items.empty()) return Undefined();
if(this->items.count(key) > 0)
return this->items[key];
return Undefined();
}
void TDictionary::SetValue(std::string key, TObject value)
{
if(std::holds_alternative<Undefined>(value))
{
if(this->items.count(key) > 0)
this->items.erase(key);
}
else
{
this->items[key] = value;
} else {
return callable->Call(ls, args);
}
}
bool TDictionary::HasValue(std::string key)
{
return this->items.count(key) > 0;
}
void TDictionary::Mark()
{
if(this->marked) return;
this->marked = true;
for(auto item : this->items)
{
GC::Mark(item.second);
return Undefined();
}
TObject TDictionary::CallMethodWithFatalError(GCList &ls, std::string key,
std::vector<TObject> args) {
ls.GetGC()->BarrierBegin();
auto res = this->GetValue(key);
ls.GetGC()->BarrierEnd();
TCallable *callable;
if (GetObjectHeap(res, callable)) {
auto closure = dynamic_cast<TClosure *>(callable);
if (closure != nullptr && !closure->closure->args.empty() &&
closure->closure->args.front() == "this") {
std::vector<TObject> args2;
args2.push_back(this);
args2.insert(args2.end(), args.begin(), args.end());
return closure->CallWithFatalError(ls, args2);
} else {
return callable->CallWithFatalError(ls, args);
}
}
TDictionary* TDictionary::Create(GCList* gc)
{
TDictionary* dict=new TDictionary();
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(dict);
_gc->Watch(dict);
return dict;
}
TDictionary* TDictionary::Create(GCList& gc)
{
TDictionary* dict=new TDictionary();
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(dict);
_gc->Watch(dict);
return dict;
}
return Undefined();
}
};
void TDictionary::DeclareFunction(
std::shared_ptr<GC> gc, std::string key, std::string documentation,
std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
gc->BarrierBegin();
GCList ls(gc);
this->SetValue(key,
TExternalMethod::Create(ls, documentation, argNames, cb));
gc->BarrierEnd();
}
void TDictionary::DeclareFunction(
std::shared_ptr<GC> gc, std::string key, std::string documentation,
std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy) {
gc->BarrierBegin();
GCList ls(gc);
this->SetValue(
key, TExternalMethod::Create(ls, documentation, argNames, cb, destroy));
gc->BarrierEnd();
}
TObject TDictionary::GetValue(std::string key) {
if (this->items.empty())
return Undefined();
if (this->items.count(key) > 0)
return this->items[key];
return Undefined();
}
void TDictionary::SetValue(std::string key, TObject value) {
if (std::holds_alternative<Undefined>(value)) {
if (this->items.count(key) > 0)
this->items.erase(key);
} else {
this->items[key] = value;
}
}
bool TDictionary::HasValue(std::string key) {
return this->items.count(key) > 0;
}
void TDictionary::Mark() {
if (this->marked)
return;
this->marked = true;
for (auto item : this->items) {
GC::Mark(item.second);
}
}
TDictionary *TDictionary::Create(GCList *gc) {
TDictionary *dict = new TDictionary();
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(dict);
_gc->Watch(dict);
return dict;
}
TDictionary *TDictionary::Create(GCList &gc) {
TDictionary *dict = new TDictionary();
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(dict);
_gc->Watch(dict);
return dict;
}
}; // namespace Tesses::CrossLang

View File

@@ -2,166 +2,146 @@
namespace Tesses::CrossLang {
EmbedStream::EmbedStream(std::shared_ptr<GC> gc, TFile* file, uint32_t resource)
{
this->offset = 0;
this->resource = resource;
this->file = CreateMarkedTObject(gc,file);
}
bool EmbedStream::CanRead()
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file))
{
if(this->resource >= file->resources.size()) return false;
if(this->offset >= file->resources[this->resource].size()) return false;
return true;
}
return false;
}
bool EmbedStream::CanSeek()
{
EmbedStream::EmbedStream(std::shared_ptr<GC> gc, TFile *file,
uint32_t resource) {
this->offset = 0;
this->resource = resource;
this->file = CreateMarkedTObject(gc, file);
}
bool EmbedStream::CanRead() {
TFile *file;
if (GetObjectHeap(this->file->GetObject(), file)) {
if (this->resource >= file->resources.size())
return false;
if (this->offset >= file->resources[this->resource].size())
return false;
return true;
}
bool EmbedStream::EndOfStream()
{
return !CanRead();
}
size_t EmbedStream::Read(uint8_t* buff, size_t len)
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file))
{
if(this->resource >= file->resources.size()) return 0;
auto flen = file->resources[this->resource].size();
if(this->offset >= flen) return 0;
len = std::min(len, std::min(
flen,
flen - this->offset
));
return false;
}
bool EmbedStream::CanSeek() { return true; }
bool EmbedStream::EndOfStream() { return !CanRead(); }
size_t EmbedStream::Read(uint8_t *buff, size_t len) {
TFile *file;
memcpy(buff,file->resources[this->resource].data() + this->offset,len);
this->offset += len;
return len;
}
return 0;
if (GetObjectHeap(this->file->GetObject(), file)) {
if (this->resource >= file->resources.size())
return 0;
auto flen = file->resources[this->resource].size();
if (this->offset >= flen)
return 0;
len = std::min(len, std::min(flen, flen - this->offset));
memcpy(buff, file->resources[this->resource].data() + this->offset,
len);
this->offset += len;
return len;
}
int64_t EmbedStream::GetPosition()
{
return (int64_t)this->offset;
return 0;
}
int64_t EmbedStream::GetPosition() { return (int64_t)this->offset; }
int64_t EmbedStream::GetLength() {
TFile *file;
if (GetObjectHeap(this->file->GetObject(), file)) {
if (this->resource >= file->resources.size())
return 0;
return (int64_t)file->resources[this->resource].size();
}
int64_t EmbedStream::GetLength()
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file))
{
if(this->resource >= file->resources.size()) return 0;
return (int64_t)file->resources[this->resource].size();
return 0;
}
void EmbedStream::Seek(int64_t pos,
Tesses::Framework::Streams::SeekOrigin whence) {
switch (whence) {
case Tesses::Framework::Streams::SeekOrigin::Begin:
this->offset = (uint32_t)pos;
break;
case Tesses::Framework::Streams::SeekOrigin::Current: {
int64_t cur = this->offset;
cur += pos;
this->offset = (uint32_t)cur;
} break;
case Tesses::Framework::Streams::SeekOrigin::End: {
TFile *file;
if (GetObjectHeap(this->file->GetObject(), file)) {
if (this->resource >= file->resources.size())
return;
int64_t cur = (int64_t)file->resources[this->resource].size();
cur += pos;
this->offset = (uint32_t)cur;
}
return 0;
break;
}
void EmbedStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
{
switch(whence)
{
case Tesses::Framework::Streams::SeekOrigin::Begin:
this->offset = (uint32_t)pos;
break;
case Tesses::Framework::Streams::SeekOrigin::Current:
{
int64_t cur = this->offset;
cur += pos;
this->offset = (uint32_t)cur;
}
break;
case Tesses::Framework::Streams::SeekOrigin::End:
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file))
{
if(this->resource >= file->resources.size()) return;
int64_t cur = (int64_t)file->resources[this->resource].size();
cur += pos;
this->offset = (uint32_t)cur;
}
break;
}
}
}
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path)
{
path = path.CollapseRelativeParents();
auto curEntry = this->dir->GetObject();
for(auto item : path.path)
{
TDictionary* dict;
if(GetObjectHeap(curEntry,dict) && dict->HasValue(item))
{
curEntry = dict->GetValue(item);
continue; //don't want to return undefined now do we
}
return Undefined();
}
return curEntry;
}
std::shared_ptr<Tesses::Framework::Streams::Stream> EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
{
if(mode != "r" && mode != "rb") return nullptr;
auto ent = getEntry(path);
TCallable* call;
if(GetObjectHeap(ent,call))
{
GCList ls(this->dir->GetGC());
auto fileO = call->Call(ls,{});
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetObject(fileO,strm)) return strm;
}
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path) {
path = path.CollapseRelativeParents();
auto curEntry = this->dir->GetObject();
for (auto item : path.path) {
TDictionary *dict;
if (GetObjectHeap(curEntry, dict) && dict->HasValue(item)) {
curEntry = dict->GetValue(item);
continue; // don't want to return undefined now do we
}
return Undefined();
}
return curEntry;
}
std::shared_ptr<Tesses::Framework::Streams::Stream>
EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path,
std::string mode) {
if (mode != "r" && mode != "rb")
return nullptr;
}
bool EmbedDirectory::Stat(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatData& data)
{
auto ent = getEntry(path);
auto ent = getEntry(path);
TCallable *call;
if (GetObjectHeap(ent, call)) {
GCList ls(this->dir->GetGC());
auto fileO = call->Call(ls, {});
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if (GetObject(fileO, strm))
return strm;
}
return nullptr;
}
TDictionary* dict;
if(GetObjectHeap(ent,dict))
{
data.Size = 0;
data.Mode = Tesses::Framework::Filesystem::MODE_DIRECTORY | 0755;
data.BlockCount = 0;
data.BlockSize = 0;
data.Device = 0;
data.DeviceId = 0;
data.GroupId = 0;
data.HardLinks = 1;
data.Inode = 0;
data.LastAccess = Tesses::Framework::Date::DateTime(0);
data.LastModified = Tesses::Framework::Date::DateTime(0);
data.LastStatus = Tesses::Framework::Date::DateTime(0);
data.UserId = 0;
return true;
}
TCallable* cal;
if(GetObjectHeap(ent, cal))
{
GCList ls(this->dir->GetGC());
auto fileO= cal->Call(ls, {});
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetObject(fileO,strm)) {
bool EmbedDirectory::Stat(Tesses::Framework::Filesystem::VFSPath path,
Tesses::Framework::Filesystem::StatData &data) {
auto ent = getEntry(path);
TDictionary *dict;
if (GetObjectHeap(ent, dict)) {
data.Size = 0;
data.Mode = Tesses::Framework::Filesystem::MODE_DIRECTORY | 0755;
data.BlockCount = 0;
data.BlockSize = 0;
data.Device = 0;
data.DeviceId = 0;
data.GroupId = 0;
data.HardLinks = 1;
data.Inode = 0;
data.LastAccess = Tesses::Framework::Date::DateTime(0);
data.LastModified = Tesses::Framework::Date::DateTime(0);
data.LastStatus = Tesses::Framework::Date::DateTime(0);
data.UserId = 0;
return true;
}
TCallable *cal;
if (GetObjectHeap(ent, cal)) {
GCList ls(this->dir->GetGC());
auto fileO = cal->Call(ls, {});
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if (GetObject(fileO, strm)) {
data.Size = (uint64_t)strm->GetLength();
data.Mode = Tesses::Framework::Filesystem::MODE_REGULAR | 0755;
data.Mode = Tesses::Framework::Filesystem::MODE_REGULAR | 0755;
data.BlockSize = 512;
data.BlockCount = data.Size / data.BlockSize;
data.Device = 0;
data.DeviceId = 0;
data.GroupId = 0;
@@ -171,84 +151,70 @@ namespace Tesses::CrossLang {
data.LastModified = Tesses::Framework::Date::DateTime(0);
data.LastStatus = Tesses::Framework::Date::DateTime(0);
data.UserId = 0;
return true;
}
}
return false;
}
}
return false;
}
class DICT_DIRENUM
{
GCList ls;
TDictionary* dict;
std::map<std::string, Tesses::CrossLang::TObject>::iterator current;
bool hasStarted = false;
public:
std::string GetCurrent()
{
return this->current->first;
}
DICT_DIRENUM(std::shared_ptr<GC> gc, TDictionary* dict) : ls(gc), dict(dict)
{
ls.Add(dict);
}
bool MoveNext()
{
if(!this->hasStarted)
{
this->hasStarted=true;
this->current = this->dict->items.begin();
return !this->dict->items.empty();
}
else
{
this->current++;
return this->current != this->dict->items.end();
}
}
class DICT_DIRENUM {
GCList ls;
TDictionary *dict;
std::map<std::string, Tesses::CrossLang::TObject>::iterator current;
bool hasStarted = false;
};
Tesses::Framework::Filesystem::VFSPathEnumerator EmbedDirectory::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
{
auto ent = getEntry(path);
TDictionary* dict;
if(GetObjectHeap(ent,dict))
{
DICT_DIRENUM* dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
Tesses::Framework::Filesystem::VFSPathEnumerator er(
[dir2,path](Tesses::Framework::Filesystem::VFSPath& path2)->bool {
if(dir2->MoveNext())
{
path2 = path / dir2->GetCurrent();
return true;
}
return false;
},
[dir2]()->void {
delete dir2;
}
);
return er;
public:
std::string GetCurrent() { return this->current->first; }
DICT_DIRENUM(std::shared_ptr<GC> gc, TDictionary *dict)
: ls(gc), dict(dict) {
ls.Add(dict);
}
bool MoveNext() {
if (!this->hasStarted) {
this->hasStarted = true;
this->current = this->dict->items.begin();
return !this->dict->items.empty();
} else {
this->current++;
return this->current != this->dict->items.end();
}
return Tesses::Framework::Filesystem::VFSPathEnumerator();
}
};
EmbedDirectory::EmbedDirectory(std::shared_ptr<GC> gc, TDictionary* dict)
{
this->dir = CreateMarkedTObject(gc, dict);
Tesses::Framework::Filesystem::VFSPathEnumerator
EmbedDirectory::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path) {
auto ent = getEntry(path);
TDictionary *dict;
if (GetObjectHeap(ent, dict)) {
DICT_DIRENUM *dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
Tesses::Framework::Filesystem::VFSPathEnumerator er(
[dir2,
path](Tesses::Framework::Filesystem::VFSPath &path2) -> bool {
if (dir2->MoveNext()) {
path2 = path / dir2->GetCurrent();
return true;
}
return false;
},
[dir2]() -> void { delete dir2; });
return er;
}
std::string EmbedDirectory::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path)
{
return path.ToString();
}
Tesses::Framework::Filesystem::VFSPath EmbedDirectory::SystemToVFSPath(std::string path)
{
return path;
}
}
return Tesses::Framework::Filesystem::VFSPathEnumerator();
}
EmbedDirectory::EmbedDirectory(std::shared_ptr<GC> gc, TDictionary *dict) {
this->dir = CreateMarkedTObject(gc, dict);
}
std::string
EmbedDirectory::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path) {
return path.ToString();
}
Tesses::Framework::Filesystem::VFSPath
EmbedDirectory::SystemToVFSPath(std::string path) {
return path;
}
} // namespace Tesses::CrossLang

View File

@@ -1,54 +1,64 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
TExternalMethod::TExternalMethod(std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::string documentation, std::vector<std::string> argNames,std::function<void()> destroy)
{
this->cb = cb;
this->args = argNames;
this->documentation = documentation;
this->destroy = destroy;
}
TExternalMethod* TExternalMethod::Create(GCList& ls,std::string documentation,std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
auto gc = ls.GetGC();
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,destroy);
ls.Add(method);
gc->Watch(method);
return method;
}
TExternalMethod* TExternalMethod::Create(GCList* ls,std::string documentation, std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
auto gc = ls->GetGC();
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,destroy);
ls->Add(method);
gc->Watch(method);
return method;
}
TExternalMethod* TExternalMethod::Create(GCList& ls,std::string documentation, std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
auto gc = ls.GetGC();
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,[]()->void{});
ls.Add(method);
gc->Watch(method);
return method;
}
TExternalMethod* TExternalMethod::Create(GCList* ls,std::string documentation, std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
auto gc = ls->GetGC();
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,[]()->void{});
ls->Add(method);
gc->Watch(method);
return method;
}
TObject TExternalMethod::Call(GCList& ls, std::vector<TObject> args)
{
if(cb == nullptr) return Undefined();
return this->cb(ls,args);
}
TExternalMethod::~TExternalMethod()
{
if(this->destroy != nullptr)
namespace Tesses::CrossLang {
TExternalMethod::TExternalMethod(
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::string documentation, std::vector<std::string> argNames,
std::function<void()> destroy) {
this->cb = cb;
this->args = argNames;
this->documentation = documentation;
this->destroy = destroy;
}
TExternalMethod *TExternalMethod::Create(
GCList &ls, std::string documentation, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy) {
auto gc = ls.GetGC();
TExternalMethod *method =
new TExternalMethod(cb, documentation, argNames, destroy);
ls.Add(method);
gc->Watch(method);
return method;
}
TExternalMethod *TExternalMethod::Create(
GCList *ls, std::string documentation, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy) {
auto gc = ls->GetGC();
TExternalMethod *method =
new TExternalMethod(cb, documentation, argNames, destroy);
ls->Add(method);
gc->Watch(method);
return method;
}
TExternalMethod *TExternalMethod::Create(
GCList &ls, std::string documentation, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
auto gc = ls.GetGC();
TExternalMethod *method =
new TExternalMethod(cb, documentation, argNames, []() -> void {});
ls.Add(method);
gc->Watch(method);
return method;
}
TExternalMethod *TExternalMethod::Create(
GCList *ls, std::string documentation, std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
auto gc = ls->GetGC();
TExternalMethod *method =
new TExternalMethod(cb, documentation, argNames, []() -> void {});
ls->Add(method);
gc->Watch(method);
return method;
}
TObject TExternalMethod::Call(GCList &ls, std::vector<TObject> args) {
if (cb == nullptr)
return Undefined();
return this->cb(ls, args);
}
TExternalMethod::~TExternalMethod() {
if (this->destroy != nullptr)
this->destroy();
}
}
}
} // namespace Tesses::CrossLang

View File

@@ -1,424 +1,393 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
bool TYieldEnumerator::MoveNext(std::shared_ptr<GC> ls)
{
CallStackEntry* ent;
GCList ls2(ls);
if(!this->hasStarted)
{
TClosure* clos;
if(!GetObjectHeap(this->enumerator,clos)) return false;
auto _enumerator= clos->Call(ls2,{});
namespace Tesses::CrossLang {
bool TYieldEnumerator::MoveNext(std::shared_ptr<GC> ls) {
CallStackEntry *ent;
GCList ls2(ls);
if (!this->hasStarted) {
TClosure *clos;
if (!GetObjectHeap(this->enumerator, clos))
return false;
auto _enumerator = clos->Call(ls2, {});
ls->BarrierBegin();
this->enumerator = _enumerator;
this->hasStarted = true;
ls->BarrierEnd();
} else {
if (GetObjectHeap(this->enumerator, ent)) {
auto _enumerator = ent->Resume(ls2);
ls->BarrierBegin();
this->enumerator = _enumerator;
this->hasStarted=true;
ls->BarrierEnd();
}
else {
if(GetObjectHeap(this->enumerator,ent))
{
auto _enumerator= ent->Resume(ls2);
ls->BarrierBegin();
this->enumerator = _enumerator;
ls->BarrierEnd();
} else return false;
}
if(GetObjectHeap(this->enumerator,ent))
{
ls->BarrierBegin();
this->current = ent->Pop(ls2);
ls->BarrierEnd();
return true;
}
return false;
}
TObject TYieldEnumerator::GetCurrent(GCList& ls)
{
ls.Add(this->current);
return this->current;
}
void TYieldEnumerator::Mark()
{
if(this->marked) return;
this->marked=true;
GC::Mark(this->current);
GC::Mark(this->enumerator);
}
TYieldEnumerator* TYieldEnumerator::Create(GCList& ls,TObject v)
{
TYieldEnumerator* yieldEnum = new TYieldEnumerator();
yieldEnum->current=nullptr;
yieldEnum->hasStarted=false;
yieldEnum->enumerator = v;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(yieldEnum);
_gc->Watch(yieldEnum);
return yieldEnum;
}
TYieldEnumerator* TYieldEnumerator::Create(GCList* ls,TObject v)
{
TYieldEnumerator* yieldEnum = new TYieldEnumerator();
yieldEnum->current=nullptr;
yieldEnum->hasStarted=false;
yieldEnum->enumerator = v;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(yieldEnum);
_gc->Watch(yieldEnum);
return yieldEnum;
} else
return false;
}
bool TCustomEnumerator::MoveNext(std::shared_ptr<GC> ls)
{
GCList ls2(ls);
auto res = this->dict->CallMethod(ls2,"MoveNext",{});
bool out;
if(GetObject(res,out)) return out;
return false;
}
TObject TCustomEnumerator::GetCurrent(GCList& ls)
{
TObject res=Undefined();
ls.GetGC()->BarrierBegin();
auto getCurrent = this->dict->GetValue("getCurrent");
TCallable* call;
if(GetObjectHeap(getCurrent,call))
{
ls.GetGC()->BarrierEnd();
res=call->Call(ls,{});
ls.GetGC()->BarrierBegin();
}else{
res=this->dict->GetValue("Current");
}
if (GetObjectHeap(this->enumerator, ent)) {
ls->BarrierBegin();
this->current = ent->Pop(ls2);
ls->BarrierEnd();
return true;
}
return false;
}
TObject TYieldEnumerator::GetCurrent(GCList &ls) {
ls.Add(this->current);
return this->current;
}
void TYieldEnumerator::Mark() {
if (this->marked)
return;
this->marked = true;
GC::Mark(this->current);
GC::Mark(this->enumerator);
}
TYieldEnumerator *TYieldEnumerator::Create(GCList &ls, TObject v) {
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
yieldEnum->current = nullptr;
yieldEnum->hasStarted = false;
yieldEnum->enumerator = v;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(yieldEnum);
_gc->Watch(yieldEnum);
return yieldEnum;
}
TYieldEnumerator *TYieldEnumerator::Create(GCList *ls, TObject v) {
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
yieldEnum->current = nullptr;
yieldEnum->hasStarted = false;
yieldEnum->enumerator = v;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(yieldEnum);
_gc->Watch(yieldEnum);
return yieldEnum;
}
bool TCustomEnumerator::MoveNext(std::shared_ptr<GC> ls) {
GCList ls2(ls);
auto res = this->dict->CallMethod(ls2, "MoveNext", {});
bool out;
if (GetObject(res, out))
return out;
return false;
}
TObject TCustomEnumerator::GetCurrent(GCList &ls) {
TObject res = Undefined();
ls.GetGC()->BarrierBegin();
auto getCurrent = this->dict->GetValue("getCurrent");
TCallable *call;
if (GetObjectHeap(getCurrent, call)) {
ls.GetGC()->BarrierEnd();
return res;
res = call->Call(ls, {});
ls.GetGC()->BarrierBegin();
} else {
res = this->dict->GetValue("Current");
}
void TCustomEnumerator::Mark()
{
if(this->marked) return;
this->dict->Mark();
}
TCustomEnumerator* TCustomEnumerator::Create(GCList* ls, TDictionary* dict)
{
TCustomEnumerator* customEnum = new TCustomEnumerator();
customEnum->dict = dict;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(customEnum);
_gc->Watch(customEnum);
return customEnum;
}
TCustomEnumerator* TCustomEnumerator::Create(GCList& ls, TDictionary* dict)
{
TCustomEnumerator* customEnum = new TCustomEnumerator();
customEnum->dict = dict;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(customEnum);
_gc->Watch(customEnum);
return customEnum;
}
TEnumerator* TEnumerator::CreateFromObject(GCList& ls, TObject obj)
{
std::string str;
TList* mls;
TDynamicList* dynList;
TDynamicDictionary* dynDict;
TDictionary* dict;
TEnumerator* enumerator;
if(GetObject(obj,str))
{
return TStringEnumerator::Create(ls, str);
ls.GetGC()->BarrierEnd();
return res;
}
void TCustomEnumerator::Mark() {
if (this->marked)
return;
this->dict->Mark();
}
TCustomEnumerator *TCustomEnumerator::Create(GCList *ls, TDictionary *dict) {
TCustomEnumerator *customEnum = new TCustomEnumerator();
customEnum->dict = dict;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(customEnum);
_gc->Watch(customEnum);
return customEnum;
}
TCustomEnumerator *TCustomEnumerator::Create(GCList &ls, TDictionary *dict) {
TCustomEnumerator *customEnum = new TCustomEnumerator();
customEnum->dict = dict;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(customEnum);
_gc->Watch(customEnum);
return customEnum;
}
TEnumerator *TEnumerator::CreateFromObject(GCList &ls, TObject obj) {
std::string str;
TList *mls;
TDynamicList *dynList;
TDynamicDictionary *dynDict;
TDictionary *dict;
TEnumerator *enumerator;
TQueryable *q;
if (GetObject(obj, str)) {
return TStringEnumerator::Create(ls, str);
} else if (GetObjectHeap(obj, mls)) {
return TListEnumerator::Create(ls, mls);
} else if (GetObjectHeap(obj, dynList)) {
return TDynamicListEnumerator::Create(ls, dynList);
} else if (GetObjectHeap(obj, dict)) {
auto res = dict->CallMethod(ls, "GetEnumerator", {});
if (GetObjectHeap(res, dict)) {
return TCustomEnumerator::Create(ls, dict);
} else if (GetObjectHeap(res, enumerator)) {
return enumerator;
}
else if(GetObjectHeap(obj,mls))
{
return TListEnumerator::Create(ls,mls);
}
else if(GetObjectHeap(obj,dynList))
{
return TDynamicListEnumerator::Create(ls,dynList);
}
else if(GetObjectHeap(obj,dict))
{
auto res=dict->CallMethod(ls,"GetEnumerator",{});
if(GetObjectHeap(res,dict))
{
return TCustomEnumerator::Create(ls,dict);
}
else if(GetObjectHeap(res,enumerator))
{
return enumerator;
}
}
return nullptr;
} else if (GetObjectHeap(obj, q)) {
return q->GetEnumerator(ls);
} else if (GetObjectHeap(obj, enumerator)) {
return enumerator;
}
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList& ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
{
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator();
vfspathe->enumerator = enumerator;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(vfspathe);
_gc->Watch(vfspathe);
return vfspathe;
return nullptr;
}
TVFSPathEnumerator *TVFSPathEnumerator::Create(
GCList &ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) {
TVFSPathEnumerator *vfspathe = new TVFSPathEnumerator();
vfspathe->enumerator = enumerator;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(vfspathe);
_gc->Watch(vfspathe);
return vfspathe;
}
TVFSPathEnumerator *TVFSPathEnumerator::Create(
GCList *ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) {
TVFSPathEnumerator *vfspathe = new TVFSPathEnumerator();
vfspathe->enumerator = enumerator;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(vfspathe);
_gc->Watch(vfspathe);
return vfspathe;
}
bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls) {
return enumerator.MoveNext();
}
TObject TVFSPathEnumerator::GetCurrent(GCList &ls) {
return enumerator.Current;
}
TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList &ls,
TDictionary *dict) {
TDictionaryEnumerator *dicte = new TDictionaryEnumerator();
dicte->dict = dict;
dicte->hasStarted = false;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(dicte);
_gc->Watch(dicte);
return dicte;
}
TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList *ls,
TDictionary *dict) {
TDictionaryEnumerator *dicte = new TDictionaryEnumerator();
dicte->dict = dict;
dicte->hasStarted = false;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(dicte);
_gc->Watch(dicte);
return dicte;
}
bool TDictionaryEnumerator::MoveNext(std::shared_ptr<GC> ls) {
if (!this->hasStarted) {
this->hasStarted = true;
this->ittr = this->dict->items.begin();
return !this->dict->items.empty();
} else {
this->ittr++;
return this->ittr != this->dict->items.end();
}
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList* ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
{
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator();
vfspathe->enumerator = enumerator;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(vfspathe);
_gc->Watch(vfspathe);
return vfspathe;
}
bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls)
{
return enumerator.MoveNext();
}
TObject TVFSPathEnumerator::GetCurrent(GCList& ls)
{
return enumerator.Current;
}
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList& ls, TDictionary* dict)
{
TDictionaryEnumerator* dicte=new TDictionaryEnumerator();
dicte->dict = dict;
dicte->hasStarted=false;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(dicte);
_gc->Watch(dicte);
return dicte;
}
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList* ls, TDictionary* dict)
{
TDictionaryEnumerator* dicte=new TDictionaryEnumerator();
dicte->dict = dict;
dicte->hasStarted=false;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(dicte);
_gc->Watch(dicte);
return dicte;
}
bool TDictionaryEnumerator::MoveNext(std::shared_ptr<GC> ls)
{
if(!this->hasStarted)
{
this->hasStarted=true;
this->ittr = this->dict->items.begin();
return !this->dict->items.empty();
}
else
{
this->ittr++;
return this->ittr != this->dict->items.end();
}
}
TObject TDictionaryEnumerator::GetCurrent(GCList& ls)
{
if(!this->hasStarted) return Undefined();
if(this->ittr != this->dict->items.end())
{
ls.GetGC()->BarrierBegin();
std::string key = this->ittr->first;
TObject value = this->ittr->second;
auto kvp = TDictionary::Create(ls);
kvp->SetValue("Key",key);
kvp->SetValue("Value",value);
ls.GetGC()->BarrierEnd();
return kvp;
}
}
TObject TDictionaryEnumerator::GetCurrent(GCList &ls) {
if (!this->hasStarted)
return Undefined();
}
void TDictionaryEnumerator::Mark()
{
if(this->marked) return;
this->marked=true;
this->dict->Mark();
}
TListEnumerator* TListEnumerator::Create(GCList& ls, TList* list)
{
TListEnumerator* liste=new TListEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
}
TListEnumerator* TListEnumerator::Create(GCList* ls, TList* list)
{
TListEnumerator* liste=new TListEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
}
bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls)
{
this->index++;
return this->index >= 0 && this->index < this->ls->Count();
}
TObject TListEnumerator::GetCurrent(GCList& ls)
{
if(this->index < -1) return nullptr;
if(this->ls->Count() == 0) return nullptr;
if(this->index >= this->ls->Count()) return nullptr;
if (this->ittr != this->dict->items.end()) {
ls.GetGC()->BarrierBegin();
TObject o = this->ls->Get(index);
std::string key = this->ittr->first;
TObject value = this->ittr->second;
auto kvp = TDictionary::Create(ls);
kvp->SetValue("Key", key);
kvp->SetValue("Value", value);
ls.GetGC()->BarrierEnd();
return o;
}
void TListEnumerator::Mark()
{
if(this->marked) return;
this->marked = true;
this->ls->Mark();
return kvp;
}
return Undefined();
}
void TDictionaryEnumerator::Mark() {
if (this->marked)
return;
this->marked = true;
this->dict->Mark();
}
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList& ls, TAssociativeArray* list)
{
TAssociativeArrayEnumerator* liste=new TAssociativeArrayEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
}
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList* ls, TAssociativeArray* list)
{
TAssociativeArrayEnumerator* liste=new TAssociativeArrayEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
}
bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls)
{
this->index++;
return this->index >= 0 && this->index < this->ls->Count();
}
TObject TAssociativeArrayEnumerator::GetCurrent(GCList& ls)
{
if(this->index < -1) return nullptr;
if(this->ls->Count() == 0) return nullptr;
if(this->index >= this->ls->Count()) return nullptr;
ls.GetGC()->BarrierBegin();
TDictionary* dict = TDictionary::Create(ls);
dict->SetValue("Key",this->ls->GetKey(this->index));
dict->SetValue("Value",this->ls->GetValue(this->index));
ls.GetGC()->BarrierEnd();
return dict;
}
void TAssociativeArrayEnumerator::Mark()
{
if(this->marked) return;
this->marked = true;
this->ls->Mark();
}
TListEnumerator *TListEnumerator::Create(GCList &ls, TList *list) {
TListEnumerator *liste = new TListEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
}
TListEnumerator *TListEnumerator::Create(GCList *ls, TList *list) {
TListEnumerator *liste = new TListEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
}
bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
this->index++;
return this->index >= 0 && this->index < this->ls->Count();
}
TObject TListEnumerator::GetCurrent(GCList &ls) {
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList& ls, TDynamicList* list)
{
TDynamicListEnumerator* liste=new TDynamicListEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
}
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList* ls, TDynamicList* list)
{
TDynamicListEnumerator* liste=new TDynamicListEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
}
bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls)
{
this->index++;
GCList ls2(ls);
return this->index >= 0 && this->index < this->ls->Count(ls2);
}
TObject TDynamicListEnumerator::GetCurrent(GCList& ls)
{
if(this->index < -1) return nullptr;
auto r = this->ls->Count(ls);
if(r == 0) return nullptr;
if(this->index >= r) return nullptr;
ls.GetGC()->BarrierBegin();
TObject o = this->ls->GetAt(ls,index);
ls.GetGC()->BarrierEnd();
return o;
}
void TDynamicListEnumerator::Mark()
{
if(this->marked) return;
this->marked = true;
this->ls->Mark();
}
TStringEnumerator* TStringEnumerator::Create(GCList& ls,std::string str)
{
TStringEnumerator* stre=new TStringEnumerator();
stre->str = str;
stre->hasStarted=false;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(stre);
_gc->Watch(stre);
return stre;
}
TStringEnumerator* TStringEnumerator::Create(GCList* ls,std::string str)
{
TStringEnumerator* stre=new TStringEnumerator();
stre->str = str;
stre->hasStarted=false;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(stre);
_gc->Watch(stre);
return stre;
}
bool TStringEnumerator::MoveNext(std::shared_ptr<GC> ls)
{
if(!this->hasStarted)
{
this->hasStarted=true;
this->index = 0;
return !this->str.empty();
}
else
{
if(this->index >= this->str.size()) return false;
this->index++;
return this->index < this->str.size();
}
}
TObject TStringEnumerator::GetCurrent(GCList& ls)
{
if(!this->hasStarted) return nullptr;
if(this->index < this->str.size()) return this->str[this->index];
if (this->index < -1)
return nullptr;
}
if (this->ls->Count() == 0)
return nullptr;
if (this->index >= this->ls->Count())
return nullptr;
ls.GetGC()->BarrierBegin();
TObject o = this->ls->Get(index);
ls.GetGC()->BarrierEnd();
return o;
}
void TListEnumerator::Mark() {
if (this->marked)
return;
this->marked = true;
this->ls->Mark();
}
};
TAssociativeArrayEnumerator *
TAssociativeArrayEnumerator::Create(GCList &ls, TAssociativeArray *list) {
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
}
TAssociativeArrayEnumerator *
TAssociativeArrayEnumerator::Create(GCList *ls, TAssociativeArray *list) {
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
}
bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls) {
this->index++;
return this->index >= 0 && this->index < this->ls->Count();
}
TObject TAssociativeArrayEnumerator::GetCurrent(GCList &ls) {
if (this->index < -1)
return nullptr;
if (this->ls->Count() == 0)
return nullptr;
if (this->index >= this->ls->Count())
return nullptr;
ls.GetGC()->BarrierBegin();
TDictionary *dict = TDictionary::Create(ls);
dict->SetValue("Key", this->ls->GetKey(this->index));
dict->SetValue("Value", this->ls->GetValue(this->index));
ls.GetGC()->BarrierEnd();
return dict;
}
void TAssociativeArrayEnumerator::Mark() {
if (this->marked)
return;
this->marked = true;
this->ls->Mark();
}
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList &ls,
TDynamicList *list) {
TDynamicListEnumerator *liste = new TDynamicListEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
}
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList *ls,
TDynamicList *list) {
TDynamicListEnumerator *liste = new TDynamicListEnumerator();
liste->ls = list;
liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
}
bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
this->index++;
GCList ls2(ls);
return this->index >= 0 && this->index < this->ls->Count(ls2);
}
TObject TDynamicListEnumerator::GetCurrent(GCList &ls) {
if (this->index < -1)
return nullptr;
auto r = this->ls->Count(ls);
if (r == 0)
return nullptr;
if (this->index >= r)
return nullptr;
ls.GetGC()->BarrierBegin();
TObject o = this->ls->GetAt(ls, index);
ls.GetGC()->BarrierEnd();
return o;
}
void TDynamicListEnumerator::Mark() {
if (this->marked)
return;
this->marked = true;
this->ls->Mark();
}
TStringEnumerator *TStringEnumerator::Create(GCList &ls, std::string str) {
TStringEnumerator *stre = new TStringEnumerator();
stre->str = str;
stre->hasStarted = false;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(stre);
_gc->Watch(stre);
return stre;
}
TStringEnumerator *TStringEnumerator::Create(GCList *ls, std::string str) {
TStringEnumerator *stre = new TStringEnumerator();
stre->str = str;
stre->hasStarted = false;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(stre);
_gc->Watch(stre);
return stre;
}
bool TStringEnumerator::MoveNext(std::shared_ptr<GC> ls) {
if (!this->hasStarted) {
this->hasStarted = true;
this->index = 0;
return !this->str.empty();
} else {
if (this->index >= this->str.size())
return false;
this->index++;
return this->index < this->str.size();
}
}
TObject TStringEnumerator::GetCurrent(GCList &ls) {
if (!this->hasStarted)
return nullptr;
if (this->index < this->str.size())
return this->str[this->index];
return nullptr;
}
}; // namespace Tesses::CrossLang

View File

@@ -1,223 +1,184 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TDynamicList* TDynamicList::Create(GCList& ls,TCallable* callable)
{
TDynamicList* list=new TDynamicList();
list->cb = callable;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(list);
_gc->Watch(list);
return list;
}
TDynamicList* TDynamicList::Create(GCList* ls,TCallable* callable)
{
TDynamicList* list=new TDynamicList();
list->cb = callable;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(list);
_gc->Watch(list);
return list;
}
TDynamicList *TDynamicList::Create(GCList &ls, TCallable *callable) {
TDynamicList *list = new TDynamicList();
list->cb = callable;
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(list);
_gc->Watch(list);
return list;
}
TDynamicList *TDynamicList::Create(GCList *ls, TCallable *callable) {
TDynamicList *list = new TDynamicList();
list->cb = callable;
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(list);
_gc->Watch(list);
return list;
}
void TDynamicList::Mark()
{
if(this->marked) return;
this->marked=true;
this->cb->Mark();
}
void TDynamicList::Mark() {
if (this->marked)
return;
this->marked = true;
this->cb->Mark();
}
int64_t TDynamicList::Count(GCList& ls)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Count");
ls.GetGC()->BarrierEnd();
auto res = cb->Call(ls,{dict});
int64_t n;
if(GetObject(res,n)) return n;
return 0;
}
TObject TDynamicList::Add(GCList& ls, TObject v)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Add");
dict->SetValue("Value",v);
ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict});
}
TObject TDynamicList::Insert(GCList& ls, int64_t index, TObject v)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Insert");
dict->SetValue("Index",index);
dict->SetValue("Value",v);
ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict});
}
TObject TDynamicList::Clear(GCList& ls)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Clear");
ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict});
}
TObject TDynamicList::Remove(GCList& ls, TObject obj)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Remove");
dict->SetValue("Value", obj);
ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict});
}
TObject TDynamicList::RemoveAllEqual(GCList& ls, TObject obj)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "RemoveAllEqual");
dict->SetValue("Value", obj);
ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict});
}
TObject TDynamicList::RemoveAt(GCList& ls, int64_t index)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "RemoveAt");
dict->SetValue("Index", index);
ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict});
}
TObject TDynamicList::ToString(GCList& ls)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "ToString");
ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict});
}
int64_t TDynamicList::Count(GCList &ls) {
TObject TDynamicList::GetAt(GCList& ls, int64_t index)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Count");
ls.GetGC()->BarrierEnd();
auto res = cb->Call(ls, {dict});
int64_t n;
if (GetObject(res, n))
return n;
return 0;
}
TObject TDynamicList::Add(GCList &ls, TObject v) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "GetAt");
dict->SetValue("Index",index);
ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict});
}
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Add");
dict->SetValue("Value", v);
ls.GetGC()->BarrierEnd();
return cb->Call(ls, {dict});
}
TObject TDynamicList::Insert(GCList &ls, int64_t index, TObject v) {
TObject TDynamicList::SetAt(GCList& ls, int64_t index, TObject val)
{
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "SetAt");
dict->SetValue("Index",index);
dict->SetValue("Value",val);
ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict});
}
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Insert");
dict->SetValue("Index", index);
dict->SetValue("Value", v);
ls.GetGC()->BarrierEnd();
return cb->Call(ls, {dict});
}
TObject TDynamicList::Clear(GCList &ls) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Clear");
ls.GetGC()->BarrierEnd();
return cb->Call(ls, {dict});
}
TObject TDynamicList::Remove(GCList &ls, TObject obj) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Remove");
dict->SetValue("Value", obj);
ls.GetGC()->BarrierEnd();
TDynamicList::~TDynamicList()
{
return cb->Call(ls, {dict});
}
TObject TDynamicList::RemoveAllEqual(GCList &ls, TObject obj) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "RemoveAllEqual");
dict->SetValue("Value", obj);
ls.GetGC()->BarrierEnd();
}
return cb->Call(ls, {dict});
}
TObject TDynamicList::RemoveAt(GCList &ls, int64_t index) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "RemoveAt");
dict->SetValue("Index", index);
ls.GetGC()->BarrierEnd();
TByteArray* TByteArray::Create(GCList& ls)
{
TByteArray* arr=new TByteArray();
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(arr);
_gc->Watch(arr);
return arr;
}
return cb->Call(ls, {dict});
}
TObject TDynamicList::ToString(GCList &ls) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "ToString");
ls.GetGC()->BarrierEnd();
TByteArray* TByteArray::Create(GCList* ls)
{
TByteArray* arr=new TByteArray();
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(arr);
_gc->Watch(arr);
return arr;
return cb->Call(ls, {dict});
}
TObject TDynamicList::GetAt(GCList &ls, int64_t index) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "GetAt");
dict->SetValue("Index", index);
ls.GetGC()->BarrierEnd();
return cb->Call(ls, {dict});
}
TObject TDynamicList::SetAt(GCList &ls, int64_t index, TObject val) {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "SetAt");
dict->SetValue("Index", index);
dict->SetValue("Value", val);
ls.GetGC()->BarrierEnd();
return cb->Call(ls, {dict});
}
TDynamicList::~TDynamicList() {}
TByteArray *TByteArray::Create(GCList &ls) {
TByteArray *arr = new TByteArray();
std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(arr);
_gc->Watch(arr);
return arr;
}
TByteArray *TByteArray::Create(GCList *ls) {
TByteArray *arr = new TByteArray();
std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(arr);
_gc->Watch(arr);
return arr;
}
TList *TList::Create(GCList *gc) {
TList *list = new TList();
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(list);
_gc->Watch(list);
return list;
}
TList *TList::Create(GCList &gc) {
TList *list = new TList();
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(list);
_gc->Watch(list);
return list;
}
void TList::Add(TObject value) { this->items.push_back(value); }
void TList::Set(int64_t index, TObject value) {
if (index >= 0 && index < this->Count()) {
this->items[index] = value;
}
TList* TList::Create(GCList* gc)
{
TList* list=new TList();
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(list);
_gc->Watch(list);
return list;
}
TObject TList::Get(int64_t index) {
if (index >= 0 && index < this->Count()) {
return this->items[index];
}
TList* TList::Create(GCList& gc)
{
TList* list=new TList();
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(list);
_gc->Watch(list);
return list;
return Undefined();
}
int64_t TList::Count() { return (int64_t)this->items.size(); }
void TList::Insert(int64_t index, TObject value) {
if (index >= 0 && index <= this->Count()) {
this->items.insert(this->items.begin() + index, value);
}
void TList::Add(TObject value)
{
this->items.push_back(value);
}
void TList::RemoveAt(int64_t index) {
if (index >= 0 && index < this->Count()) {
this->items.erase(this->items.begin() + index);
}
void TList::Set(int64_t index, TObject value)
{
if(index >= 0 && index < this->Count())
{
this->items[index] = value;
}
}
void TList::Clear() { this->items.clear(); }
void TList::Mark() {
if (this->marked)
return;
this->marked = true;
for (auto item : this->items) {
GC::Mark(item);
}
TObject TList::Get(int64_t index)
{
if(index >= 0 && index < this->Count())
{
return this->items[index];
}
return Undefined();
}
int64_t TList::Count()
{
return (int64_t)this->items.size();
}
void TList::Insert(int64_t index, TObject value)
{
if(index >= 0 && index <= this->Count())
{
this->items.insert(this->items.begin()+index,value);
}
}
void TList::RemoveAt(int64_t index)
{
if(index >= 0 && index < this->Count())
{
this->items.erase(this->items.begin()+index);
}
}
void TList::Clear()
{
this->items.clear();
}
void TList::Mark()
{
if(this->marked) return;
this->marked = true;
for(auto item : this->items)
{
GC::Mark(item);
}
}
};
}
}; // namespace Tesses::CrossLang

View File

@@ -1,75 +1,53 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
TNativeObject::~TNativeObject()
{
namespace Tesses::CrossLang {
TNativeObject::~TNativeObject() {}
}
TNative::TNative(void* ptr,std::function<void(void*)> destroy)
{
this->ptr = ptr;
this->destroyed=false;
this->destroy = destroy;
}
bool TNative::GetDestroyed()
{
return this->destroyed;
}
void* TNative::GetPointer()
{
return this->ptr;
}
void TNative::Mark()
{
if(this->marked) return;
this->marked=true;
GC::Mark(this->other);
}
void TNative::Destroy()
{
if(this->destroyed) return;
if(this->destroy != nullptr)
{
this->destroyed=true;
this->destroy(this->ptr);
}
}
bool TNativeObject::ToBool()
{
return true;
}
bool TNativeObject::Equals(std::shared_ptr<GC> gc, TObject right)
{
if(std::holds_alternative<THeapObjectHolder>(right))
{
return this == std::get<THeapObjectHolder>(right).obj;
}
return false;
}
TNative* TNative::Create(GCList& ls, void* ptr,std::function<void(void*)> destroy)
{
TNative* native = new TNative(ptr,destroy);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(native);
gc->Watch(native);
return native;
}
TNative* TNative::Create(GCList* ls, void* ptr,std::function<void(void*)> destroy)
{
TNative* native = new TNative(ptr,destroy);
std::shared_ptr<GC> gc = ls->GetGC();
ls->Add(native);
gc->Watch(native);
return native;
}
TNative::~TNative()
{
this->Destroy();
}
TNative::TNative(void *ptr, std::function<void(void *)> destroy) {
this->ptr = ptr;
this->destroyed = false;
this->destroy = destroy;
}
bool TNative::GetDestroyed() { return this->destroyed; }
void *TNative::GetPointer() { return this->ptr; }
void TNative::Mark() {
if (this->marked)
return;
this->marked = true;
GC::Mark(this->other);
}
void TNative::Destroy() {
if (this->destroyed)
return;
if (this->destroy != nullptr) {
this->destroyed = true;
this->destroy(this->ptr);
}
}
bool TNativeObject::ToBool() { return true; }
bool TNativeObject::Equals(std::shared_ptr<GC> gc, TObject right) {
if (std::holds_alternative<THeapObjectHolder>(right)) {
return this == std::get<THeapObjectHolder>(right).obj;
}
return false;
}
TNative *TNative::Create(GCList &ls, void *ptr,
std::function<void(void *)> destroy) {
TNative *native = new TNative(ptr, destroy);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(native);
gc->Watch(native);
return native;
}
TNative *TNative::Create(GCList *ls, void *ptr,
std::function<void(void *)> destroy) {
TNative *native = new TNative(ptr, destroy);
std::shared_ptr<GC> gc = ls->GetGC();
ls->Add(native);
gc->Watch(native);
return native;
}
TNative::~TNative() { this->Destroy(); }
} // namespace Tesses::CrossLang

476
src/types/queryable.cpp Normal file
View File

@@ -0,0 +1,476 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TQueryable::TQueryable(TObject parent)
: TQueryable(parent, TQueryableMode::Passthrough, {}) {}
TQueryable::TQueryable(TObject parent, TQueryableMode mode,
std::vector<TObject> args)
: parent(parent), mode(mode), args(args) {}
TQueryable *TQueryable::Skip(GCList &ls, int64_t no) {
return TQueryable::Create(ls, this, TQueryableMode::Skip, {no});
}
TQueryable *TQueryable::SkipWhile(GCList &ls, TCallable *call) {
return TQueryable::Create(ls, this, TQueryableMode::SkipWhile, {call});
}
TQueryable *TQueryable::Take(GCList &ls, int64_t no) {
return TQueryable::Create(ls, this, TQueryableMode::Take, {no});
}
TQueryable *TQueryable::TakeWhile(GCList &ls, TCallable *call) {
return TQueryable::Create(ls, this, TQueryableMode::TakeWhile, {call});
}
TQueryable *TQueryable::Select(GCList &ls, TCallable *call) {
return TQueryable::Create(ls, this, TQueryableMode::Select, {call});
}
TQueryable *TQueryable::Where(GCList &ls, TCallable *call) {
return TQueryable::Create(ls, this, TQueryableMode::Where, {call});
}
TList *TQueryable::ToList(GCList &ls) {
auto gc = ls.GetGC();
GCList ls2(gc);
auto enumerator = this->GetEnumerator(ls);
if (enumerator == nullptr)
return nullptr;
auto list = TList::Create(ls);
while (enumerator->MoveNext(gc)) {
gc->BarrierBegin();
list->Add(enumerator->GetCurrent(ls));
gc->BarrierEnd();
}
return list;
}
TQueryable *TQueryable::Create(GCList &ls, TObject parent) {
TQueryable *queryable = new TQueryable(parent);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
TQueryable *TQueryable::Create(GCList &ls, TObject parent, TQueryableMode mode,
std::vector<TObject> args) {
TQueryable *queryable = new TQueryable(parent, mode, args);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
void TQueryable::Mark() {
if (this->marked)
return;
this->marked = true;
GC::Mark(this->parent);
for (auto &item : args)
GC::Mark(item);
}
void TQueryable::ForEach(std::shared_ptr<GC> gc, TCallable *call) {
if (call == nullptr)
return;
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if (enumerator == nullptr)
return;
while (enumerator->MoveNext(gc)) {
GCList ls2(gc);
call->Call(ls2, {enumerator->GetCurrent(ls2)});
}
}
int64_t TQueryable::Count(std::shared_ptr<GC> gc, TCallable *call) {
if (call == nullptr)
return 0;
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if (enumerator == nullptr)
return 0;
int64_t count = 0;
while (enumerator->MoveNext(gc)) {
GCList ls2(gc);
if (ToBool(call->Call(ls2, {enumerator->GetCurrent(ls2)})))
count++;
}
return count;
}
int64_t TQueryable::Count(std::shared_ptr<GC> gc) {
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if (enumerator == nullptr)
return 0;
int64_t count = 0;
while (enumerator->MoveNext(gc)) {
count++;
}
return count;
}
bool TQueryable::Contains(std::shared_ptr<GC> gc, TObject value) {
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if (enumerator == nullptr)
return false;
while (enumerator->MoveNext(gc)) {
GCList ls2(gc);
if (Equals(gc, value, enumerator->GetCurrent(ls2)))
return true;
}
return false;
}
bool TQueryable::Any(std::shared_ptr<GC> gc, TCallable *call) {
if (call == nullptr)
return false;
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if (enumerator == nullptr)
return false;
while (enumerator->MoveNext(gc)) {
GCList ls2(gc);
if (ToBool(call->Call(ls2, {enumerator->GetCurrent(ls2)})))
return true;
}
return false;
}
bool TQueryable::All(std::shared_ptr<GC> gc, TCallable *call) {
if (call == nullptr)
return true;
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if (enumerator == nullptr)
return true;
while (enumerator->MoveNext(gc)) {
GCList ls2(gc);
if (!ToBool(call->Call(ls2, {enumerator->GetCurrent(ls2)})))
return false;
}
return true;
}
class SkipItterator : public TEnumerator {
private:
TEnumerator *parentEnum;
int64_t skipCount;
SkipItterator(TEnumerator *parentEnum, int64_t skipCount)
: parentEnum(parentEnum), skipCount(skipCount) {}
public:
static SkipItterator *Create(GCList &ls, TEnumerator *parentEnum,
int64_t skipCount) {
SkipItterator *queryable = new SkipItterator(parentEnum, skipCount);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls) {
if (this->parentEnum == nullptr)
return false;
while (skipCount > 0) {
if (!this->parentEnum->MoveNext(ls)) {
skipCount = 0;
return false;
}
skipCount--;
}
return this->parentEnum->MoveNext(ls);
}
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
void Mark() {
if (this->marked)
return;
this->marked = true;
if (parentEnum != nullptr)
parentEnum->Mark();
}
};
class TakeItterator : public TEnumerator {
private:
TEnumerator *parentEnum;
int64_t takeCount;
TakeItterator(TEnumerator *parentEnum, int64_t takeCount)
: parentEnum(parentEnum), takeCount(takeCount) {}
public:
static TakeItterator *Create(GCList &ls, TEnumerator *parentEnum,
int64_t takeCount) {
TakeItterator *queryable = new TakeItterator(parentEnum, takeCount);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls) {
if (this->parentEnum == nullptr)
return false;
if (takeCount > 0) {
takeCount--;
return this->parentEnum->MoveNext(ls);
}
return false;
}
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
void Mark() {
if (this->marked)
return;
this->marked = true;
if (parentEnum != nullptr)
parentEnum->Mark();
}
};
class SkipWhileItterator : public TEnumerator {
private:
TEnumerator *parentEnum;
TCallable *callable;
SkipWhileItterator(TEnumerator *parentEnum, TCallable *callable)
: parentEnum(parentEnum), callable(callable) {}
public:
static SkipWhileItterator *Create(GCList &ls, TEnumerator *parentEnum,
TCallable *callable) {
SkipWhileItterator *queryable =
new SkipWhileItterator(parentEnum, callable);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls) {
if (this->parentEnum == nullptr)
return false;
ls->BarrierBegin();
auto callable = this->callable;
ls->BarrierEnd();
if (callable != nullptr) {
while (true) {
if (this->parentEnum->MoveNext(ls)) {
GCList ls2(ls);
auto result = callable->Call(
ls2, {this->parentEnum->GetCurrent(ls2)});
if (!ToBool(result)) {
ls->BarrierBegin();
this->callable = nullptr;
ls->BarrierEnd();
return true;
}
} else {
ls->BarrierBegin();
this->callable = nullptr;
ls->BarrierEnd();
return false;
}
}
} else {
return this->parentEnum->MoveNext(ls);
}
return false;
}
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
void Mark() {
if (this->marked)
return;
this->marked = true;
if (parentEnum != nullptr)
parentEnum->Mark();
if (callable != nullptr)
callable->Mark();
}
};
class TakeWhileItterator : public TEnumerator {
private:
TEnumerator *parentEnum;
TCallable *callable;
TakeWhileItterator(TEnumerator *parentEnum, TCallable *callable)
: parentEnum(parentEnum), callable(callable) {}
public:
static TakeWhileItterator *Create(GCList &ls, TEnumerator *parentEnum,
TCallable *callable) {
TakeWhileItterator *queryable =
new TakeWhileItterator(parentEnum, callable);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls) {
if (this->parentEnum == nullptr)
return false;
ls->BarrierBegin();
auto callable = this->callable;
ls->BarrierEnd();
if (callable != nullptr) {
if (this->parentEnum->MoveNext(ls)) {
GCList ls2(ls);
auto result =
callable->Call(ls2, {this->parentEnum->GetCurrent(ls2)});
if (!ToBool(result)) {
ls->BarrierBegin();
this->callable = nullptr;
ls->BarrierEnd();
return false;
}
return true;
}
}
return false;
}
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
void Mark() {
if (this->marked)
return;
this->marked = true;
if (parentEnum != nullptr)
parentEnum->Mark();
if (callable != nullptr)
callable->Mark();
}
};
class WhereItterator : public TEnumerator {
private:
TEnumerator *parentEnum;
TCallable *callable;
WhereItterator(TEnumerator *parentEnum, TCallable *callable)
: parentEnum(parentEnum), callable(callable) {}
public:
static WhereItterator *Create(GCList &ls, TEnumerator *parentEnum,
TCallable *callable) {
WhereItterator *queryable = new WhereItterator(parentEnum, callable);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls) {
if (this->parentEnum == nullptr || this->callable == nullptr)
return false;
while (this->parentEnum->MoveNext(ls)) {
GCList ls2(ls);
auto cur = this->parentEnum->GetCurrent(ls2);
if (ToBool(callable->Call(ls2, {cur})))
return true;
}
return false;
}
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
void Mark() {
if (this->marked)
return;
this->marked = true;
if (parentEnum != nullptr)
parentEnum->Mark();
if (callable != nullptr)
callable->Mark();
}
};
class SelectItterator : public TEnumerator {
private:
TEnumerator *parentEnum;
TCallable *callable;
TObject value;
SelectItterator(TEnumerator *parentEnum, TCallable *callable)
: parentEnum(parentEnum), callable(callable) {}
public:
static SelectItterator *Create(GCList &ls, TEnumerator *parentEnum,
TCallable *callable) {
SelectItterator *queryable = new SelectItterator(parentEnum, callable);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls) {
if (this->parentEnum == nullptr || this->callable == nullptr)
return false;
if (this->parentEnum->MoveNext(ls)) {
GCList ls2(ls);
auto cur = this->parentEnum->GetCurrent(ls2);
auto value = this->callable->Call(ls2, {cur});
ls->BarrierBegin();
this->value = value;
ls->BarrierEnd();
return true;
}
return false;
}
TObject GetCurrent(GCList &ls) {
ls.GetGC()->BarrierBegin();
auto value = this->value;
ls.GetGC()->BarrierEnd();
return value;
}
void Mark() {
if (this->marked)
return;
this->marked = true;
if (parentEnum != nullptr)
parentEnum->Mark();
if (callable != nullptr)
callable->Mark();
GC::Mark(this->value);
}
};
TEnumerator *TQueryable::GetEnumerator(GCList &ls) {
switch (this->mode) {
case TQueryableMode::Skip: {
int64_t skipCount;
if (GetArgument(args, 0, skipCount))
return SkipItterator::Create(
ls, TEnumerator::CreateFromObject(ls, this->parent), skipCount);
} break;
case TQueryableMode::Take: {
int64_t takeCount;
if (GetArgument(args, 0, takeCount))
return TakeItterator::Create(
ls, TEnumerator::CreateFromObject(ls, this->parent), takeCount);
} break;
case TQueryableMode::SkipWhile: {
TCallable *callable;
if (GetArgumentHeap(args, 0, callable))
return SkipWhileItterator::Create(
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
} break;
case TQueryableMode::TakeWhile: {
TCallable *callable;
if (GetArgumentHeap(args, 0, callable))
return TakeWhileItterator::Create(
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
} break;
case TQueryableMode::Select: {
TCallable *callable;
if (GetArgumentHeap(args, 0, callable))
return SelectItterator::Create(
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
} break;
case TQueryableMode::Where: {
TCallable *callable;
if (GetArgumentHeap(args, 0, callable))
return WhereItterator::Create(
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
} break;
}
return TEnumerator::CreateFromObject(ls, this->parent);
}
} // namespace Tesses::CrossLang

View File

@@ -1,47 +1,32 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
TRandom::TRandom() : random()
{
}
TRandom::TRandom(uint64_t seed) : random(seed)
{
}
std::string TRandom::TypeName()
{
return "Random";
}
TObject TRandom::CallMethod(GCList& ls,std::string name, std::vector<TObject> args)
{
if(name == "Next")
{
int64_t first;
int64_t second;
if(GetArgument(args,0,first))
{
if(GetArgument(args,1,second))
{
return (int64_t)random.Next((int32_t)first,(int32_t)second);
}
return (int64_t)random.Next((uint32_t)first);
namespace Tesses::CrossLang {
TRandom::TRandom() : random() {}
TRandom::TRandom(uint64_t seed) : random(seed) {}
std::string TRandom::TypeName() { return "Random"; }
TObject TRandom::CallMethod(GCList &ls, std::string name,
std::vector<TObject> args) {
if (name == "Next") {
int64_t first;
int64_t second;
if (GetArgument(args, 0, first)) {
if (GetArgument(args, 1, second)) {
return (int64_t)random.Next((int32_t)first, (int32_t)second);
}
return random.Next();
return (int64_t)random.Next((uint32_t)first);
}
if(name == "NextByte")
{
return (int64_t)random.NextByte();
}
if(name == "ToString") {
return "";
}
return Undefined();
return random.Next();
}
}
if (name == "NextByte") {
return (int64_t)random.NextByte();
}
if (name == "ToString") {
return "";
}
return Undefined();
}
} // namespace Tesses::CrossLang

View File

@@ -2,394 +2,377 @@
#include <iostream>
#include <sstream>
namespace Tesses::CrossLang {
void ThrowConstError(std::string key)
{
throw std::runtime_error("Cannot set \"" + key + "\" because it is a const");
}
void ThrowConstError(std::string key) {
throw std::runtime_error("Cannot set \"" + key +
"\" because it is a const");
}
void TEnvironment::DeclareConstVariable(std::string key, TObject value)
{
this->DeclareVariable(key,value);
this->consts.push_back(key);
}
bool TEnvironment::HasConstForDeclare(std::string key)
{
for(auto item : this->consts)
if(item == key)
return true;
return false;
}
bool TEnvironment::HasConstForSet(std::string key)
{
return HasConstForDeclare(key);
}
bool TRootEnvironment::TryFindClass(std::vector<std::string>& name, size_t& index)
{
for(size_t i = 0; i < this->classes.size(); i++)
{
if(classes[i].first->classes.at(classes[i].second).name.size() != name.size()) continue;
for(size_t j = 0; j < name.size(); j++)
if(classes[i].first->classes.at(classes[i].second).name[j] != name[j]) continue;
index=i;
void TEnvironment::DeclareConstVariable(std::string key, TObject value) {
this->DeclareVariable(key, value);
this->consts.push_back(key);
}
bool TEnvironment::HasConstForDeclare(std::string key) {
for (auto item : this->consts)
if (item == key)
return true;
}
return false;
}
bool TRootEnvironment::HasVariableOrFieldRecurse(std::string key,bool setting)
{
std::string property=(setting? "set":"get") + key;
if(this->HasVariable(property))
{
auto res = this->GetVariable(property);
TCallable* callable;
if(GetObjectHeap(res,callable)) return true;
}
return this->HasVariable(key);
}
TObject TRootEnvironment::GetVariable(GCList& ls, std::string key)
{
ls.GetGC()->BarrierBegin();
if(this->HasVariable("get" + key))
{
auto item = this->GetVariable("get"+key);
TCallable* callable;
if(GetObjectHeap(item,callable))
{
ls.GetGC()->BarrierEnd();
return callable->Call(ls,{});
return false;
}
bool TEnvironment::HasConstForSet(std::string key) {
return HasConstForDeclare(key);
}
bool TRootEnvironment::TryFindClass(std::vector<std::string> &name,
size_t &index) {
for (size_t i = 0; i < this->classes.size(); i++) {
bool conUp = false;
if (classes[i].first->classes.at(classes[i].second).name.size() !=
name.size())
continue;
for (size_t j = 0; j < name.size(); j++)
if (classes[i].first->classes.at(classes[i].second).name[j] !=
name[j]) {
conUp = true;
break;
}
}
auto item = this->GetVariable(key);
ls.GetGC()->BarrierEnd();
return item;
}
TObject TRootEnvironment::SetVariable(GCList& ls, std::string key, TObject value)
{
ls.GetGC()->BarrierBegin();
if(this->HasVariable("set" + key))
{
auto item = this->GetVariable("set"+key);
TCallable* callable;
if(GetObjectHeap(item,callable))
{
ls.GetGC()->BarrierEnd();
return callable->Call(ls,{value});
}
}
this->SetVariable(key,value);
ls.GetGC()->BarrierEnd();
return value;
}
void TRootEnvironment::LoadDependency(std::shared_ptr<GC> gc,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, std::pair<std::string,TVMVersion> dep)
{
for(auto item : this->dependencies)
if(item.first == dep.first && item.second.CompareTo(dep.second) >= 0) return;
std::string name = {};
name.append(dep.first);
name.push_back('-');
name.append(dep.second.ToString());
name.append(".crvm");
std::string filename="/" + name;
if(vfs->RegularFileExists(filename))
{
auto file = vfs->OpenFile(filename,"rb");
GCList ls(gc);
TFile* f = TFile::Create(ls);
f->Load(gc, file);
LoadFileWithDependencies(gc, vfs, f);
}
else throw VMException("Could not open file: \"" + name + "\".");
}
TObject TEnvironment::Eval(GCList& ls,std::string code)
{
std::stringstream strm(code);
std::vector<LexToken> tokens;
int res =Lex("eval.tcross",strm,tokens);
if(res != 0)
{
throw VMException("Lex error at line: " + std::to_string(res));
}
Parser parser(tokens);
SyntaxNode n = parser.ParseRoot();
CodeGen gen;
gen.GenRoot(n);
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
gen.Save(ms);
ms->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
TFile* f = TFile::Create(ls);
f->Load(ls.GetGC(),ms);
return this->LoadFile(ls.GetGC(), f);
}
TDictionary* TEnvironment::EnsureDictionary(std::shared_ptr<GC> gc, std::string key)
{
TObject item = this->GetVariable(key);
TDictionary* dict;
if(GetObjectHeap(item,dict)) return dict;
GCList ls(gc);
dict = TDictionary::Create(ls);
this->DeclareVariable(key, dict);
return dict;
}
void TEnvironment::DeclareVariable(std::shared_ptr<GC> gc, std::vector<std::string> name, TObject o)
{
if(name.size() == 0)
throw VMException("name can't be empty.");
else if(name.size() == 1)
{
GCList ls(gc);
gc->BarrierBegin();
this->DeclareVariable(name[0],o);
gc->BarrierEnd();
}
else
{
GCList ls(gc);
TObject v = this->GetVariable(name[0]);
TDictionary* dict=nullptr;
if(std::holds_alternative<THeapObjectHolder>(v))
{
dict=dynamic_cast<TDictionary*>(std::get<THeapObjectHolder>(v).obj);
if(dict == nullptr)
{
dict = TDictionary::Create(ls);
gc->BarrierBegin();
this->SetVariable(name[0],dict);
gc->BarrierEnd();
}
}
else
{
dict = TDictionary::Create(ls);
gc->BarrierBegin();
this->DeclareVariable(name[0],dict);
gc->BarrierEnd();
}
for(size_t i = 1; i < name.size()-1; i++)
{
gc->BarrierBegin();
auto v = dict->GetValue(name[i]);
gc->BarrierEnd();
if(std::holds_alternative<THeapObjectHolder>(v))
{
auto dict2=dynamic_cast<TDictionary*>(std::get<THeapObjectHolder>(v).obj);
if(dict2 == nullptr)
{
dict2 = TDictionary::Create(ls);
gc->BarrierBegin();
dict->SetValue(name[i],dict2);
gc->BarrierEnd();
}
dict = dict2;
}
else
{
auto dict2 = TDictionary::Create(ls);
gc->BarrierBegin();
dict->SetValue(name[i],dict2);
gc->BarrierEnd();
dict = dict2;
}
}
gc->BarrierBegin();
dict->SetValue(name[name.size()-1],o);
gc->BarrierEnd();
}
}
TObject TEnvironment::LoadFile(std::shared_ptr<GC> gc, TFile* file)
{
file->EnsureCanRunInCrossLang();
for(size_t i = 0; i < file->classes.size(); i++)
{
this->GetRootEnvironment()->classes.push_back(std::pair<TFile*,uint32_t>(file,(uint32_t)i));
std::vector<std::string> clsPart={"New"};
clsPart.insert(clsPart.end(),file->classes[i].name.begin(),file->classes[i].name.end());
GCList ls(gc);
std::vector<std::string> name=file->classes[i].name;
auto rootEnv = this->GetRootEnvironment();
this->DeclareVariable(gc, clsPart, TExternalMethod::Create(ls,"Create instance of the class",{"$$args"},[rootEnv,file,i](GCList& ls, std::vector<TObject> args)->TObject{
return TClassObject::Create(ls, file,i,rootEnv,args);
}));
for(auto meth : file->classes[i].entry)
{
if(meth.isFunction && meth.modifier == TClassModifier::Static)
{
std::vector<std::string> method=file->classes[i].name;
method.push_back(meth.name);
auto clo = TClosure::Create(ls,this,file,meth.chunkId);
clo->closure->name = JoinPeriod(method);
clo->documentation = meth.documentation;
this->DeclareVariable(gc, method, clo);
}
}
}
for(auto fn : file->functions)
{
if(fn.first.size() < 2) throw VMException("No function name.");
std::vector<std::string> items(fn.first.begin()+1, fn.first.end());
if(fn.second >= file->chunks.size()) throw VMException("ChunkId out of bounds.");
TFileChunk* chunk = file->chunks[fn.second];
chunk->name = JoinPeriod(items);
GCList ls(gc);
TClosure* closure=TClosure::Create(ls,this,file,fn.second);
closure->documentation = fn.first[0];
this->DeclareVariable(gc,items,closure);
}
if(!file->chunks.empty())
{
GCList ls(gc);
TClosure* closure=TClosure::Create(ls,this,file,0);
return closure->Call(ls,{});
}
return nullptr;
}
void TRootEnvironment::LoadFileWithDependencies(std::shared_ptr<GC> gc,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, TFile* file)
{
this->dependencies.push_back(std::pair<std::string,TVMVersion>(file->name,file->version));
for(auto item : file->dependencies)
{
LoadDependency(gc,vfs,item);
}
LoadFile(gc, file);
}
void TRootEnvironment::LoadFileWithDependencies(std::shared_ptr<GC> gc,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path)
{
if(vfs->RegularFileExists(path))
{
auto file=vfs->OpenFile(path,"rb");
GCList ls(gc);
TFile* f = TFile::Create(ls);
f->Load(gc, file);
auto dir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(vfs,path.GetParent());
LoadFileWithDependencies(gc,dir,f);
}
else throw VMException("Could not open file: \"" + path.GetFileName() + "\".");
}
TDictionary* TRootEnvironment::GetDictionary()
{
return this->dict;
}
TObject TRootEnvironment::GetVariable(std::string key)
{
return this->dict->GetValue(key);
}
void TRootEnvironment::SetVariable(std::string key, TObject value)
{
this->dict->SetValue(key,value);
}
void TRootEnvironment::DeclareVariable(std::string key, TObject value)
{
return this->dict->SetValue(key,value);
}
bool TRootEnvironment::HasVariable(std::string key)
{
return this->dict->HasValue(key);
}
bool TRootEnvironment::HasVariableRecurse(std::string key)
{
return this->dict->HasValue(key);
}
TEnvironment* TRootEnvironment::GetParentEnvironment()
{
return this;
}
TRootEnvironment* TRootEnvironment::GetRootEnvironment()
{
return this;
}
TRootEnvironment::TRootEnvironment(TDictionary* dict)
{
this->dict = dict;
}
void TRootEnvironment::Mark()
{
if(this->marked) return;
this->marked = true;
this->dict->Mark();
if(this->permissions.customConsole != nullptr) this->permissions.customConsole->Mark();
for(auto defer : this->defers) defer->Mark();
if(this->error != nullptr) this->error->Mark();
for(auto cls : this->classes) cls.first->Mark();
}
TRootEnvironment* TRootEnvironment::Create(GCList* gc,TDictionary* dict)
{
TRootEnvironment* env=new TRootEnvironment(dict);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(env);
_gc->Watch(env);
return env;
}
TRootEnvironment* TRootEnvironment::Create(GCList& gc,TDictionary* dict)
{
TRootEnvironment* env=new TRootEnvironment(dict);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(env);
_gc->Watch(env);
return env;
}
bool TRootEnvironment::HandleException(std::shared_ptr<GC> gc,TEnvironment* env, TObject err)
{
if(error != nullptr)
{
GCList ls(gc);
return ToBool(error->Call(ls, {
TDictionary::Create(ls,{
TDItem("IsBreakpoint",false),
TDItem("Exception",err),
TDItem("Environment", env)
})
}));
}
return false;
}
bool TRootEnvironment::HandleBreakpoint(std::shared_ptr<GC> gc,TEnvironment* env, TObject err)
{
if(error != nullptr)
{
GCList ls(gc);
return ToBool(error->Call(ls, {
TDictionary::Create(ls,{
TDItem("IsBreakpoint",true),
TDItem("Breakpoint",err),
TDItem("Environment", env)
})
}));
}
if (conUp)
continue;
index = i;
return true;
}
void TRootEnvironment::RegisterOnError(TCallable* call)
{
this->error = call;
return false;
}
TDictionary *TRootEnvironment::GetPrivateFromFile(std::shared_ptr<GC> gc,
TFile *file) {
auto index = reinterpret_cast<uint64_t>(file);
gc->BarrierBegin();
TDictionary *obj;
if (this->private_file_data.count(index) > 0) {
obj = this->private_file_data[index];
} else {
GCList ls(gc);
obj = TDictionary::Create(ls);
this->private_file_data[index] = obj;
}
};
gc->BarrierEnd();
return obj;
}
bool TRootEnvironment::HasVariableOrFieldRecurse(std::string key,
bool setting) {
std::string property = (setting ? "set" : "get") + key;
if (this->HasVariable(property)) {
auto res = this->GetVariable(property);
TCallable *callable;
if (GetObjectHeap(res, callable))
return true;
}
return this->HasVariable(key);
}
TObject TRootEnvironment::GetVariable(GCList &ls, std::string key) {
ls.GetGC()->BarrierBegin();
if (this->HasVariable("get" + key)) {
auto item = this->GetVariable("get" + key);
TCallable *callable;
if (GetObjectHeap(item, callable)) {
ls.GetGC()->BarrierEnd();
return callable->Call(ls, {});
}
}
auto item = this->GetVariable(key);
ls.GetGC()->BarrierEnd();
return item;
}
TObject TRootEnvironment::SetVariable(GCList &ls, std::string key,
TObject value) {
ls.GetGC()->BarrierBegin();
if (this->HasVariable("set" + key)) {
auto item = this->GetVariable("set" + key);
TCallable *callable;
if (GetObjectHeap(item, callable)) {
ls.GetGC()->BarrierEnd();
return callable->Call(ls, {value});
}
}
this->SetVariable(key, value);
ls.GetGC()->BarrierEnd();
return value;
}
void TRootEnvironment::LoadDependency(
std::shared_ptr<GC> gc,
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
std::pair<std::string, TVMVersion> dep) {
for (auto item : this->dependencies)
if (item.first == dep.first && item.second.CompareTo(dep.second) >= 0)
return;
std::string name = {};
name.append(dep.first);
name.push_back('-');
name.append(dep.second.ToString());
name.append(".crvm");
std::string filename = "/" + name;
if (vfs->RegularFileExists(filename)) {
auto file = vfs->OpenFile(filename, "rb");
GCList ls(gc);
TFile *f = TFile::Create(ls);
f->Load(gc, file);
LoadFileWithDependencies(gc, vfs, f);
} else
throw VMException("Could not open file: \"" + name + "\".");
}
TObject TEnvironment::Eval(GCList &ls, std::string code) {
std::stringstream strm(code);
std::vector<LexToken> tokens;
int res = Lex("eval.tcross", strm, tokens);
if (res != 0) {
throw VMException("Lex error at line: " + std::to_string(res));
}
Parser parser(tokens);
SyntaxNode n = parser.ParseRoot();
CodeGen gen;
gen.GenRoot(n);
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
gen.Save(ms);
ms->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
TFile *f = TFile::Create(ls);
f->Load(ls.GetGC(), ms);
return this->LoadFile(ls.GetGC(), f);
}
TDictionary *TEnvironment::EnsureDictionary(std::shared_ptr<GC> gc,
std::string key) {
TObject item = this->GetVariable(key);
TDictionary *dict;
if (GetObjectHeap(item, dict))
return dict;
GCList ls(gc);
dict = TDictionary::Create(ls);
this->DeclareVariable(key, dict);
return dict;
}
void TEnvironment::DeclareVariable(std::shared_ptr<GC> gc,
std::vector<std::string> name, TObject o) {
if (name.size() == 0)
throw VMException("name can't be empty.");
else if (name.size() == 1) {
GCList ls(gc);
gc->BarrierBegin();
this->DeclareVariable(name[0], o);
gc->BarrierEnd();
} else {
GCList ls(gc);
TObject v = this->GetVariable(name[0]);
TDictionary *dict = nullptr;
if (std::holds_alternative<THeapObjectHolder>(v)) {
dict =
dynamic_cast<TDictionary *>(std::get<THeapObjectHolder>(v).obj);
if (dict == nullptr) {
dict = TDictionary::Create(ls);
gc->BarrierBegin();
this->SetVariable(name[0], dict);
gc->BarrierEnd();
}
} else {
dict = TDictionary::Create(ls);
gc->BarrierBegin();
this->DeclareVariable(name[0], dict);
gc->BarrierEnd();
}
for (size_t i = 1; i < name.size() - 1; i++) {
gc->BarrierBegin();
auto v = dict->GetValue(name[i]);
gc->BarrierEnd();
if (std::holds_alternative<THeapObjectHolder>(v)) {
auto dict2 = dynamic_cast<TDictionary *>(
std::get<THeapObjectHolder>(v).obj);
if (dict2 == nullptr) {
dict2 = TDictionary::Create(ls);
gc->BarrierBegin();
dict->SetValue(name[i], dict2);
gc->BarrierEnd();
}
dict = dict2;
} else {
auto dict2 = TDictionary::Create(ls);
gc->BarrierBegin();
dict->SetValue(name[i], dict2);
gc->BarrierEnd();
dict = dict2;
}
}
gc->BarrierBegin();
dict->SetValue(name[name.size() - 1], o);
gc->BarrierEnd();
}
}
TObject TEnvironment::LoadFile(std::shared_ptr<GC> gc, TFile *file) {
file->EnsureCanRunInCrossLang();
for (size_t i = 0; i < file->classes.size(); i++) {
this->GetRootEnvironment()->classes.push_back(
std::pair<TFile *, uint32_t>(file, (uint32_t)i));
std::vector<std::string> clsPart = {"New"};
clsPart.insert(clsPart.end(), file->classes[i].name.begin(),
file->classes[i].name.end());
GCList ls(gc);
std::vector<std::string> name = file->classes[i].name;
auto rootEnv = this->GetRootEnvironment();
this->DeclareVariable(
gc, clsPart,
TExternalMethod::Create(
ls, "Create instance of the class", {"$$args"},
[rootEnv, file, i](GCList &ls,
std::vector<TObject> args) -> TObject {
return TClassObject::Create(ls, file, i, rootEnv, args);
}));
for (auto meth : file->classes[i].entry) {
if (meth.isFunction && meth.modifier == TClassModifier::Static) {
std::vector<std::string> method = file->classes[i].name;
method.push_back(meth.name);
auto clo = TClosure::Create(ls, this, file, meth.chunkId);
clo->closure->name = JoinPeriod(method);
clo->documentation = meth.documentation;
this->DeclareVariable(gc, method, clo);
}
}
}
for (auto fn : file->functions) {
if (fn.first.size() < 2)
throw VMException("No function name.");
std::vector<std::string> items(fn.first.begin() + 1, fn.first.end());
if (fn.second >= file->chunks.size())
throw VMException("ChunkId out of bounds.");
TFileChunk *chunk = file->chunks[fn.second];
chunk->name = JoinPeriod(items);
GCList ls(gc);
TClosure *closure = TClosure::Create(ls, this, file, fn.second);
closure->documentation = fn.first[0];
this->DeclareVariable(gc, items, closure);
}
if (!file->chunks.empty()) {
GCList ls(gc);
TClosure *closure = TClosure::Create(ls, this, file, 0);
return closure->Call(ls, {});
}
return nullptr;
}
void TRootEnvironment::LoadFileWithDependencies(
std::shared_ptr<GC> gc,
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, TFile *file) {
this->dependencies.push_back(
std::pair<std::string, TVMVersion>(file->name, file->version));
for (auto item : file->dependencies) {
LoadDependency(gc, vfs, item);
}
LoadFile(gc, file);
}
void TRootEnvironment::LoadFileWithDependencies(
std::shared_ptr<GC> gc,
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
Tesses::Framework::Filesystem::VFSPath path) {
if (vfs->RegularFileExists(path)) {
auto file = vfs->OpenFile(path, "rb");
GCList ls(gc);
TFile *f = TFile::Create(ls);
f->Load(gc, file);
auto dir =
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
vfs, path.GetParent());
LoadFileWithDependencies(gc, dir, f);
} else
throw VMException("Could not open file: \"" + path.GetFileName() +
"\".");
}
TDictionary *TRootEnvironment::GetDictionary() { return this->dict; }
TObject TRootEnvironment::GetVariable(std::string key) {
return this->dict->GetValue(key);
}
void TRootEnvironment::SetVariable(std::string key, TObject value) {
this->dict->SetValue(key, value);
}
void TRootEnvironment::DeclareVariable(std::string key, TObject value) {
return this->dict->SetValue(key, value);
}
bool TRootEnvironment::HasVariable(std::string key) {
return this->dict->HasValue(key);
}
bool TRootEnvironment::HasVariableRecurse(std::string key) {
return this->dict->HasValue(key);
}
TEnvironment *TRootEnvironment::GetParentEnvironment() { return this; }
TRootEnvironment *TRootEnvironment::GetRootEnvironment() { return this; }
TRootEnvironment::TRootEnvironment(TDictionary *dict) { this->dict = dict; }
void TRootEnvironment::Mark() {
if (this->marked)
return;
this->marked = true;
this->dict->Mark();
if (this->permissions.customConsole != nullptr)
this->permissions.customConsole->Mark();
for (auto priv : this->private_file_data)
priv.second->Mark();
for (auto defer : this->defers)
defer->Mark();
if (this->error != nullptr)
this->error->Mark();
for (auto cls : this->classes)
cls.first->Mark();
}
TRootEnvironment *TRootEnvironment::Create(GCList *gc, TDictionary *dict) {
TRootEnvironment *env = new TRootEnvironment(dict);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(env);
_gc->Watch(env);
return env;
}
TRootEnvironment *TRootEnvironment::Create(GCList &gc, TDictionary *dict) {
TRootEnvironment *env = new TRootEnvironment(dict);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(env);
_gc->Watch(env);
return env;
}
bool TRootEnvironment::HandleException(std::shared_ptr<GC> gc,
TEnvironment *env, TObject err) {
if (error != nullptr) {
GCList ls(gc);
return ToBool(error->Call(
ls, {TDictionary::Create(ls, {TDItem("IsBreakpoint", false),
TDItem("Exception", err),
TDItem("Environment", env)})}));
}
return false;
}
bool TRootEnvironment::HandleBreakpoint(std::shared_ptr<GC> gc,
TEnvironment *env, TObject err) {
if (error != nullptr) {
GCList ls(gc);
return ToBool(error->Call(
ls, {TDictionary::Create(ls, {TDItem("IsBreakpoint", true),
TDItem("Breakpoint", err),
TDItem("Environment", env)})}));
}
return true;
}
void TRootEnvironment::RegisterOnError(TCallable *call) { this->error = call; }
}; // namespace Tesses::CrossLang

View File

@@ -1,224 +1,217 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
int64_t TObjectStream::_GetPosInternal()
{
return Tesses::Framework::Streams::Stream::GetLength();
}
TObjectStream::TObjectStream(std::shared_ptr<GC> gc, TObject obj)
{
this->ls = new GCList(gc);
this->ls->Add(obj);
this->obj = obj;
TDictionary* dict;
if(GetObjectHeap(obj,dict))
{
gc->BarrierBegin();
if(!dict->HasValue("Read"))
{
dict->DeclareFunction(gc,"Read","Read from stream",{"buff","off","len"}, [](GCList& ls, std::vector<TObject> args)->TObject {
namespace Tesses::CrossLang {
int64_t TObjectStream::_GetPosInternal() {
return Tesses::Framework::Streams::Stream::GetLength();
}
TObjectStream::TObjectStream(std::shared_ptr<GC> gc, TObject obj) {
this->ls = new GCList(gc);
this->ls->Add(obj);
this->obj = obj;
TDictionary *dict;
if (GetObjectHeap(obj, dict)) {
gc->BarrierBegin();
if (!dict->HasValue("Read")) {
dict->DeclareFunction(
gc, "Read", "Read from stream", {"buff", "off", "len"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return (int64_t)0;
});
}
if(!dict->HasValue("Write"))
{
dict->DeclareFunction(gc,"Write","Write to stream",{"buff","off","len"}, [](GCList& ls, std::vector<TObject> args)->TObject {
}
if (!dict->HasValue("Write")) {
dict->DeclareFunction(
gc, "Write", "Write to stream", {"buff", "off", "len"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return (int64_t)0;
});
}
if(!dict->HasValue("getCanRead"))
{
dict->DeclareFunction(gc,"getCanRead","Can read from stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
}
if (!dict->HasValue("getCanRead")) {
dict->DeclareFunction(
gc, "getCanRead", "Can read from stream", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return false;
});
}
}
if(!dict->HasValue("getCanWrite"))
{
dict->DeclareFunction(gc,"getCanWrite","Can write to stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
if (!dict->HasValue("getCanWrite")) {
dict->DeclareFunction(
gc, "getCanWrite", "Can write to stream", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return false;
});
}
if(!dict->HasValue("getCanSeek"))
{
dict->DeclareFunction(gc,"getCanSeek","Can seek in stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
}
if (!dict->HasValue("getCanSeek")) {
dict->DeclareFunction(
gc, "getCanSeek", "Can seek in stream", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return false;
});
}
if(!dict->HasValue("getPosition"))
{
dict->DeclareFunction(gc,"getPosition","Can get position in stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
}
if (!dict->HasValue("getPosition")) {
dict->DeclareFunction(
gc, "getPosition", "Can get position in stream", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return (int64_t)0;
});
}
if(!dict->HasValue("getLength"))
{
dict->DeclareFunction(gc,"getPosition","Can get position in stream",{}, [this](GCList& ls, std::vector<TObject> args)->TObject {
}
if (!dict->HasValue("getLength")) {
dict->DeclareFunction(
gc, "getPosition", "Can get position in stream", {},
[this](GCList &ls, std::vector<TObject> args) -> TObject {
return _GetPosInternal();
});
}
if(!dict->HasValue("getEndOfStream"))
{
dict->DeclareFunction(gc,"getEndOfStream","Is at end of stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
}
if (!dict->HasValue("getEndOfStream")) {
dict->DeclareFunction(
gc, "getEndOfStream", "Is at end of stream", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return false;
});
}
gc->BarrierEnd();
}
gc->BarrierEnd();
}
bool TObjectStream::EndOfStream()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getEndOfStream",{});
bool r;
if(GetObject(res,r)) return r;
}
return false;
}
size_t TObjectStream::Read(uint8_t* buff, size_t sz)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls2(this->ls->GetGC());
TByteArray* arr=TByteArray::Create(ls2);
arr->data.resize(sz);
auto res = dict->CallMethod(ls2, "Read",{arr, (int64_t)0L, (int64_t)sz});
memcpy(buff,arr->data.data(),std::min(sz,arr->data.size()));
int64_t r;
if(GetObject(res,r)) return r;
}
return 0;
}
size_t TObjectStream::Write(const uint8_t* buff, size_t sz)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls2(this->ls->GetGC());
TByteArray* arr=TByteArray::Create(ls2);
arr->data.resize(sz);
memcpy(arr->data.data(), buff, sz);
auto res = dict->CallMethod(ls2, "Write",{arr, (int64_t)0L, (int64_t)sz});
int64_t r;
if(GetObject(res,r)) return r;
}
return 0;
}
bool TObjectStream::CanRead()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getCanRead",{});
bool r;
if(GetObject(res,r)) return r;
}
return false;
}
bool TObjectStream::CanWrite()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getCanWrite",{});
bool r;
if(GetObject(res,r)) return r;
}
return false;
}
bool TObjectStream::CanSeek()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getCanSeek",{});
bool r;
if(GetObject(res,r)) return r;
}
return false;
}
int64_t TObjectStream::GetPosition()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getPosition",{});
int64_t r;
if(GetObject(res,r)) return r;
}
return 0;
}
int64_t TObjectStream::GetLength()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getEndOfStream",{});
bool r;
if(GetObject(res,r)) return r;
}
return Tesses::Framework::Streams::Stream::GetLength();
}
void TObjectStream::Flush()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
dict->CallMethod(*ls, "Flush",{});
}
}
void TObjectStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
dict->CallMethod(*ls, "Seek",{pos,(int64_t)(whence == Tesses::Framework::Streams::SeekOrigin::Begin ? 0 : whence == Tesses::Framework::Streams::SeekOrigin::Current ? 1 : 2) });
}
}
void TObjectStream::Close()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
dict->CallMethod(*ls,"Close",{});
}
}
TObjectStream::~TObjectStream()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
dict->CallMethod(*ls,"Close",{});
}
delete this->ls;
}
bool TObjectStream::EndOfStream() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
auto res = dict->CallMethod(*ls, "getEndOfStream", {});
bool r;
if (GetObject(res, r))
return r;
}
return false;
}
size_t TObjectStream::Read(uint8_t *buff, size_t sz) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls2(this->ls->GetGC());
}
TByteArray *arr = TByteArray::Create(ls2);
arr->data.resize(sz);
auto res =
dict->CallMethod(ls2, "Read", {arr, (int64_t)0L, (int64_t)sz});
memcpy(buff, arr->data.data(), std::min(sz, arr->data.size()));
int64_t r;
if (GetObject(res, r))
return r;
}
return 0;
}
size_t TObjectStream::Write(const uint8_t *buff, size_t sz) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls2(this->ls->GetGC());
TByteArray *arr = TByteArray::Create(ls2);
arr->data.resize(sz);
memcpy(arr->data.data(), buff, sz);
auto res =
dict->CallMethod(ls2, "Write", {arr, (int64_t)0L, (int64_t)sz});
int64_t r;
if (GetObject(res, r))
return r;
}
return 0;
}
bool TObjectStream::CanRead() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
auto res = dict->CallMethod(*ls, "getCanRead", {});
bool r;
if (GetObject(res, r))
return r;
}
return false;
}
bool TObjectStream::CanWrite() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
auto res = dict->CallMethod(*ls, "getCanWrite", {});
bool r;
if (GetObject(res, r))
return r;
}
return false;
}
bool TObjectStream::CanSeek() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
auto res = dict->CallMethod(*ls, "getCanSeek", {});
bool r;
if (GetObject(res, r))
return r;
}
return false;
}
int64_t TObjectStream::GetPosition() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
auto res = dict->CallMethod(*ls, "getPosition", {});
int64_t r;
if (GetObject(res, r))
return r;
}
return 0;
}
int64_t TObjectStream::GetLength() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
auto res = dict->CallMethod(*ls, "getEndOfStream", {});
bool r;
if (GetObject(res, r))
return r;
}
return Tesses::Framework::Streams::Stream::GetLength();
}
void TObjectStream::Flush() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
dict->CallMethod(*ls, "Flush", {});
}
}
void TObjectStream::Seek(int64_t pos,
Tesses::Framework::Streams::SeekOrigin whence) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
dict->CallMethod(
*ls, "Seek",
{pos,
(int64_t)(whence == Tesses::Framework::Streams::SeekOrigin::Begin
? 0
: whence ==
Tesses::Framework::Streams::SeekOrigin::Current
? 1
: 2)});
}
}
void TObjectStream::Close() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
dict->CallMethod(*ls, "Dispose", {});
}
}
TObjectStream::~TObjectStream() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
dict->CallMethod(*ls, "Dispose", {});
}
delete this->ls;
}
} // namespace Tesses::CrossLang

View File

@@ -1,246 +1,213 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TDictionary* TSubEnvironment::GetDictionary()
{
return this->dict;
namespace Tesses::CrossLang {
TDictionary *TSubEnvironment::GetDictionary() { return this->dict; }
bool TSubEnvironment::HasVariableOrFieldRecurse(std::string key, bool setting) {
std::string property = (setting ? "set" : "get") + key;
if (this->HasVariable(property)) {
auto res = this->GetVariable(property);
TCallable *callable;
if (GetObjectHeap(res, callable))
return true;
}
bool TSubEnvironment::HasVariableOrFieldRecurse(std::string key,bool setting)
{
std::string property=(setting? "set":"get") + key;
if(this->HasVariable(property))
{
auto res = this->GetVariable(property);
TCallable* callable;
if(GetObjectHeap(res,callable)) return true;
if (this->HasVariable(key))
return true;
return this->env->HasVariableOrFieldRecurse(key, setting);
}
TObject TSubEnvironment::GetVariable(GCList &ls, std::string key) {
ls.GetGC()->BarrierBegin();
if (this->HasVariable("get" + key)) {
auto item = this->GetVariable("get" + key);
TCallable *callable;
if (GetObjectHeap(item, callable)) {
ls.GetGC()->BarrierEnd();
return callable->Call(ls, {});
}
if(this->HasVariable(key)) return true;
return this->env->HasVariableOrFieldRecurse(key,setting);
}
TObject TSubEnvironment::GetVariable(GCList& ls, std::string key)
{
ls.GetGC()->BarrierBegin();
if(this->HasVariable("get" + key))
{
auto item = this->GetVariable("get"+key);
TCallable* callable;
if(GetObjectHeap(item,callable))
{
ls.GetGC()->BarrierEnd();
return callable->Call(ls,{});
}
}
if(this->HasVariable(key))
{
auto item = this->GetVariable(key);
ls.GetGC()->BarrierEnd();
return item;
}
if(this->env->HasVariableOrFieldRecurse(key))
{
ls.GetGC()->BarrierEnd();
return this->env->GetVariable(ls,key);
}
if (this->HasVariable(key)) {
auto item = this->GetVariable(key);
ls.GetGC()->BarrierEnd();
return Undefined();
return item;
}
bool TSubEnvironment::HasConstForSet(std::string key)
{
if(this->dict->HasValue(key))
{
return this->HasConstForDeclare(key);
}
if(this->env->HasVariableRecurse(key))
{
return this->env->HasConstForSet(key);
}
return false;
}
TObject TSubEnvironment::SetVariable(GCList& ls, std::string key, TObject value)
{
ls.GetGC()->BarrierBegin();
if(this->HasVariable("set" + key))
{
auto item = this->GetVariable("set"+key);
TCallable* callable;
if(GetObjectHeap(item,callable))
{
ls.GetGC()->BarrierEnd();
return callable->Call(ls,{value});
}
}
if(this->HasVariable(key))
{
this->SetVariable(key,value);
ls.GetGC()->BarrierEnd();
return value;
}
if(this->env->HasVariableOrFieldRecurse(key,true))
{
ls.GetGC()->BarrierEnd();
return this->env->SetVariable(ls,key,value);
}
else
{
this->env->SetVariable(key,value);
ls.GetGC()->BarrierEnd();
return value;
}
if (this->env->HasVariableOrFieldRecurse(key)) {
ls.GetGC()->BarrierEnd();
return this->env->GetVariable(ls, key);
}
TObject TSubEnvironment::GetVariable(std::string key)
{
if(this->dict->HasValue(key))
{
return this->dict->GetValue(key);
}
if(this->env->HasVariableRecurse(key))
{
return this->env->GetVariable(key);
}
return Undefined();
}
void TSubEnvironment::DeclareVariable(std::string key,TObject value)
{
this->dict->SetValue(key,value);
}
void TSubEnvironment::SetVariable(std::string key, TObject value)
{
if(this->dict->HasValue(key))
{
this->dict->SetValue(key,value);
return;
}
if(this->env->HasVariableRecurse(key))
{
this->env->SetVariable(key,value);
}
else
{
this->dict->SetValue(key,value);
}
}
bool TSubEnvironment::HasVariable(std::string key)
{
return this->dict->HasValue(key);
}
bool TSubEnvironment::HasVariableRecurse(std::string key)
{
if(this->dict->HasValue(key)) return true;
return this->env->HasVariableRecurse(key);
}
TSubEnvironment::TSubEnvironment(TEnvironment* env,TDictionary* dict)
{
this->env = env;
this->dict = dict;
}
TSubEnvironment* TEnvironment::GetSubEnvironment(TDictionary* dict)
{
TSubEnvironment* subEnv = new TSubEnvironment(this,dict);
return subEnv;
}
TObject TEnvironment::CallFunction(GCList& ls, std::string key, std::vector<TObject> args)
{
ls.GetGC()->BarrierBegin();
auto res = this->GetVariable(key);
ls.GetGC()->BarrierEnd();
TCallable* callable;
ls.GetGC()->BarrierEnd();
if(GetObjectHeap(res,callable))
{
return callable->Call(ls,args);
}
return Undefined();
return Undefined();
}
bool TSubEnvironment::HasConstForSet(std::string key) {
if (this->dict->HasValue(key)) {
return this->HasConstForDeclare(key);
}
if (this->env->HasVariableRecurse(key)) {
return this->env->HasConstForSet(key);
}
return false;
}
TObject TSubEnvironment::SetVariable(GCList &ls, std::string key,
TObject value) {
ls.GetGC()->BarrierBegin();
if (this->HasVariable("set" + key)) {
auto item = this->GetVariable("set" + key);
TCallable *callable;
if (GetObjectHeap(item, callable)) {
ls.GetGC()->BarrierEnd();
return callable->Call(ls, {value});
}
}
TObject TEnvironment::CallFunctionWithFatalError(GCList& ls, std::string key, std::vector<TObject> args)
{
ls.GetGC()->BarrierBegin();
auto res = this->GetVariable(key);
ls.GetGC()->BarrierEnd();
TCallable* callable;
if(GetObjectHeap(res,callable))
{
return callable->CallWithFatalError(ls,args);
}
return Undefined();
if (this->HasVariable(key)) {
this->SetVariable(key, value);
ls.GetGC()->BarrierEnd();
return value;
}
TSubEnvironment* TEnvironment::GetSubEnvironment(GCList* gc)
{
auto dict=TDictionary::Create(gc);
TSubEnvironment* sEnv = this->GetSubEnvironment(dict);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(sEnv);
_gc->Watch(sEnv);
return sEnv;
if (this->env->HasVariableOrFieldRecurse(key, true)) {
ls.GetGC()->BarrierEnd();
return this->env->SetVariable(ls, key, value);
} else {
this->env->SetVariable(key, value);
ls.GetGC()->BarrierEnd();
return value;
}
TSubEnvironment* TEnvironment::GetSubEnvironment(GCList& gc)
{
auto dict=TDictionary::Create(gc);
TSubEnvironment* sEnv = this->GetSubEnvironment(dict);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(sEnv);
_gc->Watch(sEnv);
return sEnv;
ls.GetGC()->BarrierEnd();
}
TObject TSubEnvironment::GetVariable(std::string key) {
if (this->dict->HasValue(key)) {
return this->dict->GetValue(key);
}
TSubEnvironment* TSubEnvironment::Create(GCList* gc, TEnvironment* env, TDictionary* dict)
{
TSubEnvironment* senv = new TSubEnvironment(env,dict);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(senv);
_gc->Watch(senv);
return senv;
if (this->env->HasVariableRecurse(key)) {
return this->env->GetVariable(key);
}
TSubEnvironment* TSubEnvironment::Create(GCList& gc, TEnvironment* env, TDictionary* dict)
{
TSubEnvironment* senv = new TSubEnvironment(env,dict);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(senv);
_gc->Watch(senv);
return senv;
return Undefined();
}
void TSubEnvironment::DeclareVariable(std::string key, TObject value) {
this->dict->SetValue(key, value);
}
void TSubEnvironment::SetVariable(std::string key, TObject value) {
if (this->dict->HasValue(key)) {
this->dict->SetValue(key, value);
return;
}
TEnvironment* TSubEnvironment::GetParentEnvironment()
{
return this->env;
if (this->env->HasVariableRecurse(key)) {
this->env->SetVariable(key, value);
} else {
this->dict->SetValue(key, value);
}
TRootEnvironment* TSubEnvironment::GetRootEnvironment()
{
return this->env->GetRootEnvironment();
}
bool TSubEnvironment::HasVariable(std::string key) {
return this->dict->HasValue(key);
}
bool TSubEnvironment::HasVariableRecurse(std::string key) {
if (this->dict->HasValue(key))
return true;
return this->env->HasVariableRecurse(key);
}
TSubEnvironment::TSubEnvironment(TEnvironment *env, TDictionary *dict) {
this->env = env;
this->dict = dict;
}
TSubEnvironment *TEnvironment::GetSubEnvironment(TDictionary *dict) {
TSubEnvironment *subEnv = new TSubEnvironment(this, dict);
return subEnv;
}
TObject TEnvironment::CallFunction(GCList &ls, std::string key,
std::vector<TObject> args) {
ls.GetGC()->BarrierBegin();
auto res = this->GetVariable(key);
ls.GetGC()->BarrierEnd();
TCallable *callable;
if (GetObjectHeap(res, callable)) {
return callable->Call(ls, args);
}
void TSubEnvironment::Mark()
{
if(this->marked) return;
this->marked=true;
this->dict->Mark();
this->env->Mark();
for(auto defer : defers) defer->Mark();
return Undefined();
}
TObject TEnvironment::CallFunctionWithFatalError(GCList &ls, std::string key,
std::vector<TObject> args) {
ls.GetGC()->BarrierBegin();
auto res = this->GetVariable(key);
ls.GetGC()->BarrierEnd();
TCallable *callable;
if (GetObjectHeap(res, callable)) {
return callable->CallWithFatalError(ls, args);
}
void TEnvironment::DeclareFunction(std::shared_ptr<GC> gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
gc->BarrierBegin();
GCList ls(gc);
this->DeclareVariable(key, TExternalMethod::Create(ls,documentation,argNames,cb));
gc->BarrierEnd();
}
void TEnvironment::DeclareFunction(std::shared_ptr<GC> gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
gc->BarrierBegin();
GCList ls(gc);
this->DeclareVariable(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
gc->BarrierEnd();
}
};
return Undefined();
}
TSubEnvironment *TEnvironment::GetSubEnvironment(GCList *gc) {
auto dict = TDictionary::Create(gc);
TSubEnvironment *sEnv = this->GetSubEnvironment(dict);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(sEnv);
_gc->Watch(sEnv);
return sEnv;
}
TSubEnvironment *TEnvironment::GetSubEnvironment(GCList &gc) {
auto dict = TDictionary::Create(gc);
TSubEnvironment *sEnv = this->GetSubEnvironment(dict);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(sEnv);
_gc->Watch(sEnv);
return sEnv;
}
TSubEnvironment *TSubEnvironment::Create(GCList *gc, TEnvironment *env,
TDictionary *dict) {
TSubEnvironment *senv = new TSubEnvironment(env, dict);
std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(senv);
_gc->Watch(senv);
return senv;
}
TSubEnvironment *TSubEnvironment::Create(GCList &gc, TEnvironment *env,
TDictionary *dict) {
TSubEnvironment *senv = new TSubEnvironment(env, dict);
std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(senv);
_gc->Watch(senv);
return senv;
}
TEnvironment *TSubEnvironment::GetParentEnvironment() { return this->env; }
TRootEnvironment *TSubEnvironment::GetRootEnvironment() {
return this->env->GetRootEnvironment();
}
void TSubEnvironment::Mark() {
if (this->marked)
return;
this->marked = true;
this->dict->Mark();
this->env->Mark();
for (auto defer : defers)
defer->Mark();
}
void TEnvironment::DeclareFunction(
std::shared_ptr<GC> gc, std::string key, std::string documentation,
std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
gc->BarrierBegin();
GCList ls(gc);
this->DeclareVariable(
key, TExternalMethod::Create(ls, documentation, argNames, cb));
gc->BarrierEnd();
}
void TEnvironment::DeclareFunction(
std::shared_ptr<GC> gc, std::string key, std::string documentation,
std::vector<std::string> argNames,
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
std::function<void()> destroy) {
gc->BarrierBegin();
GCList ls(gc);
this->DeclareVariable(
key, TExternalMethod::Create(ls, documentation, argNames, cb, destroy));
gc->BarrierEnd();
}
}; // namespace Tesses::CrossLang

View File

@@ -2,402 +2,371 @@
namespace Tesses::CrossLang {
TObjectVFS::TObjectVFS(std::shared_ptr<GC> gc, TObject obj)
{
this->ls = new GCList(gc);
this->ls->Add(obj);
this->obj = obj;
TObjectVFS::TObjectVFS(std::shared_ptr<GC> gc, TObject obj) {
this->ls = new GCList(gc);
this->ls->Add(obj);
this->obj = obj;
}
Tesses::Framework::Filesystem::FIFOCreationResult
TObjectVFS::CreateFIFO(Tesses::Framework::Filesystem::VFSPath path) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "CreateFIFO", {path});
int64_t n = 0;
if (GetObject(res, n))
return (Tesses::Framework::Filesystem::FIFOCreationResult)n;
}
Tesses::Framework::Filesystem::FIFOCreationResult TObjectVFS::CreateFIFO(Tesses::Framework::Filesystem::VFSPath path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "CreateFIFO",{path});
int64_t n=0;
if(GetObject(res, n)) return (Tesses::Framework::Filesystem::FIFOCreationResult)n;
}
return Tesses::Framework::Filesystem::FIFOCreationResult::UnknownError;
}
std::shared_ptr<Tesses::Framework::Streams::Stream> TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "OpenFile",{path,mode});
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetObject(res,strm))
{
return strm;
}
}
return nullptr;
}
void TObjectVFS::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "CreateDirectory",{path});
}
}
void TObjectVFS::DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "DeleteDirectory",{path});
return Tesses::Framework::Filesystem::FIFOCreationResult::UnknownError;
}
std::shared_ptr<Tesses::Framework::Streams::Stream>
TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path,
std::string mode) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "OpenFile", {path, mode});
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if (GetObject(res, strm)) {
return strm;
}
}
void TObjectVFS::Lock(Tesses::Framework::Filesystem::VFSPath path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Lock",{path});
}
return nullptr;
}
void TObjectVFS::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "CreateDirectory", {path});
}
void TObjectVFS::Unlock(Tesses::Framework::Filesystem::VFSPath path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Unlock",{path});
}
}
void TObjectVFS::DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "DeleteDirectory", {path});
}
void TObjectVFS::CreateSymlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath symlinkFile)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "CreateSymlink",{existingFile,symlinkFile});
}
}
void TObjectVFS::Lock(Tesses::Framework::Filesystem::VFSPath path) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Lock", {path});
}
void TObjectVFS::CreateHardlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath newName)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "CreateHardlink",{existingFile,newName});
}
}
void TObjectVFS::Unlock(Tesses::Framework::Filesystem::VFSPath path) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Unlock", {path});
}
void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "DeleteFile",{path});
}
}
void TObjectVFS::CreateSymlink(
Tesses::Framework::Filesystem::VFSPath existingFile,
Tesses::Framework::Filesystem::VFSPath symlinkFile) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "CreateSymlink", {existingFile, symlinkFile});
}
void TObjectVFS::DeleteDirectoryRecurse(Tesses::Framework::Filesystem::VFSPath path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "DeleteDirectoryRecurse",{path});
}
}
void TObjectVFS::CreateHardlink(
Tesses::Framework::Filesystem::VFSPath existingFile,
Tesses::Framework::Filesystem::VFSPath newName) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "CreateHardlink", {existingFile, newName});
}
Tesses::Framework::Filesystem::VFSPathEnumerator TObjectVFS::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList* ls=new GCList(this->ls->GetGC());
auto res = dict->CallMethod(*ls, "EnumeratePaths",{path});
auto enumerator = TEnumerator::CreateFromObject(*ls,res);
return Tesses::Framework::Filesystem::VFSPathEnumerator([path,enumerator,ls](Tesses::Framework::Filesystem::VFSPath& path0)->bool{
if(enumerator == nullptr) return false;
while(enumerator->MoveNext(ls->GetGC()))
{
}
void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "DeleteFile", {path});
}
}
void TObjectVFS::DeleteDirectoryRecurse(
Tesses::Framework::Filesystem::VFSPath path) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "DeleteDirectoryRecurse", {path});
}
}
Tesses::Framework::Filesystem::VFSPathEnumerator
TObjectVFS::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList *ls = new GCList(this->ls->GetGC());
auto res = dict->CallMethod(*ls, "EnumeratePaths", {path});
auto enumerator = TEnumerator::CreateFromObject(*ls, res);
return Tesses::Framework::Filesystem::VFSPathEnumerator(
[path, enumerator,
ls](Tesses::Framework::Filesystem::VFSPath &path0) -> bool {
if (enumerator == nullptr)
return false;
while (enumerator->MoveNext(ls->GetGC())) {
auto res = enumerator->GetCurrent(*ls);
std::string name;
Tesses::Framework::Filesystem::VFSPath path1;
if(GetObject(res,path1))
{
if (GetObject(res, path1)) {
path0 = path1;
return true;
}
else if(GetObject(res,name))
{
} else if (GetObject(res, name)) {
path0 = path / name;
return true;
}
}
return false;
},[ls]()->void{
delete ls;
});
}
return Tesses::Framework::Filesystem::VFSPathEnumerator();
},
[ls]() -> void { delete ls; });
}
void TObjectVFS::MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
{
return Tesses::Framework::Filesystem::VFSPathEnumerator();
}
void TObjectVFS::MoveFile(Tesses::Framework::Filesystem::VFSPath src,
Tesses::Framework::Filesystem::VFSPath dest) {
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "MoveFile",{src,dest});
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "MoveFile", {src, dest});
}
}
void TObjectVFS::MoveDirectory(Tesses::Framework::Filesystem::VFSPath src,
Tesses::Framework::Filesystem::VFSPath dest) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "MoveDirectory", {src, dest});
}
}
Tesses::Framework::Filesystem::VFSPath
TObjectVFS::ReadLink(Tesses::Framework::Filesystem::VFSPath path) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "ReadLink", {path});
Tesses::Framework::Filesystem::VFSPath myPath;
if (GetObject(res, myPath)) {
return myPath;
}
}
void TObjectVFS::MoveDirectory(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
{
return Tesses::Framework::Filesystem::VFSPath();
}
std::string
TObjectVFS::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path) {
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "MoveDirectory",{src,dest});
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "VFSPathToSystem", {path});
std::string myPath;
if (GetObject(res, myPath)) {
return myPath;
}
}
Tesses::Framework::Filesystem::VFSPath TObjectVFS::ReadLink(Tesses::Framework::Filesystem::VFSPath path)
{
return "/";
}
Tesses::Framework::Filesystem::VFSPath
TObjectVFS::SystemToVFSPath(std::string path) {
TDictionary *dict;
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "ReadLink",{path});
Tesses::Framework::Filesystem::VFSPath myPath;
if(GetObject(res,myPath))
{
return myPath;
}
}
return Tesses::Framework::Filesystem::VFSPath();
}
std::string TObjectVFS::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "VFSPathToSystem",{path});
std::string myPath;
if(GetObject(res,myPath))
{
return myPath;
}
}
return "/";
}
Tesses::Framework::Filesystem::VFSPath TObjectVFS::SystemToVFSPath(std::string path)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "SystemToVFSPath",{path});
Tesses::Framework::Filesystem::VFSPath myPath;
if(GetObject(res,myPath))
{
return myPath;
}
}
return Tesses::Framework::Filesystem::VFSPath();
}
void TObjectVFS::SetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime lastWrite, Tesses::Framework::Date::DateTime lastAccess)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "SetDate",{path,std::make_shared<Tesses::Framework::Date::DateTime>(lastWrite),std::make_shared<Tesses::Framework::Date::DateTime>(lastAccess)});
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "SystemToVFSPath", {path});
Tesses::Framework::Filesystem::VFSPath myPath;
if (GetObject(res, myPath)) {
return myPath;
}
}
void TObjectVFS::Chmod(Tesses::Framework::Filesystem::VFSPath path, uint32_t mode)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Chmod",{path,(int64_t)mode});
return Tesses::Framework::Filesystem::VFSPath();
}
void TObjectVFS::SetDate(Tesses::Framework::Filesystem::VFSPath path,
Tesses::Framework::Date::DateTime lastWrite,
Tesses::Framework::Date::DateTime lastAccess) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(
ls, "SetDate",
{path,
std::make_shared<Tesses::Framework::Date::DateTime>(lastWrite),
std::make_shared<Tesses::Framework::Date::DateTime>(lastAccess)});
}
}
void TObjectVFS::Chmod(Tesses::Framework::Filesystem::VFSPath path,
uint32_t mode) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Chmod", {path, (int64_t)mode});
}
}
void TObjectVFS::Chown(Tesses::Framework::Filesystem::VFSPath path,
uint32_t uid, uint32_t gid) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Chown", {path, (int64_t)uid, (int64_t)gid});
}
}
bool TObjectVFS::Stat(Tesses::Framework::Filesystem::VFSPath path,
Tesses::Framework::Filesystem::StatData &data) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "Stat", {path});
int64_t _num;
TDictionary *_dict;
TObject _o;
if (GetObjectHeap(res, _dict)) {
this->ls->GetGC()->BarrierBegin();
_o = _dict->GetValue("BlockSize");
if (GetObject(_o, _num))
data.BlockSize = (uint64_t)_num;
_o = _dict->GetValue("BlockCount");
if (GetObject(_o, _num))
data.BlockCount = (uint64_t)_num;
_o = _dict->GetValue("Device");
if (GetObject(_o, _num))
data.Device = (uint64_t)_num;
_o = _dict->GetValue("DeviceId");
if (GetObject(_o, _num))
data.DeviceId = (uint64_t)_num;
_o = _dict->GetValue("GroupId");
if (GetObject(_o, _num))
data.GroupId = (uint32_t)_num;
_o = _dict->GetValue("HardLinks");
if (GetObject(_o, _num))
data.HardLinks = (uint64_t)_num;
std::shared_ptr<Tesses::Framework::Date::DateTime> dt;
_o = _dict->GetValue("LastAccess");
if (GetObject(_o, dt))
data.LastAccess =
dt ? *dt : Tesses::Framework::Date::DateTime(0);
_o = _dict->GetValue("LastModified");
if (GetObject(_o, dt))
data.LastModified =
dt ? *dt : Tesses::Framework::Date::DateTime(0);
_o = _dict->GetValue("LastStatus");
if (GetObject(_o, dt))
data.LastStatus =
dt ? *dt : Tesses::Framework::Date::DateTime(0);
_o = _dict->GetValue("Mode");
if (GetObject(_o, _num))
data.Mode = (uint32_t)_num;
_o = _dict->GetValue("Size");
if (GetObject(_o, _num))
data.Size = (uint64_t)_num;
_o = _dict->GetValue("UserId");
if (GetObject(_o, _num))
data.UserId = (uint32_t)_num;
this->ls->GetGC()->BarrierEnd();
return true;
}
}
void TObjectVFS::Chown(Tesses::Framework::Filesystem::VFSPath path, uint32_t uid, uint32_t gid)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Chown",{path,(int64_t)uid, (int64_t)gid});
return false;
}
bool TObjectVFS::StatVFS(Tesses::Framework::Filesystem::VFSPath path,
Tesses::Framework::Filesystem::StatVFSData &data) {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "StatVFS", {path});
int64_t _num;
TDictionary *_dict;
TObject _o;
if (GetObjectHeap(res, _dict)) {
this->ls->GetGC()->BarrierBegin();
_o = _dict->GetValue("BlockSize");
if (GetObject(_o, _num))
data.BlockSize = (uint64_t)_num;
_o = _dict->GetValue("FragmentSize");
if (GetObject(_o, _num))
data.FragmentSize = (uint64_t)_num;
_o = _dict->GetValue("Blocks");
if (GetObject(_o, _num))
data.Blocks = (uint64_t)_num;
_o = _dict->GetValue("BlocksFree");
if (GetObject(_o, _num))
data.BlocksFree = (uint64_t)_num;
_o = _dict->GetValue("BlocksAvailable");
if (GetObject(_o, _num))
data.BlocksAvailable = (uint64_t)_num;
_o = _dict->GetValue("TotalInodes");
if (GetObject(_o, _num))
data.TotalInodes = (uint64_t)_num;
_o = _dict->GetValue("FreeInodes");
if (GetObject(_o, _num))
data.FreeInodes = (uint64_t)_num;
_o = _dict->GetValue("AvailableInodes");
if (GetObject(_o, _num))
data.AvailableInodes = (uint64_t)_num;
_o = _dict->GetValue("Id");
if (GetObject(_o, _num))
data.Id = (uint64_t)_num;
_o = _dict->GetValue("Flags");
if (GetObject(_o, _num))
data.Flags = (uint64_t)_num;
_o = _dict->GetValue("MaxNameLength");
if (GetObject(_o, _num))
data.MaxNameLength = (uint64_t)_num;
this->ls->GetGC()->BarrierEnd();
return true;
}
}
bool TObjectVFS::Stat(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatData& data)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "Stat",{path});
int64_t _num;
TDictionary* _dict;
TObject _o;
if(GetObjectHeap(res,_dict))
{
this->ls->GetGC()->BarrierBegin();
_o = dict->GetValue("BlockSize");
if(GetObject(_o,_num)) data.BlockSize = (uint64_t)_num;
_o = dict->GetValue("BlockCount");
if(GetObject(_o,_num)) data.BlockCount = (uint64_t)_num;
_o = dict->GetValue("Device");
if(GetObject(_o,_num)) data.Device = (uint64_t)_num;
_o = dict->GetValue("DeviceId");
if(GetObject(_o,_num)) data.DeviceId = (uint64_t)_num;
_o = dict->GetValue("GroupId");
if(GetObject(_o,_num)) data.GroupId = (uint32_t)_num;
_o = dict->GetValue("HardLinks");
if(GetObject(_o,_num)) data.HardLinks = (uint64_t)_num;
std::shared_ptr<Tesses::Framework::Date::DateTime> dt;
_o = dict->GetValue("LastAccess");
if(GetObject(_o,dt)) data.LastAccess = dt ? *dt : Tesses::Framework::Date::DateTime(0);
_o = dict->GetValue("LastModified");
if(GetObject(_o,dt)) data.LastModified = dt ? *dt : Tesses::Framework::Date::DateTime(0);
_o = dict->GetValue("LastStatus");
if(GetObject(_o,dt)) data.LastStatus = dt ? *dt : Tesses::Framework::Date::DateTime(0);
_o = dict->GetValue("Mode");
if(GetObject(_o,_num)) data.Mode = (uint32_t)_num;
_o = dict->GetValue("Size");
if(GetObject(_o,_num)) data.Size = (uint64_t)_num;
_o = dict->GetValue("UserId");
if(GetObject(_o,_num)) data.UserId = (uint32_t)_num;
this->ls->GetGC()->BarrierEnd();
return true;
}
}
return false;
return false;
}
void TObjectVFS::Close() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Dispose", {});
}
bool TObjectVFS::StatVFS(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatVFSData& data)
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "StatVFS",{path});
int64_t _num;
TDictionary* _dict;
TObject _o;
if(GetObjectHeap(res,_dict))
{
this->ls->GetGC()->BarrierBegin();
_o = dict->GetValue("BlockSize");
if(GetObject(_o,_num)) data.BlockSize = (uint64_t)_num;
_o = dict->GetValue("FragmentSize");
if(GetObject(_o,_num)) data.FragmentSize = (uint64_t)_num;
_o = dict->GetValue("Blocks");
if(GetObject(_o,_num)) data.Blocks = (uint64_t)_num;
_o = dict->GetValue("BlocksFree");
if(GetObject(_o,_num)) data.BlocksFree = (uint64_t)_num;
_o = dict->GetValue("BlocksAvailable");
if(GetObject(_o,_num)) data.BlocksAvailable = (uint64_t)_num;
_o = dict->GetValue("TotalInodes");
if(GetObject(_o,_num)) data.TotalInodes = (uint64_t)_num;
_o = dict->GetValue("FreeInodes");
if(GetObject(_o,_num)) data.FreeInodes = (uint64_t)_num;
_o = dict->GetValue("AvailableInodes");
if(GetObject(_o,_num)) data.AvailableInodes = (uint64_t)_num;
_o = dict->GetValue("Id");
if(GetObject(_o,_num)) data.Id = (uint64_t)_num;
_o = dict->GetValue("Flags");
if(GetObject(_o,_num)) data.Flags = (uint64_t)_num;
_o = dict->GetValue("MaxNameLength");
if(GetObject(_o,_num)) data.MaxNameLength = (uint64_t)_num;
this->ls->GetGC()->BarrierEnd();
return true;
}
}
return false;
}
TObjectVFS::~TObjectVFS() {
TDictionary *dict;
if (GetObjectHeap(this->obj, dict)) {
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "Dispose", {});
}
void TObjectVFS::Close()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls,"Close",{});
}
}
TObjectVFS::~TObjectVFS()
{
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls,"Close",{});
}
delete this->ls;
}
}
delete this->ls;
}
} // namespace Tesses::CrossLang

View File

@@ -2,163 +2,164 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool InterperterThread::Add(std::shared_ptr<GC> gc)
{
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
GCList ls(gc);
auto right = cse.back()->Pop(ls);
auto left = cse.back()->Pop(ls);
bool InterperterThread::Add(std::shared_ptr<GC> gc) {
std::vector<CallStackEntry *> &cse = this->call_stack_entries;
GCList ls(gc);
auto right = cse.back()->Pop(ls);
auto left = cse.back()->Pop(ls);
if (std::holds_alternative<std::string>(left) &&
std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(right)) {
cse.back()->Push(
gc, std::get<std::string>(left) +
std::get<Tesses::Framework::Filesystem::VFSPath>(right));
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<char>(right)) {
cse.back()->Push(gc,
(char)(std::get<char>(left) + std::get<char>(right)));
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<char>(right)) {
cse.back()->Push(
gc, (char)(std::get<int64_t>(left) + std::get<char>(right)));
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<int64_t>(right)) {
cse.back()->Push(
gc, (char)(std::get<char>(left) + std::get<int64_t>(right)));
} else if (std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(
left) &&
std::holds_alternative<std::string>(right)) {
cse.back()->Push(
gc, std::get<Tesses::Framework::Filesystem::VFSPath>(left) +
std::get<std::string>(right));
if(std::holds_alternative<std::string>(left) && std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(right))
{
cse.back()->Push(gc,std::get<std::string>(left) + std::get<Tesses::Framework::Filesystem::VFSPath>(right));
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<char>(right))
{
cse.back()->Push(gc,(char)(std::get<char>(left) + std::get<char>(right)));
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<char>(right))
{
cse.back()->Push(gc, (char)(std::get<int64_t>(left) + std::get<char>(right)));
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<int64_t>(right))
{
cse.back()->Push(gc, (char)(std::get<char>(left) + std::get<int64_t>(right)));
}
else if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(left) && std::holds_alternative<std::string>(right))
{
cse.back()->Push(gc,std::get<Tesses::Framework::Filesystem::VFSPath>(left) + std::get<std::string>(right));
}
}
else if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(left) && std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(right))
{
cse.back()->Push(gc,std::get<Tesses::Framework::Filesystem::VFSPath>(left) + std::get<Tesses::Framework::Filesystem::VFSPath>(right));
}
else if (std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(
left) &&
std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(
right)) {
cse.back()->Push(
gc, std::get<Tesses::Framework::Filesystem::VFSPath>(left) +
std::get<Tesses::Framework::Filesystem::VFSPath>(right));
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<int64_t>(right))
{
cse.back()->Push(gc,std::get<int64_t>(left) + std::get<int64_t>(right));
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<double>(right))
{
cse.back()->Push(gc,std::get<double>(left) + std::get<double>(right));
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<int64_t>(right))
{
cse.back()->Push(gc,std::get<double>(left) + std::get<int64_t>(right));
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<double>(right))
{
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={};
str.append(std::get<std::string>(left));
str.append(std::get<std::string>(right));
cse.back()->Push(gc,str);
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<std::string>(right))
{
std::string str={};
str.push_back(std::get<char>(left));
str.append(std::get<std::string>(right));
cse.back()->Push(gc,str);
}
else if(std::holds_alternative<std::string>(left) && std::holds_alternative<char>(right))
{
std::string str={};
str.append(std::get<std::string>(left));
str.push_back(std::get<char>(right));
cse.back()->Push(gc,str);
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary*>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
auto natObj = dynamic_cast<TNativeObject*>(obj);
auto cls = dynamic_cast<TClassObject*>(obj);
if(cls != nullptr)
{
gc->BarrierBegin();
auto obj=cls->GetValue(cse.back()->callable->className,"operator+");
gc->BarrierEnd();
TClosure* clos;
TCallable* callable;
if(GetObjectHeap(obj,clos))
{
this->AddCallStackEntry(ls,clos,{right});
return true;
}
else if(GetObjectHeap(obj,callable))
{
cse.back()->Push(gc,callable->Call(ls,{right}));
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
else if(natObj != nullptr)
{
cse.back()->Push(gc, natObj->CallMethod(ls,"operator+",{right}));
}
else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<int64_t>(right)) {
cse.back()->Push(gc,
std::get<int64_t>(left) + std::get<int64_t>(right));
}
else if (std::holds_alternative<double>(left) &&
std::holds_alternative<double>(right)) {
cse.back()->Push(gc, std::get<double>(left) + std::get<double>(right));
} else if (std::holds_alternative<double>(left) &&
std::holds_alternative<int64_t>(right)) {
cse.back()->Push(gc, std::get<double>(left) + std::get<int64_t>(right));
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<double>(right)) {
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 = {};
str.append(std::get<std::string>(left));
str.append(std::get<std::string>(right));
cse.back()->Push(gc, str);
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<std::string>(right)) {
std::string str = {};
str.push_back(std::get<char>(left));
str.append(std::get<std::string>(right));
cse.back()->Push(gc, str);
} else if (std::holds_alternative<std::string>(left) &&
std::holds_alternative<char>(right)) {
std::string str = {};
str.append(std::get<std::string>(left));
str.push_back(std::get<char>(right));
cse.back()->Push(gc, str);
} else if (std::holds_alternative<THeapObjectHolder>(left)) {
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary *>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
auto natObj = dynamic_cast<TNativeObject *>(obj);
auto cls = dynamic_cast<TClassObject *>(obj);
if (cls != nullptr) {
gc->BarrierBegin();
auto obj =
cls->GetValue(cse.back()->callable->className, "operator+");
gc->BarrierEnd();
TClosure *clos;
TCallable *callable;
if (GetObjectHeap(obj, clos)) {
this->AddCallStackEntry(ls, clos, {right});
return true;
} else if (GetObjectHeap(obj, callable)) {
cse.back()->Push(gc, callable->Call(ls, {right}));
return false;
}
else if(dict != nullptr)
{
gc->BarrierBegin();
TObject fn = dict->GetValue("operator+");
gc->BarrierEnd();
return InvokeTwo(ls,fn,left,right);
}
else if(dynDict != nullptr)
{
cse.back()->Push(gc,dynDict->CallMethod(ls,"operator+",{right}));
return false;
}
else
{
cse.back()->Push(gc, Undefined());
}
}
else
{
cse.back()->Push(gc, Undefined());
return false;
} else if (natObj != nullptr) {
cse.back()->Push(gc, natObj->CallMethod(ls, "operator+", {right}));
return false;
} else if (dict != nullptr) {
gc->BarrierBegin();
TObject fn = dict->GetValue("operator+");
gc->BarrierEnd();
return InvokeTwo(ls, fn, left, right);
} else if (dynDict != nullptr) {
cse.back()->Push(gc, dynDict->CallMethod(ls, "operator+", {right}));
return false;
} else {
cse.back()->Push(gc, Undefined());
}
return false;
} else {
cse.back()->Push(gc, Undefined());
}
}
return false;
}
} // namespace Tesses::CrossLang

View File

@@ -2,235 +2,199 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool Equals(std::shared_ptr<GC> gc, TObject left, TObject right)
{
GCList ls(gc);
if(std::holds_alternative<std::nullptr_t>(left) && std::holds_alternative<std::nullptr_t>(right))
{
bool Equals(std::shared_ptr<GC> gc, TObject left, TObject right) {
GCList ls(gc);
if (std::holds_alternative<std::nullptr_t>(left) &&
std::holds_alternative<std::nullptr_t>(right)) {
return true;
}
return true;
}
else if(std::holds_alternative<Undefined>(left) && std::holds_alternative<Undefined>(right))
{
return true;
}
else if (std::holds_alternative<Undefined>(left) &&
std::holds_alternative<Undefined>(right)) {
return true;
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<int64_t>(right))
{
return std::get<int64_t>(left) == std::get<int64_t>(right);
}
else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<int64_t>(right)) {
return std::get<int64_t>(left) == std::get<int64_t>(right);
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<double>(right))
{
return std::get<double>(left) == std::get<double>(right);
}
else if(std::holds_alternative<double>(left) && std::holds_alternative<int64_t>(right))
{
return std::get<double>(left) == std::get<int64_t>(right);
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<double>(right))
{
return std::get<int64_t>(left) == std::get<double>(right);
}
else if (std::holds_alternative<double>(left) &&
std::holds_alternative<double>(right)) {
return std::get<double>(left) == std::get<double>(right);
} else if (std::holds_alternative<double>(left) &&
std::holds_alternative<int64_t>(right)) {
return std::get<double>(left) == std::get<int64_t>(right);
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<double>(right)) {
return std::get<int64_t>(left) == std::get<double>(right);
}
else if(std::holds_alternative<std::string>(left) && std::holds_alternative<std::string>(right))
{
return std::get<std::string>(left) == std::get<std::string>(right);
}
else if (std::holds_alternative<std::string>(left) &&
std::holds_alternative<std::string>(right)) {
return std::get<std::string>(left) == std::get<std::string>(right);
}
else if(std::holds_alternative<bool>(left) && std::holds_alternative<bool>(right))
{
return std::get<bool>(left) == std::get<bool>(right);
}
else if (std::holds_alternative<bool>(left) &&
std::holds_alternative<bool>(right)) {
return std::get<bool>(left) == std::get<bool>(right);
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<char>(right))
{
return std::get<char>(left) == std::get<char>(right);
}
else if(std::holds_alternative<char>(left) && std::holds_alternative<int64_t>(right))
{
return std::get<char>(left) == std::get<int64_t>(right);
}
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<char>(right))
{
return 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))
{
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))
{
auto lver= std::get<TVMVersion>(left);
auto rver = std::get<TVMVersion>(right);
auto r = lver.CompareTo(rver);
return r == 0;
}
else if(std::holds_alternative<Tesses::Framework::Uuid>(left) && std::holds_alternative<Tesses::Framework::Uuid>(right))
{
auto l= std::get<Tesses::Framework::Uuid>(left);
auto r = std::get<Tesses::Framework::Uuid>(right);
return l == r;
}
else if(std::holds_alternative<THeapObjectHolder>(left))
{
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary*>(obj);
else if (std::holds_alternative<char>(left) &&
std::holds_alternative<char>(right)) {
return std::get<char>(left) == std::get<char>(right);
} else if (std::holds_alternative<char>(left) &&
std::holds_alternative<int64_t>(right)) {
return std::get<char>(left) == std::get<int64_t>(right);
} else if (std::holds_alternative<int64_t>(left) &&
std::holds_alternative<char>(right)) {
return 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)) {
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)) {
auto lver = std::get<TVMVersion>(left);
auto rver = std::get<TVMVersion>(right);
auto r = lver.CompareTo(rver);
return r == 0;
} else if (std::holds_alternative<Tesses::Framework::Uuid>(left) &&
std::holds_alternative<Tesses::Framework::Uuid>(right)) {
auto l = std::get<Tesses::Framework::Uuid>(left);
auto r = std::get<Tesses::Framework::Uuid>(right);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
auto native = dynamic_cast<TNative*>(obj);
auto natObj = dynamic_cast<TNativeObject*>(obj);
auto cls = dynamic_cast<TClassObject*>(obj);
if(cls != nullptr)
{
gc->BarrierBegin();
auto obj=cls->GetValue("","operator==");
gc->BarrierEnd();
TCallable* callable;
if(GetObjectHeap(obj,callable))
{
return ToBool(callable->Call(ls,{right}));
}
else if(std::holds_alternative<std::nullptr_t>(right)) {
return false;
}
else if(std::holds_alternative<Undefined>(right))
{
return false;
}
else if(std::holds_alternative<THeapObjectHolder>(right))
{
return cls == std::get<THeapObjectHolder>(right).obj;
}
return l == r;
} else if (std::holds_alternative<THeapObjectHolder>(left)) {
auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary *>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
auto native = dynamic_cast<TNative *>(obj);
auto natObj = dynamic_cast<TNativeObject *>(obj);
auto cls = dynamic_cast<TClassObject *>(obj);
if (cls != nullptr) {
gc->BarrierBegin();
auto obj = cls->GetValue("", "operator==");
gc->BarrierEnd();
TCallable *callable;
if (GetObjectHeap(obj, callable)) {
return ToBool(callable->Call(ls, {right}));
} else if (std::holds_alternative<std::nullptr_t>(right)) {
return false;
} else if (std::holds_alternative<Undefined>(right)) {
return false;
} else if (std::holds_alternative<THeapObjectHolder>(right)) {
return cls == std::get<THeapObjectHolder>(right).obj;
}
else
if(natObj != nullptr)
{
return natObj->Equals(gc, right);
}
if(dict != nullptr)
{
gc->BarrierBegin();
TObject fn = dict->GetValue("operator==");
gc->BarrierEnd();
if(!std::holds_alternative<Undefined>(fn))
{
if(std::holds_alternative<THeapObjectHolder>(fn))
{
} else if (natObj != nullptr) {
return natObj->Equals(gc, right);
}
if (dict != nullptr) {
gc->BarrierBegin();
TObject fn = dict->GetValue("operator==");
gc->BarrierEnd();
if (!std::holds_alternative<Undefined>(fn)) {
if (std::holds_alternative<THeapObjectHolder>(fn)) {
auto obj = dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj);
if(obj != nullptr)
{
auto closure = dynamic_cast<TClosure*>(obj);
if(closure != nullptr)
{
if(!closure->closure->args.empty() && closure->closure->args[0] == "this")
{
return ToBool(obj->Call(ls,{left,right}));
}
else
{
return ToBool(obj->Call(ls,{right}));
}
auto obj = dynamic_cast<TCallable *>(
std::get<THeapObjectHolder>(fn).obj);
if (obj != nullptr) {
auto closure = dynamic_cast<TClosure *>(obj);
if (closure != nullptr) {
if (!closure->closure->args.empty() &&
closure->closure->args[0] == "this") {
return ToBool(obj->Call(ls, {left, right}));
} else {
return ToBool(obj->Call(ls, {right}));
}
else
{
return ToBool(obj->Call(ls,{right}));
}
} else {
return ToBool(obj->Call(ls, {right}));
}
else {
return dict == std::get<THeapObjectHolder>(right).obj;
}
} else {
return dict == std::get<THeapObjectHolder>(right).obj;
}
return dict == std::get<THeapObjectHolder>(right).obj;
}
}
else {
} else {
return dict == std::get<THeapObjectHolder>(right).obj;
}
return false;
} else {
return dict == std::get<THeapObjectHolder>(right).obj;
}
else if(dynDict != nullptr)
{
auto res = dynDict->CallMethod(ls,"operator==",{right});
if(!std::holds_alternative<std::nullptr_t>(res) && std::holds_alternative<Undefined>(res))
{
return ToBool(res);
}
}
else if(native != nullptr && std::holds_alternative<std::nullptr_t>(right))
{
return native->GetDestroyed();
}
if(std::holds_alternative<THeapObjectHolder>(right))
{
return obj == std::get<THeapObjectHolder>(right).obj;
}
else if(std::holds_alternative<std::nullptr_t>(right))
{
return false;
}
else if(std::holds_alternative<Undefined>(right))
{
return false;
}
else
{
return false;
}
}
else if(std::holds_alternative<std::nullptr_t>(right))
{
return false;
}
else if(std::holds_alternative<Undefined>(right))
{
return false;
}
else
{
return false;
}
return false;
else if (dynDict != nullptr) {
auto res = dynDict->CallMethod(ls, "operator==", {right});
if (!std::holds_alternative<std::nullptr_t>(res) &&
std::holds_alternative<Undefined>(res)) {
return ToBool(res);
}
} else if (native != nullptr &&
std::holds_alternative<std::nullptr_t>(right)) {
return native->GetDestroyed();
}
if (std::holds_alternative<THeapObjectHolder>(right)) {
return obj == std::get<THeapObjectHolder>(right).obj;
}
else if (std::holds_alternative<std::nullptr_t>(right)) {
return false;
} else if (std::holds_alternative<Undefined>(right)) {
return false;
} else {
return false;
}
}
}
else if (std::holds_alternative<std::nullptr_t>(right)) {
return false;
} else if (std::holds_alternative<Undefined>(right)) {
return false;
} else {
return false;
}
return false;
}
} // namespace Tesses::CrossLang

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,53 +2,46 @@
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef>
#include <cstring>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool InterperterThread::InvokeMethod(GCList& ls, TObject fn, TObject instance, std::vector<TObject> args)
{
if(std::holds_alternative<THeapObjectHolder>(fn))
{
auto obj = dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj);
if(obj != nullptr)
{
auto closure = dynamic_cast<TClosure*>(obj);
if(closure != nullptr)
{
if(!closure->closure->args.empty() && closure->closure->args[0] == "this")
{
std::vector<TObject> args2;
args2.push_back(instance);
args2.insert(args2.end(), args.begin(),args.end());
this->AddCallStackEntry(ls,closure,args2);
}
else
{
this->AddCallStackEntry(ls,closure,args);
}
bool InterperterThread::InvokeMethod(GCList &ls, TObject fn, TObject instance,
std::vector<TObject> args) {
if (std::holds_alternative<THeapObjectHolder>(fn)) {
auto obj =
dynamic_cast<TCallable *>(std::get<THeapObjectHolder>(fn).obj);
if (obj != nullptr) {
auto closure = dynamic_cast<TClosure *>(obj);
if (closure != nullptr) {
if (!closure->closure->args.empty() &&
closure->closure->args[0] == "this") {
std::vector<TObject> args2;
args2.push_back(instance);
args2.insert(args2.end(), args.begin(), args.end());
this->AddCallStackEntry(ls, closure, args2);
} else {
this->AddCallStackEntry(ls, closure, args);
}
else
{
auto val = obj->Call(ls,args);
this->call_stack_entries.back()->Push(ls.GetGC(), val);
return false;
}
return true;
} else {
auto val = obj->Call(ls, args);
this->call_stack_entries.back()->Push(ls.GetGC(), val);
return false;
}
return true;
}
this->call_stack_entries.back()->Push(ls.GetGC(),Undefined());
return false;
}
}
this->call_stack_entries.back()->Push(ls.GetGC(), Undefined());
return false;
}
} // namespace Tesses::CrossLang

Some files were not shown because too many files have changed in this diff Show More