24 Commits

Author SHA1 Message Date
56b74dc6fc Fixed Process.ShellFileOrUrl was broken New.ShellFileOrUrl
All checks were successful
Build and Deploy on Tag / 🔨 Build for PowerPC (push) Successful in 47s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x64:latest, x86_64-linux-gnu, amd64) (push) Successful in 3m9s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-riscv64:latest, riscv64-linux-gnu, riscv64) (push) Successful in 3m9s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm:latest, arm-linux-gnueabihf, arm7) (push) Successful in 3m14s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm64:latest, aarch64-linux-gnu, arm64) (push) Successful in 3m21s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x86:latest, i386-linux-gnu, 386) (push) Successful in 56s
Build and Deploy on Tag / update-tap (push) Successful in 4m48s
2026-06-21 01:13:36 -05:00
a6be15410d Use new build setup
All checks were successful
Build and Deploy on Tag / 🔨 Build for PowerPC (push) Successful in 30s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-riscv64:latest, riscv64-linux-gnu, riscv64) (push) Successful in 3m4s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x64:latest, x86_64-linux-gnu, amd64) (push) Successful in 3m5s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm:latest, arm-linux-gnueabihf, arm7) (push) Successful in 3m13s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm64:latest, aarch64-linux-gnu, arm64) (push) Successful in 3m18s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x86:latest, i386-linux-gnu, 386) (push) Successful in 55s
Build and Deploy on Tag / update-tap (push) Successful in 4m13s
2026-06-20 01:51:52 -05:00
7aa7635ab6 Use new build setup
Some checks failed
Build and Deploy on Tag / 🔨 Build for PowerPC (push) Successful in 30s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-riscv64:latest, riscv64-linux-gnu, riscv64) (push) Successful in 3m4s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x64:latest, x86_64-linux-gnu, amd64) (push) Successful in 3m9s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm:latest, arm-linux-gnueabihf, arm7) (push) Successful in 3m18s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm64:latest, aarch64-linux-gnu, arm64) (push) Successful in 3m24s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x86:latest, i386-linux-gnu, 386) (push) Successful in 57s
Build and Deploy on Tag / update-tap (push) Has been cancelled
2026-06-20 01:34:32 -05:00
15785225e0 Use new build setup
All checks were successful
Build and Deploy on Tag / 🔨 Build for PowerPC (push) Successful in 30s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-riscv64:latest, riscv64-linux-gnu, riscv64) (push) Successful in 3m10s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x64:latest, x86_64-linux-gnu, amd64) (push) Successful in 3m12s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm:latest, arm-linux-gnueabihf, arm7) (push) Successful in 3m18s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm64:latest, aarch64-linux-gnu, arm64) (push) Successful in 3m22s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x86:latest, i386-linux-gnu, 386) (push) Successful in 55s
Build and Deploy on Tag / update-tap (push) Successful in 4m30s
2026-06-20 01:14:46 -05:00
1c3fda37f5 Use new build setup
Some checks failed
Build and Deploy on Tag / 🔨 Build for PowerPC (push) Successful in 29s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x64:latest, x86_64-linux-gnu, amd64) (push) Failing after 3m8s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-riscv64:latest, riscv64-linux-gnu, riscv64) (push) Failing after 3m9s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm:latest, arm-linux-gnueabihf, arm7) (push) Failing after 3m15s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm64:latest, aarch64-linux-gnu, arm64) (push) Failing after 3m19s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x86:latest, i386-linux-gnu, 386) (push) Failing after 54s
Build and Deploy on Tag / update-tap (push) Successful in 4m29s
2026-06-20 01:09:08 -05:00
a72ab256f2 Use new build setup
Some checks failed
Build and Deploy on Tag / 🔨 Build for PowerPC (push) Failing after 27s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x86:latest, i386-linux-gnu, 386) (push) Has been cancelled
Build and Deploy on Tag / update-tap (push) Has been cancelled
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm64:latest, aarch64-linux-gnu, arm64) (push) Has been cancelled
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm:latest, arm-linux-gnueabihf, arm7) (push) Has been cancelled
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-riscv64:latest, riscv64-linux-gnu, riscv64) (push) Has been cancelled
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x64:latest, x86_64-linux-gnu, amd64) (push) Has been cancelled
2026-06-20 01:06:44 -05:00
671a4c88b7 Use new build setup
Some checks failed
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x86:latest, i386-linux-gnu, 386) (push) Has been cancelled
Build and Deploy on Tag / update-tap (push) Has been cancelled
Build and Deploy on Tag / 🔨 Build for PowerPC (push) Has been cancelled
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-riscv64:latest, riscv64-linux-gnu, riscv64) (push) Has been cancelled
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x64:latest, x86_64-linux-gnu, amd64) (push) Has been cancelled
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm64:latest, aarch64-linux-gnu, arm64) (push) Has been cancelled
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm:latest, arm-linux-gnueabihf, arm7) (push) Has been cancelled
2026-06-20 01:03:23 -05:00
bdbdfde646 Fix a security vulerability in crossdump that is supposed to use uint32_t but accidently used uint8_t, set to tessesframework=0.0.5
All checks were successful
Build and Deploy on Tag / build-arch (push) Successful in 1m18s
Build and Deploy on Tag / update-tap (push) Successful in 4m8s
2026-06-01 06:49:08 -05:00
62e316b022 Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
All checks were successful
Build and Deploy on Tag / build-arch (push) Successful in 1m22s
Build and Deploy on Tag / update-tap (push) Successful in 4m16s
2026-05-29 21:13:21 -05:00
17e4ca9410 Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
Some checks failed
Build and Deploy on Tag / build-arch (push) Failing after 16s
Build and Deploy on Tag / update-tap (push) Has been cancelled
2026-05-29 21:04:56 -05:00
dcbc58481e Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
Some checks failed
Build and Deploy on Tag / build-arch (push) Failing after 55s
Build and Deploy on Tag / update-tap (push) Has been cancelled
2026-05-29 20:58:44 -05:00
abea319ea0 Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs 2026-05-29 20:52:26 -05:00
d26e357448 Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable
All checks were successful
Build and Deploy on Tag / update-tap (push) Successful in 7m1s
Build and Deploy on Tag / build-arch (push) Successful in 22m2s
2026-05-08 23:48:24 -05:00
2608e94192 Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable
Some checks failed
Build and Deploy on Tag / update-tap (push) Has been cancelled
Build and Deploy on Tag / build-arch (push) Has been cancelled
2026-05-08 23:24:57 -05:00
0f0e47003c Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable
Some checks failed
Build and Deploy on Tag / build-arch (push) Failing after 2m10s
Build and Deploy on Tag / update-tap (push) Has been cancelled
2026-05-08 23:14:10 -05:00
7008a6ae61 Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable 2026-05-08 23:10:20 -05:00
28eff630c6 Rework for git.tesses.org, GC* is std::shared_ptr maybe will fix crash during exit
All checks were successful
Build and Deploy on Tag / build-arch (push) Successful in 16m35s
Build and Deploy on Tag / update-tap (push) Successful in 6m21s
2026-05-01 11:28:36 -05:00
f23a3880d4 Update 2026-04-30 17:50:34 -05:00
37fd44fd78 Rework for git.tesses.org, GC* is std::shared_ptr maybe will fix crash during exit
All checks were successful
Build and Deploy on Tag / build-arch (push) Successful in 16m40s
Build and Deploy on Tag / update-tap (push) Successful in 6m26s
2026-04-30 17:05:53 -05:00
06f1aff2b4 Rework for git.tesses.org, GC* is std::shared_ptr maybe will fix crash during exit
Some checks failed
Build and Deploy on Tag / build-arch (push) Successful in 17m48s
Build and Deploy on Tag / update-tap (push) Failing after 6m19s
2026-04-30 16:30:32 -05:00
991f2a217d Rework for git.tesses.org, GC* is std::shared_ptr maybe will fix crash during exit
Some checks failed
Build and Deploy on Tag / update-tap (push) Has been cancelled
Build and Deploy on Tag / build-arch (push) Has been cancelled
2026-04-30 16:00:00 -05:00
fca18e63a6 Commit before replacing GC* with std::shared_ptr<GC> 2026-04-30 10:07:14 -05:00
63b00ebbcb Use alpine for Docker 2026-04-16 22:24:18 -05:00
7badbeb217 Use alpine for Docker 2026-04-16 22:18:53 -05:00
129 changed files with 26423 additions and 30536 deletions

321
.clang-format Normal file
View File

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

View File

@@ -5,68 +5,108 @@ on:
- 'v*' - 'v*'
env: env:
GITEA_AUTH: ${{ secrets.MY_GITEA_AUTH }} TF_VERSION: 0.0.6
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-ppc:
runs-on: arch-builder name: "🔨 Build for PowerPC"
runs-on: ubuntu-latest
container:
image: git.tesses.org/tesses50/linux-ppc:latest
steps: steps:
- 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: bash build-for-ppc.sh
- run: pacman-key --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.tesseslanguage.com]\nSigLevel = Optional TrustAll\nServer = https://git.tesseslanguage.com/api/packages/tesses50/arch/core/\$arch\n" >> /opt/cross/ppc/pacman.conf
- run: pacman --noconfirm -Sy mbedtls curl tesses-framework
- run: pacman --config /opt/cross/ppc/pacman.conf --noconfirm -Sy mbedtls tesses-framework
- run: cp Packaging/Linux/PKGBUILD /home/build/PKGBUILD
- run: cp Packaging/Linux/build-arch.sh /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/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
prerelease: true
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 build-packages:
name: "🔨 Build for everything else"
runs-on: fw13-ubuntu-latest
strategy:
fail-fast: true
matrix:
include:
- container: "git.tesses.org/tesses50/linux-x64:latest"
nfpmName: "amd64"
debianName: "x86_64-linux-gnu"
- container: "git.tesses.org/tesses50/linux-x86:latest"
nfpmName: "386"
debianName: "i386-linux-gnu"
- container: "git.tesses.org/tesses50/linux-arm:latest"
nfpmName: "arm7"
debianName: "arm-linux-gnueabihf"
- container: "git.tesses.org/tesses50/linux-arm64:latest"
nfpmName: "arm64"
debianName: "aarch64-linux-gnu"
- container: "git.tesses.org/tesses50/linux-riscv64:latest"
nfpmName: "riscv64"
debianName: "riscv64-linux-gnu"
container:
image: ${{ matrix.container }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build for plucky, resolute - run: bash build-for-nfpm.sh ${{ matrix.nfpmName }} ${{ matrix.debianName }}
run: | - uses: akkuman/gitea-release-action@v1
mkdir ../../artifacts env:
apt update -y NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
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 with:
bash build-ubuntu-plucky.sh prerelease: true
bash push-ubuntu-plucky.sh files: |-
bash build-slims.sh artifacts/**
working-directory: ./Packaging/Linux
- name: Build for windows
run: bash build.sh
working-directory: ./Packaging/Windows update-tap:
runs-on: global-container-mingw
steps:
- uses: actions/checkout@v4
- run: |
mkdir -p artifacts
env -C Packaging/Windows bash build.sh
- uses: akkuman/gitea-release-action@v1 - uses: akkuman/gitea-release-action@v1
prerelease: true
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

View File

@@ -1,57 +1,42 @@
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
cloneCredential: cloneCredential:
type: DefaultCredential type: DefaultCredential
withLfs: true withLfs: true
withSubmodules: false withSubmodules: false
condition: SUCCESSFUL condition: SUCCESSFUL
optional: false optional: false
- type: CommandStep - type: BuildImageStep
name: Execute build name: Build Docker Image
runInContainer: true dockerfile: Dockerfile
image: onedev.site.tesses.net/tesses-framework/tesses-framework:latest output:
interpreter: type: RegistryOutput
type: DefaultInterpreter tags: onedev.site.tesses.net/crosslang/crosslang:latest onedev.site.tesses.net/crosslang/crosslang:@commit_hash@
commands: | registryLogins:
mkdir build - registryUrl: "@server_url@"
cd build userName: "@job_token@"
cmake -S .. -B . -DCROSSLANG_FETCHCONTENT=OFF passwordSecret: dockersecret
make -j12 platforms: linux/amd64
make install DESTDIR=../out condition: SUCCESSFUL
useTTY: true optional: false
condition: SUCCESSFUL triggers:
optional: false - type: DependencyFinishedTrigger
- type: BuildImageStep projects: tesses-framework
name: Build Docker Image - type: BranchUpdateTrigger
dockerfile: Dockerfile.run branches: master
output: userMatch: anyone
type: RegistryOutput projects: crosslang
tags: onedev.site.tesses.net/crosslang/crosslang:latest onedev.site.tesses.net/crosslang/crosslang:@commit_hash@ projectDependencies:
registryLogins: - projectPath: tesses-framework
- registryUrl: '@server_url@' buildProvider:
userName: '@job_token@' type: LastFinishedBuild
passwordSecret: dockersecret jobName: Build for x86_64
platforms: linux/amd64 artifacts: "*"
condition: SUCCESSFUL retryCondition: never
optional: false maxRetries: 3
triggers: retryDelay: 30
- type: DependencyFinishedTrigger timeout: 14400
projects: tesses-framework
- type: BranchUpdateTrigger
branches: master
userMatch: anyone
projects: crosslang
projectDependencies:
- projectPath: tesses-framework
buildProvider:
type: LastFinishedBuild
jobName: Build for x86_64
artifacts: '*'
retryCondition: never
maxRetries: 3
retryDelay: 30
timeout: 14400

6
.vscode/launch.json vendored
View File

@@ -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",

View File

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

View File

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

View File

@@ -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"]

View File

@@ -1,2 +0,0 @@
FROM onedev.site.tesses.net/tesses-framework/tesses-framework:latest
COPY out /

View File

@@ -1,39 +0,0 @@
FROM --platform=linux/386 scratch
COPY --from=i686 . /
ENV CROSSLANG_CONTAINER=1
ENTRYPOINT ["/usr/bin/crossint"]
FROM --platform=linux/amd64 scratch
COPY --from=x86_64 . /
ENV CROSSLANG_CONTAINER=1
ENTRYPOINT ["/usr/bin/crossint"]
FROM --platform=linux/ppc scratch
COPY --from=powerpc . /
ENV CROSSLANG_CONTAINER=1
ENTRYPOINT ["/usr/bin/crossint"]
FROM --platform=linux/ppc64 scratch
COPY --from=powerpc64 . /
ENV CROSSLANG_CONTAINER=1
ENTRYPOINT ["/usr/bin/crossint"]
FROM --platform=linux/arm scratch
COPY --from=armv7a . /
ENV CROSSLANG_CONTAINER=1
ENTRYPOINT ["/usr/bin/crossint"]
FROM --platform=linux/arm64 scratch
COPY --from=aarch64 . /
ENV CROSSLANG_CONTAINER=1
ENTRYPOINT ["/usr/bin/crossint"]
FROM --platform=linux/riscv32 scratch
COPY --from=riscv32 . /
ENV CROSSLANG_CONTAINER=1
ENTRYPOINT ["/usr/bin/crossint"]
FROM --platform=linux/riscv64 scratch
COPY --from=riscv64 . /
ENV CROSSLANG_CONTAINER=1
ENTRYPOINT ["/usr/bin/crossint"]

View File

@@ -1,51 +0,0 @@
# Maintainer: Mike Nolan <tesses@tesses.net>
pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn'
pkgver=0.0.3
pkgrel=1
pkgdesc=""
arch=('x86_64' 'powerpc')
url="https://onedev.site.tesses.net/crosslang"
license=('GPLv3')
groups=()
depends=('mbedtls' 'tesses-framework=0.0.2')
makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
install=
source=('crosslang::git+https://onedev.site.tesses.net/crosslang')
noextract=()
sha256sums=('SKIP')
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
options=(!strip)
else
options=(!buildflags !strip)
fi
# Please refer to the 'USING VCS SOURCES' section of the PKGBUILD man page for
# a description of each element in the source array.
prepare() {
cd "$srcdir/${pkgname}"
}
build() {
cd "$srcdir/${pkgname}"
mkdir build
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release
else
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCROSSLANG_FETCHCONTENT=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN"
fi
cd build
make -j`nproc`
}
package() {
cd "$srcdir/${pkgname}/build"
make install DESTDIR="$pkgdir/"
}

View File

@@ -1,17 +0,0 @@
#!/bin/bash
cd /home/build
mkdir x86_64
cd x86_64
cp ../PKGBUILD .
makepkg
curl --user tesses50:$GITEA_AUTH \
--upload-file *.pkg.tar.zst \
https://git.tesseslanguage.com/api/packages/tesses50/arch/core
cd ..
mkdir powerpc
cd powerpc
cp ../PKGBUILD .
CARCH=powerpc CMAKE_TOOLCHAIN=/opt/cross/ppc/toolchain.cmake makepkg
curl --user tesses50:$GITEA_AUTH \
--upload-file *.pkg.tar.zst \
https://git.tesseslanguage.com/api/packages/tesses50/arch/core

View File

@@ -1,32 +0,0 @@
#!/bin/bash
mkdir -p ../../artifacts
mkdir -p crosslang-$TOOLCHAIN\-temp
cd crosslang-$TOOLCHAIN\-temp
export DIR="$PWD"
echo "set(CMAKE_C_COMPILER \"$DIR/$TOOLCHAIN\-cross/bin/$TOOLCHAIN\-gcc\")" > toolchain.cmake
echo "set(CMAKE_CXX_COMPILER \"$DIR/$TOOLCHAIN\-cross/bin/$TOOLCHAIN\-g++\")" >> toolchain.cmake
echo "set(CMAKE_C_FLAGS \"-static-libgcc -static-libstdc++ -static\")" >> toolchain.cmake
echo "set(CMAKE_CXX_FLAGS \"-static-libgcc -static-libstdc++ -static\")" >> toolchain.cmake
echo "set(CMAKE_EXE_LINKER_FLAGS \"-static-libgcc -static-libstdc++ -static\")" >> toolchain.cmake
#echo "set(CMAKE_SYSROOT \"$DIR/sysroot\")" >> toolchain.cmake
echo "set(CMAKE_SYSTEM_NAME Linux)" >> toolchain.cmake
echo "set(CMAKE_SYSTEM_PROCESSOR $ARCH)" >> toolchain.cmake
echo "set(CMAKE_POSITION_INDEPENDENT_CODE ON)" >> toolchain.cmake
wget https://downloads.tesses.net/cache/compilers/$TOOLCHAIN\-cross.tgz
#wget https://downloads.tesses.net/cache/libraries/source/mbedtls-3.6.3.1.tar.bz2
#wget -O tf.tar.gz "https://onedev.site.tesses.net/~downloads/projects/1/archives?revision=master&format=tgz"
tar xvzf $TOOLCHAIN\-cross.tgz
mkdir build
cd build
cmake -S ../../../../ -B . -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_FETCHCONTENT=ON -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCMAKE_TOOLCHAIN_FILE="$DIR/toolchain.cmake" -DCROSSLANG_ENABLE_SUPERSLIM=ON -DCMAKE_BUILD_TYPE=Release
make -j`nproc`
cp crosslang ../../../../artifacts/crosslang-slim-$TOOLCHAIN
mkdir -p ../../../../builds/containers/$ARCH/usr/bin
cp crosslang ../../../../builds/containers/$ARCH/usr/bin/crosslang
ln -s crosslang ../../../../builds/containers/$ARCH/usr/bin/crossint
ln -s crosslang ../../../../builds/containers/$ARCH/usr/bin/crossc
ln -s crosslang ../../../../builds/containers/$ARCH/usr/bin/crossvm
ln -s crosslang ../../../../builds/containers/$ARCH/usr/bin/crossarchivecreate
ln -s crosslang ../../../../builds/containers/$ARCH/usr/bin/crossarchiveextract
ln -s crosslang ../../../../builds/containers/$ARCH/usr/bin/crossdump
rm -rf "$DIR"

View File

@@ -1,8 +0,0 @@
ARCH="i686" TOOLCHAIN="i686-linux-musl" bash build-slim.sh
ARCH="x86_64" TOOLCHAIN="x86_64-linux-musl" bash build-slim.sh
ARCH="powerpc" TOOLCHAIN="powerpc-linux-musl" bash build-slim.sh
ARCH="powerpc64" TOOLCHAIN="powerpc64-linux-musl" bash build-slim.sh
ARCH="armv7a" TOOLCHAIN="armv7l-linux-musleabihf" bash build-slim.sh
ARCH="aarch64" TOOLCHAIN="aarch64-linux-musl" bash build-slim.sh
ARCH="riscv32" TOOLCHAIN="riscv32-linux-musl" bash build-slim.sh
ARCH="riscv64" TOOLCHAIN="riscv64-linux-musl" bash build-slim.sh

View File

@@ -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 -DCMAKE_BUILD_TYPE=Release
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 -DCMAKE_RELEASE_TYPE=Release
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

View File

@@ -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 -DCMAKE_BUILD_TYPE=Release
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 -DCMAKE_BUILD_TYPE=Release
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

View File

@@ -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 -DCMAKE_BUILD_TYPE=Release
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 -DCMAKE_BUILD_TYPE=Release
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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -1,2 +0,0 @@
export DEB_VERSION=0.0.3

34
Packaging/Slim/build.sh Normal file
View 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

View File

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

19
Packaging/edit-formula.sh Normal file
View 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"

View File

@@ -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)
``` ```

View File

@@ -1,280 +0,0 @@
var cpus = [
{
uname = "ppc",
name = "powerpc",
compiler = "powerpc-linux-musl-cross",
cc = "powerpc-linux-musl-gcc",
cxx = "powerpc-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "ppc64",
name = "powerpc64",
compiler = "powerpc64-linux-musl-cross",
cc = "powerpc64-linux-musl-gcc",
cxx = "powerpc64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "x86_64",
name = "x86_64",
compiler = "x86_64-linux-musl-cross",
cc = "x86_64-linux-musl-gcc",
cxx = "x86_64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname="i686",
name = "i686",
compiler = "i686-linux-musl-cross",
cc = "i686-linux-musl-gcc",
cxx = "i686-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "aarch64",
name = "aarch64",
compiler = "aarch64-linux-musl-cross",
cc = "aarch64-linux-musl-gcc",
cxx = "aarch64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "arm",
name = "arm",
compiler = "arm-linux-musleabi-cross",
cc = "arm-linux-musleabi-gcc",
cxx = "arm-linux-musleabi-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "armv7l",
name = "armv7l",
compiler = "arm-linux-musleabihf-cross",
cc = "arm-linux-musleabihf-gcc",
cxx = "arm-linux-musleabihf-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "mips",
name = "mips",
compiler = "mips-linux-musl-cross",
cc = "mips-linux-musl-gcc",
cxx = "mips-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "mips64",
name = "mips64",
compiler = "mips64-linux-musl-cross",
cc = "mips64-linux-musl-gcc",
cxx = "mips64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "riscv32",
name = "riscv32",
compiler = "riscv32-linux-musl-cross",
cc = "riscv32-linux-musl-gcc",
cxx = "riscv32-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
},
{
uname = "riscv64",
name = "riscv64",
compiler = "riscv64-linux-musl-cross",
cc = "riscv64-linux-musl-gcc",
cxx = "riscv64-linux-musl-g++",
flags = "-static-libgcc -static-libstdc++ -static"
}
];
var mbedversion="mbedtls-2.28.9";
func main(args)
{
var working = FS.CurrentPath / "Working";
FS.Local.CreateDirectory(working / "Toolchains");
FS.Local.CreateDirectory(working / "CMakeToolchains");
FS.Local.CreateDirectory(working / "Source");
FS.Local.CreateDirectory(working / "DvdFiles" / "Linux");
FS.Local.CreateDirectory(working / "DvdFiles" / "Common");
FS.Local.CreateDirectory(working / "Output");
var install = "#!/bin/bash
export CPU=`uname -m`
";
var file = $"cd {working / \"Source\"}
if [ ! -d \"{mbedversion}\" ]; then
wget -O ../DvdFiles/crosslang-license.txt https://downloads.tesses.net/gpl-3.0.txt
cp ../DvdFiles/crosslang-license.txt ../Output/crosslang-license.txt
wget -O {mbedversion}.tar.bz2 https://downloads.tesses.net/cache/libraries/source/{mbedversion}.tar.bz2
tar xf {mbedversion}.tar.bz2
rm {mbedversion}.tar.bz2
fi
git clone --depth=1 https://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>"
);
}

41
build-for-nfpm.sh Normal file
View File

@@ -0,0 +1,41 @@
if [ $# -lt 2 ]
then
echo "Not enough args, pass nfpm arch and debian tripple as argument"
echo "This script requires our docker container: git.tesses.org/tesses50/linux-*:latest"
else
curl https://git.tesses.org/tesses50/tessesframework/releases/download/v$TF_VERSION/tessesframework-v$TF_VERSION-$1.tar.gz | tar xz -C /opt/cross/staging
mkdir -p build
cd build
cmake-cross -S .. -B . -DCROSSLANG_NFPM_ARCH=$1 -DCMAKE_INSTALL_LIBDIR=lib/$2 -DCMAKE_BUILD_TYPE=Release -DCROSSLANG_FETCHCONTENT=OFF -DCROSSLANG_TF_VERSION=$TF_VERSION
make -j`nproc`
make install DESTDIR=debian
cd debian
nfpm package -f ../nfpm.yaml -p deb
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.deb \
https://git.tesses.org/api/packages/tesses50/debian/pool/universal/main/upload
#debian/pool/bionic
cd ..
if [ "$1" = "386" ] || [ "$1" = "arm7" ]
then
cmake-cross -S .. -B . -DCROSSLANG_NFPM_ARCH=$1 -DCMAKE_INSTALL_LIBDIR=lib32
else
cmake-cross -S .. -B . -DCROSSLANG_NFPM_ARCH=$1 -DCMAKE_INSTALL_LIBDIR=lib64
fi
make install DESTDIR=fedora
cd fedora
nfpm package -f ../nfpm.yaml -p rpm
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.rpm \
https://git.tesses.org/api/packages/tesses50/rpm/upload
cd ..
cmake-cross -S .. -B . -DCROSSLANG_NFPM_ARCH=$1 -DCMAKE_INSTALL_LIBDIR=lib
make install DESTDIR=arch
cd arch
nfpm package -f ../nfpm.yaml -p archlinux
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.pkg.tar.zst \
https://git.tesses.org/api/packages/tesses50/arch/core
mkdir -p ../../artifacts
tar czf ../../artifacts/crosslang-$VERSION\-$1\.tar.gz --owner=1000 --group=1000 -C usr/ . -C /opt/cross/staging/ .
fi

21
build-for-ppc.sh Normal file
View File

@@ -0,0 +1,21 @@
curl https://git.tesses.org/tesses50/tessesframework/releases/download/v$TF_VERSION/tessesframework-v$TF_VERSION-powerpc.tar.gz | tar xz -C /opt/cross/staging
mkdir -p build
pushd build
cmake-cross -S .. -B . -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release -DCROSSLANG_FETCHCONTENT=OFF -DCROSSLANG_TF_VERSION=$TF_VERSION
make -j`nproc`
mkdir -p /home/build/cl
chown build:build -R /home/build
make install DESTDIR=/home/build/cl/src
cp ppc-pkgbuild /home/build/cl/PKGBUILD
chmod 644 /home/build/cl/PKGBUILD
chown build:build -R /home/build/cl
pushd /home/build/cl
su build -c 'CARCH=powerpc makepkg -d'
curl --user tesses50:$PACKAGE_AND_BREW \
--upload-file *.pkg.tar.zst \
https://git.tesses.org/api/packages/tesses50/arch/core
popd
popd
mkdir -p artifacts
tar czf artifacts/crosslang-$VERSION\-powerpc.tar.gz --owner=1000 --group=1000 -C /home/build/cl/src/usr . -C /opt/cross/staging/ .

View File

@@ -1,5 +1,23 @@
# Changelog # Changelog
## 0.0.9
Fixed Process.ShellFileOrUrl was broken New.ShellFileOrUrl
## 0.0.8
Use new build setup
## 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 ## 0.0.3
Fixed cmake, unnecessary itteration on dictionary, and a crosslang binary bug when shell is not installed Fixed cmake, unnecessary itteration on dictionary, and a crosslang binary bug when shell is not installed

25
cmake/app.cmake Normal file
View File

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

38
cmake/cpack.cmake Normal file
View File

@@ -0,0 +1,38 @@
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 Menu.lnk' '$INSTDIR\\\\bin\\\\crosslang.exe' 'interactive'")
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\CrossLang Menu.lnk' '$INSTDIR\\\\bin\\\\crosslang.exe' 'interactive'")
include(CPack)

View File

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

14
cmake/findtf.cmake Normal file
View File

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

38
cmake/helpers.cmake Normal file
View File

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

View File

@@ -1,34 +1,28 @@
if(CROSSLANG_INSTALL_DEVELOPMENT) if(CROSSLANG_INSTALL_DEVELOPMENT)
install(TARGETS ${TessesCrossLangLibs} install(TARGETS ${CrossLangLibs}
EXPORT TessesCrossLangTargets EXPORT CrossLangTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
) )
install(FILES include/CrossLang.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/CrossLang.hpp" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/CrossLangVersion.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(EXPORT TessesCrossLangTargets
install(EXPORT CrossLangTargets
FILE TessesCrossLangTargets.cmake FILE TessesCrossLangTargets.cmake
NAMESPACE TessesCrossLang:: NAMESPACE TessesCrossLang::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang
) )
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake" configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang) INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake" install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TessesCrossLangConfig.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang) DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesCrossLang)
else()
if(CROSSLANG_ENABLE_SHARED)
install(TARGETS crosslang_shared
EXPORT TessesCrossLangTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif() endif()
endif()

View File

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

View File

@@ -1,18 +1,9 @@
option(CROSSLANG_ENABLE_STATIC "Enable Tesses CrossLang static libraries" ON)
option(CROSSLANG_ENABLE_SHARED "Enable Tesses CrossLang shared libraries" ON)
option(CROSSLANG_ENABLE_BINARIES "Enable Tesses CrossLang binaries" ON) option(CROSSLANG_ENABLE_BINARIES "Enable Tesses CrossLang binaries" ON)
option(CROSSLANG_INSTALL_DEVELOPMENT "Enable Tesses CrossLang development files" ON) option(CROSSLANG_INSTALL_DEVELOPMENT "Enable Tesses CrossLang development files" ON)
option(CROSSLANG_ENABLE_THREADING "Enable Tesses CrossLang threading" ON)
option(CROSSLANG_ENABLE_TERMIOS "Enable termios (For changing terminal options)" ON)
option(CROSSLANG_SHARED_EXECUTABLES "Link with libcrosslang_shared" ON)
option(CROSSLANG_FETCHCONTENT "Use fetchcontent" ON) option(CROSSLANG_FETCHCONTENT "Use fetchcontent" ON)
option(CROSSLANG_ENABLE_CONFIG_ENVVAR "Allow setting config directory via the environment variable CROSSLANG_CONFIG" ON)
option(CROSSLANG_ENABLE_FFI "Enable libffi" OFF) option(CROSSLANG_ENABLE_FFI "Enable libffi" OFF)
option(CROSSLANG_ENABLE_RPATH "Enable RPATH" ON) option(CROSSLANG_ENABLE_RPATH "Enable RPATH" ON)
option(CROSSLANG_ENABLE_SUPERSLIM "Enable crosslang superslim, one binary" OFF)
option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF) option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF)
option(CROSSLANG_STATIC "Build with static libraries instead of shared" OFF)
option(CROSSLANG_NFPM_ARCH "Architecture for NFPM" "")
option(CROSSLANG_TF_VERSION "TessesFramework Version for nfpm and pkgbuild" "")
set(CROSSLANG_OFFLINE_SHELL_PACKAGE "" CACHE FILEPATH "Path to the shell package generated from https://onedev.site.tesses.net/CrossLang/CrossLangExtras")

View File

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

20
cmake/sharedlib.cmake Normal file
View File

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

View File

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

View File

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

View File

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

6
cmake/staticlib.cmake Normal file
View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

183
nfpm.yaml.in Normal file
View File

@@ -0,0 +1,183 @@
# Name. (required)
name: crosslang
# Architecture. (required)
# This will expand any env var you set in the field, e.g. arch: ${GOARCH}
# The architecture is specified using Go nomenclature (GOARCH) and translated
# to the platform specific equivalent. In order to manually set the architecture
# to a platform specific value, set `{format}.arch`.
# Examples: `all`, `amd64`, `386`, `arm5`, `arm6`, `arm7`, `arm64`, `mips`,
# `mipsle`, `mips64le`, `ppc64le`, `s390`, `riscv64`
arch: @CROSSLANG_NFPM_ARCH@
# Platform.
# This will expand any env var you set in the field, e.g. platform: ${GOOS}
# This is only used by the rpm and deb packagers.
# Examples: `linux` (default), `darwin`
platform: linux
# Version. (required)
# This will expand any env var you set in the field, e.g. version: ${SEMVER}
# Some package managers, like deb, require the version to start with a digit.
# Hence, you should not prefix the version with 'v'.
version: @CROSSLANG_MAJOR_VERSION@.@CROSSLANG_MINOR_VERSION@.@CROSSLANG_PATCH_VERSION@
# Version Schema allows you to specify how to parse the version string.
# Default is `semver`
# `semver` attempt to parse the version string as a valid semver version.
# The parser is lenient; it will strip a `v` prefix and will accept
# versions with fewer than 3 components, like `v1.2`.
# If parsing succeeds, then the version will be molded into a format
# compatible with the specific packager used.
# If parsing fails, then the version is used as-is.
# `none` skip trying to parse the version string and just use what is passed in
version_schema: semver
# Version Epoch.
# A package with a higher version epoch will always be considered newer.
# See: https://www.debian.org/doc/debian-policy/ch-controlfields.html#epochs-should-be-used-sparingly
#epoch: 1
# Version Prerelease.
# Default is extracted from `version` if it is semver compatible.
# This is appended to the `version`, e.g. `1.2.3+beta1`. If the `version` is
# semver compatible, then this replaces the prerelease component of the semver.
#prerelease: alpha
# Version Metadata (previously deb.metadata).
# Default is extracted from `version` if it is semver compatible.
# Setting metadata might interfere with version comparisons depending on the
# packager. If the `version` is semver compatible, then this replaces the
# version metadata component of the semver.
# version_metadata: git
# Version Release, aka revision.
# This will expand any env var you set in the field, e.g. release: ${VERSION_RELEASE}
# This is appended to the `version` after `prerelease`. This should be
# incremented if you release an updated package of the same upstream version,
# and it should reset to 1 when bumping the version.
release: 1
# Section.
# This is only used by the deb packager.
# See: https://www.debian.org/doc/debian-policy/ch-archive.html#sections
section: default
# Priority.
# Defaults to `optional` on deb
# Defaults to empty on rpm and apk
# See: https://www.debian.org/doc/debian-policy/ch-archive.html#priorities
priority: extra
# Maintainer. (required)
# This will expand any env var you set in the field, e.g. maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>
# Defaults to empty on rpm and apk
# Leaving the 'maintainer' field unset will not be allowed in a future version
maintainer: Mike Nolan <tesses@tesses.net>
# Description.
# This will expand any env var you set in the field, e.g. description: ${DESCRIPTION}
# Defaults to `no description given`.
# Most packagers call for a one-line synopsis of the package. Some (like deb)
# also call for a multi-line description starting on the second line.
description: TessesFramework a library to make C++ easier for me, used in CrossLang
# Vendor.
# This will expand any env var you set in the field, e.g. vendor: ${VENDOR}
# This is only used by the rpm packager.
vendor: Tesses
# Package's homepage.
# This will expand any env var you set in the field, e.g. homepage: ${CI_PROJECT_URL}
homepage: https://git.tesses.org/tesses50/crosslang
# License.
license: GPLv3
# Date to be used as mtime on internal files.
#
# Default is the value of $SOURCE_DATE_EPOCH (which should be an Unix time),
# or the current time.
# Read more about SOURCE_DATE_EPOCH at https://reproducible-builds.org/docs/source-date-epoch/
#mtime: "2009-11-10T23:00:00Z"
# Changelog YAML file, see: https://github.com/goreleaser/chglog
# changelog: "changelog.yaml"
# Disables globbing for files, config_files, etc.
# disable_globbing: false
# Packages it replaces. (overridable)
# This will expand any env var you set in the field, e.g. ${REPLACE_BLA}
# the env var approach can be used to account for differences in platforms
#replaces:
# - foobar
# - ${REPLACE_BLA}
# Packages it provides. (overridable)
# This will expand any env var you set in the field, e.g. ${PROVIDES_BLA}
# the env var approach can be used to account for differences in platforms
#provides:
# - bar
# - ${PROVIDES_BLA}
# Dependencies. (overridable)
# This will expand any env var you set in the field, e.g. ${DEPENDS_NGINX}
# the env var approach can be used to account for differences in platforms
# e.g. rhel needs nginx >= 1:1.18 and deb needs nginx (>= 1.18.0)
#depends:
# - git
# - ${DEPENDS_NGINX}
# Recommended packages. (overridable)
# This will expand any env var you set in the field, e.g. ${RECOMMENDS_BLA}
# the env var approach can be used to account for differences in platforms
#recommends:
# - golang
# - ${RECOMMENDS_BLA}
# Suggested packages. (overridable)
# This will expand any env var you set in the field, e.g. ${SUGGESTS_BLA}
# the env var approach can be used to account for differences in platforms
#suggests:
# - bzr
# Packages it conflicts with. (overridable)
# This will expand any env var you set in the field, e.g. ${CONFLICTS_BLA}
# the env var approach can be used to account for differences in platforms
#conflicts:
# - mercurial
# - ${CONFLICTS_BLA}
# Contents to add to the package
# This can be binaries or any other files.
contents:
- src: usr/
dst: /usr/
type: tree
# Umask to be used on files without explicit mode set.
#
# By default, nFPM will inherit the mode of the original file that's being
# added.
# This may lead to issues if these files are checkout out in Git, for example,
# as it won't keep all the permissions on fresh checkouts, or if the local
# system has a problematic umask setting.
#
# This setting allows to set the umask for all files that are added to the
# package without a specific file_info.mode set.
#
# Default: 0o002 (will remove world-writable permissions)
umask: 0o002
overrides:
deb:
depends:
- "tessesframework (= @CROSSLANG_TF_VERSION@-1)"
rpm:
depends:
- "tessesframework = @CROSSLANG_TF_VERSION@-1"
archlinux:
depends:
- "tessesframework=@CROSSLANG_TF_VERSION@-1"

View File

@@ -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()

View File

@@ -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

View File

@@ -1,13 +0,0 @@
prefix=@CMAKE_INSTALL_PREFIX@
includedir=@PKGCONFIG_INCLUDEDIR@
libdir=@PKGCONFIG_LIBDIR@
Name: @PROJECT_NAME@
Description: @PKGCONFIG_PROJECT_DESCRIPTION@
URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
@PKGCONFIG_DEPS@
Cflags: -I"${includedir}"
Libs: -L"${libdir}" -lcrosslang_static

21
ppc-pkgbuild.in Normal file
View File

@@ -0,0 +1,21 @@
# Maintainer: Mike Nolan <tesses@tesses.net>
pkgname=crosslang # '-bzr', '-git', '-hg' or '-svn'
pkgver=@CROSSLANG_MAJOR_VERSION@.@CROSSLANG_MINOR_VERSION@.@CROSSLANG_PATCH_VERSION@
pkgrel=1
pkgdesc=""
arch=('powerpc')
url="https://git.tesses.org/tesses50/crosslang"
license=('GPLv3')
groups=()
depends=('tessesframework=@CROSSLANG_TF_VERSION@-1')
makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
install=
source=()
noextract=()
sha256sums=()
options=(!buildflags !strip)
package() {
cp -r "${srcdir}/"* "${pkgdir}/"
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -2,10 +2,10 @@
#if defined(CROSSLANG_ENABLE_JSON) #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,89 +61,79 @@ 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;
} }
return json_null(); return json_null();
} }
#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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -1,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;
}

View File

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

View File

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

View File

@@ -1,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->Add(o);
this->ls = new GCList(gc); this->o = o;
this->ls->Add(o); }
this->o = o; TObject &SharedPtrTObject::GetObject() { return this->o; }
} SharedPtrTObject::~SharedPtrTObject() {
TObject& SharedPtrTObject::GetObject() if (this->ls)
{
return this->o;
}
SharedPtrTObject::~SharedPtrTObject()
{
if(this->ls)
delete this->ls; delete this->ls;
} }
GC* SharedPtrTObject::GetGC() std::shared_ptr<GC> SharedPtrTObject::GetGC() { return this->ls->GetGC(); }
{ MarkedTObject CreateMarkedTObject(std::shared_ptr<GC> gc, TObject o) {
return this->ls->GetGC(); return std::make_shared<SharedPtrTObject>(gc, o);
} }
MarkedTObject CreateMarkedTObject(GC* gc, TObject o)
{ MarkedTObject CreateMarkedTObject(GCList *gc, TObject o) {
return std::make_shared<SharedPtrTObject>(gc,o); return CreateMarkedTObject(gc->GetGC(), o);
} }
MarkedTObject CreateMarkedTObject(GC& gc, TObject o) MarkedTObject CreateMarkedTObject(GCList &gc, TObject o) {
{ return CreateMarkedTObject(gc.GetGC(), o);
return CreateMarkedTObject(&gc,o); }
} } // namespace Tesses::CrossLang
MarkedTObject CreateMarkedTObject(GCList* gc, TObject o)
{
return CreateMarkedTObject(gc->GetGC(),o);
}
MarkedTObject CreateMarkedTObject(GCList& gc, TObject o)
{
return CreateMarkedTObject(gc.GetGC(),o);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,61 +1,58 @@
#include "CrossLang.hpp" #include "CrossLang.hpp"
using namespace Tesses::Framework; using namespace Tesses::Framework;
namespace Tesses::CrossLang::Programs { namespace Tesses::CrossLang::Programs {
TObject CrossLangVM(GCList& ls,TRootEnvironment* env, std::vector<std::string>& argv) TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
{ std::vector<std::string> &argv) {
if(argv.size() < 2) if (argv.size() < 2) {
{ std::cout << "USAGE: "
std::cout << "USAGE: " << (argv.empty() ? (std::string)"crossvm" : argv[0]) << " <filename.crvm> <args...>" << std::endl; << (argv.empty() ? (std::string) "crossvm" : argv[0])
return 1; << " <filename.crvm> <args...>" << std::endl;
} return (int64_t)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});
}
} }
}
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 (int64_t)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 (int64_t)0;
} else {
TList *args = TList::Create(ls);
for (size_t arg = 1; arg < argv.size(); arg++)
args->Add(std::string(argv[arg]));
return env->CallFunctionWithFatalError(ls, "main", {args});
}
}
} // namespace Tesses::CrossLang::Programs

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,29 +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);
std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
args[i] = argv[i];
auto res = Programs::CrossLangInterperter(ls, env, args);
int64_t myi64;
if(GetObject(res,myi64))
return (int)myi64;
return 0;
}

View File

@@ -1,29 +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);
std::vector<std::string> args(argc);
for(int i = 0; i < argc; i++)
args[i] = argv[i];
auto res = Programs::CrossLangVM(ls, env, args);
int64_t myi64;
if(GetObject(res,myi64))
return (int)myi64;
return 0;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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