Compare commits
11 Commits
37fd44fd78
...
v0.0.7
| Author | SHA1 | Date | |
|---|---|---|---|
| bdbdfde646 | |||
| 62e316b022 | |||
| 17e4ca9410 | |||
| dcbc58481e | |||
| abea319ea0 | |||
| d26e357448 | |||
| 2608e94192 | |||
| 0f0e47003c | |||
| 7008a6ae61 | |||
| 28eff630c6 | |||
| f23a3880d4 |
321
.clang-format
Normal file
321
.clang-format
Normal 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
|
||||
...
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
- run: pacman-key --config /opt/cross/ppc/pacman.conf --add /root/repository.key
|
||||
- run: printf "[tesses50.git.tesses.org]\nSigLevel = Optional TrustAll\nServer = https://git.tesses.org/api/packages/tesses50/arch/core/\$arch\n" >> /etc/pacman.conf
|
||||
- run: printf "[tesses50.git.tesses.org]\nSigLevel = Optional TrustAll\nServer = https://git.tesses.org/api/packages/tesses50/arch/core/\$arch\n" >> /opt/cross/ppc/pacman.conf
|
||||
- run: pacman --noconfirm -Sy mbedtls curl tessesframework zip zig ninja
|
||||
- run: pacman --noconfirm -Sy mbedtls tessesframework zip zig ninja
|
||||
- run: pacman --config /opt/cross/ppc/pacman.conf --noconfirm -Sy mbedtls tessesframework
|
||||
- run: cp Packaging/Linux/PKGBUILD /home/build/PKGBUILD
|
||||
- run: cp Packaging/Linux/build-arch.sh /home/build/build-arch.sh
|
||||
@@ -29,7 +29,6 @@ jobs:
|
||||
- run: chown build:build /home/build/PKGBUILD
|
||||
- run: chown build:build /home/build/build-arch.sh
|
||||
- run: su build -c /home/build/build-arch.sh
|
||||
- run: env -C Packaging/Slim bash build.sh
|
||||
- uses: akkuman/gitea-release-action@v1
|
||||
env:
|
||||
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
|
||||
@@ -39,9 +38,20 @@ jobs:
|
||||
artifacts/**
|
||||
|
||||
update-tap:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: global-container-mingw
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
mkdir -p artifacts
|
||||
env -C Packaging/Windows bash build.sh
|
||||
- uses: akkuman/gitea-release-action@v1
|
||||
env:
|
||||
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
|
||||
with:
|
||||
prerelease: true
|
||||
files: |-
|
||||
artifacts/**
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Log in to registry
|
||||
|
||||
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
@@ -8,10 +8,10 @@
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/builds/linux/crosslang",
|
||||
"args": ["token"],
|
||||
"program": "${workspaceFolder}/builds/l/crossint",
|
||||
"args": ["queryable.tcross"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"cwd": "${workspaceFolder}/builds/l",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -88,7 +88,8 @@
|
||||
"clangd.fallbackFlags": [
|
||||
"-I${workspaceFolder}/include",
|
||||
"-I/home/mike/tmp-crosslang/usr/local/include/"
|
||||
]
|
||||
],
|
||||
"editor.formatOnSave": true
|
||||
|
||||
|
||||
}
|
||||
183
CMakeLists.txt
183
CMakeLists.txt
@@ -1,188 +1,35 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include(cmake/version.cmake)
|
||||
include(cmake/options.cmake)
|
||||
|
||||
project(TessesCrossLang VERSION ${CROSSLANG_MAJOR_VERSION}.${CROSSLANG_MINOR_VERSION}.${CROSSLANG_PATCH_VERSION})
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
|
||||
if(CROSSLANG_CUSTOM_CONSOLE)
|
||||
set(CROSSLANG_ENABLE_BINARIES OFF)
|
||||
set(CROSSLANG_ENABLE_SHARED OFF)
|
||||
endif()
|
||||
|
||||
|
||||
if(CROSSLANG_FETCHCONTENT)
|
||||
|
||||
set(TESSESFRAMEWORK_ENABLE_EXAMPLES OFF)
|
||||
set(TESSESFRAMEWORK_ENABLE_APPS OFF)
|
||||
|
||||
if(NOT TESSESFRAMEWORK_ENABLE_SHARED)
|
||||
set(CROSSLANG_ENABLE_SHARED OFF)
|
||||
endif()
|
||||
if(NOT TESSESFRAMEWORK_ENABLE_STATIC)
|
||||
set(CROSSLANG_ENABLE_STATIC OFF)
|
||||
endif()
|
||||
if(NOT TESSESFRAMEWORK_ENABLE_RPATH)
|
||||
set(CROSSLANG_ENABLE_RPATH OFF)
|
||||
endif()
|
||||
|
||||
#set(CROSSLANG_ENABLE_SHARED OFF)
|
||||
#set(TESSESFRAMEWORK_ENABLE_SHARED OFF)
|
||||
#set(CROSSLANG_SHARED_EXECUTABLES OFF)
|
||||
include(GNUInstallDirs)
|
||||
include(CheckLibraryExists)
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
TessesFramework
|
||||
GIT_REPOSITORY https://git.tesses.org/tesses50/tessesframework.git
|
||||
)
|
||||
FetchContent_MakeAvailable(TessesFramework)
|
||||
list(APPEND TessesCrossLangLibs ${TessesFrameworkTargets})
|
||||
else()
|
||||
find_package(TessesFramework REQUIRED)
|
||||
endif()
|
||||
|
||||
include(cmake/sources.cmake)
|
||||
include(cmake/options.cmake)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
if(CROSSLANG_ENABLE_FFI)
|
||||
find_package(PkgConfig)
|
||||
endif()
|
||||
include(cmake/linkdeps.cmake)
|
||||
if(CROSSLANG_ENABLE_FFI AND CROSSLANG_ENABLE_SHARED)
|
||||
pkg_check_modules(LIBFFI REQUIRED IMPORTED_TARGET libffi)
|
||||
endif()
|
||||
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/CrossLangVersion.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h"
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/CrossLangVersion.h)
|
||||
|
||||
|
||||
|
||||
include(cmake/findtf.cmake)
|
||||
include(cmake/sources.cmake)
|
||||
|
||||
if(CROSSLANG_OFFLINE_SHELL_PACKAGE STREQUAL "")
|
||||
|
||||
include(cmake/cpack.cmake)
|
||||
if(CROSSLANG_STATIC)
|
||||
include(cmake/staticlib.cmake)
|
||||
else()
|
||||
install(FILES ${CROSSLANG_OFFLINE_SHELL_PACKAGE} DESTINATION share/Tesses/CrossLang)
|
||||
include(cmake/sharedlib.cmake)
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
list(APPEND CROSSLANG_WIN32_EXE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/winicon.rc")
|
||||
if(MINGW)
|
||||
ENABLE_LANGUAGE(RC)
|
||||
endif(MINGW)
|
||||
endif()
|
||||
include(cmake/install-dev.cmake)
|
||||
|
||||
include(cmake/app.cmake)
|
||||
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(CROSSLANG_ENABLE_STATIC)
|
||||
|
||||
add_library(crosslang_static STATIC ${CROSSLANG_SOURCE})
|
||||
CROSSLANG_LINK_DEPS(crosslang_static)
|
||||
if(CROSSLANG_FETCHCONTENT)
|
||||
|
||||
target_link_libraries(crosslang_static PUBLIC tessesframework)
|
||||
else()
|
||||
target_link_libraries(crosslang_static PUBLIC TessesFramework::tessesframework)
|
||||
endif()
|
||||
|
||||
list(APPEND TessesCrossLangLibs crosslang_static)
|
||||
endif()
|
||||
|
||||
|
||||
if(CROSSLANG_ENABLE_SHARED)
|
||||
add_library(crosslang_shared SHARED ${CROSSLANG_SOURCE})
|
||||
CROSSLANG_LINK_DEPS(crosslang_shared)
|
||||
if(CROSSLANG_FETCHCONTENT)
|
||||
target_link_libraries(crosslang_shared PUBLIC tessesframework_shared)
|
||||
else()
|
||||
target_link_libraries(crosslang_shared PUBLIC TessesFramework::tessesframework_shared)
|
||||
endif()
|
||||
list(APPEND TessesCrossLangLibs crosslang_shared)
|
||||
endif()
|
||||
|
||||
|
||||
if(CROSSLANG_ENABLE_SUPERSLIM)
|
||||
include(cmake/slim.cmake)
|
||||
else()
|
||||
include(cmake/shared.cmake)
|
||||
|
||||
|
||||
|
||||
if(CROSSLANG_ENABLE_BINARIES)
|
||||
if(CROSSLANG_ENABLE_SHARED AND CROSSLANG_SHARED_EXECUTABLES)
|
||||
include(cmake/shared_exec.cmake)
|
||||
elseif(CROSSLANG_ENABLE_STATIC)
|
||||
include(cmake/static_exec.cmake)
|
||||
else()
|
||||
include(cmake/exec.cmake)
|
||||
endif()
|
||||
|
||||
install(TARGETS crossc DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS crossvm DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS crossint DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS crossdump DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS crosslang DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS crossarchiveextract DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS crossarchivecreate DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS crossasm DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS crossdisasm DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS crossmerge DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
if(NOT WIN32)
|
||||
install(TARGETS crossthumbnailer DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
|
||||
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/crossvm-binfmt.conf.in "${CMAKE_CURRENT_BINARY_DIR}/crossvm-binfmt.conf"
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/binfmt.d)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/crossvm-binfmt.conf"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/binfmt.d)
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/crosslang.xml"
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mime/packages)
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/crosslang.png"
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons)
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/crosslang.thumbnailer"
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/thumbnailers)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
include(InstallRequiredSystemLibraries)
|
||||
set(CPACK_PACKAGE_CONTACT "Mike Nolan <tesses@tesses.net>")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "${TessesCrossLang_VERSION_MAJOR}")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "${TessesCrossLang_VERSION_MINOR}")
|
||||
|
||||
set(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS
|
||||
"!include \\\"FileFunc.nsh\\\"\n!include \\\"${CMAKE_CURRENT_SOURCE_DIR}/FileAssociation.nsh\\\"")
|
||||
|
||||
|
||||
# Create association on install
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
|
||||
"\\\${RegisterExtension} '$INSTDIR\\\\bin\\\\crossvm.exe' '.crvm' 'CrossLang Executable'\n\
|
||||
\\\${RefreshShellIcons}")
|
||||
|
||||
# Remove association on uninstall
|
||||
|
||||
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
|
||||
"\\\${RegisterExtension} '$INSTDIR\\\\bin\\\\crossint.exe' '.tcross' 'CrossLang Script'\n\
|
||||
\\\${RefreshShellIcons}\n\
|
||||
\\\${UnRegisterExtension} '.crvm' 'CrossLang Executable'\n\
|
||||
\\\${RefreshShellIcons}")
|
||||
|
||||
# Remove association on uninstall
|
||||
set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
|
||||
"\\\${UnRegisterExtension} '.tcross' 'CrossLang Script'\n\
|
||||
\\\${RefreshShellIcons}\n\
|
||||
\\\${UnRegisterExtension} '.crvm' 'CrossLang Executable'\n\
|
||||
\\\${RefreshShellIcons}")
|
||||
|
||||
set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/winicon.ico")
|
||||
set(CPACK_NSIS_MODIFY_PATH ON)
|
||||
set(CPACK_PACKAGE_VENDOR "Tesses")
|
||||
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$DESKTOP\\\\CrossLang Interperter.lnk' '$INSTDIR\\\\bin\\\\crossint.exe'")
|
||||
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\CrossLang Interperter.lnk' '$INSTDIR\\\\bin\\\\crossint.exe'")
|
||||
|
||||
|
||||
include(CPack)
|
||||
if(CROSSLANG_INSTALL_DEVELOPMENT)
|
||||
add_subdirectory(pkgconfig)
|
||||
endif()
|
||||
@@ -6,7 +6,7 @@ RUN apk add --no-cache cmake g++ make git
|
||||
COPY ./ /src
|
||||
|
||||
|
||||
RUN cd /src && mkdir build && cd build && cmake -S .. -B . -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_APPS=ON -DCMAKE_BUILD_TYPE=Release ; make -j`nproc` && make install DESTDIR=/out
|
||||
RUN cd /src && mkdir build && cd build && cmake -S .. -B . -DTESSESFRAMEWORK_STATIC=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_APPS=ON -DCMAKE_BUILD_TYPE=Release ; make -j`nproc` && make install DESTDIR=/out
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk update
|
||||
@@ -14,4 +14,4 @@ RUN apk add --no-cache libstdc++
|
||||
COPY --from=build /out/usr /usr
|
||||
|
||||
ENV CROSSLANG_CONTAINER=1
|
||||
ENTRYPOINT ["/usr/local/bin/crossint"]
|
||||
ENTRYPOINT ["/usr/local/bin/crosslang","int"]
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# Maintainer: Mike Nolan <tesses@tesses.net>
|
||||
pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn'
|
||||
pkgver=0.0.4
|
||||
pkgver=0.0.7
|
||||
pkgrel=1
|
||||
pkgdesc=""
|
||||
arch=('x86_64' 'powerpc')
|
||||
url="https://git.tesses.org/tesses50/crosslang"
|
||||
license=('GPLv3')
|
||||
groups=()
|
||||
depends=('mbedtls' 'tessesframework=0.0.3')
|
||||
depends=('mbedtls' 'tessesframework=0.0.5')
|
||||
makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
|
||||
install=
|
||||
source=('crosslang::git+https://git.tesses.org/tesses50/crosslang')
|
||||
source=('crosslang::git+https://git.tesses.org/tesses50/crosslang#tag=v0.0.7')
|
||||
noextract=()
|
||||
sha256sums=('SKIP')
|
||||
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
|
||||
@@ -30,14 +30,14 @@ prepare() {
|
||||
build() {
|
||||
cd "$srcdir/${pkgname}"
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
|
||||
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release
|
||||
cmake -S .. -B . -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release
|
||||
else
|
||||
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN"
|
||||
cmake -S .. -B . -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN"
|
||||
fi
|
||||
|
||||
cd build
|
||||
make -j`nproc`
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ git clone --depth 1 https://git.tesses.org/tesses50/zig-cross builds/zig-cross
|
||||
for tripple in x86_64-linux-musl x86-linux-musl aarch64-linux-musl arm-linux-musleabi riscv64-linux-musl powerpc-linux-musleabihf; do
|
||||
export BUILDDIR=builds/$tripple
|
||||
mkdir -p $BUILDDIR
|
||||
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -GNinja
|
||||
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -D -DTESSESFRAMEWORK_STATIC=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -GNinja
|
||||
cmake --build $BUILDDIR || exit 1
|
||||
cmake --install $BUILDDIR --prefix $BUILDDIR/out
|
||||
mv $BUILDDIR/out/bin/crosslang ../../artifacts/crosslang-slim-$tripple
|
||||
@@ -16,7 +16,7 @@ done
|
||||
for tripple in x86_64-windows-gnu x86-windows-gnu aarch64-windows-gnu; do
|
||||
export BUILDDIR=builds/$tripple
|
||||
mkdir -p $BUILDDIR
|
||||
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -GNinja
|
||||
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -D -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -GNinja
|
||||
cmake --build $BUILDDIR || exit 1
|
||||
cmake --install $BUILDDIR --prefix $BUILDDIR/out
|
||||
|
||||
@@ -26,7 +26,7 @@ done
|
||||
for tripple in x86_64-macos-none aarch64-macos-none; do
|
||||
export BUILDDIR=builds/$tripple
|
||||
mkdir -p $BUILDDIR
|
||||
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -GNinja -DCMAKE_EXE_LINKER_FLAGS="-Wl,--strip-all"
|
||||
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -D -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCROSSLANG_ENABLE_SUPERSLIM=ON -GNinja -DCMAKE_EXE_LINKER_FLAGS="-Wl,--strip-all"
|
||||
cmake --build $BUILDDIR || exit 1
|
||||
cmake --install $BUILDDIR --prefix $BUILDDIR/out
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
#!/bin/bash
|
||||
cmake -S ../.. -B build-x86 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x86.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DCMAKE_INSTALL_PREFIX=tmp-x86 -DCMAKE_BUILD_TYPE=Release
|
||||
mkdir -p ../../artifacts
|
||||
cmake -S ../.. -B build-x86 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x86.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_INSTALL_PREFIX=tmp-x86 -DCMAKE_BUILD_TYPE=Release
|
||||
cd build-x86
|
||||
make -j`nproc`
|
||||
cpack -G NSIS
|
||||
cpack -G ZIP
|
||||
mv TessesCrossLang-*-win32.exe ../../../artifacts/crosslang-win32.exe
|
||||
mv TessesCrossLang-*-win32.zip ../../../artifacts/crosslang-win32.zip
|
||||
mv TessesCrossLang-*-win32.exe ../../../artifacts/crosslang-win32-setup.exe
|
||||
mv crosslang.exe ../../../artifacts/crosslang-win32-portable.exe
|
||||
cd ..
|
||||
cmake -S ../.. -B build-x64 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x64.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DCMAKE_INSTALL_PREFIX=tmp-x64 -DCMAKE_BUILD_TYPE=Release
|
||||
cmake -S ../.. -B build-x64 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x64.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_INSTALL_PREFIX=tmp-x64 -DCMAKE_BUILD_TYPE=Release
|
||||
cd build-x64
|
||||
make -j`nproc`
|
||||
cpack -G NSIS
|
||||
cpack -G ZIP
|
||||
mv TessesCrossLang-*-win64.exe ../../../artifacts/crosslang-win64.exe
|
||||
mv TessesCrossLang-*-win64.zip ../../../artifacts/crosslang-win64.zip
|
||||
mv TessesCrossLang-*-win64.exe ../../../artifacts/crosslang-win64-setup.exe
|
||||
mv crosslang.exe ../../../artifacts/crosslang-win64-portable.exe
|
||||
|
||||
@@ -7,7 +7,7 @@ echo " url \"https://git.tesses.org/tesses50/crosslang/archive/$VERSION.tar.gz\
|
||||
echo " sha256 \"$HASH\"" >> "Formula/crosslang.rb"
|
||||
echo " license \"GPLv3\"" >> "Formula/crosslang.rb"
|
||||
echo " depends_on \"cmake\" => :build" >> "Formula/crosslang.rb"
|
||||
echo " depends_on \"tessesframework\"" >> "Formula/crosslang.rb"
|
||||
echo " depends_on \"tesses50/tesses-tap/tessesframework\"" >> "Formula/crosslang.rb"
|
||||
echo " def install" >> "Formula/crosslang.rb"
|
||||
echo " system \"cmake\", \"-S\", \".\", \"-B\", \"build\", \"-DCROSSLANG_FETCHCONTENT=OFF\", *std_cmake_args" >> "Formula/crosslang.rb"
|
||||
echo " system \"cmake\", \"--build\", \"build\"" >> "Formula/crosslang.rb"
|
||||
|
||||
@@ -47,7 +47,7 @@ sudo make install
|
||||
|
||||
## Build with shared libs only (self contained dependencies)
|
||||
```bash
|
||||
cmake -S ../.. -B . -DTESSESFRAMEWORK_ENABLE_STATIC=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=ON
|
||||
cmake -S ../.. -B .
|
||||
make -j`nproc`
|
||||
sudo make install
|
||||
```
|
||||
|
||||
280
build-dvd.tcross
280
build-dvd.tcross
@@ -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>"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## 0.0.7
|
||||
Fix a security vulerability in crossdump that is supposed to use uint32_t but accidently used uint8_t, set to tessesframework=0.0.5
|
||||
|
||||
## 0.0.6
|
||||
Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
|
||||
|
||||
## 0.0.5
|
||||
Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable
|
||||
|
||||
## 0.0.4
|
||||
Rework for git.tesses.org, GC* is std::shared_ptr maybe will fix crash during exit
|
||||
|
||||
|
||||
25
cmake/app.cmake
Normal file
25
cmake/app.cmake
Normal 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
39
cmake/cpack.cmake
Normal 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)
|
||||
@@ -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
14
cmake/findtf.cmake
Normal 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
38
cmake/helpers.cmake
Normal 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()
|
||||
@@ -1,34 +1,28 @@
|
||||
if(CROSSLANG_INSTALL_DEVELOPMENT)
|
||||
install(TARGETS ${TessesCrossLangLibs}
|
||||
EXPORT TessesCrossLangTargets
|
||||
install(TARGETS ${CrossLangLibs}
|
||||
EXPORT CrossLangTargets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
install(FILES include/CrossLang.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(EXPORT TessesCrossLangTargets
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/CrossLang.hpp" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
|
||||
install(EXPORT CrossLangTargets
|
||||
FILE TessesCrossLangTargets.cmake
|
||||
NAMESPACE TessesCrossLang::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang
|
||||
)
|
||||
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake"
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang)
|
||||
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang)
|
||||
else()
|
||||
|
||||
if(CROSSLANG_ENABLE_SHARED)
|
||||
install(TARGETS crosslang_shared
|
||||
EXPORT TessesCrossLangTargets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
endif()
|
||||
endif()
|
||||
@@ -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()
|
||||
@@ -1,18 +1,7 @@
|
||||
option(CROSSLANG_ENABLE_STATIC "Enable Tesses CrossLang static libraries" ON)
|
||||
option(CROSSLANG_ENABLE_SHARED "Enable Tesses CrossLang shared libraries" ON)
|
||||
option(CROSSLANG_ENABLE_BINARIES "Enable Tesses CrossLang binaries" ON)
|
||||
option(CROSSLANG_INSTALL_DEVELOPMENT "Enable Tesses CrossLang development files" ON)
|
||||
option(CROSSLANG_ENABLE_THREADING "Enable Tesses CrossLang threading" ON)
|
||||
option(CROSSLANG_ENABLE_TERMIOS "Enable termios (For changing terminal options)" ON)
|
||||
option(CROSSLANG_SHARED_EXECUTABLES "Link with libcrosslang_shared" ON)
|
||||
option(CROSSLANG_FETCHCONTENT "Use fetchcontent" ON)
|
||||
option(CROSSLANG_ENABLE_CONFIG_ENVVAR "Allow setting config directory via the environment variable CROSSLANG_CONFIG" ON)
|
||||
option(CROSSLANG_ENABLE_FFI "Enable libffi" OFF)
|
||||
option(CROSSLANG_ENABLE_RPATH "Enable RPATH" ON)
|
||||
option(CROSSLANG_ENABLE_SUPERSLIM "Enable crosslang superslim, one binary" OFF)
|
||||
|
||||
option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF)
|
||||
|
||||
|
||||
|
||||
set(CROSSLANG_OFFLINE_SHELL_PACKAGE "" CACHE FILEPATH "Path to the shell package generated from https://git.tesses.org/crosslangextras")
|
||||
option(CROSSLANG_STATIC "Build with static libraries instead of shared" OFF)
|
||||
|
||||
@@ -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
20
cmake/sharedlib.cmake
Normal 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)
|
||||
@@ -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}")
|
||||
@@ -9,9 +9,6 @@ src/vm/bc/invokemethod.cpp
|
||||
src/vm/bc/executemethod2.cpp
|
||||
src/vm/bc/invoketwo.cpp
|
||||
src/vm/bc/tobool.cpp
|
||||
src/assembler/asm.cpp
|
||||
src/assembler/disasm.cpp
|
||||
src/assembler/merge.cpp
|
||||
src/compiler/codegen.cpp
|
||||
src/compiler/lexer.cpp
|
||||
src/compiler/parser.cpp
|
||||
@@ -49,7 +46,7 @@ src/types/streamheapobject.cpp
|
||||
src/types/class.cpp
|
||||
src/types/classenvironment.cpp
|
||||
src/types/random.cpp
|
||||
src/types/relativefs.cpp
|
||||
src/types/queryable.cpp
|
||||
src/vm/filereader.cpp
|
||||
src/vm/gc.cpp
|
||||
src/vm/gclist.cpp
|
||||
|
||||
@@ -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
6
cmake/staticlib.cmake
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
add_library(crosslang STATIC ${CROSSLANG_SOURCE})
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/helpers.cmake)
|
||||
|
||||
list(APPEND CrossLangLibs crosslang)
|
||||
@@ -1,3 +1,3 @@
|
||||
set(CROSSLANG_MAJOR_VERSION 0)
|
||||
set(CROSSLANG_MINOR_VERSION 0)
|
||||
set(CROSSLANG_PATCH_VERSION 4)
|
||||
set(CROSSLANG_PATCH_VERSION 7)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[Thumbnailer Entry]
|
||||
TryExec=crossthumbnailer
|
||||
Exec=crossthumbnailer %i %o
|
||||
TryExec=crosslang
|
||||
Exec=crosslang thumbnailer %i %o
|
||||
MimeType=application/crvm;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,16 +10,8 @@ else()
|
||||
set(PKGCONFIG_DEPS "")
|
||||
endif()
|
||||
|
||||
if(CROSSLANG_ENABLE_STATIC)
|
||||
configure_file(crosslang_static.pc.in crosslang_static.pc @ONLY)
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/crosslang_static.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
endif()
|
||||
|
||||
if(CROSSLANG_ENABLE_SHARED)
|
||||
configure_file(crosslang.pc.in crosslang.pc @ONLY)
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/crosslang.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
endif()
|
||||
@@ -8,6 +8,7 @@ URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
|
||||
Version: @PROJECT_VERSION@
|
||||
|
||||
@PKGCONFIG_DEPS@
|
||||
Requires: tessesframework
|
||||
|
||||
Cflags: -I"${includedir}"
|
||||
Libs: -L"${libdir}" -lcrosslang_shared
|
||||
Libs: -L"${libdir}" -lcrosslang
|
||||
@@ -1,13 +0,0 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
includedir=@PKGCONFIG_INCLUDEDIR@
|
||||
libdir=@PKGCONFIG_LIBDIR@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: @PKGCONFIG_PROJECT_DESCRIPTION@
|
||||
URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
|
||||
Version: @PROJECT_VERSION@
|
||||
|
||||
@PKGCONFIG_DEPS@
|
||||
|
||||
Cflags: -I"${includedir}"
|
||||
Libs: -L"${libdir}" -lcrosslang_static
|
||||
222
src/archive.cpp
222
src/archive.cpp
@@ -1,23 +1,20 @@
|
||||
#include "CrossLang.hpp"
|
||||
#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::string file = "/.crossarchiveignore";
|
||||
if(vfs->FileExists(file))
|
||||
{
|
||||
if (vfs->FileExists(file)) {
|
||||
auto strm = vfs->OpenFile(file, "rb");
|
||||
if(strm != nullptr)
|
||||
{
|
||||
if (strm != nullptr) {
|
||||
Tesses::Framework::TextStreams::StreamReader reader(strm);
|
||||
std::string ignores;
|
||||
while(reader.ReadLine(ignores))
|
||||
{
|
||||
if(!ignores.empty() && ignores[0] != '#')
|
||||
{
|
||||
while (reader.ReadLine(ignores)) {
|
||||
if (!ignores.empty() && ignores[0] != '#') {
|
||||
ignored_files.push_back(ignores);
|
||||
}
|
||||
ignores.clear();
|
||||
@@ -25,40 +22,18 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
}
|
||||
static std::vector<uint8_t> error_message_byte_code = {
|
||||
PUSHSTRING,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2,
|
||||
GETVARIABLE,
|
||||
PUSHSTRING,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
PUSHSTRING,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
4,
|
||||
PUSHLONG,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
CALLMETHOD,
|
||||
RET
|
||||
};
|
||||
auto writeInt = [](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,uint32_t number)->void{
|
||||
PUSHSTRING, 0, 0, 0, 2, GETVARIABLE, PUSHSTRING, 0, 0, 0,
|
||||
3, PUSHSTRING, 0, 0, 0, 4, PUSHLONG, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, CALLMETHOD, RET};
|
||||
auto writeInt = [](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
|
||||
uint32_t number) -> void {
|
||||
uint8_t buff[4];
|
||||
BitConverter::FromUint32BE(buff[0], number);
|
||||
strm->WriteBlock(buff, 4);
|
||||
};
|
||||
auto writeStr = [&writeInt](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::string text)->void {
|
||||
auto writeStr =
|
||||
[&writeInt](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
|
||||
std::string text) -> void {
|
||||
writeInt(strm, (uint32_t)text.size());
|
||||
strm->WriteBlock((const uint8_t *)text.c_str(), text.size());
|
||||
};
|
||||
@@ -68,23 +43,24 @@ namespace Tesses::CrossLang
|
||||
strs.push_back(info);
|
||||
strs.push_back("Console");
|
||||
strs.push_back("WriteLine");
|
||||
strs.push_back("You are trying to run a crvm archive, stop it you won't get anywhere!\nUse crossarchiveextract instead.");
|
||||
strs.push_back("You are trying to run a crvm archive, stop it you won't "
|
||||
"get anywhere!\nUse crossarchiveextract instead.");
|
||||
|
||||
std::vector<std::string> resources;
|
||||
|
||||
auto ensureResource = [&resources](std::string path) -> uint32_t {
|
||||
for(uint32_t i = 0; i < (uint32_t)resources.size(); i++)
|
||||
{
|
||||
if(resources[i] == path) return i;
|
||||
for (uint32_t i = 0; i < (uint32_t)resources.size(); i++) {
|
||||
if (resources[i] == path)
|
||||
return i;
|
||||
}
|
||||
uint32_t index = (uint32_t)resources.size();
|
||||
resources.push_back(path);
|
||||
return index;
|
||||
};
|
||||
auto ensureString = [&strs](std::string str) -> uint32_t {
|
||||
for(uint32_t i = 0; i < (uint32_t)strs.size(); i++)
|
||||
{
|
||||
if(strs[i] == str) return i;
|
||||
for (uint32_t i = 0; i < (uint32_t)strs.size(); i++) {
|
||||
if (strs[i] == str)
|
||||
return i;
|
||||
}
|
||||
uint32_t index = (uint32_t)strs.size();
|
||||
strs.push_back(str);
|
||||
@@ -92,33 +68,38 @@ namespace Tesses::CrossLang
|
||||
};
|
||||
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
||||
|
||||
std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkFS = [&ignored_files,vfs,&ensureString,&ensureResource,&ms,&walkFS,&writeInt](Tesses::Framework::Filesystem::VFSPath path)->void {
|
||||
|
||||
if(vfs->DirectoryExists(path))
|
||||
{
|
||||
std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkFS =
|
||||
[&ignored_files, vfs, &ensureString, &ensureResource, &ms, &walkFS,
|
||||
&writeInt](Tesses::Framework::Filesystem::VFSPath path) -> void {
|
||||
if (vfs->DirectoryExists(path)) {
|
||||
|
||||
ms->WriteByte(1);
|
||||
std::vector<std::string> paths;
|
||||
for(auto item : vfs->EnumeratePaths(path))
|
||||
{
|
||||
if(!item.relative && item.path.size() == 1 && item.path[0] == "__resdir_tmp") continue;
|
||||
if(!item.relative && item.path.size() == 1 && item.path[0] == ".crossarchiveignore") continue;
|
||||
for (auto item : vfs->EnumeratePaths(path)) {
|
||||
if (!item.relative && item.path.size() == 1 &&
|
||||
item.path[0] == "__resdir_tmp")
|
||||
continue;
|
||||
if (!item.relative && item.path.size() == 1 &&
|
||||
item.path[0] == ".crossarchiveignore")
|
||||
continue;
|
||||
std::string filename = item.GetFileName();
|
||||
bool shallIgnore = false;
|
||||
for(auto ign : ignored_files) if(ign == filename) {shallIgnore=true; break;}
|
||||
if(shallIgnore) continue;
|
||||
for (auto ign : ignored_files)
|
||||
if (ign == filename) {
|
||||
shallIgnore = true;
|
||||
break;
|
||||
}
|
||||
if (shallIgnore)
|
||||
continue;
|
||||
if (vfs->DirectoryExists(item) || vfs->RegularFileExists(item))
|
||||
paths.push_back(item.GetFileName());
|
||||
}
|
||||
writeInt(ms, (uint32_t)paths.size());
|
||||
for(auto item : paths)
|
||||
{
|
||||
for (auto item : paths) {
|
||||
writeInt(ms, ensureString(item));
|
||||
walkFS(path / item);
|
||||
}
|
||||
}
|
||||
else if(vfs->RegularFileExists(path))
|
||||
{
|
||||
} else if (vfs->RegularFileExists(path)) {
|
||||
ms->WriteByte(0);
|
||||
writeInt(ms, ensureResource(path.ToString()));
|
||||
}
|
||||
@@ -130,7 +111,9 @@ namespace Tesses::CrossLang
|
||||
|
||||
uint8_t main_header[18];
|
||||
memcpy(main_header, "TCROSSVM", 8);
|
||||
TVMVersion rtVersion(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||
TVMVersion rtVersion(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
|
||||
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
|
||||
CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||
rtVersion.ToArray(main_header + 8);
|
||||
version.ToArray(main_header + 13);
|
||||
strm->WriteBlock(main_header, sizeof(main_header));
|
||||
@@ -141,8 +124,7 @@ namespace Tesses::CrossLang
|
||||
sz += (uint32_t)(4 + str.size());
|
||||
writeInt(strm, sz);
|
||||
writeInt(strm, (uint32_t)strs.size());
|
||||
for(auto str : strs)
|
||||
{
|
||||
for (auto str : strs) {
|
||||
writeStr(strm, str);
|
||||
}
|
||||
strm->WriteBlock((const uint8_t *)"NAME", 4);
|
||||
@@ -151,8 +133,7 @@ namespace Tesses::CrossLang
|
||||
strm->WriteBlock((const uint8_t *)"INFO", 4);
|
||||
writeInt(strm, 4);
|
||||
writeInt(strm, 1);
|
||||
if(!icon.empty())
|
||||
{
|
||||
if (!icon.empty()) {
|
||||
strm->WriteBlock((const uint8_t *)"ICON", 4);
|
||||
writeInt(strm, 4);
|
||||
writeInt(strm, ensureResource(icon));
|
||||
@@ -162,29 +143,30 @@ namespace Tesses::CrossLang
|
||||
writeInt(strm, 1);
|
||||
writeInt(strm, 0);
|
||||
writeInt(strm, (uint32_t)error_message_byte_code.size());
|
||||
strm->WriteBlock(error_message_byte_code.data(),error_message_byte_code.size());
|
||||
strm->WriteBlock(error_message_byte_code.data(),
|
||||
error_message_byte_code.size());
|
||||
|
||||
|
||||
|
||||
for(auto res : resources)
|
||||
{
|
||||
for (auto res : resources) {
|
||||
strm->WriteBlock((const uint8_t *)"RESO", 4);
|
||||
auto strm2 = vfs->OpenFile(res, "rb");
|
||||
writeInt(strm, (uint32_t)strm2->GetLength());
|
||||
strm2->CopyTo(strm);
|
||||
|
||||
}
|
||||
strm->WriteBlock((const uint8_t *)"ARCV", 4);
|
||||
writeInt(strm, (uint32_t)ms->GetLength());
|
||||
ms->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||
ms->CopyTo(strm);
|
||||
}
|
||||
std::pair<std::pair<std::string,TVMVersion>,std::string> CrossArchiveExtract(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs)
|
||||
{
|
||||
std::pair<std::pair<std::string, TVMVersion>, std::string>
|
||||
CrossArchiveExtract(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs) {
|
||||
auto ensure = [strm](uint8_t *buffer, size_t count) -> void {
|
||||
|
||||
size_t read = strm->ReadBlock(buffer, count);
|
||||
if(read < count) throw VMException("End of file, could not read " + std::to_string((int64_t)count) + " byte(s)., offset=" + std::to_string(strm->GetLength()));
|
||||
if (read < count)
|
||||
throw VMException(
|
||||
"End of file, could not read " +
|
||||
std::to_string((int64_t)count) +
|
||||
" byte(s)., offset=" + std::to_string(strm->GetLength()));
|
||||
};
|
||||
auto ensureInt = [&ensure]() -> uint32_t {
|
||||
uint8_t buffer[4];
|
||||
@@ -193,7 +175,8 @@ namespace Tesses::CrossLang
|
||||
};
|
||||
auto ensureStr = [&ensure, &ensureInt]() -> std::string {
|
||||
auto len = ensureInt();
|
||||
if(len == 0) return {};
|
||||
if (len == 0)
|
||||
return {};
|
||||
std::string str = {};
|
||||
str.resize((size_t)len);
|
||||
ensure((uint8_t *)str.data(), str.size());
|
||||
@@ -202,22 +185,25 @@ namespace Tesses::CrossLang
|
||||
std::vector<std::string> strs;
|
||||
auto getStr = [&ensure, &ensureInt, &strs]() -> std::string {
|
||||
auto index = ensureInt();
|
||||
if(index > strs.size()) throw VMException("String does not exist in TCrossVM file, expected string index: " + std::to_string(index) + ", total strings: " + std::to_string(strs.size()));
|
||||
if (index > strs.size())
|
||||
throw VMException("String does not exist in TCrossVM file, "
|
||||
"expected string index: " +
|
||||
std::to_string(index) + ", total strings: " +
|
||||
std::to_string(strs.size()));
|
||||
return strs[index];
|
||||
};
|
||||
uint8_t main_header[18];
|
||||
ensure(main_header, sizeof(main_header));
|
||||
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image.");
|
||||
if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
|
||||
throw VMException("Invalid TCrossVM image.");
|
||||
TVMVersion version(main_header + 8);
|
||||
if(version.CompareToRuntime() == 1)
|
||||
{
|
||||
if (version.CompareToRuntime() == 1) {
|
||||
throw VMException("Runtime is too old.");
|
||||
}
|
||||
TVMVersion v2(main_header + 13);
|
||||
std::string name;
|
||||
std::string info;
|
||||
|
||||
|
||||
size_t _len = (size_t)ensureInt();
|
||||
|
||||
char table_name[4];
|
||||
@@ -227,16 +213,12 @@ namespace Tesses::CrossLang
|
||||
Tesses::Framework::Filesystem::VFSPath tmpDir("/__resdir_tmp");
|
||||
|
||||
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));
|
||||
size_t tableLen = (size_t)ensureInt();
|
||||
if(strncmp(table_name,"NAME",4) == 0)
|
||||
{
|
||||
if (strncmp(table_name, "NAME", 4) == 0) {
|
||||
name = getStr();
|
||||
}
|
||||
else if(strncmp(table_name,"INFO",4) == 0)
|
||||
{
|
||||
} else if (strncmp(table_name, "INFO", 4) == 0) {
|
||||
info = getStr();
|
||||
|
||||
}
|
||||
@@ -252,7 +234,8 @@ namespace Tesses::CrossLang
|
||||
uint8_t buff[1024];
|
||||
do {
|
||||
|
||||
read = std::min(std::min(tableLen-offset,tableLen), sizeof(buff));
|
||||
read = std::min(std::min(tableLen - offset, tableLen),
|
||||
sizeof(buff));
|
||||
read = strm->Read(buff, read);
|
||||
if (read > 0)
|
||||
strm2->WriteBlock(buff, read);
|
||||
@@ -265,37 +248,38 @@ namespace Tesses::CrossLang
|
||||
else if (strncmp(table_name, "STRS", 4) == 0) // strings
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
else if(strncmp(table_name,"ARCV",4) == 0)
|
||||
{
|
||||
} else if (strncmp(table_name, "ARCV", 4) == 0) {
|
||||
size_t offset = 0;
|
||||
|
||||
std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkEntry = [strm,vfs,&getStr,&ensureInt,&tmpDir,&tableLen,&offset,&walkEntry](Tesses::Framework::Filesystem::VFSPath path)->void {
|
||||
if(offset + 1 > tableLen) return;
|
||||
std::function<void(Tesses::Framework::Filesystem::VFSPath)>
|
||||
walkEntry =
|
||||
[strm, vfs, &getStr, &ensureInt, &tmpDir, &tableLen,
|
||||
&offset, &walkEntry](
|
||||
Tesses::Framework::Filesystem::VFSPath path) -> void {
|
||||
if (offset + 1 > tableLen)
|
||||
return;
|
||||
uint8_t type = strm->ReadByte();
|
||||
offset++;
|
||||
if(type == 1)
|
||||
{
|
||||
if (type == 1) {
|
||||
// ISDIR
|
||||
vfs->CreateDirectory(path);
|
||||
if(offset + 4 > tableLen) return;
|
||||
if (offset + 4 > tableLen)
|
||||
return;
|
||||
uint32_t count = ensureInt();
|
||||
offset += 4;
|
||||
for(uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
if(offset + 4 > tableLen) return;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (offset + 4 > tableLen)
|
||||
return;
|
||||
std::string name = getStr();
|
||||
offset += 4;
|
||||
walkEntry(path / name);
|
||||
}
|
||||
}
|
||||
else if(type == 0)
|
||||
{
|
||||
if(offset + 4 > tableLen) return;
|
||||
} else if (type == 0) {
|
||||
if (offset + 4 > tableLen)
|
||||
return;
|
||||
uint32_t index = ensureInt();
|
||||
auto fSrc = tmpDir / std::to_string(index);
|
||||
vfs->MoveFile(fSrc, path);
|
||||
@@ -303,14 +287,11 @@ namespace Tesses::CrossLang
|
||||
};
|
||||
|
||||
walkEntry(std::string("/"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(strm->CanSeek())
|
||||
{
|
||||
strm->Seek((int64_t)tableLen,Tesses::Framework::Streams::SeekOrigin::Current);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
if (strm->CanSeek()) {
|
||||
strm->Seek((int64_t)tableLen,
|
||||
Tesses::Framework::Streams::SeekOrigin::Current);
|
||||
} else {
|
||||
uint8_t *buffer = new uint8_t[tableLen];
|
||||
ensure(buffer, tableLen);
|
||||
delete[] buffer;
|
||||
@@ -319,6 +300,7 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
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
@@ -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));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,10 @@
|
||||
#if defined(CROSSLANG_ENABLE_JSON)
|
||||
#include <jansson.h>
|
||||
#endif
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,bool isExpression, std::vector<SyntaxNode> nodes)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,
|
||||
bool isExpression,
|
||||
std::vector<SyntaxNode> nodes) {
|
||||
AdvancedSyntaxNode asn;
|
||||
asn.nodeName = std::string(nodeName);
|
||||
asn.isExpression = isExpression;
|
||||
@@ -14,30 +14,30 @@ AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,bool isE
|
||||
}
|
||||
|
||||
#if defined(CROSSLANG_ENABLE_JSON)
|
||||
static SyntaxNode Deserialize2(json_t* json)
|
||||
{
|
||||
if(json_is_null(json)) return nullptr;
|
||||
if(json_is_true(json)) return true;
|
||||
if(json_is_false(json)) return false;
|
||||
if(json_is_integer(json)) return (int64_t)json_integer_value(json);
|
||||
if(json_is_real(json)) return json_real_value(json);
|
||||
if(json_is_string(json)) return std::string(json_string_value(json),json_string_length(json));
|
||||
if(json_is_object(json))
|
||||
{
|
||||
static SyntaxNode Deserialize2(json_t *json) {
|
||||
if (json_is_null(json))
|
||||
return nullptr;
|
||||
if (json_is_true(json))
|
||||
return true;
|
||||
if (json_is_false(json))
|
||||
return false;
|
||||
if (json_is_integer(json))
|
||||
return (int64_t)json_integer_value(json);
|
||||
if (json_is_real(json))
|
||||
return json_real_value(json);
|
||||
if (json_is_string(json))
|
||||
return std::string(json_string_value(json), json_string_length(json));
|
||||
if (json_is_object(json)) {
|
||||
json_t *typ = json_object_get(json, "type");
|
||||
if(json_is_string(typ))
|
||||
{
|
||||
if (json_is_string(typ)) {
|
||||
std::string type(json_string_value(typ), json_string_length(typ));
|
||||
if(type == CharExpression)
|
||||
{
|
||||
if (type == CharExpression) {
|
||||
json_t *chrData = json_object_get(json, "value");
|
||||
if(json_is_integer(chrData))
|
||||
{
|
||||
if (json_is_integer(chrData)) {
|
||||
return (char)(uint8_t)json_integer_value(chrData);
|
||||
}
|
||||
}
|
||||
if(type == UndefinedExpression)
|
||||
{
|
||||
if (type == UndefinedExpression) {
|
||||
return Undefined();
|
||||
}
|
||||
json_t *isExpr = json_object_get(json, "isExpression");
|
||||
@@ -46,13 +46,11 @@ static SyntaxNode Deserialize2(json_t* json)
|
||||
asn.nodeName = type;
|
||||
asn.isExpression = isExprB;
|
||||
json_t *args = json_object_get(json, "args");
|
||||
if(json_is_array(args))
|
||||
{
|
||||
if (json_is_array(args)) {
|
||||
size_t index;
|
||||
json_t *value;
|
||||
|
||||
json_array_foreach(args, index, value)
|
||||
{
|
||||
json_array_foreach(args, index, value) {
|
||||
asn.nodes.push_back(Deserialize2(value));
|
||||
}
|
||||
}
|
||||
@@ -63,9 +61,7 @@ static SyntaxNode Deserialize2(json_t* json)
|
||||
}
|
||||
#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);
|
||||
|
||||
@@ -78,52 +74,45 @@ SyntaxNode Deserialize(std::string astData)
|
||||
return nullptr;
|
||||
}
|
||||
#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))
|
||||
return json_null();
|
||||
if(std::holds_alternative<int64_t>(node))
|
||||
{
|
||||
if (std::holds_alternative<int64_t>(node)) {
|
||||
return json_integer(std::get<int64_t>(node));
|
||||
}
|
||||
if(std::holds_alternative<double>(node))
|
||||
{
|
||||
if (std::holds_alternative<double>(node)) {
|
||||
return json_real(std::get<double>(node));
|
||||
}
|
||||
if(std::holds_alternative<bool>(node))
|
||||
{
|
||||
if (std::holds_alternative<bool>(node)) {
|
||||
return json_boolean(std::get<bool>(node));
|
||||
}
|
||||
if(std::holds_alternative<std::string>(node))
|
||||
{
|
||||
if (std::holds_alternative<std::string>(node)) {
|
||||
std::string str = std::get<std::string>(node);
|
||||
return json_stringn(str.c_str(), str.size());
|
||||
}
|
||||
if(std::holds_alternative<char>(node))
|
||||
{
|
||||
if (std::holds_alternative<char>(node)) {
|
||||
char c = std::get<char>(node);
|
||||
json_t *json = json_object();
|
||||
json_object_set_new(json,"type",json_string((const char*)CharExpression.data()));
|
||||
json_object_set_new(json, "type",
|
||||
json_string((const char *)CharExpression.data()));
|
||||
json_object_set_new(json, "value", json_integer((uint8_t)c));
|
||||
return json;
|
||||
}
|
||||
if(std::holds_alternative<Undefined>(node))
|
||||
{
|
||||
if (std::holds_alternative<Undefined>(node)) {
|
||||
json_t *json = json_object();
|
||||
json_object_set_new(json,"type",json_string((const char*)UndefinedExpression.data()));
|
||||
json_object_set_new(
|
||||
json, "type",
|
||||
json_string((const char *)UndefinedExpression.data()));
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
if(std::holds_alternative<AdvancedSyntaxNode>(node))
|
||||
{
|
||||
if (std::holds_alternative<AdvancedSyntaxNode>(node)) {
|
||||
auto asn = std::get<AdvancedSyntaxNode>(node);
|
||||
json_t *j = json_object();
|
||||
json_object_set_new(j, "type", json_string(asn.nodeName.c_str()));
|
||||
json_object_set_new(j, "isExpression", json_boolean(asn.isExpression));
|
||||
json_t *arr = json_array();
|
||||
for(auto item : asn.nodes)
|
||||
{
|
||||
for (auto item : asn.nodes) {
|
||||
json_array_append_new(arr, Serialize2(item));
|
||||
}
|
||||
json_object_set_new(j, "args", arr);
|
||||
@@ -134,8 +123,7 @@ static json_t* Serialize2(SyntaxNode node)
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string Serialize(SyntaxNode node)
|
||||
{
|
||||
std::string Serialize(SyntaxNode node) {
|
||||
|
||||
#if defined(CROSSLANG_ENABLE_JSON)
|
||||
json_t *json = Serialize2(node);
|
||||
@@ -148,4 +136,4 @@ return str;
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,90 +1,65 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
std::string EscapeString(std::string text,bool quote)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
std::string EscapeString(std::string text, bool quote) {
|
||||
std::string str = {};
|
||||
if(quote) str.push_back('\"');
|
||||
for(auto item : text)
|
||||
{
|
||||
if(item == '\\' || item == '\"' || item == '\'')
|
||||
{
|
||||
if (quote)
|
||||
str.push_back('\"');
|
||||
for (auto item : text) {
|
||||
if (item == '\\' || item == '\"' || item == '\'') {
|
||||
str.push_back('\\');
|
||||
str.push_back(item);
|
||||
}
|
||||
else if(item == '\n')
|
||||
{
|
||||
} else if (item == '\n') {
|
||||
str.push_back('\\');
|
||||
str.push_back('n');
|
||||
}
|
||||
else if(item == '\r')
|
||||
{
|
||||
} else if (item == '\r') {
|
||||
str.push_back('\\');
|
||||
str.push_back('r');
|
||||
}
|
||||
else if(item == '\t')
|
||||
{
|
||||
} else if (item == '\t') {
|
||||
str.push_back('\\');
|
||||
str.push_back('t');
|
||||
}
|
||||
else if(item == '\f')
|
||||
{
|
||||
} else if (item == '\f') {
|
||||
str.push_back('\\');
|
||||
str.push_back('f');
|
||||
}
|
||||
else if(item == '\0')
|
||||
{
|
||||
} else if (item == '\0') {
|
||||
str.push_back('\\');
|
||||
str.push_back('0');
|
||||
}
|
||||
else if(item == '\b')
|
||||
{
|
||||
} else if (item == '\b') {
|
||||
str.push_back('\\');
|
||||
str.push_back('b');
|
||||
}
|
||||
else if(item == '\a')
|
||||
{
|
||||
} else if (item == '\a') {
|
||||
str.push_back('\\');
|
||||
str.push_back('a');
|
||||
}
|
||||
else if(item == '\v')
|
||||
{
|
||||
} else if (item == '\v') {
|
||||
str.push_back('\\');
|
||||
str.push_back('v');
|
||||
}
|
||||
else if(item == '\x1B')
|
||||
{
|
||||
} else if (item == '\x1B') {
|
||||
str.push_back('\\');
|
||||
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.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex(((uint8_t)item >> 4)&0x0F));
|
||||
str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex((uint8_t)item & 0x0F));
|
||||
}
|
||||
else
|
||||
{
|
||||
str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex(
|
||||
((uint8_t)item >> 4) & 0x0F));
|
||||
str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex(
|
||||
(uint8_t)item & 0x0F));
|
||||
} else {
|
||||
str.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
if(quote) str.push_back('\"');
|
||||
if (quote)
|
||||
str.push_back('\"');
|
||||
return str;
|
||||
}
|
||||
|
||||
void LexTokenLineInfo::Subtract(size_t len)
|
||||
{
|
||||
void LexTokenLineInfo::Subtract(size_t len) {
|
||||
this->offset -= len;
|
||||
this->column -= len;
|
||||
}
|
||||
void LexTokenLineInfo::Add(int c)
|
||||
{
|
||||
void LexTokenLineInfo::Add(int c) {
|
||||
this->offset++;
|
||||
switch(c)
|
||||
{
|
||||
switch (c) {
|
||||
case ' ':
|
||||
this->column++;
|
||||
break;
|
||||
@@ -104,13 +79,12 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
auto Read = [&_peeked, &strm]() -> int {
|
||||
if(_peeked > -1)
|
||||
{
|
||||
if (_peeked > -1) {
|
||||
int _peek2 = _peeked;
|
||||
_peeked = -1;
|
||||
return _peek2;
|
||||
@@ -118,12 +92,14 @@ namespace Tesses::CrossLang
|
||||
uint8_t b;
|
||||
|
||||
strm.read((char *)&b, 1);
|
||||
if(strm.eof()) return -1;
|
||||
if (strm.eof())
|
||||
return -1;
|
||||
return b;
|
||||
};
|
||||
|
||||
auto Peek = [&_peeked, Read]() -> int {
|
||||
if(_peeked > -1) return _peeked;
|
||||
if (_peeked > -1)
|
||||
return _peeked;
|
||||
_peeked = Read();
|
||||
return _peeked;
|
||||
};
|
||||
@@ -142,9 +118,9 @@ namespace Tesses::CrossLang
|
||||
|
||||
std::string whiteSpaceCharsBefore = "";
|
||||
|
||||
auto Flush = [&buffer,&tokens,&lineInfo,&whiteSpaceCharsBefore]() -> void {
|
||||
if(!buffer.empty())
|
||||
{
|
||||
auto Flush = [&buffer, &tokens, &lineInfo,
|
||||
&whiteSpaceCharsBefore]() -> void {
|
||||
if (!buffer.empty()) {
|
||||
LexToken token;
|
||||
token.text = buffer;
|
||||
token.whiteSpaceCharsBefore = whiteSpaceCharsBefore;
|
||||
@@ -158,7 +134,8 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
};
|
||||
|
||||
auto Symbol = [&tokens,&lineInfo,&whiteSpaceCharsBefore](std::initializer_list<int> chrs)-> void {
|
||||
auto Symbol = [&tokens, &lineInfo, &whiteSpaceCharsBefore](
|
||||
std::initializer_list<int> chrs) -> void {
|
||||
LexToken token;
|
||||
|
||||
token.type = LexTokenType::Symbol;
|
||||
@@ -180,123 +157,86 @@ namespace Tesses::CrossLang
|
||||
int read = Read();
|
||||
lineInfo.Add(read);
|
||||
|
||||
if(read == -1)
|
||||
{
|
||||
if (read == -1) {
|
||||
|
||||
return std::pair<int, bool>(-1, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(read == '\\')
|
||||
{
|
||||
if (read == '\\') {
|
||||
read = Read();
|
||||
lineInfo.Add(read);
|
||||
if(read == -1)
|
||||
{
|
||||
if (read == -1) {
|
||||
return std::pair<int, bool>(-1, true);
|
||||
}
|
||||
else if(read == 'n')
|
||||
{
|
||||
} else if (read == 'n') {
|
||||
return std::pair<int, bool>('\n', true);
|
||||
}
|
||||
else if(read == 'r')
|
||||
{
|
||||
} else if (read == 'r') {
|
||||
return std::pair<int, bool>('\r', true);
|
||||
}
|
||||
else if(read == 'f')
|
||||
{
|
||||
} else if (read == 'f') {
|
||||
return std::pair<int, bool>('\f', true);
|
||||
}
|
||||
else if(read == 'b')
|
||||
{
|
||||
} else if (read == 'b') {
|
||||
return std::pair<int, bool>('\b', true);
|
||||
}
|
||||
else if(read == 'a')
|
||||
{
|
||||
} else if (read == 'a') {
|
||||
return std::pair<int, bool>('\a', true);
|
||||
}
|
||||
else if(read == '0')
|
||||
{
|
||||
} else if (read == '0') {
|
||||
return std::pair<int, bool>('\0', true);
|
||||
}
|
||||
else if(read == 'v')
|
||||
{
|
||||
} else if (read == 'v') {
|
||||
return std::pair<int, bool>('\v', true);
|
||||
}
|
||||
else if(read == 'e')
|
||||
{
|
||||
} else if (read == 'e') {
|
||||
return std::pair<int, bool>('\x1B', true);
|
||||
}
|
||||
else if(read == 't')
|
||||
{
|
||||
} else if (read == 't') {
|
||||
return std::pair<int, bool>('\t', true);
|
||||
}
|
||||
else if(read == 'x')
|
||||
{
|
||||
} else if (read == 'x') {
|
||||
int r1 = Read();
|
||||
lineInfo.Add(r1);
|
||||
if(r1 == -1)
|
||||
{
|
||||
if (r1 == -1) {
|
||||
return std::pair<int, bool>(-1, true);
|
||||
}
|
||||
int r2 = Read();
|
||||
lineInfo.Add(r2);
|
||||
if(r2 == -1)
|
||||
{
|
||||
if (r2 == -1) {
|
||||
return std::pair<int, bool>(-1, true);
|
||||
}
|
||||
|
||||
uint8_t c = (uint8_t)std::stoi(std::string{(char)r1,(char)r2},nullptr,16);
|
||||
uint8_t c = (uint8_t)std::stoi(std::string{(char)r1, (char)r2},
|
||||
nullptr, 16);
|
||||
|
||||
return std::pair<int, bool>(c, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return std::pair<int, bool>(read, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return std::pair<int, bool>(read, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
auto ParseString = [&lineInfo, &strm, Read, ReadChr,&tokens](bool interopolated)->int {
|
||||
auto ParseString = [&lineInfo, &strm, Read, ReadChr,
|
||||
&tokens](bool interopolated) -> int {
|
||||
auto lI = lineInfo;
|
||||
|
||||
std::string b = {};
|
||||
|
||||
|
||||
auto rChr = ReadChr();
|
||||
lineInfo.Add(rChr.first);
|
||||
|
||||
while(rChr.first != '\"' || rChr.second)
|
||||
{
|
||||
if(rChr.first == -1) return lineInfo.line;
|
||||
while (rChr.first != '\"' || rChr.second) {
|
||||
if (rChr.first == -1)
|
||||
return lineInfo.line;
|
||||
|
||||
b.push_back((char)rChr.first);
|
||||
rChr = ReadChr();
|
||||
lineInfo.Add(rChr.first);
|
||||
}
|
||||
|
||||
if(interopolated)
|
||||
{
|
||||
if (interopolated) {
|
||||
int e = 0;
|
||||
int escapeI = 0;
|
||||
std::string b2 = {};
|
||||
|
||||
for(size_t i = 0; i< b.size();i++)
|
||||
{
|
||||
if(b[i] == '{')
|
||||
{
|
||||
if((i+1 < b.size() && b[i+1] != '{') || escapeI >= 1)
|
||||
{
|
||||
if(b2.size() > 0 && escapeI < 1)
|
||||
{
|
||||
if(e > 0)
|
||||
{
|
||||
for (size_t i = 0; i < b.size(); i++) {
|
||||
if (b[i] == '{') {
|
||||
if ((i + 1 < b.size() && b[i + 1] != '{') || escapeI >= 1) {
|
||||
if (b2.size() > 0 && escapeI < 1) {
|
||||
if (e > 0) {
|
||||
LexToken _tkn;
|
||||
_tkn.type = LexTokenType::Symbol;
|
||||
_tkn.text = "+";
|
||||
@@ -310,29 +250,20 @@ namespace Tesses::CrossLang
|
||||
tokens.push_back(_tkn2);
|
||||
b2.clear();
|
||||
e++;
|
||||
|
||||
}
|
||||
escapeI++;
|
||||
if(escapeI > 1)
|
||||
{
|
||||
if (escapeI > 1) {
|
||||
b2.push_back('{');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
b2.push_back('{');
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(b[i] == '}')
|
||||
{
|
||||
if(escapeI >= 1)
|
||||
{
|
||||
} else if (b[i] == '}') {
|
||||
if (escapeI >= 1) {
|
||||
escapeI--;
|
||||
if(b2.size() > 0 && escapeI == 0)
|
||||
{
|
||||
if(e > 0)
|
||||
{
|
||||
if (b2.size() > 0 && escapeI == 0) {
|
||||
if (e > 0) {
|
||||
LexToken _tkn;
|
||||
_tkn.type = LexTokenType::Symbol;
|
||||
_tkn.text = "+";
|
||||
@@ -344,9 +275,11 @@ namespace Tesses::CrossLang
|
||||
_tkn2.text = "(";
|
||||
_tkn2.lineInfo = lI;
|
||||
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);
|
||||
if(res != 0) return res;
|
||||
if (res != 0)
|
||||
return res;
|
||||
|
||||
_tkn2.text = ")";
|
||||
tokens.push_back(_tkn2);
|
||||
@@ -364,8 +297,7 @@ namespace Tesses::CrossLang
|
||||
b2.clear();
|
||||
e++;
|
||||
}
|
||||
if(escapeI >= 1)
|
||||
{
|
||||
if (escapeI >= 1) {
|
||||
b2.push_back('}');
|
||||
}
|
||||
}
|
||||
@@ -373,12 +305,9 @@ namespace Tesses::CrossLang
|
||||
b2.push_back(b[i]);
|
||||
}
|
||||
}
|
||||
if(b2.size() > 0)
|
||||
{
|
||||
if(escapeI > 0)
|
||||
{
|
||||
if(e > 0)
|
||||
{
|
||||
if (b2.size() > 0) {
|
||||
if (escapeI > 0) {
|
||||
if (e > 0) {
|
||||
LexToken _tkn;
|
||||
_tkn.type = LexTokenType::Symbol;
|
||||
_tkn.text = "+";
|
||||
@@ -390,9 +319,11 @@ namespace Tesses::CrossLang
|
||||
_tkn2.text = "(";
|
||||
_tkn2.lineInfo = lI;
|
||||
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);
|
||||
if(res != 0) return res;
|
||||
if (res != 0)
|
||||
return res;
|
||||
|
||||
_tkn2.text = ")";
|
||||
tokens.push_back(_tkn2);
|
||||
@@ -410,11 +341,8 @@ namespace Tesses::CrossLang
|
||||
b2.clear();
|
||||
e++;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(e > 0)
|
||||
{
|
||||
} else {
|
||||
if (e > 0) {
|
||||
LexToken _tkn;
|
||||
_tkn.type = LexTokenType::Symbol;
|
||||
_tkn.text = "+";
|
||||
@@ -436,44 +364,37 @@ namespace Tesses::CrossLang
|
||||
_tkn2.text = b;
|
||||
_tkn2.lineInfo = lI;
|
||||
tokens.push_back(_tkn2);
|
||||
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
while((read = Read()) != -1)
|
||||
{
|
||||
while ((read = Read()) != -1) {
|
||||
|
||||
peek = Peek();
|
||||
|
||||
|
||||
switch(read)
|
||||
{
|
||||
switch (read) {
|
||||
case '$':
|
||||
if(peek == '\"')
|
||||
{
|
||||
if (peek == '\"') {
|
||||
Flush();
|
||||
lineInfo.Add(Read());
|
||||
int re = ParseString(true);
|
||||
if(re != 0) return re;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (re != 0)
|
||||
return re;
|
||||
} else {
|
||||
buffer.push_back('$');
|
||||
}
|
||||
break;
|
||||
case '\"':
|
||||
{
|
||||
case '\"': {
|
||||
Flush();
|
||||
int re = ParseString(false);
|
||||
if(re != 0) return re;
|
||||
}
|
||||
break;
|
||||
case '\'':
|
||||
{
|
||||
if (re != 0)
|
||||
return re;
|
||||
} break;
|
||||
case '\'': {
|
||||
Flush();
|
||||
auto res = ReadChr();
|
||||
if(res.first == -1) return lineInfo.line;
|
||||
if (res.first == -1)
|
||||
return lineInfo.line;
|
||||
int r = Read();
|
||||
lineInfo.Add(r);
|
||||
if (r != '\'')
|
||||
@@ -484,41 +405,34 @@ namespace Tesses::CrossLang
|
||||
token.type = LexTokenType::Char;
|
||||
|
||||
tokens.push_back(token);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case '#':
|
||||
Flush();
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
int r = Read();
|
||||
lineInfo.Add(r);
|
||||
if(r == '\n' || r == -1) break;
|
||||
if (r == '\n' || r == -1)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
if(peek == '/')
|
||||
{
|
||||
if (peek == '/') {
|
||||
Flush();
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
int r = Read();
|
||||
lineInfo.Add(r);
|
||||
if(r == '\n' || r == -1) break;
|
||||
if (r == '\n' || r == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(peek == '*')
|
||||
{
|
||||
} else if (peek == '*') {
|
||||
Flush();
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
int r = Read();
|
||||
lineInfo.Add(r);
|
||||
if(r == -1)
|
||||
{
|
||||
if (r == -1) {
|
||||
return lineInfo.line;
|
||||
}
|
||||
if(r == '*')
|
||||
{
|
||||
if (r == '*') {
|
||||
r = Read();
|
||||
lineInfo.Add(r);
|
||||
if (r == -1)
|
||||
@@ -527,28 +441,22 @@ namespace Tesses::CrossLang
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(peek == '^')
|
||||
{
|
||||
} else if (peek == '^') {
|
||||
Flush();
|
||||
lineInfo.Add(Read());
|
||||
std::string str = {};
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
int r = Read();
|
||||
lineInfo.Add(r);
|
||||
if(r == -1)
|
||||
{
|
||||
if (r == -1) {
|
||||
return lineInfo.line;
|
||||
}
|
||||
if(r == '^')
|
||||
{
|
||||
if (r == '^') {
|
||||
r = Read();
|
||||
lineInfo.Add(r);
|
||||
if (r == -1)
|
||||
return lineInfo.line;
|
||||
if(r == '^')
|
||||
{
|
||||
if (r == '^') {
|
||||
str.push_back('^');
|
||||
continue;
|
||||
}
|
||||
@@ -564,44 +472,32 @@ namespace Tesses::CrossLang
|
||||
token.lineInfo = lineInfo;
|
||||
token.text = str;
|
||||
tokens.push_back(token);
|
||||
}
|
||||
else if(peek == '=')
|
||||
{
|
||||
} else if (peek == '=') {
|
||||
Flush();
|
||||
lineInfo.Add(Read());
|
||||
Symbol({read, peek});
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Flush();
|
||||
Symbol({read});
|
||||
}
|
||||
break;
|
||||
case '<':
|
||||
case '?':
|
||||
if(peek == read)
|
||||
{
|
||||
if (peek == read) {
|
||||
Flush();
|
||||
lineInfo.Add(Read());
|
||||
int peek2 = Peek();
|
||||
if(peek2 == '=')
|
||||
{
|
||||
if (peek2 == '=') {
|
||||
lineInfo.Add(Read());
|
||||
Symbol({read, peek, peek2});
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Symbol({read, peek});
|
||||
}
|
||||
}
|
||||
else if(peek == '=')
|
||||
{
|
||||
} else if (peek == '=') {
|
||||
Flush();
|
||||
lineInfo.Add(Read());
|
||||
Symbol({read, peek});
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Flush();
|
||||
Symbol({read});
|
||||
}
|
||||
@@ -610,33 +506,25 @@ namespace Tesses::CrossLang
|
||||
case '-':
|
||||
case '|':
|
||||
case '&':
|
||||
if(peek == '=' || peek == read)
|
||||
{
|
||||
if (peek == '=' || peek == read) {
|
||||
Flush();
|
||||
lineInfo.Add(Read());
|
||||
Symbol({read, peek});
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Flush();
|
||||
Symbol({read});
|
||||
}
|
||||
break;
|
||||
case '=':
|
||||
if(peek == '>')
|
||||
{
|
||||
if (peek == '>') {
|
||||
Flush();
|
||||
lineInfo.Add(Read());
|
||||
Symbol({read, peek});
|
||||
}
|
||||
else if(peek == '=')
|
||||
{
|
||||
} else if (peek == '=') {
|
||||
Flush();
|
||||
lineInfo.Add(Read());
|
||||
Symbol({read, peek});
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Flush();
|
||||
Symbol({read});
|
||||
}
|
||||
@@ -649,14 +537,11 @@ namespace Tesses::CrossLang
|
||||
case '%':
|
||||
//*
|
||||
//*=
|
||||
if(peek == '=')
|
||||
{
|
||||
if (peek == '=') {
|
||||
Flush();
|
||||
lineInfo.Add(Read());
|
||||
Symbol({read, peek});
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Flush();
|
||||
Symbol({read});
|
||||
}
|
||||
@@ -692,4 +577,4 @@ namespace Tesses::CrossLang
|
||||
Flush();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -3,57 +3,49 @@
|
||||
#include <TessesFramework/Filesystem/LocalFS.hpp>
|
||||
#include <TessesFramework/Filesystem/VFS.hpp>
|
||||
#include <TessesFramework/Streams/Stream.hpp>
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
Tesses::Framework::TF_Init();
|
||||
std::string p = argv[0];
|
||||
auto emptyThumb =Tesses::Framework::Platform::Environment::GetRealExecutablePath(p).GetParent().GetParent() / "share" / "icons" / "crosslang.png";
|
||||
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;
|
||||
return 1;
|
||||
}
|
||||
std::string crvm = argv[1];
|
||||
std::string png = argv[2];
|
||||
|
||||
|
||||
if(Tesses::Framework::Filesystem::LocalFS->FileExists(crvm))
|
||||
{
|
||||
if (Tesses::Framework::Filesystem::LocalFS->FileExists(crvm)) {
|
||||
|
||||
Tesses::CrossLang::TFile file;
|
||||
auto f = Tesses::Framework::Filesystem::LocalFS->OpenFile(crvm, "rb");
|
||||
|
||||
file.Load(nullptr, f);
|
||||
|
||||
|
||||
if(file.icon >= 0 && file.icon < file.resources.size())
|
||||
{
|
||||
auto f2 = Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
|
||||
if(f2 != nullptr)
|
||||
{
|
||||
if (file.icon >= 0 && file.icon < file.resources.size()) {
|
||||
auto f2 =
|
||||
Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
|
||||
if (f2 != nullptr) {
|
||||
auto &icon = file.resources[file.icon];
|
||||
f2->WriteBlock(icon.data(), icon.size());
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if(Tesses::Framework::Filesystem::LocalFS->FileExists(emptyThumb))
|
||||
{
|
||||
auto src = Tesses::Framework::Filesystem::LocalFS->OpenFile(emptyThumb,"rb");
|
||||
if (Tesses::Framework::Filesystem::LocalFS->FileExists(emptyThumb)) {
|
||||
auto src =
|
||||
Tesses::Framework::Filesystem::LocalFS->OpenFile(emptyThumb, "rb");
|
||||
auto dest = Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
|
||||
if(src != nullptr && dest != nullptr)
|
||||
{
|
||||
if (src != nullptr && dest != nullptr) {
|
||||
src->CopyTo(dest);
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,37 +1,25 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
SharedPtrTObject::SharedPtrTObject(std::shared_ptr<GC> gc, TObject o)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
SharedPtrTObject::SharedPtrTObject(std::shared_ptr<GC> gc, TObject o) {
|
||||
this->ls = new GCList(gc);
|
||||
this->ls->Add(o);
|
||||
this->o = o;
|
||||
}
|
||||
TObject& SharedPtrTObject::GetObject()
|
||||
{
|
||||
return this->o;
|
||||
}
|
||||
SharedPtrTObject::~SharedPtrTObject()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
MarkedTObject CreateMarkedTObject(GCList *gc, TObject o) {
|
||||
return CreateMarkedTObject(gc->GetGC(), o);
|
||||
}
|
||||
MarkedTObject CreateMarkedTObject(GCList& gc, TObject o)
|
||||
{
|
||||
MarkedTObject CreateMarkedTObject(GCList &gc, TObject o) {
|
||||
return CreateMarkedTObject(gc.GetGC(), o);
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -3,12 +3,15 @@
|
||||
namespace Tesses::CrossLang::Programs {
|
||||
using namespace Tesses::Framework::Filesystem;
|
||||
using namespace Tesses::Framework::Streams;
|
||||
static void Help(std::string& filename)
|
||||
{
|
||||
std::cout << "USAGE: " << filename << " [OPTIONS] <dirasroot> <archive.crvm>" << std::endl;
|
||||
static void Help(std::string &filename) {
|
||||
std::cout << "USAGE: " << filename
|
||||
<< " [OPTIONS] <dirasroot> <archive.crvm>" << std::endl;
|
||||
printf("OPTIONS:\n");
|
||||
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": \"https://example.com/\", \"homepage\": \"https://example.com/\",\"license\":\"MIT\"})\n");
|
||||
printf(" -I: Set icon name (relative to dirasroot), should be a 128x128 png\n");
|
||||
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": "
|
||||
"\"https://example.com/\", \"homepage\": "
|
||||
"\"https://example.com/\",\"license\":\"MIT\"})\n");
|
||||
printf(" -I: Set icon name (relative to dirasroot), should be a 128x128 "
|
||||
"png\n");
|
||||
printf(" -v: Set version (1.0.0.0-prod defaults to 1.0.0.0-dev)\n");
|
||||
printf(" -n: Set name (MyAppOrLibName defaults to out)\n");
|
||||
printf(" -h, --help: Prints help\n");
|
||||
@@ -16,73 +19,59 @@ static void Help(std::string& filename)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int64_t CrossArchiveCreate(std::vector<std::string>& argv)
|
||||
{
|
||||
int64_t CrossArchiveCreate(std::vector<std::string> &argv) {
|
||||
Tesses::Framework::TF_Init();
|
||||
std::string name = "out";
|
||||
std::string info = "{}";
|
||||
TVMVersion version;
|
||||
std::string icon = "";
|
||||
std::vector<std::string> args;
|
||||
for(int i = 1; i < argv.size(); i++)
|
||||
{
|
||||
if(argv[i] == "--help" || argv[i] == "-h")
|
||||
{
|
||||
for (int i = 1; i < argv.size(); i++) {
|
||||
if (argv[i] == "--help" || argv[i] == "-h") {
|
||||
Help(argv[0]);
|
||||
}
|
||||
else if(argv[i] == "-i")
|
||||
{
|
||||
} else if (argv[i] == "-i") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
info = argv[i];
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-I")
|
||||
{
|
||||
} else if (argv[i] == "-I") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
icon = argv[i];
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-n")
|
||||
{
|
||||
} else if (argv[i] == "-n") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
name = argv[i];
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-v")
|
||||
{
|
||||
} else if (argv[i] == "-v") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
|
||||
if(!TVMVersion::TryParse(argv[i],version))
|
||||
{
|
||||
if (!TVMVersion::TryParse(argv[i], version)) {
|
||||
printf("ERROR: Invalid syntax for version\n");
|
||||
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
|
||||
printf("Expected "
|
||||
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
|
||||
"]]]\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
args.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(args.size() < 2) Help(argv[0]);
|
||||
if (args.size() < 2)
|
||||
Help(argv[0]);
|
||||
|
||||
|
||||
auto path = Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(args[0]);
|
||||
auto path =
|
||||
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(args[0]);
|
||||
Tesses::Framework::Filesystem::LocalFS->CreateDirectory(path);
|
||||
auto sdfs = std::make_shared<SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,path);
|
||||
auto sdfs = std::make_shared<SubdirFilesystem>(
|
||||
Tesses::Framework::Filesystem::LocalFS, path);
|
||||
|
||||
FILE *f = fopen(args[1].c_str(), "wb");
|
||||
if(f == NULL)
|
||||
{
|
||||
if (f == NULL) {
|
||||
printf("ERROR: could not open %s\n", args[1].c_str());
|
||||
return 1;
|
||||
}
|
||||
@@ -92,4 +81,4 @@ int64_t CrossArchiveCreate(std::vector<std::string>& argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang::Programs
|
||||
@@ -5,24 +5,22 @@ namespace Tesses::CrossLang::Programs {
|
||||
using namespace Tesses::Framework::Filesystem;
|
||||
using namespace Tesses::Framework::Streams;
|
||||
|
||||
int64_t CrossArchiveExtract(std::vector<std::string>& argv)
|
||||
{
|
||||
int64_t CrossArchiveExtract(std::vector<std::string> &argv) {
|
||||
Tesses::Framework::TF_Init();
|
||||
if(argv.size() < 3)
|
||||
{
|
||||
std::cout << "USAGE: " << argv[0] << " <archive.crvm> <dirasroot>" << std::endl;
|
||||
if (argv.size() < 3) {
|
||||
std::cout << "USAGE: " << argv[0] << " <archive.crvm> <dirasroot>"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto sdfs= std::make_shared<SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,std::string(argv[2]));
|
||||
auto sdfs = std::make_shared<SubdirFilesystem>(
|
||||
Tesses::Framework::Filesystem::LocalFS, std::string(argv[2]));
|
||||
auto strm = LocalFS->OpenFile(argv[1], "rb");
|
||||
if(strm->CanRead())
|
||||
{
|
||||
if (!strm->CanRead()) {
|
||||
std::cout << "ERROR: could not open " << argv[1] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
auto res = Tesses::CrossLang::CrossArchiveExtract(strm, sdfs);
|
||||
|
||||
std::cout << "Crvm Name: " << res.first.first << std::endl;
|
||||
@@ -31,4 +29,4 @@ int64_t CrossArchiveExtract(std::vector<std::string>& argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang::Programs
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
namespace Tesses::CrossLang::Programs {
|
||||
static void Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,uint8_t* buffer, size_t len)
|
||||
{
|
||||
if(strm->ReadBlock(buffer,len) != len)
|
||||
{
|
||||
throw VMException("Could not read " + std::to_string(len) + " byte(s).");
|
||||
static void Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
|
||||
uint8_t *buffer, size_t len) {
|
||||
if (strm->ReadBlock(buffer, len) != len) {
|
||||
throw VMException("Could not read " + std::to_string(len) +
|
||||
" byte(s).");
|
||||
}
|
||||
}
|
||||
static uint32_t EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
{
|
||||
static uint32_t
|
||||
EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
|
||||
uint8_t buff[4];
|
||||
Ensure(strm, buff, sizeof(buff));
|
||||
return BitConverter::ToUint32BE(buff[0]);
|
||||
}
|
||||
static std::string EnsureString(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
{
|
||||
static std::string
|
||||
EnsureString(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
|
||||
size_t len = (size_t)EnsureInt(strm);
|
||||
std::string myStr = {};
|
||||
myStr.resize(len);
|
||||
Ensure(strm, (uint8_t *)myStr.data(), len);
|
||||
return myStr;
|
||||
}
|
||||
void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
{
|
||||
void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
|
||||
uint8_t main_header[18];
|
||||
Ensure(strm, main_header, sizeof(main_header));
|
||||
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image.");
|
||||
if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
|
||||
throw VMException("Invalid TCrossVM image.");
|
||||
TVMVersion version(main_header + 8);
|
||||
if(version.CompareToRuntime() == 1)
|
||||
{
|
||||
if (version.CompareToRuntime() == 1) {
|
||||
throw VMException("Runtime is too old.");
|
||||
}
|
||||
TVMVersion v2(main_header + 13);
|
||||
@@ -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::vector<std::vector<std::string>> closures;
|
||||
|
||||
|
||||
|
||||
char table_name[4];
|
||||
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));
|
||||
size_t tableLen = (size_t)EnsureInt(strm);
|
||||
std::string tableName(table_name, 4);
|
||||
if(tableName == "ICON")
|
||||
{
|
||||
if (tableName == "ICON") {
|
||||
hasIcon = true;
|
||||
}
|
||||
else if(tableName == "STRS")
|
||||
{
|
||||
} else if (tableName == "STRS") {
|
||||
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));
|
||||
}
|
||||
}
|
||||
else if(tableName == "DEPS")
|
||||
{
|
||||
} else if (tableName == "DEPS") {
|
||||
|
||||
std::string name = strs.at((size_t)EnsureInt(strm));
|
||||
|
||||
uint8_t version_bytes[5];
|
||||
Ensure(strm, version_bytes, sizeof(version_bytes));
|
||||
TVMVersion depVersion(version_bytes);
|
||||
std::cout << "Dependency: " << name << "-" << depVersion.ToString() << std::endl;
|
||||
}
|
||||
else if(tableName == "NAME")
|
||||
{
|
||||
std::cout << "Name: " << strs.at((size_t)EnsureInt(strm)) << std::endl;
|
||||
}
|
||||
else if(tableName == "CLSS")
|
||||
{
|
||||
std::cout << "Dependency: " << name << "-" << depVersion.ToString()
|
||||
<< std::endl;
|
||||
} else if (tableName == "NAME") {
|
||||
std::cout << "Name: " << strs.at((size_t)EnsureInt(strm))
|
||||
<< std::endl;
|
||||
} else if (tableName == "CLSS") {
|
||||
std::cout << "Classes:\n";
|
||||
uint32_t clss_cnt = EnsureInt(strm);
|
||||
for(uint32_t j = 0; j < clss_cnt; j++)
|
||||
{
|
||||
std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl;
|
||||
for (uint32_t j = 0; j < clss_cnt; j++) {
|
||||
std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/"
|
||||
<< std::endl;
|
||||
uint32_t fnPartsC = EnsureInt(strm);
|
||||
std::cout << "\tName: ";
|
||||
for(uint32_t k = 0; k < fnPartsC; k++)
|
||||
{
|
||||
if(k > 0) std::cout << ".";
|
||||
for (uint32_t k = 0; k < fnPartsC; k++) {
|
||||
if (k > 0)
|
||||
std::cout << ".";
|
||||
std::cout << strs.at(EnsureInt(strm));
|
||||
}
|
||||
std::cout << std::endl;
|
||||
fnPartsC = EnsureInt(strm);
|
||||
std::cout << "\tInherits: ";
|
||||
for(uint32_t k = 0; k < fnPartsC; k++)
|
||||
{
|
||||
if(k > 0) std::cout << ".";
|
||||
for (uint32_t k = 0; k < fnPartsC; k++) {
|
||||
if (k > 0)
|
||||
std::cout << ".";
|
||||
std::cout << strs.at(EnsureInt(strm));
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
uint32_t ents = EnsureInt(strm);
|
||||
|
||||
for(uint8_t k = 0; k < ents; k++)
|
||||
{
|
||||
for (uint32_t k = 0; k < ents; k++) {
|
||||
Ensure(strm, main_header, 1);
|
||||
uint8_t flags = main_header[0];
|
||||
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl;
|
||||
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/"
|
||||
<< std::endl;
|
||||
std::string fnname = strs.at(EnsureInt(strm));
|
||||
std::string fnargs;
|
||||
uint32_t argParts = EnsureInt(strm);
|
||||
|
||||
for(uint32_t l = 0; l < argParts; l++)
|
||||
{
|
||||
if(l > 0) fnargs += ", ";
|
||||
for (uint32_t l = 0; l < argParts; l++) {
|
||||
if (l > 0)
|
||||
fnargs += ", ";
|
||||
fnargs += strs.at(EnsureInt(strm));
|
||||
}
|
||||
uint32_t fnchunk = EnsureInt(strm);
|
||||
switch(flags & 3)
|
||||
{
|
||||
switch (flags & 3) {
|
||||
case 0:
|
||||
std::cout << "\t\tprivate ";
|
||||
break;
|
||||
@@ -137,17 +124,19 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
break;
|
||||
}
|
||||
|
||||
switch((flags >> 2) & 3)
|
||||
{
|
||||
switch ((flags >> 2) & 3) {
|
||||
case 0:
|
||||
std::cout << "func " << fnname << "(" << fnargs << "), chunk = " << fnchunk << std::endl;
|
||||
std::cout << "func " << fnname << "(" << fnargs
|
||||
<< "), chunk = " << fnchunk << std::endl;
|
||||
|
||||
break;
|
||||
case 1:
|
||||
std::cout << "field " << fnname << ", chunk = " << fnchunk << std::endl;
|
||||
std::cout << "field " << fnname
|
||||
<< ", chunk = " << fnchunk << std::endl;
|
||||
break;
|
||||
case 2:
|
||||
std::cout << "abstract " << fnname << "(" << fnargs << ")" << std::endl;
|
||||
std::cout << "abstract " << fnname << "(" << fnargs
|
||||
<< ")" << std::endl;
|
||||
break;
|
||||
case 3:
|
||||
std::cout << "unset_field " << fnname << std::endl;
|
||||
@@ -156,53 +145,43 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(tableName == "CHKS")
|
||||
{
|
||||
} else if (tableName == "CHKS") {
|
||||
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;
|
||||
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)));
|
||||
}
|
||||
auto len = EnsureInt(strm);
|
||||
|
||||
strm->Seek(len,Tesses::Framework::Streams::SeekOrigin::Current);
|
||||
strm->Seek(len,
|
||||
Tesses::Framework::Streams::SeekOrigin::Current);
|
||||
|
||||
closures.push_back(args);
|
||||
}
|
||||
}
|
||||
else if(tableName == "FUNS")
|
||||
{
|
||||
} else if (tableName == "FUNS") {
|
||||
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;
|
||||
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)));
|
||||
}
|
||||
|
||||
uint32_t fnNumber = EnsureInt(strm);
|
||||
funs[fnNumber] = fnParts;
|
||||
|
||||
}
|
||||
}
|
||||
else if(tableName == "INFO")
|
||||
{
|
||||
} else if (tableName == "INFO") {
|
||||
|
||||
std::cout << "Info: " << strs.at((size_t)EnsureInt(strm)) << std::endl;
|
||||
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)
|
||||
@@ -210,33 +189,30 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
else
|
||||
std::cout << "Has Icon: no" << std::endl;
|
||||
|
||||
for(size_t i = 1; i < closures.size(); i++)
|
||||
{
|
||||
if(funs.count((uint32_t)i) > 0)
|
||||
{
|
||||
for (size_t i = 1; i < closures.size(); i++) {
|
||||
if (funs.count((uint32_t)i) > 0) {
|
||||
std::cout << "Func: ";
|
||||
auto res = funs[(uint32_t)i];
|
||||
if (!res.empty()) {
|
||||
std::cout << "/^" << res[0] << "^/ ";
|
||||
}
|
||||
for(size_t i = 1; i < res.size(); i++)
|
||||
{
|
||||
if(i > 1) std::cout << ".";
|
||||
for (size_t i = 1; i < res.size(); i++) {
|
||||
if (i > 1)
|
||||
std::cout << ".";
|
||||
std::cout << res[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cout << "Closure: ";
|
||||
}
|
||||
std::cout << "(";
|
||||
bool first = true;
|
||||
for(auto arg : closures[i])
|
||||
{
|
||||
if(!first) std::cout << ", ";
|
||||
for (auto arg : closures[i]) {
|
||||
if (!first)
|
||||
std::cout << ", ";
|
||||
std::cout << arg;
|
||||
|
||||
if(first) first=false;
|
||||
if (first)
|
||||
first = false;
|
||||
}
|
||||
std::cout << ")" << std::endl;
|
||||
}
|
||||
@@ -246,10 +222,6 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
for (auto str : strs) {
|
||||
std::cout << EscapeString(str, true) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Tesses::CrossLang::Programs
|
||||
@@ -6,143 +6,141 @@
|
||||
using namespace Tesses::Framework;
|
||||
using namespace Tesses::Framework::Http;
|
||||
|
||||
namespace Tesses::CrossLang::Programs
|
||||
{
|
||||
namespace Tesses::CrossLang::Programs {
|
||||
|
||||
static bool Download(Tesses::Framework::Filesystem::VFSPath filename,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs)
|
||||
{
|
||||
auto inContainer=Platform::Environment::GetVariable("CROSSLANG_CONTAINER");
|
||||
if(inContainer && (*inContainer=="1" || *inContainer=="y" || *inContainer=="Y"))
|
||||
{
|
||||
static bool Download(Tesses::Framework::Filesystem::VFSPath filename,
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs) {
|
||||
auto inContainer =
|
||||
Platform::Environment::GetVariable("CROSSLANG_CONTAINER");
|
||||
if (inContainer &&
|
||||
(*inContainer == "1" || *inContainer == "y" || *inContainer == "Y")) {
|
||||
HttpRequest req;
|
||||
req.followRedirects = true;
|
||||
req.url = "https://redirect.tesses.net/crosslang-shell";
|
||||
req.method = "GET";
|
||||
HttpResponse resp(req);
|
||||
if(resp.statusCode == StatusCode::OK)
|
||||
{
|
||||
if (resp.statusCode == StatusCode::OK) {
|
||||
auto strm = resp.ReadAsStream();
|
||||
CrossLang::CrossArchiveExtract(strm, vfs);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
|
||||
} else {
|
||||
std::cout << "Error when fetching the script error: "
|
||||
<< std::to_string(resp.statusCode) << " "
|
||||
<< HttpUtils::StatusCodeString(resp.statusCode)
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
std::cout << "File " << filename.ToString() << " not found, do you want to download the installer from: https://redirect.tesses.net/crosslang-shell (this may install other stuff as well) (Y/n)? ";
|
||||
while (true) {
|
||||
std::cout << "File " << filename.ToString()
|
||||
<< " not found, do you want to download the installer from: "
|
||||
"https://redirect.tesses.net/crosslang-shell (this may "
|
||||
"install other stuff as well) (Y/n)? ";
|
||||
std::string line;
|
||||
std::getline(std::cin, line);
|
||||
if(line == "Y" || line == "y")
|
||||
{
|
||||
if (line == "Y" || line == "y") {
|
||||
HttpRequest req;
|
||||
req.followRedirects = true;
|
||||
req.url = "https://redirect.tesses.net/crosslang-shell";
|
||||
req.method = "GET";
|
||||
HttpResponse resp(req);
|
||||
if(resp.statusCode == StatusCode::OK)
|
||||
{
|
||||
if (resp.statusCode == StatusCode::OK) {
|
||||
auto strm = resp.ReadAsStream();
|
||||
CrossLang::CrossArchiveExtract(strm, vfs);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
|
||||
} else {
|
||||
std::cout << "Error when fetching the script error: "
|
||||
<< std::to_string(resp.statusCode) << " "
|
||||
<< HttpUtils::StatusCodeString(resp.statusCode)
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(line == "N" || line == "n")
|
||||
{
|
||||
std::cout << "Looks like you will need to install manually" << std::endl;
|
||||
} else if (line == "N" || line == "n") {
|
||||
std::cout << "Looks like you will need to install manually"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cout << "Please use Y or N (case insensitive)" << std::endl;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TObject CrossLangShell(GCList& ls, std::vector<std::string>& argv)
|
||||
{
|
||||
TObject CrossLangShell(GCList &ls, std::vector<std::string> &argv) {
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPath dir = GetCrossLangConfigDir();
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPath filename = dir / "Shell" / "Shell.crvm";
|
||||
Tesses::Framework::Filesystem::VFSPath filename =
|
||||
dir / "Shell" / "Shell.crvm";
|
||||
|
||||
|
||||
auto p = Tesses::Framework::Platform::Environment::GetRealExecutablePath(Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[0])).GetParent().GetParent() / "share" / "Tesses" / "CrossLang" / "Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm";
|
||||
if(argv.size() == 2 && argv[1] == "configdir")
|
||||
{
|
||||
auto p =
|
||||
Tesses::Framework::Platform::Environment::GetRealExecutablePath(
|
||||
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[0]))
|
||||
.GetParent()
|
||||
.GetParent() /
|
||||
"share" / "Tesses" / "CrossLang" /
|
||||
"Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm";
|
||||
if (argv.size() == 2 && argv[1] == "configdir") {
|
||||
std::cout << dir.ToString() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
if(argv.size() > 1 && argv[1] == "update-shell")
|
||||
{
|
||||
if (argv.size() > 1 && argv[1] == "update-shell") {
|
||||
|
||||
auto subdir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,dir);
|
||||
auto subdir =
|
||||
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
|
||||
Tesses::Framework::Filesystem::LocalFS, dir);
|
||||
HttpRequest req;
|
||||
req.followRedirects = true;
|
||||
req.url = "https://redirect.tesses.net/crosslang-shell";
|
||||
req.method = "GET";
|
||||
HttpResponse resp(req);
|
||||
if(resp.statusCode == StatusCode::OK)
|
||||
{
|
||||
if (resp.statusCode == StatusCode::OK) {
|
||||
auto strm = resp.ReadAsStream();
|
||||
CrossLang::CrossArchiveExtract(strm, subdir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
|
||||
} else {
|
||||
std::cout << "Error when fetching the script error: "
|
||||
<< std::to_string(resp.statusCode) << " "
|
||||
<< HttpUtils::StatusCodeString(resp.statusCode)
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename))
|
||||
{
|
||||
auto subdir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,dir);
|
||||
if(Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p))
|
||||
{
|
||||
std::cout << "Installing " << p.ToString() << " -> " << dir.ToString() << std::endl;
|
||||
auto strm = Tesses::Framework::Filesystem::LocalFS->OpenFile(p,"rb");
|
||||
if(strm != nullptr)
|
||||
{
|
||||
if (!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename)) {
|
||||
auto subdir =
|
||||
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
|
||||
Tesses::Framework::Filesystem::LocalFS, dir);
|
||||
if (Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p)) {
|
||||
std::cout << "Installing " << p.ToString() << " -> "
|
||||
<< dir.ToString() << std::endl;
|
||||
auto strm =
|
||||
Tesses::Framework::Filesystem::LocalFS->OpenFile(p, "rb");
|
||||
if (strm != nullptr) {
|
||||
CrossLang::CrossArchiveExtract(strm, subdir);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!Download(filename,subdir)) return 1;
|
||||
} else {
|
||||
if (!Download(filename, subdir))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
|
||||
TRootEnvironment *env =
|
||||
TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
|
||||
TStd::RegisterStd(ls.GetGC(), env);
|
||||
|
||||
|
||||
env->LoadFileWithDependencies(ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
|
||||
|
||||
env->LoadFileWithDependencies(
|
||||
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
|
||||
|
||||
TList *args = TList::Create(ls);
|
||||
|
||||
@@ -152,7 +150,6 @@ TObject CrossLangShell(GCList& ls, std::vector<std::string>& argv)
|
||||
args->Add(std::string(argv[arg]));
|
||||
|
||||
return env->CallFunctionWithFatalError(ls, "main", {args});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Tesses::CrossLang::Programs
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
using namespace Tesses::Framework;
|
||||
using namespace Tesses::Framework::Filesystem;
|
||||
namespace Tesses::CrossLang::Programs {
|
||||
static void Help(std::string filename)
|
||||
{
|
||||
std::cout << "USAGE: " << filename << " [OPTIONS] source_file1 source_file2 source_file_n" << std::endl;
|
||||
static void Help(std::string filename) {
|
||||
std::cout << "USAGE: " << filename
|
||||
<< " [OPTIONS] source_file1 source_file2 source_file_n"
|
||||
<< std::endl;
|
||||
printf("OPTIONS:\n");
|
||||
printf(" -o: Output directory (OUTDIR, defaults to ./bin)\n");
|
||||
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": \"https://example.com/\", \"homepage\": \"https://example.com/\",\"license\":\"MIT\"})\n");
|
||||
printf(" -I: Set icon resource name (in the resource folder), should be a 128x128 png\n");
|
||||
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": "
|
||||
"\"https://example.com/\", \"homepage\": "
|
||||
"\"https://example.com/\",\"license\":\"MIT\"})\n");
|
||||
printf(" -I: Set icon resource name (in the resource folder), should be "
|
||||
"a 128x128 png\n");
|
||||
printf(" -v: Set version (1.0.0.0-prod defaults to 1.0.0.0-dev)\n");
|
||||
printf(" -d: Add dependency (DependencyName-1.0.0.0-prod)\n");
|
||||
printf(" -D: enable debug)\n");
|
||||
@@ -18,12 +22,14 @@ static void Help(std::string filename)
|
||||
printf(" -n: Set name (MyAppOrLibName defaults to out)\n");
|
||||
printf(" -r: Set resource directory (RESDIR defaults to res)\n");
|
||||
printf(" -h, --help: Prints help\n");
|
||||
printf(" -e: Set comptime permissions defaults to none, none for no support, \"secure\" for sane without file access, \"secure_file\" for sane with file access to current directory and sub directories, \"full\" has full runtime.\n");
|
||||
printf(" -e: Set comptime permissions defaults to none, none for no "
|
||||
"support, \"secure\" for sane without file access, \"secure_file\" "
|
||||
"for sane with file access to current directory and sub "
|
||||
"directories, \"full\" has full runtime.\n");
|
||||
printf("Options except for help have flag with arg like this: -F ARG\n");
|
||||
exit(1);
|
||||
}
|
||||
void CrossLangCompiler(std::vector<std::string>& argv)
|
||||
{
|
||||
void CrossLangCompiler(std::vector<std::string> &argv) {
|
||||
/*std::ifstream strm(argv[1],std::ios_base::in|std::ios_base::binary);
|
||||
std::vector<LexToken> tokens;
|
||||
Lex(argv[1],strm,tokens);
|
||||
@@ -49,181 +55,142 @@ void CrossLangCompiler(std::vector<std::string>& argv)
|
||||
TVMVersion version;
|
||||
bool debug = false;
|
||||
|
||||
|
||||
|
||||
for(size_t i = 1; i < argv.size(); i++)
|
||||
{
|
||||
if(argv[i] == "--help" || argv[i] == "-h")
|
||||
{
|
||||
for (size_t i = 1; i < argv.size(); i++) {
|
||||
if (argv[i] == "--help" || argv[i] == "-h") {
|
||||
Help(argv[0]);
|
||||
}
|
||||
|
||||
else if(argv[i] == "-o")
|
||||
{
|
||||
else if (argv[i] == "-o") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
outputDir = argv[i];
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-r")
|
||||
{
|
||||
} else if (argv[i] == "-r") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
resourceDir = argv[i];
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-e")
|
||||
{
|
||||
} else if (argv[i] == "-e") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
comptime = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
else if(argv[i] == "-i")
|
||||
{
|
||||
else if (argv[i] == "-i") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
info = argv[i];
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-I")
|
||||
{
|
||||
} else if (argv[i] == "-I") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
icon = argv[i];
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-d")
|
||||
{
|
||||
} else if (argv[i] == "-d") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
std::string str = argv[i];
|
||||
auto lastDash = str.find_last_of('-');
|
||||
if(lastDash < str.size())
|
||||
{
|
||||
if (lastDash < str.size()) {
|
||||
std::string str2 = str.substr(lastDash + 1);
|
||||
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod")
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (!TVMVersion::TryParse(str2, v2)) {
|
||||
printf("ERROR: Invalid syntax for version\n");
|
||||
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
|
||||
printf("Expected "
|
||||
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-"
|
||||
"prod]]]]\n");
|
||||
exit(1);
|
||||
}
|
||||
dependencies.push_back(std::pair<std::string,TVMVersion>(str1,v2));
|
||||
dependencies.push_back(
|
||||
std::pair<std::string, TVMVersion>(str1, v2));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
printf("ERROR: Dependency must have version\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-t")
|
||||
{
|
||||
} else if (argv[i] == "-t") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
std::string str = argv[i];
|
||||
auto lastDash = str.find_last_of('-');
|
||||
if(lastDash < str.size())
|
||||
{
|
||||
if (lastDash < str.size()) {
|
||||
std::string str2 = str.substr(lastDash + 1);
|
||||
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod")
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (!TVMVersion::TryParse(str2, v2)) {
|
||||
printf("ERROR: Invalid syntax for version\n");
|
||||
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
|
||||
printf("Expected "
|
||||
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-"
|
||||
"prod]]]]\n");
|
||||
exit(1);
|
||||
}
|
||||
tools.push_back(std::pair<std::string,TVMVersion>(str1,v2));
|
||||
tools.push_back(
|
||||
std::pair<std::string, TVMVersion>(str1, v2));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
printf("ERROR: Tool must have version\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-n")
|
||||
{
|
||||
} else if (argv[i] == "-n") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
name = argv[i];
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-v")
|
||||
{
|
||||
} else if (argv[i] == "-v") {
|
||||
i++;
|
||||
if(i < argv.size())
|
||||
{
|
||||
if (i < argv.size()) {
|
||||
|
||||
if(!TVMVersion::TryParse(argv[i],version))
|
||||
{
|
||||
if (!TVMVersion::TryParse(argv[i], version)) {
|
||||
printf("ERROR: Invalid syntax for version\n");
|
||||
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
|
||||
printf("Expected "
|
||||
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
|
||||
"]]]\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(argv[i] == "-D" || argv[i] == "--debug")
|
||||
{
|
||||
} else if (argv[i] == "-D" || argv[i] == "--debug") {
|
||||
debug = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
source.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
if(source.empty())
|
||||
{
|
||||
if (source.empty()) {
|
||||
Help(argv[0]);
|
||||
}
|
||||
|
||||
|
||||
std::vector<LexToken> tokens;
|
||||
|
||||
for(auto src : source)
|
||||
{
|
||||
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")
|
||||
{
|
||||
if (comptime != "none") {
|
||||
std::shared_ptr<GC> gc = std::make_shared<GC>();
|
||||
gc->Start();
|
||||
ls = std::make_shared<GCList>(gc);
|
||||
env = TRootEnvironment::Create(*ls, TDictionary::Create(*ls));
|
||||
|
||||
if(comptime == "secure")
|
||||
{
|
||||
if (comptime == "secure") {
|
||||
TStd::RegisterConsole(gc, env);
|
||||
TStd::RegisterClass(gc, env);
|
||||
TStd::RegisterCrypto(gc, env);
|
||||
@@ -232,9 +199,7 @@ void CrossLangCompiler(std::vector<std::string>& argv)
|
||||
TStd::RegisterRoot(gc, env);
|
||||
TStd::RegisterIO(gc, env, false);
|
||||
env->permissions.locked = true;
|
||||
}
|
||||
else if(comptime == "secure_file")
|
||||
{
|
||||
} else if (comptime == "secure_file") {
|
||||
TStd::RegisterConsole(gc, env);
|
||||
TStd::RegisterClass(gc, env);
|
||||
TStd::RegisterCrypto(gc, env);
|
||||
@@ -244,10 +209,11 @@ void CrossLangCompiler(std::vector<std::string>& argv)
|
||||
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")
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -257,7 +223,8 @@ void CrossLangCompiler(std::vector<std::string>& argv)
|
||||
parser.debug = debug;
|
||||
CodeGen gen;
|
||||
|
||||
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,LocalFS->SystemToVFSPath(resourceDir.string()));
|
||||
auto sfs = std::make_shared<SubdirFilesystem>(
|
||||
LocalFS, LocalFS->SystemToVFSPath(resourceDir.string()));
|
||||
gen.embedFS = sfs;
|
||||
|
||||
gen.GenRoot(parser.ParseRoot());
|
||||
@@ -265,21 +232,20 @@ void CrossLangCompiler(std::vector<std::string>& argv)
|
||||
gen.version = version;
|
||||
gen.info = info;
|
||||
gen.icon = icon;
|
||||
for(auto deps : dependencies)
|
||||
{
|
||||
for (auto deps : dependencies) {
|
||||
gen.dependencies.push_back(deps);
|
||||
}
|
||||
for(auto tool : tools)
|
||||
{
|
||||
for (auto tool : tools) {
|
||||
gen.tools.push_back(tool);
|
||||
}
|
||||
|
||||
std::filesystem::create_directory(outputDir);
|
||||
|
||||
{
|
||||
auto strm = std::make_shared<Tesses::Framework::Streams::FileStream>(outputDir / (name + "-" + version.ToString() + ".crvm"),"wb");
|
||||
auto strm = std::make_shared<Tesses::Framework::Streams::FileStream>(
|
||||
outputDir / (name + "-" + version.ToString() + ".crvm"), "wb");
|
||||
|
||||
gen.Save(strm);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang::Programs
|
||||
@@ -1,17 +1,16 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
using namespace Tesses::Framework;
|
||||
using namespace Tesses::Framework::Filesystem;
|
||||
|
||||
namespace Tesses::CrossLang::Programs {
|
||||
TObject CrossLangInterperter(GCList& ls,TRootEnvironment* env,std::vector<std::string>& argv)
|
||||
{
|
||||
TObject CrossLangInterperter(GCList &ls, TRootEnvironment *env,
|
||||
std::vector<std::string> &argv) {
|
||||
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::vector<LexToken> tokens;
|
||||
Lex(argv[1], strm, tokens);
|
||||
@@ -25,10 +24,11 @@ TObject CrossLangInterperter(GCList& ls,TRootEnvironment* env,std::vector<std::s
|
||||
gen.GenRoot(parser.ParseRoot());
|
||||
std::vector<uint8_t> data;
|
||||
{
|
||||
auto strm2 = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
||||
auto strm2 =
|
||||
std::make_shared<Tesses::Framework::Streams::MemoryStream>(
|
||||
true);
|
||||
gen.Save(strm2);
|
||||
|
||||
|
||||
{
|
||||
TFile *file = TFile::Create(ls);
|
||||
|
||||
@@ -36,8 +36,6 @@ TObject CrossLangInterperter(GCList& ls,TRootEnvironment* env,std::vector<std::s
|
||||
file->Load(gc, strm2);
|
||||
|
||||
env->LoadFile(gc, file);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,25 +45,22 @@ TObject CrossLangInterperter(GCList& ls,TRootEnvironment* env,std::vector<std::s
|
||||
|
||||
return env->CallFunctionWithFatalError(ls, "main", {args});
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
std::cout << "> ";
|
||||
std::string source;
|
||||
std::getline(std::cin, source);
|
||||
|
||||
auto strm2 = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
||||
auto strm2 =
|
||||
std::make_shared<Tesses::Framework::Streams::MemoryStream>(
|
||||
true);
|
||||
|
||||
if(source.find("loadfile ") == 0)
|
||||
{
|
||||
if (source.find("loadfile ") == 0) {
|
||||
std::string filename = source.substr(9);
|
||||
|
||||
std::ifstream strm(filename,std::ios_base::in|std::ios_base::binary);
|
||||
std::ifstream strm(filename,
|
||||
std::ios_base::in | std::ios_base::binary);
|
||||
std::vector<LexToken> tokens;
|
||||
Lex(filename, strm, tokens);
|
||||
|
||||
@@ -73,28 +68,27 @@ TObject CrossLangInterperter(GCList& ls,TRootEnvironment* env,std::vector<std::s
|
||||
|
||||
CodeGen gen;
|
||||
|
||||
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
|
||||
auto sfs =
|
||||
std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
|
||||
gen.embedFS = sfs;
|
||||
gen.GenRoot(parser.ParseRoot());
|
||||
|
||||
gen.Save(strm2);
|
||||
|
||||
}
|
||||
else if(source == "exit")
|
||||
{
|
||||
} else if (source == "exit") {
|
||||
return (int64_t)0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::vector<LexToken> tokens;
|
||||
std::stringstream strm(source,std::ios_base::in | std::ios_base::binary);
|
||||
std::stringstream strm(source, std::ios_base::in |
|
||||
std::ios_base::binary);
|
||||
Lex("lexed.tcross", strm, tokens);
|
||||
|
||||
Parser parser(tokens);
|
||||
|
||||
CodeGen gen;
|
||||
|
||||
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
|
||||
auto sfs =
|
||||
std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
|
||||
gen.embedFS = sfs;
|
||||
|
||||
gen.GenRoot(parser.ParseRoot());
|
||||
@@ -110,15 +104,11 @@ TObject CrossLangInterperter(GCList& ls,TRootEnvironment* env,std::vector<std::s
|
||||
file->Load(gc, strm2);
|
||||
|
||||
env->LoadFile(gc, file);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return (int64_t)0;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Tesses::CrossLang::Programs
|
||||
@@ -1,61 +1,58 @@
|
||||
#include "CrossLang.hpp"
|
||||
using namespace Tesses::Framework;
|
||||
namespace Tesses::CrossLang::Programs {
|
||||
TObject CrossLangVM(GCList& ls,TRootEnvironment* env, std::vector<std::string>& argv)
|
||||
{
|
||||
if(argv.size() < 2)
|
||||
{
|
||||
std::cout << "USAGE: " << (argv.empty() ? (std::string)"crossvm" : argv[0]) << " <filename.crvm> <args...>" << std::endl;
|
||||
TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
|
||||
std::vector<std::string> &argv) {
|
||||
if (argv.size() < 2) {
|
||||
std::cout << "USAGE: "
|
||||
<< (argv.empty() ? (std::string) "crossvm" : argv[0])
|
||||
<< " <filename.crvm> <args...>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
env->LoadFileWithDependencies(ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1]));
|
||||
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);
|
||||
int port = 4206;
|
||||
for(auto& item : args.options)
|
||||
{
|
||||
if(item.first == "port")
|
||||
{
|
||||
for (auto &item : args.options) {
|
||||
if (item.first == "port") {
|
||||
port = std::stoi(item.second);
|
||||
}
|
||||
}
|
||||
|
||||
env->EnsureDictionary(ls.GetGC(),"Net")->SetValue("WebServerPort", (int64_t)port);
|
||||
env->EnsureDictionary(ls.GetGC(), "Net")
|
||||
->SetValue("WebServerPort", (int64_t)port);
|
||||
TList *args2 = TList::Create(ls);
|
||||
for(auto& item : args.positional)
|
||||
{
|
||||
for (auto &item : args.positional) {
|
||||
args2->Add(item);
|
||||
}
|
||||
|
||||
auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2});
|
||||
auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(), res);
|
||||
if(svr2 == nullptr) return 1;
|
||||
if (svr2 == nullptr)
|
||||
return 1;
|
||||
Tesses::Framework::Http::HttpServer svr(port, svr2);
|
||||
svr.StartAccepting();
|
||||
TF_RunEventLoop();
|
||||
TDictionary *_dict;
|
||||
TClassObject *_co;
|
||||
if(GetObjectHeap(res,_dict))
|
||||
{
|
||||
if (GetObjectHeap(res, _dict)) {
|
||||
_dict->CallMethod(ls, "Close", {});
|
||||
}
|
||||
if(GetObjectHeap(res,_co))
|
||||
{
|
||||
if (GetObjectHeap(res, _co)) {
|
||||
_co->CallMethod(ls, "", "Close", {});
|
||||
}
|
||||
TF_Quit();
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
TList *args = TList::Create(ls);
|
||||
for (size_t arg = 1; arg < argv.size(); arg++)
|
||||
args->Add(std::string(argv[arg]));
|
||||
|
||||
return env->CallFunctionWithFatalError(ls, "main", {args});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang::Programs
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -4,102 +4,89 @@ using namespace Tesses::Framework;
|
||||
using namespace Tesses::CrossLang;
|
||||
using namespace Tesses::Framework::Filesystem;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
//crosslang crossint
|
||||
//crosslang
|
||||
//crosslang ...
|
||||
|
||||
std::string programName = "crosslang";
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
TF_InitWithConsole();
|
||||
if(argc > 0)
|
||||
{
|
||||
TF_AllowPortable(argv[0]);
|
||||
Tesses::Framework::Filesystem::VFSPath path=(std::string)argv[0];
|
||||
path.RemoveExtension();
|
||||
programName = path.GetFileName();
|
||||
}
|
||||
TF_AllowPortable();
|
||||
|
||||
std::vector<std::string> args(argc);
|
||||
|
||||
for (int i = 0; i < argc; i++)
|
||||
args[i] = argv[i];
|
||||
if(programName == "crossint")
|
||||
{
|
||||
|
||||
auto execName = TF_GetExecutableName();
|
||||
|
||||
if (!execName.empty()) {
|
||||
Tesses::Framework::Filesystem::VFSPath execPath = execName;
|
||||
if (execPath.HasExtension()) {
|
||||
execPath.RemoveExtension();
|
||||
}
|
||||
|
||||
if (Tesses::Framework::Filesystem::LocalFS->FileExists(execPath +
|
||||
".crvm")) {
|
||||
|
||||
if (args.empty())
|
||||
args.push_back(execPath.GetFileName());
|
||||
|
||||
auto crvmFile = execPath + ".crvm";
|
||||
|
||||
args.insert(args.begin() + 1, crvmFile.ToString());
|
||||
int64_t myi64 = 0;
|
||||
|
||||
std::shared_ptr<GC> gc = std::make_shared<GC>();
|
||||
gc->Start();
|
||||
GCList ls(gc);
|
||||
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
TStd::RegisterStd(gc,env);
|
||||
auto res= Programs::CrossLangInterperter(ls, env, args);
|
||||
|
||||
GetObject(res,myi64);
|
||||
|
||||
|
||||
return (int)myi64;
|
||||
}
|
||||
else if(programName == "crossc")
|
||||
{
|
||||
Programs::CrossLangCompiler(args);
|
||||
return 0;
|
||||
}
|
||||
else if(programName == "crossarchivecreate")
|
||||
{
|
||||
Programs::CrossArchiveCreate(args);
|
||||
return 0;
|
||||
}
|
||||
else if(programName == "crossarchiveextract")
|
||||
{
|
||||
Programs::CrossArchiveExtract(args);
|
||||
return 0;
|
||||
}
|
||||
else if(programName == "crossdump")
|
||||
{
|
||||
for(size_t i = 1; i < args.size(); i++)
|
||||
{
|
||||
VFSPath path = args[i];
|
||||
if(LocalFS->FileExists(path))
|
||||
{
|
||||
std::cout << "File: " << path.ToString() << std::endl;
|
||||
auto strm = LocalFS->OpenFile(path, "rb");
|
||||
Programs::CrossLangDump(strm);
|
||||
}
|
||||
else {
|
||||
std::cout << "File: " << path.ToString() << " does not exist." << std::endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if(programName == "crossvm")
|
||||
{
|
||||
std::shared_ptr<GC> gc= std::make_shared<GC>();
|
||||
gc->Start();
|
||||
int64_t myi64=0;
|
||||
|
||||
|
||||
GCList ls(gc);
|
||||
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
TRootEnvironment *env =
|
||||
TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
TStd::RegisterStd(gc, env);
|
||||
auto res = Programs::CrossLangVM(ls, env, args);
|
||||
GetObject(res, myi64);
|
||||
|
||||
return (int)myi64;
|
||||
|
||||
}
|
||||
else if(args.size() > 1)
|
||||
{
|
||||
}
|
||||
|
||||
if(args[1] == "crossint")
|
||||
{
|
||||
if (args.size() > 1) {
|
||||
if (args[1] == "--help") {
|
||||
if (!Tesses::Framework::Filesystem::LocalFS->FileExists(
|
||||
GetCrossLangConfigDir() / "Shell" / "Shell.crvm")) {
|
||||
Console::WriteLine(args[0] + " COMMAND");
|
||||
Console::WriteLine("COMMANDS:");
|
||||
Console::WriteLine(
|
||||
"int: interperter, used to be crossint");
|
||||
Console::WriteLine(
|
||||
"c: the compiler, used to be crossc");
|
||||
Console::WriteLine("archivecreate: create archives, used to "
|
||||
"be crossarchivecreate");
|
||||
Console::WriteLine("archiveextract: extract archives, used to "
|
||||
"be crossarchiveextract");
|
||||
Console::WriteLine("thumbnailer: create thumbnails on "
|
||||
"freedesktop, used to be crossthumbnailer");
|
||||
Console::WriteLine("dump: dump metadata about crvm "
|
||||
"file, used to be crossdump");
|
||||
Console::WriteLine("vm: interpert bytecode file, "
|
||||
"used to be crossvm");
|
||||
Console::WriteLine("update-shell: update the shell");
|
||||
Console::WriteLine(
|
||||
"configdir: print the config directory");
|
||||
|
||||
Console::WriteLine("");
|
||||
Console::WriteLine("NOTE: As you don't have the shell, these "
|
||||
"commands are limited");
|
||||
Console::WriteLine(
|
||||
"NOTE: You can put this binary in a folder with a crvm "
|
||||
"file, as long as filename matches (ignoring extension) it "
|
||||
"will directly launch the crvm file");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (args[1] == "int") {
|
||||
int64_t myi64 = 0;
|
||||
args.erase(args.begin());
|
||||
std::shared_ptr<GC> gc = std::make_shared<GC>();
|
||||
gc->Start();
|
||||
GCList ls(gc);
|
||||
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
TRootEnvironment *env =
|
||||
TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
TStd::RegisterStd(gc, env);
|
||||
auto res = Programs::CrossLangInterperter(ls, env, args);
|
||||
|
||||
@@ -107,56 +94,87 @@ int main(int argc, char** argv)
|
||||
|
||||
return (int)myi64;
|
||||
|
||||
}
|
||||
else if(args[1] == "crossc")
|
||||
{
|
||||
} else if (args[1] == "c") {
|
||||
args.erase(args.begin());
|
||||
Programs::CrossLangCompiler(args);
|
||||
return 0;
|
||||
}
|
||||
else if(args[1] == "crossarchivecreate")
|
||||
{
|
||||
} else if (args[1] == "archivecreate") {
|
||||
args.erase(args.begin());
|
||||
Programs::CrossArchiveCreate(args);
|
||||
return 0;
|
||||
}
|
||||
else if(args[1] == "crossarchiveextract")
|
||||
{
|
||||
} else if (args[1] == "archiveextract") {
|
||||
args.erase(args.begin());
|
||||
Programs::CrossArchiveExtract(args);
|
||||
return 0;
|
||||
} else if (args[1] == "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")
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
std::string crvm = argv[2];
|
||||
std::string png = argv[3];
|
||||
|
||||
if (Tesses::Framework::Filesystem::LocalFS->FileExists(crvm)) {
|
||||
|
||||
Tesses::CrossLang::TFile file;
|
||||
auto f = Tesses::Framework::Filesystem::LocalFS->OpenFile(crvm,
|
||||
"rb");
|
||||
|
||||
file.Load(nullptr, f);
|
||||
|
||||
if (file.icon >= 0 && file.icon < file.resources.size()) {
|
||||
auto f2 = Tesses::Framework::Filesystem::LocalFS->OpenFile(
|
||||
png, "wb");
|
||||
if (f2 != nullptr) {
|
||||
auto &icon = file.resources[file.icon];
|
||||
f2->WriteBlock(icon.data(), icon.size());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if(args[1] == "crossvm")
|
||||
{
|
||||
}
|
||||
if (Tesses::Framework::Filesystem::LocalFS->FileExists(
|
||||
emptyThumb)) {
|
||||
auto src = Tesses::Framework::Filesystem::LocalFS->OpenFile(
|
||||
emptyThumb, "rb");
|
||||
auto dest =
|
||||
Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
|
||||
if (src != nullptr && dest != nullptr) {
|
||||
src->CopyTo(dest);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else if (args[1] == "dump") {
|
||||
for (size_t i = 2; i < args.size(); i++) {
|
||||
VFSPath path = args[i];
|
||||
if (LocalFS->FileExists(path)) {
|
||||
std::cout << "File: " << path.ToString() << std::endl;
|
||||
auto strm = LocalFS->OpenFile(path, "rb");
|
||||
Programs::CrossLangDump(strm);
|
||||
} else {
|
||||
std::cout << "File: " << path.ToString()
|
||||
<< " does not exist." << std::endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else if (args[1] == "vm") {
|
||||
int64_t myi64 = 0;
|
||||
|
||||
args.erase(args.begin());
|
||||
std::shared_ptr<GC> gc = std::make_shared<GC>();
|
||||
gc->Start();
|
||||
GCList ls(gc);
|
||||
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
TRootEnvironment *env =
|
||||
TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
TStd::RegisterStd(gc, env);
|
||||
auto res = Programs::CrossLangVM(ls, env, args);
|
||||
GetObject(res, myi64);
|
||||
|
||||
|
||||
return (int)myi64;
|
||||
}
|
||||
}
|
||||
@@ -169,8 +187,6 @@ int main(int argc, char** argv)
|
||||
|
||||
GetObject(res, myi64);
|
||||
|
||||
|
||||
|
||||
return (int)myi64;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
static TList* VectorOfStringToList(GCList& ls, std::vector<std::string>& strs)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
static TList *VectorOfStringToList(GCList &ls, std::vector<std::string> &strs) {
|
||||
TList *list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for (auto &item : strs)
|
||||
@@ -12,15 +9,12 @@ namespace Tesses::CrossLang
|
||||
ls.GetGC()->BarrierEnd();
|
||||
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);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto& item : ents)
|
||||
{
|
||||
for (auto &item : ents) {
|
||||
std::string modifier = "public";
|
||||
switch(item.modifier)
|
||||
{
|
||||
switch (item.modifier) {
|
||||
case TClassModifier::Public:
|
||||
modifier = "public";
|
||||
break;
|
||||
@@ -35,247 +29,221 @@ namespace Tesses::CrossLang
|
||||
break;
|
||||
}
|
||||
|
||||
list->Add(TDictionary::Create(ls,{
|
||||
TDItem("Name",item.name),
|
||||
TDItem("IsAbstract",item.isAbstract),
|
||||
list->Add(TDictionary::Create(
|
||||
ls,
|
||||
{TDItem("Name", item.name), TDItem("IsAbstract", item.isAbstract),
|
||||
TDItem("IsFunction", item.isFunction),
|
||||
TDItem("Documentation", item.documentation),
|
||||
TDItem("ChunkId", (int64_t)item.chunkId),
|
||||
TDItem("Arguments", VectorOfStringToList(ls, item.args)),
|
||||
TDItem("Modifier",modifier)
|
||||
}));
|
||||
TDItem("Modifier", modifier)}));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TList* ClassInstanceToList(GCList& ls, TClassObject* co)
|
||||
{
|
||||
static TList *ClassInstanceToList(GCList &ls, TClassObject *co) {
|
||||
TList *list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto& item : co->entries)
|
||||
{
|
||||
if(item.modifier == TClassModifier::Public)
|
||||
{
|
||||
list->Add(TDictionary::Create(ls, {
|
||||
TDItem(
|
||||
"Name", item.name
|
||||
),
|
||||
TDItem(
|
||||
"IsFunction", !item.canSet
|
||||
),
|
||||
TDItem(
|
||||
"Owner", item.owner
|
||||
),
|
||||
TDItem(
|
||||
"Value", item.value
|
||||
)
|
||||
}));
|
||||
for (auto &item : co->entries) {
|
||||
if (item.modifier == TClassModifier::Public) {
|
||||
list->Add(TDictionary::Create(
|
||||
ls,
|
||||
{TDItem("Name", item.name), TDItem("IsFunction", !item.canSet),
|
||||
TDItem("Owner", item.owner), TDItem("Value", item.value)}));
|
||||
}
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
TObject GetClassInfo(GCList& ls,TFile* f, uint32_t index)
|
||||
{
|
||||
return TDictionary::Create(ls,{
|
||||
TDItem("Name", JoinPeriod(f->classes.at(index).name)),
|
||||
TDItem("NameParts",VectorOfStringToList(ls,f->classes.at(index).name)),
|
||||
TObject GetClassInfo(GCList &ls, TFile *f, uint32_t index) {
|
||||
return TDictionary::Create(
|
||||
ls, {TDItem("Name", JoinPeriod(f->classes.at(index).name)),
|
||||
TDItem("NameParts",
|
||||
VectorOfStringToList(ls, f->classes.at(index).name)),
|
||||
TDItem("Inherits", JoinPeriod(f->classes.at(index).inherits)),
|
||||
TDItem("InheritsParts",VectorOfStringToList(ls,f->classes.at(index).inherits)),
|
||||
TDItem("InheritsParts",
|
||||
VectorOfStringToList(ls, f->classes.at(index).inherits)),
|
||||
TDItem("Documentation", f->classes.at(index).documentation),
|
||||
TDItem("Entries",EntriesToList(ls,f->classes.at(index).entry))
|
||||
});
|
||||
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;
|
||||
if(!GetArgumentHeap(args,1,args_ls)) return nullptr;
|
||||
if (!GetArgumentHeap(args, 1, args_ls))
|
||||
return nullptr;
|
||||
TList *list;
|
||||
TClassObject *obj;
|
||||
std::string str;
|
||||
if(GetArgumentHeap(args,0,list))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, list)) {
|
||||
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);
|
||||
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);
|
||||
|
||||
if(f.name.size() != clsName.size()) continue;
|
||||
if (f.name.size() != clsName.size())
|
||||
continue;
|
||||
|
||||
bool found = true;
|
||||
for (size_t i = 0; i < f.name.size(); i++)
|
||||
if(f.name[i] != clsName[i])
|
||||
{
|
||||
if (f.name[i] != clsName[i]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
|
||||
}
|
||||
else
|
||||
if (found) {
|
||||
return TClassObject::Create(ls, item.first, item.second, env,
|
||||
args_ls->items);
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(GetArgument(args,0,str))
|
||||
{
|
||||
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
|
||||
for(auto& item : env->classes)
|
||||
{
|
||||
} else if (GetArgument(args, 0, str)) {
|
||||
std::vector<std::string> clsName =
|
||||
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
|
||||
for (auto &item : env->classes) {
|
||||
auto &f = item.first->classes.at(item.second);
|
||||
|
||||
if(f.name.size() != clsName.size()) continue;
|
||||
if (f.name.size() != clsName.size())
|
||||
continue;
|
||||
|
||||
bool found = true;
|
||||
for (size_t i = 0; i < f.name.size(); i++)
|
||||
if(f.name[i] != clsName[i])
|
||||
{
|
||||
if (f.name[i] != clsName[i]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
|
||||
if (found) {
|
||||
return TClassObject::Create(ls, item.first, item.second, env,
|
||||
args_ls->items);
|
||||
|
||||
}
|
||||
else
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
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);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto& item : env->classes)
|
||||
{
|
||||
for (auto &item : env->classes) {
|
||||
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TObject Class_GetInfo(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Class_GetInfo(TRootEnvironment *env, GCList &ls,
|
||||
std::vector<TObject> args) {
|
||||
|
||||
TList *list;
|
||||
TClassObject *obj;
|
||||
std::string str;
|
||||
if(GetArgumentHeap(args,0,list))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, list)) {
|
||||
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);
|
||||
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);
|
||||
|
||||
if(f.name.size() != clsName.size()) continue;
|
||||
if (f.name.size() != clsName.size())
|
||||
continue;
|
||||
|
||||
bool found = true;
|
||||
for (size_t i = 0; i < f.name.size(); i++)
|
||||
if(f.name[i] != clsName[i])
|
||||
{
|
||||
if (f.name[i] != clsName[i]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
if (found) {
|
||||
return GetClassInfo(ls, item.first, item.second);
|
||||
}
|
||||
else
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(GetArgument(args,0,str))
|
||||
{
|
||||
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
|
||||
for(auto& item : env->classes)
|
||||
{
|
||||
} else if (GetArgument(args, 0, str)) {
|
||||
std::vector<std::string> clsName =
|
||||
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
|
||||
for (auto &item : env->classes) {
|
||||
auto &f = item.first->classes.at(item.second);
|
||||
|
||||
if(f.name.size() != clsName.size()) continue;
|
||||
if (f.name.size() != clsName.size())
|
||||
continue;
|
||||
|
||||
bool found = true;
|
||||
for (size_t i = 0; i < f.name.size(); i++)
|
||||
if(f.name[i] != clsName[i])
|
||||
{
|
||||
if (f.name[i] != clsName[i]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
if (found) {
|
||||
return GetClassInfo(ls, item.first, item.second);
|
||||
}
|
||||
else
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(GetArgumentHeap(args,0,obj))
|
||||
{
|
||||
} else if (GetArgumentHeap(args, 0, obj)) {
|
||||
return GetClassInfo(ls, obj->file, obj->classIndex);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment* env)
|
||||
{
|
||||
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
GCList ls(gc);
|
||||
env->permissions.canRegisterClass = true;
|
||||
TDictionary *cls = env->EnsureDictionary(gc, "Class");
|
||||
gc->BarrierBegin();
|
||||
|
||||
TExternalMethod* ext = TExternalMethod::Create(ls ,"Get the class info",{"classInstanceOrClassName"},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
TExternalMethod *ext = TExternalMethod::Create(
|
||||
ls, "Get the class info", {"classInstanceOrClassName"},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Class_GetInfo(env, ls, args);
|
||||
});
|
||||
ext->watch.push_back(env);
|
||||
|
||||
cls->SetValue("GetInfo", ext);
|
||||
|
||||
ext = TExternalMethod::Create(ls ,"Get the class names",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
ext = TExternalMethod::Create(
|
||||
ls, "Get the class names", {},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Class_GetClassNames(env, ls, args);
|
||||
});
|
||||
ext->watch.push_back(env);
|
||||
|
||||
cls->SetValue("GetClassNames", ext);
|
||||
ext = TExternalMethod::Create(ls ,"Create an instance of class",{"name","args"},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
ext = TExternalMethod::Create(
|
||||
ls, "Create an instance of class", {"name", "args"},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Class_CreateInstance(env, ls, args);
|
||||
});
|
||||
ext->watch.push_back(env);
|
||||
|
||||
cls->SetValue("CreateInstance", ext);
|
||||
cls->DeclareFunction(gc,"Name","Get class name via instance",{"instance"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
cls->DeclareFunction(gc, "Name", "Get class name via instance",
|
||||
{"instance"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TClassObject *cls;
|
||||
if(GetArgumentHeap(args,0,cls))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, cls)) {
|
||||
return cls->name;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
|
||||
|
||||
cls->DeclareFunction(gc, "GetInstanceInfo", "Get the instance specific info, including current values", {}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
cls->DeclareFunction(
|
||||
gc, "GetInstanceInfo",
|
||||
"Get the instance specific info, including current values", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TClassObject *co;
|
||||
if(GetArgumentHeap(args, 0, co))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, co)) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto res= TDictionary::Create(ls,
|
||||
{
|
||||
TDItem("Name", co->name),
|
||||
TDItem("File", co->file),
|
||||
auto res = TDictionary::Create(
|
||||
ls, {TDItem("Name", co->name), TDItem("File", co->file),
|
||||
TDItem("ClassIndex", (int64_t)co->classIndex),
|
||||
TDItem("InheritList", VectorOfStringToList(ls, co->inherit_tree)),
|
||||
TDItem("Entries", ClassInstanceToList(ls,co))
|
||||
}
|
||||
);
|
||||
TDItem("InheritList",
|
||||
VectorOfStringToList(ls, co->inherit_tree)),
|
||||
TDItem("Entries", ClassInstanceToList(ls, co))});
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return res;
|
||||
}
|
||||
@@ -284,4 +252,4 @@ namespace Tesses::CrossLang
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -2,334 +2,247 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#if defined(GEKKO) || defined(__SWITCH__) || defined(_WIN32)
|
||||
#undef CROSSLANG_ENABLE_TERMIOS
|
||||
#endif
|
||||
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
namespace Tesses::CrossLang {
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios orig_termios;
|
||||
static void disableRawMode()
|
||||
{
|
||||
tcsetattr(0, TCSAFLUSH, &orig_termios);
|
||||
TObject Console_setInvertedColors(GCList &ls, std::vector<TObject> args) {
|
||||
bool inverted;
|
||||
if (GetArgument(args, 0, inverted)) {
|
||||
Tesses::Framework::Console::SetInvertedColors(inverted);
|
||||
}
|
||||
#endif
|
||||
TObject Console_getEcho(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
return (raw.c_lflag & ECHO) > 0;
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_Reset(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Console::Reset();
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getIsTTY(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
#endif
|
||||
return false;
|
||||
return Tesses::Framework::Console::IsTTY();
|
||||
}
|
||||
TObject Console_setEcho(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
||||
{
|
||||
TObject Console_getEcho(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
return Tesses::Framework::Console::GetEcho();
|
||||
}
|
||||
TObject Console_setEcho(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
if(cooked)
|
||||
{
|
||||
raw.c_lflag |= ECHO;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw.c_lflag &= ~(ECHO);
|
||||
}
|
||||
|
||||
tcsetattr(0, TCSAFLUSH, &raw);
|
||||
|
||||
#endif
|
||||
Tesses::Framework::Console::SetEcho(cooked);
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getCanonical(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
return (raw.c_lflag & ICANON) > 0;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
TObject Console_getCanonical(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Console::GetCanonical();
|
||||
}
|
||||
TObject Console_setCanonical(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
||||
{
|
||||
TObject Console_setCanonical(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
if(cooked)
|
||||
{
|
||||
raw.c_lflag |= ICANON;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw.c_lflag &= ~(ICANON);
|
||||
}
|
||||
|
||||
tcsetattr(0, TCSAFLUSH, &raw);
|
||||
|
||||
#endif
|
||||
Tesses::Framework::Console::SetCanonical(cooked);
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getSignals(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
return (raw.c_lflag & ISIG) > 0;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
TObject Console_getSignals(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Console::GetSignals();
|
||||
}
|
||||
TObject Console_setSignals(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
||||
{
|
||||
TObject Console_setSignals(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
if(cooked)
|
||||
{
|
||||
raw.c_lflag |= ISIG;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw.c_lflag &= ~(ISIG);
|
||||
}
|
||||
|
||||
tcsetattr(0, TCSAFLUSH, &raw);
|
||||
|
||||
#endif
|
||||
Tesses::Framework::Console::SetSignals(cooked);
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
TObject Console_Read(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
uint8_t byte;
|
||||
std::cin.read((char*)&byte,1);
|
||||
return std::cin.eof() ? (int64_t)-1 : (int64_t)byte;
|
||||
TObject Console_Read(GCList &ls, std::vector<TObject> args) {
|
||||
return (int64_t)Tesses::Framework::Console::Read();
|
||||
}
|
||||
TObject Console_ReadLine(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(std::cin,str);
|
||||
return str;
|
||||
TObject Console_ReadLine(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Console::ReadLine();
|
||||
}
|
||||
TObject Console_Write(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
TObject Console_ReadPassword(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Console::ReadPassword();
|
||||
}
|
||||
TObject Console_Write(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
return Undefined();
|
||||
}
|
||||
std::cout << ToString(ls.GetGC(),args[0]);
|
||||
Tesses::Framework::Console::Write(ToString(ls.GetGC(), args[0]));
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_Fatal(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
std::cout << "FATAL: <NO MESSAGE>" << std::endl;
|
||||
TObject Console_Fatal(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
Tesses::Framework::Console::ErrorLine("FATAL: <NO MESSAGE>");
|
||||
exit(1);
|
||||
}
|
||||
std::cout << "FATAL: " << ToString(ls.GetGC(),args[0]) << std::endl;
|
||||
Tesses::Framework::Console::ErrorLine("FATAL: " +
|
||||
ToString(ls.GetGC(), args[0]));
|
||||
exit(1);
|
||||
}
|
||||
TObject Console_WriteLine(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
std::cout << "\n";
|
||||
TObject Console_WriteLine(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
Tesses::Framework::Console::WriteLineView("");
|
||||
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)
|
||||
{
|
||||
TObject Console_Error(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
return Undefined();
|
||||
}
|
||||
std::cerr << ToString(ls.GetGC(),args[0]);
|
||||
Tesses::Framework::Console::Error(ToString(ls.GetGC(), args[0]));
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_ErrorLine(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
std::cout << "\n";
|
||||
TObject Console_ErrorLine(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
Tesses::Framework::Console::ErrorLine("");
|
||||
return Undefined();
|
||||
}
|
||||
std::cerr << ToString(ls.GetGC(),args[0]) << "\n";
|
||||
Tesses::Framework::Console::ErrorLine(ToString(ls.GetGC(), args[0]));
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getIn(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdin,false,"r",false);
|
||||
TObject Console_getIn(GCList &ls, std::vector<TObject> args) {
|
||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(
|
||||
stdin, false, "r", false);
|
||||
}
|
||||
|
||||
TObject Console_getOut(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdout,false,"w",false);
|
||||
TObject Console_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_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
|
||||
TObject Console_Clear(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Console::Clear();
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
});
|
||||
TObject Console_getSize(GCList &ls, std::vector<TObject> args) {
|
||||
auto sz = Tesses::Framework::Console::GetSize();
|
||||
TDictionary *dict =
|
||||
TDictionary::Create(ls, {TDItem("Width", (int64_t)sz.first),
|
||||
TDItem("Height", (int64_t)sz.second)});
|
||||
|
||||
return dict;
|
||||
}
|
||||
void TStd::RegisterConsole(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
TObject Console_List(GCList &ls, std::vector<TObject> args) {
|
||||
if (!args.empty()) {
|
||||
GCList ls2(ls.GetGC());
|
||||
auto enumerator = TEnumerator::CreateFromObject(ls2, args[0]);
|
||||
std::vector<std::string> items;
|
||||
|
||||
while (enumerator->MoveNext(ls2.GetGC())) {
|
||||
auto item = enumerator->GetCurrent(ls2);
|
||||
items.push_back(ToString(ls2.GetGC(), item));
|
||||
}
|
||||
|
||||
return (int64_t)Tesses::Framework::Console::List(items);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void TStd::RegisterConsole(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
env->permissions.canRegisterConsole = true;
|
||||
if(env->permissions.customConsole != nullptr)
|
||||
{
|
||||
if (env->permissions.customConsole != nullptr) {
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Console", env->permissions.customConsole);
|
||||
gc->BarrierEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
tcgetattr(0, &orig_termios);
|
||||
atexit(disableRawMode);
|
||||
#endif
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
|
||||
dict->DeclareFunction(gc,"getEcho","Get whether terminal is echoing characters read",{},Console_getEcho);
|
||||
dict->DeclareFunction(gc,"setEcho","Set whether terminal is echoing characters read",{"flag"},Console_setEcho);
|
||||
dict->DeclareFunction(gc,"getCanonical","Get whether terminal is buffering line by line (true) or byte by byte (false)",{},Console_getCanonical);
|
||||
dict->DeclareFunction(gc,"setCanonical","Set whether terminal is buffering line by line (true) or byte by byte (false)",{"flag"},Console_setCanonical);
|
||||
dict->DeclareFunction(gc,"getSignals","Get whether terminal is sending signals for CTRL+C (true) or via read (false)",{},Console_getSignals);
|
||||
dict->DeclareFunction(gc,"setSignals","Set whether terminal is sending signals for CTRL+C (true) or via read (false)",{"flag"},Console_setSignals);
|
||||
dict->DeclareFunction(
|
||||
gc, "getIsTTY",
|
||||
"Get whether terminal is a terminal or just piped to file", {},
|
||||
Console_getIsTTY);
|
||||
dict->DeclareFunction(gc, "getEcho",
|
||||
"Get whether terminal is echoing characters read", {},
|
||||
Console_getEcho);
|
||||
dict->DeclareFunction(gc, "setEcho",
|
||||
"Set whether terminal is echoing characters read",
|
||||
{"flag"}, Console_setEcho);
|
||||
dict->DeclareFunction(gc, "getCanonical",
|
||||
"Get whether terminal is buffering line by line "
|
||||
"(true) or byte by byte (false)",
|
||||
{}, Console_getCanonical);
|
||||
dict->DeclareFunction(gc, "setCanonical",
|
||||
"Set whether terminal is buffering line by line "
|
||||
"(true) or byte by byte (false)",
|
||||
{"flag"}, Console_setCanonical);
|
||||
dict->DeclareFunction(gc, "getSignals",
|
||||
"Get whether terminal is sending signals for CTRL+C "
|
||||
"(true) or via read (false)",
|
||||
{}, Console_getSignals);
|
||||
dict->DeclareFunction(gc, "setSignals",
|
||||
"Set whether terminal is sending signals for CTRL+C "
|
||||
"(true) or via read (false)",
|
||||
{"flag"}, Console_setSignals);
|
||||
dict->DeclareFunction(gc, "Clear", "Clear the console", {}, Console_Clear);
|
||||
dict->DeclareFunction(gc,"Read", "Reads a byte from stdin",{},Console_Read);
|
||||
dict->DeclareFunction(gc,"ReadLine","Reads line from stdin",{},Console_ReadLine);
|
||||
dict->DeclareFunction(gc,"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, "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, "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);
|
||||
dict->DeclareFunction(gc, "getOut", "Get stdout Stream", {},
|
||||
Console_getOut);
|
||||
dict->DeclareFunction(gc, "getError", "Get stderr Stream", {},
|
||||
Console_getError);
|
||||
dict->DeclareFunction(gc, "getSize", "Get console size", {},
|
||||
Console_getSize);
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Console", dict);
|
||||
auto _new = env->EnsureDictionary(gc, "New");
|
||||
_new->DeclareFunction(gc,"ConsoleReader","Read from console",{},[](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
return std::make_shared<Tesses::Framework::TextStreams::ConsoleReader>();
|
||||
_new->DeclareFunction(
|
||||
gc, "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;
|
||||
if(GetArgument(args,0,err)) return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>(err);
|
||||
return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>();
|
||||
if (GetArgument(args, 0, err))
|
||||
return std::make_shared<
|
||||
Tesses::Framework::TextStreams::ConsoleWriter>(err);
|
||||
return std::make_shared<
|
||||
Tesses::Framework::TextStreams::ConsoleWriter>();
|
||||
});
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
#endif
|
||||
|
||||
@@ -2,43 +2,36 @@
|
||||
|
||||
using namespace Tesses::Framework::Crypto;
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
static TObject Crypto_RandomBytes(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
static TObject Crypto_RandomBytes(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
int64_t size;
|
||||
std::string personalStr;
|
||||
if(GetArgument(args,0,size) && GetArgument(args,1,personalStr))
|
||||
{
|
||||
if (GetArgument(args, 0, size) && GetArgument(args, 1, personalStr)) {
|
||||
|
||||
std::vector<uint8_t> bytes;
|
||||
bytes.resize((size_t)size);
|
||||
if(RandomBytes(bytes,personalStr))
|
||||
{
|
||||
if (RandomBytes(bytes, personalStr)) {
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
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;
|
||||
TByteArray *bArraySalt;
|
||||
int64_t itterations;
|
||||
int64_t keylength;
|
||||
int64_t shanum;
|
||||
if(GetArgument(args,0,pass) && GetArgumentHeap(args,1, bArraySalt) && GetArgument(args,2, itterations) && GetArgument(args,3,keylength) && GetArgument(args,4,shanum))
|
||||
{
|
||||
if (GetArgument(args, 0, pass) && GetArgumentHeap(args, 1, bArraySalt) &&
|
||||
GetArgument(args, 2, itterations) && GetArgument(args, 3, keylength) &&
|
||||
GetArgument(args, 4, shanum)) {
|
||||
ShaVersion version = VERSION_SHA384;
|
||||
|
||||
switch(shanum)
|
||||
{
|
||||
switch (shanum) {
|
||||
case 1:
|
||||
version = VERSION_SHA1;
|
||||
break;
|
||||
@@ -57,118 +50,117 @@ namespace Tesses::CrossLang
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<uint8_t> key;
|
||||
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);
|
||||
ba->data = key;
|
||||
return ba;
|
||||
}
|
||||
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
static TObject Crypto_Base64Encode(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Crypto_Base64Encode(GCList &ls, std::vector<TObject> args) {
|
||||
TByteArray *byteArray;
|
||||
|
||||
if(GetArgumentHeap(args,0,byteArray))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, byteArray)) {
|
||||
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
|
||||
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static TObject Crypto_Base64Decode(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Crypto_Base64Decode(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
if (GetArgument(args, 0, str)) {
|
||||
TByteArray *bArray = TByteArray::Create(ls);
|
||||
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
|
||||
|
||||
return bArray;
|
||||
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterCrypto(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
void TStd::RegisterCrypto(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterCrypto = true;
|
||||
if(!HaveCrypto()) return;
|
||||
if (!HaveCrypto())
|
||||
return;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "PBKDF2","Hash passwords with PBKDF2",{"pass","salt","itterations","keylen","shanum"},Crypto_PBKDF2);
|
||||
dict->DeclareFunction(gc, "RandomBytes","Create bytearray but with random bytes in it instead of zeros (this uses mbedtls by the way)",{"byteCount","personalString"},Crypto_RandomBytes);
|
||||
dict->DeclareFunction(gc, "PBKDF2", "Hash passwords with PBKDF2",
|
||||
{"pass", "salt", "itterations", "keylen", "shanum"},
|
||||
Crypto_PBKDF2);
|
||||
dict->DeclareFunction(gc, "RandomBytes",
|
||||
"Create bytearray but with random bytes in it "
|
||||
"instead of zeros (this uses mbedtls by the way)",
|
||||
{"byteCount", "personalString"}, Crypto_RandomBytes);
|
||||
|
||||
dict->DeclareFunction(gc, "Base64Encode","Base64 encode",{"data"},Crypto_Base64Encode);
|
||||
dict->DeclareFunction(gc, "Base64Decode","Base64 decode",{"str"},Crypto_Base64Decode);
|
||||
dict->DeclareFunction(gc, "Sha1", "Hash with sha1 algorithm (please don't use sha1 unless you need to)",{"strm"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
dict->DeclareFunction(gc, "Base64Encode", "Base64 encode", {"data"},
|
||||
Crypto_Base64Encode);
|
||||
dict->DeclareFunction(gc, "Base64Decode", "Base64 decode", {"str"},
|
||||
Crypto_Base64Decode);
|
||||
dict->DeclareFunction(
|
||||
gc, "Sha1",
|
||||
"Hash with sha1 algorithm (please don't use sha1 unless you need to)",
|
||||
{"strm"}, [](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TByteArray *baSrc;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||
|
||||
if(GetArgument(args, 0, sho))
|
||||
{
|
||||
if (GetArgument(args, 0, sho)) {
|
||||
auto bytes = Sha1::ComputeHash(sho);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
if(GetArgumentHeap(args,0,baSrc))
|
||||
{
|
||||
auto bytes = Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
|
||||
if (GetArgumentHeap(args, 0, baSrc)) {
|
||||
auto bytes =
|
||||
Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Sha256", "Hash with sha256 algorithm",{"strm","$is224"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
dict->DeclareFunction(
|
||||
gc, "Sha256", "Hash with sha256 algorithm", {"strm", "$is224"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TByteArray *baSrc;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||
bool is224 = false;
|
||||
GetArgument(args, 1, is224);
|
||||
|
||||
if(GetArgument(args, 0, sho))
|
||||
{
|
||||
if (GetArgument(args, 0, sho)) {
|
||||
auto bytes = Sha256::ComputeHash(sho, is224);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
if(GetArgumentHeap(args,0,baSrc))
|
||||
{
|
||||
auto bytes = Sha256::ComputeHash(baSrc->data.data(), baSrc->data.size(), is224);
|
||||
if (GetArgumentHeap(args, 0, baSrc)) {
|
||||
auto bytes = Sha256::ComputeHash(baSrc->data.data(),
|
||||
baSrc->data.size(), is224);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Sha512", "Hash with sha512 algorithm",{"strm","$is384"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
dict->DeclareFunction(
|
||||
gc, "Sha512", "Hash with sha512 algorithm", {"strm", "$is384"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TByteArray *baSrc;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||
bool is384 = false;
|
||||
GetArgument(args, 1, is384);
|
||||
|
||||
if(GetArgument(args, 0, sho))
|
||||
{
|
||||
if (GetArgument(args, 0, sho)) {
|
||||
auto bytes = Sha512::ComputeHash(sho, is384);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
if(GetArgumentHeap(args,0,baSrc))
|
||||
{
|
||||
auto bytes = Sha512::ComputeHash(baSrc->data.data(), baSrc->data.size(), is384);
|
||||
if (GetArgumentHeap(args, 0, baSrc)) {
|
||||
auto bytes = Sha512::ComputeHash(baSrc->data.data(),
|
||||
baSrc->data.size(), is384);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
@@ -178,7 +170,5 @@ namespace Tesses::CrossLang
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Crypto", dict);
|
||||
gc->BarrierEnd();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
@@ -1,42 +1,35 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
TObject Dictionary_FindByKey(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
TObject Dictionary_FindByKey(GCList &ls, std::vector<TObject> args) {
|
||||
TList *dest = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
std::string key;
|
||||
if(GetArgument(args,1,key))
|
||||
{
|
||||
if (GetArgument(args, 1, key)) {
|
||||
|
||||
std::function<void(TObject)> crawl;
|
||||
crawl = [&](TObject o) -> void {
|
||||
TDictionary *dict;
|
||||
TList *list;
|
||||
TAssociativeArray *aa;
|
||||
if(GetObjectHeap(o,aa))
|
||||
{
|
||||
if (GetObjectHeap(o, aa)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
if(GetObjectHeap(o,dict))
|
||||
{
|
||||
for(auto& item : dict->items)
|
||||
{
|
||||
if(item.first == key) dest->Add(item.second);
|
||||
if (GetObjectHeap(o, dict)) {
|
||||
for (auto &item : dict->items) {
|
||||
if (item.first == key)
|
||||
dest->Add(item.second);
|
||||
crawl(item.second);
|
||||
}
|
||||
}
|
||||
if(GetObjectHeap(o,list))
|
||||
{
|
||||
for(auto& item : list->items)
|
||||
{
|
||||
if (GetObjectHeap(o, list)) {
|
||||
for (auto &item : list->items) {
|
||||
crawl(item);
|
||||
}
|
||||
}
|
||||
@@ -46,17 +39,17 @@ namespace Tesses::CrossLang
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dest;
|
||||
}
|
||||
TObject Dictionary_Items(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TObject Dictionary_Items(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
TDictionary *dict;
|
||||
TDynamicDictionary *dynDict;
|
||||
if(GetArgumentHeap(args,0,dynDict))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, dynDict)) {
|
||||
TDictionary *enumerableItem = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
|
||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{},[dynDict](GCList& ls2, std::vector<TObject> args)->TObject {
|
||||
auto fn = TExternalMethod::Create(
|
||||
ls, "Get Enumerator for Dictionary", {},
|
||||
[dynDict](GCList &ls2, std::vector<TObject> args) -> TObject {
|
||||
return dynDict->GetEnumerator(ls2);
|
||||
});
|
||||
fn->watch.push_back(dynDict);
|
||||
@@ -66,14 +59,14 @@ namespace Tesses::CrossLang
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return enumerableItem;
|
||||
|
||||
}
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
TDictionary *enumerableItem = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
|
||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{"dict"},[dict](GCList& ls2, std::vector<TObject> args)->TObject {
|
||||
auto fn = TExternalMethod::Create(
|
||||
ls, "Get Enumerator for Dictionary", {"dict"},
|
||||
[dict](GCList &ls2, std::vector<TObject> args) -> TObject {
|
||||
return TDictionaryEnumerator::Create(ls2, dict);
|
||||
});
|
||||
fn->watch.push_back(dict);
|
||||
@@ -83,67 +76,62 @@ namespace Tesses::CrossLang
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return enumerableItem;
|
||||
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
TObject Dictionary_GetField(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TObject Dictionary_GetField(GCList &ls, std::vector<TObject> args) {
|
||||
TDictionary *dict;
|
||||
TDynamicDictionary *dynDict;
|
||||
std::string key;
|
||||
if(GetArgument(args,1,key))
|
||||
{
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
if (GetArgument(args, 1, key)) {
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto res = dict->GetValue(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return res;
|
||||
}
|
||||
else if(GetArgumentHeap(args,0,dynDict))
|
||||
{
|
||||
} else if (GetArgumentHeap(args, 0, dynDict)) {
|
||||
return dynDict->GetField(ls, key);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
TObject Dictionary_SetField(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TObject Dictionary_SetField(GCList &ls, std::vector<TObject> args) {
|
||||
TDictionary *dict;
|
||||
TDynamicDictionary *dynDict;
|
||||
std::string key;
|
||||
if(args.size() == 3 && GetArgument(args,1,key))
|
||||
{
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
if (args.size() == 3 && GetArgument(args, 1, key)) {
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue(key, args[2]);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
}
|
||||
else if(GetArgumentHeap(args,0,dynDict))
|
||||
{
|
||||
} else if (GetArgumentHeap(args, 0, dynDict)) {
|
||||
dynDict->SetField(ls, key, args[2]);
|
||||
}
|
||||
}
|
||||
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;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
|
||||
|
||||
gc->BarrierBegin();
|
||||
dict->DeclareFunction(gc, "FindByKey","Scan object recursively, return list of items with key",{"obj","key"}, Dictionary_FindByKey);
|
||||
dict->DeclareFunction(gc, "Items","Get Dictionary Item Enumerable, for the each(item : Dictionary.Items(myDict)){item.Key; item.Value;}",{"dictionary"},Dictionary_Items);
|
||||
dict->DeclareFunction(gc, "SetField","Set a field in dictionary",{"dict","key","value"},Dictionary_SetField);
|
||||
dict->DeclareFunction(gc, "GetField","Get a field in dictionary",{"dict","key"},Dictionary_GetField);
|
||||
dict->DeclareFunction(
|
||||
gc, "FindByKey",
|
||||
"Scan object recursively, return list of items with key",
|
||||
{"obj", "key"}, Dictionary_FindByKey);
|
||||
dict->DeclareFunction(gc, "Items",
|
||||
"Get Dictionary Item Enumerable, for the each(item : "
|
||||
"Dictionary.Items(myDict)){item.Key; item.Value;}",
|
||||
{"dictionary"}, Dictionary_Items);
|
||||
dict->DeclareFunction(gc, "SetField", "Set a field in dictionary",
|
||||
{"dict", "key", "value"}, Dictionary_SetField);
|
||||
dict->DeclareFunction(gc, "GetField", "Get a field in dictionary",
|
||||
{"dict", "key"}, Dictionary_GetField);
|
||||
|
||||
env->DeclareVariable("Dictionary", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -5,8 +5,7 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
using namespace Tesses::Framework::Platform::Environment;
|
||||
#if defined(_WIN32)
|
||||
static char EnvPathSeperator = ';';
|
||||
@@ -16,154 +15,142 @@ namespace Tesses::CrossLang
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath("");
|
||||
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir()
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir() {
|
||||
if (!CrossLangConfigPath.path.empty())
|
||||
return CrossLangConfigPath;
|
||||
|
||||
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();
|
||||
}
|
||||
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();
|
||||
}
|
||||
static TObject Env_GetAt(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Env_GetAt(GCList &ls, std::vector<TObject> args) {
|
||||
std::string key;
|
||||
if(GetArgument(args,0,key))
|
||||
{
|
||||
if (GetArgument(args, 0, key)) {
|
||||
auto v = GetVariable(key);
|
||||
if(v) return v.value();
|
||||
|
||||
if (v)
|
||||
return v.value();
|
||||
}
|
||||
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 value;
|
||||
if(GetArgument(args,0,key))
|
||||
{
|
||||
if(GetArgument(args,1,value))
|
||||
{
|
||||
if (GetArgument(args, 0, key)) {
|
||||
if (GetArgument(args, 1, value)) {
|
||||
SetVariable(key, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
SetVariable(key, std::nullopt);
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
static TObject Env_getMusic(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Env_getMusic(GCList &ls, std::vector<TObject> args) {
|
||||
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();
|
||||
}
|
||||
static TObject Env_getVideos(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Env_getVideos(GCList &ls, std::vector<TObject> args) {
|
||||
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();
|
||||
}
|
||||
static TObject Env_getConfig(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Env_getConfig(GCList &ls, std::vector<TObject> args) {
|
||||
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();
|
||||
}
|
||||
static TObject Env_getState(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Env_getState(GCList &ls, std::vector<TObject> args) {
|
||||
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();
|
||||
}
|
||||
static TObject Env_getData(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Env_getData(GCList &ls, std::vector<TObject> args) {
|
||||
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();
|
||||
}
|
||||
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;
|
||||
if(GetArgumentAsPath(args,0,p))
|
||||
{
|
||||
if (GetArgumentAsPath(args, 0, p)) {
|
||||
return GetRealExecutablePath(p);
|
||||
}
|
||||
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();
|
||||
TList *list = TList::Create(ls);
|
||||
std::vector<std::pair<std::string, std::string>> env;
|
||||
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
|
||||
for(auto& item : env)
|
||||
{
|
||||
list->Add(TDictionary::Create(ls,{TDItem("Key",item.first),TDItem("Value",item.second)}));
|
||||
for (auto &item : env) {
|
||||
list->Add(TDictionary::Create(
|
||||
ls, {TDItem("Key", item.first), TDItem("Value", item.second)}));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TObject Env_getLittleEndian(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Env_getLittleEndian(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Serialization::BitConverter::IsLittleEndian();
|
||||
}
|
||||
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment* env)
|
||||
{
|
||||
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterEnv = true;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc,"GetAt","Get environment variable", {"key"}, Env_GetAt);
|
||||
dict->DeclareFunction(gc,"SetAt","Set environment variable", {"key","value"}, Env_SetAt);
|
||||
dict->DeclareFunction(gc,"GetAll","Get all of the environment variables",{},Env_GetAll);
|
||||
dict->DeclareFunction(gc, "GetAt", "Get environment variable", {"key"},
|
||||
Env_GetAt);
|
||||
dict->DeclareFunction(gc, "SetAt", "Set environment variable",
|
||||
{"key", "value"}, Env_SetAt);
|
||||
dict->DeclareFunction(gc, "GetAll", "Get all of the environment variables",
|
||||
{}, Env_GetAll);
|
||||
|
||||
dict->DeclareFunction(gc,"getDesktop","Get desktop folder",{},Env_getDesktop);
|
||||
dict->DeclareFunction(gc,"getDownloads","Get downloads folder",{},Env_getDownloads);
|
||||
dict->DeclareFunction(gc,"getDocuments","Get documents folder",{},Env_getDocuments);
|
||||
dict->DeclareFunction(gc, "getDesktop", "Get desktop folder", {},
|
||||
Env_getDesktop);
|
||||
dict->DeclareFunction(gc, "getDownloads", "Get downloads folder", {},
|
||||
Env_getDownloads);
|
||||
dict->DeclareFunction(gc, "getDocuments", "Get documents folder", {},
|
||||
Env_getDocuments);
|
||||
dict->DeclareFunction(gc, "getMusic", "Get music folder", {}, Env_getMusic);
|
||||
dict->DeclareFunction(gc,"getPictures","Get pictures folder",{},Env_getPictures);
|
||||
dict->DeclareFunction(gc,"getVideos","Get videos folder",{},Env_getVideos);
|
||||
dict->DeclareFunction(gc, "getPictures", "Get pictures folder", {},
|
||||
Env_getPictures);
|
||||
dict->DeclareFunction(gc, "getVideos", "Get videos folder", {},
|
||||
Env_getVideos);
|
||||
dict->DeclareFunction(gc, "getState", "Get state folder", {}, Env_getState);
|
||||
dict->DeclareFunction(gc, "getCache", "Get cache folder", {}, Env_getCache);
|
||||
dict->DeclareFunction(gc,"getConfig","Get config folder",{},Env_getConfig);
|
||||
dict->DeclareFunction(gc,"getCrossLangConfig","Get crosslang configuration folder",{}, Env_getCrossLangConfig);
|
||||
dict->DeclareFunction(gc, "getConfig", "Get config folder", {},
|
||||
Env_getConfig);
|
||||
dict->DeclareFunction(gc, "getCrossLangConfig",
|
||||
"Get crosslang configuration folder", {},
|
||||
Env_getCrossLangConfig);
|
||||
dict->DeclareFunction(gc, "getData", "Get data folder", {}, Env_getData);
|
||||
dict->DeclareFunction(gc, "getUser", "Get user folder", {}, Env_getUser);
|
||||
dict->DeclareFunction(gc,"getPlatform","Get platform name",{},Env_getPlatform);
|
||||
dict->DeclareFunction(gc,"GetRealExecutablePath", "Get the absolute path for executable", {"path"},Env_GetRealExecutablePath);
|
||||
dict->DeclareFunction(gc, "getLittleEndian", "Is the platform little endian", {},Env_getLittleEndian);
|
||||
dict->DeclareFunction(gc, "getPlatform", "Get platform name", {},
|
||||
Env_getPlatform);
|
||||
dict->DeclareFunction(gc, "GetRealExecutablePath",
|
||||
"Get the absolute path for executable", {"path"},
|
||||
Env_GetRealExecutablePath);
|
||||
dict->DeclareFunction(gc, "getLittleEndian",
|
||||
"Is the platform little endian", {},
|
||||
Env_getLittleEndian);
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue("EnvPathSeperator", EnvPathSeperator);
|
||||
env->SetVariable("Env", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
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> dest;
|
||||
double precision = 1000.0;
|
||||
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);
|
||||
auto len = src->GetLength();
|
||||
callable->Call(ls, {0.0});
|
||||
if(len > 0)
|
||||
{
|
||||
if (len > 0) {
|
||||
std::vector<uint8_t> buff(1024);
|
||||
int64_t pos = 0;
|
||||
int curPercent = 0;
|
||||
@@ -23,7 +21,8 @@ namespace Tesses::CrossLang {
|
||||
read = src->ReadBlock(buff.data(), buff.size());
|
||||
dest->WriteBlock(buff.data(), read);
|
||||
|
||||
if(read == 0) break;
|
||||
if (read == 0)
|
||||
break;
|
||||
pos += (int64_t)read;
|
||||
|
||||
double percent = ((double)pos / len);
|
||||
@@ -31,27 +30,24 @@ namespace Tesses::CrossLang {
|
||||
|
||||
curPercent = (int)percent;
|
||||
|
||||
|
||||
if(curPercent > lastPercent)
|
||||
{
|
||||
if (curPercent > lastPercent) {
|
||||
lastPercent = curPercent;
|
||||
callable->Call(ls, {curPercent / precision});
|
||||
}
|
||||
|
||||
|
||||
} while (read != 0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
src->CopyTo(dest);
|
||||
|
||||
}
|
||||
callable->Call(ls, {1.0});
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void TStd::RegisterHelpers(std::shared_ptr<GC> gc, TRootEnvironment* env)
|
||||
{
|
||||
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);
|
||||
}
|
||||
helpers->DeclareFunction(gc, "CopyToProgress",
|
||||
"Copy Stream to another (but with progress event)",
|
||||
{"src", "dest", "progressCB", "$precision"},
|
||||
Helpers_CopyToProgress);
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,11 +1,7 @@
|
||||
#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::Streams::Stream> strm;
|
||||
@@ -16,22 +12,22 @@ namespace Tesses::CrossLang
|
||||
std::string icon = "";
|
||||
TVMVersion version2;
|
||||
|
||||
if(GetArgument(args,0,vfs) && GetArgument(args,1,strm) && GetArgument(args,2,name) && GetArgument(args,4,info) && ((GetArgument(args,3,version) && TVMVersion::TryParse(version,version2)) || GetArgument(args,3,version2)))
|
||||
{
|
||||
if (GetArgument(args, 0, vfs) && GetArgument(args, 1, strm) &&
|
||||
GetArgument(args, 2, name) && GetArgument(args, 4, info) &&
|
||||
((GetArgument(args, 3, version) &&
|
||||
TVMVersion::TryParse(version, version2)) ||
|
||||
GetArgument(args, 3, version2))) {
|
||||
GetArgument(args, 5, icon);
|
||||
CrossArchiveCreate(vfs, strm, name, version2, info, icon);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
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::Streams::Stream> strm;
|
||||
|
||||
|
||||
if(GetArgument(args,0,strm) && GetArgument(args,1,vfs))
|
||||
{
|
||||
if (GetArgument(args, 0, strm) && GetArgument(args, 1, vfs)) {
|
||||
auto res = CrossArchiveExtract(strm, vfs);
|
||||
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
@@ -45,234 +41,223 @@ namespace Tesses::CrossLang
|
||||
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;
|
||||
|
||||
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 "";
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs, path, lines);
|
||||
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto items = TList::Create(ls);
|
||||
for(auto& l : lines) { items->Add(l);}
|
||||
for (auto &l : lines) {
|
||||
items->Add(l);
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return items;
|
||||
}
|
||||
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;
|
||||
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);
|
||||
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs,path,res->data);
|
||||
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs, path,
|
||||
res->data);
|
||||
|
||||
return res;
|
||||
}
|
||||
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;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
|
||||
TList *lines;
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,lines))
|
||||
{
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
|
||||
GetArgumentHeap(args, 2, lines)) {
|
||||
std::vector<std::string> content;
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto& item : lines->items)
|
||||
{
|
||||
for (auto &item : lines->items) {
|
||||
if (std::holds_alternative<std::string>(item))
|
||||
content.push_back(std::get<std::string>(item));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs,path,content);
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs, path,
|
||||
content);
|
||||
}
|
||||
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;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
|
||||
std::string content;
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content))
|
||||
{
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs,path,content);
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
|
||||
GetArgument(args, 2, content)) {
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs, path,
|
||||
content);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject FS_WriteAllBytes(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject FS_WriteAllBytes(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
TByteArray *bArray;
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,bArray))
|
||||
{
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs,path,bArray->data);
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
|
||||
GetArgumentHeap(args, 2, bArray)) {
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs, path,
|
||||
bArray->data);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class FS_Watcher : public TNativeObject {
|
||||
public:
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
|
||||
|
||||
FS_Watcher(std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher): watcher(watcher)
|
||||
{}
|
||||
FS_Watcher(
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher)
|
||||
: watcher(watcher) {}
|
||||
|
||||
TObject CallMethod(GCList& ls, std::string name, std::vector<TObject> args)
|
||||
{
|
||||
if(name == "getPath")
|
||||
{
|
||||
TObject CallMethod(GCList &ls, std::string name,
|
||||
std::vector<TObject> args) {
|
||||
if (name == "getPath") {
|
||||
return watcher->GetPath();
|
||||
}
|
||||
if(name == "getFilesystem")
|
||||
{
|
||||
if (name == "getFilesystem") {
|
||||
return watcher->GetFilesystem();
|
||||
}
|
||||
if(name == "setEnabled")
|
||||
{
|
||||
if (name == "setEnabled") {
|
||||
bool enabled;
|
||||
if(GetArgument(args,0,enabled))
|
||||
{
|
||||
if (GetArgument(args, 0, enabled)) {
|
||||
watcher->SetEnabled(enabled);
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
if(name == "getEnabled")
|
||||
{
|
||||
if (name == "getEnabled") {
|
||||
return watcher->GetEnabled();
|
||||
}
|
||||
if(name == "setEvents")
|
||||
{
|
||||
if (name == "setEvents") {
|
||||
int64_t evts;
|
||||
if(GetArgument(args,0,evts))
|
||||
{
|
||||
watcher->events = (Tesses::Framework::Filesystem::FSWatcherEventType)evts;
|
||||
if (GetArgument(args, 0, evts)) {
|
||||
watcher->events =
|
||||
(Tesses::Framework::Filesystem::FSWatcherEventType)evts;
|
||||
return evts;
|
||||
}
|
||||
}
|
||||
if(name == "getEvents")
|
||||
{
|
||||
if (name == "getEvents") {
|
||||
return (int64_t)watcher->events;
|
||||
}
|
||||
if(name == "setCallback")
|
||||
{
|
||||
if (name == "setCallback") {
|
||||
TCallable *callable = nullptr;
|
||||
if(GetArgumentHeap(args,0,callable))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, callable)) {
|
||||
auto markedT = CreateMarkedTObject(ls, callable);
|
||||
watcher->event = [markedT](Tesses::Framework::Filesystem::FSWatcherEvent& evt) -> void {
|
||||
watcher->event =
|
||||
[markedT](
|
||||
Tesses::Framework::Filesystem::FSWatcherEvent &evt)
|
||||
-> void {
|
||||
GCList ls(markedT->GetGC());
|
||||
TObject o = markedT->GetObject();
|
||||
TCallable *callable;
|
||||
if(GetObjectHeap(o,callable))
|
||||
{
|
||||
auto isEvent = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
|
||||
{
|
||||
if (GetObjectHeap(o, callable)) {
|
||||
auto isEvent = TExternalMethod::Create(
|
||||
ls, "", {},
|
||||
[evt](GCList &ls,
|
||||
std::vector<TObject> args) -> TObject {
|
||||
int64_t n;
|
||||
if(GetArgument(args,0,n))
|
||||
{
|
||||
if (GetArgument(args, 0, n)) {
|
||||
auto myevt = evt;
|
||||
return myevt.IsEvent((Tesses::Framework::Filesystem::FSWatcherEventType)n);
|
||||
|
||||
return myevt.IsEvent(
|
||||
(Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType)n);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
auto toString = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
|
||||
{
|
||||
auto toString = TExternalMethod::Create(
|
||||
ls, "", {},
|
||||
[evt](GCList &ls,
|
||||
std::vector<TObject> args) -> TObject {
|
||||
auto myevt = evt;
|
||||
return myevt.ToString();
|
||||
});
|
||||
|
||||
auto dict = TDictionary::Create(ls, {TDItem("IsDirectory",evt.isDir),TDItem("Type",(int64_t)evt.type),TDItem("Source",evt.src), TDItem("Destination",evt.dest),TDItem("ToString",toString),TDItem("IsEvent",isEvent)});
|
||||
auto dict = TDictionary::Create(
|
||||
ls, {TDItem("IsDirectory", evt.isDir),
|
||||
TDItem("Type", (int64_t)evt.type),
|
||||
TDItem("Source", evt.src),
|
||||
TDItem("Destination", evt.dest),
|
||||
TDItem("ToString", toString),
|
||||
TDItem("IsEvent", isEvent)});
|
||||
callable->Call(ls, {dict});
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
watcher->event = nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
if(name == "Start")
|
||||
{
|
||||
if (name == "Start") {
|
||||
watcher->SetEnabled(true);
|
||||
}
|
||||
if(name == "Stop")
|
||||
{
|
||||
if (name == "Stop") {
|
||||
watcher->SetEnabled(false);
|
||||
}
|
||||
if(name == "ToString")
|
||||
{
|
||||
if (name == "ToString") {
|
||||
return "FSWatcher";
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
std::string TypeName() {
|
||||
return "FSWatcher";
|
||||
}
|
||||
std::string TypeName() { 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;
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
|
||||
{
|
||||
return TNativeObject::Create<FS_Watcher>(ls,Tesses::Framework::Filesystem::FSWatcher::Create(vfs,path));
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
|
||||
return TNativeObject::Create<FS_Watcher>(
|
||||
ls, Tesses::Framework::Filesystem::FSWatcher::Create(vfs, path));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env, bool enable)
|
||||
{
|
||||
if(enable)
|
||||
{
|
||||
RegisterIO(gc,env,std::make_shared<RelativeFilesystem>(Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory()));
|
||||
}
|
||||
else
|
||||
{
|
||||
void TStd::RegisterIO(std::shared_ptr<GC> gc, TRootEnvironment *env,
|
||||
bool enable) {
|
||||
if (enable) {
|
||||
RegisterIO(
|
||||
gc, env,
|
||||
std::make_shared<Tesses::Framework::Filesystem::RelativeFilesystem>(
|
||||
Tesses::Framework::Filesystem::LocalFS,
|
||||
Tesses::Framework::Filesystem::VFSPath::
|
||||
GetAbsoluteCurrentDirectory()));
|
||||
} else {
|
||||
RegisterIO(gc, env, nullptr);
|
||||
}
|
||||
}
|
||||
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env,std::shared_ptr<RelativeFilesystem> fs)
|
||||
{
|
||||
void TStd::RegisterIO(
|
||||
std::shared_ptr<GC> gc, TRootEnvironment *env,
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::RelativeFilesystem> fs) {
|
||||
|
||||
env->permissions.canRegisterIO = true;
|
||||
env->permissions.localfs = fs;
|
||||
@@ -280,43 +265,77 @@ namespace Tesses::CrossLang
|
||||
|
||||
gc->BarrierBegin();
|
||||
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",
|
||||
{"vfs", "path"}, New_FSWatcher);
|
||||
auto dict = env->EnsureDictionary(gc, "FS");
|
||||
dict->SetValue("SEEK_SET",(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||
dict->SetValue("SEEK_CUR",(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
|
||||
dict->SetValue("SEEK_END",(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
|
||||
dict->SetValue("FSWatcherEvents",TDictionary::Create(ls,
|
||||
{
|
||||
TDItem("None", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::None),
|
||||
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Accessed),
|
||||
TDItem("AttributeChanged", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::AttributeChanged),
|
||||
TDItem("Writen", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
|
||||
TDItem("Read", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Read),
|
||||
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Created),
|
||||
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Deleted),
|
||||
TDItem("WatchEntryDeleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryDeleted),
|
||||
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Modified),
|
||||
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryMoved),
|
||||
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveOld),
|
||||
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveNew),
|
||||
TDItem("Opened", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
|
||||
TDItem("Closed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
|
||||
TDItem("Moved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
|
||||
TDItem("All", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::All)
|
||||
}
|
||||
));
|
||||
|
||||
if(fs)
|
||||
{
|
||||
dict->SetValue("SEEK_SET",
|
||||
(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||
dict->SetValue("SEEK_CUR",
|
||||
(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
|
||||
dict->SetValue("SEEK_END",
|
||||
(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
|
||||
dict->SetValue(
|
||||
"FSWatcherEvents",
|
||||
TDictionary::Create(
|
||||
ls,
|
||||
{TDItem(
|
||||
"None",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::None),
|
||||
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::Accessed),
|
||||
TDItem("AttributeChanged",
|
||||
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
|
||||
AttributeChanged),
|
||||
TDItem(
|
||||
"Writen",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
|
||||
TDItem(
|
||||
"Read",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Read),
|
||||
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::Created),
|
||||
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::Deleted),
|
||||
TDItem("WatchEntryDeleted",
|
||||
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
|
||||
WatchEntryDeleted),
|
||||
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::Modified),
|
||||
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::WatchEntryMoved),
|
||||
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::MoveOld),
|
||||
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::MoveNew),
|
||||
TDItem(
|
||||
"Opened",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
|
||||
TDItem(
|
||||
"Closed",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
|
||||
TDItem(
|
||||
"Moved",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
|
||||
TDItem(
|
||||
"All",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::All)}));
|
||||
|
||||
if (fs) {
|
||||
|
||||
dict->SetValue("Local", fs);
|
||||
dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},[fs](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
dict->DeclareFunction(
|
||||
gc, "MakeFull", "Make absolute path from relative path", {"path"},
|
||||
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if(GetArgumentAsPath(args,0,path))
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
if (GetArgumentAsPath(args, 0, path)) {
|
||||
if (path.relative) {
|
||||
auto myPath = fs->GetWorking() / path;
|
||||
myPath = myPath.CollapseRelativeParents();
|
||||
return myPath;
|
||||
@@ -325,31 +344,47 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
dict->DeclareFunction(gc,"getCurrentPath","Get current path",{},[fs](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
dict->DeclareFunction(
|
||||
gc, "getCurrentPath", "Get current path", {},
|
||||
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return fs->GetWorking();
|
||||
});
|
||||
dict->DeclareFunction(gc,"setCurrentPath","Set the current path",{"path"}, [fs](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
dict->DeclareFunction(
|
||||
gc, "setCurrentPath", "Set the current path", {"path"},
|
||||
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if(GetArgumentAsPath(args,0,path))
|
||||
{
|
||||
if (GetArgumentAsPath(args, 0, path)) {
|
||||
if (path.relative) {
|
||||
fs->SetWorking(path.MakeAbsolute(fs->GetWorking()));
|
||||
} else {
|
||||
fs->SetWorking(path);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
});
|
||||
}
|
||||
|
||||
dict->DeclareFunction(gc, "ReadAllText","Read all text from file", {"fs","filename"},FS_ReadAllText);
|
||||
dict->DeclareFunction(gc, "WriteAllText","Write all text to file", {"fs","filename","content"},FS_WriteAllText);
|
||||
dict->DeclareFunction(gc, "ReadAllText", "Read all text from file",
|
||||
{"fs", "filename"}, FS_ReadAllText);
|
||||
dict->DeclareFunction(gc, "WriteAllText", "Write all text to file",
|
||||
{"fs", "filename", "content"}, FS_WriteAllText);
|
||||
|
||||
dict->DeclareFunction(gc, "ReadAllLines","Read all lines from file", {"fs","filename"},FS_ReadAllLines);
|
||||
dict->DeclareFunction(gc, "WriteAllLines","Write all lines to file", {"fs","filename","lines"},FS_WriteAllLines);
|
||||
dict->DeclareFunction(gc, "ReadAllLines", "Read all lines from file",
|
||||
{"fs", "filename"}, FS_ReadAllLines);
|
||||
dict->DeclareFunction(gc, "WriteAllLines", "Write all lines to file",
|
||||
{"fs", "filename", "lines"}, FS_WriteAllLines);
|
||||
|
||||
dict->DeclareFunction(gc, "ReadAllBytes","Read all bytes from file", {"fs","filename"},FS_ReadAllBytes);
|
||||
dict->DeclareFunction(gc, "WriteAllBytes","Write all bytes to file", {"fs","filename","content"},FS_WriteAllBytes);
|
||||
dict->DeclareFunction(gc, "ReadAllBytes", "Read all bytes from file",
|
||||
{"fs", "filename"}, FS_ReadAllBytes);
|
||||
dict->DeclareFunction(gc, "WriteAllBytes", "Write all bytes to file",
|
||||
{"fs", "filename", "content"}, FS_WriteAllBytes);
|
||||
|
||||
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",{"fs","strm","name","version","info"},FS_CreateArchive);
|
||||
dict->DeclareFunction(gc,"ExtractArchive", "Extract a crvm archive",{"strm","vfs"},FS_ExtractArchive);
|
||||
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",
|
||||
{"fs", "strm", "name", "version", "info"},
|
||||
FS_CreateArchive);
|
||||
dict->DeclareFunction(gc, "ExtractArchive", "Extract a crvm archive",
|
||||
{"strm", "vfs"}, FS_ExtractArchive);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -2,52 +2,54 @@
|
||||
#include "CrossLang.hpp"
|
||||
using namespace Tesses::Framework::Serialization::Json;
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
static bool IsValidForJson(TObject v)
|
||||
{
|
||||
if(std::holds_alternative<std::nullptr_t>(v)) return true;
|
||||
static bool IsValidForJson(TObject v) {
|
||||
if (std::holds_alternative<std::nullptr_t>(v))
|
||||
return true;
|
||||
|
||||
if(std::holds_alternative<int64_t>(v)) return true;
|
||||
if (std::holds_alternative<int64_t>(v))
|
||||
return true;
|
||||
|
||||
if(std::holds_alternative<double>(v)) return true;
|
||||
if (std::holds_alternative<double>(v))
|
||||
return true;
|
||||
|
||||
if (std::holds_alternative<bool>(v))
|
||||
return true;
|
||||
|
||||
if(std::holds_alternative<bool>(v)) return true;
|
||||
if (std::holds_alternative<std::string>(v))
|
||||
return true;
|
||||
|
||||
|
||||
if(std::holds_alternative<std::string>(v)) return true;
|
||||
|
||||
|
||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
||||
{
|
||||
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||
auto res = std::get<THeapObjectHolder>(v);
|
||||
auto ls = dynamic_cast<TList *>(res.obj);
|
||||
auto dict = dynamic_cast<TDictionary *>(res.obj);
|
||||
if(ls != nullptr) return true;
|
||||
if(dict != nullptr) return true;
|
||||
if (ls != nullptr)
|
||||
return true;
|
||||
if (dict != nullptr)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static JToken JsonSerialize(TObject v)
|
||||
{
|
||||
if(std::holds_alternative<std::nullptr_t>(v)) return nullptr;
|
||||
if(std::holds_alternative<int64_t>(v)) return std::get<int64_t>(v);
|
||||
if(std::holds_alternative<double>(v)) return std::get<double>(v);
|
||||
if(std::holds_alternative<bool>(v)) return std::get<bool>(v);
|
||||
if(std::holds_alternative<std::string>(v)) return std::get<std::string>(v);
|
||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
||||
{
|
||||
static JToken JsonSerialize(TObject v) {
|
||||
if (std::holds_alternative<std::nullptr_t>(v))
|
||||
return nullptr;
|
||||
if (std::holds_alternative<int64_t>(v))
|
||||
return std::get<int64_t>(v);
|
||||
if (std::holds_alternative<double>(v))
|
||||
return std::get<double>(v);
|
||||
if (std::holds_alternative<bool>(v))
|
||||
return std::get<bool>(v);
|
||||
if (std::holds_alternative<std::string>(v))
|
||||
return std::get<std::string>(v);
|
||||
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||
auto obj = std::get<THeapObjectHolder>(v).obj;
|
||||
auto ls = dynamic_cast<TList *>(obj);
|
||||
auto dict = dynamic_cast<TDictionary *>(obj);
|
||||
|
||||
if(ls != nullptr)
|
||||
{
|
||||
if (ls != nullptr) {
|
||||
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);
|
||||
if (IsValidForJson(val))
|
||||
items.Add(JsonSerialize(val));
|
||||
@@ -55,11 +57,9 @@ namespace Tesses::CrossLang
|
||||
return items;
|
||||
}
|
||||
|
||||
if(dict != nullptr)
|
||||
{
|
||||
if (dict != nullptr) {
|
||||
JObject obj;
|
||||
for(auto item : dict->items)
|
||||
{
|
||||
for (auto item : dict->items) {
|
||||
if (IsValidForJson(item.second))
|
||||
obj.SetValue(item.first, JsonSerialize(item.second));
|
||||
}
|
||||
@@ -69,11 +69,11 @@ namespace Tesses::CrossLang
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
static TObject JsonEncode(GCList& ls2, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() >= 1)
|
||||
{
|
||||
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
|
||||
static TObject JsonEncode(GCList &ls2, std::vector<TObject> args) {
|
||||
if (args.size() >= 1) {
|
||||
bool indent =
|
||||
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
|
||||
std::get<bool>(args[1]));
|
||||
|
||||
auto json = JsonSerialize(args[0]);
|
||||
|
||||
@@ -81,41 +81,42 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
return "null";
|
||||
}
|
||||
static TObject JsonDocEncode(GCList& ls2, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() >= 1)
|
||||
{
|
||||
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
|
||||
static TObject JsonDocEncode(GCList &ls2, std::vector<TObject> args) {
|
||||
if (args.size() >= 1) {
|
||||
bool indent =
|
||||
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
|
||||
std::get<bool>(args[1]));
|
||||
|
||||
auto json = JsonSerialize(args[0]);
|
||||
JArray ar;
|
||||
if (TryGetJToken(json, ar))
|
||||
return Json::DocEncode(ar, indent);
|
||||
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static TObject JsonDeserialize(GCList& ls2,JToken json)
|
||||
{
|
||||
if(std::holds_alternative<JUndefined>(json)) return nullptr;
|
||||
if(std::holds_alternative<std::nullptr_t>(json)) return nullptr;
|
||||
static TObject JsonDeserialize(GCList &ls2, JToken json) {
|
||||
if (std::holds_alternative<JUndefined>(json))
|
||||
return nullptr;
|
||||
if (std::holds_alternative<std::nullptr_t>(json))
|
||||
return nullptr;
|
||||
bool b;
|
||||
int64_t _i64;
|
||||
double _f64;
|
||||
std::string str;
|
||||
JArray arr;
|
||||
JObject obj;
|
||||
if(TryGetJToken(json,b)) return b;
|
||||
if(TryGetJToken(json,_i64)) return _i64;
|
||||
if(TryGetJToken(json,_f64)) return _f64;
|
||||
if(TryGetJToken(json,str)) return str;
|
||||
if(TryGetJToken(json,arr))
|
||||
{
|
||||
if (TryGetJToken(json, b))
|
||||
return b;
|
||||
if (TryGetJToken(json, _i64))
|
||||
return _i64;
|
||||
if (TryGetJToken(json, _f64))
|
||||
return _f64;
|
||||
if (TryGetJToken(json, str))
|
||||
return str;
|
||||
if (TryGetJToken(json, arr)) {
|
||||
TList *ls = TList::Create(ls2);
|
||||
|
||||
for(auto& item : arr)
|
||||
{
|
||||
for (auto &item : arr) {
|
||||
auto itemRes = JsonDeserialize(ls2, item);
|
||||
ls2.GetGC()->BarrierBegin();
|
||||
ls->Add(itemRes);
|
||||
@@ -123,14 +124,11 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
return ls;
|
||||
}
|
||||
if(TryGetJToken(json,obj))
|
||||
{
|
||||
if (TryGetJToken(json, obj)) {
|
||||
|
||||
TDictionary *dict = TDictionary::Create(ls2);
|
||||
|
||||
|
||||
for(auto& item : obj)
|
||||
{
|
||||
for (auto &item : obj) {
|
||||
|
||||
auto itemRes = JsonDeserialize(ls2, item.second);
|
||||
ls2.GetGC()->BarrierBegin();
|
||||
@@ -141,67 +139,56 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
static TObject JsonDecode(GCList& ls2,std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
|
||||
{
|
||||
|
||||
|
||||
return JsonDeserialize(ls2, Json::Decode(std::get<std::string>(args[0])));
|
||||
|
||||
static TObject JsonDecode(GCList &ls2, std::vector<TObject> args) {
|
||||
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
|
||||
|
||||
return JsonDeserialize(ls2,
|
||||
Json::Decode(std::get<std::string>(args[0])));
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
static TObject JsonDocDecode(GCList& ls2,std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
|
||||
{
|
||||
|
||||
|
||||
return JsonDeserialize(ls2, Json::DocDecode(std::get<std::string>(args[0])));
|
||||
|
||||
static TObject JsonDocDecode(GCList &ls2, std::vector<TObject> args) {
|
||||
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
|
||||
|
||||
return JsonDeserialize(ls2,
|
||||
Json::DocDecode(std::get<std::string>(args[0])));
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
std::string Json_Encode(TObject o,bool indent)
|
||||
{
|
||||
std::string Json_Encode(TObject o, bool 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));
|
||||
}
|
||||
std::string Json_DocEncode(TObject o,bool indent)
|
||||
{
|
||||
std::string Json_DocEncode(TObject o, bool indent) {
|
||||
auto obj = JsonSerialize(o);
|
||||
JArray ls;
|
||||
if (TryGetJToken(obj, ls))
|
||||
return Json::DocEncode(ls, indent);
|
||||
return "";
|
||||
}
|
||||
TObject Json_DocDecode(GCList ls,std::string str)
|
||||
{
|
||||
TObject Json_DocDecode(GCList ls, std::string 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;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "Decode","Deserialize Json",{"jsonString"},JsonDecode);
|
||||
dict->DeclareFunction(gc, "Encode","Serialize Json",{"any","$indent"},JsonEncode);
|
||||
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc", {"jsonDocString"},JsonDocDecode);
|
||||
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc", {"ls","$indent"},JsonDocEncode);
|
||||
|
||||
|
||||
dict->DeclareFunction(gc, "Decode", "Deserialize Json", {"jsonString"},
|
||||
JsonDecode);
|
||||
dict->DeclareFunction(gc, "Encode", "Serialize Json", {"any", "$indent"},
|
||||
JsonEncode);
|
||||
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc",
|
||||
{"jsonDocString"}, JsonDocDecode);
|
||||
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc",
|
||||
{"ls", "$indent"}, JsonDocEncode);
|
||||
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Json", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,44 +1,38 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
#if defined(GEKKO)
|
||||
#include <ogcsys.h>
|
||||
#include <gccore.h>
|
||||
#include <ogc/pad.h>
|
||||
#include <ogcsys.h>
|
||||
#if defined(HW_RVL)
|
||||
#include <wiiuse/wpad.h>
|
||||
#endif
|
||||
#endif
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
#if defined(GEKKO)
|
||||
#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();
|
||||
}
|
||||
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;
|
||||
if (GetArgument(args, 0, chan))
|
||||
return (int64_t)WPAD_ButtonsUp((int)chan);
|
||||
return 0;
|
||||
}
|
||||
static TObject OGC_WPAD_ButtonsDown(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject OGC_WPAD_ButtonsDown(GCList &ls, std::vector<TObject> args) {
|
||||
int64_t chan;
|
||||
if (GetArgument(args, 0, chan))
|
||||
return (int64_t)WPAD_ButtonsDown((int)chan);
|
||||
return 0;
|
||||
}
|
||||
static TObject OGC_WPAD_ButtonsHeld(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject OGC_WPAD_ButtonsHeld(GCList &ls, std::vector<TObject> args) {
|
||||
int64_t chan;
|
||||
if (GetArgument(args, 0, chan))
|
||||
return (int64_t)WPAD_ButtonsDown((int)chan);
|
||||
return 0;
|
||||
}
|
||||
static TObject OGC_WPAD_BatteryLevel(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject OGC_WPAD_BatteryLevel(GCList &ls, std::vector<TObject> args) {
|
||||
int64_t chan;
|
||||
if (GetArgument(args, 0, chan))
|
||||
return (int64_t)WPAD_BatteryLevel((int)chan);
|
||||
@@ -46,19 +40,19 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
#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);
|
||||
#if defined(GEKKO)
|
||||
|
||||
|
||||
gc->BarrierBegin();
|
||||
|
||||
TDictionary *dict_ogc_pad = TDictionary::Create(ls);
|
||||
#if defined(HW_RVL)
|
||||
TDictionary *dict_rvl_wpad = TDictionary::Create(ls);
|
||||
dict_rvl_wpad->DeclareFunction(gc, "ScanPads","Scan wiimotes",{},OGC_WPAD_ScanPads);
|
||||
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown","Is button down",{"pad"},OGC_WPAD_ButtonsDown);
|
||||
dict_rvl_wpad->DeclareFunction(gc, "ScanPads", "Scan wiimotes", {},
|
||||
OGC_WPAD_ScanPads);
|
||||
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown", "Is button down", {"pad"},
|
||||
OGC_WPAD_ButtonsDown);
|
||||
dict_rvl_wpad->SetValue("BUTTON_A", (int64_t)WPAD_BUTTON_A);
|
||||
dict_rvl_wpad->SetValue("BUTTON_B", (int64_t)WPAD_BUTTON_B);
|
||||
dict_rvl_wpad->SetValue("BUTTON_HOME", (int64_t)WPAD_BUTTON_HOME);
|
||||
@@ -77,8 +71,5 @@ namespace Tesses::CrossLang
|
||||
gc->BarrierEnd();
|
||||
#endif
|
||||
env->permissions.canRegisterOGC = true;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,60 +1,51 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
bool GetObjectAsPath(TObject& obj, Tesses::Framework::Filesystem::VFSPath& path, bool allowString)
|
||||
{
|
||||
if(GetObject(obj,path)) return true;
|
||||
namespace Tesses::CrossLang {
|
||||
bool GetObjectAsPath(TObject &obj, Tesses::Framework::Filesystem::VFSPath &path,
|
||||
bool allowString) {
|
||||
if (GetObject(obj, path))
|
||||
return true;
|
||||
std::string str;
|
||||
if(allowString && GetObject<std::string>(obj,str))
|
||||
{
|
||||
if (allowString && GetObject<std::string>(obj, str)) {
|
||||
path = Tesses::Framework::Filesystem::VFSPath(str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool GetArgumentAsPath(std::vector<TObject>& args, size_t index, Tesses::Framework::Filesystem::VFSPath& path,bool allowString)
|
||||
{
|
||||
if(GetArgument(args,index,path)) return true;
|
||||
bool GetArgumentAsPath(std::vector<TObject> &args, size_t index,
|
||||
Tesses::Framework::Filesystem::VFSPath &path,
|
||||
bool allowString) {
|
||||
if (GetArgument(args, index, path))
|
||||
return true;
|
||||
std::string str;
|
||||
if(allowString && GetArgument<std::string>(args,index,str))
|
||||
{
|
||||
if (allowString && GetArgument<std::string>(args, index, str)) {
|
||||
path = Tesses::Framework::Filesystem::VFSPath(str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static TObject Path_Root(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
auto res = Tesses::Framework::Filesystem::VFSPath();\
|
||||
static TObject Path_Root(GCList &ls, std::vector<TObject> args) {
|
||||
auto res = Tesses::Framework::Filesystem::VFSPath();
|
||||
res.relative = false;
|
||||
return res;
|
||||
}
|
||||
static TObject Path_FromString(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Path_FromString(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
if (GetArgument(args, 0, str)) {
|
||||
return Tesses::Framework::Filesystem::VFSPath(str);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Path_Create(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Path_Create(GCList &ls, std::vector<TObject> args) {
|
||||
TList *myls;
|
||||
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;
|
||||
for(int64_t i = 0; i < myls->Count(); i++)
|
||||
{
|
||||
for (int64_t i = 0; i < myls->Count(); i++) {
|
||||
std::string str;
|
||||
TObject o = myls->Get(i);
|
||||
if(GetObject<std::string>(o,str))
|
||||
{
|
||||
if (GetObject<std::string>(o, str)) {
|
||||
items.push_back(str);
|
||||
}
|
||||
}
|
||||
@@ -65,19 +56,21 @@ namespace Tesses::CrossLang
|
||||
|
||||
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;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
|
||||
gc->BarrierBegin();
|
||||
dict->DeclareFunction(gc,"FromString","Create a Path from string",{"path"},Path_FromString);
|
||||
dict->DeclareFunction(gc, "FromString", "Create a Path from string",
|
||||
{"path"}, Path_FromString);
|
||||
|
||||
dict->DeclareFunction(gc,"Create","Create a Path from parts",{"relative","parts"},Path_Create);
|
||||
dict->DeclareFunction(gc,"Root","Create Absolute Root Path",{}, Path_Root);
|
||||
dict->DeclareFunction(gc, "Create", "Create a Path from parts",
|
||||
{"relative", "parts"}, Path_Create);
|
||||
dict->DeclareFunction(gc, "Root", "Create Absolute Root Path", {},
|
||||
Path_Root);
|
||||
env->DeclareVariable("Path", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,19 +1,13 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
class ProcessObject : public TNativeObject {
|
||||
public:
|
||||
ProcessObject()
|
||||
{
|
||||
ProcessObject() {
|
||||
arguments = nullptr;
|
||||
environment = nullptr;
|
||||
|
||||
}
|
||||
ProcessObject(GCList& ls)
|
||||
{
|
||||
ProcessObject(GCList &ls) {
|
||||
arguments = TList::Create(ls);
|
||||
environment = TList::Create(ls);
|
||||
process.includeThisEnv = true;
|
||||
@@ -26,178 +20,153 @@ namespace Tesses::CrossLang
|
||||
TList *arguments;
|
||||
TList *environment;
|
||||
Tesses::Framework::Platform::Process process;
|
||||
std::string TypeName()
|
||||
{
|
||||
return "Process";
|
||||
}
|
||||
void Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
std::string TypeName() { return "Process"; }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
if(arguments != nullptr) arguments->Mark();
|
||||
if(environment != nullptr) environment->Mark();
|
||||
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))
|
||||
{
|
||||
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args) {
|
||||
if (key == "setFileName" && GetArgument(args, 0, process.name)) {
|
||||
return process.name;
|
||||
}
|
||||
if(key == "getFileName")
|
||||
{
|
||||
if (key == "getFileName") {
|
||||
return process.name;
|
||||
}
|
||||
|
||||
if(key == "setRedirectStandardInput" && GetArgument(args,0,process.redirectStdIn))
|
||||
{
|
||||
if (key == "setRedirectStandardInput" &&
|
||||
GetArgument(args, 0, process.redirectStdIn)) {
|
||||
return process.redirectStdIn;
|
||||
}
|
||||
if(key == "getRedirectStandardInput")
|
||||
{
|
||||
if (key == "getRedirectStandardInput") {
|
||||
return process.redirectStdIn;
|
||||
}
|
||||
if(key == "setRedirectStandardOutput" && GetArgument(args,0,process.redirectStdOut))
|
||||
{
|
||||
if (key == "setRedirectStandardOutput" &&
|
||||
GetArgument(args, 0, process.redirectStdOut)) {
|
||||
return process.redirectStdOut;
|
||||
}
|
||||
if(key == "getRedirectStandardOutput")
|
||||
{
|
||||
if (key == "getRedirectStandardOutput") {
|
||||
return process.redirectStdOut;
|
||||
}
|
||||
if(key == "setRedirectStandardError" && GetArgument(args,0,process.redirectStdErr))
|
||||
{
|
||||
if (key == "setRedirectStandardError" &&
|
||||
GetArgument(args, 0, process.redirectStdErr)) {
|
||||
return process.redirectStdErr;
|
||||
}
|
||||
if(key == "getRedirectStandardError")
|
||||
{
|
||||
if (key == "getRedirectStandardError") {
|
||||
return process.redirectStdErr;
|
||||
}
|
||||
if(key == "setWorkingDirectory" && GetArgument(args,0,process.workingDirectory))
|
||||
{
|
||||
if (key == "setWorkingDirectory" &&
|
||||
GetArgument(args, 0, process.workingDirectory)) {
|
||||
return process.workingDirectory;
|
||||
}
|
||||
if(key == "getWorkingDirectory")
|
||||
{
|
||||
if (key == "getWorkingDirectory") {
|
||||
return process.workingDirectory;
|
||||
}
|
||||
if(key == "setInheritParentEnvironment" && GetArgument(args,0,process.includeThisEnv))
|
||||
{
|
||||
if (key == "setInheritParentEnvironment" &&
|
||||
GetArgument(args, 0, process.includeThisEnv)) {
|
||||
return process.includeThisEnv;
|
||||
}
|
||||
if(key == "getInheritParentEnvironment")
|
||||
{
|
||||
if (key == "getInheritParentEnvironment") {
|
||||
return process.includeThisEnv;
|
||||
}
|
||||
if(key == "getArguments")
|
||||
{
|
||||
if(arguments == nullptr) return nullptr;
|
||||
if (key == "getArguments") {
|
||||
if (arguments == nullptr)
|
||||
return nullptr;
|
||||
return arguments;
|
||||
}
|
||||
if(key == "setArguments")
|
||||
{
|
||||
if(GetArgumentHeap(args,0,arguments))
|
||||
{
|
||||
if (key == "setArguments") {
|
||||
if (GetArgumentHeap(args, 0, arguments)) {
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
if(key == "getEnvironment")
|
||||
{
|
||||
if(environment == nullptr) return nullptr;
|
||||
if (key == "getEnvironment") {
|
||||
if (environment == nullptr)
|
||||
return nullptr;
|
||||
return environment;
|
||||
}
|
||||
if(key == "getEnvironment")
|
||||
{
|
||||
if(GetArgumentHeap(args,0,environment))
|
||||
{
|
||||
if (key == "getEnvironment") {
|
||||
if (GetArgumentHeap(args, 0, environment)) {
|
||||
return environment;
|
||||
}
|
||||
}
|
||||
if(key == "Start")
|
||||
{
|
||||
if (key == "Start") {
|
||||
this->process.args.push_back(process.name);
|
||||
if(arguments != nullptr)
|
||||
{
|
||||
for(int64_t i = 0; i < arguments->Count(); i++)
|
||||
{
|
||||
if (arguments != nullptr) {
|
||||
for (int64_t i = 0; i < arguments->Count(); i++) {
|
||||
TObject argVal = arguments->Get(i);
|
||||
std::string argValStr;
|
||||
if (GetObject(argVal, argValStr))
|
||||
this->process.args.push_back(argValStr);
|
||||
}
|
||||
}
|
||||
if(environment != nullptr)
|
||||
{
|
||||
for(int64_t i = 0; i < environment->Count(); i++)
|
||||
{
|
||||
if (environment != nullptr) {
|
||||
for (int64_t i = 0; i < environment->Count(); i++) {
|
||||
TObject arg = environment->Get(i);
|
||||
std::string argstr;
|
||||
if(GetObject(arg,argstr))
|
||||
{
|
||||
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
|
||||
if(kvp.size()==2)
|
||||
{
|
||||
process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
|
||||
}
|
||||
else if(kvp.size()==1)
|
||||
{
|
||||
process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
|
||||
if (GetObject(arg, argstr)) {
|
||||
auto kvp =
|
||||
Tesses::Framework::Http::HttpUtils::SplitString(
|
||||
argstr, "=", 2);
|
||||
if (kvp.size() == 2) {
|
||||
process.env.push_back(
|
||||
std::pair<std::string, std::string>(kvp[0],
|
||||
kvp[1]));
|
||||
} else if (kvp.size() == 1) {
|
||||
process.env.push_back(
|
||||
std::pair<std::string, std::string>(kvp[0],
|
||||
""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return process.Start();
|
||||
}
|
||||
if(key == "Join" || key == "WaitForExit")
|
||||
{
|
||||
if (key == "Join" || key == "WaitForExit") {
|
||||
return (int64_t)process.WaitForExit();
|
||||
}
|
||||
if(key == "getHasExited")
|
||||
{
|
||||
if (key == "getHasExited") {
|
||||
return process.HasExited();
|
||||
}
|
||||
if(key == "Terminate")
|
||||
{
|
||||
if (key == "Terminate") {
|
||||
process.Kill(SIGTERM);
|
||||
}
|
||||
if(key == "CloseStdInNow")
|
||||
{
|
||||
if (key == "CloseStdInNow") {
|
||||
process.CloseStdInNow();
|
||||
|
||||
}
|
||||
int64_t k;
|
||||
if(key == "Kill" && GetArgument(args,0,k))
|
||||
{
|
||||
if (key == "Kill" && GetArgument(args, 0, k)) {
|
||||
process.Kill((int)k);
|
||||
}
|
||||
if(key == "getStandardInput")
|
||||
{
|
||||
if (key == "getStandardInput") {
|
||||
return process.GetStdinStream();
|
||||
}
|
||||
if(key == "getStandardOutput")
|
||||
{
|
||||
if (key == "getStandardOutput") {
|
||||
return process.GetStdoutStream();
|
||||
}
|
||||
if(key == "getStandardError")
|
||||
{
|
||||
if (key == "getStandardError") {
|
||||
return process.GetStderrStream();
|
||||
}
|
||||
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({
|
||||
// FileName = "git",
|
||||
// Arguments = ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
|
||||
// Arguments =
|
||||
// ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
|
||||
// Environment = [],
|
||||
// InheritParentEnvironment=true
|
||||
// })
|
||||
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
auto process = TNativeObject::Create<ProcessObject>(ls);
|
||||
auto name = dict->GetValue("FileName");
|
||||
auto inh = dict->GetValue("InheritParentEnvironment");
|
||||
@@ -220,58 +189,50 @@ namespace Tesses::CrossLang
|
||||
GetObject(name, process->process.name);
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPath wdPath;
|
||||
if(env->permissions.localfs)
|
||||
{
|
||||
process->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
|
||||
if (env->permissions.localfs) {
|
||||
process->process.workingDirectory =
|
||||
env->permissions.localfs->GetWorking().ToString();
|
||||
}
|
||||
|
||||
if(GetObject(workingDirectory,wdPath))
|
||||
{
|
||||
process->process.workingDirectory= wdPath.MakeAbsolute().ToString();
|
||||
if (GetObject(workingDirectory, wdPath)) {
|
||||
process->process.workingDirectory =
|
||||
wdPath.MakeAbsolute().ToString();
|
||||
}
|
||||
|
||||
GetObject(workingDirectory, process->process.workingDirectory);
|
||||
|
||||
|
||||
|
||||
process->process.args.push_back(process->process.name);
|
||||
auto argumentsO = dict->GetValue("Arguments");
|
||||
TList *arguments;
|
||||
if(GetObjectHeap(argumentsO,arguments))
|
||||
{
|
||||
for(int64_t i = 0; i < arguments->Count(); i++)
|
||||
{
|
||||
if (GetObjectHeap(argumentsO, arguments)) {
|
||||
for (int64_t i = 0; i < arguments->Count(); i++) {
|
||||
TObject arg = arguments->Get(i);
|
||||
std::string argstr;
|
||||
if(GetObject(arg,argstr))
|
||||
{
|
||||
if (GetObject(arg, argstr)) {
|
||||
process->process.args.push_back(argstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
argumentsO = dict->GetValue("Environment");
|
||||
if(GetObjectHeap(argumentsO,arguments))
|
||||
{
|
||||
for(int64_t i = 0; i < arguments->Count(); i++)
|
||||
{
|
||||
if (GetObjectHeap(argumentsO, arguments)) {
|
||||
for (int64_t i = 0; i < arguments->Count(); i++) {
|
||||
TObject arg = arguments->Get(i);
|
||||
std::string argstr;
|
||||
if(GetObject(arg,argstr))
|
||||
{
|
||||
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
|
||||
if(kvp.size()==2)
|
||||
{
|
||||
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
|
||||
}
|
||||
else if(kvp.size()==1)
|
||||
{
|
||||
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
|
||||
if (GetObject(arg, argstr)) {
|
||||
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(
|
||||
argstr, "=", 2);
|
||||
if (kvp.size() == 2) {
|
||||
process->process.env.push_back(
|
||||
std::pair<std::string, std::string>(kvp[0],
|
||||
kvp[1]));
|
||||
} else if (kvp.size() == 1) {
|
||||
process->process.env.push_back(
|
||||
std::pair<std::string, std::string>(kvp[0], ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(process->process.Start())
|
||||
{
|
||||
if (process->process.Start()) {
|
||||
return process;
|
||||
}
|
||||
}
|
||||
@@ -279,43 +240,56 @@ namespace Tesses::CrossLang
|
||||
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;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
|
||||
gc->BarrierBegin();
|
||||
auto processStart = TExternalMethod::Create(ls,"Start a process",{"process_object"},[env](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
auto processStart = TExternalMethod::Create(
|
||||
ls, "Start a process", {"process_object"},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Process_Start(ls, args, env);
|
||||
});
|
||||
processStart->watch.push_back(env);
|
||||
dict->SetValue("Start", processStart);
|
||||
|
||||
|
||||
env->SetVariable("Process", dict);
|
||||
auto process = env->EnsureDictionary(gc, "New");
|
||||
auto newProcess = TExternalMethod::Create(ls, "Create process",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
auto newProcess = TExternalMethod::Create(
|
||||
ls, "Create process", {},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
auto obj = TNativeObject::Create<ProcessObject>(ls, ls);
|
||||
if(env->permissions.localfs)
|
||||
{
|
||||
obj->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
|
||||
if (env->permissions.localfs) {
|
||||
obj->process.workingDirectory =
|
||||
env->permissions.localfs->GetWorking().ToString();
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
newProcess->watch.push_back(env);
|
||||
process->SetValue("Process", newProcess);
|
||||
// process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
|
||||
process->DeclareFunction(gc, "CGIServer", "Create a CGI Server",{"path"},[](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
process->DeclareFunction(
|
||||
gc, "CGIServer", "Create a CGI Server", {"path"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if(GetArgumentAsPath(args,0,path))
|
||||
{
|
||||
return std::make_shared<Tesses::Framework::Http::CGIServer>(path);
|
||||
if (GetArgumentAsPath(args, 0, path)) {
|
||||
return std::make_shared<Tesses::Framework::Http::CGIServer>(
|
||||
path);
|
||||
}
|
||||
return Undefined();
|
||||
});
|
||||
|
||||
process->DeclareFunction(
|
||||
gc, "ShellFileOrUrl", "Launch file or url in shell", {"urlOrFilename"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
std::string fileOrUrl;
|
||||
if (GetArgument(args, 0, fileOrUrl))
|
||||
Tesses::Framework::Platform::ShellFileOrUrl(fileOrUrl);
|
||||
|
||||
return Undefined();
|
||||
});
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
@@ -5,83 +5,106 @@
|
||||
namespace Tesses::CrossLang {
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
||||
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;
|
||||
double d;
|
||||
bool b;
|
||||
|
||||
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
if (GetArgument(args, 0, str)) {
|
||||
return SQLiteDatabase::Escape(str);
|
||||
}
|
||||
if(GetArgument(args,0,n))
|
||||
{
|
||||
if (GetArgument(args, 0, n)) {
|
||||
return std::to_string(n);
|
||||
}
|
||||
if(GetArgument(args,0,b))
|
||||
{
|
||||
if (GetArgument(args, 0, b)) {
|
||||
return b ? "1" : "0";
|
||||
}
|
||||
if(GetArgument(args,0,d))
|
||||
{
|
||||
if (GetArgument(args, 0, d)) {
|
||||
return std::to_string(d);
|
||||
}
|
||||
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
TObject Sqlite_Prepare(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
TList *list;
|
||||
|
||||
class SQLiteObject : public TNativeObject
|
||||
{
|
||||
std::string newStr = "";
|
||||
if (GetArgument(args, 0, str) && GetArgumentHeap(args, 1, list)) {
|
||||
int64_t item = 0;
|
||||
|
||||
for (size_t i = 0; i < str.size(); i++) {
|
||||
if (str[i] == '@' && (i + 1 >= str.size() || str[i + 1] != '@')) {
|
||||
auto v = list->Get(item);
|
||||
int64_t n;
|
||||
double d;
|
||||
bool b;
|
||||
|
||||
std::string str;
|
||||
if (GetObject(v, str)) {
|
||||
newStr += SQLiteDatabase::Escape(str);
|
||||
} else if (GetObject(v, n)) {
|
||||
newStr += std::to_string(n);
|
||||
} else if (GetObject(v, b)) {
|
||||
newStr += (b ? "1" : "0");
|
||||
} else if (GetObject(v, d)) {
|
||||
newStr += std::to_string(d);
|
||||
} else {
|
||||
|
||||
newStr += "NULL";
|
||||
}
|
||||
} else {
|
||||
newStr += str[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return newStr;
|
||||
}
|
||||
|
||||
class SQLiteObject : public TNativeObject {
|
||||
public:
|
||||
SQLiteDatabase *db;
|
||||
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
db = new SQLiteDatabase(path);
|
||||
}
|
||||
|
||||
std::string TypeName()
|
||||
{
|
||||
return "SQLiteDatabase";
|
||||
}
|
||||
void Close()
|
||||
{
|
||||
if(this->db == nullptr) return;
|
||||
std::string TypeName() { return "SQLiteDatabase"; }
|
||||
void Close() {
|
||||
if (this->db == nullptr)
|
||||
return;
|
||||
delete this->db;
|
||||
this->db = nullptr;
|
||||
|
||||
}
|
||||
bool ToBool()
|
||||
{
|
||||
return 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();
|
||||
TObject CallMethod(GCList &ls, std::string name,
|
||||
std::vector<TObject> args) {
|
||||
if (name == "Close")
|
||||
this->Close();
|
||||
if (name == "Escape") {
|
||||
return Sqlite_Escape(ls, args);
|
||||
}
|
||||
if(name == "Exec")
|
||||
{
|
||||
if (name == "Prepare") {
|
||||
return Sqlite_Prepare(ls, args);
|
||||
}
|
||||
if (name == "Exec") {
|
||||
std::string arg;
|
||||
if(GetArgument(args,0,arg))
|
||||
{
|
||||
if(this->db == nullptr) return nullptr;
|
||||
std::vector<std::vector<std::pair<std::string, std::optional<std::string>>>> res;
|
||||
if (GetArgument(args, 0, arg)) {
|
||||
if (this->db == nullptr)
|
||||
return nullptr;
|
||||
std::vector<std::vector<
|
||||
std::pair<std::string, std::optional<std::string>>>>
|
||||
res;
|
||||
|
||||
this->db->Exec(arg, res);
|
||||
|
||||
TList *list = TList::Create(ls);
|
||||
|
||||
for(auto& item : res)
|
||||
{
|
||||
for (auto &item : res) {
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
for(auto& item2 : item)
|
||||
{
|
||||
for (auto &item2 : item) {
|
||||
if (item2.second)
|
||||
dict->SetValue(item2.first, item2.second.value());
|
||||
else
|
||||
@@ -97,21 +120,17 @@ namespace Tesses::CrossLang {
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
|
||||
~SQLiteObject()
|
||||
{
|
||||
~SQLiteObject() {
|
||||
if (this->db != nullptr)
|
||||
delete this->db;
|
||||
}
|
||||
};
|
||||
|
||||
TObject Sqlite_Open(GCList& ls, std::vector<TObject> args,TRootEnvironment* env)
|
||||
{
|
||||
TObject Sqlite_Open(GCList &ls, std::vector<TObject> args,
|
||||
TRootEnvironment *env) {
|
||||
Tesses::Framework::Filesystem::VFSPath p;
|
||||
if(GetArgumentAsPath(args,0,p))
|
||||
{
|
||||
if(env->permissions.sqlite3Scoped)
|
||||
{
|
||||
if (GetArgumentAsPath(args, 0, p)) {
|
||||
if (env->permissions.sqlite3Scoped) {
|
||||
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
|
||||
}
|
||||
|
||||
@@ -119,54 +138,57 @@ namespace Tesses::CrossLang {
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
|
||||
}
|
||||
TObject Sqlite_Exec(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TObject Sqlite_Exec(GCList &ls, std::vector<TObject> args) {
|
||||
SQLiteObject *sql;
|
||||
std::string cmd;
|
||||
if(GetArgumentHeap(args,0,sql) && GetArgument(args,1,cmd))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, sql) && GetArgument(args, 1, cmd)) {
|
||||
try {
|
||||
return sql->CallMethod(ls, "Exec", {cmd});
|
||||
} catch(std::runtime_error& ex)
|
||||
{
|
||||
} catch (std::runtime_error &ex) {
|
||||
return (std::string)ex.what();
|
||||
}
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
|
||||
}
|
||||
|
||||
TObject Sqlite_Close(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TObject Sqlite_Close(GCList &ls, std::vector<TObject> args) {
|
||||
SQLiteObject *sql;
|
||||
if(GetArgumentHeap(args,0,sql))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, sql)) {
|
||||
sql->Close();
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
#endif
|
||||
void TStd::RegisterSqlite(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
void TStd::RegisterSqlite(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterSqlite = true;
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc,"Open","Opens the database (returns database handle or an error message as string or undefined)",{"filename"},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
dict->DeclareFunction(
|
||||
gc, "Open",
|
||||
"Opens the database (returns database handle or an error message as "
|
||||
"string or undefined)",
|
||||
{"filename"}, [env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Sqlite_Open(ls, args, env);
|
||||
});
|
||||
dict->DeclareFunction(gc,"Exec","Execute sql (returns dictionary of columns key=value, an error message as string or undefined)",{"handle","sql"},Sqlite_Exec);
|
||||
dict->DeclareFunction(gc,"Close","Close sql database",{"handle"},Sqlite_Close);
|
||||
dict->DeclareFunction(gc,"Escape","Escape sql text",{"text"},Sqlite_Escape);
|
||||
dict->DeclareFunction(gc, "Exec",
|
||||
"Execute sql (returns dictionary of columns "
|
||||
"key=value, an error message as string or undefined)",
|
||||
{"handle", "sql"}, Sqlite_Exec);
|
||||
dict->DeclareFunction(gc, "Close", "Close sql database", {"handle"},
|
||||
Sqlite_Close);
|
||||
dict->DeclareFunction(gc, "Escape", "Escape sql text", {"text"},
|
||||
Sqlite_Escape);
|
||||
dict->DeclareFunction(gc, "Prepare", "Prepare sql", {"sql", "items"},
|
||||
Sqlite_Prepare);
|
||||
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Sqlite", dict);
|
||||
gc->BarrierEnd();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,40 +1,42 @@
|
||||
#include "TessesFramework/Uuid.hpp"
|
||||
#include "CrossLang.hpp"
|
||||
#include "TessesFramework/Serialization/BitConverter.hpp"
|
||||
#include "TessesFramework/Uuid.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
static TObject Uuid_NewUuid(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Uuid_NewUuid(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Uuid::Generate();
|
||||
}
|
||||
static TObject Uuid_TryParse(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Uuid_TryParse(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
Tesses::Framework::Uuid uuid;
|
||||
if(GetArgument(args, 0, str) && Tesses::Framework::Uuid::TryParse(str,uuid))
|
||||
if (GetArgument(args, 0, str) &&
|
||||
Tesses::Framework::Uuid::TryParse(str, uuid))
|
||||
return uuid;
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Uuid_FromBytes(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject Uuid_FromBytes(GCList &ls, std::vector<TObject> args) {
|
||||
TByteArray *ba;
|
||||
int64_t index;
|
||||
if(GetArgumentHeap(args,0,ba) && GetArgument(args, 1, index) && (size_t)index < ba->data.size() && (size_t)index + 16 <= ba->data.size())
|
||||
{
|
||||
return Tesses::Framework::Serialization::BitConverter::ToUuid(ba->data[(size_t)index]);
|
||||
if (GetArgumentHeap(args, 0, ba) && GetArgument(args, 1, index) &&
|
||||
(size_t)index < ba->data.size() &&
|
||||
(size_t)index + 16 <= ba->data.size()) {
|
||||
return Tesses::Framework::Serialization::BitConverter::ToUuid(
|
||||
ba->data[(size_t)index]);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment* env)
|
||||
{
|
||||
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
gc->BarrierBegin();
|
||||
TDictionary *guid = env->EnsureDictionary(gc, "Uuid");
|
||||
guid->DeclareFunction(gc,"NewUuid","Create random uuid",{},Uuid_NewUuid);
|
||||
guid->DeclareFunction(gc, "TryParse","Try to parse",{"str"}, Uuid_TryParse);
|
||||
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",{"byteArray","offset"}, Uuid_FromBytes);
|
||||
guid->DeclareFunction(gc, "NewUuid", "Create random uuid", {},
|
||||
Uuid_NewUuid);
|
||||
guid->DeclareFunction(gc, "TryParse", "Try to parse", {"str"},
|
||||
Uuid_TryParse);
|
||||
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",
|
||||
{"byteArray", "offset"}, Uuid_FromBytes);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,58 +1,46 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#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))
|
||||
return nullptr;
|
||||
if(std::holds_alternative<int64_t>(node))
|
||||
{
|
||||
if (std::holds_alternative<int64_t>(node)) {
|
||||
return std::get<int64_t>(node);
|
||||
}
|
||||
if(std::holds_alternative<double>(node))
|
||||
{
|
||||
if (std::holds_alternative<double>(node)) {
|
||||
return std::get<double>(node);
|
||||
}
|
||||
if(std::holds_alternative<bool>(node))
|
||||
{
|
||||
if (std::holds_alternative<bool>(node)) {
|
||||
return std::get<bool>(node);
|
||||
}
|
||||
if(std::holds_alternative<std::string>(node))
|
||||
{
|
||||
if (std::holds_alternative<std::string>(node)) {
|
||||
std::string str = std::get<std::string>(node);
|
||||
return str;
|
||||
}
|
||||
if(std::holds_alternative<char>(node))
|
||||
{
|
||||
if (std::holds_alternative<char>(node)) {
|
||||
char c = std::get<char>(node);
|
||||
return c;
|
||||
}
|
||||
if(std::holds_alternative<Undefined>(node))
|
||||
{
|
||||
if (std::holds_alternative<Undefined>(node)) {
|
||||
auto r = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
r->SetValue("Type", std::string(UndefinedExpression));
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(std::holds_alternative<AdvancedSyntaxNode>(node))
|
||||
{
|
||||
if (std::holds_alternative<AdvancedSyntaxNode>(node)) {
|
||||
auto asn = std::get<AdvancedSyntaxNode>(node);
|
||||
auto r = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
r->SetValue("Type", asn.nodeName);
|
||||
r->SetValue("IsExpression", asn.isExpression);
|
||||
TList *ls2 = TList::Create(ls);
|
||||
for(auto item : asn.nodes)
|
||||
{
|
||||
for (auto item : asn.nodes) {
|
||||
ls2->Add(AstToTObject(ls, item));
|
||||
}
|
||||
r->SetValue("Arguments", ls2);
|
||||
@@ -61,16 +49,13 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
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;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
if (GetArgument(args, 0, str)) {
|
||||
std::stringstream strm(str);
|
||||
std::vector<LexToken> tokens;
|
||||
int res = Lex("memory.tcross", strm, tokens);
|
||||
if(res != 0)
|
||||
{
|
||||
if (res != 0) {
|
||||
throw VMException("Lex error at line: " + std::to_string(res));
|
||||
}
|
||||
Parser p(tokens);
|
||||
@@ -79,20 +64,16 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
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;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
if(current_function != nullptr)
|
||||
{
|
||||
if (GetArgument(args, 0, str)) {
|
||||
if (current_function != nullptr) {
|
||||
return current_function->env->Eval(ls, str);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Failure(GCList& ls, std::string reason)
|
||||
{
|
||||
static TObject Failure(GCList &ls, std::string reason) {
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Success", false);
|
||||
@@ -100,24 +81,24 @@ namespace Tesses::CrossLang
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
static TObject Success(GCList& ls)
|
||||
{
|
||||
static TObject Success(GCList &ls) {
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Success", true);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
static TObject VM_getCurrentEnvironment(GCList& ls2,std::vector<TObject> args)
|
||||
{
|
||||
if(current_function != nullptr) return current_function->env;
|
||||
static TObject VM_getCurrentEnvironment(GCList &ls2,
|
||||
std::vector<TObject> args) {
|
||||
if (current_function != nullptr)
|
||||
return current_function->env;
|
||||
return Undefined();
|
||||
}
|
||||
static TObject VM_Compile(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
static TObject VM_Compile(GCList &ls, std::vector<TObject> args) {
|
||||
try {
|
||||
TDictionary *dict;
|
||||
if(!GetArgumentHeap<TDictionary*>(args,0,dict)) return Undefined();
|
||||
if (!GetArgumentHeap<TDictionary *>(args, 0, dict))
|
||||
return Undefined();
|
||||
/*
|
||||
VM.Compile
|
||||
{
|
||||
@@ -133,7 +114,9 @@ namespace Tesses::CrossLang
|
||||
|
||||
std::string name = "Out";
|
||||
std::vector<std::pair<std::string, std::string>> sources;
|
||||
TVMVersion version(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||
TVMVersion version(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
|
||||
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
|
||||
CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||
std::vector<std::pair<std::string, TVMVersion>> dependencies;
|
||||
std::vector<std::pair<std::string, TVMVersion>> tools;
|
||||
std::string info;
|
||||
@@ -155,7 +138,8 @@ namespace Tesses::CrossLang
|
||||
TObject _out = dict->GetValue("Output");
|
||||
TObject _dbg = dict->GetValue("Debug");
|
||||
TList *_toolList;
|
||||
TList* _depList; TList* srcLst;
|
||||
TList *_depList;
|
||||
TList *srcLst;
|
||||
TRootEnvironment *comptimeEnv = nullptr;
|
||||
GetObject<std::string>(_name, name);
|
||||
GetObject<std::string>(_info, info);
|
||||
@@ -169,95 +153,88 @@ namespace Tesses::CrossLang
|
||||
else
|
||||
GetObject(_version, version);
|
||||
|
||||
if(GetObjectHeap<TList*>(_dependencies,_depList))
|
||||
{
|
||||
for(int64_t i = 0; i < _depList->Count(); i++)
|
||||
{
|
||||
if (GetObjectHeap<TList *>(_dependencies, _depList)) {
|
||||
for (int64_t i = 0; i < _depList->Count(); i++) {
|
||||
TObject _dep = _depList->Get(i);
|
||||
TDictionary *_depD;
|
||||
if(GetObjectHeap<TDictionary*>(_dep, _depD))
|
||||
{
|
||||
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
|
||||
TObject _name2 = _depD->GetValue("Name");
|
||||
TObject _version2 = _depD->GetValue("Version");
|
||||
std::string name2;
|
||||
std::string version2;
|
||||
TVMVersion version02;
|
||||
|
||||
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
|
||||
{
|
||||
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
||||
}
|
||||
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
|
||||
{
|
||||
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
||||
if (GetObject<std::string>(_name2, name2) &&
|
||||
GetObject<std::string>(_version2, version2) &&
|
||||
TVMVersion::TryParse(version2, version02)) {
|
||||
dependencies.push_back(
|
||||
std::pair<std::string, TVMVersion>(name2,
|
||||
version02));
|
||||
} else if (GetObject<std::string>(_name2, name2) &&
|
||||
GetObject(_version2, version02)) {
|
||||
dependencies.push_back(
|
||||
std::pair<std::string, TVMVersion>(name2,
|
||||
version02));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(GetObjectHeap<TList*>(_tools,_toolList))
|
||||
{
|
||||
for(int64_t i = 0; i < _toolList->Count(); i++)
|
||||
{
|
||||
if (GetObjectHeap<TList *>(_tools, _toolList)) {
|
||||
for (int64_t i = 0; i < _toolList->Count(); i++) {
|
||||
TObject _dep = _toolList->Get(i);
|
||||
TDictionary *_depD;
|
||||
if(GetObjectHeap<TDictionary*>(_dep, _depD))
|
||||
{
|
||||
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
|
||||
TObject _name2 = _depD->GetValue("Name");
|
||||
TObject _version2 = _depD->GetValue("Version");
|
||||
std::string name2;
|
||||
std::string version2;
|
||||
TVMVersion version02;
|
||||
|
||||
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
|
||||
{
|
||||
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
||||
}
|
||||
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
|
||||
{
|
||||
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
||||
if (GetObject<std::string>(_name2, name2) &&
|
||||
GetObject<std::string>(_version2, version2) &&
|
||||
TVMVersion::TryParse(version2, version02)) {
|
||||
tools.push_back(std::pair<std::string, TVMVersion>(
|
||||
name2, version02));
|
||||
} else if (GetObject<std::string>(_name2, name2) &&
|
||||
GetObject(_version2, version02)) {
|
||||
tools.push_back(std::pair<std::string, TVMVersion>(
|
||||
name2, version02));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(GetObjectHeap<TList*>(_sources,srcLst))
|
||||
{
|
||||
for(int64_t i = 0; i < srcLst->Count(); i++)
|
||||
{
|
||||
if (GetObjectHeap<TList *>(_sources, srcLst)) {
|
||||
for (int64_t i = 0; i < srcLst->Count(); i++) {
|
||||
TObject _src = srcLst->Get(i);
|
||||
TDictionary *_srcD;
|
||||
if(GetObjectHeap<TDictionary*>(_src, _srcD))
|
||||
{
|
||||
if (GetObjectHeap<TDictionary *>(_src, _srcD)) {
|
||||
TObject _sourceTxt = _srcD->GetValue("Source");
|
||||
TObject _filename = _srcD->GetValue("FileName");
|
||||
|
||||
|
||||
std::string srctxt = "";
|
||||
std::string filename = "memory_" + std::to_string(i) + ".tcross";
|
||||
std::string filename =
|
||||
"memory_" + std::to_string(i) + ".tcross";
|
||||
bool fromFile = false;
|
||||
|
||||
GetObject<std::string>(_sourceTxt, srctxt);
|
||||
GetObject<std::string>(_filename, filename);
|
||||
|
||||
|
||||
sources.push_back(std::pair<std::string,std::string>(srctxt,filename));
|
||||
sources.push_back(
|
||||
std::pair<std::string, std::string>(srctxt, filename));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
std::vector<LexToken> tokens;
|
||||
for(auto source : sources)
|
||||
{
|
||||
for (auto source : sources) {
|
||||
std::stringstream strm(source.first);
|
||||
|
||||
int res = Lex(source.second, strm, tokens);
|
||||
if(res != 0)
|
||||
{
|
||||
return Failure(ls, "Lex error in file \"" + source.second + "\":" + std::to_string(res));
|
||||
if (res != 0) {
|
||||
return Failure(ls, "Lex error in file \"" + source.second +
|
||||
"\":" + std::to_string(res));
|
||||
}
|
||||
}
|
||||
Parser parser(tokens, ls.GetGC(), comptimeEnv);
|
||||
@@ -274,38 +251,32 @@ namespace Tesses::CrossLang
|
||||
gen.icon = icon;
|
||||
std::string outpath;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> stream;
|
||||
if(GetObject(_out, stream))
|
||||
{
|
||||
if (GetObject(_out, stream)) {
|
||||
gen.Save(stream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return Success(ls);
|
||||
} catch(std::exception& ex)
|
||||
{
|
||||
} catch (std::exception &ex) {
|
||||
return Failure(ls, ex.what());
|
||||
}
|
||||
}
|
||||
static TObject VM_GetStacktrace(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(current_function != nullptr)
|
||||
{
|
||||
if(current_function->thread != nullptr)
|
||||
{
|
||||
static TObject VM_GetStacktrace(GCList &ls, std::vector<TObject> args) {
|
||||
if (current_function != nullptr) {
|
||||
if (current_function->thread != nullptr) {
|
||||
TList *list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto item : current_function->thread->call_stack_entries)
|
||||
{
|
||||
for (auto item : current_function->thread->call_stack_entries) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
if (item->callable->closure->name)
|
||||
dict->SetValue("Name", *item->callable->closure->name);
|
||||
|
||||
dict->SetValue("Closure", item->callable->closure);
|
||||
dict->SetValue("FileName", item->callable->file->name + "-" + item->callable->file->version.ToString() + ".crvm");
|
||||
dict->SetValue("FileName",
|
||||
item->callable->file->name + "-" +
|
||||
item->callable->file->version.ToString() +
|
||||
".crvm");
|
||||
dict->SetValue("IP", (int64_t)item->ip);
|
||||
if(item->srcline >= 1)
|
||||
{
|
||||
if (item->srcline >= 1) {
|
||||
dict->SetValue("SourceFile", item->srcfile);
|
||||
dict->SetValue("SourceLine", item->srcline);
|
||||
}
|
||||
@@ -317,104 +288,99 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
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;
|
||||
GCList ls(gc);
|
||||
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "GetStacktrace","Get the current stack trace", {}, VM_GetStacktrace);
|
||||
dict->DeclareFunction(gc, "getRootEnvironmentAsDictionary","Get root environment as a dictionary",{},[env](GCList& ls, std::vector<TObject> args)-> TObject{
|
||||
dict->DeclareFunction(gc, "GetStacktrace", "Get the current stack trace",
|
||||
{}, VM_GetStacktrace);
|
||||
dict->DeclareFunction(
|
||||
gc, "getRootEnvironmentAsDictionary",
|
||||
"Get root environment as a dictionary", {},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return env->GetDictionary();
|
||||
});
|
||||
dict->DeclareFunction(gc, "getRootEnvironment","Get root environment, for reflection purposes",{},[env](GCList& ls2,std::vector<TObject> args)->TObject {return env;});
|
||||
dict->DeclareFunction(gc, "getCurrentEnvironment","Get current environment, for reflection purposes",{},VM_getCurrentEnvironment);
|
||||
dict->DeclareFunction(gc, "CreateEnvironment","Create root environment",{"$dict"},[env](GCList& ls,std::vector<TObject> args)->TObject{
|
||||
dict->DeclareFunction(
|
||||
gc, "getRootEnvironment",
|
||||
"Get root environment, for reflection purposes", {},
|
||||
[env](GCList &ls2, std::vector<TObject> args) -> TObject {
|
||||
return env;
|
||||
});
|
||||
dict->DeclareFunction(gc, "getCurrentEnvironment",
|
||||
"Get current environment, for reflection purposes",
|
||||
{}, VM_getCurrentEnvironment);
|
||||
dict->DeclareFunction(
|
||||
gc, "CreateEnvironment", "Create root environment", {"$dict"},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TDictionary *dict;
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
auto renv = TRootEnvironment::Create(ls, dict);
|
||||
renv->permissions.customConsole = env->permissions.customConsole;
|
||||
renv->permissions.customConsole =
|
||||
env->permissions.customConsole;
|
||||
return renv;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto renv = TRootEnvironment::Create(ls,TDictionary::Create(ls));
|
||||
renv->permissions.customConsole = env->permissions.customConsole;
|
||||
} else {
|
||||
auto renv =
|
||||
TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
renv->permissions.customConsole =
|
||||
env->permissions.customConsole;
|
||||
return renv;
|
||||
}
|
||||
});
|
||||
dict->DeclareFunction(gc, "LoadExecutable", "Load a crossvm executable",{"stream"},[](GCList& ls,std::vector<TObject> args)->TObject{
|
||||
dict->DeclareFunction(
|
||||
gc, "LoadExecutable", "Load a crossvm executable", {"stream"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if(GetArgument(args,0,strm))
|
||||
{
|
||||
if (GetArgument(args, 0, strm)) {
|
||||
TFile *f = TFile::Create(ls);
|
||||
f->Load(ls.GetGC(), strm);
|
||||
return f;
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
#if defined(CROSSLANG_ENABLE_SUPERSLIM)
|
||||
dict->SetValue("SuperSlim", true);
|
||||
#else
|
||||
dict->SetValue("SuperSlim", false);
|
||||
#endif
|
||||
dict->DeclareFunction(gc, "Eval", "Eval source code",{"source"}, VM_Eval);
|
||||
dict->DeclareFunction(gc, "Compile", "Compile Source",{"dict"},VM_Compile);
|
||||
|
||||
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast", {"source"}, VM_SourceToAst);
|
||||
dict->DeclareFunction(gc, "getRuntimeVersion","Get the runtime version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
return TVMVersion(CROSSLANG_MAJOR,CROSSLANG_MINOR,CROSSLANG_PATCH,0,TVMVersionStage::DevVersion);
|
||||
dict->DeclareFunction(gc, "Eval", "Eval source code", {"source"}, VM_Eval);
|
||||
dict->DeclareFunction(gc, "Compile", "Compile Source", {"dict"},
|
||||
VM_Compile);
|
||||
|
||||
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast",
|
||||
{"source"}, VM_SourceToAst);
|
||||
dict->DeclareFunction(
|
||||
gc, "getRuntimeVersion", "Get the runtime version", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return TVMVersion(CROSSLANG_MAJOR, CROSSLANG_MINOR, CROSSLANG_PATCH,
|
||||
0, TVMVersionStage::DevVersion);
|
||||
});
|
||||
dict->DeclareFunction(gc, "getBytecodeVersion","Get the bytecode version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
return TVMVersion(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||
dict->DeclareFunction(
|
||||
gc, "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();
|
||||
});
|
||||
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();
|
||||
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();
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Merge", "Merge crvm files", {"srcVFS","sourcePath","destVFS"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcVFS;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> destVFS;
|
||||
Tesses::Framework::Filesystem::VFSPath sourcePath;
|
||||
if(GetArgument(args,0, srcVFS) && GetArgumentAsPath(args,1,sourcePath) && GetArgument(args,2,destVFS))
|
||||
return Merge(srcVFS, sourcePath, destVFS);
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Disassemble","Disassemble crvm file",{"strm","vfs","$generateJSON","$extractResources"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
bool generateJSON=true;
|
||||
bool extractResources=true;
|
||||
if(GetArgument(args,0,strm) && GetArgument(args,1, vfs))
|
||||
{
|
||||
GetArgument(args,2,generateJSON);
|
||||
GetArgument(args,3,extractResources);
|
||||
Disassemble(strm,vfs, generateJSON, extractResources);
|
||||
}
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Assemble", "Assemble crvm file",{"vfs"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
if(GetArgument(args,0, vfs))
|
||||
return Assemble(vfs);
|
||||
return Undefined();
|
||||
});
|
||||
|
||||
gc->BarrierBegin();
|
||||
|
||||
|
||||
|
||||
env->DeclareVariable("VM", dict);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
TAny* TAny::Create(GCList& ls)
|
||||
{
|
||||
TAny *TAny::Create(GCList &ls) {
|
||||
TAny *anyObj = new TAny();
|
||||
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
@@ -10,8 +9,7 @@ namespace Tesses::CrossLang {
|
||||
gc->Watch(anyObj);
|
||||
return anyObj;
|
||||
}
|
||||
TAny* TAny::Create(GCList* ls)
|
||||
{
|
||||
TAny *TAny::Create(GCList *ls) {
|
||||
TAny *anyObj = new TAny();
|
||||
|
||||
std::shared_ptr<GC> gc = ls->GetGC();
|
||||
@@ -19,10 +17,10 @@ namespace Tesses::CrossLang {
|
||||
gc->Watch(anyObj);
|
||||
return anyObj;
|
||||
}
|
||||
void TAny::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TAny::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
GC::Mark(this->other);
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,42 +1,35 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
TAssociativeArray* TAssociativeArray::Create(GCList& ls)
|
||||
{
|
||||
TAssociativeArray *TAssociativeArray::Create(GCList &ls) {
|
||||
TAssociativeArray *list = new TAssociativeArray();
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TAssociativeArray* TAssociativeArray::Create(GCList* ls)
|
||||
{
|
||||
TAssociativeArray *TAssociativeArray::Create(GCList *ls) {
|
||||
TAssociativeArray *list = new TAssociativeArray();
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
void TAssociativeArray::Set(std::shared_ptr<GC> gc, TObject key, TObject value)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(key)) return;
|
||||
void TAssociativeArray::Set(std::shared_ptr<GC> gc, TObject key,
|
||||
TObject value) {
|
||||
if (std::holds_alternative<Undefined>(key))
|
||||
return;
|
||||
gc->BarrierBegin();
|
||||
for(auto index = this->items.begin(); index < this->items.end(); index++)
|
||||
{
|
||||
for (auto index = this->items.begin(); index < this->items.end(); index++) {
|
||||
auto first = index->first;
|
||||
gc->BarrierEnd();
|
||||
auto eq = Equals(gc, key, first);
|
||||
gc->BarrierBegin();
|
||||
if(eq)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(value))
|
||||
{
|
||||
if (eq) {
|
||||
if (std::holds_alternative<Undefined>(value)) {
|
||||
this->items.erase(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
index->second = value;
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
@@ -46,18 +39,16 @@ namespace Tesses::CrossLang
|
||||
this->items.push_back(std::pair<TObject, TObject>(key, value));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
TObject TAssociativeArray::Get(std::shared_ptr<GC> gc, TObject key)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(key)) return Undefined();
|
||||
TObject TAssociativeArray::Get(std::shared_ptr<GC> gc, TObject key) {
|
||||
if (std::holds_alternative<Undefined>(key))
|
||||
return Undefined();
|
||||
gc->BarrierBegin();
|
||||
for(auto& item : this->items)
|
||||
{
|
||||
for (auto &item : this->items) {
|
||||
auto first = item.first;
|
||||
gc->BarrierEnd();
|
||||
auto eq = Equals(gc, key, first);
|
||||
gc->BarrierBegin();
|
||||
if(eq)
|
||||
{
|
||||
if (eq) {
|
||||
gc->BarrierEnd();
|
||||
return item.second;
|
||||
}
|
||||
@@ -65,52 +56,41 @@ namespace Tesses::CrossLang
|
||||
gc->BarrierEnd();
|
||||
return Undefined();
|
||||
}
|
||||
TObject TAssociativeArray::GetKey(int64_t index)
|
||||
{
|
||||
if(index >= 0 && index < (int64_t)this->items.size())
|
||||
{
|
||||
TObject TAssociativeArray::GetKey(int64_t index) {
|
||||
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||
return this->items[index].first;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject TAssociativeArray::GetValue(int64_t index)
|
||||
{
|
||||
if(index >= 0 && index < (int64_t)this->items.size())
|
||||
{
|
||||
TObject TAssociativeArray::GetValue(int64_t index) {
|
||||
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||
return this->items[index].second;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void TAssociativeArray::SetKey(int64_t index, TObject key)
|
||||
{
|
||||
void TAssociativeArray::SetKey(int64_t index, TObject key) {
|
||||
|
||||
if(std::holds_alternative<Undefined>(key)) return;
|
||||
if(index >= 0 && index < (int64_t)this->items.size())
|
||||
{
|
||||
if (std::holds_alternative<Undefined>(key))
|
||||
return;
|
||||
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||
this->items[index].first = key;
|
||||
}
|
||||
|
||||
}
|
||||
void TAssociativeArray::SetValue(int64_t index,TObject value)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(value)) return;
|
||||
if(index >= 0 && index < (int64_t)this->items.size())
|
||||
{
|
||||
void TAssociativeArray::SetValue(int64_t index, TObject value) {
|
||||
if (std::holds_alternative<Undefined>(value))
|
||||
return;
|
||||
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||
this->items[index].first = value;
|
||||
}
|
||||
}
|
||||
int64_t TAssociativeArray::Count()
|
||||
{
|
||||
return (int64_t)this->items.size();
|
||||
}
|
||||
void TAssociativeArray::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
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)
|
||||
{
|
||||
for (auto &item : this->items) {
|
||||
GC::Mark(item.first);
|
||||
GC::Mark(item.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,30 +1,26 @@
|
||||
#include "CrossLang.hpp"
|
||||
// THANKS TO https://www.youtube.com/watch?v=R-z2Hv-7nxk
|
||||
namespace Tesses::CrossLang {
|
||||
TTask::TTask(std::shared_ptr<GC> gc)
|
||||
{
|
||||
this->gc = gc;
|
||||
}
|
||||
TTask* TTask::Create(GCList& ls)
|
||||
{
|
||||
TTask::TTask(std::shared_ptr<GC> gc) { this->gc = gc; }
|
||||
TTask *TTask::Create(GCList &ls) {
|
||||
TTask *task = new TTask(ls.GetGC());
|
||||
ls.Add(task);
|
||||
task->gc->Watch(task);
|
||||
return task;
|
||||
}
|
||||
bool TTask::IsCompleted()
|
||||
{
|
||||
bool TTask::IsCompleted() {
|
||||
gc->BarrierBegin();
|
||||
bool r = this->isCompleted;
|
||||
gc->BarrierEnd();
|
||||
|
||||
return r;
|
||||
}
|
||||
TTask* TTask::ContinueWith(GCList& ls, TCallable* callable)
|
||||
{
|
||||
TTask *TTask::ContinueWith(GCList &ls, TCallable *callable) {
|
||||
TTask *task = TTask::Create(ls);
|
||||
|
||||
TExternalMethod* em = TExternalMethod::Create(ls,"Internal async thing",{"_asyncObj"},[callable,task](GCList& ls,std::vector<TObject> args)->TObject{
|
||||
TExternalMethod *em = TExternalMethod::Create(
|
||||
ls, "Internal async thing", {"_asyncObj"},
|
||||
[callable, task](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
try {
|
||||
task->SetSucceeded(callable->Call(ls, args));
|
||||
} catch (...) {
|
||||
@@ -35,31 +31,25 @@ namespace Tesses::CrossLang {
|
||||
em->watch = {callable, task};
|
||||
|
||||
this->gc->BarrierBegin();
|
||||
if(this->isCompleted)
|
||||
{
|
||||
if (this->isCompleted) {
|
||||
this->gc->BarrierEnd();
|
||||
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
|
||||
auto cobj = this->obj;
|
||||
ls->Add(cobj);
|
||||
ls->Add(em);
|
||||
this->gc->GetPool()->Schedule([ls,em,cobj](size_t s)->void {
|
||||
em->Call(*ls,{cobj});
|
||||
});
|
||||
this->gc->GetPool()->Schedule(
|
||||
[ls, em, cobj](size_t s) -> void { em->Call(*ls, {cobj}); });
|
||||
return task;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->cont = em;
|
||||
}
|
||||
|
||||
this->gc->BarrierEnd();
|
||||
return task;
|
||||
}
|
||||
void TTask::ContinueWith(TCallable* callable)
|
||||
{
|
||||
void TTask::ContinueWith(TCallable *callable) {
|
||||
this->gc->BarrierBegin();
|
||||
if(this->isCompleted)
|
||||
{
|
||||
if (this->isCompleted) {
|
||||
this->gc->BarrierEnd();
|
||||
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
|
||||
auto cobj = this->obj;
|
||||
@@ -67,31 +57,22 @@ namespace Tesses::CrossLang {
|
||||
ls->Add(callable);
|
||||
this->gc->GetPool()->Schedule([ls, callable, cobj](size_t s) -> void {
|
||||
callable->Call(*ls, {cobj});
|
||||
|
||||
});
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->cont = callable;
|
||||
}
|
||||
|
||||
this->gc->BarrierEnd();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TTask::SetFailed(std::exception_ptr ex)
|
||||
{
|
||||
void TTask::SetFailed(std::exception_ptr ex) {
|
||||
this->ex = ex;
|
||||
this->SetSucceeded(nullptr);
|
||||
}
|
||||
void TTask::SetSucceeded(TObject v)
|
||||
{
|
||||
void TTask::SetSucceeded(TObject v) {
|
||||
gc->BarrierBegin();
|
||||
if(this->isCompleted)
|
||||
{
|
||||
if (this->isCompleted) {
|
||||
gc->BarrierEnd();
|
||||
return;
|
||||
}
|
||||
@@ -99,28 +80,22 @@ namespace Tesses::CrossLang {
|
||||
this->obj = v;
|
||||
auto cont = this->cont;
|
||||
gc->BarrierEnd();
|
||||
if(cont != nullptr)
|
||||
{
|
||||
if (cont != nullptr) {
|
||||
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
|
||||
|
||||
auto callable = cont;
|
||||
ls->Add(v);
|
||||
ls->Add(callable);
|
||||
this->gc->GetPool()->Schedule([ls,callable,v](size_t s)->void {
|
||||
callable->Call(*ls,{v});
|
||||
});
|
||||
this->gc->GetPool()->Schedule(
|
||||
[ls, callable, v](size_t s) -> void { callable->Call(*ls, {v}); });
|
||||
}
|
||||
}
|
||||
|
||||
TObject TTask::Wait()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
TObject TTask::Wait() {
|
||||
while (true) {
|
||||
gc->BarrierBegin();
|
||||
if(this->isCompleted)
|
||||
{
|
||||
if(this->ex)
|
||||
{
|
||||
if (this->isCompleted) {
|
||||
if (this->ex) {
|
||||
auto error = this->ex;
|
||||
gc->BarrierEnd();
|
||||
std::rethrow_exception(error);
|
||||
@@ -129,34 +104,29 @@ namespace Tesses::CrossLang {
|
||||
auto o = this->obj;
|
||||
gc->BarrierEnd();
|
||||
return o;
|
||||
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
void TTask::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TTask::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
GC::Mark(this->obj);
|
||||
if (this->cont != nullptr)
|
||||
this->cont->Mark();
|
||||
}
|
||||
|
||||
TTask* TTask::Run(GCList& ls, TCallable* callable)
|
||||
{
|
||||
TTask *TTask::Run(GCList &ls, TCallable *callable) {
|
||||
TTask *task = TTask::Create(ls);
|
||||
std::shared_ptr<GCList> ls2 = std::make_shared<GCList>(ls.GetGC());
|
||||
ls2->Add(callable);
|
||||
ls2->Add(task);
|
||||
|
||||
ls.GetGC()->GetPool()->Schedule([ls2, callable, task](size_t s) -> void {
|
||||
try
|
||||
{
|
||||
try {
|
||||
task->SetSucceeded(callable->Call(*ls2, {}));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
} catch (...) {
|
||||
task->SetFailed(std::current_exception());
|
||||
}
|
||||
});
|
||||
@@ -164,8 +134,7 @@ namespace Tesses::CrossLang {
|
||||
return task;
|
||||
}
|
||||
|
||||
TTask* TTask::FromResult(GCList& ls, TObject v)
|
||||
{
|
||||
TTask *TTask::FromResult(GCList &ls, TObject v) {
|
||||
TTask *task = TTask::Create(ls);
|
||||
task->SetSucceeded(v);
|
||||
return task;
|
||||
@@ -174,29 +143,31 @@ namespace Tesses::CrossLang {
|
||||
class TTaskCseObj {
|
||||
std::shared_ptr<GC> gc;
|
||||
TTask *task;
|
||||
|
||||
public:
|
||||
TTaskCseObj(std::shared_ptr<GC> gc, TTask* task)
|
||||
{
|
||||
TTaskCseObj(std::shared_ptr<GC> gc, TTask *task) {
|
||||
this->gc = gc;
|
||||
this->task = task;
|
||||
}
|
||||
|
||||
void Invoke(std::shared_ptr<TTaskCseObj> shared_o,CallStackEntry* cse, TObject o)
|
||||
{
|
||||
void Invoke(std::shared_ptr<TTaskCseObj> shared_o, CallStackEntry *cse,
|
||||
TObject o) {
|
||||
try {
|
||||
GCList ls(gc);
|
||||
cse->Push(gc, o);
|
||||
auto res = cse->Resume(ls);
|
||||
CallStackEntry *cse2;
|
||||
if(GetObjectHeap(res,cse2))
|
||||
{
|
||||
if (GetObjectHeap(res, cse2)) {
|
||||
auto taskPiece = cse2->Pop(ls);
|
||||
TTask *task;
|
||||
if(GetObjectHeap(taskPiece,task))
|
||||
{
|
||||
auto em = TExternalMethod::Create(ls,"",{"obj"},[cse2,task,shared_o](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
|
||||
shared_o->Invoke(shared_o,cse2,args.empty() ? (TObject)Undefined():args[0]);
|
||||
if (GetObjectHeap(taskPiece, task)) {
|
||||
auto em = TExternalMethod::Create(
|
||||
ls, "", {"obj"},
|
||||
[cse2, task, shared_o](
|
||||
GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
shared_o->Invoke(shared_o, cse2,
|
||||
args.empty() ? (TObject)Undefined()
|
||||
: args[0]);
|
||||
|
||||
return nullptr;
|
||||
});
|
||||
@@ -205,8 +176,7 @@ namespace Tesses::CrossLang {
|
||||
|
||||
task->ContinueWith(em);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this->task->SetSucceeded(res);
|
||||
}
|
||||
} catch (...) {
|
||||
@@ -214,18 +184,15 @@ namespace Tesses::CrossLang {
|
||||
}
|
||||
}
|
||||
};
|
||||
TTask* TTask::FromClosure(GCList& ls, TClosure* closure)
|
||||
{
|
||||
TTask *TTask::FromClosure(GCList &ls, TClosure *closure) {
|
||||
auto res = closure->Call(ls, {});
|
||||
CallStackEntry *ent;
|
||||
if(GetObjectHeap(res,ent))
|
||||
{
|
||||
if (GetObjectHeap(res, ent)) {
|
||||
return FromCallStackEntry(ls, ent);
|
||||
}
|
||||
return FromResult(ls, res);
|
||||
}
|
||||
TTask* TTask::FromCallStackEntry(GCList& ls, CallStackEntry* ent)
|
||||
{
|
||||
TTask *TTask::FromCallStackEntry(GCList &ls, CallStackEntry *ent) {
|
||||
TTask *task = TTask::Create(ls);
|
||||
|
||||
// try {
|
||||
@@ -234,15 +201,15 @@ namespace Tesses::CrossLang {
|
||||
|
||||
std::shared_ptr<TTaskCseObj> obj = std::make_shared<TTaskCseObj>(gc, task);
|
||||
|
||||
|
||||
ls2.Add(task);
|
||||
auto res = ent->Pop(ls2);
|
||||
TTask *task2;
|
||||
if(GetObjectHeap(res,task2))
|
||||
{
|
||||
auto em = TExternalMethod::Create(ls2,"",{},[ent,task,obj](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
|
||||
obj->Invoke(obj,ent,args.empty() ? (TObject)Undefined():args[0]);
|
||||
if (GetObjectHeap(res, task2)) {
|
||||
auto em = TExternalMethod::Create(
|
||||
ls2, "", {},
|
||||
[ent, task, obj](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
obj->Invoke(obj, ent,
|
||||
args.empty() ? (TObject)Undefined() : args[0]);
|
||||
|
||||
return nullptr;
|
||||
});
|
||||
@@ -258,4 +225,4 @@ namespace Tesses::CrossLang {
|
||||
|
||||
return task;
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,40 +1,34 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
std::string TClassObject::TypeName()
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
std::string TClassObject::TypeName() {
|
||||
std::string type = "class ";
|
||||
type += this->name;
|
||||
for(auto& item : this->inherit_tree) type += " : " + item;
|
||||
for (auto &item : this->inherit_tree)
|
||||
type += " : " + item;
|
||||
return type;
|
||||
}
|
||||
TObject TClassObject::CallMethod(GCList& ls, std::string className, std::string name,std::vector<TObject> args)
|
||||
{
|
||||
TObject TClassObject::CallMethod(GCList &ls, std::string className,
|
||||
std::string name, std::vector<TObject> args) {
|
||||
auto value = this->GetValue(className, name);
|
||||
TCallable *callable;
|
||||
if(GetObjectHeap(value, callable))
|
||||
{
|
||||
if (GetObjectHeap(value, callable)) {
|
||||
return callable->Call(ls, args);
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TClassObjectEntry* TClassObject::GetEntry(std::string classN, std::string key)
|
||||
{
|
||||
for(auto& item : this->entries)
|
||||
{
|
||||
if(item.name == key)
|
||||
{
|
||||
switch(item.modifier)
|
||||
{
|
||||
TClassObjectEntry *TClassObject::GetEntry(std::string classN, std::string key) {
|
||||
for (auto &item : this->entries) {
|
||||
if (item.name == key) {
|
||||
switch (item.modifier) {
|
||||
case TClassModifier::Private:
|
||||
if(classN != item.owner) return nullptr;
|
||||
if (classN != item.owner)
|
||||
return nullptr;
|
||||
break;
|
||||
case TClassModifier::Protected:
|
||||
if(classN.empty()) return nullptr;
|
||||
if(classN != item.owner)
|
||||
{
|
||||
for(auto inh : this->inherit_tree)
|
||||
{
|
||||
if (classN.empty())
|
||||
return nullptr;
|
||||
if (classN != item.owner) {
|
||||
for (auto inh : this->inherit_tree) {
|
||||
if (inh == classN) {
|
||||
|
||||
return &item;
|
||||
@@ -53,60 +47,63 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
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,
|
||||
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 = "";
|
||||
for(size_t i = 0; i < p.size(); i++)
|
||||
{
|
||||
if(i > 0) newStr.push_back('.');
|
||||
for (size_t i = 0; i < p.size(); i++) {
|
||||
if (i > 0)
|
||||
newStr.push_back('.');
|
||||
newStr += p[i];
|
||||
}
|
||||
return newStr;
|
||||
}
|
||||
TClassObject* TClassObject::Create(GCList* ls, TFile* f, uint32_t classIndex, TEnvironment* env, std::vector<TObject> args)
|
||||
{
|
||||
if(ls == nullptr) return nullptr;
|
||||
TClassObject *TClassObject::Create(GCList *ls, TFile *f, uint32_t classIndex,
|
||||
TEnvironment *env,
|
||||
std::vector<TObject> args) {
|
||||
if (ls == nullptr)
|
||||
return nullptr;
|
||||
TClassObject *obj = new TClassObject();
|
||||
obj->file = f;
|
||||
obj->classIndex = classIndex;
|
||||
obj->ogEnv = env;
|
||||
obj->env = TClassEnvironment::Create(ls, env, obj);
|
||||
obj->name = JoinPeriod(f->classes[classIndex].name);
|
||||
|
||||
bool hasToString = false;
|
||||
|
||||
for(auto entry : f->classes[classIndex].entry)
|
||||
{
|
||||
if(entry.modifier == TClassModifier::Static) continue;
|
||||
for (auto &entry : f->classes[classIndex].entry) {
|
||||
if (entry.modifier == TClassModifier::Static)
|
||||
continue;
|
||||
TClassObjectEntry ent;
|
||||
ent.name = entry.name;
|
||||
ent.modifier = entry.modifier;
|
||||
ent.canSet = !entry.isFunction;
|
||||
ent.owner = obj->name;
|
||||
|
||||
if(entry.isFunction)
|
||||
{
|
||||
if(ent.name == "ToString") hasToString=true;
|
||||
if(entry.isAbstract)
|
||||
{
|
||||
if (entry.isFunction) {
|
||||
if (entry.name == "ToString")
|
||||
hasToString = true;
|
||||
if (entry.isAbstract) {
|
||||
delete obj;
|
||||
throw VMException("Method " + ent.name + " in " + ent.owner + " is abstract.");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto clos = TClosure::Create(ls,obj->env,obj->file,entry.chunkId);
|
||||
throw VMException("Method " + ent.name + " in " + ent.owner +
|
||||
" is abstract.");
|
||||
} else {
|
||||
auto clos =
|
||||
TClosure::Create(ls, obj->env, obj->file, entry.chunkId);
|
||||
clos->documentation = entry.documentation;
|
||||
clos->className = ent.owner;
|
||||
ent.value = clos;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (entry.isAbstract)
|
||||
ent.value = Undefined();
|
||||
else {
|
||||
if(entry.isAbstract) ent.value = Undefined();
|
||||
else {
|
||||
auto clos = TClosure::Create(ls,obj->env,obj->file,entry.chunkId);
|
||||
auto clos =
|
||||
TClosure::Create(ls, obj->env, obj->file, entry.chunkId);
|
||||
|
||||
clos->className = ent.owner;
|
||||
ent.value = clos->Call(*ls, {});
|
||||
@@ -118,26 +115,27 @@ namespace Tesses::CrossLang
|
||||
|
||||
TClass *clsCur = &f->classes[classIndex];
|
||||
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));
|
||||
size_t idx;
|
||||
if(rEnv->TryFindClass(clsCur->inherits,idx))
|
||||
{
|
||||
if (rEnv->TryFindClass(clsCur->inherits, idx)) {
|
||||
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);
|
||||
for(auto entry : clsCur->entry)
|
||||
{
|
||||
if(entry.modifier == TClassModifier::Static) continue;
|
||||
for (auto &entry : clsCur->entry) {
|
||||
if (entry.modifier == TClassModifier::Static)
|
||||
continue;
|
||||
bool cont = false;
|
||||
for (auto e : obj->entries)
|
||||
if(e.name == entry.name)
|
||||
{
|
||||
if (e.name == entry.name) {
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
if(cont) continue;
|
||||
if (cont)
|
||||
continue;
|
||||
|
||||
TClassObjectEntry ent;
|
||||
ent.name = entry.name;
|
||||
@@ -145,28 +143,28 @@ namespace Tesses::CrossLang
|
||||
ent.canSet = !entry.isFunction;
|
||||
ent.owner = ownerNow;
|
||||
|
||||
if(entry.isFunction)
|
||||
{
|
||||
if (entry.isFunction) {
|
||||
|
||||
if(ent.name == "ToString") hasToString=true;
|
||||
if(entry.isAbstract)
|
||||
{
|
||||
if (entry.name == "ToString")
|
||||
hasToString = true;
|
||||
if (entry.isAbstract) {
|
||||
delete obj;
|
||||
throw VMException("Method " + ent.name + " in " + ownerNow + " is abstract.");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto clos = TClosure::Create(ls,obj->env,file,entry.chunkId);
|
||||
throw VMException("Method " + ent.name + " in " +
|
||||
ownerNow + " is abstract.");
|
||||
} else {
|
||||
auto clos =
|
||||
TClosure::Create(ls, obj->env, file, entry.chunkId);
|
||||
clos->closure->name = obj->name + "::" + ent.name;
|
||||
clos->className = ownerNow;
|
||||
clos->documentation = entry.documentation;
|
||||
ent.value = clos;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (entry.isAbstract)
|
||||
ent.value = Undefined();
|
||||
else {
|
||||
if(entry.isAbstract) ent.value = Undefined();
|
||||
else {
|
||||
auto clos = TClosure::Create(ls,obj->env,file,entry.chunkId);
|
||||
auto clos =
|
||||
TClosure::Create(ls, obj->env, file, entry.chunkId);
|
||||
clos->closure->name = obj->name + "::" + ent.name;
|
||||
clos->className = ownerNow;
|
||||
ent.value = clos->Call(*ls, {});
|
||||
@@ -175,73 +173,76 @@ namespace Tesses::CrossLang
|
||||
|
||||
obj->entries.push_back(ent);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if(!hasToString)
|
||||
{
|
||||
if (!hasToString) {
|
||||
TClassObjectEntry ent;
|
||||
ent.canSet = false;
|
||||
ent.modifier = TClassModifier::Public;
|
||||
ent.name = "ToString";
|
||||
ent.owner = obj->name;
|
||||
ent.value = TExternalMethod::Create(ls,"The ToString",{},[obj](GCList& ls,std::vector<TObject> args)->TObject { return obj->TypeName();});
|
||||
ent.value = TExternalMethod::Create(
|
||||
ls, "The ToString", {},
|
||||
[obj](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return obj->TypeName();
|
||||
});
|
||||
obj->entries.push_back(ent);
|
||||
}
|
||||
TCallable *call = nullptr;
|
||||
std::string fnName = f->classes[classIndex].name[f->classes[classIndex].name.size()-1];
|
||||
std::string fnName =
|
||||
f->classes[classIndex].name[f->classes[classIndex].name.size() - 1];
|
||||
for (auto &item : obj->entries)
|
||||
if(item.name == fnName)
|
||||
{
|
||||
if (item.name == fnName) {
|
||||
GetObjectHeap(item.value, call);
|
||||
break;
|
||||
}
|
||||
ls->Add(obj);
|
||||
ls->GetGC()->Watch(obj);
|
||||
|
||||
if(call != nullptr) call->Call(*ls,args);
|
||||
if (call != nullptr)
|
||||
call->Call(*ls, args);
|
||||
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);
|
||||
if(ent == nullptr) return Undefined();
|
||||
if (ent == nullptr)
|
||||
return Undefined();
|
||||
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);
|
||||
if(ent == nullptr) return;
|
||||
if(ent->canSet) ent->value = value;
|
||||
if (ent == nullptr)
|
||||
return;
|
||||
if (ent->canSet)
|
||||
ent->value = value;
|
||||
}
|
||||
bool TClassObject::HasValue(std::string className,std::string key)
|
||||
{
|
||||
bool TClassObject::HasValue(std::string className, std::string key) {
|
||||
auto ent = GetEntry(className, key);
|
||||
return ent != nullptr;
|
||||
|
||||
}
|
||||
bool TClassObject::HasField(std::string className,std::string key)
|
||||
{
|
||||
bool TClassObject::HasField(std::string className, std::string key) {
|
||||
auto ent = GetEntry(className, key);
|
||||
if(ent == nullptr) return false;
|
||||
if (ent == nullptr)
|
||||
return false;
|
||||
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);
|
||||
if(ent == nullptr) return false;
|
||||
if (ent == nullptr)
|
||||
return false;
|
||||
TCallable *call;
|
||||
return GetObjectHeap(ent->value, call);
|
||||
}
|
||||
void TClassObject::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TClassObject::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->env->Mark();
|
||||
this->file->Mark();
|
||||
this->ogEnv->Mark();
|
||||
for(auto& item : this->entries) GC::Mark(item.value);
|
||||
|
||||
}
|
||||
for (auto &item : this->entries)
|
||||
GC::Mark(item.value);
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,15 +1,13 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang {
|
||||
bool TClassEnvironment::HasConstForSet(std::string key)
|
||||
{
|
||||
if(this->env->HasVariableRecurse(key))
|
||||
{
|
||||
bool TClassEnvironment::HasConstForSet(std::string key) {
|
||||
if (this->env->HasVariableRecurse(key)) {
|
||||
return this->env->HasConstForSet(key);
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -18,8 +16,8 @@ namespace Tesses::CrossLang {
|
||||
_gc->Watch(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);
|
||||
|
||||
@@ -28,103 +26,117 @@ namespace Tesses::CrossLang {
|
||||
_gc->Watch(env2);
|
||||
return env2;
|
||||
}
|
||||
TClassEnvironment::TClassEnvironment(TEnvironment* env,TClassObject* obj)
|
||||
{
|
||||
TClassEnvironment::TClassEnvironment(TEnvironment *env, TClassObject *obj) {
|
||||
this->env = env;
|
||||
this->clsObj = obj;
|
||||
}
|
||||
bool TClassEnvironment::HasVariable(std::string key)
|
||||
{
|
||||
if(key == "this") return true;
|
||||
if(this->clsObj->HasValue(current_function == nullptr ? "" : current_function->callable->className,key)) return true;
|
||||
bool TClassEnvironment::HasVariable(std::string key) {
|
||||
if (key == "this")
|
||||
return true;
|
||||
if (this->clsObj->HasValue(current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className,
|
||||
key))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool TClassEnvironment::HasVariableRecurse(std::string key)
|
||||
{
|
||||
if(HasVariable(key)) return true;
|
||||
bool TClassEnvironment::HasVariableRecurse(std::string key) {
|
||||
if (HasVariable(key))
|
||||
return true;
|
||||
return this->env->HasVariableRecurse(key);
|
||||
}
|
||||
bool TClassEnvironment::HasVariableOrFieldRecurse(std::string key, bool setting)
|
||||
{
|
||||
if(key == "this") return true;
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
if(clsObj->HasMethod(clsName,(setting ? "set" : "get")+key)) return true;
|
||||
if(clsObj->HasValue(clsName,key)) return true;
|
||||
bool TClassEnvironment::HasVariableOrFieldRecurse(std::string key,
|
||||
bool setting) {
|
||||
if (key == "this")
|
||||
return true;
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
if (clsObj->HasMethod(clsName, (setting ? "set" : "get") + key))
|
||||
return true;
|
||||
if (clsObj->HasValue(clsName, key))
|
||||
return true;
|
||||
return env->HasVariableOrFieldRecurse(key, setting);
|
||||
}
|
||||
|
||||
TObject TClassEnvironment::GetVariable(std::string key)
|
||||
{
|
||||
if(key == "this") return this->clsObj;
|
||||
TObject TClassEnvironment::GetVariable(std::string key) {
|
||||
if (key == "this")
|
||||
return this->clsObj;
|
||||
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
|
||||
if(clsObj->HasValue(clsName,key)) return this->clsObj->GetValue(clsName,key);
|
||||
return env->GetVariable(key);
|
||||
}
|
||||
void TClassEnvironment::SetVariable(std::string key, TObject value)
|
||||
{
|
||||
if(key == "this") return;
|
||||
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
|
||||
if (clsObj->HasValue(clsName, key))
|
||||
{
|
||||
return this->clsObj->GetValue(clsName, key);
|
||||
return env->GetVariable(key);
|
||||
}
|
||||
void TClassEnvironment::SetVariable(std::string key, TObject value) {
|
||||
if (key == "this")
|
||||
return;
|
||||
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
|
||||
if (clsObj->HasValue(clsName, key)) {
|
||||
this->clsObj->SetValue(clsName, key, value);
|
||||
return;
|
||||
}
|
||||
this->env->SetVariable(key, value);
|
||||
return;
|
||||
}
|
||||
TObject TClassEnvironment::GetVariable(GCList& ls, std::string key)
|
||||
{
|
||||
if(key == "this") return this->clsObj;
|
||||
TObject TClassEnvironment::GetVariable(GCList &ls, std::string key) {
|
||||
if (key == "this")
|
||||
return this->clsObj;
|
||||
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
if(this->clsObj->HasMethod(clsName,"get"+key))
|
||||
{
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
if (this->clsObj->HasMethod(clsName, "get" + key)) {
|
||||
auto res = this->clsObj->GetValue(clsName, "get" + key);
|
||||
TCallable *call;
|
||||
if(GetObjectHeap(res,call)) return call->Call(ls,{});
|
||||
if (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->clsObj->GetValue(clsName, key);
|
||||
return this->env->GetVariable(ls, key);
|
||||
}
|
||||
TObject TClassEnvironment::SetVariable(GCList& ls, std::string key, TObject v)
|
||||
{
|
||||
if(key == "this") return this->clsObj;
|
||||
TObject TClassEnvironment::SetVariable(GCList &ls, std::string key, TObject v) {
|
||||
if (key == "this")
|
||||
return this->clsObj;
|
||||
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
if(this->clsObj->HasMethod(clsName,"set"+key))
|
||||
{
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
if (this->clsObj->HasMethod(clsName, "set" + key)) {
|
||||
auto res = this->clsObj->GetValue(clsName, "set" + key);
|
||||
TCallable *call;
|
||||
if(GetObjectHeap(res,call)) return call->Call(ls,{v});
|
||||
if (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 v;}
|
||||
|
||||
return this->env->SetVariable(ls, key, v);
|
||||
}
|
||||
|
||||
void TClassEnvironment::DeclareVariable(std::string key, TObject value)
|
||||
{
|
||||
|
||||
}
|
||||
TRootEnvironment* TClassEnvironment::GetRootEnvironment()
|
||||
{
|
||||
void TClassEnvironment::DeclareVariable(std::string key, TObject value) {}
|
||||
TRootEnvironment *TClassEnvironment::GetRootEnvironment() {
|
||||
return this->env->GetRootEnvironment();
|
||||
}
|
||||
TEnvironment* TClassEnvironment::GetParentEnvironment()
|
||||
{
|
||||
return this->env;
|
||||
}
|
||||
TEnvironment *TClassEnvironment::GetParentEnvironment() { return this->env; }
|
||||
|
||||
void TClassEnvironment::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TClassEnvironment::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->clsObj->Mark();
|
||||
this->env->Mark();
|
||||
for(auto item : this->defers) item->Mark();
|
||||
}
|
||||
for (auto item : this->defers)
|
||||
item->Mark();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang {
|
||||
TArgWrapper* TArgWrapper::Create(GCList& ls, TCallable* callable)
|
||||
{
|
||||
TArgWrapper *TArgWrapper::Create(GCList &ls, TCallable *callable) {
|
||||
TArgWrapper *argWrapper = new TArgWrapper();
|
||||
argWrapper->callable = callable;
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
@@ -9,8 +8,7 @@ namespace Tesses::CrossLang {
|
||||
gc->Watch(argWrapper);
|
||||
return argWrapper;
|
||||
}
|
||||
TArgWrapper* TArgWrapper::Create(GCList* ls, TCallable* callable)
|
||||
{
|
||||
TArgWrapper *TArgWrapper::Create(GCList *ls, TCallable *callable) {
|
||||
TArgWrapper *argWrapper = new TArgWrapper();
|
||||
argWrapper->callable = callable;
|
||||
std::shared_ptr<GC> gc = ls->GetGC();
|
||||
@@ -18,8 +16,7 @@ namespace Tesses::CrossLang {
|
||||
gc->Watch(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;
|
||||
TList *argList = TList::Create(ls);
|
||||
argList->items = args;
|
||||
@@ -27,30 +24,30 @@ namespace Tesses::CrossLang {
|
||||
current_function = cse;
|
||||
return v;
|
||||
}
|
||||
void TArgWrapper::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TArgWrapper::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->callable->Mark();
|
||||
GC::Mark(this->tag);
|
||||
}
|
||||
void TCallable::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TCallable::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
GC::Mark(this->tag);
|
||||
}
|
||||
void TClosure::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TClosure::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->file->Mark();
|
||||
this->env->Mark();
|
||||
this->closure->Mark();
|
||||
GC::Mark(this->tag);
|
||||
}
|
||||
TClosure* TClosure::Create(GCList& ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
|
||||
{
|
||||
TClosure *TClosure::Create(GCList &ls, TEnvironment *env, TFile *file,
|
||||
uint32_t chunkId, bool ownScope) {
|
||||
TClosure *closure = new TClosure();
|
||||
closure->className = "";
|
||||
closure->ownScope = ownScope;
|
||||
@@ -60,14 +57,15 @@ namespace Tesses::CrossLang {
|
||||
closure->chunkId = chunkId;
|
||||
if (chunkId < file->chunks.size())
|
||||
closure->closure = file->chunks[chunkId];
|
||||
else throw VMException("ChunkId out of bounds.");
|
||||
else
|
||||
throw VMException("ChunkId out of bounds.");
|
||||
closure->env = env;
|
||||
closure->file = file;
|
||||
|
||||
return closure;
|
||||
}
|
||||
TClosure* TClosure::Create(GCList* ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
|
||||
{
|
||||
TClosure *TClosure::Create(GCList *ls, TEnvironment *env, TFile *file,
|
||||
uint32_t chunkId, bool ownScope) {
|
||||
TClosure *closure = new TClosure();
|
||||
closure->className = "";
|
||||
closure->ownScope = ownScope;
|
||||
@@ -77,15 +75,15 @@ namespace Tesses::CrossLang {
|
||||
closure->chunkId = chunkId;
|
||||
if (chunkId < file->chunks.size())
|
||||
closure->closure = file->chunks[chunkId];
|
||||
else throw VMException("ChunkId out of bounds.");
|
||||
else
|
||||
throw VMException("ChunkId out of bounds.");
|
||||
closure->env = env;
|
||||
closure->file = file;
|
||||
|
||||
return closure;
|
||||
}
|
||||
|
||||
TObject TClosure::Call(GCList& ls,std::vector<TObject> args)
|
||||
{
|
||||
TObject TClosure::Call(GCList &ls, std::vector<TObject> args) {
|
||||
auto cse = current_function;
|
||||
InterperterThread *thrd = InterperterThread::Create(ls);
|
||||
thrd->AddCallStackEntry(ls, this, args);
|
||||
@@ -96,4 +94,4 @@ namespace Tesses::CrossLang {
|
||||
current_function = cse;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
TDynamicDictionary* TDynamicDictionary::Create(GCList& ls,TCallable* callable)
|
||||
{
|
||||
TDynamicDictionary *TDynamicDictionary::Create(GCList &ls,
|
||||
TCallable *callable) {
|
||||
|
||||
TDynamicDictionary *dict = new TDynamicDictionary();
|
||||
dict->cb = callable;
|
||||
@@ -11,8 +11,8 @@ namespace Tesses::CrossLang {
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
TDynamicDictionary* TDynamicDictionary::Create(GCList* ls,TCallable* callable)
|
||||
{
|
||||
TDynamicDictionary *TDynamicDictionary::Create(GCList *ls,
|
||||
TCallable *callable) {
|
||||
TDynamicDictionary *dict = new TDynamicDictionary();
|
||||
dict->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
@@ -21,15 +21,14 @@ namespace Tesses::CrossLang {
|
||||
return dict;
|
||||
}
|
||||
|
||||
void TDynamicDictionary::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TDynamicDictionary::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->cb->Mark();
|
||||
}
|
||||
|
||||
TObject TDynamicDictionary::GetField(GCList& ls, std::string key)
|
||||
{
|
||||
TObject TDynamicDictionary::GetField(GCList &ls, std::string key) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "GetField");
|
||||
@@ -38,8 +37,8 @@ namespace Tesses::CrossLang {
|
||||
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);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "SetField");
|
||||
@@ -49,8 +48,8 @@ namespace Tesses::CrossLang {
|
||||
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);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "CallMethod");
|
||||
@@ -62,8 +61,7 @@ namespace Tesses::CrossLang {
|
||||
return this->cb->Call(ls, {dict});
|
||||
}
|
||||
|
||||
TEnumerator* TDynamicDictionary::GetEnumerator(GCList& ls)
|
||||
{
|
||||
TEnumerator *TDynamicDictionary::GetEnumerator(GCList &ls) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "GetEnumerator");
|
||||
@@ -72,8 +70,7 @@ namespace Tesses::CrossLang {
|
||||
|
||||
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();
|
||||
auto r = this->GetValue(method);
|
||||
TCallable *callable;
|
||||
@@ -81,8 +78,7 @@ namespace Tesses::CrossLang {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return res;
|
||||
}
|
||||
bool TDynamicDictionary::MethodExists(GCList& ls,std::string name)
|
||||
{
|
||||
bool TDynamicDictionary::MethodExists(GCList &ls, std::string name) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "MethodExists");
|
||||
@@ -92,125 +88,114 @@ namespace Tesses::CrossLang {
|
||||
|
||||
auto res = this->cb->Call(ls, {dict});
|
||||
bool r2;
|
||||
if(GetObject(res,r2)) return r2;
|
||||
if (GetObject(res, r2))
|
||||
return r2;
|
||||
return false;
|
||||
}
|
||||
|
||||
TDynamicDictionary::~TDynamicDictionary()
|
||||
{
|
||||
|
||||
}
|
||||
TObject TDictionary::CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
|
||||
{
|
||||
TDynamicDictionary::~TDynamicDictionary() {}
|
||||
TObject TDictionary::CallMethod(GCList &ls, std::string key,
|
||||
std::vector<TObject> args) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto res = this->GetValue(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
TCallable *callable;
|
||||
|
||||
if(GetObjectHeap(res,callable))
|
||||
{
|
||||
if (GetObjectHeap(res, callable)) {
|
||||
auto closure = dynamic_cast<TClosure *>(callable);
|
||||
if(closure != nullptr && !closure->closure->args.empty() && closure->closure->args.front() == "this")
|
||||
{
|
||||
if (closure != nullptr && !closure->closure->args.empty() &&
|
||||
closure->closure->args.front() == "this") {
|
||||
std::vector<TObject> args2;
|
||||
args2.push_back(this);
|
||||
args2.insert(args2.end(), args.begin(), args.end());
|
||||
return closure->Call(ls, args2);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return callable->Call(ls, args);
|
||||
|
||||
}
|
||||
}
|
||||
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();
|
||||
auto res = this->GetValue(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
TCallable *callable;
|
||||
|
||||
if(GetObjectHeap(res,callable))
|
||||
{
|
||||
if (GetObjectHeap(res, callable)) {
|
||||
auto closure = dynamic_cast<TClosure *>(callable);
|
||||
if(closure != nullptr && !closure->closure->args.empty() && closure->closure->args.front() == "this")
|
||||
{
|
||||
if (closure != nullptr && !closure->closure->args.empty() &&
|
||||
closure->closure->args.front() == "this") {
|
||||
std::vector<TObject> args2;
|
||||
args2.push_back(this);
|
||||
args2.insert(args2.end(), args.begin(), args.end());
|
||||
return closure->CallWithFatalError(ls, args2);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return callable->CallWithFatalError(ls, args);
|
||||
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
void TDictionary::DeclareFunction(std::shared_ptr<GC> gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
|
||||
{
|
||||
void TDictionary::DeclareFunction(
|
||||
std::shared_ptr<GC> gc, std::string key, std::string documentation,
|
||||
std::vector<std::string> argNames,
|
||||
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
|
||||
gc->BarrierBegin();
|
||||
GCList ls(gc);
|
||||
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb));
|
||||
this->SetValue(key,
|
||||
TExternalMethod::Create(ls, documentation, argNames, cb));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
void TDictionary::DeclareFunction(std::shared_ptr<GC> gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
|
||||
{
|
||||
void TDictionary::DeclareFunction(
|
||||
std::shared_ptr<GC> gc, std::string key, std::string documentation,
|
||||
std::vector<std::string> argNames,
|
||||
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
|
||||
std::function<void()> destroy) {
|
||||
gc->BarrierBegin();
|
||||
GCList ls(gc);
|
||||
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
|
||||
this->SetValue(
|
||||
key, TExternalMethod::Create(ls, documentation, argNames, cb, destroy));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
TObject TDictionary::GetValue(std::string key)
|
||||
{
|
||||
if(this->items.empty()) return Undefined();
|
||||
TObject TDictionary::GetValue(std::string key) {
|
||||
if (this->items.empty())
|
||||
return Undefined();
|
||||
if (this->items.count(key) > 0)
|
||||
return this->items[key];
|
||||
return Undefined();
|
||||
}
|
||||
void TDictionary::SetValue(std::string key, TObject value)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(value))
|
||||
{
|
||||
void TDictionary::SetValue(std::string key, TObject value) {
|
||||
if (std::holds_alternative<Undefined>(value)) {
|
||||
if (this->items.count(key) > 0)
|
||||
this->items.erase(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->items[key] = value;
|
||||
}
|
||||
}
|
||||
bool TDictionary::HasValue(std::string key)
|
||||
{
|
||||
bool TDictionary::HasValue(std::string key) {
|
||||
return this->items.count(key) > 0;
|
||||
}
|
||||
void TDictionary::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TDictionary::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
for(auto item : this->items)
|
||||
{
|
||||
for (auto item : this->items) {
|
||||
GC::Mark(item.second);
|
||||
}
|
||||
}
|
||||
TDictionary* TDictionary::Create(GCList* gc)
|
||||
{
|
||||
TDictionary *TDictionary::Create(GCList *gc) {
|
||||
TDictionary *dict = new TDictionary();
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(dict);
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
TDictionary* TDictionary::Create(GCList& gc)
|
||||
{
|
||||
TDictionary *TDictionary::Create(GCList &gc) {
|
||||
TDictionary *dict = new TDictionary();
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(dict);
|
||||
@@ -218,4 +203,4 @@ namespace Tesses::CrossLang {
|
||||
return dict;
|
||||
}
|
||||
|
||||
};
|
||||
}; // namespace Tesses::CrossLang
|
||||
|
||||
@@ -2,88 +2,72 @@
|
||||
|
||||
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->resource = resource;
|
||||
this->file = CreateMarkedTObject(gc, file);
|
||||
}
|
||||
bool EmbedStream::CanRead()
|
||||
{
|
||||
bool EmbedStream::CanRead() {
|
||||
TFile *file;
|
||||
if(GetObjectHeap(this->file->GetObject(),file))
|
||||
{
|
||||
if(this->resource >= file->resources.size()) return false;
|
||||
if(this->offset >= file->resources[this->resource].size()) return false;
|
||||
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||
if (this->resource >= file->resources.size())
|
||||
return false;
|
||||
if (this->offset >= file->resources[this->resource].size())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool EmbedStream::CanSeek()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool EmbedStream::EndOfStream()
|
||||
{
|
||||
return !CanRead();
|
||||
}
|
||||
size_t EmbedStream::Read(uint8_t* buff, size_t len)
|
||||
{
|
||||
bool EmbedStream::CanSeek() { return true; }
|
||||
bool EmbedStream::EndOfStream() { return !CanRead(); }
|
||||
size_t EmbedStream::Read(uint8_t *buff, size_t len) {
|
||||
TFile *file;
|
||||
|
||||
if(GetObjectHeap(this->file->GetObject(),file))
|
||||
{
|
||||
if(this->resource >= file->resources.size()) return 0;
|
||||
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||
if (this->resource >= file->resources.size())
|
||||
return 0;
|
||||
auto flen = file->resources[this->resource].size();
|
||||
if(this->offset >= flen) return 0;
|
||||
if (this->offset >= flen)
|
||||
return 0;
|
||||
|
||||
len = std::min(len, std::min(
|
||||
flen,
|
||||
flen - this->offset
|
||||
));
|
||||
len = std::min(len, std::min(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;
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int64_t EmbedStream::GetPosition()
|
||||
{
|
||||
return (int64_t)this->offset;
|
||||
}
|
||||
int64_t EmbedStream::GetLength()
|
||||
{
|
||||
int64_t EmbedStream::GetPosition() { return (int64_t)this->offset; }
|
||||
int64_t EmbedStream::GetLength() {
|
||||
TFile *file;
|
||||
|
||||
if(GetObjectHeap(this->file->GetObject(),file))
|
||||
{
|
||||
if(this->resource >= file->resources.size()) return 0;
|
||||
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||
if (this->resource >= file->resources.size())
|
||||
return 0;
|
||||
return (int64_t)file->resources[this->resource].size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void EmbedStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
|
||||
{
|
||||
switch(whence)
|
||||
{
|
||||
void EmbedStream::Seek(int64_t pos,
|
||||
Tesses::Framework::Streams::SeekOrigin whence) {
|
||||
switch (whence) {
|
||||
case Tesses::Framework::Streams::SeekOrigin::Begin:
|
||||
this->offset = (uint32_t)pos;
|
||||
break;
|
||||
case Tesses::Framework::Streams::SeekOrigin::Current:
|
||||
{
|
||||
case Tesses::Framework::Streams::SeekOrigin::Current: {
|
||||
int64_t cur = this->offset;
|
||||
cur += pos;
|
||||
this->offset = (uint32_t)cur;
|
||||
}
|
||||
break;
|
||||
case Tesses::Framework::Streams::SeekOrigin::End:
|
||||
{
|
||||
} break;
|
||||
case Tesses::Framework::Streams::SeekOrigin::End: {
|
||||
TFile *file;
|
||||
|
||||
if(GetObjectHeap(this->file->GetObject(),file))
|
||||
{
|
||||
if(this->resource >= file->resources.size()) return;
|
||||
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||
if (this->resource >= file->resources.size())
|
||||
return;
|
||||
int64_t cur = (int64_t)file->resources[this->resource].size();
|
||||
cur += pos;
|
||||
this->offset = (uint32_t)cur;
|
||||
@@ -92,15 +76,12 @@ namespace Tesses::CrossLang {
|
||||
}
|
||||
}
|
||||
}
|
||||
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
path = path.CollapseRelativeParents();
|
||||
auto curEntry = this->dir->GetObject();
|
||||
for(auto item : path.path)
|
||||
{
|
||||
for (auto item : path.path) {
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(curEntry,dict) && dict->HasValue(item))
|
||||
{
|
||||
if (GetObjectHeap(curEntry, dict) && dict->HasValue(item)) {
|
||||
curEntry = dict->GetValue(item);
|
||||
continue; // don't want to return undefined now do we
|
||||
}
|
||||
@@ -109,30 +90,30 @@ namespace Tesses::CrossLang {
|
||||
return curEntry;
|
||||
}
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
|
||||
{
|
||||
if(mode != "r" && mode != "rb") return nullptr;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream>
|
||||
EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path,
|
||||
std::string mode) {
|
||||
if (mode != "r" && mode != "rb")
|
||||
return nullptr;
|
||||
|
||||
auto ent = getEntry(path);
|
||||
TCallable *call;
|
||||
if(GetObjectHeap(ent,call))
|
||||
{
|
||||
if (GetObjectHeap(ent, call)) {
|
||||
GCList ls(this->dir->GetGC());
|
||||
auto fileO = call->Call(ls, {});
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if(GetObject(fileO,strm)) return strm;
|
||||
if (GetObject(fileO, strm))
|
||||
return strm;
|
||||
}
|
||||
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);
|
||||
|
||||
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(ent,dict))
|
||||
{
|
||||
if (GetObjectHeap(ent, dict)) {
|
||||
data.Size = 0;
|
||||
data.Mode = Tesses::Framework::Filesystem::MODE_DIRECTORY | 0755;
|
||||
data.BlockCount = 0;
|
||||
@@ -150,8 +131,7 @@ namespace Tesses::CrossLang {
|
||||
return true;
|
||||
}
|
||||
TCallable *cal;
|
||||
if(GetObjectHeap(ent, cal))
|
||||
{
|
||||
if (GetObjectHeap(ent, cal)) {
|
||||
GCList ls(this->dir->GetGC());
|
||||
auto fileO = cal->Call(ls, {});
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
@@ -178,77 +158,63 @@ namespace Tesses::CrossLang {
|
||||
return false;
|
||||
}
|
||||
|
||||
class DICT_DIRENUM
|
||||
{
|
||||
class DICT_DIRENUM {
|
||||
GCList ls;
|
||||
TDictionary *dict;
|
||||
std::map<std::string, Tesses::CrossLang::TObject>::iterator current;
|
||||
bool hasStarted = false;
|
||||
|
||||
public:
|
||||
std::string GetCurrent()
|
||||
{
|
||||
return this->current->first;
|
||||
}
|
||||
DICT_DIRENUM(std::shared_ptr<GC> gc, TDictionary* dict) : ls(gc), dict(dict)
|
||||
{
|
||||
std::string GetCurrent() { return this->current->first; }
|
||||
DICT_DIRENUM(std::shared_ptr<GC> gc, TDictionary *dict)
|
||||
: ls(gc), dict(dict) {
|
||||
ls.Add(dict);
|
||||
}
|
||||
bool MoveNext()
|
||||
{
|
||||
if(!this->hasStarted)
|
||||
{
|
||||
bool MoveNext() {
|
||||
if (!this->hasStarted) {
|
||||
this->hasStarted = true;
|
||||
this->current = this->dict->items.begin();
|
||||
return !this->dict->items.empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->current++;
|
||||
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);
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(ent,dict))
|
||||
{
|
||||
if (GetObjectHeap(ent, dict)) {
|
||||
DICT_DIRENUM *dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPathEnumerator er(
|
||||
[dir2,path](Tesses::Framework::Filesystem::VFSPath& path2)->bool {
|
||||
if(dir2->MoveNext())
|
||||
{
|
||||
[dir2,
|
||||
path](Tesses::Framework::Filesystem::VFSPath &path2) -> bool {
|
||||
if (dir2->MoveNext()) {
|
||||
path2 = path / dir2->GetCurrent();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[dir2]()->void {
|
||||
delete dir2;
|
||||
}
|
||||
);
|
||||
[dir2]() -> void { delete dir2; });
|
||||
|
||||
return er;
|
||||
}
|
||||
return Tesses::Framework::Filesystem::VFSPathEnumerator();
|
||||
}
|
||||
|
||||
EmbedDirectory::EmbedDirectory(std::shared_ptr<GC> gc, TDictionary* dict)
|
||||
{
|
||||
EmbedDirectory::EmbedDirectory(std::shared_ptr<GC> gc, TDictionary *dict) {
|
||||
this->dir = CreateMarkedTObject(gc, dict);
|
||||
}
|
||||
|
||||
std::string EmbedDirectory::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
std::string
|
||||
EmbedDirectory::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
return path.ToString();
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath EmbedDirectory::SystemToVFSPath(std::string path)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath
|
||||
EmbedDirectory::SystemToVFSPath(std::string path) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,54 +1,64 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
TExternalMethod::TExternalMethod(std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::string documentation, std::vector<std::string> argNames,std::function<void()> destroy)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
TExternalMethod::TExternalMethod(
|
||||
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
|
||||
std::string documentation, std::vector<std::string> argNames,
|
||||
std::function<void()> destroy) {
|
||||
|
||||
this->cb = cb;
|
||||
this->args = argNames;
|
||||
this->documentation = documentation;
|
||||
this->destroy = destroy;
|
||||
}
|
||||
TExternalMethod* TExternalMethod::Create(GCList& ls,std::string documentation,std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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{});
|
||||
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)
|
||||
{
|
||||
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{});
|
||||
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();
|
||||
TObject TExternalMethod::Call(GCList &ls, std::vector<TObject> args) {
|
||||
if (cb == nullptr)
|
||||
return Undefined();
|
||||
return this->cb(ls, args);
|
||||
}
|
||||
TExternalMethod::~TExternalMethod()
|
||||
{
|
||||
TExternalMethod::~TExternalMethod() {
|
||||
if (this->destroy != nullptr)
|
||||
this->destroy();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,35 +1,31 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
bool TYieldEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
bool TYieldEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
CallStackEntry *ent;
|
||||
GCList ls2(ls);
|
||||
if(!this->hasStarted)
|
||||
{
|
||||
if (!this->hasStarted) {
|
||||
TClosure *clos;
|
||||
if(!GetObjectHeap(this->enumerator,clos)) return false;
|
||||
if (!GetObjectHeap(this->enumerator, clos))
|
||||
return false;
|
||||
auto _enumerator = clos->Call(ls2, {});
|
||||
ls->BarrierBegin();
|
||||
this->enumerator = _enumerator;
|
||||
this->hasStarted = true;
|
||||
ls->BarrierEnd();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
if(GetObjectHeap(this->enumerator,ent))
|
||||
{
|
||||
if (GetObjectHeap(this->enumerator, ent)) {
|
||||
auto _enumerator = ent->Resume(ls2);
|
||||
ls->BarrierBegin();
|
||||
this->enumerator = _enumerator;
|
||||
ls->BarrierEnd();
|
||||
|
||||
} else return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
if(GetObjectHeap(this->enumerator,ent))
|
||||
{
|
||||
if (GetObjectHeap(this->enumerator, ent)) {
|
||||
ls->BarrierBegin();
|
||||
this->current = ent->Pop(ls2);
|
||||
ls->BarrierEnd();
|
||||
@@ -37,20 +33,18 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject TYieldEnumerator::GetCurrent(GCList& ls)
|
||||
{
|
||||
TObject TYieldEnumerator::GetCurrent(GCList &ls) {
|
||||
ls.Add(this->current);
|
||||
return this->current;
|
||||
}
|
||||
void TYieldEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TYieldEnumerator::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
GC::Mark(this->current);
|
||||
GC::Mark(this->enumerator);
|
||||
}
|
||||
TYieldEnumerator* TYieldEnumerator::Create(GCList& ls,TObject v)
|
||||
{
|
||||
TYieldEnumerator *TYieldEnumerator::Create(GCList &ls, TObject v) {
|
||||
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
|
||||
yieldEnum->current = nullptr;
|
||||
yieldEnum->hasStarted = false;
|
||||
@@ -61,8 +55,7 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(yieldEnum);
|
||||
return yieldEnum;
|
||||
}
|
||||
TYieldEnumerator* TYieldEnumerator::Create(GCList* ls,TObject v)
|
||||
{
|
||||
TYieldEnumerator *TYieldEnumerator::Create(GCList *ls, TObject v) {
|
||||
|
||||
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
|
||||
yieldEnum->current = nullptr;
|
||||
@@ -75,22 +68,20 @@ namespace Tesses::CrossLang
|
||||
return yieldEnum;
|
||||
}
|
||||
|
||||
bool TCustomEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
bool TCustomEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
GCList ls2(ls);
|
||||
auto res = this->dict->CallMethod(ls2, "MoveNext", {});
|
||||
bool out;
|
||||
if(GetObject(res,out)) return out;
|
||||
if (GetObject(res, out))
|
||||
return out;
|
||||
return false;
|
||||
}
|
||||
TObject TCustomEnumerator::GetCurrent(GCList& ls)
|
||||
{
|
||||
TObject TCustomEnumerator::GetCurrent(GCList &ls) {
|
||||
TObject res = Undefined();
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto getCurrent = this->dict->GetValue("getCurrent");
|
||||
TCallable *call;
|
||||
if(GetObjectHeap(getCurrent,call))
|
||||
{
|
||||
if (GetObjectHeap(getCurrent, call)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
res = call->Call(ls, {});
|
||||
ls.GetGC()->BarrierBegin();
|
||||
@@ -101,13 +92,12 @@ namespace Tesses::CrossLang
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return res;
|
||||
}
|
||||
void TCustomEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TCustomEnumerator::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->dict->Mark();
|
||||
}
|
||||
TCustomEnumerator* TCustomEnumerator::Create(GCList* ls, TDictionary* dict)
|
||||
{
|
||||
TCustomEnumerator *TCustomEnumerator::Create(GCList *ls, TDictionary *dict) {
|
||||
TCustomEnumerator *customEnum = new TCustomEnumerator();
|
||||
customEnum->dict = dict;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
@@ -115,8 +105,7 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(customEnum);
|
||||
return customEnum;
|
||||
}
|
||||
TCustomEnumerator* TCustomEnumerator::Create(GCList& ls, TDictionary* dict)
|
||||
{
|
||||
TCustomEnumerator *TCustomEnumerator::Create(GCList &ls, TDictionary *dict) {
|
||||
TCustomEnumerator *customEnum = new TCustomEnumerator();
|
||||
customEnum->dict = dict;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
@@ -124,42 +113,36 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(customEnum);
|
||||
return customEnum;
|
||||
}
|
||||
TEnumerator* TEnumerator::CreateFromObject(GCList& ls, TObject obj)
|
||||
{
|
||||
TEnumerator *TEnumerator::CreateFromObject(GCList &ls, TObject obj) {
|
||||
std::string str;
|
||||
TList *mls;
|
||||
TDynamicList *dynList;
|
||||
TDynamicDictionary *dynDict;
|
||||
TDictionary *dict;
|
||||
TEnumerator *enumerator;
|
||||
if(GetObject(obj,str))
|
||||
{
|
||||
TQueryable *q;
|
||||
if (GetObject(obj, 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))
|
||||
{
|
||||
} else if (GetObjectHeap(obj, dynList)) {
|
||||
return TDynamicListEnumerator::Create(ls, dynList);
|
||||
}
|
||||
else if(GetObjectHeap(obj,dict))
|
||||
{
|
||||
} else if (GetObjectHeap(obj, dict)) {
|
||||
auto res = dict->CallMethod(ls, "GetEnumerator", {});
|
||||
if(GetObjectHeap(res,dict))
|
||||
{
|
||||
if (GetObjectHeap(res, dict)) {
|
||||
return TCustomEnumerator::Create(ls, dict);
|
||||
}
|
||||
else if(GetObjectHeap(res,enumerator))
|
||||
{
|
||||
} else if (GetObjectHeap(res, enumerator)) {
|
||||
return enumerator;
|
||||
}
|
||||
} else if (GetObjectHeap(obj, q)) {
|
||||
return q->GetEnumerator(ls);
|
||||
} else if (GetObjectHeap(obj, enumerator)) {
|
||||
return enumerator;
|
||||
}
|
||||
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();
|
||||
vfspathe->enumerator = enumerator;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
@@ -167,8 +150,8 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(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();
|
||||
vfspathe->enumerator = enumerator;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
@@ -176,16 +159,14 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(vfspathe);
|
||||
return vfspathe;
|
||||
}
|
||||
bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
return enumerator.MoveNext();
|
||||
}
|
||||
TObject TVFSPathEnumerator::GetCurrent(GCList& ls)
|
||||
{
|
||||
TObject TVFSPathEnumerator::GetCurrent(GCList &ls) {
|
||||
return enumerator.Current;
|
||||
}
|
||||
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList& ls, TDictionary* dict)
|
||||
{
|
||||
TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList &ls,
|
||||
TDictionary *dict) {
|
||||
TDictionaryEnumerator *dicte = new TDictionaryEnumerator();
|
||||
dicte->dict = dict;
|
||||
dicte->hasStarted = false;
|
||||
@@ -194,8 +175,8 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(dicte);
|
||||
return dicte;
|
||||
}
|
||||
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList* ls, TDictionary* dict)
|
||||
{
|
||||
TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList *ls,
|
||||
TDictionary *dict) {
|
||||
TDictionaryEnumerator *dicte = new TDictionaryEnumerator();
|
||||
dicte->dict = dict;
|
||||
dicte->hasStarted = false;
|
||||
@@ -205,25 +186,20 @@ namespace Tesses::CrossLang
|
||||
return dicte;
|
||||
}
|
||||
|
||||
bool TDictionaryEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
if(!this->hasStarted)
|
||||
{
|
||||
bool TDictionaryEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (!this->hasStarted) {
|
||||
this->hasStarted = true;
|
||||
this->ittr = this->dict->items.begin();
|
||||
return !this->dict->items.empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ittr++;
|
||||
return this->ittr != this->dict->items.end();
|
||||
}
|
||||
}
|
||||
TObject TDictionaryEnumerator::GetCurrent(GCList& ls)
|
||||
{
|
||||
if(!this->hasStarted) return Undefined();
|
||||
if(this->ittr != this->dict->items.end())
|
||||
{
|
||||
TObject TDictionaryEnumerator::GetCurrent(GCList &ls) {
|
||||
if (!this->hasStarted)
|
||||
return Undefined();
|
||||
if (this->ittr != this->dict->items.end()) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
std::string key = this->ittr->first;
|
||||
TObject value = this->ittr->second;
|
||||
@@ -235,16 +211,14 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void TDictionaryEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TDictionaryEnumerator::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->dict->Mark();
|
||||
}
|
||||
|
||||
|
||||
TListEnumerator* TListEnumerator::Create(GCList& ls, TList* list)
|
||||
{
|
||||
TListEnumerator *TListEnumerator::Create(GCList &ls, TList *list) {
|
||||
TListEnumerator *liste = new TListEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
@@ -253,8 +227,7 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
TListEnumerator* TListEnumerator::Create(GCList* ls, TList* list)
|
||||
{
|
||||
TListEnumerator *TListEnumerator::Create(GCList *ls, TList *list) {
|
||||
TListEnumerator *liste = new TListEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
@@ -263,31 +236,32 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
this->index++;
|
||||
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->ls->Count() == 0) return nullptr;
|
||||
if(this->index >= this->ls->Count()) return nullptr;
|
||||
if (this->index < -1)
|
||||
return nullptr;
|
||||
if (this->ls->Count() == 0)
|
||||
return nullptr;
|
||||
if (this->index >= this->ls->Count())
|
||||
return nullptr;
|
||||
ls.GetGC()->BarrierBegin();
|
||||
TObject o = this->ls->Get(index);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return o;
|
||||
}
|
||||
void TListEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TListEnumerator::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->ls->Mark();
|
||||
}
|
||||
|
||||
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList& ls, TAssociativeArray* list)
|
||||
{
|
||||
TAssociativeArrayEnumerator *
|
||||
TAssociativeArrayEnumerator::Create(GCList &ls, TAssociativeArray *list) {
|
||||
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
@@ -296,8 +270,8 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList* ls, TAssociativeArray* list)
|
||||
{
|
||||
TAssociativeArrayEnumerator *
|
||||
TAssociativeArrayEnumerator::Create(GCList *ls, TAssociativeArray *list) {
|
||||
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
@@ -306,17 +280,18 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
this->index++;
|
||||
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->ls->Count() == 0) return nullptr;
|
||||
if(this->index >= this->ls->Count()) return nullptr;
|
||||
if (this->index < -1)
|
||||
return nullptr;
|
||||
if (this->ls->Count() == 0)
|
||||
return nullptr;
|
||||
if (this->index >= this->ls->Count())
|
||||
return nullptr;
|
||||
ls.GetGC()->BarrierBegin();
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->SetValue("Key", this->ls->GetKey(this->index));
|
||||
@@ -324,17 +299,15 @@ namespace Tesses::CrossLang
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
void TAssociativeArrayEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TAssociativeArrayEnumerator::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->ls->Mark();
|
||||
}
|
||||
|
||||
|
||||
|
||||
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList& ls, TDynamicList* list)
|
||||
{
|
||||
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList &ls,
|
||||
TDynamicList *list) {
|
||||
TDynamicListEnumerator *liste = new TDynamicListEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
@@ -343,8 +316,8 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList* ls, TDynamicList* list)
|
||||
{
|
||||
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList *ls,
|
||||
TDynamicList *list) {
|
||||
TDynamicListEnumerator *liste = new TDynamicListEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
@@ -353,34 +326,33 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
this->index++;
|
||||
GCList ls2(ls);
|
||||
return this->index >= 0 && this->index < this->ls->Count(ls2);
|
||||
}
|
||||
TObject TDynamicListEnumerator::GetCurrent(GCList& ls)
|
||||
{
|
||||
TObject TDynamicListEnumerator::GetCurrent(GCList &ls) {
|
||||
|
||||
if(this->index < -1) return nullptr;
|
||||
if (this->index < -1)
|
||||
return nullptr;
|
||||
auto r = this->ls->Count(ls);
|
||||
if(r == 0) return nullptr;
|
||||
if(this->index >= r) return nullptr;
|
||||
if (r == 0)
|
||||
return nullptr;
|
||||
if (this->index >= r)
|
||||
return nullptr;
|
||||
ls.GetGC()->BarrierBegin();
|
||||
TObject o = this->ls->GetAt(ls, index);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return o;
|
||||
}
|
||||
void TDynamicListEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TDynamicListEnumerator::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->ls->Mark();
|
||||
}
|
||||
|
||||
|
||||
TStringEnumerator* TStringEnumerator::Create(GCList& ls,std::string str)
|
||||
{
|
||||
TStringEnumerator *TStringEnumerator::Create(GCList &ls, std::string str) {
|
||||
TStringEnumerator *stre = new TStringEnumerator();
|
||||
stre->str = str;
|
||||
stre->hasStarted = false;
|
||||
@@ -389,8 +361,7 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(stre);
|
||||
return stre;
|
||||
}
|
||||
TStringEnumerator* TStringEnumerator::Create(GCList* ls,std::string str)
|
||||
{
|
||||
TStringEnumerator *TStringEnumerator::Create(GCList *ls, std::string str) {
|
||||
TStringEnumerator *stre = new TStringEnumerator();
|
||||
stre->str = str;
|
||||
stre->hasStarted = false;
|
||||
@@ -399,26 +370,24 @@ namespace Tesses::CrossLang
|
||||
_gc->Watch(stre);
|
||||
return stre;
|
||||
}
|
||||
bool TStringEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
if(!this->hasStarted)
|
||||
{
|
||||
bool TStringEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (!this->hasStarted) {
|
||||
this->hasStarted = true;
|
||||
this->index = 0;
|
||||
return !this->str.empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this->index >= this->str.size()) return false;
|
||||
} else {
|
||||
if (this->index >= this->str.size())
|
||||
return false;
|
||||
this->index++;
|
||||
return this->index < this->str.size();
|
||||
}
|
||||
}
|
||||
TObject TStringEnumerator::GetCurrent(GCList& ls)
|
||||
{
|
||||
if(!this->hasStarted) return nullptr;
|
||||
if(this->index < this->str.size()) return this->str[this->index];
|
||||
TObject TStringEnumerator::GetCurrent(GCList &ls) {
|
||||
if (!this->hasStarted)
|
||||
return nullptr;
|
||||
if (this->index < this->str.size())
|
||||
return this->str[this->index];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
};
|
||||
}; // namespace Tesses::CrossLang
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang {
|
||||
TDynamicList* TDynamicList::Create(GCList& ls,TCallable* callable)
|
||||
{
|
||||
TDynamicList *TDynamicList::Create(GCList &ls, TCallable *callable) {
|
||||
TDynamicList *list = new TDynamicList();
|
||||
list->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
@@ -9,8 +8,7 @@ namespace Tesses::CrossLang {
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TDynamicList* TDynamicList::Create(GCList* ls,TCallable* callable)
|
||||
{
|
||||
TDynamicList *TDynamicList::Create(GCList *ls, TCallable *callable) {
|
||||
TDynamicList *list = new TDynamicList();
|
||||
list->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
@@ -19,15 +17,14 @@ namespace Tesses::CrossLang {
|
||||
return list;
|
||||
}
|
||||
|
||||
void TDynamicList::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TDynamicList::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->cb->Mark();
|
||||
}
|
||||
|
||||
int64_t TDynamicList::Count(GCList& ls)
|
||||
{
|
||||
int64_t TDynamicList::Count(GCList &ls) {
|
||||
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
@@ -35,11 +32,11 @@ namespace Tesses::CrossLang {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
auto res = cb->Call(ls, {dict});
|
||||
int64_t n;
|
||||
if(GetObject(res,n)) return n;
|
||||
if (GetObject(res, n))
|
||||
return n;
|
||||
return 0;
|
||||
}
|
||||
TObject TDynamicList::Add(GCList& ls, TObject v)
|
||||
{
|
||||
TObject TDynamicList::Add(GCList &ls, TObject v) {
|
||||
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
@@ -47,10 +44,8 @@ namespace Tesses::CrossLang {
|
||||
dict->SetValue("Value", v);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
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);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
@@ -59,18 +54,15 @@ namespace Tesses::CrossLang {
|
||||
dict->SetValue("Value", v);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls, {dict});
|
||||
|
||||
}
|
||||
TObject TDynamicList::Clear(GCList& ls)
|
||||
{
|
||||
TObject TDynamicList::Clear(GCList &ls) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Clear");
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
TObject TDynamicList::Remove(GCList& ls, TObject obj)
|
||||
{
|
||||
TObject TDynamicList::Remove(GCList &ls, TObject obj) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Remove");
|
||||
@@ -79,8 +71,7 @@ namespace Tesses::CrossLang {
|
||||
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
TObject TDynamicList::RemoveAllEqual(GCList& ls, TObject obj)
|
||||
{
|
||||
TObject TDynamicList::RemoveAllEqual(GCList &ls, TObject obj) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "RemoveAllEqual");
|
||||
@@ -89,8 +80,7 @@ namespace Tesses::CrossLang {
|
||||
|
||||
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);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "RemoveAt");
|
||||
@@ -99,8 +89,7 @@ namespace Tesses::CrossLang {
|
||||
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
TObject TDynamicList::ToString(GCList& ls)
|
||||
{
|
||||
TObject TDynamicList::ToString(GCList &ls) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "ToString");
|
||||
@@ -109,8 +98,7 @@ namespace Tesses::CrossLang {
|
||||
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);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
@@ -120,8 +108,7 @@ namespace Tesses::CrossLang {
|
||||
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);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "SetAt");
|
||||
@@ -131,14 +118,9 @@ namespace Tesses::CrossLang {
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
|
||||
TDynamicList::~TDynamicList()
|
||||
{
|
||||
TDynamicList::~TDynamicList() {}
|
||||
|
||||
}
|
||||
|
||||
|
||||
TByteArray* TByteArray::Create(GCList& ls)
|
||||
{
|
||||
TByteArray *TByteArray::Create(GCList &ls) {
|
||||
TByteArray *arr = new TByteArray();
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(arr);
|
||||
@@ -146,78 +128,57 @@ namespace Tesses::CrossLang {
|
||||
return arr;
|
||||
}
|
||||
|
||||
TByteArray* TByteArray::Create(GCList* ls)
|
||||
{
|
||||
TByteArray *TByteArray::Create(GCList *ls) {
|
||||
TByteArray *arr = new TByteArray();
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(arr);
|
||||
_gc->Watch(arr);
|
||||
return arr;
|
||||
}
|
||||
TList* TList::Create(GCList* gc)
|
||||
{
|
||||
TList *TList::Create(GCList *gc) {
|
||||
TList *list = new TList();
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TList* TList::Create(GCList& gc)
|
||||
{
|
||||
TList *TList::Create(GCList &gc) {
|
||||
TList *list = new TList();
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
void TList::Add(TObject value)
|
||||
{
|
||||
this->items.push_back(value);
|
||||
}
|
||||
void TList::Set(int64_t index, TObject value)
|
||||
{
|
||||
if(index >= 0 && index < this->Count())
|
||||
{
|
||||
void TList::Add(TObject value) { this->items.push_back(value); }
|
||||
void TList::Set(int64_t index, TObject value) {
|
||||
if (index >= 0 && index < this->Count()) {
|
||||
this->items[index] = value;
|
||||
}
|
||||
}
|
||||
TObject TList::Get(int64_t index)
|
||||
{
|
||||
if(index >= 0 && index < this->Count())
|
||||
{
|
||||
TObject TList::Get(int64_t index) {
|
||||
if (index >= 0 && index < this->Count()) {
|
||||
return this->items[index];
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
int64_t TList::Count()
|
||||
{
|
||||
return (int64_t)this->items.size();
|
||||
}
|
||||
void TList::Insert(int64_t index, TObject value)
|
||||
{
|
||||
if(index >= 0 && index <= this->Count())
|
||||
{
|
||||
int64_t TList::Count() { return (int64_t)this->items.size(); }
|
||||
void TList::Insert(int64_t index, TObject value) {
|
||||
if (index >= 0 && index <= this->Count()) {
|
||||
this->items.insert(this->items.begin() + index, value);
|
||||
}
|
||||
}
|
||||
void TList::RemoveAt(int64_t index)
|
||||
{
|
||||
if(index >= 0 && index < this->Count())
|
||||
{
|
||||
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;
|
||||
void TList::Clear() { this->items.clear(); }
|
||||
void TList::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
for(auto item : this->items)
|
||||
{
|
||||
for (auto item : this->items) {
|
||||
GC::Mark(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
}; // namespace Tesses::CrossLang
|
||||
@@ -1,75 +1,53 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
TNativeObject::~TNativeObject()
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
TNativeObject::~TNativeObject() {}
|
||||
|
||||
}
|
||||
|
||||
TNative::TNative(void* ptr,std::function<void(void*)> destroy)
|
||||
{
|
||||
TNative::TNative(void *ptr, std::function<void(void *)> destroy) {
|
||||
this->ptr = ptr;
|
||||
this->destroyed = false;
|
||||
this->destroy = destroy;
|
||||
|
||||
}
|
||||
bool TNative::GetDestroyed()
|
||||
{
|
||||
return this->destroyed;
|
||||
}
|
||||
void* TNative::GetPointer()
|
||||
{
|
||||
return this->ptr;
|
||||
}
|
||||
void TNative::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
bool TNative::GetDestroyed() { return this->destroyed; }
|
||||
void *TNative::GetPointer() { return this->ptr; }
|
||||
void TNative::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
GC::Mark(this->other);
|
||||
|
||||
}
|
||||
void TNative::Destroy()
|
||||
{
|
||||
if(this->destroyed) return;
|
||||
if(this->destroy != nullptr)
|
||||
{
|
||||
void TNative::Destroy() {
|
||||
if (this->destroyed)
|
||||
return;
|
||||
if (this->destroy != nullptr) {
|
||||
this->destroyed = true;
|
||||
this->destroy(this->ptr);
|
||||
}
|
||||
}
|
||||
bool TNativeObject::ToBool()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool TNativeObject::Equals(std::shared_ptr<GC> gc, TObject right)
|
||||
{
|
||||
if(std::holds_alternative<THeapObjectHolder>(right))
|
||||
{
|
||||
bool TNativeObject::ToBool() { return true; }
|
||||
bool TNativeObject::Equals(std::shared_ptr<GC> gc, TObject right) {
|
||||
if (std::holds_alternative<THeapObjectHolder>(right)) {
|
||||
return this == std::get<THeapObjectHolder>(right).obj;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TNative* TNative::Create(GCList& ls, void* ptr,std::function<void(void*)> destroy)
|
||||
{
|
||||
TNative *TNative::Create(GCList &ls, void *ptr,
|
||||
std::function<void(void *)> destroy) {
|
||||
TNative *native = new TNative(ptr, destroy);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(native);
|
||||
gc->Watch(native);
|
||||
return native;
|
||||
}
|
||||
TNative* TNative::Create(GCList* ls, void* ptr,std::function<void(void*)> destroy)
|
||||
{
|
||||
TNative *TNative::Create(GCList *ls, void *ptr,
|
||||
std::function<void(void *)> destroy) {
|
||||
TNative *native = new TNative(ptr, destroy);
|
||||
std::shared_ptr<GC> gc = ls->GetGC();
|
||||
ls->Add(native);
|
||||
gc->Watch(native);
|
||||
return native;
|
||||
}
|
||||
TNative::~TNative()
|
||||
{
|
||||
this->Destroy();
|
||||
}
|
||||
TNative::~TNative() { this->Destroy(); }
|
||||
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
476
src/types/queryable.cpp
Normal file
476
src/types/queryable.cpp
Normal file
@@ -0,0 +1,476 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
TQueryable::TQueryable(TObject parent)
|
||||
: TQueryable(parent, TQueryableMode::Passthrough, {}) {}
|
||||
TQueryable::TQueryable(TObject parent, TQueryableMode mode,
|
||||
std::vector<TObject> args)
|
||||
: parent(parent), mode(mode), args(args) {}
|
||||
|
||||
TQueryable *TQueryable::Skip(GCList &ls, int64_t no) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::Skip, {no});
|
||||
}
|
||||
TQueryable *TQueryable::SkipWhile(GCList &ls, TCallable *call) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::SkipWhile, {call});
|
||||
}
|
||||
TQueryable *TQueryable::Take(GCList &ls, int64_t no) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::Take, {no});
|
||||
}
|
||||
TQueryable *TQueryable::TakeWhile(GCList &ls, TCallable *call) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::TakeWhile, {call});
|
||||
}
|
||||
TQueryable *TQueryable::Select(GCList &ls, TCallable *call) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::Select, {call});
|
||||
}
|
||||
TQueryable *TQueryable::Where(GCList &ls, TCallable *call) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::Where, {call});
|
||||
}
|
||||
|
||||
TList *TQueryable::ToList(GCList &ls) {
|
||||
auto gc = ls.GetGC();
|
||||
GCList ls2(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return nullptr;
|
||||
auto list = TList::Create(ls);
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
gc->BarrierBegin();
|
||||
list->Add(enumerator->GetCurrent(ls));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
TQueryable *TQueryable::Create(GCList &ls, TObject parent) {
|
||||
TQueryable *queryable = new TQueryable(parent);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
TQueryable *TQueryable::Create(GCList &ls, TObject parent, TQueryableMode mode,
|
||||
std::vector<TObject> args) {
|
||||
TQueryable *queryable = new TQueryable(parent, mode, args);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
|
||||
void TQueryable::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
GC::Mark(this->parent);
|
||||
for (auto &item : args)
|
||||
GC::Mark(item);
|
||||
}
|
||||
|
||||
void TQueryable::ForEach(std::shared_ptr<GC> gc, TCallable *call) {
|
||||
if (call == nullptr)
|
||||
return;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return;
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
call->Call(ls2, {enumerator->GetCurrent(ls2)});
|
||||
}
|
||||
}
|
||||
int64_t TQueryable::Count(std::shared_ptr<GC> gc, TCallable *call) {
|
||||
if (call == nullptr)
|
||||
return 0;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return 0;
|
||||
int64_t count = 0;
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
if (ToBool(call->Call(ls2, {enumerator->GetCurrent(ls2)})))
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
int64_t TQueryable::Count(std::shared_ptr<GC> gc) {
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return 0;
|
||||
int64_t count = 0;
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
bool TQueryable::Contains(std::shared_ptr<GC> gc, TObject value) {
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return false;
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
|
||||
if (Equals(gc, value, enumerator->GetCurrent(ls2)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TQueryable::Any(std::shared_ptr<GC> gc, TCallable *call) {
|
||||
if (call == nullptr)
|
||||
return false;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return false;
|
||||
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
if (ToBool(call->Call(ls2, {enumerator->GetCurrent(ls2)})))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TQueryable::All(std::shared_ptr<GC> gc, TCallable *call) {
|
||||
if (call == nullptr)
|
||||
return true;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return true;
|
||||
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
if (!ToBool(call->Call(ls2, {enumerator->GetCurrent(ls2)})))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class SkipItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
int64_t skipCount;
|
||||
SkipItterator(TEnumerator *parentEnum, int64_t skipCount)
|
||||
: parentEnum(parentEnum), skipCount(skipCount) {}
|
||||
|
||||
public:
|
||||
static SkipItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
int64_t skipCount) {
|
||||
SkipItterator *queryable = new SkipItterator(parentEnum, skipCount);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr)
|
||||
return false;
|
||||
while (skipCount > 0) {
|
||||
if (!this->parentEnum->MoveNext(ls)) {
|
||||
skipCount = 0;
|
||||
return false;
|
||||
}
|
||||
skipCount--;
|
||||
}
|
||||
return this->parentEnum->MoveNext(ls);
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
}
|
||||
};
|
||||
class TakeItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
int64_t takeCount;
|
||||
TakeItterator(TEnumerator *parentEnum, int64_t takeCount)
|
||||
: parentEnum(parentEnum), takeCount(takeCount) {}
|
||||
|
||||
public:
|
||||
static TakeItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
int64_t takeCount) {
|
||||
TakeItterator *queryable = new TakeItterator(parentEnum, takeCount);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr)
|
||||
return false;
|
||||
if (takeCount > 0) {
|
||||
takeCount--;
|
||||
return this->parentEnum->MoveNext(ls);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
}
|
||||
};
|
||||
class SkipWhileItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
TCallable *callable;
|
||||
SkipWhileItterator(TEnumerator *parentEnum, TCallable *callable)
|
||||
: parentEnum(parentEnum), callable(callable) {}
|
||||
|
||||
public:
|
||||
static SkipWhileItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
TCallable *callable) {
|
||||
SkipWhileItterator *queryable =
|
||||
new SkipWhileItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr)
|
||||
return false;
|
||||
ls->BarrierBegin();
|
||||
auto callable = this->callable;
|
||||
ls->BarrierEnd();
|
||||
|
||||
if (callable != nullptr) {
|
||||
while (true) {
|
||||
if (this->parentEnum->MoveNext(ls)) {
|
||||
GCList ls2(ls);
|
||||
auto result = callable->Call(
|
||||
ls2, {this->parentEnum->GetCurrent(ls2)});
|
||||
if (!ToBool(result)) {
|
||||
ls->BarrierBegin();
|
||||
this->callable = nullptr;
|
||||
ls->BarrierEnd();
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
ls->BarrierBegin();
|
||||
this->callable = nullptr;
|
||||
ls->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this->parentEnum->MoveNext(ls);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
if (callable != nullptr)
|
||||
callable->Mark();
|
||||
}
|
||||
};
|
||||
class TakeWhileItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
TCallable *callable;
|
||||
TakeWhileItterator(TEnumerator *parentEnum, TCallable *callable)
|
||||
: parentEnum(parentEnum), callable(callable) {}
|
||||
|
||||
public:
|
||||
static TakeWhileItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
TCallable *callable) {
|
||||
TakeWhileItterator *queryable =
|
||||
new TakeWhileItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr)
|
||||
return false;
|
||||
ls->BarrierBegin();
|
||||
auto callable = this->callable;
|
||||
ls->BarrierEnd();
|
||||
if (callable != nullptr) {
|
||||
if (this->parentEnum->MoveNext(ls)) {
|
||||
GCList ls2(ls);
|
||||
auto result =
|
||||
callable->Call(ls2, {this->parentEnum->GetCurrent(ls2)});
|
||||
if (!ToBool(result)) {
|
||||
ls->BarrierBegin();
|
||||
this->callable = nullptr;
|
||||
ls->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
if (callable != nullptr)
|
||||
callable->Mark();
|
||||
}
|
||||
};
|
||||
class WhereItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
TCallable *callable;
|
||||
WhereItterator(TEnumerator *parentEnum, TCallable *callable)
|
||||
: parentEnum(parentEnum), callable(callable) {}
|
||||
|
||||
public:
|
||||
static WhereItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
TCallable *callable) {
|
||||
WhereItterator *queryable = new WhereItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr || this->callable == nullptr)
|
||||
return false;
|
||||
while (this->parentEnum->MoveNext(ls)) {
|
||||
GCList ls2(ls);
|
||||
auto cur = this->parentEnum->GetCurrent(ls2);
|
||||
if (ToBool(callable->Call(ls2, {cur})))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
if (callable != nullptr)
|
||||
callable->Mark();
|
||||
}
|
||||
};
|
||||
class SelectItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
TCallable *callable;
|
||||
TObject value;
|
||||
SelectItterator(TEnumerator *parentEnum, TCallable *callable)
|
||||
: parentEnum(parentEnum), callable(callable) {}
|
||||
|
||||
public:
|
||||
static SelectItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
TCallable *callable) {
|
||||
SelectItterator *queryable = new SelectItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr || this->callable == nullptr)
|
||||
return false;
|
||||
if (this->parentEnum->MoveNext(ls)) {
|
||||
GCList ls2(ls);
|
||||
auto cur = this->parentEnum->GetCurrent(ls2);
|
||||
auto value = this->callable->Call(ls2, {cur});
|
||||
|
||||
ls->BarrierBegin();
|
||||
this->value = value;
|
||||
ls->BarrierEnd();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto value = this->value;
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return value;
|
||||
}
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
if (callable != nullptr)
|
||||
callable->Mark();
|
||||
|
||||
GC::Mark(this->value);
|
||||
}
|
||||
};
|
||||
|
||||
TEnumerator *TQueryable::GetEnumerator(GCList &ls) {
|
||||
switch (this->mode) {
|
||||
case TQueryableMode::Skip: {
|
||||
int64_t skipCount;
|
||||
if (GetArgument(args, 0, skipCount))
|
||||
return SkipItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), skipCount);
|
||||
} break;
|
||||
case TQueryableMode::Take: {
|
||||
int64_t takeCount;
|
||||
if (GetArgument(args, 0, takeCount))
|
||||
return TakeItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), takeCount);
|
||||
|
||||
} break;
|
||||
case TQueryableMode::SkipWhile: {
|
||||
TCallable *callable;
|
||||
if (GetArgumentHeap(args, 0, callable))
|
||||
return SkipWhileItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
} break;
|
||||
case TQueryableMode::TakeWhile: {
|
||||
TCallable *callable;
|
||||
if (GetArgumentHeap(args, 0, callable))
|
||||
return TakeWhileItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
} break;
|
||||
case TQueryableMode::Select: {
|
||||
TCallable *callable;
|
||||
if (GetArgumentHeap(args, 0, callable))
|
||||
return SelectItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
} break;
|
||||
case TQueryableMode::Where: {
|
||||
TCallable *callable;
|
||||
if (GetArgumentHeap(args, 0, callable))
|
||||
return WhereItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
return TEnumerator::CreateFromObject(ls, this->parent);
|
||||
}
|
||||
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,29 +1,16 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
TRandom::TRandom() : random()
|
||||
{
|
||||
|
||||
}
|
||||
TRandom::TRandom(uint64_t seed) : random(seed)
|
||||
{
|
||||
|
||||
}
|
||||
std::string TRandom::TypeName()
|
||||
{
|
||||
return "Random";
|
||||
}
|
||||
TObject TRandom::CallMethod(GCList& ls,std::string name, std::vector<TObject> args)
|
||||
{
|
||||
if(name == "Next")
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
TRandom::TRandom() : random() {}
|
||||
TRandom::TRandom(uint64_t seed) : random(seed) {}
|
||||
std::string TRandom::TypeName() { return "Random"; }
|
||||
TObject TRandom::CallMethod(GCList &ls, std::string name,
|
||||
std::vector<TObject> args) {
|
||||
if (name == "Next") {
|
||||
int64_t first;
|
||||
int64_t second;
|
||||
if(GetArgument(args,0,first))
|
||||
{
|
||||
if(GetArgument(args,1,second))
|
||||
{
|
||||
if (GetArgument(args, 0, first)) {
|
||||
if (GetArgument(args, 1, second)) {
|
||||
return (int64_t)random.Next((int32_t)first, (int32_t)second);
|
||||
}
|
||||
|
||||
@@ -31,11 +18,9 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
|
||||
return random.Next();
|
||||
|
||||
}
|
||||
|
||||
if(name == "NextByte")
|
||||
{
|
||||
if (name == "NextByte") {
|
||||
return (int64_t)random.NextByte();
|
||||
}
|
||||
|
||||
@@ -44,4 +29,4 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,275 +0,0 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
RelativeFilesystem::RelativeFilesystem(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath working)
|
||||
{
|
||||
this->vfs = vfs;
|
||||
this->path = working;
|
||||
}
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> RelativeFilesystem::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
return this->vfs->OpenFile(path.MakeAbsolute(GetWorking()), mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->vfs->OpenFile(path,mode);
|
||||
}
|
||||
}
|
||||
|
||||
void RelativeFilesystem::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
this->vfs->CreateDirectory(path.MakeAbsolute(GetWorking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->vfs->CreateDirectory(path);
|
||||
}
|
||||
}
|
||||
void RelativeFilesystem::DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
this->vfs->DeleteDirectory(path.MakeAbsolute(GetWorking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->vfs->DeleteDirectory(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RelativeFilesystem::DeleteFile(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
this->vfs->DeleteFile(path.MakeAbsolute(GetWorking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->vfs->DeleteFile(path);
|
||||
}
|
||||
}
|
||||
void RelativeFilesystem::CreateSymlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath symlinkFile)
|
||||
{
|
||||
if(symlinkFile.relative)
|
||||
{
|
||||
this->vfs->CreateSymlink(existingFile,symlinkFile.MakeAbsolute(GetWorking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->vfs->CreateSymlink(existingFile, symlinkFile);
|
||||
}
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPathEnumerator RelativeFilesystem::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
return this->vfs->EnumeratePaths(path.MakeAbsolute(GetWorking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->vfs->EnumeratePaths(path);
|
||||
}
|
||||
}
|
||||
void RelativeFilesystem::CreateHardlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath newName)
|
||||
{
|
||||
auto working = GetWorking();
|
||||
if(existingFile.relative)
|
||||
{
|
||||
existingFile = existingFile.MakeAbsolute(working);
|
||||
existingFile = existingFile.CollapseRelativeParents();
|
||||
}
|
||||
|
||||
if(newName.relative)
|
||||
{
|
||||
newName = newName.MakeAbsolute(working);
|
||||
newName = newName.CollapseRelativeParents();
|
||||
}
|
||||
|
||||
this->vfs->CreateHardlink(existingFile, newName);
|
||||
}
|
||||
|
||||
void RelativeFilesystem::MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
|
||||
{
|
||||
auto working = GetWorking();
|
||||
if(src.relative)
|
||||
{
|
||||
src = src.MakeAbsolute(working);
|
||||
src = src.CollapseRelativeParents();
|
||||
}
|
||||
|
||||
if(dest.relative)
|
||||
{
|
||||
dest = dest.MakeAbsolute(working);
|
||||
dest = dest.CollapseRelativeParents();
|
||||
}
|
||||
|
||||
this->vfs->MoveFile(src, dest);
|
||||
}
|
||||
|
||||
void RelativeFilesystem::MoveDirectory(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
|
||||
{
|
||||
|
||||
auto working = GetWorking();
|
||||
if(src.relative)
|
||||
{
|
||||
src = src.MakeAbsolute(working);
|
||||
src = src.CollapseRelativeParents();
|
||||
}
|
||||
|
||||
if(dest.relative)
|
||||
{
|
||||
dest = dest.MakeAbsolute(working);
|
||||
dest = dest.CollapseRelativeParents();
|
||||
}
|
||||
|
||||
this->vfs->MoveFile(src, dest);
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath RelativeFilesystem::ReadLink(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
return this->vfs->ReadLink(path.MakeAbsolute(GetWorking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->vfs->ReadLink(path);
|
||||
}
|
||||
}
|
||||
std::string RelativeFilesystem::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
return this->vfs->VFSPathToSystem(path);
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath RelativeFilesystem::SystemToVFSPath(std::string path)
|
||||
{
|
||||
return this->vfs->SystemToVFSPath(path);
|
||||
}
|
||||
|
||||
void RelativeFilesystem::SetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime lastWrite, Tesses::Framework::Date::DateTime lastAccess)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
this->vfs->SetDate(path.MakeAbsolute(GetWorking()), lastWrite,lastAccess);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->vfs->SetDate(path,lastWrite,lastAccess);
|
||||
}
|
||||
}
|
||||
bool RelativeFilesystem::Stat(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatData& stat)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
return this->vfs->Stat(path.MakeAbsolute(GetWorking()), stat);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->vfs->Stat(path,stat);
|
||||
}
|
||||
}
|
||||
bool RelativeFilesystem::StatVFS(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatVFSData& vfsData)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
return this->vfs->StatVFS(path.MakeAbsolute(GetWorking()), vfsData);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->vfs->StatVFS(path,vfsData);
|
||||
}
|
||||
}
|
||||
|
||||
void RelativeFilesystem::Chmod(Tesses::Framework::Filesystem::VFSPath path, uint32_t mode)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
this->vfs->Chmod(path.MakeAbsolute(GetWorking()), mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->vfs->Chmod(path,mode);
|
||||
}
|
||||
}
|
||||
void RelativeFilesystem::Chown(Tesses::Framework::Filesystem::VFSPath path, uint32_t uid, uint32_t gid)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
this->vfs->Chown(path.MakeAbsolute(GetWorking()), uid, gid);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->vfs->Chown(path,uid,gid);
|
||||
}
|
||||
}
|
||||
|
||||
void RelativeFilesystem::Lock(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
this->vfs->Lock(path.MakeAbsolute(GetWorking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->vfs->Lock(path);
|
||||
}
|
||||
}
|
||||
void RelativeFilesystem::Unlock(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
this->vfs->Unlock(path.MakeAbsolute(GetWorking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->vfs->Unlock(path);
|
||||
}
|
||||
}
|
||||
|
||||
Tesses::Framework::Filesystem::FIFOCreationResult RelativeFilesystem::CreateFIFO(Tesses::Framework::Filesystem::VFSPath path, uint32_t mod)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
return this->vfs->CreateFIFO(path.MakeAbsolute(GetWorking()), mod);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->vfs->CreateFIFO(path, mod);
|
||||
}
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath RelativeFilesystem::GetWorking()
|
||||
{
|
||||
mtx.Lock();
|
||||
auto path = this->path;
|
||||
mtx.Unlock();
|
||||
return path;
|
||||
}
|
||||
void RelativeFilesystem::SetWorking(Tesses::Framework::Filesystem::VFSPath working)
|
||||
{
|
||||
mtx.Lock();
|
||||
this->path = working;
|
||||
mtx.Unlock();
|
||||
}
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> RelativeFilesystem::GetVFS()
|
||||
{
|
||||
return this->vfs;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> RelativeFilesystem::CreateWatcher(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
return Tesses::Framework::Filesystem::FSWatcher::Create(vfs, path.MakeAbsolute(GetWorking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Tesses::Framework::Filesystem::FSWatcher::Create(vfs,path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,60 +2,78 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
namespace Tesses::CrossLang {
|
||||
void ThrowConstError(std::string key)
|
||||
{
|
||||
throw std::runtime_error("Cannot set \"" + key + "\" because it is a const");
|
||||
void ThrowConstError(std::string key) {
|
||||
throw std::runtime_error("Cannot set \"" + key +
|
||||
"\" because it is a const");
|
||||
}
|
||||
|
||||
void TEnvironment::DeclareConstVariable(std::string key, TObject value)
|
||||
{
|
||||
void TEnvironment::DeclareConstVariable(std::string key, TObject value) {
|
||||
this->DeclareVariable(key, value);
|
||||
this->consts.push_back(key);
|
||||
}
|
||||
bool TEnvironment::HasConstForDeclare(std::string key)
|
||||
{
|
||||
bool TEnvironment::HasConstForDeclare(std::string key) {
|
||||
for (auto item : this->consts)
|
||||
if (item == key)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool TEnvironment::HasConstForSet(std::string key)
|
||||
{
|
||||
bool TEnvironment::HasConstForSet(std::string key) {
|
||||
return HasConstForDeclare(key);
|
||||
}
|
||||
bool TRootEnvironment::TryFindClass(std::vector<std::string>& name, size_t& index)
|
||||
{
|
||||
for(size_t i = 0; i < this->classes.size(); i++)
|
||||
{
|
||||
if(classes[i].first->classes.at(classes[i].second).name.size() != name.size()) continue;
|
||||
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]) continue;
|
||||
if (classes[i].first->classes.at(classes[i].second).name[j] !=
|
||||
name[j]) {
|
||||
conUp = true;
|
||||
break;
|
||||
}
|
||||
if (conUp)
|
||||
continue;
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TRootEnvironment::HasVariableOrFieldRecurse(std::string key,bool setting)
|
||||
{
|
||||
TDictionary *TRootEnvironment::GetPrivateFromFile(std::shared_ptr<GC> gc,
|
||||
TFile *file) {
|
||||
auto index = reinterpret_cast<uint64_t>(file);
|
||||
gc->BarrierBegin();
|
||||
TDictionary *obj;
|
||||
if (this->private_file_data.count(index) > 0) {
|
||||
obj = this->private_file_data[index];
|
||||
} else {
|
||||
GCList ls(gc);
|
||||
obj = TDictionary::Create(ls);
|
||||
this->private_file_data[index] = obj;
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
|
||||
return obj;
|
||||
}
|
||||
bool TRootEnvironment::HasVariableOrFieldRecurse(std::string key,
|
||||
bool setting) {
|
||||
std::string property = (setting ? "set" : "get") + key;
|
||||
if(this->HasVariable(property))
|
||||
{
|
||||
if (this->HasVariable(property)) {
|
||||
auto res = this->GetVariable(property);
|
||||
TCallable *callable;
|
||||
if(GetObjectHeap(res,callable)) return true;
|
||||
if (GetObjectHeap(res, callable))
|
||||
return true;
|
||||
}
|
||||
|
||||
return this->HasVariable(key);
|
||||
}
|
||||
TObject TRootEnvironment::GetVariable(GCList& ls, std::string key)
|
||||
{
|
||||
TObject TRootEnvironment::GetVariable(GCList &ls, std::string key) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if(this->HasVariable("get" + key))
|
||||
{
|
||||
if (this->HasVariable("get" + key)) {
|
||||
auto item = this->GetVariable("get" + key);
|
||||
TCallable *callable;
|
||||
if(GetObjectHeap(item,callable))
|
||||
{
|
||||
if (GetObjectHeap(item, callable)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls, {});
|
||||
}
|
||||
@@ -66,15 +84,13 @@ namespace Tesses::CrossLang {
|
||||
|
||||
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();
|
||||
if(this->HasVariable("set" + key))
|
||||
{
|
||||
if (this->HasVariable("set" + key)) {
|
||||
auto item = this->GetVariable("set" + key);
|
||||
TCallable *callable;
|
||||
if(GetObjectHeap(item,callable))
|
||||
{
|
||||
if (GetObjectHeap(item, callable)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls, {value});
|
||||
}
|
||||
@@ -86,10 +102,13 @@ namespace Tesses::CrossLang {
|
||||
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,
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
|
||||
std::pair<std::string, TVMVersion> dep) {
|
||||
for (auto item : this->dependencies)
|
||||
if(item.first == dep.first && item.second.CompareTo(dep.second) >= 0) return;
|
||||
if (item.first == dep.first && item.second.CompareTo(dep.second) >= 0)
|
||||
return;
|
||||
std::string name = {};
|
||||
name.append(dep.first);
|
||||
name.push_back('-');
|
||||
@@ -97,24 +116,21 @@ namespace Tesses::CrossLang {
|
||||
name.append(".crvm");
|
||||
std::string filename = "/" + name;
|
||||
|
||||
if(vfs->RegularFileExists(filename))
|
||||
{
|
||||
if (vfs->RegularFileExists(filename)) {
|
||||
auto file = vfs->OpenFile(filename, "rb");
|
||||
GCList ls(gc);
|
||||
TFile *f = TFile::Create(ls);
|
||||
f->Load(gc, file);
|
||||
|
||||
LoadFileWithDependencies(gc, vfs, f);
|
||||
} else
|
||||
throw VMException("Could not open file: \"" + name + "\".");
|
||||
}
|
||||
else 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::vector<LexToken> tokens;
|
||||
int res = Lex("eval.tcross", strm, tokens);
|
||||
if(res != 0)
|
||||
{
|
||||
if (res != 0) {
|
||||
throw VMException("Lex error at line: " + std::to_string(res));
|
||||
}
|
||||
Parser parser(tokens);
|
||||
@@ -129,73 +145,64 @@ namespace Tesses::CrossLang {
|
||||
f->Load(ls.GetGC(), ms);
|
||||
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);
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(item,dict)) return dict;
|
||||
if (GetObjectHeap(item, dict))
|
||||
return dict;
|
||||
GCList ls(gc);
|
||||
dict = TDictionary::Create(ls);
|
||||
this->DeclareVariable(key, dict);
|
||||
return dict;
|
||||
}
|
||||
void TEnvironment::DeclareVariable(std::shared_ptr<GC> gc, std::vector<std::string> name, TObject o)
|
||||
{
|
||||
void TEnvironment::DeclareVariable(std::shared_ptr<GC> gc,
|
||||
std::vector<std::string> name, TObject o) {
|
||||
if (name.size() == 0)
|
||||
throw VMException("name can't be empty.");
|
||||
|
||||
else if(name.size() == 1)
|
||||
{
|
||||
else if (name.size() == 1) {
|
||||
GCList ls(gc);
|
||||
|
||||
gc->BarrierBegin();
|
||||
this->DeclareVariable(name[0], o);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
GCList ls(gc);
|
||||
|
||||
TObject v = this->GetVariable(name[0]);
|
||||
TDictionary *dict = nullptr;
|
||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
||||
{
|
||||
dict=dynamic_cast<TDictionary*>(std::get<THeapObjectHolder>(v).obj);
|
||||
if(dict == nullptr)
|
||||
{
|
||||
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||
dict =
|
||||
dynamic_cast<TDictionary *>(std::get<THeapObjectHolder>(v).obj);
|
||||
if (dict == nullptr) {
|
||||
dict = TDictionary::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
this->SetVariable(name[0], dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
dict = TDictionary::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
this->DeclareVariable(name[0], dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
for(size_t i = 1; i < name.size()-1; i++)
|
||||
{
|
||||
for (size_t i = 1; i < name.size() - 1; i++) {
|
||||
gc->BarrierBegin();
|
||||
auto v = dict->GetValue(name[i]);
|
||||
gc->BarrierEnd();
|
||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
||||
{
|
||||
auto dict2=dynamic_cast<TDictionary*>(std::get<THeapObjectHolder>(v).obj);
|
||||
if(dict2 == nullptr)
|
||||
{
|
||||
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||
auto dict2 = dynamic_cast<TDictionary *>(
|
||||
std::get<THeapObjectHolder>(v).obj);
|
||||
if (dict2 == nullptr) {
|
||||
dict2 = TDictionary::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue(name[i], dict2);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
dict = dict2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
auto dict2 = TDictionary::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue(name[i], dict2);
|
||||
@@ -209,148 +216,135 @@ namespace Tesses::CrossLang {
|
||||
}
|
||||
}
|
||||
|
||||
TObject TEnvironment::LoadFile(std::shared_ptr<GC> gc, TFile* file)
|
||||
{
|
||||
TObject TEnvironment::LoadFile(std::shared_ptr<GC> gc, TFile *file) {
|
||||
file->EnsureCanRunInCrossLang();
|
||||
for(size_t i = 0; i < file->classes.size(); i++)
|
||||
{
|
||||
this->GetRootEnvironment()->classes.push_back(std::pair<TFile*,uint32_t>(file,(uint32_t)i));
|
||||
for (size_t i = 0; i < file->classes.size(); i++) {
|
||||
this->GetRootEnvironment()->classes.push_back(
|
||||
std::pair<TFile *, uint32_t>(file, (uint32_t)i));
|
||||
std::vector<std::string> clsPart = {"New"};
|
||||
clsPart.insert(clsPart.end(),file->classes[i].name.begin(),file->classes[i].name.end());
|
||||
clsPart.insert(clsPart.end(), file->classes[i].name.begin(),
|
||||
file->classes[i].name.end());
|
||||
GCList ls(gc);
|
||||
std::vector<std::string> name = file->classes[i].name;
|
||||
auto rootEnv = this->GetRootEnvironment();
|
||||
this->DeclareVariable(gc, clsPart, TExternalMethod::Create(ls,"Create instance of the class",{"$$args"},[rootEnv,file,i](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
this->DeclareVariable(
|
||||
gc, clsPart,
|
||||
TExternalMethod::Create(
|
||||
ls, "Create instance of the class", {"$$args"},
|
||||
[rootEnv, file, i](GCList &ls,
|
||||
std::vector<TObject> args) -> TObject {
|
||||
return TClassObject::Create(ls, file, i, rootEnv, args);
|
||||
}));
|
||||
for(auto meth : file->classes[i].entry)
|
||||
{
|
||||
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;
|
||||
method.push_back(meth.name);
|
||||
auto clo = TClosure::Create(ls, this, file, meth.chunkId);
|
||||
clo->closure->name = JoinPeriod(method);
|
||||
|
||||
|
||||
clo->documentation = meth.documentation;
|
||||
this->DeclareVariable(gc, method, clo);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for(auto fn : file->functions)
|
||||
{
|
||||
for (auto fn : file->functions) {
|
||||
|
||||
|
||||
|
||||
if(fn.first.size() < 2) throw VMException("No function name.");
|
||||
if (fn.first.size() < 2)
|
||||
throw VMException("No function name.");
|
||||
|
||||
std::vector<std::string> items(fn.first.begin() + 1, fn.first.end());
|
||||
|
||||
if(fn.second >= file->chunks.size()) throw VMException("ChunkId out of bounds.");
|
||||
if (fn.second >= file->chunks.size())
|
||||
throw VMException("ChunkId out of bounds.");
|
||||
TFileChunk *chunk = file->chunks[fn.second];
|
||||
chunk->name = JoinPeriod(items);
|
||||
GCList ls(gc);
|
||||
TClosure *closure = TClosure::Create(ls, this, file, fn.second);
|
||||
closure->documentation = fn.first[0];
|
||||
this->DeclareVariable(gc, items, closure);
|
||||
|
||||
}
|
||||
if(!file->chunks.empty())
|
||||
{
|
||||
if (!file->chunks.empty()) {
|
||||
GCList ls(gc);
|
||||
TClosure *closure = TClosure::Create(ls, this, file, 0);
|
||||
return closure->Call(ls, {});
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TRootEnvironment::LoadFileWithDependencies(std::shared_ptr<GC> gc,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, TFile* file)
|
||||
{
|
||||
this->dependencies.push_back(std::pair<std::string,TVMVersion>(file->name,file->version));
|
||||
for(auto item : file->dependencies)
|
||||
{
|
||||
void TRootEnvironment::LoadFileWithDependencies(
|
||||
std::shared_ptr<GC> gc,
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, TFile *file) {
|
||||
this->dependencies.push_back(
|
||||
std::pair<std::string, TVMVersion>(file->name, file->version));
|
||||
for (auto item : file->dependencies) {
|
||||
LoadDependency(gc, vfs, item);
|
||||
}
|
||||
LoadFile(gc, file);
|
||||
|
||||
}
|
||||
void TRootEnvironment::LoadFileWithDependencies(std::shared_ptr<GC> gc,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (vfs->RegularFileExists(path)) {
|
||||
auto file = vfs->OpenFile(path, "rb");
|
||||
GCList ls(gc);
|
||||
TFile *f = TFile::Create(ls);
|
||||
f->Load(gc, file);
|
||||
|
||||
auto dir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(vfs,path.GetParent());
|
||||
auto dir =
|
||||
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
|
||||
vfs, path.GetParent());
|
||||
LoadFileWithDependencies(gc, dir, f);
|
||||
} else
|
||||
throw VMException("Could not open file: \"" + path.GetFileName() +
|
||||
"\".");
|
||||
}
|
||||
else throw VMException("Could not open file: \"" + path.GetFileName() + "\".");
|
||||
|
||||
}
|
||||
TDictionary* TRootEnvironment::GetDictionary()
|
||||
{
|
||||
return this->dict;
|
||||
}
|
||||
TObject TRootEnvironment::GetVariable(std::string key)
|
||||
{
|
||||
TDictionary *TRootEnvironment::GetDictionary() { return this->dict; }
|
||||
TObject TRootEnvironment::GetVariable(std::string key) {
|
||||
return this->dict->GetValue(key);
|
||||
}
|
||||
void TRootEnvironment::SetVariable(std::string key, TObject value)
|
||||
{
|
||||
void TRootEnvironment::SetVariable(std::string key, TObject 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);
|
||||
}
|
||||
bool TRootEnvironment::HasVariable(std::string key)
|
||||
{
|
||||
bool TRootEnvironment::HasVariable(std::string key) {
|
||||
return this->dict->HasValue(key);
|
||||
}
|
||||
bool TRootEnvironment::HasVariableRecurse(std::string key)
|
||||
{
|
||||
bool TRootEnvironment::HasVariableRecurse(std::string key) {
|
||||
return this->dict->HasValue(key);
|
||||
}
|
||||
TEnvironment* TRootEnvironment::GetParentEnvironment()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
TRootEnvironment* TRootEnvironment::GetRootEnvironment()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
TEnvironment *TRootEnvironment::GetParentEnvironment() { return this; }
|
||||
TRootEnvironment *TRootEnvironment::GetRootEnvironment() { return this; }
|
||||
|
||||
TRootEnvironment::TRootEnvironment(TDictionary* dict)
|
||||
{
|
||||
this->dict = dict;
|
||||
}
|
||||
TRootEnvironment::TRootEnvironment(TDictionary *dict) { this->dict = dict; }
|
||||
|
||||
void TRootEnvironment::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TRootEnvironment::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->dict->Mark();
|
||||
if(this->permissions.customConsole != nullptr) this->permissions.customConsole->Mark();
|
||||
for(auto defer : this->defers) defer->Mark();
|
||||
if(this->error != nullptr) this->error->Mark();
|
||||
for(auto cls : this->classes) cls.first->Mark();
|
||||
if (this->permissions.customConsole != nullptr)
|
||||
this->permissions.customConsole->Mark();
|
||||
for (auto priv : this->private_file_data)
|
||||
priv.second->Mark();
|
||||
for (auto defer : this->defers)
|
||||
defer->Mark();
|
||||
if (this->error != nullptr)
|
||||
this->error->Mark();
|
||||
for (auto cls : this->classes)
|
||||
cls.first->Mark();
|
||||
}
|
||||
TRootEnvironment* TRootEnvironment::Create(GCList* gc,TDictionary* dict)
|
||||
{
|
||||
TRootEnvironment *TRootEnvironment::Create(GCList *gc, TDictionary *dict) {
|
||||
TRootEnvironment *env = new TRootEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(env);
|
||||
_gc->Watch(env);
|
||||
return env;
|
||||
}
|
||||
TRootEnvironment* TRootEnvironment::Create(GCList& gc,TDictionary* dict)
|
||||
{
|
||||
TRootEnvironment *TRootEnvironment::Create(GCList &gc, TDictionary *dict) {
|
||||
TRootEnvironment *env = new TRootEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(env);
|
||||
@@ -358,38 +352,27 @@ namespace Tesses::CrossLang {
|
||||
return env;
|
||||
}
|
||||
|
||||
bool TRootEnvironment::HandleException(std::shared_ptr<GC> gc,TEnvironment* env, TObject err)
|
||||
{
|
||||
if(error != nullptr)
|
||||
{
|
||||
bool TRootEnvironment::HandleException(std::shared_ptr<GC> gc,
|
||||
TEnvironment *env, TObject err) {
|
||||
if (error != nullptr) {
|
||||
GCList ls(gc);
|
||||
return ToBool(error->Call(ls, {
|
||||
TDictionary::Create(ls,{
|
||||
TDItem("IsBreakpoint",false),
|
||||
return ToBool(error->Call(
|
||||
ls, {TDictionary::Create(ls, {TDItem("IsBreakpoint", false),
|
||||
TDItem("Exception", err),
|
||||
TDItem("Environment", env)
|
||||
})
|
||||
}));
|
||||
TDItem("Environment", env)})}));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TRootEnvironment::HandleBreakpoint(std::shared_ptr<GC> gc,TEnvironment* env, TObject err)
|
||||
{
|
||||
if(error != nullptr)
|
||||
{
|
||||
bool TRootEnvironment::HandleBreakpoint(std::shared_ptr<GC> gc,
|
||||
TEnvironment *env, TObject err) {
|
||||
if (error != nullptr) {
|
||||
GCList ls(gc);
|
||||
return ToBool(error->Call(ls, {
|
||||
TDictionary::Create(ls,{
|
||||
TDItem("IsBreakpoint",true),
|
||||
return ToBool(error->Call(
|
||||
ls, {TDictionary::Create(ls, {TDItem("IsBreakpoint", true),
|
||||
TDItem("Breakpoint", err),
|
||||
TDItem("Environment", env)
|
||||
})
|
||||
}));
|
||||
TDItem("Environment", env)})}));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void TRootEnvironment::RegisterOnError(TCallable* call)
|
||||
{
|
||||
this->error = call;
|
||||
}
|
||||
};
|
||||
void TRootEnvironment::RegisterOnError(TCallable *call) { this->error = call; }
|
||||
}; // namespace Tesses::CrossLang
|
||||
|
||||
@@ -1,224 +1,217 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
int64_t TObjectStream::_GetPosInternal()
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
int64_t TObjectStream::_GetPosInternal() {
|
||||
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->Add(obj);
|
||||
this->obj = obj;
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(obj,dict))
|
||||
{
|
||||
if (GetObjectHeap(obj, dict)) {
|
||||
gc->BarrierBegin();
|
||||
if(!dict->HasValue("Read"))
|
||||
{
|
||||
dict->DeclareFunction(gc,"Read","Read from stream",{"buff","off","len"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if (!dict->HasValue("Read")) {
|
||||
dict->DeclareFunction(
|
||||
gc, "Read", "Read from stream", {"buff", "off", "len"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return (int64_t)0;
|
||||
});
|
||||
}
|
||||
if(!dict->HasValue("Write"))
|
||||
{
|
||||
dict->DeclareFunction(gc,"Write","Write to stream",{"buff","off","len"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if (!dict->HasValue("Write")) {
|
||||
dict->DeclareFunction(
|
||||
gc, "Write", "Write to stream", {"buff", "off", "len"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return (int64_t)0;
|
||||
});
|
||||
}
|
||||
if(!dict->HasValue("getCanRead"))
|
||||
{
|
||||
dict->DeclareFunction(gc,"getCanRead","Can read from stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if (!dict->HasValue("getCanRead")) {
|
||||
dict->DeclareFunction(
|
||||
gc, "getCanRead", "Can read from stream", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
if(!dict->HasValue("getCanWrite"))
|
||||
{
|
||||
dict->DeclareFunction(gc,"getCanWrite","Can write to stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if (!dict->HasValue("getCanWrite")) {
|
||||
dict->DeclareFunction(
|
||||
gc, "getCanWrite", "Can write to stream", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
if(!dict->HasValue("getCanSeek"))
|
||||
{
|
||||
dict->DeclareFunction(gc,"getCanSeek","Can seek in stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if (!dict->HasValue("getCanSeek")) {
|
||||
dict->DeclareFunction(
|
||||
gc, "getCanSeek", "Can seek in stream", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
if(!dict->HasValue("getPosition"))
|
||||
{
|
||||
dict->DeclareFunction(gc,"getPosition","Can get position in stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if (!dict->HasValue("getPosition")) {
|
||||
dict->DeclareFunction(
|
||||
gc, "getPosition", "Can get position in stream", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return (int64_t)0;
|
||||
});
|
||||
}
|
||||
if(!dict->HasValue("getLength"))
|
||||
{
|
||||
dict->DeclareFunction(gc,"getPosition","Can get position in stream",{}, [this](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if (!dict->HasValue("getLength")) {
|
||||
dict->DeclareFunction(
|
||||
gc, "getPosition", "Can get position in stream", {},
|
||||
[this](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return _GetPosInternal();
|
||||
});
|
||||
}
|
||||
if(!dict->HasValue("getEndOfStream"))
|
||||
{
|
||||
dict->DeclareFunction(gc,"getEndOfStream","Is at end of stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if (!dict->HasValue("getEndOfStream")) {
|
||||
dict->DeclareFunction(
|
||||
gc, "getEndOfStream", "Is at end of stream", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
bool TObjectStream::EndOfStream()
|
||||
{
|
||||
bool TObjectStream::EndOfStream() {
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getEndOfStream", {});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
size_t TObjectStream::Read(uint8_t* buff, size_t sz)
|
||||
{
|
||||
size_t TObjectStream::Read(uint8_t *buff, size_t sz) {
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls2(this->ls->GetGC());
|
||||
|
||||
TByteArray *arr = TByteArray::Create(ls2);
|
||||
arr->data.resize(sz);
|
||||
|
||||
auto res = dict->CallMethod(ls2, "Read",{arr, (int64_t)0L, (int64_t)sz});
|
||||
auto res =
|
||||
dict->CallMethod(ls2, "Read", {arr, (int64_t)0L, (int64_t)sz});
|
||||
|
||||
memcpy(buff, arr->data.data(), std::min(sz, arr->data.size()));
|
||||
|
||||
int64_t r;
|
||||
if(GetObject(res,r)) return r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
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;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls2(this->ls->GetGC());
|
||||
|
||||
TByteArray *arr = TByteArray::Create(ls2);
|
||||
arr->data.resize(sz);
|
||||
memcpy(arr->data.data(), buff, sz);
|
||||
|
||||
auto res = dict->CallMethod(ls2, "Write",{arr, (int64_t)0L, (int64_t)sz});
|
||||
auto res =
|
||||
dict->CallMethod(ls2, "Write", {arr, (int64_t)0L, (int64_t)sz});
|
||||
int64_t r;
|
||||
if(GetObject(res,r)) return r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
bool TObjectStream::CanRead()
|
||||
{
|
||||
bool TObjectStream::CanRead() {
|
||||
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getCanRead", {});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool TObjectStream::CanWrite()
|
||||
{
|
||||
bool TObjectStream::CanWrite() {
|
||||
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getCanWrite", {});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TObjectStream::CanSeek()
|
||||
{
|
||||
bool TObjectStream::CanSeek() {
|
||||
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getCanSeek", {});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
int64_t TObjectStream::GetPosition()
|
||||
{
|
||||
int64_t TObjectStream::GetPosition() {
|
||||
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getPosition", {});
|
||||
int64_t r;
|
||||
if(GetObject(res,r)) return r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int64_t TObjectStream::GetLength()
|
||||
{
|
||||
int64_t TObjectStream::GetLength() {
|
||||
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getEndOfStream", {});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return Tesses::Framework::Streams::Stream::GetLength();
|
||||
}
|
||||
void TObjectStream::Flush()
|
||||
{
|
||||
void TObjectStream::Flush() {
|
||||
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
dict->CallMethod(*ls, "Flush", {});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void TObjectStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
|
||||
{
|
||||
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) });
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
dict->CallMethod(
|
||||
*ls, "Seek",
|
||||
{pos,
|
||||
(int64_t)(whence == Tesses::Framework::Streams::SeekOrigin::Begin
|
||||
? 0
|
||||
: whence ==
|
||||
Tesses::Framework::Streams::SeekOrigin::Current
|
||||
? 1
|
||||
: 2)});
|
||||
}
|
||||
|
||||
}
|
||||
void TObjectStream::Close()
|
||||
{
|
||||
void TObjectStream::Close() {
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
dict->CallMethod(*ls,"Close",{});
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
dict->CallMethod(*ls, "Dispose", {});
|
||||
}
|
||||
}
|
||||
TObjectStream::~TObjectStream()
|
||||
{
|
||||
TObjectStream::~TObjectStream() {
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
dict->CallMethod(*ls,"Close",{});
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
dict->CallMethod(*ls, "Dispose", {});
|
||||
}
|
||||
delete this->ls;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,183 +1,147 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
TDictionary* TSubEnvironment::GetDictionary()
|
||||
{
|
||||
return this->dict;
|
||||
}
|
||||
bool TSubEnvironment::HasVariableOrFieldRecurse(std::string key,bool setting)
|
||||
{
|
||||
TDictionary *TSubEnvironment::GetDictionary() { return this->dict; }
|
||||
bool TSubEnvironment::HasVariableOrFieldRecurse(std::string key, bool setting) {
|
||||
std::string property = (setting ? "set" : "get") + key;
|
||||
if(this->HasVariable(property))
|
||||
{
|
||||
if (this->HasVariable(property)) {
|
||||
auto res = this->GetVariable(property);
|
||||
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);
|
||||
}
|
||||
TObject TSubEnvironment::GetVariable(GCList& ls, std::string key)
|
||||
{
|
||||
TObject TSubEnvironment::GetVariable(GCList &ls, std::string key) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if(this->HasVariable("get" + key))
|
||||
{
|
||||
if (this->HasVariable("get" + key)) {
|
||||
auto item = this->GetVariable("get" + key);
|
||||
TCallable *callable;
|
||||
if(GetObjectHeap(item,callable))
|
||||
{
|
||||
if (GetObjectHeap(item, callable)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls, {});
|
||||
}
|
||||
}
|
||||
|
||||
if(this->HasVariable(key))
|
||||
{
|
||||
if (this->HasVariable(key)) {
|
||||
auto item = this->GetVariable(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return item;
|
||||
}
|
||||
if(this->env->HasVariableOrFieldRecurse(key))
|
||||
{
|
||||
if (this->env->HasVariableOrFieldRecurse(key)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->env->GetVariable(ls, key);
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
bool TSubEnvironment::HasConstForSet(std::string key)
|
||||
{
|
||||
if(this->dict->HasValue(key))
|
||||
{
|
||||
bool TSubEnvironment::HasConstForSet(std::string key) {
|
||||
if (this->dict->HasValue(key)) {
|
||||
return this->HasConstForDeclare(key);
|
||||
}
|
||||
if(this->env->HasVariableRecurse(key))
|
||||
{
|
||||
if (this->env->HasVariableRecurse(key)) {
|
||||
return this->env->HasConstForSet(key);
|
||||
}
|
||||
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();
|
||||
if(this->HasVariable("set" + key))
|
||||
{
|
||||
if (this->HasVariable("set" + key)) {
|
||||
auto item = this->GetVariable("set" + key);
|
||||
TCallable *callable;
|
||||
if(GetObjectHeap(item,callable))
|
||||
{
|
||||
if (GetObjectHeap(item, callable)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls, {value});
|
||||
}
|
||||
}
|
||||
|
||||
if(this->HasVariable(key))
|
||||
{
|
||||
if (this->HasVariable(key)) {
|
||||
this->SetVariable(key, value);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return value;
|
||||
}
|
||||
if(this->env->HasVariableOrFieldRecurse(key,true))
|
||||
{
|
||||
if (this->env->HasVariableOrFieldRecurse(key, true)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->env->SetVariable(ls, key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->env->SetVariable(key, value);
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return value;
|
||||
}
|
||||
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);
|
||||
}
|
||||
if(this->env->HasVariableRecurse(key))
|
||||
{
|
||||
if (this->env->HasVariableRecurse(key)) {
|
||||
return this->env->GetVariable(key);
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void TSubEnvironment::DeclareVariable(std::string key,TObject value)
|
||||
{
|
||||
void TSubEnvironment::DeclareVariable(std::string key, TObject value) {
|
||||
this->dict->SetValue(key, value);
|
||||
}
|
||||
void TSubEnvironment::SetVariable(std::string key, TObject value)
|
||||
{
|
||||
if(this->dict->HasValue(key))
|
||||
{
|
||||
void TSubEnvironment::SetVariable(std::string key, TObject value) {
|
||||
if (this->dict->HasValue(key)) {
|
||||
this->dict->SetValue(key, value);
|
||||
return;
|
||||
}
|
||||
if(this->env->HasVariableRecurse(key))
|
||||
{
|
||||
if (this->env->HasVariableRecurse(key)) {
|
||||
this->env->SetVariable(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->dict->SetValue(key, value);
|
||||
}
|
||||
}
|
||||
bool TSubEnvironment::HasVariable(std::string key)
|
||||
{
|
||||
bool TSubEnvironment::HasVariable(std::string key) {
|
||||
return this->dict->HasValue(key);
|
||||
}
|
||||
bool TSubEnvironment::HasVariableRecurse(std::string key)
|
||||
{
|
||||
if(this->dict->HasValue(key)) return true;
|
||||
bool TSubEnvironment::HasVariableRecurse(std::string key) {
|
||||
if (this->dict->HasValue(key))
|
||||
return true;
|
||||
return this->env->HasVariableRecurse(key);
|
||||
}
|
||||
TSubEnvironment::TSubEnvironment(TEnvironment* env,TDictionary* dict)
|
||||
{
|
||||
TSubEnvironment::TSubEnvironment(TEnvironment *env, TDictionary *dict) {
|
||||
this->env = env;
|
||||
this->dict = dict;
|
||||
}
|
||||
TSubEnvironment* TEnvironment::GetSubEnvironment(TDictionary* dict)
|
||||
{
|
||||
TSubEnvironment *TEnvironment::GetSubEnvironment(TDictionary *dict) {
|
||||
TSubEnvironment *subEnv = new TSubEnvironment(this, dict);
|
||||
return subEnv;
|
||||
}
|
||||
TObject TEnvironment::CallFunction(GCList& ls, std::string key, std::vector<TObject> args)
|
||||
{
|
||||
TObject TEnvironment::CallFunction(GCList &ls, std::string key,
|
||||
std::vector<TObject> args) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto res = this->GetVariable(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
TCallable *callable;
|
||||
|
||||
if(GetObjectHeap(res,callable))
|
||||
{
|
||||
if (GetObjectHeap(res, callable)) {
|
||||
return callable->Call(ls, args);
|
||||
}
|
||||
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();
|
||||
auto res = this->GetVariable(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
TCallable *callable;
|
||||
|
||||
if(GetObjectHeap(res,callable))
|
||||
{
|
||||
if (GetObjectHeap(res, callable)) {
|
||||
return callable->CallWithFatalError(ls, args);
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TSubEnvironment* TEnvironment::GetSubEnvironment(GCList* gc)
|
||||
{
|
||||
TSubEnvironment *TEnvironment::GetSubEnvironment(GCList *gc) {
|
||||
auto dict = TDictionary::Create(gc);
|
||||
TSubEnvironment *sEnv = this->GetSubEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
@@ -185,8 +149,7 @@ namespace Tesses::CrossLang {
|
||||
_gc->Watch(sEnv);
|
||||
return sEnv;
|
||||
}
|
||||
TSubEnvironment* TEnvironment::GetSubEnvironment(GCList& gc)
|
||||
{
|
||||
TSubEnvironment *TEnvironment::GetSubEnvironment(GCList &gc) {
|
||||
auto dict = TDictionary::Create(gc);
|
||||
TSubEnvironment *sEnv = this->GetSubEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
@@ -194,53 +157,57 @@ namespace Tesses::CrossLang {
|
||||
_gc->Watch(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);
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(senv);
|
||||
_gc->Watch(senv);
|
||||
return senv;
|
||||
}
|
||||
TSubEnvironment* TSubEnvironment::Create(GCList& gc, TEnvironment* env, TDictionary* dict)
|
||||
{
|
||||
TSubEnvironment *TSubEnvironment::Create(GCList &gc, TEnvironment *env,
|
||||
TDictionary *dict) {
|
||||
TSubEnvironment *senv = new TSubEnvironment(env, dict);
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(senv);
|
||||
_gc->Watch(senv);
|
||||
return senv;
|
||||
}
|
||||
TEnvironment* TSubEnvironment::GetParentEnvironment()
|
||||
{
|
||||
return this->env;
|
||||
}
|
||||
TRootEnvironment* TSubEnvironment::GetRootEnvironment()
|
||||
{
|
||||
TEnvironment *TSubEnvironment::GetParentEnvironment() { return this->env; }
|
||||
TRootEnvironment *TSubEnvironment::GetRootEnvironment() {
|
||||
return this->env->GetRootEnvironment();
|
||||
}
|
||||
|
||||
void TSubEnvironment::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
void TSubEnvironment::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->dict->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();
|
||||
GCList ls(gc);
|
||||
this->DeclareVariable(key, TExternalMethod::Create(ls,documentation,argNames,cb));
|
||||
this->DeclareVariable(
|
||||
key, TExternalMethod::Create(ls, documentation, argNames, cb));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
void TEnvironment::DeclareFunction(std::shared_ptr<GC> gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
|
||||
{
|
||||
void TEnvironment::DeclareFunction(
|
||||
std::shared_ptr<GC> gc, std::string key, std::string documentation,
|
||||
std::vector<std::string> argNames,
|
||||
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
|
||||
std::function<void()> destroy) {
|
||||
gc->BarrierBegin();
|
||||
GCList ls(gc);
|
||||
this->DeclareVariable(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
|
||||
this->DeclareVariable(
|
||||
key, TExternalMethod::Create(ls, documentation, argNames, cb, destroy));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
};
|
||||
}; // namespace Tesses::CrossLang
|
||||
|
||||
@@ -2,326 +2,295 @@
|
||||
|
||||
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->Add(obj);
|
||||
this->obj = obj;
|
||||
|
||||
|
||||
}
|
||||
Tesses::Framework::Filesystem::FIFOCreationResult TObjectVFS::CreateFIFO(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
Tesses::Framework::Filesystem::FIFOCreationResult
|
||||
TObjectVFS::CreateFIFO(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "CreateFIFO", {path});
|
||||
int64_t n = 0;
|
||||
if(GetObject(res, n)) return (Tesses::Framework::Filesystem::FIFOCreationResult)n;
|
||||
if (GetObject(res, n))
|
||||
return (Tesses::Framework::Filesystem::FIFOCreationResult)n;
|
||||
}
|
||||
return Tesses::Framework::Filesystem::FIFOCreationResult::UnknownError;
|
||||
}
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
|
||||
{
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream>
|
||||
TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path,
|
||||
std::string mode) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "OpenFile", {path, mode});
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if(GetObject(res,strm))
|
||||
{
|
||||
if (GetObject(res, strm)) {
|
||||
return strm;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TObjectVFS::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
void TObjectVFS::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
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))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "DeleteDirectory", {path});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Lock(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
void TObjectVFS::Lock(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Lock", {path});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Unlock(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
void TObjectVFS::Unlock(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
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,
|
||||
Tesses::Framework::Filesystem::VFSPath symlinkFile) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
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,
|
||||
Tesses::Framework::Filesystem::VFSPath newName) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "CreateHardlink", {existingFile, newName});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "DeleteFile", {path});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::DeleteDirectoryRecurse(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
void TObjectVFS::DeleteDirectoryRecurse(
|
||||
Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "DeleteDirectoryRecurse", {path});
|
||||
|
||||
}
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPathEnumerator TObjectVFS::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPathEnumerator
|
||||
TObjectVFS::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList *ls = new GCList(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(*ls, "EnumeratePaths", {path});
|
||||
auto enumerator = TEnumerator::CreateFromObject(*ls, res);
|
||||
return Tesses::Framework::Filesystem::VFSPathEnumerator([path,enumerator,ls](Tesses::Framework::Filesystem::VFSPath& path0)->bool{
|
||||
if(enumerator == nullptr) return false;
|
||||
while(enumerator->MoveNext(ls->GetGC()))
|
||||
{
|
||||
return Tesses::Framework::Filesystem::VFSPathEnumerator(
|
||||
[path, enumerator,
|
||||
ls](Tesses::Framework::Filesystem::VFSPath &path0) -> bool {
|
||||
if (enumerator == nullptr)
|
||||
return false;
|
||||
while (enumerator->MoveNext(ls->GetGC())) {
|
||||
auto res = enumerator->GetCurrent(*ls);
|
||||
std::string name;
|
||||
Tesses::Framework::Filesystem::VFSPath path1;
|
||||
if(GetObject(res,path1))
|
||||
{
|
||||
if (GetObject(res, path1)) {
|
||||
path0 = path1;
|
||||
return true;
|
||||
}
|
||||
else if(GetObject(res,name))
|
||||
{
|
||||
} else if (GetObject(res, name)) {
|
||||
path0 = path / name;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},[ls]()->void{
|
||||
delete ls;
|
||||
});
|
||||
},
|
||||
[ls]() -> void { delete ls; });
|
||||
}
|
||||
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;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "MoveFile", {src, dest});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::MoveDirectory(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
|
||||
{
|
||||
void TObjectVFS::MoveDirectory(Tesses::Framework::Filesystem::VFSPath src,
|
||||
Tesses::Framework::Filesystem::VFSPath dest) {
|
||||
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "MoveDirectory", {src, dest});
|
||||
|
||||
}
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath TObjectVFS::ReadLink(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath
|
||||
TObjectVFS::ReadLink(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "ReadLink", {path});
|
||||
Tesses::Framework::Filesystem::VFSPath myPath;
|
||||
if(GetObject(res,myPath))
|
||||
{
|
||||
if (GetObject(res, myPath)) {
|
||||
return myPath;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "VFSPathToSystem", {path});
|
||||
std::string myPath;
|
||||
if(GetObject(res,myPath))
|
||||
{
|
||||
if (GetObject(res, myPath)) {
|
||||
return myPath;
|
||||
}
|
||||
}
|
||||
return "/";
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath TObjectVFS::SystemToVFSPath(std::string path)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath
|
||||
TObjectVFS::SystemToVFSPath(std::string path) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "SystemToVFSPath", {path});
|
||||
Tesses::Framework::Filesystem::VFSPath myPath;
|
||||
if(GetObject(res,myPath))
|
||||
{
|
||||
if (GetObject(res, myPath)) {
|
||||
return myPath;
|
||||
}
|
||||
}
|
||||
return Tesses::Framework::Filesystem::VFSPath();
|
||||
}
|
||||
void TObjectVFS::SetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime lastWrite, Tesses::Framework::Date::DateTime lastAccess)
|
||||
{
|
||||
void TObjectVFS::SetDate(Tesses::Framework::Filesystem::VFSPath path,
|
||||
Tesses::Framework::Date::DateTime lastWrite,
|
||||
Tesses::Framework::Date::DateTime lastAccess) {
|
||||
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "SetDate",{path,std::make_shared<Tesses::Framework::Date::DateTime>(lastWrite),std::make_shared<Tesses::Framework::Date::DateTime>(lastAccess)});
|
||||
|
||||
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;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Chmod", {path, (int64_t)mode});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Chown(Tesses::Framework::Filesystem::VFSPath path, uint32_t uid, uint32_t gid)
|
||||
{
|
||||
void TObjectVFS::Chown(Tesses::Framework::Filesystem::VFSPath path,
|
||||
uint32_t uid, uint32_t gid) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Chown", {path, (int64_t)uid, (int64_t)gid});
|
||||
|
||||
}
|
||||
}
|
||||
bool TObjectVFS::Stat(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatData& data)
|
||||
{
|
||||
bool TObjectVFS::Stat(Tesses::Framework::Filesystem::VFSPath path,
|
||||
Tesses::Framework::Filesystem::StatData &data) {
|
||||
TDictionary *dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "Stat", {path});
|
||||
int64_t _num;
|
||||
TDictionary *_dict;
|
||||
TObject _o;
|
||||
if(GetObjectHeap(res,_dict))
|
||||
{
|
||||
if (GetObjectHeap(res, _dict)) {
|
||||
this->ls->GetGC()->BarrierBegin();
|
||||
_o = dict->GetValue("BlockSize");
|
||||
if(GetObject(_o,_num)) data.BlockSize = (uint64_t)_num;
|
||||
_o = _dict->GetValue("BlockSize");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlockSize = (uint64_t)_num;
|
||||
|
||||
_o = dict->GetValue("BlockCount");
|
||||
if(GetObject(_o,_num)) data.BlockCount = (uint64_t)_num;
|
||||
_o = _dict->GetValue("BlockCount");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlockCount = (uint64_t)_num;
|
||||
|
||||
_o = dict->GetValue("Device");
|
||||
if(GetObject(_o,_num)) data.Device = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Device");
|
||||
if (GetObject(_o, _num))
|
||||
data.Device = (uint64_t)_num;
|
||||
|
||||
_o = dict->GetValue("DeviceId");
|
||||
if(GetObject(_o,_num)) data.DeviceId = (uint64_t)_num;
|
||||
_o = _dict->GetValue("DeviceId");
|
||||
if (GetObject(_o, _num))
|
||||
data.DeviceId = (uint64_t)_num;
|
||||
|
||||
_o = dict->GetValue("GroupId");
|
||||
if(GetObject(_o,_num)) data.GroupId = (uint32_t)_num;
|
||||
_o = _dict->GetValue("GroupId");
|
||||
if (GetObject(_o, _num))
|
||||
data.GroupId = (uint32_t)_num;
|
||||
|
||||
_o = dict->GetValue("HardLinks");
|
||||
if(GetObject(_o,_num)) data.HardLinks = (uint64_t)_num;
|
||||
_o = _dict->GetValue("HardLinks");
|
||||
if (GetObject(_o, _num))
|
||||
data.HardLinks = (uint64_t)_num;
|
||||
std::shared_ptr<Tesses::Framework::Date::DateTime> dt;
|
||||
_o = dict->GetValue("LastAccess");
|
||||
if(GetObject(_o,dt)) data.LastAccess = dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
_o = _dict->GetValue("LastAccess");
|
||||
if (GetObject(_o, dt))
|
||||
data.LastAccess =
|
||||
dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
_o = _dict->GetValue("LastModified");
|
||||
if (GetObject(_o, dt))
|
||||
data.LastModified =
|
||||
dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
_o = dict->GetValue("LastModified");
|
||||
if(GetObject(_o,dt)) data.LastModified = dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
_o = _dict->GetValue("LastStatus");
|
||||
if (GetObject(_o, dt))
|
||||
data.LastStatus =
|
||||
dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
_o = _dict->GetValue("Mode");
|
||||
if (GetObject(_o, _num))
|
||||
data.Mode = (uint32_t)_num;
|
||||
|
||||
_o = _dict->GetValue("Size");
|
||||
if (GetObject(_o, _num))
|
||||
data.Size = (uint64_t)_num;
|
||||
|
||||
_o = dict->GetValue("LastStatus");
|
||||
if(GetObject(_o,dt)) data.LastStatus = dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
|
||||
|
||||
_o = dict->GetValue("Mode");
|
||||
if(GetObject(_o,_num)) data.Mode = (uint32_t)_num;
|
||||
|
||||
_o = dict->GetValue("Size");
|
||||
if(GetObject(_o,_num)) data.Size = (uint64_t)_num;
|
||||
|
||||
_o = dict->GetValue("UserId");
|
||||
if(GetObject(_o,_num)) data.UserId = (uint32_t)_num;
|
||||
|
||||
_o = _dict->GetValue("UserId");
|
||||
if (GetObject(_o, _num))
|
||||
data.UserId = (uint32_t)_num;
|
||||
|
||||
this->ls->GetGC()->BarrierEnd();
|
||||
return true;
|
||||
@@ -330,48 +299,52 @@ namespace Tesses::CrossLang {
|
||||
|
||||
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;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "StatVFS", {path});
|
||||
int64_t _num;
|
||||
TDictionary *_dict;
|
||||
TObject _o;
|
||||
if(GetObjectHeap(res,_dict))
|
||||
{
|
||||
if (GetObjectHeap(res, _dict)) {
|
||||
this->ls->GetGC()->BarrierBegin();
|
||||
_o = dict->GetValue("BlockSize");
|
||||
if(GetObject(_o,_num)) data.BlockSize = (uint64_t)_num;
|
||||
|
||||
_o = dict->GetValue("FragmentSize");
|
||||
if(GetObject(_o,_num)) data.FragmentSize = (uint64_t)_num;
|
||||
_o = dict->GetValue("Blocks");
|
||||
if(GetObject(_o,_num)) data.Blocks = (uint64_t)_num;
|
||||
_o = dict->GetValue("BlocksFree");
|
||||
if(GetObject(_o,_num)) data.BlocksFree = (uint64_t)_num;
|
||||
_o = dict->GetValue("BlocksAvailable");
|
||||
if(GetObject(_o,_num)) data.BlocksAvailable = (uint64_t)_num;
|
||||
_o = dict->GetValue("TotalInodes");
|
||||
if(GetObject(_o,_num)) data.TotalInodes = (uint64_t)_num;
|
||||
_o = dict->GetValue("FreeInodes");
|
||||
if(GetObject(_o,_num)) data.FreeInodes = (uint64_t)_num;
|
||||
_o = dict->GetValue("AvailableInodes");
|
||||
if(GetObject(_o,_num)) data.AvailableInodes = (uint64_t)_num;
|
||||
_o = dict->GetValue("Id");
|
||||
if(GetObject(_o,_num)) data.Id = (uint64_t)_num;
|
||||
_o = dict->GetValue("Flags");
|
||||
if(GetObject(_o,_num)) data.Flags = (uint64_t)_num;
|
||||
_o = dict->GetValue("MaxNameLength");
|
||||
if(GetObject(_o,_num)) data.MaxNameLength = (uint64_t)_num;
|
||||
|
||||
|
||||
|
||||
|
||||
_o = _dict->GetValue("BlockSize");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlockSize = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("FragmentSize");
|
||||
if (GetObject(_o, _num))
|
||||
data.FragmentSize = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Blocks");
|
||||
if (GetObject(_o, _num))
|
||||
data.Blocks = (uint64_t)_num;
|
||||
_o = _dict->GetValue("BlocksFree");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlocksFree = (uint64_t)_num;
|
||||
_o = _dict->GetValue("BlocksAvailable");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlocksAvailable = (uint64_t)_num;
|
||||
_o = _dict->GetValue("TotalInodes");
|
||||
if (GetObject(_o, _num))
|
||||
data.TotalInodes = (uint64_t)_num;
|
||||
_o = _dict->GetValue("FreeInodes");
|
||||
if (GetObject(_o, _num))
|
||||
data.FreeInodes = (uint64_t)_num;
|
||||
_o = _dict->GetValue("AvailableInodes");
|
||||
if (GetObject(_o, _num))
|
||||
data.AvailableInodes = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Id");
|
||||
if (GetObject(_o, _num))
|
||||
data.Id = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Flags");
|
||||
if (GetObject(_o, _num))
|
||||
data.Flags = (uint64_t)_num;
|
||||
_o = _dict->GetValue("MaxNameLength");
|
||||
if (GetObject(_o, _num))
|
||||
data.MaxNameLength = (uint64_t)_num;
|
||||
|
||||
this->ls->GetGC()->BarrierEnd();
|
||||
return true;
|
||||
@@ -380,24 +353,20 @@ namespace Tesses::CrossLang {
|
||||
|
||||
return false;
|
||||
}
|
||||
void TObjectVFS::Close()
|
||||
{
|
||||
void TObjectVFS::Close() {
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls,"Close",{});
|
||||
dict->CallMethod(ls, "Dispose", {});
|
||||
}
|
||||
}
|
||||
TObjectVFS::~TObjectVFS()
|
||||
{
|
||||
TObjectVFS::~TObjectVFS() {
|
||||
TDictionary *dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls,"Close",{});
|
||||
dict->CallMethod(ls, "Dispose", {});
|
||||
}
|
||||
delete this->ls;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -2,163 +2,164 @@
|
||||
#include "TessesFramework/Serialization/BitConverter.hpp"
|
||||
#include "TessesFramework/Streams/ByteReader.hpp"
|
||||
#include "TessesFramework/Uuid.hpp"
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <variant>
|
||||
namespace Tesses::CrossLang {
|
||||
bool InterperterThread::Add(std::shared_ptr<GC> gc)
|
||||
{
|
||||
bool InterperterThread::Add(std::shared_ptr<GC> gc) {
|
||||
std::vector<CallStackEntry *> &cse = this->call_stack_entries;
|
||||
GCList ls(gc);
|
||||
auto right = cse.back()->Pop(ls);
|
||||
auto left = cse.back()->Pop(ls);
|
||||
|
||||
if (std::holds_alternative<std::string>(left) &&
|
||||
std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(right)) {
|
||||
cse.back()->Push(
|
||||
gc, std::get<std::string>(left) +
|
||||
std::get<Tesses::Framework::Filesystem::VFSPath>(right));
|
||||
|
||||
|
||||
if(std::holds_alternative<std::string>(left) && std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(right))
|
||||
{
|
||||
cse.back()->Push(gc,std::get<std::string>(left) + std::get<Tesses::Framework::Filesystem::VFSPath>(right));
|
||||
|
||||
}
|
||||
else if(std::holds_alternative<char>(left) && std::holds_alternative<char>(right))
|
||||
{
|
||||
cse.back()->Push(gc,(char)(std::get<char>(left) + std::get<char>(right)));
|
||||
}
|
||||
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<char>(right))
|
||||
{
|
||||
cse.back()->Push(gc, (char)(std::get<int64_t>(left) + std::get<char>(right)));
|
||||
}
|
||||
else if(std::holds_alternative<char>(left) && std::holds_alternative<int64_t>(right))
|
||||
{
|
||||
cse.back()->Push(gc, (char)(std::get<char>(left) + std::get<int64_t>(right)));
|
||||
}
|
||||
else if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(left) && std::holds_alternative<std::string>(right))
|
||||
{
|
||||
cse.back()->Push(gc,std::get<Tesses::Framework::Filesystem::VFSPath>(left) + std::get<std::string>(right));
|
||||
} else if (std::holds_alternative<char>(left) &&
|
||||
std::holds_alternative<char>(right)) {
|
||||
cse.back()->Push(gc,
|
||||
(char)(std::get<char>(left) + std::get<char>(right)));
|
||||
} else if (std::holds_alternative<int64_t>(left) &&
|
||||
std::holds_alternative<char>(right)) {
|
||||
cse.back()->Push(
|
||||
gc, (char)(std::get<int64_t>(left) + std::get<char>(right)));
|
||||
} else if (std::holds_alternative<char>(left) &&
|
||||
std::holds_alternative<int64_t>(right)) {
|
||||
cse.back()->Push(
|
||||
gc, (char)(std::get<char>(left) + std::get<int64_t>(right)));
|
||||
} else if (std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(
|
||||
left) &&
|
||||
std::holds_alternative<std::string>(right)) {
|
||||
cse.back()->Push(
|
||||
gc, std::get<Tesses::Framework::Filesystem::VFSPath>(left) +
|
||||
std::get<std::string>(right));
|
||||
|
||||
}
|
||||
|
||||
else if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(left) && std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(right))
|
||||
{
|
||||
cse.back()->Push(gc,std::get<Tesses::Framework::Filesystem::VFSPath>(left) + std::get<Tesses::Framework::Filesystem::VFSPath>(right));
|
||||
else if (std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(
|
||||
left) &&
|
||||
std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(
|
||||
right)) {
|
||||
cse.back()->Push(
|
||||
gc, std::get<Tesses::Framework::Filesystem::VFSPath>(left) +
|
||||
std::get<Tesses::Framework::Filesystem::VFSPath>(right));
|
||||
|
||||
}
|
||||
|
||||
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<int64_t>(right))
|
||||
{
|
||||
cse.back()->Push(gc,std::get<int64_t>(left) + std::get<int64_t>(right));
|
||||
else if (std::holds_alternative<int64_t>(left) &&
|
||||
std::holds_alternative<int64_t>(right)) {
|
||||
cse.back()->Push(gc,
|
||||
std::get<int64_t>(left) + std::get<int64_t>(right));
|
||||
}
|
||||
|
||||
else if(std::holds_alternative<double>(left) && std::holds_alternative<double>(right))
|
||||
{
|
||||
else if (std::holds_alternative<double>(left) &&
|
||||
std::holds_alternative<double>(right)) {
|
||||
cse.back()->Push(gc, std::get<double>(left) + std::get<double>(right));
|
||||
}
|
||||
else if(std::holds_alternative<double>(left) && std::holds_alternative<int64_t>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<double>(left) &&
|
||||
std::holds_alternative<int64_t>(right)) {
|
||||
cse.back()->Push(gc, std::get<double>(left) + std::get<int64_t>(right));
|
||||
}
|
||||
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<double>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<int64_t>(left) &&
|
||||
std::holds_alternative<double>(right)) {
|
||||
cse.back()->Push(gc, std::get<int64_t>(left) + std::get<double>(right));
|
||||
}
|
||||
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
|
||||
{
|
||||
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
|
||||
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
|
||||
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::TimeSpan>((*l) + (*r)));
|
||||
}
|
||||
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
|
||||
{
|
||||
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
|
||||
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
|
||||
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
|
||||
}
|
||||
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
|
||||
{
|
||||
auto& l = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
|
||||
auto& r = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
|
||||
cse.back()->Push(gc,std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
|
||||
}
|
||||
else if(std::holds_alternative<std::string>(left) && std::holds_alternative<std::string>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) &&
|
||||
std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)) {
|
||||
auto &l =
|
||||
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
|
||||
auto &r =
|
||||
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
|
||||
cse.back()->Push(
|
||||
gc,
|
||||
std::make_shared<Tesses::Framework::Date::TimeSpan>((*l) + (*r)));
|
||||
} else if (std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) &&
|
||||
std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)) {
|
||||
auto &l =
|
||||
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left);
|
||||
auto &r =
|
||||
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right);
|
||||
cse.back()->Push(
|
||||
gc,
|
||||
std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
|
||||
} else if (std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) &&
|
||||
std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)) {
|
||||
auto &l =
|
||||
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left);
|
||||
auto &r =
|
||||
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right);
|
||||
cse.back()->Push(
|
||||
gc,
|
||||
std::make_shared<Tesses::Framework::Date::DateTime>((*l) + (*r)));
|
||||
} else if (std::holds_alternative<std::string>(left) &&
|
||||
std::holds_alternative<std::string>(right)) {
|
||||
std::string str = {};
|
||||
str.append(std::get<std::string>(left));
|
||||
str.append(std::get<std::string>(right));
|
||||
cse.back()->Push(gc, str);
|
||||
}
|
||||
else if(std::holds_alternative<char>(left) && std::holds_alternative<std::string>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<char>(left) &&
|
||||
std::holds_alternative<std::string>(right)) {
|
||||
std::string str = {};
|
||||
str.push_back(std::get<char>(left));
|
||||
str.append(std::get<std::string>(right));
|
||||
cse.back()->Push(gc, str);
|
||||
}
|
||||
else if(std::holds_alternative<std::string>(left) && std::holds_alternative<char>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<std::string>(left) &&
|
||||
std::holds_alternative<char>(right)) {
|
||||
std::string str = {};
|
||||
str.append(std::get<std::string>(left));
|
||||
str.push_back(std::get<char>(right));
|
||||
cse.back()->Push(gc, str);
|
||||
}
|
||||
else if(std::holds_alternative<THeapObjectHolder>(left))
|
||||
{
|
||||
} else if (std::holds_alternative<THeapObjectHolder>(left)) {
|
||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||
auto dict = dynamic_cast<TDictionary *>(obj);
|
||||
auto dynDict = dynamic_cast<TDynamicDictionary *>(obj);
|
||||
auto natObj = dynamic_cast<TNativeObject *>(obj);
|
||||
auto cls = dynamic_cast<TClassObject *>(obj);
|
||||
if(cls != nullptr)
|
||||
{
|
||||
if (cls != nullptr) {
|
||||
gc->BarrierBegin();
|
||||
auto obj=cls->GetValue(cse.back()->callable->className,"operator+");
|
||||
auto obj =
|
||||
cls->GetValue(cse.back()->callable->className, "operator+");
|
||||
gc->BarrierEnd();
|
||||
TClosure *clos;
|
||||
TCallable *callable;
|
||||
if(GetObjectHeap(obj,clos))
|
||||
{
|
||||
if (GetObjectHeap(obj, clos)) {
|
||||
this->AddCallStackEntry(ls, clos, {right});
|
||||
return true;
|
||||
}
|
||||
else if(GetObjectHeap(obj,callable))
|
||||
{
|
||||
} else if (GetObjectHeap(obj, callable)) {
|
||||
cse.back()->Push(gc, callable->Call(ls, {right}));
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc, Undefined());
|
||||
return false;
|
||||
|
||||
}
|
||||
else if(natObj != nullptr)
|
||||
{
|
||||
} else if (natObj != nullptr) {
|
||||
cse.back()->Push(gc, natObj->CallMethod(ls, "operator+", {right}));
|
||||
return false;
|
||||
}
|
||||
else if(dict != nullptr)
|
||||
{
|
||||
} else if (dict != nullptr) {
|
||||
gc->BarrierBegin();
|
||||
TObject fn = dict->GetValue("operator+");
|
||||
gc->BarrierEnd();
|
||||
return InvokeTwo(ls, fn, left, right);
|
||||
}
|
||||
else if(dynDict != nullptr)
|
||||
{
|
||||
} else if (dynDict != nullptr) {
|
||||
cse.back()->Push(gc, dynDict->CallMethod(ls, "operator+", {right}));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cse.back()->Push(gc, Undefined());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cse.back()->Push(gc, Undefined());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -2,95 +2,97 @@
|
||||
#include "TessesFramework/Serialization/BitConverter.hpp"
|
||||
#include "TessesFramework/Streams/ByteReader.hpp"
|
||||
#include "TessesFramework/Uuid.hpp"
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <variant>
|
||||
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
bool Equals(std::shared_ptr<GC> gc, TObject left, TObject right)
|
||||
{
|
||||
bool Equals(std::shared_ptr<GC> gc, TObject left, TObject right) {
|
||||
GCList ls(gc);
|
||||
if(std::holds_alternative<std::nullptr_t>(left) && std::holds_alternative<std::nullptr_t>(right))
|
||||
{
|
||||
if (std::holds_alternative<std::nullptr_t>(left) &&
|
||||
std::holds_alternative<std::nullptr_t>(right)) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else if(std::holds_alternative<double>(left) && std::holds_alternative<int64_t>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<double>(left) &&
|
||||
std::holds_alternative<int64_t>(right)) {
|
||||
return std::get<double>(left) == std::get<int64_t>(right);
|
||||
}
|
||||
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<double>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<int64_t>(left) &&
|
||||
std::holds_alternative<double>(right)) {
|
||||
return std::get<int64_t>(left) == std::get<double>(right);
|
||||
}
|
||||
|
||||
else if(std::holds_alternative<std::string>(left) && std::holds_alternative<std::string>(right))
|
||||
{
|
||||
else if (std::holds_alternative<std::string>(left) &&
|
||||
std::holds_alternative<std::string>(right)) {
|
||||
return std::get<std::string>(left) == std::get<std::string>(right);
|
||||
}
|
||||
|
||||
else if(std::holds_alternative<bool>(left) && std::holds_alternative<bool>(right))
|
||||
{
|
||||
else if (std::holds_alternative<bool>(left) &&
|
||||
std::holds_alternative<bool>(right)) {
|
||||
return std::get<bool>(left) == std::get<bool>(right);
|
||||
}
|
||||
|
||||
else if(std::holds_alternative<char>(left) && std::holds_alternative<char>(right))
|
||||
{
|
||||
else if (std::holds_alternative<char>(left) &&
|
||||
std::holds_alternative<char>(right)) {
|
||||
return std::get<char>(left) == std::get<char>(right);
|
||||
}
|
||||
else if(std::holds_alternative<char>(left) && std::holds_alternative<int64_t>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<char>(left) &&
|
||||
std::holds_alternative<int64_t>(right)) {
|
||||
return std::get<char>(left) == std::get<int64_t>(right);
|
||||
}
|
||||
else if(std::holds_alternative<int64_t>(left) && std::holds_alternative<char>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<int64_t>(left) &&
|
||||
std::holds_alternative<char>(right)) {
|
||||
return std::get<int64_t>(left) == std::get<char>(right);
|
||||
}
|
||||
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right))
|
||||
{
|
||||
return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(left)->ToEpoch() == std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)->ToEpoch();
|
||||
}
|
||||
else if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) && std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right))
|
||||
{
|
||||
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left)->TotalSeconds() == std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)->TotalSeconds();
|
||||
}
|
||||
else if(std::holds_alternative<TVMVersion>(left) && std::holds_alternative<TVMVersion>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::DateTime>>(left) &&
|
||||
std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::DateTime>>(right)) {
|
||||
return std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(
|
||||
left)
|
||||
->ToEpoch() ==
|
||||
std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(
|
||||
right)
|
||||
->ToEpoch();
|
||||
} else if (std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(left) &&
|
||||
std::holds_alternative<
|
||||
std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(right)) {
|
||||
return std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(
|
||||
left)
|
||||
->TotalSeconds() ==
|
||||
std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(
|
||||
right)
|
||||
->TotalSeconds();
|
||||
} else if (std::holds_alternative<TVMVersion>(left) &&
|
||||
std::holds_alternative<TVMVersion>(right)) {
|
||||
auto lver = std::get<TVMVersion>(left);
|
||||
auto rver = std::get<TVMVersion>(right);
|
||||
auto r = lver.CompareTo(rver);
|
||||
return r == 0;
|
||||
}
|
||||
else if(std::holds_alternative<Tesses::Framework::Uuid>(left) && std::holds_alternative<Tesses::Framework::Uuid>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<Tesses::Framework::Uuid>(left) &&
|
||||
std::holds_alternative<Tesses::Framework::Uuid>(right)) {
|
||||
auto l = std::get<Tesses::Framework::Uuid>(left);
|
||||
auto r = std::get<Tesses::Framework::Uuid>(right);
|
||||
|
||||
return l == r;
|
||||
}
|
||||
else if(std::holds_alternative<THeapObjectHolder>(left))
|
||||
{
|
||||
} else if (std::holds_alternative<THeapObjectHolder>(left)) {
|
||||
auto obj = std::get<THeapObjectHolder>(left).obj;
|
||||
auto dict = dynamic_cast<TDictionary *>(obj);
|
||||
|
||||
@@ -98,70 +100,49 @@ namespace Tesses::CrossLang {
|
||||
auto native = dynamic_cast<TNative *>(obj);
|
||||
auto natObj = dynamic_cast<TNativeObject *>(obj);
|
||||
auto cls = dynamic_cast<TClassObject *>(obj);
|
||||
if(cls != nullptr)
|
||||
{
|
||||
if (cls != nullptr) {
|
||||
gc->BarrierBegin();
|
||||
auto obj = cls->GetValue("", "operator==");
|
||||
gc->BarrierEnd();
|
||||
TCallable *callable;
|
||||
|
||||
if(GetObjectHeap(obj,callable))
|
||||
{
|
||||
if (GetObjectHeap(obj, callable)) {
|
||||
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;
|
||||
}
|
||||
else if(std::holds_alternative<Undefined>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<Undefined>(right)) {
|
||||
return false;
|
||||
}
|
||||
else if(std::holds_alternative<THeapObjectHolder>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<THeapObjectHolder>(right)) {
|
||||
return cls == std::get<THeapObjectHolder>(right).obj;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(natObj != nullptr)
|
||||
{
|
||||
} else if (natObj != nullptr) {
|
||||
return natObj->Equals(gc, right);
|
||||
}
|
||||
if(dict != nullptr)
|
||||
{
|
||||
if (dict != nullptr) {
|
||||
gc->BarrierBegin();
|
||||
TObject fn = dict->GetValue("operator==");
|
||||
gc->BarrierEnd();
|
||||
if(!std::holds_alternative<Undefined>(fn))
|
||||
{
|
||||
if(std::holds_alternative<THeapObjectHolder>(fn))
|
||||
{
|
||||
if (!std::holds_alternative<Undefined>(fn)) {
|
||||
if (std::holds_alternative<THeapObjectHolder>(fn)) {
|
||||
|
||||
auto obj = dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj);
|
||||
if(obj != nullptr)
|
||||
{
|
||||
auto obj = dynamic_cast<TCallable *>(
|
||||
std::get<THeapObjectHolder>(fn).obj);
|
||||
if (obj != nullptr) {
|
||||
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}));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return ToBool(obj->Call(ls, {right}));
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return ToBool(obj->Call(ls, {right}));
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
|
||||
return dict == std::get<THeapObjectHolder>(right).obj;
|
||||
}
|
||||
@@ -171,8 +152,7 @@ namespace Tesses::CrossLang {
|
||||
return dict == std::get<THeapObjectHolder>(right).obj;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
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});
|
||||
if(!std::holds_alternative<std::nullptr_t>(res) && std::holds_alternative<Undefined>(res))
|
||||
{
|
||||
if (!std::holds_alternative<std::nullptr_t>(res) &&
|
||||
std::holds_alternative<Undefined>(res)) {
|
||||
return ToBool(res);
|
||||
}
|
||||
}
|
||||
else if(native != nullptr && std::holds_alternative<std::nullptr_t>(right))
|
||||
{
|
||||
} else if (native != nullptr &&
|
||||
std::holds_alternative<std::nullptr_t>(right)) {
|
||||
return native->GetDestroyed();
|
||||
|
||||
}
|
||||
|
||||
if(std::holds_alternative<THeapObjectHolder>(right))
|
||||
{
|
||||
if (std::holds_alternative<THeapObjectHolder>(right)) {
|
||||
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;
|
||||
}
|
||||
else if(std::holds_alternative<Undefined>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<Undefined>(right)) {
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if(std::holds_alternative<std::nullptr_t>(right))
|
||||
{
|
||||
else if (std::holds_alternative<std::nullptr_t>(right)) {
|
||||
return false;
|
||||
}
|
||||
else if(std::holds_alternative<Undefined>(right))
|
||||
{
|
||||
} else if (std::holds_alternative<Undefined>(right)) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user