Compare commits
25 Commits
v0.0.1
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
| bdbdfde646 | |||
| 62e316b022 | |||
| 17e4ca9410 | |||
| dcbc58481e | |||
| abea319ea0 | |||
| d26e357448 | |||
| 2608e94192 | |||
| 0f0e47003c | |||
| 7008a6ae61 | |||
| 28eff630c6 | |||
| f23a3880d4 | |||
| 37fd44fd78 | |||
| 06f1aff2b4 | |||
| 991f2a217d | |||
| fca18e63a6 | |||
| 63b00ebbcb | |||
| 7badbeb217 | |||
| 66f5b704ee | |||
| c2d9627405 | |||
| 8e1ea768b0 | |||
| dc1e02cb9f | |||
| e9b4057e32 | |||
| fa5bc42908 | |||
| 572c0ab468 | |||
| 5be9d96b54 |
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
|
||||||
|
...
|
||||||
|
|
||||||
2
.clangd
2
.clangd
@@ -1,2 +0,0 @@
|
|||||||
CompileFlags: # Tweak the parse settings, example directory given to show format
|
|
||||||
Add: ["-Iinclude","-std=gnu++17"]
|
|
||||||
@@ -5,66 +5,79 @@ on:
|
|||||||
- 'v*'
|
- 'v*'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GITEA_AUTH: ${{ secrets.MY_GITEA_AUTH }}
|
PACKAGE_AND_BREW: ${{ secrets.PACKAGE_AND_BREW }}
|
||||||
|
VERSION: ${{ gitea.ref_name }}
|
||||||
|
RESULT_IMAGE_NAME: tesses50/crosslang
|
||||||
|
GITEA_DOMAIN: git.tesses.org
|
||||||
|
GITEA_REGISTRY_USER: tesses50
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-arch:
|
build-arch:
|
||||||
runs-on: arch-builder
|
runs-on: arch-builder
|
||||||
steps:
|
steps:
|
||||||
- run: pacman --noconfirm -Sy nodejs npm
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- run: wget -O /root/repository.key https://git.tesseslanguage.com/api/packages/tesses50/arch/repository.key
|
- run: wget -O /root/repository.key https://git.tesses.org/api/packages/tesses50/arch/repository.key
|
||||||
- run: pacman-key --add /root/repository.key
|
- run: pacman-key --add /root/repository.key
|
||||||
- run: pacman-key --config /opt/cross/ppc/pacman.conf --add /root/repository.key
|
- run: pacman-key --config /opt/cross/ppc/pacman.conf --add /root/repository.key
|
||||||
- run: printf "[tesses50.git.tesseslanguage.com]\nSigLevel = Optional TrustAll\nServer = https://git.tesseslanguage.com/api/packages/tesses50/arch/core/\$arch\n" >> /etc/pacman.conf
|
- run: printf "[tesses50.git.tesses.org]\nSigLevel = Optional TrustAll\nServer = https://git.tesses.org/api/packages/tesses50/arch/core/\$arch\n" >> /etc/pacman.conf
|
||||||
- run: printf "[tesses50.git.tesseslanguage.com]\nSigLevel = Optional TrustAll\nServer = https://git.tesseslanguage.com/api/packages/tesses50/arch/core/\$arch\n" >> /opt/cross/ppc/pacman.conf
|
- run: printf "[tesses50.git.tesses.org]\nSigLevel = Optional TrustAll\nServer = https://git.tesses.org/api/packages/tesses50/arch/core/\$arch\n" >> /opt/cross/ppc/pacman.conf
|
||||||
- run: pacman --noconfirm -Sy mbedtls curl tesses-framework
|
- run: pacman --noconfirm -Sy mbedtls tessesframework zip zig ninja
|
||||||
- run: pacman --config /opt/cross/ppc/pacman.conf --noconfirm -Sy mbedtls tesses-framework
|
- run: pacman --config /opt/cross/ppc/pacman.conf --noconfirm -Sy mbedtls tessesframework
|
||||||
- run: cp Packaging/Linux/PKGBUILD /home/build/PKGBUILD
|
- run: cp Packaging/Linux/PKGBUILD /home/build/PKGBUILD
|
||||||
- run: cp Packaging/Linux/build-arch.sh /home/build/build-arch.sh
|
- run: cp Packaging/Linux/build-arch.sh /home/build/build-arch.sh
|
||||||
- run: chmod 755 /home/build/build-arch.sh
|
- run: chmod 755 /home/build/build-arch.sh
|
||||||
- run: chown build:build /home/build/PKGBUILD
|
- run: chown build:build /home/build/PKGBUILD
|
||||||
- run: chown build:build /home/build/build-arch.sh
|
- run: chown build:build /home/build/build-arch.sh
|
||||||
- run: su build -c /home/build/build-arch.sh
|
- run: su build -c /home/build/build-arch.sh
|
||||||
build-jammy:
|
|
||||||
runs-on: deb-builder-jammy
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Build for jammy, noble
|
|
||||||
run: |
|
|
||||||
mkdir ../../artifacts
|
|
||||||
apt update -y
|
|
||||||
apt install -y pkg-config git
|
|
||||||
bash build-ubuntu-jammy.sh
|
|
||||||
bash push-ubuntu-jammy.sh
|
|
||||||
bash build-tars.sh
|
|
||||||
working-directory: ./Packaging/Linux
|
|
||||||
- uses: akkuman/gitea-release-action@v1
|
- uses: akkuman/gitea-release-action@v1
|
||||||
env:
|
env:
|
||||||
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
|
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
|
||||||
with:
|
with:
|
||||||
|
prerelease: true
|
||||||
files: |-
|
files: |-
|
||||||
artifacts/**
|
artifacts/**
|
||||||
build-plucky:
|
|
||||||
runs-on: deb-builder-plucky
|
update-tap:
|
||||||
|
runs-on: global-container-mingw
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Build for plucky, resolute
|
- run: |
|
||||||
run: |
|
mkdir -p artifacts
|
||||||
mkdir ../../artifacts
|
env -C Packaging/Windows bash build.sh
|
||||||
apt update -y
|
|
||||||
apt install -y pkg-config git gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 gcc-mingw-w64-i686 g++-mingw-w64-i686 nsis
|
|
||||||
bash build-ubuntu-plucky.sh
|
|
||||||
bash push-ubuntu-plucky.sh
|
|
||||||
working-directory: ./Packaging/Linux
|
|
||||||
|
|
||||||
- name: Build for windows
|
|
||||||
run: bash build.sh
|
|
||||||
|
|
||||||
working-directory: ./Packaging/Windows
|
|
||||||
- uses: akkuman/gitea-release-action@v1
|
- uses: akkuman/gitea-release-action@v1
|
||||||
env:
|
env:
|
||||||
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
|
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
|
||||||
with:
|
with:
|
||||||
|
prerelease: true
|
||||||
files: |-
|
files: |-
|
||||||
artifacts/**
|
artifacts/**
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
- name: Log in to registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.GITEA_DOMAIN }}
|
||||||
|
username: ${{ env.GITEA_REGISTRY_USER }}
|
||||||
|
password: ${{ secrets.PACKAGE_AND_BREW }}
|
||||||
|
- name: Build and push image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: ${{ env.GITEA_DOMAIN }}/${{ env.RESULT_IMAGE_NAME }}:latest
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: "master"
|
||||||
|
path: "tapdir"
|
||||||
|
repository: "tesses50/tesses-tap.git"
|
||||||
|
token: ${{ env.PACKAGE_AND_BREW }}
|
||||||
|
- run: |
|
||||||
|
cd tapdir
|
||||||
|
bash ../Packaging/edit-formula.sh
|
||||||
|
git config user.name "Tesses Gitea Bot"
|
||||||
|
git config user.email "noreply@tesses.net"
|
||||||
|
git add .
|
||||||
|
git commit -m "Push crosslang=${{ env.VERSION }}"
|
||||||
|
git push
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -11,3 +11,6 @@ bin
|
|||||||
*.exe
|
*.exe
|
||||||
build-x86
|
build-x86
|
||||||
build-x64
|
build-x64
|
||||||
|
build-x86-slim
|
||||||
|
build-x64-slim
|
||||||
|
crosslang-*-temp
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
version: 43
|
version: 43
|
||||||
jobs:
|
jobs:
|
||||||
- name: Build for x86_64
|
- name: Build for x86_64
|
||||||
steps:
|
steps:
|
||||||
- type: CheckoutStep
|
- type: CheckoutStep
|
||||||
name: Checkout
|
name: Checkout
|
||||||
@@ -10,30 +10,15 @@ jobs:
|
|||||||
withSubmodules: false
|
withSubmodules: false
|
||||||
condition: SUCCESSFUL
|
condition: SUCCESSFUL
|
||||||
optional: false
|
optional: false
|
||||||
- type: CommandStep
|
|
||||||
name: Execute build
|
|
||||||
runInContainer: true
|
|
||||||
image: onedev.site.tesses.net/tesses-framework/tesses-framework:latest
|
|
||||||
interpreter:
|
|
||||||
type: DefaultInterpreter
|
|
||||||
commands: |
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake -S .. -B . -DCROSSLANG_FETCHCONTENT=OFF
|
|
||||||
make -j12
|
|
||||||
make install DESTDIR=../out
|
|
||||||
useTTY: true
|
|
||||||
condition: SUCCESSFUL
|
|
||||||
optional: false
|
|
||||||
- type: BuildImageStep
|
- type: BuildImageStep
|
||||||
name: Build Docker Image
|
name: Build Docker Image
|
||||||
dockerfile: Dockerfile.run
|
dockerfile: Dockerfile
|
||||||
output:
|
output:
|
||||||
type: RegistryOutput
|
type: RegistryOutput
|
||||||
tags: onedev.site.tesses.net/crosslang/crosslang:latest onedev.site.tesses.net/crosslang/crosslang:@commit_hash@
|
tags: onedev.site.tesses.net/crosslang/crosslang:latest onedev.site.tesses.net/crosslang/crosslang:@commit_hash@
|
||||||
registryLogins:
|
registryLogins:
|
||||||
- registryUrl: '@server_url@'
|
- registryUrl: "@server_url@"
|
||||||
userName: '@job_token@'
|
userName: "@job_token@"
|
||||||
passwordSecret: dockersecret
|
passwordSecret: dockersecret
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
condition: SUCCESSFUL
|
condition: SUCCESSFUL
|
||||||
@@ -50,7 +35,7 @@ jobs:
|
|||||||
buildProvider:
|
buildProvider:
|
||||||
type: LastFinishedBuild
|
type: LastFinishedBuild
|
||||||
jobName: Build for x86_64
|
jobName: Build for x86_64
|
||||||
artifacts: '*'
|
artifacts: "*"
|
||||||
retryCondition: never
|
retryCondition: never
|
||||||
maxRetries: 3
|
maxRetries: 3
|
||||||
retryDelay: 30
|
retryDelay: 30
|
||||||
|
|||||||
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
@@ -8,10 +8,10 @@
|
|||||||
"name": "(gdb) Launch",
|
"name": "(gdb) Launch",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/builds/linux/crosslang",
|
"program": "${workspaceFolder}/builds/l/crossint",
|
||||||
"args": ["token"],
|
"args": ["queryable.tcross"],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}/builds/l",
|
||||||
"environment": [],
|
"environment": [],
|
||||||
"externalConsole": false,
|
"externalConsole": false,
|
||||||
"MIMode": "gdb",
|
"MIMode": "gdb",
|
||||||
|
|||||||
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@@ -84,7 +84,12 @@
|
|||||||
"stack": "cpp",
|
"stack": "cpp",
|
||||||
"stdfloat": "cpp"
|
"stdfloat": "cpp"
|
||||||
},
|
},
|
||||||
|
|
||||||
"clangd.fallbackFlags": [
|
"clangd.fallbackFlags": [
|
||||||
"-Iinclude"
|
"-I${workspaceFolder}/include",
|
||||||
]
|
"-I/home/mike/tmp-crosslang/usr/local/include/"
|
||||||
|
],
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
463
CMakeLists.txt
463
CMakeLists.txt
@@ -1,468 +1,35 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
set(CROSSLANG_MAJOR_VERSION 0)
|
include(cmake/version.cmake)
|
||||||
set(CROSSLANG_MINOR_VERSION 0)
|
|
||||||
set(CROSSLANG_PATCH_VERSION 1)
|
|
||||||
|
|
||||||
project(TessesCrossLang VERSION ${CROSSLANG_MAJOR_VERSION}.${CROSSLANG_MINOR_VERSION}.${CROSSLANG_PATCH_VERSION})
|
project(TessesCrossLang VERSION ${CROSSLANG_MAJOR_VERSION}.${CROSSLANG_MINOR_VERSION}.${CROSSLANG_PATCH_VERSION})
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
include(GNUInstallDirs)
|
||||||
|
include(CheckLibraryExists)
|
||||||
#option(CROSSLANG_ENABLE_DOXYGEN "Enable doxygen" ON)
|
|
||||||
|
|
||||||
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_CUSTOM_CONSOLE "Enable custom Console" OFF)
|
|
||||||
|
|
||||||
#if(CROSSLANG_ENABLE_DOXYGEN)
|
|
||||||
#find_package(Doxygen REQUIRED)
|
|
||||||
#doxygen_add_docs(doxygen-crosslang "${CMAKE_CURRENT_SOURCE_DIR}/include/CrossLang.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/docs" "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
|
||||||
#add_custom_target(crosslang_doxygen ALL
|
|
||||||
# COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.doxygen-crosslang
|
|
||||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
#)
|
|
||||||
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
if(CROSSLANG_CUSTOM_CONSOLE)
|
|
||||||
set(CROSSLANG_ENABLE_BINARIES OFF)
|
|
||||||
set(CROSSLANG_ENABLE_SHARED OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CROSSLANG_OFFLINE_SHELL_PACKAGE "" CACHE FILEPATH "Path to the shell package generated from https://onedev.site.tesses.net/CrossLang/CrossLangExtras")
|
|
||||||
|
|
||||||
if(CROSSLANG_FETCHCONTENT)
|
|
||||||
|
|
||||||
set(TESSESFRAMEWORK_ENABLE_EXAMPLES OFF)
|
|
||||||
set(TESSESFRAMEWORK_ENABLE_APPS OFF)
|
|
||||||
|
|
||||||
if(NOT TESSESFRAMEWORK_ENABLE_SHARED)
|
|
||||||
set(CROSSLANG_ENABLE_SHARED OFF)
|
|
||||||
endif()
|
|
||||||
if(NOT TESSESFRAMEWORK_ENABLE_STATIC)
|
|
||||||
set(CROSSLANG_ENABLE_STATIC OFF)
|
|
||||||
endif()
|
|
||||||
if(NOT TESSESFRAMEWORK_ENABLE_RPATH)
|
|
||||||
set(CROSSLANG_ENABLE_RPATH OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#set(CROSSLANG_ENABLE_SHARED OFF)
|
|
||||||
#set(TESSESFRAMEWORK_ENABLE_SHARED OFF)
|
|
||||||
#set(CROSSLANG_SHARED_EXECUTABLES OFF)
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
FetchContent_Declare(
|
include(cmake/sources.cmake)
|
||||||
TessesFramework
|
include(cmake/options.cmake)
|
||||||
GIT_REPOSITORY https://onedev.site.tesses.net/tesses-framework.git
|
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||||
)
|
|
||||||
FetchContent_MakeAvailable(TessesFramework)
|
|
||||||
list(APPEND TessesCrossLangLibs ${TessesFrameworkTargets})
|
|
||||||
else()
|
|
||||||
find_package(TessesFramework REQUIRED)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CROSSLANG_ENABLE_FFI)
|
if(CROSSLANG_ENABLE_FFI)
|
||||||
find_package(PkgConfig)
|
find_package(PkgConfig)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CROSSLANG_ENABLE_FFI AND CROSSLANG_ENABLE_SHARED)
|
|
||||||
pkg_check_modules(LIBFFI REQUIRED IMPORTED_TARGET libffi)
|
|
||||||
endif()
|
|
||||||
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_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()
|
|
||||||
|
|
||||||
list(APPEND CROSSLANG_SOURCE
|
|
||||||
src/assembler/asm.cpp
|
|
||||||
src/assembler/disasm.cpp
|
|
||||||
src/assembler/merge.cpp
|
|
||||||
src/compiler/codegen.cpp
|
|
||||||
src/compiler/lexer.cpp
|
|
||||||
src/compiler/parser.cpp
|
|
||||||
src/compiler/ast.cpp
|
|
||||||
src/runtime_methods/class.cpp
|
|
||||||
src/runtime_methods/console.cpp
|
|
||||||
src/runtime_methods/io.cpp
|
|
||||||
src/runtime_methods/std.cpp
|
|
||||||
src/runtime_methods/net.cpp
|
|
||||||
src/runtime_methods/vm.cpp
|
|
||||||
src/runtime_methods/json.cpp
|
|
||||||
src/runtime_methods/sqlite.cpp
|
|
||||||
src/runtime_methods/dictionary.cpp
|
|
||||||
src/runtime_methods/crypto.cpp
|
|
||||||
src/runtime_methods/ogc.cpp
|
|
||||||
src/runtime_methods/path.cpp
|
|
||||||
src/runtime_methods/env.cpp
|
|
||||||
src/runtime_methods/process.cpp
|
|
||||||
src/runtime_methods/helpers.cpp
|
|
||||||
src/types/embed.cpp
|
|
||||||
src/types/async.cpp
|
|
||||||
src/types/associativearray.cpp
|
|
||||||
src/types/any.cpp
|
|
||||||
src/types/ittr.cpp
|
|
||||||
src/types/closure.cpp
|
|
||||||
src/types/dictionary.cpp
|
|
||||||
src/types/externalmethod.cpp
|
|
||||||
src/types/list.cpp
|
|
||||||
src/types/native.cpp
|
|
||||||
src/types/rootenvironment.cpp
|
|
||||||
src/types/subenvironment.cpp
|
|
||||||
src/types/vfsheapobject.cpp
|
|
||||||
src/types/streamheapobject.cpp
|
|
||||||
src/types/class.cpp
|
|
||||||
src/types/classenvironment.cpp
|
|
||||||
src/types/random.cpp
|
|
||||||
src/vm/filereader.cpp
|
|
||||||
src/vm/gc.cpp
|
|
||||||
src/vm/gclist.cpp
|
|
||||||
src/vm/vm.cpp
|
|
||||||
src/vm/exception.cpp
|
|
||||||
src/archive.cpp
|
|
||||||
src/markedtobject.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
if(CROSSLANG_OFFLINE_SHELL_PACKAGE STREQUAL "")
|
|
||||||
|
|
||||||
|
include(cmake/findtf.cmake)
|
||||||
|
include(cmake/sources.cmake)
|
||||||
|
include(cmake/cpack.cmake)
|
||||||
|
if(CROSSLANG_STATIC)
|
||||||
|
include(cmake/staticlib.cmake)
|
||||||
else()
|
else()
|
||||||
install(FILES ${CROSSLANG_OFFLINE_SHELL_PACKAGE} DESTINATION share/Tesses/CrossLang)
|
include(cmake/sharedlib.cmake)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MINGW)
|
include(cmake/install-dev.cmake)
|
||||||
list(APPEND CROSSLANG_WIN32_EXE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/winicon.rc")
|
|
||||||
if(MINGW)
|
|
||||||
ENABLE_LANGUAGE(RC)
|
|
||||||
endif(MINGW)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
include(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()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
include(cmake/app.cmake)
|
||||||
|
|
||||||
if(CROSSLANG_INSTALL_DEVELOPMENT)
|
if(CROSSLANG_INSTALL_DEVELOPMENT)
|
||||||
install(TARGETS ${TessesCrossLangLibs}
|
|
||||||
EXPORT TessesCrossLangTargets
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
||||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
install(FILES include/CrossLang.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
||||||
install(EXPORT TessesCrossLangTargets
|
|
||||||
FILE TessesCrossLangTargets.cmake
|
|
||||||
NAMESPACE TessesCrossLang::
|
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake"
|
|
||||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang)
|
|
||||||
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)
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(CROSSLANG_ENABLE_BINARIES)
|
|
||||||
if(CROSSLANG_ENABLE_SHARED AND CROSSLANG_SHARED_EXECUTABLES)
|
|
||||||
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/crosslangcompiler.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossvm src/crosslangvm.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossint src/crosslanginterperter.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossdump src/crosslangdump.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crosslang src/crosslang.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossarchiveextract src/crossarchiveextract.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossarchivecreate src/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()
|
|
||||||
elseif(CROSSLANG_ENABLE_STATIC)
|
|
||||||
|
|
||||||
add_executable(crossc src/crosslangcompiler.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossvm src/crosslangvm.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossint src/crosslanginterperter.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossdump src/crosslangdump.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crosslang src/crosslang.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossarchiveextract src/crossarchiveextract.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossarchivecreate src/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()
|
|
||||||
else()
|
|
||||||
add_executable(crossc src/crosslangcompiler.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossvm src/crosslangvm.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossint src/crosslanginterperter.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossdump src/crosslangdump.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crosslang src/crosslang.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossarchiveextract src/crossarchiveextract.cpp ${CROSSLANG_SOURCE} ${CROSSLANG_WIN32_EXE_SRC})
|
|
||||||
add_executable(crossarchivecreate src/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()
|
|
||||||
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()
|
|
||||||
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)
|
|
||||||
|
|
||||||
add_subdirectory(pkgconfig)
|
add_subdirectory(pkgconfig)
|
||||||
|
endif()
|
||||||
25
Dockerfile
25
Dockerfile
@@ -1,8 +1,17 @@
|
|||||||
FROM onedev.site.tesses.net/tesses-framework/tesses-framework:latest
|
FROM alpine:latest AS build
|
||||||
RUN apt update -y && \
|
|
||||||
apt install -y --no-install-recommends \
|
RUN apk update
|
||||||
libjansson-dev wget && \
|
RUN apk add --no-cache cmake g++ make git
|
||||||
apt clean -y && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
COPY ./ /src
|
||||||
RUN mkdir /src && cd /src && git clone https://onedev.site.tesses.net/crosslang . && cd /src && mkdir build && cd build && cmake -S .. -B . && make -j4 && make install && cd / && rm -r /src
|
|
||||||
WORKDIR /
|
|
||||||
|
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
|
||||||
|
RUN apk add --no-cache libstdc++
|
||||||
|
COPY --from=build /out/usr /usr
|
||||||
|
|
||||||
|
ENV CROSSLANG_CONTAINER=1
|
||||||
|
ENTRYPOINT ["/usr/local/bin/crosslang","int"]
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
FROM onedev.site.tesses.net/tesses-framework/tesses-framework:latest
|
|
||||||
COPY out /
|
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
# Maintainer: Mike Nolan <tesses@tesses.net>
|
# Maintainer: Mike Nolan <tesses@tesses.net>
|
||||||
pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn'
|
pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn'
|
||||||
pkgver=0.0.1
|
pkgver=0.0.7
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc=""
|
pkgdesc=""
|
||||||
arch=('x86_64' 'powerpc')
|
arch=('x86_64' 'powerpc')
|
||||||
url="https://onedev.site.tesses.net/crosslang"
|
url="https://git.tesses.org/tesses50/crosslang"
|
||||||
license=('GPLv3')
|
license=('GPLv3')
|
||||||
groups=()
|
groups=()
|
||||||
depends=('mbedtls' 'tesses-framework')
|
depends=('mbedtls' 'tessesframework=0.0.5')
|
||||||
makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
|
makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
|
||||||
install=
|
install=
|
||||||
source=('crosslang::git+https://onedev.site.tesses.net/crosslang')
|
source=('crosslang::git+https://git.tesses.org/tesses50/crosslang#tag=v0.0.7')
|
||||||
noextract=()
|
noextract=()
|
||||||
sha256sums=('SKIP')
|
sha256sums=('SKIP')
|
||||||
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
|
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
|
||||||
@@ -30,14 +30,14 @@ prepare() {
|
|||||||
build() {
|
build() {
|
||||||
cd "$srcdir/${pkgname}"
|
cd "$srcdir/${pkgname}"
|
||||||
mkdir build
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
|
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
|
||||||
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
cmake -S .. -B . -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release
|
||||||
else
|
else
|
||||||
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN"
|
cmake -S .. -B . -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd build
|
|
||||||
make -j`nproc`
|
make -j`nproc`
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -49,4 +49,3 @@ package() {
|
|||||||
cd "$srcdir/${pkgname}/build"
|
cd "$srcdir/${pkgname}/build"
|
||||||
make install DESTDIR="$pkgdir/"
|
make install DESTDIR="$pkgdir/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ mkdir x86_64
|
|||||||
cd x86_64
|
cd x86_64
|
||||||
cp ../PKGBUILD .
|
cp ../PKGBUILD .
|
||||||
makepkg
|
makepkg
|
||||||
curl --user tesses50:$GITEA_AUTH \
|
curl --user tesses50:$PACKAGE_AND_BREW \
|
||||||
--upload-file *.pkg.tar.zst \
|
--upload-file *.pkg.tar.zst \
|
||||||
https://git.tesseslanguage.com/api/packages/tesses50/arch/core
|
https://git.tesses.org/api/packages/tesses50/arch/core
|
||||||
cd ..
|
cd ..
|
||||||
mkdir powerpc
|
mkdir powerpc
|
||||||
cd powerpc
|
cd powerpc
|
||||||
cp ../PKGBUILD .
|
cp ../PKGBUILD .
|
||||||
CARCH=powerpc CMAKE_TOOLCHAIN=/opt/cross/ppc/toolchain.cmake makepkg
|
CARCH=powerpc CMAKE_TOOLCHAIN=/opt/cross/ppc/toolchain.cmake makepkg
|
||||||
curl --user tesses50:$GITEA_AUTH \
|
curl --user tesses50:$PACKAGE_AND_BREW \
|
||||||
--upload-file *.pkg.tar.zst \
|
--upload-file *.pkg.tar.zst \
|
||||||
https://git.tesseslanguage.com/api/packages/tesses50/arch/core
|
https://git.tesses.org/api/packages/tesses50/arch/core
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
mkdir build-x86_64-tar
|
|
||||||
cd build-x86_64-tar
|
|
||||||
cmake -S ../../.. -B . -DTESSESFRAMEWORK_ENABLE_SHARED=ON -DTESSESFRAMEWORK_ENABLE_STATIC=OFF -DTESSESFRAMEWORK_FETCHCONTENT=ON
|
|
||||||
make -j`nproc`
|
|
||||||
make install DESTDIR=./crosslang-x86_64
|
|
||||||
mkdir -p crosslang-x86_64/share/Tesses/CrossLang
|
|
||||||
cp ../build/jammy/Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm crosslang-x86_64/share/Tesses/CrossLang/Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm
|
|
||||||
tar cvzf ../../../artifacts/crosslang-linux-x86_64.tar.gz crosslang-x86_64
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
foreign() {
|
|
||||||
mkdir build-$1\-tar
|
|
||||||
cd build-$1\-tar
|
|
||||||
cmake -S ../../.. -B . -DTESSESFRAMEWORK_ENABLE_SHARED=ON -DTESSESFRAMEWORK_ENABLE_STATIC=OFF -DTESSESFRAMEWORK_FETCHCONTENT=ON -DCMAKE_TOOLCHAIN_FILE=/opt/toolchains/$1\.cmake
|
|
||||||
make -j`nproc`
|
|
||||||
make install DESTDIR=./crosslang-$1
|
|
||||||
mkdir -p crosslang-$1\/share/Tesses/CrossLang
|
|
||||||
cp ../build/jammy/Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm crosslang-$1\/share/Tesses/CrossLang/Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm
|
|
||||||
tar cvzf ../../../artifacts/crosslang-linux-$1\.tar.gz crosslang-$1
|
|
||||||
cd ..
|
|
||||||
}
|
|
||||||
foreign arm64
|
|
||||||
foreign riscv64
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
source ./version.sh
|
|
||||||
mkdir -p build/jammy
|
|
||||||
cd build/jammy
|
|
||||||
wget -O Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm https://downloads.tesses.net/ShellPackage.crvm
|
|
||||||
mkdir build-amd64
|
|
||||||
apt install -y tessesframework
|
|
||||||
cmake -S ../../../../ -B build-amd64 -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF
|
|
||||||
cd build-amd64
|
|
||||||
make -j`nproc`
|
|
||||||
make install DESTDIR=../crosslang_$DEB_VERSION\_amd64
|
|
||||||
apt remove -y tessesframework
|
|
||||||
mkdir -p ../crosslang_$DEB_VERSION\_amd64/DEBIAN
|
|
||||||
bash ../../../make-control.sh ../crosslang_$DEB_VERSION\_amd64/DEBIAN/control amd64
|
|
||||||
cd ../
|
|
||||||
mkdir -p crosslang_$DEB_VERSION\_amd64/usr/share/Tesses/CrossLang
|
|
||||||
cp Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm crosslang_$DEB_VERSION\_amd64/usr/share/Tesses/CrossLang/Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm
|
|
||||||
dpkg-deb --build crosslang_$DEB_VERSION\_amd64
|
|
||||||
|
|
||||||
foreign() {
|
|
||||||
apt install -y tessesframework:$1
|
|
||||||
mkdir build-$1
|
|
||||||
cmake -S ../../../../ -B build-$1 -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_TOOLCHAIN_FILE=/opt/toolchains/$1\.cmake
|
|
||||||
cd build-$1
|
|
||||||
make -j`nproc`
|
|
||||||
make install DESTDIR=../crosslang_$DEB_VERSION\_$1
|
|
||||||
mkdir -p ../crosslang_$DEB_VERSION\_$1/DEBIAN
|
|
||||||
bash ../../../make-control.sh ../crosslang_$DEB_VERSION\_$1\/DEBIAN/control $1
|
|
||||||
cd ../
|
|
||||||
mkdir -p crosslang_$DEB_VERSION\_$1\/usr/share/Tesses/CrossLang
|
|
||||||
cp Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm crosslang_$DEB_VERSION\_$1\/usr/share/Tesses/CrossLang/Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm
|
|
||||||
dpkg-deb --build crosslang_$DEB_VERSION\_$1
|
|
||||||
apt remove -y tessesframework:$1
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign arm64
|
|
||||||
foreign riscv64
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
source ./version.sh
|
|
||||||
mkdir -p build/plucky
|
|
||||||
cd build/plucky
|
|
||||||
wget -O Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm https://downloads.tesses.net/ShellPackage.crvm
|
|
||||||
mkdir build-amd64
|
|
||||||
apt install -y tessesframework
|
|
||||||
cmake -S ../../../../ -B build-amd64 -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF
|
|
||||||
cd build-amd64
|
|
||||||
make -j`nproc`
|
|
||||||
make install DESTDIR=../crosslang_$DEB_VERSION\_amd64
|
|
||||||
apt remove -y tessesframework
|
|
||||||
mkdir -p ../crosslang_$DEB_VERSION\_amd64/DEBIAN
|
|
||||||
bash ../../../make-control.sh ../crosslang_$DEB_VERSION\_amd64/DEBIAN/control amd64
|
|
||||||
cd ../
|
|
||||||
mkdir -p crosslang_$DEB_VERSION\_amd64/usr/share/Tesses/CrossLang
|
|
||||||
cp Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm crosslang_$DEB_VERSION\_amd64/usr/share/Tesses/CrossLang/Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm
|
|
||||||
dpkg-deb --build crosslang_$DEB_VERSION\_amd64
|
|
||||||
|
|
||||||
foreign() {
|
|
||||||
apt install -y tessesframework:$1
|
|
||||||
mkdir build-$1
|
|
||||||
cmake -S ../../../../ -B build-$1 -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_TOOLCHAIN_FILE=/opt/toolchains/$1\.cmake
|
|
||||||
cd build-$1
|
|
||||||
make -j`nproc`
|
|
||||||
make install DESTDIR=../crosslang_$DEB_VERSION\_$1
|
|
||||||
mkdir -p ../crosslang_$DEB_VERSION\_$1/DEBIAN
|
|
||||||
bash ../../../make-control.sh ../crosslang_$DEB_VERSION\_$1\/DEBIAN/control $1
|
|
||||||
cd ../
|
|
||||||
mkdir -p crosslang_$DEB_VERSION\_$1\/usr/share/Tesses/CrossLang
|
|
||||||
cp Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm crosslang_$DEB_VERSION\_$1\/usr/share/Tesses/CrossLang/Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm
|
|
||||||
dpkg-deb --build crosslang_$DEB_VERSION\_$1
|
|
||||||
apt remove -y tessesframework:$1
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign arm64
|
|
||||||
foreign riscv64
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
echo "Package: crosslang" > "$1"
|
|
||||||
echo "Version: $DEB_VERSION" >> "$1"
|
|
||||||
echo "Architecture: $2" >> "$1"
|
|
||||||
echo "Essential: no" >> "$1"
|
|
||||||
echo "Priority: optional" >> "$1"
|
|
||||||
echo "Depends: tessesframework, libffi-dev" >> "$1"
|
|
||||||
echo "Maintainer: Mike Nolan" >> "$1"
|
|
||||||
echo "Description: A programming language" >> "$1"
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
source ./version.sh
|
|
||||||
upload() {
|
|
||||||
curl --user tesses50:$GITEA_AUTH -X DELETE \
|
|
||||||
https://git.tesseslanguage.com/api/packages/tesses50/debian/pool/jammy/main/crosslang/$DEB_VERSION/$1
|
|
||||||
curl --user tesses50:$GITEA_AUTH \
|
|
||||||
--upload-file build/jammy/crosslang_$DEB_VERSION\_$1\.deb \
|
|
||||||
https://git.tesseslanguage.com/api/packages/tesses50/debian/pool/jammy/main/upload
|
|
||||||
}
|
|
||||||
upload amd64
|
|
||||||
upload arm64
|
|
||||||
upload riscv64
|
|
||||||
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
source ./version.sh
|
|
||||||
upload() {
|
|
||||||
curl --user tesses50:$GITEA_AUTH -X DELETE \
|
|
||||||
https://git.tesseslanguage.com/api/packages/tesses50/debian/pool/plucky/main/crosslang/$DEB_VERSION/$1
|
|
||||||
curl --user tesses50:$GITEA_AUTH \
|
|
||||||
--upload-file build/plucky/crosslang_$DEB_VERSION\_$1\.deb \
|
|
||||||
https://git.tesseslanguage.com/api/packages/tesses50/debian/pool/plucky/main/upload
|
|
||||||
}
|
|
||||||
upload amd64
|
|
||||||
upload arm64
|
|
||||||
upload riscv64
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
|
|
||||||
export DEB_VERSION=0.0.1
|
|
||||||
34
Packaging/Slim/build.sh
Normal file
34
Packaging/Slim/build.sh
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
mkdir -p ../../artifacts
|
||||||
|
mkdir -p builds
|
||||||
|
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 -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
|
||||||
|
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 -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
|
||||||
|
|
||||||
|
mv $BUILDDIR/out/bin/crosslang.exe ../../artifacts/crosslang-slim-$tripple\.exe
|
||||||
|
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 -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
|
||||||
|
|
||||||
|
mv $BUILDDIR/out/bin/crosslang ../../artifacts/crosslang-slim-$tripple
|
||||||
|
done
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cmake -S ../.. -B build-x86 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x86.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DCMAKE_INSTALL_PREFIX=tmp-x86
|
mkdir -p ../../artifacts
|
||||||
|
cmake -S ../.. -B build-x86 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x86.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_INSTALL_PREFIX=tmp-x86 -DCMAKE_BUILD_TYPE=Release
|
||||||
cd build-x86
|
cd build-x86
|
||||||
make -j`nproc`
|
make -j`nproc`
|
||||||
cpack -G NSIS
|
cpack -G NSIS
|
||||||
cpack -G ZIP
|
mv TessesCrossLang-*-win32.exe ../../../artifacts/crosslang-win32-setup.exe
|
||||||
mv TessesCrossLang-*-win32.exe ../../../artifacts/crosslang-win32.exe
|
mv crosslang.exe ../../../artifacts/crosslang-win32-portable.exe
|
||||||
mv TessesCrossLang-*-win32.zip ../../../artifacts/crosslang-win32.zip
|
|
||||||
cd ..
|
cd ..
|
||||||
cmake -S ../.. -B build-x64 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x64.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DCMAKE_INSTALL_PREFIX=tmp-x64
|
cmake -S ../.. -B build-x64 -DCMAKE_TOOLCHAIN_FILE=`pwd`/WindowsToolchains/x64.cmake -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_APPS=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_STATIC=ON -DCMAKE_INSTALL_PREFIX=tmp-x64 -DCMAKE_BUILD_TYPE=Release
|
||||||
cd build-x64
|
cd build-x64
|
||||||
make -j`nproc`
|
make -j`nproc`
|
||||||
cpack -G NSIS
|
cpack -G NSIS
|
||||||
cpack -G ZIP
|
mv TessesCrossLang-*-win64.exe ../../../artifacts/crosslang-win64-setup.exe
|
||||||
mv TessesCrossLang-*-win64.exe ../../../artifacts/crosslang-win64.exe
|
mv crosslang.exe ../../../artifacts/crosslang-win64-portable.exe
|
||||||
mv TessesCrossLang-*-win64.zip ../../../artifacts/crosslang-win64.zip
|
|
||||||
|
|||||||
19
Packaging/edit-formula.sh
Normal file
19
Packaging/edit-formula.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export HASH=`curl https://git.tesses.org/tesses50/crosslang/archive/$VERSION.tar.gz 2> /dev/null | shasum -a 256 | awk '{print $1}'`
|
||||||
|
|
||||||
|
echo "class Crosslang < Formula" > "Formula/crosslang.rb"
|
||||||
|
echo " desc \"\"" >> "Formula/crosslang.rb"
|
||||||
|
echo " homepage \"\"" >> "Formula/crosslang.rb"
|
||||||
|
echo " url \"https://git.tesses.org/tesses50/crosslang/archive/$VERSION.tar.gz\"" >> "Formula/crosslang.rb"
|
||||||
|
echo " sha256 \"$HASH\"" >> "Formula/crosslang.rb"
|
||||||
|
echo " license \"GPLv3\"" >> "Formula/crosslang.rb"
|
||||||
|
echo " depends_on \"cmake\" => :build" >> "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"
|
||||||
|
echo " system \"cmake\", \"--install\", \"build\"" >> "Formula/crosslang.rb"
|
||||||
|
echo " end" >> "Formula/crosslang.rb"
|
||||||
|
echo " test do" >> "Formula/crosslang.rb"
|
||||||
|
echo " system \"true\"" >> "Formula/crosslang.rb"
|
||||||
|
echo " end" >> "Formula/crosslang.rb"
|
||||||
|
echo "end" >> "Formula/crosslang.rb"
|
||||||
40
README.md
40
README.md
@@ -6,38 +6,38 @@ Tesses Cross Language
|
|||||||
[WebSite](https://crosslang.tesseslanguage.com/)
|
[WebSite](https://crosslang.tesseslanguage.com/)
|
||||||
|
|
||||||
## What is required to build this project
|
## What is required to build this project
|
||||||
- [TessesFramework](https://onedev.site.tesses.net/tesses-framework) (if you turn CROSSLANG_FETCHCONTENT off otherwise it will be grabbed automaticly)
|
- [TessesFramework](https://git.tesses.org/tesses50/tessesframework) (if you turn CROSSLANG_FETCHCONTENT off otherwise it will be grabbed automaticly)
|
||||||
- CMake
|
- CMake
|
||||||
|
|
||||||
|
|
||||||
## Use in docker (use my container)
|
## Use in docker (use my container)
|
||||||
```bash
|
```bash
|
||||||
sudo docker pull -t onedev.site.tesses.net/crosslang/crosslang:latest
|
sudo docker pull -t git.tesses.org/tesses50/crosslang:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## Use in docker (build the container yourself)
|
## Use in docker (build the container yourself)
|
||||||
```bash
|
```bash
|
||||||
git clone https://onedev.site.tesses.net/crosslang
|
git clone https://git.tesses.org/tesses50/crosslang
|
||||||
cd crosslang
|
cd crosslang
|
||||||
sudo docker build -t crosslang:latest .
|
sudo docker build -t crosslang:latest .
|
||||||
```
|
```
|
||||||
|
|
||||||
## To Install
|
## To Install
|
||||||
- Install [mbedtls](https://github.com/Mbed-TLS/mbedtls) (use sudo apt install libmbedtls-dev on debian) for TessesFramework
|
- Install [mbedtls](https://github.com/Mbed-TLS/mbedtls) (use sudo apt install libmbedtls-dev on debian) for TessesFramework (no longer works on debian, needs -DTESSESFRAMEWORK_FETCHCONTENT=ON for debian)
|
||||||
- Follow the commands bellow
|
- Follow the commands bellow
|
||||||
|
|
||||||
## Run these commands to install crosslang (with plugin support)
|
## Run these commands to install crosslang (with plugin support)
|
||||||
```bash
|
```bash
|
||||||
git clone https://onedev.site.tesses.net/tesses-framework
|
git clone https://git.tesses.org/tesses50/tessesframework
|
||||||
cd tesses-framework
|
cd tessesframework
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -S .. -B .
|
cmake -S .. -B . -DTESSESFRAMEWORK_FETCHCONTENT=OFF
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
cd ../..
|
cd ../..
|
||||||
git clone https://onedev.site.tesses.net/CrossLang
|
git clone https://git.tesses.org/tesses50/crosslang
|
||||||
cd CrossLang
|
cd crosslang
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -S .. -B . -DCROSSLANG_FETCHCONTENT=OFF
|
cmake -S .. -B . -DCROSSLANG_FETCHCONTENT=OFF
|
||||||
@@ -47,31 +47,11 @@ sudo make install
|
|||||||
|
|
||||||
## Build with shared libs only (self contained dependencies)
|
## Build with shared libs only (self contained dependencies)
|
||||||
```bash
|
```bash
|
||||||
cmake -S ../.. -B . -DTESSESFRAMEWORK_ENABLE_STATIC=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=ON -DTESSESFRAMEWORK_FETCHCONTENT=ON
|
cmake -S ../.. -B .
|
||||||
make -j`nproc`
|
make -j`nproc`
|
||||||
sudo make install
|
sudo make install
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://onedev.site.tesses.net/CrossLang
|
|
||||||
cd CrossLang
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake -S .. -B .
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
```
|
|
||||||
|
|
||||||
## To Create the binaries and ISO (You need linux for this)
|
|
||||||
```bash
|
|
||||||
sudo apt install xorriso wget curl mingw-w64 nsis cmake tar zip
|
|
||||||
mkdir dvdwork
|
|
||||||
cp build-dvd.tcross dvdwork/
|
|
||||||
cd dvdwork
|
|
||||||
crossint build-dvd.tcross
|
|
||||||
bash script.sh # the iso and tarballs will be in Working/Output
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Ye are of God, little children, and have overcome them: because greater is he that is in you, than he that is in the world. (1 John 4:4)
|
Ye are of God, little children, and have overcome them: because greater is he that is in you, than he that is in the world. (1 John 4:4)
|
||||||
```
|
```
|
||||||
|
|||||||
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://onedev.site.tesses.net/tesses-framework
|
|
||||||
git clone --depth=1 https://onedev.site.tesses.net/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://downloads.tesses.net/ShellPackage.crvm
|
|
||||||
";
|
|
||||||
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>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
22
changelog.md
Normal file
22
changelog.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
## 0.0.3
|
||||||
|
Fixed cmake, unnecessary itteration on dictionary, and a crosslang binary bug when shell is not installed
|
||||||
|
|
||||||
|
## 0.0.2
|
||||||
|
Add uuids, bytestreams and single file runtime binaries
|
||||||
|
|
||||||
|
## 0.0.1
|
||||||
|
Start versioning
|
||||||
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)
|
||||||
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()
|
||||||
28
cmake/install-dev.cmake
Normal file
28
cmake/install-dev.cmake
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
if(CROSSLANG_INSTALL_DEVELOPMENT)
|
||||||
|
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 "${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)
|
||||||
|
|
||||||
|
endif()
|
||||||
7
cmake/options.cmake
Normal file
7
cmake/options.cmake
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
option(CROSSLANG_ENABLE_BINARIES "Enable Tesses CrossLang binaries" ON)
|
||||||
|
option(CROSSLANG_INSTALL_DEVELOPMENT "Enable Tesses CrossLang development files" ON)
|
||||||
|
option(CROSSLANG_FETCHCONTENT "Use fetchcontent" ON)
|
||||||
|
option(CROSSLANG_ENABLE_FFI "Enable libffi" OFF)
|
||||||
|
option(CROSSLANG_ENABLE_RPATH "Enable RPATH" ON)
|
||||||
|
option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF)
|
||||||
|
option(CROSSLANG_STATIC "Build with static libraries instead of shared" OFF)
|
||||||
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)
|
||||||
64
cmake/sources.cmake
Normal file
64
cmake/sources.cmake
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
list(APPEND CROSSLANG_SOURCE
|
||||||
|
src/vm/bc/add.cpp
|
||||||
|
src/vm/bc/sub.cpp
|
||||||
|
src/vm/bc/getfield.cpp
|
||||||
|
src/vm/bc/setfield.cpp
|
||||||
|
src/vm/bc/tostring.cpp
|
||||||
|
src/vm/bc/equals.cpp
|
||||||
|
src/vm/bc/invokemethod.cpp
|
||||||
|
src/vm/bc/executemethod2.cpp
|
||||||
|
src/vm/bc/invoketwo.cpp
|
||||||
|
src/vm/bc/tobool.cpp
|
||||||
|
src/compiler/codegen.cpp
|
||||||
|
src/compiler/lexer.cpp
|
||||||
|
src/compiler/parser.cpp
|
||||||
|
src/compiler/ast.cpp
|
||||||
|
src/runtime_methods/uuid.cpp
|
||||||
|
src/runtime_methods/class.cpp
|
||||||
|
src/runtime_methods/console.cpp
|
||||||
|
src/runtime_methods/io.cpp
|
||||||
|
src/runtime_methods/std.cpp
|
||||||
|
src/runtime_methods/net.cpp
|
||||||
|
src/runtime_methods/vm.cpp
|
||||||
|
src/runtime_methods/json.cpp
|
||||||
|
src/runtime_methods/sqlite.cpp
|
||||||
|
src/runtime_methods/dictionary.cpp
|
||||||
|
src/runtime_methods/crypto.cpp
|
||||||
|
src/runtime_methods/ogc.cpp
|
||||||
|
src/runtime_methods/path.cpp
|
||||||
|
src/runtime_methods/env.cpp
|
||||||
|
src/runtime_methods/process.cpp
|
||||||
|
src/runtime_methods/helpers.cpp
|
||||||
|
src/types/embed.cpp
|
||||||
|
src/types/async.cpp
|
||||||
|
src/types/associativearray.cpp
|
||||||
|
src/types/any.cpp
|
||||||
|
src/types/ittr.cpp
|
||||||
|
src/types/closure.cpp
|
||||||
|
src/types/dictionary.cpp
|
||||||
|
src/types/externalmethod.cpp
|
||||||
|
src/types/list.cpp
|
||||||
|
src/types/native.cpp
|
||||||
|
src/types/rootenvironment.cpp
|
||||||
|
src/types/subenvironment.cpp
|
||||||
|
src/types/vfsheapobject.cpp
|
||||||
|
src/types/streamheapobject.cpp
|
||||||
|
src/types/class.cpp
|
||||||
|
src/types/classenvironment.cpp
|
||||||
|
src/types/random.cpp
|
||||||
|
src/types/queryable.cpp
|
||||||
|
src/vm/filereader.cpp
|
||||||
|
src/vm/gc.cpp
|
||||||
|
src/vm/gclist.cpp
|
||||||
|
src/vm/vm.cpp
|
||||||
|
src/vm/exception.cpp
|
||||||
|
src/archive.cpp
|
||||||
|
src/markedtobject.cpp
|
||||||
|
src/program_lib/crossarchivecreate.cpp
|
||||||
|
src/program_lib/crossarchiveextract.cpp
|
||||||
|
src/program_lib/crossdump.cpp
|
||||||
|
src/program_lib/crosslang.cpp
|
||||||
|
src/program_lib/crosslangcompiler.cpp
|
||||||
|
src/program_lib/crosslanginterperter.cpp
|
||||||
|
src/program_lib/crosslangvm.cpp
|
||||||
|
)
|
||||||
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)
|
||||||
3
cmake/version.cmake
Normal file
3
cmake/version.cmake
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
set(CROSSLANG_MAJOR_VERSION 0)
|
||||||
|
set(CROSSLANG_MINOR_VERSION 0)
|
||||||
|
set(CROSSLANG_PATCH_VERSION 7)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
[Thumbnailer Entry]
|
[Thumbnailer Entry]
|
||||||
TryExec=crossthumbnailer
|
TryExec=crosslang
|
||||||
Exec=crossthumbnailer %i %o
|
Exec=crosslang thumbnailer %i %o
|
||||||
MimeType=application/crvm;
|
MimeType=application/crvm;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ set(PKGCONFIG_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
|
|||||||
set(PKGCONFIG_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
|
set(PKGCONFIG_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
|
||||||
set(PKGCONFIG_PROJECT_DESCRIPTION "A programming language")
|
set(PKGCONFIG_PROJECT_DESCRIPTION "A programming language")
|
||||||
set(PKGCONFIG_PROJECT_HOMEPAGE_URL "https://onedev.site.tesses.net/crosslang")
|
set(PKGCONFIG_PROJECT_HOMEPAGE_URL "https://crosslang.tesseslanguage.com/")
|
||||||
|
|
||||||
if(CROSSLANG_ENABLE_FFI)
|
if(CROSSLANG_ENABLE_FFI)
|
||||||
set(PKGCONFIG_DEPS "Requires: libffi")
|
set(PKGCONFIG_DEPS "Requires: libffi")
|
||||||
@@ -10,16 +10,8 @@ else()
|
|||||||
set(PKGCONFIG_DEPS "")
|
set(PKGCONFIG_DEPS "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CROSSLANG_ENABLE_STATIC)
|
|
||||||
configure_file(crosslang_static.pc.in crosslang_static.pc @ONLY)
|
|
||||||
install(FILES
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/crosslang_static.pc
|
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CROSSLANG_ENABLE_SHARED)
|
|
||||||
configure_file(crosslang.pc.in crosslang.pc @ONLY)
|
configure_file(crosslang.pc.in crosslang.pc @ONLY)
|
||||||
install(FILES
|
install(FILES
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/crosslang.pc
|
${CMAKE_CURRENT_BINARY_DIR}/crosslang.pc
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
endif()
|
|
||||||
@@ -8,6 +8,7 @@ URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
|
|||||||
Version: @PROJECT_VERSION@
|
Version: @PROJECT_VERSION@
|
||||||
|
|
||||||
@PKGCONFIG_DEPS@
|
@PKGCONFIG_DEPS@
|
||||||
|
Requires: tessesframework
|
||||||
|
|
||||||
Cflags: -I"${includedir}"
|
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
|
|
||||||
364
src/archive.cpp
364
src/archive.cpp
@@ -1,23 +1,20 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
|
||||||
|
|
||||||
void CrossArchiveCreate(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::string name, TVMVersion version, std::string info, std::string icon)
|
void CrossArchiveCreate(
|
||||||
{
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm, std::string name,
|
||||||
|
TVMVersion version, std::string info, std::string icon) {
|
||||||
std::vector<std::string> ignored_files;
|
std::vector<std::string> ignored_files;
|
||||||
std::string file = "/.crossarchiveignore";
|
std::string file = "/.crossarchiveignore";
|
||||||
if(vfs->FileExists(file))
|
if (vfs->FileExists(file)) {
|
||||||
{
|
auto strm = vfs->OpenFile(file, "rb");
|
||||||
auto strm = vfs->OpenFile(file,"rb");
|
if (strm != nullptr) {
|
||||||
if(strm != nullptr)
|
|
||||||
{
|
|
||||||
Tesses::Framework::TextStreams::StreamReader reader(strm);
|
Tesses::Framework::TextStreams::StreamReader reader(strm);
|
||||||
std::string ignores;
|
std::string ignores;
|
||||||
while(reader.ReadLine(ignores))
|
while (reader.ReadLine(ignores)) {
|
||||||
{
|
if (!ignores.empty() && ignores[0] != '#') {
|
||||||
if(!ignores.empty() && ignores[0] != '#')
|
|
||||||
{
|
|
||||||
ignored_files.push_back(ignores);
|
ignored_files.push_back(ignores);
|
||||||
}
|
}
|
||||||
ignores.clear();
|
ignores.clear();
|
||||||
@@ -25,42 +22,20 @@ namespace Tesses::CrossLang
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
static std::vector<uint8_t> error_message_byte_code = {
|
static std::vector<uint8_t> error_message_byte_code = {
|
||||||
PUSHSTRING,
|
PUSHSTRING, 0, 0, 0, 2, GETVARIABLE, PUSHSTRING, 0, 0, 0,
|
||||||
0,
|
3, PUSHSTRING, 0, 0, 0, 4, PUSHLONG, 0, 0, 0,
|
||||||
0,
|
0, 0, 0, 0, 1, CALLMETHOD, RET};
|
||||||
0,
|
auto writeInt = [](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
|
||||||
2,
|
uint32_t number) -> void {
|
||||||
GETVARIABLE,
|
|
||||||
PUSHSTRING,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
3,
|
|
||||||
PUSHSTRING,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
4,
|
|
||||||
PUSHLONG,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
CALLMETHOD,
|
|
||||||
RET
|
|
||||||
};
|
|
||||||
auto writeInt = [](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,uint32_t number)->void{
|
|
||||||
uint8_t buff[4];
|
uint8_t buff[4];
|
||||||
BitConverter::FromUint32BE(buff[0],number);
|
BitConverter::FromUint32BE(buff[0], number);
|
||||||
strm->WriteBlock(buff,4);
|
strm->WriteBlock(buff, 4);
|
||||||
};
|
};
|
||||||
auto writeStr = [&writeInt](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::string text)->void {
|
auto writeStr =
|
||||||
writeInt(strm,(uint32_t)text.size());
|
[&writeInt](std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
|
||||||
strm->WriteBlock((const uint8_t*)text.c_str(),text.size());
|
std::string text) -> void {
|
||||||
|
writeInt(strm, (uint32_t)text.size());
|
||||||
|
strm->WriteBlock((const uint8_t *)text.c_str(), text.size());
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::string> strs;
|
std::vector<std::string> strs;
|
||||||
@@ -68,23 +43,24 @@ namespace Tesses::CrossLang
|
|||||||
strs.push_back(info);
|
strs.push_back(info);
|
||||||
strs.push_back("Console");
|
strs.push_back("Console");
|
||||||
strs.push_back("WriteLine");
|
strs.push_back("WriteLine");
|
||||||
strs.push_back("You are trying to run a crvm archive, stop it you won't get anywhere!\nUse crossarchiveextract instead.");
|
strs.push_back("You are trying to run a crvm archive, stop it you won't "
|
||||||
|
"get anywhere!\nUse crossarchiveextract instead.");
|
||||||
|
|
||||||
std::vector<std::string> resources;
|
std::vector<std::string> resources;
|
||||||
|
|
||||||
auto ensureResource = [&resources](std::string path)->uint32_t {
|
auto ensureResource = [&resources](std::string path) -> uint32_t {
|
||||||
for(uint32_t i = 0; i < (uint32_t)resources.size(); i++)
|
for (uint32_t i = 0; i < (uint32_t)resources.size(); i++) {
|
||||||
{
|
if (resources[i] == path)
|
||||||
if(resources[i] == path) return i;
|
return i;
|
||||||
}
|
}
|
||||||
uint32_t index = (uint32_t)resources.size();
|
uint32_t index = (uint32_t)resources.size();
|
||||||
resources.push_back(path);
|
resources.push_back(path);
|
||||||
return index;
|
return index;
|
||||||
};
|
};
|
||||||
auto ensureString = [&strs](std::string str)->uint32_t {
|
auto ensureString = [&strs](std::string str) -> uint32_t {
|
||||||
for(uint32_t i = 0; i < (uint32_t)strs.size(); i++)
|
for (uint32_t i = 0; i < (uint32_t)strs.size(); i++) {
|
||||||
{
|
if (strs[i] == str)
|
||||||
if(strs[i] == str) return i;
|
return i;
|
||||||
}
|
}
|
||||||
uint32_t index = (uint32_t)strs.size();
|
uint32_t index = (uint32_t)strs.size();
|
||||||
strs.push_back(str);
|
strs.push_back(str);
|
||||||
@@ -92,132 +68,142 @@ namespace Tesses::CrossLang
|
|||||||
};
|
};
|
||||||
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
||||||
|
|
||||||
std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkFS = [&ignored_files,vfs,&ensureString,&ensureResource,&ms,&walkFS,&writeInt](Tesses::Framework::Filesystem::VFSPath path)->void {
|
std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkFS =
|
||||||
|
[&ignored_files, vfs, &ensureString, &ensureResource, &ms, &walkFS,
|
||||||
if(vfs->DirectoryExists(path))
|
&writeInt](Tesses::Framework::Filesystem::VFSPath path) -> void {
|
||||||
{
|
if (vfs->DirectoryExists(path)) {
|
||||||
|
|
||||||
ms->WriteByte(1);
|
ms->WriteByte(1);
|
||||||
std::vector<std::string> paths;
|
std::vector<std::string> paths;
|
||||||
for(auto item : vfs->EnumeratePaths(path))
|
for (auto item : vfs->EnumeratePaths(path)) {
|
||||||
{
|
if (!item.relative && item.path.size() == 1 &&
|
||||||
if(!item.relative && item.path.size() == 1 && item.path[0] == "__resdir_tmp") continue;
|
item.path[0] == "__resdir_tmp")
|
||||||
if(!item.relative && item.path.size() == 1 && item.path[0] == ".crossarchiveignore") continue;
|
continue;
|
||||||
|
if (!item.relative && item.path.size() == 1 &&
|
||||||
|
item.path[0] == ".crossarchiveignore")
|
||||||
|
continue;
|
||||||
std::string filename = item.GetFileName();
|
std::string filename = item.GetFileName();
|
||||||
bool shallIgnore=false;
|
bool shallIgnore = false;
|
||||||
for(auto ign : ignored_files) if(ign == filename) {shallIgnore=true; break;}
|
for (auto ign : ignored_files)
|
||||||
if(shallIgnore) continue;
|
if (ign == filename) {
|
||||||
if(vfs->DirectoryExists(item) || vfs->RegularFileExists(item))
|
shallIgnore = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (shallIgnore)
|
||||||
|
continue;
|
||||||
|
if (vfs->DirectoryExists(item) || vfs->RegularFileExists(item))
|
||||||
paths.push_back(item.GetFileName());
|
paths.push_back(item.GetFileName());
|
||||||
}
|
}
|
||||||
writeInt(ms,(uint32_t)paths.size());
|
writeInt(ms, (uint32_t)paths.size());
|
||||||
for(auto item : paths)
|
for (auto item : paths) {
|
||||||
{
|
writeInt(ms, ensureString(item));
|
||||||
writeInt(ms,ensureString(item));
|
|
||||||
walkFS(path / item);
|
walkFS(path / item);
|
||||||
}
|
}
|
||||||
}
|
} else if (vfs->RegularFileExists(path)) {
|
||||||
else if(vfs->RegularFileExists(path))
|
|
||||||
{
|
|
||||||
ms->WriteByte(0);
|
ms->WriteByte(0);
|
||||||
writeInt(ms,ensureResource(path.ToString()));
|
writeInt(ms, ensureResource(path.ToString()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
walkFS(std::string("/"));
|
walkFS(std::string("/"));
|
||||||
if(!icon.empty())
|
if (!icon.empty())
|
||||||
ensureResource(icon);
|
ensureResource(icon);
|
||||||
|
|
||||||
uint8_t main_header[18];
|
uint8_t main_header[18];
|
||||||
memcpy(main_header,"TCROSSVM",8);
|
memcpy(main_header, "TCROSSVM", 8);
|
||||||
TVMVersion rtVersion(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
|
TVMVersion rtVersion(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
|
||||||
rtVersion.ToArray(main_header+8);
|
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
|
||||||
version.ToArray(main_header+13);
|
CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||||
strm->WriteBlock(main_header,sizeof(main_header));
|
rtVersion.ToArray(main_header + 8);
|
||||||
writeInt(strm,(uint32_t)((icon.empty() ? 5 : 6)+resources.size()));
|
version.ToArray(main_header + 13);
|
||||||
strm->WriteBlock((const uint8_t*)"STRS",4);
|
strm->WriteBlock(main_header, sizeof(main_header));
|
||||||
uint32_t sz=4;
|
writeInt(strm, (uint32_t)((icon.empty() ? 5 : 6) + resources.size()));
|
||||||
for(auto str : strs)
|
strm->WriteBlock((const uint8_t *)"STRS", 4);
|
||||||
|
uint32_t sz = 4;
|
||||||
|
for (auto str : strs)
|
||||||
sz += (uint32_t)(4 + str.size());
|
sz += (uint32_t)(4 + str.size());
|
||||||
writeInt(strm,sz);
|
writeInt(strm, sz);
|
||||||
writeInt(strm,(uint32_t)strs.size());
|
writeInt(strm, (uint32_t)strs.size());
|
||||||
for(auto str : strs)
|
for (auto str : strs) {
|
||||||
{
|
writeStr(strm, str);
|
||||||
writeStr(strm,str);
|
|
||||||
}
|
}
|
||||||
strm->WriteBlock((const uint8_t*)"NAME",4);
|
strm->WriteBlock((const uint8_t *)"NAME", 4);
|
||||||
writeInt(strm,4);
|
writeInt(strm, 4);
|
||||||
writeInt(strm,0);
|
writeInt(strm, 0);
|
||||||
strm->WriteBlock((const uint8_t*)"INFO",4);
|
strm->WriteBlock((const uint8_t *)"INFO", 4);
|
||||||
writeInt(strm,4);
|
writeInt(strm, 4);
|
||||||
writeInt(strm,1);
|
writeInt(strm, 1);
|
||||||
if(!icon.empty())
|
if (!icon.empty()) {
|
||||||
{
|
strm->WriteBlock((const uint8_t *)"ICON", 4);
|
||||||
strm->WriteBlock((const uint8_t*)"ICON",4);
|
writeInt(strm, 4);
|
||||||
writeInt(strm,4);
|
writeInt(strm, ensureResource(icon));
|
||||||
writeInt(strm,ensureResource(icon));
|
|
||||||
}
|
}
|
||||||
strm->WriteBlock((const uint8_t*)"CHKS",4);
|
strm->WriteBlock((const uint8_t *)"CHKS", 4);
|
||||||
writeInt(strm,(uint32_t)(12+error_message_byte_code.size()));
|
writeInt(strm, (uint32_t)(12 + error_message_byte_code.size()));
|
||||||
writeInt(strm,1);
|
writeInt(strm, 1);
|
||||||
writeInt(strm,0);
|
writeInt(strm, 0);
|
||||||
writeInt(strm,(uint32_t)error_message_byte_code.size());
|
writeInt(strm, (uint32_t)error_message_byte_code.size());
|
||||||
strm->WriteBlock(error_message_byte_code.data(),error_message_byte_code.size());
|
strm->WriteBlock(error_message_byte_code.data(),
|
||||||
|
error_message_byte_code.size());
|
||||||
|
|
||||||
|
for (auto res : resources) {
|
||||||
|
strm->WriteBlock((const uint8_t *)"RESO", 4);
|
||||||
for(auto res : resources)
|
auto strm2 = vfs->OpenFile(res, "rb");
|
||||||
{
|
writeInt(strm, (uint32_t)strm2->GetLength());
|
||||||
strm->WriteBlock((const uint8_t*)"RESO",4);
|
|
||||||
auto strm2 = vfs->OpenFile(res,"rb");
|
|
||||||
writeInt(strm,(uint32_t)strm2->GetLength());
|
|
||||||
strm2->CopyTo(strm);
|
strm2->CopyTo(strm);
|
||||||
|
|
||||||
}
|
}
|
||||||
strm->WriteBlock((const uint8_t*)"ARCV",4);
|
strm->WriteBlock((const uint8_t *)"ARCV", 4);
|
||||||
writeInt(strm,(uint32_t)ms->GetLength());
|
writeInt(strm, (uint32_t)ms->GetLength());
|
||||||
ms->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
|
ms->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||||
ms->CopyTo(strm);
|
ms->CopyTo(strm);
|
||||||
}
|
}
|
||||||
std::pair<std::pair<std::string,TVMVersion>,std::string> CrossArchiveExtract(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs)
|
std::pair<std::pair<std::string, TVMVersion>, std::string>
|
||||||
{
|
CrossArchiveExtract(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
|
||||||
auto ensure = [strm](uint8_t* buffer,size_t count)->void{
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs) {
|
||||||
|
auto ensure = [strm](uint8_t *buffer, size_t count) -> void {
|
||||||
size_t read = strm->ReadBlock(buffer, count);
|
size_t read = strm->ReadBlock(buffer, count);
|
||||||
if(read < count) throw VMException("End of file, could not read " + std::to_string((int64_t)count) + " byte(s)., offset=" + std::to_string(strm->GetLength()));
|
if (read < count)
|
||||||
|
throw VMException(
|
||||||
|
"End of file, could not read " +
|
||||||
|
std::to_string((int64_t)count) +
|
||||||
|
" byte(s)., offset=" + std::to_string(strm->GetLength()));
|
||||||
};
|
};
|
||||||
auto ensureInt = [&ensure]()->uint32_t {
|
auto ensureInt = [&ensure]() -> uint32_t {
|
||||||
uint8_t buffer[4];
|
uint8_t buffer[4];
|
||||||
ensure(buffer,4);
|
ensure(buffer, 4);
|
||||||
return BitConverter::ToUint32BE(buffer[0]);
|
return BitConverter::ToUint32BE(buffer[0]);
|
||||||
};
|
};
|
||||||
auto ensureStr = [&ensure,&ensureInt]()-> std::string {
|
auto ensureStr = [&ensure, &ensureInt]() -> std::string {
|
||||||
auto len = ensureInt();
|
auto len = ensureInt();
|
||||||
if(len == 0) return {};
|
if (len == 0)
|
||||||
std::string str={};
|
return {};
|
||||||
|
std::string str = {};
|
||||||
str.resize((size_t)len);
|
str.resize((size_t)len);
|
||||||
ensure((uint8_t*)str.data(),str.size());
|
ensure((uint8_t *)str.data(), str.size());
|
||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
std::vector<std::string> strs;
|
std::vector<std::string> strs;
|
||||||
auto getStr = [&ensure,&ensureInt,&strs]()-> std::string {
|
auto getStr = [&ensure, &ensureInt, &strs]() -> std::string {
|
||||||
auto index = ensureInt();
|
auto index = ensureInt();
|
||||||
if(index > strs.size()) throw VMException("String does not exist in TCrossVM file, expected string index: " + std::to_string(index) + ", total strings: " + std::to_string(strs.size()));
|
if (index > strs.size())
|
||||||
|
throw VMException("String does not exist in TCrossVM file, "
|
||||||
|
"expected string index: " +
|
||||||
|
std::to_string(index) + ", total strings: " +
|
||||||
|
std::to_string(strs.size()));
|
||||||
return strs[index];
|
return strs[index];
|
||||||
};
|
};
|
||||||
uint8_t main_header[18];
|
uint8_t main_header[18];
|
||||||
ensure(main_header,sizeof(main_header));
|
ensure(main_header, sizeof(main_header));
|
||||||
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image.");
|
if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
|
||||||
TVMVersion version(main_header+8);
|
throw VMException("Invalid TCrossVM image.");
|
||||||
if(version.CompareToRuntime() == 1)
|
TVMVersion version(main_header + 8);
|
||||||
{
|
if (version.CompareToRuntime() == 1) {
|
||||||
throw VMException("Runtime is too old.");
|
throw VMException("Runtime is too old.");
|
||||||
}
|
}
|
||||||
TVMVersion v2(main_header+13);
|
TVMVersion v2(main_header + 13);
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string info;
|
std::string info;
|
||||||
|
|
||||||
|
|
||||||
size_t _len = (size_t)ensureInt();
|
size_t _len = (size_t)ensureInt();
|
||||||
|
|
||||||
char table_name[4];
|
char table_name[4];
|
||||||
@@ -227,98 +213,94 @@ namespace Tesses::CrossLang
|
|||||||
Tesses::Framework::Filesystem::VFSPath tmpDir("/__resdir_tmp");
|
Tesses::Framework::Filesystem::VFSPath tmpDir("/__resdir_tmp");
|
||||||
|
|
||||||
vfs->CreateDirectory(tmpDir);
|
vfs->CreateDirectory(tmpDir);
|
||||||
for(size_t i = 0;i < _len; i++)
|
for (size_t i = 0; i < _len; i++) {
|
||||||
{
|
ensure((uint8_t *)table_name, sizeof(table_name));
|
||||||
ensure((uint8_t*)table_name,sizeof(table_name));
|
|
||||||
size_t tableLen = (size_t)ensureInt();
|
size_t tableLen = (size_t)ensureInt();
|
||||||
if(strncmp(table_name,"NAME",4) == 0)
|
if (strncmp(table_name, "NAME", 4) == 0) {
|
||||||
{
|
|
||||||
name = getStr();
|
name = getStr();
|
||||||
}
|
} else if (strncmp(table_name, "INFO", 4) == 0) {
|
||||||
else if(strncmp(table_name,"INFO",4) == 0)
|
|
||||||
{
|
|
||||||
info = getStr();
|
info = getStr();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(strncmp(table_name,"RESO",4) == 0) //resources (using embed)
|
else if (strncmp(table_name, "RESO", 4) == 0) // resources (using embed)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto path = tmpDir /std::to_string(resource_id);
|
auto path = tmpDir / std::to_string(resource_id);
|
||||||
|
|
||||||
auto strm2 = vfs->OpenFile(path,"wb");
|
auto strm2 = vfs->OpenFile(path, "wb");
|
||||||
size_t read = 0;
|
size_t read = 0;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
uint8_t buff[1024];
|
uint8_t buff[1024];
|
||||||
do {
|
do {
|
||||||
|
|
||||||
read = std::min(std::min(tableLen-offset,tableLen), sizeof(buff));
|
read = std::min(std::min(tableLen - offset, tableLen),
|
||||||
read = strm->Read(buff,read);
|
sizeof(buff));
|
||||||
if(read > 0)
|
read = strm->Read(buff, read);
|
||||||
strm2->WriteBlock(buff,read);
|
if (read > 0)
|
||||||
offset+=read;
|
strm2->WriteBlock(buff, read);
|
||||||
} while(read > 0);
|
offset += read;
|
||||||
|
} while (read > 0);
|
||||||
|
|
||||||
resource_id++;
|
resource_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(strncmp(table_name,"STRS",4) == 0) //strings
|
else if (strncmp(table_name, "STRS", 4) == 0) // strings
|
||||||
{
|
{
|
||||||
size_t strsLen = (size_t)ensureInt();
|
size_t strsLen = (size_t)ensureInt();
|
||||||
for(size_t j = 0;j < strsLen;j++)
|
for (size_t j = 0; j < strsLen; j++) {
|
||||||
{
|
|
||||||
strs.push_back(ensureStr());
|
strs.push_back(ensureStr());
|
||||||
}
|
}
|
||||||
}
|
} else if (strncmp(table_name, "ARCV", 4) == 0) {
|
||||||
else if(strncmp(table_name,"ARCV",4) == 0)
|
|
||||||
{
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
std::function<void(Tesses::Framework::Filesystem::VFSPath)> walkEntry = [strm,vfs,&getStr,&ensureInt,&tmpDir,&tableLen,&offset,&walkEntry](Tesses::Framework::Filesystem::VFSPath path)->void {
|
std::function<void(Tesses::Framework::Filesystem::VFSPath)>
|
||||||
if(offset + 1 > tableLen) return;
|
walkEntry =
|
||||||
|
[strm, vfs, &getStr, &ensureInt, &tmpDir, &tableLen,
|
||||||
|
&offset, &walkEntry](
|
||||||
|
Tesses::Framework::Filesystem::VFSPath path) -> void {
|
||||||
|
if (offset + 1 > tableLen)
|
||||||
|
return;
|
||||||
uint8_t type = strm->ReadByte();
|
uint8_t type = strm->ReadByte();
|
||||||
offset++;
|
offset++;
|
||||||
if(type == 1)
|
if (type == 1) {
|
||||||
{
|
// ISDIR
|
||||||
//ISDIR
|
|
||||||
vfs->CreateDirectory(path);
|
vfs->CreateDirectory(path);
|
||||||
if(offset + 4 > tableLen) return;
|
if (offset + 4 > tableLen)
|
||||||
|
return;
|
||||||
uint32_t count = ensureInt();
|
uint32_t count = ensureInt();
|
||||||
offset +=4;
|
offset += 4;
|
||||||
for(uint32_t i = 0; i < count; i++)
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
{
|
if (offset + 4 > tableLen)
|
||||||
if(offset + 4 > tableLen) return;
|
return;
|
||||||
std::string name = getStr();
|
std::string name = getStr();
|
||||||
offset +=4;
|
offset += 4;
|
||||||
walkEntry(path / name);
|
walkEntry(path / name);
|
||||||
}
|
}
|
||||||
}
|
} else if (type == 0) {
|
||||||
else if(type == 0)
|
if (offset + 4 > tableLen)
|
||||||
{
|
return;
|
||||||
if(offset + 4 > tableLen) return;
|
|
||||||
uint32_t index = ensureInt();
|
uint32_t index = ensureInt();
|
||||||
auto fSrc = tmpDir /std::to_string(index);
|
auto fSrc = tmpDir / std::to_string(index);
|
||||||
vfs->MoveFile(fSrc, path);
|
vfs->MoveFile(fSrc, path);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
walkEntry(std::string("/"));
|
walkEntry(std::string("/"));
|
||||||
}
|
} else {
|
||||||
else
|
if (strm->CanSeek()) {
|
||||||
{
|
strm->Seek((int64_t)tableLen,
|
||||||
if(strm->CanSeek())
|
Tesses::Framework::Streams::SeekOrigin::Current);
|
||||||
{
|
} else {
|
||||||
strm->Seek((int64_t)tableLen,Tesses::Framework::Streams::SeekOrigin::Current);
|
uint8_t *buffer = new uint8_t[tableLen];
|
||||||
}
|
ensure(buffer, tableLen);
|
||||||
else{
|
|
||||||
uint8_t* buffer=new uint8_t[tableLen];
|
|
||||||
ensure(buffer,tableLen);
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vfs->DeleteDirectoryRecurse(tmpDir);
|
vfs->DeleteDirectoryRecurse(tmpDir);
|
||||||
|
|
||||||
return std::pair<std::pair<std::string,TVMVersion>,std::string>(std::pair<std::string,TVMVersion>(name,v2),info);
|
return std::pair<std::pair<std::string, TVMVersion>, std::string>(
|
||||||
}
|
std::pair<std::string, TVMVersion>(name, v2), info);
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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)
|
#if defined(CROSSLANG_ENABLE_JSON)
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#endif
|
#endif
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,
|
||||||
AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,bool isExpression, std::vector<SyntaxNode> nodes)
|
bool isExpression,
|
||||||
{
|
std::vector<SyntaxNode> nodes) {
|
||||||
AdvancedSyntaxNode asn;
|
AdvancedSyntaxNode asn;
|
||||||
asn.nodeName = std::string(nodeName);
|
asn.nodeName = std::string(nodeName);
|
||||||
asn.isExpression = isExpression;
|
asn.isExpression = isExpression;
|
||||||
@@ -14,45 +14,43 @@ AdvancedSyntaxNode AdvancedSyntaxNode::Create(std::string_view nodeName,bool isE
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CROSSLANG_ENABLE_JSON)
|
#if defined(CROSSLANG_ENABLE_JSON)
|
||||||
static SyntaxNode Deserialize2(json_t* json)
|
static SyntaxNode Deserialize2(json_t *json) {
|
||||||
{
|
if (json_is_null(json))
|
||||||
if(json_is_null(json)) return nullptr;
|
return nullptr;
|
||||||
if(json_is_true(json)) return true;
|
if (json_is_true(json))
|
||||||
if(json_is_false(json)) return false;
|
return true;
|
||||||
if(json_is_integer(json)) return (int64_t)json_integer_value(json);
|
if (json_is_false(json))
|
||||||
if(json_is_real(json)) return json_real_value(json);
|
return false;
|
||||||
if(json_is_string(json)) return std::string(json_string_value(json),json_string_length(json));
|
if (json_is_integer(json))
|
||||||
if(json_is_object(json))
|
return (int64_t)json_integer_value(json);
|
||||||
{
|
if (json_is_real(json))
|
||||||
json_t* typ = json_object_get(json, "type");
|
return json_real_value(json);
|
||||||
if(json_is_string(typ))
|
if (json_is_string(json))
|
||||||
{
|
return std::string(json_string_value(json), json_string_length(json));
|
||||||
std::string type(json_string_value(typ),json_string_length(typ));
|
if (json_is_object(json)) {
|
||||||
if(type == CharExpression)
|
json_t *typ = json_object_get(json, "type");
|
||||||
{
|
if (json_is_string(typ)) {
|
||||||
json_t* chrData = json_object_get(json,"value");
|
std::string type(json_string_value(typ), json_string_length(typ));
|
||||||
if(json_is_integer(chrData))
|
if (type == CharExpression) {
|
||||||
{
|
json_t *chrData = json_object_get(json, "value");
|
||||||
|
if (json_is_integer(chrData)) {
|
||||||
return (char)(uint8_t)json_integer_value(chrData);
|
return (char)(uint8_t)json_integer_value(chrData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(type == UndefinedExpression)
|
if (type == UndefinedExpression) {
|
||||||
{
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
json_t* isExpr = json_object_get(json,"isExpression");
|
json_t *isExpr = json_object_get(json, "isExpression");
|
||||||
bool isExprB = json_is_true(isExpr);
|
bool isExprB = json_is_true(isExpr);
|
||||||
AdvancedSyntaxNode asn;
|
AdvancedSyntaxNode asn;
|
||||||
asn.nodeName = type;
|
asn.nodeName = type;
|
||||||
asn.isExpression = isExprB;
|
asn.isExpression = isExprB;
|
||||||
json_t* args = json_object_get(json, "args");
|
json_t *args = json_object_get(json, "args");
|
||||||
if(json_is_array(args))
|
if (json_is_array(args)) {
|
||||||
{
|
|
||||||
size_t index;
|
size_t index;
|
||||||
json_t* value;
|
json_t *value;
|
||||||
|
|
||||||
json_array_foreach(args, index, value)
|
json_array_foreach(args, index, value) {
|
||||||
{
|
|
||||||
asn.nodes.push_back(Deserialize2(value));
|
asn.nodes.push_back(Deserialize2(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,68 +61,59 @@ static SyntaxNode Deserialize2(json_t* json)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
SyntaxNode Deserialize(std::string astData) {
|
||||||
SyntaxNode Deserialize(std::string astData)
|
#if defined(CROSSLANG_ENABLE_JSON)
|
||||||
{
|
json_t *json = json_loadb(astData.c_str(), astData.size(), 0, NULL);
|
||||||
#if defined(CROSSLANG_ENABLE_JSON)
|
|
||||||
json_t* json = json_loadb(astData.c_str(),astData.size(), 0, NULL);
|
|
||||||
|
|
||||||
auto r = Deserialize2(json);
|
auto r = Deserialize2(json);
|
||||||
json_decref(json);
|
json_decref(json);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#if defined(CROSSLANG_ENABLE_JSON)
|
#if defined(CROSSLANG_ENABLE_JSON)
|
||||||
static json_t* Serialize2(SyntaxNode node)
|
static json_t *Serialize2(SyntaxNode node) {
|
||||||
{
|
if (std::holds_alternative<std::nullptr_t>(node))
|
||||||
if(std::holds_alternative<std::nullptr_t>(node))
|
|
||||||
return json_null();
|
return json_null();
|
||||||
if(std::holds_alternative<int64_t>(node))
|
if (std::holds_alternative<int64_t>(node)) {
|
||||||
{
|
|
||||||
return json_integer(std::get<int64_t>(node));
|
return json_integer(std::get<int64_t>(node));
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<double>(node))
|
if (std::holds_alternative<double>(node)) {
|
||||||
{
|
|
||||||
return json_real(std::get<double>(node));
|
return json_real(std::get<double>(node));
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<bool>(node))
|
if (std::holds_alternative<bool>(node)) {
|
||||||
{
|
|
||||||
return json_boolean(std::get<bool>(node));
|
return json_boolean(std::get<bool>(node));
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<std::string>(node))
|
if (std::holds_alternative<std::string>(node)) {
|
||||||
{
|
|
||||||
std::string str = std::get<std::string>(node);
|
std::string str = std::get<std::string>(node);
|
||||||
return json_stringn(str.c_str(),str.size());
|
return json_stringn(str.c_str(), str.size());
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<char>(node))
|
if (std::holds_alternative<char>(node)) {
|
||||||
{
|
|
||||||
char c = std::get<char>(node);
|
char c = std::get<char>(node);
|
||||||
json_t* json = json_object();
|
json_t *json = json_object();
|
||||||
json_object_set_new(json,"type",json_string((const char*)CharExpression.data()));
|
json_object_set_new(json, "type",
|
||||||
|
json_string((const char *)CharExpression.data()));
|
||||||
json_object_set_new(json, "value", json_integer((uint8_t)c));
|
json_object_set_new(json, "value", json_integer((uint8_t)c));
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<Undefined>(node))
|
if (std::holds_alternative<Undefined>(node)) {
|
||||||
{
|
json_t *json = json_object();
|
||||||
json_t* json = json_object();
|
json_object_set_new(
|
||||||
json_object_set_new(json,"type",json_string((const char*)UndefinedExpression.data()));
|
json, "type",
|
||||||
|
json_string((const char *)UndefinedExpression.data()));
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (std::holds_alternative<AdvancedSyntaxNode>(node)) {
|
||||||
if(std::holds_alternative<AdvancedSyntaxNode>(node))
|
|
||||||
{
|
|
||||||
auto asn = std::get<AdvancedSyntaxNode>(node);
|
auto asn = std::get<AdvancedSyntaxNode>(node);
|
||||||
json_t* j = json_object();
|
json_t *j = json_object();
|
||||||
json_object_set_new(j, "type", json_string(asn.nodeName.c_str()));
|
json_object_set_new(j, "type", json_string(asn.nodeName.c_str()));
|
||||||
json_object_set_new(j, "isExpression",json_boolean(asn.isExpression));
|
json_object_set_new(j, "isExpression", json_boolean(asn.isExpression));
|
||||||
json_t* arr=json_array();
|
json_t *arr = json_array();
|
||||||
for(auto item : asn.nodes)
|
for (auto item : asn.nodes) {
|
||||||
{
|
json_array_append_new(arr, Serialize2(item));
|
||||||
json_array_append_new(arr,Serialize2(item));
|
|
||||||
}
|
}
|
||||||
json_object_set_new(j, "args", arr);
|
json_object_set_new(j, "args", arr);
|
||||||
return j;
|
return j;
|
||||||
@@ -134,18 +123,17 @@ static json_t* Serialize2(SyntaxNode node)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string Serialize(SyntaxNode node)
|
std::string Serialize(SyntaxNode node) {
|
||||||
{
|
|
||||||
|
|
||||||
#if defined(CROSSLANG_ENABLE_JSON)
|
#if defined(CROSSLANG_ENABLE_JSON)
|
||||||
json_t* json = Serialize2(node);
|
json_t *json = Serialize2(node);
|
||||||
char* txt = json_dumps(json,0);
|
char *txt = json_dumps(json, 0);
|
||||||
std::string str(txt);
|
std::string str(txt);
|
||||||
free(json);
|
free(json);
|
||||||
json_decref(json);
|
json_decref(json);
|
||||||
return str;
|
return str;
|
||||||
#endif
|
#endif
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Tesses::CrossLang
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,95 +1,70 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
std::string EscapeString(std::string text, bool quote) {
|
||||||
std::string EscapeString(std::string text,bool quote)
|
std::string str = {};
|
||||||
{
|
if (quote)
|
||||||
std::string str={};
|
str.push_back('\"');
|
||||||
if(quote) str.push_back('\"');
|
for (auto item : text) {
|
||||||
for(auto item : text)
|
if (item == '\\' || item == '\"' || item == '\'') {
|
||||||
{
|
|
||||||
if(item == '\\' || item == '\"' || item == '\'')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back(item);
|
str.push_back(item);
|
||||||
}
|
} else if (item == '\n') {
|
||||||
else if(item == '\n')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back('n');
|
str.push_back('n');
|
||||||
}
|
} else if (item == '\r') {
|
||||||
else if(item == '\r')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back('r');
|
str.push_back('r');
|
||||||
}
|
} else if (item == '\t') {
|
||||||
else if(item == '\t')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back('t');
|
str.push_back('t');
|
||||||
}
|
} else if (item == '\f') {
|
||||||
else if(item == '\f')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back('f');
|
str.push_back('f');
|
||||||
}
|
} else if (item == '\0') {
|
||||||
else if(item == '\0')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back('0');
|
str.push_back('0');
|
||||||
}
|
} else if (item == '\b') {
|
||||||
else if(item == '\b')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back('b');
|
str.push_back('b');
|
||||||
}
|
} else if (item == '\a') {
|
||||||
else if(item == '\a')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back('a');
|
str.push_back('a');
|
||||||
}
|
} else if (item == '\v') {
|
||||||
else if(item == '\v')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back('v');
|
str.push_back('v');
|
||||||
}
|
} else if (item == '\x1B') {
|
||||||
else if(item == '\x1B')
|
|
||||||
{
|
|
||||||
str.push_back('\\');
|
str.push_back('\\');
|
||||||
str.push_back('e');
|
str.push_back('e');
|
||||||
}
|
} else if ((uint8_t)item < 32 || (uint8_t)item > 126) {
|
||||||
else if((uint8_t)item < 32 || (uint8_t)item > 126)
|
|
||||||
{
|
|
||||||
str.append("\\x");
|
str.append("\\x");
|
||||||
str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex(((uint8_t)item >> 4)&0x0F));
|
str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex(
|
||||||
str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex((uint8_t)item & 0x0F));
|
((uint8_t)item >> 4) & 0x0F));
|
||||||
}
|
str.push_back(Tesses::Framework::Http::HttpUtils::NibbleToHex(
|
||||||
else
|
(uint8_t)item & 0x0F));
|
||||||
{
|
} else {
|
||||||
str.push_back(item);
|
str.push_back(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(quote) str.push_back('\"');
|
if (quote)
|
||||||
|
str.push_back('\"');
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LexTokenLineInfo::Subtract(size_t len)
|
void LexTokenLineInfo::Subtract(size_t len) {
|
||||||
{
|
|
||||||
this->offset -= len;
|
this->offset -= len;
|
||||||
this->column -= len;
|
this->column -= len;
|
||||||
}
|
}
|
||||||
void LexTokenLineInfo::Add(int c)
|
void LexTokenLineInfo::Add(int c) {
|
||||||
{
|
|
||||||
this->offset++;
|
this->offset++;
|
||||||
switch(c)
|
switch (c) {
|
||||||
{
|
|
||||||
case ' ':
|
case ' ':
|
||||||
this->column++;
|
this->column++;
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
this->column=1;
|
this->column = 1;
|
||||||
this->line++;
|
this->line++;
|
||||||
break;
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
@@ -102,28 +77,29 @@ namespace Tesses::CrossLang
|
|||||||
this->column++;
|
this->column++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Lex(std::string filename, std::istream& strm, std::vector<LexToken>& tokens)
|
int Lex(std::string filename, std::istream &strm,
|
||||||
{
|
std::vector<LexToken> &tokens) {
|
||||||
int _peeked=-1;
|
int _peeked = -1;
|
||||||
|
|
||||||
auto Read = [&_peeked,&strm]()->int {
|
auto Read = [&_peeked, &strm]() -> int {
|
||||||
if(_peeked > -1)
|
if (_peeked > -1) {
|
||||||
{
|
|
||||||
int _peek2 = _peeked;
|
int _peek2 = _peeked;
|
||||||
_peeked=-1;
|
_peeked = -1;
|
||||||
return _peek2;
|
return _peek2;
|
||||||
}
|
}
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
|
|
||||||
strm.read((char*)&b,1);
|
strm.read((char *)&b, 1);
|
||||||
if(strm.eof()) return -1;
|
if (strm.eof())
|
||||||
|
return -1;
|
||||||
return b;
|
return b;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto Peek = [&_peeked,Read]()->int {
|
auto Peek = [&_peeked, Read]() -> int {
|
||||||
if(_peeked > -1) return _peeked;
|
if (_peeked > -1)
|
||||||
|
return _peeked;
|
||||||
_peeked = Read();
|
_peeked = Read();
|
||||||
return _peeked;
|
return _peeked;
|
||||||
};
|
};
|
||||||
@@ -131,7 +107,7 @@ namespace Tesses::CrossLang
|
|||||||
int read;
|
int read;
|
||||||
int peek;
|
int peek;
|
||||||
|
|
||||||
std::string buffer={};
|
std::string buffer = {};
|
||||||
|
|
||||||
LexTokenLineInfo lineInfo;
|
LexTokenLineInfo lineInfo;
|
||||||
|
|
||||||
@@ -140,11 +116,11 @@ namespace Tesses::CrossLang
|
|||||||
lineInfo.line = 1;
|
lineInfo.line = 1;
|
||||||
lineInfo.offset = 0;
|
lineInfo.offset = 0;
|
||||||
|
|
||||||
std::string whiteSpaceCharsBefore="";
|
std::string whiteSpaceCharsBefore = "";
|
||||||
|
|
||||||
auto Flush = [&buffer,&tokens,&lineInfo,&whiteSpaceCharsBefore]() -> void {
|
auto Flush = [&buffer, &tokens, &lineInfo,
|
||||||
if(!buffer.empty())
|
&whiteSpaceCharsBefore]() -> void {
|
||||||
{
|
if (!buffer.empty()) {
|
||||||
LexToken token;
|
LexToken token;
|
||||||
token.text = buffer;
|
token.text = buffer;
|
||||||
token.whiteSpaceCharsBefore = whiteSpaceCharsBefore;
|
token.whiteSpaceCharsBefore = whiteSpaceCharsBefore;
|
||||||
@@ -154,149 +130,113 @@ namespace Tesses::CrossLang
|
|||||||
tokens.push_back(token);
|
tokens.push_back(token);
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
|
|
||||||
whiteSpaceCharsBefore="";
|
whiteSpaceCharsBefore = "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto Symbol = [&tokens,&lineInfo,&whiteSpaceCharsBefore](std::initializer_list<int> chrs)-> void {
|
auto Symbol = [&tokens, &lineInfo, &whiteSpaceCharsBefore](
|
||||||
|
std::initializer_list<int> chrs) -> void {
|
||||||
LexToken token;
|
LexToken token;
|
||||||
|
|
||||||
token.type = LexTokenType::Symbol;
|
token.type = LexTokenType::Symbol;
|
||||||
token.lineInfo = lineInfo;
|
token.lineInfo = lineInfo;
|
||||||
|
|
||||||
token.whiteSpaceCharsBefore=whiteSpaceCharsBefore;
|
token.whiteSpaceCharsBefore = whiteSpaceCharsBefore;
|
||||||
|
|
||||||
token.text.reserve(chrs.size());
|
token.text.reserve(chrs.size());
|
||||||
|
|
||||||
for(auto i : chrs)
|
for (auto i : chrs)
|
||||||
token.text.push_back((char)i);
|
token.text.push_back((char)i);
|
||||||
|
|
||||||
tokens.push_back(token);
|
tokens.push_back(token);
|
||||||
|
|
||||||
whiteSpaceCharsBefore="";
|
whiteSpaceCharsBefore = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
auto ReadChr = [&lineInfo, &strm, Read]() -> std::pair<int,bool> {
|
auto ReadChr = [&lineInfo, &strm, Read]() -> std::pair<int, bool> {
|
||||||
int read=Read();
|
int read = Read();
|
||||||
lineInfo.Add(read);
|
lineInfo.Add(read);
|
||||||
|
|
||||||
if(read == -1)
|
if (read == -1) {
|
||||||
{
|
|
||||||
|
|
||||||
return std::pair<int,bool>(-1,false);
|
return std::pair<int, bool>(-1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (read == '\\') {
|
||||||
|
|
||||||
if(read == '\\')
|
|
||||||
{
|
|
||||||
read = Read();
|
read = Read();
|
||||||
lineInfo.Add(read);
|
lineInfo.Add(read);
|
||||||
if(read == -1)
|
if (read == -1) {
|
||||||
{
|
return std::pair<int, bool>(-1, true);
|
||||||
return std::pair<int,bool>(-1,true);
|
} else if (read == 'n') {
|
||||||
}
|
return std::pair<int, bool>('\n', true);
|
||||||
else if(read == 'n')
|
} else if (read == 'r') {
|
||||||
{
|
return std::pair<int, bool>('\r', true);
|
||||||
return std::pair<int,bool>('\n',true);
|
} else if (read == 'f') {
|
||||||
}
|
return std::pair<int, bool>('\f', true);
|
||||||
else if(read == 'r')
|
} else if (read == 'b') {
|
||||||
{
|
return std::pair<int, bool>('\b', true);
|
||||||
return std::pair<int,bool>('\r',true);
|
} else if (read == 'a') {
|
||||||
}
|
return std::pair<int, bool>('\a', true);
|
||||||
else if(read == 'f')
|
} else if (read == '0') {
|
||||||
{
|
return std::pair<int, bool>('\0', true);
|
||||||
return std::pair<int,bool>('\f',true);
|
} else if (read == 'v') {
|
||||||
}
|
return std::pair<int, bool>('\v', true);
|
||||||
else if(read == 'b')
|
} else if (read == 'e') {
|
||||||
{
|
return std::pair<int, bool>('\x1B', true);
|
||||||
return std::pair<int,bool>('\b',true);
|
} else if (read == 't') {
|
||||||
}
|
return std::pair<int, bool>('\t', true);
|
||||||
else if(read == 'a')
|
} else if (read == 'x') {
|
||||||
{
|
|
||||||
return std::pair<int,bool>('\a',true);
|
|
||||||
}
|
|
||||||
else if(read == '0')
|
|
||||||
{
|
|
||||||
return std::pair<int,bool>('\0',true);
|
|
||||||
}
|
|
||||||
else if(read == 'v')
|
|
||||||
{
|
|
||||||
return std::pair<int,bool>('\v',true);
|
|
||||||
}
|
|
||||||
else if(read == 'e')
|
|
||||||
{
|
|
||||||
return std::pair<int,bool>('\x1B',true);
|
|
||||||
}
|
|
||||||
else if(read == 't')
|
|
||||||
{
|
|
||||||
return std::pair<int,bool>('\t',true);
|
|
||||||
}
|
|
||||||
else if(read == 'x')
|
|
||||||
{
|
|
||||||
int r1 = Read();
|
int r1 = Read();
|
||||||
lineInfo.Add(r1);
|
lineInfo.Add(r1);
|
||||||
if(r1 == -1)
|
if (r1 == -1) {
|
||||||
{
|
return std::pair<int, bool>(-1, true);
|
||||||
return std::pair<int,bool>(-1,true);
|
|
||||||
}
|
}
|
||||||
int r2 = Read();
|
int r2 = Read();
|
||||||
lineInfo.Add(r2);
|
lineInfo.Add(r2);
|
||||||
if(r2 == -1)
|
if (r2 == -1) {
|
||||||
{
|
return std::pair<int, bool>(-1, true);
|
||||||
return std::pair<int,bool>(-1,true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t c = (uint8_t)std::stoi(std::string{(char)r1,(char)r2},nullptr,16);
|
uint8_t c = (uint8_t)std::stoi(std::string{(char)r1, (char)r2},
|
||||||
|
nullptr, 16);
|
||||||
|
|
||||||
return std::pair<int,bool>(c,true);
|
return std::pair<int, bool>(c, true);
|
||||||
|
} else {
|
||||||
|
return std::pair<int, bool>(read, true);
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
{
|
return std::pair<int, bool>(read, false);
|
||||||
return std::pair<int,bool>(read,true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return std::pair<int,bool>(read,false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto ParseString = [&lineInfo, &strm, Read, ReadChr,
|
||||||
auto ParseString = [&lineInfo, &strm, Read, ReadChr,&tokens](bool interopolated)->int {
|
&tokens](bool interopolated) -> int {
|
||||||
auto lI = lineInfo;
|
auto lI = lineInfo;
|
||||||
|
|
||||||
std::string b={};
|
std::string b = {};
|
||||||
|
|
||||||
|
|
||||||
auto rChr = ReadChr();
|
auto rChr = ReadChr();
|
||||||
lineInfo.Add(rChr.first);
|
lineInfo.Add(rChr.first);
|
||||||
|
|
||||||
while(rChr.first != '\"' || rChr.second)
|
while (rChr.first != '\"' || rChr.second) {
|
||||||
{
|
if (rChr.first == -1)
|
||||||
if(rChr.first == -1) return lineInfo.line;
|
return lineInfo.line;
|
||||||
|
|
||||||
b.push_back((char)rChr.first);
|
b.push_back((char)rChr.first);
|
||||||
rChr = ReadChr();
|
rChr = ReadChr();
|
||||||
lineInfo.Add(rChr.first);
|
lineInfo.Add(rChr.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(interopolated)
|
if (interopolated) {
|
||||||
{
|
|
||||||
int e = 0;
|
int e = 0;
|
||||||
int escapeI = 0;
|
int escapeI = 0;
|
||||||
std::string b2 = {};
|
std::string b2 = {};
|
||||||
|
|
||||||
for(size_t i = 0; i< b.size();i++)
|
for (size_t i = 0; i < b.size(); i++) {
|
||||||
{
|
if (b[i] == '{') {
|
||||||
if(b[i] == '{')
|
if ((i + 1 < b.size() && b[i + 1] != '{') || escapeI >= 1) {
|
||||||
{
|
if (b2.size() > 0 && escapeI < 1) {
|
||||||
if((i+1 < b.size() && b[i+1] != '{') || escapeI >= 1)
|
if (e > 0) {
|
||||||
{
|
|
||||||
if(b2.size() > 0 && escapeI < 1)
|
|
||||||
{
|
|
||||||
if(e > 0)
|
|
||||||
{
|
|
||||||
LexToken _tkn;
|
LexToken _tkn;
|
||||||
_tkn.type = LexTokenType::Symbol;
|
_tkn.type = LexTokenType::Symbol;
|
||||||
_tkn.text = "+";
|
_tkn.text = "+";
|
||||||
@@ -310,29 +250,20 @@ namespace Tesses::CrossLang
|
|||||||
tokens.push_back(_tkn2);
|
tokens.push_back(_tkn2);
|
||||||
b2.clear();
|
b2.clear();
|
||||||
e++;
|
e++;
|
||||||
|
|
||||||
}
|
}
|
||||||
escapeI++;
|
escapeI++;
|
||||||
if(escapeI > 1)
|
if (escapeI > 1) {
|
||||||
{
|
|
||||||
b2.push_back('{');
|
b2.push_back('{');
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
b2.push_back('{');
|
b2.push_back('{');
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
} else if (b[i] == '}') {
|
||||||
else if(b[i] == '}')
|
if (escapeI >= 1) {
|
||||||
{
|
|
||||||
if(escapeI >= 1)
|
|
||||||
{
|
|
||||||
escapeI--;
|
escapeI--;
|
||||||
if(b2.size() > 0 && escapeI == 0)
|
if (b2.size() > 0 && escapeI == 0) {
|
||||||
{
|
if (e > 0) {
|
||||||
if(e > 0)
|
|
||||||
{
|
|
||||||
LexToken _tkn;
|
LexToken _tkn;
|
||||||
_tkn.type = LexTokenType::Symbol;
|
_tkn.type = LexTokenType::Symbol;
|
||||||
_tkn.text = "+";
|
_tkn.text = "+";
|
||||||
@@ -344,9 +275,11 @@ namespace Tesses::CrossLang
|
|||||||
_tkn2.text = "(";
|
_tkn2.text = "(";
|
||||||
_tkn2.lineInfo = lI;
|
_tkn2.lineInfo = lI;
|
||||||
tokens.push_back(_tkn2);
|
tokens.push_back(_tkn2);
|
||||||
std::stringstream strm2(b2,std::ios_base::in | std::ios_base::binary);
|
std::stringstream strm2(
|
||||||
|
b2, std::ios_base::in | std::ios_base::binary);
|
||||||
int res = Lex("lexGen", strm2, tokens);
|
int res = Lex("lexGen", strm2, tokens);
|
||||||
if(res != 0) return res;
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
_tkn2.text = ")";
|
_tkn2.text = ")";
|
||||||
tokens.push_back(_tkn2);
|
tokens.push_back(_tkn2);
|
||||||
@@ -364,8 +297,7 @@ namespace Tesses::CrossLang
|
|||||||
b2.clear();
|
b2.clear();
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
if(escapeI >= 1)
|
if (escapeI >= 1) {
|
||||||
{
|
|
||||||
b2.push_back('}');
|
b2.push_back('}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,12 +305,9 @@ namespace Tesses::CrossLang
|
|||||||
b2.push_back(b[i]);
|
b2.push_back(b[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(b2.size() > 0)
|
if (b2.size() > 0) {
|
||||||
{
|
if (escapeI > 0) {
|
||||||
if(escapeI > 0)
|
if (e > 0) {
|
||||||
{
|
|
||||||
if(e > 0)
|
|
||||||
{
|
|
||||||
LexToken _tkn;
|
LexToken _tkn;
|
||||||
_tkn.type = LexTokenType::Symbol;
|
_tkn.type = LexTokenType::Symbol;
|
||||||
_tkn.text = "+";
|
_tkn.text = "+";
|
||||||
@@ -390,9 +319,11 @@ namespace Tesses::CrossLang
|
|||||||
_tkn2.text = "(";
|
_tkn2.text = "(";
|
||||||
_tkn2.lineInfo = lI;
|
_tkn2.lineInfo = lI;
|
||||||
tokens.push_back(_tkn2);
|
tokens.push_back(_tkn2);
|
||||||
std::stringstream strm2(b2,std::ios_base::in | std::ios_base::binary);
|
std::stringstream strm2(b2, std::ios_base::in |
|
||||||
|
std::ios_base::binary);
|
||||||
int res = Lex("lexGen", strm2, tokens);
|
int res = Lex("lexGen", strm2, tokens);
|
||||||
if(res != 0) return res;
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
_tkn2.text = ")";
|
_tkn2.text = ")";
|
||||||
tokens.push_back(_tkn2);
|
tokens.push_back(_tkn2);
|
||||||
@@ -410,11 +341,8 @@ namespace Tesses::CrossLang
|
|||||||
b2.clear();
|
b2.clear();
|
||||||
e++;
|
e++;
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else
|
if (e > 0) {
|
||||||
{
|
|
||||||
if(e > 0)
|
|
||||||
{
|
|
||||||
LexToken _tkn;
|
LexToken _tkn;
|
||||||
_tkn.type = LexTokenType::Symbol;
|
_tkn.type = LexTokenType::Symbol;
|
||||||
_tkn.text = "+";
|
_tkn.text = "+";
|
||||||
@@ -436,47 +364,40 @@ namespace Tesses::CrossLang
|
|||||||
_tkn2.text = b;
|
_tkn2.text = b;
|
||||||
_tkn2.lineInfo = lI;
|
_tkn2.lineInfo = lI;
|
||||||
tokens.push_back(_tkn2);
|
tokens.push_back(_tkn2);
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
while((read = Read()) != -1)
|
while ((read = Read()) != -1) {
|
||||||
{
|
|
||||||
|
|
||||||
peek = Peek();
|
peek = Peek();
|
||||||
|
|
||||||
|
switch (read) {
|
||||||
switch(read)
|
|
||||||
{
|
|
||||||
case '$':
|
case '$':
|
||||||
if(peek == '\"')
|
if (peek == '\"') {
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
int re = ParseString(true);
|
int re = ParseString(true);
|
||||||
if(re != 0) return re;
|
if (re != 0)
|
||||||
}
|
return re;
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
buffer.push_back('$');
|
buffer.push_back('$');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\"':
|
case '\"': {
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
int re = ParseString(false);
|
int re = ParseString(false);
|
||||||
if(re != 0) return re;
|
if (re != 0)
|
||||||
}
|
return re;
|
||||||
break;
|
} break;
|
||||||
case '\'':
|
case '\'': {
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
auto res = ReadChr();
|
auto res = ReadChr();
|
||||||
if(res.first == -1) return lineInfo.line;
|
if (res.first == -1)
|
||||||
|
return lineInfo.line;
|
||||||
int r = Read();
|
int r = Read();
|
||||||
lineInfo.Add(r);
|
lineInfo.Add(r);
|
||||||
if(r != '\'')
|
if (r != '\'')
|
||||||
return lineInfo.line;
|
return lineInfo.line;
|
||||||
LexToken token;
|
LexToken token;
|
||||||
token.text = {(char)(uint8_t)res.first};
|
token.text = {(char)(uint8_t)res.first};
|
||||||
@@ -484,75 +405,62 @@ namespace Tesses::CrossLang
|
|||||||
token.type = LexTokenType::Char;
|
token.type = LexTokenType::Char;
|
||||||
|
|
||||||
tokens.push_back(token);
|
tokens.push_back(token);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case '#':
|
case '#':
|
||||||
Flush();
|
Flush();
|
||||||
while(true)
|
while (true) {
|
||||||
{
|
|
||||||
int r = Read();
|
int r = Read();
|
||||||
lineInfo.Add(r);
|
lineInfo.Add(r);
|
||||||
if(r == '\n' || r == -1) break;
|
if (r == '\n' || r == -1)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
if(peek == '/')
|
if (peek == '/') {
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
while(true)
|
while (true) {
|
||||||
{
|
|
||||||
int r = Read();
|
int r = Read();
|
||||||
lineInfo.Add(r);
|
lineInfo.Add(r);
|
||||||
if(r == '\n' || r == -1) break;
|
if (r == '\n' || r == -1)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else if (peek == '*') {
|
||||||
else if(peek == '*')
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
while(true)
|
while (true) {
|
||||||
{
|
|
||||||
int r = Read();
|
int r = Read();
|
||||||
lineInfo.Add(r);
|
lineInfo.Add(r);
|
||||||
if(r == -1)
|
if (r == -1) {
|
||||||
{
|
|
||||||
return lineInfo.line;
|
return lineInfo.line;
|
||||||
}
|
}
|
||||||
if(r == '*')
|
if (r == '*') {
|
||||||
{
|
|
||||||
r = Read();
|
r = Read();
|
||||||
lineInfo.Add(r);
|
lineInfo.Add(r);
|
||||||
if(r == -1)
|
if (r == -1)
|
||||||
return lineInfo.line;
|
return lineInfo.line;
|
||||||
if(r == '/')
|
if (r == '/')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (peek == '^') {
|
||||||
else if(peek == '^')
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
std::string str={};
|
std::string str = {};
|
||||||
while(true)
|
while (true) {
|
||||||
{
|
|
||||||
int r = Read();
|
int r = Read();
|
||||||
lineInfo.Add(r);
|
lineInfo.Add(r);
|
||||||
if(r == -1)
|
if (r == -1) {
|
||||||
{
|
|
||||||
return lineInfo.line;
|
return lineInfo.line;
|
||||||
}
|
}
|
||||||
if(r == '^')
|
if (r == '^') {
|
||||||
{
|
|
||||||
r = Read();
|
r = Read();
|
||||||
lineInfo.Add(r);
|
lineInfo.Add(r);
|
||||||
if(r == -1)
|
if (r == -1)
|
||||||
return lineInfo.line;
|
return lineInfo.line;
|
||||||
if(r == '^')
|
if (r == '^') {
|
||||||
{
|
|
||||||
str.push_back('^');
|
str.push_back('^');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(r == '/')
|
if (r == '/')
|
||||||
break;
|
break;
|
||||||
str.push_back('^');
|
str.push_back('^');
|
||||||
}
|
}
|
||||||
@@ -564,44 +472,32 @@ namespace Tesses::CrossLang
|
|||||||
token.lineInfo = lineInfo;
|
token.lineInfo = lineInfo;
|
||||||
token.text = str;
|
token.text = str;
|
||||||
tokens.push_back(token);
|
tokens.push_back(token);
|
||||||
}
|
} else if (peek == '=') {
|
||||||
else if(peek == '=')
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
Symbol({read,peek});
|
Symbol({read, peek});
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
Symbol({read});
|
Symbol({read});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
case '?':
|
case '?':
|
||||||
if(peek == read)
|
if (peek == read) {
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
int peek2=Peek();
|
int peek2 = Peek();
|
||||||
if(peek2 == '=')
|
if (peek2 == '=') {
|
||||||
{
|
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
Symbol({read,peek,peek2});
|
Symbol({read, peek, peek2});
|
||||||
|
} else {
|
||||||
|
Symbol({read, peek});
|
||||||
}
|
}
|
||||||
else
|
} else if (peek == '=') {
|
||||||
{
|
|
||||||
Symbol({read,peek});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(peek == '=')
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
Symbol({read,peek});
|
Symbol({read, peek});
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
Symbol({read});
|
Symbol({read});
|
||||||
}
|
}
|
||||||
@@ -610,33 +506,25 @@ namespace Tesses::CrossLang
|
|||||||
case '-':
|
case '-':
|
||||||
case '|':
|
case '|':
|
||||||
case '&':
|
case '&':
|
||||||
if(peek == '=' || peek == read)
|
if (peek == '=' || peek == read) {
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
Symbol({read,peek});
|
Symbol({read, peek});
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
Symbol({read});
|
Symbol({read});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
if(peek == '>')
|
if (peek == '>') {
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
Symbol({read,peek});
|
Symbol({read, peek});
|
||||||
}
|
} else if (peek == '=') {
|
||||||
else if(peek == '=')
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
Symbol({read,peek});
|
Symbol({read, peek});
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
Symbol({read});
|
Symbol({read});
|
||||||
}
|
}
|
||||||
@@ -649,14 +537,11 @@ namespace Tesses::CrossLang
|
|||||||
case '%':
|
case '%':
|
||||||
//*
|
//*
|
||||||
//*=
|
//*=
|
||||||
if(peek == '=')
|
if (peek == '=') {
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
lineInfo.Add(Read());
|
lineInfo.Add(Read());
|
||||||
Symbol({read,peek});
|
Symbol({read, peek});
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Flush();
|
Flush();
|
||||||
Symbol({read});
|
Symbol({read});
|
||||||
}
|
}
|
||||||
@@ -691,5 +576,5 @@ namespace Tesses::CrossLang
|
|||||||
}
|
}
|
||||||
Flush();
|
Flush();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,93 +0,0 @@
|
|||||||
#include "CrossLang.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
using namespace Tesses::CrossLang;
|
|
||||||
using namespace Tesses::Framework::Filesystem;
|
|
||||||
using namespace Tesses::Framework::Streams;
|
|
||||||
void Help(const char* filename)
|
|
||||||
{
|
|
||||||
printf("USAGE: %s [OPTIONS] <dirasroot> <archive.crvm>\n", filename);
|
|
||||||
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(" -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");
|
|
||||||
printf("Options except for help have flag with arg like this: -F ARG\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
int main(int argc, char** 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 < argc; i++)
|
|
||||||
{
|
|
||||||
if(strcmp(argv[i],"--help") == 0 || strcmp(argv[i],"-h")==0)
|
|
||||||
{
|
|
||||||
Help(argv[0]);
|
|
||||||
}
|
|
||||||
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], "-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 {
|
|
||||||
args.push_back(argv[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(args.size() < 2) Help(argv[0]);
|
|
||||||
|
|
||||||
|
|
||||||
auto path = Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(args[0]);
|
|
||||||
Tesses::Framework::Filesystem::LocalFS->CreateDirectory(path);
|
|
||||||
auto sdfs = std::make_shared<SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,path);
|
|
||||||
|
|
||||||
FILE* f = fopen(args[1].c_str(),"wb");
|
|
||||||
if(f == NULL)
|
|
||||||
{
|
|
||||||
printf("ERROR: could not open %s\n", args[1].c_str());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto strm = std::make_shared<FileStream>(f,true,"wb",true);
|
|
||||||
CrossArchiveCreate(sdfs,strm,name,version,info,icon);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#include "CrossLang.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
using namespace Tesses::CrossLang;
|
|
||||||
using namespace Tesses::Framework::Filesystem;
|
|
||||||
using namespace Tesses::Framework::Streams;
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
Tesses::Framework::TF_Init();
|
|
||||||
if(argc < 3)
|
|
||||||
{
|
|
||||||
printf("USAGE: %s <archive.crvm> <dirasroot>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto sdfs= std::make_shared<SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,std::string(argv[2]));
|
|
||||||
|
|
||||||
FILE* f = fopen(argv[1],"rb");
|
|
||||||
if(f == NULL)
|
|
||||||
{
|
|
||||||
printf("ERROR: could not open %s\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto strm = std::make_shared<FileStream>(f,true,"rb",true);
|
|
||||||
|
|
||||||
auto res = CrossArchiveExtract(strm,sdfs);
|
|
||||||
|
|
||||||
std::cout << "Crvm Name: " << res.first.first << std::endl;
|
|
||||||
std::cout << "Crvm Version: " << res.first.second.ToString() << std::endl;
|
|
||||||
std::cout << "Crvm Info: " << std::endl << res.second << std::endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -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,141 +0,0 @@
|
|||||||
#include "CrossLang.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
using namespace Tesses::Framework;
|
|
||||||
using namespace Tesses::CrossLang;
|
|
||||||
using namespace Tesses::Framework::Http;
|
|
||||||
|
|
||||||
bool Download(Tesses::Framework::Filesystem::VFSPath filename,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs)
|
|
||||||
{
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
std::cout << "File " << filename.ToString() << " not found, do you want to download the installer from: https://downloads.tesses.net/ShellPackage.crvm (this may install other stuff as well) (Y/n)? ";
|
|
||||||
std::string line;
|
|
||||||
std::getline(std::cin,line);
|
|
||||||
if(line == "Y" || line == "y")
|
|
||||||
{
|
|
||||||
HttpRequest req;
|
|
||||||
req.url = "https://downloads.tesses.net/ShellPackage.crvm";
|
|
||||||
req.method = "GET";
|
|
||||||
HttpResponse resp(req);
|
|
||||||
if(resp.statusCode == StatusCode::OK)
|
|
||||||
{
|
|
||||||
auto strm = resp.ReadAsStream();
|
|
||||||
CrossArchiveExtract(strm, vfs);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(line == "N" || line == "n")
|
|
||||||
{
|
|
||||||
std::cout << "Looks like you will need to install manually" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Please use Y or N (case insensitive)" << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
TF_InitWithConsole();
|
|
||||||
if(argc > 0)
|
|
||||||
TF_AllowPortable(argv[0]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Tesses::Framework::Filesystem::VFSPath dir = GetCrossLangConfigDir();
|
|
||||||
|
|
||||||
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(argc == 2 && strcmp(argv[1],"configdir") == 0)
|
|
||||||
{
|
|
||||||
std::cout << dir.ToString() << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(argc > 1 && strcmp(argv[1],"update-shell") == 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
auto subdir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,dir);
|
|
||||||
HttpRequest req;
|
|
||||||
req.url = "https://downloads.tesses.net/ShellPackage.crvm";
|
|
||||||
req.method = "GET";
|
|
||||||
HttpResponse resp(req);
|
|
||||||
if(resp.statusCode == StatusCode::OK)
|
|
||||||
{
|
|
||||||
auto strm = resp.ReadAsStream();
|
|
||||||
CrossArchiveExtract(strm, subdir);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
CrossArchiveExtract(strm, subdir);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!Download(filename,subdir)) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GC gc;
|
|
||||||
gc.Start();
|
|
||||||
|
|
||||||
GCList ls(gc);
|
|
||||||
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
|
||||||
|
|
||||||
|
|
||||||
TStd::RegisterStd(&gc,env);
|
|
||||||
|
|
||||||
|
|
||||||
env->LoadFileWithDependencies(&gc, Tesses::Framework::Filesystem::LocalFS, filename);
|
|
||||||
|
|
||||||
|
|
||||||
TList* args = TList::Create(ls);
|
|
||||||
|
|
||||||
args->Add(filename.ToString());
|
|
||||||
|
|
||||||
for(int arg=1;arg<argc;arg++)
|
|
||||||
args->Add(std::string(argv[arg]));
|
|
||||||
|
|
||||||
auto res = env->CallFunctionWithFatalError(ls,"main",{args});
|
|
||||||
int64_t iresult;
|
|
||||||
if(GetObject(res,iresult))
|
|
||||||
return (int)iresult;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,290 +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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GC* gc=nullptr;
|
|
||||||
GCList* ls=nullptr;
|
|
||||||
TRootEnvironment* env=nullptr;
|
|
||||||
if(comptime != "none")
|
|
||||||
{
|
|
||||||
gc = new GC();
|
|
||||||
gc->Start();
|
|
||||||
ls = new 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);
|
|
||||||
}
|
|
||||||
if(gc != nullptr)
|
|
||||||
{
|
|
||||||
delete ls;
|
|
||||||
delete gc;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,273 +0,0 @@
|
|||||||
#include "CrossLang.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
using namespace Tesses::CrossLang;
|
|
||||||
void Ensure(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).");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint32_t EnsureInt(Tesses::Framework::Streams::Stream& strm)
|
|
||||||
{
|
|
||||||
uint8_t buff[4];
|
|
||||||
Ensure(strm,buff,sizeof(buff));
|
|
||||||
return BitConverter::ToUint32BE(buff[0]);
|
|
||||||
}
|
|
||||||
std::string EnsureString(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 DumpFile(std::filesystem::path p)
|
|
||||||
{
|
|
||||||
if(std::filesystem::is_regular_file(p))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::cout << "File: " << p.string() << std::endl;
|
|
||||||
Tesses::Framework::Streams::FileStream strm(p,"rb");
|
|
||||||
uint8_t main_header[18];
|
|
||||||
Ensure(strm,main_header,sizeof(main_header));
|
|
||||||
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image.");
|
|
||||||
TVMVersion version(main_header+8);
|
|
||||||
if(version.CompareToRuntime() == 1)
|
|
||||||
{
|
|
||||||
throw VMException("Runtime is too old.");
|
|
||||||
}
|
|
||||||
TVMVersion v2(main_header+13);
|
|
||||||
std::cout << "Version: " << v2.ToString() << std::endl;
|
|
||||||
|
|
||||||
size_t _len = (size_t)EnsureInt(strm);
|
|
||||||
|
|
||||||
std::cout << "SectionCount: " << _len << std::endl;
|
|
||||||
|
|
||||||
std::vector<std::string> strs;
|
|
||||||
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
Ensure(strm,(uint8_t*)table_name,sizeof(table_name));
|
|
||||||
size_t tableLen = (size_t)EnsureInt(strm);
|
|
||||||
std::string tableName(table_name,4);
|
|
||||||
if(tableName == "ICON")
|
|
||||||
{
|
|
||||||
hasIcon=true;
|
|
||||||
}
|
|
||||||
else if(tableName == "STRS")
|
|
||||||
{
|
|
||||||
size_t strsLen = (size_t)EnsureInt(strm);
|
|
||||||
for(size_t j = 0;j < strsLen;j++)
|
|
||||||
{
|
|
||||||
strs.push_back(EnsureString(strm));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(tableName == "DEPS")
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string name = strs.at((size_t)EnsureInt(strm));
|
|
||||||
|
|
||||||
uint8_t version_bytes[5];
|
|
||||||
Ensure(strm,version_bytes,sizeof(version_bytes));
|
|
||||||
TVMVersion depVersion(version_bytes);
|
|
||||||
std::cout << "Dependency: " << name << "-" << depVersion.ToString() << std::endl;
|
|
||||||
}
|
|
||||||
else if(tableName == "NAME")
|
|
||||||
{
|
|
||||||
std::cout << "Name: " << strs.at((size_t)EnsureInt(strm)) << std::endl;
|
|
||||||
}
|
|
||||||
else if(tableName == "CLSS")
|
|
||||||
{
|
|
||||||
std::cout << "Classes:\n";
|
|
||||||
uint32_t clss_cnt= EnsureInt(strm);
|
|
||||||
for(uint32_t j = 0; j < clss_cnt; j++)
|
|
||||||
{
|
|
||||||
std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl;
|
|
||||||
uint32_t fnPartsC = EnsureInt(strm);
|
|
||||||
std::cout << "\tName: ";
|
|
||||||
for(uint32_t k = 0; k < fnPartsC; k++)
|
|
||||||
{
|
|
||||||
if(k > 0) std::cout << ".";
|
|
||||||
std::cout << strs.at(EnsureInt(strm));
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
fnPartsC = EnsureInt(strm);
|
|
||||||
std::cout << "\tInherits: ";
|
|
||||||
for(uint32_t k = 0; k < fnPartsC; k++)
|
|
||||||
{
|
|
||||||
if(k > 0) std::cout << ".";
|
|
||||||
std::cout << strs.at(EnsureInt(strm));
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
uint32_t ents = EnsureInt(strm);
|
|
||||||
|
|
||||||
for(uint8_t k = 0; k < ents; k++)
|
|
||||||
{
|
|
||||||
Ensure(strm,main_header,1);
|
|
||||||
uint8_t flags = main_header[0];
|
|
||||||
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl;
|
|
||||||
std::string fnname = strs.at(EnsureInt(strm));
|
|
||||||
std::string fnargs;
|
|
||||||
uint32_t argParts = EnsureInt(strm);
|
|
||||||
|
|
||||||
for(uint32_t l = 0; l < argParts; l++)
|
|
||||||
{
|
|
||||||
if(l > 0) fnargs += ", ";
|
|
||||||
fnargs += strs.at(EnsureInt(strm));
|
|
||||||
}
|
|
||||||
uint32_t fnchunk = EnsureInt(strm);
|
|
||||||
switch(flags & 3)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
std::cout << "\t\tprivate ";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
std::cout << "\t\tprotected ";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
std::cout << "\t\tpublic ";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
std::cout << "\t\tstatic ";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch((flags >> 2) & 3)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
std::cout << "func " << fnname << "(" << fnargs << "), chunk = " << fnchunk << std::endl;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
std::cout << "field " << fnname << ", chunk = " << fnchunk << std::endl;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
std::cout << "abstract " << fnname << "(" << fnargs << ")" << std::endl;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
std::cout << "unset_field " << fnname << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(tableName == "CHKS")
|
|
||||||
{
|
|
||||||
size_t chunkCount = (size_t)EnsureInt(strm);
|
|
||||||
|
|
||||||
for(size_t j = 0; j < chunkCount; j++)
|
|
||||||
{
|
|
||||||
std::vector<std::string> args;
|
|
||||||
size_t argCount = (size_t)EnsureInt(strm);
|
|
||||||
for(size_t k = 0; k < argCount; k++)
|
|
||||||
{
|
|
||||||
args.push_back(strs.at(EnsureInt(strm)));
|
|
||||||
}
|
|
||||||
auto len = EnsureInt(strm);
|
|
||||||
|
|
||||||
strm.Seek(len,Tesses::Framework::Streams::SeekOrigin::Current);
|
|
||||||
|
|
||||||
closures.push_back(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(tableName == "FUNS")
|
|
||||||
{
|
|
||||||
size_t funLength = (size_t)EnsureInt(strm);
|
|
||||||
|
|
||||||
for(size_t j = 0; j < funLength;j++)
|
|
||||||
{
|
|
||||||
std::vector<std::string> fnParts;
|
|
||||||
uint32_t fnPartsC = EnsureInt(strm);
|
|
||||||
for(uint32_t k = 0; k < fnPartsC; k++)
|
|
||||||
{
|
|
||||||
fnParts.push_back(strs.at(EnsureInt(strm)));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fnNumber = EnsureInt(strm);
|
|
||||||
funs[fnNumber] = fnParts;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(tableName == "INFO")
|
|
||||||
{
|
|
||||||
|
|
||||||
std::cout << "Info: " << strs.at((size_t)EnsureInt(strm)) << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strm.Seek((int64_t)tableLen,Tesses::Framework::Streams::SeekOrigin::Current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(hasIcon)
|
|
||||||
std::cout << "Has Icon: yes" << std::endl;
|
|
||||||
else
|
|
||||||
std::cout << "Has Icon: no" << std::endl;
|
|
||||||
|
|
||||||
for(size_t i = 1; i < closures.size(); i++)
|
|
||||||
{
|
|
||||||
if(funs.count((uint32_t)i) > 0)
|
|
||||||
{
|
|
||||||
std::cout << "Func: ";
|
|
||||||
auto res = funs[(uint32_t)i];
|
|
||||||
if(!res.empty()) {
|
|
||||||
std::cout << "/^" << res[0] << "^/ ";
|
|
||||||
}
|
|
||||||
for(size_t i = 1; i < res.size(); i++)
|
|
||||||
{
|
|
||||||
if(i > 1) std::cout << ".";
|
|
||||||
std::cout << res[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Closure: ";
|
|
||||||
}
|
|
||||||
std::cout << "(";
|
|
||||||
bool first=true;
|
|
||||||
for(auto arg : closures[i])
|
|
||||||
{
|
|
||||||
if(!first) std::cout << ", ";
|
|
||||||
std::cout << arg;
|
|
||||||
|
|
||||||
if(first) first=false;
|
|
||||||
}
|
|
||||||
std::cout << ")" << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << "String Table:" << std::endl;
|
|
||||||
|
|
||||||
for(auto str : strs) {
|
|
||||||
std::cout << EscapeString(str, true) << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(std::exception& ex)
|
|
||||||
{
|
|
||||||
std::cout << "Error when reading file \"" << p.string() << "\" " << ex.what() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "CrossVM file \"" << p.string() << "\" does not exist." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
Tesses::Framework::TF_Init();
|
|
||||||
for(int i = 1; i < argc; i++)
|
|
||||||
{
|
|
||||||
DumpFile(argv[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,129 +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]);
|
|
||||||
GC gc;
|
|
||||||
gc.Start();
|
|
||||||
GCList ls(gc);
|
|
||||||
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
|
||||||
TStd::RegisterStd(&gc,env);
|
|
||||||
|
|
||||||
if(argc > 1)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
|
|
||||||
gen.embedFS = sfs;
|
|
||||||
gen.GenRoot(parser.ParseRoot());
|
|
||||||
std::vector<uint8_t> data;
|
|
||||||
{
|
|
||||||
auto strm2 = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
|
||||||
gen.Save(strm2);
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
TFile* file = TFile::Create(ls);
|
|
||||||
|
|
||||||
strm2->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
|
|
||||||
file->Load(&gc,strm2);
|
|
||||||
|
|
||||||
env->LoadFile(&gc, file);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TList* args = TList::Create(ls);
|
|
||||||
for(int arg=1;arg<argc;arg++)
|
|
||||||
args->Add(std::string(argv[arg]));
|
|
||||||
|
|
||||||
auto res = env->CallFunctionWithFatalError(ls,"main",{args});
|
|
||||||
int64_t iresult;
|
|
||||||
if(GetObject(res,iresult))
|
|
||||||
return (int)iresult;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
std::cout << "> ";
|
|
||||||
std::string source;
|
|
||||||
std::getline(std::cin,source);
|
|
||||||
|
|
||||||
auto strm2 = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
|
||||||
|
|
||||||
if(source.find("loadfile ") == 0)
|
|
||||||
{
|
|
||||||
std::string filename = source.substr(9);
|
|
||||||
|
|
||||||
std::ifstream strm(filename,std::ios_base::in|std::ios_base::binary);
|
|
||||||
std::vector<LexToken> tokens;
|
|
||||||
Lex(filename,strm,tokens);
|
|
||||||
|
|
||||||
Parser parser(tokens);
|
|
||||||
|
|
||||||
CodeGen gen;
|
|
||||||
|
|
||||||
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
|
|
||||||
gen.embedFS = sfs;
|
|
||||||
gen.GenRoot(parser.ParseRoot());
|
|
||||||
|
|
||||||
gen.Save(strm2);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(source == "exit")
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::vector<LexToken> tokens;
|
|
||||||
std::stringstream strm(source,std::ios_base::in | std::ios_base::binary);
|
|
||||||
Lex("lexed.tcross",strm,tokens);
|
|
||||||
|
|
||||||
Parser parser(tokens);
|
|
||||||
|
|
||||||
CodeGen gen;
|
|
||||||
|
|
||||||
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
|
|
||||||
gen.embedFS = sfs;
|
|
||||||
|
|
||||||
gen.GenRoot(parser.ParseRoot());
|
|
||||||
|
|
||||||
gen.Save(strm2);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
TFile* file = TFile::Create(ls);
|
|
||||||
|
|
||||||
strm2->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
|
|
||||||
file->Load(&gc,strm2);
|
|
||||||
|
|
||||||
env->LoadFile(&gc, file);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#include "CrossLang.hpp"
|
|
||||||
using namespace Tesses::Framework;
|
|
||||||
using namespace Tesses::CrossLang;
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
TF_InitWithConsole();
|
|
||||||
|
|
||||||
if(argc < 2)
|
|
||||||
{
|
|
||||||
printf("USAGE: %s <filename.crvm> <args...>\n",argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if(argc > 0)
|
|
||||||
TF_AllowPortable(argv[0]);
|
|
||||||
|
|
||||||
GC gc;
|
|
||||||
gc.Start();
|
|
||||||
GCList ls(gc);
|
|
||||||
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
|
||||||
|
|
||||||
TStd::RegisterStd(&gc,env);
|
|
||||||
env->LoadFileWithDependencies(&gc, Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1]));
|
|
||||||
|
|
||||||
if(env->HasVariable("WebAppMain"))
|
|
||||||
{
|
|
||||||
Args args(argc, argv);
|
|
||||||
int port = 4206;
|
|
||||||
for(auto& item : args.options)
|
|
||||||
{
|
|
||||||
if(item.first == "port")
|
|
||||||
{
|
|
||||||
port = std::stoi(item.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
env->EnsureDictionary(&gc,"Net")->SetValue("WebServerPort", (int64_t)port);
|
|
||||||
TList* args2 = TList::Create(ls);
|
|
||||||
for(auto& item : args.positional)
|
|
||||||
{
|
|
||||||
args2->Add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2});
|
|
||||||
auto svr2 = Tesses::CrossLang::ToHttpServer(&gc,res);
|
|
||||||
if(svr2 == nullptr) return 1;
|
|
||||||
Tesses::Framework::Http::HttpServer svr(port,svr2);
|
|
||||||
svr.StartAccepting();
|
|
||||||
TF_RunEventLoop();
|
|
||||||
TDictionary* _dict;
|
|
||||||
TClassObject* _co;
|
|
||||||
if(GetObjectHeap(res,_dict))
|
|
||||||
{
|
|
||||||
_dict->CallMethod(ls,"Close",{});
|
|
||||||
}
|
|
||||||
if(GetObjectHeap(res,_co))
|
|
||||||
{
|
|
||||||
_co->CallMethod(ls,"","Close",{});
|
|
||||||
}
|
|
||||||
TF_Quit();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
TList* args = TList::Create(ls);
|
|
||||||
for(int arg=1;arg<argc;arg++)
|
|
||||||
args->Add(std::string(argv[arg]));
|
|
||||||
|
|
||||||
auto res = env->CallFunctionWithFatalError(ls,"main",{args});
|
|
||||||
int64_t iresult;
|
|
||||||
if(GetObject(res,iresult))
|
|
||||||
return (int)iresult;
|
|
||||||
}
|
|
||||||
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/LocalFS.hpp>
|
||||||
#include <TessesFramework/Filesystem/VFS.hpp>
|
#include <TessesFramework/Filesystem/VFS.hpp>
|
||||||
#include <TessesFramework/Streams/Stream.hpp>
|
#include <TessesFramework/Streams/Stream.hpp>
|
||||||
|
#include <fstream>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
int main(int argc, char **argv) {
|
||||||
int main(int argc,char** argv)
|
|
||||||
{
|
|
||||||
Tesses::Framework::TF_Init();
|
Tesses::Framework::TF_Init();
|
||||||
std::string p = argv[0];
|
std::string p = argv[0];
|
||||||
auto emptyThumb =Tesses::Framework::Platform::Environment::GetRealExecutablePath(p).GetParent().GetParent() / "share" / "icons" / "crosslang.png";
|
auto emptyThumb =
|
||||||
|
Tesses::Framework::Platform::Environment::GetRealExecutablePath(p)
|
||||||
|
.GetParent()
|
||||||
|
.GetParent() /
|
||||||
|
"share" / "icons" / "crosslang.png";
|
||||||
|
|
||||||
if(argc < 3)
|
if (argc < 3) {
|
||||||
{
|
|
||||||
std::cout << "USAGE: " << argv[0] << " CRVMFILE NEWPNG" << std::endl;
|
std::cout << "USAGE: " << argv[0] << " CRVMFILE NEWPNG" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
std::string crvm = argv[1];
|
std::string crvm = argv[1];
|
||||||
std::string png = argv[2];
|
std::string png = argv[2];
|
||||||
|
|
||||||
|
if (Tesses::Framework::Filesystem::LocalFS->FileExists(crvm)) {
|
||||||
if(Tesses::Framework::Filesystem::LocalFS->FileExists(crvm))
|
|
||||||
{
|
|
||||||
|
|
||||||
Tesses::CrossLang::TFile file;
|
Tesses::CrossLang::TFile file;
|
||||||
auto f = Tesses::Framework::Filesystem::LocalFS->OpenFile(crvm, "rb");
|
auto f = Tesses::Framework::Filesystem::LocalFS->OpenFile(crvm, "rb");
|
||||||
|
|
||||||
file.Load(nullptr,f);
|
file.Load(nullptr, f);
|
||||||
|
|
||||||
|
|
||||||
if(file.icon >= 0 && file.icon < file.resources.size())
|
|
||||||
{
|
|
||||||
auto f2 = Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
|
|
||||||
if(f2 != nullptr)
|
|
||||||
{
|
|
||||||
auto& icon = file.resources[file.icon];
|
|
||||||
f2->WriteBlock(icon.data(),icon.size());
|
|
||||||
|
|
||||||
|
if (file.icon >= 0 && file.icon < file.resources.size()) {
|
||||||
|
auto f2 =
|
||||||
|
Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
|
||||||
|
if (f2 != nullptr) {
|
||||||
|
auto &icon = file.resources[file.icon];
|
||||||
|
f2->WriteBlock(icon.data(), icon.size());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if(Tesses::Framework::Filesystem::LocalFS->FileExists(emptyThumb))
|
if (Tesses::Framework::Filesystem::LocalFS->FileExists(emptyThumb)) {
|
||||||
{
|
auto src =
|
||||||
auto src = Tesses::Framework::Filesystem::LocalFS->OpenFile(emptyThumb,"rb");
|
Tesses::Framework::Filesystem::LocalFS->OpenFile(emptyThumb, "rb");
|
||||||
auto dest = Tesses::Framework::Filesystem::LocalFS->OpenFile(png,"wb");
|
auto dest = Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb");
|
||||||
if(src != nullptr && dest != nullptr)
|
if (src != nullptr && dest != nullptr) {
|
||||||
{
|
|
||||||
src->CopyTo(dest);
|
src->CopyTo(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1,40 +1,25 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
SharedPtrTObject::SharedPtrTObject(std::shared_ptr<GC> gc, TObject o) {
|
||||||
SharedPtrTObject::SharedPtrTObject(GC* gc, TObject o)
|
|
||||||
{
|
|
||||||
this->ls = new GCList(gc);
|
this->ls = new GCList(gc);
|
||||||
this->ls->Add(o);
|
this->ls->Add(o);
|
||||||
this->o = o;
|
this->o = o;
|
||||||
}
|
|
||||||
TObject& SharedPtrTObject::GetObject()
|
|
||||||
{
|
|
||||||
return this->o;
|
|
||||||
}
|
|
||||||
SharedPtrTObject::~SharedPtrTObject()
|
|
||||||
{
|
|
||||||
if(this->ls)
|
|
||||||
delete this->ls;
|
|
||||||
}
|
|
||||||
GC* SharedPtrTObject::GetGC()
|
|
||||||
{
|
|
||||||
return this->ls->GetGC();
|
|
||||||
}
|
|
||||||
MarkedTObject CreateMarkedTObject(GC* gc, TObject o)
|
|
||||||
{
|
|
||||||
return std::make_shared<SharedPtrTObject>(gc,o);
|
|
||||||
}
|
|
||||||
MarkedTObject CreateMarkedTObject(GC& gc, TObject o)
|
|
||||||
{
|
|
||||||
return CreateMarkedTObject(&gc,o);
|
|
||||||
}
|
|
||||||
MarkedTObject CreateMarkedTObject(GCList* gc, TObject o)
|
|
||||||
{
|
|
||||||
return CreateMarkedTObject(gc->GetGC(),o);
|
|
||||||
}
|
|
||||||
MarkedTObject CreateMarkedTObject(GCList& gc, TObject o)
|
|
||||||
{
|
|
||||||
return CreateMarkedTObject(gc.GetGC(),o);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TObject &SharedPtrTObject::GetObject() { return this->o; }
|
||||||
|
SharedPtrTObject::~SharedPtrTObject() {
|
||||||
|
if (this->ls)
|
||||||
|
delete this->ls;
|
||||||
|
}
|
||||||
|
std::shared_ptr<GC> SharedPtrTObject::GetGC() { return this->ls->GetGC(); }
|
||||||
|
MarkedTObject CreateMarkedTObject(std::shared_ptr<GC> gc, TObject o) {
|
||||||
|
return std::make_shared<SharedPtrTObject>(gc, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
MarkedTObject CreateMarkedTObject(GCList *gc, TObject o) {
|
||||||
|
return CreateMarkedTObject(gc->GetGC(), o);
|
||||||
|
}
|
||||||
|
MarkedTObject CreateMarkedTObject(GCList &gc, TObject o) {
|
||||||
|
return CreateMarkedTObject(gc.GetGC(), o);
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
84
src/program_lib/crossarchivecreate.cpp
Normal file
84
src/program_lib/crossarchivecreate.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
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;
|
||||||
|
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(" -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");
|
||||||
|
printf("Options except for help have flag with arg like this: -F ARG\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
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") {
|
||||||
|
Help(argv[0]);
|
||||||
|
} else if (argv[i] == "-i") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
info = argv[i];
|
||||||
|
}
|
||||||
|
} else if (argv[i] == "-I") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
icon = argv[i];
|
||||||
|
}
|
||||||
|
} else if (argv[i] == "-n") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
name = argv[i];
|
||||||
|
}
|
||||||
|
} else if (argv[i] == "-v") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
|
||||||
|
if (!TVMVersion::TryParse(argv[i], version)) {
|
||||||
|
printf("ERROR: Invalid syntax for version\n");
|
||||||
|
printf("Expected "
|
||||||
|
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
|
||||||
|
"]]]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.push_back(argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.size() < 2)
|
||||||
|
Help(argv[0]);
|
||||||
|
|
||||||
|
auto path =
|
||||||
|
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(args[0]);
|
||||||
|
Tesses::Framework::Filesystem::LocalFS->CreateDirectory(path);
|
||||||
|
auto sdfs = std::make_shared<SubdirFilesystem>(
|
||||||
|
Tesses::Framework::Filesystem::LocalFS, path);
|
||||||
|
|
||||||
|
FILE *f = fopen(args[1].c_str(), "wb");
|
||||||
|
if (f == NULL) {
|
||||||
|
printf("ERROR: could not open %s\n", args[1].c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto strm = std::make_shared<FileStream>(f, true, "wb", true);
|
||||||
|
CrossArchiveCreate(sdfs, strm, name, version, info, icon);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang::Programs
|
||||||
32
src/program_lib/crossarchiveextract.cpp
Normal file
32
src/program_lib/crossarchiveextract.cpp
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang::Programs {
|
||||||
|
using namespace Tesses::Framework::Filesystem;
|
||||||
|
using namespace Tesses::Framework::Streams;
|
||||||
|
|
||||||
|
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;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto sdfs = std::make_shared<SubdirFilesystem>(
|
||||||
|
Tesses::Framework::Filesystem::LocalFS, std::string(argv[2]));
|
||||||
|
auto strm = LocalFS->OpenFile(argv[1], "rb");
|
||||||
|
if (!strm->CanRead()) {
|
||||||
|
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;
|
||||||
|
std::cout << "Crvm Version: " << res.first.second.ToString() << std::endl;
|
||||||
|
std::cout << "Crvm Info: " << std::endl << res.second << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang::Programs
|
||||||
227
src/program_lib/crossdump.cpp
Normal file
227
src/program_lib/crossdump.cpp
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
#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 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) {
|
||||||
|
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) {
|
||||||
|
uint8_t main_header[18];
|
||||||
|
Ensure(strm, main_header, sizeof(main_header));
|
||||||
|
if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
|
||||||
|
throw VMException("Invalid TCrossVM image.");
|
||||||
|
TVMVersion version(main_header + 8);
|
||||||
|
if (version.CompareToRuntime() == 1) {
|
||||||
|
throw VMException("Runtime is too old.");
|
||||||
|
}
|
||||||
|
TVMVersion v2(main_header + 13);
|
||||||
|
std::cout << "Version: " << v2.ToString() << std::endl;
|
||||||
|
|
||||||
|
size_t _len = (size_t)EnsureInt(strm);
|
||||||
|
|
||||||
|
std::cout << "SectionCount: " << _len << std::endl;
|
||||||
|
|
||||||
|
std::vector<std::string> strs;
|
||||||
|
|
||||||
|
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++) {
|
||||||
|
Ensure(strm, (uint8_t *)table_name, sizeof(table_name));
|
||||||
|
size_t tableLen = (size_t)EnsureInt(strm);
|
||||||
|
std::string tableName(table_name, 4);
|
||||||
|
if (tableName == "ICON") {
|
||||||
|
hasIcon = true;
|
||||||
|
} else if (tableName == "STRS") {
|
||||||
|
size_t strsLen = (size_t)EnsureInt(strm);
|
||||||
|
for (size_t j = 0; j < strsLen; j++) {
|
||||||
|
strs.push_back(EnsureString(strm));
|
||||||
|
}
|
||||||
|
} else if (tableName == "DEPS") {
|
||||||
|
|
||||||
|
std::string name = strs.at((size_t)EnsureInt(strm));
|
||||||
|
|
||||||
|
uint8_t version_bytes[5];
|
||||||
|
Ensure(strm, version_bytes, sizeof(version_bytes));
|
||||||
|
TVMVersion depVersion(version_bytes);
|
||||||
|
std::cout << "Dependency: " << name << "-" << depVersion.ToString()
|
||||||
|
<< std::endl;
|
||||||
|
} else if (tableName == "NAME") {
|
||||||
|
std::cout << "Name: " << strs.at((size_t)EnsureInt(strm))
|
||||||
|
<< std::endl;
|
||||||
|
} else if (tableName == "CLSS") {
|
||||||
|
std::cout << "Classes:\n";
|
||||||
|
uint32_t clss_cnt = EnsureInt(strm);
|
||||||
|
for (uint32_t j = 0; j < clss_cnt; j++) {
|
||||||
|
std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/"
|
||||||
|
<< std::endl;
|
||||||
|
uint32_t fnPartsC = EnsureInt(strm);
|
||||||
|
std::cout << "\tName: ";
|
||||||
|
for (uint32_t k = 0; k < fnPartsC; k++) {
|
||||||
|
if (k > 0)
|
||||||
|
std::cout << ".";
|
||||||
|
std::cout << strs.at(EnsureInt(strm));
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
fnPartsC = EnsureInt(strm);
|
||||||
|
std::cout << "\tInherits: ";
|
||||||
|
for (uint32_t k = 0; k < fnPartsC; k++) {
|
||||||
|
if (k > 0)
|
||||||
|
std::cout << ".";
|
||||||
|
std::cout << strs.at(EnsureInt(strm));
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
uint32_t ents = EnsureInt(strm);
|
||||||
|
|
||||||
|
for (uint32_t k = 0; k < ents; k++) {
|
||||||
|
Ensure(strm, main_header, 1);
|
||||||
|
uint8_t flags = main_header[0];
|
||||||
|
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/"
|
||||||
|
<< std::endl;
|
||||||
|
std::string fnname = strs.at(EnsureInt(strm));
|
||||||
|
std::string fnargs;
|
||||||
|
uint32_t argParts = EnsureInt(strm);
|
||||||
|
|
||||||
|
for (uint32_t l = 0; l < argParts; l++) {
|
||||||
|
if (l > 0)
|
||||||
|
fnargs += ", ";
|
||||||
|
fnargs += strs.at(EnsureInt(strm));
|
||||||
|
}
|
||||||
|
uint32_t fnchunk = EnsureInt(strm);
|
||||||
|
switch (flags & 3) {
|
||||||
|
case 0:
|
||||||
|
std::cout << "\t\tprivate ";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
std::cout << "\t\tprotected ";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
std::cout << "\t\tpublic ";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
std::cout << "\t\tstatic ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((flags >> 2) & 3) {
|
||||||
|
case 0:
|
||||||
|
std::cout << "func " << fnname << "(" << fnargs
|
||||||
|
<< "), chunk = " << fnchunk << std::endl;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
std::cout << "field " << fnname
|
||||||
|
<< ", chunk = " << fnchunk << std::endl;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
std::cout << "abstract " << fnname << "(" << fnargs
|
||||||
|
<< ")" << std::endl;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
std::cout << "unset_field " << fnname << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (tableName == "CHKS") {
|
||||||
|
size_t chunkCount = (size_t)EnsureInt(strm);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < chunkCount; j++) {
|
||||||
|
std::vector<std::string> args;
|
||||||
|
size_t argCount = (size_t)EnsureInt(strm);
|
||||||
|
for (size_t k = 0; k < argCount; k++) {
|
||||||
|
args.push_back(strs.at(EnsureInt(strm)));
|
||||||
|
}
|
||||||
|
auto len = EnsureInt(strm);
|
||||||
|
|
||||||
|
strm->Seek(len,
|
||||||
|
Tesses::Framework::Streams::SeekOrigin::Current);
|
||||||
|
|
||||||
|
closures.push_back(args);
|
||||||
|
}
|
||||||
|
} else if (tableName == "FUNS") {
|
||||||
|
size_t funLength = (size_t)EnsureInt(strm);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < funLength; j++) {
|
||||||
|
std::vector<std::string> fnParts;
|
||||||
|
uint32_t fnPartsC = EnsureInt(strm);
|
||||||
|
for (uint32_t k = 0; k < fnPartsC; k++) {
|
||||||
|
fnParts.push_back(strs.at(EnsureInt(strm)));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fnNumber = EnsureInt(strm);
|
||||||
|
funs[fnNumber] = fnParts;
|
||||||
|
}
|
||||||
|
} else if (tableName == "INFO") {
|
||||||
|
|
||||||
|
std::cout << "Info: " << strs.at((size_t)EnsureInt(strm))
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
strm->Seek((int64_t)tableLen,
|
||||||
|
Tesses::Framework::Streams::SeekOrigin::Current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasIcon)
|
||||||
|
std::cout << "Has Icon: yes" << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "Has Icon: no" << std::endl;
|
||||||
|
|
||||||
|
for (size_t i = 1; i < closures.size(); i++) {
|
||||||
|
if (funs.count((uint32_t)i) > 0) {
|
||||||
|
std::cout << "Func: ";
|
||||||
|
auto res = funs[(uint32_t)i];
|
||||||
|
if (!res.empty()) {
|
||||||
|
std::cout << "/^" << res[0] << "^/ ";
|
||||||
|
}
|
||||||
|
for (size_t i = 1; i < res.size(); i++) {
|
||||||
|
if (i > 1)
|
||||||
|
std::cout << ".";
|
||||||
|
std::cout << res[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cout << "Closure: ";
|
||||||
|
}
|
||||||
|
std::cout << "(";
|
||||||
|
bool first = true;
|
||||||
|
for (auto arg : closures[i]) {
|
||||||
|
if (!first)
|
||||||
|
std::cout << ", ";
|
||||||
|
std::cout << arg;
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
std::cout << ")" << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "String Table:" << std::endl;
|
||||||
|
|
||||||
|
for (auto str : strs) {
|
||||||
|
std::cout << EscapeString(str, true) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tesses::CrossLang::Programs
|
||||||
155
src/program_lib/crosslang.cpp
Normal file
155
src/program_lib/crosslang.cpp
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
#include "TessesFramework/Platform/Environment.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
using namespace Tesses::Framework;
|
||||||
|
using namespace Tesses::Framework::Http;
|
||||||
|
|
||||||
|
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")) {
|
||||||
|
HttpRequest req;
|
||||||
|
req.followRedirects = true;
|
||||||
|
req.url = "https://redirect.tesses.net/crosslang-shell";
|
||||||
|
req.method = "GET";
|
||||||
|
HttpResponse resp(req);
|
||||||
|
if (resp.statusCode == StatusCode::OK) {
|
||||||
|
auto strm = resp.ReadAsStream();
|
||||||
|
CrossLang::CrossArchiveExtract(strm, vfs);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
std::cout << "Error when fetching the script error: "
|
||||||
|
<< std::to_string(resp.statusCode) << " "
|
||||||
|
<< HttpUtils::StatusCodeString(resp.statusCode)
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
std::cout << "File " << filename.ToString()
|
||||||
|
<< " not found, do you want to download the installer from: "
|
||||||
|
"https://redirect.tesses.net/crosslang-shell (this may "
|
||||||
|
"install other stuff as well) (Y/n)? ";
|
||||||
|
std::string line;
|
||||||
|
std::getline(std::cin, line);
|
||||||
|
if (line == "Y" || line == "y") {
|
||||||
|
HttpRequest req;
|
||||||
|
req.followRedirects = true;
|
||||||
|
req.url = "https://redirect.tesses.net/crosslang-shell";
|
||||||
|
req.method = "GET";
|
||||||
|
HttpResponse resp(req);
|
||||||
|
if (resp.statusCode == StatusCode::OK) {
|
||||||
|
auto strm = resp.ReadAsStream();
|
||||||
|
CrossLang::CrossArchiveExtract(strm, vfs);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
std::cout << "Error when fetching the script error: "
|
||||||
|
<< std::to_string(resp.statusCode) << " "
|
||||||
|
<< HttpUtils::StatusCodeString(resp.statusCode)
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (line == "N" || line == "n") {
|
||||||
|
std::cout << "Looks like you will need to install manually"
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
std::cout << "Please use Y or N (case insensitive)" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TObject CrossLangShell(GCList &ls, std::vector<std::string> &argv) {
|
||||||
|
|
||||||
|
Tesses::Framework::Filesystem::VFSPath dir = GetCrossLangConfigDir();
|
||||||
|
|
||||||
|
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") {
|
||||||
|
std::cout << dir.ToString() << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (argv.size() > 1 && argv[1] == "update-shell") {
|
||||||
|
|
||||||
|
auto subdir =
|
||||||
|
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
|
||||||
|
Tesses::Framework::Filesystem::LocalFS, dir);
|
||||||
|
HttpRequest req;
|
||||||
|
req.followRedirects = true;
|
||||||
|
req.url = "https://redirect.tesses.net/crosslang-shell";
|
||||||
|
req.method = "GET";
|
||||||
|
HttpResponse resp(req);
|
||||||
|
if (resp.statusCode == StatusCode::OK) {
|
||||||
|
auto strm = resp.ReadAsStream();
|
||||||
|
CrossLang::CrossArchiveExtract(strm, subdir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
std::cout << "Error when fetching the script error: "
|
||||||
|
<< std::to_string(resp.statusCode) << " "
|
||||||
|
<< HttpUtils::StatusCodeString(resp.statusCode)
|
||||||
|
<< std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename)) {
|
||||||
|
auto subdir =
|
||||||
|
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
|
||||||
|
Tesses::Framework::Filesystem::LocalFS, dir);
|
||||||
|
if (Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p)) {
|
||||||
|
std::cout << "Installing " << p.ToString() << " -> "
|
||||||
|
<< dir.ToString() << std::endl;
|
||||||
|
auto strm =
|
||||||
|
Tesses::Framework::Filesystem::LocalFS->OpenFile(p, "rb");
|
||||||
|
if (strm != nullptr) {
|
||||||
|
CrossLang::CrossArchiveExtract(strm, subdir);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!Download(filename, subdir))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRootEnvironment *env =
|
||||||
|
TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||||
|
|
||||||
|
TStd::RegisterStd(ls.GetGC(), env);
|
||||||
|
|
||||||
|
env->LoadFileWithDependencies(
|
||||||
|
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
|
||||||
|
|
||||||
|
TList *args = TList::Create(ls);
|
||||||
|
|
||||||
|
args->Add(filename.ToString());
|
||||||
|
|
||||||
|
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
|
||||||
251
src/program_lib/crosslangcompiler.cpp
Normal file
251
src/program_lib/crosslangcompiler.cpp
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
#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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
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 (size_t i = 1; i < argv.size(); i++) {
|
||||||
|
if (argv[i] == "--help" || argv[i] == "-h") {
|
||||||
|
Help(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (argv[i] == "-o") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
outputDir = argv[i];
|
||||||
|
}
|
||||||
|
} else if (argv[i] == "-r") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
resourceDir = argv[i];
|
||||||
|
}
|
||||||
|
} else if (argv[i] == "-e") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
comptime = argv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (argv[i] == "-i") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
info = argv[i];
|
||||||
|
}
|
||||||
|
} else if (argv[i] == "-I") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
icon = argv[i];
|
||||||
|
}
|
||||||
|
} else if (argv[i] == "-d") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
std::string str = argv[i];
|
||||||
|
auto lastDash = str.find_last_of('-');
|
||||||
|
if (lastDash < str.size()) {
|
||||||
|
std::string str2 = str.substr(lastDash + 1);
|
||||||
|
if (str2 == "dev" || str2 == "alpha" || str2 == "beta" ||
|
||||||
|
str2 == "prod") {
|
||||||
|
lastDash = str.find_last_of('-', lastDash - 1);
|
||||||
|
}
|
||||||
|
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 (argv[i] == "-t") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
std::string str = argv[i];
|
||||||
|
auto lastDash = str.find_last_of('-');
|
||||||
|
if (lastDash < str.size()) {
|
||||||
|
std::string str2 = str.substr(lastDash + 1);
|
||||||
|
if (str2 == "dev" || str2 == "alpha" || str2 == "beta" ||
|
||||||
|
str2 == "prod") {
|
||||||
|
lastDash = str.find_last_of('-', lastDash - 1);
|
||||||
|
}
|
||||||
|
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 (argv[i] == "-n") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
name = argv[i];
|
||||||
|
}
|
||||||
|
} else if (argv[i] == "-v") {
|
||||||
|
i++;
|
||||||
|
if (i < argv.size()) {
|
||||||
|
|
||||||
|
if (!TVMVersion::TryParse(argv[i], version)) {
|
||||||
|
printf("ERROR: Invalid syntax for version\n");
|
||||||
|
printf("Expected "
|
||||||
|
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
|
||||||
|
"]]]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (argv[i] == "-D" || argv[i] == "--debug") {
|
||||||
|
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") {
|
||||||
|
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") {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang::Programs
|
||||||
114
src/program_lib/crosslanginterperter.cpp
Normal file
114
src/program_lib/crosslanginterperter.cpp
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
using namespace Tesses::Framework;
|
||||||
|
using namespace Tesses::Framework::Filesystem;
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang::Programs {
|
||||||
|
TObject CrossLangInterperter(GCList &ls, TRootEnvironment *env,
|
||||||
|
std::vector<std::string> &argv) {
|
||||||
|
std::shared_ptr<GC> gc = ls.GetGC();
|
||||||
|
if (argv.size() > 1) {
|
||||||
|
std::ifstream strm(argv[1], std::ios_base::in | std::ios_base::binary);
|
||||||
|
std::vector<LexToken> tokens;
|
||||||
|
Lex(argv[1], strm, tokens);
|
||||||
|
|
||||||
|
Parser parser(tokens);
|
||||||
|
|
||||||
|
CodeGen gen;
|
||||||
|
|
||||||
|
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
|
||||||
|
gen.embedFS = sfs;
|
||||||
|
gen.GenRoot(parser.ParseRoot());
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
{
|
||||||
|
auto strm2 =
|
||||||
|
std::make_shared<Tesses::Framework::Streams::MemoryStream>(
|
||||||
|
true);
|
||||||
|
gen.Save(strm2);
|
||||||
|
|
||||||
|
{
|
||||||
|
TFile *file = TFile::Create(ls);
|
||||||
|
|
||||||
|
strm2->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||||
|
file->Load(gc, strm2);
|
||||||
|
|
||||||
|
env->LoadFile(gc, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TList *args = TList::Create(ls);
|
||||||
|
for (int arg = 1; arg < argv.size(); arg++)
|
||||||
|
args->Add(std::string(argv[arg]));
|
||||||
|
|
||||||
|
return env->CallFunctionWithFatalError(ls, "main", {args});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
std::cout << "> ";
|
||||||
|
std::string source;
|
||||||
|
std::getline(std::cin, source);
|
||||||
|
|
||||||
|
auto strm2 =
|
||||||
|
std::make_shared<Tesses::Framework::Streams::MemoryStream>(
|
||||||
|
true);
|
||||||
|
|
||||||
|
if (source.find("loadfile ") == 0) {
|
||||||
|
std::string filename = source.substr(9);
|
||||||
|
|
||||||
|
std::ifstream strm(filename,
|
||||||
|
std::ios_base::in | std::ios_base::binary);
|
||||||
|
std::vector<LexToken> tokens;
|
||||||
|
Lex(filename, strm, tokens);
|
||||||
|
|
||||||
|
Parser parser(tokens);
|
||||||
|
|
||||||
|
CodeGen gen;
|
||||||
|
|
||||||
|
auto sfs =
|
||||||
|
std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
|
||||||
|
gen.embedFS = sfs;
|
||||||
|
gen.GenRoot(parser.ParseRoot());
|
||||||
|
|
||||||
|
gen.Save(strm2);
|
||||||
|
|
||||||
|
} else if (source == "exit") {
|
||||||
|
return (int64_t)0;
|
||||||
|
} else {
|
||||||
|
std::vector<LexToken> tokens;
|
||||||
|
std::stringstream strm(source, std::ios_base::in |
|
||||||
|
std::ios_base::binary);
|
||||||
|
Lex("lexed.tcross", strm, tokens);
|
||||||
|
|
||||||
|
Parser parser(tokens);
|
||||||
|
|
||||||
|
CodeGen gen;
|
||||||
|
|
||||||
|
auto sfs =
|
||||||
|
std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
|
||||||
|
gen.embedFS = sfs;
|
||||||
|
|
||||||
|
gen.GenRoot(parser.ParseRoot());
|
||||||
|
|
||||||
|
gen.Save(strm2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
TFile *file = TFile::Create(ls);
|
||||||
|
|
||||||
|
strm2->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||||
|
file->Load(gc, strm2);
|
||||||
|
|
||||||
|
env->LoadFile(gc, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int64_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tesses::CrossLang::Programs
|
||||||
58
src/program_lib/crosslangvm.cpp
Normal file
58
src/program_lib/crosslangvm.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
using namespace Tesses::Framework;
|
||||||
|
namespace Tesses::CrossLang::Programs {
|
||||||
|
TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
|
||||||
|
std::vector<std::string> &argv) {
|
||||||
|
if (argv.size() < 2) {
|
||||||
|
std::cout << "USAGE: "
|
||||||
|
<< (argv.empty() ? (std::string) "crossvm" : argv[0])
|
||||||
|
<< " <filename.crvm> <args...>" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
env->LoadFileWithDependencies(
|
||||||
|
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS,
|
||||||
|
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1]));
|
||||||
|
|
||||||
|
if (env->HasVariable("WebAppMain")) {
|
||||||
|
Args args(argv);
|
||||||
|
int port = 4206;
|
||||||
|
for (auto &item : args.options) {
|
||||||
|
if (item.first == "port") {
|
||||||
|
port = std::stoi(item.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
env->EnsureDictionary(ls.GetGC(), "Net")
|
||||||
|
->SetValue("WebServerPort", (int64_t)port);
|
||||||
|
TList *args2 = TList::Create(ls);
|
||||||
|
for (auto &item : args.positional) {
|
||||||
|
args2->Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2});
|
||||||
|
auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(), res);
|
||||||
|
if (svr2 == nullptr)
|
||||||
|
return 1;
|
||||||
|
Tesses::Framework::Http::HttpServer svr(port, svr2);
|
||||||
|
svr.StartAccepting();
|
||||||
|
TF_RunEventLoop();
|
||||||
|
TDictionary *_dict;
|
||||||
|
TClassObject *_co;
|
||||||
|
if (GetObjectHeap(res, _dict)) {
|
||||||
|
_dict->CallMethod(ls, "Close", {});
|
||||||
|
}
|
||||||
|
if (GetObjectHeap(res, _co)) {
|
||||||
|
_co->CallMethod(ls, "", "Close", {});
|
||||||
|
}
|
||||||
|
TF_Quit();
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
TList *args = TList::Create(ls);
|
||||||
|
for (size_t arg = 1; arg < argv.size(); arg++)
|
||||||
|
args->Add(std::string(argv[arg]));
|
||||||
|
|
||||||
|
return env->CallFunctionWithFatalError(ls, "main", {args});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang::Programs
|
||||||
192
src/programs/slim.cpp
Normal file
192
src/programs/slim.cpp
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
#include "CrossLang.hpp"
|
||||||
|
#include "TessesFramework/Filesystem/VFS.hpp"
|
||||||
|
using namespace Tesses::Framework;
|
||||||
|
using namespace Tesses::CrossLang;
|
||||||
|
using namespace Tesses::Framework::Filesystem;
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
TF_InitWithConsole();
|
||||||
|
TF_AllowPortable();
|
||||||
|
|
||||||
|
std::vector<std::string> args(argc);
|
||||||
|
|
||||||
|
for (int i = 0; i < argc; i++)
|
||||||
|
args[i] = argv[i];
|
||||||
|
|
||||||
|
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::CrossLangVM(ls, env, args);
|
||||||
|
GetObject(res, myi64);
|
||||||
|
return (int)myi64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
TStd::RegisterStd(gc, env);
|
||||||
|
auto res = Programs::CrossLangInterperter(ls, env, args);
|
||||||
|
|
||||||
|
GetObject(res, myi64);
|
||||||
|
|
||||||
|
return (int)myi64;
|
||||||
|
|
||||||
|
} else if (args[1] == "c") {
|
||||||
|
args.erase(args.begin());
|
||||||
|
Programs::CrossLangCompiler(args);
|
||||||
|
return 0;
|
||||||
|
} else if (args[1] == "archivecreate") {
|
||||||
|
args.erase(args.begin());
|
||||||
|
Programs::CrossArchiveCreate(args);
|
||||||
|
return 0;
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
TStd::RegisterStd(gc, env);
|
||||||
|
auto res = Programs::CrossLangVM(ls, env, args);
|
||||||
|
GetObject(res, myi64);
|
||||||
|
|
||||||
|
return (int)myi64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int64_t myi64 = 0;
|
||||||
|
std::shared_ptr<GC> gc = std::make_shared<GC>();
|
||||||
|
gc->Start();
|
||||||
|
GCList ls(gc);
|
||||||
|
auto res = Programs::CrossLangShell(ls, args);
|
||||||
|
|
||||||
|
GetObject(res, myi64);
|
||||||
|
|
||||||
|
return (int)myi64;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +1,20 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
namespace Tesses::CrossLang
|
static TList *VectorOfStringToList(GCList &ls, std::vector<std::string> &strs) {
|
||||||
{
|
TList *list = TList::Create(ls);
|
||||||
static TList* VectorOfStringToList(GCList& ls, std::vector<std::string>& strs)
|
|
||||||
{
|
|
||||||
TList* list = TList::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for(auto& item : strs)
|
for (auto &item : strs)
|
||||||
list->Add(item);
|
list->Add(item);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
static TList* EntriesToList(GCList& ls, std::vector<TClassEntry>& ents)
|
static TList *EntriesToList(GCList &ls, std::vector<TClassEntry> &ents) {
|
||||||
{
|
TList *list = TList::Create(ls);
|
||||||
TList* list=TList::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for(auto& item : ents)
|
for (auto &item : ents) {
|
||||||
{
|
|
||||||
std::string modifier = "public";
|
std::string modifier = "public";
|
||||||
switch(item.modifier)
|
switch (item.modifier) {
|
||||||
{
|
|
||||||
case TClassModifier::Public:
|
case TClassModifier::Public:
|
||||||
modifier = "public";
|
modifier = "public";
|
||||||
break;
|
break;
|
||||||
@@ -35,247 +29,221 @@ namespace Tesses::CrossLang
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
list->Add(TDictionary::Create(ls,{
|
list->Add(TDictionary::Create(
|
||||||
TDItem("Name",item.name),
|
ls,
|
||||||
TDItem("IsAbstract",item.isAbstract),
|
{TDItem("Name", item.name), TDItem("IsAbstract", item.isAbstract),
|
||||||
TDItem("IsFunction",item.isFunction),
|
TDItem("IsFunction", item.isFunction),
|
||||||
TDItem("Documentation",item.documentation),
|
TDItem("Documentation", item.documentation),
|
||||||
TDItem("ChunkId",(int64_t)item.chunkId),
|
TDItem("ChunkId", (int64_t)item.chunkId),
|
||||||
TDItem("Arguments",VectorOfStringToList(ls,item.args)),
|
TDItem("Arguments", VectorOfStringToList(ls, item.args)),
|
||||||
TDItem("Modifier",modifier)
|
TDItem("Modifier", modifier)}));
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
static TList* ClassInstanceToList(GCList& ls, TClassObject* co)
|
static TList *ClassInstanceToList(GCList &ls, TClassObject *co) {
|
||||||
{
|
TList *list = TList::Create(ls);
|
||||||
TList* list=TList::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for(auto& item : co->entries)
|
for (auto &item : co->entries) {
|
||||||
{
|
if (item.modifier == TClassModifier::Public) {
|
||||||
if(item.modifier == TClassModifier::Public)
|
list->Add(TDictionary::Create(
|
||||||
{
|
ls,
|
||||||
list->Add(TDictionary::Create(ls, {
|
{TDItem("Name", item.name), TDItem("IsFunction", !item.canSet),
|
||||||
TDItem(
|
TDItem("Owner", item.owner), TDItem("Value", item.value)}));
|
||||||
"Name", item.name
|
|
||||||
),
|
|
||||||
TDItem(
|
|
||||||
"IsFunction", !item.canSet
|
|
||||||
),
|
|
||||||
TDItem(
|
|
||||||
"Owner", item.owner
|
|
||||||
),
|
|
||||||
TDItem(
|
|
||||||
"Value", item.value
|
|
||||||
)
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
TObject GetClassInfo(GCList& ls,TFile* f, uint32_t index)
|
TObject GetClassInfo(GCList &ls, TFile *f, uint32_t index) {
|
||||||
{
|
return TDictionary::Create(
|
||||||
return TDictionary::Create(ls,{
|
ls, {TDItem("Name", JoinPeriod(f->classes.at(index).name)),
|
||||||
TDItem("Name", JoinPeriod(f->classes.at(index).name)),
|
TDItem("NameParts",
|
||||||
TDItem("NameParts",VectorOfStringToList(ls,f->classes.at(index).name)),
|
VectorOfStringToList(ls, f->classes.at(index).name)),
|
||||||
TDItem("Inherits", JoinPeriod(f->classes.at(index).inherits)),
|
TDItem("Inherits", JoinPeriod(f->classes.at(index).inherits)),
|
||||||
TDItem("InheritsParts",VectorOfStringToList(ls,f->classes.at(index).inherits)),
|
TDItem("InheritsParts",
|
||||||
TDItem("Documentation",f->classes.at(index).documentation),
|
VectorOfStringToList(ls, f->classes.at(index).inherits)),
|
||||||
TDItem("Entries",EntriesToList(ls,f->classes.at(index).entry))
|
TDItem("Documentation", f->classes.at(index).documentation),
|
||||||
});
|
TDItem("Entries", EntriesToList(ls, f->classes.at(index).entry))});
|
||||||
}
|
}
|
||||||
static TObject Class_CreateInstance(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
|
static TObject Class_CreateInstance(TRootEnvironment *env, GCList &ls,
|
||||||
{
|
std::vector<TObject> args) {
|
||||||
TList* args_ls;
|
TList *args_ls;
|
||||||
if(!GetArgumentHeap(args,1,args_ls)) return nullptr;
|
if (!GetArgumentHeap(args, 1, args_ls))
|
||||||
TList* list;
|
return nullptr;
|
||||||
TClassObject* obj;
|
TList *list;
|
||||||
|
TClassObject *obj;
|
||||||
std::string str;
|
std::string str;
|
||||||
if(GetArgumentHeap(args,0,list))
|
if (GetArgumentHeap(args, 0, list)) {
|
||||||
{
|
|
||||||
std::vector<std::string> clsName;
|
std::vector<std::string> clsName;
|
||||||
for(int64_t i = 0; i < list->Count(); i++)
|
for (int64_t i = 0; i < list->Count(); i++) {
|
||||||
{
|
|
||||||
auto o = list->Get(i);
|
auto o = list->Get(i);
|
||||||
if(GetObject(o,str)) clsName.push_back(str);
|
if (GetObject(o, str))
|
||||||
|
clsName.push_back(str);
|
||||||
}
|
}
|
||||||
for(auto& item : env->classes)
|
for (auto &item : env->classes) {
|
||||||
{
|
auto &f = item.first->classes.at(item.second);
|
||||||
auto& f=item.first->classes.at(item.second);
|
|
||||||
|
|
||||||
if(f.name.size() != clsName.size()) continue;
|
if (f.name.size() != clsName.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
bool found=true;
|
bool found = true;
|
||||||
for(size_t i = 0; i < f.name.size(); i++)
|
for (size_t i = 0; i < f.name.size(); i++)
|
||||||
if(f.name[i] != clsName[i])
|
if (f.name[i] != clsName[i]) {
|
||||||
{
|
found = false;
|
||||||
found=false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(found)
|
if (found) {
|
||||||
{
|
return TClassObject::Create(ls, item.first, item.second, env,
|
||||||
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
|
args_ls->items);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
} else if (GetArgument(args, 0, str)) {
|
||||||
else if(GetArgument(args,0,str))
|
std::vector<std::string> clsName =
|
||||||
{
|
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
|
||||||
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
|
for (auto &item : env->classes) {
|
||||||
for(auto& item : env->classes)
|
auto &f = item.first->classes.at(item.second);
|
||||||
{
|
|
||||||
auto& f=item.first->classes.at(item.second);
|
|
||||||
|
|
||||||
if(f.name.size() != clsName.size()) continue;
|
if (f.name.size() != clsName.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
bool found=true;
|
bool found = true;
|
||||||
for(size_t i = 0; i < f.name.size(); i++)
|
for (size_t i = 0; i < f.name.size(); i++)
|
||||||
if(f.name[i] != clsName[i])
|
if (f.name[i] != clsName[i]) {
|
||||||
{
|
found = false;
|
||||||
found=false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(found)
|
if (found) {
|
||||||
{
|
return TClassObject::Create(ls, item.first, item.second, env,
|
||||||
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
|
args_ls->items);
|
||||||
|
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject Class_GetClassNames(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
|
static TObject Class_GetClassNames(TRootEnvironment *env, GCList &ls,
|
||||||
{
|
std::vector<TObject> args) {
|
||||||
TList* list = TList::Create(ls);
|
TList *list = TList::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for(auto& item : env->classes)
|
for (auto &item : env->classes) {
|
||||||
{
|
|
||||||
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
|
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
|
||||||
}
|
}
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
static TObject Class_GetInfo(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
|
static TObject Class_GetInfo(TRootEnvironment *env, GCList &ls,
|
||||||
{
|
std::vector<TObject> args) {
|
||||||
|
|
||||||
TList* list;
|
TList *list;
|
||||||
TClassObject* obj;
|
TClassObject *obj;
|
||||||
std::string str;
|
std::string str;
|
||||||
if(GetArgumentHeap(args,0,list))
|
if (GetArgumentHeap(args, 0, list)) {
|
||||||
{
|
|
||||||
std::vector<std::string> clsName;
|
std::vector<std::string> clsName;
|
||||||
for(int64_t i = 0; i < list->Count(); i++)
|
for (int64_t i = 0; i < list->Count(); i++) {
|
||||||
{
|
|
||||||
auto o = list->Get(i);
|
auto o = list->Get(i);
|
||||||
if(GetObject(o,str)) clsName.push_back(str);
|
if (GetObject(o, str))
|
||||||
|
clsName.push_back(str);
|
||||||
}
|
}
|
||||||
for(auto& item : env->classes)
|
for (auto &item : env->classes) {
|
||||||
{
|
auto &f = item.first->classes.at(item.second);
|
||||||
auto& f=item.first->classes.at(item.second);
|
|
||||||
|
|
||||||
if(f.name.size() != clsName.size()) continue;
|
if (f.name.size() != clsName.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
bool found=true;
|
bool found = true;
|
||||||
for(size_t i = 0; i < f.name.size(); i++)
|
for (size_t i = 0; i < f.name.size(); i++)
|
||||||
if(f.name[i] != clsName[i])
|
if (f.name[i] != clsName[i]) {
|
||||||
{
|
found = false;
|
||||||
found=false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(found)
|
if (found) {
|
||||||
{
|
return GetClassInfo(ls, item.first, item.second);
|
||||||
return GetClassInfo(ls,item.first,item.second);
|
} else
|
||||||
}
|
|
||||||
else
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
} else if (GetArgument(args, 0, str)) {
|
||||||
else if(GetArgument(args,0,str))
|
std::vector<std::string> clsName =
|
||||||
{
|
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
|
||||||
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
|
for (auto &item : env->classes) {
|
||||||
for(auto& item : env->classes)
|
auto &f = item.first->classes.at(item.second);
|
||||||
{
|
|
||||||
auto& f=item.first->classes.at(item.second);
|
|
||||||
|
|
||||||
if(f.name.size() != clsName.size()) continue;
|
if (f.name.size() != clsName.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
bool found=true;
|
bool found = true;
|
||||||
for(size_t i = 0; i < f.name.size(); i++)
|
for (size_t i = 0; i < f.name.size(); i++)
|
||||||
if(f.name[i] != clsName[i])
|
if (f.name[i] != clsName[i]) {
|
||||||
{
|
found = false;
|
||||||
found=false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(found)
|
if (found) {
|
||||||
{
|
return GetClassInfo(ls, item.first, item.second);
|
||||||
return GetClassInfo(ls,item.first,item.second);
|
} else
|
||||||
}
|
|
||||||
else
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
} else if (GetArgumentHeap(args, 0, obj)) {
|
||||||
else if(GetArgumentHeap(args,0,obj))
|
return GetClassInfo(ls, obj->file, obj->classIndex);
|
||||||
{
|
|
||||||
return GetClassInfo(ls,obj->file,obj->classIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
void TStd::RegisterClass(GC* gc, TRootEnvironment* env)
|
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
{
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
env->permissions.canRegisterClass=true;
|
env->permissions.canRegisterClass = true;
|
||||||
TDictionary* cls= env->EnsureDictionary(gc, "Class");
|
TDictionary *cls = env->EnsureDictionary(gc, "Class");
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
|
|
||||||
TExternalMethod* ext = TExternalMethod::Create(ls ,"Get the class info",{"classInstanceOrClassName"},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
TExternalMethod *ext = TExternalMethod::Create(
|
||||||
return Class_GetInfo(env,ls,args);
|
ls, "Get the class info", {"classInstanceOrClassName"},
|
||||||
|
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
return Class_GetInfo(env, ls, args);
|
||||||
});
|
});
|
||||||
ext->watch.push_back(env);
|
ext->watch.push_back(env);
|
||||||
|
|
||||||
cls->SetValue("GetInfo",ext);
|
cls->SetValue("GetInfo", ext);
|
||||||
|
|
||||||
ext = TExternalMethod::Create(ls ,"Get the class names",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
ext = TExternalMethod::Create(
|
||||||
return Class_GetClassNames(env,ls,args);
|
ls, "Get the class names", {},
|
||||||
|
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
return Class_GetClassNames(env, ls, args);
|
||||||
});
|
});
|
||||||
ext->watch.push_back(env);
|
ext->watch.push_back(env);
|
||||||
|
|
||||||
cls->SetValue("GetClassNames",ext);
|
cls->SetValue("GetClassNames", ext);
|
||||||
ext = TExternalMethod::Create(ls ,"Create an instance of class",{"name","args"},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
ext = TExternalMethod::Create(
|
||||||
return Class_CreateInstance(env,ls,args);
|
ls, "Create an instance of class", {"name", "args"},
|
||||||
|
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
return Class_CreateInstance(env, ls, args);
|
||||||
});
|
});
|
||||||
ext->watch.push_back(env);
|
ext->watch.push_back(env);
|
||||||
|
|
||||||
cls->SetValue("CreateInstance",ext);
|
cls->SetValue("CreateInstance", ext);
|
||||||
cls->DeclareFunction(gc,"Name","Get class name via instance",{"instance"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
cls->DeclareFunction(gc, "Name", "Get class name via instance",
|
||||||
TClassObject* cls;
|
{"instance"},
|
||||||
if(GetArgumentHeap(args,0,cls))
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
{
|
TClassObject *cls;
|
||||||
|
if (GetArgumentHeap(args, 0, cls)) {
|
||||||
return cls->name;
|
return cls->name;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cls->DeclareFunction(
|
||||||
cls->DeclareFunction(gc, "GetInstanceInfo", "Get the instance specific info, including current values", {}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
gc, "GetInstanceInfo",
|
||||||
TClassObject* co;
|
"Get the instance specific info, including current values", {},
|
||||||
if(GetArgumentHeap(args, 0, co))
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
{
|
TClassObject *co;
|
||||||
|
if (GetArgumentHeap(args, 0, co)) {
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
auto res= TDictionary::Create(ls,
|
auto res = TDictionary::Create(
|
||||||
{
|
ls, {TDItem("Name", co->name), TDItem("File", co->file),
|
||||||
TDItem("Name", co->name),
|
|
||||||
TDItem("File", co->file),
|
|
||||||
TDItem("ClassIndex", (int64_t)co->classIndex),
|
TDItem("ClassIndex", (int64_t)co->classIndex),
|
||||||
TDItem("InheritList", VectorOfStringToList(ls, co->inherit_tree)),
|
TDItem("InheritList",
|
||||||
TDItem("Entries", ClassInstanceToList(ls,co))
|
VectorOfStringToList(ls, co->inherit_tree)),
|
||||||
}
|
TDItem("Entries", ClassInstanceToList(ls, co))});
|
||||||
);
|
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -283,5 +251,5 @@ namespace Tesses::CrossLang
|
|||||||
});
|
});
|
||||||
|
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -2,334 +2,247 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(GEKKO) || defined(__SWITCH__) || defined(_WIN32)
|
|
||||||
#undef CROSSLANG_ENABLE_TERMIOS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
|
||||||
#include <termios.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
TObject Console_setInvertedColors(GCList &ls, std::vector<TObject> args) {
|
||||||
struct termios orig_termios;
|
bool inverted;
|
||||||
static void disableRawMode()
|
if (GetArgument(args, 0, inverted)) {
|
||||||
{
|
Tesses::Framework::Console::SetInvertedColors(inverted);
|
||||||
tcsetattr(0, TCSAFLUSH, &orig_termios);
|
|
||||||
}
|
}
|
||||||
#endif
|
return Undefined();
|
||||||
TObject Console_getEcho(GCList& ls, std::vector<TObject> args)
|
}
|
||||||
{
|
TObject Console_Reset(GCList &ls, std::vector<TObject> args) {
|
||||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
Tesses::Framework::Console::Reset();
|
||||||
struct termios raw;
|
return Undefined();
|
||||||
tcgetattr(0, &raw);
|
}
|
||||||
return (raw.c_lflag & ECHO) > 0;
|
TObject Console_getIsTTY(GCList &ls, std::vector<TObject> args) {
|
||||||
|
|
||||||
#endif
|
return Tesses::Framework::Console::IsTTY();
|
||||||
return false;
|
}
|
||||||
}
|
TObject Console_getEcho(GCList &ls, std::vector<TObject> args) {
|
||||||
TObject Console_setEcho(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
return Tesses::Framework::Console::GetEcho();
|
||||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
}
|
||||||
{
|
TObject Console_setEcho(GCList &ls, std::vector<TObject> args) {
|
||||||
|
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
|
||||||
bool cooked = std::get<bool>(args[0]);
|
bool cooked = std::get<bool>(args[0]);
|
||||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
Tesses::Framework::Console::SetEcho(cooked);
|
||||||
struct termios raw;
|
|
||||||
tcgetattr(0, &raw);
|
|
||||||
if(cooked)
|
|
||||||
{
|
|
||||||
raw.c_lflag |= ECHO;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
raw.c_lflag &= ~(ECHO);
|
|
||||||
}
|
|
||||||
|
|
||||||
tcsetattr(0, TCSAFLUSH, &raw);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return cooked;
|
return cooked;
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject Console_getCanonical(GCList& ls, std::vector<TObject> args)
|
TObject Console_getCanonical(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
return Tesses::Framework::Console::GetCanonical();
|
||||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
}
|
||||||
struct termios raw;
|
TObject Console_setCanonical(GCList &ls, std::vector<TObject> args) {
|
||||||
tcgetattr(0, &raw);
|
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
|
||||||
return (raw.c_lflag & ICANON) > 0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TObject Console_setCanonical(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
|
||||||
{
|
|
||||||
bool cooked = std::get<bool>(args[0]);
|
bool cooked = std::get<bool>(args[0]);
|
||||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
Tesses::Framework::Console::SetCanonical(cooked);
|
||||||
struct termios raw;
|
|
||||||
tcgetattr(0, &raw);
|
|
||||||
if(cooked)
|
|
||||||
{
|
|
||||||
raw.c_lflag |= ICANON;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
raw.c_lflag &= ~(ICANON);
|
|
||||||
}
|
|
||||||
|
|
||||||
tcsetattr(0, TCSAFLUSH, &raw);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return cooked;
|
return cooked;
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject Console_getSignals(GCList& ls, std::vector<TObject> args)
|
TObject Console_getSignals(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
return Tesses::Framework::Console::GetSignals();
|
||||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
}
|
||||||
struct termios raw;
|
TObject Console_setSignals(GCList &ls, std::vector<TObject> args) {
|
||||||
tcgetattr(0, &raw);
|
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
|
||||||
return (raw.c_lflag & ISIG) > 0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TObject Console_setSignals(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
|
||||||
{
|
|
||||||
bool cooked = std::get<bool>(args[0]);
|
bool cooked = std::get<bool>(args[0]);
|
||||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
Tesses::Framework::Console::SetSignals(cooked);
|
||||||
struct termios raw;
|
|
||||||
tcgetattr(0, &raw);
|
|
||||||
if(cooked)
|
|
||||||
{
|
|
||||||
raw.c_lflag |= ISIG;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
raw.c_lflag &= ~(ISIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
tcsetattr(0, TCSAFLUSH, &raw);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return cooked;
|
return cooked;
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject Console_Read(GCList& ls, std::vector<TObject> args)
|
TObject Console_Read(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
return (int64_t)Tesses::Framework::Console::Read();
|
||||||
uint8_t byte;
|
}
|
||||||
std::cin.read((char*)&byte,1);
|
TObject Console_ReadLine(GCList &ls, std::vector<TObject> args) {
|
||||||
return std::cin.eof() ? (int64_t)-1 : (int64_t)byte;
|
return Tesses::Framework::Console::ReadLine();
|
||||||
}
|
}
|
||||||
TObject Console_ReadLine(GCList& ls, std::vector<TObject> args)
|
TObject Console_ReadPassword(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
return Tesses::Framework::Console::ReadPassword();
|
||||||
std::string str;
|
}
|
||||||
std::getline(std::cin,str);
|
TObject Console_Write(GCList &ls, std::vector<TObject> args) {
|
||||||
return str;
|
if (args.size() < 1) {
|
||||||
}
|
|
||||||
TObject Console_Write(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
if(args.size() < 1)
|
|
||||||
{
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
std::cout << ToString(ls.GetGC(),args[0]);
|
Tesses::Framework::Console::Write(ToString(ls.GetGC(), args[0]));
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject Console_Fatal(GCList& ls, std::vector<TObject> args)
|
TObject Console_Fatal(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
if (args.size() < 1) {
|
||||||
if(args.size() < 1)
|
Tesses::Framework::Console::ErrorLine("FATAL: <NO MESSAGE>");
|
||||||
{
|
|
||||||
std::cout << "FATAL: <NO MESSAGE>" << std::endl;
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
std::cout << "FATAL: " << ToString(ls.GetGC(),args[0]) << std::endl;
|
Tesses::Framework::Console::ErrorLine("FATAL: " +
|
||||||
|
ToString(ls.GetGC(), args[0]));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
TObject Console_WriteLine(GCList& ls, std::vector<TObject> args)
|
TObject Console_WriteLine(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
if (args.size() < 1) {
|
||||||
if(args.size() < 1)
|
Tesses::Framework::Console::WriteLineView("");
|
||||||
{
|
|
||||||
std::cout << "\n";
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
std::cout << ToString(ls.GetGC(),args[0]) << "\n";
|
Tesses::Framework::Console::WriteLine(ToString(ls.GetGC(), args[0]));
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
TObject Console_Error(GCList &ls, std::vector<TObject> args) {
|
||||||
|
if (args.size() < 1) {
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject Console_Error(GCList& ls, std::vector<TObject> args)
|
Tesses::Framework::Console::Error(ToString(ls.GetGC(), args[0]));
|
||||||
{
|
return Undefined();
|
||||||
if(args.size() < 1)
|
}
|
||||||
{
|
TObject Console_ErrorLine(GCList &ls, std::vector<TObject> args) {
|
||||||
|
if (args.size() < 1) {
|
||||||
|
Tesses::Framework::Console::ErrorLine("");
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
std::cerr << ToString(ls.GetGC(),args[0]);
|
Tesses::Framework::Console::ErrorLine(ToString(ls.GetGC(), args[0]));
|
||||||
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject Console_ErrorLine(GCList& ls, std::vector<TObject> args)
|
TObject Console_getIn(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
return std::make_shared<Tesses::Framework::Streams::FileStream>(
|
||||||
if(args.size() < 1)
|
stdin, false, "r", false);
|
||||||
{
|
}
|
||||||
std::cout << "\n";
|
|
||||||
|
TObject Console_getOut(GCList &ls, std::vector<TObject> args) {
|
||||||
|
return std::make_shared<Tesses::Framework::Streams::FileStream>(
|
||||||
|
stdout, false, "w", false);
|
||||||
|
}
|
||||||
|
TObject Console_getError(GCList &ls, std::vector<TObject> args) {
|
||||||
|
return std::make_shared<Tesses::Framework::Streams::FileStream>(
|
||||||
|
stderr, false, "w", false);
|
||||||
|
}
|
||||||
|
TObject Console_Clear(GCList &ls, std::vector<TObject> args) {
|
||||||
|
Tesses::Framework::Console::Clear();
|
||||||
return Undefined();
|
return Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
TObject Console_ProgressBar(GCList &ls, std::vector<TObject> args) {
|
||||||
|
double dbl;
|
||||||
|
int64_t i64;
|
||||||
|
if (GetArgument(args, 0, i64)) {
|
||||||
|
Tesses::Framework::Console::ProgressBar((int)i64);
|
||||||
|
} else if (GetArgument(args, 0, dbl)) {
|
||||||
|
Tesses::Framework::Console::ProgressBar(dbl);
|
||||||
}
|
}
|
||||||
std::cerr << ToString(ls.GetGC(),args[0]) << "\n";
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject Console_getIn(GCList& ls, std::vector<TObject> args)
|
TObject Console_getSize(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
auto sz = Tesses::Framework::Console::GetSize();
|
||||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdin,false,"r",false);
|
TDictionary *dict =
|
||||||
}
|
TDictionary::Create(ls, {TDItem("Width", (int64_t)sz.first),
|
||||||
|
TDItem("Height", (int64_t)sz.second)});
|
||||||
TObject Console_getOut(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdout,false,"w",false);
|
|
||||||
}
|
|
||||||
TObject Console_getError(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(stderr,false,"w",false);
|
|
||||||
}
|
|
||||||
TObject Console_Clear(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
//because I just really want a clear function
|
|
||||||
#if defined(_WIN32)
|
|
||||||
system("cls");
|
|
||||||
#else
|
|
||||||
std::cout << "\x1b[2J\x1b[H" << std::flush; //because of wii and stuff (dont want to rely on clear command)
|
|
||||||
#endif
|
|
||||||
return Undefined();
|
|
||||||
}
|
|
||||||
static void con_sz(int& w, int& h)
|
|
||||||
{
|
|
||||||
w = 0;
|
|
||||||
h = 0;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
|
|
||||||
#elif defined(CROSSLANG_ENABLE_TERMIOS)
|
|
||||||
if(!isatty(STDOUT_FILENO))
|
|
||||||
return;
|
|
||||||
struct winsize ws;
|
|
||||||
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0)
|
|
||||||
{
|
|
||||||
w = ws.ws_col;
|
|
||||||
h = ws.ws_row;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
TObject Console_ProgressBar(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
//[=== ] 50%
|
|
||||||
bool showBar = true;
|
|
||||||
#if defined(CROSSLANG_ENABLE_TERMIOS)
|
|
||||||
if(!isatty(STDOUT_FILENO)) showBar=false;
|
|
||||||
#endif
|
|
||||||
int64_t progress = 0;
|
|
||||||
double pdbl = 0;
|
|
||||||
GetArgument(args,0,pdbl);
|
|
||||||
if(GetArgument(args,0,progress)) pdbl = progress / 100.0;
|
|
||||||
if(pdbl < 0) pdbl=0;
|
|
||||||
if(pdbl > 1) pdbl=1;
|
|
||||||
|
|
||||||
std::cout << "\r";
|
|
||||||
if(showBar)
|
|
||||||
{
|
|
||||||
int w,h;
|
|
||||||
con_sz(w,h);
|
|
||||||
|
|
||||||
int totalBlocks = w - 10;
|
|
||||||
if(totalBlocks > 0)
|
|
||||||
{
|
|
||||||
std::cout << "[\033[0;32m";
|
|
||||||
int i;
|
|
||||||
int off = pdbl * totalBlocks;
|
|
||||||
for(int i = 0; i < totalBlocks; i++)
|
|
||||||
{
|
|
||||||
if(i < off)
|
|
||||||
std::cout << "=";
|
|
||||||
else
|
|
||||||
std::cout << " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "\033[0m] ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << std::setw(3) << (int)(pdbl*100) << "%" << std::flush;
|
|
||||||
return Undefined();
|
|
||||||
}
|
|
||||||
TObject Console_getSize(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
#if defined(CROSSLANG_ENABLE_TERMIOS)
|
|
||||||
if(!isatty(STDOUT_FILENO)) return nullptr;
|
|
||||||
#endif
|
|
||||||
int w, h;
|
|
||||||
con_sz(w,h);
|
|
||||||
TDictionary* dict = TDictionary::Create(ls,{
|
|
||||||
TDItem("Width", (int64_t)w),
|
|
||||||
TDItem("Height",(int64_t)h)
|
|
||||||
});
|
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
|
}
|
||||||
|
TObject Console_List(GCList &ls, std::vector<TObject> args) {
|
||||||
|
if (!args.empty()) {
|
||||||
|
GCList ls2(ls.GetGC());
|
||||||
|
auto enumerator = TEnumerator::CreateFromObject(ls2, args[0]);
|
||||||
|
std::vector<std::string> items;
|
||||||
|
|
||||||
|
while (enumerator->MoveNext(ls2.GetGC())) {
|
||||||
|
auto item = enumerator->GetCurrent(ls2);
|
||||||
|
items.push_back(ToString(ls2.GetGC(), item));
|
||||||
}
|
}
|
||||||
void TStd::RegisterConsole(GC* gc,TRootEnvironment* env)
|
|
||||||
{
|
return (int64_t)Tesses::Framework::Console::List(items);
|
||||||
env->permissions.canRegisterConsole=true;
|
}
|
||||||
if(env->permissions.customConsole != nullptr)
|
return 0;
|
||||||
{
|
}
|
||||||
|
void TStd::RegisterConsole(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
|
env->permissions.canRegisterConsole = true;
|
||||||
|
if (env->permissions.customConsole != nullptr) {
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
env->DeclareVariable("Console", env->permissions.customConsole );
|
env->DeclareVariable("Console", env->permissions.customConsole);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
|
||||||
tcgetattr(0, &orig_termios);
|
|
||||||
atexit(disableRawMode);
|
|
||||||
#endif
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc,"getEcho","Get whether terminal is echoing characters read",{},Console_getEcho);
|
gc, "getIsTTY",
|
||||||
dict->DeclareFunction(gc,"setEcho","Set whether terminal is echoing characters read",{"flag"},Console_setEcho);
|
"Get whether terminal is a terminal or just piped to file", {},
|
||||||
dict->DeclareFunction(gc,"getCanonical","Get whether terminal is buffering line by line (true) or byte by byte (false)",{},Console_getCanonical);
|
Console_getIsTTY);
|
||||||
dict->DeclareFunction(gc,"setCanonical","Set whether terminal is buffering line by line (true) or byte by byte (false)",{"flag"},Console_setCanonical);
|
dict->DeclareFunction(gc, "getEcho",
|
||||||
dict->DeclareFunction(gc,"getSignals","Get whether terminal is sending signals for CTRL+C (true) or via read (false)",{},Console_getSignals);
|
"Get whether terminal is echoing characters read", {},
|
||||||
dict->DeclareFunction(gc,"setSignals","Set whether terminal is sending signals for CTRL+C (true) or via read (false)",{"flag"},Console_setSignals);
|
Console_getEcho);
|
||||||
dict->DeclareFunction(gc,"Clear", "Clear the console",{},Console_Clear);
|
dict->DeclareFunction(gc, "setEcho",
|
||||||
dict->DeclareFunction(gc,"Read", "Reads a byte from stdin",{},Console_Read);
|
"Set whether terminal is echoing characters read",
|
||||||
dict->DeclareFunction(gc,"ReadLine","Reads line from stdin",{},Console_ReadLine);
|
{"flag"}, Console_setEcho);
|
||||||
dict->DeclareFunction(gc,"Write","Write text \"text\" to stdout",{"text"},Console_Write);
|
dict->DeclareFunction(gc, "getCanonical",
|
||||||
dict->DeclareFunction(gc,"WriteLine","Write text \"text\" to stdout with new line",{"$text"},Console_WriteLine);
|
"Get whether terminal is buffering line by line "
|
||||||
dict->DeclareFunction(gc,"Error", "Write text \"error\" to stderr",{"error"},Console_Error);
|
"(true) or byte by byte (false)",
|
||||||
dict->DeclareFunction(gc,"ErrorLine","Write text \"error\" to stderr",{"$error"},Console_ErrorLine);
|
{}, Console_getCanonical);
|
||||||
dict->DeclareFunction(gc,"ProgressBar","Draw progressbar", {}, Console_ProgressBar);
|
dict->DeclareFunction(gc, "setCanonical",
|
||||||
if(env->permissions.canRegisterEverything)
|
"Set whether terminal is buffering line by line "
|
||||||
dict->DeclareFunction(gc,"Fatal","Stop the program with an optional error message",{"$text"},Console_Fatal);
|
"(true) or byte by byte (false)",
|
||||||
dict->DeclareFunction(gc,"getIn","Get stdin Stream",{},Console_getIn);
|
{"flag"}, Console_setCanonical);
|
||||||
dict->DeclareFunction(gc,"getOut","Get stdout Stream",{},Console_getOut);
|
dict->DeclareFunction(gc, "getSignals",
|
||||||
dict->DeclareFunction(gc,"getError", "Get stderr Stream",{},Console_getError);
|
"Get whether terminal is sending signals for CTRL+C "
|
||||||
dict->DeclareFunction(gc, "getSize", "Get console size",{},Console_getSize);
|
"(true) or via read (false)",
|
||||||
|
{}, Console_getSignals);
|
||||||
|
dict->DeclareFunction(gc, "setSignals",
|
||||||
|
"Set whether terminal is sending signals for CTRL+C "
|
||||||
|
"(true) or via read (false)",
|
||||||
|
{"flag"}, Console_setSignals);
|
||||||
|
dict->DeclareFunction(gc, "Clear", "Clear the console", {}, Console_Clear);
|
||||||
|
dict->DeclareFunction(gc, "Read", "Reads a byte from stdin", {},
|
||||||
|
Console_Read);
|
||||||
|
dict->DeclareFunction(gc, "ReadLine", "Reads line from stdin", {},
|
||||||
|
Console_ReadLine);
|
||||||
|
dict->DeclareFunction(gc, "ReadPassword", "Reads password from stdin", {},
|
||||||
|
Console_ReadPassword);
|
||||||
|
dict->DeclareFunction(gc, "Write", "Write text \"text\" to stdout",
|
||||||
|
{"text"}, Console_Write);
|
||||||
|
dict->DeclareFunction(gc, "WriteLine",
|
||||||
|
"Write text \"text\" to stdout with new line",
|
||||||
|
{"$text"}, Console_WriteLine);
|
||||||
|
dict->DeclareFunction(gc, "Error", "Write text \"error\" to stderr",
|
||||||
|
{"error"}, Console_Error);
|
||||||
|
dict->DeclareFunction(gc, "ErrorLine", "Write text \"error\" to stderr",
|
||||||
|
{"$error"}, Console_ErrorLine);
|
||||||
|
dict->DeclareFunction(gc, "ProgressBar", "Draw progressbar", {},
|
||||||
|
Console_ProgressBar);
|
||||||
|
dict->DeclareFunction(gc, "List", "Draw list", {"itemsitterator"},
|
||||||
|
Console_List);
|
||||||
|
if (env->permissions.canRegisterEverything)
|
||||||
|
dict->DeclareFunction(gc, "Fatal",
|
||||||
|
"Stop the program with an optional error message",
|
||||||
|
{"$text"}, Console_Fatal);
|
||||||
|
dict->DeclareFunction(gc, "getIn", "Get stdin Stream", {}, Console_getIn);
|
||||||
|
dict->DeclareFunction(gc, "getOut", "Get stdout Stream", {},
|
||||||
|
Console_getOut);
|
||||||
|
dict->DeclareFunction(gc, "getError", "Get stderr Stream", {},
|
||||||
|
Console_getError);
|
||||||
|
dict->DeclareFunction(gc, "getSize", "Get console size", {},
|
||||||
|
Console_getSize);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
env->DeclareVariable("Console", dict);
|
env->DeclareVariable("Console", dict);
|
||||||
auto _new = env->EnsureDictionary(gc,"New");
|
auto _new = env->EnsureDictionary(gc, "New");
|
||||||
_new->DeclareFunction(gc,"ConsoleReader","Read from console",{},[](GCList& ls,std::vector<TObject> args)->TObject {
|
_new->DeclareFunction(
|
||||||
return std::make_shared<Tesses::Framework::TextStreams::ConsoleReader>();
|
gc, "ConsoleReader", "Read from console", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
return std::make_shared<
|
||||||
|
Tesses::Framework::TextStreams::ConsoleReader>();
|
||||||
});
|
});
|
||||||
_new->DeclareFunction(gc,"ConsoleWriter","Write to console",{"$isStderr"},[](GCList& ls,std::vector<TObject> args)->TObject {
|
_new->DeclareFunction(
|
||||||
|
gc, "ConsoleWriter", "Write to console", {"$isStderr"},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
bool err;
|
bool err;
|
||||||
if(GetArgument(args,0,err)) return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>(err);
|
if (GetArgument(args, 0, err))
|
||||||
return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>();
|
return std::make_shared<
|
||||||
|
Tesses::Framework::TextStreams::ConsoleWriter>(err);
|
||||||
|
return std::make_shared<
|
||||||
|
Tesses::Framework::TextStreams::ConsoleWriter>();
|
||||||
});
|
});
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,43 +2,36 @@
|
|||||||
|
|
||||||
using namespace Tesses::Framework::Crypto;
|
using namespace Tesses::Framework::Crypto;
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
static TObject Crypto_RandomBytes(GCList &ls, std::vector<TObject> args) {
|
||||||
static TObject Crypto_RandomBytes(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
|
|
||||||
int64_t size;
|
int64_t size;
|
||||||
std::string personalStr;
|
std::string personalStr;
|
||||||
if(GetArgument(args,0,size) && GetArgument(args,1,personalStr))
|
if (GetArgument(args, 0, size) && GetArgument(args, 1, personalStr)) {
|
||||||
{
|
|
||||||
|
|
||||||
std::vector<uint8_t> bytes;
|
std::vector<uint8_t> bytes;
|
||||||
bytes.resize((size_t)size);
|
bytes.resize((size_t)size);
|
||||||
if(RandomBytes(bytes,personalStr))
|
if (RandomBytes(bytes, personalStr)) {
|
||||||
{
|
|
||||||
auto ba = TByteArray::Create(ls);
|
auto ba = TByteArray::Create(ls);
|
||||||
ba->data = bytes;
|
ba->data = bytes;
|
||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject Crypto_PBKDF2(GCList& ls, std::vector<TObject> args)
|
static TObject Crypto_PBKDF2(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::string pass;
|
std::string pass;
|
||||||
TByteArray* bArraySalt;
|
TByteArray *bArraySalt;
|
||||||
int64_t itterations;
|
int64_t itterations;
|
||||||
int64_t keylength;
|
int64_t keylength;
|
||||||
int64_t shanum;
|
int64_t shanum;
|
||||||
if(GetArgument(args,0,pass) && GetArgumentHeap(args,1, bArraySalt) && GetArgument(args,2, itterations) && GetArgument(args,3,keylength) && GetArgument(args,4,shanum))
|
if (GetArgument(args, 0, pass) && GetArgumentHeap(args, 1, bArraySalt) &&
|
||||||
{
|
GetArgument(args, 2, itterations) && GetArgument(args, 3, keylength) &&
|
||||||
|
GetArgument(args, 4, shanum)) {
|
||||||
ShaVersion version = VERSION_SHA384;
|
ShaVersion version = VERSION_SHA384;
|
||||||
|
|
||||||
switch(shanum)
|
switch (shanum) {
|
||||||
{
|
|
||||||
case 1:
|
case 1:
|
||||||
version = VERSION_SHA1;
|
version = VERSION_SHA1;
|
||||||
break;
|
break;
|
||||||
@@ -57,118 +50,117 @@ namespace Tesses::CrossLang
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<uint8_t> key;
|
std::vector<uint8_t> key;
|
||||||
key.resize((size_t)keylength);
|
key.resize((size_t)keylength);
|
||||||
|
|
||||||
if(PBKDF2(key,pass,bArraySalt->data,(long)itterations,version))
|
if (PBKDF2(key, pass, bArraySalt->data, (long)itterations, version)) {
|
||||||
{
|
TByteArray *ba = TByteArray::Create(ls);
|
||||||
TByteArray* ba = TByteArray::Create(ls);
|
|
||||||
ba->data = key;
|
ba->data = key;
|
||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TObject Crypto_Base64Encode(GCList &ls, std::vector<TObject> args) {
|
||||||
|
TByteArray *byteArray;
|
||||||
|
|
||||||
static TObject Crypto_Base64Encode(GCList& ls, std::vector<TObject> args)
|
if (GetArgumentHeap(args, 0, byteArray)) {
|
||||||
{
|
|
||||||
TByteArray* byteArray;
|
|
||||||
|
|
||||||
if(GetArgumentHeap(args,0,byteArray))
|
|
||||||
{
|
|
||||||
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
|
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
static TObject Crypto_Base64Decode(GCList& ls, std::vector<TObject> args)
|
static TObject Crypto_Base64Decode(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::string str;
|
std::string str;
|
||||||
if(GetArgument(args,0,str))
|
if (GetArgument(args, 0, str)) {
|
||||||
{
|
TByteArray *bArray = TByteArray::Create(ls);
|
||||||
TByteArray* bArray = TByteArray::Create(ls);
|
|
||||||
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
|
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
|
||||||
|
|
||||||
return bArray;
|
return bArray;
|
||||||
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
void TStd::RegisterCrypto(GC* gc,TRootEnvironment* env)
|
void TStd::RegisterCrypto(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
{
|
|
||||||
|
|
||||||
env->permissions.canRegisterCrypto=true;
|
env->permissions.canRegisterCrypto = true;
|
||||||
if(!HaveCrypto()) return;
|
if (!HaveCrypto())
|
||||||
|
return;
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
dict->DeclareFunction(gc, "PBKDF2","Hash passwords with PBKDF2",{"pass","salt","itterations","keylen","shanum"},Crypto_PBKDF2);
|
dict->DeclareFunction(gc, "PBKDF2", "Hash passwords with PBKDF2",
|
||||||
dict->DeclareFunction(gc, "RandomBytes","Create bytearray but with random bytes in it instead of zeros (this uses mbedtls by the way)",{"byteCount","personalString"},Crypto_RandomBytes);
|
{"pass", "salt", "itterations", "keylen", "shanum"},
|
||||||
|
Crypto_PBKDF2);
|
||||||
|
dict->DeclareFunction(gc, "RandomBytes",
|
||||||
|
"Create bytearray but with random bytes in it "
|
||||||
|
"instead of zeros (this uses mbedtls by the way)",
|
||||||
|
{"byteCount", "personalString"}, Crypto_RandomBytes);
|
||||||
|
|
||||||
dict->DeclareFunction(gc, "Base64Encode","Base64 encode",{"data"},Crypto_Base64Encode);
|
dict->DeclareFunction(gc, "Base64Encode", "Base64 encode", {"data"},
|
||||||
dict->DeclareFunction(gc, "Base64Decode","Base64 decode",{"str"},Crypto_Base64Decode);
|
Crypto_Base64Encode);
|
||||||
dict->DeclareFunction(gc, "Sha1", "Hash with sha1 algorithm (please don't use sha1 unless you need to)",{"strm"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
dict->DeclareFunction(gc, "Base64Decode", "Base64 decode", {"str"},
|
||||||
TByteArray* baSrc;
|
Crypto_Base64Decode);
|
||||||
|
dict->DeclareFunction(
|
||||||
|
gc, "Sha1",
|
||||||
|
"Hash with sha1 algorithm (please don't use sha1 unless you need to)",
|
||||||
|
{"strm"}, [](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
TByteArray *baSrc;
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||||
|
|
||||||
if(GetArgument(args, 0, sho))
|
if (GetArgument(args, 0, sho)) {
|
||||||
{
|
|
||||||
auto bytes = Sha1::ComputeHash(sho);
|
auto bytes = Sha1::ComputeHash(sho);
|
||||||
auto ba = TByteArray::Create(ls);
|
auto ba = TByteArray::Create(ls);
|
||||||
ba->data = bytes;
|
ba->data = bytes;
|
||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
if(GetArgumentHeap(args,0,baSrc))
|
if (GetArgumentHeap(args, 0, baSrc)) {
|
||||||
{
|
auto bytes =
|
||||||
auto bytes = Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
|
Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
|
||||||
auto ba = TByteArray::Create(ls);
|
auto ba = TByteArray::Create(ls);
|
||||||
ba->data = bytes;
|
ba->data = bytes;
|
||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "Sha256", "Hash with sha256 algorithm",{"strm","$is224"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
dict->DeclareFunction(
|
||||||
TByteArray* baSrc;
|
gc, "Sha256", "Hash with sha256 algorithm", {"strm", "$is224"},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
TByteArray *baSrc;
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||||
bool is224=false;
|
bool is224 = false;
|
||||||
GetArgument(args,1,is224);
|
GetArgument(args, 1, is224);
|
||||||
|
|
||||||
if(GetArgument(args, 0, sho))
|
if (GetArgument(args, 0, sho)) {
|
||||||
{
|
auto bytes = Sha256::ComputeHash(sho, is224);
|
||||||
auto bytes = Sha256::ComputeHash(sho,is224);
|
|
||||||
auto ba = TByteArray::Create(ls);
|
auto ba = TByteArray::Create(ls);
|
||||||
ba->data = bytes;
|
ba->data = bytes;
|
||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
if(GetArgumentHeap(args,0,baSrc))
|
if (GetArgumentHeap(args, 0, baSrc)) {
|
||||||
{
|
auto bytes = Sha256::ComputeHash(baSrc->data.data(),
|
||||||
auto bytes = Sha256::ComputeHash(baSrc->data.data(), baSrc->data.size(), is224);
|
baSrc->data.size(), is224);
|
||||||
auto ba = TByteArray::Create(ls);
|
auto ba = TByteArray::Create(ls);
|
||||||
ba->data = bytes;
|
ba->data = bytes;
|
||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "Sha512", "Hash with sha512 algorithm",{"strm","$is384"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
dict->DeclareFunction(
|
||||||
TByteArray* baSrc;
|
gc, "Sha512", "Hash with sha512 algorithm", {"strm", "$is384"},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
TByteArray *baSrc;
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||||
bool is384=false;
|
bool is384 = false;
|
||||||
GetArgument(args,1,is384);
|
GetArgument(args, 1, is384);
|
||||||
|
|
||||||
if(GetArgument(args, 0, sho))
|
if (GetArgument(args, 0, sho)) {
|
||||||
{
|
auto bytes = Sha512::ComputeHash(sho, is384);
|
||||||
auto bytes = Sha512::ComputeHash(sho,is384);
|
|
||||||
auto ba = TByteArray::Create(ls);
|
auto ba = TByteArray::Create(ls);
|
||||||
ba->data = bytes;
|
ba->data = bytes;
|
||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
if(GetArgumentHeap(args,0,baSrc))
|
if (GetArgumentHeap(args, 0, baSrc)) {
|
||||||
{
|
auto bytes = Sha512::ComputeHash(baSrc->data.data(),
|
||||||
auto bytes = Sha512::ComputeHash(baSrc->data.data(), baSrc->data.size(), is384);
|
baSrc->data.size(), is384);
|
||||||
auto ba = TByteArray::Create(ls);
|
auto ba = TByteArray::Create(ls);
|
||||||
ba->data = bytes;
|
ba->data = bytes;
|
||||||
return ba;
|
return ba;
|
||||||
@@ -178,7 +170,5 @@ namespace Tesses::CrossLang
|
|||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
env->DeclareVariable("Crypto", dict);
|
env->DeclareVariable("Crypto", dict);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
|
|||||||
@@ -1,42 +1,35 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
TObject Dictionary_FindByKey(GCList &ls, std::vector<TObject> args) {
|
||||||
TObject Dictionary_FindByKey(GCList& ls, std::vector<TObject> args)
|
TList *dest = TList::Create(ls);
|
||||||
{
|
|
||||||
TList* dest = TList::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
std::string key;
|
std::string key;
|
||||||
if(GetArgument(args,1,key))
|
if (GetArgument(args, 1, key)) {
|
||||||
{
|
|
||||||
|
|
||||||
std::function<void(TObject)> crawl;
|
std::function<void(TObject)> crawl;
|
||||||
crawl = [&](TObject o) -> void {
|
crawl = [&](TObject o) -> void {
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
TList* list;
|
TList *list;
|
||||||
TAssociativeArray* aa;
|
TAssociativeArray *aa;
|
||||||
if(GetObjectHeap(o,aa))
|
if (GetObjectHeap(o, aa)) {
|
||||||
{
|
|
||||||
std::string k0;
|
std::string k0;
|
||||||
for(auto& item : aa->items)
|
for (auto &item : aa->items) {
|
||||||
{
|
|
||||||
|
|
||||||
if(GetObject(item.first,k0) && k0 == key) dest->Add(item.second);
|
if (GetObject(item.first, k0) && k0 == key)
|
||||||
|
dest->Add(item.second);
|
||||||
crawl(item.second);
|
crawl(item.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(GetObjectHeap(o,dict))
|
if (GetObjectHeap(o, dict)) {
|
||||||
{
|
for (auto &item : dict->items) {
|
||||||
for(auto& item : dict->items)
|
if (item.first == key)
|
||||||
{
|
dest->Add(item.second);
|
||||||
if(item.first == key) dest->Add(item.second);
|
|
||||||
crawl(item.second);
|
crawl(item.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(GetObjectHeap(o,list))
|
if (GetObjectHeap(o, list)) {
|
||||||
{
|
for (auto &item : list->items) {
|
||||||
for(auto& item : list->items)
|
|
||||||
{
|
|
||||||
crawl(item);
|
crawl(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,18 +38,18 @@ namespace Tesses::CrossLang
|
|||||||
}
|
}
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
TObject Dictionary_Items(GCList& ls, std::vector<TObject> args)
|
TObject Dictionary_Items(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
|
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
TDynamicDictionary* dynDict;
|
TDynamicDictionary *dynDict;
|
||||||
if(GetArgumentHeap(args,0,dynDict))
|
if (GetArgumentHeap(args, 0, dynDict)) {
|
||||||
{
|
TDictionary *enumerableItem = TDictionary::Create(ls);
|
||||||
TDictionary* enumerableItem = TDictionary::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
|
|
||||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{},[dynDict](GCList& ls2, std::vector<TObject> args)->TObject {
|
auto fn = TExternalMethod::Create(
|
||||||
|
ls, "Get Enumerator for Dictionary", {},
|
||||||
|
[dynDict](GCList &ls2, std::vector<TObject> args) -> TObject {
|
||||||
return dynDict->GetEnumerator(ls2);
|
return dynDict->GetEnumerator(ls2);
|
||||||
});
|
});
|
||||||
fn->watch.push_back(dynDict);
|
fn->watch.push_back(dynDict);
|
||||||
@@ -66,15 +59,15 @@ namespace Tesses::CrossLang
|
|||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return enumerableItem;
|
return enumerableItem;
|
||||||
|
|
||||||
}
|
}
|
||||||
if(GetArgumentHeap(args,0,dict))
|
if (GetArgumentHeap(args, 0, dict)) {
|
||||||
{
|
TDictionary *enumerableItem = TDictionary::Create(ls);
|
||||||
TDictionary* enumerableItem = TDictionary::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
|
|
||||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{"dict"},[dict](GCList& ls2, std::vector<TObject> args)->TObject {
|
auto fn = TExternalMethod::Create(
|
||||||
return TDictionaryEnumerator::Create(ls2,dict);
|
ls, "Get Enumerator for Dictionary", {"dict"},
|
||||||
|
[dict](GCList &ls2, std::vector<TObject> args) -> TObject {
|
||||||
|
return TDictionaryEnumerator::Create(ls2, dict);
|
||||||
});
|
});
|
||||||
fn->watch.push_back(dict);
|
fn->watch.push_back(dict);
|
||||||
|
|
||||||
@@ -83,67 +76,62 @@ namespace Tesses::CrossLang
|
|||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return enumerableItem;
|
return enumerableItem;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject Dictionary_GetField(GCList& ls, std::vector<TObject> args)
|
TObject Dictionary_GetField(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
TDictionary *dict;
|
||||||
TDictionary* dict;
|
TDynamicDictionary *dynDict;
|
||||||
TDynamicDictionary* dynDict;
|
|
||||||
std::string key;
|
std::string key;
|
||||||
if(GetArgument(args,1,key))
|
if (GetArgument(args, 1, key)) {
|
||||||
{
|
if (GetArgumentHeap(args, 0, dict)) {
|
||||||
if(GetArgumentHeap(args,0,dict))
|
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
auto res = dict->GetValue(key);
|
auto res = dict->GetValue(key);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return res;
|
return res;
|
||||||
}
|
} else if (GetArgumentHeap(args, 0, dynDict)) {
|
||||||
else if(GetArgumentHeap(args,0,dynDict))
|
return dynDict->GetField(ls, key);
|
||||||
{
|
|
||||||
return dynDict->GetField(ls,key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
TObject Dictionary_SetField(GCList& ls, std::vector<TObject> args)
|
TObject Dictionary_SetField(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
TDictionary *dict;
|
||||||
TDictionary* dict;
|
TDynamicDictionary *dynDict;
|
||||||
TDynamicDictionary* dynDict;
|
|
||||||
std::string key;
|
std::string key;
|
||||||
if(args.size() == 3 && GetArgument(args,1,key))
|
if (args.size() == 3 && GetArgument(args, 1, key)) {
|
||||||
{
|
if (GetArgumentHeap(args, 0, dict)) {
|
||||||
if(GetArgumentHeap(args,0,dict))
|
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue(key,args[2]);
|
dict->SetValue(key, args[2]);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
}
|
} else if (GetArgumentHeap(args, 0, dynDict)) {
|
||||||
else if(GetArgumentHeap(args,0,dynDict))
|
dynDict->SetField(ls, key, args[2]);
|
||||||
{
|
|
||||||
dynDict->SetField(ls,key,args[2]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
void TStd::RegisterDictionary(GC* gc,TRootEnvironment* env)
|
void TStd::RegisterDictionary(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
{
|
|
||||||
|
|
||||||
env->permissions.canRegisterDictionary=true;
|
env->permissions.canRegisterDictionary = true;
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
|
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
dict->DeclareFunction(gc, "FindByKey","Scan object recursively, return list of items with key",{"obj","key"}, Dictionary_FindByKey);
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc, "Items","Get Dictionary Item Enumerable, for the each(item : Dictionary.Items(myDict)){item.Key; item.Value;}",{"dictionary"},Dictionary_Items);
|
gc, "FindByKey",
|
||||||
dict->DeclareFunction(gc, "SetField","Set a field in dictionary",{"dict","key","value"},Dictionary_SetField);
|
"Scan object recursively, return list of items with key",
|
||||||
dict->DeclareFunction(gc, "GetField","Get a field in dictionary",{"dict","key"},Dictionary_GetField);
|
{"obj", "key"}, Dictionary_FindByKey);
|
||||||
|
dict->DeclareFunction(gc, "Items",
|
||||||
|
"Get Dictionary Item Enumerable, for the each(item : "
|
||||||
|
"Dictionary.Items(myDict)){item.Key; item.Value;}",
|
||||||
|
{"dictionary"}, Dictionary_Items);
|
||||||
|
dict->DeclareFunction(gc, "SetField", "Set a field in dictionary",
|
||||||
|
{"dict", "key", "value"}, Dictionary_SetField);
|
||||||
|
dict->DeclareFunction(gc, "GetField", "Get a field in dictionary",
|
||||||
|
{"dict", "key"}, Dictionary_GetField);
|
||||||
|
|
||||||
env->DeclareVariable("Dictionary", dict);
|
env->DeclareVariable("Dictionary", dict);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,163 +1,156 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
#include "TessesFramework/Serialization/BitConverter.hpp"
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
using namespace Tesses::Framework::Platform::Environment;
|
||||||
using namespace Tesses::Framework::Platform::Environment;
|
#if defined(_WIN32)
|
||||||
#if defined(_WIN32)
|
static char EnvPathSeperator = ';';
|
||||||
static char EnvPathSeperator=';';
|
#else
|
||||||
#else
|
static char EnvPathSeperator = ':';
|
||||||
static char EnvPathSeperator=':';
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath("");
|
Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath("");
|
||||||
|
|
||||||
|
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir() {
|
||||||
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir()
|
if (!CrossLangConfigPath.path.empty())
|
||||||
{
|
|
||||||
if(!CrossLangConfigPath.path.empty())
|
|
||||||
return CrossLangConfigPath;
|
return CrossLangConfigPath;
|
||||||
|
|
||||||
return SpecialFolders::GetConfig() / "Tesses" / "CrossLang";
|
return SpecialFolders::GetConfig() / "Tesses" / "CrossLang";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TObject Env_getCrossLangConfig(GCList &ls, std::vector<TObject> args) {
|
||||||
|
|
||||||
static TObject Env_getCrossLangConfig(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
return GetCrossLangConfigDir();
|
return GetCrossLangConfigDir();
|
||||||
}
|
}
|
||||||
static TObject Env_getPlatform(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getPlatform(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return Tesses::Framework::Platform::Environment::GetPlatform();
|
return Tesses::Framework::Platform::Environment::GetPlatform();
|
||||||
}
|
}
|
||||||
static TObject Env_GetAt(GCList& ls, std::vector<TObject> args)
|
static TObject Env_GetAt(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::string key;
|
std::string key;
|
||||||
if(GetArgument(args,0,key))
|
if (GetArgument(args, 0, key)) {
|
||||||
{
|
|
||||||
auto v = GetVariable(key);
|
auto v = GetVariable(key);
|
||||||
if(v) return v.value();
|
if (v)
|
||||||
|
return v.value();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject Env_SetAt(GCList& ls, std::vector<TObject> args)
|
static TObject Env_SetAt(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::string key;
|
std::string key;
|
||||||
std::string value;
|
std::string value;
|
||||||
if(GetArgument(args,0,key))
|
if (GetArgument(args, 0, key)) {
|
||||||
{
|
if (GetArgument(args, 1, value)) {
|
||||||
if(GetArgument(args,1,value))
|
SetVariable(key, value);
|
||||||
{
|
|
||||||
SetVariable(key,value);
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
} else {
|
||||||
else
|
SetVariable(key, std::nullopt);
|
||||||
{
|
|
||||||
SetVariable(key,std::nullopt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject Env_getDownloads(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getDownloads(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetDownloads();
|
return SpecialFolders::GetDownloads();
|
||||||
}
|
}
|
||||||
static TObject Env_getMusic(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getMusic(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetMusic();
|
return SpecialFolders::GetMusic();
|
||||||
}
|
}
|
||||||
static TObject Env_getPictures(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getPictures(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetPictures();
|
return SpecialFolders::GetPictures();
|
||||||
}
|
}
|
||||||
static TObject Env_getVideos(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getVideos(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetVideos();
|
return SpecialFolders::GetVideos();
|
||||||
}
|
}
|
||||||
static TObject Env_getDocuments(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getDocuments(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetDocuments();
|
return SpecialFolders::GetDocuments();
|
||||||
}
|
}
|
||||||
static TObject Env_getConfig(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getConfig(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetConfig();
|
return SpecialFolders::GetConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
static TObject Env_getDesktop(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getDesktop(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetDesktop();
|
return SpecialFolders::GetDesktop();
|
||||||
}
|
}
|
||||||
static TObject Env_getState(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getState(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetState();
|
return SpecialFolders::GetState();
|
||||||
}
|
}
|
||||||
static TObject Env_getCache(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getCache(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetCache();
|
return SpecialFolders::GetCache();
|
||||||
}
|
}
|
||||||
static TObject Env_getData(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getData(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetData();
|
return SpecialFolders::GetData();
|
||||||
}
|
}
|
||||||
static TObject Env_getUser(GCList& ls, std::vector<TObject> args)
|
static TObject Env_getUser(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
return SpecialFolders::GetHomeFolder();
|
return SpecialFolders::GetHomeFolder();
|
||||||
}
|
}
|
||||||
static TObject Env_GetRealExecutablePath(GCList& ls, std::vector<TObject> args)
|
static TObject Env_GetRealExecutablePath(GCList &ls,
|
||||||
{
|
std::vector<TObject> args) {
|
||||||
Tesses::Framework::Filesystem::VFSPath p;
|
Tesses::Framework::Filesystem::VFSPath p;
|
||||||
if(GetArgumentAsPath(args,0,p))
|
if (GetArgumentAsPath(args, 0, p)) {
|
||||||
{
|
|
||||||
return GetRealExecutablePath(p);
|
return GetRealExecutablePath(p);
|
||||||
}
|
}
|
||||||
return Tesses::Framework::Filesystem::VFSPath();
|
return Tesses::Framework::Filesystem::VFSPath();
|
||||||
}
|
}
|
||||||
static TObject Env_GetAll(GCList& ls, std::vector<TObject> args)
|
static TObject Env_GetAll(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
TList* list = TList::Create(ls);
|
TList *list = TList::Create(ls);
|
||||||
std::vector<std::pair<std::string, std::string>> env;
|
std::vector<std::pair<std::string, std::string>> env;
|
||||||
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
|
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
|
||||||
for(auto& item : env)
|
for (auto &item : env) {
|
||||||
{
|
list->Add(TDictionary::Create(
|
||||||
list->Add(TDictionary::Create(ls,{TDItem("Key",item.first),TDItem("Value",item.second)}));
|
ls, {TDItem("Key", item.first), TDItem("Value", item.second)}));
|
||||||
}
|
}
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
void TStd::RegisterEnv(GC* gc, TRootEnvironment* env)
|
static TObject Env_getLittleEndian(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
return Tesses::Framework::Serialization::BitConverter::IsLittleEndian();
|
||||||
|
}
|
||||||
|
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
|
|
||||||
env->permissions.canRegisterEnv=true;
|
env->permissions.canRegisterEnv = true;
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
dict->DeclareFunction(gc,"GetAt","Get environment variable", {"key"}, Env_GetAt);
|
dict->DeclareFunction(gc, "GetAt", "Get environment variable", {"key"},
|
||||||
dict->DeclareFunction(gc,"SetAt","Set environment variable", {"key","value"}, Env_SetAt);
|
Env_GetAt);
|
||||||
dict->DeclareFunction(gc,"GetAll","Get all of the environment variables",{},Env_GetAll);
|
dict->DeclareFunction(gc, "SetAt", "Set environment variable",
|
||||||
|
{"key", "value"}, Env_SetAt);
|
||||||
|
dict->DeclareFunction(gc, "GetAll", "Get all of the environment variables",
|
||||||
|
{}, Env_GetAll);
|
||||||
|
|
||||||
dict->DeclareFunction(gc,"getDesktop","Get desktop folder",{},Env_getDesktop);
|
dict->DeclareFunction(gc, "getDesktop", "Get desktop folder", {},
|
||||||
dict->DeclareFunction(gc,"getDownloads","Get downloads folder",{},Env_getDownloads);
|
Env_getDesktop);
|
||||||
dict->DeclareFunction(gc,"getDocuments","Get documents folder",{},Env_getDocuments);
|
dict->DeclareFunction(gc, "getDownloads", "Get downloads folder", {},
|
||||||
dict->DeclareFunction(gc,"getMusic","Get music folder",{},Env_getMusic);
|
Env_getDownloads);
|
||||||
dict->DeclareFunction(gc,"getPictures","Get pictures folder",{},Env_getPictures);
|
dict->DeclareFunction(gc, "getDocuments", "Get documents folder", {},
|
||||||
dict->DeclareFunction(gc,"getVideos","Get videos folder",{},Env_getVideos);
|
Env_getDocuments);
|
||||||
dict->DeclareFunction(gc,"getState","Get state folder",{},Env_getState);
|
dict->DeclareFunction(gc, "getMusic", "Get music folder", {}, Env_getMusic);
|
||||||
dict->DeclareFunction(gc,"getCache","Get cache folder",{},Env_getCache);
|
dict->DeclareFunction(gc, "getPictures", "Get pictures folder", {},
|
||||||
dict->DeclareFunction(gc,"getConfig","Get config folder",{},Env_getConfig);
|
Env_getPictures);
|
||||||
dict->DeclareFunction(gc,"getCrossLangConfig","Get crosslang configuration folder",{}, Env_getCrossLangConfig);
|
dict->DeclareFunction(gc, "getVideos", "Get videos folder", {},
|
||||||
dict->DeclareFunction(gc,"getData","Get data folder",{},Env_getData);
|
Env_getVideos);
|
||||||
dict->DeclareFunction(gc,"getUser","Get user folder",{},Env_getUser);
|
dict->DeclareFunction(gc, "getState", "Get state folder", {}, Env_getState);
|
||||||
dict->DeclareFunction(gc,"getPlatform","Get platform name",{},Env_getPlatform);
|
dict->DeclareFunction(gc, "getCache", "Get cache folder", {}, Env_getCache);
|
||||||
dict->DeclareFunction(gc,"GetRealExecutablePath", "Get the absolute path for executable", {"path"},Env_GetRealExecutablePath);
|
dict->DeclareFunction(gc, "getConfig", "Get config folder", {},
|
||||||
|
Env_getConfig);
|
||||||
|
dict->DeclareFunction(gc, "getCrossLangConfig",
|
||||||
|
"Get crosslang configuration folder", {},
|
||||||
|
Env_getCrossLangConfig);
|
||||||
|
dict->DeclareFunction(gc, "getData", "Get data folder", {}, Env_getData);
|
||||||
|
dict->DeclareFunction(gc, "getUser", "Get user folder", {}, Env_getUser);
|
||||||
|
dict->DeclareFunction(gc, "getPlatform", "Get platform name", {},
|
||||||
|
Env_getPlatform);
|
||||||
|
dict->DeclareFunction(gc, "GetRealExecutablePath",
|
||||||
|
"Get the absolute path for executable", {"path"},
|
||||||
|
Env_GetRealExecutablePath);
|
||||||
|
dict->DeclareFunction(gc, "getLittleEndian",
|
||||||
|
"Is the platform little endian", {},
|
||||||
|
Env_getLittleEndian);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
dict->SetValue("EnvPathSeperator",EnvPathSeperator);
|
dict->SetValue("EnvPathSeperator", EnvPathSeperator);
|
||||||
env->SetVariable("Env", dict);
|
env->SetVariable("Env", dict);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
|
|||||||
@@ -1,29 +1,28 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
static TObject Helpers_CopyToProgress(GCList& ls, std::vector<TObject> args)
|
static TObject Helpers_CopyToProgress(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> src;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> src;
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> dest;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> dest;
|
||||||
double precision=1000.0;
|
double precision = 1000.0;
|
||||||
TCallable* callable;
|
TCallable *callable;
|
||||||
if(GetArgument(args,0,src) && GetArgument(args,1,dest) && GetArgumentHeap(args,2,callable))
|
if (GetArgument(args, 0, src) && GetArgument(args, 1, dest) &&
|
||||||
{
|
GetArgumentHeap(args, 2, callable)) {
|
||||||
GetArgument(args,3,precision);
|
GetArgument(args, 3, precision);
|
||||||
auto len = src->GetLength();
|
auto len = src->GetLength();
|
||||||
callable->Call(ls,{0.0});
|
callable->Call(ls, {0.0});
|
||||||
if(len > 0)
|
if (len > 0) {
|
||||||
{
|
|
||||||
std::vector<uint8_t> buff(1024);
|
std::vector<uint8_t> buff(1024);
|
||||||
int64_t pos=0;
|
int64_t pos = 0;
|
||||||
int curPercent=0;
|
int curPercent = 0;
|
||||||
int lastPercent=0;
|
int lastPercent = 0;
|
||||||
size_t read = 0;
|
size_t read = 0;
|
||||||
do {
|
do {
|
||||||
read = src->ReadBlock(buff.data(),buff.size());
|
read = src->ReadBlock(buff.data(), buff.size());
|
||||||
dest->WriteBlock(buff.data(),read);
|
dest->WriteBlock(buff.data(), read);
|
||||||
|
|
||||||
if(read == 0) break;
|
if (read == 0)
|
||||||
|
break;
|
||||||
pos += (int64_t)read;
|
pos += (int64_t)read;
|
||||||
|
|
||||||
double percent = ((double)pos / len);
|
double percent = ((double)pos / len);
|
||||||
@@ -31,27 +30,24 @@ namespace Tesses::CrossLang {
|
|||||||
|
|
||||||
curPercent = (int)percent;
|
curPercent = (int)percent;
|
||||||
|
|
||||||
|
if (curPercent > lastPercent) {
|
||||||
if(curPercent > lastPercent)
|
|
||||||
{
|
|
||||||
lastPercent = curPercent;
|
lastPercent = curPercent;
|
||||||
callable->Call(ls,{curPercent/precision});
|
callable->Call(ls, {curPercent / precision});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} while (read != 0);
|
||||||
} while(read != 0);
|
} else {
|
||||||
}
|
|
||||||
else {
|
|
||||||
src->CopyTo(dest);
|
src->CopyTo(dest);
|
||||||
|
|
||||||
}
|
}
|
||||||
callable->Call(ls,{1.0});
|
callable->Call(ls, {1.0});
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
|
||||||
void TStd::RegisterHelpers(GC* gc, TRootEnvironment* env)
|
|
||||||
{
|
|
||||||
auto helpers=env->EnsureDictionary(gc,"Helpers");
|
|
||||||
helpers->DeclareFunction(gc,"CopyToProgress","Copy Stream to another (but with progress event)",{"src","dest","progressCB","$precision"},Helpers_CopyToProgress);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
void TStd::RegisterHelpers(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
|
auto helpers = env->EnsureDictionary(gc, "Helpers");
|
||||||
|
helpers->DeclareFunction(gc, "CopyToProgress",
|
||||||
|
"Copy Stream to another (but with progress event)",
|
||||||
|
{"src", "dest", "progressCB", "$precision"},
|
||||||
|
Helpers_CopyToProgress);
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,28 +1,7 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
static TObject FS_CreateArchive(GCList &ls, std::vector<TObject> args) {
|
||||||
namespace Tesses::CrossLang
|
|
||||||
{
|
|
||||||
static TObject FS_MakeFull(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
|
||||||
if(GetArgumentAsPath(args,0,path))
|
|
||||||
{
|
|
||||||
if(path.relative)
|
|
||||||
{
|
|
||||||
Tesses::Framework::Filesystem::LocalFilesystem lfs;
|
|
||||||
auto curDir = std::filesystem::current_path();
|
|
||||||
auto myPath = lfs.SystemToVFSPath(curDir.string()) / path;
|
|
||||||
myPath = myPath.CollapseRelativeParents();
|
|
||||||
return myPath;
|
|
||||||
}
|
|
||||||
return path.CollapseRelativeParents();
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
static TObject FS_CreateArchive(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
|
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||||
@@ -30,321 +9,382 @@ namespace Tesses::CrossLang
|
|||||||
std::string name;
|
std::string name;
|
||||||
std::string version;
|
std::string version;
|
||||||
std::string info;
|
std::string info;
|
||||||
std::string icon="";
|
std::string icon = "";
|
||||||
TVMVersion version2;
|
TVMVersion version2;
|
||||||
|
|
||||||
if(GetArgument(args,0,vfs) && GetArgument(args,1,strm) && GetArgument(args,2,name) && GetArgument(args,4,info) && ((GetArgument(args,3,version) && TVMVersion::TryParse(version,version2)) || GetArgument(args,3,version2)))
|
if (GetArgument(args, 0, vfs) && GetArgument(args, 1, strm) &&
|
||||||
{
|
GetArgument(args, 2, name) && GetArgument(args, 4, info) &&
|
||||||
GetArgument(args,5,icon);
|
((GetArgument(args, 3, version) &&
|
||||||
CrossArchiveCreate(vfs,strm,name,version2,info,icon);
|
TVMVersion::TryParse(version, version2)) ||
|
||||||
|
GetArgument(args, 3, version2))) {
|
||||||
|
GetArgument(args, 5, icon);
|
||||||
|
CrossArchiveCreate(vfs, strm, name, version2, info, icon);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject FS_ExtractArchive(GCList& ls, std::vector<TObject> args)
|
static TObject FS_ExtractArchive(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
|
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||||
|
|
||||||
|
if (GetArgument(args, 0, strm) && GetArgument(args, 1, vfs)) {
|
||||||
|
auto res = CrossArchiveExtract(strm, vfs);
|
||||||
|
|
||||||
if(GetArgument(args,0,strm) && GetArgument(args,1,vfs))
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
{
|
|
||||||
auto res = CrossArchiveExtract(strm,vfs);
|
|
||||||
|
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Name",res.first.first);
|
dict->SetValue("Name", res.first.first);
|
||||||
dict->SetValue("Version",res.first.second.ToString());
|
dict->SetValue("Version", res.first.second.ToString());
|
||||||
dict->SetValue("Info",res.second);
|
dict->SetValue("Info", res.second);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TObject FS_ReadAllText(GCList& ls, std::vector<TObject> args)
|
static TObject FS_ReadAllText(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
|
|
||||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
|
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
|
||||||
{
|
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs, path);
|
||||||
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs,path);
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static TObject FS_ReadAllLines(GCList& ls, std::vector<TObject> args)
|
static TObject FS_ReadAllLines(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
|
|
||||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
|
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
|
||||||
{
|
|
||||||
std::vector<std::string> lines;
|
std::vector<std::string> lines;
|
||||||
|
|
||||||
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs,path,lines);
|
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs, path, lines);
|
||||||
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
auto items = TList::Create(ls);
|
auto items = TList::Create(ls);
|
||||||
for(auto& l : lines) { items->Add(l);}
|
for (auto &l : lines) {
|
||||||
|
items->Add(l);
|
||||||
|
}
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TObject FS_ReadAllBytes(GCList& ls, std::vector<TObject> args)
|
static TObject FS_ReadAllBytes(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
|
|
||||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
|
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
|
||||||
{
|
|
||||||
auto res = TByteArray::Create(ls);
|
auto res = TByteArray::Create(ls);
|
||||||
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs,path,res->data);
|
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs, path,
|
||||||
|
res->data);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TObject FS_WriteAllLines(GCList &ls, std::vector<TObject> args) {
|
||||||
static TObject FS_WriteAllLines(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
|
|
||||||
|
TList *lines;
|
||||||
TList* lines;
|
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
|
||||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,lines))
|
GetArgumentHeap(args, 2, lines)) {
|
||||||
{
|
|
||||||
std::vector<std::string> content;
|
std::vector<std::string> content;
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for(auto& item : lines->items)
|
for (auto &item : lines->items) {
|
||||||
{
|
if (std::holds_alternative<std::string>(item))
|
||||||
if(std::holds_alternative<std::string>(item))
|
|
||||||
content.push_back(std::get<std::string>(item));
|
content.push_back(std::get<std::string>(item));
|
||||||
}
|
}
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs,path,content);
|
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs, path,
|
||||||
|
content);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject FS_WriteAllText(GCList& ls, std::vector<TObject> args)
|
static TObject FS_WriteAllText(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
|
|
||||||
|
|
||||||
std::string content;
|
std::string content;
|
||||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content))
|
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
|
||||||
{
|
GetArgument(args, 2, content)) {
|
||||||
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs,path,content);
|
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs, path,
|
||||||
|
content);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject FS_WriteAllBytes(GCList& ls, std::vector<TObject> args)
|
static TObject FS_WriteAllBytes(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
|
|
||||||
TByteArray* bArray;
|
TByteArray *bArray;
|
||||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,bArray))
|
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
|
||||||
{
|
GetArgumentHeap(args, 2, bArray)) {
|
||||||
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs,path,bArray->data);
|
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs, path,
|
||||||
|
bArray->data);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TObject FS_getCurrentPath(GCList& ls, std::vector<TObject> args)
|
class FS_Watcher : public TNativeObject {
|
||||||
{
|
|
||||||
return Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory();
|
|
||||||
}
|
|
||||||
static TObject FS_setCurrentPath(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
|
||||||
if(GetArgumentAsPath(args,0,path))
|
|
||||||
Tesses::Framework::Filesystem::VFSPath::SetAbsoluteCurrentDirectory(path);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FS_Watcher : public TNativeObject {
|
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
|
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
|
||||||
|
|
||||||
FS_Watcher(std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher): watcher(watcher)
|
FS_Watcher(
|
||||||
{}
|
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher)
|
||||||
|
: watcher(watcher) {}
|
||||||
|
|
||||||
TObject CallMethod(GCList& ls, std::string name, std::vector<TObject> args)
|
TObject CallMethod(GCList &ls, std::string name,
|
||||||
{
|
std::vector<TObject> args) {
|
||||||
if(name == "getPath")
|
if (name == "getPath") {
|
||||||
{
|
|
||||||
return watcher->GetPath();
|
return watcher->GetPath();
|
||||||
}
|
}
|
||||||
if(name == "getFilesystem")
|
if (name == "getFilesystem") {
|
||||||
{
|
|
||||||
return watcher->GetFilesystem();
|
return watcher->GetFilesystem();
|
||||||
}
|
}
|
||||||
if(name == "setEnabled")
|
if (name == "setEnabled") {
|
||||||
{
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
if(GetArgument(args,0,enabled))
|
if (GetArgument(args, 0, enabled)) {
|
||||||
{
|
|
||||||
watcher->SetEnabled(enabled);
|
watcher->SetEnabled(enabled);
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(name == "getEnabled")
|
if (name == "getEnabled") {
|
||||||
{
|
|
||||||
return watcher->GetEnabled();
|
return watcher->GetEnabled();
|
||||||
}
|
}
|
||||||
if(name == "setEvents")
|
if (name == "setEvents") {
|
||||||
{
|
|
||||||
int64_t evts;
|
int64_t evts;
|
||||||
if(GetArgument(args,0,evts))
|
if (GetArgument(args, 0, evts)) {
|
||||||
{
|
watcher->events =
|
||||||
watcher->events = (Tesses::Framework::Filesystem::FSWatcherEventType)evts;
|
(Tesses::Framework::Filesystem::FSWatcherEventType)evts;
|
||||||
return evts;
|
return evts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(name == "getEvents")
|
if (name == "getEvents") {
|
||||||
{
|
|
||||||
return (int64_t)watcher->events;
|
return (int64_t)watcher->events;
|
||||||
}
|
}
|
||||||
if(name == "setCallback")
|
if (name == "setCallback") {
|
||||||
{
|
TCallable *callable = nullptr;
|
||||||
TCallable* callable=nullptr;
|
if (GetArgumentHeap(args, 0, callable)) {
|
||||||
if(GetArgumentHeap(args,0,callable))
|
auto markedT = CreateMarkedTObject(ls, callable);
|
||||||
{
|
watcher->event =
|
||||||
auto markedT = CreateMarkedTObject(ls,callable);
|
[markedT](
|
||||||
watcher->event = [markedT](Tesses::Framework::Filesystem::FSWatcherEvent& evt) -> void {
|
Tesses::Framework::Filesystem::FSWatcherEvent &evt)
|
||||||
|
-> void {
|
||||||
GCList ls(markedT->GetGC());
|
GCList ls(markedT->GetGC());
|
||||||
TObject o = markedT->GetObject();
|
TObject o = markedT->GetObject();
|
||||||
TCallable* callable;
|
TCallable *callable;
|
||||||
if(GetObjectHeap(o,callable))
|
if (GetObjectHeap(o, callable)) {
|
||||||
{
|
auto isEvent = TExternalMethod::Create(
|
||||||
auto isEvent = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
|
ls, "", {},
|
||||||
{
|
[evt](GCList &ls,
|
||||||
|
std::vector<TObject> args) -> TObject {
|
||||||
int64_t n;
|
int64_t n;
|
||||||
if(GetArgument(args,0,n))
|
if (GetArgument(args, 0, n)) {
|
||||||
{
|
|
||||||
auto myevt = evt;
|
auto myevt = evt;
|
||||||
return myevt.IsEvent((Tesses::Framework::Filesystem::FSWatcherEventType)n);
|
return myevt.IsEvent(
|
||||||
|
(Tesses::Framework::Filesystem::
|
||||||
|
FSWatcherEventType)n);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
auto toString = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
|
auto toString = TExternalMethod::Create(
|
||||||
{
|
ls, "", {},
|
||||||
|
[evt](GCList &ls,
|
||||||
|
std::vector<TObject> args) -> TObject {
|
||||||
auto myevt = evt;
|
auto myevt = evt;
|
||||||
return myevt.ToString();
|
return myevt.ToString();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto dict = TDictionary::Create(ls, {TDItem("IsDirectory",evt.isDir),TDItem("Type",(int64_t)evt.type),TDItem("Source",evt.src), TDItem("Destination",evt.dest),TDItem("ToString",toString),TDItem("IsEvent",isEvent)});
|
auto dict = TDictionary::Create(
|
||||||
callable->Call(ls,{dict});
|
ls, {TDItem("IsDirectory", evt.isDir),
|
||||||
|
TDItem("Type", (int64_t)evt.type),
|
||||||
|
TDItem("Source", evt.src),
|
||||||
|
TDItem("Destination", evt.dest),
|
||||||
|
TDItem("ToString", toString),
|
||||||
|
TDItem("IsEvent", isEvent)});
|
||||||
|
callable->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} else {
|
||||||
else {
|
watcher->event = nullptr;
|
||||||
watcher->event=nullptr;
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if(name == "Start")
|
if (name == "Start") {
|
||||||
{
|
|
||||||
watcher->SetEnabled(true);
|
watcher->SetEnabled(true);
|
||||||
}
|
}
|
||||||
if(name == "Stop")
|
if (name == "Stop") {
|
||||||
{
|
|
||||||
watcher->SetEnabled(false);
|
watcher->SetEnabled(false);
|
||||||
}
|
}
|
||||||
if(name == "ToString")
|
if (name == "ToString") {
|
||||||
{
|
|
||||||
return "FSWatcher";
|
return "FSWatcher";
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TypeName() {
|
std::string TypeName() { return "FSWatcher"; }
|
||||||
return "FSWatcher";
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TObject New_FSWatcher(GCList& ls, std::vector<TObject> args)
|
TObject New_FSWatcher(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
|
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
|
||||||
{
|
return TNativeObject::Create<FS_Watcher>(
|
||||||
return TNativeObject::Create<FS_Watcher>(ls,Tesses::Framework::Filesystem::FSWatcher::Create(vfs,path));
|
ls, Tesses::Framework::Filesystem::FSWatcher::Create(vfs, path));
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
void TStd::RegisterIO(std::shared_ptr<GC> gc, TRootEnvironment *env,
|
||||||
|
bool enable) {
|
||||||
|
if (enable) {
|
||||||
|
RegisterIO(
|
||||||
|
gc, env,
|
||||||
|
std::make_shared<Tesses::Framework::Filesystem::RelativeFilesystem>(
|
||||||
|
Tesses::Framework::Filesystem::LocalFS,
|
||||||
|
Tesses::Framework::Filesystem::VFSPath::
|
||||||
|
GetAbsoluteCurrentDirectory()));
|
||||||
|
} else {
|
||||||
|
RegisterIO(gc, env, nullptr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
void TStd::RegisterIO(
|
||||||
|
std::shared_ptr<GC> gc, TRootEnvironment *env,
|
||||||
|
std::shared_ptr<Tesses::Framework::Filesystem::RelativeFilesystem> fs) {
|
||||||
|
|
||||||
void TStd::RegisterIO(GC* gc,TRootEnvironment* env,bool enableLocalFilesystem)
|
env->permissions.canRegisterIO = true;
|
||||||
{
|
env->permissions.localfs = fs;
|
||||||
|
|
||||||
env->permissions.canRegisterIO=true;
|
|
||||||
env->permissions.canRegisterLocalFS = enableLocalFilesystem;
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
auto newDict = env->EnsureDictionary(gc, "New");
|
auto newDict = env->EnsureDictionary(gc, "New");
|
||||||
newDict->DeclareFunction(gc,"FSWatcher","Watch a file/directory",{"vfs","path"}, New_FSWatcher);
|
newDict->DeclareFunction(gc, "FSWatcher", "Watch a file/directory",
|
||||||
auto dict = env->EnsureDictionary(gc,"FS");
|
{"vfs", "path"}, New_FSWatcher);
|
||||||
dict->SetValue("SEEK_SET",(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
|
auto dict = env->EnsureDictionary(gc, "FS");
|
||||||
dict->SetValue("SEEK_CUR",(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
|
dict->SetValue("SEEK_SET",
|
||||||
dict->SetValue("SEEK_END",(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
|
(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||||
dict->SetValue("FSWatcherEvents",TDictionary::Create(ls,
|
dict->SetValue("SEEK_CUR",
|
||||||
{
|
(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
|
||||||
TDItem("None", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::None),
|
dict->SetValue("SEEK_END",
|
||||||
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Accessed),
|
(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
|
||||||
TDItem("AttributeChanged", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::AttributeChanged),
|
dict->SetValue(
|
||||||
TDItem("Writen", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
|
"FSWatcherEvents",
|
||||||
TDItem("Read", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Read),
|
TDictionary::Create(
|
||||||
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Created),
|
ls,
|
||||||
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Deleted),
|
{TDItem(
|
||||||
TDItem("WatchEntryDeleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryDeleted),
|
"None",
|
||||||
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Modified),
|
(int64_t)
|
||||||
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryMoved),
|
Tesses::Framework::Filesystem::FSWatcherEventType::None),
|
||||||
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveOld),
|
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::
|
||||||
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveNew),
|
FSWatcherEventType::Accessed),
|
||||||
TDItem("Opened", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
|
TDItem("AttributeChanged",
|
||||||
TDItem("Closed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
|
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
|
||||||
TDItem("Moved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
|
AttributeChanged),
|
||||||
TDItem("All", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::All)
|
TDItem(
|
||||||
|
"Writen",
|
||||||
|
(int64_t)
|
||||||
|
Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
|
||||||
|
TDItem(
|
||||||
|
"Read",
|
||||||
|
(int64_t)
|
||||||
|
Tesses::Framework::Filesystem::FSWatcherEventType::Read),
|
||||||
|
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::
|
||||||
|
FSWatcherEventType::Created),
|
||||||
|
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::
|
||||||
|
FSWatcherEventType::Deleted),
|
||||||
|
TDItem("WatchEntryDeleted",
|
||||||
|
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
|
||||||
|
WatchEntryDeleted),
|
||||||
|
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::
|
||||||
|
FSWatcherEventType::Modified),
|
||||||
|
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::
|
||||||
|
FSWatcherEventType::WatchEntryMoved),
|
||||||
|
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::
|
||||||
|
FSWatcherEventType::MoveOld),
|
||||||
|
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::
|
||||||
|
FSWatcherEventType::MoveNew),
|
||||||
|
TDItem(
|
||||||
|
"Opened",
|
||||||
|
(int64_t)
|
||||||
|
Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
|
||||||
|
TDItem(
|
||||||
|
"Closed",
|
||||||
|
(int64_t)
|
||||||
|
Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
|
||||||
|
TDItem(
|
||||||
|
"Moved",
|
||||||
|
(int64_t)
|
||||||
|
Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
|
||||||
|
TDItem(
|
||||||
|
"All",
|
||||||
|
(int64_t)
|
||||||
|
Tesses::Framework::Filesystem::FSWatcherEventType::All)}));
|
||||||
|
|
||||||
|
if (fs) {
|
||||||
|
|
||||||
|
dict->SetValue("Local", fs);
|
||||||
|
dict->DeclareFunction(
|
||||||
|
gc, "MakeFull", "Make absolute path from relative path", {"path"},
|
||||||
|
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
|
if (GetArgumentAsPath(args, 0, path)) {
|
||||||
|
if (path.relative) {
|
||||||
|
auto myPath = fs->GetWorking() / path;
|
||||||
|
myPath = myPath.CollapseRelativeParents();
|
||||||
|
return myPath;
|
||||||
}
|
}
|
||||||
));
|
return path.CollapseRelativeParents();
|
||||||
|
}
|
||||||
if(enableLocalFilesystem)
|
return nullptr;
|
||||||
{
|
});
|
||||||
|
dict->DeclareFunction(
|
||||||
|
gc, "getCurrentPath", "Get current path", {},
|
||||||
dict->SetValue("Local", Tesses::Framework::Filesystem::LocalFS);
|
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},FS_MakeFull);
|
return fs->GetWorking();
|
||||||
dict->DeclareFunction(gc,"getCurrentPath","Get current path",{},FS_getCurrentPath);
|
});
|
||||||
dict->DeclareFunction(gc,"setCurrentPath","Set the current path",{"path"},FS_setCurrentPath);
|
dict->DeclareFunction(
|
||||||
|
gc, "setCurrentPath", "Set the current path", {"path"},
|
||||||
|
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
|
if (GetArgumentAsPath(args, 0, path)) {
|
||||||
|
if (path.relative) {
|
||||||
|
fs->SetWorking(path.MakeAbsolute(fs->GetWorking()));
|
||||||
|
} else {
|
||||||
|
fs->SetWorking(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dict->DeclareFunction(gc, "ReadAllText","Read all text from file", {"fs","filename"},FS_ReadAllText);
|
dict->DeclareFunction(gc, "ReadAllText", "Read all text from file",
|
||||||
dict->DeclareFunction(gc, "WriteAllText","Write all text to file", {"fs","filename","content"},FS_WriteAllText);
|
{"fs", "filename"}, FS_ReadAllText);
|
||||||
|
dict->DeclareFunction(gc, "WriteAllText", "Write all text to file",
|
||||||
|
{"fs", "filename", "content"}, FS_WriteAllText);
|
||||||
|
|
||||||
dict->DeclareFunction(gc, "ReadAllLines","Read all lines from file", {"fs","filename"},FS_ReadAllLines);
|
dict->DeclareFunction(gc, "ReadAllLines", "Read all lines from file",
|
||||||
dict->DeclareFunction(gc, "WriteAllLines","Write all lines to file", {"fs","filename","lines"},FS_WriteAllLines);
|
{"fs", "filename"}, FS_ReadAllLines);
|
||||||
|
dict->DeclareFunction(gc, "WriteAllLines", "Write all lines to file",
|
||||||
|
{"fs", "filename", "lines"}, FS_WriteAllLines);
|
||||||
|
|
||||||
dict->DeclareFunction(gc, "ReadAllBytes","Read all bytes from file", {"fs","filename"},FS_ReadAllBytes);
|
dict->DeclareFunction(gc, "ReadAllBytes", "Read all bytes from file",
|
||||||
dict->DeclareFunction(gc, "WriteAllBytes","Write all bytes to file", {"fs","filename","content"},FS_WriteAllBytes);
|
{"fs", "filename"}, FS_ReadAllBytes);
|
||||||
|
dict->DeclareFunction(gc, "WriteAllBytes", "Write all bytes to file",
|
||||||
|
{"fs", "filename", "content"}, FS_WriteAllBytes);
|
||||||
|
|
||||||
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",{"fs","strm","name","version","info"},FS_CreateArchive);
|
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",
|
||||||
dict->DeclareFunction(gc,"ExtractArchive", "Extract a crvm archive",{"strm","vfs"},FS_ExtractArchive);
|
{"fs", "strm", "name", "version", "info"},
|
||||||
|
FS_CreateArchive);
|
||||||
|
dict->DeclareFunction(gc, "ExtractArchive", "Extract a crvm archive",
|
||||||
|
{"strm", "vfs"}, FS_ExtractArchive);
|
||||||
|
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -2,206 +2,193 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
using namespace Tesses::Framework::Serialization::Json;
|
using namespace Tesses::Framework::Serialization::Json;
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
|
||||||
|
|
||||||
static bool IsValidForJson(TObject v)
|
static bool IsValidForJson(TObject v) {
|
||||||
{
|
if (std::holds_alternative<std::nullptr_t>(v))
|
||||||
if(std::holds_alternative<std::nullptr_t>(v)) return true;
|
return true;
|
||||||
|
|
||||||
if(std::holds_alternative<int64_t>(v)) return true;
|
if (std::holds_alternative<int64_t>(v))
|
||||||
|
return true;
|
||||||
|
|
||||||
if(std::holds_alternative<double>(v)) return true;
|
if (std::holds_alternative<double>(v))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (std::holds_alternative<bool>(v))
|
||||||
|
return true;
|
||||||
|
|
||||||
if(std::holds_alternative<bool>(v)) return true;
|
if (std::holds_alternative<std::string>(v))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||||
if(std::holds_alternative<std::string>(v)) return true;
|
|
||||||
|
|
||||||
|
|
||||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
|
||||||
{
|
|
||||||
auto res = std::get<THeapObjectHolder>(v);
|
auto res = std::get<THeapObjectHolder>(v);
|
||||||
auto ls = dynamic_cast<TList*>(res.obj);
|
auto ls = dynamic_cast<TList *>(res.obj);
|
||||||
auto dict = dynamic_cast<TDictionary*>(res.obj);
|
auto dict = dynamic_cast<TDictionary *>(res.obj);
|
||||||
if(ls != nullptr) return true;
|
if (ls != nullptr)
|
||||||
if(dict != nullptr) return true;
|
return true;
|
||||||
|
if (dict != nullptr)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static JToken JsonSerialize(TObject v)
|
static JToken JsonSerialize(TObject v) {
|
||||||
{
|
if (std::holds_alternative<std::nullptr_t>(v))
|
||||||
if(std::holds_alternative<std::nullptr_t>(v)) return nullptr;
|
return nullptr;
|
||||||
if(std::holds_alternative<int64_t>(v)) return std::get<int64_t>(v);
|
if (std::holds_alternative<int64_t>(v))
|
||||||
if(std::holds_alternative<double>(v)) return std::get<double>(v);
|
return std::get<int64_t>(v);
|
||||||
if(std::holds_alternative<bool>(v)) return std::get<bool>(v);
|
if (std::holds_alternative<double>(v))
|
||||||
if(std::holds_alternative<std::string>(v)) return std::get<std::string>(v);
|
return std::get<double>(v);
|
||||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
if (std::holds_alternative<bool>(v))
|
||||||
{
|
return std::get<bool>(v);
|
||||||
|
if (std::holds_alternative<std::string>(v))
|
||||||
|
return std::get<std::string>(v);
|
||||||
|
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||||
auto obj = std::get<THeapObjectHolder>(v).obj;
|
auto obj = std::get<THeapObjectHolder>(v).obj;
|
||||||
auto ls = dynamic_cast<TList*>(obj);
|
auto ls = dynamic_cast<TList *>(obj);
|
||||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
auto dict = dynamic_cast<TDictionary *>(obj);
|
||||||
|
|
||||||
if(ls != nullptr)
|
if (ls != nullptr) {
|
||||||
{
|
|
||||||
JArray items;
|
JArray items;
|
||||||
for(int64_t i = 0; i < ls->Count(); i++)
|
for (int64_t i = 0; i < ls->Count(); i++) {
|
||||||
{
|
|
||||||
auto val = ls->Get(i);
|
auto val = ls->Get(i);
|
||||||
if(IsValidForJson(val))
|
if (IsValidForJson(val))
|
||||||
items.Add(JsonSerialize(val));
|
items.Add(JsonSerialize(val));
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dict != nullptr)
|
if (dict != nullptr) {
|
||||||
{
|
|
||||||
JObject obj;
|
JObject obj;
|
||||||
for(auto item : dict->items)
|
for (auto item : dict->items) {
|
||||||
{
|
if (IsValidForJson(item.second))
|
||||||
if(IsValidForJson(item.second))
|
obj.SetValue(item.first, JsonSerialize(item.second));
|
||||||
obj.SetValue(item.first,JsonSerialize(item.second));
|
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject JsonEncode(GCList& ls2, std::vector<TObject> args)
|
static TObject JsonEncode(GCList &ls2, std::vector<TObject> args) {
|
||||||
{
|
if (args.size() >= 1) {
|
||||||
if(args.size() >= 1)
|
bool indent =
|
||||||
{
|
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
|
||||||
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
|
std::get<bool>(args[1]));
|
||||||
|
|
||||||
auto json = JsonSerialize(args[0]);
|
auto json = JsonSerialize(args[0]);
|
||||||
|
|
||||||
return Json::Encode(json,indent);
|
return Json::Encode(json, indent);
|
||||||
}
|
}
|
||||||
return "null";
|
return "null";
|
||||||
}
|
}
|
||||||
static TObject JsonDocEncode(GCList& ls2, std::vector<TObject> args)
|
static TObject JsonDocEncode(GCList &ls2, std::vector<TObject> args) {
|
||||||
{
|
if (args.size() >= 1) {
|
||||||
if(args.size() >= 1)
|
bool indent =
|
||||||
{
|
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
|
||||||
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
|
std::get<bool>(args[1]));
|
||||||
|
|
||||||
auto json = JsonSerialize(args[0]);
|
auto json = JsonSerialize(args[0]);
|
||||||
JArray ar;
|
JArray ar;
|
||||||
if(TryGetJToken(json,ar))
|
if (TryGetJToken(json, ar))
|
||||||
return Json::DocEncode(ar,indent);
|
return Json::DocEncode(ar, indent);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
static TObject JsonDeserialize(GCList& ls2,JToken json)
|
static TObject JsonDeserialize(GCList &ls2, JToken json) {
|
||||||
{
|
if (std::holds_alternative<JUndefined>(json))
|
||||||
if(std::holds_alternative<JUndefined>(json)) return nullptr;
|
return nullptr;
|
||||||
if(std::holds_alternative<std::nullptr_t>(json)) return nullptr;
|
if (std::holds_alternative<std::nullptr_t>(json))
|
||||||
|
return nullptr;
|
||||||
bool b;
|
bool b;
|
||||||
int64_t _i64;
|
int64_t _i64;
|
||||||
double _f64;
|
double _f64;
|
||||||
std::string str;
|
std::string str;
|
||||||
JArray arr;
|
JArray arr;
|
||||||
JObject obj;
|
JObject obj;
|
||||||
if(TryGetJToken(json,b)) return b;
|
if (TryGetJToken(json, b))
|
||||||
if(TryGetJToken(json,_i64)) return _i64;
|
return b;
|
||||||
if(TryGetJToken(json,_f64)) return _f64;
|
if (TryGetJToken(json, _i64))
|
||||||
if(TryGetJToken(json,str)) return str;
|
return _i64;
|
||||||
if(TryGetJToken(json,arr))
|
if (TryGetJToken(json, _f64))
|
||||||
{
|
return _f64;
|
||||||
TList* ls = TList::Create(ls2);
|
if (TryGetJToken(json, str))
|
||||||
|
return str;
|
||||||
|
if (TryGetJToken(json, arr)) {
|
||||||
|
TList *ls = TList::Create(ls2);
|
||||||
|
|
||||||
for(auto& item : arr)
|
for (auto &item : arr) {
|
||||||
{
|
auto itemRes = JsonDeserialize(ls2, item);
|
||||||
auto itemRes = JsonDeserialize(ls2,item);
|
|
||||||
ls2.GetGC()->BarrierBegin();
|
ls2.GetGC()->BarrierBegin();
|
||||||
ls->Add(itemRes);
|
ls->Add(itemRes);
|
||||||
ls2.GetGC()->BarrierEnd();
|
ls2.GetGC()->BarrierEnd();
|
||||||
}
|
}
|
||||||
return ls;
|
return ls;
|
||||||
}
|
}
|
||||||
if(TryGetJToken(json,obj))
|
if (TryGetJToken(json, obj)) {
|
||||||
{
|
|
||||||
|
|
||||||
TDictionary* dict = TDictionary::Create(ls2);
|
TDictionary *dict = TDictionary::Create(ls2);
|
||||||
|
|
||||||
|
for (auto &item : obj) {
|
||||||
|
|
||||||
for(auto& item : obj)
|
auto itemRes = JsonDeserialize(ls2, item.second);
|
||||||
{
|
|
||||||
|
|
||||||
auto itemRes = JsonDeserialize(ls2,item.second);
|
|
||||||
ls2.GetGC()->BarrierBegin();
|
ls2.GetGC()->BarrierBegin();
|
||||||
dict->SetValue(item.first,itemRes);
|
dict->SetValue(item.first, itemRes);
|
||||||
ls2.GetGC()->BarrierEnd();
|
ls2.GetGC()->BarrierEnd();
|
||||||
}
|
}
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
static TObject JsonDecode(GCList& ls2,std::vector<TObject> args)
|
static TObject JsonDecode(GCList &ls2, std::vector<TObject> args) {
|
||||||
{
|
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
|
||||||
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
return JsonDeserialize(ls2, Json::Decode(std::get<std::string>(args[0])));
|
|
||||||
|
|
||||||
|
|
||||||
|
return JsonDeserialize(ls2,
|
||||||
|
Json::Decode(std::get<std::string>(args[0])));
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
static TObject JsonDocDecode(GCList& ls2,std::vector<TObject> args)
|
static TObject JsonDocDecode(GCList &ls2, std::vector<TObject> args) {
|
||||||
{
|
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
|
||||||
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
return JsonDeserialize(ls2, Json::DocDecode(std::get<std::string>(args[0])));
|
|
||||||
|
|
||||||
|
|
||||||
|
return JsonDeserialize(ls2,
|
||||||
|
Json::DocDecode(std::get<std::string>(args[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
std::string Json_Encode(TObject o,bool indent)
|
std::string Json_Encode(TObject o, bool indent) {
|
||||||
{
|
return Json::Encode(JsonSerialize(o), indent);
|
||||||
return Json::Encode(JsonSerialize(o),indent);
|
}
|
||||||
}
|
TObject Json_Decode(GCList ls, std::string str) {
|
||||||
TObject Json_Decode(GCList ls,std::string str)
|
return JsonDeserialize(ls, Json::Decode(str));
|
||||||
{
|
}
|
||||||
return JsonDeserialize(ls,Json::Decode(str));
|
std::string Json_DocEncode(TObject o, bool indent) {
|
||||||
}
|
|
||||||
std::string Json_DocEncode(TObject o,bool indent)
|
|
||||||
{
|
|
||||||
auto obj = JsonSerialize(o);
|
auto obj = JsonSerialize(o);
|
||||||
JArray ls;
|
JArray ls;
|
||||||
if(TryGetJToken(obj,ls))
|
if (TryGetJToken(obj, ls))
|
||||||
return Json::DocEncode(ls,indent);
|
return Json::DocEncode(ls, indent);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
TObject Json_DocDecode(GCList ls,std::string str)
|
TObject Json_DocDecode(GCList ls, std::string str) {
|
||||||
{
|
return JsonDeserialize(ls, Json::DocDecode(str));
|
||||||
return JsonDeserialize(ls,Json::DocDecode(str));
|
}
|
||||||
}
|
void TStd::RegisterJson(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
void TStd::RegisterJson(GC* gc,TRootEnvironment* env)
|
|
||||||
{
|
|
||||||
|
|
||||||
env->permissions.canRegisterJSON=true;
|
env->permissions.canRegisterJSON = true;
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
dict->DeclareFunction(gc, "Decode","Deserialize Json",{"jsonString"},JsonDecode);
|
dict->DeclareFunction(gc, "Decode", "Deserialize Json", {"jsonString"},
|
||||||
dict->DeclareFunction(gc, "Encode","Serialize Json",{"any","$indent"},JsonEncode);
|
JsonDecode);
|
||||||
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc", {"jsonDocString"},JsonDocDecode);
|
dict->DeclareFunction(gc, "Encode", "Serialize Json", {"any", "$indent"},
|
||||||
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc", {"ls","$indent"},JsonDocEncode);
|
JsonEncode);
|
||||||
|
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc",
|
||||||
|
{"jsonDocString"}, JsonDocDecode);
|
||||||
|
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc",
|
||||||
|
{"ls", "$indent"}, JsonDocEncode);
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
env->DeclareVariable("Json", dict);
|
env->DeclareVariable("Json", dict);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,84 +1,75 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
#if defined(GEKKO)
|
#if defined(GEKKO)
|
||||||
#include <ogcsys.h>
|
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
#include <ogc/pad.h>
|
#include <ogc/pad.h>
|
||||||
|
#include <ogcsys.h>
|
||||||
#if defined(HW_RVL)
|
#if defined(HW_RVL)
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
#if defined(GEKKO)
|
||||||
#if defined(GEKKO)
|
#if defined(HW_RVL)
|
||||||
#if defined(HW_RVL)
|
static TObject OGC_WPAD_ScanPads(GCList &ls, std::vector<TObject> args) {
|
||||||
static TObject OGC_WPAD_ScanPads(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
return (int64_t)WPAD_ScanPads();
|
return (int64_t)WPAD_ScanPads();
|
||||||
}
|
}
|
||||||
static TObject OGC_WPAD_ButtonsUp(GCList& ls, std::vector<TObject> args)
|
static TObject OGC_WPAD_ButtonsUp(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
int64_t chan;
|
int64_t chan;
|
||||||
if(GetArgument(args,0,chan))
|
if (GetArgument(args, 0, chan))
|
||||||
return (int64_t)WPAD_ButtonsUp((int)chan);
|
return (int64_t)WPAD_ButtonsUp((int)chan);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static TObject OGC_WPAD_ButtonsDown(GCList& ls, std::vector<TObject> args)
|
static TObject OGC_WPAD_ButtonsDown(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
int64_t chan;
|
int64_t chan;
|
||||||
if(GetArgument(args,0,chan))
|
if (GetArgument(args, 0, chan))
|
||||||
return (int64_t)WPAD_ButtonsDown((int)chan);
|
return (int64_t)WPAD_ButtonsDown((int)chan);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static TObject OGC_WPAD_ButtonsHeld(GCList& ls, std::vector<TObject> args)
|
static TObject OGC_WPAD_ButtonsHeld(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
int64_t chan;
|
int64_t chan;
|
||||||
if(GetArgument(args,0,chan))
|
if (GetArgument(args, 0, chan))
|
||||||
return (int64_t)WPAD_ButtonsDown((int)chan);
|
return (int64_t)WPAD_ButtonsDown((int)chan);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static TObject OGC_WPAD_BatteryLevel(GCList& ls, std::vector<TObject> args)
|
static TObject OGC_WPAD_BatteryLevel(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
int64_t chan;
|
int64_t chan;
|
||||||
if(GetArgument(args,0,chan))
|
if (GetArgument(args, 0, chan))
|
||||||
return (int64_t)WPAD_BatteryLevel((int)chan);
|
return (int64_t)WPAD_BatteryLevel((int)chan);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void TStd::RegisterOGC(GC* gc, TRootEnvironment* env)
|
void TStd::RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
{
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
#if defined(GEKKO)
|
#if defined(GEKKO)
|
||||||
|
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
|
|
||||||
TDictionary* dict_ogc_pad = TDictionary::Create(ls);
|
TDictionary *dict_ogc_pad = TDictionary::Create(ls);
|
||||||
#if defined(HW_RVL)
|
#if defined(HW_RVL)
|
||||||
TDictionary* dict_rvl_wpad = TDictionary::Create(ls);
|
TDictionary *dict_rvl_wpad = TDictionary::Create(ls);
|
||||||
dict_rvl_wpad->DeclareFunction(gc, "ScanPads","Scan wiimotes",{},OGC_WPAD_ScanPads);
|
dict_rvl_wpad->DeclareFunction(gc, "ScanPads", "Scan wiimotes", {},
|
||||||
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown","Is button down",{"pad"},OGC_WPAD_ButtonsDown);
|
OGC_WPAD_ScanPads);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_A",(int64_t)WPAD_BUTTON_A);
|
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown", "Is button down", {"pad"},
|
||||||
dict_rvl_wpad->SetValue("BUTTON_B",(int64_t)WPAD_BUTTON_B);
|
OGC_WPAD_ButtonsDown);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_HOME",(int64_t)WPAD_BUTTON_HOME);
|
dict_rvl_wpad->SetValue("BUTTON_A", (int64_t)WPAD_BUTTON_A);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_UP",(int64_t)WPAD_BUTTON_UP);
|
dict_rvl_wpad->SetValue("BUTTON_B", (int64_t)WPAD_BUTTON_B);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_DOWN",(int64_t)WPAD_BUTTON_DOWN);
|
dict_rvl_wpad->SetValue("BUTTON_HOME", (int64_t)WPAD_BUTTON_HOME);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_LEFT",(int64_t)WPAD_BUTTON_LEFT);
|
dict_rvl_wpad->SetValue("BUTTON_UP", (int64_t)WPAD_BUTTON_UP);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_RIGHT",(int64_t)WPAD_BUTTON_RIGHT);
|
dict_rvl_wpad->SetValue("BUTTON_DOWN", (int64_t)WPAD_BUTTON_DOWN);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_1",(int64_t)WPAD_BUTTON_1);
|
dict_rvl_wpad->SetValue("BUTTON_LEFT", (int64_t)WPAD_BUTTON_LEFT);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_2",(int64_t)WPAD_BUTTON_2);
|
dict_rvl_wpad->SetValue("BUTTON_RIGHT", (int64_t)WPAD_BUTTON_RIGHT);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_PLUS",(int64_t)WPAD_BUTTON_PLUS);
|
dict_rvl_wpad->SetValue("BUTTON_1", (int64_t)WPAD_BUTTON_1);
|
||||||
dict_rvl_wpad->SetValue("BUTTON_MINUS",(int64_t)WPAD_BUTTON_MINUS);
|
dict_rvl_wpad->SetValue("BUTTON_2", (int64_t)WPAD_BUTTON_2);
|
||||||
|
dict_rvl_wpad->SetValue("BUTTON_PLUS", (int64_t)WPAD_BUTTON_PLUS);
|
||||||
|
dict_rvl_wpad->SetValue("BUTTON_MINUS", (int64_t)WPAD_BUTTON_MINUS);
|
||||||
env->DeclareVariable("WPAD", dict_rvl_wpad);
|
env->DeclareVariable("WPAD", dict_rvl_wpad);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
env->DeclareVariable("PAD", dict_ogc_pad);
|
env->DeclareVariable("PAD", dict_ogc_pad);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
#endif
|
#endif
|
||||||
env->permissions.canRegisterOGC=true;
|
env->permissions.canRegisterOGC = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,60 +1,51 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
bool GetObjectAsPath(TObject &obj, Tesses::Framework::Filesystem::VFSPath &path,
|
||||||
namespace Tesses::CrossLang
|
bool allowString) {
|
||||||
{
|
if (GetObject(obj, path))
|
||||||
bool GetObjectAsPath(TObject& obj, Tesses::Framework::Filesystem::VFSPath& path, bool allowString)
|
return true;
|
||||||
{
|
|
||||||
if(GetObject(obj,path)) return true;
|
|
||||||
std::string str;
|
std::string str;
|
||||||
if(allowString && GetObject<std::string>(obj,str))
|
if (allowString && GetObject<std::string>(obj, str)) {
|
||||||
{
|
|
||||||
path = Tesses::Framework::Filesystem::VFSPath(str);
|
path = Tesses::Framework::Filesystem::VFSPath(str);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool GetArgumentAsPath(std::vector<TObject>& args, size_t index, Tesses::Framework::Filesystem::VFSPath& path,bool allowString)
|
bool GetArgumentAsPath(std::vector<TObject> &args, size_t index,
|
||||||
{
|
Tesses::Framework::Filesystem::VFSPath &path,
|
||||||
if(GetArgument(args,index,path)) return true;
|
bool allowString) {
|
||||||
|
if (GetArgument(args, index, path))
|
||||||
|
return true;
|
||||||
std::string str;
|
std::string str;
|
||||||
if(allowString && GetArgument<std::string>(args,index,str))
|
if (allowString && GetArgument<std::string>(args, index, str)) {
|
||||||
{
|
|
||||||
path = Tesses::Framework::Filesystem::VFSPath(str);
|
path = Tesses::Framework::Filesystem::VFSPath(str);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TObject Path_Root(GCList& ls, std::vector<TObject> args)
|
static TObject Path_Root(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
auto res = Tesses::Framework::Filesystem::VFSPath();
|
||||||
auto res = Tesses::Framework::Filesystem::VFSPath();\
|
res.relative = false;
|
||||||
res.relative=false;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
static TObject Path_FromString(GCList& ls, std::vector<TObject> args)
|
static TObject Path_FromString(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::string str;
|
std::string str;
|
||||||
if(GetArgument(args,0,str))
|
if (GetArgument(args, 0, str)) {
|
||||||
{
|
|
||||||
return Tesses::Framework::Filesystem::VFSPath(str);
|
return Tesses::Framework::Filesystem::VFSPath(str);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject Path_Create(GCList& ls, std::vector<TObject> args)
|
static TObject Path_Create(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
TList *myls;
|
||||||
TList* myls;
|
|
||||||
bool relative;
|
bool relative;
|
||||||
if(GetArgument(args,0,relative) && GetArgumentHeap(args,1,myls))
|
if (GetArgument(args, 0, relative) && GetArgumentHeap(args, 1, myls)) {
|
||||||
{
|
|
||||||
std::vector<std::string> items;
|
std::vector<std::string> items;
|
||||||
for(int64_t i = 0; i < myls->Count(); i++)
|
for (int64_t i = 0; i < myls->Count(); i++) {
|
||||||
{
|
|
||||||
std::string str;
|
std::string str;
|
||||||
TObject o =myls->Get(i);
|
TObject o = myls->Get(i);
|
||||||
if(GetObject<std::string>(o,str))
|
if (GetObject<std::string>(o, str)) {
|
||||||
{
|
|
||||||
items.push_back(str);
|
items.push_back(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,20 +55,22 @@ namespace Tesses::CrossLang
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
void TStd::RegisterPath(GC* gc,TRootEnvironment* env)
|
void TStd::RegisterPath(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
{
|
|
||||||
|
|
||||||
env->permissions.canRegisterPath=true;
|
env->permissions.canRegisterPath = true;
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
dict->DeclareFunction(gc,"FromString","Create a Path from string",{"path"},Path_FromString);
|
dict->DeclareFunction(gc, "FromString", "Create a Path from string",
|
||||||
|
{"path"}, Path_FromString);
|
||||||
|
|
||||||
dict->DeclareFunction(gc,"Create","Create a Path from parts",{"relative","parts"},Path_Create);
|
dict->DeclareFunction(gc, "Create", "Create a Path from parts",
|
||||||
dict->DeclareFunction(gc,"Root","Create Absolute Root Path",{}, Path_Root);
|
{"relative", "parts"}, Path_Create);
|
||||||
|
dict->DeclareFunction(gc, "Root", "Create Absolute Root Path", {},
|
||||||
|
Path_Root);
|
||||||
env->DeclareVariable("Path", dict);
|
env->DeclareVariable("Path", dict);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,203 +1,172 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
class ProcessObject : public TNativeObject {
|
||||||
namespace Tesses::CrossLang
|
|
||||||
{
|
|
||||||
class ProcessObject : public TNativeObject {
|
|
||||||
public:
|
public:
|
||||||
ProcessObject()
|
ProcessObject() {
|
||||||
{
|
arguments = nullptr;
|
||||||
arguments=nullptr;
|
environment = nullptr;
|
||||||
environment=nullptr;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
ProcessObject(GCList& ls)
|
ProcessObject(GCList &ls) {
|
||||||
{
|
|
||||||
arguments = TList::Create(ls);
|
arguments = TList::Create(ls);
|
||||||
environment = TList::Create(ls);
|
environment = TList::Create(ls);
|
||||||
process.includeThisEnv=true;
|
process.includeThisEnv = true;
|
||||||
process.redirectStdIn=false;
|
process.redirectStdIn = false;
|
||||||
|
|
||||||
process.redirectStdOut=false;
|
process.redirectStdOut = false;
|
||||||
|
|
||||||
process.redirectStdErr=false;
|
process.redirectStdErr = false;
|
||||||
}
|
}
|
||||||
TList* arguments;
|
TList *arguments;
|
||||||
TList* environment;
|
TList *environment;
|
||||||
Tesses::Framework::Platform::Process process;
|
Tesses::Framework::Platform::Process process;
|
||||||
std::string TypeName()
|
std::string TypeName() { return "Process"; }
|
||||||
{
|
void Mark() {
|
||||||
return "Process";
|
if (this->marked)
|
||||||
|
return;
|
||||||
|
this->marked = true;
|
||||||
|
if (arguments != nullptr)
|
||||||
|
arguments->Mark();
|
||||||
|
if (environment != nullptr)
|
||||||
|
environment->Mark();
|
||||||
}
|
}
|
||||||
void Mark()
|
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args) {
|
||||||
{
|
if (key == "setFileName" && GetArgument(args, 0, process.name)) {
|
||||||
if(this->marked) return;
|
|
||||||
this->marked=true;
|
|
||||||
if(arguments != nullptr) arguments->Mark();
|
|
||||||
if(environment != nullptr) environment->Mark();
|
|
||||||
}
|
|
||||||
TObject CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
if(key == "setFileName" && GetArgument(args,0,process.name))
|
|
||||||
{
|
|
||||||
return process.name;
|
return process.name;
|
||||||
}
|
}
|
||||||
if(key == "getFileName")
|
if (key == "getFileName") {
|
||||||
{
|
|
||||||
return process.name;
|
return process.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key == "setRedirectStandardInput" && GetArgument(args,0,process.redirectStdIn))
|
if (key == "setRedirectStandardInput" &&
|
||||||
{
|
GetArgument(args, 0, process.redirectStdIn)) {
|
||||||
return process.redirectStdIn;
|
return process.redirectStdIn;
|
||||||
}
|
}
|
||||||
if(key == "getRedirectStandardInput")
|
if (key == "getRedirectStandardInput") {
|
||||||
{
|
|
||||||
return process.redirectStdIn;
|
return process.redirectStdIn;
|
||||||
}
|
}
|
||||||
if(key == "setRedirectStandardOutput" && GetArgument(args,0,process.redirectStdOut))
|
if (key == "setRedirectStandardOutput" &&
|
||||||
{
|
GetArgument(args, 0, process.redirectStdOut)) {
|
||||||
return process.redirectStdOut;
|
return process.redirectStdOut;
|
||||||
}
|
}
|
||||||
if(key == "getRedirectStandardOutput")
|
if (key == "getRedirectStandardOutput") {
|
||||||
{
|
|
||||||
return process.redirectStdOut;
|
return process.redirectStdOut;
|
||||||
}
|
}
|
||||||
if(key == "setRedirectStandardError" && GetArgument(args,0,process.redirectStdErr))
|
if (key == "setRedirectStandardError" &&
|
||||||
{
|
GetArgument(args, 0, process.redirectStdErr)) {
|
||||||
return process.redirectStdErr;
|
return process.redirectStdErr;
|
||||||
}
|
}
|
||||||
if(key == "getRedirectStandardError")
|
if (key == "getRedirectStandardError") {
|
||||||
{
|
|
||||||
return process.redirectStdErr;
|
return process.redirectStdErr;
|
||||||
}
|
}
|
||||||
if(key == "setWorkingDirectory" && GetArgument(args,0,process.workingDirectory))
|
if (key == "setWorkingDirectory" &&
|
||||||
{
|
GetArgument(args, 0, process.workingDirectory)) {
|
||||||
return process.workingDirectory;
|
return process.workingDirectory;
|
||||||
}
|
}
|
||||||
if(key == "getWorkingDirectory")
|
if (key == "getWorkingDirectory") {
|
||||||
{
|
|
||||||
return process.workingDirectory;
|
return process.workingDirectory;
|
||||||
}
|
}
|
||||||
if(key == "setInheritParentEnvironment" && GetArgument(args,0,process.includeThisEnv))
|
if (key == "setInheritParentEnvironment" &&
|
||||||
{
|
GetArgument(args, 0, process.includeThisEnv)) {
|
||||||
return process.includeThisEnv;
|
return process.includeThisEnv;
|
||||||
}
|
}
|
||||||
if(key == "getInheritParentEnvironment")
|
if (key == "getInheritParentEnvironment") {
|
||||||
{
|
|
||||||
return process.includeThisEnv;
|
return process.includeThisEnv;
|
||||||
}
|
}
|
||||||
if(key == "getArguments")
|
if (key == "getArguments") {
|
||||||
{
|
if (arguments == nullptr)
|
||||||
if(arguments == nullptr) return nullptr;
|
return nullptr;
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
if(key == "setArguments")
|
if (key == "setArguments") {
|
||||||
{
|
if (GetArgumentHeap(args, 0, arguments)) {
|
||||||
if(GetArgumentHeap(args,0,arguments))
|
|
||||||
{
|
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(key == "getEnvironment")
|
if (key == "getEnvironment") {
|
||||||
{
|
if (environment == nullptr)
|
||||||
if(environment == nullptr) return nullptr;
|
return nullptr;
|
||||||
return environment;
|
return environment;
|
||||||
}
|
}
|
||||||
if(key == "getEnvironment")
|
if (key == "getEnvironment") {
|
||||||
{
|
if (GetArgumentHeap(args, 0, environment)) {
|
||||||
if(GetArgumentHeap(args,0,environment))
|
|
||||||
{
|
|
||||||
return environment;
|
return environment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(key == "Start")
|
if (key == "Start") {
|
||||||
{
|
|
||||||
this->process.args.push_back(process.name);
|
this->process.args.push_back(process.name);
|
||||||
if(arguments != nullptr)
|
if (arguments != nullptr) {
|
||||||
{
|
for (int64_t i = 0; i < arguments->Count(); i++) {
|
||||||
for(int64_t i = 0; i < arguments->Count(); i++)
|
TObject argVal = arguments->Get(i);
|
||||||
{
|
|
||||||
TObject argVal=arguments->Get(i);
|
|
||||||
std::string argValStr;
|
std::string argValStr;
|
||||||
if(GetObject(argVal,argValStr))
|
if (GetObject(argVal, argValStr))
|
||||||
this->process.args.push_back(argValStr);
|
this->process.args.push_back(argValStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(environment != nullptr)
|
if (environment != nullptr) {
|
||||||
{
|
for (int64_t i = 0; i < environment->Count(); i++) {
|
||||||
for(int64_t i = 0; i < environment->Count(); i++)
|
|
||||||
{
|
|
||||||
TObject arg = environment->Get(i);
|
TObject arg = environment->Get(i);
|
||||||
std::string argstr;
|
std::string argstr;
|
||||||
if(GetObject(arg,argstr))
|
if (GetObject(arg, argstr)) {
|
||||||
{
|
auto kvp =
|
||||||
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
|
Tesses::Framework::Http::HttpUtils::SplitString(
|
||||||
if(kvp.size()==2)
|
argstr, "=", 2);
|
||||||
{
|
if (kvp.size() == 2) {
|
||||||
process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
|
process.env.push_back(
|
||||||
}
|
std::pair<std::string, std::string>(kvp[0],
|
||||||
else if(kvp.size()==1)
|
kvp[1]));
|
||||||
{
|
} else if (kvp.size() == 1) {
|
||||||
process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
|
process.env.push_back(
|
||||||
|
std::pair<std::string, std::string>(kvp[0],
|
||||||
|
""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return process.Start();
|
return process.Start();
|
||||||
}
|
}
|
||||||
if(key == "Join" || key == "WaitForExit")
|
if (key == "Join" || key == "WaitForExit") {
|
||||||
{
|
|
||||||
return (int64_t)process.WaitForExit();
|
return (int64_t)process.WaitForExit();
|
||||||
}
|
}
|
||||||
if(key == "getHasExited")
|
if (key == "getHasExited") {
|
||||||
{
|
|
||||||
return process.HasExited();
|
return process.HasExited();
|
||||||
}
|
}
|
||||||
if(key == "Terminate")
|
if (key == "Terminate") {
|
||||||
{
|
|
||||||
process.Kill(SIGTERM);
|
process.Kill(SIGTERM);
|
||||||
}
|
}
|
||||||
if(key == "CloseStdInNow")
|
if (key == "CloseStdInNow") {
|
||||||
{
|
|
||||||
process.CloseStdInNow();
|
process.CloseStdInNow();
|
||||||
|
|
||||||
}
|
}
|
||||||
int64_t k;
|
int64_t k;
|
||||||
if(key == "Kill" && GetArgument(args,0,k))
|
if (key == "Kill" && GetArgument(args, 0, k)) {
|
||||||
{
|
|
||||||
process.Kill((int)k);
|
process.Kill((int)k);
|
||||||
}
|
}
|
||||||
if(key == "getStandardInput")
|
if (key == "getStandardInput") {
|
||||||
{
|
|
||||||
return process.GetStdinStream();
|
return process.GetStdinStream();
|
||||||
}
|
}
|
||||||
if(key == "getStandardOutput")
|
if (key == "getStandardOutput") {
|
||||||
{
|
|
||||||
return process.GetStdoutStream();
|
return process.GetStdoutStream();
|
||||||
}
|
}
|
||||||
if(key == "getStandardError")
|
if (key == "getStandardError") {
|
||||||
{
|
|
||||||
return process.GetStderrStream();
|
return process.GetStderrStream();
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static TObject Process_Start(GCList& ls, std::vector<TObject> args)
|
static TObject Process_Start(GCList &ls, std::vector<TObject> args,
|
||||||
{
|
TRootEnvironment *env) {
|
||||||
|
|
||||||
//Process.Start({
|
// Process.Start({
|
||||||
// FileName = "git",
|
// FileName = "git",
|
||||||
// Arguments = ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
|
// Arguments =
|
||||||
|
// ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
|
||||||
// Environment = [],
|
// Environment = [],
|
||||||
// InheritParentEnvironment=true
|
// InheritParentEnvironment=true
|
||||||
//})
|
// })
|
||||||
|
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
|
|
||||||
if(GetArgumentHeap(args,0,dict))
|
if (GetArgumentHeap(args, 0, dict)) {
|
||||||
{
|
|
||||||
auto process = TNativeObject::Create<ProcessObject>(ls);
|
auto process = TNativeObject::Create<ProcessObject>(ls);
|
||||||
auto name = dict->GetValue("FileName");
|
auto name = dict->GetValue("FileName");
|
||||||
auto inh = dict->GetValue("InheritParentEnvironment");
|
auto inh = dict->GetValue("InheritParentEnvironment");
|
||||||
@@ -206,99 +175,121 @@ namespace Tesses::CrossLang
|
|||||||
|
|
||||||
auto rStdErr = dict->GetValue("RedirectStandardError");
|
auto rStdErr = dict->GetValue("RedirectStandardError");
|
||||||
auto workingDirectory = dict->GetValue("WorkingDirectory");
|
auto workingDirectory = dict->GetValue("WorkingDirectory");
|
||||||
process->process.includeThisEnv=true;
|
process->process.includeThisEnv = true;
|
||||||
process->process.redirectStdIn=false;
|
process->process.redirectStdIn = false;
|
||||||
|
|
||||||
process->process.redirectStdOut=false;
|
process->process.redirectStdOut = false;
|
||||||
|
|
||||||
process->process.redirectStdErr=false;
|
process->process.redirectStdErr = false;
|
||||||
GetObject(inh,process->process.includeThisEnv);
|
GetObject(inh, process->process.includeThisEnv);
|
||||||
GetObject(rStdIn,process->process.redirectStdIn);
|
GetObject(rStdIn, process->process.redirectStdIn);
|
||||||
GetObject(rStdOut,process->process.redirectStdOut);
|
GetObject(rStdOut, process->process.redirectStdOut);
|
||||||
GetObject(rStdErr,process->process.redirectStdErr);
|
GetObject(rStdErr, process->process.redirectStdErr);
|
||||||
|
|
||||||
GetObject(name,process->process.name);
|
GetObject(name, process->process.name);
|
||||||
|
|
||||||
Tesses::Framework::Filesystem::VFSPath wdPath;
|
Tesses::Framework::Filesystem::VFSPath wdPath;
|
||||||
|
if (env->permissions.localfs) {
|
||||||
if(GetObject(workingDirectory,wdPath))
|
process->process.workingDirectory =
|
||||||
{
|
env->permissions.localfs->GetWorking().ToString();
|
||||||
process->process.workingDirectory= wdPath.MakeAbsolute().ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GetObject(workingDirectory,process->process.workingDirectory);
|
if (GetObject(workingDirectory, wdPath)) {
|
||||||
|
process->process.workingDirectory =
|
||||||
|
wdPath.MakeAbsolute().ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
GetObject(workingDirectory, process->process.workingDirectory);
|
||||||
|
|
||||||
process->process.args.push_back(process->process.name);
|
process->process.args.push_back(process->process.name);
|
||||||
auto argumentsO = dict->GetValue("Arguments");
|
auto argumentsO = dict->GetValue("Arguments");
|
||||||
TList* arguments;
|
TList *arguments;
|
||||||
if(GetObjectHeap(argumentsO,arguments))
|
if (GetObjectHeap(argumentsO, arguments)) {
|
||||||
{
|
for (int64_t i = 0; i < arguments->Count(); i++) {
|
||||||
for(int64_t i = 0; i < arguments->Count(); i++)
|
|
||||||
{
|
|
||||||
TObject arg = arguments->Get(i);
|
TObject arg = arguments->Get(i);
|
||||||
std::string argstr;
|
std::string argstr;
|
||||||
if(GetObject(arg,argstr))
|
if (GetObject(arg, argstr)) {
|
||||||
{
|
|
||||||
process->process.args.push_back(argstr);
|
process->process.args.push_back(argstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
argumentsO = dict->GetValue("Environment");
|
argumentsO = dict->GetValue("Environment");
|
||||||
if(GetObjectHeap(argumentsO,arguments))
|
if (GetObjectHeap(argumentsO, arguments)) {
|
||||||
{
|
for (int64_t i = 0; i < arguments->Count(); i++) {
|
||||||
for(int64_t i = 0; i < arguments->Count(); i++)
|
|
||||||
{
|
|
||||||
TObject arg = arguments->Get(i);
|
TObject arg = arguments->Get(i);
|
||||||
std::string argstr;
|
std::string argstr;
|
||||||
if(GetObject(arg,argstr))
|
if (GetObject(arg, argstr)) {
|
||||||
{
|
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(
|
||||||
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
|
argstr, "=", 2);
|
||||||
if(kvp.size()==2)
|
if (kvp.size() == 2) {
|
||||||
{
|
process->process.env.push_back(
|
||||||
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
|
std::pair<std::string, std::string>(kvp[0],
|
||||||
}
|
kvp[1]));
|
||||||
else if(kvp.size()==1)
|
} else if (kvp.size() == 1) {
|
||||||
{
|
process->process.env.push_back(
|
||||||
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
|
std::pair<std::string, std::string>(kvp[0], ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(process->process.Start())
|
if (process->process.Start()) {
|
||||||
{
|
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject New_Process(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
return TNativeObject::Create<ProcessObject>(ls,ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TStd::RegisterProcess(GC* gc,TRootEnvironment* env)
|
void TStd::RegisterProcess(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
{
|
|
||||||
|
|
||||||
env->permissions.canRegisterProcess=true;
|
env->permissions.canRegisterProcess = true;
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
dict->DeclareFunction(gc,"Start","Start a process",{"process_object"},Process_Start);
|
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
env->SetVariable("Process",dict);
|
auto processStart = TExternalMethod::Create(
|
||||||
auto process = env->EnsureDictionary(gc,"New");
|
ls, "Start a process", {"process_object"},
|
||||||
process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
|
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
process->DeclareFunction(gc, "CGIServer", "Create a CGI Server",{"path"},[](GCList& ls, std::vector<TObject> args)->TObject{
|
return Process_Start(ls, args, env);
|
||||||
|
});
|
||||||
|
processStart->watch.push_back(env);
|
||||||
|
dict->SetValue("Start", processStart);
|
||||||
|
|
||||||
|
env->SetVariable("Process", dict);
|
||||||
|
auto process = env->EnsureDictionary(gc, "New");
|
||||||
|
auto newProcess = TExternalMethod::Create(
|
||||||
|
ls, "Create process", {},
|
||||||
|
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
auto obj = TNativeObject::Create<ProcessObject>(ls, ls);
|
||||||
|
if (env->permissions.localfs) {
|
||||||
|
obj->process.workingDirectory =
|
||||||
|
env->permissions.localfs->GetWorking().ToString();
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
});
|
||||||
|
newProcess->watch.push_back(env);
|
||||||
|
process->SetValue("Process", newProcess);
|
||||||
|
// process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
|
||||||
|
process->DeclareFunction(
|
||||||
|
gc, "CGIServer", "Create a CGI Server", {"path"},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
Tesses::Framework::Filesystem::VFSPath path;
|
Tesses::Framework::Filesystem::VFSPath path;
|
||||||
if(GetArgumentAsPath(args,0,path))
|
if (GetArgumentAsPath(args, 0, path)) {
|
||||||
{
|
return std::make_shared<Tesses::Framework::Http::CGIServer>(
|
||||||
return std::make_shared<Tesses::Framework::Http::CGIServer>(path);
|
path);
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
process->DeclareFunction(
|
||||||
|
gc, "ShellFileOrUrl", "Launch file or url in shell", {"urlOrFilename"},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
std::string fileOrUrl;
|
||||||
|
if (GetArgument(args, 0, fileOrUrl))
|
||||||
|
Tesses::Framework::Platform::ShellFileOrUrl(fileOrUrl);
|
||||||
|
|
||||||
|
return Undefined();
|
||||||
|
});
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
|
|||||||
@@ -3,89 +3,112 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
||||||
using namespace Tesses::Framework::Serialization;
|
using namespace Tesses::Framework::Serialization;
|
||||||
TObject Sqlite_Escape(GCList& ls, std::vector<TObject> args)
|
TObject Sqlite_Escape(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
int64_t n;
|
int64_t n;
|
||||||
double d;
|
double d;
|
||||||
bool b;
|
bool b;
|
||||||
|
|
||||||
|
|
||||||
std::string str;
|
std::string str;
|
||||||
if(GetArgument(args,0,str))
|
if (GetArgument(args, 0, str)) {
|
||||||
{
|
|
||||||
return SQLiteDatabase::Escape(str);
|
return SQLiteDatabase::Escape(str);
|
||||||
}
|
}
|
||||||
if(GetArgument(args,0,n))
|
if (GetArgument(args, 0, n)) {
|
||||||
{
|
|
||||||
return std::to_string(n);
|
return std::to_string(n);
|
||||||
}
|
}
|
||||||
if(GetArgument(args,0,b))
|
if (GetArgument(args, 0, b)) {
|
||||||
{
|
|
||||||
return b ? "1" : "0";
|
return b ? "1" : "0";
|
||||||
}
|
}
|
||||||
if(GetArgument(args,0,d))
|
if (GetArgument(args, 0, d)) {
|
||||||
{
|
|
||||||
return std::to_string(d);
|
return std::to_string(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "NULL";
|
return "NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
TObject Sqlite_Prepare(GCList &ls, std::vector<TObject> args) {
|
||||||
|
std::string str;
|
||||||
|
TList *list;
|
||||||
|
|
||||||
|
std::string newStr = "";
|
||||||
|
if (GetArgument(args, 0, str) && GetArgumentHeap(args, 1, list)) {
|
||||||
|
int64_t item = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < str.size(); i++) {
|
||||||
|
if (str[i] == '@' && (i + 1 >= str.size() || str[i + 1] != '@')) {
|
||||||
|
auto v = list->Get(item);
|
||||||
|
int64_t n;
|
||||||
|
double d;
|
||||||
|
bool b;
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
if (GetObject(v, str)) {
|
||||||
|
newStr += SQLiteDatabase::Escape(str);
|
||||||
|
} else if (GetObject(v, n)) {
|
||||||
|
newStr += std::to_string(n);
|
||||||
|
} else if (GetObject(v, b)) {
|
||||||
|
newStr += (b ? "1" : "0");
|
||||||
|
} else if (GetObject(v, d)) {
|
||||||
|
newStr += std::to_string(d);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
newStr += "NULL";
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
newStr += str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SQLiteObject : public TNativeObject {
|
||||||
class SQLiteObject : public TNativeObject
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
SQLiteDatabase* db;
|
SQLiteDatabase *db;
|
||||||
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path)
|
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path) {
|
||||||
{
|
db = new SQLiteDatabase(path);
|
||||||
db=new SQLiteDatabase(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TypeName()
|
std::string TypeName() { return "SQLiteDatabase"; }
|
||||||
{
|
void Close() {
|
||||||
return "SQLiteDatabase";
|
if (this->db == nullptr)
|
||||||
}
|
return;
|
||||||
void Close()
|
|
||||||
{
|
|
||||||
if(this->db == nullptr) return;
|
|
||||||
delete this->db;
|
delete this->db;
|
||||||
this->db = nullptr;
|
this->db = nullptr;
|
||||||
|
}
|
||||||
|
bool ToBool() { return this->db != nullptr; }
|
||||||
|
|
||||||
|
TObject CallMethod(GCList &ls, std::string name,
|
||||||
|
std::vector<TObject> args) {
|
||||||
|
if (name == "Close")
|
||||||
|
this->Close();
|
||||||
|
if (name == "Escape") {
|
||||||
|
return Sqlite_Escape(ls, args);
|
||||||
}
|
}
|
||||||
bool ToBool()
|
if (name == "Prepare") {
|
||||||
{
|
return Sqlite_Prepare(ls, args);
|
||||||
return this->db != nullptr;
|
|
||||||
}
|
}
|
||||||
|
if (name == "Exec") {
|
||||||
TObject CallMethod(GCList& ls,std::string name, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
if(name == "Close") this->Close();
|
|
||||||
if(name == "Escape") {
|
|
||||||
return Sqlite_Escape(ls,args);
|
|
||||||
}
|
|
||||||
if(name == "Exec")
|
|
||||||
{
|
|
||||||
std::string arg;
|
std::string arg;
|
||||||
if(GetArgument(args,0,arg))
|
if (GetArgument(args, 0, arg)) {
|
||||||
{
|
if (this->db == nullptr)
|
||||||
if(this->db == nullptr) return nullptr;
|
return nullptr;
|
||||||
std::vector<std::vector<std::pair<std::string, std::optional<std::string>>>> res;
|
std::vector<std::vector<
|
||||||
|
std::pair<std::string, std::optional<std::string>>>>
|
||||||
|
res;
|
||||||
|
|
||||||
this->db->Exec(arg,res);
|
this->db->Exec(arg, res);
|
||||||
|
|
||||||
TList* list = TList::Create(ls);
|
TList *list = TList::Create(ls);
|
||||||
|
|
||||||
for(auto& item : res)
|
for (auto &item : res) {
|
||||||
{
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
for (auto &item2 : item) {
|
||||||
for(auto& item2 : item)
|
if (item2.second)
|
||||||
{
|
dict->SetValue(item2.first, item2.second.value());
|
||||||
if(item2.second)
|
|
||||||
dict->SetValue(item2.first,item2.second.value());
|
|
||||||
else
|
else
|
||||||
dict->SetValue(item2.first,nullptr);
|
dict->SetValue(item2.first, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
list->Add(dict);
|
list->Add(dict);
|
||||||
@@ -97,76 +120,75 @@ namespace Tesses::CrossLang {
|
|||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~SQLiteObject() {
|
||||||
~SQLiteObject()
|
if (this->db != nullptr)
|
||||||
{
|
|
||||||
if(this->db != nullptr)
|
|
||||||
delete this->db;
|
delete this->db;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TObject Sqlite_Open(GCList& ls, std::vector<TObject> args,TRootEnvironment* env)
|
TObject Sqlite_Open(GCList &ls, std::vector<TObject> args,
|
||||||
{
|
TRootEnvironment *env) {
|
||||||
Tesses::Framework::Filesystem::VFSPath p;
|
Tesses::Framework::Filesystem::VFSPath p;
|
||||||
if(GetArgumentAsPath(args,0,p))
|
if (GetArgumentAsPath(args, 0, p)) {
|
||||||
{
|
if (env->permissions.sqlite3Scoped) {
|
||||||
if(env->permissions.sqlite3Scoped)
|
|
||||||
{
|
|
||||||
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
|
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
|
||||||
}
|
}
|
||||||
|
|
||||||
return TNativeObject::Create<SQLiteObject>(ls,p);
|
return TNativeObject::Create<SQLiteObject>(ls, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
|
}
|
||||||
}
|
TObject Sqlite_Exec(GCList &ls, std::vector<TObject> args) {
|
||||||
TObject Sqlite_Exec(GCList& ls, std::vector<TObject> args)
|
SQLiteObject *sql;
|
||||||
{
|
|
||||||
SQLiteObject* sql;
|
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
if(GetArgumentHeap(args,0,sql) && GetArgument(args,1,cmd))
|
if (GetArgumentHeap(args, 0, sql) && GetArgument(args, 1, cmd)) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
return sql->CallMethod(ls,"Exec",{cmd});
|
return sql->CallMethod(ls, "Exec", {cmd});
|
||||||
} catch(std::runtime_error& ex)
|
} catch (std::runtime_error &ex) {
|
||||||
{
|
|
||||||
return (std::string)ex.what();
|
return (std::string)ex.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
TObject Sqlite_Close(GCList &ls, std::vector<TObject> args) {
|
||||||
|
SQLiteObject *sql;
|
||||||
TObject Sqlite_Close(GCList& ls, std::vector<TObject> args)
|
if (GetArgumentHeap(args, 0, sql)) {
|
||||||
{
|
|
||||||
SQLiteObject* sql;
|
|
||||||
if(GetArgumentHeap(args,0,sql))
|
|
||||||
{
|
|
||||||
sql->Close();
|
sql->Close();
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
void TStd::RegisterSqlite(GC* gc,TRootEnvironment* env)
|
void TStd::RegisterSqlite(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
{
|
|
||||||
|
|
||||||
env->permissions.canRegisterSqlite=true;
|
env->permissions.canRegisterSqlite = true;
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
dict->DeclareFunction(gc,"Open","Opens the database (returns database handle or an error message as string or undefined)",{"filename"},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
dict->DeclareFunction(
|
||||||
return Sqlite_Open(ls,args,env);
|
gc, "Open",
|
||||||
|
"Opens the database (returns database handle or an error message as "
|
||||||
|
"string or undefined)",
|
||||||
|
{"filename"}, [env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
return Sqlite_Open(ls, args, env);
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc,"Exec","Execute sql (returns dictionary of columns key=value, an error message as string or undefined)",{"handle","sql"},Sqlite_Exec);
|
dict->DeclareFunction(gc, "Exec",
|
||||||
dict->DeclareFunction(gc,"Close","Close sql database",{"handle"},Sqlite_Close);
|
"Execute sql (returns dictionary of columns "
|
||||||
dict->DeclareFunction(gc,"Escape","Escape sql text",{"text"},Sqlite_Escape);
|
"key=value, an error message as string or undefined)",
|
||||||
|
{"handle", "sql"}, Sqlite_Exec);
|
||||||
|
dict->DeclareFunction(gc, "Close", "Close sql database", {"handle"},
|
||||||
|
Sqlite_Close);
|
||||||
|
dict->DeclareFunction(gc, "Escape", "Escape sql text", {"text"},
|
||||||
|
Sqlite_Escape);
|
||||||
|
dict->DeclareFunction(gc, "Prepare", "Prepare sql", {"sql", "items"},
|
||||||
|
Sqlite_Prepare);
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
env->DeclareVariable("Sqlite", dict);
|
env->DeclareVariable("Sqlite", dict);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
42
src/runtime_methods/uuid.cpp
Normal file
42
src/runtime_methods/uuid.cpp
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#include "TessesFramework/Uuid.hpp"
|
||||||
|
#include "CrossLang.hpp"
|
||||||
|
#include "TessesFramework/Serialization/BitConverter.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::CrossLang {
|
||||||
|
static TObject Uuid_NewUuid(GCList &ls, std::vector<TObject> args) {
|
||||||
|
return Tesses::Framework::Uuid::Generate();
|
||||||
|
}
|
||||||
|
static TObject Uuid_TryParse(GCList &ls, std::vector<TObject> args) {
|
||||||
|
std::string str;
|
||||||
|
Tesses::Framework::Uuid uuid;
|
||||||
|
if (GetArgument(args, 0, str) &&
|
||||||
|
Tesses::Framework::Uuid::TryParse(str, uuid))
|
||||||
|
return uuid;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
static TObject Uuid_FromBytes(GCList &ls, std::vector<TObject> args) {
|
||||||
|
TByteArray *ba;
|
||||||
|
int64_t index;
|
||||||
|
if (GetArgumentHeap(args, 0, ba) && GetArgument(args, 1, index) &&
|
||||||
|
(size_t)index < ba->data.size() &&
|
||||||
|
(size_t)index + 16 <= ba->data.size()) {
|
||||||
|
return Tesses::Framework::Serialization::BitConverter::ToUuid(
|
||||||
|
ba->data[(size_t)index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
|
gc->BarrierBegin();
|
||||||
|
TDictionary *guid = env->EnsureDictionary(gc, "Uuid");
|
||||||
|
guid->DeclareFunction(gc, "NewUuid", "Create random uuid", {},
|
||||||
|
Uuid_NewUuid);
|
||||||
|
guid->DeclareFunction(gc, "TryParse", "Try to parse", {"str"},
|
||||||
|
Uuid_TryParse);
|
||||||
|
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",
|
||||||
|
{"byteArray", "offset"}, Uuid_FromBytes);
|
||||||
|
|
||||||
|
gc->BarrierEnd();
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,123 +1,104 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
|
||||||
|
|
||||||
static TObject AstToTObject(GCList& ls,SyntaxNode node)
|
static TObject AstToTObject(GCList &ls, SyntaxNode node) {
|
||||||
{
|
if (std::holds_alternative<std::nullptr_t>(node))
|
||||||
if(std::holds_alternative<std::nullptr_t>(node))
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if(std::holds_alternative<int64_t>(node))
|
if (std::holds_alternative<int64_t>(node)) {
|
||||||
{
|
|
||||||
return std::get<int64_t>(node);
|
return std::get<int64_t>(node);
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<double>(node))
|
if (std::holds_alternative<double>(node)) {
|
||||||
{
|
|
||||||
return std::get<double>(node);
|
return std::get<double>(node);
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<bool>(node))
|
if (std::holds_alternative<bool>(node)) {
|
||||||
{
|
|
||||||
return std::get<bool>(node);
|
return std::get<bool>(node);
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<std::string>(node))
|
if (std::holds_alternative<std::string>(node)) {
|
||||||
{
|
|
||||||
std::string str = std::get<std::string>(node);
|
std::string str = std::get<std::string>(node);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<char>(node))
|
if (std::holds_alternative<char>(node)) {
|
||||||
{
|
|
||||||
char c = std::get<char>(node);
|
char c = std::get<char>(node);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<Undefined>(node))
|
if (std::holds_alternative<Undefined>(node)) {
|
||||||
{
|
|
||||||
auto r = TDictionary::Create(ls);
|
auto r = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
r->SetValue("Type",std::string(UndefinedExpression));
|
r->SetValue("Type", std::string(UndefinedExpression));
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (std::holds_alternative<AdvancedSyntaxNode>(node)) {
|
||||||
if(std::holds_alternative<AdvancedSyntaxNode>(node))
|
|
||||||
{
|
|
||||||
auto asn = std::get<AdvancedSyntaxNode>(node);
|
auto asn = std::get<AdvancedSyntaxNode>(node);
|
||||||
auto r = TDictionary::Create(ls);
|
auto r = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
r->SetValue("Type",asn.nodeName);
|
r->SetValue("Type", asn.nodeName);
|
||||||
r->SetValue("IsExpression",asn.isExpression);
|
r->SetValue("IsExpression", asn.isExpression);
|
||||||
TList* ls2 = TList::Create(ls);
|
TList *ls2 = TList::Create(ls);
|
||||||
for(auto item : asn.nodes)
|
for (auto item : asn.nodes) {
|
||||||
{
|
ls2->Add(AstToTObject(ls, item));
|
||||||
ls2->Add(AstToTObject(ls,item));
|
|
||||||
}
|
}
|
||||||
r->SetValue("Arguments", ls2);
|
r->SetValue("Arguments", ls2);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject VM_SourceToAst(GCList& ls, std::vector<TObject> args)
|
static TObject VM_SourceToAst(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::string str;
|
std::string str;
|
||||||
if(GetArgument(args,0,str))
|
if (GetArgument(args, 0, str)) {
|
||||||
{
|
|
||||||
std::stringstream strm(str);
|
std::stringstream strm(str);
|
||||||
std::vector<LexToken> tokens;
|
std::vector<LexToken> tokens;
|
||||||
int res = Lex("memory.tcross",strm,tokens);
|
int res = Lex("memory.tcross", strm, tokens);
|
||||||
if(res != 0)
|
if (res != 0) {
|
||||||
{
|
|
||||||
throw VMException("Lex error at line: " + std::to_string(res));
|
throw VMException("Lex error at line: " + std::to_string(res));
|
||||||
}
|
}
|
||||||
Parser p(tokens);
|
Parser p(tokens);
|
||||||
auto res2 =p.ParseRoot();
|
auto res2 = p.ParseRoot();
|
||||||
return AstToTObject(ls,res2);
|
return AstToTObject(ls, res2);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject VM_Eval(GCList& ls, std::vector<TObject> args)
|
static TObject VM_Eval(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
std::string str;
|
std::string str;
|
||||||
if(GetArgument(args,0,str))
|
if (GetArgument(args, 0, str)) {
|
||||||
{
|
if (current_function != nullptr) {
|
||||||
if(current_function != nullptr)
|
return current_function->env->Eval(ls, str);
|
||||||
{
|
|
||||||
return current_function->env->Eval(ls,str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static TObject Failure(GCList& ls, std::string reason)
|
static TObject Failure(GCList &ls, std::string reason) {
|
||||||
{
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Success",false);
|
dict->SetValue("Success", false);
|
||||||
dict->SetValue("Reason", reason);
|
dict->SetValue("Reason", reason);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
static TObject Success(GCList& ls)
|
static TObject Success(GCList &ls) {
|
||||||
{
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Success",true);
|
dict->SetValue("Success", true);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
static TObject VM_getCurrentEnvironment(GCList& ls2,std::vector<TObject> args)
|
static TObject VM_getCurrentEnvironment(GCList &ls2,
|
||||||
{
|
std::vector<TObject> args) {
|
||||||
if(current_function != nullptr) return current_function->env;
|
if (current_function != nullptr)
|
||||||
|
return current_function->env;
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
static TObject VM_Compile(GCList& ls, std::vector<TObject> args)
|
static TObject VM_Compile(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(!GetArgumentHeap<TDictionary*>(args,0,dict)) return Undefined();
|
if (!GetArgumentHeap<TDictionary *>(args, 0, dict))
|
||||||
|
return Undefined();
|
||||||
/*
|
/*
|
||||||
VM.Compile
|
VM.Compile
|
||||||
{
|
{
|
||||||
@@ -132,13 +113,15 @@ namespace Tesses::CrossLang
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
std::string name = "Out";
|
std::string name = "Out";
|
||||||
std::vector<std::pair<std::string,std::string>> sources;
|
std::vector<std::pair<std::string, std::string>> sources;
|
||||||
TVMVersion version(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
|
TVMVersion version(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
|
||||||
std::vector<std::pair<std::string,TVMVersion>> dependencies;
|
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
|
||||||
std::vector<std::pair<std::string,TVMVersion>> tools;
|
CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||||
|
std::vector<std::pair<std::string, TVMVersion>> dependencies;
|
||||||
|
std::vector<std::pair<std::string, TVMVersion>> tools;
|
||||||
std::string info;
|
std::string info;
|
||||||
std::string icon;
|
std::string icon;
|
||||||
bool debug=false;
|
bool debug = false;
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||||
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
@@ -154,113 +137,107 @@ namespace Tesses::CrossLang
|
|||||||
|
|
||||||
TObject _out = dict->GetValue("Output");
|
TObject _out = dict->GetValue("Output");
|
||||||
TObject _dbg = dict->GetValue("Debug");
|
TObject _dbg = dict->GetValue("Debug");
|
||||||
TList* _toolList;
|
TList *_toolList;
|
||||||
TList* _depList; TList* srcLst;
|
TList *_depList;
|
||||||
TRootEnvironment* comptimeEnv=nullptr;
|
TList *srcLst;
|
||||||
GetObject<std::string>(_name,name);
|
TRootEnvironment *comptimeEnv = nullptr;
|
||||||
GetObject<std::string>(_info,info);
|
GetObject<std::string>(_name, name);
|
||||||
GetObject<std::string>(_icon,icon);
|
GetObject<std::string>(_info, info);
|
||||||
|
GetObject<std::string>(_icon, icon);
|
||||||
GetObject(_resourceFileSystem, vfs);
|
GetObject(_resourceFileSystem, vfs);
|
||||||
GetObjectHeap(_comptime,comptimeEnv);
|
GetObjectHeap(_comptime, comptimeEnv);
|
||||||
GetObject(_dbg,debug);
|
GetObject(_dbg, debug);
|
||||||
std::string v2;
|
std::string v2;
|
||||||
if(GetObject<std::string>(_version,v2))
|
if (GetObject<std::string>(_version, v2))
|
||||||
TVMVersion::TryParse(v2, version);
|
TVMVersion::TryParse(v2, version);
|
||||||
else
|
else
|
||||||
GetObject(_version,version);
|
GetObject(_version, version);
|
||||||
|
|
||||||
if(GetObjectHeap<TList*>(_dependencies,_depList))
|
if (GetObjectHeap<TList *>(_dependencies, _depList)) {
|
||||||
{
|
for (int64_t i = 0; i < _depList->Count(); i++) {
|
||||||
for(int64_t i = 0; i < _depList->Count(); i++)
|
|
||||||
{
|
|
||||||
TObject _dep = _depList->Get(i);
|
TObject _dep = _depList->Get(i);
|
||||||
TDictionary* _depD;
|
TDictionary *_depD;
|
||||||
if(GetObjectHeap<TDictionary*>(_dep, _depD))
|
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
|
||||||
{
|
|
||||||
TObject _name2 = _depD->GetValue("Name");
|
TObject _name2 = _depD->GetValue("Name");
|
||||||
TObject _version2 = _depD->GetValue("Version");
|
TObject _version2 = _depD->GetValue("Version");
|
||||||
std::string name2;
|
std::string name2;
|
||||||
std::string version2;
|
std::string version2;
|
||||||
TVMVersion version02;
|
TVMVersion version02;
|
||||||
|
|
||||||
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
|
if (GetObject<std::string>(_name2, name2) &&
|
||||||
{
|
GetObject<std::string>(_version2, version2) &&
|
||||||
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
TVMVersion::TryParse(version2, version02)) {
|
||||||
}
|
dependencies.push_back(
|
||||||
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
|
std::pair<std::string, TVMVersion>(name2,
|
||||||
{
|
version02));
|
||||||
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
} else if (GetObject<std::string>(_name2, name2) &&
|
||||||
|
GetObject(_version2, version02)) {
|
||||||
|
dependencies.push_back(
|
||||||
|
std::pair<std::string, TVMVersion>(name2,
|
||||||
|
version02));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if(GetObjectHeap<TList*>(_tools,_toolList))
|
if (GetObjectHeap<TList *>(_tools, _toolList)) {
|
||||||
{
|
for (int64_t i = 0; i < _toolList->Count(); i++) {
|
||||||
for(int64_t i = 0; i < _toolList->Count(); i++)
|
|
||||||
{
|
|
||||||
TObject _dep = _toolList->Get(i);
|
TObject _dep = _toolList->Get(i);
|
||||||
TDictionary* _depD;
|
TDictionary *_depD;
|
||||||
if(GetObjectHeap<TDictionary*>(_dep, _depD))
|
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
|
||||||
{
|
|
||||||
TObject _name2 = _depD->GetValue("Name");
|
TObject _name2 = _depD->GetValue("Name");
|
||||||
TObject _version2 = _depD->GetValue("Version");
|
TObject _version2 = _depD->GetValue("Version");
|
||||||
std::string name2;
|
std::string name2;
|
||||||
std::string version2;
|
std::string version2;
|
||||||
TVMVersion version02;
|
TVMVersion version02;
|
||||||
|
|
||||||
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
|
if (GetObject<std::string>(_name2, name2) &&
|
||||||
{
|
GetObject<std::string>(_version2, version2) &&
|
||||||
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
TVMVersion::TryParse(version2, version02)) {
|
||||||
}
|
tools.push_back(std::pair<std::string, TVMVersion>(
|
||||||
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
|
name2, version02));
|
||||||
{
|
} else if (GetObject<std::string>(_name2, name2) &&
|
||||||
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
GetObject(_version2, version02)) {
|
||||||
|
tools.push_back(std::pair<std::string, TVMVersion>(
|
||||||
|
name2, version02));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if(GetObjectHeap<TList*>(_sources,srcLst))
|
if (GetObjectHeap<TList *>(_sources, srcLst)) {
|
||||||
{
|
for (int64_t i = 0; i < srcLst->Count(); i++) {
|
||||||
for(int64_t i = 0; i < srcLst->Count(); i++)
|
|
||||||
{
|
|
||||||
TObject _src = srcLst->Get(i);
|
TObject _src = srcLst->Get(i);
|
||||||
TDictionary* _srcD;
|
TDictionary *_srcD;
|
||||||
if(GetObjectHeap<TDictionary*>(_src, _srcD))
|
if (GetObjectHeap<TDictionary *>(_src, _srcD)) {
|
||||||
{
|
|
||||||
TObject _sourceTxt = _srcD->GetValue("Source");
|
TObject _sourceTxt = _srcD->GetValue("Source");
|
||||||
TObject _filename = _srcD->GetValue("FileName");
|
TObject _filename = _srcD->GetValue("FileName");
|
||||||
|
|
||||||
|
|
||||||
std::string srctxt = "";
|
std::string srctxt = "";
|
||||||
std::string filename = "memory_" + std::to_string(i) + ".tcross";
|
std::string filename =
|
||||||
|
"memory_" + std::to_string(i) + ".tcross";
|
||||||
bool fromFile = false;
|
bool fromFile = false;
|
||||||
|
|
||||||
GetObject<std::string>(_sourceTxt,srctxt);
|
GetObject<std::string>(_sourceTxt, srctxt);
|
||||||
GetObject<std::string>(_filename,filename);
|
GetObject<std::string>(_filename, filename);
|
||||||
|
|
||||||
|
sources.push_back(
|
||||||
sources.push_back(std::pair<std::string,std::string>(srctxt,filename));
|
std::pair<std::string, std::string>(srctxt, filename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
std::vector<LexToken> tokens;
|
std::vector<LexToken> tokens;
|
||||||
for(auto source : sources)
|
for (auto source : sources) {
|
||||||
{
|
|
||||||
std::stringstream strm(source.first);
|
std::stringstream strm(source.first);
|
||||||
|
|
||||||
int res = Lex(source.second, strm, tokens);
|
int res = Lex(source.second, strm, tokens);
|
||||||
if(res != 0)
|
if (res != 0) {
|
||||||
{
|
return Failure(ls, "Lex error in file \"" + source.second +
|
||||||
return Failure(ls, "Lex error in file \"" + source.second + "\":" + std::to_string(res));
|
"\":" + std::to_string(res));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Parser parser(tokens,ls.GetGC(),comptimeEnv);
|
Parser parser(tokens, ls.GetGC(), comptimeEnv);
|
||||||
parser.debug = debug;
|
parser.debug = debug;
|
||||||
SyntaxNode n = parser.ParseRoot();
|
SyntaxNode n = parser.ParseRoot();
|
||||||
CodeGen gen;
|
CodeGen gen;
|
||||||
@@ -274,40 +251,34 @@ namespace Tesses::CrossLang
|
|||||||
gen.icon = icon;
|
gen.icon = icon;
|
||||||
std::string outpath;
|
std::string outpath;
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> stream;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> stream;
|
||||||
if(GetObject(_out, stream))
|
if (GetObject(_out, stream)) {
|
||||||
{
|
|
||||||
gen.Save(stream);
|
gen.Save(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Success(ls);
|
return Success(ls);
|
||||||
} catch(std::exception& ex)
|
} catch (std::exception &ex) {
|
||||||
{
|
|
||||||
return Failure(ls, ex.what());
|
return Failure(ls, ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static TObject VM_GetStacktrace(GCList& ls, std::vector<TObject> args)
|
static TObject VM_GetStacktrace(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
if (current_function != nullptr) {
|
||||||
if(current_function != nullptr)
|
if (current_function->thread != nullptr) {
|
||||||
{
|
TList *list = TList::Create(ls);
|
||||||
if(current_function->thread != nullptr)
|
|
||||||
{
|
|
||||||
TList* list = TList::Create(ls);
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
for(auto item : current_function->thread->call_stack_entries)
|
for (auto item : current_function->thread->call_stack_entries) {
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
if(item->callable->closure->name)
|
if (item->callable->closure->name)
|
||||||
dict->SetValue("Name", *item->callable->closure->name);
|
dict->SetValue("Name", *item->callable->closure->name);
|
||||||
|
|
||||||
dict->SetValue("Closure", item->callable->closure);
|
dict->SetValue("Closure", item->callable->closure);
|
||||||
dict->SetValue("FileName", item->callable->file->name + "-" + item->callable->file->version.ToString() + ".crvm");
|
dict->SetValue("FileName",
|
||||||
dict->SetValue("IP",(int64_t)item->ip);
|
item->callable->file->name + "-" +
|
||||||
if(item->srcline >= 1)
|
item->callable->file->version.ToString() +
|
||||||
{
|
".crvm");
|
||||||
|
dict->SetValue("IP", (int64_t)item->ip);
|
||||||
|
if (item->srcline >= 1) {
|
||||||
dict->SetValue("SourceFile", item->srcfile);
|
dict->SetValue("SourceFile", item->srcfile);
|
||||||
dict->SetValue("SourceLine",item->srcline);
|
dict->SetValue("SourceLine", item->srcline);
|
||||||
}
|
}
|
||||||
list->Add(dict);
|
list->Add(dict);
|
||||||
}
|
}
|
||||||
@@ -316,100 +287,100 @@ namespace Tesses::CrossLang
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
void TStd::RegisterVM(GC* gc,TRootEnvironment* env)
|
void TStd::RegisterVM(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||||
{
|
env->permissions.canRegisterVM = true;
|
||||||
env->permissions.canRegisterVM=true;
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
|
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
dict->DeclareFunction(gc, "GetStacktrace","Get the current stack trace", {}, VM_GetStacktrace);
|
dict->DeclareFunction(gc, "GetStacktrace", "Get the current stack trace",
|
||||||
dict->DeclareFunction(gc, "getRootEnvironmentAsDictionary","Get root environment as a dictionary",{},[env](GCList& ls, std::vector<TObject> args)-> TObject{
|
{}, VM_GetStacktrace);
|
||||||
|
dict->DeclareFunction(
|
||||||
|
gc, "getRootEnvironmentAsDictionary",
|
||||||
|
"Get root environment as a dictionary", {},
|
||||||
|
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return env->GetDictionary();
|
return env->GetDictionary();
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "getRootEnvironment","Get root environment, for reflection purposes",{},[env](GCList& ls2,std::vector<TObject> args)->TObject {return env;});
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc, "getCurrentEnvironment","Get current environment, for reflection purposes",{},VM_getCurrentEnvironment);
|
gc, "getRootEnvironment",
|
||||||
dict->DeclareFunction(gc, "CreateEnvironment","Create root environment",{"$dict"},[env](GCList& ls,std::vector<TObject> args)->TObject{
|
"Get root environment, for reflection purposes", {},
|
||||||
TDictionary* dict;
|
[env](GCList &ls2, std::vector<TObject> args) -> TObject {
|
||||||
if(GetArgumentHeap(args,0,dict))
|
return env;
|
||||||
{
|
});
|
||||||
auto renv = TRootEnvironment::Create(ls,dict);
|
dict->DeclareFunction(gc, "getCurrentEnvironment",
|
||||||
renv->permissions.customConsole = env->permissions.customConsole;
|
"Get current environment, for reflection purposes",
|
||||||
|
{}, VM_getCurrentEnvironment);
|
||||||
|
dict->DeclareFunction(
|
||||||
|
gc, "CreateEnvironment", "Create root environment", {"$dict"},
|
||||||
|
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
TDictionary *dict;
|
||||||
|
if (GetArgumentHeap(args, 0, dict)) {
|
||||||
|
auto renv = TRootEnvironment::Create(ls, dict);
|
||||||
|
renv->permissions.customConsole =
|
||||||
|
env->permissions.customConsole;
|
||||||
return renv;
|
return renv;
|
||||||
}
|
} else {
|
||||||
else
|
auto renv =
|
||||||
{
|
TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||||
auto renv = TRootEnvironment::Create(ls,TDictionary::Create(ls));
|
renv->permissions.customConsole =
|
||||||
renv->permissions.customConsole = env->permissions.customConsole;
|
env->permissions.customConsole;
|
||||||
return renv;
|
return renv;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "LoadExecutable", "Load a crossvm executable",{"stream"},[](GCList& ls,std::vector<TObject> args)->TObject{
|
dict->DeclareFunction(
|
||||||
|
gc, "LoadExecutable", "Load a crossvm executable", {"stream"},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||||
if(GetArgument(args,0,strm))
|
if (GetArgument(args, 0, strm)) {
|
||||||
{
|
TFile *f = TFile::Create(ls);
|
||||||
TFile* f =TFile::Create(ls);
|
f->Load(ls.GetGC(), strm);
|
||||||
f->Load(ls.GetGC(),strm);
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "Eval", "Eval source code",{"source"}, VM_Eval);
|
|
||||||
dict->DeclareFunction(gc, "Compile", "Compile Source",{"dict"},VM_Compile);
|
|
||||||
|
|
||||||
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast", {"source"}, VM_SourceToAst);
|
dict->DeclareFunction(gc, "Eval", "Eval source code", {"source"}, VM_Eval);
|
||||||
dict->DeclareFunction(gc, "getRuntimeVersion","Get the runtime version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
|
dict->DeclareFunction(gc, "Compile", "Compile Source", {"dict"},
|
||||||
return TVMVersion(CROSSLANG_MAJOR,CROSSLANG_MINOR,CROSSLANG_PATCH,0,TVMVersionStage::DevVersion);
|
VM_Compile);
|
||||||
|
|
||||||
|
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast",
|
||||||
|
{"source"}, VM_SourceToAst);
|
||||||
|
dict->DeclareFunction(
|
||||||
|
gc, "getRuntimeVersion", "Get the runtime version", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
return TVMVersion(CROSSLANG_MAJOR, CROSSLANG_MINOR, CROSSLANG_PATCH,
|
||||||
|
0, TVMVersionStage::DevVersion);
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "getBytecodeVersion","Get the bytecode version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
|
dict->DeclareFunction(
|
||||||
return TVMVersion(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
|
gc, "getBytecodeVersion", "Get the bytecode version", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
return TVMVersion(
|
||||||
|
CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
|
||||||
|
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
|
||||||
|
CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "getIsRunning","Is the program still running",{},[](GCList& ls, std::vector<TObject> args)->TObject {
|
dict->DeclareFunction(gc, "getIsRunning", "Is the program still running",
|
||||||
|
{},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return Tesses::Framework::TF_IsRunning();
|
return Tesses::Framework::TF_IsRunning();
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "RunEventLoopItteration","Run Event Loop Itteration",{},[](GCList& ls, std::vector<TObject> args)->TObject {
|
dict->DeclareFunction(gc, "RunEventLoopItteration",
|
||||||
|
"Run Event Loop Itteration", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
Tesses::Framework::TF_RunEventLoopItteration();
|
Tesses::Framework::TF_RunEventLoopItteration();
|
||||||
return Undefined();
|
return Undefined();
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "RunEventLoop","Run Event Loop",{},[](GCList& ls, std::vector<TObject> args)->TObject {
|
dict->DeclareFunction(gc, "RunEventLoop", "Run Event Loop", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
Tesses::Framework::TF_RunEventLoop();
|
Tesses::Framework::TF_RunEventLoop();
|
||||||
return Undefined();
|
return Undefined();
|
||||||
});
|
});
|
||||||
dict->DeclareFunction(gc, "Merge", "Merge crvm files", {"srcVFS","sourcePath","destVFS"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcVFS;
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> destVFS;
|
|
||||||
Tesses::Framework::Filesystem::VFSPath sourcePath;
|
|
||||||
if(GetArgument(args,0, srcVFS) && GetArgumentAsPath(args,1,sourcePath) && GetArgument(args,2,destVFS))
|
|
||||||
return Merge(srcVFS, sourcePath, destVFS);
|
|
||||||
return Undefined();
|
|
||||||
});
|
|
||||||
dict->DeclareFunction(gc, "Disassemble","Disassemble crvm file",{"strm","vfs","$generateJSON","$extractResources"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
|
||||||
bool generateJSON=true;
|
|
||||||
bool extractResources=true;
|
|
||||||
if(GetArgument(args,0,strm) && GetArgument(args,1, vfs))
|
|
||||||
{
|
|
||||||
GetArgument(args,2,generateJSON);
|
|
||||||
GetArgument(args,3,extractResources);
|
|
||||||
Disassemble(strm,vfs, generateJSON, extractResources);
|
|
||||||
}
|
|
||||||
return Undefined();
|
|
||||||
});
|
|
||||||
dict->DeclareFunction(gc, "Assemble", "Assemble crvm file",{"vfs"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
|
||||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
|
||||||
if(GetArgument(args,0, vfs))
|
|
||||||
return Assemble(vfs);
|
|
||||||
return Undefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
env->DeclareVariable("VM", dict);
|
env->DeclareVariable("VM", dict);
|
||||||
|
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,28 +1,26 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
TAny* TAny::Create(GCList& ls)
|
TAny *TAny::Create(GCList &ls) {
|
||||||
{
|
TAny *anyObj = new TAny();
|
||||||
TAny* anyObj = new TAny();
|
|
||||||
|
|
||||||
GC* gc = ls.GetGC();
|
std::shared_ptr<GC> gc = ls.GetGC();
|
||||||
ls.Add(anyObj);
|
ls.Add(anyObj);
|
||||||
gc->Watch(anyObj);
|
gc->Watch(anyObj);
|
||||||
return anyObj;
|
return anyObj;
|
||||||
}
|
}
|
||||||
TAny* TAny::Create(GCList* ls)
|
TAny *TAny::Create(GCList *ls) {
|
||||||
{
|
TAny *anyObj = new TAny();
|
||||||
TAny* anyObj = new TAny();
|
|
||||||
|
|
||||||
GC* gc = ls->GetGC();
|
std::shared_ptr<GC> gc = ls->GetGC();
|
||||||
ls->Add(anyObj);
|
ls->Add(anyObj);
|
||||||
gc->Watch(anyObj);
|
gc->Watch(anyObj);
|
||||||
return anyObj;
|
return anyObj;
|
||||||
}
|
|
||||||
void TAny::Mark()
|
|
||||||
{
|
|
||||||
if(this->marked) return;
|
|
||||||
this->marked=true;
|
|
||||||
GC::Mark(this->other);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
void TAny::Mark() {
|
||||||
|
if (this->marked)
|
||||||
|
return;
|
||||||
|
this->marked = true;
|
||||||
|
GC::Mark(this->other);
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,116 +1,96 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
|
||||||
|
|
||||||
TAssociativeArray* TAssociativeArray::Create(GCList& ls)
|
TAssociativeArray *TAssociativeArray::Create(GCList &ls) {
|
||||||
{
|
TAssociativeArray *list = new TAssociativeArray();
|
||||||
TAssociativeArray* list=new TAssociativeArray();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
GC* _gc = ls.GetGC();
|
|
||||||
ls.Add(list);
|
ls.Add(list);
|
||||||
_gc->Watch(list);
|
_gc->Watch(list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
TAssociativeArray* TAssociativeArray::Create(GCList* ls)
|
TAssociativeArray *TAssociativeArray::Create(GCList *ls) {
|
||||||
{
|
TAssociativeArray *list = new TAssociativeArray();
|
||||||
TAssociativeArray* list=new TAssociativeArray();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
GC* _gc = ls->GetGC();
|
|
||||||
ls->Add(list);
|
ls->Add(list);
|
||||||
_gc->Watch(list);
|
_gc->Watch(list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
void TAssociativeArray::Set(GC* gc, TObject key, TObject value)
|
void TAssociativeArray::Set(std::shared_ptr<GC> gc, TObject key,
|
||||||
{
|
TObject value) {
|
||||||
if(std::holds_alternative<Undefined>(key)) return;
|
if (std::holds_alternative<Undefined>(key))
|
||||||
|
return;
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for(auto index = this->items.begin(); index < this->items.end(); index++)
|
for (auto index = this->items.begin(); index < this->items.end(); index++) {
|
||||||
{
|
auto first = index->first;
|
||||||
auto first= index->first;
|
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
auto eq = Equals(gc,key,first);
|
auto eq = Equals(gc, key, first);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
if(eq)
|
if (eq) {
|
||||||
{
|
if (std::holds_alternative<Undefined>(value)) {
|
||||||
if(std::holds_alternative<Undefined>(value))
|
|
||||||
{
|
|
||||||
this->items.erase(index);
|
this->items.erase(index);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
index->second = value;
|
index->second = value;
|
||||||
}
|
}
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->items.push_back(std::pair<TObject,TObject>(key,value));
|
this->items.push_back(std::pair<TObject, TObject>(key, value));
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
TObject TAssociativeArray::Get(GC* gc, TObject key)
|
TObject TAssociativeArray::Get(std::shared_ptr<GC> gc, TObject key) {
|
||||||
{
|
if (std::holds_alternative<Undefined>(key))
|
||||||
if(std::holds_alternative<Undefined>(key)) return Undefined();
|
return Undefined();
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
for(auto& item : this->items)
|
for (auto &item : this->items) {
|
||||||
{
|
auto first = item.first;
|
||||||
auto first= item.first;
|
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
auto eq = Equals(gc,key,first);
|
auto eq = Equals(gc, key, first);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
if(eq)
|
if (eq) {
|
||||||
{
|
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return item.second;
|
return item.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject TAssociativeArray::GetKey(int64_t index)
|
TObject TAssociativeArray::GetKey(int64_t index) {
|
||||||
{
|
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||||
if(index >= 0 && index < (int64_t)this->items.size())
|
|
||||||
{
|
|
||||||
return this->items[index].first;
|
return this->items[index].first;
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject TAssociativeArray::GetValue(int64_t index)
|
TObject TAssociativeArray::GetValue(int64_t index) {
|
||||||
{
|
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||||
if(index >= 0 && index < (int64_t)this->items.size())
|
|
||||||
{
|
|
||||||
return this->items[index].second;
|
return this->items[index].second;
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
void TAssociativeArray::SetKey(int64_t index, TObject key)
|
void TAssociativeArray::SetKey(int64_t index, TObject key) {
|
||||||
{
|
|
||||||
|
|
||||||
if(std::holds_alternative<Undefined>(key)) return;
|
if (std::holds_alternative<Undefined>(key))
|
||||||
if(index >= 0 && index < (int64_t)this->items.size())
|
return;
|
||||||
{
|
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||||
this->items[index].first=key;
|
this->items[index].first = key;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
void TAssociativeArray::SetValue(int64_t index, TObject value) {
|
||||||
|
if (std::holds_alternative<Undefined>(value))
|
||||||
|
return;
|
||||||
|
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||||
|
this->items[index].first = value;
|
||||||
}
|
}
|
||||||
void TAssociativeArray::SetValue(int64_t index,TObject value)
|
}
|
||||||
{
|
int64_t TAssociativeArray::Count() { return (int64_t)this->items.size(); }
|
||||||
if(std::holds_alternative<Undefined>(value)) return;
|
void TAssociativeArray::Mark() {
|
||||||
if(index >= 0 && index < (int64_t)this->items.size())
|
if (this->marked)
|
||||||
{
|
return;
|
||||||
this->items[index].first=value;
|
this->marked = true;
|
||||||
}
|
for (auto &item : this->items) {
|
||||||
}
|
|
||||||
int64_t TAssociativeArray::Count()
|
|
||||||
{
|
|
||||||
return (int64_t)this->items.size();
|
|
||||||
}
|
|
||||||
void TAssociativeArray::Mark()
|
|
||||||
{
|
|
||||||
if(this->marked) return;
|
|
||||||
this->marked=true;
|
|
||||||
for(auto& item : this->items)
|
|
||||||
{
|
|
||||||
GC::Mark(item.first);
|
GC::Mark(item.first);
|
||||||
GC::Mark(item.second);
|
GC::Mark(item.second);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,126 +1,101 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
//THANKS TO https://www.youtube.com/watch?v=R-z2Hv-7nxk
|
// THANKS TO https://www.youtube.com/watch?v=R-z2Hv-7nxk
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
TTask::TTask(GC* gc)
|
TTask::TTask(std::shared_ptr<GC> gc) { this->gc = gc; }
|
||||||
{
|
TTask *TTask::Create(GCList &ls) {
|
||||||
this->gc = gc;
|
TTask *task = new TTask(ls.GetGC());
|
||||||
}
|
|
||||||
TTask* TTask::Create(GCList& ls)
|
|
||||||
{
|
|
||||||
TTask* task = new TTask(ls.GetGC());
|
|
||||||
ls.Add(task);
|
ls.Add(task);
|
||||||
task->gc->Watch(task);
|
task->gc->Watch(task);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
bool TTask::IsCompleted()
|
bool TTask::IsCompleted() {
|
||||||
{
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
bool r = this->isCompleted;
|
bool r = this->isCompleted;
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
TTask* TTask::ContinueWith(GCList& ls, TCallable* callable)
|
TTask *TTask::ContinueWith(GCList &ls, TCallable *callable) {
|
||||||
{
|
TTask *task = TTask::Create(ls);
|
||||||
TTask* task = TTask::Create(ls);
|
|
||||||
|
|
||||||
TExternalMethod* em = TExternalMethod::Create(ls,"Internal async thing",{"_asyncObj"},[callable,task](GCList& ls,std::vector<TObject> args)->TObject{
|
TExternalMethod *em = TExternalMethod::Create(
|
||||||
|
ls, "Internal async thing", {"_asyncObj"},
|
||||||
|
[callable, task](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
try {
|
try {
|
||||||
task->SetSucceeded(callable->Call(ls,args));
|
task->SetSucceeded(callable->Call(ls, args));
|
||||||
} catch(...) {
|
} catch (...) {
|
||||||
task->SetFailed(std::current_exception());
|
task->SetFailed(std::current_exception());
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
});
|
});
|
||||||
em->watch = {callable,task};
|
em->watch = {callable, task};
|
||||||
|
|
||||||
this->gc->BarrierBegin();
|
this->gc->BarrierBegin();
|
||||||
if(this->isCompleted)
|
if (this->isCompleted) {
|
||||||
{
|
|
||||||
this->gc->BarrierEnd();
|
this->gc->BarrierEnd();
|
||||||
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
|
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
|
||||||
auto cobj = this->obj;
|
auto cobj = this->obj;
|
||||||
ls->Add(cobj);
|
ls->Add(cobj);
|
||||||
ls->Add(em);
|
ls->Add(em);
|
||||||
this->gc->GetPool()->Schedule([ls,em,cobj](size_t s)->void {
|
this->gc->GetPool()->Schedule(
|
||||||
em->Call(*ls,{cobj});
|
[ls, em, cobj](size_t s) -> void { em->Call(*ls, {cobj}); });
|
||||||
});
|
|
||||||
return task;
|
return task;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
this->cont = em;
|
this->cont = em;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->gc->BarrierEnd();
|
this->gc->BarrierEnd();
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
void TTask::ContinueWith(TCallable* callable)
|
void TTask::ContinueWith(TCallable *callable) {
|
||||||
{
|
|
||||||
this->gc->BarrierBegin();
|
this->gc->BarrierBegin();
|
||||||
if(this->isCompleted)
|
if (this->isCompleted) {
|
||||||
{
|
|
||||||
this->gc->BarrierEnd();
|
this->gc->BarrierEnd();
|
||||||
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
|
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
|
||||||
auto cobj = this->obj;
|
auto cobj = this->obj;
|
||||||
ls->Add(cobj);
|
ls->Add(cobj);
|
||||||
ls->Add(callable);
|
ls->Add(callable);
|
||||||
this->gc->GetPool()->Schedule([ls,callable,cobj](size_t s)->void {
|
this->gc->GetPool()->Schedule([ls, callable, cobj](size_t s) -> void {
|
||||||
callable->Call(*ls,{cobj});
|
callable->Call(*ls, {cobj});
|
||||||
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
this->cont = callable;
|
this->cont = callable;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->gc->BarrierEnd();
|
this->gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TTask::SetFailed(std::exception_ptr ex) {
|
||||||
|
|
||||||
|
|
||||||
void TTask::SetFailed(std::exception_ptr ex)
|
|
||||||
{
|
|
||||||
this->ex = ex;
|
this->ex = ex;
|
||||||
this->SetSucceeded(nullptr);
|
this->SetSucceeded(nullptr);
|
||||||
}
|
}
|
||||||
void TTask::SetSucceeded(TObject v)
|
void TTask::SetSucceeded(TObject v) {
|
||||||
{
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
if(this->isCompleted)
|
if (this->isCompleted) {
|
||||||
{
|
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->isCompleted=true;
|
this->isCompleted = true;
|
||||||
this->obj = v;
|
this->obj = v;
|
||||||
auto cont = this->cont;
|
auto cont = this->cont;
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
if(cont != nullptr)
|
if (cont != nullptr) {
|
||||||
{
|
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
|
||||||
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
|
|
||||||
|
|
||||||
auto callable = cont;
|
auto callable = cont;
|
||||||
ls->Add(v);
|
ls->Add(v);
|
||||||
ls->Add(callable);
|
ls->Add(callable);
|
||||||
this->gc->GetPool()->Schedule([ls,callable,v](size_t s)->void {
|
this->gc->GetPool()->Schedule(
|
||||||
callable->Call(*ls,{v});
|
[ls, callable, v](size_t s) -> void { callable->Call(*ls, {v}); });
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TObject TTask::Wait()
|
TObject TTask::Wait() {
|
||||||
{
|
while (true) {
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
if(this->isCompleted)
|
if (this->isCompleted) {
|
||||||
{
|
if (this->ex) {
|
||||||
if(this->ex)
|
|
||||||
{
|
|
||||||
auto error = this->ex;
|
auto error = this->ex;
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
std::rethrow_exception(error);
|
std::rethrow_exception(error);
|
||||||
@@ -129,74 +104,70 @@ namespace Tesses::CrossLang {
|
|||||||
auto o = this->obj;
|
auto o = this->obj;
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
return o;
|
return o;
|
||||||
|
|
||||||
}
|
}
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TTask::Mark()
|
void TTask::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked=true;
|
this->marked = true;
|
||||||
GC::Mark(this->obj);
|
GC::Mark(this->obj);
|
||||||
if(this->cont != nullptr)
|
if (this->cont != nullptr)
|
||||||
this->cont->Mark();
|
this->cont->Mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
TTask* TTask::Run(GCList& ls, TCallable* callable)
|
TTask *TTask::Run(GCList &ls, TCallable *callable) {
|
||||||
{
|
TTask *task = TTask::Create(ls);
|
||||||
TTask* task = TTask::Create(ls);
|
std::shared_ptr<GCList> ls2 = std::make_shared<GCList>(ls.GetGC());
|
||||||
std::shared_ptr<GCList> ls2=std::make_shared<GCList>(ls.GetGC());
|
|
||||||
ls2->Add(callable);
|
ls2->Add(callable);
|
||||||
ls2->Add(task);
|
ls2->Add(task);
|
||||||
|
|
||||||
ls.GetGC()->GetPool()->Schedule([ls2,callable,task](size_t s)->void {
|
ls.GetGC()->GetPool()->Schedule([ls2, callable, task](size_t s) -> void {
|
||||||
try
|
try {
|
||||||
{
|
task->SetSucceeded(callable->Call(*ls2, {}));
|
||||||
task->SetSucceeded(callable->Call(*ls2,{}));
|
} catch (...) {
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
task->SetFailed(std::current_exception());
|
task->SetFailed(std::current_exception());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTask* TTask::FromResult(GCList& ls, TObject v)
|
TTask *TTask::FromResult(GCList &ls, TObject v) {
|
||||||
{
|
TTask *task = TTask::Create(ls);
|
||||||
TTask* task = TTask::Create(ls);
|
|
||||||
task->SetSucceeded(v);
|
task->SetSucceeded(v);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TTaskCseObj {
|
||||||
|
std::shared_ptr<GC> gc;
|
||||||
|
TTask *task;
|
||||||
|
|
||||||
class TTaskCseObj {
|
|
||||||
GC* gc;
|
|
||||||
TTask* task;
|
|
||||||
public:
|
public:
|
||||||
TTaskCseObj(GC* gc, TTask* task)
|
TTaskCseObj(std::shared_ptr<GC> gc, TTask *task) {
|
||||||
{
|
|
||||||
this->gc = gc;
|
this->gc = gc;
|
||||||
this->task = task;
|
this->task = task;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Invoke(std::shared_ptr<TTaskCseObj> shared_o,CallStackEntry* cse, TObject o)
|
void Invoke(std::shared_ptr<TTaskCseObj> shared_o, CallStackEntry *cse,
|
||||||
{
|
TObject o) {
|
||||||
try {
|
try {
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
cse->Push(gc,o);
|
cse->Push(gc, o);
|
||||||
auto res = cse->Resume(ls);
|
auto res = cse->Resume(ls);
|
||||||
CallStackEntry* cse2;
|
CallStackEntry *cse2;
|
||||||
if(GetObjectHeap(res,cse2))
|
if (GetObjectHeap(res, cse2)) {
|
||||||
{
|
auto taskPiece = cse2->Pop(ls);
|
||||||
auto taskPiece=cse2->Pop(ls);
|
TTask *task;
|
||||||
TTask* task;
|
if (GetObjectHeap(taskPiece, task)) {
|
||||||
if(GetObjectHeap(taskPiece,task))
|
auto em = TExternalMethod::Create(
|
||||||
{
|
ls, "", {"obj"},
|
||||||
auto em = TExternalMethod::Create(ls,"",{"obj"},[cse2,task,shared_o](GCList& ls, std::vector<TObject> args)->TObject {
|
[cse2, task, shared_o](
|
||||||
|
GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
shared_o->Invoke(shared_o,cse2,args.empty() ? (TObject)Undefined():args[0]);
|
shared_o->Invoke(shared_o, cse2,
|
||||||
|
args.empty() ? (TObject)Undefined()
|
||||||
|
: args[0]);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
});
|
});
|
||||||
@@ -205,44 +176,40 @@ namespace Tesses::CrossLang {
|
|||||||
|
|
||||||
task->ContinueWith(em);
|
task->ContinueWith(em);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this->task->SetSucceeded(res);
|
this->task->SetSucceeded(res);
|
||||||
}
|
}
|
||||||
} catch(...) {
|
} catch (...) {
|
||||||
this->task->SetFailed(std::current_exception());
|
this->task->SetFailed(std::current_exception());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TTask* TTask::FromClosure(GCList& ls, TClosure* closure)
|
TTask *TTask::FromClosure(GCList &ls, TClosure *closure) {
|
||||||
{
|
auto res = closure->Call(ls, {});
|
||||||
auto res = closure->Call(ls,{});
|
CallStackEntry *ent;
|
||||||
CallStackEntry* ent;
|
if (GetObjectHeap(res, ent)) {
|
||||||
if(GetObjectHeap(res,ent))
|
return FromCallStackEntry(ls, ent);
|
||||||
{
|
|
||||||
return FromCallStackEntry(ls,ent);
|
|
||||||
}
|
}
|
||||||
return FromResult(ls,res);
|
return FromResult(ls, res);
|
||||||
}
|
}
|
||||||
TTask* TTask::FromCallStackEntry(GCList& ls, CallStackEntry* ent)
|
TTask *TTask::FromCallStackEntry(GCList &ls, CallStackEntry *ent) {
|
||||||
{
|
TTask *task = TTask::Create(ls);
|
||||||
TTask* task = TTask::Create(ls);
|
|
||||||
|
|
||||||
//try {
|
// try {
|
||||||
GCList ls2(ls.GetGC());
|
GCList ls2(ls.GetGC());
|
||||||
GC* gc = ls.GetGC();
|
std::shared_ptr<GC> gc = ls.GetGC();
|
||||||
|
|
||||||
std::shared_ptr<TTaskCseObj> obj = std::make_shared<TTaskCseObj>(gc,task);
|
|
||||||
|
|
||||||
|
std::shared_ptr<TTaskCseObj> obj = std::make_shared<TTaskCseObj>(gc, task);
|
||||||
|
|
||||||
ls2.Add(task);
|
ls2.Add(task);
|
||||||
auto res = ent->Pop(ls2);
|
auto res = ent->Pop(ls2);
|
||||||
TTask* task2;
|
TTask *task2;
|
||||||
if(GetObjectHeap(res,task2))
|
if (GetObjectHeap(res, task2)) {
|
||||||
{
|
auto em = TExternalMethod::Create(
|
||||||
auto em = TExternalMethod::Create(ls2,"",{},[ent,task,obj](GCList& ls, std::vector<TObject> args)->TObject {
|
ls2, "", {},
|
||||||
|
[ent, task, obj](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
obj->Invoke(obj,ent,args.empty() ? (TObject)Undefined():args[0]);
|
obj->Invoke(obj, ent,
|
||||||
|
args.empty() ? (TObject)Undefined() : args[0]);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
});
|
});
|
||||||
@@ -257,5 +224,5 @@ namespace Tesses::CrossLang {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,41 +1,35 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
std::string TClassObject::TypeName() {
|
||||||
std::string TClassObject::TypeName()
|
|
||||||
{
|
|
||||||
std::string type = "class ";
|
std::string type = "class ";
|
||||||
type += this->name;
|
type += this->name;
|
||||||
for(auto& item : this->inherit_tree) type += " : " + item;
|
for (auto &item : this->inherit_tree)
|
||||||
|
type += " : " + item;
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
TObject TClassObject::CallMethod(GCList& ls, std::string className, std::string name,std::vector<TObject> args)
|
TObject TClassObject::CallMethod(GCList &ls, std::string className,
|
||||||
{
|
std::string name, std::vector<TObject> args) {
|
||||||
auto value = this->GetValue(className,name);
|
auto value = this->GetValue(className, name);
|
||||||
TCallable* callable;
|
TCallable *callable;
|
||||||
if(GetObjectHeap(value, callable))
|
if (GetObjectHeap(value, callable)) {
|
||||||
{
|
return callable->Call(ls, args);
|
||||||
return callable->Call(ls,args);
|
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TClassObjectEntry* TClassObject::GetEntry(std::string classN, std::string key)
|
TClassObjectEntry *TClassObject::GetEntry(std::string classN, std::string key) {
|
||||||
{
|
for (auto &item : this->entries) {
|
||||||
for(auto& item : this->entries)
|
if (item.name == key) {
|
||||||
{
|
switch (item.modifier) {
|
||||||
if(item.name == key)
|
|
||||||
{
|
|
||||||
switch(item.modifier)
|
|
||||||
{
|
|
||||||
case TClassModifier::Private:
|
case TClassModifier::Private:
|
||||||
if(classN != item.owner) return nullptr;
|
if (classN != item.owner)
|
||||||
|
return nullptr;
|
||||||
break;
|
break;
|
||||||
case TClassModifier::Protected:
|
case TClassModifier::Protected:
|
||||||
if(classN.empty()) return nullptr;
|
if (classN.empty())
|
||||||
if(classN != item.owner)
|
return nullptr;
|
||||||
{
|
if (classN != item.owner) {
|
||||||
for(auto inh : this->inherit_tree)
|
for (auto inh : this->inherit_tree) {
|
||||||
{
|
if (inh == classN) {
|
||||||
if(inh == classN) {
|
|
||||||
|
|
||||||
return &item;
|
return &item;
|
||||||
}
|
}
|
||||||
@@ -43,98 +37,105 @@ namespace Tesses::CrossLang
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// DO NOTHING
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return &item;
|
return &item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
TClassObject* TClassObject::Create(GCList& ls, TFile* f, uint32_t classIndex, TEnvironment* env, std::vector<TObject> args)
|
TClassObject *TClassObject::Create(GCList &ls, TFile *f, uint32_t classIndex,
|
||||||
{
|
TEnvironment *env,
|
||||||
return Create(&ls,f,classIndex,env,args);
|
std::vector<TObject> args) {
|
||||||
}
|
return Create(&ls, f, classIndex, env, args);
|
||||||
std::string JoinPeriod(std::vector<std::string>& p)
|
}
|
||||||
{
|
std::string JoinPeriod(std::vector<std::string> &p) {
|
||||||
std::string newStr = "";
|
std::string newStr = "";
|
||||||
for(size_t i = 0; i < p.size(); i++)
|
for (size_t i = 0; i < p.size(); i++) {
|
||||||
{
|
if (i > 0)
|
||||||
if(i > 0) newStr.push_back('.');
|
newStr.push_back('.');
|
||||||
newStr += p[i];
|
newStr += p[i];
|
||||||
}
|
}
|
||||||
return newStr;
|
return newStr;
|
||||||
}
|
}
|
||||||
TClassObject* TClassObject::Create(GCList* ls, TFile* f, uint32_t classIndex, TEnvironment* env, std::vector<TObject> args)
|
TClassObject *TClassObject::Create(GCList *ls, TFile *f, uint32_t classIndex,
|
||||||
{
|
TEnvironment *env,
|
||||||
if(ls == nullptr) return nullptr;
|
std::vector<TObject> args) {
|
||||||
TClassObject* obj = new TClassObject();
|
if (ls == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
TClassObject *obj = new TClassObject();
|
||||||
obj->file = f;
|
obj->file = f;
|
||||||
obj->classIndex = classIndex;
|
obj->classIndex = classIndex;
|
||||||
obj->ogEnv=env;
|
obj->ogEnv = env;
|
||||||
obj->env = TClassEnvironment::Create(ls,env,obj);
|
obj->env = TClassEnvironment::Create(ls, env, obj);
|
||||||
obj->name = JoinPeriod(f->classes[classIndex].name);
|
obj->name = JoinPeriod(f->classes[classIndex].name);
|
||||||
bool hasToString=false;
|
|
||||||
|
|
||||||
for(auto entry : f->classes[classIndex].entry)
|
bool hasToString = false;
|
||||||
{
|
|
||||||
if(entry.modifier == TClassModifier::Static) continue;
|
for (auto &entry : f->classes[classIndex].entry) {
|
||||||
|
if (entry.modifier == TClassModifier::Static)
|
||||||
|
continue;
|
||||||
TClassObjectEntry ent;
|
TClassObjectEntry ent;
|
||||||
ent.name = entry.name;
|
ent.name = entry.name;
|
||||||
ent.modifier = entry.modifier;
|
ent.modifier = entry.modifier;
|
||||||
ent.canSet = !entry.isFunction;
|
ent.canSet = !entry.isFunction;
|
||||||
ent.owner = obj->name;
|
ent.owner = obj->name;
|
||||||
|
|
||||||
if(entry.isFunction)
|
if (entry.isFunction) {
|
||||||
{
|
if (entry.name == "ToString")
|
||||||
if(ent.name == "ToString") hasToString=true;
|
hasToString = true;
|
||||||
if(entry.isAbstract)
|
if (entry.isAbstract) {
|
||||||
{
|
|
||||||
delete obj;
|
delete obj;
|
||||||
throw VMException("Method " + ent.name + " in " + ent.owner + " is abstract.");
|
throw VMException("Method " + ent.name + " in " + ent.owner +
|
||||||
}
|
" is abstract.");
|
||||||
else
|
} else {
|
||||||
{
|
auto clos =
|
||||||
auto clos = TClosure::Create(ls,obj->env,obj->file,entry.chunkId);
|
TClosure::Create(ls, obj->env, obj->file, entry.chunkId);
|
||||||
clos->documentation = entry.documentation;
|
clos->documentation = entry.documentation;
|
||||||
clos->className = ent.owner;
|
clos->className = ent.owner;
|
||||||
ent.value = clos;
|
ent.value = clos;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
if (entry.isAbstract)
|
||||||
|
ent.value = Undefined();
|
||||||
else {
|
else {
|
||||||
if(entry.isAbstract) ent.value = Undefined();
|
auto clos =
|
||||||
else {
|
TClosure::Create(ls, obj->env, obj->file, entry.chunkId);
|
||||||
auto clos = TClosure::Create(ls,obj->env,obj->file,entry.chunkId);
|
|
||||||
|
|
||||||
clos->className=ent.owner;
|
clos->className = ent.owner;
|
||||||
ent.value = clos->Call(*ls,{});
|
ent.value = clos->Call(*ls, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj->entries.push_back(ent);
|
obj->entries.push_back(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
TClass* clsCur = &f->classes[classIndex];
|
TClass *clsCur = &f->classes[classIndex];
|
||||||
TRootEnvironment* rEnv = env->GetRootEnvironment();
|
TRootEnvironment *rEnv = env->GetRootEnvironment();
|
||||||
while(!clsCur->inherits.empty() && !(clsCur->inherits.size() == 1 && clsCur->inherits[0] == "ClassObject"))
|
while (!clsCur->inherits.empty() &&
|
||||||
{
|
!(clsCur->inherits.size() == 1 &&
|
||||||
|
clsCur->inherits[0] == "ClassObject")) {
|
||||||
obj->inherit_tree.push_back(JoinPeriod(clsCur->inherits));
|
obj->inherit_tree.push_back(JoinPeriod(clsCur->inherits));
|
||||||
size_t idx;
|
size_t idx;
|
||||||
if(rEnv->TryFindClass(clsCur->inherits,idx))
|
if (rEnv->TryFindClass(clsCur->inherits, idx)) {
|
||||||
{
|
|
||||||
auto file = rEnv->classes[idx].first;
|
auto file = rEnv->classes[idx].first;
|
||||||
clsCur = &rEnv->classes[idx].first->classes.at(rEnv->classes[idx].second);
|
clsCur = &rEnv->classes[idx].first->classes.at(
|
||||||
|
rEnv->classes[idx].second);
|
||||||
auto ownerNow = JoinPeriod(clsCur->name);
|
auto ownerNow = JoinPeriod(clsCur->name);
|
||||||
for(auto entry : clsCur->entry)
|
for (auto &entry : clsCur->entry) {
|
||||||
{
|
if (entry.modifier == TClassModifier::Static)
|
||||||
if(entry.modifier == TClassModifier::Static) continue;
|
continue;
|
||||||
bool cont=false;
|
bool cont = false;
|
||||||
for(auto e : obj->entries)
|
for (auto e : obj->entries)
|
||||||
if(e.name == entry.name)
|
if (e.name == entry.name) {
|
||||||
{
|
cont = true;
|
||||||
cont=true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(cont) continue;
|
if (cont)
|
||||||
|
continue;
|
||||||
|
|
||||||
TClassObjectEntry ent;
|
TClassObjectEntry ent;
|
||||||
ent.name = entry.name;
|
ent.name = entry.name;
|
||||||
@@ -142,103 +143,106 @@ namespace Tesses::CrossLang
|
|||||||
ent.canSet = !entry.isFunction;
|
ent.canSet = !entry.isFunction;
|
||||||
ent.owner = ownerNow;
|
ent.owner = ownerNow;
|
||||||
|
|
||||||
if(entry.isFunction)
|
if (entry.isFunction) {
|
||||||
{
|
|
||||||
|
|
||||||
if(ent.name == "ToString") hasToString=true;
|
if (entry.name == "ToString")
|
||||||
if(entry.isAbstract)
|
hasToString = true;
|
||||||
{
|
if (entry.isAbstract) {
|
||||||
delete obj;
|
delete obj;
|
||||||
throw VMException("Method " + ent.name + " in " + ownerNow + " is abstract.");
|
throw VMException("Method " + ent.name + " in " +
|
||||||
}
|
ownerNow + " is abstract.");
|
||||||
else
|
} else {
|
||||||
{
|
auto clos =
|
||||||
auto clos = TClosure::Create(ls,obj->env,file,entry.chunkId);
|
TClosure::Create(ls, obj->env, file, entry.chunkId);
|
||||||
clos->closure->name = obj->name + "::" + ent.name;
|
clos->closure->name = obj->name + "::" + ent.name;
|
||||||
clos->className = ownerNow;
|
clos->className = ownerNow;
|
||||||
clos->documentation = entry.documentation;
|
clos->documentation = entry.documentation;
|
||||||
ent.value = clos;
|
ent.value = clos;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
if (entry.isAbstract)
|
||||||
|
ent.value = Undefined();
|
||||||
else {
|
else {
|
||||||
if(entry.isAbstract) ent.value = Undefined();
|
auto clos =
|
||||||
else {
|
TClosure::Create(ls, obj->env, file, entry.chunkId);
|
||||||
auto clos = TClosure::Create(ls,obj->env,file,entry.chunkId);
|
|
||||||
clos->closure->name = obj->name + "::" + ent.name;
|
clos->closure->name = obj->name + "::" + ent.name;
|
||||||
clos->className = ownerNow;
|
clos->className = ownerNow;
|
||||||
ent.value = clos->Call(*ls,{});
|
ent.value = clos->Call(*ls, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj->entries.push_back(ent);
|
obj->entries.push_back(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!hasToString)
|
if (!hasToString) {
|
||||||
{
|
|
||||||
TClassObjectEntry ent;
|
TClassObjectEntry ent;
|
||||||
ent.canSet=false;
|
ent.canSet = false;
|
||||||
ent.modifier = TClassModifier::Public;
|
ent.modifier = TClassModifier::Public;
|
||||||
ent.name = "ToString";
|
ent.name = "ToString";
|
||||||
ent.owner = obj->name;
|
ent.owner = obj->name;
|
||||||
ent.value = TExternalMethod::Create(ls,"The ToString",{},[obj](GCList& ls,std::vector<TObject> args)->TObject { return obj->TypeName();});
|
ent.value = TExternalMethod::Create(
|
||||||
|
ls, "The ToString", {},
|
||||||
|
[obj](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
|
return obj->TypeName();
|
||||||
|
});
|
||||||
obj->entries.push_back(ent);
|
obj->entries.push_back(ent);
|
||||||
}
|
}
|
||||||
TCallable* call=nullptr;
|
TCallable *call = nullptr;
|
||||||
std::string fnName = f->classes[classIndex].name[f->classes[classIndex].name.size()-1];
|
std::string fnName =
|
||||||
for(auto& item : obj->entries)
|
f->classes[classIndex].name[f->classes[classIndex].name.size() - 1];
|
||||||
if(item.name == fnName)
|
for (auto &item : obj->entries)
|
||||||
{
|
if (item.name == fnName) {
|
||||||
GetObjectHeap(item.value,call);
|
GetObjectHeap(item.value, call);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ls->Add(obj);
|
ls->Add(obj);
|
||||||
ls->GetGC()->Watch(obj);
|
ls->GetGC()->Watch(obj);
|
||||||
|
|
||||||
if(call != nullptr) call->Call(*ls,args);
|
if (call != nullptr)
|
||||||
|
call->Call(*ls, args);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject TClassObject::GetValue(std::string className, std::string key)
|
TObject TClassObject::GetValue(std::string className, std::string key) {
|
||||||
{
|
auto ent = GetEntry(className, key);
|
||||||
auto ent = GetEntry(className,key);
|
if (ent == nullptr)
|
||||||
if(ent == nullptr) return Undefined();
|
return Undefined();
|
||||||
return ent->value;
|
return ent->value;
|
||||||
}
|
}
|
||||||
void TClassObject::SetValue(std::string className, std::string key,TObject value)
|
void TClassObject::SetValue(std::string className, std::string key,
|
||||||
{
|
TObject value) {
|
||||||
auto ent = GetEntry(className,key);
|
auto ent = GetEntry(className, key);
|
||||||
if(ent == nullptr) return;
|
if (ent == nullptr)
|
||||||
if(ent->canSet) ent->value = value;
|
return;
|
||||||
}
|
if (ent->canSet)
|
||||||
bool TClassObject::HasValue(std::string className,std::string key)
|
ent->value = value;
|
||||||
{
|
}
|
||||||
auto ent = GetEntry(className,key);
|
bool TClassObject::HasValue(std::string className, std::string key) {
|
||||||
|
auto ent = GetEntry(className, key);
|
||||||
return ent != nullptr;
|
return ent != nullptr;
|
||||||
|
}
|
||||||
}
|
bool TClassObject::HasField(std::string className, std::string key) {
|
||||||
bool TClassObject::HasField(std::string className,std::string key)
|
auto ent = GetEntry(className, key);
|
||||||
{
|
if (ent == nullptr)
|
||||||
auto ent = GetEntry(className,key);
|
return false;
|
||||||
if(ent == nullptr) return false;
|
|
||||||
return ent->canSet;
|
return ent->canSet;
|
||||||
}
|
}
|
||||||
bool TClassObject::HasMethod(std::string className,std::string key)
|
bool TClassObject::HasMethod(std::string className, std::string key) {
|
||||||
{
|
auto ent = GetEntry(className, key);
|
||||||
auto ent = GetEntry(className,key);
|
if (ent == nullptr)
|
||||||
if(ent == nullptr) return false;
|
return false;
|
||||||
TCallable* call;
|
TCallable *call;
|
||||||
return GetObjectHeap(ent->value,call);
|
return GetObjectHeap(ent->value, call);
|
||||||
}
|
}
|
||||||
void TClassObject::Mark()
|
void TClassObject::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked=true;
|
this->marked = true;
|
||||||
this->env->Mark();
|
this->env->Mark();
|
||||||
this->file->Mark();
|
this->file->Mark();
|
||||||
this->ogEnv->Mark();
|
this->ogEnv->Mark();
|
||||||
for(auto& item : this->entries) GC::Mark(item.value);
|
for (auto &item : this->entries)
|
||||||
|
GC::Mark(item.value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,130 +1,142 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
bool TClassEnvironment::HasConstForSet(std::string key)
|
bool TClassEnvironment::HasConstForSet(std::string key) {
|
||||||
{
|
if (this->env->HasVariableRecurse(key)) {
|
||||||
if(this->env->HasVariableRecurse(key))
|
|
||||||
{
|
|
||||||
return this->env->HasConstForSet(key);
|
return this->env->HasConstForSet(key);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TClassEnvironment* TClassEnvironment::Create(GCList* gc,TEnvironment* env,TClassObject* obj)
|
TClassEnvironment *TClassEnvironment::Create(GCList *gc, TEnvironment *env,
|
||||||
{
|
TClassObject *obj) {
|
||||||
|
|
||||||
TClassEnvironment* env2=new TClassEnvironment(env,obj);
|
TClassEnvironment *env2 = new TClassEnvironment(env, obj);
|
||||||
|
|
||||||
GC* _gc = gc->GetGC();
|
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||||
gc->Add(env2);
|
gc->Add(env2);
|
||||||
_gc->Watch(env2);
|
_gc->Watch(env2);
|
||||||
return env2;
|
return env2;
|
||||||
}
|
}
|
||||||
TClassEnvironment* TClassEnvironment::Create(GCList& gc,TEnvironment* env,TClassObject* obj)
|
TClassEnvironment *TClassEnvironment::Create(GCList &gc, TEnvironment *env,
|
||||||
{
|
TClassObject *obj) {
|
||||||
|
|
||||||
TClassEnvironment* env2=new TClassEnvironment(env,obj);
|
TClassEnvironment *env2 = new TClassEnvironment(env, obj);
|
||||||
|
|
||||||
GC* _gc = gc.GetGC();
|
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||||
gc.Add(env2);
|
gc.Add(env2);
|
||||||
_gc->Watch(env2);
|
_gc->Watch(env2);
|
||||||
return env2;
|
return env2;
|
||||||
}
|
}
|
||||||
TClassEnvironment::TClassEnvironment(TEnvironment* env,TClassObject* obj)
|
TClassEnvironment::TClassEnvironment(TEnvironment *env, TClassObject *obj) {
|
||||||
{
|
|
||||||
this->env = env;
|
this->env = env;
|
||||||
this->clsObj=obj;
|
this->clsObj = obj;
|
||||||
}
|
}
|
||||||
bool TClassEnvironment::HasVariable(std::string key)
|
bool TClassEnvironment::HasVariable(std::string key) {
|
||||||
{
|
if (key == "this")
|
||||||
if(key == "this") return true;
|
return true;
|
||||||
if(this->clsObj->HasValue(current_function == nullptr ? "" : current_function->callable->className,key)) return true;
|
if (this->clsObj->HasValue(current_function == nullptr
|
||||||
|
? ""
|
||||||
|
: current_function->callable->className,
|
||||||
|
key))
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool TClassEnvironment::HasVariableRecurse(std::string key)
|
bool TClassEnvironment::HasVariableRecurse(std::string key) {
|
||||||
{
|
if (HasVariable(key))
|
||||||
if(HasVariable(key)) return true;
|
return true;
|
||||||
return this->env->HasVariableRecurse(key);
|
return this->env->HasVariableRecurse(key);
|
||||||
}
|
}
|
||||||
bool TClassEnvironment::HasVariableOrFieldRecurse(std::string key, bool setting)
|
bool TClassEnvironment::HasVariableOrFieldRecurse(std::string key,
|
||||||
{
|
bool setting) {
|
||||||
if(key == "this") return true;
|
if (key == "this")
|
||||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
return true;
|
||||||
if(clsObj->HasMethod(clsName,(setting ? "set" : "get")+key)) return true;
|
std::string clsName = current_function == nullptr
|
||||||
if(clsObj->HasValue(clsName,key)) return true;
|
? ""
|
||||||
return env->HasVariableOrFieldRecurse(key,setting);
|
: current_function->callable->className;
|
||||||
}
|
if (clsObj->HasMethod(clsName, (setting ? "set" : "get") + key))
|
||||||
|
return true;
|
||||||
|
if (clsObj->HasValue(clsName, key))
|
||||||
|
return true;
|
||||||
|
return env->HasVariableOrFieldRecurse(key, setting);
|
||||||
|
}
|
||||||
|
|
||||||
TObject TClassEnvironment::GetVariable(std::string key)
|
TObject TClassEnvironment::GetVariable(std::string key) {
|
||||||
{
|
if (key == "this")
|
||||||
if(key == "this") return this->clsObj;
|
return this->clsObj;
|
||||||
|
|
||||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
std::string clsName = current_function == nullptr
|
||||||
|
? ""
|
||||||
|
: current_function->callable->className;
|
||||||
|
|
||||||
if(clsObj->HasValue(clsName,key)) return this->clsObj->GetValue(clsName,key);
|
if (clsObj->HasValue(clsName, key))
|
||||||
|
return this->clsObj->GetValue(clsName, key);
|
||||||
return env->GetVariable(key);
|
return env->GetVariable(key);
|
||||||
}
|
}
|
||||||
void TClassEnvironment::SetVariable(std::string key, TObject value)
|
void TClassEnvironment::SetVariable(std::string key, TObject value) {
|
||||||
{
|
if (key == "this")
|
||||||
if(key == "this") return;
|
return;
|
||||||
|
|
||||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
std::string clsName = current_function == nullptr
|
||||||
|
? ""
|
||||||
|
: current_function->callable->className;
|
||||||
|
|
||||||
if(clsObj->HasValue(clsName,key))
|
if (clsObj->HasValue(clsName, key)) {
|
||||||
{
|
this->clsObj->SetValue(clsName, key, value);
|
||||||
this->clsObj->SetValue(clsName,key,value);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->env->SetVariable(key,value);
|
this->env->SetVariable(key, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TObject TClassEnvironment::GetVariable(GCList& ls, std::string key)
|
TObject TClassEnvironment::GetVariable(GCList &ls, std::string key) {
|
||||||
{
|
if (key == "this")
|
||||||
if(key == "this") return this->clsObj;
|
return this->clsObj;
|
||||||
|
|
||||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
std::string clsName = current_function == nullptr
|
||||||
if(this->clsObj->HasMethod(clsName,"get"+key))
|
? ""
|
||||||
{
|
: current_function->callable->className;
|
||||||
auto res=this->clsObj->GetValue(clsName,"get"+key);
|
if (this->clsObj->HasMethod(clsName, "get" + key)) {
|
||||||
TCallable* call;
|
auto res = this->clsObj->GetValue(clsName, "get" + key);
|
||||||
if(GetObjectHeap(res,call)) return call->Call(ls,{});
|
TCallable *call;
|
||||||
|
if (GetObjectHeap(res, call))
|
||||||
|
return call->Call(ls, {});
|
||||||
}
|
}
|
||||||
if(this->clsObj->HasValue(clsName,key)) return this->clsObj->GetValue(clsName,key);
|
if (this->clsObj->HasValue(clsName, key))
|
||||||
return this->env->GetVariable(ls,key);
|
return this->clsObj->GetValue(clsName, key);
|
||||||
}
|
return this->env->GetVariable(ls, key);
|
||||||
TObject TClassEnvironment::SetVariable(GCList& ls, std::string key, TObject v)
|
}
|
||||||
{
|
TObject TClassEnvironment::SetVariable(GCList &ls, std::string key, TObject v) {
|
||||||
if(key == "this") return this->clsObj;
|
if (key == "this")
|
||||||
|
return this->clsObj;
|
||||||
|
|
||||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
std::string clsName = current_function == nullptr
|
||||||
if(this->clsObj->HasMethod(clsName,"set"+key))
|
? ""
|
||||||
{
|
: current_function->callable->className;
|
||||||
auto res=this->clsObj->GetValue(clsName,"set"+key);
|
if (this->clsObj->HasMethod(clsName, "set" + key)) {
|
||||||
TCallable* call;
|
auto res = this->clsObj->GetValue(clsName, "set" + key);
|
||||||
if(GetObjectHeap(res,call)) return call->Call(ls,{v});
|
TCallable *call;
|
||||||
|
if (GetObjectHeap(res, call))
|
||||||
|
return call->Call(ls, {v});
|
||||||
}
|
}
|
||||||
if(this->clsObj->HasValue(clsName,key)) { this->clsObj->SetValue(clsName,key,v); return v;}
|
if (this->clsObj->HasValue(clsName, key)) {
|
||||||
|
this->clsObj->SetValue(clsName, key, v);
|
||||||
return this->env->SetVariable(ls,key,v);
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TClassEnvironment::DeclareVariable(std::string key, TObject value)
|
return this->env->SetVariable(ls, key, v);
|
||||||
{
|
}
|
||||||
|
|
||||||
}
|
void TClassEnvironment::DeclareVariable(std::string key, TObject value) {}
|
||||||
TRootEnvironment* TClassEnvironment::GetRootEnvironment()
|
TRootEnvironment *TClassEnvironment::GetRootEnvironment() {
|
||||||
{
|
|
||||||
return this->env->GetRootEnvironment();
|
return this->env->GetRootEnvironment();
|
||||||
}
|
}
|
||||||
TEnvironment* TClassEnvironment::GetParentEnvironment()
|
TEnvironment *TClassEnvironment::GetParentEnvironment() { return this->env; }
|
||||||
{
|
|
||||||
return this->env;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TClassEnvironment::Mark()
|
void TClassEnvironment::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked=true;
|
this->marked = true;
|
||||||
this->clsObj->Mark();
|
this->clsObj->Mark();
|
||||||
this->env->Mark();
|
this->env->Mark();
|
||||||
for(auto item : this->defers) item->Mark();
|
for (auto item : this->defers)
|
||||||
}
|
item->Mark();
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,99 +1,97 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
TArgWrapper* TArgWrapper::Create(GCList& ls, TCallable* callable)
|
TArgWrapper *TArgWrapper::Create(GCList &ls, TCallable *callable) {
|
||||||
{
|
TArgWrapper *argWrapper = new TArgWrapper();
|
||||||
TArgWrapper* argWrapper = new TArgWrapper();
|
|
||||||
argWrapper->callable = callable;
|
argWrapper->callable = callable;
|
||||||
GC* gc = ls.GetGC();
|
std::shared_ptr<GC> gc = ls.GetGC();
|
||||||
ls.Add(argWrapper);
|
ls.Add(argWrapper);
|
||||||
gc->Watch(argWrapper);
|
gc->Watch(argWrapper);
|
||||||
return argWrapper;
|
return argWrapper;
|
||||||
}
|
}
|
||||||
TArgWrapper* TArgWrapper::Create(GCList* ls, TCallable* callable)
|
TArgWrapper *TArgWrapper::Create(GCList *ls, TCallable *callable) {
|
||||||
{
|
TArgWrapper *argWrapper = new TArgWrapper();
|
||||||
TArgWrapper* argWrapper = new TArgWrapper();
|
|
||||||
argWrapper->callable = callable;
|
argWrapper->callable = callable;
|
||||||
GC* gc = ls->GetGC();
|
std::shared_ptr<GC> gc = ls->GetGC();
|
||||||
ls->Add(argWrapper);
|
ls->Add(argWrapper);
|
||||||
gc->Watch(argWrapper);
|
gc->Watch(argWrapper);
|
||||||
return argWrapper;
|
return argWrapper;
|
||||||
}
|
}
|
||||||
TObject TArgWrapper::Call(GCList& ls,std::vector<TObject> args)
|
TObject TArgWrapper::Call(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
auto cse = current_function;
|
auto cse = current_function;
|
||||||
TList* argList = TList::Create(ls);
|
TList *argList = TList::Create(ls);
|
||||||
argList->items = args;
|
argList->items = args;
|
||||||
TObject v=this->callable->Call(ls,{argList});
|
TObject v = this->callable->Call(ls, {argList});
|
||||||
current_function = cse;
|
current_function = cse;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
void TArgWrapper::Mark()
|
void TArgWrapper::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked = true;
|
this->marked = true;
|
||||||
this->callable->Mark();
|
this->callable->Mark();
|
||||||
GC::Mark(this->tag);
|
GC::Mark(this->tag);
|
||||||
}
|
}
|
||||||
void TCallable::Mark()
|
void TCallable::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked=true;
|
this->marked = true;
|
||||||
GC::Mark(this->tag);
|
GC::Mark(this->tag);
|
||||||
}
|
}
|
||||||
void TClosure::Mark()
|
void TClosure::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked=true;
|
this->marked = true;
|
||||||
this->file->Mark();
|
this->file->Mark();
|
||||||
this->env->Mark();
|
this->env->Mark();
|
||||||
this->closure->Mark();
|
this->closure->Mark();
|
||||||
GC::Mark(this->tag);
|
GC::Mark(this->tag);
|
||||||
}
|
}
|
||||||
TClosure* TClosure::Create(GCList& ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
|
TClosure *TClosure::Create(GCList &ls, TEnvironment *env, TFile *file,
|
||||||
{
|
uint32_t chunkId, bool ownScope) {
|
||||||
TClosure* closure = new TClosure();
|
TClosure *closure = new TClosure();
|
||||||
closure->className="";
|
closure->className = "";
|
||||||
closure->ownScope=ownScope;
|
closure->ownScope = ownScope;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(closure);
|
ls.Add(closure);
|
||||||
_gc->Watch(closure);
|
_gc->Watch(closure);
|
||||||
closure->chunkId = chunkId;
|
closure->chunkId = chunkId;
|
||||||
if(chunkId < file->chunks.size())
|
if (chunkId < file->chunks.size())
|
||||||
closure->closure = file->chunks[chunkId];
|
closure->closure = file->chunks[chunkId];
|
||||||
else throw VMException("ChunkId out of bounds.");
|
else
|
||||||
|
throw VMException("ChunkId out of bounds.");
|
||||||
closure->env = env;
|
closure->env = env;
|
||||||
closure->file = file;
|
closure->file = file;
|
||||||
|
|
||||||
return closure;
|
return closure;
|
||||||
}
|
}
|
||||||
TClosure* TClosure::Create(GCList* ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
|
TClosure *TClosure::Create(GCList *ls, TEnvironment *env, TFile *file,
|
||||||
{
|
uint32_t chunkId, bool ownScope) {
|
||||||
TClosure* closure = new TClosure();
|
TClosure *closure = new TClosure();
|
||||||
closure->className="";
|
closure->className = "";
|
||||||
closure->ownScope=ownScope;
|
closure->ownScope = ownScope;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(closure);
|
ls->Add(closure);
|
||||||
_gc->Watch(closure);
|
_gc->Watch(closure);
|
||||||
closure->chunkId = chunkId;
|
closure->chunkId = chunkId;
|
||||||
if(chunkId < file->chunks.size())
|
if (chunkId < file->chunks.size())
|
||||||
closure->closure = file->chunks[chunkId];
|
closure->closure = file->chunks[chunkId];
|
||||||
else throw VMException("ChunkId out of bounds.");
|
else
|
||||||
|
throw VMException("ChunkId out of bounds.");
|
||||||
closure->env = env;
|
closure->env = env;
|
||||||
closure->file = file;
|
closure->file = file;
|
||||||
|
|
||||||
return closure;
|
return closure;
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject TClosure::Call(GCList& ls,std::vector<TObject> args)
|
TObject TClosure::Call(GCList &ls, std::vector<TObject> args) {
|
||||||
{
|
|
||||||
auto cse = current_function;
|
auto cse = current_function;
|
||||||
InterperterThread* thrd=InterperterThread::Create(ls);
|
InterperterThread *thrd = InterperterThread::Create(ls);
|
||||||
thrd->AddCallStackEntry(ls,this, args);
|
thrd->AddCallStackEntry(ls, this, args);
|
||||||
|
|
||||||
thrd->Execute(ls.GetGC());
|
thrd->Execute(ls.GetGC());
|
||||||
|
|
||||||
TObject v= thrd->call_stack_entries[0]->Pop(ls);
|
TObject v = thrd->call_stack_entries[0]->Pop(ls);
|
||||||
current_function = cse;
|
current_function = cse;
|
||||||
return v;
|
return v;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,56 +1,55 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
TDynamicDictionary* TDynamicDictionary::Create(GCList& ls,TCallable* callable)
|
TDynamicDictionary *TDynamicDictionary::Create(GCList &ls,
|
||||||
{
|
TCallable *callable) {
|
||||||
|
|
||||||
TDynamicDictionary* dict=new TDynamicDictionary();
|
TDynamicDictionary *dict = new TDynamicDictionary();
|
||||||
dict->cb = callable;
|
dict->cb = callable;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(dict);
|
ls.Add(dict);
|
||||||
_gc->Watch(dict);
|
_gc->Watch(dict);
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
TDynamicDictionary* TDynamicDictionary::Create(GCList* ls,TCallable* callable)
|
TDynamicDictionary *TDynamicDictionary::Create(GCList *ls,
|
||||||
{
|
TCallable *callable) {
|
||||||
TDynamicDictionary* dict=new TDynamicDictionary();
|
TDynamicDictionary *dict = new TDynamicDictionary();
|
||||||
dict->cb = callable;
|
dict->cb = callable;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(dict);
|
ls->Add(dict);
|
||||||
_gc->Watch(dict);
|
_gc->Watch(dict);
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDynamicDictionary::Mark()
|
void TDynamicDictionary::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked=true;
|
this->marked = true;
|
||||||
this->cb->Mark();
|
this->cb->Mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject TDynamicDictionary::GetField(GCList& ls, std::string key)
|
TObject TDynamicDictionary::GetField(GCList &ls, std::string key) {
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "GetField");
|
dict->SetValue("Type", "GetField");
|
||||||
dict->SetValue("Key", key);
|
dict->SetValue("Key", key);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return this->cb->Call(ls,{dict});
|
return this->cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject TDynamicDictionary::SetField(GCList& ls, std::string key, TObject value)
|
TObject TDynamicDictionary::SetField(GCList &ls, std::string key,
|
||||||
{
|
TObject value) {
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "SetField");
|
dict->SetValue("Type", "SetField");
|
||||||
dict->SetValue("Key", key);
|
dict->SetValue("Key", key);
|
||||||
dict->SetValue("Value", value);
|
dict->SetValue("Value", value);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return this->cb->Call(ls,{dict});
|
return this->cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject TDynamicDictionary::CallMethod(GCList& ls, std::string name, std::vector<TObject> args)
|
TObject TDynamicDictionary::CallMethod(GCList &ls, std::string name,
|
||||||
{
|
std::vector<TObject> args) {
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "CallMethod");
|
dict->SetValue("Type", "CallMethod");
|
||||||
@@ -59,30 +58,27 @@ namespace Tesses::CrossLang {
|
|||||||
argVal->items = args;
|
argVal->items = args;
|
||||||
dict->SetValue("Arguments", argVal);
|
dict->SetValue("Arguments", argVal);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return this->cb->Call(ls,{dict});
|
return this->cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEnumerator* TDynamicDictionary::GetEnumerator(GCList& ls)
|
TEnumerator *TDynamicDictionary::GetEnumerator(GCList &ls) {
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "GetEnumerator");
|
dict->SetValue("Type", "GetEnumerator");
|
||||||
|
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return TEnumerator::CreateFromObject(ls,this->cb->Call(ls,{dict}));
|
return TEnumerator::CreateFromObject(ls, this->cb->Call(ls, {dict}));
|
||||||
}
|
}
|
||||||
bool TDictionary::MethodExists(GCList& ls,std::string method)
|
bool TDictionary::MethodExists(GCList &ls, std::string method) {
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
auto r = this->GetValue(method);
|
auto r = this->GetValue(method);
|
||||||
TCallable* callable;
|
TCallable *callable;
|
||||||
bool res = GetObjectHeap(r,callable);
|
bool res = GetObjectHeap(r, callable);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
bool TDynamicDictionary::MethodExists(GCList& ls,std::string name)
|
bool TDynamicDictionary::MethodExists(GCList &ls, std::string name) {
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "MethodExists");
|
dict->SetValue("Type", "MethodExists");
|
||||||
@@ -90,146 +86,121 @@ namespace Tesses::CrossLang {
|
|||||||
|
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
auto res = this->cb->Call(ls,{dict});
|
auto res = this->cb->Call(ls, {dict});
|
||||||
bool r2;
|
bool r2;
|
||||||
if(GetObject(res,r2)) return r2;
|
if (GetObject(res, r2))
|
||||||
|
return r2;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDynamicDictionary::~TDynamicDictionary()
|
TDynamicDictionary::~TDynamicDictionary() {}
|
||||||
{
|
TObject TDictionary::CallMethod(GCList &ls, std::string key,
|
||||||
|
std::vector<TObject> args) {
|
||||||
}
|
|
||||||
TObject TDictionary::CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
auto res = this->GetValue(key);
|
auto res = this->GetValue(key);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
TCallable* callable;
|
TCallable *callable;
|
||||||
|
|
||||||
if(GetObjectHeap(res,callable))
|
if (GetObjectHeap(res, callable)) {
|
||||||
{
|
auto closure = dynamic_cast<TClosure *>(callable);
|
||||||
auto closure = dynamic_cast<TClosure*>(callable);
|
if (closure != nullptr && !closure->closure->args.empty() &&
|
||||||
if(closure != nullptr && !closure->closure->args.empty() && closure->closure->args.front() == "this")
|
closure->closure->args.front() == "this") {
|
||||||
{
|
|
||||||
std::vector<TObject> args2;
|
std::vector<TObject> args2;
|
||||||
args2.push_back(this);
|
args2.push_back(this);
|
||||||
args2.insert(args2.end(), args.begin(),args.end());
|
args2.insert(args2.end(), args.begin(), args.end());
|
||||||
return closure->Call(ls,args2);
|
return closure->Call(ls, args2);
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return callable->Call(ls,args);
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return callable->Call(ls, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
TObject TDictionary::CallMethodWithFatalError(GCList& ls, std::string key, std::vector<TObject> args)
|
TObject TDictionary::CallMethodWithFatalError(GCList &ls, std::string key,
|
||||||
{
|
std::vector<TObject> args) {
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
auto res = this->GetValue(key);
|
auto res = this->GetValue(key);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
TCallable* callable;
|
TCallable *callable;
|
||||||
|
|
||||||
if(GetObjectHeap(res,callable))
|
if (GetObjectHeap(res, callable)) {
|
||||||
{
|
auto closure = dynamic_cast<TClosure *>(callable);
|
||||||
auto closure = dynamic_cast<TClosure*>(callable);
|
if (closure != nullptr && !closure->closure->args.empty() &&
|
||||||
if(closure != nullptr && !closure->closure->args.empty() && closure->closure->args.front() == "this")
|
closure->closure->args.front() == "this") {
|
||||||
{
|
|
||||||
std::vector<TObject> args2;
|
std::vector<TObject> args2;
|
||||||
args2.push_back(this);
|
args2.push_back(this);
|
||||||
args2.insert(args2.end(), args.begin(),args.end());
|
args2.insert(args2.end(), args.begin(), args.end());
|
||||||
return closure->CallWithFatalError(ls,args2);
|
return closure->CallWithFatalError(ls, args2);
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return callable->CallWithFatalError(ls,args);
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return callable->CallWithFatalError(ls, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDictionary::DeclareFunction(GC* gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
|
void TDictionary::DeclareFunction(
|
||||||
{
|
std::shared_ptr<GC> gc, std::string key, std::string documentation,
|
||||||
|
std::vector<std::string> argNames,
|
||||||
|
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb));
|
this->SetValue(key,
|
||||||
|
TExternalMethod::Create(ls, documentation, argNames, cb));
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
void TDictionary::DeclareFunction(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(
|
||||||
gc.BarrierBegin();
|
std::shared_ptr<GC> gc, std::string key, std::string documentation,
|
||||||
GCList ls(gc);
|
std::vector<std::string> argNames,
|
||||||
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb));
|
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
|
||||||
gc.BarrierEnd();
|
std::function<void()> destroy) {
|
||||||
}
|
|
||||||
void TDictionary::DeclareFunction(GC* gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
|
|
||||||
{
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
|
this->SetValue(
|
||||||
|
key, TExternalMethod::Create(ls, documentation, argNames, cb, destroy));
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
void TDictionary::DeclareFunction(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)
|
|
||||||
{
|
TObject TDictionary::GetValue(std::string key) {
|
||||||
gc.BarrierBegin();
|
if (this->items.empty())
|
||||||
GCList ls(gc);
|
|
||||||
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
|
|
||||||
gc.BarrierEnd();
|
|
||||||
}
|
|
||||||
TObject TDictionary::GetValue(std::string key)
|
|
||||||
{
|
|
||||||
if(this->items.empty()) return Undefined();
|
|
||||||
for(auto item : this->items)
|
|
||||||
{
|
|
||||||
if(item.first == key) return item.second;
|
|
||||||
}
|
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
if (this->items.count(key) > 0)
|
||||||
void TDictionary::SetValue(std::string key, TObject value)
|
return this->items[key];
|
||||||
{
|
return Undefined();
|
||||||
if(std::holds_alternative<Undefined>(value))
|
}
|
||||||
{
|
void TDictionary::SetValue(std::string key, TObject value) {
|
||||||
if(this->items.count(key) > 0)
|
if (std::holds_alternative<Undefined>(value)) {
|
||||||
|
if (this->items.count(key) > 0)
|
||||||
this->items.erase(key);
|
this->items.erase(key);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
this->items[key] = value;
|
this->items[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool TDictionary::HasValue(std::string key)
|
bool TDictionary::HasValue(std::string key) {
|
||||||
{
|
|
||||||
return this->items.count(key) > 0;
|
return this->items.count(key) > 0;
|
||||||
}
|
}
|
||||||
void TDictionary::Mark()
|
void TDictionary::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked = true;
|
this->marked = true;
|
||||||
for(auto item : this->items)
|
for (auto item : this->items) {
|
||||||
{
|
|
||||||
GC::Mark(item.second);
|
GC::Mark(item.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TDictionary* TDictionary::Create(GCList* gc)
|
TDictionary *TDictionary::Create(GCList *gc) {
|
||||||
{
|
TDictionary *dict = new TDictionary();
|
||||||
TDictionary* dict=new TDictionary();
|
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||||
GC* _gc = gc->GetGC();
|
|
||||||
gc->Add(dict);
|
gc->Add(dict);
|
||||||
_gc->Watch(dict);
|
_gc->Watch(dict);
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
TDictionary* TDictionary::Create(GCList& gc)
|
TDictionary *TDictionary::Create(GCList &gc) {
|
||||||
{
|
TDictionary *dict = new TDictionary();
|
||||||
TDictionary* dict=new TDictionary();
|
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||||
GC* _gc = gc.GetGC();
|
|
||||||
gc.Add(dict);
|
gc.Add(dict);
|
||||||
_gc->Watch(dict);
|
_gc->Watch(dict);
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
}; // namespace Tesses::CrossLang
|
||||||
|
|||||||
@@ -2,88 +2,72 @@
|
|||||||
|
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
|
|
||||||
EmbedStream::EmbedStream(GC* gc, TFile* file, uint32_t resource)
|
EmbedStream::EmbedStream(std::shared_ptr<GC> gc, TFile *file,
|
||||||
{
|
uint32_t resource) {
|
||||||
this->offset = 0;
|
this->offset = 0;
|
||||||
this->resource = resource;
|
this->resource = resource;
|
||||||
this->file = CreateMarkedTObject(gc,file);
|
this->file = CreateMarkedTObject(gc, file);
|
||||||
}
|
}
|
||||||
bool EmbedStream::CanRead()
|
bool EmbedStream::CanRead() {
|
||||||
{
|
TFile *file;
|
||||||
TFile* file;
|
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||||
if(GetObjectHeap(this->file->GetObject(),file))
|
if (this->resource >= file->resources.size())
|
||||||
{
|
return false;
|
||||||
if(this->resource >= file->resources.size()) return false;
|
if (this->offset >= file->resources[this->resource].size())
|
||||||
if(this->offset >= file->resources[this->resource].size()) return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool EmbedStream::CanSeek()
|
bool EmbedStream::CanSeek() { return true; }
|
||||||
{
|
bool EmbedStream::EndOfStream() { return !CanRead(); }
|
||||||
return true;
|
size_t EmbedStream::Read(uint8_t *buff, size_t len) {
|
||||||
}
|
TFile *file;
|
||||||
bool EmbedStream::EndOfStream()
|
|
||||||
{
|
|
||||||
return !CanRead();
|
|
||||||
}
|
|
||||||
size_t EmbedStream::Read(uint8_t* buff, size_t len)
|
|
||||||
{
|
|
||||||
TFile* file;
|
|
||||||
|
|
||||||
if(GetObjectHeap(this->file->GetObject(),file))
|
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||||
{
|
if (this->resource >= file->resources.size())
|
||||||
if(this->resource >= file->resources.size()) return 0;
|
return 0;
|
||||||
auto flen = file->resources[this->resource].size();
|
auto flen = file->resources[this->resource].size();
|
||||||
if(this->offset >= flen) return 0;
|
if (this->offset >= flen)
|
||||||
|
return 0;
|
||||||
|
|
||||||
len = std::min(len, std::min(
|
len = std::min(len, std::min(flen, flen - this->offset));
|
||||||
flen,
|
|
||||||
flen - this->offset
|
|
||||||
));
|
|
||||||
|
|
||||||
memcpy(buff,file->resources[this->resource].data() + this->offset,len);
|
memcpy(buff, file->resources[this->resource].data() + this->offset,
|
||||||
|
len);
|
||||||
this->offset += len;
|
this->offset += len;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int64_t EmbedStream::GetPosition()
|
int64_t EmbedStream::GetPosition() { return (int64_t)this->offset; }
|
||||||
{
|
int64_t EmbedStream::GetLength() {
|
||||||
return (int64_t)this->offset;
|
TFile *file;
|
||||||
}
|
|
||||||
int64_t EmbedStream::GetLength()
|
|
||||||
{
|
|
||||||
TFile* file;
|
|
||||||
|
|
||||||
if(GetObjectHeap(this->file->GetObject(),file))
|
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||||
{
|
if (this->resource >= file->resources.size())
|
||||||
if(this->resource >= file->resources.size()) return 0;
|
return 0;
|
||||||
return (int64_t)file->resources[this->resource].size();
|
return (int64_t)file->resources[this->resource].size();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void EmbedStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
|
void EmbedStream::Seek(int64_t pos,
|
||||||
{
|
Tesses::Framework::Streams::SeekOrigin whence) {
|
||||||
switch(whence)
|
switch (whence) {
|
||||||
{
|
|
||||||
case Tesses::Framework::Streams::SeekOrigin::Begin:
|
case Tesses::Framework::Streams::SeekOrigin::Begin:
|
||||||
this->offset = (uint32_t)pos;
|
this->offset = (uint32_t)pos;
|
||||||
break;
|
break;
|
||||||
case Tesses::Framework::Streams::SeekOrigin::Current:
|
case Tesses::Framework::Streams::SeekOrigin::Current: {
|
||||||
{
|
|
||||||
int64_t cur = this->offset;
|
int64_t cur = this->offset;
|
||||||
cur += pos;
|
cur += pos;
|
||||||
this->offset = (uint32_t)cur;
|
this->offset = (uint32_t)cur;
|
||||||
}
|
} break;
|
||||||
break;
|
case Tesses::Framework::Streams::SeekOrigin::End: {
|
||||||
case Tesses::Framework::Streams::SeekOrigin::End:
|
TFile *file;
|
||||||
{
|
|
||||||
TFile* file;
|
|
||||||
|
|
||||||
if(GetObjectHeap(this->file->GetObject(),file))
|
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||||
{
|
if (this->resource >= file->resources.size())
|
||||||
if(this->resource >= file->resources.size()) return;
|
return;
|
||||||
int64_t cur = (int64_t)file->resources[this->resource].size();
|
int64_t cur = (int64_t)file->resources[this->resource].size();
|
||||||
cur += pos;
|
cur += pos;
|
||||||
this->offset = (uint32_t)cur;
|
this->offset = (uint32_t)cur;
|
||||||
@@ -91,138 +75,146 @@ namespace Tesses::CrossLang {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path)
|
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path) {
|
||||||
{
|
|
||||||
path = path.CollapseRelativeParents();
|
path = path.CollapseRelativeParents();
|
||||||
auto curEntry = this->dir->GetObject();
|
auto curEntry = this->dir->GetObject();
|
||||||
for(auto item : path.path)
|
for (auto item : path.path) {
|
||||||
{
|
TDictionary *dict;
|
||||||
TDictionary* dict;
|
if (GetObjectHeap(curEntry, dict) && dict->HasValue(item)) {
|
||||||
if(GetObjectHeap(curEntry,dict) && dict->HasValue(item))
|
|
||||||
{
|
|
||||||
curEntry = dict->GetValue(item);
|
curEntry = dict->GetValue(item);
|
||||||
continue; //don't want to return undefined now do we
|
continue; // don't want to return undefined now do we
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
return curEntry;
|
return curEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
|
std::shared_ptr<Tesses::Framework::Streams::Stream>
|
||||||
{
|
EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path,
|
||||||
if(mode != "r" && mode != "rb") return nullptr;
|
std::string mode) {
|
||||||
|
if (mode != "r" && mode != "rb")
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
auto ent = getEntry(path);
|
auto ent = getEntry(path);
|
||||||
TCallable* call;
|
TCallable *call;
|
||||||
if(GetObjectHeap(ent,call))
|
if (GetObjectHeap(ent, call)) {
|
||||||
{
|
|
||||||
GCList ls(this->dir->GetGC());
|
GCList ls(this->dir->GetGC());
|
||||||
auto fileO = call->Call(ls,{});
|
auto fileO = call->Call(ls, {});
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||||
if(GetObject(fileO,strm)) return strm;
|
if (GetObject(fileO, strm))
|
||||||
|
return strm;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
bool EmbedDirectory::RegularFileExists(Tesses::Framework::Filesystem::VFSPath path)
|
|
||||||
{
|
|
||||||
auto ent = getEntry(path);
|
|
||||||
TCallable* call;
|
|
||||||
return GetObjectHeap(ent,call);
|
|
||||||
}
|
|
||||||
bool EmbedDirectory::DirectoryExists(Tesses::Framework::Filesystem::VFSPath path)
|
|
||||||
{
|
|
||||||
auto ent = getEntry(path);
|
|
||||||
TDictionary* dict;
|
|
||||||
return GetObjectHeap(ent,dict);
|
|
||||||
}
|
|
||||||
|
|
||||||
class DICT_DIRENUM
|
bool EmbedDirectory::Stat(Tesses::Framework::Filesystem::VFSPath path,
|
||||||
{
|
Tesses::Framework::Filesystem::StatData &data) {
|
||||||
|
auto ent = getEntry(path);
|
||||||
|
|
||||||
|
TDictionary *dict;
|
||||||
|
if (GetObjectHeap(ent, dict)) {
|
||||||
|
data.Size = 0;
|
||||||
|
data.Mode = Tesses::Framework::Filesystem::MODE_DIRECTORY | 0755;
|
||||||
|
data.BlockCount = 0;
|
||||||
|
data.BlockSize = 0;
|
||||||
|
data.Device = 0;
|
||||||
|
data.DeviceId = 0;
|
||||||
|
data.GroupId = 0;
|
||||||
|
data.HardLinks = 1;
|
||||||
|
data.Inode = 0;
|
||||||
|
data.LastAccess = Tesses::Framework::Date::DateTime(0);
|
||||||
|
data.LastModified = Tesses::Framework::Date::DateTime(0);
|
||||||
|
data.LastStatus = Tesses::Framework::Date::DateTime(0);
|
||||||
|
data.UserId = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
TCallable *cal;
|
||||||
|
if (GetObjectHeap(ent, cal)) {
|
||||||
|
GCList ls(this->dir->GetGC());
|
||||||
|
auto fileO = cal->Call(ls, {});
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||||
|
if (GetObject(fileO, strm)) {
|
||||||
|
|
||||||
|
data.Size = (uint64_t)strm->GetLength();
|
||||||
|
data.Mode = Tesses::Framework::Filesystem::MODE_REGULAR | 0755;
|
||||||
|
data.BlockSize = 512;
|
||||||
|
data.BlockCount = data.Size / data.BlockSize;
|
||||||
|
|
||||||
|
data.Device = 0;
|
||||||
|
data.DeviceId = 0;
|
||||||
|
data.GroupId = 0;
|
||||||
|
data.HardLinks = 1;
|
||||||
|
data.Inode = 0;
|
||||||
|
data.LastAccess = Tesses::Framework::Date::DateTime(0);
|
||||||
|
data.LastModified = Tesses::Framework::Date::DateTime(0);
|
||||||
|
data.LastStatus = Tesses::Framework::Date::DateTime(0);
|
||||||
|
data.UserId = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DICT_DIRENUM {
|
||||||
GCList ls;
|
GCList ls;
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
std::map<std::string, Tesses::CrossLang::TObject>::iterator current;
|
std::map<std::string, Tesses::CrossLang::TObject>::iterator current;
|
||||||
bool hasStarted = false;
|
bool hasStarted = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string GetCurrent()
|
std::string GetCurrent() { return this->current->first; }
|
||||||
{
|
DICT_DIRENUM(std::shared_ptr<GC> gc, TDictionary *dict)
|
||||||
return this->current->first;
|
: ls(gc), dict(dict) {
|
||||||
}
|
|
||||||
DICT_DIRENUM(GC* gc, TDictionary* dict) : ls(gc), dict(dict)
|
|
||||||
{
|
|
||||||
ls.Add(dict);
|
ls.Add(dict);
|
||||||
}
|
}
|
||||||
bool MoveNext()
|
bool MoveNext() {
|
||||||
{
|
if (!this->hasStarted) {
|
||||||
if(!this->hasStarted)
|
this->hasStarted = true;
|
||||||
{
|
|
||||||
this->hasStarted=true;
|
|
||||||
this->current = this->dict->items.begin();
|
this->current = this->dict->items.begin();
|
||||||
return !this->dict->items.empty();
|
return !this->dict->items.empty();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
this->current++;
|
this->current++;
|
||||||
return this->current != this->dict->items.end();
|
return this->current != this->dict->items.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
};
|
Tesses::Framework::Filesystem::VFSPathEnumerator
|
||||||
|
EmbedDirectory::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path) {
|
||||||
|
|
||||||
Tesses::Framework::Filesystem::VFSPathEnumerator EmbedDirectory::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
|
|
||||||
{
|
|
||||||
auto ent = getEntry(path);
|
auto ent = getEntry(path);
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(GetObjectHeap(ent,dict))
|
if (GetObjectHeap(ent, dict)) {
|
||||||
{
|
DICT_DIRENUM *dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
|
||||||
DICT_DIRENUM* dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
|
|
||||||
|
|
||||||
Tesses::Framework::Filesystem::VFSPathEnumerator er(
|
Tesses::Framework::Filesystem::VFSPathEnumerator er(
|
||||||
[dir2,path](Tesses::Framework::Filesystem::VFSPath& path2)->bool {
|
[dir2,
|
||||||
if(dir2->MoveNext())
|
path](Tesses::Framework::Filesystem::VFSPath &path2) -> bool {
|
||||||
{
|
if (dir2->MoveNext()) {
|
||||||
path2 = path / dir2->GetCurrent();
|
path2 = path / dir2->GetCurrent();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
[dir2]()->void {
|
[dir2]() -> void { delete dir2; });
|
||||||
delete dir2;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return er;
|
return er;
|
||||||
}
|
}
|
||||||
return Tesses::Framework::Filesystem::VFSPathEnumerator();
|
return Tesses::Framework::Filesystem::VFSPathEnumerator();
|
||||||
}
|
|
||||||
|
|
||||||
EmbedDirectory::EmbedDirectory(GC* gc, TDictionary* dict)
|
|
||||||
{
|
|
||||||
this->dir = CreateMarkedTObject(gc, dict);
|
|
||||||
}
|
|
||||||
void EmbedDirectory::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path)
|
|
||||||
{
|
|
||||||
//DO NOTHING
|
|
||||||
}
|
|
||||||
void EmbedDirectory::DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
void EmbedDirectory::DeleteFile(Tesses::Framework::Filesystem::VFSPath path)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
void EmbedDirectory::MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
std::string EmbedDirectory::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path)
|
|
||||||
{
|
|
||||||
return path.ToString();
|
|
||||||
}
|
|
||||||
Tesses::Framework::Filesystem::VFSPath EmbedDirectory::SystemToVFSPath(std::string path)
|
|
||||||
{
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmbedDirectory::EmbedDirectory(std::shared_ptr<GC> gc, TDictionary *dict) {
|
||||||
|
this->dir = CreateMarkedTObject(gc, dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
EmbedDirectory::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path) {
|
||||||
|
return path.ToString();
|
||||||
|
}
|
||||||
|
Tesses::Framework::Filesystem::VFSPath
|
||||||
|
EmbedDirectory::SystemToVFSPath(std::string path) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,54 +1,64 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
TExternalMethod::TExternalMethod(
|
||||||
TExternalMethod::TExternalMethod(std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::string documentation, std::vector<std::string> argNames,std::function<void()> destroy)
|
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
|
||||||
{
|
std::string documentation, std::vector<std::string> argNames,
|
||||||
|
std::function<void()> destroy) {
|
||||||
|
|
||||||
this->cb = cb;
|
this->cb = cb;
|
||||||
this->args = argNames;
|
this->args = argNames;
|
||||||
this->documentation = documentation;
|
this->documentation = documentation;
|
||||||
this->destroy = destroy;
|
this->destroy = destroy;
|
||||||
}
|
|
||||||
TExternalMethod* TExternalMethod::Create(GCList& ls,std::string documentation,std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
|
|
||||||
{
|
|
||||||
auto gc = ls.GetGC();
|
|
||||||
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,destroy);
|
|
||||||
ls.Add(method);
|
|
||||||
gc->Watch(method);
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
TExternalMethod* TExternalMethod::Create(GCList* ls,std::string documentation, std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
|
|
||||||
{
|
|
||||||
auto gc = ls->GetGC();
|
|
||||||
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,destroy);
|
|
||||||
ls->Add(method);
|
|
||||||
gc->Watch(method);
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
TExternalMethod* TExternalMethod::Create(GCList& ls,std::string documentation, std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
|
|
||||||
{
|
|
||||||
auto gc = ls.GetGC();
|
|
||||||
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,[]()->void{});
|
|
||||||
ls.Add(method);
|
|
||||||
gc->Watch(method);
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
TExternalMethod* TExternalMethod::Create(GCList* ls,std::string documentation, std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
|
|
||||||
{
|
|
||||||
auto gc = ls->GetGC();
|
|
||||||
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,[]()->void{});
|
|
||||||
ls->Add(method);
|
|
||||||
gc->Watch(method);
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
TObject TExternalMethod::Call(GCList& ls, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
if(cb == nullptr) return Undefined();
|
|
||||||
return this->cb(ls,args);
|
|
||||||
}
|
|
||||||
TExternalMethod::~TExternalMethod()
|
|
||||||
{
|
|
||||||
if(this->destroy != nullptr)
|
|
||||||
this->destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TExternalMethod *TExternalMethod::Create(
|
||||||
|
GCList &ls, std::string documentation, std::vector<std::string> argNames,
|
||||||
|
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
|
||||||
|
std::function<void()> destroy) {
|
||||||
|
auto gc = ls.GetGC();
|
||||||
|
TExternalMethod *method =
|
||||||
|
new TExternalMethod(cb, documentation, argNames, destroy);
|
||||||
|
ls.Add(method);
|
||||||
|
gc->Watch(method);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
TExternalMethod *TExternalMethod::Create(
|
||||||
|
GCList *ls, std::string documentation, std::vector<std::string> argNames,
|
||||||
|
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb,
|
||||||
|
std::function<void()> destroy) {
|
||||||
|
auto gc = ls->GetGC();
|
||||||
|
TExternalMethod *method =
|
||||||
|
new TExternalMethod(cb, documentation, argNames, destroy);
|
||||||
|
ls->Add(method);
|
||||||
|
gc->Watch(method);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
TExternalMethod *TExternalMethod::Create(
|
||||||
|
GCList &ls, std::string documentation, std::vector<std::string> argNames,
|
||||||
|
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
|
||||||
|
auto gc = ls.GetGC();
|
||||||
|
TExternalMethod *method =
|
||||||
|
new TExternalMethod(cb, documentation, argNames, []() -> void {});
|
||||||
|
ls.Add(method);
|
||||||
|
gc->Watch(method);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
TExternalMethod *TExternalMethod::Create(
|
||||||
|
GCList *ls, std::string documentation, std::vector<std::string> argNames,
|
||||||
|
std::function<TObject(GCList &ls, std::vector<TObject> args)> cb) {
|
||||||
|
auto gc = ls->GetGC();
|
||||||
|
TExternalMethod *method =
|
||||||
|
new TExternalMethod(cb, documentation, argNames, []() -> void {});
|
||||||
|
ls->Add(method);
|
||||||
|
gc->Watch(method);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
TObject TExternalMethod::Call(GCList &ls, std::vector<TObject> args) {
|
||||||
|
if (cb == nullptr)
|
||||||
|
return Undefined();
|
||||||
|
return this->cb(ls, args);
|
||||||
|
}
|
||||||
|
TExternalMethod::~TExternalMethod() {
|
||||||
|
if (this->destroy != nullptr)
|
||||||
|
this->destroy();
|
||||||
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -1,424 +1,393 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
bool TYieldEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||||
bool TYieldEnumerator::MoveNext(GC* ls)
|
CallStackEntry *ent;
|
||||||
{
|
|
||||||
CallStackEntry* ent;
|
|
||||||
GCList ls2(ls);
|
GCList ls2(ls);
|
||||||
if(!this->hasStarted)
|
if (!this->hasStarted) {
|
||||||
{
|
TClosure *clos;
|
||||||
TClosure* clos;
|
if (!GetObjectHeap(this->enumerator, clos))
|
||||||
if(!GetObjectHeap(this->enumerator,clos)) return false;
|
return false;
|
||||||
auto _enumerator= clos->Call(ls2,{});
|
auto _enumerator = clos->Call(ls2, {});
|
||||||
ls->BarrierBegin();
|
ls->BarrierBegin();
|
||||||
this->enumerator = _enumerator;
|
this->enumerator = _enumerator;
|
||||||
this->hasStarted=true;
|
this->hasStarted = true;
|
||||||
ls->BarrierEnd();
|
ls->BarrierEnd();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
|
||||||
if(GetObjectHeap(this->enumerator,ent))
|
if (GetObjectHeap(this->enumerator, ent)) {
|
||||||
{
|
auto _enumerator = ent->Resume(ls2);
|
||||||
auto _enumerator= ent->Resume(ls2);
|
|
||||||
ls->BarrierBegin();
|
ls->BarrierBegin();
|
||||||
this->enumerator = _enumerator;
|
this->enumerator = _enumerator;
|
||||||
ls->BarrierEnd();
|
ls->BarrierEnd();
|
||||||
|
|
||||||
} else return false;
|
} else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetObjectHeap(this->enumerator,ent))
|
if (GetObjectHeap(this->enumerator, ent)) {
|
||||||
{
|
|
||||||
ls->BarrierBegin();
|
ls->BarrierBegin();
|
||||||
this->current = ent->Pop(ls2);
|
this->current = ent->Pop(ls2);
|
||||||
ls->BarrierEnd();
|
ls->BarrierEnd();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TObject TYieldEnumerator::GetCurrent(GCList& ls)
|
TObject TYieldEnumerator::GetCurrent(GCList &ls) {
|
||||||
{
|
|
||||||
ls.Add(this->current);
|
ls.Add(this->current);
|
||||||
return this->current;
|
return this->current;
|
||||||
}
|
}
|
||||||
void TYieldEnumerator::Mark()
|
void TYieldEnumerator::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked=true;
|
this->marked = true;
|
||||||
GC::Mark(this->current);
|
GC::Mark(this->current);
|
||||||
GC::Mark(this->enumerator);
|
GC::Mark(this->enumerator);
|
||||||
}
|
}
|
||||||
TYieldEnumerator* TYieldEnumerator::Create(GCList& ls,TObject v)
|
TYieldEnumerator *TYieldEnumerator::Create(GCList &ls, TObject v) {
|
||||||
{
|
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
|
||||||
TYieldEnumerator* yieldEnum = new TYieldEnumerator();
|
yieldEnum->current = nullptr;
|
||||||
yieldEnum->current=nullptr;
|
yieldEnum->hasStarted = false;
|
||||||
yieldEnum->hasStarted=false;
|
|
||||||
yieldEnum->enumerator = v;
|
yieldEnum->enumerator = v;
|
||||||
|
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(yieldEnum);
|
ls.Add(yieldEnum);
|
||||||
_gc->Watch(yieldEnum);
|
_gc->Watch(yieldEnum);
|
||||||
return yieldEnum;
|
return yieldEnum;
|
||||||
}
|
}
|
||||||
TYieldEnumerator* TYieldEnumerator::Create(GCList* ls,TObject v)
|
TYieldEnumerator *TYieldEnumerator::Create(GCList *ls, TObject v) {
|
||||||
{
|
|
||||||
|
|
||||||
TYieldEnumerator* yieldEnum = new TYieldEnumerator();
|
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
|
||||||
yieldEnum->current=nullptr;
|
yieldEnum->current = nullptr;
|
||||||
yieldEnum->hasStarted=false;
|
yieldEnum->hasStarted = false;
|
||||||
yieldEnum->enumerator = v;
|
yieldEnum->enumerator = v;
|
||||||
|
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(yieldEnum);
|
ls->Add(yieldEnum);
|
||||||
_gc->Watch(yieldEnum);
|
_gc->Watch(yieldEnum);
|
||||||
return yieldEnum;
|
return yieldEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCustomEnumerator::MoveNext(GC* ls)
|
bool TCustomEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||||
{
|
|
||||||
GCList ls2(ls);
|
GCList ls2(ls);
|
||||||
auto res = this->dict->CallMethod(ls2,"MoveNext",{});
|
auto res = this->dict->CallMethod(ls2, "MoveNext", {});
|
||||||
bool out;
|
bool out;
|
||||||
if(GetObject(res,out)) return out;
|
if (GetObject(res, out))
|
||||||
|
return out;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TObject TCustomEnumerator::GetCurrent(GCList& ls)
|
TObject TCustomEnumerator::GetCurrent(GCList &ls) {
|
||||||
{
|
TObject res = Undefined();
|
||||||
TObject res=Undefined();
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
auto getCurrent = this->dict->GetValue("getCurrent");
|
auto getCurrent = this->dict->GetValue("getCurrent");
|
||||||
TCallable* call;
|
TCallable *call;
|
||||||
if(GetObjectHeap(getCurrent,call))
|
if (GetObjectHeap(getCurrent, call)) {
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
res=call->Call(ls,{});
|
res = call->Call(ls, {});
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
}else{
|
} else {
|
||||||
|
|
||||||
res=this->dict->GetValue("Current");
|
res = this->dict->GetValue("Current");
|
||||||
}
|
}
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
void TCustomEnumerator::Mark()
|
void TCustomEnumerator::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->dict->Mark();
|
this->dict->Mark();
|
||||||
}
|
}
|
||||||
TCustomEnumerator* TCustomEnumerator::Create(GCList* ls, TDictionary* dict)
|
TCustomEnumerator *TCustomEnumerator::Create(GCList *ls, TDictionary *dict) {
|
||||||
{
|
TCustomEnumerator *customEnum = new TCustomEnumerator();
|
||||||
TCustomEnumerator* customEnum = new TCustomEnumerator();
|
|
||||||
customEnum->dict = dict;
|
customEnum->dict = dict;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(customEnum);
|
ls->Add(customEnum);
|
||||||
_gc->Watch(customEnum);
|
_gc->Watch(customEnum);
|
||||||
return customEnum;
|
return customEnum;
|
||||||
}
|
}
|
||||||
TCustomEnumerator* TCustomEnumerator::Create(GCList& ls, TDictionary* dict)
|
TCustomEnumerator *TCustomEnumerator::Create(GCList &ls, TDictionary *dict) {
|
||||||
{
|
TCustomEnumerator *customEnum = new TCustomEnumerator();
|
||||||
TCustomEnumerator* customEnum = new TCustomEnumerator();
|
|
||||||
customEnum->dict = dict;
|
customEnum->dict = dict;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(customEnum);
|
ls.Add(customEnum);
|
||||||
_gc->Watch(customEnum);
|
_gc->Watch(customEnum);
|
||||||
return customEnum;
|
return customEnum;
|
||||||
}
|
}
|
||||||
TEnumerator* TEnumerator::CreateFromObject(GCList& ls, TObject obj)
|
TEnumerator *TEnumerator::CreateFromObject(GCList &ls, TObject obj) {
|
||||||
{
|
|
||||||
std::string str;
|
std::string str;
|
||||||
TList* mls;
|
TList *mls;
|
||||||
TDynamicList* dynList;
|
TDynamicList *dynList;
|
||||||
TDynamicDictionary* dynDict;
|
TDynamicDictionary *dynDict;
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
TEnumerator* enumerator;
|
TEnumerator *enumerator;
|
||||||
if(GetObject(obj,str))
|
TQueryable *q;
|
||||||
{
|
if (GetObject(obj, str)) {
|
||||||
return TStringEnumerator::Create(ls, str);
|
return TStringEnumerator::Create(ls, str);
|
||||||
}
|
} else if (GetObjectHeap(obj, mls)) {
|
||||||
else if(GetObjectHeap(obj,mls))
|
return TListEnumerator::Create(ls, mls);
|
||||||
{
|
} else if (GetObjectHeap(obj, dynList)) {
|
||||||
return TListEnumerator::Create(ls,mls);
|
return TDynamicListEnumerator::Create(ls, dynList);
|
||||||
}
|
} else if (GetObjectHeap(obj, dict)) {
|
||||||
else if(GetObjectHeap(obj,dynList))
|
auto res = dict->CallMethod(ls, "GetEnumerator", {});
|
||||||
{
|
if (GetObjectHeap(res, dict)) {
|
||||||
return TDynamicListEnumerator::Create(ls,dynList);
|
return TCustomEnumerator::Create(ls, dict);
|
||||||
}
|
} else if (GetObjectHeap(res, enumerator)) {
|
||||||
else if(GetObjectHeap(obj,dict))
|
|
||||||
{
|
|
||||||
auto res=dict->CallMethod(ls,"GetEnumerator",{});
|
|
||||||
if(GetObjectHeap(res,dict))
|
|
||||||
{
|
|
||||||
return TCustomEnumerator::Create(ls,dict);
|
|
||||||
}
|
|
||||||
else if(GetObjectHeap(res,enumerator))
|
|
||||||
{
|
|
||||||
return enumerator;
|
return enumerator;
|
||||||
}
|
}
|
||||||
|
} else if (GetObjectHeap(obj, q)) {
|
||||||
|
return q->GetEnumerator(ls);
|
||||||
|
} else if (GetObjectHeap(obj, enumerator)) {
|
||||||
|
return enumerator;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList& ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
|
TVFSPathEnumerator *TVFSPathEnumerator::Create(
|
||||||
{
|
GCList &ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) {
|
||||||
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator();
|
TVFSPathEnumerator *vfspathe = new TVFSPathEnumerator();
|
||||||
vfspathe->enumerator = enumerator;
|
vfspathe->enumerator = enumerator;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(vfspathe);
|
ls.Add(vfspathe);
|
||||||
_gc->Watch(vfspathe);
|
_gc->Watch(vfspathe);
|
||||||
return vfspathe;
|
return vfspathe;
|
||||||
}
|
}
|
||||||
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList* ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
|
TVFSPathEnumerator *TVFSPathEnumerator::Create(
|
||||||
{
|
GCList *ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) {
|
||||||
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator();
|
TVFSPathEnumerator *vfspathe = new TVFSPathEnumerator();
|
||||||
vfspathe->enumerator = enumerator;
|
vfspathe->enumerator = enumerator;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(vfspathe);
|
ls->Add(vfspathe);
|
||||||
_gc->Watch(vfspathe);
|
_gc->Watch(vfspathe);
|
||||||
return vfspathe;
|
return vfspathe;
|
||||||
}
|
}
|
||||||
bool TVFSPathEnumerator::MoveNext(GC* ls)
|
bool TVFSPathEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||||
{
|
|
||||||
return enumerator.MoveNext();
|
return enumerator.MoveNext();
|
||||||
}
|
}
|
||||||
TObject TVFSPathEnumerator::GetCurrent(GCList& ls)
|
TObject TVFSPathEnumerator::GetCurrent(GCList &ls) {
|
||||||
{
|
|
||||||
return enumerator.Current;
|
return enumerator.Current;
|
||||||
}
|
}
|
||||||
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList& ls, TDictionary* dict)
|
TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList &ls,
|
||||||
{
|
TDictionary *dict) {
|
||||||
TDictionaryEnumerator* dicte=new TDictionaryEnumerator();
|
TDictionaryEnumerator *dicte = new TDictionaryEnumerator();
|
||||||
dicte->dict = dict;
|
dicte->dict = dict;
|
||||||
dicte->hasStarted=false;
|
dicte->hasStarted = false;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(dicte);
|
ls.Add(dicte);
|
||||||
_gc->Watch(dicte);
|
_gc->Watch(dicte);
|
||||||
return dicte;
|
return dicte;
|
||||||
}
|
}
|
||||||
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList* ls, TDictionary* dict)
|
TDictionaryEnumerator *TDictionaryEnumerator::Create(GCList *ls,
|
||||||
{
|
TDictionary *dict) {
|
||||||
TDictionaryEnumerator* dicte=new TDictionaryEnumerator();
|
TDictionaryEnumerator *dicte = new TDictionaryEnumerator();
|
||||||
dicte->dict = dict;
|
dicte->dict = dict;
|
||||||
dicte->hasStarted=false;
|
dicte->hasStarted = false;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(dicte);
|
ls->Add(dicte);
|
||||||
_gc->Watch(dicte);
|
_gc->Watch(dicte);
|
||||||
return dicte;
|
return dicte;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TDictionaryEnumerator::MoveNext(GC* ls)
|
bool TDictionaryEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||||
{
|
if (!this->hasStarted) {
|
||||||
if(!this->hasStarted)
|
this->hasStarted = true;
|
||||||
{
|
|
||||||
this->hasStarted=true;
|
|
||||||
this->ittr = this->dict->items.begin();
|
this->ittr = this->dict->items.begin();
|
||||||
return !this->dict->items.empty();
|
return !this->dict->items.empty();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
this->ittr++;
|
this->ittr++;
|
||||||
return this->ittr != this->dict->items.end();
|
return this->ittr != this->dict->items.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TObject TDictionaryEnumerator::GetCurrent(GCList& ls)
|
TObject TDictionaryEnumerator::GetCurrent(GCList &ls) {
|
||||||
{
|
if (!this->hasStarted)
|
||||||
if(!this->hasStarted) return Undefined();
|
return Undefined();
|
||||||
if(this->ittr != this->dict->items.end())
|
if (this->ittr != this->dict->items.end()) {
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
std::string key = this->ittr->first;
|
std::string key = this->ittr->first;
|
||||||
TObject value = this->ittr->second;
|
TObject value = this->ittr->second;
|
||||||
auto kvp = TDictionary::Create(ls);
|
auto kvp = TDictionary::Create(ls);
|
||||||
kvp->SetValue("Key",key);
|
kvp->SetValue("Key", key);
|
||||||
kvp->SetValue("Value",value);
|
kvp->SetValue("Value", value);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return kvp;
|
return kvp;
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
void TDictionaryEnumerator::Mark()
|
void TDictionaryEnumerator::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked=true;
|
this->marked = true;
|
||||||
this->dict->Mark();
|
this->dict->Mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TListEnumerator *TListEnumerator::Create(GCList &ls, TList *list) {
|
||||||
TListEnumerator* TListEnumerator::Create(GCList& ls, TList* list)
|
TListEnumerator *liste = new TListEnumerator();
|
||||||
{
|
|
||||||
TListEnumerator* liste=new TListEnumerator();
|
|
||||||
liste->ls = list;
|
liste->ls = list;
|
||||||
liste->index = -1;
|
liste->index = -1;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(liste);
|
ls.Add(liste);
|
||||||
_gc->Watch(liste);
|
_gc->Watch(liste);
|
||||||
return liste;
|
return liste;
|
||||||
}
|
}
|
||||||
TListEnumerator* TListEnumerator::Create(GCList* ls, TList* list)
|
TListEnumerator *TListEnumerator::Create(GCList *ls, TList *list) {
|
||||||
{
|
TListEnumerator *liste = new TListEnumerator();
|
||||||
TListEnumerator* liste=new TListEnumerator();
|
|
||||||
liste->ls = list;
|
liste->ls = list;
|
||||||
liste->index = -1;
|
liste->index = -1;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(liste);
|
ls->Add(liste);
|
||||||
_gc->Watch(liste);
|
_gc->Watch(liste);
|
||||||
return liste;
|
return liste;
|
||||||
}
|
}
|
||||||
bool TListEnumerator::MoveNext(GC* ls)
|
bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||||
{
|
|
||||||
this->index++;
|
this->index++;
|
||||||
return this->index >= 0 && this->index < this->ls->Count();
|
return this->index >= 0 && this->index < this->ls->Count();
|
||||||
}
|
}
|
||||||
TObject TListEnumerator::GetCurrent(GCList& ls)
|
TObject TListEnumerator::GetCurrent(GCList &ls) {
|
||||||
{
|
|
||||||
|
|
||||||
if(this->index < -1) return nullptr;
|
if (this->index < -1)
|
||||||
if(this->ls->Count() == 0) return nullptr;
|
return nullptr;
|
||||||
if(this->index >= this->ls->Count()) return nullptr;
|
if (this->ls->Count() == 0)
|
||||||
|
return nullptr;
|
||||||
|
if (this->index >= this->ls->Count())
|
||||||
|
return nullptr;
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
TObject o = this->ls->Get(index);
|
TObject o = this->ls->Get(index);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
void TListEnumerator::Mark()
|
void TListEnumerator::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked = true;
|
this->marked = true;
|
||||||
this->ls->Mark();
|
this->ls->Mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList& ls, TAssociativeArray* list)
|
TAssociativeArrayEnumerator *
|
||||||
{
|
TAssociativeArrayEnumerator::Create(GCList &ls, TAssociativeArray *list) {
|
||||||
TAssociativeArrayEnumerator* liste=new TAssociativeArrayEnumerator();
|
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
|
||||||
liste->ls = list;
|
liste->ls = list;
|
||||||
liste->index = -1;
|
liste->index = -1;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(liste);
|
ls.Add(liste);
|
||||||
_gc->Watch(liste);
|
_gc->Watch(liste);
|
||||||
return liste;
|
return liste;
|
||||||
}
|
}
|
||||||
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList* ls, TAssociativeArray* list)
|
TAssociativeArrayEnumerator *
|
||||||
{
|
TAssociativeArrayEnumerator::Create(GCList *ls, TAssociativeArray *list) {
|
||||||
TAssociativeArrayEnumerator* liste=new TAssociativeArrayEnumerator();
|
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
|
||||||
liste->ls = list;
|
liste->ls = list;
|
||||||
liste->index = -1;
|
liste->index = -1;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(liste);
|
ls->Add(liste);
|
||||||
_gc->Watch(liste);
|
_gc->Watch(liste);
|
||||||
return liste;
|
return liste;
|
||||||
}
|
}
|
||||||
bool TAssociativeArrayEnumerator::MoveNext(GC* ls)
|
bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||||
{
|
|
||||||
this->index++;
|
this->index++;
|
||||||
return this->index >= 0 && this->index < this->ls->Count();
|
return this->index >= 0 && this->index < this->ls->Count();
|
||||||
}
|
}
|
||||||
TObject TAssociativeArrayEnumerator::GetCurrent(GCList& ls)
|
TObject TAssociativeArrayEnumerator::GetCurrent(GCList &ls) {
|
||||||
{
|
|
||||||
|
|
||||||
if(this->index < -1) return nullptr;
|
if (this->index < -1)
|
||||||
if(this->ls->Count() == 0) return nullptr;
|
return nullptr;
|
||||||
if(this->index >= this->ls->Count()) return nullptr;
|
if (this->ls->Count() == 0)
|
||||||
|
return nullptr;
|
||||||
|
if (this->index >= this->ls->Count())
|
||||||
|
return nullptr;
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
TDictionary* dict = TDictionary::Create(ls);
|
TDictionary *dict = TDictionary::Create(ls);
|
||||||
dict->SetValue("Key",this->ls->GetKey(this->index));
|
dict->SetValue("Key", this->ls->GetKey(this->index));
|
||||||
dict->SetValue("Value",this->ls->GetValue(this->index));
|
dict->SetValue("Value", this->ls->GetValue(this->index));
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
void TAssociativeArrayEnumerator::Mark()
|
void TAssociativeArrayEnumerator::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked = true;
|
this->marked = true;
|
||||||
this->ls->Mark();
|
this->ls->Mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList &ls,
|
||||||
|
TDynamicList *list) {
|
||||||
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList& ls, TDynamicList* list)
|
TDynamicListEnumerator *liste = new TDynamicListEnumerator();
|
||||||
{
|
|
||||||
TDynamicListEnumerator* liste=new TDynamicListEnumerator();
|
|
||||||
liste->ls = list;
|
liste->ls = list;
|
||||||
liste->index = -1;
|
liste->index = -1;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(liste);
|
ls.Add(liste);
|
||||||
_gc->Watch(liste);
|
_gc->Watch(liste);
|
||||||
return liste;
|
return liste;
|
||||||
}
|
}
|
||||||
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList* ls, TDynamicList* list)
|
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList *ls,
|
||||||
{
|
TDynamicList *list) {
|
||||||
TDynamicListEnumerator* liste=new TDynamicListEnumerator();
|
TDynamicListEnumerator *liste = new TDynamicListEnumerator();
|
||||||
liste->ls = list;
|
liste->ls = list;
|
||||||
liste->index = -1;
|
liste->index = -1;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(liste);
|
ls->Add(liste);
|
||||||
_gc->Watch(liste);
|
_gc->Watch(liste);
|
||||||
return liste;
|
return liste;
|
||||||
}
|
}
|
||||||
bool TDynamicListEnumerator::MoveNext(GC* ls)
|
bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||||
{
|
|
||||||
this->index++;
|
this->index++;
|
||||||
GCList ls2(ls);
|
GCList ls2(ls);
|
||||||
return this->index >= 0 && this->index < this->ls->Count(ls2);
|
return this->index >= 0 && this->index < this->ls->Count(ls2);
|
||||||
}
|
}
|
||||||
TObject TDynamicListEnumerator::GetCurrent(GCList& ls)
|
TObject TDynamicListEnumerator::GetCurrent(GCList &ls) {
|
||||||
{
|
|
||||||
|
|
||||||
if(this->index < -1) return nullptr;
|
if (this->index < -1)
|
||||||
|
return nullptr;
|
||||||
auto r = this->ls->Count(ls);
|
auto r = this->ls->Count(ls);
|
||||||
if(r == 0) return nullptr;
|
if (r == 0)
|
||||||
if(this->index >= r) return nullptr;
|
return nullptr;
|
||||||
|
if (this->index >= r)
|
||||||
|
return nullptr;
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
TObject o = this->ls->GetAt(ls,index);
|
TObject o = this->ls->GetAt(ls, index);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
void TDynamicListEnumerator::Mark()
|
void TDynamicListEnumerator::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked = true;
|
this->marked = true;
|
||||||
this->ls->Mark();
|
this->ls->Mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TStringEnumerator *TStringEnumerator::Create(GCList &ls, std::string str) {
|
||||||
TStringEnumerator* TStringEnumerator::Create(GCList& ls,std::string str)
|
TStringEnumerator *stre = new TStringEnumerator();
|
||||||
{
|
|
||||||
TStringEnumerator* stre=new TStringEnumerator();
|
|
||||||
stre->str = str;
|
stre->str = str;
|
||||||
stre->hasStarted=false;
|
stre->hasStarted = false;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(stre);
|
ls.Add(stre);
|
||||||
_gc->Watch(stre);
|
_gc->Watch(stre);
|
||||||
return stre;
|
return stre;
|
||||||
}
|
}
|
||||||
TStringEnumerator* TStringEnumerator::Create(GCList* ls,std::string str)
|
TStringEnumerator *TStringEnumerator::Create(GCList *ls, std::string str) {
|
||||||
{
|
TStringEnumerator *stre = new TStringEnumerator();
|
||||||
TStringEnumerator* stre=new TStringEnumerator();
|
|
||||||
stre->str = str;
|
stre->str = str;
|
||||||
stre->hasStarted=false;
|
stre->hasStarted = false;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(stre);
|
ls->Add(stre);
|
||||||
_gc->Watch(stre);
|
_gc->Watch(stre);
|
||||||
return stre;
|
return stre;
|
||||||
}
|
}
|
||||||
bool TStringEnumerator::MoveNext(GC* ls)
|
bool TStringEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||||
{
|
if (!this->hasStarted) {
|
||||||
if(!this->hasStarted)
|
this->hasStarted = true;
|
||||||
{
|
|
||||||
this->hasStarted=true;
|
|
||||||
this->index = 0;
|
this->index = 0;
|
||||||
return !this->str.empty();
|
return !this->str.empty();
|
||||||
}
|
} else {
|
||||||
else
|
if (this->index >= this->str.size())
|
||||||
{
|
return false;
|
||||||
if(this->index >= this->str.size()) return false;
|
|
||||||
this->index++;
|
this->index++;
|
||||||
return this->index < this->str.size();
|
return this->index < this->str.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TObject TStringEnumerator::GetCurrent(GCList& ls)
|
TObject TStringEnumerator::GetCurrent(GCList &ls) {
|
||||||
{
|
if (!this->hasStarted)
|
||||||
if(!this->hasStarted) return nullptr;
|
|
||||||
if(this->index < this->str.size()) return this->str[this->index];
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
if (this->index < this->str.size())
|
||||||
|
return this->str[this->index];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
}; // namespace Tesses::CrossLang
|
||||||
@@ -1,223 +1,184 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
TDynamicList* TDynamicList::Create(GCList& ls,TCallable* callable)
|
TDynamicList *TDynamicList::Create(GCList &ls, TCallable *callable) {
|
||||||
{
|
TDynamicList *list = new TDynamicList();
|
||||||
TDynamicList* list=new TDynamicList();
|
|
||||||
list->cb = callable;
|
list->cb = callable;
|
||||||
GC* _gc = ls.GetGC();
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
ls.Add(list);
|
ls.Add(list);
|
||||||
_gc->Watch(list);
|
_gc->Watch(list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
TDynamicList* TDynamicList::Create(GCList* ls,TCallable* callable)
|
TDynamicList *TDynamicList::Create(GCList *ls, TCallable *callable) {
|
||||||
{
|
TDynamicList *list = new TDynamicList();
|
||||||
TDynamicList* list=new TDynamicList();
|
|
||||||
list->cb = callable;
|
list->cb = callable;
|
||||||
GC* _gc = ls->GetGC();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
ls->Add(list);
|
ls->Add(list);
|
||||||
_gc->Watch(list);
|
_gc->Watch(list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDynamicList::Mark()
|
void TDynamicList::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked=true;
|
this->marked = true;
|
||||||
this->cb->Mark();
|
this->cb->Mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t TDynamicList::Count(GCList& ls)
|
int64_t TDynamicList::Count(GCList &ls) {
|
||||||
{
|
|
||||||
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Count");
|
dict->SetValue("Type", "Count");
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
auto res = cb->Call(ls,{dict});
|
auto res = cb->Call(ls, {dict});
|
||||||
int64_t n;
|
int64_t n;
|
||||||
if(GetObject(res,n)) return n;
|
if (GetObject(res, n))
|
||||||
|
return n;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
TObject TDynamicList::Add(GCList& ls, TObject v)
|
TObject TDynamicList::Add(GCList &ls, TObject v) {
|
||||||
{
|
|
||||||
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Add");
|
dict->SetValue("Type", "Add");
|
||||||
dict->SetValue("Value",v);
|
dict->SetValue("Value", v);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return cb->Call(ls,{dict});
|
return cb->Call(ls, {dict});
|
||||||
|
}
|
||||||
}
|
TObject TDynamicList::Insert(GCList &ls, int64_t index, TObject v) {
|
||||||
TObject TDynamicList::Insert(GCList& ls, int64_t index, TObject v)
|
|
||||||
{
|
|
||||||
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Insert");
|
dict->SetValue("Type", "Insert");
|
||||||
dict->SetValue("Index",index);
|
dict->SetValue("Index", index);
|
||||||
dict->SetValue("Value",v);
|
dict->SetValue("Value", v);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return cb->Call(ls,{dict});
|
return cb->Call(ls, {dict});
|
||||||
|
}
|
||||||
}
|
TObject TDynamicList::Clear(GCList &ls) {
|
||||||
TObject TDynamicList::Clear(GCList& ls)
|
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Clear");
|
dict->SetValue("Type", "Clear");
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return cb->Call(ls,{dict});
|
return cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
TObject TDynamicList::Remove(GCList& ls, TObject obj)
|
TObject TDynamicList::Remove(GCList &ls, TObject obj) {
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "Remove");
|
dict->SetValue("Type", "Remove");
|
||||||
dict->SetValue("Value", obj);
|
dict->SetValue("Value", obj);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return cb->Call(ls,{dict});
|
return cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
TObject TDynamicList::RemoveAllEqual(GCList& ls, TObject obj)
|
TObject TDynamicList::RemoveAllEqual(GCList &ls, TObject obj) {
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "RemoveAllEqual");
|
dict->SetValue("Type", "RemoveAllEqual");
|
||||||
dict->SetValue("Value", obj);
|
dict->SetValue("Value", obj);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return cb->Call(ls,{dict});
|
return cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
TObject TDynamicList::RemoveAt(GCList& ls, int64_t index)
|
TObject TDynamicList::RemoveAt(GCList &ls, int64_t index) {
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "RemoveAt");
|
dict->SetValue("Type", "RemoveAt");
|
||||||
dict->SetValue("Index", index);
|
dict->SetValue("Index", index);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return cb->Call(ls,{dict});
|
return cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
TObject TDynamicList::ToString(GCList& ls)
|
TObject TDynamicList::ToString(GCList &ls) {
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "ToString");
|
dict->SetValue("Type", "ToString");
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return cb->Call(ls,{dict});
|
return cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject TDynamicList::GetAt(GCList& ls, int64_t index)
|
TObject TDynamicList::GetAt(GCList &ls, int64_t index) {
|
||||||
{
|
|
||||||
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "GetAt");
|
dict->SetValue("Type", "GetAt");
|
||||||
dict->SetValue("Index",index);
|
dict->SetValue("Index", index);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return cb->Call(ls,{dict});
|
return cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject TDynamicList::SetAt(GCList& ls, int64_t index, TObject val)
|
TObject TDynamicList::SetAt(GCList &ls, int64_t index, TObject val) {
|
||||||
{
|
|
||||||
auto dict = TDictionary::Create(ls);
|
auto dict = TDictionary::Create(ls);
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
dict->SetValue("Type", "SetAt");
|
dict->SetValue("Type", "SetAt");
|
||||||
dict->SetValue("Index",index);
|
dict->SetValue("Index", index);
|
||||||
dict->SetValue("Value",val);
|
dict->SetValue("Value", val);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return cb->Call(ls,{dict});
|
return cb->Call(ls, {dict});
|
||||||
}
|
}
|
||||||
|
|
||||||
TDynamicList::~TDynamicList()
|
TDynamicList::~TDynamicList() {}
|
||||||
{
|
|
||||||
|
|
||||||
}
|
TByteArray *TByteArray::Create(GCList &ls) {
|
||||||
|
TByteArray *arr = new TByteArray();
|
||||||
|
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||||
TByteArray* TByteArray::Create(GCList& ls)
|
|
||||||
{
|
|
||||||
TByteArray* arr=new TByteArray();
|
|
||||||
GC* _gc = ls.GetGC();
|
|
||||||
ls.Add(arr);
|
ls.Add(arr);
|
||||||
_gc->Watch(arr);
|
_gc->Watch(arr);
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TByteArray* TByteArray::Create(GCList* ls)
|
TByteArray *TByteArray::Create(GCList *ls) {
|
||||||
{
|
TByteArray *arr = new TByteArray();
|
||||||
TByteArray* arr=new TByteArray();
|
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||||
GC* _gc = ls->GetGC();
|
|
||||||
ls->Add(arr);
|
ls->Add(arr);
|
||||||
_gc->Watch(arr);
|
_gc->Watch(arr);
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
TList* TList::Create(GCList* gc)
|
TList *TList::Create(GCList *gc) {
|
||||||
{
|
TList *list = new TList();
|
||||||
TList* list=new TList();
|
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||||
GC* _gc = gc->GetGC();
|
|
||||||
gc->Add(list);
|
gc->Add(list);
|
||||||
_gc->Watch(list);
|
_gc->Watch(list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
TList* TList::Create(GCList& gc)
|
TList *TList::Create(GCList &gc) {
|
||||||
{
|
TList *list = new TList();
|
||||||
TList* list=new TList();
|
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||||
GC* _gc = gc.GetGC();
|
|
||||||
gc.Add(list);
|
gc.Add(list);
|
||||||
_gc->Watch(list);
|
_gc->Watch(list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
void TList::Add(TObject value)
|
void TList::Add(TObject value) { this->items.push_back(value); }
|
||||||
{
|
void TList::Set(int64_t index, TObject value) {
|
||||||
this->items.push_back(value);
|
if (index >= 0 && index < this->Count()) {
|
||||||
}
|
|
||||||
void TList::Set(int64_t index, TObject value)
|
|
||||||
{
|
|
||||||
if(index >= 0 && index < this->Count())
|
|
||||||
{
|
|
||||||
this->items[index] = value;
|
this->items[index] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TObject TList::Get(int64_t index)
|
TObject TList::Get(int64_t index) {
|
||||||
{
|
if (index >= 0 && index < this->Count()) {
|
||||||
if(index >= 0 && index < this->Count())
|
|
||||||
{
|
|
||||||
return this->items[index];
|
return this->items[index];
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
|
}
|
||||||
|
int64_t TList::Count() { return (int64_t)this->items.size(); }
|
||||||
|
void TList::Insert(int64_t index, TObject value) {
|
||||||
|
if (index >= 0 && index <= this->Count()) {
|
||||||
|
this->items.insert(this->items.begin() + index, value);
|
||||||
}
|
}
|
||||||
int64_t TList::Count()
|
}
|
||||||
{
|
void TList::RemoveAt(int64_t index) {
|
||||||
return (int64_t)this->items.size();
|
if (index >= 0 && index < this->Count()) {
|
||||||
|
this->items.erase(this->items.begin() + index);
|
||||||
}
|
}
|
||||||
void TList::Insert(int64_t index, TObject value)
|
}
|
||||||
{
|
void TList::Clear() { this->items.clear(); }
|
||||||
if(index >= 0 && index <= this->Count())
|
void TList::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
this->items.insert(this->items.begin()+index,value);
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
void TList::RemoveAt(int64_t index)
|
|
||||||
{
|
|
||||||
if(index >= 0 && index < this->Count())
|
|
||||||
{
|
|
||||||
this->items.erase(this->items.begin()+index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void TList::Clear()
|
|
||||||
{
|
|
||||||
this->items.clear();
|
|
||||||
}
|
|
||||||
void TList::Mark()
|
|
||||||
{
|
|
||||||
if(this->marked) return;
|
|
||||||
this->marked = true;
|
this->marked = true;
|
||||||
for(auto item : this->items)
|
for (auto item : this->items) {
|
||||||
{
|
|
||||||
GC::Mark(item);
|
GC::Mark(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}; // namespace Tesses::CrossLang
|
||||||
@@ -1,75 +1,53 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
TNativeObject::~TNativeObject() {}
|
||||||
TNativeObject::~TNativeObject()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
TNative::TNative(void *ptr, std::function<void(void *)> destroy) {
|
||||||
|
|
||||||
TNative::TNative(void* ptr,std::function<void(void*)> destroy)
|
|
||||||
{
|
|
||||||
this->ptr = ptr;
|
this->ptr = ptr;
|
||||||
this->destroyed=false;
|
this->destroyed = false;
|
||||||
this->destroy = destroy;
|
this->destroy = destroy;
|
||||||
|
}
|
||||||
}
|
bool TNative::GetDestroyed() { return this->destroyed; }
|
||||||
bool TNative::GetDestroyed()
|
void *TNative::GetPointer() { return this->ptr; }
|
||||||
{
|
void TNative::Mark() {
|
||||||
return this->destroyed;
|
if (this->marked)
|
||||||
}
|
return;
|
||||||
void* TNative::GetPointer()
|
this->marked = true;
|
||||||
{
|
|
||||||
return this->ptr;
|
|
||||||
}
|
|
||||||
void TNative::Mark()
|
|
||||||
{
|
|
||||||
if(this->marked) return;
|
|
||||||
this->marked=true;
|
|
||||||
|
|
||||||
GC::Mark(this->other);
|
GC::Mark(this->other);
|
||||||
|
}
|
||||||
}
|
void TNative::Destroy() {
|
||||||
void TNative::Destroy()
|
if (this->destroyed)
|
||||||
{
|
return;
|
||||||
if(this->destroyed) return;
|
if (this->destroy != nullptr) {
|
||||||
if(this->destroy != nullptr)
|
this->destroyed = true;
|
||||||
{
|
|
||||||
this->destroyed=true;
|
|
||||||
this->destroy(this->ptr);
|
this->destroy(this->ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool TNativeObject::ToBool()
|
bool TNativeObject::ToBool() { return true; }
|
||||||
{
|
bool TNativeObject::Equals(std::shared_ptr<GC> gc, TObject right) {
|
||||||
return true;
|
if (std::holds_alternative<THeapObjectHolder>(right)) {
|
||||||
}
|
|
||||||
bool TNativeObject::Equals(GC* gc, TObject right)
|
|
||||||
{
|
|
||||||
if(std::holds_alternative<THeapObjectHolder>(right))
|
|
||||||
{
|
|
||||||
return this == std::get<THeapObjectHolder>(right).obj;
|
return this == std::get<THeapObjectHolder>(right).obj;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TNative* TNative::Create(GCList& ls, void* ptr,std::function<void(void*)> destroy)
|
TNative *TNative::Create(GCList &ls, void *ptr,
|
||||||
{
|
std::function<void(void *)> destroy) {
|
||||||
TNative* native = new TNative(ptr,destroy);
|
TNative *native = new TNative(ptr, destroy);
|
||||||
GC* gc = ls.GetGC();
|
std::shared_ptr<GC> gc = ls.GetGC();
|
||||||
ls.Add(native);
|
ls.Add(native);
|
||||||
gc->Watch(native);
|
gc->Watch(native);
|
||||||
return native;
|
return native;
|
||||||
}
|
}
|
||||||
TNative* TNative::Create(GCList* ls, void* ptr,std::function<void(void*)> destroy)
|
TNative *TNative::Create(GCList *ls, void *ptr,
|
||||||
{
|
std::function<void(void *)> destroy) {
|
||||||
TNative* native = new TNative(ptr,destroy);
|
TNative *native = new TNative(ptr, destroy);
|
||||||
GC* gc = ls->GetGC();
|
std::shared_ptr<GC> gc = ls->GetGC();
|
||||||
ls->Add(native);
|
ls->Add(native);
|
||||||
gc->Watch(native);
|
gc->Watch(native);
|
||||||
return native;
|
return native;
|
||||||
}
|
|
||||||
TNative::~TNative()
|
|
||||||
{
|
|
||||||
this->Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
TNative::~TNative() { this->Destroy(); }
|
||||||
|
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
|
|||||||
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,47 +1,32 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
TRandom::TRandom() : random() {}
|
||||||
TRandom::TRandom() : random()
|
TRandom::TRandom(uint64_t seed) : random(seed) {}
|
||||||
{
|
std::string TRandom::TypeName() { return "Random"; }
|
||||||
|
TObject TRandom::CallMethod(GCList &ls, std::string name,
|
||||||
}
|
std::vector<TObject> args) {
|
||||||
TRandom::TRandom(uint64_t seed) : random(seed)
|
if (name == "Next") {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
std::string TRandom::TypeName()
|
|
||||||
{
|
|
||||||
return "Random";
|
|
||||||
}
|
|
||||||
TObject TRandom::CallMethod(GCList& ls,std::string name, std::vector<TObject> args)
|
|
||||||
{
|
|
||||||
if(name == "Next")
|
|
||||||
{
|
|
||||||
int64_t first;
|
int64_t first;
|
||||||
int64_t second;
|
int64_t second;
|
||||||
if(GetArgument(args,0,first))
|
if (GetArgument(args, 0, first)) {
|
||||||
{
|
if (GetArgument(args, 1, second)) {
|
||||||
if(GetArgument(args,1,second))
|
return (int64_t)random.Next((int32_t)first, (int32_t)second);
|
||||||
{
|
|
||||||
return (int64_t)random.Next((int32_t)first,(int32_t)second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int64_t)random.Next((uint32_t)first);
|
return (int64_t)random.Next((uint32_t)first);
|
||||||
}
|
}
|
||||||
|
|
||||||
return random.Next();
|
return random.Next();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name == "NextByte")
|
if (name == "NextByte") {
|
||||||
{
|
|
||||||
return (int64_t)random.NextByte();
|
return (int64_t)random.NextByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name == "ToString") {
|
if (name == "ToString") {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
@@ -2,62 +2,80 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
namespace Tesses::CrossLang {
|
namespace Tesses::CrossLang {
|
||||||
void ThrowConstError(std::string key)
|
void ThrowConstError(std::string key) {
|
||||||
{
|
throw std::runtime_error("Cannot set \"" + key +
|
||||||
throw std::runtime_error("Cannot set \"" + key + "\" because it is a const");
|
"\" because it is a const");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TEnvironment::DeclareConstVariable(std::string key, TObject value)
|
void TEnvironment::DeclareConstVariable(std::string key, TObject value) {
|
||||||
{
|
this->DeclareVariable(key, value);
|
||||||
this->DeclareVariable(key,value);
|
|
||||||
this->consts.push_back(key);
|
this->consts.push_back(key);
|
||||||
}
|
}
|
||||||
bool TEnvironment::HasConstForDeclare(std::string key)
|
bool TEnvironment::HasConstForDeclare(std::string key) {
|
||||||
{
|
for (auto item : this->consts)
|
||||||
for(auto item : this->consts)
|
if (item == key)
|
||||||
if(item == key)
|
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool TEnvironment::HasConstForSet(std::string key)
|
bool TEnvironment::HasConstForSet(std::string key) {
|
||||||
{
|
|
||||||
return HasConstForDeclare(key);
|
return HasConstForDeclare(key);
|
||||||
|
}
|
||||||
|
bool TRootEnvironment::TryFindClass(std::vector<std::string> &name,
|
||||||
|
size_t &index) {
|
||||||
|
for (size_t i = 0; i < this->classes.size(); i++) {
|
||||||
|
bool conUp = false;
|
||||||
|
if (classes[i].first->classes.at(classes[i].second).name.size() !=
|
||||||
|
name.size())
|
||||||
|
continue;
|
||||||
|
for (size_t j = 0; j < name.size(); j++)
|
||||||
|
if (classes[i].first->classes.at(classes[i].second).name[j] !=
|
||||||
|
name[j]) {
|
||||||
|
conUp = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
bool TRootEnvironment::TryFindClass(std::vector<std::string>& name, size_t& index)
|
if (conUp)
|
||||||
{
|
continue;
|
||||||
for(size_t i = 0; i < this->classes.size(); i++)
|
index = i;
|
||||||
{
|
|
||||||
if(classes[i].first->classes.at(classes[i].second).name.size() != name.size()) continue;
|
|
||||||
for(size_t j = 0; j < name.size(); j++)
|
|
||||||
if(classes[i].first->classes.at(classes[i].second).name[j] != name[j]) continue;
|
|
||||||
index=i;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
TDictionary *TRootEnvironment::GetPrivateFromFile(std::shared_ptr<GC> gc,
|
||||||
|
TFile *file) {
|
||||||
|
auto index = reinterpret_cast<uint64_t>(file);
|
||||||
|
gc->BarrierBegin();
|
||||||
|
TDictionary *obj;
|
||||||
|
if (this->private_file_data.count(index) > 0) {
|
||||||
|
obj = this->private_file_data[index];
|
||||||
|
} else {
|
||||||
|
GCList ls(gc);
|
||||||
|
obj = TDictionary::Create(ls);
|
||||||
|
this->private_file_data[index] = obj;
|
||||||
}
|
}
|
||||||
bool TRootEnvironment::HasVariableOrFieldRecurse(std::string key,bool setting)
|
gc->BarrierEnd();
|
||||||
{
|
|
||||||
std::string property=(setting? "set":"get") + key;
|
return obj;
|
||||||
if(this->HasVariable(property))
|
}
|
||||||
{
|
bool TRootEnvironment::HasVariableOrFieldRecurse(std::string key,
|
||||||
|
bool setting) {
|
||||||
|
std::string property = (setting ? "set" : "get") + key;
|
||||||
|
if (this->HasVariable(property)) {
|
||||||
auto res = this->GetVariable(property);
|
auto res = this->GetVariable(property);
|
||||||
TCallable* callable;
|
TCallable *callable;
|
||||||
if(GetObjectHeap(res,callable)) return true;
|
if (GetObjectHeap(res, callable))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->HasVariable(key);
|
return this->HasVariable(key);
|
||||||
}
|
}
|
||||||
TObject TRootEnvironment::GetVariable(GCList& ls, std::string key)
|
TObject TRootEnvironment::GetVariable(GCList &ls, std::string key) {
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
if(this->HasVariable("get" + key))
|
if (this->HasVariable("get" + key)) {
|
||||||
{
|
auto item = this->GetVariable("get" + key);
|
||||||
auto item = this->GetVariable("get"+key);
|
TCallable *callable;
|
||||||
TCallable* callable;
|
if (GetObjectHeap(item, callable)) {
|
||||||
if(GetObjectHeap(item,callable))
|
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return callable->Call(ls,{});
|
return callable->Call(ls, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,56 +83,54 @@ namespace Tesses::CrossLang {
|
|||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
TObject TRootEnvironment::SetVariable(GCList& ls, std::string key, TObject value)
|
TObject TRootEnvironment::SetVariable(GCList &ls, std::string key,
|
||||||
{
|
TObject value) {
|
||||||
ls.GetGC()->BarrierBegin();
|
ls.GetGC()->BarrierBegin();
|
||||||
if(this->HasVariable("set" + key))
|
if (this->HasVariable("set" + key)) {
|
||||||
{
|
auto item = this->GetVariable("set" + key);
|
||||||
auto item = this->GetVariable("set"+key);
|
TCallable *callable;
|
||||||
TCallable* callable;
|
if (GetObjectHeap(item, callable)) {
|
||||||
if(GetObjectHeap(item,callable))
|
|
||||||
{
|
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
return callable->Call(ls,{value});
|
return callable->Call(ls, {value});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetVariable(key,value);
|
this->SetVariable(key, value);
|
||||||
ls.GetGC()->BarrierEnd();
|
ls.GetGC()->BarrierEnd();
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TRootEnvironment::LoadDependency(GC* gc,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, std::pair<std::string,TVMVersion> dep)
|
void TRootEnvironment::LoadDependency(
|
||||||
{
|
std::shared_ptr<GC> gc,
|
||||||
for(auto item : this->dependencies)
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
|
||||||
if(item.first == dep.first && item.second.CompareTo(dep.second) >= 0) return;
|
std::pair<std::string, TVMVersion> dep) {
|
||||||
|
for (auto item : this->dependencies)
|
||||||
|
if (item.first == dep.first && item.second.CompareTo(dep.second) >= 0)
|
||||||
|
return;
|
||||||
std::string name = {};
|
std::string name = {};
|
||||||
name.append(dep.first);
|
name.append(dep.first);
|
||||||
name.push_back('-');
|
name.push_back('-');
|
||||||
name.append(dep.second.ToString());
|
name.append(dep.second.ToString());
|
||||||
name.append(".crvm");
|
name.append(".crvm");
|
||||||
std::string filename="/" + name;
|
std::string filename = "/" + name;
|
||||||
|
|
||||||
if(vfs->RegularFileExists(filename))
|
if (vfs->RegularFileExists(filename)) {
|
||||||
{
|
auto file = vfs->OpenFile(filename, "rb");
|
||||||
auto file = vfs->OpenFile(filename,"rb");
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TFile* f = TFile::Create(ls);
|
TFile *f = TFile::Create(ls);
|
||||||
f->Load(gc, file);
|
f->Load(gc, file);
|
||||||
|
|
||||||
LoadFileWithDependencies(gc, vfs, f);
|
LoadFileWithDependencies(gc, vfs, f);
|
||||||
}
|
} else
|
||||||
else throw VMException("Could not open file: \"" + name + "\".");
|
throw VMException("Could not open file: \"" + name + "\".");
|
||||||
}
|
}
|
||||||
TObject TEnvironment::Eval(GCList& ls,std::string code)
|
TObject TEnvironment::Eval(GCList &ls, std::string code) {
|
||||||
{
|
|
||||||
std::stringstream strm(code);
|
std::stringstream strm(code);
|
||||||
std::vector<LexToken> tokens;
|
std::vector<LexToken> tokens;
|
||||||
int res =Lex("eval.tcross",strm,tokens);
|
int res = Lex("eval.tcross", strm, tokens);
|
||||||
if(res != 0)
|
if (res != 0) {
|
||||||
{
|
|
||||||
throw VMException("Lex error at line: " + std::to_string(res));
|
throw VMException("Lex error at line: " + std::to_string(res));
|
||||||
}
|
}
|
||||||
Parser parser(tokens);
|
Parser parser(tokens);
|
||||||
@@ -124,272 +140,239 @@ namespace Tesses::CrossLang {
|
|||||||
gen.GenRoot(n);
|
gen.GenRoot(n);
|
||||||
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
||||||
gen.Save(ms);
|
gen.Save(ms);
|
||||||
ms->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
|
ms->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||||
TFile* f = TFile::Create(ls);
|
TFile *f = TFile::Create(ls);
|
||||||
f->Load(ls.GetGC(),ms);
|
f->Load(ls.GetGC(), ms);
|
||||||
return this->LoadFile(ls.GetGC(), f);
|
return this->LoadFile(ls.GetGC(), f);
|
||||||
}
|
}
|
||||||
TDictionary* TEnvironment::EnsureDictionary(GC* gc, std::string key)
|
TDictionary *TEnvironment::EnsureDictionary(std::shared_ptr<GC> gc,
|
||||||
{
|
std::string key) {
|
||||||
TObject item = this->GetVariable(key);
|
TObject item = this->GetVariable(key);
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(GetObjectHeap(item,dict)) return dict;
|
if (GetObjectHeap(item, dict))
|
||||||
|
return dict;
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
dict = TDictionary::Create(ls);
|
dict = TDictionary::Create(ls);
|
||||||
this->DeclareVariable(key, dict);
|
this->DeclareVariable(key, dict);
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
void TEnvironment::DeclareVariable(GC* gc, std::vector<std::string> name, TObject o)
|
void TEnvironment::DeclareVariable(std::shared_ptr<GC> gc,
|
||||||
{
|
std::vector<std::string> name, TObject o) {
|
||||||
if(name.size() == 0)
|
if (name.size() == 0)
|
||||||
throw VMException("name can't be empty.");
|
throw VMException("name can't be empty.");
|
||||||
|
|
||||||
else if(name.size() == 1)
|
else if (name.size() == 1) {
|
||||||
{
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
this->DeclareVariable(name[0],o);
|
this->DeclareVariable(name[0], o);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
|
|
||||||
TObject v = this->GetVariable(name[0]);
|
TObject v = this->GetVariable(name[0]);
|
||||||
TDictionary* dict=nullptr;
|
TDictionary *dict = nullptr;
|
||||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||||
{
|
dict =
|
||||||
dict=dynamic_cast<TDictionary*>(std::get<THeapObjectHolder>(v).obj);
|
dynamic_cast<TDictionary *>(std::get<THeapObjectHolder>(v).obj);
|
||||||
if(dict == nullptr)
|
if (dict == nullptr) {
|
||||||
{
|
|
||||||
dict = TDictionary::Create(ls);
|
dict = TDictionary::Create(ls);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
this->SetVariable(name[0],dict);
|
this->SetVariable(name[0], dict);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
dict = TDictionary::Create(ls);
|
dict = TDictionary::Create(ls);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
this->DeclareVariable(name[0],dict);
|
this->DeclareVariable(name[0], dict);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t i = 1; i < name.size()-1; i++)
|
for (size_t i = 1; i < name.size() - 1; i++) {
|
||||||
{
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
auto v = dict->GetValue(name[i]);
|
auto v = dict->GetValue(name[i]);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||||
{
|
auto dict2 = dynamic_cast<TDictionary *>(
|
||||||
auto dict2=dynamic_cast<TDictionary*>(std::get<THeapObjectHolder>(v).obj);
|
std::get<THeapObjectHolder>(v).obj);
|
||||||
if(dict2 == nullptr)
|
if (dict2 == nullptr) {
|
||||||
{
|
|
||||||
dict2 = TDictionary::Create(ls);
|
dict2 = TDictionary::Create(ls);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
dict->SetValue(name[i],dict2);
|
dict->SetValue(name[i], dict2);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
dict = dict2;
|
dict = dict2;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
auto dict2 = TDictionary::Create(ls);
|
auto dict2 = TDictionary::Create(ls);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
dict->SetValue(name[i],dict2);
|
dict->SetValue(name[i], dict2);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
dict = dict2;
|
dict = dict2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
dict->SetValue(name[name.size()-1],o);
|
dict->SetValue(name[name.size() - 1], o);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject TEnvironment::LoadFile(GC* gc, TFile* file)
|
TObject TEnvironment::LoadFile(std::shared_ptr<GC> gc, TFile *file) {
|
||||||
{
|
|
||||||
file->EnsureCanRunInCrossLang();
|
file->EnsureCanRunInCrossLang();
|
||||||
for(size_t i = 0; i < file->classes.size(); i++)
|
for (size_t i = 0; i < file->classes.size(); i++) {
|
||||||
{
|
this->GetRootEnvironment()->classes.push_back(
|
||||||
this->GetRootEnvironment()->classes.push_back(std::pair<TFile*,uint32_t>(file,(uint32_t)i));
|
std::pair<TFile *, uint32_t>(file, (uint32_t)i));
|
||||||
std::vector<std::string> clsPart={"New"};
|
std::vector<std::string> clsPart = {"New"};
|
||||||
clsPart.insert(clsPart.end(),file->classes[i].name.begin(),file->classes[i].name.end());
|
clsPart.insert(clsPart.end(), file->classes[i].name.begin(),
|
||||||
|
file->classes[i].name.end());
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
std::vector<std::string> name=file->classes[i].name;
|
std::vector<std::string> name = file->classes[i].name;
|
||||||
auto rootEnv = this->GetRootEnvironment();
|
auto rootEnv = this->GetRootEnvironment();
|
||||||
this->DeclareVariable(gc, clsPart, TExternalMethod::Create(ls,"Create instance of the class",{"$$args"},[rootEnv,file,i](GCList& ls, std::vector<TObject> args)->TObject{
|
this->DeclareVariable(
|
||||||
return TClassObject::Create(ls, file,i,rootEnv,args);
|
gc, clsPart,
|
||||||
|
TExternalMethod::Create(
|
||||||
|
ls, "Create instance of the class", {"$$args"},
|
||||||
|
[rootEnv, file, i](GCList &ls,
|
||||||
|
std::vector<TObject> args) -> TObject {
|
||||||
|
return TClassObject::Create(ls, file, i, rootEnv, args);
|
||||||
}));
|
}));
|
||||||
for(auto meth : file->classes[i].entry)
|
for (auto meth : file->classes[i].entry) {
|
||||||
{
|
|
||||||
|
|
||||||
if(meth.isFunction && meth.modifier == TClassModifier::Static)
|
if (meth.isFunction && meth.modifier == TClassModifier::Static) {
|
||||||
{
|
std::vector<std::string> method = file->classes[i].name;
|
||||||
std::vector<std::string> method=file->classes[i].name;
|
|
||||||
method.push_back(meth.name);
|
method.push_back(meth.name);
|
||||||
auto clo = TClosure::Create(ls,this,file,meth.chunkId);
|
auto clo = TClosure::Create(ls, this, file, meth.chunkId);
|
||||||
clo->closure->name = JoinPeriod(method);
|
clo->closure->name = JoinPeriod(method);
|
||||||
|
|
||||||
|
|
||||||
clo->documentation = meth.documentation;
|
clo->documentation = meth.documentation;
|
||||||
this->DeclareVariable(gc, method, clo);
|
this->DeclareVariable(gc, method, clo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
for(auto fn : file->functions)
|
for (auto fn : file->functions) {
|
||||||
{
|
|
||||||
|
|
||||||
|
if (fn.first.size() < 2)
|
||||||
|
throw VMException("No function name.");
|
||||||
|
|
||||||
|
std::vector<std::string> items(fn.first.begin() + 1, fn.first.end());
|
||||||
|
|
||||||
if(fn.first.size() < 2) throw VMException("No function name.");
|
if (fn.second >= file->chunks.size())
|
||||||
|
throw VMException("ChunkId out of bounds.");
|
||||||
std::vector<std::string> items(fn.first.begin()+1, fn.first.end());
|
TFileChunk *chunk = file->chunks[fn.second];
|
||||||
|
|
||||||
if(fn.second >= file->chunks.size()) throw VMException("ChunkId out of bounds.");
|
|
||||||
TFileChunk* chunk = file->chunks[fn.second];
|
|
||||||
chunk->name = JoinPeriod(items);
|
chunk->name = JoinPeriod(items);
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TClosure* closure=TClosure::Create(ls,this,file,fn.second);
|
TClosure *closure = TClosure::Create(ls, this, file, fn.second);
|
||||||
closure->documentation = fn.first[0];
|
closure->documentation = fn.first[0];
|
||||||
this->DeclareVariable(gc,items,closure);
|
this->DeclareVariable(gc, items, closure);
|
||||||
|
|
||||||
}
|
}
|
||||||
if(!file->chunks.empty())
|
if (!file->chunks.empty()) {
|
||||||
{
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TClosure* closure=TClosure::Create(ls,this,file,0);
|
TClosure *closure = TClosure::Create(ls, this, file, 0);
|
||||||
return closure->Call(ls,{});
|
return closure->Call(ls, {});
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
void TRootEnvironment::LoadFileWithDependencies(GC* gc,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, TFile* file)
|
void TRootEnvironment::LoadFileWithDependencies(
|
||||||
{
|
std::shared_ptr<GC> gc,
|
||||||
this->dependencies.push_back(std::pair<std::string,TVMVersion>(file->name,file->version));
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, TFile *file) {
|
||||||
for(auto item : file->dependencies)
|
this->dependencies.push_back(
|
||||||
{
|
std::pair<std::string, TVMVersion>(file->name, file->version));
|
||||||
LoadDependency(gc,vfs,item);
|
for (auto item : file->dependencies) {
|
||||||
|
LoadDependency(gc, vfs, item);
|
||||||
}
|
}
|
||||||
LoadFile(gc, file);
|
LoadFile(gc, file);
|
||||||
|
}
|
||||||
|
void TRootEnvironment::LoadFileWithDependencies(
|
||||||
|
std::shared_ptr<GC> gc,
|
||||||
|
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
|
||||||
|
Tesses::Framework::Filesystem::VFSPath path) {
|
||||||
|
|
||||||
}
|
if (vfs->RegularFileExists(path)) {
|
||||||
void TRootEnvironment::LoadFileWithDependencies(GC* gc,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path)
|
auto file = vfs->OpenFile(path, "rb");
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
if(vfs->RegularFileExists(path))
|
|
||||||
{
|
|
||||||
auto file=vfs->OpenFile(path,"rb");
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
TFile* f = TFile::Create(ls);
|
TFile *f = TFile::Create(ls);
|
||||||
f->Load(gc, file);
|
f->Load(gc, file);
|
||||||
|
|
||||||
auto dir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(vfs,path.GetParent());
|
auto dir =
|
||||||
LoadFileWithDependencies(gc,dir,f);
|
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
|
||||||
}
|
vfs, path.GetParent());
|
||||||
else throw VMException("Could not open file: \"" + path.GetFileName() + "\".");
|
LoadFileWithDependencies(gc, dir, f);
|
||||||
|
} else
|
||||||
}
|
throw VMException("Could not open file: \"" + path.GetFileName() +
|
||||||
TDictionary* TRootEnvironment::GetDictionary()
|
"\".");
|
||||||
{
|
}
|
||||||
return this->dict;
|
TDictionary *TRootEnvironment::GetDictionary() { return this->dict; }
|
||||||
}
|
TObject TRootEnvironment::GetVariable(std::string key) {
|
||||||
TObject TRootEnvironment::GetVariable(std::string key)
|
|
||||||
{
|
|
||||||
return this->dict->GetValue(key);
|
return this->dict->GetValue(key);
|
||||||
}
|
}
|
||||||
void TRootEnvironment::SetVariable(std::string key, TObject value)
|
void TRootEnvironment::SetVariable(std::string key, TObject value) {
|
||||||
{
|
this->dict->SetValue(key, value);
|
||||||
this->dict->SetValue(key,value);
|
}
|
||||||
}
|
void TRootEnvironment::DeclareVariable(std::string key, TObject value) {
|
||||||
void TRootEnvironment::DeclareVariable(std::string key, TObject value)
|
return this->dict->SetValue(key, value);
|
||||||
{
|
}
|
||||||
return this->dict->SetValue(key,value);
|
bool TRootEnvironment::HasVariable(std::string key) {
|
||||||
}
|
|
||||||
bool TRootEnvironment::HasVariable(std::string key)
|
|
||||||
{
|
|
||||||
return this->dict->HasValue(key);
|
return this->dict->HasValue(key);
|
||||||
}
|
}
|
||||||
bool TRootEnvironment::HasVariableRecurse(std::string key)
|
bool TRootEnvironment::HasVariableRecurse(std::string key) {
|
||||||
{
|
|
||||||
return this->dict->HasValue(key);
|
return this->dict->HasValue(key);
|
||||||
}
|
}
|
||||||
TEnvironment* TRootEnvironment::GetParentEnvironment()
|
TEnvironment *TRootEnvironment::GetParentEnvironment() { return this; }
|
||||||
{
|
TRootEnvironment *TRootEnvironment::GetRootEnvironment() { return this; }
|
||||||
return this;
|
|
||||||
}
|
|
||||||
TRootEnvironment* TRootEnvironment::GetRootEnvironment()
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRootEnvironment::TRootEnvironment(TDictionary* dict)
|
TRootEnvironment::TRootEnvironment(TDictionary *dict) { this->dict = dict; }
|
||||||
{
|
|
||||||
this->dict = dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRootEnvironment::Mark()
|
void TRootEnvironment::Mark() {
|
||||||
{
|
if (this->marked)
|
||||||
if(this->marked) return;
|
return;
|
||||||
this->marked = true;
|
this->marked = true;
|
||||||
this->dict->Mark();
|
this->dict->Mark();
|
||||||
if(this->permissions.customConsole != nullptr) this->permissions.customConsole->Mark();
|
if (this->permissions.customConsole != nullptr)
|
||||||
for(auto defer : this->defers) defer->Mark();
|
this->permissions.customConsole->Mark();
|
||||||
if(this->error != nullptr) this->error->Mark();
|
for (auto priv : this->private_file_data)
|
||||||
for(auto cls : this->classes) cls.first->Mark();
|
priv.second->Mark();
|
||||||
}
|
for (auto defer : this->defers)
|
||||||
TRootEnvironment* TRootEnvironment::Create(GCList* gc,TDictionary* dict)
|
defer->Mark();
|
||||||
{
|
if (this->error != nullptr)
|
||||||
TRootEnvironment* env=new TRootEnvironment(dict);
|
this->error->Mark();
|
||||||
GC* _gc = gc->GetGC();
|
for (auto cls : this->classes)
|
||||||
|
cls.first->Mark();
|
||||||
|
}
|
||||||
|
TRootEnvironment *TRootEnvironment::Create(GCList *gc, TDictionary *dict) {
|
||||||
|
TRootEnvironment *env = new TRootEnvironment(dict);
|
||||||
|
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||||
gc->Add(env);
|
gc->Add(env);
|
||||||
_gc->Watch(env);
|
_gc->Watch(env);
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
TRootEnvironment* TRootEnvironment::Create(GCList& gc,TDictionary* dict)
|
TRootEnvironment *TRootEnvironment::Create(GCList &gc, TDictionary *dict) {
|
||||||
{
|
TRootEnvironment *env = new TRootEnvironment(dict);
|
||||||
TRootEnvironment* env=new TRootEnvironment(dict);
|
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||||
GC* _gc = gc.GetGC();
|
|
||||||
gc.Add(env);
|
gc.Add(env);
|
||||||
_gc->Watch(env);
|
_gc->Watch(env);
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TRootEnvironment::HandleException(GC* gc,TEnvironment* env, TObject err)
|
bool TRootEnvironment::HandleException(std::shared_ptr<GC> gc,
|
||||||
{
|
TEnvironment *env, TObject err) {
|
||||||
if(error != nullptr)
|
if (error != nullptr) {
|
||||||
{
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
return ToBool(error->Call(ls, {
|
return ToBool(error->Call(
|
||||||
TDictionary::Create(ls,{
|
ls, {TDictionary::Create(ls, {TDItem("IsBreakpoint", false),
|
||||||
TDItem("IsBreakpoint",false),
|
TDItem("Exception", err),
|
||||||
TDItem("Exception",err),
|
TDItem("Environment", env)})}));
|
||||||
TDItem("Environment", env)
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool TRootEnvironment::HandleBreakpoint(GC* gc,TEnvironment* env, TObject err)
|
bool TRootEnvironment::HandleBreakpoint(std::shared_ptr<GC> gc,
|
||||||
{
|
TEnvironment *env, TObject err) {
|
||||||
if(error != nullptr)
|
if (error != nullptr) {
|
||||||
{
|
|
||||||
GCList ls(gc);
|
GCList ls(gc);
|
||||||
return ToBool(error->Call(ls, {
|
return ToBool(error->Call(
|
||||||
TDictionary::Create(ls,{
|
ls, {TDictionary::Create(ls, {TDItem("IsBreakpoint", true),
|
||||||
TDItem("IsBreakpoint",true),
|
TDItem("Breakpoint", err),
|
||||||
TDItem("Breakpoint",err),
|
TDItem("Environment", env)})}));
|
||||||
TDItem("Environment", env)
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void TRootEnvironment::RegisterOnError(TCallable* call)
|
void TRootEnvironment::RegisterOnError(TCallable *call) { this->error = call; }
|
||||||
{
|
}; // namespace Tesses::CrossLang
|
||||||
this->error = call;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,224 +1,217 @@
|
|||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang {
|
||||||
{
|
int64_t TObjectStream::_GetPosInternal() {
|
||||||
int64_t TObjectStream::_GetPosInternal()
|
|
||||||
{
|
|
||||||
return Tesses::Framework::Streams::Stream::GetLength();
|
return Tesses::Framework::Streams::Stream::GetLength();
|
||||||
}
|
}
|
||||||
TObjectStream::TObjectStream(GC* gc, TObject obj)
|
TObjectStream::TObjectStream(std::shared_ptr<GC> gc, TObject obj) {
|
||||||
{
|
|
||||||
this->ls = new GCList(gc);
|
this->ls = new GCList(gc);
|
||||||
this->ls->Add(obj);
|
this->ls->Add(obj);
|
||||||
this->obj = obj;
|
this->obj = obj;
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(GetObjectHeap(obj,dict))
|
if (GetObjectHeap(obj, dict)) {
|
||||||
{
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
if(!dict->HasValue("Read"))
|
if (!dict->HasValue("Read")) {
|
||||||
{
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc,"Read","Read from stream",{"buff","off","len"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
gc, "Read", "Read from stream", {"buff", "off", "len"},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return (int64_t)0;
|
return (int64_t)0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(!dict->HasValue("Write"))
|
if (!dict->HasValue("Write")) {
|
||||||
{
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc,"Write","Write to stream",{"buff","off","len"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
gc, "Write", "Write to stream", {"buff", "off", "len"},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return (int64_t)0;
|
return (int64_t)0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(!dict->HasValue("getCanRead"))
|
if (!dict->HasValue("getCanRead")) {
|
||||||
{
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc,"getCanRead","Can read from stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
gc, "getCanRead", "Can read from stream", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!dict->HasValue("getCanWrite"))
|
if (!dict->HasValue("getCanWrite")) {
|
||||||
{
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc,"getCanWrite","Can write to stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
gc, "getCanWrite", "Can write to stream", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(!dict->HasValue("getCanSeek"))
|
if (!dict->HasValue("getCanSeek")) {
|
||||||
{
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc,"getCanSeek","Can seek in stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
gc, "getCanSeek", "Can seek in stream", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(!dict->HasValue("getPosition"))
|
if (!dict->HasValue("getPosition")) {
|
||||||
{
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc,"getPosition","Can get position in stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
gc, "getPosition", "Can get position in stream", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return (int64_t)0;
|
return (int64_t)0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(!dict->HasValue("getLength"))
|
if (!dict->HasValue("getLength")) {
|
||||||
{
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc,"getPosition","Can get position in stream",{}, [this](GCList& ls, std::vector<TObject> args)->TObject {
|
gc, "getPosition", "Can get position in stream", {},
|
||||||
|
[this](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return _GetPosInternal();
|
return _GetPosInternal();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(!dict->HasValue("getEndOfStream"))
|
if (!dict->HasValue("getEndOfStream")) {
|
||||||
{
|
dict->DeclareFunction(
|
||||||
dict->DeclareFunction(gc,"getEndOfStream","Is at end of stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
gc, "getEndOfStream", "Is at end of stream", {},
|
||||||
|
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool TObjectStream::EndOfStream()
|
bool TObjectStream::EndOfStream() {
|
||||||
{
|
TDictionary *dict;
|
||||||
TDictionary* dict;
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
if(GetObjectHeap(this->obj, dict))
|
auto res = dict->CallMethod(*ls, "getEndOfStream", {});
|
||||||
{
|
|
||||||
auto res = dict->CallMethod(*ls, "getEndOfStream",{});
|
|
||||||
bool r;
|
bool r;
|
||||||
if(GetObject(res,r)) return r;
|
if (GetObject(res, r))
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t TObjectStream::Read(uint8_t* buff, size_t sz)
|
size_t TObjectStream::Read(uint8_t *buff, size_t sz) {
|
||||||
{
|
TDictionary *dict;
|
||||||
TDictionary* dict;
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
if(GetObjectHeap(this->obj, dict))
|
|
||||||
{
|
|
||||||
GCList ls2(this->ls->GetGC());
|
GCList ls2(this->ls->GetGC());
|
||||||
|
|
||||||
TByteArray* arr=TByteArray::Create(ls2);
|
TByteArray *arr = TByteArray::Create(ls2);
|
||||||
arr->data.resize(sz);
|
arr->data.resize(sz);
|
||||||
|
|
||||||
auto res = dict->CallMethod(ls2, "Read",{arr, (int64_t)0L, (int64_t)sz});
|
auto res =
|
||||||
|
dict->CallMethod(ls2, "Read", {arr, (int64_t)0L, (int64_t)sz});
|
||||||
|
|
||||||
memcpy(buff,arr->data.data(),std::min(sz,arr->data.size()));
|
memcpy(buff, arr->data.data(), std::min(sz, arr->data.size()));
|
||||||
|
|
||||||
int64_t r;
|
int64_t r;
|
||||||
if(GetObject(res,r)) return r;
|
if (GetObject(res, r))
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
size_t TObjectStream::Write(const uint8_t* buff, size_t sz)
|
size_t TObjectStream::Write(const uint8_t *buff, size_t sz) {
|
||||||
{
|
TDictionary *dict;
|
||||||
TDictionary* dict;
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
if(GetObjectHeap(this->obj, dict))
|
|
||||||
{
|
|
||||||
GCList ls2(this->ls->GetGC());
|
GCList ls2(this->ls->GetGC());
|
||||||
|
|
||||||
TByteArray* arr=TByteArray::Create(ls2);
|
TByteArray *arr = TByteArray::Create(ls2);
|
||||||
arr->data.resize(sz);
|
arr->data.resize(sz);
|
||||||
memcpy(arr->data.data(), buff, sz);
|
memcpy(arr->data.data(), buff, sz);
|
||||||
|
|
||||||
auto res = dict->CallMethod(ls2, "Write",{arr, (int64_t)0L, (int64_t)sz});
|
auto res =
|
||||||
|
dict->CallMethod(ls2, "Write", {arr, (int64_t)0L, (int64_t)sz});
|
||||||
int64_t r;
|
int64_t r;
|
||||||
if(GetObject(res,r)) return r;
|
if (GetObject(res, r))
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
bool TObjectStream::CanRead()
|
bool TObjectStream::CanRead() {
|
||||||
{
|
|
||||||
|
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(GetObjectHeap(this->obj, dict))
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
{
|
auto res = dict->CallMethod(*ls, "getCanRead", {});
|
||||||
auto res = dict->CallMethod(*ls, "getCanRead",{});
|
|
||||||
bool r;
|
bool r;
|
||||||
if(GetObject(res,r)) return r;
|
if (GetObject(res, r))
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool TObjectStream::CanWrite()
|
bool TObjectStream::CanWrite() {
|
||||||
{
|
|
||||||
|
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(GetObjectHeap(this->obj, dict))
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
{
|
auto res = dict->CallMethod(*ls, "getCanWrite", {});
|
||||||
auto res = dict->CallMethod(*ls, "getCanWrite",{});
|
|
||||||
bool r;
|
bool r;
|
||||||
if(GetObject(res,r)) return r;
|
if (GetObject(res, r))
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool TObjectStream::CanSeek()
|
bool TObjectStream::CanSeek() {
|
||||||
{
|
|
||||||
|
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(GetObjectHeap(this->obj, dict))
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
{
|
auto res = dict->CallMethod(*ls, "getCanSeek", {});
|
||||||
auto res = dict->CallMethod(*ls, "getCanSeek",{});
|
|
||||||
bool r;
|
bool r;
|
||||||
if(GetObject(res,r)) return r;
|
if (GetObject(res, r))
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int64_t TObjectStream::GetPosition()
|
int64_t TObjectStream::GetPosition() {
|
||||||
{
|
|
||||||
|
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(GetObjectHeap(this->obj, dict))
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
{
|
auto res = dict->CallMethod(*ls, "getPosition", {});
|
||||||
auto res = dict->CallMethod(*ls, "getPosition",{});
|
|
||||||
int64_t r;
|
int64_t r;
|
||||||
if(GetObject(res,r)) return r;
|
if (GetObject(res, r))
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int64_t TObjectStream::GetLength()
|
int64_t TObjectStream::GetLength() {
|
||||||
{
|
|
||||||
|
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(GetObjectHeap(this->obj, dict))
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
{
|
auto res = dict->CallMethod(*ls, "getEndOfStream", {});
|
||||||
auto res = dict->CallMethod(*ls, "getEndOfStream",{});
|
|
||||||
bool r;
|
bool r;
|
||||||
if(GetObject(res,r)) return r;
|
if (GetObject(res, r))
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Tesses::Framework::Streams::Stream::GetLength();
|
return Tesses::Framework::Streams::Stream::GetLength();
|
||||||
}
|
}
|
||||||
void TObjectStream::Flush()
|
void TObjectStream::Flush() {
|
||||||
{
|
|
||||||
|
|
||||||
TDictionary* dict;
|
|
||||||
if(GetObjectHeap(this->obj, dict))
|
|
||||||
{
|
|
||||||
dict->CallMethod(*ls, "Flush",{});
|
|
||||||
|
|
||||||
|
TDictionary *dict;
|
||||||
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
|
dict->CallMethod(*ls, "Flush", {});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
void TObjectStream::Seek(int64_t pos,
|
||||||
|
Tesses::Framework::Streams::SeekOrigin whence) {
|
||||||
|
TDictionary *dict;
|
||||||
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
|
dict->CallMethod(
|
||||||
|
*ls, "Seek",
|
||||||
|
{pos,
|
||||||
|
(int64_t)(whence == Tesses::Framework::Streams::SeekOrigin::Begin
|
||||||
|
? 0
|
||||||
|
: whence ==
|
||||||
|
Tesses::Framework::Streams::SeekOrigin::Current
|
||||||
|
? 1
|
||||||
|
: 2)});
|
||||||
}
|
}
|
||||||
void TObjectStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
|
}
|
||||||
{
|
void TObjectStream::Close() {
|
||||||
TDictionary* dict;
|
TDictionary *dict;
|
||||||
if(GetObjectHeap(this->obj, dict))
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
{
|
dict->CallMethod(*ls, "Dispose", {});
|
||||||
dict->CallMethod(*ls, "Seek",{pos,(int64_t)(whence == Tesses::Framework::Streams::SeekOrigin::Begin ? 0 : whence == Tesses::Framework::Streams::SeekOrigin::Current ? 1 : 2) });
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
TObjectStream::~TObjectStream() {
|
||||||
void TObjectStream::Close()
|
TDictionary *dict;
|
||||||
{
|
if (GetObjectHeap(this->obj, dict)) {
|
||||||
TDictionary* dict;
|
dict->CallMethod(*ls, "Dispose", {});
|
||||||
if(GetObjectHeap(this->obj, dict))
|
|
||||||
{
|
|
||||||
dict->CallMethod(*ls,"Close",{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TObjectStream::~TObjectStream()
|
|
||||||
{
|
|
||||||
TDictionary* dict;
|
|
||||||
if(GetObjectHeap(this->obj, dict))
|
|
||||||
{
|
|
||||||
dict->CallMethod(*ls,"Close",{});
|
|
||||||
}
|
}
|
||||||
delete this->ls;
|
delete this->ls;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Tesses::CrossLang
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user