7 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
110 changed files with 25742 additions and 31019 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: 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" >> /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: 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: pacman --config /opt/cross/ppc/pacman.conf --noconfirm -Sy mbedtls tessesframework
- run: cp Packaging/Linux/PKGBUILD /home/build/PKGBUILD - run: cp Packaging/Linux/PKGBUILD /home/build/PKGBUILD
- run: cp Packaging/Linux/build-arch.sh /home/build/build-arch.sh - 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/PKGBUILD
- run: chown build:build /home/build/build-arch.sh - run: chown build:build /home/build/build-arch.sh
- run: su build -c /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 - uses: akkuman/gitea-release-action@v1
env: env:
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18 NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
@@ -39,9 +38,20 @@ jobs:
artifacts/** artifacts/**
update-tap: update-tap:
runs-on: ubuntu-latest runs-on: global-container-mingw
steps: steps:
- uses: actions/checkout@v4 - 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 - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Log in to registry - name: Log in to registry

View File

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

View File

@@ -1,188 +1,35 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
include(cmake/version.cmake) include(cmake/version.cmake)
include(cmake/options.cmake)
project(TessesCrossLang VERSION ${CROSSLANG_MAJOR_VERSION}.${CROSSLANG_MINOR_VERSION}.${CROSSLANG_PATCH_VERSION}) project(TessesCrossLang VERSION ${CROSSLANG_MAJOR_VERSION}.${CROSSLANG_MINOR_VERSION}.${CROSSLANG_PATCH_VERSION})
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) include(GNUInstallDirs)
include(CheckLibraryExists)
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(FetchContent) include(FetchContent)
FetchContent_Declare( include(cmake/sources.cmake)
TessesFramework include(cmake/options.cmake)
GIT_REPOSITORY https://git.tesses.org/tesses50/tessesframework.git set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
)
FetchContent_MakeAvailable(TessesFramework)
list(APPEND TessesCrossLangLibs ${TessesFrameworkTargets})
else()
find_package(TessesFramework REQUIRED)
endif()
if(CROSSLANG_ENABLE_FFI) if(CROSSLANG_ENABLE_FFI)
find_package(PkgConfig) find_package(PkgConfig)
endif() endif()
include(cmake/linkdeps.cmake)
if(CROSSLANG_ENABLE_FFI AND CROSSLANG_ENABLE_SHARED)
pkg_check_modules(LIBFFI REQUIRED IMPORTED_TARGET libffi)
endif() include(cmake/findtf.cmake)
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/sources.cmake) include(cmake/sources.cmake)
include(cmake/cpack.cmake)
if(CROSSLANG_OFFLINE_SHELL_PACKAGE STREQUAL "") if(CROSSLANG_STATIC)
include(cmake/staticlib.cmake)
else() else()
install(FILES ${CROSSLANG_OFFLINE_SHELL_PACKAGE} DESTINATION share/Tesses/CrossLang) include(cmake/sharedlib.cmake)
endif() endif()
if(MINGW) include(cmake/install-dev.cmake)
list(APPEND CROSSLANG_WIN32_EXE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/winicon.rc")
if(MINGW)
ENABLE_LANGUAGE(RC)
endif(MINGW)
endif()
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) if(CROSSLANG_INSTALL_DEVELOPMENT)
add_subdirectory(pkgconfig) add_subdirectory(pkgconfig)
endif() endif()

View File

@@ -6,7 +6,7 @@ RUN apk add --no-cache cmake g++ make git
COPY ./ /src 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 FROM alpine:latest
RUN apk update RUN apk update
@@ -14,4 +14,4 @@ RUN apk add --no-cache libstdc++
COPY --from=build /out/usr /usr COPY --from=build /out/usr /usr
ENV CROSSLANG_CONTAINER=1 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> # Maintainer: Mike Nolan <tesses@tesses.net>
pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn' pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn'
pkgver=0.0.4 pkgver=0.0.7
pkgrel=1 pkgrel=1
pkgdesc="" pkgdesc=""
arch=('x86_64' 'powerpc') arch=('x86_64' 'powerpc')
url="https://git.tesses.org/tesses50/crosslang" url="https://git.tesses.org/tesses50/crosslang"
license=('GPLv3') license=('GPLv3')
groups=() 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' makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
install= install=
source=('crosslang::git+https://git.tesses.org/tesses50/crosslang') source=('crosslang::git+https://git.tesses.org/tesses50/crosslang#tag=v0.0.7')
noextract=() noextract=()
sha256sums=('SKIP') sha256sums=('SKIP')
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
@@ -30,14 +30,14 @@ prepare() {
build() { build() {
cd "$srcdir/${pkgname}" cd "$srcdir/${pkgname}"
mkdir build mkdir build
cd build
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then 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 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 fi
cd build
make -j`nproc` 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 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 export BUILDDIR=builds/$tripple
mkdir -p $BUILDDIR 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 --build $BUILDDIR || exit 1
cmake --install $BUILDDIR --prefix $BUILDDIR/out cmake --install $BUILDDIR --prefix $BUILDDIR/out
mv $BUILDDIR/out/bin/crosslang ../../artifacts/crosslang-slim-$tripple 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 for tripple in x86_64-windows-gnu x86-windows-gnu aarch64-windows-gnu; do
export BUILDDIR=builds/$tripple export BUILDDIR=builds/$tripple
mkdir -p $BUILDDIR 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 --build $BUILDDIR || exit 1
cmake --install $BUILDDIR --prefix $BUILDDIR/out cmake --install $BUILDDIR --prefix $BUILDDIR/out
@@ -26,7 +26,7 @@ done
for tripple in x86_64-macos-none aarch64-macos-none; do for tripple in x86_64-macos-none aarch64-macos-none; do
export BUILDDIR=builds/$tripple export BUILDDIR=builds/$tripple
mkdir -p $BUILDDIR 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 --build $BUILDDIR || exit 1
cmake --install $BUILDDIR --prefix $BUILDDIR/out cmake --install $BUILDDIR --prefix $BUILDDIR/out

View File

@@ -1,16 +1,15 @@
#!/bin/bash #!/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 cd build-x86
make -j`nproc` make -j`nproc`
cpack -G NSIS cpack -G NSIS
cpack -G ZIP mv TessesCrossLang-*-win32.exe ../../../artifacts/crosslang-win32-setup.exe
mv TessesCrossLang-*-win32.exe ../../../artifacts/crosslang-win32.exe mv crosslang.exe ../../../artifacts/crosslang-win32-portable.exe
mv TessesCrossLang-*-win32.zip ../../../artifacts/crosslang-win32.zip
cd .. 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 cd build-x64
make -j`nproc` make -j`nproc`
cpack -G NSIS cpack -G NSIS
cpack -G ZIP mv TessesCrossLang-*-win64.exe ../../../artifacts/crosslang-win64-setup.exe
mv TessesCrossLang-*-win64.exe ../../../artifacts/crosslang-win64.exe mv crosslang.exe ../../../artifacts/crosslang-win64-portable.exe
mv TessesCrossLang-*-win64.zip ../../../artifacts/crosslang-win64.zip

View File

@@ -47,7 +47,7 @@ sudo make install
## Build with shared libs only (self contained dependencies) ## Build with shared libs only (self contained dependencies)
```bash ```bash
cmake -S ../.. -B . -DTESSESFRAMEWORK_ENABLE_STATIC=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=ON cmake -S ../.. -B .
make -j`nproc` make -j`nproc`
sudo make install 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,11 @@
# Changelog # 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 ## 0.0.5
Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable

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) if(CROSSLANG_INSTALL_DEVELOPMENT)
install(TARGETS ${TessesCrossLangLibs} install(TARGETS ${CrossLangLibs}
EXPORT TessesCrossLangTargets EXPORT CrossLangTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
) )
install(FILES include/CrossLang.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 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(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(EXPORT TessesCrossLangTargets
install(EXPORT CrossLangTargets
FILE TessesCrossLangTargets.cmake FILE TessesCrossLangTargets.cmake
NAMESPACE TessesCrossLang:: NAMESPACE TessesCrossLang::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/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" 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_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake" install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang) 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()
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_ENABLE_BINARIES "Enable Tesses CrossLang binaries" ON)
option(CROSSLANG_INSTALL_DEVELOPMENT "Enable Tesses CrossLang development files" 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_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_FFI "Enable libffi" OFF)
option(CROSSLANG_ENABLE_RPATH "Enable RPATH" ON) 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) option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF)
option(CROSSLANG_STATIC "Build with static libraries instead of shared" OFF)
set(CROSSLANG_OFFLINE_SHELL_PACKAGE "" CACHE FILEPATH "Path to the shell package generated from https://git.tesses.org/crosslangextras")

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/executemethod2.cpp
src/vm/bc/invoketwo.cpp src/vm/bc/invoketwo.cpp
src/vm/bc/tobool.cpp src/vm/bc/tobool.cpp
src/assembler/asm.cpp
src/assembler/disasm.cpp
src/assembler/merge.cpp
src/compiler/codegen.cpp src/compiler/codegen.cpp
src/compiler/lexer.cpp src/compiler/lexer.cpp
src/compiler/parser.cpp src/compiler/parser.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_MAJOR_VERSION 0)
set(CROSSLANG_MINOR_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] [Thumbnailer Entry]
TryExec=crossthumbnailer TryExec=crosslang
Exec=crossthumbnailer %i %o Exec=crosslang thumbnailer %i %o
MimeType=application/crvm; MimeType=application/crvm;

File diff suppressed because it is too large Load Diff

View File

@@ -10,16 +10,8 @@ else()
set(PKGCONFIG_DEPS "") set(PKGCONFIG_DEPS "")
endif() 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) configure_file(crosslang.pc.in crosslang.pc @ONLY)
install(FILES install(FILES
${CMAKE_CURRENT_BINARY_DIR}/crosslang.pc ${CMAKE_CURRENT_BINARY_DIR}/crosslang.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()

View File

@@ -11,4 +11,4 @@ Version: @PROJECT_VERSION@
Requires: tessesframework Requires: tessesframework
Cflags: -I"${includedir}" Cflags: -I"${includedir}"
Libs: -L"${libdir}" -lcrosslang_shared Libs: -L"${libdir}" -lcrosslang

View File

@@ -1,14 +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@
Requires: tessesframework_static
Cflags: -I"${includedir}"
Libs: -L"${libdir}" -lcrosslang_static

View File

@@ -1,23 +1,20 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
#include <iostream> #include <iostream>
namespace Tesses::CrossLang 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) 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::vector<std::string> ignored_files;
std::string file = "/.crossarchiveignore"; std::string file = "/.crossarchiveignore";
if(vfs->FileExists(file)) if (vfs->FileExists(file)) {
{ auto strm = vfs->OpenFile(file, "rb");
auto strm = vfs->OpenFile(file,"rb"); if (strm != nullptr) {
if(strm != nullptr)
{
Tesses::Framework::TextStreams::StreamReader reader(strm); Tesses::Framework::TextStreams::StreamReader reader(strm);
std::string ignores; std::string ignores;
while(reader.ReadLine(ignores)) while (reader.ReadLine(ignores)) {
{ if (!ignores.empty() && ignores[0] != '#') {
if(!ignores.empty() && ignores[0] != '#')
{
ignored_files.push_back(ignores); ignored_files.push_back(ignores);
} }
ignores.clear(); ignores.clear();
@@ -25,42 +22,20 @@ namespace Tesses::CrossLang
} }
} }
static std::vector<uint8_t> error_message_byte_code = { static std::vector<uint8_t> error_message_byte_code = {
PUSHSTRING, PUSHSTRING, 0, 0, 0, 2, GETVARIABLE, PUSHSTRING, 0, 0, 0,
0, 3, PUSHSTRING, 0, 0, 0, 4, PUSHLONG, 0, 0, 0,
0, 0, 0, 0, 0, 1, CALLMETHOD, RET};
0, auto writeInt = [](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
2, uint32_t number) -> void {
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]; uint8_t buff[4];
BitConverter::FromUint32BE(buff[0],number); BitConverter::FromUint32BE(buff[0], number);
strm->WriteBlock(buff,4); strm->WriteBlock(buff, 4);
}; };
auto writeStr = [&writeInt](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::string text)->void { auto writeStr =
writeInt(strm,(uint32_t)text.size()); [&writeInt](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
strm->WriteBlock((const uint8_t*)text.c_str(),text.size()); 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; std::vector<std::string> strs;
@@ -68,23 +43,24 @@ namespace Tesses::CrossLang
strs.push_back(info); strs.push_back(info);
strs.push_back("Console"); strs.push_back("Console");
strs.push_back("WriteLine"); 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."); 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; std::vector<std::string> resources;
auto ensureResource = [&resources](std::string path)->uint32_t { auto ensureResource = [&resources](std::string path) -> uint32_t {
for(uint32_t i = 0; i < (uint32_t)resources.size(); i++) for (uint32_t i = 0; i < (uint32_t)resources.size(); i++) {
{ if (resources[i] == path)
if(resources[i] == path) return i; return i;
} }
uint32_t index = (uint32_t)resources.size(); uint32_t index = (uint32_t)resources.size();
resources.push_back(path); resources.push_back(path);
return index; return index;
}; };
auto ensureString = [&strs](std::string str)->uint32_t { auto ensureString = [&strs](std::string str) -> uint32_t {
for(uint32_t i = 0; i < (uint32_t)strs.size(); i++) for (uint32_t i = 0; i < (uint32_t)strs.size(); i++) {
{ if (strs[i] == str)
if(strs[i] == str) return i; return i;
} }
uint32_t index = (uint32_t)strs.size(); uint32_t index = (uint32_t)strs.size();
strs.push_back(str); strs.push_back(str);
@@ -92,132 +68,142 @@ namespace Tesses::CrossLang
}; };
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true); 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 { std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkFS =
[&ignored_files, vfs, &ensureString, &ensureResource, &ms, &walkFS,
if(vfs->DirectoryExists(path)) &writeInt](Tesses::Framework::Filesystem::VFSPath path) -> void {
{ if (vfs->DirectoryExists(path)) {
ms->WriteByte(1); ms->WriteByte(1);
std::vector<std::string> paths; std::vector<std::string> paths;
for(auto item : vfs->EnumeratePaths(path)) for (auto item : vfs->EnumeratePaths(path)) {
{ if (!item.relative && item.path.size() == 1 &&
if(!item.relative && item.path.size() == 1 && item.path[0] == "__resdir_tmp") continue; item.path[0] == "__resdir_tmp")
if(!item.relative && item.path.size() == 1 && item.path[0] == ".crossarchiveignore") continue; continue;
if (!item.relative && item.path.size() == 1 &&
item.path[0] == ".crossarchiveignore")
continue;
std::string filename = item.GetFileName(); std::string filename = item.GetFileName();
bool shallIgnore=false; bool shallIgnore = false;
for(auto ign : ignored_files) if(ign == filename) {shallIgnore=true; break;} for (auto ign : ignored_files)
if(shallIgnore) continue; if (ign == filename) {
if(vfs->DirectoryExists(item) || vfs->RegularFileExists(item)) shallIgnore = true;
break;
}
if (shallIgnore)
continue;
if (vfs->DirectoryExists(item) || vfs->RegularFileExists(item))
paths.push_back(item.GetFileName()); paths.push_back(item.GetFileName());
} }
writeInt(ms,(uint32_t)paths.size()); writeInt(ms, (uint32_t)paths.size());
for(auto item : paths) for (auto item : paths) {
{ writeInt(ms, ensureString(item));
writeInt(ms,ensureString(item));
walkFS(path / item); walkFS(path / item);
} }
} } else if (vfs->RegularFileExists(path)) {
else if(vfs->RegularFileExists(path))
{
ms->WriteByte(0); ms->WriteByte(0);
writeInt(ms,ensureResource(path.ToString())); writeInt(ms, ensureResource(path.ToString()));
} }
}; };
walkFS(std::string("/")); walkFS(std::string("/"));
if(!icon.empty()) if (!icon.empty())
ensureResource(icon); ensureResource(icon);
uint8_t main_header[18]; uint8_t main_header[18];
memcpy(main_header,"TCROSSVM",8); memcpy(main_header, "TCROSSVM", 8);
TVMVersion rtVersion(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE); TVMVersion rtVersion(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
rtVersion.ToArray(main_header+8); CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
version.ToArray(main_header+13); CROSSLANG_BYTECODE_VERSIONSTAGE);
strm->WriteBlock(main_header,sizeof(main_header)); rtVersion.ToArray(main_header + 8);
writeInt(strm,(uint32_t)((icon.empty() ? 5 : 6)+resources.size())); version.ToArray(main_header + 13);
strm->WriteBlock((const uint8_t*)"STRS",4); strm->WriteBlock(main_header, sizeof(main_header));
uint32_t sz=4; writeInt(strm, (uint32_t)((icon.empty() ? 5 : 6) + resources.size()));
for(auto str : strs) strm->WriteBlock((const uint8_t *)"STRS", 4);
uint32_t sz = 4;
for (auto str : strs)
sz += (uint32_t)(4 + str.size()); sz += (uint32_t)(4 + str.size());
writeInt(strm,sz); writeInt(strm, sz);
writeInt(strm,(uint32_t)strs.size()); writeInt(strm, (uint32_t)strs.size());
for(auto str : strs) for (auto str : strs) {
{ writeStr(strm, str);
writeStr(strm,str);
} }
strm->WriteBlock((const uint8_t*)"NAME",4); strm->WriteBlock((const uint8_t *)"NAME", 4);
writeInt(strm,4); writeInt(strm, 4);
writeInt(strm,0); writeInt(strm, 0);
strm->WriteBlock((const uint8_t*)"INFO",4); strm->WriteBlock((const uint8_t *)"INFO", 4);
writeInt(strm,4); writeInt(strm, 4);
writeInt(strm,1); writeInt(strm, 1);
if(!icon.empty()) if (!icon.empty()) {
{ strm->WriteBlock((const uint8_t *)"ICON", 4);
strm->WriteBlock((const uint8_t*)"ICON",4); writeInt(strm, 4);
writeInt(strm,4); writeInt(strm, ensureResource(icon));
writeInt(strm,ensureResource(icon));
} }
strm->WriteBlock((const uint8_t*)"CHKS",4); strm->WriteBlock((const uint8_t *)"CHKS", 4);
writeInt(strm,(uint32_t)(12+error_message_byte_code.size())); writeInt(strm, (uint32_t)(12 + error_message_byte_code.size()));
writeInt(strm,1); writeInt(strm, 1);
writeInt(strm,0); writeInt(strm, 0);
writeInt(strm,(uint32_t)error_message_byte_code.size()); writeInt(strm, (uint32_t)error_message_byte_code.size());
strm->WriteBlock(error_message_byte_code.data(),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);
for(auto res : resources) auto strm2 = vfs->OpenFile(res, "rb");
{ writeInt(strm, (uint32_t)strm2->GetLength());
strm->WriteBlock((const uint8_t*)"RESO",4);
auto strm2 = vfs->OpenFile(res,"rb");
writeInt(strm,(uint32_t)strm2->GetLength());
strm2->CopyTo(strm); strm2->CopyTo(strm);
} }
strm->WriteBlock((const uint8_t*)"ARCV",4); strm->WriteBlock((const uint8_t *)"ARCV", 4);
writeInt(strm,(uint32_t)ms->GetLength()); writeInt(strm, (uint32_t)ms->GetLength());
ms->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); ms->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
ms->CopyTo(strm); 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) std::pair<std::pair<std::string, TVMVersion>, std::string>
{ CrossArchiveExtract(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
auto ensure = [strm](uint8_t* buffer,size_t count)->void{ 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); 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())); 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 { auto ensureInt = [&ensure]() -> uint32_t {
uint8_t buffer[4]; uint8_t buffer[4];
ensure(buffer,4); ensure(buffer, 4);
return BitConverter::ToUint32BE(buffer[0]); return BitConverter::ToUint32BE(buffer[0]);
}; };
auto ensureStr = [&ensure,&ensureInt]()-> std::string { auto ensureStr = [&ensure, &ensureInt]() -> std::string {
auto len = ensureInt(); auto len = ensureInt();
if(len == 0) return {}; if (len == 0)
std::string str={}; return {};
std::string str = {};
str.resize((size_t)len); str.resize((size_t)len);
ensure((uint8_t*)str.data(),str.size()); ensure((uint8_t *)str.data(), str.size());
return str; return str;
}; };
std::vector<std::string> strs; std::vector<std::string> strs;
auto getStr = [&ensure,&ensureInt,&strs]()-> std::string { auto getStr = [&ensure, &ensureInt, &strs]() -> std::string {
auto index = ensureInt(); 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())); 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]; return strs[index];
}; };
uint8_t main_header[18]; uint8_t main_header[18];
ensure(main_header,sizeof(main_header)); ensure(main_header, sizeof(main_header));
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image."); if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
TVMVersion version(main_header+8); throw VMException("Invalid TCrossVM image.");
if(version.CompareToRuntime() == 1) TVMVersion version(main_header + 8);
{ if (version.CompareToRuntime() == 1) {
throw VMException("Runtime is too old."); throw VMException("Runtime is too old.");
} }
TVMVersion v2(main_header+13); TVMVersion v2(main_header + 13);
std::string name; std::string name;
std::string info; std::string info;
size_t _len = (size_t)ensureInt(); size_t _len = (size_t)ensureInt();
char table_name[4]; char table_name[4];
@@ -227,98 +213,94 @@ namespace Tesses::CrossLang
Tesses::Framework::Filesystem::VFSPath tmpDir("/__resdir_tmp"); Tesses::Framework::Filesystem::VFSPath tmpDir("/__resdir_tmp");
vfs->CreateDirectory(tmpDir); vfs->CreateDirectory(tmpDir);
for(size_t i = 0;i < _len; i++) for (size_t i = 0; i < _len; i++) {
{ ensure((uint8_t *)table_name, sizeof(table_name));
ensure((uint8_t*)table_name,sizeof(table_name));
size_t tableLen = (size_t)ensureInt(); size_t tableLen = (size_t)ensureInt();
if(strncmp(table_name,"NAME",4) == 0) if (strncmp(table_name, "NAME", 4) == 0) {
{
name = getStr(); name = getStr();
} } else if (strncmp(table_name, "INFO", 4) == 0) {
else if(strncmp(table_name,"INFO",4) == 0)
{
info = getStr(); info = getStr();
} }
else if(strncmp(table_name,"RESO",4) == 0) //resources (using embed) else if (strncmp(table_name, "RESO", 4) == 0) // resources (using embed)
{ {
auto path = tmpDir /std::to_string(resource_id); auto path = tmpDir / std::to_string(resource_id);
auto strm2 = vfs->OpenFile(path,"wb"); auto strm2 = vfs->OpenFile(path, "wb");
size_t read = 0; size_t read = 0;
size_t offset = 0; size_t offset = 0;
uint8_t buff[1024]; uint8_t buff[1024];
do { do {
read = std::min(std::min(tableLen-offset,tableLen), sizeof(buff)); read = std::min(std::min(tableLen - offset, tableLen),
read = strm->Read(buff,read); sizeof(buff));
if(read > 0) read = strm->Read(buff, read);
strm2->WriteBlock(buff,read); if (read > 0)
offset+=read; strm2->WriteBlock(buff, read);
} while(read > 0); offset += read;
} while (read > 0);
resource_id++; resource_id++;
} }
else if(strncmp(table_name,"STRS",4) == 0) //strings else if (strncmp(table_name, "STRS", 4) == 0) // strings
{ {
size_t strsLen = (size_t)ensureInt(); size_t strsLen = (size_t)ensureInt();
for(size_t j = 0;j < strsLen;j++) for (size_t j = 0; j < strsLen; j++) {
{
strs.push_back(ensureStr()); strs.push_back(ensureStr());
} }
} } else if (strncmp(table_name, "ARCV", 4) == 0) {
else if(strncmp(table_name,"ARCV",4) == 0)
{
size_t offset = 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 { std::function<void(Tesses::Framework::Filesystem::VFSPath)>
if(offset + 1 > tableLen) return; 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(); uint8_t type = strm->ReadByte();
offset++; offset++;
if(type == 1) if (type == 1) {
{ // ISDIR
//ISDIR
vfs->CreateDirectory(path); vfs->CreateDirectory(path);
if(offset + 4 > tableLen) return; if (offset + 4 > tableLen)
return;
uint32_t count = ensureInt(); uint32_t count = ensureInt();
offset +=4; offset += 4;
for(uint32_t i = 0; i < count; i++) for (uint32_t i = 0; i < count; i++) {
{ if (offset + 4 > tableLen)
if(offset + 4 > tableLen) return; return;
std::string name = getStr(); std::string name = getStr();
offset +=4; offset += 4;
walkEntry(path / name); walkEntry(path / name);
} }
} } else if (type == 0) {
else if(type == 0) if (offset + 4 > tableLen)
{ return;
if(offset + 4 > tableLen) return;
uint32_t index = ensureInt(); uint32_t index = ensureInt();
auto fSrc = tmpDir /std::to_string(index); auto fSrc = tmpDir / std::to_string(index);
vfs->MoveFile(fSrc, path); vfs->MoveFile(fSrc, path);
} }
}; };
walkEntry(std::string("/")); walkEntry(std::string("/"));
} } else {
else if (strm->CanSeek()) {
{ strm->Seek((int64_t)tableLen,
if(strm->CanSeek()) Tesses::Framework::Streams::SeekOrigin::Current);
{ } else {
strm->Seek((int64_t)tableLen,Tesses::Framework::Streams::SeekOrigin::Current); uint8_t *buffer = new uint8_t[tableLen];
} ensure(buffer, tableLen);
else{
uint8_t* buffer=new uint8_t[tableLen];
ensure(buffer,tableLen);
delete[] buffer; delete[] buffer;
} }
} }
} }
vfs->DeleteDirectoryRecurse(tmpDir); vfs->DeleteDirectoryRecurse(tmpDir);
return std::pair<std::pair<std::string,TVMVersion>,std::string>(std::pair<std::string,TVMVersion>(name,v2),info); 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) #if defined(CROSSLANG_ENABLE_JSON)
#include <jansson.h> #include <jansson.h>
#endif #endif
namespace Tesses::CrossLang namespace Tesses::CrossLang {
{ AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,
AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,bool isExpression, std::vector<SyntaxNode> nodes) bool isExpression,
{ std::vector<SyntaxNode> nodes) {
AdvancedSyntaxNode asn; AdvancedSyntaxNode asn;
asn.nodeName = std::string(nodeName); asn.nodeName = std::string(nodeName);
asn.isExpression = isExpression; asn.isExpression = isExpression;
@@ -14,45 +14,43 @@ AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,bool isE
} }
#if defined(CROSSLANG_ENABLE_JSON) #if defined(CROSSLANG_ENABLE_JSON)
static SyntaxNode Deserialize2(json_t* json) static SyntaxNode Deserialize2(json_t *json) {
{ if (json_is_null(json))
if(json_is_null(json)) return nullptr; return nullptr;
if(json_is_true(json)) return true; if (json_is_true(json))
if(json_is_false(json)) return false; return true;
if(json_is_integer(json)) return (int64_t)json_integer_value(json); if (json_is_false(json))
if(json_is_real(json)) return json_real_value(json); return false;
if(json_is_string(json)) return std::string(json_string_value(json),json_string_length(json)); if (json_is_integer(json))
if(json_is_object(json)) return (int64_t)json_integer_value(json);
{ if (json_is_real(json))
json_t* typ = json_object_get(json, "type"); return json_real_value(json);
if(json_is_string(typ)) if (json_is_string(json))
{ return std::string(json_string_value(json), json_string_length(json));
std::string type(json_string_value(typ),json_string_length(typ)); if (json_is_object(json)) {
if(type == CharExpression) json_t *typ = json_object_get(json, "type");
{ if (json_is_string(typ)) {
json_t* chrData = json_object_get(json,"value"); std::string type(json_string_value(typ), json_string_length(typ));
if(json_is_integer(chrData)) if (type == CharExpression) {
{ json_t *chrData = json_object_get(json, "value");
if (json_is_integer(chrData)) {
return (char)(uint8_t)json_integer_value(chrData); return (char)(uint8_t)json_integer_value(chrData);
} }
} }
if(type == UndefinedExpression) if (type == UndefinedExpression) {
{
return Undefined(); return Undefined();
} }
json_t* isExpr = json_object_get(json,"isExpression"); json_t *isExpr = json_object_get(json, "isExpression");
bool isExprB = json_is_true(isExpr); bool isExprB = json_is_true(isExpr);
AdvancedSyntaxNode asn; AdvancedSyntaxNode asn;
asn.nodeName = type; asn.nodeName = type;
asn.isExpression = isExprB; asn.isExpression = isExprB;
json_t* args = json_object_get(json, "args"); json_t *args = json_object_get(json, "args");
if(json_is_array(args)) if (json_is_array(args)) {
{
size_t index; size_t index;
json_t* value; json_t *value;
json_array_foreach(args, index, value) json_array_foreach(args, index, value) {
{
asn.nodes.push_back(Deserialize2(value)); asn.nodes.push_back(Deserialize2(value));
} }
} }
@@ -63,68 +61,59 @@ static SyntaxNode Deserialize2(json_t* json)
} }
#endif #endif
SyntaxNode Deserialize(std::string astData) {
SyntaxNode Deserialize(std::string astData) #if defined(CROSSLANG_ENABLE_JSON)
{ json_t *json = json_loadb(astData.c_str(), astData.size(), 0, NULL);
#if defined(CROSSLANG_ENABLE_JSON)
json_t* json = json_loadb(astData.c_str(),astData.size(), 0, NULL);
auto r = Deserialize2(json); auto r = Deserialize2(json);
json_decref(json); json_decref(json);
return r; return r;
#endif #endif
return nullptr; return nullptr;
} }
#if defined(CROSSLANG_ENABLE_JSON) #if defined(CROSSLANG_ENABLE_JSON)
static json_t* Serialize2(SyntaxNode node) static json_t *Serialize2(SyntaxNode node) {
{ if (std::holds_alternative<std::nullptr_t>(node))
if(std::holds_alternative<std::nullptr_t>(node))
return json_null(); 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)); 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)); 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)); 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); 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); char c = std::get<char>(node);
json_t* json = json_object(); json_t *json = json_object();
json_object_set_new(json,"type",json_string((const char*)CharExpression.data())); json_object_set_new(json, "type",
json_string((const char *)CharExpression.data()));
json_object_set_new(json, "value", json_integer((uint8_t)c)); json_object_set_new(json, "value", json_integer((uint8_t)c));
return json; return json;
} }
if(std::holds_alternative<Undefined>(node)) if (std::holds_alternative<Undefined>(node)) {
{ json_t *json = json_object();
json_t* json = json_object(); json_object_set_new(
json_object_set_new(json,"type",json_string((const char*)UndefinedExpression.data())); json, "type",
json_string((const char *)UndefinedExpression.data()));
return json; return json;
} }
if (std::holds_alternative<AdvancedSyntaxNode>(node)) {
if(std::holds_alternative<AdvancedSyntaxNode>(node))
{
auto asn = std::get<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, "type", json_string(asn.nodeName.c_str()));
json_object_set_new(j, "isExpression",json_boolean(asn.isExpression)); json_object_set_new(j, "isExpression", json_boolean(asn.isExpression));
json_t* arr=json_array(); json_t *arr = json_array();
for(auto item : asn.nodes) for (auto item : asn.nodes) {
{ json_array_append_new(arr, Serialize2(item));
json_array_append_new(arr,Serialize2(item));
} }
json_object_set_new(j, "args", arr); json_object_set_new(j, "args", arr);
return j; return j;
@@ -134,18 +123,17 @@ static json_t* Serialize2(SyntaxNode node)
} }
#endif #endif
std::string Serialize(SyntaxNode node) std::string Serialize(SyntaxNode node) {
{
#if defined(CROSSLANG_ENABLE_JSON) #if defined(CROSSLANG_ENABLE_JSON)
json_t* json = Serialize2(node); json_t *json = Serialize2(node);
char* txt = json_dumps(json,0); char *txt = json_dumps(json, 0);
std::string str(txt); std::string str(txt);
free(json); free(json);
json_decref(json); json_decref(json);
return str; return str;
#endif #endif
return ""; return "";
} }
} } // namespace Tesses::CrossLang

File diff suppressed because it is too large Load Diff

View File

@@ -1,95 +1,70 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
namespace Tesses::CrossLang namespace Tesses::CrossLang {
{ std::string EscapeString(std::string text, bool quote) {
std::string EscapeString(std::string text,bool quote) std::string str = {};
{ if (quote)
std::string str={}; str.push_back('\"');
if(quote) str.push_back('\"'); for (auto item : text) {
for(auto item : text) if (item == '\\' || item == '\"' || item == '\'') {
{
if(item == '\\' || item == '\"' || item == '\'')
{
str.push_back('\\'); str.push_back('\\');
str.push_back(item); str.push_back(item);
} } else if (item == '\n') {
else if(item == '\n')
{
str.push_back('\\'); str.push_back('\\');
str.push_back('n'); str.push_back('n');
} } else if (item == '\r') {
else if(item == '\r')
{
str.push_back('\\'); str.push_back('\\');
str.push_back('r'); str.push_back('r');
} } else if (item == '\t') {
else if(item == '\t')
{
str.push_back('\\'); str.push_back('\\');
str.push_back('t'); str.push_back('t');
} } else if (item == '\f') {
else if(item == '\f')
{
str.push_back('\\'); str.push_back('\\');
str.push_back('f'); str.push_back('f');
} } else if (item == '\0') {
else if(item == '\0')
{
str.push_back('\\'); str.push_back('\\');
str.push_back('0'); str.push_back('0');
} } else if (item == '\b') {
else if(item == '\b')
{
str.push_back('\\'); str.push_back('\\');
str.push_back('b'); str.push_back('b');
} } else if (item == '\a') {
else if(item == '\a')
{
str.push_back('\\'); str.push_back('\\');
str.push_back('a'); str.push_back('a');
} } else if (item == '\v') {
else if(item == '\v')
{
str.push_back('\\'); str.push_back('\\');
str.push_back('v'); str.push_back('v');
} } else if (item == '\x1B') {
else if(item == '\x1B')
{
str.push_back('\\'); str.push_back('\\');
str.push_back('e'); str.push_back('e');
} } else if ((uint8_t)item < 32 || (uint8_t)item > 126) {
else if((uint8_t)item < 32 || (uint8_t)item > 126)
{
str.append("\\x"); str.append("\\x");
str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex(((uint8_t)item >> 4)&0x0F)); str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex(
str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex((uint8_t)item & 0x0F)); ((uint8_t)item >> 4) & 0x0F));
} str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex(
else (uint8_t)item & 0x0F));
{ } else {
str.push_back(item); str.push_back(item);
} }
} }
if(quote) str.push_back('\"'); if (quote)
str.push_back('\"');
return str; return str;
} }
void LexTokenLineInfo::Subtract(size_t len) void LexTokenLineInfo::Subtract(size_t len) {
{
this->offset -= len; this->offset -= len;
this->column -= len; this->column -= len;
} }
void LexTokenLineInfo::Add(int c) void LexTokenLineInfo::Add(int c) {
{
this->offset++; this->offset++;
switch(c) switch (c) {
{
case ' ': case ' ':
this->column++; this->column++;
break; break;
case '\n': case '\n':
this->column=1; this->column = 1;
this->line++; this->line++;
break; break;
case '\t': case '\t':
@@ -102,28 +77,29 @@ namespace Tesses::CrossLang
this->column++; this->column++;
break; break;
} }
} }
int Lex(std::string filename, std::istream& strm, std::vector<LexToken>& tokens) int Lex(std::string filename, std::istream &strm,
{ std::vector<LexToken> &tokens) {
int _peeked=-1; int _peeked = -1;
auto Read = [&_peeked,&strm]()->int { auto Read = [&_peeked, &strm]() -> int {
if(_peeked > -1) if (_peeked > -1) {
{
int _peek2 = _peeked; int _peek2 = _peeked;
_peeked=-1; _peeked = -1;
return _peek2; return _peek2;
} }
uint8_t b; uint8_t b;
strm.read((char*)&b,1); strm.read((char *)&b, 1);
if(strm.eof()) return -1; if (strm.eof())
return -1;
return b; return b;
}; };
auto Peek = [&_peeked,Read]()->int { auto Peek = [&_peeked, Read]() -> int {
if(_peeked > -1) return _peeked; if (_peeked > -1)
return _peeked;
_peeked = Read(); _peeked = Read();
return _peeked; return _peeked;
}; };
@@ -131,7 +107,7 @@ namespace Tesses::CrossLang
int read; int read;
int peek; int peek;
std::string buffer={}; std::string buffer = {};
LexTokenLineInfo lineInfo; LexTokenLineInfo lineInfo;
@@ -140,11 +116,11 @@ namespace Tesses::CrossLang
lineInfo.line = 1; lineInfo.line = 1;
lineInfo.offset = 0; lineInfo.offset = 0;
std::string whiteSpaceCharsBefore=""; std::string whiteSpaceCharsBefore = "";
auto Flush = [&buffer,&tokens,&lineInfo,&whiteSpaceCharsBefore]() -> void { auto Flush = [&buffer, &tokens, &lineInfo,
if(!buffer.empty()) &whiteSpaceCharsBefore]() -> void {
{ if (!buffer.empty()) {
LexToken token; LexToken token;
token.text = buffer; token.text = buffer;
token.whiteSpaceCharsBefore = whiteSpaceCharsBefore; token.whiteSpaceCharsBefore = whiteSpaceCharsBefore;
@@ -154,149 +130,113 @@ namespace Tesses::CrossLang
tokens.push_back(token); tokens.push_back(token);
buffer.clear(); buffer.clear();
whiteSpaceCharsBefore=""; whiteSpaceCharsBefore = "";
} }
}; };
auto Symbol = [&tokens,&lineInfo,&whiteSpaceCharsBefore](std::initializer_list<int> chrs)-> void { auto Symbol = [&tokens, &lineInfo, &whiteSpaceCharsBefore](
std::initializer_list<int> chrs) -> void {
LexToken token; LexToken token;
token.type = LexTokenType::Symbol; token.type = LexTokenType::Symbol;
token.lineInfo = lineInfo; token.lineInfo = lineInfo;
token.whiteSpaceCharsBefore=whiteSpaceCharsBefore; token.whiteSpaceCharsBefore = whiteSpaceCharsBefore;
token.text.reserve(chrs.size()); token.text.reserve(chrs.size());
for(auto i : chrs) for (auto i : chrs)
token.text.push_back((char)i); token.text.push_back((char)i);
tokens.push_back(token); tokens.push_back(token);
whiteSpaceCharsBefore=""; whiteSpaceCharsBefore = "";
}; };
auto ReadChr = [&lineInfo, &strm, Read]() -> std::pair<int,bool> { auto ReadChr = [&lineInfo, &strm, Read]() -> std::pair<int, bool> {
int read=Read(); int read = Read();
lineInfo.Add(read); lineInfo.Add(read);
if(read == -1) if (read == -1) {
{
return std::pair<int,bool>(-1,false); return std::pair<int, bool>(-1, false);
} }
if (read == '\\') {
if(read == '\\')
{
read = Read(); read = Read();
lineInfo.Add(read); lineInfo.Add(read);
if(read == -1) if (read == -1) {
{ return std::pair<int, bool>(-1, true);
return std::pair<int,bool>(-1,true); } else if (read == 'n') {
} return std::pair<int, bool>('\n', true);
else if(read == 'n') } else if (read == 'r') {
{ return std::pair<int, bool>('\r', true);
return std::pair<int,bool>('\n',true); } else if (read == 'f') {
} return std::pair<int, bool>('\f', true);
else if(read == 'r') } else if (read == 'b') {
{ return std::pair<int, bool>('\b', true);
return std::pair<int,bool>('\r',true); } else if (read == 'a') {
} return std::pair<int, bool>('\a', true);
else if(read == 'f') } else if (read == '0') {
{ return std::pair<int, bool>('\0', true);
return std::pair<int,bool>('\f',true); } else if (read == 'v') {
} return std::pair<int, bool>('\v', true);
else if(read == 'b') } else if (read == 'e') {
{ return std::pair<int, bool>('\x1B', true);
return std::pair<int,bool>('\b',true); } else if (read == 't') {
} return std::pair<int, bool>('\t', true);
else if(read == 'a') } else if (read == 'x') {
{
return std::pair<int,bool>('\a',true);
}
else if(read == '0')
{
return std::pair<int,bool>('\0',true);
}
else if(read == 'v')
{
return std::pair<int,bool>('\v',true);
}
else if(read == 'e')
{
return std::pair<int,bool>('\x1B',true);
}
else if(read == 't')
{
return std::pair<int,bool>('\t',true);
}
else if(read == 'x')
{
int r1 = Read(); int r1 = Read();
lineInfo.Add(r1); lineInfo.Add(r1);
if(r1 == -1) if (r1 == -1) {
{ return std::pair<int, bool>(-1, true);
return std::pair<int,bool>(-1,true);
} }
int r2 = Read(); int r2 = Read();
lineInfo.Add(r2); lineInfo.Add(r2);
if(r2 == -1) if (r2 == -1) {
{ return std::pair<int, bool>(-1, true);
return std::pair<int,bool>(-1,true);
} }
uint8_t c = (uint8_t)std::stoi(std::string{(char)r1,(char)r2},nullptr,16); uint8_t c = (uint8_t)std::stoi(std::string{(char)r1, (char)r2},
nullptr, 16);
return std::pair<int,bool>(c,true); return std::pair<int, bool>(c, true);
} else {
return std::pair<int, bool>(read, true);
} }
else } else {
{ return std::pair<int, bool>(read, false);
return std::pair<int,bool>(read,true);
}
}
else
{
return std::pair<int,bool>(read,false);
} }
}; };
auto ParseString = [&lineInfo, &strm, Read, ReadChr,
auto ParseString = [&lineInfo, &strm, Read, ReadChr,&tokens](bool interopolated)->int { &tokens](bool interopolated) -> int {
auto lI = lineInfo; auto lI = lineInfo;
std::string b={}; std::string b = {};
auto rChr = ReadChr(); auto rChr = ReadChr();
lineInfo.Add(rChr.first); lineInfo.Add(rChr.first);
while(rChr.first != '\"' || rChr.second) while (rChr.first != '\"' || rChr.second) {
{ if (rChr.first == -1)
if(rChr.first == -1) return lineInfo.line; return lineInfo.line;
b.push_back((char)rChr.first); b.push_back((char)rChr.first);
rChr = ReadChr(); rChr = ReadChr();
lineInfo.Add(rChr.first); lineInfo.Add(rChr.first);
} }
if(interopolated) if (interopolated) {
{
int e = 0; int e = 0;
int escapeI = 0; int escapeI = 0;
std::string b2 = {}; std::string b2 = {};
for(size_t i = 0; i< b.size();i++) for (size_t i = 0; i < b.size(); i++) {
{ if (b[i] == '{') {
if(b[i] == '{') if ((i + 1 < b.size() && b[i + 1] != '{') || escapeI >= 1) {
{ if (b2.size() > 0 && escapeI < 1) {
if((i+1 < b.size() && b[i+1] != '{') || escapeI >= 1) if (e > 0) {
{
if(b2.size() > 0 && escapeI < 1)
{
if(e > 0)
{
LexToken _tkn; LexToken _tkn;
_tkn.type = LexTokenType::Symbol; _tkn.type = LexTokenType::Symbol;
_tkn.text = "+"; _tkn.text = "+";
@@ -310,29 +250,20 @@ namespace Tesses::CrossLang
tokens.push_back(_tkn2); tokens.push_back(_tkn2);
b2.clear(); b2.clear();
e++; e++;
} }
escapeI++; escapeI++;
if(escapeI > 1) if (escapeI > 1) {
{
b2.push_back('{'); b2.push_back('{');
} }
} } else {
else
{
b2.push_back('{'); b2.push_back('{');
i++; i++;
} }
} } else if (b[i] == '}') {
else if(b[i] == '}') if (escapeI >= 1) {
{
if(escapeI >= 1)
{
escapeI--; escapeI--;
if(b2.size() > 0 && escapeI == 0) if (b2.size() > 0 && escapeI == 0) {
{ if (e > 0) {
if(e > 0)
{
LexToken _tkn; LexToken _tkn;
_tkn.type = LexTokenType::Symbol; _tkn.type = LexTokenType::Symbol;
_tkn.text = "+"; _tkn.text = "+";
@@ -344,9 +275,11 @@ namespace Tesses::CrossLang
_tkn2.text = "("; _tkn2.text = "(";
_tkn2.lineInfo = lI; _tkn2.lineInfo = lI;
tokens.push_back(_tkn2); tokens.push_back(_tkn2);
std::stringstream strm2(b2,std::ios_base::in | std::ios_base::binary); std::stringstream strm2(
b2, std::ios_base::in | std::ios_base::binary);
int res = Lex("lexGen", strm2, tokens); int res = Lex("lexGen", strm2, tokens);
if(res != 0) return res; if (res != 0)
return res;
_tkn2.text = ")"; _tkn2.text = ")";
tokens.push_back(_tkn2); tokens.push_back(_tkn2);
@@ -364,8 +297,7 @@ namespace Tesses::CrossLang
b2.clear(); b2.clear();
e++; e++;
} }
if(escapeI >= 1) if (escapeI >= 1) {
{
b2.push_back('}'); b2.push_back('}');
} }
} }
@@ -373,12 +305,9 @@ namespace Tesses::CrossLang
b2.push_back(b[i]); b2.push_back(b[i]);
} }
} }
if(b2.size() > 0) if (b2.size() > 0) {
{ if (escapeI > 0) {
if(escapeI > 0) if (e > 0) {
{
if(e > 0)
{
LexToken _tkn; LexToken _tkn;
_tkn.type = LexTokenType::Symbol; _tkn.type = LexTokenType::Symbol;
_tkn.text = "+"; _tkn.text = "+";
@@ -390,9 +319,11 @@ namespace Tesses::CrossLang
_tkn2.text = "("; _tkn2.text = "(";
_tkn2.lineInfo = lI; _tkn2.lineInfo = lI;
tokens.push_back(_tkn2); tokens.push_back(_tkn2);
std::stringstream strm2(b2,std::ios_base::in | std::ios_base::binary); std::stringstream strm2(b2, std::ios_base::in |
std::ios_base::binary);
int res = Lex("lexGen", strm2, tokens); int res = Lex("lexGen", strm2, tokens);
if(res != 0) return res; if (res != 0)
return res;
_tkn2.text = ")"; _tkn2.text = ")";
tokens.push_back(_tkn2); tokens.push_back(_tkn2);
@@ -410,11 +341,8 @@ namespace Tesses::CrossLang
b2.clear(); b2.clear();
e++; e++;
} } else {
else if (e > 0) {
{
if(e > 0)
{
LexToken _tkn; LexToken _tkn;
_tkn.type = LexTokenType::Symbol; _tkn.type = LexTokenType::Symbol;
_tkn.text = "+"; _tkn.text = "+";
@@ -436,47 +364,40 @@ namespace Tesses::CrossLang
_tkn2.text = b; _tkn2.text = b;
_tkn2.lineInfo = lI; _tkn2.lineInfo = lI;
tokens.push_back(_tkn2); tokens.push_back(_tkn2);
} }
return 0; return 0;
}; };
while((read = Read()) != -1) while ((read = Read()) != -1) {
{
peek = Peek(); peek = Peek();
switch (read) {
switch(read)
{
case '$': case '$':
if(peek == '\"') if (peek == '\"') {
{
Flush(); Flush();
lineInfo.Add(Read()); lineInfo.Add(Read());
int re = ParseString(true); int re = ParseString(true);
if(re != 0) return re; if (re != 0)
} return re;
else } else {
{
buffer.push_back('$'); buffer.push_back('$');
} }
break; break;
case '\"': case '\"': {
{
Flush(); Flush();
int re = ParseString(false); int re = ParseString(false);
if(re != 0) return re; if (re != 0)
} return re;
break; } break;
case '\'': case '\'': {
{
Flush(); Flush();
auto res = ReadChr(); auto res = ReadChr();
if(res.first == -1) return lineInfo.line; if (res.first == -1)
return lineInfo.line;
int r = Read(); int r = Read();
lineInfo.Add(r); lineInfo.Add(r);
if(r != '\'') if (r != '\'')
return lineInfo.line; return lineInfo.line;
LexToken token; LexToken token;
token.text = {(char)(uint8_t)res.first}; token.text = {(char)(uint8_t)res.first};
@@ -484,75 +405,62 @@ namespace Tesses::CrossLang
token.type = LexTokenType::Char; token.type = LexTokenType::Char;
tokens.push_back(token); tokens.push_back(token);
} } break;
break;
case '#': case '#':
Flush(); Flush();
while(true) while (true) {
{
int r = Read(); int r = Read();
lineInfo.Add(r); lineInfo.Add(r);
if(r == '\n' || r == -1) break; if (r == '\n' || r == -1)
break;
} }
break; break;
case '/': case '/':
if(peek == '/') if (peek == '/') {
{
Flush(); Flush();
while(true) while (true) {
{
int r = Read(); int r = Read();
lineInfo.Add(r); lineInfo.Add(r);
if(r == '\n' || r == -1) break; if (r == '\n' || r == -1)
break;
} }
} } else if (peek == '*') {
else if(peek == '*')
{
Flush(); Flush();
while(true) while (true) {
{
int r = Read(); int r = Read();
lineInfo.Add(r); lineInfo.Add(r);
if(r == -1) if (r == -1) {
{
return lineInfo.line; return lineInfo.line;
} }
if(r == '*') if (r == '*') {
{
r = Read(); r = Read();
lineInfo.Add(r); lineInfo.Add(r);
if(r == -1) if (r == -1)
return lineInfo.line; return lineInfo.line;
if(r == '/') if (r == '/')
break; break;
} }
} }
} } else if (peek == '^') {
else if(peek == '^')
{
Flush(); Flush();
lineInfo.Add(Read()); lineInfo.Add(Read());
std::string str={}; std::string str = {};
while(true) while (true) {
{
int r = Read(); int r = Read();
lineInfo.Add(r); lineInfo.Add(r);
if(r == -1) if (r == -1) {
{
return lineInfo.line; return lineInfo.line;
} }
if(r == '^') if (r == '^') {
{
r = Read(); r = Read();
lineInfo.Add(r); lineInfo.Add(r);
if(r == -1) if (r == -1)
return lineInfo.line; return lineInfo.line;
if(r == '^') if (r == '^') {
{
str.push_back('^'); str.push_back('^');
continue; continue;
} }
if(r == '/') if (r == '/')
break; break;
str.push_back('^'); str.push_back('^');
} }
@@ -564,44 +472,32 @@ namespace Tesses::CrossLang
token.lineInfo = lineInfo; token.lineInfo = lineInfo;
token.text = str; token.text = str;
tokens.push_back(token); tokens.push_back(token);
} } else if (peek == '=') {
else if(peek == '=')
{
Flush(); Flush();
lineInfo.Add(Read()); lineInfo.Add(Read());
Symbol({read,peek}); Symbol({read, peek});
} } else {
else
{
Flush(); Flush();
Symbol({read}); Symbol({read});
} }
break; break;
case '<': case '<':
case '?': case '?':
if(peek == read) if (peek == read) {
{
Flush(); Flush();
lineInfo.Add(Read()); lineInfo.Add(Read());
int peek2=Peek(); int peek2 = Peek();
if(peek2 == '=') if (peek2 == '=') {
{
lineInfo.Add(Read()); lineInfo.Add(Read());
Symbol({read,peek,peek2}); Symbol({read, peek, peek2});
} else {
Symbol({read, peek});
} }
else } else if (peek == '=') {
{
Symbol({read,peek});
}
}
else if(peek == '=')
{
Flush(); Flush();
lineInfo.Add(Read()); lineInfo.Add(Read());
Symbol({read,peek}); Symbol({read, peek});
} } else {
else
{
Flush(); Flush();
Symbol({read}); Symbol({read});
} }
@@ -610,33 +506,25 @@ namespace Tesses::CrossLang
case '-': case '-':
case '|': case '|':
case '&': case '&':
if(peek == '=' || peek == read) if (peek == '=' || peek == read) {
{
Flush(); Flush();
lineInfo.Add(Read()); lineInfo.Add(Read());
Symbol({read,peek}); Symbol({read, peek});
} } else {
else
{
Flush(); Flush();
Symbol({read}); Symbol({read});
} }
break; break;
case '=': case '=':
if(peek == '>') if (peek == '>') {
{
Flush(); Flush();
lineInfo.Add(Read()); lineInfo.Add(Read());
Symbol({read,peek}); Symbol({read, peek});
} } else if (peek == '=') {
else if(peek == '=')
{
Flush(); Flush();
lineInfo.Add(Read()); lineInfo.Add(Read());
Symbol({read,peek}); Symbol({read, peek});
} } else {
else
{
Flush(); Flush();
Symbol({read}); Symbol({read});
} }
@@ -649,14 +537,11 @@ namespace Tesses::CrossLang
case '%': case '%':
//* //*
//*= //*=
if(peek == '=') if (peek == '=') {
{
Flush(); Flush();
lineInfo.Add(Read()); lineInfo.Add(Read());
Symbol({read,peek}); Symbol({read, peek});
} } else {
else
{
Flush(); Flush();
Symbol({read}); Symbol({read});
} }
@@ -691,5 +576,5 @@ namespace Tesses::CrossLang
} }
Flush(); Flush();
return 0; return 0;
}
} }
} // namespace Tesses::CrossLang

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

View File

@@ -1,37 +1,25 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang namespace Tesses::CrossLang {
{ SharedPtrTObject::SharedPtrTObject(std::shared_ptr<GC> gc, TObject o) {
SharedPtrTObject::SharedPtrTObject(std::shared_ptr<GC> gc, TObject o)
{
this->ls = new GCList(gc); this->ls = new GCList(gc);
this->ls->Add(o); this->ls->Add(o);
this->o = 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);
}
} }
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);
}
} // namespace Tesses::CrossLang

View File

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

View File

@@ -1,38 +1,37 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
#include <iostream> #include <iostream>
namespace Tesses::CrossLang::Programs { namespace Tesses::CrossLang::Programs {
static void Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,uint8_t* buffer, size_t len) static void Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
{ uint8_t *buffer, size_t len) {
if(strm->ReadBlock(buffer,len) != len) if (strm->ReadBlock(buffer, len) != len) {
{ throw VMException("Could not read " + std::to_string(len) +
throw VMException("Could not read " + std::to_string(len) + " byte(s)."); " 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]; uint8_t buff[4];
Ensure(strm,buff,sizeof(buff)); Ensure(strm, buff, sizeof(buff));
return BitConverter::ToUint32BE(buff[0]); 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); size_t len = (size_t)EnsureInt(strm);
std::string myStr={}; std::string myStr = {};
myStr.resize(len); myStr.resize(len);
Ensure(strm,(uint8_t*)myStr.data(), len); Ensure(strm, (uint8_t *)myStr.data(), len);
return myStr; 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]; uint8_t main_header[18];
Ensure(strm,main_header,sizeof(main_header)); Ensure(strm, main_header, sizeof(main_header));
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image."); if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
TVMVersion version(main_header+8); throw VMException("Invalid TCrossVM image.");
if(version.CompareToRuntime() == 1) TVMVersion version(main_header + 8);
{ if (version.CompareToRuntime() == 1) {
throw VMException("Runtime is too old."); throw VMException("Runtime is too old.");
} }
TVMVersion v2(main_header+13); TVMVersion v2(main_header + 13);
std::cout << "Version: " << v2.ToString() << std::endl; std::cout << "Version: " << v2.ToString() << std::endl;
size_t _len = (size_t)EnsureInt(strm); size_t _len = (size_t)EnsureInt(strm);
@@ -44,85 +43,73 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
std::unordered_map<uint32_t, std::vector<std::string>> funs; std::unordered_map<uint32_t, std::vector<std::string>> funs;
std::vector<std::vector<std::string>> closures; std::vector<std::vector<std::string>> closures;
char table_name[4]; char table_name[4];
bool hasIcon=false; bool hasIcon = false;
for(size_t i = 0; i < _len; i++) for (size_t i = 0; i < _len; i++) {
{ Ensure(strm, (uint8_t *)table_name, sizeof(table_name));
Ensure(strm,(uint8_t*)table_name,sizeof(table_name));
size_t tableLen = (size_t)EnsureInt(strm); size_t tableLen = (size_t)EnsureInt(strm);
std::string tableName(table_name,4); std::string tableName(table_name, 4);
if(tableName == "ICON") if (tableName == "ICON") {
{ hasIcon = true;
hasIcon=true; } else if (tableName == "STRS") {
}
else if(tableName == "STRS")
{
size_t strsLen = (size_t)EnsureInt(strm); size_t strsLen = (size_t)EnsureInt(strm);
for(size_t j = 0;j < strsLen;j++) for (size_t j = 0; j < strsLen; j++) {
{
strs.push_back(EnsureString(strm)); strs.push_back(EnsureString(strm));
} }
} } else if (tableName == "DEPS") {
else if(tableName == "DEPS")
{
std::string name = strs.at((size_t)EnsureInt(strm)); std::string name = strs.at((size_t)EnsureInt(strm));
uint8_t version_bytes[5]; uint8_t version_bytes[5];
Ensure(strm,version_bytes,sizeof(version_bytes)); Ensure(strm, version_bytes, sizeof(version_bytes));
TVMVersion depVersion(version_bytes); TVMVersion depVersion(version_bytes);
std::cout << "Dependency: " << name << "-" << depVersion.ToString() << std::endl; std::cout << "Dependency: " << name << "-" << depVersion.ToString()
} << std::endl;
else if(tableName == "NAME") } else if (tableName == "NAME") {
{ std::cout << "Name: " << strs.at((size_t)EnsureInt(strm))
std::cout << "Name: " << strs.at((size_t)EnsureInt(strm)) << std::endl; << std::endl;
} } else if (tableName == "CLSS") {
else if(tableName == "CLSS")
{
std::cout << "Classes:\n"; std::cout << "Classes:\n";
uint32_t clss_cnt= EnsureInt(strm); uint32_t clss_cnt = EnsureInt(strm);
for(uint32_t j = 0; j < clss_cnt; j++) for (uint32_t j = 0; j < clss_cnt; j++) {
{ std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/"
std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl; << std::endl;
uint32_t fnPartsC = EnsureInt(strm); uint32_t fnPartsC = EnsureInt(strm);
std::cout << "\tName: "; std::cout << "\tName: ";
for(uint32_t k = 0; k < fnPartsC; k++) for (uint32_t k = 0; k < fnPartsC; k++) {
{ if (k > 0)
if(k > 0) std::cout << "."; std::cout << ".";
std::cout << strs.at(EnsureInt(strm)); std::cout << strs.at(EnsureInt(strm));
} }
std::cout << std::endl; std::cout << std::endl;
fnPartsC = EnsureInt(strm); fnPartsC = EnsureInt(strm);
std::cout << "\tInherits: "; std::cout << "\tInherits: ";
for(uint32_t k = 0; k < fnPartsC; k++) for (uint32_t k = 0; k < fnPartsC; k++) {
{ if (k > 0)
if(k > 0) std::cout << "."; std::cout << ".";
std::cout << strs.at(EnsureInt(strm)); std::cout << strs.at(EnsureInt(strm));
} }
std::cout << std::endl; std::cout << std::endl;
uint32_t ents = EnsureInt(strm); uint32_t ents = EnsureInt(strm);
for(uint8_t k = 0; k < ents; k++) for (uint32_t k = 0; k < ents; k++) {
{ Ensure(strm, main_header, 1);
Ensure(strm,main_header,1);
uint8_t flags = main_header[0]; uint8_t flags = main_header[0];
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl; std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/"
<< std::endl;
std::string fnname = strs.at(EnsureInt(strm)); std::string fnname = strs.at(EnsureInt(strm));
std::string fnargs; std::string fnargs;
uint32_t argParts = EnsureInt(strm); uint32_t argParts = EnsureInt(strm);
for(uint32_t l = 0; l < argParts; l++) for (uint32_t l = 0; l < argParts; l++) {
{ if (l > 0)
if(l > 0) fnargs += ", "; fnargs += ", ";
fnargs += strs.at(EnsureInt(strm)); fnargs += strs.at(EnsureInt(strm));
} }
uint32_t fnchunk = EnsureInt(strm); uint32_t fnchunk = EnsureInt(strm);
switch(flags & 3) switch (flags & 3) {
{
case 0: case 0:
std::cout << "\t\tprivate "; std::cout << "\t\tprivate ";
break; break;
@@ -137,17 +124,19 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
break; break;
} }
switch((flags >> 2) & 3) switch ((flags >> 2) & 3) {
{
case 0: case 0:
std::cout << "func " << fnname << "(" << fnargs << "), chunk = " << fnchunk << std::endl; std::cout << "func " << fnname << "(" << fnargs
<< "), chunk = " << fnchunk << std::endl;
break; break;
case 1: case 1:
std::cout << "field " << fnname << ", chunk = " << fnchunk << std::endl; std::cout << "field " << fnname
<< ", chunk = " << fnchunk << std::endl;
break; break;
case 2: case 2:
std::cout << "abstract " << fnname << "(" << fnargs << ")" << std::endl; std::cout << "abstract " << fnname << "(" << fnargs
<< ")" << std::endl;
break; break;
case 3: case 3:
std::cout << "unset_field " << fnname << std::endl; std::cout << "unset_field " << fnname << std::endl;
@@ -156,100 +145,83 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
std::cout << std::endl; std::cout << std::endl;
} }
} }
} } else if (tableName == "CHKS") {
else if(tableName == "CHKS")
{
size_t chunkCount = (size_t)EnsureInt(strm); size_t chunkCount = (size_t)EnsureInt(strm);
for(size_t j = 0; j < chunkCount; j++) for (size_t j = 0; j < chunkCount; j++) {
{
std::vector<std::string> args; std::vector<std::string> args;
size_t argCount = (size_t)EnsureInt(strm); size_t argCount = (size_t)EnsureInt(strm);
for(size_t k = 0; k < argCount; k++) for (size_t k = 0; k < argCount; k++) {
{
args.push_back(strs.at(EnsureInt(strm))); args.push_back(strs.at(EnsureInt(strm)));
} }
auto len = EnsureInt(strm); auto len = EnsureInt(strm);
strm->Seek(len,Tesses::Framework::Streams::SeekOrigin::Current); strm->Seek(len,
Tesses::Framework::Streams::SeekOrigin::Current);
closures.push_back(args); closures.push_back(args);
} }
} } else if (tableName == "FUNS") {
else if(tableName == "FUNS")
{
size_t funLength = (size_t)EnsureInt(strm); size_t funLength = (size_t)EnsureInt(strm);
for(size_t j = 0; j < funLength;j++) for (size_t j = 0; j < funLength; j++) {
{
std::vector<std::string> fnParts; std::vector<std::string> fnParts;
uint32_t fnPartsC = EnsureInt(strm); uint32_t fnPartsC = EnsureInt(strm);
for(uint32_t k = 0; k < fnPartsC; k++) for (uint32_t k = 0; k < fnPartsC; k++) {
{
fnParts.push_back(strs.at(EnsureInt(strm))); fnParts.push_back(strs.at(EnsureInt(strm)));
} }
uint32_t fnNumber = EnsureInt(strm); uint32_t fnNumber = EnsureInt(strm);
funs[fnNumber] = fnParts; funs[fnNumber] = fnParts;
}
} else if (tableName == "INFO") {
} std::cout << "Info: " << strs.at((size_t)EnsureInt(strm))
} << std::endl;
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);
else
{
strm->Seek((int64_t)tableLen,Tesses::Framework::Streams::SeekOrigin::Current);
} }
} }
if(hasIcon) if (hasIcon)
std::cout << "Has Icon: yes" << std::endl; std::cout << "Has Icon: yes" << std::endl;
else else
std::cout << "Has Icon: no" << std::endl; std::cout << "Has Icon: no" << std::endl;
for(size_t i = 1; i < closures.size(); i++) for (size_t i = 1; i < closures.size(); i++) {
{ if (funs.count((uint32_t)i) > 0) {
if(funs.count((uint32_t)i) > 0)
{
std::cout << "Func: "; std::cout << "Func: ";
auto res = funs[(uint32_t)i]; auto res = funs[(uint32_t)i];
if(!res.empty()) { if (!res.empty()) {
std::cout << "/^" << res[0] << "^/ "; std::cout << "/^" << res[0] << "^/ ";
} }
for(size_t i = 1; i < res.size(); i++) for (size_t i = 1; i < res.size(); i++) {
{ if (i > 1)
if(i > 1) std::cout << "."; std::cout << ".";
std::cout << res[i]; std::cout << res[i];
} }
} } else {
else
{
std::cout << "Closure: "; std::cout << "Closure: ";
} }
std::cout << "("; std::cout << "(";
bool first=true; bool first = true;
for(auto arg : closures[i]) for (auto arg : closures[i]) {
{ if (!first)
if(!first) std::cout << ", "; std::cout << ", ";
std::cout << arg; std::cout << arg;
if(first) first=false; if (first)
first = false;
} }
std::cout << ")" << std::endl; std::cout << ")" << std::endl;
} }
std::cout << std::endl; std::cout << std::endl;
std::cout << "String Table:" << std::endl; std::cout << "String Table:" << std::endl;
for(auto str : strs) { for (auto str : strs) {
std::cout << EscapeString(str, true) << std::endl; 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;
using namespace Tesses::Framework::Http; 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) static bool Download(Tesses::Framework::Filesystem::VFSPath filename,
{ std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs) {
auto inContainer=Platform::Environment::GetVariable("CROSSLANG_CONTAINER"); auto inContainer =
if(inContainer && (*inContainer=="1" || *inContainer=="y" || *inContainer=="Y")) Platform::Environment::GetVariable("CROSSLANG_CONTAINER");
{ if (inContainer &&
HttpRequest req; (*inContainer == "1" || *inContainer == "y" || *inContainer == "Y")) {
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, vfs);
return true;
}
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)? ";
std::string line;
std::getline(std::cin,line);
if(line == "Y" || line == "y")
{
HttpRequest req; HttpRequest req;
req.followRedirects = true; req.followRedirects = true;
req.url = "https://redirect.tesses.net/crosslang-shell"; req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET"; req.method = "GET";
HttpResponse resp(req); HttpResponse resp(req);
if(resp.statusCode == StatusCode::OK) if (resp.statusCode == StatusCode::OK) {
{
auto strm = resp.ReadAsStream(); auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, vfs); CrossLang::CrossArchiveExtract(strm, vfs);
return true; return true;
} } else {
else std::cout << "Error when fetching the script error: "
{ << std::to_string(resp.statusCode) << " "
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl; << HttpUtils::StatusCodeString(resp.statusCode)
<< std::endl;
return false; return false;
} }
} }
else if(line == "N" || line == "n")
{
std::cout << "Looks like you will need to install manually" << std::endl;
return false;
}
else
{
std::cout << "Please use Y or N (case insensitive)" << std::endl;
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") {
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, vfs);
return true;
} 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;
return false;
} else {
std::cout << "Please use Y or N (case insensitive)" << std::endl;
} }
} }
return false; 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 dir = GetCrossLangConfigDir();
Tesses::Framework::Filesystem::VFSPath filename = dir / "Shell" / "Shell.crvm"; Tesses::Framework::Filesystem::VFSPath filename =
dir / "Shell" / "Shell.crvm";
auto p =
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"; Tesses::Framework::Platform::Environment::GetRealExecutablePath(
if(argv.size() == 2 && argv[1] == "configdir") 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; std::cout << dir.ToString() << std::endl;
return 0; 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; HttpRequest req;
req.followRedirects=true; req.followRedirects = true;
req.url = "https://redirect.tesses.net/crosslang-shell"; req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET"; req.method = "GET";
HttpResponse resp(req); HttpResponse resp(req);
if(resp.statusCode == StatusCode::OK) if (resp.statusCode == StatusCode::OK) {
{
auto strm = resp.ReadAsStream(); auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, subdir); CrossLang::CrossArchiveExtract(strm, subdir);
return 0; return 0;
} } else {
else std::cout << "Error when fetching the script error: "
{ << std::to_string(resp.statusCode) << " "
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl; << HttpUtils::StatusCodeString(resp.statusCode)
<< std::endl;
return 1; return 1;
} }
return 0; return 0;
} }
if(!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename)) if (!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename)) {
{ auto subdir =
auto subdir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,dir); std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
if(Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p)) Tesses::Framework::Filesystem::LocalFS, dir);
{ if (Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p)) {
std::cout << "Installing " << p.ToString() << " -> " << dir.ToString() << std::endl; std::cout << "Installing " << p.ToString() << " -> "
auto strm = Tesses::Framework::Filesystem::LocalFS->OpenFile(p,"rb"); << dir.ToString() << std::endl;
if(strm != nullptr) auto strm =
{ Tesses::Framework::Filesystem::LocalFS->OpenFile(p, "rb");
if (strm != nullptr) {
CrossLang::CrossArchiveExtract(strm, subdir); CrossLang::CrossArchiveExtract(strm, subdir);
} } else {
else
{
return 1; return 1;
} }
} } else {
else if (!Download(filename, subdir))
{ return 1;
if(!Download(filename,subdir)) return 1;
return 0; 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); TList *args = TList::Create(ls);
env->LoadFileWithDependencies(ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
TList* args = TList::Create(ls);
args->Add(filename.ToString()); 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])); 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 "CrossLang.hpp"
#include <iostream>
#include <fstream> #include <fstream>
#include <iostream>
using namespace Tesses::Framework; using namespace Tesses::Framework;
using namespace Tesses::Framework::Filesystem; using namespace Tesses::Framework::Filesystem;
namespace Tesses::CrossLang::Programs { namespace Tesses::CrossLang::Programs {
static void Help(std::string filename) static void Help(std::string filename) {
{ std::cout << "USAGE: " << filename
std::cout << "USAGE: " << filename << " [OPTIONS] source_file1 source_file2 source_file_n" << std::endl; << " [OPTIONS] source_file1 source_file2 source_file_n"
<< std::endl;
printf("OPTIONS:\n"); printf("OPTIONS:\n");
printf(" -o: Output directory (OUTDIR, defaults to ./bin)\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 info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": "
printf(" -I: Set icon resource name (in the resource folder), should be a 128x128 png\n"); "\"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(" -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: Add dependency (DependencyName-1.0.0.0-prod)\n");
printf(" -D: enable debug)\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(" -n: Set name (MyAppOrLibName defaults to out)\n");
printf(" -r: Set resource directory (RESDIR defaults to res)\n"); printf(" -r: Set resource directory (RESDIR defaults to res)\n");
printf(" -h, --help: Prints help\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"); printf("Options except for help have flag with arg like this: -F ARG\n");
exit(1); 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::ifstream strm(argv[1],std::ios_base::in|std::ios_base::binary);
std::vector<LexToken> tokens; std::vector<LexToken> tokens;
Lex(argv[1],strm,tokens); Lex(argv[1],strm,tokens);
@@ -42,222 +48,183 @@ void CrossLangCompiler(std::vector<std::string>& argv)
std::filesystem::path resourceDir = std::filesystem::current_path() / "res"; std::filesystem::path resourceDir = std::filesystem::current_path() / "res";
std::vector<std::pair<std::string, TVMVersion>> dependencies; std::vector<std::pair<std::string, TVMVersion>> dependencies;
std::vector<std::pair<std::string, TVMVersion>> tools; std::vector<std::pair<std::string, TVMVersion>> tools;
std::string name="out"; std::string name = "out";
std::string info="{}"; std::string info = "{}";
std::string icon=""; std::string icon = "";
std::string comptime="none"; std::string comptime = "none";
TVMVersion version; TVMVersion version;
bool debug=false; 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]); Help(argv[0]);
} }
else if(argv[i] == "-o") else if (argv[i] == "-o") {
{
i++; i++;
if(i < argv.size()) if (i < argv.size()) {
{
outputDir = argv[i]; outputDir = argv[i];
} }
} } else if (argv[i] == "-r") {
else if(argv[i] == "-r")
{
i++; i++;
if(i < argv.size()) if (i < argv.size()) {
{
resourceDir = argv[i]; resourceDir = argv[i];
} }
} } else if (argv[i] == "-e") {
else if(argv[i] == "-e")
{
i++; i++;
if(i < argv.size()) if (i < argv.size()) {
{
comptime = argv[i]; comptime = argv[i];
} }
} }
else if(argv[i] == "-i") else if (argv[i] == "-i") {
{
i++; i++;
if(i < argv.size()) if (i < argv.size()) {
{
info = argv[i]; info = argv[i];
} }
} } else if (argv[i] == "-I") {
else if(argv[i] == "-I")
{
i++; i++;
if(i < argv.size()) if (i < argv.size()) {
{
icon = argv[i]; icon = argv[i];
} }
} } else if (argv[i] == "-d") {
else if(argv[i] == "-d")
{
i++; i++;
if(i < argv.size()) if (i < argv.size()) {
{
std::string str = argv[i]; std::string str = argv[i];
auto lastDash = str.find_last_of('-'); auto lastDash = str.find_last_of('-');
if(lastDash < str.size()) if (lastDash < str.size()) {
{ std::string str2 = str.substr(lastDash + 1);
std::string str2 = str.substr(lastDash+1); if (str2 == "dev" || str2 == "alpha" || str2 == "beta" ||
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod") str2 == "prod") {
{ lastDash = str.find_last_of('-', lastDash - 1);
lastDash = str.find_last_of('-',lastDash-1);
} }
std::string str1 = str.substr(0,lastDash); std::string str1 = str.substr(0, lastDash);
str2 = str.substr(lastDash+1); str2 = str.substr(lastDash + 1);
TVMVersion v2; TVMVersion v2;
if(!TVMVersion::TryParse(str2,v2)) if (!TVMVersion::TryParse(str2, v2)) {
{
printf("ERROR: Invalid syntax for version\n"); 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); exit(1);
} }
dependencies.push_back(std::pair<std::string,TVMVersion>(str1,v2)); dependencies.push_back(
std::pair<std::string, TVMVersion>(str1, v2));
} } else {
else
{
printf("ERROR: Dependency must have version\n"); printf("ERROR: Dependency must have version\n");
exit(1); exit(1);
} }
} }
} } else if (argv[i] == "-t") {
else if(argv[i] == "-t")
{
i++; i++;
if(i < argv.size()) if (i < argv.size()) {
{
std::string str = argv[i]; std::string str = argv[i];
auto lastDash = str.find_last_of('-'); auto lastDash = str.find_last_of('-');
if(lastDash < str.size()) if (lastDash < str.size()) {
{ std::string str2 = str.substr(lastDash + 1);
std::string str2 = str.substr(lastDash+1); if (str2 == "dev" || str2 == "alpha" || str2 == "beta" ||
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod") str2 == "prod") {
{ lastDash = str.find_last_of('-', lastDash - 1);
lastDash = str.find_last_of('-',lastDash-1);
} }
std::string str1 = str.substr(0,lastDash); std::string str1 = str.substr(0, lastDash);
str2 = str.substr(lastDash+1); str2 = str.substr(lastDash + 1);
TVMVersion v2; TVMVersion v2;
if(!TVMVersion::TryParse(str2,v2)) if (!TVMVersion::TryParse(str2, v2)) {
{
printf("ERROR: Invalid syntax for version\n"); 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); exit(1);
} }
tools.push_back(std::pair<std::string,TVMVersion>(str1,v2)); tools.push_back(
std::pair<std::string, TVMVersion>(str1, v2));
} } else {
else
{
printf("ERROR: Tool must have version\n"); printf("ERROR: Tool must have version\n");
exit(1); exit(1);
} }
} }
} } else if (argv[i] == "-n") {
else if(argv[i] == "-n")
{
i++; i++;
if(i < argv.size()) if (i < argv.size()) {
{
name = argv[i]; name = argv[i];
} }
} } else if (argv[i] == "-v") {
else if(argv[i] == "-v")
{
i++; i++;
if(i < argv.size()) if (i < argv.size()) {
{
if(!TVMVersion::TryParse(argv[i],version)) if (!TVMVersion::TryParse(argv[i], version)) {
{
printf("ERROR: Invalid syntax for version\n"); 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); exit(1);
} }
} }
} } else if (argv[i] == "-D" || argv[i] == "--debug") {
else if(argv[i] == "-D" || argv[i] == "--debug")
{
debug = true; debug = true;
} } else {
else {
source.push_back(argv[i]); source.push_back(argv[i]);
} }
} }
if(source.empty()) if (source.empty()) {
{
Help(argv[0]); Help(argv[0]);
} }
std::vector<LexToken> tokens; std::vector<LexToken> tokens;
for(auto src : source) for (auto src : source) {
{ std::ifstream strm(src, std::ios_base::in | std::ios_base::binary);
std::ifstream strm(src,std::ios_base::in|std::ios_base::binary); int res = Lex(std::filesystem::absolute(src).string(), strm, tokens);
int res = Lex(std::filesystem::absolute(src).string(),strm,tokens);
} }
std::shared_ptr<GC> gc; std::shared_ptr<GC> gc;
std::shared_ptr<GCList> ls; std::shared_ptr<GCList> ls;
TRootEnvironment* env=nullptr; TRootEnvironment *env = nullptr;
if(comptime != "none") if (comptime != "none") {
{ std::shared_ptr<GC> gc = std::make_shared<GC>();
std::shared_ptr<GC> gc= std::make_shared<GC>();
gc->Start(); gc->Start();
ls = std::make_shared<GCList>(gc); ls = std::make_shared<GCList>(gc);
env = TRootEnvironment::Create(*ls,TDictionary::Create(*ls)); env = TRootEnvironment::Create(*ls, TDictionary::Create(*ls));
if(comptime == "secure") if (comptime == "secure") {
{ TStd::RegisterConsole(gc, env);
TStd::RegisterConsole(gc,env); TStd::RegisterClass(gc, env);
TStd::RegisterClass(gc,env); TStd::RegisterCrypto(gc, env);
TStd::RegisterCrypto(gc,env); TStd::RegisterDictionary(gc, env);
TStd::RegisterDictionary(gc,env); TStd::RegisterJson(gc, env);
TStd::RegisterJson(gc,env); TStd::RegisterRoot(gc, env);
TStd::RegisterRoot(gc,env); TStd::RegisterIO(gc, env, false);
TStd::RegisterIO(gc,env,false); env->permissions.locked = true;
env->permissions.locked=true; } else if (comptime == "secure_file") {
} TStd::RegisterConsole(gc, env);
else if(comptime == "secure_file") TStd::RegisterClass(gc, env);
{ TStd::RegisterCrypto(gc, env);
TStd::RegisterConsole(gc,env); TStd::RegisterDictionary(gc, env);
TStd::RegisterClass(gc,env); TStd::RegisterJson(gc, env);
TStd::RegisterCrypto(gc,env); TStd::RegisterRoot(gc, env);
TStd::RegisterDictionary(gc,env); TStd::RegisterIO(gc, env, false);
TStd::RegisterJson(gc,env); env->permissions.locked = true;
TStd::RegisterRoot(gc,env); auto fs = env->EnsureDictionary(gc, "FS");
TStd::RegisterIO(gc,env,false); fs->SetValue("Local",
env->permissions.locked=true; std::make_shared<SubdirFilesystem>(
auto fs = env->EnsureDictionary(gc,"FS"); LocalFS, Tesses::Framework::Filesystem::VFSPath::
fs->SetValue("Local", std::make_shared<SubdirFilesystem>(LocalFS,Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory())); GetAbsoluteCurrentDirectory()));
} } else if (comptime == "full") {
else if(comptime == "full") TStd::RegisterStd(gc, env);
{ env->permissions.locked = true;
TStd::RegisterStd(gc,env);
env->permissions.locked=true;
} }
} }
Parser parser(tokens,gc,env); Parser parser(tokens, gc, env);
parser.debug = debug; parser.debug = debug;
CodeGen gen; 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.embedFS = sfs;
gen.GenRoot(parser.ParseRoot()); gen.GenRoot(parser.ParseRoot());
@@ -265,21 +232,20 @@ void CrossLangCompiler(std::vector<std::string>& argv)
gen.version = version; gen.version = version;
gen.info = info; gen.info = info;
gen.icon = icon; gen.icon = icon;
for(auto deps : dependencies) for (auto deps : dependencies) {
{
gen.dependencies.push_back(deps); gen.dependencies.push_back(deps);
} }
for(auto tool : tools) for (auto tool : tools) {
{
gen.tools.push_back(tool); gen.tools.push_back(tool);
} }
std::filesystem::create_directory(outputDir); 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); gen.Save(strm);
} }
} }
} } // namespace Tesses::CrossLang::Programs

View File

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

View File

@@ -1,61 +1,58 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
using namespace Tesses::Framework; using namespace Tesses::Framework;
namespace Tesses::CrossLang::Programs { namespace Tesses::CrossLang::Programs {
TObject CrossLangVM(GCList& ls,TRootEnvironment* env, std::vector<std::string>& argv) TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
{ std::vector<std::string> &argv) {
if(argv.size() < 2) if (argv.size() < 2) {
{ std::cout << "USAGE: "
std::cout << "USAGE: " << (argv.empty() ? (std::string)"crossvm" : argv[0]) << " <filename.crvm> <args...>" << std::endl; << (argv.empty() ? (std::string) "crossvm" : argv[0])
<< " <filename.crvm> <args...>" << std::endl;
return 1; return 1;
} }
env->LoadFileWithDependencies(ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1])); env->LoadFileWithDependencies(
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS,
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1]));
if(env->HasVariable("WebAppMain")) if (env->HasVariable("WebAppMain")) {
{
Args args(argv); Args args(argv);
int port = 4206; int port = 4206;
for(auto& item : args.options) for (auto &item : args.options) {
{ if (item.first == "port") {
if(item.first == "port")
{
port = std::stoi(item.second); port = std::stoi(item.second);
} }
} }
env->EnsureDictionary(ls.GetGC(),"Net")->SetValue("WebServerPort", (int64_t)port); env->EnsureDictionary(ls.GetGC(), "Net")
TList* args2 = TList::Create(ls); ->SetValue("WebServerPort", (int64_t)port);
for(auto& item : args.positional) TList *args2 = TList::Create(ls);
{ for (auto &item : args.positional) {
args2->Add(item); args2->Add(item);
} }
auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2}); auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2});
auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(),res); auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(), res);
if(svr2 == nullptr) return 1; if (svr2 == nullptr)
Tesses::Framework::Http::HttpServer svr(port,svr2); return 1;
Tesses::Framework::Http::HttpServer svr(port, svr2);
svr.StartAccepting(); svr.StartAccepting();
TF_RunEventLoop(); TF_RunEventLoop();
TDictionary* _dict; TDictionary *_dict;
TClassObject* _co; TClassObject *_co;
if(GetObjectHeap(res,_dict)) if (GetObjectHeap(res, _dict)) {
{ _dict->CallMethod(ls, "Close", {});
_dict->CallMethod(ls,"Close",{});
} }
if(GetObjectHeap(res,_co)) if (GetObjectHeap(res, _co)) {
{ _co->CallMethod(ls, "", "Close", {});
_co->CallMethod(ls,"","Close",{});
} }
TF_Quit(); TF_Quit();
return 0; return 0;
} } else {
else { TList *args = TList::Create(ls);
TList* args = TList::Create(ls); for (size_t arg = 1; arg < argv.size(); arg++)
for(size_t arg=1;arg<argv.size();arg++)
args->Add(std::string(argv[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,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,172 +4,188 @@ using namespace Tesses::Framework;
using namespace Tesses::CrossLang; using namespace Tesses::CrossLang;
using namespace Tesses::Framework::Filesystem; using namespace Tesses::Framework::Filesystem;
int main(int argc, char** argv) int main(int argc, char **argv) {
{
//crosslang crossint
//crosslang
//crosslang ...
std::string programName = "crosslang";
TF_InitWithConsole(); TF_InitWithConsole();
if(argc > 0) TF_AllowPortable();
{
TF_AllowPortable(argv[0]);
Tesses::Framework::Filesystem::VFSPath path=(std::string)argv[0];
path.RemoveExtension();
programName = path.GetFileName();
}
std::vector<std::string> args(argc); std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
for (int i = 0; i < argc; i++)
args[i] = argv[i]; args[i] = argv[i];
if(programName == "crossint")
{
int64_t myi64=0; auto execName = TF_GetExecutableName();
std::shared_ptr<GC> gc= std::make_shared<GC>(); 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(); gc->Start();
GCList ls(gc); GCList ls(gc);
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); TRootEnvironment *env =
TStd::RegisterStd(gc,env); TRootEnvironment::Create(ls, TDictionary::Create(ls));
auto res= Programs::CrossLangInterperter(ls, env, args); TStd::RegisterStd(gc, env);
auto res = Programs::CrossLangVM(ls, env, args);
GetObject(res,myi64); GetObject(res, myi64);
return (int)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;
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");
GCList ls(gc); Console::WriteLine("");
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); Console::WriteLine("NOTE: As you don't have the shell, these "
TStd::RegisterStd(gc,env); "commands are limited");
auto res= Programs::CrossLangVM(ls, env, args); Console::WriteLine(
GetObject(res,myi64); "NOTE: You can put this binary in a folder with a crvm "
"file, as long as filename matches (ignoring extension) it "
return (int)myi64; "will directly launch the crvm file");
return 1;
} }
else if(args.size() > 1) }
{ if (args[1] == "int") {
int64_t myi64 = 0;
if(args[1] == "crossint")
{
int64_t myi64=0;
args.erase(args.begin()); args.erase(args.begin());
std::shared_ptr<GC> gc= std::make_shared<GC>(); std::shared_ptr<GC> gc = std::make_shared<GC>();
gc->Start(); gc->Start();
GCList ls(gc); GCList ls(gc);
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); TRootEnvironment *env =
TStd::RegisterStd(gc,env); TRootEnvironment::Create(ls, TDictionary::Create(ls));
auto res= Programs::CrossLangInterperter(ls, env, args); TStd::RegisterStd(gc, env);
auto res = Programs::CrossLangInterperter(ls, env, args);
GetObject(res,myi64); GetObject(res, myi64);
return (int)myi64; return (int)myi64;
} } else if (args[1] == "c") {
else if(args[1] == "crossc")
{
args.erase(args.begin()); args.erase(args.begin());
Programs::CrossLangCompiler(args); Programs::CrossLangCompiler(args);
return 0; return 0;
} } else if (args[1] == "archivecreate") {
else if(args[1] == "crossarchivecreate")
{
args.erase(args.begin()); args.erase(args.begin());
Programs::CrossArchiveCreate(args); Programs::CrossArchiveCreate(args);
return 0; return 0;
} } else if (args[1] == "archiveextract") {
else if(args[1] == "crossarchiveextract")
{
args.erase(args.begin()); args.erase(args.begin());
Programs::CrossArchiveExtract(args); Programs::CrossArchiveExtract(args);
return 0; return 0;
} 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;
} }
else if(args[1] == "crossdump")
{ std::string crvm = argv[2];
for(size_t i = 2; i < args.size(); i++) std::string png = argv[3];
{
VFSPath path = args[i]; if (Tesses::Framework::Filesystem::LocalFS->FileExists(crvm)) {
if(LocalFS->FileExists(path))
{ Tesses::CrossLang::TFile file;
std::cout << "File: " << path.ToString() << std::endl; auto f = Tesses::Framework::Filesystem::LocalFS->OpenFile(crvm,
auto strm = LocalFS->OpenFile(path, "rb"); "rb");
Programs::CrossLangDump(strm);
} file.Load(nullptr, f);
else {
std::cout << "File: " << path.ToString() << " does not exist." << std::endl; 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; return 0;
} }
else if(args[1] == "crossvm") }
{ if (Tesses::Framework::Filesystem::LocalFS->FileExists(
int64_t myi64=0; 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] == "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()); args.erase(args.begin());
std::shared_ptr<GC> gc= std::make_shared<GC>(); std::shared_ptr<GC> gc = std::make_shared<GC>();
gc->Start(); gc->Start();
GCList ls(gc); GCList ls(gc);
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); TRootEnvironment *env =
TStd::RegisterStd(gc,env); TRootEnvironment::Create(ls, TDictionary::Create(ls));
auto res= Programs::CrossLangVM(ls, env, args); TStd::RegisterStd(gc, env);
GetObject(res,myi64); auto res = Programs::CrossLangVM(ls, env, args);
GetObject(res, myi64);
return (int)myi64; return (int)myi64;
} }
} }
{ {
int64_t myi64=0; int64_t myi64 = 0;
std::shared_ptr<GC> gc= std::make_shared<GC>(); std::shared_ptr<GC> gc = std::make_shared<GC>();
gc->Start(); gc->Start();
GCList ls(gc); GCList ls(gc);
auto res= Programs::CrossLangShell(ls, args); auto res = Programs::CrossLangShell(ls, args);
GetObject(res,myi64);
GetObject(res, myi64);
return (int)myi64; return (int)myi64;
} }

View File

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

View File

@@ -2,334 +2,247 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
#include <iostream> #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 { namespace Tesses::CrossLang {
#ifdef CROSSLANG_ENABLE_TERMIOS TObject Console_setInvertedColors(GCList &ls, std::vector<TObject> args) {
struct termios orig_termios; bool inverted;
static void disableRawMode() if (GetArgument(args, 0, inverted)) {
{ Tesses::Framework::Console::SetInvertedColors(inverted);
tcsetattr(0, TCSAFLUSH, &orig_termios);
} }
#endif return Undefined();
TObject Console_getEcho(GCList& ls, std::vector<TObject> args) }
{ TObject Console_Reset(GCList &ls, std::vector<TObject> args) {
#ifdef CROSSLANG_ENABLE_TERMIOS Tesses::Framework::Console::Reset();
struct termios raw; return Undefined();
tcgetattr(0, &raw); }
return (raw.c_lflag & ECHO) > 0; TObject Console_getIsTTY(GCList &ls, std::vector<TObject> args) {
#endif return Tesses::Framework::Console::IsTTY();
return false; }
} TObject Console_getEcho(GCList &ls, std::vector<TObject> args) {
TObject Console_setEcho(GCList& ls, std::vector<TObject> args)
{ return Tesses::Framework::Console::GetEcho();
if(args.size() == 1 && std::holds_alternative<bool>(args[0])) }
{ 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]); bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS Tesses::Framework::Console::SetEcho(cooked);
struct termios raw;
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ECHO;
}
else
{
raw.c_lflag &= ~(ECHO);
}
tcsetattr(0, TCSAFLUSH, &raw);
#endif
return cooked; return cooked;
} }
return Undefined(); return Undefined();
} }
TObject Console_getCanonical(GCList& ls, std::vector<TObject> args) TObject Console_getCanonical(GCList &ls, std::vector<TObject> args) {
{ return Tesses::Framework::Console::GetCanonical();
#ifdef CROSSLANG_ENABLE_TERMIOS }
struct termios raw; TObject Console_setCanonical(GCList &ls, std::vector<TObject> args) {
tcgetattr(0, &raw); if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
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]); bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS Tesses::Framework::Console::SetCanonical(cooked);
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 cooked;
} }
return Undefined(); return Undefined();
} }
TObject Console_getSignals(GCList& ls, std::vector<TObject> args) TObject Console_getSignals(GCList &ls, std::vector<TObject> args) {
{ return Tesses::Framework::Console::GetSignals();
#ifdef CROSSLANG_ENABLE_TERMIOS }
struct termios raw; TObject Console_setSignals(GCList &ls, std::vector<TObject> args) {
tcgetattr(0, &raw); if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
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]); bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS Tesses::Framework::Console::SetSignals(cooked);
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 cooked;
} }
return Undefined(); return Undefined();
} }
TObject Console_Read(GCList& ls, std::vector<TObject> args) TObject Console_Read(GCList &ls, std::vector<TObject> args) {
{ return (int64_t)Tesses::Framework::Console::Read();
uint8_t byte; }
std::cin.read((char*)&byte,1); TObject Console_ReadLine(GCList &ls, std::vector<TObject> args) {
return std::cin.eof() ? (int64_t)-1 : (int64_t)byte; return Tesses::Framework::Console::ReadLine();
} }
TObject Console_ReadLine(GCList& ls, std::vector<TObject> args) TObject Console_ReadPassword(GCList &ls, std::vector<TObject> args) {
{ return Tesses::Framework::Console::ReadPassword();
std::string str; }
std::getline(std::cin,str); TObject Console_Write(GCList &ls, std::vector<TObject> args) {
return str; if (args.size() < 1) {
}
TObject Console_Write(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
return Undefined(); return Undefined();
} }
std::cout << ToString(ls.GetGC(),args[0]); Tesses::Framework::Console::Write(ToString(ls.GetGC(), args[0]));
return Undefined(); return Undefined();
} }
TObject Console_Fatal(GCList& ls, std::vector<TObject> args) TObject Console_Fatal(GCList &ls, std::vector<TObject> args) {
{ if (args.size() < 1) {
if(args.size() < 1) Tesses::Framework::Console::ErrorLine("FATAL: <NO MESSAGE>");
{
std::cout << "FATAL: <NO MESSAGE>" << std::endl;
exit(1); exit(1);
} }
std::cout << "FATAL: " << ToString(ls.GetGC(),args[0]) << std::endl; Tesses::Framework::Console::ErrorLine("FATAL: " +
ToString(ls.GetGC(), args[0]));
exit(1); exit(1);
} }
TObject Console_WriteLine(GCList& ls, std::vector<TObject> args) TObject Console_WriteLine(GCList &ls, std::vector<TObject> args) {
{ if (args.size() < 1) {
if(args.size() < 1) Tesses::Framework::Console::WriteLineView("");
{
std::cout << "\n";
return Undefined(); return Undefined();
} }
std::cout << ToString(ls.GetGC(),args[0]) << "\n"; 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(); return Undefined();
} }
TObject Console_Error(GCList& ls, std::vector<TObject> args) Tesses::Framework::Console::Error(ToString(ls.GetGC(), args[0]));
{ return Undefined();
if(args.size() < 1) }
{ TObject Console_ErrorLine(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
Tesses::Framework::Console::ErrorLine("");
return Undefined(); return Undefined();
} }
std::cerr << ToString(ls.GetGC(),args[0]); Tesses::Framework::Console::ErrorLine(ToString(ls.GetGC(), args[0]));
return Undefined(); return Undefined();
} }
TObject Console_ErrorLine(GCList& ls, std::vector<TObject> args) TObject Console_getIn(GCList &ls, std::vector<TObject> args) {
{ return std::make_shared<Tesses::Framework::Streams::FileStream>(
if(args.size() < 1) stdin, false, "r", false);
{ }
std::cout << "\n";
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(); 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);
} }
std::cerr << ToString(ls.GetGC(),args[0]) << "\n";
return Undefined(); return Undefined();
} }
TObject Console_getIn(GCList& ls, std::vector<TObject> args) TObject Console_getSize(GCList &ls, std::vector<TObject> args) {
{ auto sz = Tesses::Framework::Console::GetSize();
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdin,false,"r",false); TDictionary *dict =
} TDictionary::Create(ls, {TDItem("Width", (int64_t)sz.first),
TDItem("Height", (int64_t)sz.second)});
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; 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));
} }
void TStd::RegisterConsole(std::shared_ptr<GC> gc,TRootEnvironment* env)
{ return (int64_t)Tesses::Framework::Console::List(items);
env->permissions.canRegisterConsole=true; }
if(env->permissions.customConsole != nullptr) return 0;
{ }
void TStd::RegisterConsole(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterConsole = true;
if (env->permissions.customConsole != nullptr) {
gc->BarrierBegin(); gc->BarrierBegin();
env->DeclareVariable("Console", env->permissions.customConsole ); env->DeclareVariable("Console", env->permissions.customConsole);
gc->BarrierEnd(); gc->BarrierEnd();
return; return;
} }
#ifdef CROSSLANG_ENABLE_TERMIOS
tcgetattr(0, &orig_termios);
atexit(disableRawMode);
#endif
GCList ls(gc); GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls); TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(
dict->DeclareFunction(gc,"getEcho","Get whether terminal is echoing characters read",{},Console_getEcho); gc, "getIsTTY",
dict->DeclareFunction(gc,"setEcho","Set whether terminal is echoing characters read",{"flag"},Console_setEcho); "Get whether terminal is a terminal or just piped to file", {},
dict->DeclareFunction(gc,"getCanonical","Get whether terminal is buffering line by line (true) or byte by byte (false)",{},Console_getCanonical); Console_getIsTTY);
dict->DeclareFunction(gc,"setCanonical","Set whether terminal is buffering line by line (true) or byte by byte (false)",{"flag"},Console_setCanonical); dict->DeclareFunction(gc, "getEcho",
dict->DeclareFunction(gc,"getSignals","Get whether terminal is sending signals for CTRL+C (true) or via read (false)",{},Console_getSignals); "Get whether terminal is echoing characters read", {},
dict->DeclareFunction(gc,"setSignals","Set whether terminal is sending signals for CTRL+C (true) or via read (false)",{"flag"},Console_setSignals); Console_getEcho);
dict->DeclareFunction(gc,"Clear", "Clear the console",{},Console_Clear); dict->DeclareFunction(gc, "setEcho",
dict->DeclareFunction(gc,"Read", "Reads a byte from stdin",{},Console_Read); "Set whether terminal is echoing characters read",
dict->DeclareFunction(gc,"ReadLine","Reads line from stdin",{},Console_ReadLine); {"flag"}, Console_setEcho);
dict->DeclareFunction(gc,"Write","Write text \"text\" to stdout",{"text"},Console_Write); dict->DeclareFunction(gc, "getCanonical",
dict->DeclareFunction(gc,"WriteLine","Write text \"text\" to stdout with new line",{"$text"},Console_WriteLine); "Get whether terminal is buffering line by line "
dict->DeclareFunction(gc,"Error", "Write text \"error\" to stderr",{"error"},Console_Error); "(true) or byte by byte (false)",
dict->DeclareFunction(gc,"ErrorLine","Write text \"error\" to stderr",{"$error"},Console_ErrorLine); {}, Console_getCanonical);
dict->DeclareFunction(gc,"ProgressBar","Draw progressbar", {}, Console_ProgressBar); dict->DeclareFunction(gc, "setCanonical",
if(env->permissions.canRegisterEverything) "Set whether terminal is buffering line by line "
dict->DeclareFunction(gc,"Fatal","Stop the program with an optional error message",{"$text"},Console_Fatal); "(true) or byte by byte (false)",
dict->DeclareFunction(gc,"getIn","Get stdin Stream",{},Console_getIn); {"flag"}, Console_setCanonical);
dict->DeclareFunction(gc,"getOut","Get stdout Stream",{},Console_getOut); dict->DeclareFunction(gc, "getSignals",
dict->DeclareFunction(gc,"getError", "Get stderr Stream",{},Console_getError); "Get whether terminal is sending signals for CTRL+C "
dict->DeclareFunction(gc, "getSize", "Get console size",{},Console_getSize); "(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(); gc->BarrierBegin();
env->DeclareVariable("Console", dict); env->DeclareVariable("Console", dict);
auto _new = env->EnsureDictionary(gc,"New"); auto _new = env->EnsureDictionary(gc, "New");
_new->DeclareFunction(gc,"ConsoleReader","Read from console",{},[](GCList& ls,std::vector<TObject> args)->TObject { _new->DeclareFunction(
return std::make_shared<Tesses::Framework::TextStreams::ConsoleReader>(); 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 { _new->DeclareFunction(
gc, "ConsoleWriter", "Write to console", {"$isStderr"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
bool err; bool err;
if(GetArgument(args,0,err)) return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>(err); if (GetArgument(args, 0, err))
return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>(); return std::make_shared<
Tesses::Framework::TextStreams::ConsoleWriter>(err);
return std::make_shared<
Tesses::Framework::TextStreams::ConsoleWriter>();
}); });
gc->BarrierEnd(); gc->BarrierEnd();
}
} }
} // namespace Tesses::CrossLang
#endif #endif

View File

@@ -2,43 +2,36 @@
using namespace Tesses::Framework::Crypto; using namespace Tesses::Framework::Crypto;
namespace Tesses::CrossLang namespace Tesses::CrossLang {
{ static TObject Crypto_RandomBytes(GCList &ls, std::vector<TObject> args) {
static TObject Crypto_RandomBytes(GCList& ls, std::vector<TObject> args)
{
int64_t size; int64_t size;
std::string personalStr; std::string personalStr;
if(GetArgument(args,0,size) && GetArgument(args,1,personalStr)) if (GetArgument(args, 0, size) && GetArgument(args, 1, personalStr)) {
{
std::vector<uint8_t> bytes; std::vector<uint8_t> bytes;
bytes.resize((size_t)size); bytes.resize((size_t)size);
if(RandomBytes(bytes,personalStr)) if (RandomBytes(bytes, personalStr)) {
{
auto ba = TByteArray::Create(ls); auto ba = TByteArray::Create(ls);
ba->data = bytes; ba->data = bytes;
return ba; return ba;
} }
return nullptr; return nullptr;
} }
return nullptr; return nullptr;
} }
static TObject Crypto_PBKDF2(GCList& ls, std::vector<TObject> args) static TObject Crypto_PBKDF2(GCList &ls, std::vector<TObject> args) {
{
std::string pass; std::string pass;
TByteArray* bArraySalt; TByteArray *bArraySalt;
int64_t itterations; int64_t itterations;
int64_t keylength; int64_t keylength;
int64_t shanum; int64_t shanum;
if(GetArgument(args,0,pass) && GetArgumentHeap(args,1, bArraySalt) && GetArgument(args,2, itterations) && GetArgument(args,3,keylength) && GetArgument(args,4,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; ShaVersion version = VERSION_SHA384;
switch(shanum) switch (shanum) {
{
case 1: case 1:
version = VERSION_SHA1; version = VERSION_SHA1;
break; break;
@@ -57,118 +50,117 @@ namespace Tesses::CrossLang
break; break;
} }
std::vector<uint8_t> key; std::vector<uint8_t> key;
key.resize((size_t)keylength); key.resize((size_t)keylength);
if(PBKDF2(key,pass,bArraySalt->data,(long)itterations,version)) if (PBKDF2(key, pass, bArraySalt->data, (long)itterations, version)) {
{ TByteArray *ba = TByteArray::Create(ls);
TByteArray* ba = TByteArray::Create(ls);
ba->data = key; ba->data = key;
return ba; 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) if (GetArgumentHeap(args, 0, byteArray)) {
{
TByteArray* byteArray;
if(GetArgumentHeap(args,0,byteArray))
{
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data); return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
} }
return ""; return "";
} }
static TObject Crypto_Base64Decode(GCList& ls, std::vector<TObject> args) static TObject Crypto_Base64Decode(GCList &ls, std::vector<TObject> args) {
{
std::string str; std::string str;
if(GetArgument(args,0,str)) if (GetArgument(args, 0, str)) {
{ TByteArray *bArray = TByteArray::Create(ls);
TByteArray* bArray = TByteArray::Create(ls);
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str); bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
return bArray; return bArray;
} }
return nullptr; return nullptr;
} }
void TStd::RegisterCrypto(std::shared_ptr<GC> gc,TRootEnvironment* env) void TStd::RegisterCrypto(std::shared_ptr<GC> gc, TRootEnvironment *env) {
{
env->permissions.canRegisterCrypto=true; env->permissions.canRegisterCrypto = true;
if(!HaveCrypto()) return; if (!HaveCrypto())
return;
GCList ls(gc); GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls); TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "PBKDF2","Hash passwords with PBKDF2",{"pass","salt","itterations","keylen","shanum"},Crypto_PBKDF2); dict->DeclareFunction(gc, "PBKDF2", "Hash passwords with 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); {"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, "Base64Encode", "Base64 encode", {"data"},
dict->DeclareFunction(gc, "Base64Decode","Base64 decode",{"str"},Crypto_Base64Decode); Crypto_Base64Encode);
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 { dict->DeclareFunction(gc, "Base64Decode", "Base64 decode", {"str"},
TByteArray* baSrc; 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; std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
if(GetArgument(args, 0, sho)) if (GetArgument(args, 0, sho)) {
{
auto bytes = Sha1::ComputeHash(sho); auto bytes = Sha1::ComputeHash(sho);
auto ba = TByteArray::Create(ls); auto ba = TByteArray::Create(ls);
ba->data = bytes; ba->data = bytes;
return ba; return ba;
} }
if(GetArgumentHeap(args,0,baSrc)) if (GetArgumentHeap(args, 0, baSrc)) {
{ auto bytes =
auto bytes = Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size()); Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
auto ba = TByteArray::Create(ls); auto ba = TByteArray::Create(ls);
ba->data = bytes; ba->data = bytes;
return ba; return ba;
} }
return Undefined(); return Undefined();
}); });
dict->DeclareFunction(gc, "Sha256", "Hash with sha256 algorithm",{"strm","$is224"}, [](GCList& ls, std::vector<TObject> args)->TObject { dict->DeclareFunction(
TByteArray* baSrc; 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; std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
bool is224=false; bool is224 = false;
GetArgument(args,1,is224); GetArgument(args, 1, is224);
if(GetArgument(args, 0, sho)) if (GetArgument(args, 0, sho)) {
{ auto bytes = Sha256::ComputeHash(sho, is224);
auto bytes = Sha256::ComputeHash(sho,is224);
auto ba = TByteArray::Create(ls); auto ba = TByteArray::Create(ls);
ba->data = bytes; ba->data = bytes;
return ba; return ba;
} }
if(GetArgumentHeap(args,0,baSrc)) if (GetArgumentHeap(args, 0, baSrc)) {
{ auto bytes = Sha256::ComputeHash(baSrc->data.data(),
auto bytes = Sha256::ComputeHash(baSrc->data.data(), baSrc->data.size(), is224); baSrc->data.size(), is224);
auto ba = TByteArray::Create(ls); auto ba = TByteArray::Create(ls);
ba->data = bytes; ba->data = bytes;
return ba; return ba;
} }
return Undefined(); return Undefined();
}); });
dict->DeclareFunction(gc, "Sha512", "Hash with sha512 algorithm",{"strm","$is384"}, [](GCList& ls, std::vector<TObject> args)->TObject { dict->DeclareFunction(
TByteArray* baSrc; 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; std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
bool is384=false; bool is384 = false;
GetArgument(args,1,is384); GetArgument(args, 1, is384);
if(GetArgument(args, 0, sho)) if (GetArgument(args, 0, sho)) {
{ auto bytes = Sha512::ComputeHash(sho, is384);
auto bytes = Sha512::ComputeHash(sho,is384);
auto ba = TByteArray::Create(ls); auto ba = TByteArray::Create(ls);
ba->data = bytes; ba->data = bytes;
return ba; return ba;
} }
if(GetArgumentHeap(args,0,baSrc)) if (GetArgumentHeap(args, 0, baSrc)) {
{ auto bytes = Sha512::ComputeHash(baSrc->data.data(),
auto bytes = Sha512::ComputeHash(baSrc->data.data(), baSrc->data.size(), is384); baSrc->data.size(), is384);
auto ba = TByteArray::Create(ls); auto ba = TByteArray::Create(ls);
ba->data = bytes; ba->data = bytes;
return ba; return ba;
@@ -178,7 +170,5 @@ namespace Tesses::CrossLang
gc->BarrierBegin(); gc->BarrierBegin();
env->DeclareVariable("Crypto", dict); env->DeclareVariable("Crypto", dict);
gc->BarrierEnd(); gc->BarrierEnd();
}
} }
} // namespace Tesses::CrossLang

View File

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

View File

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

View File

@@ -1,29 +1,28 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
static TObject Helpers_CopyToProgress(GCList& ls, std::vector<TObject> args) 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> src;
std::shared_ptr<Tesses::Framework::Streams::Stream> dest; std::shared_ptr<Tesses::Framework::Streams::Stream> dest;
double precision=1000.0; double precision = 1000.0;
TCallable* callable; TCallable *callable;
if(GetArgument(args,0,src) && GetArgument(args,1,dest) && GetArgumentHeap(args,2,callable)) if (GetArgument(args, 0, src) && GetArgument(args, 1, dest) &&
{ GetArgumentHeap(args, 2, callable)) {
GetArgument(args,3,precision); GetArgument(args, 3, precision);
auto len = src->GetLength(); auto len = src->GetLength();
callable->Call(ls,{0.0}); callable->Call(ls, {0.0});
if(len > 0) if (len > 0) {
{
std::vector<uint8_t> buff(1024); std::vector<uint8_t> buff(1024);
int64_t pos=0; int64_t pos = 0;
int curPercent=0; int curPercent = 0;
int lastPercent=0; int lastPercent = 0;
size_t read = 0; size_t read = 0;
do { do {
read = src->ReadBlock(buff.data(),buff.size()); read = src->ReadBlock(buff.data(), buff.size());
dest->WriteBlock(buff.data(),read); dest->WriteBlock(buff.data(), read);
if(read == 0) break; if (read == 0)
break;
pos += (int64_t)read; pos += (int64_t)read;
double percent = ((double)pos / len); double percent = ((double)pos / len);
@@ -31,27 +30,24 @@ namespace Tesses::CrossLang {
curPercent = (int)percent; curPercent = (int)percent;
if (curPercent > lastPercent) {
if(curPercent > lastPercent)
{
lastPercent = curPercent; lastPercent = curPercent;
callable->Call(ls,{curPercent/precision}); callable->Call(ls, {curPercent / precision});
} }
} while (read != 0);
} while(read != 0); } else {
}
else {
src->CopyTo(dest); src->CopyTo(dest);
} }
callable->Call(ls,{1.0}); callable->Call(ls, {1.0});
} }
return Undefined(); 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);
}
} }
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,11 +1,7 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang {
static TObject FS_CreateArchive(GCList &ls, std::vector<TObject> args) {
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::Filesystem::VFS> vfs;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm; std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
@@ -13,310 +9,333 @@ namespace Tesses::CrossLang
std::string name; std::string name;
std::string version; std::string version;
std::string info; std::string info;
std::string icon=""; std::string icon = "";
TVMVersion version2; 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))) if (GetArgument(args, 0, vfs) && GetArgument(args, 1, strm) &&
{ GetArgument(args, 2, name) && GetArgument(args, 4, info) &&
GetArgument(args,5,icon); ((GetArgument(args, 3, version) &&
CrossArchiveCreate(vfs,strm,name,version2,info,icon); TVMVersion::TryParse(version, version2)) ||
GetArgument(args, 3, version2))) {
GetArgument(args, 5, icon);
CrossArchiveCreate(vfs, strm, name, version2, info, icon);
} }
return nullptr; return nullptr;
} }
static TObject FS_ExtractArchive(GCList& ls, std::vector<TObject> args) static TObject FS_ExtractArchive(GCList &ls, std::vector<TObject> args) {
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs; std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm; std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if (GetArgument(args, 0, strm) && GetArgument(args, 1, vfs)) {
auto res = CrossArchiveExtract(strm, vfs);
if(GetArgument(args,0,strm) && GetArgument(args,1,vfs)) TDictionary *dict = TDictionary::Create(ls);
{
auto res = CrossArchiveExtract(strm,vfs);
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Name",res.first.first); dict->SetValue("Name", res.first.first);
dict->SetValue("Version",res.first.second.ToString()); dict->SetValue("Version", res.first.second.ToString());
dict->SetValue("Info",res.second); dict->SetValue("Info", res.second);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return dict; return dict;
} }
return nullptr; return nullptr;
} }
static TObject FS_ReadAllText(GCList& ls, std::vector<TObject> args) static TObject FS_ReadAllText(GCList &ls, std::vector<TObject> args) {
{
Tesses::Framework::Filesystem::VFSPath path; Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs; std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path)) if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
{ return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs, path);
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs,path);
} }
return ""; return "";
} }
static TObject FS_ReadAllLines(GCList& ls, std::vector<TObject> args) static TObject FS_ReadAllLines(GCList &ls, std::vector<TObject> args) {
{
Tesses::Framework::Filesystem::VFSPath path; Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs; std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path)) if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
{
std::vector<std::string> lines; std::vector<std::string> lines;
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs,path,lines); Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs, path, lines);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
auto items = TList::Create(ls); auto items = TList::Create(ls);
for(auto& l : lines) { items->Add(l);} for (auto &l : lines) {
items->Add(l);
}
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return items; return items;
} }
return nullptr; return nullptr;
} }
static TObject FS_ReadAllBytes(GCList& ls, std::vector<TObject> args) static TObject FS_ReadAllBytes(GCList &ls, std::vector<TObject> args) {
{
Tesses::Framework::Filesystem::VFSPath path; Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs; std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path)) if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
{
auto res = TByteArray::Create(ls); auto res = TByteArray::Create(ls);
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs,path,res->data); Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs, path,
res->data);
return res; return res;
} }
return nullptr; return nullptr;
} }
static TObject FS_WriteAllLines(GCList &ls, std::vector<TObject> args) {
static TObject FS_WriteAllLines(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path; Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs; std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TList *lines;
TList* lines; if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,lines)) GetArgumentHeap(args, 2, lines)) {
{
std::vector<std::string> content; std::vector<std::string> content;
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
for(auto& item : lines->items) for (auto &item : lines->items) {
{ if (std::holds_alternative<std::string>(item))
if(std::holds_alternative<std::string>(item))
content.push_back(std::get<std::string>(item)); content.push_back(std::get<std::string>(item));
} }
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs,path,content); Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs, path,
content);
} }
return nullptr; return nullptr;
} }
static TObject FS_WriteAllText(GCList& ls, std::vector<TObject> args) static TObject FS_WriteAllText(GCList &ls, std::vector<TObject> args) {
{
Tesses::Framework::Filesystem::VFSPath path; Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs; std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::string content; std::string content;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content)) if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
{ GetArgument(args, 2, content)) {
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs,path,content); Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs, path,
content);
} }
return nullptr; return nullptr;
} }
static TObject FS_WriteAllBytes(GCList& ls, std::vector<TObject> args) static TObject FS_WriteAllBytes(GCList &ls, std::vector<TObject> args) {
{
Tesses::Framework::Filesystem::VFSPath path; Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs; std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TByteArray* bArray; TByteArray *bArray;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,bArray)) if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
{ GetArgumentHeap(args, 2, bArray)) {
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs,path,bArray->data); Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs, path,
bArray->data);
} }
return nullptr; return nullptr;
} }
class FS_Watcher : public TNativeObject {
class FS_Watcher : public TNativeObject {
public: public:
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher; std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
FS_Watcher(std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher): watcher(watcher) FS_Watcher(
{} std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher)
: watcher(watcher) {}
TObject CallMethod(GCList& ls, std::string name, std::vector<TObject> args) TObject CallMethod(GCList &ls, std::string name,
{ std::vector<TObject> args) {
if(name == "getPath") if (name == "getPath") {
{
return watcher->GetPath(); return watcher->GetPath();
} }
if(name == "getFilesystem") if (name == "getFilesystem") {
{
return watcher->GetFilesystem(); return watcher->GetFilesystem();
} }
if(name == "setEnabled") if (name == "setEnabled") {
{
bool enabled; bool enabled;
if(GetArgument(args,0,enabled)) if (GetArgument(args, 0, enabled)) {
{
watcher->SetEnabled(enabled); watcher->SetEnabled(enabled);
return enabled; return enabled;
} }
} }
if(name == "getEnabled") if (name == "getEnabled") {
{
return watcher->GetEnabled(); return watcher->GetEnabled();
} }
if(name == "setEvents") if (name == "setEvents") {
{
int64_t evts; int64_t evts;
if(GetArgument(args,0,evts)) if (GetArgument(args, 0, evts)) {
{ watcher->events =
watcher->events = (Tesses::Framework::Filesystem::FSWatcherEventType)evts; (Tesses::Framework::Filesystem::FSWatcherEventType)evts;
return evts; return evts;
} }
} }
if(name == "getEvents") if (name == "getEvents") {
{
return (int64_t)watcher->events; return (int64_t)watcher->events;
} }
if(name == "setCallback") if (name == "setCallback") {
{ TCallable *callable = nullptr;
TCallable* callable=nullptr; if (GetArgumentHeap(args, 0, callable)) {
if(GetArgumentHeap(args,0,callable)) auto markedT = CreateMarkedTObject(ls, callable);
{ watcher->event =
auto markedT = CreateMarkedTObject(ls,callable); [markedT](
watcher->event = [markedT](Tesses::Framework::Filesystem::FSWatcherEvent& evt) -> void { Tesses::Framework::Filesystem::FSWatcherEvent &evt)
-> void {
GCList ls(markedT->GetGC()); GCList ls(markedT->GetGC());
TObject o = markedT->GetObject(); TObject o = markedT->GetObject();
TCallable* callable; TCallable *callable;
if(GetObjectHeap(o,callable)) if (GetObjectHeap(o, callable)) {
{ auto isEvent = TExternalMethod::Create(
auto isEvent = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject ls, "", {},
{ [evt](GCList &ls,
std::vector<TObject> args) -> TObject {
int64_t n; int64_t n;
if(GetArgument(args,0,n)) if (GetArgument(args, 0, n)) {
{
auto myevt = evt; auto myevt = evt;
return myevt.IsEvent((Tesses::Framework::Filesystem::FSWatcherEventType)n); return myevt.IsEvent(
(Tesses::Framework::Filesystem::
FSWatcherEventType)n);
} }
return false; 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; auto myevt = evt;
return myevt.ToString(); 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)}); auto dict = TDictionary::Create(
callable->Call(ls,{dict}); 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 {
else { watcher->event = nullptr;
watcher->event=nullptr;
} }
return nullptr; return nullptr;
} }
if(name == "Start") if (name == "Start") {
{
watcher->SetEnabled(true); watcher->SetEnabled(true);
} }
if(name == "Stop") if (name == "Stop") {
{
watcher->SetEnabled(false); watcher->SetEnabled(false);
} }
if(name == "ToString") if (name == "ToString") {
{
return "FSWatcher"; return "FSWatcher";
} }
return Undefined(); return Undefined();
} }
std::string TypeName() { std::string TypeName() { return "FSWatcher"; }
return "FSWatcher"; };
}
};
TObject New_FSWatcher(GCList& ls, std::vector<TObject> args) TObject New_FSWatcher(GCList &ls, std::vector<TObject> args) {
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs; std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path; Tesses::Framework::Filesystem::VFSPath path;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path)) if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
{ return TNativeObject::Create<FS_Watcher>(
return TNativeObject::Create<FS_Watcher>(ls,Tesses::Framework::Filesystem::FSWatcher::Create(vfs,path)); ls, Tesses::Framework::Filesystem::FSWatcher::Create(vfs, path));
} }
return nullptr; 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, bool enable) }
{ void TStd::RegisterIO(
if(enable) std::shared_ptr<GC> gc, TRootEnvironment *env,
{ std::shared_ptr<Tesses::Framework::Filesystem::RelativeFilesystem> fs) {
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.canRegisterIO = true;
env->permissions.localfs = fs; env->permissions.localfs = fs;
GCList ls(gc); GCList ls(gc);
gc->BarrierBegin(); gc->BarrierBegin();
auto newDict = env->EnsureDictionary(gc, "New"); auto newDict = env->EnsureDictionary(gc, "New");
newDict->DeclareFunction(gc,"FSWatcher","Watch a file/directory",{"vfs","path"}, New_FSWatcher); newDict->DeclareFunction(gc, "FSWatcher", "Watch a file/directory",
auto dict = env->EnsureDictionary(gc,"FS"); {"vfs", "path"}, New_FSWatcher);
dict->SetValue("SEEK_SET",(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin); auto dict = env->EnsureDictionary(gc, "FS");
dict->SetValue("SEEK_CUR",(int64_t)Tesses::Framework::Streams::SeekOrigin::Current); dict->SetValue("SEEK_SET",
dict->SetValue("SEEK_END",(int64_t)Tesses::Framework::Streams::SeekOrigin::End); (int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
dict->SetValue("FSWatcherEvents",TDictionary::Create(ls, dict->SetValue("SEEK_CUR",
{ (int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
TDItem("None", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::None), dict->SetValue("SEEK_END",
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Accessed), (int64_t)Tesses::Framework::Streams::SeekOrigin::End);
TDItem("AttributeChanged", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::AttributeChanged), dict->SetValue(
TDItem("Writen", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Writen), "FSWatcherEvents",
TDItem("Read", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Read), TDictionary::Create(
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Created), ls,
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Deleted), {TDItem(
TDItem("WatchEntryDeleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryDeleted), "None",
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Modified), (int64_t)
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryMoved), Tesses::Framework::Filesystem::FSWatcherEventType::None),
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveOld), TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveNew), FSWatcherEventType::Accessed),
TDItem("Opened", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Opened), TDItem("AttributeChanged",
TDItem("Closed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Closed), (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
TDItem("Moved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Moved), AttributeChanged),
TDItem("All", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::All) TDItem(
} "Writen",
)); (int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
if(fs) 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->SetValue("Local", fs);
dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},[fs](GCList& ls, std::vector<TObject> args)->TObject{ dict->DeclareFunction(
gc, "MakeFull", "Make absolute path from relative path", {"path"},
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::Filesystem::VFSPath path; Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path)) if (GetArgumentAsPath(args, 0, path)) {
{ if (path.relative) {
if(path.relative)
{
auto myPath = fs->GetWorking() / path; auto myPath = fs->GetWorking() / path;
myPath = myPath.CollapseRelativeParents(); myPath = myPath.CollapseRelativeParents();
return myPath; return myPath;
@@ -325,18 +344,19 @@ namespace Tesses::CrossLang
} }
return nullptr; 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(); 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; Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path)) if (GetArgumentAsPath(args, 0, path)) {
{ if (path.relative) {
if(path.relative)
{
fs->SetWorking(path.MakeAbsolute(fs->GetWorking())); fs->SetWorking(path.MakeAbsolute(fs->GetWorking()));
} } else {
else {
fs->SetWorking(path); fs->SetWorking(path);
} }
} }
@@ -344,18 +364,27 @@ namespace Tesses::CrossLang
}); });
} }
dict->DeclareFunction(gc, "ReadAllText","Read all text from file", {"fs","filename"},FS_ReadAllText); dict->DeclareFunction(gc, "ReadAllText", "Read all text from file",
dict->DeclareFunction(gc, "WriteAllText","Write all text to file", {"fs","filename","content"},FS_WriteAllText); {"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, "ReadAllLines", "Read all lines from file",
dict->DeclareFunction(gc, "WriteAllLines","Write all lines to file", {"fs","filename","lines"},FS_WriteAllLines); {"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, "ReadAllBytes", "Read all bytes from file",
dict->DeclareFunction(gc, "WriteAllBytes","Write all bytes to file", {"fs","filename","content"},FS_WriteAllBytes); {"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, "CreateArchive", "Create a crvm archive",
dict->DeclareFunction(gc,"ExtractArchive", "Extract a crvm archive",{"strm","vfs"},FS_ExtractArchive); {"fs", "strm", "name", "version", "info"},
FS_CreateArchive);
dict->DeclareFunction(gc, "ExtractArchive", "Extract a crvm archive",
{"strm", "vfs"}, FS_ExtractArchive);
gc->BarrierEnd(); gc->BarrierEnd();
}
} }
} // namespace Tesses::CrossLang

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@@ -3,144 +3,112 @@
#include <iostream> #include <iostream>
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE) #if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
using namespace Tesses::Framework::Serialization; using namespace Tesses::Framework::Serialization;
TObject Sqlite_Escape(GCList& ls, std::vector<TObject> args) TObject Sqlite_Escape(GCList &ls, std::vector<TObject> args) {
{
int64_t n; int64_t n;
double d; double d;
bool b; bool b;
std::string str; std::string str;
if(GetArgument(args,0,str)) if (GetArgument(args, 0, str)) {
{
return SQLiteDatabase::Escape(str); return SQLiteDatabase::Escape(str);
} }
if(GetArgument(args,0,n)) if (GetArgument(args, 0, n)) {
{
return std::to_string(n); return std::to_string(n);
} }
if(GetArgument(args,0,b)) if (GetArgument(args, 0, b)) {
{
return b ? "1" : "0"; return b ? "1" : "0";
} }
if(GetArgument(args,0,d)) if (GetArgument(args, 0, d)) {
{
return std::to_string(d); return std::to_string(d);
} }
return "NULL"; return "NULL";
} }
TObject Sqlite_Prepare(GCList& ls, std::vector<TObject> args) TObject Sqlite_Prepare(GCList &ls, std::vector<TObject> args) {
{
std::string str; std::string str;
TList* list; TList *list;
std::string newStr = ""; std::string newStr = "";
if(GetArgument(args,0,str) && GetArgumentHeap(args,1,list)) if (GetArgument(args, 0, str) && GetArgumentHeap(args, 1, list)) {
{
int64_t item = 0; int64_t item = 0;
for (size_t i = 0; i < str.size(); i++) {
for(size_t i = 0; i < str.size(); i++) if (str[i] == '@' && (i + 1 >= str.size() || str[i + 1] != '@')) {
{
if(str[i] == '@' && (i+1>=str.size() || str[i+1] != '@'))
{
auto v = list->Get(item); auto v = list->Get(item);
int64_t n; int64_t n;
double d; double d;
bool b; bool b;
std::string str; std::string str;
if(GetObject(v,str)) if (GetObject(v, str)) {
{ newStr += SQLiteDatabase::Escape(str);
newStr+= SQLiteDatabase::Escape(str); } else if (GetObject(v, n)) {
} newStr += std::to_string(n);
else if(GetObject(v,n)) } else if (GetObject(v, b)) {
{ newStr += (b ? "1" : "0");
newStr+= std::to_string(n); } else if (GetObject(v, d)) {
} newStr += std::to_string(d);
else if(GetObject(v,b)) } else {
{
newStr+= (b ? "1" : "0");
}
else if(GetObject(v,d))
{
newStr+= std::to_string(d);
}
else {
newStr+= "NULL"; newStr += "NULL";
}
} else {
newStr += str[i];
} }
} }
else {
newStr+=str[i];
}
}
} }
return newStr; return newStr;
} }
class SQLiteObject : public TNativeObject class SQLiteObject : public TNativeObject {
{
public: public:
SQLiteDatabase* db; SQLiteDatabase *db;
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path) SQLiteObject(Tesses::Framework::Filesystem::VFSPath path) {
{ db = new SQLiteDatabase(path);
db=new SQLiteDatabase(path);
} }
std::string TypeName() std::string TypeName() { return "SQLiteDatabase"; }
{ void Close() {
return "SQLiteDatabase"; if (this->db == nullptr)
} return;
void Close()
{
if(this->db == nullptr) return;
delete this->db; delete this->db;
this->db = nullptr; 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);
} }
bool ToBool() if (name == "Prepare") {
{ return Sqlite_Prepare(ls, args);
return this->db != nullptr;
} }
if (name == "Exec") {
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; std::string arg;
if(GetArgument(args,0,arg)) if (GetArgument(args, 0, arg)) {
{ if (this->db == nullptr)
if(this->db == nullptr) return nullptr; return nullptr;
std::vector<std::vector<std::pair<std::string, std::optional<std::string>>>> res; std::vector<std::vector<
std::pair<std::string, std::optional<std::string>>>>
res;
this->db->Exec(arg,res); this->db->Exec(arg, res);
TList* list = TList::Create(ls); TList *list = TList::Create(ls);
for(auto& item : res) for (auto &item : res) {
{ TDictionary *dict = TDictionary::Create(ls);
TDictionary* dict = TDictionary::Create(ls); for (auto &item2 : item) {
for(auto& item2 : item) if (item2.second)
{ dict->SetValue(item2.first, item2.second.value());
if(item2.second)
dict->SetValue(item2.first,item2.second.value());
else else
dict->SetValue(item2.first,nullptr); dict->SetValue(item2.first, nullptr);
} }
list->Add(dict); list->Add(dict);
@@ -152,79 +120,75 @@ namespace Tesses::CrossLang {
return Undefined(); return Undefined();
} }
~SQLiteObject() {
~SQLiteObject() if (this->db != nullptr)
{
if(this->db != nullptr)
delete this->db; delete this->db;
} }
}; };
TObject Sqlite_Open(GCList &ls, std::vector<TObject> args,
TObject Sqlite_Open(GCList& ls, std::vector<TObject> args,TRootEnvironment* env) TRootEnvironment *env) {
{
Tesses::Framework::Filesystem::VFSPath p; Tesses::Framework::Filesystem::VFSPath p;
if(GetArgumentAsPath(args,0,p)) if (GetArgumentAsPath(args, 0, p)) {
{ if (env->permissions.sqlite3Scoped) {
if(env->permissions.sqlite3Scoped)
{
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents(); p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
} }
return TNativeObject::Create<SQLiteObject>(ls,p); return TNativeObject::Create<SQLiteObject>(ls, p);
} }
return Undefined(); return Undefined();
}
} TObject Sqlite_Exec(GCList &ls, std::vector<TObject> args) {
TObject Sqlite_Exec(GCList& ls, std::vector<TObject> args) SQLiteObject *sql;
{
SQLiteObject* sql;
std::string cmd; std::string cmd;
if(GetArgumentHeap(args,0,sql) && GetArgument(args,1,cmd)) if (GetArgumentHeap(args, 0, sql) && GetArgument(args, 1, cmd)) {
{
try { try {
return sql->CallMethod(ls,"Exec",{cmd}); return sql->CallMethod(ls, "Exec", {cmd});
} catch(std::runtime_error& ex) } catch (std::runtime_error &ex) {
{
return (std::string)ex.what(); return (std::string)ex.what();
} }
} }
return Undefined(); return Undefined();
}
} TObject Sqlite_Close(GCList &ls, std::vector<TObject> args) {
SQLiteObject *sql;
TObject Sqlite_Close(GCList& ls, std::vector<TObject> args) if (GetArgumentHeap(args, 0, sql)) {
{
SQLiteObject* sql;
if(GetArgumentHeap(args,0,sql))
{
sql->Close(); sql->Close();
} }
return Undefined(); return Undefined();
} }
#endif
void TStd::RegisterSqlite(std::shared_ptr<GC> gc, TRootEnvironment *env) {
#endif env->permissions.canRegisterSqlite = true;
void TStd::RegisterSqlite(std::shared_ptr<GC> gc,TRootEnvironment* env) #if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
{
env->permissions.canRegisterSqlite=true;
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
GCList ls(gc); GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls); 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 { dict->DeclareFunction(
return Sqlite_Open(ls,args,env); 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, "Exec",
dict->DeclareFunction(gc,"Close","Close sql database",{"handle"},Sqlite_Close); "Execute sql (returns dictionary of columns "
dict->DeclareFunction(gc,"Escape","Escape sql text",{"text"},Sqlite_Escape); "key=value, an error message as string or undefined)",
dict->DeclareFunction(gc,"Prepare", "Prepare sql",{"sql","items"}, Sqlite_Prepare); {"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(); gc->BarrierBegin();
env->DeclareVariable("Sqlite", dict); env->DeclareVariable("Sqlite", dict);
gc->BarrierEnd(); gc->BarrierEnd();
#endif #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 "CrossLang.hpp"
#include "TessesFramework/Serialization/BitConverter.hpp" #include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Uuid.hpp"
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
static TObject Uuid_NewUuid(GCList& ls, std::vector<TObject> args) static TObject Uuid_NewUuid(GCList &ls, std::vector<TObject> args) {
{
return Tesses::Framework::Uuid::Generate(); return Tesses::Framework::Uuid::Generate();
} }
static TObject Uuid_TryParse(GCList& ls, std::vector<TObject> args) static TObject Uuid_TryParse(GCList &ls, std::vector<TObject> args) {
{
std::string str; std::string str;
Tesses::Framework::Uuid uuid; Tesses::Framework::Uuid uuid;
if(GetArgument(args, 0, str) && Tesses::Framework::Uuid::TryParse(str,uuid)) if (GetArgument(args, 0, str) &&
Tesses::Framework::Uuid::TryParse(str, uuid))
return uuid; return uuid;
return nullptr; return nullptr;
} }
static TObject Uuid_FromBytes(GCList& ls, std::vector<TObject> args) static TObject Uuid_FromBytes(GCList &ls, std::vector<TObject> args) {
{ TByteArray *ba;
TByteArray* ba;
int64_t index; 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()) if (GetArgumentHeap(args, 0, ba) && GetArgument(args, 1, index) &&
{ (size_t)index < ba->data.size() &&
return Tesses::Framework::Serialization::BitConverter::ToUuid(ba->data[(size_t)index]); (size_t)index + 16 <= ba->data.size()) {
return Tesses::Framework::Serialization::BitConverter::ToUuid(
ba->data[(size_t)index]);
} }
return nullptr; return nullptr;
} }
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment* env) void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment *env) {
{
gc->BarrierBegin(); gc->BarrierBegin();
TDictionary* guid = env->EnsureDictionary(gc, "Uuid"); TDictionary *guid = env->EnsureDictionary(gc, "Uuid");
guid->DeclareFunction(gc,"NewUuid","Create random uuid",{},Uuid_NewUuid); guid->DeclareFunction(gc, "NewUuid", "Create random uuid", {},
guid->DeclareFunction(gc, "TryParse","Try to parse",{"str"}, Uuid_TryParse); Uuid_NewUuid);
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",{"byteArray","offset"}, Uuid_FromBytes); guid->DeclareFunction(gc, "TryParse", "Try to parse", {"str"},
Uuid_TryParse);
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",
{"byteArray", "offset"}, Uuid_FromBytes);
gc->BarrierEnd(); gc->BarrierEnd();
}
} }
} // namespace Tesses::CrossLang

View File

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

View File

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

View File

@@ -1,126 +1,101 @@
#include "CrossLang.hpp" #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 { namespace Tesses::CrossLang {
TTask::TTask(std::shared_ptr<GC> gc) TTask::TTask(std::shared_ptr<GC> gc) { this->gc = gc; }
{ TTask *TTask::Create(GCList &ls) {
this->gc = gc; TTask *task = new TTask(ls.GetGC());
}
TTask* TTask::Create(GCList& ls)
{
TTask* task = new TTask(ls.GetGC());
ls.Add(task); ls.Add(task);
task->gc->Watch(task); task->gc->Watch(task);
return task; return task;
} }
bool TTask::IsCompleted() bool TTask::IsCompleted() {
{
gc->BarrierBegin(); gc->BarrierBegin();
bool r = this->isCompleted; bool r = this->isCompleted;
gc->BarrierEnd(); gc->BarrierEnd();
return r; return r;
} }
TTask* TTask::ContinueWith(GCList& ls, TCallable* callable) TTask *TTask::ContinueWith(GCList &ls, TCallable *callable) {
{ TTask *task = TTask::Create(ls);
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 { try {
task->SetSucceeded(callable->Call(ls,args)); task->SetSucceeded(callable->Call(ls, args));
} catch(...) { } catch (...) {
task->SetFailed(std::current_exception()); task->SetFailed(std::current_exception());
} }
return nullptr; return nullptr;
}); });
em->watch = {callable,task}; em->watch = {callable, task};
this->gc->BarrierBegin(); this->gc->BarrierBegin();
if(this->isCompleted) if (this->isCompleted) {
{
this->gc->BarrierEnd(); this->gc->BarrierEnd();
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc); std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
auto cobj = this->obj; auto cobj = this->obj;
ls->Add(cobj); ls->Add(cobj);
ls->Add(em); ls->Add(em);
this->gc->GetPool()->Schedule([ls,em,cobj](size_t s)->void { this->gc->GetPool()->Schedule(
em->Call(*ls,{cobj}); [ls, em, cobj](size_t s) -> void { em->Call(*ls, {cobj}); });
});
return task; return task;
} } else {
else
{
this->cont = em; this->cont = em;
} }
this->gc->BarrierEnd(); this->gc->BarrierEnd();
return task; return task;
} }
void TTask::ContinueWith(TCallable* callable) void TTask::ContinueWith(TCallable *callable) {
{
this->gc->BarrierBegin(); this->gc->BarrierBegin();
if(this->isCompleted) if (this->isCompleted) {
{
this->gc->BarrierEnd(); this->gc->BarrierEnd();
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc); std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
auto cobj = this->obj; auto cobj = this->obj;
ls->Add(cobj); ls->Add(cobj);
ls->Add(callable); ls->Add(callable);
this->gc->GetPool()->Schedule([ls,callable,cobj](size_t s)->void { this->gc->GetPool()->Schedule([ls, callable, cobj](size_t s) -> void {
callable->Call(*ls,{cobj}); callable->Call(*ls, {cobj});
}); });
return; return;
} } else {
else
{
this->cont = callable; this->cont = callable;
} }
this->gc->BarrierEnd(); this->gc->BarrierEnd();
} }
void TTask::SetFailed(std::exception_ptr ex) {
void TTask::SetFailed(std::exception_ptr ex)
{
this->ex = ex; this->ex = ex;
this->SetSucceeded(nullptr); this->SetSucceeded(nullptr);
} }
void TTask::SetSucceeded(TObject v) void TTask::SetSucceeded(TObject v) {
{
gc->BarrierBegin(); gc->BarrierBegin();
if(this->isCompleted) if (this->isCompleted) {
{
gc->BarrierEnd(); gc->BarrierEnd();
return; return;
} }
this->isCompleted=true; this->isCompleted = true;
this->obj = v; this->obj = v;
auto cont = this->cont; auto cont = this->cont;
gc->BarrierEnd(); gc->BarrierEnd();
if(cont != nullptr) if (cont != nullptr) {
{ std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
auto callable = cont; auto callable = cont;
ls->Add(v); ls->Add(v);
ls->Add(callable); ls->Add(callable);
this->gc->GetPool()->Schedule([ls,callable,v](size_t s)->void { this->gc->GetPool()->Schedule(
callable->Call(*ls,{v}); [ls, callable, v](size_t s) -> void { callable->Call(*ls, {v}); });
});
}
} }
}
TObject TTask::Wait() TObject TTask::Wait() {
{ while (true) {
while(true)
{
gc->BarrierBegin(); gc->BarrierBegin();
if(this->isCompleted) if (this->isCompleted) {
{ if (this->ex) {
if(this->ex)
{
auto error = this->ex; auto error = this->ex;
gc->BarrierEnd(); gc->BarrierEnd();
std::rethrow_exception(error); std::rethrow_exception(error);
@@ -129,74 +104,70 @@ namespace Tesses::CrossLang {
auto o = this->obj; auto o = this->obj;
gc->BarrierEnd(); gc->BarrierEnd();
return o; return o;
} }
gc->BarrierEnd(); gc->BarrierEnd();
} }
} }
void TTask::Mark() void TTask::Mark() {
{ if (this->marked)
if(this->marked) return; return;
this->marked=true; this->marked = true;
GC::Mark(this->obj); GC::Mark(this->obj);
if(this->cont != nullptr) if (this->cont != nullptr)
this->cont->Mark(); this->cont->Mark();
} }
TTask* TTask::Run(GCList& ls, TCallable* callable) TTask *TTask::Run(GCList &ls, TCallable *callable) {
{ TTask *task = TTask::Create(ls);
TTask* task = TTask::Create(ls); std::shared_ptr<GCList> ls2 = std::make_shared<GCList>(ls.GetGC());
std::shared_ptr<GCList> ls2=std::make_shared<GCList>(ls.GetGC());
ls2->Add(callable); ls2->Add(callable);
ls2->Add(task); ls2->Add(task);
ls.GetGC()->GetPool()->Schedule([ls2,callable,task](size_t s)->void { ls.GetGC()->GetPool()->Schedule([ls2, callable, task](size_t s) -> void {
try try {
{ task->SetSucceeded(callable->Call(*ls2, {}));
task->SetSucceeded(callable->Call(*ls2,{})); } catch (...) {
}
catch(...)
{
task->SetFailed(std::current_exception()); task->SetFailed(std::current_exception());
} }
}); });
return task; return task;
} }
TTask* TTask::FromResult(GCList& ls, TObject v) TTask *TTask::FromResult(GCList &ls, TObject v) {
{ TTask *task = TTask::Create(ls);
TTask* task = TTask::Create(ls);
task->SetSucceeded(v); task->SetSucceeded(v);
return task; return task;
} }
class TTaskCseObj { class TTaskCseObj {
std::shared_ptr<GC> gc; std::shared_ptr<GC> gc;
TTask* task; TTask *task;
public: public:
TTaskCseObj(std::shared_ptr<GC> gc, TTask* task) TTaskCseObj(std::shared_ptr<GC> gc, TTask *task) {
{
this->gc = gc; this->gc = gc;
this->task = task; this->task = task;
} }
void Invoke(std::shared_ptr<TTaskCseObj> shared_o,CallStackEntry* cse, TObject o) void Invoke(std::shared_ptr<TTaskCseObj> shared_o, CallStackEntry *cse,
{ TObject o) {
try { try {
GCList ls(gc); GCList ls(gc);
cse->Push(gc,o); cse->Push(gc, o);
auto res = cse->Resume(ls); auto res = cse->Resume(ls);
CallStackEntry* cse2; CallStackEntry *cse2;
if(GetObjectHeap(res,cse2)) if (GetObjectHeap(res, cse2)) {
{ auto taskPiece = cse2->Pop(ls);
auto taskPiece=cse2->Pop(ls); TTask *task;
TTask* task; if (GetObjectHeap(taskPiece, task)) {
if(GetObjectHeap(taskPiece,task)) auto em = TExternalMethod::Create(
{ ls, "", {"obj"},
auto em = TExternalMethod::Create(ls,"",{"obj"},[cse2,task,shared_o](GCList& ls, std::vector<TObject> args)->TObject { [cse2, task, shared_o](
GCList &ls, std::vector<TObject> args) -> TObject {
shared_o->Invoke(shared_o,cse2,args.empty() ? (TObject)Undefined():args[0]); shared_o->Invoke(shared_o, cse2,
args.empty() ? (TObject)Undefined()
: args[0]);
return nullptr; return nullptr;
}); });
@@ -205,44 +176,40 @@ namespace Tesses::CrossLang {
task->ContinueWith(em); task->ContinueWith(em);
} }
} } else {
else {
this->task->SetSucceeded(res); this->task->SetSucceeded(res);
} }
} catch(...) { } catch (...) {
this->task->SetFailed(std::current_exception()); this->task->SetFailed(std::current_exception());
} }
} }
}; };
TTask* TTask::FromClosure(GCList& ls, TClosure* closure) TTask *TTask::FromClosure(GCList &ls, TClosure *closure) {
{ auto res = closure->Call(ls, {});
auto res = closure->Call(ls,{}); CallStackEntry *ent;
CallStackEntry* ent; if (GetObjectHeap(res, ent)) {
if(GetObjectHeap(res,ent)) return FromCallStackEntry(ls, ent);
{
return FromCallStackEntry(ls,ent);
} }
return FromResult(ls,res); return FromResult(ls, res);
} }
TTask* TTask::FromCallStackEntry(GCList& ls, CallStackEntry* ent) TTask *TTask::FromCallStackEntry(GCList &ls, CallStackEntry *ent) {
{ TTask *task = TTask::Create(ls);
TTask* task = TTask::Create(ls);
//try { // try {
GCList ls2(ls.GetGC()); GCList ls2(ls.GetGC());
std::shared_ptr<GC> gc = ls.GetGC(); std::shared_ptr<GC> gc = ls.GetGC();
std::shared_ptr<TTaskCseObj> obj = std::make_shared<TTaskCseObj>(gc,task); std::shared_ptr<TTaskCseObj> obj = std::make_shared<TTaskCseObj>(gc, task);
ls2.Add(task); ls2.Add(task);
auto res = ent->Pop(ls2); auto res = ent->Pop(ls2);
TTask* task2; TTask *task2;
if(GetObjectHeap(res,task2)) if (GetObjectHeap(res, task2)) {
{ auto em = TExternalMethod::Create(
auto em = TExternalMethod::Create(ls2,"",{},[ent,task,obj](GCList& ls, std::vector<TObject> args)->TObject { ls2, "", {},
[ent, task, obj](GCList &ls, std::vector<TObject> args) -> TObject {
obj->Invoke(obj,ent,args.empty() ? (TObject)Undefined():args[0]); obj->Invoke(obj, ent,
args.empty() ? (TObject)Undefined() : args[0]);
return nullptr; return nullptr;
}); });
@@ -257,5 +224,5 @@ namespace Tesses::CrossLang {
}*/ }*/
return task; return task;
}
} }
} // namespace Tesses::CrossLang

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,88 +2,72 @@
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
EmbedStream::EmbedStream(std::shared_ptr<GC> gc, TFile* file, uint32_t resource) EmbedStream::EmbedStream(std::shared_ptr<GC> gc, TFile *file,
{ uint32_t resource) {
this->offset = 0; this->offset = 0;
this->resource = resource; this->resource = resource;
this->file = CreateMarkedTObject(gc,file); this->file = CreateMarkedTObject(gc, file);
} }
bool EmbedStream::CanRead() bool EmbedStream::CanRead() {
{ TFile *file;
TFile* file; if (GetObjectHeap(this->file->GetObject(), file)) {
if(GetObjectHeap(this->file->GetObject(),file)) if (this->resource >= file->resources.size())
{ return false;
if(this->resource >= file->resources.size()) return false; if (this->offset >= file->resources[this->resource].size())
if(this->offset >= file->resources[this->resource].size()) return false; return false;
return true; return true;
} }
return false; return false;
} }
bool EmbedStream::CanSeek() bool EmbedStream::CanSeek() { return true; }
{ bool EmbedStream::EndOfStream() { return !CanRead(); }
return true; size_t EmbedStream::Read(uint8_t *buff, size_t len) {
} TFile *file;
bool EmbedStream::EndOfStream()
{
return !CanRead();
}
size_t EmbedStream::Read(uint8_t* buff, size_t len)
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file)) if (GetObjectHeap(this->file->GetObject(), file)) {
{ if (this->resource >= file->resources.size())
if(this->resource >= file->resources.size()) return 0; return 0;
auto flen = file->resources[this->resource].size(); auto flen = file->resources[this->resource].size();
if(this->offset >= flen) return 0; if (this->offset >= flen)
return 0;
len = std::min(len, std::min( len = std::min(len, std::min(flen, flen - this->offset));
flen,
flen - this->offset
));
memcpy(buff,file->resources[this->resource].data() + this->offset,len); memcpy(buff, file->resources[this->resource].data() + this->offset,
len);
this->offset += len; this->offset += len;
return len; return len;
} }
return 0; return 0;
} }
int64_t EmbedStream::GetPosition() int64_t EmbedStream::GetPosition() { return (int64_t)this->offset; }
{ int64_t EmbedStream::GetLength() {
return (int64_t)this->offset; TFile *file;
}
int64_t EmbedStream::GetLength()
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file)) if (GetObjectHeap(this->file->GetObject(), file)) {
{ if (this->resource >= file->resources.size())
if(this->resource >= file->resources.size()) return 0; return 0;
return (int64_t)file->resources[this->resource].size(); return (int64_t)file->resources[this->resource].size();
} }
return 0; return 0;
} }
void EmbedStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence) void EmbedStream::Seek(int64_t pos,
{ Tesses::Framework::Streams::SeekOrigin whence) {
switch(whence) switch (whence) {
{
case Tesses::Framework::Streams::SeekOrigin::Begin: case Tesses::Framework::Streams::SeekOrigin::Begin:
this->offset = (uint32_t)pos; this->offset = (uint32_t)pos;
break; break;
case Tesses::Framework::Streams::SeekOrigin::Current: case Tesses::Framework::Streams::SeekOrigin::Current: {
{
int64_t cur = this->offset; int64_t cur = this->offset;
cur += pos; cur += pos;
this->offset = (uint32_t)cur; this->offset = (uint32_t)cur;
} } break;
break; case Tesses::Framework::Streams::SeekOrigin::End: {
case Tesses::Framework::Streams::SeekOrigin::End: TFile *file;
{
TFile* file;
if(GetObjectHeap(this->file->GetObject(),file)) if (GetObjectHeap(this->file->GetObject(), file)) {
{ if (this->resource >= file->resources.size())
if(this->resource >= file->resources.size()) return; return;
int64_t cur = (int64_t)file->resources[this->resource].size(); int64_t cur = (int64_t)file->resources[this->resource].size();
cur += pos; cur += pos;
this->offset = (uint32_t)cur; this->offset = (uint32_t)cur;
@@ -91,48 +75,45 @@ namespace Tesses::CrossLang {
break; break;
} }
} }
} }
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path) TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path) {
{
path = path.CollapseRelativeParents(); path = path.CollapseRelativeParents();
auto curEntry = this->dir->GetObject(); auto curEntry = this->dir->GetObject();
for(auto item : path.path) for (auto item : path.path) {
{ TDictionary *dict;
TDictionary* dict; if (GetObjectHeap(curEntry, dict) && dict->HasValue(item)) {
if(GetObjectHeap(curEntry,dict) && dict->HasValue(item))
{
curEntry = dict->GetValue(item); curEntry = dict->GetValue(item);
continue; //don't want to return undefined now do we continue; // don't want to return undefined now do we
} }
return Undefined(); return Undefined();
} }
return curEntry; return curEntry;
} }
std::shared_ptr<Tesses::Framework::Streams::Stream> EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode) std::shared_ptr<Tesses::Framework::Streams::Stream>
{ EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path,
if(mode != "r" && mode != "rb") return nullptr; std::string mode) {
if (mode != "r" && mode != "rb")
return nullptr;
auto ent = getEntry(path); auto ent = getEntry(path);
TCallable* call; TCallable *call;
if(GetObjectHeap(ent,call)) if (GetObjectHeap(ent, call)) {
{
GCList ls(this->dir->GetGC()); GCList ls(this->dir->GetGC());
auto fileO = call->Call(ls,{}); auto fileO = call->Call(ls, {});
std::shared_ptr<Tesses::Framework::Streams::Stream> strm; std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetObject(fileO,strm)) return strm; if (GetObject(fileO, strm))
return strm;
} }
return nullptr; return nullptr;
} }
bool EmbedDirectory::Stat(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatData& data) bool EmbedDirectory::Stat(Tesses::Framework::Filesystem::VFSPath path,
{ Tesses::Framework::Filesystem::StatData &data) {
auto ent = getEntry(path); auto ent = getEntry(path);
TDictionary *dict;
TDictionary* dict; if (GetObjectHeap(ent, dict)) {
if(GetObjectHeap(ent,dict))
{
data.Size = 0; data.Size = 0;
data.Mode = Tesses::Framework::Filesystem::MODE_DIRECTORY | 0755; data.Mode = Tesses::Framework::Filesystem::MODE_DIRECTORY | 0755;
data.BlockCount = 0; data.BlockCount = 0;
@@ -149,13 +130,12 @@ namespace Tesses::CrossLang {
return true; return true;
} }
TCallable* cal; TCallable *cal;
if(GetObjectHeap(ent, cal)) if (GetObjectHeap(ent, cal)) {
{
GCList ls(this->dir->GetGC()); GCList ls(this->dir->GetGC());
auto fileO= cal->Call(ls, {}); auto fileO = cal->Call(ls, {});
std::shared_ptr<Tesses::Framework::Streams::Stream> strm; std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetObject(fileO,strm)) { if (GetObject(fileO, strm)) {
data.Size = (uint64_t)strm->GetLength(); data.Size = (uint64_t)strm->GetLength();
data.Mode = Tesses::Framework::Filesystem::MODE_REGULAR | 0755; data.Mode = Tesses::Framework::Filesystem::MODE_REGULAR | 0755;
@@ -176,79 +156,65 @@ namespace Tesses::CrossLang {
} }
} }
return false; return false;
} }
class DICT_DIRENUM class DICT_DIRENUM {
{
GCList ls; GCList ls;
TDictionary* dict; TDictionary *dict;
std::map<std::string, Tesses::CrossLang::TObject>::iterator current; std::map<std::string, Tesses::CrossLang::TObject>::iterator current;
bool hasStarted = false; bool hasStarted = false;
public: public:
std::string GetCurrent() std::string GetCurrent() { return this->current->first; }
{ DICT_DIRENUM(std::shared_ptr<GC> gc, TDictionary *dict)
return this->current->first; : ls(gc), dict(dict) {
}
DICT_DIRENUM(std::shared_ptr<GC> gc, TDictionary* dict) : ls(gc), dict(dict)
{
ls.Add(dict); ls.Add(dict);
} }
bool MoveNext() bool MoveNext() {
{ if (!this->hasStarted) {
if(!this->hasStarted) this->hasStarted = true;
{
this->hasStarted=true;
this->current = this->dict->items.begin(); this->current = this->dict->items.begin();
return !this->dict->items.empty(); return !this->dict->items.empty();
} } else {
else
{
this->current++; this->current++;
return this->current != this->dict->items.end(); return this->current != this->dict->items.end();
} }
} }
};
}; Tesses::Framework::Filesystem::VFSPathEnumerator
EmbedDirectory::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path) {
Tesses::Framework::Filesystem::VFSPathEnumerator EmbedDirectory::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
{
auto ent = getEntry(path); auto ent = getEntry(path);
TDictionary* dict; TDictionary *dict;
if(GetObjectHeap(ent,dict)) if (GetObjectHeap(ent, dict)) {
{ DICT_DIRENUM *dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
DICT_DIRENUM* dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
Tesses::Framework::Filesystem::VFSPathEnumerator er( Tesses::Framework::Filesystem::VFSPathEnumerator er(
[dir2,path](Tesses::Framework::Filesystem::VFSPath& path2)->bool { [dir2,
if(dir2->MoveNext()) path](Tesses::Framework::Filesystem::VFSPath &path2) -> bool {
{ if (dir2->MoveNext()) {
path2 = path / dir2->GetCurrent(); path2 = path / dir2->GetCurrent();
return true; return true;
} }
return false; return false;
}, },
[dir2]()->void { [dir2]() -> void { delete dir2; });
delete dir2;
}
);
return er; return er;
} }
return Tesses::Framework::Filesystem::VFSPathEnumerator(); 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;
}
} }
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" #include "CrossLang.hpp"
namespace Tesses::CrossLang namespace Tesses::CrossLang {
{ TExternalMethod::TExternalMethod(
TExternalMethod::TExternalMethod(std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::string documentation, std::vector<std::string> argNames,std::function<void()> destroy) 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->cb = cb;
this->args = argNames; this->args = argNames;
this->documentation = documentation; this->documentation = documentation;
this->destroy = destroy; 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();
}
} }
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,433 +1,393 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang namespace Tesses::CrossLang {
{ bool TYieldEnumerator::MoveNext(std::shared_ptr<GC> ls) {
bool TYieldEnumerator::MoveNext(std::shared_ptr<GC> ls) CallStackEntry *ent;
{
CallStackEntry* ent;
GCList ls2(ls); GCList ls2(ls);
if(!this->hasStarted) if (!this->hasStarted) {
{ TClosure *clos;
TClosure* clos; if (!GetObjectHeap(this->enumerator, clos))
if(!GetObjectHeap(this->enumerator,clos)) return false; return false;
auto _enumerator= clos->Call(ls2,{}); auto _enumerator = clos->Call(ls2, {});
ls->BarrierBegin(); ls->BarrierBegin();
this->enumerator = _enumerator; this->enumerator = _enumerator;
this->hasStarted=true; this->hasStarted = true;
ls->BarrierEnd(); ls->BarrierEnd();
} } else {
else {
if(GetObjectHeap(this->enumerator,ent)) if (GetObjectHeap(this->enumerator, ent)) {
{ auto _enumerator = ent->Resume(ls2);
auto _enumerator= ent->Resume(ls2);
ls->BarrierBegin(); ls->BarrierBegin();
this->enumerator = _enumerator; this->enumerator = _enumerator;
ls->BarrierEnd(); ls->BarrierEnd();
} else return false; } else
return false;
} }
if(GetObjectHeap(this->enumerator,ent)) if (GetObjectHeap(this->enumerator, ent)) {
{
ls->BarrierBegin(); ls->BarrierBegin();
this->current = ent->Pop(ls2); this->current = ent->Pop(ls2);
ls->BarrierEnd(); ls->BarrierEnd();
return true; return true;
} }
return false; return false;
} }
TObject TYieldEnumerator::GetCurrent(GCList& ls) TObject TYieldEnumerator::GetCurrent(GCList &ls) {
{
ls.Add(this->current); ls.Add(this->current);
return this->current; return this->current;
} }
void TYieldEnumerator::Mark() void TYieldEnumerator::Mark() {
{ if (this->marked)
if(this->marked) return; return;
this->marked=true; this->marked = true;
GC::Mark(this->current); GC::Mark(this->current);
GC::Mark(this->enumerator); GC::Mark(this->enumerator);
} }
TYieldEnumerator* TYieldEnumerator::Create(GCList& ls,TObject v) TYieldEnumerator *TYieldEnumerator::Create(GCList &ls, TObject v) {
{ TYieldEnumerator *yieldEnum = new TYieldEnumerator();
TYieldEnumerator* yieldEnum = new TYieldEnumerator(); yieldEnum->current = nullptr;
yieldEnum->current=nullptr; yieldEnum->hasStarted = false;
yieldEnum->hasStarted=false;
yieldEnum->enumerator = v; yieldEnum->enumerator = v;
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(yieldEnum); ls.Add(yieldEnum);
_gc->Watch(yieldEnum); _gc->Watch(yieldEnum);
return yieldEnum; return yieldEnum;
} }
TYieldEnumerator* TYieldEnumerator::Create(GCList* ls,TObject v) TYieldEnumerator *TYieldEnumerator::Create(GCList *ls, TObject v) {
{
TYieldEnumerator* yieldEnum = new TYieldEnumerator(); TYieldEnumerator *yieldEnum = new TYieldEnumerator();
yieldEnum->current=nullptr; yieldEnum->current = nullptr;
yieldEnum->hasStarted=false; yieldEnum->hasStarted = false;
yieldEnum->enumerator = v; yieldEnum->enumerator = v;
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(yieldEnum); ls->Add(yieldEnum);
_gc->Watch(yieldEnum); _gc->Watch(yieldEnum);
return yieldEnum; return yieldEnum;
} }
bool TCustomEnumerator::MoveNext(std::shared_ptr<GC> ls) bool TCustomEnumerator::MoveNext(std::shared_ptr<GC> ls) {
{
GCList ls2(ls); GCList ls2(ls);
auto res = this->dict->CallMethod(ls2,"MoveNext",{}); auto res = this->dict->CallMethod(ls2, "MoveNext", {});
bool out; bool out;
if(GetObject(res,out)) return out; if (GetObject(res, out))
return out;
return false; return false;
} }
TObject TCustomEnumerator::GetCurrent(GCList& ls) TObject TCustomEnumerator::GetCurrent(GCList &ls) {
{ TObject res = Undefined();
TObject res=Undefined();
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
auto getCurrent = this->dict->GetValue("getCurrent"); auto getCurrent = this->dict->GetValue("getCurrent");
TCallable* call; TCallable *call;
if(GetObjectHeap(getCurrent,call)) if (GetObjectHeap(getCurrent, call)) {
{
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
res=call->Call(ls,{}); res = call->Call(ls, {});
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
}else{ } else {
res=this->dict->GetValue("Current"); res = this->dict->GetValue("Current");
} }
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return res; return res;
} }
void TCustomEnumerator::Mark() void TCustomEnumerator::Mark() {
{ if (this->marked)
if(this->marked) return; return;
this->dict->Mark(); this->dict->Mark();
} }
TCustomEnumerator* TCustomEnumerator::Create(GCList* ls, TDictionary* dict) TCustomEnumerator *TCustomEnumerator::Create(GCList *ls, TDictionary *dict) {
{ TCustomEnumerator *customEnum = new TCustomEnumerator();
TCustomEnumerator* customEnum = new TCustomEnumerator();
customEnum->dict = dict; customEnum->dict = dict;
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(customEnum); ls->Add(customEnum);
_gc->Watch(customEnum); _gc->Watch(customEnum);
return customEnum; return customEnum;
} }
TCustomEnumerator* TCustomEnumerator::Create(GCList& ls, TDictionary* dict) TCustomEnumerator *TCustomEnumerator::Create(GCList &ls, TDictionary *dict) {
{ TCustomEnumerator *customEnum = new TCustomEnumerator();
TCustomEnumerator* customEnum = new TCustomEnumerator();
customEnum->dict = dict; customEnum->dict = dict;
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(customEnum); ls.Add(customEnum);
_gc->Watch(customEnum); _gc->Watch(customEnum);
return customEnum; return customEnum;
} }
TEnumerator* TEnumerator::CreateFromObject(GCList& ls, TObject obj) TEnumerator *TEnumerator::CreateFromObject(GCList &ls, TObject obj) {
{
std::string str; std::string str;
TList* mls; TList *mls;
TDynamicList* dynList; TDynamicList *dynList;
TDynamicDictionary* dynDict; TDynamicDictionary *dynDict;
TDictionary* dict; TDictionary *dict;
TEnumerator* enumerator; TEnumerator *enumerator;
TQueryable* q; TQueryable *q;
if(GetObject(obj,str)) if (GetObject(obj, str)) {
{
return TStringEnumerator::Create(ls, str); return TStringEnumerator::Create(ls, str);
} } else if (GetObjectHeap(obj, mls)) {
else if(GetObjectHeap(obj,mls)) return TListEnumerator::Create(ls, mls);
{ } else if (GetObjectHeap(obj, dynList)) {
return TListEnumerator::Create(ls,mls); return TDynamicListEnumerator::Create(ls, dynList);
} } else if (GetObjectHeap(obj, dict)) {
else if(GetObjectHeap(obj,dynList)) auto res = dict->CallMethod(ls, "GetEnumerator", {});
{ if (GetObjectHeap(res, dict)) {
return TDynamicListEnumerator::Create(ls,dynList); return TCustomEnumerator::Create(ls, dict);
} } else if (GetObjectHeap(res, enumerator)) {
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 enumerator;
} }
} } else if (GetObjectHeap(obj, q)) {
else if(GetObjectHeap(obj, q))
{
return q->GetEnumerator(ls); return q->GetEnumerator(ls);
} } else if (GetObjectHeap(obj, enumerator)) {
else if(GetObjectHeap(obj, enumerator))
{
return enumerator; return enumerator;
} }
return nullptr; return nullptr;
} }
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList& ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) TVFSPathEnumerator *TVFSPathEnumerator::Create(
{ GCList &ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) {
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator(); TVFSPathEnumerator *vfspathe = new TVFSPathEnumerator();
vfspathe->enumerator = enumerator; vfspathe->enumerator = enumerator;
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(vfspathe); ls.Add(vfspathe);
_gc->Watch(vfspathe); _gc->Watch(vfspathe);
return vfspathe; return vfspathe;
} }
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList* ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) TVFSPathEnumerator *TVFSPathEnumerator::Create(
{ GCList *ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) {
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator(); TVFSPathEnumerator *vfspathe = new TVFSPathEnumerator();
vfspathe->enumerator = enumerator; vfspathe->enumerator = enumerator;
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(vfspathe); ls->Add(vfspathe);
_gc->Watch(vfspathe); _gc->Watch(vfspathe);
return vfspathe; return vfspathe;
} }
bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls) bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls) {
{
return enumerator.MoveNext(); return enumerator.MoveNext();
} }
TObject TVFSPathEnumerator::GetCurrent(GCList& ls) TObject TVFSPathEnumerator::GetCurrent(GCList &ls) {
{
return enumerator.Current; return enumerator.Current;
} }
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList& ls, TDictionary* dict) TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList &ls,
{ TDictionary *dict) {
TDictionaryEnumerator* dicte=new TDictionaryEnumerator(); TDictionaryEnumerator *dicte = new TDictionaryEnumerator();
dicte->dict = dict; dicte->dict = dict;
dicte->hasStarted=false; dicte->hasStarted = false;
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(dicte); ls.Add(dicte);
_gc->Watch(dicte); _gc->Watch(dicte);
return dicte; return dicte;
} }
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList* ls, TDictionary* dict) TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList *ls,
{ TDictionary *dict) {
TDictionaryEnumerator* dicte=new TDictionaryEnumerator(); TDictionaryEnumerator *dicte = new TDictionaryEnumerator();
dicte->dict = dict; dicte->dict = dict;
dicte->hasStarted=false; dicte->hasStarted = false;
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(dicte); ls->Add(dicte);
_gc->Watch(dicte); _gc->Watch(dicte);
return dicte; return dicte;
} }
bool TDictionaryEnumerator::MoveNext(std::shared_ptr<GC> ls) bool TDictionaryEnumerator::MoveNext(std::shared_ptr<GC> ls) {
{ if (!this->hasStarted) {
if(!this->hasStarted) this->hasStarted = true;
{
this->hasStarted=true;
this->ittr = this->dict->items.begin(); this->ittr = this->dict->items.begin();
return !this->dict->items.empty(); return !this->dict->items.empty();
} } else {
else
{
this->ittr++; this->ittr++;
return this->ittr != this->dict->items.end(); return this->ittr != this->dict->items.end();
} }
} }
TObject TDictionaryEnumerator::GetCurrent(GCList& ls) TObject TDictionaryEnumerator::GetCurrent(GCList &ls) {
{ if (!this->hasStarted)
if(!this->hasStarted) return Undefined(); return Undefined();
if(this->ittr != this->dict->items.end()) if (this->ittr != this->dict->items.end()) {
{
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
std::string key = this->ittr->first; std::string key = this->ittr->first;
TObject value = this->ittr->second; TObject value = this->ittr->second;
auto kvp = TDictionary::Create(ls); auto kvp = TDictionary::Create(ls);
kvp->SetValue("Key",key); kvp->SetValue("Key", key);
kvp->SetValue("Value",value); kvp->SetValue("Value", value);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return kvp; return kvp;
} }
return Undefined(); return Undefined();
} }
void TDictionaryEnumerator::Mark() void TDictionaryEnumerator::Mark() {
{ if (this->marked)
if(this->marked) return; return;
this->marked=true; this->marked = true;
this->dict->Mark(); this->dict->Mark();
} }
TListEnumerator *TListEnumerator::Create(GCList &ls, TList *list) {
TListEnumerator* TListEnumerator::Create(GCList& ls, TList* list) TListEnumerator *liste = new TListEnumerator();
{
TListEnumerator* liste=new TListEnumerator();
liste->ls = list; liste->ls = list;
liste->index = -1; liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste); ls.Add(liste);
_gc->Watch(liste); _gc->Watch(liste);
return liste; return liste;
} }
TListEnumerator* TListEnumerator::Create(GCList* ls, TList* list) TListEnumerator *TListEnumerator::Create(GCList *ls, TList *list) {
{ TListEnumerator *liste = new TListEnumerator();
TListEnumerator* liste=new TListEnumerator();
liste->ls = list; liste->ls = list;
liste->index = -1; liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste); ls->Add(liste);
_gc->Watch(liste); _gc->Watch(liste);
return liste; return liste;
} }
bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls) bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
{
this->index++; this->index++;
return this->index >= 0 && this->index < this->ls->Count(); return this->index >= 0 && this->index < this->ls->Count();
} }
TObject TListEnumerator::GetCurrent(GCList& ls) TObject TListEnumerator::GetCurrent(GCList &ls) {
{
if(this->index < -1) return nullptr; if (this->index < -1)
if(this->ls->Count() == 0) return nullptr; return nullptr;
if(this->index >= this->ls->Count()) return nullptr; if (this->ls->Count() == 0)
return nullptr;
if (this->index >= this->ls->Count())
return nullptr;
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
TObject o = this->ls->Get(index); TObject o = this->ls->Get(index);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return o; return o;
} }
void TListEnumerator::Mark() void TListEnumerator::Mark() {
{ if (this->marked)
if(this->marked) return; return;
this->marked = true; this->marked = true;
this->ls->Mark(); this->ls->Mark();
} }
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList& ls, TAssociativeArray* list) TAssociativeArrayEnumerator *
{ TAssociativeArrayEnumerator::Create(GCList &ls, TAssociativeArray *list) {
TAssociativeArrayEnumerator* liste=new TAssociativeArrayEnumerator(); TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
liste->ls = list; liste->ls = list;
liste->index = -1; liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste); ls.Add(liste);
_gc->Watch(liste); _gc->Watch(liste);
return liste; return liste;
} }
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList* ls, TAssociativeArray* list) TAssociativeArrayEnumerator *
{ TAssociativeArrayEnumerator::Create(GCList *ls, TAssociativeArray *list) {
TAssociativeArrayEnumerator* liste=new TAssociativeArrayEnumerator(); TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
liste->ls = list; liste->ls = list;
liste->index = -1; liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste); ls->Add(liste);
_gc->Watch(liste); _gc->Watch(liste);
return liste; return liste;
} }
bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls) bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls) {
{
this->index++; this->index++;
return this->index >= 0 && this->index < this->ls->Count(); return this->index >= 0 && this->index < this->ls->Count();
} }
TObject TAssociativeArrayEnumerator::GetCurrent(GCList& ls) TObject TAssociativeArrayEnumerator::GetCurrent(GCList &ls) {
{
if(this->index < -1) return nullptr; if (this->index < -1)
if(this->ls->Count() == 0) return nullptr; return nullptr;
if(this->index >= this->ls->Count()) return nullptr; if (this->ls->Count() == 0)
return nullptr;
if (this->index >= this->ls->Count())
return nullptr;
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
TDictionary* dict = TDictionary::Create(ls); TDictionary *dict = TDictionary::Create(ls);
dict->SetValue("Key",this->ls->GetKey(this->index)); dict->SetValue("Key", this->ls->GetKey(this->index));
dict->SetValue("Value",this->ls->GetValue(this->index)); dict->SetValue("Value", this->ls->GetValue(this->index));
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return dict; return dict;
} }
void TAssociativeArrayEnumerator::Mark() void TAssociativeArrayEnumerator::Mark() {
{ if (this->marked)
if(this->marked) return; return;
this->marked = true; this->marked = true;
this->ls->Mark(); this->ls->Mark();
} }
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList &ls,
TDynamicList *list) {
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList& ls, TDynamicList* list) TDynamicListEnumerator *liste = new TDynamicListEnumerator();
{
TDynamicListEnumerator* liste=new TDynamicListEnumerator();
liste->ls = list; liste->ls = list;
liste->index = -1; liste->index = -1;
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(liste); ls.Add(liste);
_gc->Watch(liste); _gc->Watch(liste);
return liste; return liste;
} }
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList* ls, TDynamicList* list) TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList *ls,
{ TDynamicList *list) {
TDynamicListEnumerator* liste=new TDynamicListEnumerator(); TDynamicListEnumerator *liste = new TDynamicListEnumerator();
liste->ls = list; liste->ls = list;
liste->index = -1; liste->index = -1;
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(liste); ls->Add(liste);
_gc->Watch(liste); _gc->Watch(liste);
return liste; return liste;
} }
bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls) bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
{
this->index++; this->index++;
GCList ls2(ls); GCList ls2(ls);
return this->index >= 0 && this->index < this->ls->Count(ls2); return this->index >= 0 && this->index < this->ls->Count(ls2);
} }
TObject TDynamicListEnumerator::GetCurrent(GCList& ls) TObject TDynamicListEnumerator::GetCurrent(GCList &ls) {
{
if(this->index < -1) return nullptr; if (this->index < -1)
return nullptr;
auto r = this->ls->Count(ls); auto r = this->ls->Count(ls);
if(r == 0) return nullptr; if (r == 0)
if(this->index >= r) return nullptr; return nullptr;
if (this->index >= r)
return nullptr;
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
TObject o = this->ls->GetAt(ls,index); TObject o = this->ls->GetAt(ls, index);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return o; return o;
} }
void TDynamicListEnumerator::Mark() void TDynamicListEnumerator::Mark() {
{ if (this->marked)
if(this->marked) return; return;
this->marked = true; this->marked = true;
this->ls->Mark(); this->ls->Mark();
} }
TStringEnumerator *TStringEnumerator::Create(GCList &ls, std::string str) {
TStringEnumerator* TStringEnumerator::Create(GCList& ls,std::string str) TStringEnumerator *stre = new TStringEnumerator();
{
TStringEnumerator* stre=new TStringEnumerator();
stre->str = str; stre->str = str;
stre->hasStarted=false; stre->hasStarted = false;
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(stre); ls.Add(stre);
_gc->Watch(stre); _gc->Watch(stre);
return stre; return stre;
} }
TStringEnumerator* TStringEnumerator::Create(GCList* ls,std::string str) TStringEnumerator *TStringEnumerator::Create(GCList *ls, std::string str) {
{ TStringEnumerator *stre = new TStringEnumerator();
TStringEnumerator* stre=new TStringEnumerator();
stre->str = str; stre->str = str;
stre->hasStarted=false; stre->hasStarted = false;
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(stre); ls->Add(stre);
_gc->Watch(stre); _gc->Watch(stre);
return stre; return stre;
} }
bool TStringEnumerator::MoveNext(std::shared_ptr<GC> ls) bool TStringEnumerator::MoveNext(std::shared_ptr<GC> ls) {
{ if (!this->hasStarted) {
if(!this->hasStarted) this->hasStarted = true;
{
this->hasStarted=true;
this->index = 0; this->index = 0;
return !this->str.empty(); return !this->str.empty();
} } else {
else if (this->index >= this->str.size())
{ return false;
if(this->index >= this->str.size()) return false;
this->index++; this->index++;
return this->index < this->str.size(); return this->index < this->str.size();
} }
} }
TObject TStringEnumerator::GetCurrent(GCList& ls) TObject TStringEnumerator::GetCurrent(GCList &ls) {
{ if (!this->hasStarted)
if(!this->hasStarted) return nullptr;
if(this->index < this->str.size()) return this->str[this->index];
return nullptr; 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" #include "CrossLang.hpp"
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
TDynamicList* TDynamicList::Create(GCList& ls,TCallable* callable) TDynamicList *TDynamicList::Create(GCList &ls, TCallable *callable) {
{ TDynamicList *list = new TDynamicList();
TDynamicList* list=new TDynamicList();
list->cb = callable; list->cb = callable;
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(list); ls.Add(list);
_gc->Watch(list); _gc->Watch(list);
return list; return list;
} }
TDynamicList* TDynamicList::Create(GCList* ls,TCallable* callable) TDynamicList *TDynamicList::Create(GCList *ls, TCallable *callable) {
{ TDynamicList *list = new TDynamicList();
TDynamicList* list=new TDynamicList();
list->cb = callable; list->cb = callable;
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(list); ls->Add(list);
_gc->Watch(list); _gc->Watch(list);
return list; return list;
} }
void TDynamicList::Mark() void TDynamicList::Mark() {
{ if (this->marked)
if(this->marked) return; return;
this->marked=true; this->marked = true;
this->cb->Mark(); this->cb->Mark();
} }
int64_t TDynamicList::Count(GCList& ls) int64_t TDynamicList::Count(GCList &ls) {
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Count"); dict->SetValue("Type", "Count");
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
auto res = cb->Call(ls,{dict}); auto res = cb->Call(ls, {dict});
int64_t n; int64_t n;
if(GetObject(res,n)) return n; if (GetObject(res, n))
return n;
return 0; return 0;
} }
TObject TDynamicList::Add(GCList& ls, TObject v) TObject TDynamicList::Add(GCList &ls, TObject v) {
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Add"); dict->SetValue("Type", "Add");
dict->SetValue("Value",v); dict->SetValue("Value", v);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict}); return cb->Call(ls, {dict});
}
} TObject TDynamicList::Insert(GCList &ls, int64_t index, TObject v) {
TObject TDynamicList::Insert(GCList& ls, int64_t index, TObject v)
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Insert"); dict->SetValue("Type", "Insert");
dict->SetValue("Index",index); dict->SetValue("Index", index);
dict->SetValue("Value",v); dict->SetValue("Value", v);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict}); return cb->Call(ls, {dict});
}
} TObject TDynamicList::Clear(GCList &ls) {
TObject TDynamicList::Clear(GCList& ls)
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Clear"); dict->SetValue("Type", "Clear");
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict}); return cb->Call(ls, {dict});
} }
TObject TDynamicList::Remove(GCList& ls, TObject obj) TObject TDynamicList::Remove(GCList &ls, TObject obj) {
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "Remove"); dict->SetValue("Type", "Remove");
dict->SetValue("Value", obj); dict->SetValue("Value", obj);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict}); return cb->Call(ls, {dict});
} }
TObject TDynamicList::RemoveAllEqual(GCList& ls, TObject obj) TObject TDynamicList::RemoveAllEqual(GCList &ls, TObject obj) {
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "RemoveAllEqual"); dict->SetValue("Type", "RemoveAllEqual");
dict->SetValue("Value", obj); dict->SetValue("Value", obj);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict}); return cb->Call(ls, {dict});
} }
TObject TDynamicList::RemoveAt(GCList& ls, int64_t index) TObject TDynamicList::RemoveAt(GCList &ls, int64_t index) {
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "RemoveAt"); dict->SetValue("Type", "RemoveAt");
dict->SetValue("Index", index); dict->SetValue("Index", index);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict}); return cb->Call(ls, {dict});
} }
TObject TDynamicList::ToString(GCList& ls) TObject TDynamicList::ToString(GCList &ls) {
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "ToString"); dict->SetValue("Type", "ToString");
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict}); return cb->Call(ls, {dict});
} }
TObject TDynamicList::GetAt(GCList& ls, int64_t index) TObject TDynamicList::GetAt(GCList &ls, int64_t index) {
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "GetAt"); dict->SetValue("Type", "GetAt");
dict->SetValue("Index",index); dict->SetValue("Index", index);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict}); return cb->Call(ls, {dict});
} }
TObject TDynamicList::SetAt(GCList& ls, int64_t index, TObject val) TObject TDynamicList::SetAt(GCList &ls, int64_t index, TObject val) {
{
auto dict = TDictionary::Create(ls); auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin(); ls.GetGC()->BarrierBegin();
dict->SetValue("Type", "SetAt"); dict->SetValue("Type", "SetAt");
dict->SetValue("Index",index); dict->SetValue("Index", index);
dict->SetValue("Value",val); dict->SetValue("Value", val);
ls.GetGC()->BarrierEnd(); ls.GetGC()->BarrierEnd();
return cb->Call(ls,{dict}); return cb->Call(ls, {dict});
} }
TDynamicList::~TDynamicList() TDynamicList::~TDynamicList() {}
{
} TByteArray *TByteArray::Create(GCList &ls) {
TByteArray *arr = new TByteArray();
TByteArray* TByteArray::Create(GCList& ls)
{
TByteArray* arr=new TByteArray();
std::shared_ptr<GC> _gc = ls.GetGC(); std::shared_ptr<GC> _gc = ls.GetGC();
ls.Add(arr); ls.Add(arr);
_gc->Watch(arr); _gc->Watch(arr);
return arr; return arr;
} }
TByteArray* TByteArray::Create(GCList* ls) TByteArray *TByteArray::Create(GCList *ls) {
{ TByteArray *arr = new TByteArray();
TByteArray* arr=new TByteArray();
std::shared_ptr<GC> _gc = ls->GetGC(); std::shared_ptr<GC> _gc = ls->GetGC();
ls->Add(arr); ls->Add(arr);
_gc->Watch(arr); _gc->Watch(arr);
return arr; return arr;
} }
TList* TList::Create(GCList* gc) TList *TList::Create(GCList *gc) {
{ TList *list = new TList();
TList* list=new TList();
std::shared_ptr<GC> _gc = gc->GetGC(); std::shared_ptr<GC> _gc = gc->GetGC();
gc->Add(list); gc->Add(list);
_gc->Watch(list); _gc->Watch(list);
return list; return list;
} }
TList* TList::Create(GCList& gc) TList *TList::Create(GCList &gc) {
{ TList *list = new TList();
TList* list=new TList();
std::shared_ptr<GC> _gc = gc.GetGC(); std::shared_ptr<GC> _gc = gc.GetGC();
gc.Add(list); gc.Add(list);
_gc->Watch(list); _gc->Watch(list);
return list; return list;
} }
void TList::Add(TObject value) void TList::Add(TObject value) { this->items.push_back(value); }
{ void TList::Set(int64_t index, TObject value) {
this->items.push_back(value); if (index >= 0 && index < this->Count()) {
}
void TList::Set(int64_t index, TObject value)
{
if(index >= 0 && index < this->Count())
{
this->items[index] = value; this->items[index] = value;
} }
} }
TObject TList::Get(int64_t index) TObject TList::Get(int64_t index) {
{ if (index >= 0 && index < this->Count()) {
if(index >= 0 && index < this->Count())
{
return this->items[index]; return this->items[index];
} }
return Undefined(); 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);
} }
int64_t TList::Count() }
{ void TList::RemoveAt(int64_t index) {
return (int64_t)this->items.size(); if (index >= 0 && index < this->Count()) {
this->items.erase(this->items.begin() + index);
} }
void TList::Insert(int64_t index, TObject value) }
{ void TList::Clear() { this->items.clear(); }
if(index >= 0 && index <= this->Count()) void TList::Mark() {
{ if (this->marked)
this->items.insert(this->items.begin()+index,value); return;
}
}
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; this->marked = true;
for(auto item : this->items) for (auto item : this->items) {
{
GC::Mark(item); GC::Mark(item);
} }
} }
}; }; // namespace Tesses::CrossLang

View File

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

View File

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

View File

@@ -1,47 +1,32 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
namespace Tesses::CrossLang namespace Tesses::CrossLang {
{ TRandom::TRandom() : random() {}
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) {
TRandom::TRandom(uint64_t seed) : random(seed) if (name == "Next") {
{
}
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 first;
int64_t second; int64_t second;
if(GetArgument(args,0,first)) if (GetArgument(args, 0, first)) {
{ if (GetArgument(args, 1, second)) {
if(GetArgument(args,1,second)) return (int64_t)random.Next((int32_t)first, (int32_t)second);
{
return (int64_t)random.Next((int32_t)first,(int32_t)second);
} }
return (int64_t)random.Next((uint32_t)first); return (int64_t)random.Next((uint32_t)first);
} }
return random.Next(); return random.Next();
} }
if(name == "NextByte") if (name == "NextByte") {
{
return (int64_t)random.NextByte(); return (int64_t)random.NextByte();
} }
if(name == "ToString") { if (name == "ToString") {
return ""; return "";
} }
return Undefined(); return Undefined();
}
} }
} // namespace Tesses::CrossLang

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,166 +2,147 @@
#include "TessesFramework/Serialization/BitConverter.hpp" #include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp" #include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp" #include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef> #include <cstddef>
#include <cstring>
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <cmath>
#include <cstring>
#include <sstream> #include <sstream>
#include <variant> #include <variant>
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
bool Equals(std::shared_ptr<GC> gc, TObject left, TObject right) bool Equals(std::shared_ptr<GC> gc, TObject left, TObject right) {
{
GCList ls(gc); GCList ls(gc);
if(std::holds_alternative<std::nullptr_t>(left) && std::holds_alternative<std::nullptr_t>(right)) 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)) else if (std::holds_alternative<Undefined>(left) &&
{ std::holds_alternative<Undefined>(right)) {
return true; return true;
} }
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<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); return std::get<int64_t>(left) == std::get<int64_t>(right);
} }
else if(std::holds_alternative<double>(left) && std::holds_alternative<double>(right)) else if (std::holds_alternative<double>(left) &&
{ std::holds_alternative<double>(right)) {
return std::get<double>(left) == std::get<double>(right); return std::get<double>(left) == std::get<double>(right);
} } else if (std::holds_alternative<double>(left) &&
else if(std::holds_alternative<double>(left) && std::holds_alternative<int64_t>(right)) std::holds_alternative<int64_t>(right)) {
{
return std::get<double>(left) == std::get<int64_t>(right); return std::get<double>(left) == std::get<int64_t>(right);
} } else if (std::holds_alternative<int64_t>(left) &&
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<double>(right)) std::holds_alternative<double>(right)) {
{
return std::get<int64_t>(left) == std::get<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)) 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); return std::get<std::string>(left) == std::get<std::string>(right);
} }
else if(std::holds_alternative<bool>(left) && std::holds_alternative<bool>(right)) else if (std::holds_alternative<bool>(left) &&
{ std::holds_alternative<bool>(right)) {
return std::get<bool>(left) == std::get<bool>(right); return std::get<bool>(left) == std::get<bool>(right);
} }
else if(std::holds_alternative<char>(left) && std::holds_alternative<char>(right)) else if (std::holds_alternative<char>(left) &&
{ std::holds_alternative<char>(right)) {
return std::get<char>(left) == std::get<char>(right); return std::get<char>(left) == std::get<char>(right);
} } else if (std::holds_alternative<char>(left) &&
else if(std::holds_alternative<char>(left) && std::holds_alternative<int64_t>(right)) std::holds_alternative<int64_t>(right)) {
{
return std::get<char>(left) == std::get<int64_t>(right); return std::get<char>(left) == std::get<int64_t>(right);
} } else if (std::holds_alternative<int64_t>(left) &&
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<char>(right)) std::holds_alternative<char>(right)) {
{
return std::get<int64_t>(left) == std::get<char>(right); return std::get<int64_t>(left) == std::get<char>(right);
} } else if (std::holds_alternative<
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)) std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) &&
{ std::holds_alternative<
return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left)->ToEpoch() == std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)->ToEpoch(); std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)) {
} return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)) left)
{ ->ToEpoch() ==
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left)->TotalSeconds() == std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)->TotalSeconds(); std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(
} right)
else if(std::holds_alternative<TVMVersion>(left) && std::holds_alternative<TVMVersion>(right)) ->ToEpoch();
{ } else if (std::holds_alternative<
auto lver= std::get<TVMVersion>(left); 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 rver = std::get<TVMVersion>(right);
auto r = lver.CompareTo(rver); auto r = lver.CompareTo(rver);
return r == 0; return r == 0;
} } else if (std::holds_alternative<Tesses::Framework::Uuid>(left) &&
else if(std::holds_alternative<Tesses::Framework::Uuid>(left) && std::holds_alternative<Tesses::Framework::Uuid>(right)) std::holds_alternative<Tesses::Framework::Uuid>(right)) {
{ auto l = std::get<Tesses::Framework::Uuid>(left);
auto l= std::get<Tesses::Framework::Uuid>(left);
auto r = std::get<Tesses::Framework::Uuid>(right); auto r = std::get<Tesses::Framework::Uuid>(right);
return l == r; return l == r;
} } else if (std::holds_alternative<THeapObjectHolder>(left)) {
else if(std::holds_alternative<THeapObjectHolder>(left))
{
auto obj = std::get<THeapObjectHolder>(left).obj; auto obj = std::get<THeapObjectHolder>(left).obj;
auto dict = dynamic_cast<TDictionary*>(obj); auto dict = dynamic_cast<TDictionary *>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj); auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
auto native = dynamic_cast<TNative*>(obj); auto native = dynamic_cast<TNative *>(obj);
auto natObj = dynamic_cast<TNativeObject*>(obj); auto natObj = dynamic_cast<TNativeObject *>(obj);
auto cls = dynamic_cast<TClassObject*>(obj); auto cls = dynamic_cast<TClassObject *>(obj);
if(cls != nullptr) if (cls != nullptr) {
{
gc->BarrierBegin(); gc->BarrierBegin();
auto obj=cls->GetValue("","operator=="); auto obj = cls->GetValue("", "operator==");
gc->BarrierEnd(); gc->BarrierEnd();
TCallable* callable; TCallable *callable;
if(GetObjectHeap(obj,callable)) if (GetObjectHeap(obj, callable)) {
{ return ToBool(callable->Call(ls, {right}));
return ToBool(callable->Call(ls,{right}));
} } else if (std::holds_alternative<std::nullptr_t>(right)) {
else if(std::holds_alternative<std::nullptr_t>(right)) {
return false; return false;
} } else if (std::holds_alternative<Undefined>(right)) {
else if(std::holds_alternative<Undefined>(right))
{
return false; return false;
} } else if (std::holds_alternative<THeapObjectHolder>(right)) {
else if(std::holds_alternative<THeapObjectHolder>(right))
{
return cls == std::get<THeapObjectHolder>(right).obj; return cls == std::get<THeapObjectHolder>(right).obj;
} }
} } else if (natObj != nullptr) {
else
if(natObj != nullptr)
{
return natObj->Equals(gc, right); return natObj->Equals(gc, right);
} }
if(dict != nullptr) if (dict != nullptr) {
{
gc->BarrierBegin(); gc->BarrierBegin();
TObject fn = dict->GetValue("operator=="); TObject fn = dict->GetValue("operator==");
gc->BarrierEnd(); gc->BarrierEnd();
if(!std::holds_alternative<Undefined>(fn)) if (!std::holds_alternative<Undefined>(fn)) {
{ if (std::holds_alternative<THeapObjectHolder>(fn)) {
if(std::holds_alternative<THeapObjectHolder>(fn))
{
auto obj = dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj); auto obj = dynamic_cast<TCallable *>(
if(obj != nullptr) std::get<THeapObjectHolder>(fn).obj);
{ if (obj != nullptr) {
auto closure = dynamic_cast<TClosure*>(obj); auto closure = dynamic_cast<TClosure *>(obj);
if(closure != nullptr) if (closure != nullptr) {
{
if(!closure->closure->args.empty() && closure->closure->args[0] == "this") if (!closure->closure->args.empty() &&
{ closure->closure->args[0] == "this") {
return ToBool(obj->Call(ls,{left,right})); return ToBool(obj->Call(ls, {left, right}));
} } else {
else return ToBool(obj->Call(ls, {right}));
{
return ToBool(obj->Call(ls,{right}));
} }
} else {
return ToBool(obj->Call(ls, {right}));
} }
else } else {
{
return ToBool(obj->Call(ls,{right}));
}
}
else {
return dict == std::get<THeapObjectHolder>(right).obj; return dict == std::get<THeapObjectHolder>(right).obj;
} }
@@ -171,8 +152,7 @@ namespace Tesses::CrossLang {
return dict == std::get<THeapObjectHolder>(right).obj; return dict == std::get<THeapObjectHolder>(right).obj;
} }
} } else {
else {
return dict == std::get<THeapObjectHolder>(right).obj; return dict == std::get<THeapObjectHolder>(right).obj;
} }
@@ -180,57 +160,41 @@ namespace Tesses::CrossLang {
} }
else if(dynDict != nullptr) else if (dynDict != nullptr) {
{ auto res = dynDict->CallMethod(ls, "operator==", {right});
auto res = dynDict->CallMethod(ls,"operator==",{right}); if (!std::holds_alternative<std::nullptr_t>(res) &&
if(!std::holds_alternative<std::nullptr_t>(res) && std::holds_alternative<Undefined>(res)) std::holds_alternative<Undefined>(res)) {
{
return ToBool(res); return ToBool(res);
} }
} } else if (native != nullptr &&
else if(native != nullptr && std::holds_alternative<std::nullptr_t>(right)) std::holds_alternative<std::nullptr_t>(right)) {
{
return native->GetDestroyed(); return native->GetDestroyed();
} }
if(std::holds_alternative<THeapObjectHolder>(right)) if (std::holds_alternative<THeapObjectHolder>(right)) {
{
return obj == std::get<THeapObjectHolder>(right).obj; return obj == std::get<THeapObjectHolder>(right).obj;
} }
else if(std::holds_alternative<std::nullptr_t>(right)) else if (std::holds_alternative<std::nullptr_t>(right)) {
{
return false; return false;
} } else if (std::holds_alternative<Undefined>(right)) {
else if(std::holds_alternative<Undefined>(right))
{
return false; return false;
} } else {
else
{
return false; return false;
} }
} }
else if(std::holds_alternative<std::nullptr_t>(right)) else if (std::holds_alternative<std::nullptr_t>(right)) {
{
return false; return false;
} } else if (std::holds_alternative<Undefined>(right)) {
else if(std::holds_alternative<Undefined>(right))
{
return false; return false;
} } else {
else
{
return false; return false;
} }
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/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp" #include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp" #include "TessesFramework/Uuid.hpp"
#include <cmath>
#include <cstddef> #include <cstddef>
#include <cstring>
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <cmath>
#include <cstring>
#include <sstream> #include <sstream>
#include <variant> #include <variant>
namespace Tesses::CrossLang { namespace Tesses::CrossLang {
bool InterperterThread::InvokeMethod(GCList& ls, TObject fn, TObject instance, std::vector<TObject> args) bool InterperterThread::InvokeMethod(GCList &ls, TObject fn, TObject instance,
{ std::vector<TObject> args) {
if(std::holds_alternative<THeapObjectHolder>(fn)) if (std::holds_alternative<THeapObjectHolder>(fn)) {
{
auto obj = dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj); auto obj =
if(obj != nullptr) dynamic_cast<TCallable *>(std::get<THeapObjectHolder>(fn).obj);
{ if (obj != nullptr) {
auto closure = dynamic_cast<TClosure*>(obj); auto closure = dynamic_cast<TClosure *>(obj);
if(closure != nullptr) if (closure != nullptr) {
{
if(!closure->closure->args.empty() && closure->closure->args[0] == "this") if (!closure->closure->args.empty() &&
{ closure->closure->args[0] == "this") {
std::vector<TObject> args2; std::vector<TObject> args2;
args2.push_back(instance); args2.push_back(instance);
args2.insert(args2.end(), args.begin(),args.end()); args2.insert(args2.end(), args.begin(), args.end());
this->AddCallStackEntry(ls,closure,args2); this->AddCallStackEntry(ls, closure, args2);
} } else {
else this->AddCallStackEntry(ls, closure, args);
{
this->AddCallStackEntry(ls,closure,args);
} }
} } else {
else auto val = obj->Call(ls, args);
{
auto val = obj->Call(ls,args);
this->call_stack_entries.back()->Push(ls.GetGC(), val); this->call_stack_entries.back()->Push(ls.GetGC(), val);
return false; return false;
} }
return true; return true;
} }
} }
this->call_stack_entries.back()->Push(ls.GetGC(),Undefined()); this->call_stack_entries.back()->Push(ls.GetGC(), Undefined());
return false; return false;
}
} }
} // namespace Tesses::CrossLang

View File

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

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