From 2dc8a57a94aa60dc4a3c187d33669ebf21136567 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:30:03 +0100 Subject: [PATCH] Remove abandoned javatools_backend and Makefile The javatools_backend was an abandoned experiment to compile XTC into Java source. It had no dependencies from the rest of the project and contained no reusable assets. The Makefile was a parallel build system to Gradle used primarily for the backend workflow, with no remaining unique functionality. --- Makefile | 449 ------ javatools_backend/bin/makedepends.sh | 5 - .../src/main/java/org/xvm/XEC.java | 150 -- .../src/main/java/org/xvm/notes.txt | 152 -- .../main/java/org/xvm/util/AbstractEntry.java | 47 - .../src/main/java/org/xvm/util/Ary.java | 350 ---- .../src/main/java/org/xvm/util/AryInt.java | 186 --- .../org/xvm/util/ConcurrentAutoTable.java | 212 --- .../java/org/xvm/util/NonBlockingHashMap.java | 1429 ----------------- .../org/xvm/util/NonBlockingHashMapLong.java | 1355 ---------------- .../src/main/java/org/xvm/util/S.java | 49 - .../src/main/java/org/xvm/util/SB.java | 107 -- .../src/main/java/org/xvm/util/TLS.java | 23 - .../main/java/org/xvm/util/UtilUnsafe.java | 38 - .../src/main/java/org/xvm/util/VBitSet.java | 10 - .../src/main/java/org/xvm/xec/Fun.java | 8 - .../src/main/java/org/xvm/xec/XRunClz.java | 11 - .../src/main/java/org/xvm/xec/XTC.java | 160 -- .../org/xvm/xec/ecstasy/AbstractRange.java | 69 - .../java/org/xvm/xec/ecstasy/Appender.java | 7 - .../org/xvm/xec/ecstasy/Appenderchar.java | 11 - .../java/org/xvm/xec/ecstasy/Boolean.java | 16 - .../java/org/xvm/xec/ecstasy/Comparable.java | 66 - .../main/java/org/xvm/xec/ecstasy/Const.java | 98 -- .../main/java/org/xvm/xec/ecstasy/Enum.java | 67 - .../java/org/xvm/xec/ecstasy/Freezable.java | 5 - .../java/org/xvm/xec/ecstasy/Iterable.java | 15 - .../java/org/xvm/xec/ecstasy/Iterator.java | 23 - .../main/java/org/xvm/xec/ecstasy/Object.java | 20 - .../java/org/xvm/xec/ecstasy/Orderable.java | 117 -- .../java/org/xvm/xec/ecstasy/Ordered.java | 12 - .../java/org/xvm/xec/ecstasy/RangeEE.java | 7 - .../java/org/xvm/xec/ecstasy/RangeEI.java | 7 - .../java/org/xvm/xec/ecstasy/RangeIE.java | 7 - .../java/org/xvm/xec/ecstasy/RangeII.java | 7 - .../java/org/xvm/xec/ecstasy/Sequential.java | 5 - .../java/org/xvm/xec/ecstasy/Service.java | 224 --- .../xvm/xec/ecstasy/annotations/Future.java | 25 - .../xvm/xec/ecstasy/collections/Array.java | 118 -- .../xec/ecstasy/collections/AryString.java | 164 -- .../xvm/xec/ecstasy/collections/AryUInt8.java | 115 -- .../xvm/xec/ecstasy/collections/AryXTC.java | 124 -- .../xec/ecstasy/collections/Aryboolean.java | 136 -- .../xvm/xec/ecstasy/collections/Arychar.java | 129 -- .../xvm/xec/ecstasy/collections/Aryint.java | 166 -- .../xvm/xec/ecstasy/collections/Arylong.java | 161 -- .../xvm/xec/ecstasy/collections/Hashable.java | 59 - .../org/xvm/xec/ecstasy/collections/Map.java | 51 - .../xvm/xec/ecstasy/collections/Tuple.java | 146 -- .../xvm/xec/ecstasy/collections/Tuple0.java | 125 -- .../xvm/xec/ecstasy/collections/Tuple1.java | 11 - .../xvm/xec/ecstasy/collections/Tuple2.java | 11 - .../xvm/xec/ecstasy/collections/Tuple3.java | 11 - .../xvm/xec/ecstasy/collections/Tuple4.java | 11 - .../xvm/xec/ecstasy/collections/TupleN.java | 13 - .../java/org/xvm/xec/ecstasy/io/Console.java | 44 - .../xec/ecstasy/numbers/BinaryFPNumber.java | 8 - .../java/org/xvm/xec/ecstasy/numbers/Bit.java | 28 - .../org/xvm/xec/ecstasy/numbers/Dec128.java | 20 - .../org/xvm/xec/ecstasy/numbers/Dec64.java | 90 -- .../xec/ecstasy/numbers/DecimalFPNumber.java | 22 - .../xvm/xec/ecstasy/numbers/FPLiteral.java | 23 - .../org/xvm/xec/ecstasy/numbers/FPNumber.java | 22 - .../org/xvm/xec/ecstasy/numbers/Float128.java | 11 - .../org/xvm/xec/ecstasy/numbers/Float32.java | 13 - .../org/xvm/xec/ecstasy/numbers/Float64.java | 15 - .../org/xvm/xec/ecstasy/numbers/Int128.java | 104 -- .../org/xvm/xec/ecstasy/numbers/Int32.java | 50 - .../org/xvm/xec/ecstasy/numbers/Int64.java | 57 - .../xec/ecstasy/numbers/IntConvertible.java | 5 - .../xvm/xec/ecstasy/numbers/IntLiteral.java | 23 - .../org/xvm/xec/ecstasy/numbers/IntN.java | 27 - .../xvm/xec/ecstasy/numbers/IntNumber.java | 22 - .../org/xvm/xec/ecstasy/numbers/Number.java | 45 - .../org/xvm/xec/ecstasy/numbers/UInt128.java | 27 - .../org/xvm/xec/ecstasy/numbers/UInt16.java | 41 - .../org/xvm/xec/ecstasy/numbers/UInt32.java | 41 - .../org/xvm/xec/ecstasy/numbers/UInt64.java | 41 - .../org/xvm/xec/ecstasy/numbers/UInt8.java | 40 - .../org/xvm/xec/ecstasy/numbers/UIntN.java | 27 - .../xvm/xec/ecstasy/numbers/UIntNumber.java | 19 - .../org/xvm/xec/ecstasy/reflect/Argument.java | 13 - .../java/org/xvm/xec/ecstasy/reflect/Ref.java | 4 - .../org/xvm/xec/ecstasy/reflect/Type.java | 15 - .../java/org/xvm/xec/ecstasy/text/Char.java | 58 - .../java/org/xvm/xec/ecstasy/text/String.java | 98 -- .../xvm/xec/ecstasy/text/StringBuffer.java | 39 - .../org/xvm/xec/ecstasy/text/Stringable.java | 6 - .../src/main/java/org/xvm/xrun/Container.java | 53 - .../main/java/org/xvm/xrun/MainContainer.java | 10 - .../main/java/org/xvm/xrun/NativeConsole.java | 6 - .../java/org/xvm/xrun/NativeContainer.java | 21 - .../main/java/org/xvm/xrun/NativeTimer.java | 140 -- .../src/main/java/org/xvm/xrun/Never.java | 3 - .../src/main/java/org/xvm/xrun/XExpr.java | 5 - .../src/main/java/org/xvm/xrun/XRuntime.java | 89 - .../src/main/java/org/xvm/xtc/CPool.java | 283 ---- .../src/main/java/org/xvm/xtc/ClassPart.java | 180 --- .../src/main/java/org/xvm/xtc/ClzBldSet.java | 72 - .../src/main/java/org/xvm/xtc/ClzBuilder.java | 873 ---------- .../src/main/java/org/xvm/xtc/Contrib.java | 83 - .../src/main/java/org/xvm/xtc/FilePart.java | 94 -- .../src/main/java/org/xvm/xtc/JavaC.java | 239 --- .../main/java/org/xvm/xtc/MMethodPart.java | 66 - .../src/main/java/org/xvm/xtc/MethodPart.java | 205 --- .../src/main/java/org/xvm/xtc/ModPart.java | 115 -- .../main/java/org/xvm/xtc/PackagePart.java | 13 - .../src/main/java/org/xvm/xtc/Parameter.java | 50 - .../src/main/java/org/xvm/xtc/ParmPart.java | 19 - .../src/main/java/org/xvm/xtc/Part.java | 308 ---- .../main/java/org/xvm/xtc/PropBuilder.java | 205 --- .../src/main/java/org/xvm/xtc/PropPart.java | 63 - .../src/main/java/org/xvm/xtc/RelPart.java | 51 - .../src/main/java/org/xvm/xtc/TDefPart.java | 23 - .../src/main/java/org/xvm/xtc/VerTree.java | 10 - .../src/main/java/org/xvm/xtc/Version.java | 73 - .../src/main/java/org/xvm/xtc/XBase.java | 45 - .../src/main/java/org/xvm/xtc/XClz.java | 895 ----------- .../src/main/java/org/xvm/xtc/XCons.java | 308 ---- .../src/main/java/org/xvm/xtc/XFun.java | 208 --- .../src/main/java/org/xvm/xtc/XInter.java | 40 - .../src/main/java/org/xvm/xtc/XType.java | 412 ----- .../src/main/java/org/xvm/xtc/XValue.java | 242 --- .../src/main/java/org/xvm/xtc/ast/AST.java | 261 --- .../main/java/org/xvm/xtc/ast/AssertAST.java | 37 - .../main/java/org/xvm/xtc/ast/AssignAST.java | 258 --- .../main/java/org/xvm/xtc/ast/BinOpAST.java | 201 --- .../java/org/xvm/xtc/ast/BindFuncAST.java | 164 -- .../java/org/xvm/xtc/ast/BindMethAST.java | 28 - .../main/java/org/xvm/xtc/ast/BlockAST.java | 108 -- .../main/java/org/xvm/xtc/ast/BreakAST.java | 15 - .../main/java/org/xvm/xtc/ast/CallAST.java | 180 --- .../java/org/xvm/xtc/ast/CmpChainAST.java | 84 - .../src/main/java/org/xvm/xtc/ast/ConAST.java | 66 - .../java/org/xvm/xtc/ast/ContinueAST.java | 35 - .../main/java/org/xvm/xtc/ast/ConvAST.java | 62 - .../main/java/org/xvm/xtc/ast/DefRegAST.java | 53 - .../main/java/org/xvm/xtc/ast/DivRemAST.java | 54 - .../main/java/org/xvm/xtc/ast/DoWhileAST.java | 34 - .../main/java/org/xvm/xtc/ast/ElvisAST.java | 93 -- .../main/java/org/xvm/xtc/ast/ExprAST.java | 51 - .../src/main/java/org/xvm/xtc/ast/ForAST.java | 60 - .../java/org/xvm/xtc/ast/ForIterStmtAST.java | 39 - .../java/org/xvm/xtc/ast/ForRangeAST.java | 65 - .../main/java/org/xvm/xtc/ast/ForStmtAST.java | 33 - .../src/main/java/org/xvm/xtc/ast/IfAST.java | 59 - .../main/java/org/xvm/xtc/ast/InitAST.java | 14 - .../main/java/org/xvm/xtc/ast/InvokeAST.java | 278 ---- .../main/java/org/xvm/xtc/ast/ListAST.java | 34 - .../src/main/java/org/xvm/xtc/ast/MapAST.java | 38 - .../main/java/org/xvm/xtc/ast/MultiAST.java | 98 -- .../main/java/org/xvm/xtc/ast/NarrowAST.java | 31 - .../src/main/java/org/xvm/xtc/ast/NewAST.java | 114 -- .../main/java/org/xvm/xtc/ast/NewVirtAST.java | 44 - .../main/java/org/xvm/xtc/ast/NoneAST.java | 12 - .../main/java/org/xvm/xtc/ast/OrderAST.java | 34 - .../main/java/org/xvm/xtc/ast/OuterAST.java | 31 - .../java/org/xvm/xtc/ast/PropertyAST.java | 53 - .../src/main/java/org/xvm/xtc/ast/RegAST.java | 54 - .../main/java/org/xvm/xtc/ast/ReturnAST.java | 88 - .../main/java/org/xvm/xtc/ast/SwitchAST.java | 347 ---- .../java/org/xvm/xtc/ast/TemplateAST.java | 26 - .../main/java/org/xvm/xtc/ast/TernaryAST.java | 75 - .../main/java/org/xvm/xtc/ast/ThrowAST.java | 21 - .../java/org/xvm/xtc/ast/TryCatchAST.java | 80 - .../main/java/org/xvm/xtc/ast/UniOpAST.java | 151 -- .../main/java/org/xvm/xtc/ast/UnpackAST.java | 13 - .../main/java/org/xvm/xtc/ast/WhileAST.java | 53 - .../java/org/xvm/xtc/cons/AccessTCon.java | 22 - .../src/main/java/org/xvm/xtc/cons/Annot.java | 34 - .../main/java/org/xvm/xtc/cons/AnnotTCon.java | 29 - .../java/org/xvm/xtc/cons/AnonClzTCon.java | 14 - .../main/java/org/xvm/xtc/cons/AryCon.java | 31 - .../main/java/org/xvm/xtc/cons/ByteCon.java | 23 - .../main/java/org/xvm/xtc/cons/CharCon.java | 10 - .../main/java/org/xvm/xtc/cons/ClassCon.java | 12 - .../main/java/org/xvm/xtc/cons/ClzCon.java | 7 - .../main/java/org/xvm/xtc/cons/CondCon.java | 11 - .../src/main/java/org/xvm/xtc/cons/Const.java | 403 ----- .../main/java/org/xvm/xtc/cons/Dec128Con.java | 112 -- .../main/java/org/xvm/xtc/cons/Dec32Con.java | 83 - .../main/java/org/xvm/xtc/cons/Dec64Con.java | 171 -- .../main/java/org/xvm/xtc/cons/DecACon.java | 12 - .../main/java/org/xvm/xtc/cons/DecClzCon.java | 16 - .../main/java/org/xvm/xtc/cons/DecCon.java | 210 --- .../main/java/org/xvm/xtc/cons/DepTCon.java | 27 - .../main/java/org/xvm/xtc/cons/DiffTCon.java | 18 - .../java/org/xvm/xtc/cons/DynFormalCon.java | 37 - .../main/java/org/xvm/xtc/cons/EnumCon.java | 10 - .../main/java/org/xvm/xtc/cons/FPNCon.java | 19 - .../main/java/org/xvm/xtc/cons/FSNodeCon.java | 29 - .../java/org/xvm/xtc/cons/FileStoreCon.java | 21 - .../main/java/org/xvm/xtc/cons/Flt128Con.java | 14 - .../main/java/org/xvm/xtc/cons/Flt32Con.java | 116 -- .../main/java/org/xvm/xtc/cons/Flt64Con.java | 16 - .../main/java/org/xvm/xtc/cons/Flt8e4Con.java | 22 - .../main/java/org/xvm/xtc/cons/Flt8e5Con.java | 24 - .../main/java/org/xvm/xtc/cons/FormalCon.java | 12 - .../org/xvm/xtc/cons/FormalTChildCon.java | 18 - .../src/main/java/org/xvm/xtc/cons/IdCon.java | 5 - .../main/java/org/xvm/xtc/cons/ImmutTCon.java | 21 - .../java/org/xvm/xtc/cons/InnerDepTCon.java | 23 - .../main/java/org/xvm/xtc/cons/IntCon.java | 81 - .../main/java/org/xvm/xtc/cons/InterTCon.java | 19 - .../java/org/xvm/xtc/cons/KeywordCon.java | 12 - .../main/java/org/xvm/xtc/cons/LitCon.java | 19 - .../java/org/xvm/xtc/cons/MMethodCon.java | 30 - .../main/java/org/xvm/xtc/cons/MapCon.java | 36 - .../java/org/xvm/xtc/cons/MatchAnyCon.java | 24 - .../java/org/xvm/xtc/cons/MethodBindCon.java | 15 - .../main/java/org/xvm/xtc/cons/MethodCon.java | 71 - .../main/java/org/xvm/xtc/cons/ModCon.java | 20 - .../main/java/org/xvm/xtc/cons/NamedCon.java | 20 - .../java/org/xvm/xtc/cons/NamedCondCon.java | 19 - .../main/java/org/xvm/xtc/cons/NumCon.java | 11 - .../java/org/xvm/xtc/cons/PackageCon.java | 10 - .../main/java/org/xvm/xtc/cons/ParClzCon.java | 18 - .../main/java/org/xvm/xtc/cons/ParamTCon.java | 38 - .../main/java/org/xvm/xtc/cons/PartCon.java | 33 - .../java/org/xvm/xtc/cons/PropClzCon.java | 17 - .../main/java/org/xvm/xtc/cons/PropCon.java | 12 - .../main/java/org/xvm/xtc/cons/RangeCon.java | 36 - .../main/java/org/xvm/xtc/cons/RecurTCon.java | 13 - .../main/java/org/xvm/xtc/cons/RegCon.java | 11 - .../main/java/org/xvm/xtc/cons/RelTCon.java | 28 - .../java/org/xvm/xtc/cons/ServiceTCon.java | 21 - .../main/java/org/xvm/xtc/cons/SigCon.java | 33 - .../main/java/org/xvm/xtc/cons/SingleCon.java | 19 - .../main/java/org/xvm/xtc/cons/StringCon.java | 14 - .../src/main/java/org/xvm/xtc/cons/TCon.java | 22 - .../main/java/org/xvm/xtc/cons/TDefCon.java | 10 - .../main/java/org/xvm/xtc/cons/TParmCon.java | 18 - .../main/java/org/xvm/xtc/cons/TSeqTCon.java | 18 - .../main/java/org/xvm/xtc/cons/TermTCon.java | 26 - .../java/org/xvm/xtc/cons/ThisClzCon.java | 19 - .../java/org/xvm/xtc/cons/UInt8AryCon.java | 11 - .../main/java/org/xvm/xtc/cons/UnionTCon.java | 19 - .../main/java/org/xvm/xtc/cons/VerCon.java | 19 - .../java/org/xvm/xtc/cons/VirtDepTCon.java | 31 - 239 files changed, 19934 deletions(-) delete mode 100644 Makefile delete mode 100755 javatools_backend/bin/makedepends.sh delete mode 100644 javatools_backend/src/main/java/org/xvm/XEC.java delete mode 100644 javatools_backend/src/main/java/org/xvm/notes.txt delete mode 100644 javatools_backend/src/main/java/org/xvm/util/AbstractEntry.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/Ary.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/AryInt.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/ConcurrentAutoTable.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/NonBlockingHashMap.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/NonBlockingHashMapLong.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/S.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/SB.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/TLS.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/UtilUnsafe.java delete mode 100644 javatools_backend/src/main/java/org/xvm/util/VBitSet.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/Fun.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/XRunClz.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/XTC.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/AbstractRange.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Appender.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Appenderchar.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Boolean.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Comparable.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Const.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Enum.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Freezable.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Iterable.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Iterator.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Object.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Orderable.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Ordered.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeEE.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeEI.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeIE.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeII.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Sequential.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/Service.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/annotations/Future.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Array.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/AryString.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/AryUInt8.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/AryXTC.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Aryboolean.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Arychar.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Aryint.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Arylong.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Hashable.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Map.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Tuple.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Tuple0.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Tuple1.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Tuple2.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Tuple3.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Tuple4.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/TupleN.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/io/Console.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/BinaryFPNumber.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Bit.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Dec128.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Dec64.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/DecimalFPNumber.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/FPLiteral.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/FPNumber.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float128.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float32.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float64.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Int128.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Int32.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Int64.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/IntConvertible.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/IntLiteral.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/IntN.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/IntNumber.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Number.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt128.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt16.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt32.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt64.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt8.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UIntN.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UIntNumber.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Argument.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Ref.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Type.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/Char.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/String.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/StringBuffer.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/Stringable.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xrun/Container.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xrun/MainContainer.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xrun/NativeConsole.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xrun/NativeContainer.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xrun/NativeTimer.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xrun/Never.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xrun/XExpr.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xrun/XRuntime.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/CPool.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ClassPart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ClzBldSet.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ClzBuilder.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/Contrib.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/FilePart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/JavaC.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/MMethodPart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/MethodPart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ModPart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/PackagePart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/Parameter.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ParmPart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/Part.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/PropBuilder.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/PropPart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/RelPart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/TDefPart.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/VerTree.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/Version.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/XBase.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/XClz.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/XCons.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/XFun.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/XInter.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/XType.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/XValue.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/AST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/AssertAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/AssignAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/BinOpAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/BindFuncAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/BindMethAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/BlockAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/BreakAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/CallAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/CmpChainAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ConAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ContinueAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ConvAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/DefRegAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/DivRemAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/DoWhileAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ElvisAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ExprAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ForAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ForIterStmtAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ForRangeAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ForStmtAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/IfAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/InitAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/InvokeAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ListAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/MapAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/MultiAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/NarrowAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/NewAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/NewVirtAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/NoneAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/OrderAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/OuterAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/PropertyAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/RegAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ReturnAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/SwitchAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/TemplateAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/TernaryAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/ThrowAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/TryCatchAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/UniOpAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/UnpackAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/ast/WhileAST.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/AccessTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Annot.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/AnnotTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/AnonClzTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/AryCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/ByteCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/CharCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/ClassCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/ClzCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/CondCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Const.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Dec128Con.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Dec32Con.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Dec64Con.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/DecACon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/DecClzCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/DecCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/DepTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/DiffTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/DynFormalCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/EnumCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/FPNCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/FSNodeCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/FileStoreCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Flt128Con.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Flt32Con.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Flt64Con.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Flt8e4Con.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/Flt8e5Con.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/FormalCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/FormalTChildCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/IdCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/ImmutTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/InnerDepTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/IntCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/InterTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/KeywordCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/LitCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/MMethodCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/MapCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/MatchAnyCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/MethodBindCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/MethodCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/ModCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/NamedCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/NamedCondCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/NumCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/PackageCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/ParClzCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/ParamTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/PartCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/PropClzCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/PropCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/RangeCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/RecurTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/RegCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/RelTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/ServiceTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/SigCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/SingleCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/StringCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/TCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/TDefCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/TParmCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/TSeqTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/TermTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/ThisClzCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/UInt8AryCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/UnionTCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/VerCon.java delete mode 100644 javatools_backend/src/main/java/org/xvm/xtc/cons/VirtDepTCon.java diff --git a/Makefile b/Makefile deleted file mode 100644 index 6bae2c3997..0000000000 --- a/Makefile +++ /dev/null @@ -1,449 +0,0 @@ -# -# Makefile expects to run at the project root, and not nested inside anywhere -# -# cd $DESK/xvm; make - -# macOS specific notes: -# -# install necessary packages using brew: -# -# brew install wget -# brew install make -# brew install bash -# -# as of April 2024: -# -# ~$ wget --version -# GNU Wget 1.24.5 built on darwin21.6.0. -# -# xvm$ gmake -version -# GNU Make 4.4.1 -# Built for aarch64-apple-darwin23.0.0 -# Copyright (C) 1988-2023 Free Software Foundation, Inc. -# License GPLv3+: GNU GPL version 3 or later -# This is free software: you are free to change and redistribute it. -# There is NO WARRANTY, to the extent permitted by law. -# -# ~$ bash -version -# GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin21) -# Copyright (C) 2007 Free Software Foundation, Inc. -# -# note that brew installs GNU make as the "gmake" command, to avoid conflicting with the ancient -# version of make that comes with macOS xcode. -# -# first time only - this is the only thing that hits the Interwebs -# -# gmake init -# -# any time you want to nuke everything from space: -# -# gmake clean -# -# run a test -# (do this twice, since the first run may have to compile any dependencies ... same thing goes for -# any timing examples) -# -# time gmake doc/examples/OneHundredPrisoners.exe -# time gmake doc/examples/OneHundredPrisoners.exe -# -# compare that to the interpreter (by replacing the pretend extension .exe with .com) -# -# time gmake doc/examples/OneHundredPrisoners.com -# time gmake doc/examples/OneHundredPrisoners.com -# -# run the tck (but only after commenting out the last 4 tests in tck.x -- known TODO for Cliff) -# -# time gmake tck/src/main/x/tck.exe -# -# compare it to the interpreter (by replacing .exe with .com) -# -# time gmake tck/src/main/x/tck.com - -####################################################### -# -# Boilerplate because make syntax isn't the best -# - -# Use bash for recipes -SHELL := /bin/bash - -# Keep partial builds but not partial recipes -.NOTINTERMEDIATE: - -# for printing variable values -# usage: make print-VARIABLE -# > VARIABLE = value_of_variable -print-% : ; @echo $* = $($*) - -# literal space -space := $() $() - -# jar-file seperator - I can make this more specific for e.g. mac vs linux -ifeq ($(OS),Windows_NT) -SEP = ; -else -SEP = : -endif - -# Find a reasonable ctags. -CTAGS = $(shell which ctags) -# Hack for MacOS: /usr/bin/ctags is unfriendly, so look for ctags from brew -ifeq ($(UNAME),Darwin) - CTAGS = $(shell brew list ctags 2> /dev/null | grep bin/ctags) -endif - -MAKE_MIN_VERSION = 4.4.0 -ifneq "$(MAKE_MIN_VERSION)" "$(firstword $(sort $(MAKE_VERSION) $(MAKE_MIN_VERSION)))" - $(error make version is $(MAKE_VERSION), but needs to be version $(MAKE_MIN_VERSION) or later) -endif - - -# Fun Args to javac. -JAVAC_ARGS = --release 21 -XDignore.symbol.file -Xlint:-deprecation -Xlint:-unchecked - -XEC := org/xvm - -####################################################### -default: - @echo "Need to pass some make options, here are some suggestions" - @echo " init - one-time init; requires a good internet connection" - @echo " build/xdk/javatools/javatools.jar" - @echo " xlib - all lib_*.xtc libraries" - @echo " *.xtc - will build from the matching *.x" - @echo " *.exe - will execute new backend from the matching *.x" - @echo " *.com - will execute old backend from the matching *.x" - @echo " tck - run the tcks with new backend" - @echo " examples_exe - run the doc/examples with new backend" - @echo " manuals_exe - run the manualTests/src/main/x/new_backend" - -####################################################### -# Download libs from maven -# One time, per installation, with a good internet connection -# -init: lib - -LIBS := build/lib -lib: $(LIBS)/junit-jupiter-api-5.10.2.jar $(LIBS)/apiguardian-api-1.1.2.jar $(LIBS)/jline-3.25.1.jar - -# Unit testing -$(LIBS)/junit-jupiter-api-5.10.2.jar: - @[ -d $(LIBS) ] || mkdir -p $(LIBS) - @(cd $(LIBS); wget https://repo1.maven.org/maven2/org/junit/jupiter/junit-jupiter-api/5.10.2/junit-jupiter-api-5.10.2.jar) - -$(LIBS)/apiguardian-api-1.1.2.jar: - @[ -d $(LIBS) ] || mkdir -p $(LIBS) - @(cd $(LIBS); wget https://repo1.maven.org/maven2/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar) - -$(LIBS)/jline-3.25.1.jar: - @[ -d $(LIBS) ] || mkdir -p $(LIBS) - @(cd $(LIBS); wget https://repo1.maven.org/maven2/org/jline/jline/3.25.1/jline-3.25.1.jar) - -libs = $(wildcard $(LIBS)/*jar) - - - -####################################################### -# javatools_backend -SRCB := javatools_backend/src/main/java -CLZB:= build/classes/backend -javasB := $(wildcard $(SRCB)/$(XEC)/*java $(SRCB)/$(XEC)/*/*java $(SRCB)/$(XEC)/*/*/*java $(SRCB)/$(XEC)/xec/*/*/*java) -clzesB := $(patsubst $(SRCB)/%java,$(CLZB)/main/%class,$(javasB)) - -OODB := -$(CLZB)/.tag: $(clzesB) $(javasB) - @[ -d $(CLZB)/main ] || mkdir -p $(CLZB)/main - @# This crap is really just "javac", but with a beautiful error message. - @# The very very long list of java files is suppressed and counted. - @# The required output "Note: blah blah deprecated blah" is suppressed. - $(file > .argsB.txt, $(OODB)) - @if [ ! -z "$(OODB)" ] ; then \ - echo "compiling backend because " $< " and " `wc -w < .argsB.txt` " more files" ; \ - if ! javac $(JAVAC_ARGS) -cp "$(CLZB)/main$(SEP)$(LIBS)" -sourcepath $(SRCB) -d $(CLZB)/main $(OODB) >& .outB.txt ; then \ - cat .outB.txt ; \ - exit 1; \ - fi ; \ - rm -rf .outB.txt ; \ - fi - @touch $(CLZB)/.tag - @rm -f .argsB.txt - -# Collect just the out-of-date files -$(clzesB): $(CLZB)/main/%class: $(SRCB)/%java - $(eval OODB += $$<) - -####################################################### -# javatools_utils -SRCU := javatools_utils/src/main/java -CLZU := build/classes/utils -javasU := $(wildcard $(SRCU)/$(XEC)/*java $(SRCU)/$(XEC)/*/*java $(SRCU)/$(XEC)/*/*/*java) -clzesU := $(patsubst $(SRCU)/%java,$(CLZU)/main/%class,$(javasU)) - -OODU := -$(CLZU)/.tag: $(clzesU) $(javasU) - @[ -d $(CLZU)/main ] || mkdir -p $(CLZU)/main - @# This crap is really just javac, but with a beautiful error message. - @# The very very long list of java files is suppressed and counted. - @# The required output "Note: blah blah deprecated blah" is suppressed. - $(file > .argsU.txt, $(OODU)) - @if [ ! -z "$(OODU)" ] ; then \ - echo "compiling javatools_utils because " $< " and " `wc -w < .argsU.txt` " more files" ; \ - if ! javac $(JAVAC_ARGS) -cp "$(CLZU)/main$(SEP)$(LIBS)" -sourcepath $(SRCU) -d $(CLZU)/main $(OODU) >& .outU.txt ; then \ - cat .outU.txt ; \ - exit 1; \ - fi ; \ - rm -rf .outU.txt ; \ - fi - @touch $(CLZU)/.tag - @rm -f .argsU.txt - -# Collect just the out-of-date files -$(clzesU): $(CLZU)/main/%class: $(SRCU)/%java - $(eval OODU += $$<) - -####################################################### -# javatools -SRCT := javatools/src/main/java -CLZT:= build/classes/javatools -javasT := $(wildcard $(SRCT)/$(XEC)/*java $(SRCT)/$(XEC)/*/*java $(SRCT)/$(XEC)/*/*/*java $(SRCT)/$(XEC)/*/*/*/*java) -clzesT := $(patsubst $(SRCT)/%java,$(CLZT)/main/%class,$(javasT)) - -OODT := -$(CLZT)/.tag: $(clzesT) $(javasT) $(CLZU)/.tag - @[ -d $(CLZT)/main ] || mkdir -p $(CLZT)/main - @# This crap is really just javac, but with a beautiful error message. - @# The very very long list of java files is suppressed and counted. - @# The required output "Note: blah blah deprecated blah" is suppressed. - $(file > .argsT.txt, $(OODT)) - @if [ ! -z "$(OODT)" ] ; then \ - echo "compiling javatools because " $< " and " `wc -w < .argsT.txt` " more files" ; \ - if ! javac $(JAVAC_ARGS) -cp "$(CLZT)/main$(SEP)$(CLZU)/main$(SEP)$(LIBS)/*" -sourcepath $(SRCT) -d $(CLZT)/main @.argsT.txt >& .outT.txt ; then \ - cat .outT.txt ; \ - exit 1; \ - fi ; \ - rm -rf .outT.txt ; \ - fi - @touch $(CLZT)/.tag - @rm -f .argsT.txt - -# Collect just the out-of-date files -$(clzesT): $(CLZT)/main/%class: $(SRCT)/%java - $(eval OODT += $$<) - - -####################################################### -# Build a jar from all the class files in $(CLZT)/main and $(CLZU)/main - -# XDK setup -# Gradle XDK -#XDK_DIR = xdk/build/install/xdk -# Make XDK -XDK_DIR = build/xdk -XDK_JAR = $(XDK_DIR)/javatools/javatools.jar -XDK_LIB = $(XDK_DIR)/lib - -$(XDK_JAR): $(clzesT) $(clzesU) $(CLZT)/.tag $(CLZU)/.tag $(XDK_DIR)/MANIFEST.MF javatools/src/main/resources/errors.properties lib_ecstasy/src/main/resources/implicit.x - @$(file > .args.txt, $? ) - @echo " jarring " $@ " because " $< " and " `wc -w < .args.txt` " more files" - @rm -f .args.txt - @jar -cfm $@ $(XDK_DIR)/MANIFEST.MF -C $(CLZT)/main . -C $(CLZU)/main . -C javatools/src/main/resources errors.properties -C lib_ecstasy/src/main/resources implicit.x - -# Build the manifest -$(XDK_DIR)/MANIFEST.MF: VERSION - @[ -d $(XDK_DIR) ] || mkdir -p $(XDK_DIR) - @echo Manifest-Version: 1.0 > $@ - @echo Xdk-Version: org.xtclang:javatools:`cat VERSION` >> $@ - @echo Sealed: true >> $@ - @echo Main-Class: org.xvm.tool.Launcher >> $@ - @echo Name: /org/xvm/ >> $@ - @echo Specification-Title: xvm >> $@ - @echo Specification-Version: `cat VERSION` >> $@ - @echo Specification-Vendor: xtclang.org >> $@ - @echo Implementation-Title: xvm-prototype >> $@ - @echo Implementation-Version: `cat VERSION` >> $@ - @echo Implementation-Vendor: xtclang.org >> $@ - - -####################################################### -# Build the library XDK. - -XCC = java -jar $(XDK_JAR) xcc -L $(XDK_DIR)/javatools -L $(XDK_LIB) --rebuild - -# Build ecstasy.xtc. This one is special, because it needs mack.x and makes a turtle.xtc. -# the make-depend .d file is next to the generated XTC instead of next to the sources. -SRCX = lib_ecstasy/src/main/x/ecstasy -MACK = javatools_turtle/src/main/resources/mack -TURTLE = $(XDK_DIR)/javatools/javatools_turtle.xtc -XDKX = $(XDK_LIB)/ecstasy -$(XDKX).xtc $(TURTLE): $(SRCX).x $(XDKX).d $(MACK).x $(XDK_JAR) - $(file > .argsX.txt, $?) - @echo "compiling " $@ " because " $< " and " `wc -w < .argsX.txt` " more files" - @rm -f .argsX.txt - @[ -d $(XDK_LIB) ] || mkdir -p $(XDK_LIB) - @javatools_backend/bin/makedepends.sh $(SRCX) $(XDKX) - @java -jar $(XDK_JAR) xcc -L $(XDK_DIR)/javatools -L $(XDK_LIB) --rebuild $(SRCX).x $(MACK).x - @mv $(MACK).xtc $(TURTLE) - @mv lib_ecstasy/build/ecstasy.xtc $(XDKX).xtc - -SRCCRY = lib_crypto/src/main/x/crypto -LIBCRY = $(XDK_LIB)/crypto -$(LIBCRY).xtc: $(SRCCRY).x $(LIBCRY).d $(XDK_JAR) $(XDKX).xtc - @echo "compiling " $@ " because " $? - @javatools_backend/bin/makedepends.sh $(SRCCRY) $(LIBCRY) - @$(XCC) $< -o $@ - -SRCNET = lib_net/src/main/x/net -LIBNET = $(XDK_LIB)/net -$(LIBNET).xtc: $(SRCNET).x $(LIBNET).d $(XDK_JAR) $(LIBCRY).xtc - @echo "compiling " $@ " because " $? - @javatools_backend/bin/makedepends.sh $(SRCNET) $(LIBNET) - @$(XCC) $< -o $@ - - -SRCAGG = lib_aggregate/src/main/x/aggregate -LIBAGG = $(XDK_LIB)/aggregate -$(LIBAGG).xtc: $(SRCAGG).x $(LIBAGG).d $(XDK_JAR) $(XDKX).xtc - @echo "compiling " $@ " because " $? - @javatools_backend/bin/makedepends.sh $(SRCAGG) $(LIBAGG) - @$(XCC) $< -o $@ - -SRCCOL = lib_collections/src/main/x/collections -LIBCOL = $(XDK_LIB)/collections -$(LIBCOL).xtc: $(SRCCOL).x $(LIBCOL).d $(XDK_JAR) $(XDKX).xtc - @echo "compiling " $@ " because " $? - @javatools_backend/bin/makedepends.sh $(SRCCOL) $(LIBCOL) - @$(XCC) $< -o $@ - -SRCJSN = lib_json/src/main/x/json -LIBJSN = $(XDK_LIB)/json -$(LIBJSN).xtc: $(SRCJSN).x $(LIBJSN).d $(XDK_JAR) $(XDKX).xtc - @echo "compiling " $@ " because " $? - @javatools_backend/bin/makedepends.sh $(SRCJSN) $(LIBJSN) - @$(XCC) $< -o $@ - -SRCCVT = lib_convert/src/main/x/convert -LIBCVT = $(XDK_LIB)/convert -$(LIBCVT).xtc: $(SRCCVT).x $(LIBCVT).d $(XDK_JAR) $(XDKX).xtc $(LIBJSN).xtc $(LIBNET).xtc - @echo "compiling " $@ " because " $? - @javatools_backend/bin/makedepends.sh $(SRCCVT) $(LIBCVT) - @$(XCC) $< -o $@ - -SRCWEB = lib_web/src/main/x/web -LIBWEB = $(XDK_LIB)/web -$(LIBWEB).xtc: $(SRCWEB).x $(LIBWEB).d $(XDK_JAR) $(XDKX).xtc $(LIBAGG).xtc $(LIBCOL).xtc $(LIBCRY).xtc $(LIBJSN).xtc $(LIBNET).xtc $(LIBCVT).xtc - @echo "compiling " $@ " because " $? - @javatools_backend/bin/makedepends.sh $(SRCWEB) $(LIBWEB) - @$(XCC) $< -o $@ - -SRCNAT = javatools_bridge/src/main/x/_native -LIBNAT = $(XDK_DIR)/javatools/javatools_bridge -$(LIBNAT).xtc: $(SRCNAT).x $(LIBNAT).d $(XDK_JAR) $(XDKX).xtc $(LIBCRY).xtc $(LIBNET).xtc $(LIBWEB).xtc - @echo "compiling " $@ " because " $? - @javatools_backend/bin/makedepends.sh $(SRCNAT) $(LIBNAT) - @$(XCC) $< -o $@ - - -# All the core libs -XLIB = $(XDKX).xtc $(LIBCRY).xtc $(LIBNET).xtc $(LIBAGG).xtc $(LIBCOL).xtc $(LIBJSN).xtc $(LIBWEB).xtc $(LIBNAT).xtc $(LIBCVT).xtc -xlib: $(XLIB) - -include $(XLIB:.xtc=.d) - - -# General recipe for making an XTC from a X file -# Automatic X-file dependency generation; .d file is next to both the XTC and sources. -%.xtc: %.x %.d $(XDK_JAR) $(XDK_LIB)/ecstasy.xtc - @echo "compiling " $@ " because " $? - @javatools_backend/bin/makedepends.sh $* $* - @$(XCC) $< -o $@ - -# No complaints if these do not exist, just go make them -%.d: ; - - -####################################################### -# Running XTC files via either the old or new backends -# -# General recipe for executing an XTC, by making an "EXE" file from an XTC - -# since no "EXE" is ever made, this just always runs the module. -# Additional arguments can be passed from the command line via "ARG=arg" -%.exe: %.xtc $(clzesB) $(CLZB)/.tag $(XDKX).xtc - @echo " running " $@ - @java -ea -cp "$(CLZB)/main" org.xvm.XEC -L $(XDK_LIB) $< $(ARG) - -# General recipe for executing an XTC with the existing interpreter-based backend. -# Since no "COM" is ever made, this just always runs the module. -# Additional arguments can be passed from the command line via "ARG=arg" -%.com: %.xtc $(XDK_JAR) $(XDKX).xtc $(LIBNAT).xtc - @echo " running " $@ - @java -cp "$(XDK_JAR)$(SEP)$(LIBS)/jline-3.25.1.jar" org.xvm.tool.Launcher xec -L $(XDK_DIR)/javatools -L $(XDK_LIB) $< $(ARG) - - -####################################################### - -# Pick up any make-depends files for each desired XTC file. -# Useful to pick up updates in top-level XTC modules from deep child X files. -ifeq (,$(filter clean tags,$(MAKECMDGOALS))) -MAKE_DEPS = $(filter %.d,$(sort $(MAKECMDGOALS:.xtc=.d) $(MAKECMDGOALS:.exe=.d) $(MAKECMDGOALS:.com=.d))) -include $(MAKE_DEPS) -endif - - -####################################################### -# Common build targets when testing the new backend -# -examples_x = $(wildcard doc/examples/*.x) - -examples_xtc: $(examples_x:x=xtc) $(XDK_JAR) - -examples_exe: $(examples_x:x=exe) $(clazesB) - -examples_com: $(examples_x:x=com) $(clazesB) - - -# Build TCK -.PHONY: tck -tck: tck/src/main/x/tck.exe - -# Manual tests use an explicit list -MANUAL_DIR = manualTests/src/main/x/new_backend -#MANUAL_TESTS = annos.x array.x collections.x defasn.x exceptions.x generics.x innerOuter.x files.x IO.x lambda.x loop.x nesting.x numbers.x prop.x maps.x queues.x services.x reflect.x regex.x tuple.x TestMisc.x TestModIFace.x -MANUAL_TESTS = TestMisc.x TestModIFace.x - -manuals_x = $(patsubst %.x,$(MANUAL_DIR)/%.x,$(MANUAL_TESTS)) - -manuals_xtc: $(manuals_x:x=xtc) $(XDK_JAR) - -manuals_exe: $(manuals_x:x=exe) $(classesB) - -manuals_com: $(manuals_x:x=com) $(classesB) - - -#MULTI = multiModule/Lib.x multiModule/Main.x -#multi_x = $(patsubst %.x,$(MANUAL_DIR)/%.x,$(MULTI)) -#$(multi_x:x=xtc): $(MANUAL_DIR)/%.xtc: $(MANUAL_DIR)/%.x $(XDK_JAR) -# @echo "compiling " $@ " because " $? -# @$(XCC) $(filter-out $(XDK_JAR),$^) -L $(MANUAL_DIR)/multiModule -o $(MANUAL_DIR)/multiModule -# -# -#multi_exe: $(XDK_JAR) $(classesB) $(multi_x:x=xtc) -# @echo "Running test" $? -# @$(JVM) org.xvm.XEC -L $(XDK_LIB) -L $(MANUAL_DIR)/multiModule $(MANUAL_DIR)/multiModule/Main.xtc - - -# TAGS -tags: TAGS - -TAGS: $(javasB) $(javasT) $(javasU) - @rm -f TAGS - @$(CTAGS) -o TAGS -e --recurse=yes --extra=+q --fields=+fksaiS $(SRCB) $(SRCT) - -.PHONY: clean -clean: - rm -rf build/classes - rm -rf build/xdk - rm -rf out - rm -f TAGS - rm -f tck/src/main/x/*.xtc - rm -f doc/examples/*.xtc - rm -f manualTests/src/main/x/new_backend/*.xtc manualTests/src/main/x/new_backend/*/*.xtc - (find . -name "*~" -exec rm {} \; 2>/dev/null; exit 0) diff --git a/javatools_backend/bin/makedepends.sh b/javatools_backend/bin/makedepends.sh deleted file mode 100755 index 7423e411a9..0000000000 --- a/javatools_backend/bin/makedepends.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# Automatic make-dependency discovery for X files -# Usage: src (without the .x) dst (without the .d) -echo -n $2.d $2.xtc ": " > $2.d; -((test -d $1 && (/usr/bin/find $1 -name *.x | xargs echo)) >> $2.d ) || true; diff --git a/javatools_backend/src/main/java/org/xvm/XEC.java b/javatools_backend/src/main/java/org/xvm/XEC.java deleted file mode 100644 index 92da236e2e..0000000000 --- a/javatools_backend/src/main/java/org/xvm/XEC.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.xvm; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import org.xvm.util.S; -import org.xvm.xrun.*; -import org.xvm.xtc.FilePart; -import org.xvm.xtc.ModPart; -import org.xvm.xtc.Part; - -/** - Exploring XTC bytecodes. Fakes as a XEC runtime translator to JVM bytecodes. - - */ -public class XEC { - // Local project root - public static final String ROOT = "org.xvm"; - // All the generated code is generated here: - public static final String XCLZ = ROOT+".xec"; - - // Every thread runs in the context of some Container, which manages runtime - // & CPU gas, memory, resources (such as i/o and access to the file system). - public static final ThreadLocal CONTAINER = new ThreadLocal<>(); - - // The Repository of all code - public static ModRepo REPO; - - // The main Ecstasy module - public static ModPart ECSTASY; - - // Main Launcher. - // Usage: (-L path)* [-M main] file.xtc args - public static void main( String[] args ) throws IOException { - - // Parse options - // Parse (-L path)* libs - String[] libs = libs(args); - // Check for alternate run method - String xrun = "run"; - int ndx = libs.length*2; - if( ndx < args.length && args[ndx].equals("-M") ) throw XEC.TODO(); - // File to run - String xtc = xtc(ndx++,args); - // Arguments - String[] xargs = args(ndx,args); - - - REPO = new ModRepo(); - // Load XTC file into repo - ModPart mod = REPO.load(xtc); - // Load XDK - for( String lib : libs ) REPO.load(lib); - // Link the repo - REPO.link(); - - // Start the thread pool up - XRuntime.start(); - - // Start the native container. Top of the container tree. - NativeContainer N = new NativeContainer(); - // Start the initial container - MainContainer M = new MainContainer(N,mod); - CONTAINER.set(M); - - /*Joinable J=*/M.invoke(xrun,xargs); // Returns something to join against - //J.join(); - } - - // Parse options: Count and gather libs - private static String[] libs(String[] args) { - int nlibs = 0; - for( int i=0; i= args.length) { - System.err.println("Usage: xec (-L path)* [-M main] file.xtc args"); - System.exit(1); - } - - // File to parse - String xtc = args[ndx]; - if( !xtc.endsWith(".xtc") ) { - System.err.println("Error: "+xtc+" does not end with .xtc"); - System.exit(1); - } - return xtc; - } - - // Parse options: args to the main file - private static String[] args(int ndx, String[] args) { - return Arrays.copyOfRange(args,ndx,args.length); - } - - - // Module Repository: Mapping from module name Strings to ModParts. - public static class ModRepo extends HashMap { - // Load a single file or directory of files. Return a single module or null. - ModPart load( String s ) throws IOException { return load(new File(s)); } - ModPart load( File f ) throws IOException { - // Check for file already parsed - ModPart mod = get(f.toString()); - if( mod != null ) return mod; - // Recursively load directories - if( f.isDirectory() ) { - for( File file : f.listFiles(ModulesOnly) ) - load(file); - return null; // Null for directories - } else { - FilePart file = new FilePart(f); // Parse the entire file, drops buffer after parsing - mod = file._mod; // Extract main module - put(mod._name,mod); // Installed under module name - put(f.toString(),mod); // Installed under file name - if( S.eq(mod._name,"ecstasy.xtclang.org") ) ECSTASY = mod; - return mod; // Return single module for single file - } - } - // Filter to readable XTC named files only - static final FileFilter ModulesOnly = file -> - file.getName().length() > 4 && file.getName().endsWith(".xtc") && - file.exists() && file.isFile() && file.canRead() && file.length() > 0; - - // Link. Replace *Con references to *Part references. - public static final HashMap VISIT = new HashMap<>(); - void link() { - VISIT.clear(); - // For all modules in repo - for( ModPart mod : values() ) - // Get the parent's set of child modules and link them against the repo - mod._par.link(this); - } - } - - public static RuntimeException TODO() { return TODO("TODO"); } - public static RuntimeException TODO(String msg) { return new RuntimeException(msg); } - -} diff --git a/javatools_backend/src/main/java/org/xvm/notes.txt b/javatools_backend/src/main/java/org/xvm/notes.txt deleted file mode 100644 index 1d84790929..0000000000 --- a/javatools_backend/src/main/java/org/xvm/notes.txt +++ /dev/null @@ -1,152 +0,0 @@ -Cliff-Notes for Cliff - -Mar 12, 2024: A random collection of design thinking. At some future date these notes will all be outdated, -but for now they're useful. - -Ignore packages for now? - - -* org/xvm/XEC.java - entry point - -* org/xvm/xtc - Read an XTC file support classes; ClassPart, *Part, CPool,Version,VerTree -* org/xvm/xtc/cons - "cons" things from XTC files -* org/xvm/xtc/AST - "AST" things from XTC files - -* org/xvm/xtc/ClzBuilder, ModBuilder, Javac, XType, XValue, - -* org/xvm/xec - generated class strings act "as if" loaded from here -* org/xvm/xec - runtime support classes (no ties with gen classes) -* org/xvm/xec/XTC - base class for gen'd classes. - org/xvm/xec/?? - Common methods like TRACE, common enums... -* org/xvm/xec/XRunClz - Runnable XTC - org/xvm/xec/ecstasy/Iterable64 - extends XTC, implements Iterator - org/xvm/xec/ecstasy/collections/Array - extends XTC, implements array list - org/xvm/xec/ecstasy/collections/Array64 - extends XTC, implements array list - - -*XTC Modules- -*- gen as org/xvm/xec/module.java, includes static init -*- includes main & run -*- which pass off to module/class run - -*XTC module+class Class- -*- gen as org/xvm/xec/module.java - -XTC lower class - - gen as org/xvm/xec/module/CLASSNAME.java - - -#So multiMethod example: -# -#org/xvm/xec/Main.java - extends xec.XTC; import default; run() { new Main.Main().run(); } -#org/xvm/xec/Main/Main.java - extends Main; import MLib.JLib; run() { console.log; call Lib.greeting(); } -#org/xvm/xec/Lib.java - extends xec.Xclz; import default; empty_static; -#org/xvm/xec/Lib/Lib.java - extends Lib; String greeting() {return "hello world"} - -* Simple 1-class modules can keep their short form: -* org/xvm/xec/Main.java -* org/xvm/xec/Lib.java - - -* XType - intercepts Appendable, TODO - - MAPS TO interface xec/ecstasy/Appendable$Char - TemplateAST - - DefReg of ecstasy/text/StringBuffer <<-->> NEW JAVA xec/ecstasy/text/StringBufffer.java - Every thing is either- - - prim base: sb.p(prim) - - else : obj.appendTo(sb) // Must call appendTo, so can be overridden by object - - ---------------------------- -XTC Null is Java null. -XTC objects have a constructor, an assert & a finally. -XTC Obj construct sequence. - -- Alloc raw memory -- Default init; Java 0s. Maybe some XTC bits after this. -- - Replace Java null ptrs with typed TombStone, to avoid null-vs-#uninit confusion -- Constructs are called as user writes them; only called on child. -- - Operate on C struct flavor of memory -- - Can call any parent construct in any order, any number of times (0, 1 or many) -- - Fields must check for #uninit before use -- - - Int/Flt fields are pre-init/pre-zero -- - - Check Tombstone on reads & throw -- - Structs can escape, and be worked on by non-constructor methods & still must check #uninit -- - Check for #uninit at exit -- Call child assert, which auto-calls parent asserts -- Call child finally, which auto-calls parent finally in pre-order - -Later Optimizations -- XTC MAY be able to declare "no uses of #uninit" -- XTC MAY be able to declare "no escapes" - ------------------- - -Immutable -- XTC objs can be declared immutable at any time, via e.g. reflection -- Write to immutable objects must throw -- Current strat: -- - Set a immut bit. - -- - Test bit before EVERY write - - - ------------------- -class B { - String[] names; - construct() { - names = ["bob", "sue"]; // note: actually read from disk, not const pool value - - this.foo(); // compiler error - - // Cliff - TO DISCUSS - (struct B) s = this; // extends Struct - other.foo(s); // Here foo tortures over time - s.names = ["sue"]; - } finally { - // Cliff - TO DISCUSS when does this get run? - B b = this; - this.foo(); - } - - assert() { - // this gets called after the constructor before the finally - } - - void foo() {...} -} - -class D extends B { - construct() { - names = ["Cliff"]; - if (...) { - construct B(); - } else { - construct B(1,2,3); - } - - // Cliff - TO DISCUSS - (struct D) s = this; // extends Struct, extends (struct B) - } finally { - // Cliff - TO DISCUSS when does this get run? - D d = this; - } - - assert() { - // this gets called after the constructor before the finally - } -} - -Call chain order - - -D.construct() - D.con1(); - B.construct() // in-order as user writes - D.con2(); -D.assert - B.assert (pre/post either call) -(cast struct D to XTC D; set immutable bit) -D.finally - B.finally (pre-order call) - diff --git a/javatools_backend/src/main/java/org/xvm/util/AbstractEntry.java b/javatools_backend/src/main/java/org/xvm/util/AbstractEntry.java deleted file mode 100644 index 12b094ca9c..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/AbstractEntry.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.xvm.util; - -import java.util.Map; - -/** - * A simple implementation of {@link java.util.Map.Entry}. - * Does not implement {@link java.util.Map.Entry#setValue}, that is done by users of the class. - * - * @since 1.5 - * @author Cliff Click - * @param the type of keys maintained by this map - * @param the type of mapped values - */ - -abstract class AbstractEntry implements Map.Entry { - /** Strongly typed key */ - protected final TypeK _key; - /** Strongly typed value */ - protected TypeV _val; - - public AbstractEntry(final TypeK key, final TypeV val) { _key = key; _val = val; } - public AbstractEntry(final Map.Entry e ) { _key = e.getKey(); _val = e.getValue(); } - /** Return "key=val" string */ - public String toString() { return _key + "=" + _val; } - /** Return key */ - public TypeK getKey () { return _key; } - /** Return val */ - public TypeV getValue() { return _val; } - - /** Equal if the underlying key & value are equal */ - public boolean equals(final Object o) { - if (!(o instanceof Map.Entry)) return false; - final Map.Entry e = (Map.Entry)o; - return eq(_key, e.getKey()) && eq(_val, e.getValue()); - } - - /** Compute "key.hashCode() ^ val.hashCode()" */ - public int hashCode() { - return - ((_key == null) ? 0 : _key.hashCode()) ^ - ((_val == null) ? 0 : _val.hashCode()); - } - - private static boolean eq(final Object o1, final Object o2) { - return (o1 == null ? o2 == null : o1.equals(o2)); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/util/Ary.java b/javatools_backend/src/main/java/org/xvm/util/Ary.java deleted file mode 100644 index 22b1d03af2..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/Ary.java +++ /dev/null @@ -1,350 +0,0 @@ -package org.xvm.util; - -import java.lang.reflect.Array; -import java.util.*; -import java.util.function.Function; -import java.util.function.Predicate; - -// ArrayList with saner syntax -public class Ary implements Iterable { - public E[] _es; - public int _len; - public Ary(E[] es) { this(es,es.length); } - public Ary(E[] es, int len) { if( es.length==0 ) es=Arrays.copyOf(es,1); _es=es; _len=len; } - @SuppressWarnings("unchecked") - public Ary(Class clazz) { this((E[]) Array.newInstance(clazz, 1),0); } - - /** @return list is empty */ - public boolean isEmpty() { return _len==0; } - /** @return active list length */ - public int len() { return _len; } - /** @param i element index - * @return element being returned; throws if OOB - * @exception AIOOBE if !(0 <= i < _len) - */ - public E at( int i ) { - range_check(i); - return _es[i]; - } - /** @param i element index - * @return element being returned, or null if OOB */ - public E atX( int i ) { - return i < _len ? _es[i] : null; - } - /** @return last element */ - public E last( ) { - range_check(0); - return _es[_len-1]; - } - public void last(int i) { - range_check(i); - E tmp = _es[i]; - _es[i] = _es[_len-1]; - _es[_len-1] = tmp; - } - - /** @return remove and return last element or null */ - public E pop( ) { - return _len==0 ? null : _es[--_len]; - } - - /** Add element in amortized constant time - * @param e Element to add at end of list - * @return 'this' for flow-coding */ - public Ary add( E e ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = e; - return this; - } - - /** Add element in amortized constant time - * @param e Element to add at end of list - **/ - public E push( E e ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - return (_es[_len++] = e); - } - - /** Slow, linear-time, element insert. Preserves order. - * @param i index to insert at, between 0 and _len inclusive. - * @param e Element to insert - */ - public void insert( int i, E e ) { - if( i < 0 || i>_len ) - throw new ArrayIndexOutOfBoundsException(""+i+" >= "+_len); - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - System.arraycopy(_es,i,_es,i+1,(_len++)-i); - _es[i] = e; - } - - /** Fast, constant-time, element removal. Does not preserve order - * @param i element to be removed - * @return element removed */ - public E del( int i ) { - range_check(i); - E tmp = _es[i]; - _es[i]=_es[--_len]; - return tmp; - } - - /** Element removal, using '=='. Does not preserve order. - * @param e element to be removed - * @return element removed */ - public E del( E e ) { - for( int i=0; i<_len; i++ ) { - E tmp = _es[i]; - if( tmp==e ) { - _es[i]=_es[--_len]; - return tmp; - } - } - return null; - } - - /** Slow, linear-time, element removal. Preserves order. - * @param i element to be removed - * @return element removed */ - public E remove( int i ) { - range_check(i); - E e = _es[i]; - System.arraycopy(_es,i+1,_es,i,(--_len)-i); - return e; - } - - /** Remove all elements */ - public void clear( ) { _len=0; } - - public void fill( E e ) { Arrays.fill(_es,0,_len,e); } - - /** Extend and set. null fills as needed and does not throw AIOOBE. - * @param i element to set - * @param e value to set - * @return old value - */ - public E setX( int i, E e ) { - if( i >= _len ) Arrays.fill(_es,_len,_es.length,null); - while( i>= _es.length ) _es = Arrays.copyOf(_es,_es.length<<1); - if( i >= _len ) _len = i+1; - return (_es[i] = e); - } - - /** Clear element. Does nothing if element is OOB, since these are clear by - * default. - * @param i element to clear - */ - public void clear( int i ) { if( i<_len ) _es[i]=null; } - - /** Set existing element - * @param i element to set - * @param e value to set - * @return old value - * @exception AIOOBE if !(0 <= i < _len) - */ - public E set( int i, E e ) { - range_check(i); - E old = _es[i]; - _es[i] = e; - return old; - } - - // Increment length, revealing the E behind the _len, or null - public E inc_len( ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,_es.length<<1); - return _es[_len++]; - } - public Ary set_len( int len ) { - if( len > _len ) - if( _es.length==0 ) _es = Arrays.copyOf(_es,2); - else while( len>= _es.length ) _es = Arrays.copyOf(_es,_es.length<<1); - _len = len; - while( _es.length > (len<<1) ) // Shrink if hugely too large - _es = Arrays.copyOf(_es,_es.length>>1); - Arrays.fill(_es,len,_es.length,null); - return this; - } - - /** @param c Collection to be added */ - public Ary addAll( Collection c ) { if( c!=null ) for( E e : c ) add(e); return this; } - - /** @param es Array to be added */ - public Ary addAll( F[] es ) { - if( es==null || es.length==0 ) return this; - while( _len+es.length > _es.length ) _es = Arrays.copyOf(_es,_es.length<<1); - System.arraycopy(es,0,_es,_len,es.length); - _len += es.length; - return this; - } - - /** @param c Collection to be added */ - public Ary addAll( Ary c ) { - if( c==null || c._len==0 ) return this; - while( _len+c._len > _es.length ) _es = Arrays.copyOf(_es,_es.length<<1); - System.arraycopy(c._es,0,_es,_len,c._len); - _len += c._len; - return this; - } - - /** @return compact array version */ - public E[] asAry() { return Arrays.copyOf(_es,_len); } - - /** @param f function to apply to each element. Updates in-place. */ - public Ary map_update( Function f ) { for( int i = 0; i<_len; i++ ) _es[i] = f.apply(_es[i]); return this; } - /** @param P filter out elements failing to pass the predicate; updates in - * place and shuffles list. - * @return this, for flow-coding */ - public Ary filter_update( Predicate P ) { - for( int i=0; i<_len; i++ ) - if( !P.test(_es[i]) ) - del(i--); - return this; - } - /** Sorts in-place - * @param c Comparator to sort by */ - public void sort_update(Comparator c ) { Arrays.sort(_es, 0, _len, c); } - /** Find the first matching element using ==, or -1 if none. Note that - * most del calls shuffle the list, so the first element might be random. - * @param e Element to find - * @return index of first matching element, or -1 if none */ - public int find( E e ) { - for( int i=0; i<_len; i++ ) if( _es[i]==e ) return i; - return -1; - } - /** Find the first element matching predicate P, or -1 if none. Note that - * most del calls shuffle the list, so the first element might be random. - * @param P Predicate to match - * @return index of first matching element, or -1 if none */ - public int find( Predicate P ) { - for( int i=0; i<_len; i++ ) if( P.test(_es[i]) ) return i; - return -1; - } - /** Find and replace the first matching element using ==. - * @param old Element to find - * @param nnn Element replacing old - * @return true if replacement happened */ - public boolean replace( E old, E nnn ) { - for( int i=0; i<_len; i++ ) if( _es[i]==old ) { _es[i]=nnn; return true; } - return false; - } - - - /** Merge-Or. Merge 2 sorted Arys, tossing out duplicates. Return a new - * sorted Ary with the merged list. Undefined if the original arrays are - * not sorted. Error if they are not of the same type. Elements must - * implement Comparable. - * @param a0 Sorted Ary to merge - * @param a1 Sorted Ary to merge - * @return A new sorted merged Ary - */ - public static > Ary merge_or( Ary a0, Ary a1 ) { - int i=0, j=0; - Ary res = new Ary<>(Arrays.copyOf(a0._es,a0._len+a1._len),0); - - while( i0 ) { res.add(y); j++; } - else { res.add(x); i++; j++; } - } - while( i Ary merge_or( Ary a0, Ary a1, Comparator cmpr, Predicate filter) { - int i=0, j=0; - Ary res = new Ary<>(Arrays.copyOf(a0._es,a0._len+a1._len),0); - - while( i0 ) { res.add(y); j++; } - else { res.add(x); i++; j++; } - } - while( i> Ary merge_and( Ary a0, Ary a1 ) { - int i=0, j=0; - Ary res = new Ary<>(Arrays.copyOf(a0._es,Math.min(a0._len,a1._len)),0); - while( i0 ) { j++; } - else { res.add(x); i++; j++; } - } - return res; - } - - /** @return an iterator */ - @Override public Iterator iterator() { return new Iter(); } - private class Iter implements Iterator { - int _i=0; - @Override public boolean hasNext() { return _i<_len; } - @Override public E next() { return _es[_i++]; } - } - - @Override public String toString() { - SB sb = new SB().p('{'); - for( int i=0; i<_len; i++ ) { - if( i>0 ) sb.p(','); - if( _es[i] != null ) sb.p(_es[i].toString()); - } - return sb.p('}').toString(); - } - - private void range_check( int i ) { - if( i < 0 || i>=_len ) - throw new ArrayIndexOutOfBoundsException(""+i+" >= "+_len); - } - - // Note that the hashCode() and equals() are not invariant to changes in the - // underlying array. If the hashCode() is used (e.g., inserting into a - // HashMap) and the then the array changes, the hashCode() will change also. - @Override public boolean equals( Object o ) { - if( this==o ) return true; - if( !(o instanceof Ary ary) ) return false; - if( _len != ary._len ) return false; - if( _es == ary._es ) return true; - for( int i=0; i<_len; i++ ) - if( !(_es[i]==null ? (ary._es[i] == null) : _es[i].equals(ary._es[i])) ) - return false; - return true; - } - @Override public int hashCode( ) { - int sum=_len; - for( int i=0; i<_len; i++ ) - sum += _es[i]==null ? 0 : _es[i].hashCode(); - return sum; - } - - public Ary deepCopy() { - return new Ary<>(_es.clone(),_len); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/util/AryInt.java b/javatools_backend/src/main/java/org/xvm/util/AryInt.java deleted file mode 100644 index 18ed5c5df6..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/AryInt.java +++ /dev/null @@ -1,186 +0,0 @@ -package org.xvm.util; - -import java.util.Arrays; -import java.util.Collection; -import java.util.function.IntUnaryOperator; - -// ArrayList with saner syntax -public class AryInt { - public int[] _es; - public int _len; - public AryInt(int[] es) { this(es,es.length); } - public AryInt(int[] es, int len) { _es=es; _len=len; } - public AryInt() { this(new int[1],0); } - - /** @return list is empty */ - public boolean isEmpty() { return _len==0; } - /** @return active list length */ - public int len() { return _len; } - /** @param i element index - * @return element being returned; throws if OOB */ - public int at( int i ) { - range_check(i); - return _es[i]; - } - /** @param i element index - * @return element being returned, or 0 if OOB */ - public int atX( int i ) { - return i < _len ? _es[i] : 0; - } - /** @return last element */ - public int last( ) { - range_check(0); - return _es[_len-1]; - } - - /** @return remove and return last element */ - public int pop( ) { - range_check(0); - return _es[--_len]; - } - - /** Add element in amortized constant time - * @param e element to add at end of list - * @return 'this' for flow-coding */ - public AryInt push( int e ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = e; - return this; - } - - /** Slow, linear-time, element insert. Preserves order. - * @param i index to insert at, between 0 and _len inclusive. - * @param e intlement to insert - */ - public void insert( int i, int e ) { - if( i < 0 || i>_len ) - throw new ArrayIndexOutOfBoundsException(""+i+" >= "+_len); - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - System.arraycopy(_es,i,_es,i+1,(_len++)-i); - _es[i] = e; - } - - /** Fast, constant-time, element removal. Does not preserve order - * @param i element to be removed - * @return element removed */ - public int del( int i ) { - range_check(i); - int tmp = _es[i]; - _es[i]=_es[--_len]; - return tmp; - } - - /** Slow, linear-time, element removal. Preserves order. - * @param i element to be removed - * @return element removed */ - public int remove( int i ) { - range_check(i); - int e = _es[i]; - System.arraycopy(_es,i+1,_es,i,(--_len)-i); - return e; - } - - /** Remove all elements */ - public void clear( ) { Arrays.fill(_es,0,_len,0); _len=0; } - - // Extend and set - public int setX( int i, int e ) { - while( i>= _es.length ) _es = Arrays.copyOf(_es,_es.length<<1); - if( i >= _len ) _len = i+1; - return (_es[i] = e); - } - - public int set( int i, int e ) { - range_check(i); - return (_es[i] = e); - } - - public AryInt set_as( int e ) { _es[0] = e; _len=1; return this; } - public AryInt set_len( int len ) { - if( len > _len ) - while( len>= _es.length ) _es = Arrays.copyOf(_es,_es.length<<1); - _len = len; - while( _es.length > (len<<1) ) // Shrink if hugely too large - _es = Arrays.copyOf(_es,_es.length>>1); - return this; - } - - /** @param c Collection to be added */ - public AryInt addAll( Collection c ) { for( int e : c ) push(e); return this; } - - /** @param es Array to be added */ - public AryInt addAll( int[] es ) { - if( es.length==0 ) return this; - while( _len+es.length > _es.length ) _es = Arrays.copyOf(_es,_es.length<<1); - System.arraycopy(es,0,_es,_len,es.length); - _len += es.length; - return this; - } - - public AryInt map_update( IntUnaryOperator f ) { for( int i = 0; i<_len; i++ ) _es[i] = f.applyAsInt(_es[i]); return this; } - - /** @return compact array version. */ - public int[] asAry() { return Arrays.copyOf(_es,_len); } - - /** Sorts in-place */ - public void sort_update() { Arrays.sort(_es, 0, _len); } - /** Find the first matching element using ==, or -1 if none. Note that - * most del calls shuffle the list, so the first element might be random. - * @param e intlement to find - * @return index of first matching element, or -1 if none */ - public int find( int e ) { - for( int i=0; i<_len; i++ ) if( _es[i]==e ) return i; - return -1; - } - - @Override public String toString() { - SB sb = new SB().p('['); - for( int i=0; i<_len; i++ ) - sb.p(_es[i]).p(','); - return sb.unchar().p(']').toString(); - } - - private void range_check( int i ) { - if( i < 0 || i>=_len ) - throw new ArrayIndexOutOfBoundsException(""+i+" >= "+_len); - } - - // Binary search sorted _es. Returns insertion point. - // Undefined results if _es is not sorted. - public int binary_search( int e ) { - int lo=0, hi=_len-1; - while( lo <= hi ) { - int mid = (hi + lo) >>> 1; // midpoint, rounded down - int mval = _es[mid]; - if( e==mval ) { - // If dups, get to the first. - while( mid>0 && e==_es[mid-1] ) mid--; - return mid; - } - if( e >mval ) lo = mid+1; - else hi = mid-1; - } - return lo; - } - - // Note that the hashCode() and equals() are not invariant to changes in the - // underlying array. If the hashCode() is used (e.g., inserting into a - // HashMap) and the then the array changes, the hashCode() will change also. - @Override public boolean equals( Object o ) { - if( this==o ) return true; - if( !(o instanceof AryInt) ) return false; - AryInt ary = (AryInt)o; - if( _len != ary._len ) return false; - if( _es == ary._es ) return true; - for( int i=0; i<_len; i++ ) - if( _es[i] != ary._es[i] ) - return false; - return true; - } - @Override public int hashCode( ) { - int sum=_len; - for( int i=0; i<_len; i++ ) - sum += _es[i]; - return sum; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/util/ConcurrentAutoTable.java b/javatools_backend/src/main/java/org/xvm/util/ConcurrentAutoTable.java deleted file mode 100644 index ea4e626baa..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/ConcurrentAutoTable.java +++ /dev/null @@ -1,212 +0,0 @@ -package org.xvm.util; - -import java.io.Serializable; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.Arrays; - -import sun.misc.Unsafe; - -/** - * An auto-resizing table of {@code longs}, supporting low-contention CAS - * operations. Updates are done with CAS's to no particular table element. - * The intent is to support highly scalable counters, r/w locks, and other - * structures where the updates are associative, loss-free (no-brainer), and - * otherwise happen at such a high volume that the cache contention for - * CAS'ing a single word is unacceptable. - * - * @since 1.5 - * @author Cliff Click - */ -public class ConcurrentAutoTable implements Serializable { - - // --- public interface --- - - /** - * Add the given value to current counter value. Concurrent updates will - * not be lost, but addAndGet or getAndAdd are not implemented because the - * total counter value (i.e., {@link #get}) is not atomically updated. - * Updates are striped across an array of counters to avoid cache contention - * and has been tested with performance scaling linearly up to 768 CPUs. - */ - public void add( long x ) { add_if( x); } - /** {@link #add} with -1 */ - public void decrement() { add_if(-1L); } - /** {@link #add} with +1 */ - public void increment() { add_if( 1L); } - - /** Atomically set the sum of the striped counters to specified value. - * Rather more expensive than a simple store, in order to remain atomic. - */ - public void set( long x ) { - CAT newcat = new CAT(null,4,x); - // Spin until CAS works - while( !CAS_cat(_cat,newcat) ) {/*empty*/} - } - - /** - * Not-atomic clear - */ - public void clear() { Arrays.fill(_cat._t,0); } - /** - * Current value of the counter. Since other threads are updating furiously - * the value is only approximate, but it includes all counts made by the - * current thread. Requires a pass over the internally striped counters. - */ - public long get() { return _cat.sum(); } - /** Same as {@link #get}, included for completeness. */ - public int intValue() { return (int)_cat.sum(); } - /** Same as {@link #get}, included for completeness. */ - public long longValue() { return _cat.sum(); } - - /** - * A cheaper {@link #get}. Updated only once/millisecond, but as fast as a - * simple load instruction when not updating. - */ - public long estimate_get( ) { return _cat.estimate_sum(); } - - /** - * Return the counter's {@code long} value converted to a string. - */ - public String toString() { return _cat.toString(); } - - /** - * A more verbose print than {@link #toString}, showing internal structure. - * Useful for debugging. - */ - public void print() { _cat.print(); } - - /** - * Return the internal counter striping factor. Useful for diagnosing - * performance problems. - */ - public int internal_size() { return _cat._t.length; } - - // Only add 'x' to some slot in table, hinted at by 'hash'. The sum can - // overflow. Value is CAS'd so no counts are lost. The CAS is retried until - // it succeeds. Returned value is the old value. - private long add_if( long x ) { return _cat.add_if(x,hash(),this); } - - // The underlying array of concurrently updated long counters - private volatile CAT _cat = new CAT(null,1/*Start Small, Think Big!*/,0L); - private static AtomicReferenceFieldUpdater _catUpdater = - AtomicReferenceFieldUpdater.newUpdater(ConcurrentAutoTable.class,CAT.class, "_cat"); - private boolean CAS_cat( CAT oldcat, CAT newcat ) { return _catUpdater.compareAndSet(this,oldcat,newcat); } - - // Hash spreader - private static int hash() { - //int h = (int)Thread.currentThread().getId(); - int h = System.identityHashCode(Thread.currentThread()); - return h<<3; // Pad out cache lines. The goal is to avoid cache-line contention - } - - // --- CAT ----------------------------------------------------------------- - private static class CAT implements Serializable { - - // Unsafe crud: get a function which will CAS arrays - private static final Unsafe _unsafe = UtilUnsafe.getUnsafe(); - private static final int _Lbase = _unsafe.arrayBaseOffset(long[].class); - private static final int _Lscale = _unsafe.arrayIndexScale(long[].class); - private static long rawIndex(long[] ary, int i) { - assert i >= 0 && i < ary.length; - return _Lbase + i * _Lscale; - } - private static boolean CAS( long[] A, int idx, long old, long nnn ) { - return _unsafe.compareAndSwapLong( A, rawIndex(A,idx), old, nnn ); - } - - //volatile long _resizers; // count of threads attempting a resize - //static private final AtomicLongFieldUpdater _resizerUpdater = - // AtomicLongFieldUpdater.newUpdater(CAT.class, "_resizers"); - - private final CAT _next; - private volatile long _fuzzy_sum_cache; - private volatile long _fuzzy_time; - private static final int MAX_SPIN=1; - private final long[] _t; // Power-of-2 array of longs - - CAT( CAT next, int sz, long init ) { - _next = next; - _t = new long[sz]; - _t[0] = init; - } - - // Only add 'x' to some slot in table, hinted at by 'hash'. The sum can - // overflow. Value is CAS'd so no counts are lost. The CAS is attempted - // ONCE. - public long add_if( long x, int hash, ConcurrentAutoTable master ) { - final long[] t = _t; - final int idx = hash & (t.length-1); - // Peel loop; try once fast - long old = t[idx]; - final boolean ok = CAS( t, idx, old, old+x ); - if( ok ) return old; // Got it - // Try harder - int cnt=0; - while( true ) { - old = t[idx]; - if( CAS( t, idx, old, old+x ) ) break; // Got it! - cnt++; - } - if( cnt < MAX_SPIN ) return old; // Allowable spin loop count - if( t.length >= 1024*1024 ) return old; // too big already - - // Too much contention; double array size in an effort to reduce contention - //long r = _resizers; - //final int newbytes = (t.length<<1)<<3/*word to bytes*/; - //while( !_resizerUpdater.compareAndSet(this,r,r+newbytes) ) - // r = _resizers; - //r += newbytes; - if( master._cat != this ) return old; // Already doubled, don't bother - //if( (r>>17) != 0 ) { // Already too much allocation attempts? - // // We could use a wait with timeout, so we'll wakeup as soon as the new - // // table is ready, or after the timeout in any case. Annoyingly, this - // // breaks the non-blocking property - so for now we just briefly sleep. - // //synchronized( this ) { wait(8*megs); } // Timeout - we always wakeup - // try { Thread.sleep(r>>17); } catch( InterruptedException e ) { } - // if( master._cat != this ) return old; - //} - - CAT newcat = new CAT(this,t.length*2,0); - // Take 1 stab at updating the CAT with the new larger size. If this - // fails, we assume some other thread already expanded the CAT - so we - // do not need to retry until it succeeds. - while( master._cat == this && !master.CAS_cat(this,newcat) ) {/*empty*/} - return old; - } - - - // Return the current sum of all things in the table. Writers can be - // updating the table furiously, so the sum is only locally accurate. - public long sum( ) { - long sum = _next == null ? 0 : _next.sum(); // Recursively get cached sum - final long[] t = _t; - for( long cnt : t ) sum += cnt; - return sum; - } - - // Fast fuzzy version. Used a cached value until it gets old, then re-up - // the cache. - public long estimate_sum( ) { - // For short tables, just do the work - if( _t.length <= 64 ) return sum(); - // For bigger tables, periodically freshen a cached value - long millis = System.currentTimeMillis(); - if( _fuzzy_time != millis ) { // Time marches on? - _fuzzy_sum_cache = sum(); // Get sum the hard way - _fuzzy_time = millis; // Indicate freshness of cached value - } - return _fuzzy_sum_cache; // Return cached sum - } - - public String toString( ) { return Long.toString(sum()); } - - public void print() { - long[] t = _t; - System.out.print("["+t[0]); - for( int i=1; iHashtable. However, even though all operations are - * thread-safe, operations do not entail locking and there is - * not any support for locking the entire table in a way that - * prevents all access. This class is fully interoperable with - * Hashtable in programs that rely on its thread safety but not on - * its synchronization details. - * - *

Operations (including put) generally do not block, so may - * overlap with other update operations (including other puts and - * removes). Retrievals reflect the results of the most recently - * completed update operations holding upon their onset. For - * aggregate operations such as putAll, concurrent retrievals may - * reflect insertion or removal of only some entries. Similarly, Iterators - * and Enumerations return elements reflecting the state of the hash table at - * some point at or since the creation of the iterator/enumeration. They do - * not throw {@link ConcurrentModificationException}. However, - * iterators are designed to be used by only one thread at a time. - * - *

Very full tables, or tables with high reprobe rates may trigger an - * internal resize operation to move into a larger table. Resizing is not - * terribly expensive, but it is not free either; during resize operations - * table throughput may drop somewhat. All threads that visit the table - * during a resize will 'help' the resizing but will still be allowed to - * complete their operation before the resize is finished (i.e., a simple - * 'get' operation on a million-entry table undergoing resizing will not need - * to block until the entire million entries are copied). - * - *

This class and its views and iterators implement all of the - * optional methods of the {@link Map} and {@link Iterator} - * interfaces. - * - *

Like {@link Hashtable} but unlike {@link HashMap}, this class - * does not allow null to be used as a key or value. - * - * - * @since 1.5 - * @author Cliff Click - * @param the type of keys maintained by this map - * @param the type of mapped values - */ - -public class NonBlockingHashMap - extends AbstractMap - implements ConcurrentMap, Cloneable, Serializable { - - private static final long serialVersionUID = 1234123412341234123L; - - private static final int REPROBE_LIMIT=10; // Too many reprobes then force a table-resize - - // --- Bits to allow Unsafe access to arrays - private static final Unsafe _unsafe = UtilUnsafe.getUnsafe(); - private static final int _Obase = _unsafe.arrayBaseOffset(Object[].class); - private static final int _Oscale = _unsafe.arrayIndexScale(Object[].class); - private static final int _Olog = _Oscale==4?2:(_Oscale==8?3:9999); - private static long rawIndex(final Object[] ary, final int idx) { - assert idx >= 0 && idx < ary.length; - // Note the long-math requirement, to handle arrays of more than 2^31 bytes - // - or 2^28 - or about 268M - 8-byte pointer elements. - return _Obase + ((long)idx << _Olog); - } - - // --- Setup to use Unsafe - private static final long _kvs_offset; - static { // - Field f = null; - try { f = NonBlockingHashMap.class.getDeclaredField("_kvs"); } - catch( java.lang.NoSuchFieldException e ) { throw new RuntimeException(e); } - _kvs_offset = _unsafe.objectFieldOffset(f); - } - private boolean CAS_kvs( final Object[] oldkvs, final Object[] newkvs ) { - return _unsafe.compareAndSwapObject(this, _kvs_offset, oldkvs, newkvs ); - } - - // --- Adding a 'prime' bit onto Values via wrapping with a junk wrapper class - private static final class Prime { - final Object _V; - Prime( Object V ) { _V = V; } - static Object unbox( Object V ) { return V instanceof Prime ? ((Prime)V)._V : V; } - } - - // --- hash ---------------------------------------------------------------- - // Helper function to spread lousy hashCodes - private static int hash( final Object key) { - int h = key.hashCode(); // The real hashCode call - h ^= (h>>>20) ^ (h>>>12); - h ^= (h>>> 7) ^ (h>>> 4); - return h; - } - - - - // --- The Hash Table -------------------- - // Slot 0 is always used for a 'CHM' entry below to hold the interesting - // bits of the hash table. Slot 1 holds full hashes as an array of ints. - // Slots {2,3}, {4,5}, etc hold {Key,Value} pairs. The entire hash table - // can be atomically replaced by CASing the _kvs field. - // - // Why is CHM buried inside the _kvs Object array, instead of the other way - // around? The CHM info is used during resize events and updates, but not - // during standard 'get' operations. I assume 'get' is much more frequent - // than 'put'. 'get' can skip the extra indirection of skipping through the - // CHM to reach the _kvs array. - private transient Object[] _kvs; - private static CHM chm ( Object[] kvs) { return (CHM )kvs[0]; } - private static int[] hashes( Object[] kvs) { return (int[])kvs[1]; } - // Number of K,V pairs in the table - private static int len( Object[] kvs) { return (kvs.length-2)>>1; } - - // Time since last resize - private transient long _last_resize_milli; - - // --- Minimum table size ---------------- - // Pick size 4 K/V pairs, which turns into (4*2+2)*4+12 = 54 bytes on a - // standard 32-bit HotSpot, and (4*2+2)*8+12 = 92 bytes on 64-bit JVM. - private static final int MIN_SIZE_LOG=2; // - private static final int MIN_SIZE=(1<>4); - } - - // --- NonBlockingHashMap -------------------------------------------------- - // Constructors - - /** Create a new NonBlockingHashMap with default minimum size (currently set - * to 8 K/V pairs or roughly 84 bytes on a standard 32-bit JVM). */ - public NonBlockingHashMap( ) { this(MIN_SIZE); } - - /** Create a new NonBlockingHashMap with initial room for the given number of - * elements, thus avoiding internal resizing operations to reach an - * appropriate size. Large numbers here when used with a small count of - * elements will sacrifice space for a small amount of time gained. The - * initial size will be rounded up internally to the next larger power of 2. */ - public NonBlockingHashMap( final int initial_sz ) { initialize(initial_sz); } - private void initialize( int initial_sz ) { - if( initial_sz < 0 ) throw new IllegalArgumentException(); - int i; // Convert to next largest power-of-2 - if( initial_sz > 1024*1024 ) initial_sz = 1024*1024; - for( i=MIN_SIZE_LOG; (1<size() == 0. - * @return size() == 0 */ - @Override - public boolean isEmpty ( ) { return size() == 0; } - - /** Tests if the key in the table using the equals method. - * @return true if the key is in the table using the equals method - * @throws NullPointerException if the specified key is null */ - @Override - public boolean containsKey( Object key ) { return get(key) != null; } - - /** Legacy method testing if some key maps into the specified value in this - * table. This method is identical in functionality to {@link - * #containsValue}, and exists solely to ensure full compatibility with - * class {@link java.util.Hashtable}, which supported this method prior to - * introduction of the Java Collections framework. - * @param val a value to search for - * @return true if this map maps one or more keys to the specified value - * @throws NullPointerException if the specified value is null */ - public boolean contains ( Object val ) { return containsValue(val); } - - /** Maps the specified key to the specified value in the table. Neither key - * nor value can be null. - *

The value can be retrieved by calling {@link #get} with a key that is - * equal to the original key. - * @param key key with which the specified value is to be associated - * @param val value to be associated with the specified key - * @return the previous value associated with key, or - * null if there was no mapping for key - * @throws NullPointerException if the specified key or value is null */ - @Override - public TypeV put ( TypeK key, TypeV val ) { return putIfMatch( key, val, NO_MATCH_OLD); } - - /** Atomically, do a {@link #put} if-and-only-if the key is not mapped. - * Useful to ensure that only a single mapping for the key exists, even if - * many threads are trying to create the mapping in parallel. - * @return the previous value associated with the specified key, - * or null if there was no mapping for the key - * @throws NullPointerException if the specified key or value is null */ - public TypeV putIfAbsent( TypeK key, TypeV val ) { return putIfMatch( key, val, TOMBSTONE ); } - - /** Removes the key (and its corresponding value) from this map. - * This method does nothing if the key is not in the map. - * @return the previous value associated with key, or - * null if there was no mapping for key - * @throws NullPointerException if the specified key is null */ - @Override - public TypeV remove ( Object key ) { return putIfMatch( key,TOMBSTONE, NO_MATCH_OLD); } - - /** Atomically do a {@link #remove(Object)} if-and-only-if the key is mapped - * to a value which is equals to the given value. - * @throws NullPointerException if the specified key or value is null */ - public boolean remove ( Object key,Object val ) { return putIfMatch( key,TOMBSTONE, val ) == val; } - - /** Atomically do a put(key,val) if-and-only-if the key is - * mapped to some value already. - * @throws NullPointerException if the specified key or value is null */ - public TypeV replace ( TypeK key, TypeV val ) { return putIfMatch( key, val,MATCH_ANY ); } - - /** Atomically do a put(key,newValue) if-and-only-if the key is - * mapped a value which is equals to oldValue. - * @throws NullPointerException if the specified key or value is null */ - public boolean replace ( TypeK key, TypeV oldValue, TypeV newValue ) { - return putIfMatch( key, newValue, oldValue ) == oldValue; - } - - - // Atomically replace newVal for oldVal, returning the value that existed - // there before. If oldVal is the returned value, then newVal was inserted, - // otherwise not. A null oldVal means the key does not exist (only insert if - // missing); a null newVal means to remove the key. - @SuppressWarnings("unchecked") - public final TypeV putIfMatchAllowNull( Object key, Object newVal, Object oldVal ) { - if( oldVal == null ) oldVal = TOMBSTONE; - if( newVal == null ) newVal = TOMBSTONE; - final TypeV res = (TypeV)putIfMatch( this, _kvs, key, newVal, oldVal ); - assert !(res instanceof Prime); - //assert res != null; - return res == TOMBSTONE ? null : res; - } - - @SuppressWarnings("unchecked") - private final TypeV putIfMatch( Object key, Object newVal, Object oldVal ) { - if (oldVal == null || newVal == null) throw new NullPointerException(); - final Object res = putIfMatch( this, _kvs, key, newVal, oldVal ); - assert !(res instanceof Prime); - assert res != null; - return res == TOMBSTONE ? null : (TypeV)res; - } - - - /** Copies all of the mappings from the specified map to this one, replacing - * any existing mappings. - * @param m mappings to be stored in this map */ - @Override - public void putAll(Map m) { - for (Map.Entry e : m.entrySet()) - put(e.getKey(), e.getValue()); - } - - /** Removes all of the mappings from this map. */ - @Override - public void clear() { // Smack a new empty table down - Object[] newkvs = new NonBlockingHashMap(MIN_SIZE)._kvs; - while( !CAS_kvs(_kvs,newkvs) ) // Spin until the clear works - ; - } - // Non-atomic clear, preserving existing large arrays - public void clear(boolean large) { // Smack a new empty table down - for( int i=2; i<_kvs.length; i++ ) _kvs[i]=null; - Arrays.fill(hashes(_kvs),0); - chm(_kvs).clear(); - } - - /** Returns true if this Map maps one or more keys to the specified - * value. Note: This method requires a full internal traversal of the - * hash table and is much slower than {@link #containsKey}. - * @param val value whose presence in this map is to be tested - * @return true if this map maps one or more keys to the specified value - * @throws NullPointerException if the specified value is null */ - @Override - public boolean containsValue( final Object val ) { - if( val == null ) throw new NullPointerException(); - for( TypeV V : values() ) - if( V == val || V.equals(val) ) - return true; - return false; - } - - // This function is supposed to do something for Hashtable, and the JCK - // tests hang until it gets called... by somebody ... for some reason, - // any reason.... - protected void rehash() { - } - - /** - * Creates a shallow copy of this hashtable. All the structure of the - * hashtable itself is copied, but the keys and values are not cloned. - * This is a relatively expensive operation. - * - * @return a clone of the hashtable. - */ - @SuppressWarnings("unchecked") - @Override - public Object clone() { - try { - // Must clone, to get the class right; NBHM might have been - // extended, so it would be wrong to just make a new NBHM. - NonBlockingHashMap t = (NonBlockingHashMap) super.clone(); - // But I don't have an atomic clone operation - the underlying _kvs - // structure is undergoing rapid change. If I just clone the _kvs - // field, the CHM in _kvs[0] won't be in sync. - // - // Wipe out the cloned array (it was shallow anyways). - t.clear(); - // Now copy sanely - for( TypeK K : keySet() ) { - final TypeV V = get(K); // Do an official 'get' - t.put(K,V); - } - return t; - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new InternalError(); - } - } - - /** - * Returns a string representation of this map. The string representation - * consists of a list of key-value mappings in the order returned by the - * map's entrySet view's iterator, enclosed in braces - * ("{}"). Adjacent mappings are separated by the characters - * ", " (comma and space). Each key-value mapping is rendered as - * the key followed by an equals sign ("=") followed by the - * associated value. Keys and values are converted to strings as by - * {@link String#valueOf(Object)}. - * - * @return a string representation of this map - */ - @Override - public String toString() { - Iterator> i = entrySet().iterator(); - if( !i.hasNext()) - return "{}"; - - StringBuilder sb = new StringBuilder(); - sb.append('{'); - for (;;) { - Entry e = i.next(); - TypeK key = e.getKey(); - TypeV value = e.getValue(); - sb.append(key == this ? "(this Map)" : key); - sb.append('='); - sb.append(value == this ? "(this Map)" : value); - if( !i.hasNext()) - return sb.append('}').toString(); - sb.append(", "); - } - } - - // Get *any* valid Key. Useful for making worklists out of a hashtable - the - // hashtable can remove dup work. Repeated calls probably return the same - // Key, so only useful if keys are removed after calling. - @SuppressWarnings("unchecked") - public TypeK getKey() { return (TypeK)_getKey(_kvs); } - private static Object _getKey(Object[] kvs) { - for( int i=0; iMore formally, if this map contains a mapping from a key {@code k} to - * a value {@code v} such that {@code key.equals(k)}, then this method - * returns {@code v}; otherwise it returns {@code null}. (There can be at - * most one such mapping.) - * @throws NullPointerException if the specified key is null */ - // Never returns a Prime nor a Tombstone. - @SuppressWarnings("unchecked") - @Override - public TypeV get( Object key ) { - final Object V = get_impl(this,_kvs,key); - assert !(V instanceof Prime); // Never return a Prime - assert V != TOMBSTONE; - return (TypeV)V; - } - - private static Object get_impl( final NonBlockingHashMap topmap, final Object[] kvs, final Object key ) { - final int fullhash= hash (key); // throws NullPointerException if key is null - final int len = len (kvs); // Count of key/value pairs, reads kvs.length - final CHM chm = chm (kvs); // The CHM, for a volatile read below; reads slot 0 of kvs - final int[] hashes=hashes(kvs); // The memoized hashes; reads slot 1 of kvs - - int idx = fullhash & (len-1); // First key hash - - // Main spin/reprobe loop, looking for a Key hit - int reprobe_cnt=0; - try { - while( true ) { - // Probe table. Each read of 'val' probably misses in cache in a big - // table; hopefully the read of 'key' then hits in cache. - final Object K = key(kvs,idx); // Get key before volatile read, could be null - final Object V = val(kvs,idx); // Get value before volatile read, could be null or Tombstone or Prime - if( K == null ) return null; // A clear miss - - // We need a volatile-read here to preserve happens-before semantics on - // newly inserted Keys. If the Key body was written just before inserting - // into the table a Key-compare here might read the uninitialized Key body. - // Annoyingly this means we have to volatile-read before EACH key compare. - // . - // We also need a volatile-read between reading a newly inserted Value - // and returning the Value (so the user might end up reading the stale - // Value contents). Same problem as with keys - and the one volatile - // read covers both. - final Object[] newkvs = chm._newkvs; // VOLATILE READ before key compare - - // Key-compare - if( keyeq(K,key,hashes,idx,fullhash) ) { - // Key hit! Check for no table-copy-in-progress - if( !(V instanceof Prime) ) // No copy? - return (V == TOMBSTONE) ? null : V; // Return the value - // Key hit - but slot is (possibly partially) copied to the new table. - // Finish the copy & retry in the new table. - return get_impl(topmap,chm.copy_slot_and_check(topmap,kvs,idx,key),key); // Retry in the new table - } - // get and put must have the same key lookup logic! But only 'put' - // needs to force a table-resize for a too-long key-reprobe sequence. - // Check for too-many-reprobes on get - and flip to the new table. - if( ++reprobe_cnt >= reprobe_limit(len) || // too many probes - K == TOMBSTONE ) // found a TOMBSTONE key, means no more keys in this table - return newkvs == null ? null : get_impl(topmap,topmap.help_copy(newkvs),key); // Retry in the new table - - idx = (idx+((fullhash>>16)|1))&(len-1); // Divergent reprobe chain - } - } finally { - topmap.record(reprobe_cnt); - } - } - - // --- getk ----------------------------------------------------------------- - /** Returns the Key to which the specified key is mapped, or {@code null} - * if this map contains no mapping for the key. - * @throws NullPointerException if the specified key is null */ - // Never returns a Prime nor a Tombstone. - @SuppressWarnings("unchecked") - public TypeK getk( TypeK key ) { - return (TypeK)getk_impl(this,_kvs,key); - } - - private static final Object getk_impl( final NonBlockingHashMap topmap, final Object[] kvs, final Object key ) { - final int fullhash= hash (key); // throws NullPointerException if key is null - final int len = len (kvs); // Count of key/value pairs, reads kvs.length - final CHM chm = chm (kvs); // The CHM, for a volatile read below; reads slot 0 of kvs - final int[] hashes=hashes(kvs); // The memoized hashes; reads slot 1 of kvs - - int idx = fullhash & (len-1); // First key hash - - // Main spin/reprobe loop, looking for a Key hit - int reprobe_cnt=0; - try { - while( true ) { - // Probe table. - final Object K = key(kvs,idx); // Get key before volatile read, could be null - if( K == null ) return null; // A clear miss - - // We need a volatile-read here to preserve happens-before semantics on - // newly inserted Keys. If the Key body was written just before inserting - // into the table a Key-compare here might read the uninitialized Key body. - // Annoyingly this means we have to volatile-read before EACH key compare. - // . - // We also need a volatile-read between reading a newly inserted Value - // and returning the Value (so the user might end up reading the stale - // Value contents). Same problem as with keys - and the one volatile - // read covers both. - final Object[] newkvs = chm._newkvs; // VOLATILE READ before key compare - - // Key-compare - if( keyeq(K,key,hashes,idx,fullhash) ) - return K; // Return existing Key! - - // get and put must have the same key lookup logic! But only 'put' - // needs to force a table-resize for a too-long key-reprobe sequence. - // Check for too-many-reprobes on get - and flip to the new table. - if( ++reprobe_cnt >= reprobe_limit(len) || // too many probes - K == TOMBSTONE ) { // found a TOMBSTONE key, means no more keys in this table - return newkvs == null ? null : getk_impl(topmap,topmap.help_copy(newkvs),key); // Retry in the new table - } - - idx = (idx+((fullhash>>16)|1))&(len-1); // Divergent reprobe chain - } - } finally { - topmap.record(reprobe_cnt); - } - } - - // --- putIfMatch --------------------------------------------------------- - // Put, Remove, PutIfAbsent, etc. Return the old value. If the returned - // value is equal to expVal (or expVal is NO_MATCH_OLD) then the put can be - // assumed to work (although might have been immediately overwritten). Only - // the path through copy_slot passes in an expected value of null, and - // putIfMatch only returns a null if passed in an expected null. - static volatile int DUMMY_VOLATILE; - private static final Object putIfMatch( final NonBlockingHashMap topmap, final Object[] kvs, final Object key, final Object putval, final Object expVal ) { - assert putval != null; - assert !(putval instanceof Prime); - assert !(expVal instanceof Prime); - final int fullhash = hash (key); // throws NullPointerException if key null - final int len = len (kvs); // Count of key/value pairs, reads kvs.length - final CHM chm = chm (kvs); // Reads kvs[0] - final int[] hashes = hashes(kvs); // Reads kvs[1], read before kvs[0] - int idx = fullhash & (len-1); - - // --- - // Key-Claim stanza: spin till we can claim a Key (or force a resizing). - int reprobe_cnt=0; - Object K=null, V=null; - Object[] newkvs=null; - try { - while( true ) { // Spin till we get a Key slot - V = val(kvs,idx); // Get old value (before volatile read below!) - K = key(kvs,idx); // Get current key - if( K == null ) { // Slot is free? - // Found an empty Key slot - which means this Key has never been in - // this table. No need to put a Tombstone - the Key is not here! - if( putval == TOMBSTONE ) return putval; // Not-now & never-been in this table - if( expVal == MATCH_ANY ) return null; // Will not match, even after K inserts - // Claim the null key-slot - if( CAS_key(kvs,idx, null, key ) ) { // Claim slot for Key - chm._slots.add(1); // Raise key-slots-used count - hashes[idx] = fullhash; // Memoize fullhash - break; // Got it! - } - // CAS to claim the key-slot failed. - // - // This re-read of the Key points out an annoying short-coming of Java - // CAS. Most hardware CAS's report back the existing value - so that - // if you fail you have a *witness* - the value which caused the CAS to - // fail. The Java API turns this into a boolean destroying the - // witness. Re-reading does not recover the witness because another - // thread can write over the memory after the CAS. Hence we can be in - // the unfortunate situation of having a CAS fail *for cause* but - // having that cause removed by a later store. This turns a - // non-spurious-failure CAS (such as Azul has) into one that can - // apparently spuriously fail - and we avoid apparent spurious failure - // by not allowing Keys to ever change. - - // Volatile read, to force loads of K to retry despite JIT, otherwise - // it is legal to e.g. haul the load of "K = key(kvs,idx);" outside of - // this loop (since failed CAS ops have no memory ordering semantics). - int dummy = DUMMY_VOLATILE; - continue; - } - // Key slot was not null, there exists a Key here - - // We need a volatile-read here to preserve happens-before semantics on - // newly inserted Keys. If the Key body was written just before inserting - // into the table a Key-compare here might read the uninitialized Key body. - // Annoyingly this means we have to volatile-read before EACH key compare. - newkvs = chm._newkvs; // VOLATILE READ before key compare - - if( keyeq(K,key,hashes,idx,fullhash) ) - break; // Got it! - - // get and put must have the same key lookup logic! Lest 'get' give - // up looking too soon. - //topmap._reprobes.add(1); - if( ++reprobe_cnt >= reprobe_limit(len) || // too many probes or - K == TOMBSTONE ) { // found a TOMBSTONE key, means no more keys - // We simply must have a new table to do a 'put'. At this point a - // 'get' will also go to the new table (if any). We do not need - // to claim a key slot (indeed, we cannot find a free one to claim!). - newkvs = chm.resize(topmap,kvs); - if( expVal != null ) topmap.help_copy(newkvs); // help along an existing copy - return putIfMatch(topmap,newkvs,key,putval,expVal); - } - - idx = (idx+((fullhash>>16)|1))&(len-1); // Divergent reprobe chain - } // End of spinning till we get a Key slot - } finally { - topmap.record(reprobe_cnt); - } - - // --- - // Found the proper Key slot, now update the matching Value slot. We - // never put a null, so Value slots monotonically move from null to - // not-null (deleted Values use Tombstone). Thus if 'V' is null we - // fail this fast cutout and fall into the check for table-full. - if( putval == V ) return V; // Fast cutout for no-change - - // See if we want to move to a new table (to avoid high average re-probe - // counts). We only check on the initial set of a Value from null to - // not-null (i.e., once per key-insert). Of course we got a 'free' check - // of newkvs once per key-compare (not really free, but paid-for by the - // time we get here). - if( newkvs == null && // New table-copy already spotted? - // Once per fresh key-insert check the hard way - ((V == null && chm.tableFull(reprobe_cnt,len)) || - // Or we found a Prime, but the JMM allowed reordering such that we - // did not spot the new table (very rare race here: the writing - // thread did a CAS of _newkvs then a store of a Prime. This thread - // reads the Prime, then reads _newkvs - but the read of Prime was so - // delayed (or the read of _newkvs was so accelerated) that they - // swapped and we still read a null _newkvs. The resize call below - // will do a CAS on _newkvs forcing the read. - V instanceof Prime) ) - newkvs = chm.resize(topmap,kvs); // Force the new table copy to start - // See if we are moving to a new table. - // If so, copy our slot and retry in the new table. - if( newkvs != null ) - return putIfMatch(topmap,chm.copy_slot_and_check(topmap,kvs,idx,expVal),key,putval,expVal); - - // --- - // We are finally prepared to update the existing table - assert !(V instanceof Prime); - - // Must match old, and we do not? Then bail out now. Note that either V - // or expVal might be TOMBSTONE. Also V can be null, if we've never - // inserted a value before. expVal can be null if we are called from - // copy_slot. - - if( expVal != NO_MATCH_OLD && // Do we care about expected-Value at all? - V != expVal && // No instant match already? - (expVal != MATCH_ANY || V == TOMBSTONE || V == null) && - !(V==null && expVal == TOMBSTONE) && // Match on null/TOMBSTONE combo - (expVal == null || !expVal.equals(V)) ) // Expensive equals check at the last - return V; // Do not update! - - // Actually change the Value in the Key,Value pair - if( CAS_val(kvs, idx, V, putval ) ) { - // CAS succeeded - we did the update! - // Both normal put's and table-copy calls putIfMatch, but table-copy - // does not (effectively) increase the number of live k/v pairs. - if( expVal != null ) { - // Adjust sizes - a striped counter - if( (V == null || V == TOMBSTONE) && putval != TOMBSTONE ) chm._size.add( 1); - if( !(V == null || V == TOMBSTONE) && putval == TOMBSTONE ) chm._size.add(-1); - } - } else { // Else CAS failed - V = val(kvs,idx); // Get new value - // If a Prime'd value got installed, we need to re-run the put on the - // new table. Otherwise we lost the CAS to another racing put. - // Simply retry from the start. - if( V instanceof Prime ) - return putIfMatch(topmap,chm.copy_slot_and_check(topmap,kvs,idx,expVal),key,putval,expVal); - } - // Win or lose the CAS, we are done. If we won then we know the update - // happened as expected. If we lost, it means "we won but another thread - // immediately stomped our update with no chance of a reader reading". - return (V==null && expVal!=null) ? TOMBSTONE : V; - } - - // --- help_copy --------------------------------------------------------- - // Help along an existing resize operation. This is just a fast cut-out - // wrapper, to encourage inlining for the fast no-copy-in-progress case. We - // always help the top-most table copy, even if there are nested table - // copies in progress. - private final Object[] help_copy( Object[] helper ) { - // Read the top-level KVS only once. We'll try to help this copy along, - // even if it gets promoted out from under us (i.e., the copy completes - // and another KVS becomes the top-level copy). - Object[] topkvs = _kvs; - CHM topchm = chm(topkvs); - if( topchm._newkvs == null ) return helper; // No copy in-progress - topchm.help_copy_impl(this,topkvs,false); - return helper; - } - - - // --- CHM ----------------------------------------------------------------- - // The control structure for the NonBlockingHashMap - private static final class CHM { - // Size in active K,V pairs - private final ConcurrentAutoTable _size; - public int size () { return (int)_size.get(); } - - // --- - // These next 2 fields are used in the resizing heuristics, to judge when - // it is time to resize or copy the table. Slots is a count of used-up - // key slots, and when it nears a large fraction of the table we probably - // end up reprobing too much. Last-resize-milli is the time since the - // last resize; if we are running back-to-back resizes without growing - // (because there are only a few live keys but many slots full of dead - // keys) then we need a larger table to cut down on the churn. - - // Count of used slots, to tell when table is full of dead unusable slots - private final ConcurrentAutoTable _slots; - public int slots() { return (int)_slots.get(); } - - // --- - // New mappings, used during resizing. - // The 'new KVs' array - created during a resize operation. This - // represents the new table being copied from the old one. It's the - // volatile variable that is read as we cross from one table to the next, - // to get the required memory orderings. It monotonically transits from - // null to set (once). - volatile Object[] _newkvs; - private final AtomicReferenceFieldUpdater _newkvsUpdater = - AtomicReferenceFieldUpdater.newUpdater(CHM.class,Object[].class, "_newkvs"); - // Set the _next field if we can. - boolean CAS_newkvs( Object[] newkvs ) { - while( _newkvs == null ) - if( _newkvsUpdater.compareAndSet(this,null,newkvs) ) - return true; - return false; - } - - // Sometimes many threads race to create a new very large table. Only 1 - // wins the race, but the losers all allocate a junk large table with - // hefty allocation costs. Attempt to control the overkill here by - // throttling attempts to create a new table. I cannot really block here - // (lest I lose the non-blocking property) but late-arriving threads can - // give the initial resizing thread a little time to allocate the initial - // new table. The Right Long Term Fix here is to use array-lets and - // incrementally create the new very large array. In C I'd make the array - // with malloc (which would mmap under the hood) which would only eat - // virtual-address and not real memory - and after Somebody wins then we - // could in parallel initialize the array. Java does not allow - // un-initialized array creation (especially of ref arrays!). - volatile long _resizers; // count of threads attempting an initial resize - private static final AtomicLongFieldUpdater _resizerUpdater = - AtomicLongFieldUpdater.newUpdater(CHM.class, "_resizers"); - - // --- - // Simple constructor - CHM( ConcurrentAutoTable size ) { - _size = size; - _slots= new ConcurrentAutoTable(); - } - - // Fast, not-atomic clear - public void clear() { _size.clear(); _slots.clear(); } - - // --- tableFull --------------------------------------------------------- - // Heuristic to decide if this table is too full, and we should start a - // new table. Note that if a 'get' call has reprobed too many times and - // decided the table must be full, then always the estimate_sum must be - // high and we must report the table is full. If we do not, then we might - // end up deciding that the table is not full and inserting into the - // current table, while a 'get' has decided the same key cannot be in this - // table because of too many reprobes. The invariant is: - // slots.estimate_sum >= max_reprobe_cnt >= reprobe_limit(len) - private final boolean tableFull( int reprobe_cnt, int len ) { - return - // Do the cheap check first: we allow some number of reprobes always - reprobe_cnt >= REPROBE_LIMIT && - (reprobe_cnt >= reprobe_limit(len) || - // More expensive check: see if the table is > 1/2 full. - _slots.estimate_get() >= (len>>1)); - } - - // --- resize ------------------------------------------------------------ - // Resizing after too many probes. "How Big???" heuristics are here. - // Callers will (not this routine) will 'help_copy' any in-progress copy. - // Since this routine has a fast cutout for copy-already-started, callers - // MUST 'help_copy' lest we have a path which forever runs through - // 'resize' only to discover a copy-in-progress which never progresses. - private final Object[] resize( NonBlockingHashMap topmap, Object[] kvs) { - assert chm(kvs) == this; - - // Check for resize already in progress, probably triggered by another thread - Object[] newkvs = _newkvs; // VOLATILE READ - if( newkvs != null ) // See if resize is already in progress - return newkvs; // Use the new table already - - // No copy in-progress, so start one. First up: compute new table size. - int oldlen = len(kvs); // Old count of K,V pairs allowed - int sz = size(); // Get current table count of active K,V pairs - int newsz = sz; // First size estimate - - // Heuristic to determine new size. We expect plenty of dead-slots-with-keys - // and we need some decent padding to avoid endless reprobing. - if( sz >= (oldlen>>2) ) { // If we are >25% full of keys then... - newsz = oldlen<<1; // Double size, so new table will be between 12.5% and 25% full - // For tables less than 1M entries, if >50% full of keys then... - // For tables more than 1M entries, if >75% full of keys then... - if( 4L*sz >= ((oldlen>>20)!=0?3L:2L)*oldlen ) - newsz = oldlen<<2; // Double double size, so new table will be between %12.5 (18.75%) and 25% (25%) - } - // This heuristic in the next 2 lines leads to a much denser table - // with a higher reprobe rate - //if( sz >= (oldlen>>1) ) // If we are >50% full of keys then... - // newsz = oldlen<<1; // Double size - - // Last (re)size operation was very recent? Then double again; slows - // down resize operations for tables subject to a high key churn rate. - long tm = System.currentTimeMillis(); - long q=0; - if( newsz <= oldlen && // New table would shrink or hold steady? - (tm <= topmap._last_resize_milli+10000 || // Recent resize (less than 10 sec ago) - (q=_slots.estimate_get()) >= (sz<<1)) ) // 1/2 of keys are dead? - newsz = oldlen<<1; // Double the existing size - - // Do not shrink, ever - if( newsz < oldlen ) newsz = oldlen; - - // Convert to power-of-2 - int log2; - for( log2=MIN_SIZE_LOG; (1< ((len >> 2) + (len >> 1))) throw new RuntimeException("Table is full."); - } - - // Now limit the number of threads actually allocating memory to a - // handful - lest we have 750 threads all trying to allocate a giant - // resized array. - long r = _resizers; - while( !_resizerUpdater.compareAndSet(this,r,r+1) ) - r = _resizers; - // Size calculation: 2 words (K+V) per table entry, plus a handful. We - // guess at 64-bit pointers; 32-bit pointers screws up the size calc by - // 2x but does not screw up the heuristic very much. - long megs = ((((1L<>20/*megs*/; - if( r >= 2 && megs > 0 ) { // Already 2 guys trying; wait and see - newkvs = _newkvs; // Between dorking around, another thread did it - if( newkvs != null ) // See if resize is already in progress - return newkvs; // Use the new table already - // TODO - use a wait with timeout, so we'll wakeup as soon as the new table - // is ready, or after the timeout in any case. - //synchronized( this ) { wait(8*megs); } // Timeout - we always wakeup - // For now, sleep a tad and see if the 2 guys already trying to make - // the table actually get around to making it happen. - try { Thread.sleep(megs); } catch( Exception e ) { } - } - // Last check, since the 'new' below is expensive and there is a chance - // that another thread slipped in a new thread while we ran the heuristic. - newkvs = _newkvs; - if( newkvs != null ) // See if resize is already in progress - return newkvs; // Use the new table already - - // Double size for K,V pairs, add 1 for CHM - newkvs = new Object[(int)len]; // This can get expensive for big arrays - newkvs[0] = new CHM(_size); // CHM in slot 0 - newkvs[1] = new int[1< _copyIdxUpdater = - AtomicLongFieldUpdater.newUpdater(CHM.class, "_copyIdx"); - - // Work-done reporting. Used to efficiently signal when we can move to - // the new table. From 0 to len(oldkvs) refers to copying from the old - // table to the new. - volatile long _copyDone= 0; - static private final AtomicLongFieldUpdater _copyDoneUpdater = - AtomicLongFieldUpdater.newUpdater(CHM.class, "_copyDone"); - - // --- help_copy_impl ---------------------------------------------------- - // Help along an existing resize operation. We hope its the top-level - // copy (it was when we started) but this CHM might have been promoted out - // of the top position. - private final void help_copy_impl( NonBlockingHashMap topmap, Object[] oldkvs, boolean copy_all ) { - assert chm(oldkvs) == this; - Object[] newkvs = _newkvs; - assert newkvs != null; // Already checked by caller - int oldlen = len(oldkvs); // Total amount to copy - final int MIN_COPY_WORK = Math.min(oldlen,1024); // Limit per-thread work - - // --- - int panic_start = -1; - int copyidx=-9999; // Fool javac to think it's initialized - while( _copyDone < oldlen ) { // Still needing to copy? - // Carve out a chunk of work. The counter wraps around so every - // thread eventually tries to copy every slot repeatedly. - - // We "panic" if we have tried TWICE to copy every slot - and it still - // has not happened. i.e., twice some thread somewhere claimed they - // would copy 'slot X' (by bumping _copyIdx) but they never claimed to - // have finished (by bumping _copyDone). Our choices become limited: - // we can wait for the work-claimers to finish (and become a blocking - // algorithm) or do the copy work ourselves. Tiny tables with huge - // thread counts trying to copy the table often 'panic'. - if( panic_start == -1 ) { // No panic? - copyidx = (int)_copyIdx; - while( !_copyIdxUpdater.compareAndSet(this,copyidx,copyidx+MIN_COPY_WORK) ) - copyidx = (int)_copyIdx; // Re-read - if( !(copyidx < (oldlen<<1)) ) // Panic! - panic_start = copyidx; // Record where we started to panic-copy - } - - // We now know what to copy. Try to copy. - int workdone = 0; - for( int i=0; i 0 ) // Report work-done occasionally - copy_check_and_promote( topmap, oldkvs, workdone );// See if we can promote - - copyidx += MIN_COPY_WORK; - // Uncomment these next 2 lines to turn on incremental table-copy. - // Otherwise this thread continues to copy until it is all done. - if( !copy_all && panic_start == -1 ) // No panic? - return; // Then done copying after doing MIN_COPY_WORK - } - // Extra promotion check, in case another thread finished all copying - // then got stalled before promoting. - copy_check_and_promote( topmap, oldkvs, 0 );// See if we can promote - } - - // --- copy_slot_and_check ----------------------------------------------- - // Copy slot 'idx' from the old table to the new table. If this thread - // confirmed the copy, update the counters and check for promotion. - // - // Returns the result of reading the volatile _newkvs, mostly as a - // convenience to callers. We come here with 1-shot copy requests - // typically because the caller has found a Prime, and has not yet read - // the _newkvs volatile - which must have changed from null-to-not-null - // before any Prime appears. So the caller needs to read the _newkvs - // field to retry his operation in the new table, but probably has not - // read it yet. - private final Object[] copy_slot_and_check( NonBlockingHashMap topmap, Object[] oldkvs, int idx, Object should_help ) { - assert chm(oldkvs) == this; - Object[] newkvs = _newkvs; // VOLATILE READ - // We're only here because the caller saw a Prime, which implies a - // table-copy is in progress. - assert newkvs != null; - if( copy_slot(topmap,idx,oldkvs,_newkvs) ) // Copy the desired slot - copy_check_and_promote(topmap, oldkvs, 1); // Record the slot copied - // Generically help along any copy (except if called recursively from a helper) - return (should_help == null) ? newkvs : topmap.help_copy(newkvs); - } - - // --- copy_check_and_promote -------------------------------------------- - private final void copy_check_and_promote( NonBlockingHashMap topmap, Object[] oldkvs, int workdone ) { - assert chm(oldkvs) == this; - int oldlen = len(oldkvs); - // We made a slot unusable and so did some of the needed copy work - long copyDone = _copyDone; - assert (copyDone+workdone) <= oldlen; - if( workdone > 0 ) { - while( !_copyDoneUpdater.compareAndSet(this,copyDone,copyDone+workdone) ) { - copyDone = _copyDone; // Reload, retry - assert (copyDone+workdone) <= oldlen; - } - //if( (10*copyDone/oldlen) != (10*(copyDone+workdone)/oldlen) ) - //System.out.print(" "+(copyDone+workdone)*100/oldlen+"%"+"_"+(_copyIdx*100/oldlen)+"%"); - } - - // Check for copy being ALL done, and promote. Note that we might have - // nested in-progress copies and manage to finish a nested copy before - // finishing the top-level copy. We only promote top-level copies. - if( copyDone+workdone == oldlen && // Ready to promote this table? - topmap._kvs == oldkvs && // Looking at the top-level table? - // Attempt to promote - topmap.CAS_kvs(oldkvs,_newkvs) ) { - topmap._last_resize_milli = System.currentTimeMillis(); // Record resize time for next check - //long nano = System.nanoTime(); - //System.out.println(" "+nano+" Promote table to "+len(_newkvs)); - //if( System.out != null ) System.out.print("]"); - } - } - - // --- copy_slot --------------------------------------------------------- - // Copy one K/V pair from oldkvs[i] to newkvs. Returns true if we can - // confirm that the new table guaranteed has a value for this old-table - // slot. We need an accurate confirmed-copy count so that we know when we - // can promote (if we promote the new table too soon, other threads may - // 'miss' on values not-yet-copied from the old table). We don't allow - // any direct updates on the new table, unless they first happened to the - // old table - so that any transition in the new table from null to - // not-null must have been from a copy_slot (or other old-table overwrite) - // and not from a thread directly writing in the new table. Thus we can - // count null-to-not-null transitions in the new table. - private boolean copy_slot( NonBlockingHashMap topmap, int idx, Object[] oldkvs, Object[] newkvs ) { - // Blindly set the key slot from null to TOMBSTONE, to eagerly stop - // fresh put's from inserting new values in the old table when the old - // table is mid-resize. We don't need to act on the results here, - // because our correctness stems from box'ing the Value field. Slamming - // the Key field is a minor speed optimization. - Object key; - while( (key=key(oldkvs,idx)) == null ) - CAS_key(oldkvs,idx, null, TOMBSTONE); - - // --- - // Prevent new values from appearing in the old table. - // Box what we see in the old table, to prevent further updates. - Object oldval = val(oldkvs,idx); // Read OLD table - while( !(oldval instanceof Prime) ) { - final Prime box = (oldval == null || oldval == TOMBSTONE) ? TOMBPRIME : new Prime(oldval); - if( CAS_val(oldkvs,idx,oldval,box) ) { // CAS down a box'd version of oldval - // If we made the Value slot hold a TOMBPRIME, then we both - // prevented further updates here but also the (absent) - // oldval is vacuously available in the new table. We - // return with true here: any thread looking for a value for - // this key can correctly go straight to the new table and - // skip looking in the old table. - if( box == TOMBPRIME ) - return true; - // Otherwise we boxed something, but it still needs to be - // copied into the new table. - oldval = box; // Record updated oldval - break; // Break loop; oldval is now boxed by us - } - oldval = val(oldkvs,idx); // Else try, try again - } - if( oldval == TOMBPRIME ) return false; // Copy already complete here! - - // --- - // Copy the value into the new table, but only if we overwrite a null. - // If another value is already in the new table, then somebody else - // wrote something there and that write is happens-after any value that - // appears in the old table. If putIfMatch does not find a null in the - // new table - somebody else should have recorded the null-not_null - // transition in this copy. - Object old_unboxed = ((Prime)oldval)._V; - assert old_unboxed != TOMBSTONE; - putIfMatch(topmap, newkvs, key, old_unboxed, null); - - // --- - // Finally, now that any old value is exposed in the new table, we can - // forever hide the old-table value by slapping a TOMBPRIME down. This - // will stop other threads from uselessly attempting to copy this slot - // (i.e., it's a speed optimization not a correctness issue). - while( oldval != TOMBPRIME && !CAS_val(oldkvs,idx,oldval,TOMBPRIME) ) - oldval = val(oldkvs,idx); - - return true; - } // end copy_slot - } // End of CHM - - - // --- Snapshot ------------------------------------------------------------ - // The main class for iterating over the NBHM. It "snapshots" a clean - // view of the K/V array. - private class SnapshotV implements Iterator, Enumeration { - final Object[] _sskvs; - public SnapshotV() { - while( true ) { // Verify no table-copy-in-progress - Object[] topkvs = _kvs; - CHM topchm = chm(topkvs); - if( topchm._newkvs == null ) { // No table-copy-in-progress - // The "linearization point" for the iteration. Every key in this - // table will be visited, but keys added later might be skipped or - // even be added to a following table (also not iterated over). - _sskvs = topkvs; - break; - } - // Table copy in-progress - so we cannot get a clean iteration. We - // must help finish the table copy before we can start iterating. - topchm.help_copy_impl(NonBlockingHashMap.this,topkvs,true); - } - // Warm-up the iterator - next(); - } - int length() { return len(_sskvs); } - Object key(int idx) { return NonBlockingHashMap.key(_sskvs,idx); } - Object val(int idx) { return NonBlockingHashMap.val(_sskvs,idx); } - private int _idx; // Varies from 0-keys.length - private Object _nextK, _prevK; // Last 2 keys found - private TypeV _nextV, _prevV; // Last 2 values found - public boolean hasNext() { return _nextV != null; } - @SuppressWarnings("unchecked") - public TypeV next() { - // 'next' actually knows what the next value will be - it had to - // figure that out last go-around lest 'hasNext' report true and - // some other thread deleted the last value. Instead, 'next' - // spends all its effort finding the key that comes after the - // 'next' key. - if( _idx != 0 && _nextV == null ) throw new NoSuchElementException(); - _prevK = _nextK; // This will become the previous key - _prevV = _nextV; // This will become the previous value - _nextV = null; // We have no more next-key - Object nV; - // Attempt to set <_nextK,_nextV> to the next K,V pair. - // _nextV is the trigger: stop searching when it is != null - while( _idx elements() { return new SnapshotV(); } - - // --- values -------------------------------------------------------------- - /** Returns a {@link Collection} view of the values contained in this map. - * The collection is backed by the map, so changes to the map are reflected - * in the collection, and vice-versa. The collection supports element - * removal, which removes the corresponding mapping from this map, via the - * Iterator.remove, Collection.remove, - * removeAll, retainAll, and clear operations. - * It does not support the add or addAll operations. - * - *

The view's iterator is a "weakly consistent" iterator that - * will never throw {@link ConcurrentModificationException}, and guarantees - * to traverse elements as they existed upon construction of the iterator, - * and may (but is not guaranteed to) reflect any modifications subsequent - * to construction. */ - @Override - public Collection values() { - return new AbstractCollection() { - @Override public void clear ( ) { NonBlockingHashMap.this.clear ( ); } - @Override public int size ( ) { return NonBlockingHashMap.this.size ( ); } - @Override public boolean contains( Object v ) { return NonBlockingHashMap.this.containsValue(v); } - @Override public Iterator iterator() { return new SnapshotV(); } - }; - } - - // --- keySet -------------------------------------------------------------- - @SuppressWarnings("unchecked") - private class SnapshotK implements Iterator, Enumeration { - final SnapshotV _ss; - public SnapshotK() { _ss = new SnapshotV(); } - public void remove() { _ss.remove(); } - public TypeK next() { _ss.next(); return (TypeK)_ss._prevK; } - public boolean hasNext() { return _ss.hasNext(); } - public TypeK nextElement() { return next(); } - public boolean hasMoreElements() { return hasNext(); } - } - - /** Returns an enumeration of the keys in this table. - * @return an enumeration of the keys in this table - * @see #keySet() */ - public Enumeration keys() { return new SnapshotK(); } - - /** Returns a {@link Set} view of the keys contained in this map. The set - * is backed by the map, so changes to the map are reflected in the set, - * and vice-versa. The set supports element removal, which removes the - * corresponding mapping from this map, via the Iterator.remove, - * Set.remove, removeAll, retainAll, and - * clear operations. It does not support the add or - * addAll operations. - * - *

The view's iterator is a "weakly consistent" iterator that - * will never throw {@link ConcurrentModificationException}, and guarantees - * to traverse elements as they existed upon construction of the iterator, - * and may (but is not guaranteed to) reflect any modifications subsequent - * to construction. */ - @Override - public Set keySet() { - return new AbstractSet () { - @Override public void clear ( ) { NonBlockingHashMap.this.clear ( ); } - @Override public int size ( ) { return NonBlockingHashMap.this.size ( ); } - @Override public boolean contains( Object k ) { return NonBlockingHashMap.this.containsKey(k); } - @Override public boolean remove ( Object k ) { return NonBlockingHashMap.this.remove (k) != null; } - @Override public Iterator iterator() { return new SnapshotK(); } - }; - } - - - // --- entrySet ------------------------------------------------------------ - // Warning: Each call to 'next' in this iterator constructs a new NBHMEntry. - private class NBHMEntry extends AbstractEntry { - NBHMEntry( final TypeK k, final TypeV v ) { super(k,v); } - public TypeV setValue(final TypeV val) { - if( val == null ) throw new NullPointerException(); - _val = val; - return put(_key, val); - } - } - - @SuppressWarnings("unchecked") - private class SnapshotE implements Iterator> { - final SnapshotV _ss; - public SnapshotE() { _ss = new SnapshotV(); } - public void remove() { _ss.remove(); } - public Map.Entry next() { _ss.next(); return new NBHMEntry((TypeK)_ss._prevK,_ss._prevV); } - public boolean hasNext() { return _ss.hasNext(); } - } - - /** Returns a {@link Set} view of the mappings contained in this map. The - * set is backed by the map, so changes to the map are reflected in the - * set, and vice-versa. The set supports element removal, which removes - * the corresponding mapping from the map, via the - * Iterator.remove, Set.remove, removeAll, - * retainAll, and clear operations. It does not support - * the add or addAll operations. - * - *

The view's iterator is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. - * - *

Warning: the iterator associated with this Set - * requires the creation of {@link java.util.Map.Entry} objects with each - * iteration. The {@link NonBlockingHashMap} does not normally create or - * using {@link java.util.Map.Entry} objects so they will be created soley - * to support this iteration. Iterating using {@link #keySet} or {@link - * #values} will be more efficient. - */ - @Override - public Set> entrySet() { - return new AbstractSet>() { - @Override public void clear ( ) { NonBlockingHashMap.this.clear( ); } - @Override public int size ( ) { return NonBlockingHashMap.this.size ( ); } - @Override public boolean remove( final Object o ) { - if( !(o instanceof Map.Entry)) return false; - final Map.Entry e = (Map.Entry)o; - return NonBlockingHashMap.this.remove(e.getKey(), e.getValue()); - } - @Override public boolean contains(final Object o) { - if( !(o instanceof Map.Entry)) return false; - final Map.Entry e = (Map.Entry)o; - TypeV v = get(e.getKey()); - return v.equals(e.getValue()); - } - @Override public Iterator> iterator() { return new SnapshotE(); } - }; - } - - // --- writeObject ------------------------------------------------------- - // Write a NBHM to a stream - private void writeObject(java.io.ObjectOutputStream s) throws IOException { - s.defaultWriteObject(); // Nothing to write - for( Object K : keySet() ) { - final Object V = get(K); // Do an official 'get' - s.writeObject(K); // Write the pair - s.writeObject(V); - } - s.writeObject(null); // Sentinel to indicate end-of-data - s.writeObject(null); - } - - // --- readObject -------------------------------------------------------- - // Read a CHM from a stream - @SuppressWarnings("unchecked") - private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { - s.defaultReadObject(); // Read nothing - initialize(MIN_SIZE); - for(;;) { - final TypeK K = (TypeK) s.readObject(); - final TypeV V = (TypeV) s.readObject(); - if( K == null ) break; - put(K,V); // Insert with an offical put - } - } - -} // End NonBlockingHashMap class diff --git a/javatools_backend/src/main/java/org/xvm/util/NonBlockingHashMapLong.java b/javatools_backend/src/main/java/org/xvm/util/NonBlockingHashMapLong.java deleted file mode 100644 index a9806ea293..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/NonBlockingHashMapLong.java +++ /dev/null @@ -1,1355 +0,0 @@ -package org.xvm.util; - -import java.io.IOException; -import java.io.Serializable; -import java.util.*; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicLongFieldUpdater; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - -import static org.xvm.util.UtilUnsafe.UNSAFE; -import static org.xvm.util.UtilUnsafe.fieldOffset; - -/* - * Written by Cliff Click and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -/** - * A lock-free alternate implementation of {@link java.util.concurrent.ConcurrentHashMap} - * with primitive long keys, better scaling properties and - * generally lower costs. The use of {@code long} keys allows for faster - * compares and lower memory costs. The Map provides identical correctness - * properties as ConcurrentHashMap. All operations are non-blocking and - * multi-thread safe, including all update operations. {@link - * NonBlockingHashMapLong} scales substatially better than {@link - * java.util.concurrent.ConcurrentHashMap} for high update rates, even with a large - * concurrency factor. Scaling is linear up to 768 CPUs on a 768-CPU Azul - * box, even with 100% updates or 100% reads or any fraction in-between. - * Linear scaling up to all cpus has been observed on a 32-way Sun US2 box, - * 32-way Sun Niagra box, 8-way Intel box and a 4-way Power box. - * - *

The main benefit of this class over using plain {@link - * org.jctools.maps.NonBlockingHashMap} with {@link Long} keys is - * that it avoids the auto-boxing and unboxing costs. Since auto-boxing is - * automatic, it is easy to accidentally cause auto-boxing and negate - * the space and speed benefits. - * - *

This class obeys the same functional specification as {@link - * java.util.Hashtable}, and includes versions of methods corresponding to - * each method of Hashtable. However, even though all operations are - * thread-safe, operations do not entail locking and there is - * not any support for locking the entire table in a way that - * prevents all access. This class is fully interoperable with - * Hashtable in programs that rely on its thread safety but not on - * its synchronization details. - * - *

Operations (including put) generally do not block, so may - * overlap with other update operations (including other puts and - * removes). Retrievals reflect the results of the most recently - * completed update operations holding upon their onset. For - * aggregate operations such as putAll, concurrent retrievals may - * reflect insertion or removal of only some entries. Similarly, Iterators - * and Enumerations return elements reflecting the state of the hash table at - * some point at or since the creation of the iterator/enumeration. They do - * not throw {@link ConcurrentModificationException}. However, - * iterators are designed to be used by only one thread at a time. - * - *

Very full tables, or tables with high re-probe rates may trigger an - * internal resize operation to move into a larger table. Resizing is not - * terribly expensive, but it is not free either; during resize operations - * table throughput may drop somewhat. All threads that visit the table - * during a resize will 'help' the resizing but will still be allowed to - * complete their operation before the resize is finished (i.e., a simple - * 'get' operation on a million-entry table undergoing resizing will not need - * to block until the entire million entries are copied). - * - *

This class and its views and iterators implement all of the - * optional methods of the {@link Map} and {@link Iterator} - * interfaces. - * - *

Like {@link Hashtable} but unlike {@link HashMap}, this class - * does not allow null to be used as a value. - * - * - * @since 1.5 - * @author Cliff Click - * @param the type of mapped values - */ - -public class NonBlockingHashMapLong - extends AbstractMap - implements ConcurrentMap, Cloneable, Serializable { - - private static final long serialVersionUID = 1234123412341234124L; - - private static final int REPROBE_LIMIT=10; // Too many reprobes then force a table-resize - - // --- Bits to allow Unsafe access to arrays - private static final int _Obase = UNSAFE.arrayBaseOffset(Object[].class); - private static final int _Oscale = UNSAFE.arrayIndexScale(Object[].class); - private static long rawIndex(final Object[] ary, final int idx) { - assert idx >= 0 && idx < ary.length; - // Note the long-math requirement, to handle arrays of more than 2^31 bytes - // - or 2^28 - or about 268M - 8-byte pointer elements. - return _Obase + ((long)idx * _Oscale); - } - private static final int _Lbase = UNSAFE.arrayBaseOffset(long[].class); - private static final int _Lscale = UNSAFE.arrayIndexScale(long[].class); - private static long rawIndex(final long[] ary, final int idx) { - assert idx >= 0 && idx < ary.length; - // Note the long-math requirement, to handle arrays of more than 2^31 bytes - // - or 2^28 - or about 268M - 8-byte pointer elements. - return _Lbase + ((long)idx * _Lscale); - } - - // --- Bits to allow Unsafe CAS'ing of the CHM field - private static final long _chm_offset = fieldOffset(NonBlockingHashMapLong.class, "_chm"); - private static final long _val_1_offset = fieldOffset(NonBlockingHashMapLong.class, "_val_1"); - - private boolean CAS( final long offset, final Object old, final Object nnn ) { - return UNSAFE.compareAndSwapObject(this, offset, old, nnn ); - } - - // --- Adding a 'prime' bit onto Values via wrapping with a junk wrapper class - private static final class Prime { - final Object _V; - Prime( Object V ) { _V = V; } - static Object unbox( Object V ) { return V instanceof Prime ? ((Prime)V)._V : V; } - } - - // --- The Hash Table -------------------- - private transient CHM _chm; - // This next field holds the value for Key 0 - the special key value which - // is the initial array value, and also means: no-key-inserted-yet. - private transient Object _val_1; // Value for Key: NO_KEY - - // Time since last resize - private transient long _last_resize_milli; - - // Optimize for space: use a 1/2-sized table and allow more re-probes - private final boolean _opt_for_space; - - // --- Minimum table size ---------------- - // Pick size 16 K/V pairs, which turns into (16*2)*4+12 = 140 bytes on a - // standard 32-bit HotSpot, and (16*2)*8+12 = 268 bytes on 64-bit Azul. - private static final int MIN_SIZE_LOG=2; // - private static final int MIN_SIZE=(1<entrySet view's iterator, enclosed in braces - * ("{}"). Adjacent mappings are separated by the characters - * ", " (comma and space). Each key-value mapping is rendered as - * the key followed by an equals sign ("=") followed by the - * associated value. Keys and values are converted to strings as by - * {@link String#valueOf(Object)}. - * - * @return a string representation of this map - */ - @Override - public String toString() { - IteratorLong iter = new IteratorLong(); - if( !iter.hasNext() ) return "{}"; - SB sb = new SB("{"); - for( long key=iter.next(); iter.hasNext(); key=iter.next() ) { - TypeV val = get(key); - sb.p(key).p('=').p(val == this ? "(this Map)" : val.toString()).p(", "); - } - return sb.unchar(2).p("}").toString(); - } - - - // Count of reprobes - private transient AryInt _reprobes = null; - - /** Get and clear the current count of reprobes. Reprobes happen on key - * collisions, and a high reprobe rate may indicate a poor hash function or - * weaknesses in the table resizing function. - * @return the count of reprobes since the last call to {@link #reprobes} - * or since the table was created. */ - public AryInt reprobes() { return _reprobes==null ? (_reprobes = new AryInt()) : _reprobes; } - private void record( int ps ) { if( _reprobes!=null ) _record(ps); } - private void _record( int ps ) { _reprobes.setX(ps,_reprobes.atX(ps)+1); } - - - // --- reprobe_limit ----------------------------------------------------- - // Heuristic to decide if we have reprobed toooo many times. Running over - // the reprobe limit on a 'get' call acts as a 'miss'; on a 'put' call it - // can trigger a table resize. Several places must have exact agreement on - // what the reprobe_limit is, so we share it here. - private static int reprobe_limit( int len ) { - return REPROBE_LIMIT + (len>>4); - } - - // --- NonBlockingHashMapLong ---------------------------------------------- - // Constructors - - /** Create a new NonBlockingHashMapLong with default minimum size (currently set - * to 8 K/V pairs or roughly 84 bytes on a standard 32-bit JVM). */ - public NonBlockingHashMapLong( ) { this(MIN_SIZE,true); } - - /** Create a new NonBlockingHashMapLong with initial room for the given - * number of elements, thus avoiding internal resizing operations to reach - * an appropriate size. Large numbers here when used with a small count of - * elements will sacrifice space for a small amount of time gained. The - * initial size will be rounded up internally to the next larger power of 2. */ - public NonBlockingHashMapLong( final int initial_sz ) { this(initial_sz,true); } - - /** Create a new NonBlockingHashMapLong, setting the space-for-speed - * tradeoff. {@code true} optimizes for space and is the default. {@code - * false} optimizes for speed and doubles space costs for roughly a 10% - * speed improvement. */ - public NonBlockingHashMapLong( final boolean opt_for_space ) { this(1,opt_for_space); } - - /** Create a new NonBlockingHashMapLong, setting both the initial size and - * the space-for-speed tradeoff. {@code true} optimizes for space and is - * the default. {@code false} optimizes for speed and doubles space costs - * for roughly a 10% speed improvement. */ - public NonBlockingHashMapLong( final int initial_sz, final boolean opt_for_space ) { - _opt_for_space = opt_for_space; - initialize(initial_sz); - } - private void initialize( final int initial_sz ) { - if( initial_sz < 0 ) throw new IllegalArgumentException("initial_sz argument must be >= 0"); - int i; // Convert to next largest power-of-2 - for( i=MIN_SIZE_LOG; (1<true if the key is in the table */ - public boolean containsKey( long key ) { return get(key) != null; } - - /** Legacy method testing if some key maps into the specified value in this - * table. This method is identical in functionality to {@link - * #containsValue}, and exists solely to ensure full compatibility with - * class {@link java.util.Hashtable}, which supported this method prior to - * introduction of the Java Collections framework. - * @param val a value to search for - * @return true if this map maps one or more keys to the specified value - * @throws NullPointerException if the specified value is null */ - public boolean contains ( Object val ) { return containsValue(val); } - - /** Maps the specified key to the specified value in the table. The value - * cannot be null.

The value can be retrieved by calling {@link #get} - * with a key that is equal to the original key. - * @param key key with which the specified value is to be associated - * @param val value to be associated with the specified key - * @return the previous value associated with key, or - * null if there was no mapping for key - * @throws NullPointerException if the specified value is null */ - public TypeV put ( long key, TypeV val ) { return putIfMatch( key, val,NO_MATCH_OLD);} - - /** Atomically, do a {@link #put} if-and-only-if the key is not mapped. - * Useful to ensure that only a single mapping for the key exists, even if - * many threads are trying to create the mapping in parallel. - * @return the previous value associated with the specified key, - * or null if there was no mapping for the key - * @throws NullPointerException if the specified is value is null */ - public TypeV putIfAbsent( long key, TypeV val ) { return putIfMatch( key, val,TOMBSTONE );} - - /** Removes the key (and its corresponding value) from this map. - * This method does nothing if the key is not in the map. - * @return the previous value associated with key, or - * null if there was no mapping for key*/ - public TypeV remove ( long key ) { return putIfMatch( key,TOMBSTONE,NO_MATCH_OLD);} - - /** Atomically do a {@link #remove(long)} if-and-only-if the key is mapped - * to a value which is equals to the given value. - * @throws NullPointerException if the specified value is null */ - public boolean remove ( long key,Object val ) { return putIfMatch( key,TOMBSTONE,val ) == val ;} - - /** Atomically do a put(key,val) if-and-only-if the key is - * mapped to some value already. - * @throws NullPointerException if the specified value is null */ - public TypeV replace ( long key, TypeV val ) { return putIfMatch( key, val,MATCH_ANY );} - - /** Atomically do a put(key,newValue) if-and-only-if the key is - * mapped a value which is equals to oldValue. - * @throws NullPointerException if the specified value is null */ - public boolean replace ( long key, TypeV oldValue, TypeV newValue ) { - return putIfMatch( key, newValue, oldValue ) == oldValue; - } - - @SuppressWarnings("unchecked") - private TypeV putIfMatch( long key, Object newVal, Object oldVal ) { - if (oldVal == null || newVal == null) throw new NullPointerException(); - if( key == NO_KEY ) { - Object curVal = _val_1; - if( oldVal == NO_MATCH_OLD || // Do we care about expected-Value at all? - curVal == oldVal || // No instant match already? - (oldVal == MATCH_ANY && curVal != TOMBSTONE) || - oldVal.equals(curVal) ) { // Expensive equals check - if( !CAS(_val_1_offset,curVal,newVal) ) // One shot CAS update attempt - curVal = _val_1; // Failed; get failing witness - } - return curVal == TOMBSTONE ? null : (TypeV)curVal; // Return the last value present - } - final Object res = _chm.putIfMatch( key, newVal, oldVal ); - assert !(res instanceof Prime); - assert res != null; - return res == TOMBSTONE ? null : (TypeV)res; - } - - /** Removes all the mappings from this map. */ - public void clear() { // Smack a new empty table down - CHM newchm = new CHM(this,new ConcurrentAutoTable(),MIN_SIZE_LOG); - while( !CAS(_chm_offset,_chm,newchm) ) { /*Spin until the clear works*/} - CAS(_val_1_offset,_val_1,TOMBSTONE); - } - // Non-atomic clear, preserving existing large arrays - public void clear(boolean large) { // Smack a new empty table down - _chm.clear(); - CAS(_val_1_offset,_val_1,TOMBSTONE); - } - - /** Returns true if this Map maps one or more keys to the specified - * value. Note: This method requires a full internal traversal of the - * hash table and is much slower than {@link #containsKey}. - * @param val value whose presence in this map is to be tested - * @return true if this Map maps one or more keys to the specified value - * @throws NullPointerException if the specified value is null */ - public boolean containsValue( Object val ) { - if( val == null ) return false; - if( val == _val_1 ) return true; // Key 0 - for( TypeV V : values() ) - if( V == val || V.equals(val) ) - return true; - return false; - } - - // Get *any* valid Key. Useful for making worklists out of a hashtable - the - // hashtable can remove dup work. Repeated calls probably return the same - // Key, so only useful if keys are removed after calling. - public long getKey() { - if( _val_1 != TOMBSTONE ) throw new IllegalArgumentException("Cannot return key 0 and distinguish from no key"); - return _chm._getKey(); - } - - // --- get ----------------------------------------------------------------- - /** Returns the value to which the specified key is mapped, or {@code null} - * if this map contains no mapping for the key. - *

More formally, if this map contains a mapping from a key {@code k} to - * a value {@code v} such that {@code key==k}, then this method - * returns {@code v}; otherwise it returns {@code null}. (There can be at - * most one such mapping.) - * @throws NullPointerException if the specified key is null */ - // Never returns a Prime nor a Tombstone. - @SuppressWarnings("unchecked") - public final TypeV get( long key ) { - if( key == NO_KEY ) { - final Object V = _val_1; - return V == TOMBSTONE ? null : (TypeV)V; - } - final Object V = _chm.get_impl(key); - assert !(V instanceof Prime); // Never return a Prime - assert V != TOMBSTONE; - return (TypeV)V; - } - - /** Auto-boxing version of {@link #get(long)}. */ - public TypeV get ( Object key ) { return (key instanceof Long) ? get (((Long)key).longValue()) : null; } - /** Auto-boxing version of {@link #remove(long)}. */ - public TypeV remove ( Object key ) { return (key instanceof Long) ? remove (((Long)key).longValue()) : null; } - /** Auto-boxing version of {@link #remove(long,Object)}. */ - public boolean remove ( Object key, Object Val ) { return (key instanceof Long) && remove(((Long) key).longValue(), Val); } - /** Auto-boxing version of {@link #containsKey(long)}. */ - public boolean containsKey( Object key ) { return (key instanceof Long) && containsKey(((Long) key).longValue()); } - /** Auto-boxing version of {@link #putIfAbsent}. */ - public TypeV putIfAbsent( Long key, TypeV val ) { return putIfAbsent( key.longValue(), val ); } - /** Auto-boxing version of {@link #replace}. */ - public TypeV replace( Long key, TypeV Val ) { return replace(key.longValue(), Val); } - /** Auto-boxing version of {@link #put}. */ - public TypeV put ( Long key, TypeV val ) { return put(key.longValue(),val); } - /** Auto-boxing version of {@link #replace}. */ - public boolean replace( Long key, TypeV oldValue, TypeV newValue ) { - return replace(key.longValue(), oldValue, newValue); - } - - // --- help_copy ----------------------------------------------------------- - // Help along an existing resize operation. This is just a fast cut-out - // wrapper, to encourage inlining for the fast no-copy-in-progress case. We - // always help the top-most table copy, even if there are nested table - // copies in progress. - private void help_copy( ) { - // Read the top-level CHM only once. We'll try to help this copy along, - // even if it gets promoted out from under us (i.e., the copy completes - // and another KVS becomes the top-level copy). - CHM topchm = _chm; - if( topchm._newchm == null ) return; // No copy in-progress - topchm.help_copy_impl(false); - } - - // --- hash ---------------------------------------------------------------- - // Helper function to spread lousy hashCodes Throws NPE for null Key, on - // purpose - as the first place to conveniently toss the required NPE for a - // null Key. - private static int hash( long h) { - h ^= (h>>>20) ^ (h>>>12); - h ^= (h>>> 7) ^ (h>>> 4); - h += h<<7; // smear low bits up high, for hashcodes that only differ by 1 - return (int)h; - } - - - // --- CHM ----------------------------------------------------------------- - // The control structure for the NonBlockingHashMapLong - private static final class CHM implements Serializable { - // Back-pointer to top-level structure - final NonBlockingHashMapLong _nbhml; - - // Size in active K,V pairs - private ConcurrentAutoTable _size; - public int size () { return (int)_size.get(); } - - // --- - // These next 2 fields are used in the resizing heuristics, to judge when - // it is time to resize or copy the table. Slots is a count of used-up - // key slots, and when it nears a large fraction of the table we probably - // end up reprobing too much. Last-resize-milli is the time since the - // last resize; if we are running back-to-back resizes without growing - // (because there are only a few live keys but many slots full of dead - // keys) then we need a larger table to cut down on the churn. - - // Count of used slots, to tell when table is full of dead unusable slots - private ConcurrentAutoTable _slots; - public int slots() { return (int)_slots.get(); } - - // --- - // New mappings, used during resizing. - // The 'next' CHM - created during a resize operation. This represents - // the new table being copied from the old one. It's the volatile - // variable that is read as we cross from one table to the next, to get - // the required memory orderings. It monotonically transits from null to - // set (once). - volatile CHM _newchm; - private static final AtomicReferenceFieldUpdater _newchmUpdater = - AtomicReferenceFieldUpdater.newUpdater(CHM.class,CHM.class, "_newchm"); - // Set the _newchm field if we can. AtomicUpdaters do not fail spuriously. - boolean CAS_newchm( CHM newchm ) { - return _newchmUpdater.compareAndSet(this,null,newchm); - } - // Sometimes many threads race to create a new very large table. Only 1 - // wins the race, but the losers all allocate a junk large table with - // hefty allocation costs. Attempt to control the overkill here by - // throttling attempts to create a new table. I cannot really block here - // (lest I lose the non-blocking property) but late-arriving threads can - // give the initial resizing thread a little time to allocate the initial - // new table. The Right Long Term Fix here is to use array-lets and - // incrementally create the new very large array. In C I'd make the array - // with malloc (which would mmap under the hood) which would only eat - // virtual-address and not real memory - and after Somebody wins then we - // could in parallel initialize the array. Java does not allow - // un-initialized array creation (especially of ref arrays!). - volatile long _resizers; // count of threads attempting an initial resize - private static final AtomicLongFieldUpdater _resizerUpdater = - AtomicLongFieldUpdater.newUpdater(CHM.class, "_resizers"); - - // --- key,val ------------------------------------------------------------- - // Access K,V for a given idx - private boolean CAS_key( int idx, long old, long key ) { - return UNSAFE.compareAndSwapLong ( _keys, rawIndex(_keys, idx), old, key ); - } - private boolean CAS_val( int idx, Object old, Object val ) { - return UNSAFE.compareAndSwapObject( _vals, rawIndex(_vals, idx), old, val ); - } - - final long [] _keys; - final Object [] _vals; - - // Simple constructor - CHM( final NonBlockingHashMapLong nbhml, ConcurrentAutoTable size, final int logsize ) { - _nbhml = nbhml; - _size = size; - _slots= new ConcurrentAutoTable(); - _keys = new long [1<= reprobe_limit(len) ) // too many probes - return _newchm == null // Table copy in progress? - ? null // Nope! A clear miss - : copy_slot_and_check(idx,key).get_impl(key); // Retry in the new table - - idx = (idx+((hash>>16)|1))&(len-1); // Divergent reprobe chain - } - } finally { - _nbhml.record(reprobe_cnt); - } - } - - // --- putIfMatch --------------------------------------------------------- - // Put, Remove, PutIfAbsent, etc. Return the old value. If the returned - // value is equal to expVal (or expVal is NO_MATCH_OLD) then the put can - // be assumed to work (although might have been immediately overwritten). - // Only the path through copy_slot passes in an expected value of null, - // and putIfMatch only returns a null if passed in an expected null. - private static volatile int DUMMY_VOLATILE; - private Object putIfMatch( final long key, final Object putval, final Object expVal ) { - final int hash = hash(key); - assert putval != null; - assert !(putval instanceof Prime); - assert !(expVal instanceof Prime); - final int len = _keys.length; - int idx = (hash & (len-1)); // The first key - - // --- - // Key-Claim stanza: spin till we can claim a Key (or force a resizing). - int reprobe_cnt=0; - long K; - Object V; - try { - while( true ) { // Spin till we get a Key slot - V = _vals[idx]; // Get old value - K = _keys[idx]; // Get current key - if( K == NO_KEY ) { // Slot is free? - // Found an empty Key slot - which means this Key has never been in - // this table. No need to put a Tombstone - the Key is not here! - if( putval == TOMBSTONE ) return TOMBSTONE; // Not-now & never-been in this table - if( expVal == MATCH_ANY ) return TOMBSTONE; // Will not match, even after K inserts - // Claim the zero key-slot - if( CAS_key(idx, NO_KEY, key) ) { // Claim slot for Key - _slots.add(1); // Raise key-slots-used count - break; // Got it! - } - // CAS to claim the key-slot failed. - // - // This re-read of the Key points out an annoying short-coming of Java - // CAS. Most hardware CAS's report back the existing value - so that - // if you fail you have a *witness* - the value which caused the CAS - // to fail. The Java API turns this into a boolean destroying the - // witness. Re-reading does not recover the witness because another - // thread can write over the memory after the CAS. Hence we can be in - // the unfortunate situation of having a CAS fail *for cause* but - // having that cause removed by a later store. This turns a - // non-spurious-failure CAS (such as Azul has) into one that can - // apparently spuriously fail - and we avoid apparent spurious failure - // by not allowing Keys to ever change. - K = _keys[idx]; // CAS failed, get updated value - assert K != NO_KEY ; // If keys[idx] is NO_KEY, CAS shoulda worked - } - // Key slot was not null, there exists a Key here - if( K == key ) - break; // Got it! - - // get and put must have the same key lookup logic! Lest 'get' give - // up looking too soon. - //topmap._reprobes.add(1); - if( ++reprobe_cnt >= reprobe_limit(len) ) { - // We simply must have a new table to do a 'put'. At this point a - // 'get' will also go to the new table (if any). We do not need - // to claim a key slot (indeed, we cannot find a free one to claim!). - final CHM newchm = resize(); - if( expVal != null ) _nbhml.help_copy(); // help along an existing copy - return newchm.putIfMatch(key,putval,expVal); - } - - idx = (idx+((hash>>16)|1))&(len-1); // Divergent reprobe chain - } // End of spinning till we get a Key slot - } finally { - _nbhml.record(reprobe_cnt); - } - - while ( true ) { // Spin till we insert a value - // --- - // Found the proper Key slot, now update the matching Value slot. We - // never put a null, so Value slots monotonically move from null to - // not-null (deleted Values use Tombstone). Thus if 'V' is null we - // fail this fast cutout and fall into the check for table-full. - if( putval == V ) return V; // Fast cutout for no-change - - // See if we want to move to a new table (to avoid high average re-probe - // counts). We only check on the initial set of a Value from null to - // not-null (i.e., once per key-insert). - if( (V == null && tableFull(reprobe_cnt,len)) || - // Or we found a Prime: resize is already in progress. The resize - // call below will do a CAS on _newchm forcing the read. - V instanceof Prime) { - resize(); // Force the new table copy to start - return copy_slot_and_check(idx,expVal).putIfMatch(key,putval,expVal); - } - - // --- - // We are finally prepared to update the existing table - //assert !(V instanceof Prime); // always true, so IDE warnings if uncommented - - // Must match old, and we do not? Then bail out now. Note that either V - // or expVal might be TOMBSTONE. Also V can be null, if we've never - // inserted a value before. expVal can be null if we are called from - // copy_slot. - - if( expVal != NO_MATCH_OLD && // Do we care about expected-Value at all? - V != expVal && // No instant match already? - (expVal != MATCH_ANY || V == TOMBSTONE || V == null) && - !(V==null && expVal == TOMBSTONE) && // Match on null/TOMBSTONE combo - (expVal == null || !expVal.equals(V)) ) // Expensive equals check at the last - return (V==null) ? TOMBSTONE : V; // Do not update! - - // Actually change the Value in the Key,Value pair - if( CAS_val(idx, V, putval ) ) break; - - // CAS failed - // Because we have no witness, we do not know why it failed. - // Indeed, by the time we look again the value under test might have flipped - // a thousand times and now be the expected value (despite the CAS failing). - // Check for the never-succeed condition of a Prime value and jump to any - // nested table, or else just re-run. - - // We would not need this load at all if CAS returned the value on which - // the CAS failed (AKA witness). The new CAS semantics are supported via - // VarHandle in JDK9. - V = _vals[idx]; // Get new value - - // If a Prime'd value got installed, we need to re-run the put on the - // new table. Otherwise we lost the CAS to another racing put. - // Simply retry from the start. - if( V instanceof Prime ) - return copy_slot_and_check(idx,expVal).putIfMatch(key,putval,expVal); - - // Simply retry from the start. - // NOTE: need the fence, since otherwise '_vals[idx]' load could be hoisted - // out of loop. - int dummy = DUMMY_VOLATILE; - } - - // CAS succeeded - we did the update! - // Both normal put's and table-copy calls putIfMatch, but table-copy - // does not (effectively) increase the number of live k/v pairs. - if( expVal != null ) { - // Adjust sizes - a striped counter - if( (V == null || V == TOMBSTONE) && putval != TOMBSTONE ) _size.add( 1); - if( !(V == null || V == TOMBSTONE) && putval == TOMBSTONE ) _size.add(-1); - } - - // We won; we know the update happened as expected. - return (V==null && expVal!=null) ? TOMBSTONE : V; - } - - // --- tableFull --------------------------------------------------------- - // Heuristic to decide if this table is too full, and we should start a - // new table. Note that if a 'get' call has reprobed too many times and - // decided the table must be full, then always the estimate_sum must be - // high and we must report the table is full. If we do not, then we might - // end up deciding that the table is not full and inserting into the - // current table, while a 'get' has decided the same key cannot be in this - // table because of too many reprobes. The invariant is: - // slots.estimate_sum >= max_reprobe_cnt >= reprobe_limit(len) - private boolean tableFull( int reprobe_cnt, int len ) { - return - // Do the cheap check first: we allow some number of reprobes always - reprobe_cnt >= REPROBE_LIMIT && - (reprobe_cnt >= reprobe_limit(len) || - // More expensive check: see if the table is > 1/2 full. - _slots.estimate_get() >= (len>>1)); - } - - // --- resize ------------------------------------------------------------ - // Resizing after too many probes. "How Big???" heuristics are here. - // Callers will (not this routine) will 'help_copy' any in-progress copy. - // Since this routine has a fast cutout for copy-already-started, callers - // MUST 'help_copy' lest we have a path which forever runs through - // 'resize' only to discover a copy-in-progress which never progresses. - private CHM resize() { - // Check for resize already in progress, probably triggered by another thread - CHM newchm = _newchm; // VOLATILE READ - if( newchm != null ) // See if resize is already in progress - return newchm; // Use the new table already - - // No copy in-progress, so start one. First up: compute new table size. - int oldlen = _keys.length; // Old count of K,V pairs allowed - int sz = size(); // Get current table count of active K,V pairs - int newsz = sz; // First size estimate - - // Heuristic to determine new size. We expect plenty of dead-slots-with-keys - // and we need some decent padding to avoid endless reprobing. - if( _nbhml._opt_for_space ) { - // This heuristic leads to a much denser table with a higher reprobe rate - if( sz >= (oldlen>>1) ) // If we are >50% full of keys then... - newsz = oldlen<<1; // Double size - } else { - if( sz >= (oldlen>>2) ) { // If we are >25% full of keys then... - newsz = oldlen<<1; // Double size - if( sz >= (oldlen>>1) ) // If we are >50% full of keys then... - newsz = oldlen<<2; // Double double size - } - } - - // Last (re)size operation was very recent? Then double again - // despite having few live keys; slows down resize operations - // for tables subject to a high key churn rate - but do not - // forever grow the table. If there is a high key churn rate - // the table needs a steady state of rare same-size resize - // operations to clean out the dead keys. - long tm = System.currentTimeMillis(); - if( newsz <= oldlen && // New table would shrink or hold steady? - tm <= _nbhml._last_resize_milli+10000) // Recent resize (less than 10 sec ago) - newsz = oldlen<<1; // Double the existing size - - // Do not shrink, ever. If we hit this size once, assume we - // will again. - if( newsz < oldlen ) newsz = oldlen; - - // Convert to power-of-2 - int log2; - for( log2=MIN_SIZE_LOG; (1< ((len >> 2) + (len >> 1))) throw new RuntimeException("Table is full."); - } - - // Now limit the number of threads actually allocating memory to a - // handful - lest we have 750 threads all trying to allocate a giant - // resized array. - long r = _resizers; - while( !_resizerUpdater.compareAndSet(this,r,r+1) ) - r = _resizers; - // Size calculation: 2 words (K+V) per table entry, plus a handful. We - // guess at 64-bit pointers; 32-bit pointers screws up the size calc by - // 2x but does not screw up the heuristic very much. - long megs = ((((1L<>20/*megs*/; - if( r >= 2 && megs > 0 ) { // Already 2 guys trying; wait and see - newchm = _newchm; // Between dorking around, another thread did it - if( newchm != null ) // See if resize is already in progress - return newchm; // Use the new table already - // We could use a wait with timeout, so we'll wakeup as soon as the new table - // is ready, or after the timeout in any case. - //synchronized( this ) { wait(8*megs); } // Timeout - we always wakeup - // For now, sleep a tad and see if the 2 guys already trying to make - // the table actually get around to making it happen. - try { Thread.sleep(megs); } catch( Exception e ) { /*empty*/} - } - // Last check, since the 'new' below is expensive and there is a chance - // that another thread slipped in a new thread while we ran the heuristic. - newchm = _newchm; - if( newchm != null ) // See if resize is already in progress - return newchm; // Use the new table already - - // New CHM - actually allocate the big arrays - newchm = new CHM(_nbhml,_size,log2); - - // Another check after the slow allocation - if( _newchm != null ) // See if resize is already in progress - return _newchm; // Use the new table already - - // The new table must be CAS'd in so only 1 winner amongst duplicate - // racing resizing threads. Extra CHM's will be GC'd. - if( CAS_newchm( newchm ) ) { // NOW a resize-is-in-progress! - //notifyAll(); // Wake up any sleepers - //long nano = System.nanoTime(); - //System.out.println(" "+nano+" Resize from "+oldlen+" to "+(1< _copyIdxUpdater = - AtomicLongFieldUpdater.newUpdater(CHM.class, "_copyIdx"); - - // Work-done reporting. Used to efficiently signal when we can move to - // the new table. From 0 to len(oldkvs) refers to copying from the old - // table to the new. - volatile long _copyDone= 0; - static private final AtomicLongFieldUpdater _copyDoneUpdater = - AtomicLongFieldUpdater.newUpdater(CHM.class, "_copyDone"); - - // --- help_copy_impl ---------------------------------------------------- - // Help along an existing resize operation. We hope its the top-level - // copy (it was when we started) but this CHM might have been promoted out - // of the top position. - private void help_copy_impl( final boolean copy_all ) { - final CHM newchm = _newchm; - assert newchm != null; // Already checked by caller - int oldlen = _keys.length; // Total amount to copy - final int MIN_COPY_WORK = Math.min(oldlen,1024); // Limit per-thread work - - // --- - int panic_start = -1; - int copyidx=-9999; // Fool javac to think it's initialized - while( _copyDone < oldlen ) { // Still needing to copy? - // Carve out a chunk of work. The counter wraps around so every - // thread eventually tries to copy every slot repeatedly. - - // We "panic" if we have tried TWICE to copy every slot - and it still - // has not happened. i.e., twice some thread somewhere claimed they - // would copy 'slot X' (by bumping _copyIdx) but they never claimed to - // have finished (by bumping _copyDone). Our choices become limited: - // we can wait for the work-claimers to finish (and become a blocking - // algorithm) or do the copy work ourselves. Tiny tables with huge - // thread counts trying to copy the table often 'panic'. - if( panic_start == -1 ) { // No panic? - copyidx = (int)_copyIdx; - while( copyidx < (oldlen<<1) && // 'panic' check - !_copyIdxUpdater.compareAndSet(this,copyidx,copyidx+MIN_COPY_WORK) ) - copyidx = (int)_copyIdx; // Re-read - if( !(copyidx < (oldlen<<1)) ) // Panic! - panic_start = copyidx; // Record where we started to panic-copy - } - - // We now know what to copy. Try to copy. - int workdone = 0; - for( int i=0; i 0 ) // Report work-done occasionally - copy_check_and_promote( workdone );// See if we can promote - //for( int i=0; i 0 ) { - while( !_copyDoneUpdater.compareAndSet(this,copyDone,nowDone) ) { - copyDone = _copyDone; // Reload, retry - nowDone = copyDone+workdone; - assert nowDone <= oldlen; - } - } - - // Check for copy being ALL done, and promote. Note that we might have - // nested in-progress copies and manage to finish a nested copy before - // finishing the top-level copy. We only promote top-level copies. - if( nowDone == oldlen && // Ready to promote this table? - _nbhml._chm == this && // Looking at the top-level table? - // Attempt to promote - _nbhml.CAS(_chm_offset,this,_newchm) ) { - _nbhml._last_resize_milli = System.currentTimeMillis(); // Record resize time for next check - } - } - - // --- copy_slot --------------------------------------------------------- - // Copy one K/V pair from oldkvs[i] to newkvs. Returns true if we can - // confirm that we set an old-table slot to TOMBPRIME, and only returns after - // updating the new table. We need an accurate confirmed-copy count so - // that we know when we can promote (if we promote the new table too soon, - // other threads may 'miss' on values not-yet-copied from the old table). - // We don't allow any direct updates on the new table, unless they first - // happened to the old table - so that any transition in the new table from - // null to not-null must have been from a copy_slot (or other old-table - // overwrite) and not from a thread directly writing in the new table. - private boolean copy_slot( int idx ) { - // Blindly set the key slot from NO_KEY to some key which hashes here, - // to eagerly stop fresh put's from inserting new values in the old - // table when the old table is mid-resize. We don't need to act on the - // results here, because our correctness stems from box'ing the Value - // field. Slamming the Key field is a minor speed optimization. - long key; - while( (key=_keys[idx]) == NO_KEY ) - CAS_key(idx, NO_KEY, (idx+_keys.length)/*a non-zero key which hashes here*/); - - // --- - // Prevent new values from appearing in the old table. - // Box what we see in the old table, to prevent further updates. - Object oldval = _vals[idx]; // Read OLD table - while( !(oldval instanceof Prime) ) { - final Prime box = (oldval == null || oldval == TOMBSTONE) ? TOMBPRIME : new Prime(oldval); - if( CAS_val(idx,oldval,box) ) { // CAS down a box'd version of oldval - // If we made the Value slot hold a TOMBPRIME, then we both - // prevented further updates here but also the (absent) oldval is - // vaccuously available in the new table. We return with true here: - // any thread looking for a value for this key can correctly go - // straight to the new table and skip looking in the old table. - if( box == TOMBPRIME ) - return true; - // Otherwise we boxed something, but it still needs to be - // copied into the new table. - oldval = box; // Record updated oldval - break; // Break loop; oldval is now boxed by us - } - oldval = _vals[idx]; // Else try, try again - } - if( oldval == TOMBPRIME ) return false; // Copy already complete here! - - // --- - // Copy the value into the new table, but only if we overwrite a null. - // If another value is already in the new table, then somebody else - // wrote something there and that write is happens-after any value that - // appears in the old table. - Object old_unboxed = ((Prime)oldval)._V; - assert old_unboxed != TOMBSTONE; - boolean copied_into_new = (_newchm.putIfMatch(key, old_unboxed, null) == null); - - // --- - // Finally, now that any old value is exposed in the new table, we can - // forever hide the old-table value by slapping a TOMBPRIME down. This - // will stop other threads from uselessly attempting to copy this slot - // (i.e., it's a speed optimization not a correctness issue). - while( oldval != TOMBPRIME && !CAS_val(idx,oldval,TOMBPRIME) ) - oldval = _vals[idx]; - - return copied_into_new; - } // end copy_slot - - // Get *any* random key, or 0 - private long _getKey() { - for( int i=0; i<_keys.length; i++ ) - if( _keys[i] != NO_KEY && Prime.unbox(_vals[i])!=TOMBSTONE ) - return _keys[i]; - return _newchm == null ? 0 : _newchm._getKey(); - } - - } // End of CHM - - - // --- Snapshot ------------------------------------------------------------ - // The main class for iterating over the NBHM. It "snapshots" a clean - // view of the K/V array. - private class SnapshotV implements Iterator, Enumeration { - final CHM _sschm; - public SnapshotV() { - CHM topchm; - while( true ) { // Verify no table-copy-in-progress - topchm = _chm; - if( topchm._newchm == null ) // No table-copy-in-progress - break; - // Table copy in-progress - so we cannot get a clean iteration. We - // must help finish the table copy before we can start iterating. - topchm.help_copy_impl(true); - } - // The "linearization point" for the iteration. Every key in this table - // will be visited, but keys added later might be skipped or even be - // added to a following table (also not iterated over). - _sschm = topchm; - // Warm-up the iterator - _idx = -1; - next(); - } - int length() { return _sschm._keys.length; } - long key(final int idx) { return _sschm._keys[idx]; } - private int _idx; // -2 for NO_KEY, -1 for CHECK_NEW_TABLE_LONG, 0-keys.length - private long _nextK, _prevK; // Last 2 keys found - private TypeV _nextV, _prevV; // Last 2 values found - public boolean hasNext() { return _nextV != null; } - public TypeV next() { - // 'next' actually knows what the next value will be - it had to - // figure that out last go 'round lest 'hasNext' report true and - // some other thread deleted the last value. Instead, 'next' - // spends all its effort finding the key that comes after the - // 'next' key. - if( _idx != -1 && _nextV == null ) throw new NoSuchElementException(); - _prevK = _nextK; // This will become the previous key - _prevV = _nextV; // This will become the previous value - _nextV = null; // We have no more next-key - // Attempt to set <_nextK,_nextV> to the next K,V pair. - // _nextV is the trigger: stop searching when it is != null - if( _idx == -1 ) { // Check for NO_KEY - _idx = 0; // Setup for next phase of search - _nextK = NO_KEY; - if( (_nextV=get(_nextK)) != null ) return _prevV; - } - while( _idx, but the JDK always - // removes by key, even when the value has changed. - removeKey(); - } - - public TypeV nextElement() { return next(); } - public boolean hasMoreElements() { return hasNext(); } - } - - /** Returns an enumeration of the values in this table. - * @return an enumeration of the values in this table - * @see #values() */ - public Enumeration elements() { return new SnapshotV(); } - - // --- values -------------------------------------------------------------- - /** Returns a {@link Collection} view of the values contained in this map. - * The collection is backed by the map, so changes to the map are reflected - * in the collection, and vice-versa. The collection supports element - * removal, which removes the corresponding mapping from this map, via the - * Iterator.remove, Collection.remove, - * removeAll, retainAll, and clear operations. - * It does not support the add or addAll operations. - * - *

The view's iterator is a "weakly consistent" iterator that - * will never throw {@link ConcurrentModificationException}, and guarantees - * to traverse elements as they existed upon construction of the iterator, - * and may (but is not guaranteed to) reflect any modifications subsequent - * to construction. */ - public Collection values() { - return new AbstractCollection() { - public void clear ( ) { NonBlockingHashMapLong.this.clear ( ); } - public int size ( ) { return NonBlockingHashMapLong.this.size ( ); } - public boolean contains( Object v ) { return NonBlockingHashMapLong.this.containsValue(v); } - public Iterator iterator() { return new SnapshotV(); } - }; - } - - // --- keySet -------------------------------------------------------------- - /** A class which implements the {@link Iterator} and {@link Enumeration} - * interfaces, generified to the {@link Long} class and supporting a - * non-auto-boxing {@link #nextLong} function. */ - public class IteratorLong implements Iterator, Enumeration { - private final SnapshotV _ss; - /** A new IteratorLong */ - public IteratorLong() { _ss = new SnapshotV(); } - /** Remove last key returned by {@link #next} or {@link #nextLong}. */ - public void remove() { _ss.removeKey(); } - /** Auto-box and return the next key. */ - public Long next () { _ss.next(); return _ss._prevK; } - /** Return the next key as a primitive {@code long}. */ - public long nextLong() { _ss.next(); return _ss._prevK; } - /** True if there are more keys to iterate over. */ - public boolean hasNext() { return _ss.hasNext(); } - /** Auto-box and return the next key. */ - public Long nextElement() { return next(); } - /** True if there are more keys to iterate over. */ - public boolean hasMoreElements() { return hasNext(); } - } - /** Returns an enumeration of the auto-boxed keys in this table. - * Warning: this version will auto-box all returned keys. - * @return an enumeration of the auto-boxed keys in this table - * @see #keySet() */ - public Enumeration keys() { return new IteratorLong(); } - - /** Returns a {@link Set} view of the keys contained in this map; with care - * the keys may be iterated over without auto-boxing. The - * set is backed by the map, so changes to the map are reflected in the - * set, and vice-versa. The set supports element removal, which removes - * the corresponding mapping from this map, via the - * Iterator.remove, Set.remove, removeAll, - * retainAll, and clear operations. It does not support - * the add or addAll operations. - * - *

The view's iterator is a "weakly consistent" iterator that - * will never throw {@link ConcurrentModificationException}, and guarantees - * to traverse elements as they existed upon construction of the iterator, - * and may (but is not guaranteed to) reflect any modifications subsequent - * to construction. */ - public Set keySet() { - return new AbstractSet () { - public void clear ( ) { NonBlockingHashMapLong.this.clear ( ); } - public int size ( ) { return NonBlockingHashMapLong.this.size ( ); } - public boolean contains( Object k ) { return NonBlockingHashMapLong.this.containsKey(k); } - public boolean remove ( Object k ) { return NonBlockingHashMapLong.this.remove (k) != null; } - public IteratorLong iterator() { return new IteratorLong(); } - }; - } - - /** Keys as a long array. Array may be zero-padded if keys are concurrently deleted. */ - @SuppressWarnings("unchecked") - public long[] keySetLong() { - long[] dom = new long[size()]; - IteratorLong i=(IteratorLong)keySet().iterator(); - int j=0; - while( j < dom.length && i.hasNext() ) - dom[j++] = i.nextLong(); - return dom; - } - - // --- entrySet ------------------------------------------------------------ - // Warning: Each call to 'next' in this iterator constructs a new Long and a - // new NBHMLEntry. - private class NBHMLEntry extends AbstractEntry { - NBHMLEntry( final Long k, final TypeV v ) { super(k,v); } - public TypeV setValue(final TypeV val) { - if (val == null) throw new NullPointerException(); - _val = val; - return put(_key, val); - } - } - private class SnapshotE implements Iterator> { - final SnapshotV _ss; - public SnapshotE() { _ss = new SnapshotV(); } - public void remove() { - // NOTE: it would seem logical that entry removal will semantically mean - // removing the matching pair , but the JDK always removes by key, - // even when the value has changed. - _ss.removeKey(); - } - public Map.Entry next() { _ss.next(); return new NBHMLEntry(_ss._prevK,_ss._prevV); } - public boolean hasNext() { return _ss.hasNext(); } - } - - /** Returns a {@link Set} view of the mappings contained in this map. The - * set is backed by the map, so changes to the map are reflected in the - * set, and vice-versa. The set supports element removal, which removes - * the corresponding mapping from the map, via the - * Iterator.remove, Set.remove, removeAll, - * retainAll, and clear operations. It does not support - * the add or addAll operations. - * - *

The view's iterator is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. - * - *

Warning: the iterator associated with this Set - * requires the creation of {@link java.util.Map.Entry} objects with each - * iteration. The {@link org.jctools.maps.NonBlockingHashMap} - * does not normally create or using {@link java.util.Map.Entry} objects so - * they will be created soley to support this iteration. Iterating using - * {@link Map#keySet} or {@link Map#values} will be more efficient. In addition, - * this version requires auto-boxing the keys. - */ - public Set> entrySet() { - return new AbstractSet>() { - public void clear ( ) { NonBlockingHashMapLong.this.clear( ); } - public int size ( ) { return NonBlockingHashMapLong.this.size ( ); } - public boolean remove( final Object o ) { - if (!(o instanceof Map.Entry)) return false; - final Map.Entry e = (Map.Entry)o; - return NonBlockingHashMapLong.this.remove(e.getKey(), e.getValue()); - } - public boolean contains(final Object o) { - if (!(o instanceof Map.Entry)) return false; - final Map.Entry e = (Map.Entry)o; - TypeV v = get(e.getKey()); - return v != null && v.equals(e.getValue()); - } - public Iterator> iterator() { return new SnapshotE(); } - }; - } - - // --- writeObject ------------------------------------------------------- - // Write a NBHML to a stream - private void writeObject(java.io.ObjectOutputStream s) throws IOException { - s.defaultWriteObject(); // Write nothing - for( long K : keySet() ) { - final Object V = get(K); // Do an official 'get' - s.writeLong (K); // Write the pair - s.writeObject(V); - } - s.writeLong(NO_KEY); // Sentinel to indicate end-of-data - s.writeObject(null); - } - - // --- readObject -------------------------------------------------------- - // Read a CHM from a stream - @SuppressWarnings("unchecked") - private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { - s.defaultReadObject(); // Read nothing - initialize(MIN_SIZE); - for (;;) { - final long K = s.readLong(); - final TypeV V = (TypeV) s.readObject(); - if( K == NO_KEY && V == null ) break; - put(K,V); // Insert with an offical put - } - } - - /** - * Creates a shallow copy of this hashtable. All the structure of the - * hashtable itself is copied, but the keys and values are not cloned. - * This is a relatively expensive operation. - * - * @return a clone of the hashtable. - */ - @SuppressWarnings("unchecked") - @Override - public NonBlockingHashMapLong clone() { - try { - // Must clone, to get the class right; NBHML might have been - // extended so it would be wrong to just make a new NBHML. - NonBlockingHashMapLong t = (NonBlockingHashMapLong) super.clone(); - // But I don't have an atomic clone operation - the underlying _kvs - // structure is undergoing rapid change. If I just clone the _kvs - // field, the CHM in _kvs[0] won't be in sync. - // - // Wipe out the cloned array (it was shallow anyways). - t.clear(); - // Now copy sanely - for( long K : keySetLong() ) - t.put(K,get(K)); - return t; - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new InternalError(); - } - } - -} // End NonBlockingHashMapLong class diff --git a/javatools_backend/src/main/java/org/xvm/util/S.java b/javatools_backend/src/main/java/org/xvm/util/S.java deleted file mode 100644 index 7d48521fd9..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/S.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.xvm.util; - -// Force strings to be interned, so we can use ptr-equals as equals -public abstract class S { - public static boolean eq(String s0, String s1) { - if( s0==s1 ) return true; - assert s0==null || s0==s0.intern(); - assert s1==null || s1==s1.intern(); - return false; - } - - // Fast linear scan for a hit, returns index or -1. - // Uses '==' not '.equals' - public static int find( E[] es, E e ) { - if( es != null ) - for( int i=0; i X[] swap( X[] ary, int i, int j ) { - X tmp = ary[i]; - ary[i] = ary[j]; - ary[j] = tmp; - return ary; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/util/SB.java b/javatools_backend/src/main/java/org/xvm/util/SB.java deleted file mode 100644 index 54508c009c..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/SB.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.xvm.util; - -/** Tight/tiny StringBuilder wrapper. - * Short short names on purpose; so they don't obscure the printing. - * Can't believe this wasn't done long, long ago. */ -public final class SB { - private final StringBuilder _sb; - private int _indent = 0; - public SB( ) { _sb = new StringBuilder( ); } - public SB(String s) { _sb = new StringBuilder(s); } - public SB p( String s ) { if( s!=null ) _sb.append(s); return this; } - public SB p( float s ) { - if( Float.isNaN(s) ) - _sb.append( "Float.NaN"); - else if( Float.isInfinite(s) ) { - _sb.append(s > 0 ? "Float.POSITIVE_INFINITY" : "Float.NEGATIVE_INFINITY"); - } else _sb.append(s); - return this; - } - public SB p( double s ) { - if( Double.isNaN(s) ) - _sb.append("Double.NaN"); - else if( Double.isInfinite(s) ) { - _sb.append(s > 0 ? "Double.POSITIVE_INFINITY" : "Double.NEGATIVE_INFINITY"); - } else _sb.append(s); - return this; - } - public SB p( char s ) { _sb.append(s); return this; } - public SB p( int s ) { _sb.append(s); return this; } - public SB p( long s ) { _sb.append(s); return this; } - public SB p( boolean s) { _sb.append(s); return this; } - // Not spelled "p" on purpose: too easy to accidentally say "p(1.0)" and - // suddenly call the autoboxed version. - public SB pobj( Object s ) { _sb.append(s.toString()); return this; } - public SB i( int d ) { for( int i=0; i p("\\"); - case '\n' -> p("\\n"); - case '"' -> p("\\\""); - default -> p(s.charAt(i)); - } - } - p('"'); - return this; - } - - // Replace all %0 with a - public SB fmt( String fmt, String a ) { - assert fmt.contains( "%0" ) : "Looks like the extra string is never used in the format"; - return p(fmt.replace("%0",a)); - } - public SB ifmt( String fmt, String a ) { return i().fmt(fmt,a); } - public SB ifmt( String fmt, long l ) { return i().fmt(fmt,l); } - public SB fmt( String fmt, long l ) { return fmt(fmt,Long.toString(l)); } - public SB fmt( String fmt, String a, String b ) { return p(fmt.replace("%0",a).replace("%1",b)); } - public SB fmt( String fmt, String a, String b, String c ) { return p(fmt.replace("%0",a).replace("%1",b).replace("%2",c)); } - public SB fmt( String fmt, String a, long l ) { return fmt(fmt,a,Long.toString(l)); } - public SB ifmt( String fmt, String a, String b ) { return i().p(fmt.replace("%0",a).replace("%1",b)); } - public SB ifmt( String fmt, String a, long l ) { return i().fmt(fmt,a,Long.toString(l)); } - public SB ifmt( String fmt, long l, String a, String b ) { return i().fmt(fmt,Long.toString(l),a,b); } - -} diff --git a/javatools_backend/src/main/java/org/xvm/util/TLS.java b/javatools_backend/src/main/java/org/xvm/util/TLS.java deleted file mode 100644 index 0e990a40dd..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/TLS.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.xvm.util; - - -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Objects; - -import java.util.function.Function; -import java.util.function.Supplier; - - -/** - * A {@link ThreadLocal} variant optimized for short-lived thread-locals. Essentially, if the - * reference to the thread-local is not {@code static}, it will be advantageous to use a - * {@link TransientThreadLocal} rather than a {@link ThreadLocal}. - * - * @param the value type - * - * @author mf - */ -public class TLS extends ThreadLocal { - -} diff --git a/javatools_backend/src/main/java/org/xvm/util/UtilUnsafe.java b/javatools_backend/src/main/java/org/xvm/util/UtilUnsafe.java deleted file mode 100644 index 9f66c6f1e2..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/UtilUnsafe.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.xvm.util; - -import java.lang.reflect.Field; - -import sun.misc.Unsafe; - -/** - * Simple class to obtain access to the {@link Unsafe} object. {@link Unsafe} - * is required to allow efficient CAS operations on arrays. Note that the - * versions in java.util.concurrent.atomic, such as {@link - * java.util.concurrent.atomic.AtomicLongArray}, require extra memory ordering - * guarantees which are generally not needed in these algorithms and are also - * expensive on most processors. - */ -public class UtilUnsafe { - private UtilUnsafe() { } // dummy private constructor - static final Unsafe UNSAFE = getUnsafe(); - /** Fetch the Unsafe. Use With Caution. */ - public static Unsafe getUnsafe() { - // Not on bootclasspath - if( UtilUnsafe.class.getClassLoader() == null ) - return Unsafe.getUnsafe(); - try { - final Field fld = Unsafe.class.getDeclaredField("theUnsafe"); - fld.setAccessible(true); - return (Unsafe) fld.get(UtilUnsafe.class); - } catch (Exception e) { - throw new RuntimeException("Could not obtain access to sun.misc.Unsafe", e); - } - } - - static final long fieldOffset( Class clz, String field ) { - Field f = null; - try { f = clz.getDeclaredField(field); } - catch( java.lang.NoSuchFieldException e ) { throw new RuntimeException(e); } - return UNSAFE.objectFieldOffset(f); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/util/VBitSet.java b/javatools_backend/src/main/java/org/xvm/util/VBitSet.java deleted file mode 100644 index 9407f6dc57..0000000000 --- a/javatools_backend/src/main/java/org/xvm/util/VBitSet.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.xvm.util; - -import java.util.BitSet; - -public class VBitSet extends BitSet { - // Cannot override 'set' to return a value... :-P - public boolean tset(int idx) { boolean b = get(idx); set(idx); return b; } - public boolean test(int idx) { return get(idx); } - public VBitSet clr() { clear(); return this; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/Fun.java b/javatools_backend/src/main/java/org/xvm/xec/Fun.java deleted file mode 100644 index a7388902a4..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/Fun.java +++ /dev/null @@ -1,8 +0,0 @@ -// --------------------------------------------------------------- -// Auto Generated by Tuple from Fun - -package org.xvm.xec; - -public interface Fun { - abstract void call(); -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/XRunClz.java b/javatools_backend/src/main/java/org/xvm/xec/XRunClz.java deleted file mode 100644 index 05e053aaa2..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/XRunClz.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.xvm.xec; - -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.collections.AryString; - -// Some kind of base class for a Java class that implements an XTC Module -public abstract class XRunClz extends XTC { - public XRunClz( Never n ) { } - public void run( AryString args ) { run(); } - public abstract void run( ); -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/XTC.java b/javatools_backend/src/main/java/org/xvm/xec/XTC.java deleted file mode 100644 index 4f702fd7ec..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/XTC.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.xvm.xec; - -import org.xvm.util.Ary; -import org.xvm.xrun.*; -import org.xvm.xec.ecstasy.collections.Array.Mutability; -import org.xvm.XEC; -import org.xvm.xec.ecstasy.Ordered; - -import java.io.IOException; - -// The base "ecstasy.x" module - as a Java class. -// -// Why "XTC" and not "ecstasy"? -// -// Since Java does not allow a class to be named the same as a package, and a -// package is really just a directory - naming this class "ecstasy" conflicts -// with the package/directory of the same name. - -public class XTC { - public XTC( Never n ) {} // No arg constructor - public XTC() {} // No arg constructor - public static XTC GOLD = new XTC(); - - // -------------------------------------------------------------------------- - // A bunch of classes and functions that are always available (e.g. TRACE - // from asserts), or defined in ecstasy.x, or needed for the Java port. - - // Ecstasy's normal "equals" call calls the "equals" from "clz" and not a - // subclass implementation. This requires a runtime lookup, unless clz is a - // constant. This call is done in the Comparable interface, but it uses this - // signature so can use a java virtual call instead of a java interface call. - // This will only be called with two Comparables. - public boolean equals( XTC x0, XTC x1 ) { throw XEC.TODO(); } - - // Ecstasy's normal "compare" call calls the "compare" from "clz" and not a - // subclass implementation. This requires a runtime lookup, unless clz is a - // constant. This call is done in the Orderable interface, but it uses this - // signature so can use a java virtual call instead of a java interface call. - // This will only be called with two Orderables. - public Ordered compare( XTC x0, XTC x1 ) { throw XEC.TODO(); } - - // TODO: this should move into e.g. Const, but Java doesn't understand - // GOLDS[Enum.idx].equals(...); - // TODO: Instead: Enum.GOLD .equals(...) should work - public boolean equals(Ordered x0, Ordered x1) { return x0==x1; } - - // Ecstasy's normal "hash" call calls the "hash" from "clz" and not a - // subclass implementation. This requires a runtime lookup, unless clz is a - // constant. This call is done in the Hashable interface, but it uses this - // signature so can use a java virtual call instead of a java interface call. - // This will only be called with a Hashable. - public long hashCode( XTC x ) { throw XEC.TODO(); } - - - // Default mutability - public Mutability mutability$get() { return Mutability.Mutable; } - public int mutability$getOrd() { return Mutability.Mutable.ordinal(); } - - // 'that' isa 'this' ? - // 'this.getClass().isInstance(that)' - public boolean isa(XTC that) { - // TODO CHECK IMM - return getClass().isInstance(this); - } - // Test immutable - public static boolean isa_ro(XTC that) { return that.mutability$get() == Mutability.Constant; } - - public XTC freeze( boolean inPlace ) { - if( mutability$get() == Mutability.Constant ) return this; - throw XEC.TODO(); - } - - // Trace - public static X TRACE( X x ) { return x; } - public static String TRACE(String x) { return x; } - public static long TRACE(long x) { return x; } - public static int TRACE(int x) { return x; } - public static boolean TRACE(boolean x) { return x; } - - // Assert is always-on runtime test - public static void xassert( boolean cond ) { - if( !cond ) - throw new IllegalState(""); - } - public static void xassert( boolean cond, String msg ) { - if( !cond ) - throw new IllegalState(msg); - } - public static void xassert( ) { xassert(false); } - - /** -------------------------------------------------------------------------- -

    -
  • XTC {@code IllegalStateException} is thrown by {@code assert} and by {@code close}.
  • - -
  • Java {@code assert} throws {@link AssertionError}.
  • - -
  • Java {@code close} throws {@link IOException}.
  • - -
  • I don't see/expect any catches of assert exceptions, except for demo - purposes, and possibly a few times in some testing harness.
  • - -
  • I DO see exactly 2 catches of IllegalState (in the JSONDB Catalog.x). - I might expect more from users, used to catching close fails.
  • - -
  • Since the exception throw by XTC {@code assert} and {@code close} are - the same thing, and can be caught by the same thing, I need to force the - matching Java exceptions to map to some same thing, so they can be caught - by whatever I map XTC's {@code IllegalStateException} to.
  • - -
  • This means I need to merge Java's {@link IOException} and Java's - {@link AssertionError}.
  • - -
  • That means I need to catch every Java {@code close} call or every - Java {@code assert} call (or both), and remap the exception.
  • - -
  • Right now, every XTC {@code assert} is mapped to a Java {@code assert}; - and this means I might wrap (in Java) for every XTC {@code - assert}... OR
  • - -
  • when I call the Java mapping for every XTC {@code close}, I'll have - to catch Java's obvious {@link IOException} and map it.
  • - -
  • There's a lot less wrapping of exceptions going on, if we can - unbundle XTC assert's {@code IllegalStateException} from XTC close's - {@code IllegalStateException}.
  • - -
- So I am Once Again, asking for a language change: make the XTC assert - throw e.g. AssertionError instead of IllegalStateException. - */ - - public static class Exception extends RuntimeException { - public Exception(String msg) {super(msg); } - public Exception() { } - public static Exception construct(String s, String cause) { return new Exception(s); } - public String message$get() { return getMessage(); }; - } - - - // XTC IllegalState mapped to Java - public static class IllegalState extends Exception { - public IllegalState(String msg) {super(msg); } - public static IllegalState construct(String s) { return new IllegalState(s); } - } - - // XTC IllegalArgument mapped to Java - public static class IllegalArgument extends Exception { - public IllegalArgument(String s) { super(s); } - public static IllegalArgument construct(String s, String cause) { return new IllegalArgument(s); } - public static IllegalArgument construct(String s) { return new IllegalArgument(s); } - } - - // XTC ReadOnlyException mapped to Java - public static class ReadOnlyException extends Exception { } - - public static class Unsupported extends Exception {} - - // XTC NotImplemented mapped to Java - public static class NotImplemented extends Unsupported {} -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/AbstractRange.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/AbstractRange.java deleted file mode 100644 index 84acc08717..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/AbstractRange.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.numbers.Int64; -import org.xvm.xtc.XClz; -import org.xvm.xtc.ast.AST; -import org.xvm.xtc.ast.ConAST; -import org.xvm.xtc.XCons; -import org.xvm.xtc.cons.RangeCon; - -import java.lang.Iterable; -import java.util.Iterator; - -/** - Support XTC range iterator -*/ -abstract public class AbstractRange extends XTC implements Iterable { - public AbstractRange( ) {_start=_end=0; _lx=_hx=false; _incr=1; } // No arg constructor - - public final long _start, _end, _incr; // Inclusive start, exclusive end - public final boolean _lx, _hx; // True if exclusive - AbstractRange( long start, long end, boolean lx, boolean hx ) { - int incr = 1; - if( start > end ) - incr = -1; - if( !hx ) end +=incr; - if( lx ) start+=incr; - _start=start; - _end=end; - _lx=lx; - _hx=hx; - _incr = incr; - } - - @Override public final String toString() { - return - (_lx ? "("+(_start-_incr) : "["+_start ) + - ".." + - (!_hx ? ""+(_end-_incr)+"]" : ""+_end+")" ); - } - - public long span() { return _end-_start; } - public static long start(RangeCon rcon) { return rcon.lo() + (rcon._xlo ? 1 : 0); } - public static long end (RangeCon rcon) { return rcon.hi() + (rcon._xhi ? 0 : 1); } - public boolean in( long x ) { return _incr == 1 ? x < _end : x > _end; } - - public static AbstractRange range(AST ast) { - XClz rng = (XClz)ast.type(); - int lo = con(ast._kids[0]); - int hi = con(ast._kids[1]); - if( rng==XCons.RANGEII ) return new RangeII(lo,hi); - throw XEC.TODO(); - } - // Peel off a "L" from a ConAST of "3L" - private static int con(AST ast) { - String s = (((ConAST)ast))._con; - return Integer.valueOf(s.substring(0,s.length()-1)); - } - - - /** @return an iterator */ - @Override public Iterator iterator() { - throw XEC.TODO(); - } - // --- Comparable - public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Appender.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Appender.java deleted file mode 100644 index 854f3e6b9a..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Appender.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.xvm.xec.ecstasy; -import org.xvm.xec.XTC; - -public interface Appender { - abstract Appender add(E xtc); - default Appender ensureCapacity(int count) { return this; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Appenderchar.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Appenderchar.java deleted file mode 100644 index 878a8c2430..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Appenderchar.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.xvm.xec.ecstasy; -import org.xvm.xec.ecstasy.text.Char; - -public interface Appenderchar extends Appender { - Appenderchar add(char v); - Appenderchar addAll(String s); - Appenderchar appendTo(org.xvm.xec.ecstasy.text.String s); - Appenderchar appendTo(java.lang.String s); - Appenderchar appendTo(long l); - default Appenderchar ensureCapacity(int count) { return this; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Boolean.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Boolean.java deleted file mode 100644 index 89525c245e..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Boolean.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.xec.XTC; -import org.xvm.xrun.Never; - -public class Boolean extends Enum { - public static final Boolean GOLD = new Boolean(false); - public Boolean(Never n) {_i=false;} - private Boolean(boolean b) {_i=b;} - public final boolean _i; - public static Boolean TRUE = new Boolean(true), FALSE = new Boolean(false); - public static boolean equals$Boolean( XTC gold, E ord0, E ord1 ) { return ord0==ord1; } - public static Boolean make(boolean b) { return b ? TRUE : FALSE; } - public static Boolean construct(boolean b) { return b ? TRUE : FALSE; } - @Override public boolean equals ( XTC x0, XTC x1 ) { return x0==x1; } // Both are Boolean, interned -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Comparable.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Comparable.java deleted file mode 100644 index 1ed3fe32b0..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Comparable.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.util.S; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xtc.*; - -// Not-The-Java Comparable. XTC Comparable adds 'equals' not 'compareTo'. -public interface Comparable { - - // The fully dynamic equals lookup, based on the given compile-time class - static boolean equals( XTC gold_type, XTC x0, XTC x1 ) { - return gold_type.equals(x0,x1); // Dynamic against gold - } - - // Require implementations define this, which can typically be done with a - // default implementation. This same signature appears in the XTC base - // class, so we can do a v-call instead of an i-call. - boolean equals( XTC x0, XTC x1 ); - - // If the XTC compiler knows 'this' and 'x1' are the same class it emits a - // short-form equals call in which dispatch to either side is ok. - default boolean equals( XTC x1 ) { return equals((XTC)this,x1); } - - /** Each implementation will define the above abstract equals as: - * {@code public boolean equals(XTC x0, XTC x1) { return equals$CLZ((CLZ)x0,(CLZ)x1) } } - * Each implementation will also define (commonly with a default gen'd code): - * {@code public boolean equals$CLZ(CLZ x0, CLZ x1) { ... field-by-field or user-speced... } } - * - * The default implementation never uses the gold argument, but user-defined - * equals have access to it. - */ - - /* Generate: - public boolean equals( XTC x0, XTC x1 ) { // Called by the fully dynamic lookup - return equals$CLZ(GOLD,(CLZ)x0,(CLZ)x1); - } - public static boolean equals$CLZ( XTC gold, CLZ x0, CLZ x1 ) { - if( x0==x1 ) return true; - return x0.fld0.equals(x1.fld0) && x0.fld1==x1.fld1 && ... x0.fldN.equals(x1.fldN); - } - */ - static void make_equals_default( ClassPart clz, String clzname, SB sb ) { - sb.ifmt("public static boolean equals$%0( XTC gold, %0 x0, %0 x1 ) {\n",clzname).ii(); - sb.ip( "if( x0==x1 ) return true;\n"); - sb.ip( "return "); - boolean any=false; - for( Part p : clz._name2kid.values() ) - if( p instanceof PropPart prop && prop.isField() ) { - any = true; - XType xt = XType.xtype(prop._con,false); - xt.do_eq(sb.p("x0.").p(prop._name),"x1."+prop._name).p(" && "); - } - if( any ) sb.unchar(4); - else sb.p("true"); - sb.p(";\n").di(); - sb.ip("}\n"); - } - // Just a default Java equals, when the user overwrites the Const default equals - public static void make_equals( String clzname, SB sb ) { - sb.ip("// Default equals\n"); - sb.ip("public boolean equals( XTC x0, XTC x1 ) {\n").ii(); - sb.ifmt("return equals$%0(GOLD,(%0)x0,(%0)x1);\n",clzname).di(); - sb.ip("}\n"); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Const.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Const.java deleted file mode 100644 index de81704827..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Const.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.XEC; -import org.xvm.util.Ary; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.collections.Array.Mutability; -import org.xvm.xec.ecstasy.collections.Hashable; -import org.xvm.xec.ecstasy.numbers.Int64; -import org.xvm.xec.ecstasy.text.Char; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xrun.Never; -import org.xvm.xtc.*; - - -/** The Java Const class, implementing an XTC hidden internal class. - The XTC Const is an *XTC interface*, not an XTC class, but it has many class-like properties. - The XTC Const interface is thus treated like this Java Class. - */ -public class Const extends XTC - implements org.xvm.xec.ecstasy.Orderable, // XTC comparable adds compare,equals - Hashable, // XTC hashCode - Stringable // has appendTo -{ - public static final Const GOLD = new Const(null); - public Const() {} // Explicit no-arg-no-work constructor - public Const(Never n) {} // Forced no-arg-no-work constructor - - - /* Generate: - @Override public String toString() { - SB sb = new SB().p("("); - sb.p(fld0.toString()).p(","); - sb.p( fld_prim ).p(","); - sb.p(fldN.toString()).p(");"); - return sb.toString(); - } - */ - public static void make_toString( ClassPart clz, SB sb ) { - sb.ip("// Default toString\n"); - sb.ip("@Override public String toString() {\n").ii(); - sb.ip("StringBuilder sb = new StringBuilder().append(\"(\");\n"); - Ary pps = new Ary<>(PropPart.class); - // TODO: Need a static cutout test - for( Part p : clz._name2kid.values() ) - if( p instanceof PropPart prop ) - pps.setX(prop._order,prop); - for( int i=0; i boolean equals$Const(XTC gold, E c0, E c1 ) { - // Lost all type info, need to make sure same subclass - return c0.getClass() == c1.getClass() && c0.equals(c1); - } - - public static boolean equals$Const(XTC gold, Const c0, long i ) { - // Lost all type info, need to make sure same subclass - return c0 instanceof Int64 i0 && i0._i == i; - } - public static boolean equals$Const(XTC gold, Const c0, char c ) { - // Lost all type info, need to make sure same subclass - return c0 instanceof Char i0 && i0._i == c; - } - - public static boolean equals$Const(XTC gold, XTC c0, XTC c1 ) { return equals$Const(gold,(Const)c0,(Const)c1); } - - public static boolean equals$Const(XTC gold, char c0, char c1 ) { return c0==c1; } - public static Ordered compare$Const(XTC gold, char c0, char c1 ) { - return c0==c1 ? Ordered.Equal : (c0 < c1 ? Ordered.Lesser : Ordered.Greater); - } - public static boolean equals$Const(org.xvm.xec.ecstasy.text.String gold, String c0, String c1 ) { throw XEC.TODO(); } - public static Ordered compare$Const(org.xvm.xec.ecstasy.text.String gold, String s0, String s1 ) { return gold.compare(s0,s1); } - - public static boolean equals$String(XTC gold, String s0, String s1 ) { return s0.equals(s1); } - public static Ordered compare$String(XTC gold, String s0, String s1 ) { return org.xvm.xec.ecstasy.text.String.GOLD.compare(s0,s1); } - - @Override public Const freeze( boolean inPlace ) { assert mutability$get() == Mutability.Constant; return this; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Enum.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Enum.java deleted file mode 100644 index 61752edce9..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Enum.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.XEC; -import org.xvm.util.Ary; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xrun.Never; -import org.xvm.xtc.ClassPart; -import org.xvm.xtc.ClzBuilder; -import org.xvm.xtc.Part; -import org.xvm.xtc.XCons; - -/** The Java Enum class, implementing an XTC hidden internal class. - The XTC Enum is an *XTC interface*, not an XTC class, but it has many class-like properties. - - The XTC Enum interface is thus treated like this Java Class. - */ -public class Enum extends Const { - public static final Enum GOLD = new Enum(); - public Enum() {} // Explicit no-arg-no-work constructor - public Enum(Never n) {} // Forced no-arg-no-work constructor - - // --- Comparable - public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } - - public static boolean equals$Enum( XTC gold, E ord0, E ord1 ) { return ord0==ord1; } - public static boolean equals$Enum( XTC gold, boolean ord0, boolean ord1 ) { return ord0==ord1; } - - // Build the VALUES array for ENUMS - // private static final ENUM[] _VALUES = new ENUM[]{....}; - // public static final AryXTC VALUES = new AryXTC(ENUM.GOLD,_VALUES); - // public final AryXTC value$get() { return VALUES; } - public static ClassPart[] makeValues(ClassPart clz, SB sb) { - assert clz._f == Part.Format.ENUM; - String name = clz._tclz._name; - - // The enum values are intermixed with implemented methods - Ary cs = new Ary<>(ClassPart.class); - for( Part p : clz._name2kid.values() ) - if( p instanceof ClassPart e && e._f == Part.Format.ENUMVALUE ) - cs.setX(e._ord,e); - ClassPart[] es = cs.asAry(); - - // private static final ENUM[] _VALUES = new ENUM[]{....}; - sb.ifmt("private static final %0[] _VALUES = new %0[]{ ",name); - for( ClassPart e : es ) - sb.p(e._name).p(".GOLD, "); - sb.unchar(2).p("};").nl(); - - // public static final AryXTC VALUES = new AryXTC(ENUM.GOLD,_VALUES); - sb.ifmt("public static final AryXTC<%0> VALUES = new AryXTC<%0>(%0.GOLD,_VALUES);\n",name); - - // public final AryXTC value$get() { return VALUES; } - sb.ifmt("public final AryXTC<%0> values$get() { return VALUES; }\n",name); - - // Now the enum instances - //public static class ENUMVALUE extends ENUM { - // public static final ENUMVALUE GOLD = new ENUMVALUE(); - //} - sb.nl(); - for( ClassPart e : es ) - sb.ifmt("public static class %1 extends %0 { public static final %1 GOLD = new %1(); }\n",name,e._name); - sb.nl(); - - return es; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Freezable.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Freezable.java deleted file mode 100644 index 086f36635a..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Freezable.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.xvm.xec.ecstasy; -// Marker interface -public interface Freezable { - Freezable freeze(boolean inPlace); -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Iterable.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Iterable.java deleted file mode 100644 index ee67243dab..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Iterable.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.numbers.Int64; -import org.xvm.xec.ecstasy.collections.Arylong; -import org.xvm.xrun.Never; -import org.xvm.xrun.XRuntime; - -/** - XTC Iterable interface and also the Java Iterable interface -*/ -public interface Iterable extends java.lang.Iterable { - abstract public int size$get(); - abstract public Iterator iterator(); -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Iterator.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Iterator.java deleted file mode 100644 index 51f40d7db5..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Iterator.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xrun.XRuntime; - -/** - XTC Iterator interface and also the Java Iterator interface -*/ -public abstract class Iterator extends XTC implements java.util.Iterator { - public long next8() { throw XEC.TODO(); } - public char next2() { throw XEC.TODO(); } - public String nextStr() { throw XEC.TODO(); } - - // Conditional return known size - public long knownSize() { return XRuntime.False(0); } - public boolean knownEmpty() { - long sz = knownSize(); - return XRuntime.$COND && sz==0; - } - - Iterator concat(Iterator that) { throw XEC.TODO(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Object.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Object.java deleted file mode 100644 index 7978dcbaf8..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Object.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.util.S; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xtc.*; - -// Not-The-Java Object. -public interface Object extends Comparable { - // The fully dynamic equals lookup, based on the given compile-time class - static boolean equals( XTC gold_type, XTC x0, XTC x1 ) { - return gold_type.equals(x0,x1); // Dynamic against gold - } - - - static boolean equals$Object( XTC gold_type, XTC x0, XTC x1 ) { - return x0==x1; // Purely pointer equality - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Orderable.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Orderable.java deleted file mode 100644 index c778fbc11f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Orderable.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.XEC; -import org.xvm.util.Ary; -import org.xvm.util.S; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xtc.*; - -// XTC Orderable adds 'compare'. -// Any XTC classes which implement XTC 'Orderable' should also implement Java -// 'compareTo'. -public interface Orderable extends org.xvm.xec.ecstasy.Comparable { - - // The fully dynamic compare lookup - public static Ordered compare( XTC gold_type, XTC x0, XTC x1 ) { - return gold_type.compare(x0,x1); // Dynamic against gold - } - - public static Ordered compare$Orderable( XTC gold_type, XTC x0, XTC x1 ) { - // Compare as Orderables, and both x0 and x1 have the same class as gold_type. - // But this is the generic orderables compare. - throw XEC.TODO(); - } - - // Require implementations define this, which can typically be done with a - // default implementation. This same signature appears in the XTC base - // class, so we can do a v-call instead of an i-call. - public abstract Ordered compare( XTC x0, XTC x1 ); - - // If the XTC compiler knows 'this' and 'x1' are the same class it emits a - // short-form compare call, to directly check <,<=,>,>= - default boolean CompLt(Orderable ord) { - return compare((XTC)this,(XTC)ord) == Ordered.Lesser; - } - default boolean CompEq(Orderable ord) { - return compare((XTC)this,(XTC)ord) == Ordered.Equal; - } - - /** Each implementation will define the above abstract equals as: - * {@code public Ordered compare(XTC x0, XTC x1) { return compare$CLZ((CLZ)x0,(CLZ)x1) } } - * Each implemention will also define (commonly with a default gen'd code): - * {@code public Ordered compare$CLZ(CLZ x0, CLZ x1) { ... field-by-field or user-speced... } } - * - * The default implementation never uses the gold argument, but user-defined - * equals have access to it. - */ - - /* Generate: - public Ordered compare( XTC x0, XTC x1 ) { // Called by the fully dynamic lookup - return compare$CLZ(GOLD,(CLZ)x0,(CLZ)x1); - } - public static Ordered compare$CLZ( XTC gold, CLZ x0, CLZ x1 ) { - if( x0==x1 ) return Equal; - Ordered x; - if( (x=x0.fld0.compare(x1.fld0)) != Equal ) return x; - if( (x=x0.fld1.compare(x1.fld1)) != Equal ) return x; - if( (spaceship(x0.fld2,x1.fld2)) != Equal ) return x; - ... - return Equal; - } - */ - static void make_compare_default( ClassPart clz, String clzname, SB sb ) { - sb.ifmt("public static Ordered compare$%0( XTC gold, %0 x0,%0 x1 ) {\n",clzname).ii(); - sb.ip("if( x0==x1 ) return Ordered.Equal;\n"); - sb.ip("Ordered $x;\n"); - - Ary pps = new Ary<>(PropPart.class); - for( Part p : clz._name2kid.values() ) - if( p instanceof PropPart prop && prop.isField() ) - pps.setX(prop._order,prop); - for( PropPart prop : pps ) { - String fld = prop._name; - sb.ip( "if( ($x="); - if( xeq(prop) ) { sb.p("Orderable.spaceship( x0.").p(fld).p(",x1.").p(fld).p(")"); ClzBuilder.add_import(XCons.ORDERABLE); } - else { sb.fmt("gold.compare(x0.%0,x1.%0)",fld); } - sb.p(") != Ordered.Equal ) return $x;\n"); - } - sb.ip( "return Ordered.Equal;\n").di(); - sb.ip("}\n"); - }; - // Just a default Java compare, when the user overwrites the Const default compare - static void make_compare( String clzname, SB sb ) { - sb.ip("// Default compare\n"); - sb.ip("public Ordered compare( XTC x0, XTC x1 ) {\n").ii(); - sb.ifmt("return compare$%0(GOLD,(%0)x0,(%0)x1);\n",clzname).di(); - sb.ip("}\n"); - } - private static boolean xeq(PropPart p) { - return XType.xtype(p._con,false).is_jdk(); - } - - - // Called via explicit "3 <=> 5" - static Ordered spaceship(long x, long y) { - if( x < y ) return Ordered.Lesser; - if( x== y ) return Ordered.Equal; - return Ordered.Greater; - } - - static Ordered spaceship(String x, String y) { - int o = x.compareTo(y); - return o < 0 ? Ordered.Lesser - : o > 0 ? Ordered.Greater - : Ordered.Equal; - } - - - public static boolean lesser ( Ordered x ) { return x==Ordered.Lesser ; } - public static boolean greater( Ordered x ) { return x==Ordered.Greater; } - - public static O minOf( XTC gold, O o0, O o1 ) { - return compare(gold,(XTC)o0,(XTC)o1)==Ordered.Greater ? o1 : o0; - } - public static long minOf( XTC gold, long o0, long o1 ) { return Math.min(o0,o1); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Ordered.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Ordered.java deleted file mode 100644 index 4916a371da..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Ordered.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.xvm.xec.ecstasy; - -import org.xvm.xec.ecstasy.Enum; - -public enum Ordered { - Lesser, - Equal, - Greater; - public static final Ordered[] VALUES = values(); - public static final Enum GOLD = Enum.GOLD; // Dispatch against Ordered class same as Enum class - public static boolean equals$Ordered( Enum gold, Ordered o0, Ordered o1 ) { return o0==o1; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeEE.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeEE.java deleted file mode 100644 index fa27186e16..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeEE.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.xvm.xec.ecstasy; -public class RangeEE extends AbstractRange { - static final RangeEE GOLD = new RangeEE(); - public RangeEE( ) { } // No arg constructor - public RangeEE( long lo, long hi ) { super(lo,hi,true,true); } - public static RangeEE construct(long lo, long hi) { return new RangeEE(lo,hi); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeEI.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeEI.java deleted file mode 100644 index a1279b344e..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeEI.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.xvm.xec.ecstasy; -public class RangeEI extends AbstractRange { - static final RangeEI GOLD = new RangeEI(); - public RangeEI( ) { } // No arg constructor - public RangeEI( long lo, long hi ) { super(lo,hi,true,false); } - public static RangeEI construct(long lo, long hi) { return new RangeEI(lo,hi); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeIE.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeIE.java deleted file mode 100644 index 0fdf6d0d79..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeIE.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.xvm.xec.ecstasy; -public class RangeIE extends AbstractRange { - static final RangeIE GOLD = new RangeIE(); - public RangeIE( ) { } // No arg constructor - public RangeIE( long lo, long hi ) { super(lo,hi,false,true); } - public static RangeIE construct(long lo, long hi) { return new RangeIE(lo,hi); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeII.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeII.java deleted file mode 100644 index 261ac7a8d0..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/RangeII.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.xvm.xec.ecstasy; -public class RangeII extends AbstractRange { - public static final RangeII GOLD = new RangeII(); - public RangeII( ) { } // No arg constructor - public RangeII( long lo, long hi ) { super(lo,hi,false,false); } - public static RangeII construct(long lo, long hi) { return new RangeII(lo,hi); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Sequential.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Sequential.java deleted file mode 100644 index 889766447a..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Sequential.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.xvm.xec.ecstasy; - - -public interface Sequential { -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Service.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Service.java deleted file mode 100644 index 671b1b2c4a..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/Service.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.xvm.xec.ecstasy; - -import java.util.concurrent.*; -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xrun.Container; -import org.xvm.xrun.Never; -import org.xvm.xtc.*; - -import static org.xvm.XEC.TODO; - -/** The Java Service class, implementing an XTC hidden internal class. - The XTC Service is an *XTC interface*, not an XTC class, but it has many class-like properties. - - The XTC Service interface is thus treated like this Java Class. - -First cut Service impl comments: -- $sync Callers call normally; $async callers user alternate entry -- All internal calls just wrap args in a FutureTask & MethodHandle (meth ref); -- - FT is enqueued all in current thread -- $async version returns FT; $sync version returns FT.get() - -- Example: a normal call "I64 foo(long arg0, String arg1) { return arg0+cache(arg1).get(); }" -- Entry point in Service: - private I64 foo(int arg0, String arg1) { return arg0+cache(arg1).get(); } // Does the work, but in the ES thread - I64 $foo(int arg0, String arg1) { return $$foo(arg0,arg1).get(); } // Blocking entry - Future $$foo(int arg0, String arg1) { return $enqueue(new FT$foo(arg0,arg1)); } // Non-blocking entry; enqueues work - static private class FT$foo extends FutureTask { - private final int arg0; - private final String arg1; - FT$foo( int arg0, String arg1 ) { - this.arg0 = arg0; - this.arg1 = arg1; - } - I64 call() { return foo(arg0,arg1); } - } - - - -- ENqueue FT - -- - Make SvcQ if null -- - Add to SvcQ, get atomic Q size -- - If SvcQ was idle on add, then ALSO poke special FT to Main Q. -- - Main Q only takes FTs from Services, to awaken ES to that SvcQ - -- All ES threads pull from Main Q, get a SvcQ. -- One thread works each SvcQ, in order, until empty or e.g. timeout. -- TImeout: re-Q the SvcQ to MainQ, but at the end. Part of Fairness. -- Idle: no SvcQ on MainQ, so go fetch a different SvcQ -- MainQ is empty... ES manages threads down to min (e.g. 1). - - -"Logical Thread of Execution" -- Every calling thread maintains a stack of nested services. -- when calling into a service we do a "can nest" check & atomic acquire -- - if can nest, run the service in the current thread -- - if not nest, enqueue a FJ task and block -- - if running async ALWAYS fail "can nest" and enqueue -- When nesting increase current thread stack by self service -- "Can nest" if svc is already on stack, always "can nest" -- - If fail atomic acquire, enqueue - -Plan C- -- Simple, bad -- 1 Thread per Svc, personal Q -- Returns are boxed - - - - */ -public abstract class Service extends XTC -{ - public Service() {} // Explicit no-arg-no-work constructor - public Service(Never n) {} // Forced no-arg-no-work constructor - - - // Service work Q. Can be null for idle. - private volatile LinkedBlockingQueue Q; // Queue for this Service, to order callers - - // Self worker thread. - private volatile SvcThread T; - - // Self container, has to be the same as the allocating thread - final Container C = XEC.CONTAINER.get(); - - private class SvcThread extends Thread { - SvcThread() { - setName(getClass().getSimpleName()); - } - - public void run() { - XEC.CONTAINER.set(C); - while( true ) { - try { - XFT xft = Q.poll(1000,TimeUnit.MILLISECONDS); - if( xft==null ) // Idle queue - synchronized(this) { - xft = Q.poll(); // Check again under lock - if( xft==null ) { // Queue is idle, kill queue and thread - Q = null; - T = null; - break; // Thread dies here - } - } - xft.run(); - } catch( InterruptedException ee ) { - System.err.println(ee); - throw new RuntimeException(ee); - } - } - } - } - - - // Run by current thread, not service thread - public XFT $enqueue(Callable call) { - XFT xft = new XFT<>(call); - if( Q==null ) - synchronized(this) { - if( Q == null ) { - Q = new LinkedBlockingQueue<>(); - T = new SvcThread(); - T.start(); - } - }; - - try { Q.put(xft); } - catch( InterruptedException ee ) { System.err.println(ee); throw new RuntimeException(ee); } - return xft; - } - - // A FutureTask with a no-checked-exception get. - // Probably need e.g. CompletableFuture which doesn't throw exceptions. - public static class XFT extends FutureTask { - XFT(Callable call) { super(call); } - public V xget() { - try { - return get(); - } catch( InterruptedException | ExecutionException ie ) { - throw new XTC.Exception(ie.toString()); - } - } - } - - // A named callable. Nicer debugging. - public abstract static class XCall implements Callable { - public final String _name; - public XCall(String name) { _name=name; } - @Override public String toString() { return _name; } - } - - static public void make_methods(MethodPart meth, String java_class_name, SB sb ) { - ClzBuilder.add_import("java.util.concurrent.FutureTask"); - ClzBuilder.add_import("java.util.concurrent.Callable"); - - // Blocking single-$ version. - // Run by current thread, not service thread - //RET $MNAME(ARGS) { return $$foo(ARGS).get(); } // Blocking entry - sb.ip("public "); - ClzBuilder.ret_sig(meth,sb); - sb.p("$").p(meth._name).p("( "); - ClzBuilder.args(meth,sb,null,false); - sb.p(" ) { "); - boolean isVoidRet = meth.ret()==XCons.VOID; - if( !isVoidRet ) sb.p("return "); - sb.p("$$").p(meth._name).p("("); - ClzBuilder.arg_names(meth,sb,null); - sb.p(").xget(); }").nl(); - - SB gsb = new SB().p("XFT"); - if( !isVoidRet ) - ClzBuilder.ret_sig(meth,gsb.p("<")).p(">"); - String gen_ft = gsb.toString(); - - // Non-blocking double-$ version - // Run by current thread, not service thread - //XFT $$MNAME(ARGS) { return $enqueue(new Call$MNAME(ARGS)) } - sb.ip("public ").p(gen_ft); - sb.p(" $$").p(meth._name).p("( "); - ClzBuilder.args(meth,sb,null,false); - sb.p(" ) { return $enqueue(new Call$").p(meth._name).p("( "); - ClzBuilder.arg_names(meth,sb,null); - sb.p(")); }").nl(); - - // Now the wrapper class, one per every function call. - //static private class Call$foo extends Callable { - // private final int arg0; - // private final String arg1; - // Call$foo( int arg0, String arg1 ) { - // this.arg0 = arg0; - // this.arg1 = arg1; - // } - // I64 call() { return foo(arg0,arg1); } - //} - - sb.ifmt("private class Call$%0 extends XCall implements Callable {\n",meth._name).ii(); - // Final fields for args - XFun fun = meth.xfun(); - for( int i=0; i extends XTC { - public Future(Never n) {_future=null;} - - private final CompletableFuture _future; - public Future() { _future = new CompletableFuture<>(); } - public Referent $get() throws XTC.Exception { - try { - return _future.get(); - } catch( InterruptedException ie ) { - throw XEC.TODO(); // Not expecting the XTC runtime to interrupt - } catch( ExecutionException ee ) { - throw (XTC.Exception)ee.getCause(); // Need to rethrow the completed exception - } - } - public void $set(Referent ref) { _future.complete(ref); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Array.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Array.java deleted file mode 100644 index 06efbdf97d..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Array.java +++ /dev/null @@ -1,118 +0,0 @@ -package org.xvm.xec.ecstasy.collections; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.AbstractRange; -import org.xvm.xec.ecstasy.Appender; -import org.xvm.xec.ecstasy.Boolean; -import org.xvm.xec.ecstasy.Enum; -import org.xvm.xec.ecstasy.Freezable; -import org.xvm.xec.ecstasy.Iterable; -import org.xvm.xec.ecstasy.Iterator; -import org.xvm.xec.ecstasy.numbers.Int64; -import org.xvm.xec.ecstasy.text.Char; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xrun.Never; - -// ArrayList with a saner syntax and an exposed API for direct use by code-gen. -// Not intended for hand use. -public abstract class Array extends XTC - implements Appender, Iterable, Stringable, Freezable { - public static final Array GOLD = null; - public Array(Never n) { _gold=null; _mut=null; } // No-arg-no-work constructor - - public final E _gold; // Golden instance type - public Mutability _mut; - public int _len; - - Array( E gold, Mutability mut, int len ) { _gold=gold; _mut = mut; _len=len; } - - public static Array $new( XTC gold, Mutability mut, Array ary ) { - if( ary._len==0 ) { - if( gold == Boolean.GOLD ) return new Aryboolean(mut, Aryboolean.EMPTY); - if( gold == Char .GOLD ) return new Arychar (mut, Arychar .EMPTY); - if( gold == Int64 .GOLD ) return new Arylong (mut, Arylong .EMPTY); - if( gold == org.xvm.xec.ecstasy.text.String.GOLD ) return new AryString(mut, AryString.EMPTY); - throw XEC.TODO(); - } - assert gold==ary._gold : "Given GOLD: " + gold + " and an ary.GOLD: " + ary._gold; - - if( gold == Boolean.GOLD ) return new Aryboolean(mut, (Aryboolean)ary); - if( gold == Char .GOLD ) return new Arychar (mut, (Arychar )ary); - if( gold == Int64 .GOLD ) return new Arylong (mut, (Arylong )ary); - if( gold == org.xvm.xec.ecstasy.text.String.GOLD ) return new AryString(mut, (AryString)ary); - throw XEC.TODO(); - } - - /** Empty, as encoded as a size property read */ - public final boolean empty$get() { return _len==0; } - - /** Length, as encoded as a size property read */ - public final int size$get() { return _len; } - - public final E Element$get() { return _gold; } - - /** Element at */ - abstract public E at( long idx ); - - /** Add an element, doubling base array as needed */ - abstract public Array add( E e ); - - /** Slice */ - abstract public Array slice( AbstractRange r ); - - /** @return an iterator */ - abstract public Iterator iterator(); - - @Override public Mutability mutability$get() { return _mut; } - @Override public int mutability$getOrd() { return _mut.ordinal(); } - - public Array toArray(Mutability mut, boolean inPlace) { - if( inPlace && (mut == null || mut == _mut) ) return this; - if( mut == Mutability.Constant ) return freeze(inPlace); - if( !inPlace || mut.ordinal() > _mut.ordinal()) - return $new(_gold, mut, this); // return a copy that has the desired mutability - _mut = mut; - return this; - } - - static final SB SBX = new SB(); - abstract public String toString(); - - // --- Freezable - abstract public Array freeze( boolean inPlace ); - - // --- Comparable - abstract public boolean equals( Object o ); - - // --- Hashable - abstract public int hashCode( ); - - // --- Mutability - public enum Mutability { - Constant, // Deeply immutable - Persistent, // Odd name, but shallow immutable. Deeper elements can change. - Fixed, // Tuples and arrays are fixed length, but mutable array contents - Mutable; // Classic mutable - public static final Mutability[] VALUES = values(); - public static final Enum GOLD = Enum.GOLD; // Dispatch against Ordered class same as Enum class - } - - // --- text/Stringable - @Override public long estimateStringLength() { return _len*10L; } - - // --- Comparable - public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } - - public static boolean equals$Array(Array gold, Array a0, Array a1) { - if( a0 == a1 ) return true; - if( a0._len != a1._len ) return false; - for( int i=0; i { - public static final AryString GOLD = new AryString(); - public static final AryString EMPTY= new AryString(); - - public String[] _es; - private AryString(Mutability mut, String[] es, int len) { super(org.xvm.xec.ecstasy.text.String.GOLD,mut,len); _es = es; } - public AryString( ) { this(Mutable , new String[ 0 ],0); } - private AryString(int len ) { this(Fixed , new String[len],len); } - public AryString(double x, String... es) { this(Constant, es,es.length); } - public AryString(Mutability mut, AryString as) { this(mut,as._es.clone(),as._len); } - public AryString(AryString as) { this(as._mut,as._es.clone(),as._len); } - - public AryString( long len, LongFunction fcn ) { - this((int)len); - if( _len != len ) throw XEC.TODO(); // Too Big - for( int i=0; i<_len; i++ ) - _es[i] = fcn.apply(i); - } - - public static AryString construct(long len, LongFunction fcn) { return new AryString(len,fcn); } - public static AryString construct() { return new AryString(); } - public static AryString construct(Mutability mut, AryString as) { return new AryString(mut,as); } - - // Add an element, doubling base array as needed - public AryString add( org.xvm.xec.ecstasy.text.String s ) { return add(s._i); } - // Add an element, doubling base array as needed - public AryString add( String s ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = s; - return this; - } - - // Fetch element - public String at8(long idx) { - if( 0 <= idx && idx < _len ) - return _es[(int)idx]; - throw new ArrayIndexOutOfBoundsException(""+idx+" >= "+_len); - } - - @Override public org.xvm.xec.ecstasy.text.String at(long idx) { - return org.xvm.xec.ecstasy.text.String.construct(at8(idx)); - } - - /** Slice */ - public AryString slice( AbstractRange r ) { - if( r._incr != 1 ) throw XEC.TODO(); - return new AryString(_mut, Arrays.copyOfRange(_es,(int)r._start,(int)r._end), (int)r.span()); - } - - public int indexOf( String e ) { - for( int i=0; i<_len; i++ ) - if( _es[i].equals(e) ) - return XRuntime.True(i); - return XRuntime.False(-1); - } - public AryString removeUnordered(String e) { - int idx = indexOf(e); - return idx== -1 ? this : deleteUnordered(idx); - } - public AryString deleteUnordered(int idx) { - _es[idx] = _es[--_len]; - return this; - } - - public AryString delete(long idx) { - System.arraycopy(_es,(int)idx+1,_es,(int)idx,--_len-(int)idx); - return this; - } - - /** @return an iterator */ - @Override public Iterator iterator() { return new IterXString(); } - public class IterXString extends Iterator { - private int _i; - @Override public org.xvm.xec.ecstasy.text.String next() { return org.xvm.xec.ecstasy.text.String.construct(nextStr()); } - @Override public String nextStr() { return (XRuntime.$COND = hasNext()) ? _es[_i++] : null; } - @Override public boolean hasNext() { return _i<_len; } - @Override public final String toString() { return ""+_i+".."+_len; } - // --- Comparable - public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } - } - - /** @return an iterator */ - private class IterPrim implements Iterable { - public IterString iterator() { return new IterString(); } - } - public Iterable iterStr() { return new IterPrim(); } - private class IterString extends Iterator { - private int _i; - @Override public String next() { return _es[_i++]; } - @Override public boolean hasNext() { return _i<_len; } - } - - - // Note that the hashCode() and equals() are not invariant to changes in the - // underlying array. If the hashCode() is used (e.g., inserting into a - // HashMap) and the then the array changes, the hashCode() will change also. - @Override public boolean equals( Object o ) { - if( this==o ) return true; - if( !(o instanceof AryString ary) ) return false; - if( _len != ary._len ) return false; - if( _es == ary._es ) return true; - for( int i=0; i<_len; i++ ) - if( _es[i].equals(ary._es[i]) ) - return false; - return true; - } - @Override public int hashCode( ) { - long sum=_len; - for( int i=0; i<_len; i++ ) - sum ^= _es[i].hashCode(); - return (int)sum; - } - - AryString clear() { _len=0; return this; } - - // --- Collections - @Override public String toString() { return toString(", ","[","]",null,null,null); } - - public String toString(String sep, String pre, String post, Int64 limit, String trunc, Fun render) { - if( limit != null ) throw XEC.TODO(); - if( render != null ) throw XEC.TODO(); - SBX.clear(); - SBX.p(pre); - if( _len > 0 ) { - for( int i=0; i<_len; i++ ) - SBX.p('"').p(_es[i]).p('"').p(sep); - SBX.unchar(sep.length()); - } - String str = SBX.p(post).toString(); - SBX.clear(); - return str; - } - - // --- Freezable - @Override public AryString freeze(boolean inPlace) { - if( _mut==Mutability.Constant ) return this; - if( !inPlace ) return construct(Mutability.Constant,this); - _mut = Mutability.Constant; - return this; - } - - // --- Appender - - // --- text/Stringable - @Override public long estimateStringLength() { return _len; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/AryUInt8.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/AryUInt8.java deleted file mode 100644 index fdf5b9357c..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/AryUInt8.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.xvm.xec.ecstasy.collections; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xec.ecstasy.Iterator; -import org.xvm.xec.ecstasy.AbstractRange; -import org.xvm.xec.ecstasy.numbers.UInt8; - -import static org.xvm.xec.ecstasy.collections.Array.Mutability.*; - -import java.util.Arrays; - -// ArrayList with primitives and an exposed API for direct use by code-gen. -// Not intended for hand use. -public class AryUInt8 extends Array { - public static final AryUInt8 GOLD = new AryUInt8(); - - public byte[] _es; - public AryUInt8(Mutability mut, byte[] es) { super(UInt8.GOLD,mut,es.length); _es = es; } - public AryUInt8( ) { this(Mutable , new byte[ 0 ]); } - public AryUInt8(int len ) { this(Fixed , new byte[len]); } - public AryUInt8(double x, byte... es) { this(Constant, es); } - public AryUInt8(Mutability mut, AryUInt8 as) { this(mut,as._es.clone()); } - public AryUInt8(AryUInt8 as) { this(as._mut,as._es.clone()); } - - public static AryUInt8 construct() { return new AryUInt8(); } - public static AryUInt8 construct(Mutability mut, AryUInt8 as) { return new AryUInt8(mut,as); } - - // Fetch element; cannot specify an "unsigned" get at the java level - public int at8(long idx) { - if( 0 <= idx && idx < _len ) - return (_es[(int)idx]&0xFF); - throw new ArrayIndexOutOfBoundsException(""+idx+" >= "+_len); - } - @Override public UInt8 at(long idx) { return UInt8.make((byte)at8(idx)); } - - // Add an element, doubling base array as needed - public AryUInt8 add( int e ) { - if( _len >= _es.length ) { - int len=1; - while( len <= _es.length ) len<<=1; - _es = Arrays.copyOf(_es,len); - } - _es[_len++] = (byte)e; - return this; - } - - // Add an element, doubling base array as needed - public AryUInt8 add( UInt8 e ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = e._i; // Unbox - return this; - } - - /** Slice */ - public AryUInt8 slice( AbstractRange r ) { throw XEC.TODO(); } - - public AryUInt8 addAll( AryUInt8 ls ) { throw XEC.TODO(); } - - public void removeUnordered(byte idx) { throw XEC.TODO(); } - public void deleteUnordered(byte idx) { throw XEC.TODO(); } - public AryUInt8 delete(long idx) { - System.arraycopy(_es,(int)idx+1,_es,(int)idx,--_len-(int)idx); - return this; - } - - - private static final SB SBX = new SB(); - @Override public String toString() { - SBX.p('['); - for( int i=0; i<_len; i++ ) - SBX.p(_es[i]&0xFF).p(", "); - String str = SBX.unchar(2).p(']').toString(); - SBX.clear(); - return str; - } - - // Note that the hashCode() and equals() are not invariant to changes in the - // underlying array. If the hashCode() is used (e.g., inserting into a - // HashMap) and the then the array changes, the hashCode() will change also. - @Override public boolean equals( Object o ) { - if( this==o ) return true; - if( !(o instanceof AryUInt8 ary) ) return false; - if( _len != ary._len ) return false; - if( _es == ary._es ) return true; - for( int i=0; i<_len; i++ ) - if( _es[i] != ary._es[i] ) - return false; - return true; - } - @Override public int hashCode( ) { - long sum=_len; - for( int i=0; i<_len; i++ ) - sum += _es[i]; - return (int)(sum ^ (sum>>32)); - } - - - /** @return an iterator */ - @Override public Iterator iterator() { throw XEC.TODO(); } - - // --- Freezable - @Override public AryUInt8 freeze(boolean inPlace) { - if( _mut==Mutability.Constant ) return this; - if( !inPlace ) return construct(Mutability.Constant,this); - _mut = Mutability.Constant; - return this; - } - - // --- Appender - - // --- text/Stringable - @Override public long estimateStringLength() { return _len*5; } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/AryXTC.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/AryXTC.java deleted file mode 100644 index ea9d2bd3a0..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/AryXTC.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.xvm.xec.ecstasy.collections; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Iterator; -import org.xvm.xec.ecstasy.AbstractRange; -import org.xvm.xrun.Never; -import org.xvm.xrun.XRuntime; - -import static org.xvm.xec.ecstasy.collections.Array.Mutability.*; - -import java.util.Arrays; -import java.util.function.LongFunction; - -// ArrayList with a saner syntax and an exposed API for direct use by code-gen. -// Not intended for hand use. -public class AryXTC extends Array { - public static final AryXTC GOLD = new AryXTC((Never)null); - public AryXTC(Never n) { super(n); } // No-arg-no-work constructor - public static final AryXTC EMPTY = new AryXTC(null,new XTC[0]); - - public E[] _es; - private AryXTC(E gold, Mutability mut, E[] es) { super(gold,mut,es.length); _es = es; } - public AryXTC(E gold ) { this(gold , Mutable , EMPTY); } - public AryXTC(E gold, int len) { this(gold , Mutable , (E[]) java.lang.reflect.Array.newInstance(gold.getClass(), len)); } - public AryXTC(E gold, E[] es ) { this(gold , Constant, es); } - public AryXTC(E... es ) { this(es[0], Constant, Arrays.copyOfRange(es,1,es.length)); } - public AryXTC(E gold, Mutability mut, AryXTC as) { this(gold,mut,as._es.clone()); } - public AryXTC(AryXTC as) { this(as._gold,as._mut,as._es.clone()); } - - public static AryXTC construct(E gold) { return new AryXTC<>(gold); } - - - public AryXTC(E gold, long len, LongFunction fcn ) { - this(gold, Fixed, (E[]) java.lang.reflect.Array.newInstance(gold.getClass(), (int)len)); - if( _len != len ) throw XEC.TODO(); // Too Big - for( int i=0; i<_len; i++ ) - _es[i] = fcn.apply(i); - } - - /** Element at */ - public E at( long idx ) { return at8(idx); } - public E at8( long idx ) { - if( idx >= _len ) throw new ArrayIndexOutOfBoundsException((int)idx); - return _es[(int)idx]; - } - - /** Add an element, doubling base array as needed */ - public AryXTC add( E e ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = e; - return this; - } - - /** Slice */ - public AryXTC slice( AbstractRange r ) { throw XEC.TODO(); } - public AryXTC delete(long idx) { - System.arraycopy(_es,(int)idx+1,_es,(int)idx,--_len-(int)idx); - return this; - } - - /** @return an iterator */ - @Override public Iterator iterator() { return new Iter(); } - private class Iter extends Iterator { - private int _i; - @Override public E next() { return (XRuntime.$COND = hasNext()) ? _es[_i++] : null; } - @Override public boolean hasNext() { return _i<_len; } - @Override public final String toString() { return ""+_i+".."+_len; } - // --- Comparable - @Override public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } - } - - @Override public AryXTC freeze( boolean inPlace ) { - if( _mut == Constant ) return this; - // TODO: no need for array clone on Persistent - AryXTC ary = inPlace ? this : new AryXTC(_gold,Constant,_es); - ary._mut = Constant; - for( E e : ary._es ) - if( e!=null ) - e.freeze(inPlace); - return ary; - } - - // Recusively used, optimistic - private static SB SBX = new SB(); - @Override public String toString() { - SB sb; - if( SBX==null ) sb = new SB(); - else { sb=SBX; SBX=null; } - for( int i=0; i<_len; i++ ) - sb.p(_es[i]==null ? "null" : _es[i].toString()).p(", "); - String str = sb.unchar(2).p(']').toString(); - sb.clear(); - SBX=sb; // Free up for next call - return str; - } - - // --- Appender - - public static boolean equals$AryXTC( AryXTC gold, Array a0, Array a1 ) { - if( a0 == a1 ) return true; - if( a0._len != a1._len ) return false; - for( int i=0; i { - public static final Aryboolean GOLD = new Aryboolean(); - public static final Aryboolean EMPTY= new Aryboolean(); - - public boolean[] _es; - private Aryboolean(Mutability mut, boolean[] es) { super(Boolean.GOLD,mut,es.length); _es = es; } - public Aryboolean( ) { this(Mutable , new boolean[ 0 ]); } - public Aryboolean(long len ) { this(Fixed , new boolean[(int)len]); } - public Aryboolean(double x, boolean... es) { this(Constant, es); } - public Aryboolean(Mutability mut, Aryboolean as) { this(mut,as._es.clone()); } - public Aryboolean(Aryboolean as) { this(as._mut,as); } - - public interface IntBooleanOper { boolean apply(int i); } - public Aryboolean( long len, IntBooleanOper fcn ) { - this((int)len); - if( _len != len ) throw XEC.TODO(); // Too Big - for( int i=0; i<_len; i++ ) - _es[i] = fcn.apply(i); - } - - public static Aryboolean construct(Mutability mut, Aryboolean as) { return new Aryboolean(mut,as); } - public static Aryboolean construct(long len) { return new Aryboolean(len); } - public static Aryboolean construct( long len, IntBooleanOper fcn ) { return new Aryboolean(len,fcn); } - - // Fetch element - public boolean at8(long idx) { - if( 0 <= idx && idx < _len ) - return _es[(int)idx]; - throw new ArrayIndexOutOfBoundsException( idx+" >= "+_len ); - } - public boolean getElement(long idx ) { return at8(idx); } - - // Fetch element - @Override public Boolean at(long idx) { return Boolean.make(at8(idx)); } - - // Add an element, doubling base array as needed - public Aryboolean add( boolean c ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = c; - return this; - } - // Add an element, doubling base array as needed - @Override public Aryboolean add( Boolean c ) { return add(c==Boolean.TRUE); } - - public void set(long idx, boolean e) { - if( !(0 <= idx && idx < _len) ) - throw new ArrayIndexOutOfBoundsException( idx+" >= "+_len ); - _es[(int)idx] = e; - } - - public void setElement(long idx, boolean e) { set(idx,e); } - - /** Slice */ - public Aryboolean slice( AbstractRange r ) { throw XEC.TODO(); } - - public Aryboolean delete(long idx) { - System.arraycopy(_es,(int)idx+1,_es,(int)idx,--_len-(int)idx); - return this; - } - - @Override public Aryboolean toArray(Mutability mut, boolean inPlace) { - return (Aryboolean)super.toArray(mut,inPlace); - } - - @Override public String toString() { - SBX.p('['); - for( int i=0; i<_len; i++ ) - SBX.p(_es[i]).p(", "); - String str = SBX.unchar(2).p(']').toString(); - SBX.clear(); - return str; - } - - // Note that the hashCode() and equals() are not invariant to changes in the - // underlying array. If the hashCode() is used (e.g., inserting into a - // HashMap) and the then the array changes, the hashCode() will change also. - @Override public boolean equals( java.lang.Object o ) { - if( this==o ) return true; - if( !(o instanceof Aryboolean ary) ) return false; - if( _len != ary._len ) return false; - if( _es == ary._es ) return true; - for( int i=0; i<_len; i++ ) - if( _es[i] != ary._es[i] ) - return false; - return true; - } - @Override public int hashCode( ) { - long sum=_len; - for( int i=0; i<_len; i++ ) - sum = (sum<<1) | (sum>>>63) ^ (_es[i] ? 1 : 0); - return (int)sum; - } - - Aryboolean clear() { _len=0; return this; } - - /** @return an iterator */ - @Override public Iterboolean iterator() { return new Iterboolean(); } - public class Iterboolean extends Iterator { - private int _i; - @Override public Boolean next() { return (XRuntime.$COND = hasNext()) ? Boolean.make(_es[_i++]) : Boolean.FALSE; } - @Override public boolean hasNext() { return _i<_len; } - @Override public final String toString() { return _i+".."+_len; } - // --- Comparable - @Override public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } - } - - - // --- Freezable - @Override public Aryboolean freeze(boolean inPlace) { - if( _mut==Mutability.Constant ) return this; - if( !inPlace ) return construct(Mutability.Constant,this); - _mut = Mutability.Constant; - return this; - } - - // --- Appender - - // --- text/Stringable - @Override public long estimateStringLength() { return _len; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Arychar.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Arychar.java deleted file mode 100644 index 7c80b53963..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Arychar.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.xvm.xec.ecstasy.collections; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Iterator; -import org.xvm.xec.ecstasy.AbstractRange; -import org.xvm.xec.ecstasy.text.Char; -import org.xvm.xrun.XRuntime; - -import static org.xvm.xec.ecstasy.collections.Array.Mutability.*; - -import java.util.Arrays; -import java.util.function.LongUnaryOperator; - -// ArrayList with primitives and an exposed API for direct use by code-gen. -// Not intended for hand use. -@SuppressWarnings("unused") -public class Arychar extends Array { - public static final Arychar GOLD = new Arychar(); - public static final Arychar EMPTY= new Arychar(); - - public char[] _es; - protected Arychar(Mutability mut, int len, char[] es) { super(Char.GOLD,mut,len); _es = es; } - public Arychar( ) { this(Mutable , 0 , new char[ 0 ]); } - public Arychar(int len ) { this(Fixed , len, new char[len]); } - public Arychar(Mutability mut, Arychar as) { this(mut, as._len, as._es.clone()); } - public Arychar(double x, char... es) { this(Constant, es.length, es); } - public Arychar(Arychar as) { this(as._mut,as); } - - public Arychar( long len, LongUnaryOperator fcn ) { - this((int)len); - if( _len != len ) throw XEC.TODO(); // Too Big - for( int i=0; i<_len; i++ ) - _es[i] = (char)fcn.applyAsLong(i); - } - - public Arychar(String s) { - this(s.length(), i -> s.charAt((int)i)); - } - - public static Arychar construct(Arychar as) { return new Arychar(as); } - public static Arychar construct() { return new Arychar(); } - public static Arychar construct( String s ) { return new Arychar(s); } - public static Arychar construct( long len, LongUnaryOperator fcn ) { return new Arychar(len,fcn); } - public static Arychar construct( Mutability mut, Arychar as) { return new Arychar(mut,as); } - - // Fetch element - public char at8(long idx) { - if( 0 <= idx && idx < _len ) - return _es[(int)idx]; - throw new ArrayIndexOutOfBoundsException( idx+" >= "+_len ); - } - // Fetch element - @Override public Char at(long idx) { return Char.make(at8(idx)); } - - // Add an element, doubling base array as needed - public Arychar add( char c ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = c; - return this; - } - public Arychar add( long x ) { return add((char)x); } - // Add an element, doubling base array as needed - @Override public Arychar add( Char c ) { return add(c._i); } - - public Arychar delete(long idx) { - System.arraycopy(_es,(int)idx+1,_es,(int)idx,--_len-(int)idx); - return this; - } - - /** Slice */ - public Arychar slice( AbstractRange r ) { throw XEC.TODO(); } - - @Override public String toString() { - SBX.p('['); - for( int i=0; i<_len; i++ ) - SBX.p(_es[i]).p(", "); - String str = SBX.unchar(2).p(']').toString(); - SBX.clear(); - return str; - } - - // Note that the hashCode() and equals() are not invariant to changes in the - // underlying array. If the hashCode() is used (e.g., inserting into a - // HashMap) and the then the array changes, the hashCode() will change also. - @Override public boolean equals( Object o ) { - if( this==o ) return true; - if( !(o instanceof Arychar ary) ) return false; - if( _len != ary._len ) return false; - if( _es == ary._es ) return true; - for( int i=0; i<_len; i++ ) - if( _es[i] != ary._es[i] ) - return false; - return true; - } - @Override public int hashCode( ) { - long sum=_len; - for( int i=0; i<_len; i++ ) - sum += _es[i]; - return (int)sum; - } - - Arychar clear() { _len=0; return this; } - - /** @return an iterator */ - @Override public Iterchar iterator() { return new Iterchar(); } - public class Iterchar extends Iterator { - private int _i; - @Override public Char next() { return Char.make((char)next8()); } - @Override public long next8() { return (XRuntime.$COND = hasNext()) ? _es[_i++] : 0; } - @Override public boolean hasNext() { return _i<_len; } - @Override public final String toString() { return _i+".."+_len; } - @Override public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } - } - - // --- Freezable - @Override public Arychar freeze(boolean inPlace) { - if( _mut==Mutability.Constant ) return this; - if( !inPlace ) return construct(Mutability.Constant,this); - _mut = Mutability.Constant; - return this; - } - - // --- Appender - - // --- text/Stringable - @Override public long estimateStringLength() { return _len; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Aryint.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Aryint.java deleted file mode 100644 index c02e2971de..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Aryint.java +++ /dev/null @@ -1,166 +0,0 @@ -package org.xvm.xec.ecstasy.collections; - -import java.util.Arrays; -import java.util.Random; -import java.util.function.IntUnaryOperator; -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.AbstractRange; -import org.xvm.xec.ecstasy.Boolean; -import org.xvm.xec.ecstasy.Iterator; -import org.xvm.xec.ecstasy.numbers.Int32; -import org.xvm.xrun.XRuntime; -import static org.xvm.xec.ecstasy.collections.Array.Mutability.*; - -// ArrayList with primitives and an exposed API for direct use by code-gen. -// Not intended for hand use. -@SuppressWarnings("unused") -public class Aryint extends Array { - public static final Aryint GOLD = new Aryint(); - public static final Aryint EMPTY= new Aryint(); - - public int[] _es; - private Aryint(Mutability mut, int[] es) { super(Int32.GOLD,mut,es.length); _es = es; } - public Aryint( ) { this(Mutable , new int[ 0 ]); } - public Aryint(int len ) { this(Fixed , new int[len]); } - public Aryint(double x, int... es) { this(Constant, es); } - public Aryint(Mutability mut, Aryint as) { this(mut,as._es.clone()); } - public Aryint(Aryint as) { this(as._mut,as); } - public Aryint(double x, long... es) { - super(Int32.GOLD,Constant,es.length); - _es = new int[es.length]; - for( int i=0; i= "+_len ); - } - @Override public Int32 at(long idx) { return Int32.make(at8(idx)); } - - // Add an element, doubling base array as needed - public Aryint add( int e ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = e; - return this; - } - - // Add an element, doubling base array as needed - public Aryint add( Int32 e ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = e._i; // Unbox - return this; - } - - /** Slice */ - public Aryint slice( AbstractRange r ) { - throw XEC.TODO(); - } - - public Aryint addAll( Aryint ls ) { - for( int i=0; i { - private int _i; - @Override public Int32 next() { return Int32.make(next8()); } - @Override public long next8() { return (XRuntime.$COND = hasNext()) ? _es[_i++] : 0; } - @Override public boolean hasNext() { return _i<_len; } - @Override public final String toString() { return _i+".."+_len; } - // --- Comparable - @Override public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } - } - - // --- Freezable - @Override public Aryint freeze(boolean inPlace) { - if( _mut==Constant ) return this; - if( !inPlace ) return construct(Constant,this); - _mut = Constant; - return this; - } - - // --- Appender - @Override public String toString() { - SBX.p("[ "); - for( int i=0; i<_len; i++ ) - SBX.p(_es[i]).p(", "); - String str = SBX.unchar(2).p("]").toString(); - SBX.clear(); - return str; - } - - // Note that the hashCode() and equals() are not invariant to changes in the - // underlying array. If the hashCode() is used (e.g., inserting into a - // HashMap) and the then the array changes, the hashCode() will change also. - @Override public boolean equals( Object o ) { - if( this==o ) return true; - if( !(o instanceof Aryint ary) ) return false; - if( _len != ary._len ) return false; - if( _es == ary._es ) return true; - for( int i=0; i<_len; i++ ) - if( _es[i] != ary._es[i] ) - return false; - return true; - } - @Override public int hashCode( ) { - int sum=_len; - for( int i=0; i<_len; i++ ) - sum += _es[i]; - return (int)(sum ^ (sum>>32)); - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Arylong.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Arylong.java deleted file mode 100644 index 87cbab5c0e..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Arylong.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.xvm.xec.ecstasy.collections; - -import java.util.Arrays; -import java.util.Random; -import java.util.function.LongUnaryOperator; -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.AbstractRange; -import org.xvm.xec.ecstasy.Boolean; -import org.xvm.xec.ecstasy.Iterator; -import org.xvm.xec.ecstasy.numbers.Int64; -import org.xvm.xrun.XRuntime; -import static org.xvm.xec.ecstasy.collections.Array.Mutability.*; - -// ArrayList with primitives and an exposed API for direct use by code-gen. -// Not intended for hand use. -@SuppressWarnings("unused") -public class Arylong extends Array { - public static final Arylong GOLD = new Arylong(); - public static final Arylong EMPTY= new Arylong(); - - public long[] _es; - private Arylong(Mutability mut, long[] es) { super(Int64.GOLD,mut,es.length); _es = es; } - public Arylong( ) { this(Mutable , new long[ 0 ]); } - public Arylong(int len ) { this(Fixed , new long[len]); } - public Arylong(double x, long... es) { this(Constant, es); } - public Arylong(Mutability mut, Arylong as) { this(mut,as._es.clone()); } - public Arylong(Arylong as) { this(as._mut,as); } - - public Arylong( long len, LongUnaryOperator fcn ) { - this((int)len); - if( _len != len ) throw XEC.TODO(); // Too Big - for( int i=0; i<_len; i++ ) - _es[i] = fcn.applyAsLong(i); - } - public static Arylong construct(Mutability mut, Arylong as) { return new Arylong(mut,as); } - public static Arylong construct() { return new Arylong(); } - public static Arylong construct(long len, LongUnaryOperator fcn ) { return new Arylong(len,fcn); } - public static Arylong construct(long len, long fill) { return new Arylong((int)len, i->fill ); } - public static Arylong construct(long len) { return new Arylong((int)len); } - - - // Fetch element - public long at8(long idx) { - if( 0 <= idx && idx < _len ) - return _es[(int)idx]; - throw new ArrayIndexOutOfBoundsException( idx+" >= "+_len ); - } - @Override public Int64 at(long idx) { return Int64.make(at8(idx)); } - - // Add an element, doubling base array as needed - public Arylong add( long e ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = e; - return this; - } - - // Add an element, doubling base array as needed - public Arylong add( Int64 e ) { - if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1)); - _es[_len++] = e._i; // Unbox - return this; - } - - /** Slice */ - public Arylong slice( AbstractRange r ) { - throw XEC.TODO(); - } - - public Arylong addAll( Arylong ls ) { - for( int i=0; i { - private int _i; - @Override public Int64 next() { return Int64.make(next8()); } - @Override public long next8() { return (XRuntime.$COND = hasNext()) ? _es[_i++] : 0; } - @Override public boolean hasNext() { return _i<_len; } - @Override public final String toString() { return _i+".."+_len; } - // --- Comparable - @Override public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } - } - - // --- Freezable - @Override public Arylong freeze(boolean inPlace) { - if( _mut==Constant ) return this; - if( !inPlace ) return construct(Constant,this); - _mut = Constant; - return this; - } - - // --- Appender - @Override public String toString() { - SBX.p("[ "); - for( int i=0; i<_len; i++ ) - SBX.p(_es[i]).p(", "); - String str = SBX.unchar(2).p("]").toString(); - SBX.clear(); - return str; - } - - // Note that the hashCode() and equals() are not invariant to changes in the - // underlying array. If the hashCode() is used (e.g., inserting into a - // HashMap) and the then the array changes, the hashCode() will change also. - @Override public boolean equals( Object o ) { - if( this==o ) return true; - if( !(o instanceof Arylong ary) ) return false; - if( _len != ary._len ) return false; - if( _es == ary._es ) return true; - for( int i=0; i<_len; i++ ) - if( _es[i] != ary._es[i] ) - return false; - return true; - } - @Override public int hashCode( ) { - long sum=_len; - for( int i=0; i<_len; i++ ) - sum += _es[i]; - return (int)(sum ^ (sum>>32)); - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Hashable.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Hashable.java deleted file mode 100644 index 069c7e5708..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Hashable.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.xvm.xec.ecstasy.collections; - -import org.xvm.util.SB; -import org.xvm.util.S; -import org.xvm.xec.XTC; -import org.xvm.xtc.*; - -public interface Hashable extends org.xvm.xec.ecstasy.Comparable { - - // The fully dynamic hash lookup - public static long hashCode$Hashable( XTC gold_type, Hashable x ) { - return gold_type.hashCode((XTC)x); // Dynamic against gold - } - - // The fully dynamic hash lookup - public static boolean equals$Hashable( XTC gold_type, Hashable x0, Hashable x1 ) { - return gold_type.equals((XTC)x0,(XTC)x1); // Dynamic against gold - } - - - // Require implementations define this, which can typically be done with a - // default implementation. This same signature appears in the XTC base - // class, so we can do a v-call instead of an i-call. - public abstract long hashCode( XTC x ); - - /* Generate: - public long hash(XTC x0) { // Called by the fully dynamic lookup - return hash$CLZ(GOLD,(CLZ)x0); - } - public static long hash$CLZ( XTC gold, CLZ x ) { - return x.fld0.hash()^x.fld1^...^x.fldN.hash(); - } - */ - static void make_hashCode_default( ClassPart clz, String clzname, SB sb ) { - sb.ifmt("public static long hashCode$%0(XTC gold, %0 x) {\n",clzname).ii(); - sb.ip( "return "); - boolean any=false; - for( Part p : clz._name2kid.values() ) - if( p instanceof PropPart prop && prop.isField() ) { - any = true; - sb.p("x.").p(prop._name); - XType xt = XType.xtype(prop._con,false); - if( !xt.zero() ) // Numbers as themselves for hash - sb.p(".hashCode()"); // Others call hashCode - sb.p(" ^ "); - } - if( any ) sb.unchar(3); - else sb.p("0xDEADBEEF"); - sb.p(";\n").di(); - sb.ip("}\n"); - }; - static void make_hashCode( String clzname, SB sb ) { - sb.ip("// Default hash\n"); - sb.ifmt("public long hashCode( XTC x ) { return hashCode$%0(GOLD,(%0)x); }\n",clzname); - } - - // Java 32-bit hashCode() wrapping XTC 64-bit hash() - //public int hashCode() { long h = hash(); return (int)((h>>32)^h); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Map.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Map.java deleted file mode 100644 index 844a49f2ff..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Map.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.xvm.xec.ecstasy.collections; - -import org.xvm.util.SB; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xec.ecstasy.numbers.Int64; - -import java.util.HashMap; - -public abstract class Map extends XTC implements Stringable { - private final HashMap _map; - - public Map() { _map = new HashMap<>(); } - - public static Map make( Map map ) { return map; } - - public void put( K key, V val ) { _map.put(key,val); } - public void put( long key, String val ) { _map.put((K)Int64.make(key),(V)org.xvm.xec.ecstasy.text.String.make(val)); } - - // Java default equals. - // TODO: This needs to use XTC equals - @Override public boolean equals( Object o ) { - if( o==this ) return true; - return o instanceof Map that && _map.equals(that._map); - } - - - //// Return a tuple class for this set of types. The class is cached, and can - //// be used many times. - //public static String make_class( HashMap cache, TCon[] parms ) { - // XType xkey = XType.xtype(parms[0],true); - // XType xval = XType.xtype(parms[1],true); - // SB sb = new SB().p("XMap$"); - // xkey.str(sb).p("$"); - // xval.str(sb); - // String tclz = sb.toString(); - // sb.clear(); - // - // // Lookup cached version - // if( !cache.containsKey(tclz) ) { - // // XMap N class - // sb.p("class ").p(tclz).p(" extends XMap<"); - // xkey.str(sb).p(","); - // xval.str(sb).p("> {").nl().ii(); - // sb.di().ip("}").nl(); - // cache.put(tclz,sb.toString()); - // } - // - // return tclz; - //} -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Tuple.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Tuple.java deleted file mode 100644 index 57beebb650..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/collections/Tuple.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.xvm.xec.ecstasy.collections; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xtc.*; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.AbstractRange; -import org.xvm.xec.ecstasy.Comparable; -import org.xvm.xec.ecstasy.collections.Array.Mutability; - -public interface Tuple extends Cloneable, Comparable { - // Array-like interface - abstract public XTC at(long i); // At an index - abstract public void set(long i, XTC o); // Set an index - - public abstract int size$get(); - - // Using slice call instead of array syntax - default public Tuple slice( AbstractRange r) { return at(r); } - - public abstract Tuple at( AbstractRange r); - - public abstract Mutability mutability$get(); - - public abstract Tuple add( XTC x ); - - public abstract Tuple addAll( Tuple tup ); - - public abstract Tuple ensureMutability(Mutability mut0, boolean inPlace); - - public static boolean equals$Tuple(Tuple0 gold, Tuple0 t0, Tuple0 t1 ) { - return gold.equals(t0,t1); - } - - // Return a tuple class for this set of types. The class is cached, and can - // be used many times. - public static XClz make_class( XClz xtt ) { - // Lookup cached version - int N = xtt._xts.length; - if( N==0 ) return xtt; // Tuple0 already exists in the base runtime - - String tclz = xtt.clz(new SB()).toString(); - String pack = (XEC.XCLZ+"."+xtt._pack).intern(); - String qual = (pack+"."+tclz).intern(); - ClzBuilder.add_import(qual); - if( ClzBldSet.find(qual) ) return xtt; - /* Gotta build one. Looks like: - class Tuple3$long$String$char extends Tuple3 { - public static Tuple3$long$String$char GOLD = new Tuple3$long$String$char(); - private Tuple3$long$String$char(){} - public long _f0; - public String _f1; - public char _f2; - Tuple3$long$String$char(long f0, String f1, char f2) { - _f0=f0; _f1=f1; _f2=f2; - } - public Int64 f0() { return Int64.make(_f0); } - public org.xvm.xec.ecstasy.text.String f1() { return org.xvm.xec.ecstasy.text.String.make(_f1); } - public Char f2() { return Char.make(_f2); } - public void f0(XTC e) { _f0= ((Int64)e)._x; } - public void f1(XTC e) { _f1= ((org.xvm.xec.ecstasy.text.String)e)._x; } - public void f2(XTC e) { _f2= ((Char)e)._x; } - public long at80() { return _f0; } - public String at81() { return _f1; } - public char at82() { return _f2; } - } - */ - // Tuple N class - SB sb = new SB(); - sb.p("// ---------------------------------------------------------------").nl(); - sb.p("// Auto Generated by Tuple from ").p(tclz).nl().nl(); - sb.fmt("package %0;\n\n",pack); - sb.fmt("import %0.Tuple%1;\n",pack,N); - sb.p ("import org.xvm.xec.XTC;\n"); - xtt.makeImports(sb); - - sb.fmt("public class %0 extends Tuple%1 {\n",tclz,N).ii(); - sb.ifmt("public static %0 GOLD = new %0();",tclz).nl(); - sb.ifmt("private %0(){}",tclz).nl(); - // N field declares - for( int i=0; i toBitArray(Array.Mutability mut) { throw XEC.TODO(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Dec64.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Dec64.java deleted file mode 100644 index cf261ed60b..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Dec64.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Const; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.collections.Array; -import org.xvm.xec.ecstasy.collections.AryUInt8; -import org.xvm.xec.ecstasy.collections.AryXTC; -import org.xvm.xec.ecstasy.numbers.Bit; -import org.xvm.xrun.Never; -import org.xvm.xtc.cons.Dec64Con; - -import java.math.BigDecimal; -import java.math.MathContext; -import java.math.RoundingMode; - -/** - Support XTC Number -*/ -public class Dec64 extends DecimalFPNumber { - public static final Dec64 GOLD = new Dec64((Never)null); - - static final MathContext[] MATHCONTEXTS = new MathContext[]{ - new MathContext(64,RoundingMode.HALF_EVEN), - new MathContext(64,RoundingMode.UP ), - new MathContext(64,RoundingMode.CEILING ), - new MathContext(64,RoundingMode.DOWN ), - new MathContext(64,RoundingMode.FLOOR ), - }; - - private final long _dec64; - private final BigDecimal _bd; - - public Dec64(Never n ) { _bd=null; _dec64=0; } - public Dec64(BigDecimal bd) { - _bd = bd; - _dec64 = Dec64Con.toLongBits(_bd); - } - public Dec64(String s) { this(new BigDecimal(s,MathContext.DECIMAL64)); } - public Dec64(double d) { this(new BigDecimal(d)); } - public static Dec64 construct( AryXTC bits ) { return new Dec64(bits); } - public Dec64(AryXTC bits) { - long dec = 0; - for( int i=0; i<64; i++ ) - dec = dec | ((bits.at8(i)._b ? 1L : 0L) << i); - _dec64 = dec; - _bd = Dec64Con.toBigDecimal64(dec); - } - public static Dec64 construct( AryUInt8 ary ) { return new Dec64(ary); } - public Dec64(AryUInt8 ary) { - long dec = 0; - for( int i=0; i<8; i++ ) - dec = dec | ((long)ary.at8(i)<<(i*8)); - _dec64 = dec; - _bd = Dec64Con.toBigDecimal64(dec); - } - - public static Dec64 construct( long d ) { return new Dec64((double)d); } - - public Dec64 ceil() { return new Dec64(_bd.setScale(0,RoundingMode.CEILING)); } - public Dec64 floor() { return new Dec64(_bd.setScale(0,RoundingMode.FLOOR )); } - public Dec64 round(DecimalFPNumber.Rounding rnd) { - return new Dec64(_bd.setScale(0,DecimalFPNumber.ROUNDINGMODE[rnd.ordinal()])); - } - - public Dec64 mul( Dec64 dec ) { return new Dec64(_bd.multiply(dec._bd)); } - public Dec64 div( Dec64 dec ) { return new Dec64(_bd.divide (dec._bd)); } - - public Dec128 toDec128() { throw XEC.TODO(); } - public AryXTC toBitArray(Array.Mutability mut) { - Bit[] bits = new Bit[64]; - for( int i=0; i<64; i++ ) - bits[i] = new Bit((_dec64>>i)&1); - return new AryXTC<>(Bit.GOLD,bits); - } - public AryUInt8 toByteArray(Array.Mutability mut) { - byte[] bs = new byte[8]; - for( int i=0; i<8; i++ ) - bs[i] = (byte)(_dec64>>(i*8)); - return new AryUInt8(mut,bs); - } - - // --- Stringable - @Override public String toString() { return _bd.toString(); } - // --- Comparable - @Override public boolean equals( XTC x0, XTC x1 ) { - return ((Dec64)x0)._dec64==(((Dec64)x1)._dec64); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/DecimalFPNumber.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/DecimalFPNumber.java deleted file mode 100644 index abe54a832b..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/DecimalFPNumber.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.xec.ecstasy.Const; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xrun.Never; - -import java.math.RoundingMode; - -/** - Support XTC Number -*/ -public abstract class DecimalFPNumber extends FPNumber { - public DecimalFPNumber(Never n ) {} - public DecimalFPNumber() {} - public static RoundingMode[] ROUNDINGMODE = new RoundingMode[]{ - RoundingMode.HALF_EVEN, // TiesToEven - RoundingMode.HALF_EVEN, // TiesToAway - RoundingMode.CEILING, // TowardPositive - RoundingMode.DOWN, // TowardZero - RoundingMode.FLOOR // TowardNegative - }; -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/FPLiteral.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/FPLiteral.java deleted file mode 100644 index 51fd3093f6..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/FPLiteral.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.Const; - -/** - Support XTC FPLiteral -*/ -public class FPLiteral extends Const { - public static final FPLiteral GOLD = new FPLiteral((Never)null); - public FPLiteral(Never n ) {_s=null;} - - public final String _s; - - public FPLiteral(String s) { _s=s; } - public FPLiteral(org.xvm.xec.ecstasy.text.String s) { this(s._i); } - public FPLiteral(double x) { _s=Double.toString(x); } - - public Dec64 toDec64() { return new Dec64(_s); } - - @Override public String toString() { return _s; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/FPNumber.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/FPNumber.java deleted file mode 100644 index 7c1b6e21c5..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/FPNumber.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.xec.ecstasy.Const; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xrun.Never; - -/** - Support XTC Number -*/ -public abstract class FPNumber extends Number { - public FPNumber(Never n ) {} - public FPNumber() {} - public static final FPLiteral PI = new FPLiteral("3.141592653589793238462643383279502884197169399375105820974944592307816406286"); - public static final FPLiteral PI$get() { return PI; } - - /** - * Options for rounding. - * - * These are the rounding directions defined by the IEEE 754 standard. - */ - public enum Rounding {TiesToEven, TiesToAway, TowardPositive, TowardZero, TowardNegative} -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float128.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float128.java deleted file mode 100644 index 705780b704..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float128.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.collections.Array; - -public class Float128 extends BinaryFPNumber { - public Float128(Never n ) {} - public Float128() {} - Array toBitArray(Array.Mutability mut) { throw XEC.TODO(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float32.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float32.java deleted file mode 100644 index bfe272cea5..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float32.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.collections.Array; - -public class Float32 extends BinaryFPNumber { - public static final Float32 GOLD = new Float32((Never)null); - public Float32(Never n ) {this(0);} - public Float32(float f) { _i = f; } - public final float _i; - Array toBitArray(Array.Mutability mut) { throw XEC.TODO(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float64.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float64.java deleted file mode 100644 index 7c15b7ece9..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Float64.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.collections.Array; - -public class Float64 extends BinaryFPNumber { - public static final Float64 GOLD = new Float64((Never)null); - public Float64(Never n ) {this(0);} - public Float64(double d) { _i = d; } - public final double _i; - public static Float64 construct( double d ) { return new Float64(d); } - public static Float64 make ( double d ) { return new Float64(d); } - Array toBitArray(Array.Mutability mut) { throw XEC.TODO(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Int128.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Int128.java deleted file mode 100644 index 709ec7b6d0..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Int128.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Appenderchar; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.collections.Array; -import org.xvm.xec.ecstasy.numbers.Dec128; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xrun.Never; -import static org.xvm.xec.ecstasy.Ordered.*; - -/** - Support XTC Int128 -*/ -public class Int128 extends IntNumber { - public static final Int128 GOLD = new Int128(null); - public Int128(Never n ) { this(0,0); } // No-arg constructor - - static final Int128 ZERO = new Int128(0,0); - public final long _lo, _hi; // low, high - - public Int128(long lo, long hi) { _lo=lo; _hi=hi; } - public Int128(long lo) { _lo=lo; _hi=0; } - - public static Int128 construct(long lo) { return lo==0 ? ZERO : new Int128(lo); } - public static Int128 construct(long lo, long hi) { return new Int128(lo,hi); } - - public Int128 add( long x ) { throw XEC.TODO(); } - public Int128 sub( long x ) { throw XEC.TODO(); } - public Int128 mul( long x ) { throw XEC.TODO(); } - public Int128 div( long x ) { throw XEC.TODO(); } - public Int128 add( Int128 x ) { - long lo = _lo+x._lo; - long hi = _hi+x._hi; - if( (~(_lo | x._lo)) < 0 && lo < 0 ) { - throw XEC.TODO(); // Overflow - } - return construct(lo,hi); - } - public Int128 sub( Int128 x ) { - long lo = _lo-x._lo; - long hi = _hi-x._hi; - if( (~(_lo | x._lo)) < 0 && lo < 0 ) { - throw XEC.TODO(); // Overflow - } - return construct(lo,hi); - } - public Int128 mul( Int128 x ) { - long lo = _lo*x._lo; - long hi = _hi*x._hi + Math.multiplyHigh(_lo,x._lo) + _lo*x._hi + _hi*x._lo; - return new Int128(lo,hi); - } - public Int128 div( Int128 x ) { throw XEC.TODO(); } - public Int128 mod( Int128 x ) { throw XEC.TODO(); } - public Int128 abs() { throw XEC.TODO(); } - public Int128 neg() { throw XEC.TODO(); } - @Override public Signum sign$get() { throw XEC.TODO(); } - public boolean eq( Int128 x ) { throw XEC.TODO(); } - public boolean gt( Int128 x ) { return _hi != x._hi ? (_hi > x._hi) : (_lo > x._lo); } - public boolean ge( Int128 x ) { return _hi != x._hi ? (_hi >= x._hi) : (_lo >= x._lo); } - - Array toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - public Dec128 toDec128() { throw XEC.TODO(); } - public int toInt32(boolean check) { - if( check ) throw XEC.TODO(); - return (int)_lo; - } - public long toInt64(boolean check) { - if( check ) throw XEC.TODO(); - return _lo; - } - public long toInt(boolean check) { - if( check ) throw XEC.TODO(); - return _lo; - } - public long toUInt32(boolean check) { - if( check ) throw XEC.TODO(); - return _lo; - } - public Int128 toInt128(boolean check) { - if( check ) throw XEC.TODO(); - return this; - } - - @Override public long hashCode( XTC x ) { throw XEC.TODO(); } - @Override public boolean equals ( XTC x0, XTC x1 ) { throw XEC.TODO(); } - @Override public Ordered compare( XTC x0, XTC x1 ) { return ((Int128)x0).compare( (Int128)x1 ); } - public Ordered compare( Int128 x ) { - if( _hi < x._hi ) return Lesser; - if( _hi > x._hi ) return Greater; - if( _lo < x._lo ) return Lesser; - if( _lo > x._lo ) return Greater; - return Equal; - } - - @Override public final String toString() { - if( _hi != (_lo>>63) ) - throw XEC.TODO(); - return Long.toString(_lo); - } - @Override public long estimateStringLength() { return 128; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Int32.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Int32.java deleted file mode 100644 index f599ef1bcb..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Int32.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.Appenderchar; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xec.ecstasy.collections.Array; - -/** - Support XTC Int32 -*/ -public class Int32 extends IntNumber { - public static final Int32 GOLD = new Int32((Never)null); - private static Int32[] CACHE = new Int32[128]; - static { - for( int i=0; i>1)); - } - public static Int32 make(long x) { - long y = x + (CACHE.length>>1); - if( 0 <= y && y < CACHE.length ) return CACHE[(int)y]; - return new Int32(x); - } - public Int32(Never n ) { this(0); } // No-arg constructor - - public final int _i; - - public Int32(String s) { this(Integer.valueOf(s)); } - public Int32(org.xvm.xec.ecstasy.text.String s) { this(s._i); } - public Int32( long i ) { _i = (int)i; if( _i != i ) throw XEC.TODO(); } - - Array toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - - - // All the XTC types here are guaranteed to be Int32 - @Override public long hashCode(XTC x) { return ((Int32)x)._i; } - @Override public boolean equals ( XTC x0, XTC x1 ) { return ((Int32)x0)._i == ((Int32)x1)._i; } - @Override public Ordered compare( XTC x0, XTC x1 ) { - int i0 = ((Int32)x0)._i; - int i1 = ((Int32)x1)._i; - if( i0==i1 ) return Ordered.Equal; - return i0>1)); - } - public static Int64 make(long x) { - long y = x + (CACHE.length>>1); - if( 0 <= y && y < CACHE.length ) return CACHE[(int)y]; - return new Int64(x); - } - public Int64(Never n ) { this(0); } // No-arg constructor - - public final long _i; - - public Int64(String s) { this(Long.valueOf(s)); } - public Int64(org.xvm.xec.ecstasy.text.String s) { this(s._i); } - public Int64( long i ) { _i = i; } - - public static Int64 construct( String s ) { return new Int64(s); } - public static Int64 construct( long i ) { return new Int64(i); } - - public boolean eq( long x ) { return _i==x; } - public Int64 div( long i ) { return make(_i/i); } - - Array toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - - // All the XTC types here are guaranteed to be Int64 - @Override public boolean equals ( XTC x0, XTC x1 ) { return ((Int64)x0)._i == ((Int64)x1)._i; } - public static boolean equals$Int64(XTC gold, E i0, long i1 ) { return i0._i==i1; } - public static boolean equals$Int64(XTC gold, E i0, E i1 ) { return i0._i==i1._i; } - @Override public long hashCode(XTC x) { return ((Int64)x)._i; } - @Override public Ordered compare( XTC x0, XTC x1 ) { - long i0 = ((Int64)x0)._i; - long i1 = ((Int64)x1)._i; - if( i0==i1 ) return Ordered.Equal; - return i0 toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - - @Override public long hashCode( XTC x ) { throw XEC.TODO(); } - @Override public boolean equals ( XTC x0, XTC x1 ) { throw XEC.TODO(); } - @Override public Ordered compare( XTC x0, XTC x1 ) { throw XEC.TODO(); } - - @Override public final String toString() { throw XEC.TODO(); } - @Override public long estimateStringLength() { return 128; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/IntNumber.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/IntNumber.java deleted file mode 100644 index 1a898724df..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/IntNumber.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xrun.Never; - -import java.lang.Math; - -/** - Support XTC IntNumber -*/ -public abstract class IntNumber extends Number { - public IntNumber(Never n ) {} - public IntNumber() {} - - public static Int128 toInt128(long x) { return new Int128(x); } - public static long estimateStringLength(long x) { throw XEC.TODO(); } - public static long abs(long i) { return Math.abs(i); } - - public static boolean equals$IntNumber(IntNumber gold, IntNumber x, IntNumber y) { return gold.equals (x,y); } - public static Ordered compare$IntNumber(IntNumber gold, IntNumber x, IntNumber y) { return gold.compare(x,y); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Number.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Number.java deleted file mode 100644 index 0705248870..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/Number.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Const; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.collections.Array; -import org.xvm.xrun.Never; - -/** - Support XTC Number -*/ -public abstract class Number extends Const implements Orderable { - public Number(Never n ) {} - public Number() {} - - public static boolean equals$Number( XTC gold, Number n0, Number n1 ) { - if( n0.getClass()==n1.getClass() ) - return n0.equals(n1); // Same class, normal dispatch is ok - // Widening rules for Number equality - throw XEC.TODO(); - } - public static boolean equals$Number( XTC gold, double n0, double n1 ) { return n0==n1; } - - abstract Array toBitArray(Array.Mutability mut); - - public Signum sign$get() { throw XEC.TODO(); } - - public enum Signum { - Negative("-", -1, Ordered.Lesser ), - Zero ("" , 0, Ordered.Equal ), - Positive("+", +1, Ordered.Greater); - public final String prefix; - public final int factor; - public final Ordered ordered; - private Signum( String pre, int fact, Ordered ord) { - prefix = pre; - factor = fact; - ordered= ord; - } - } - - -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt128.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt128.java deleted file mode 100644 index 87b511324f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt128.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.Appenderchar; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xec.ecstasy.collections.Array; - -/** - Support XTC UInt128 -*/ -public class UInt128 extends UIntNumber { - public static final UInt128 GOLD = new UInt128(null); - public UInt128(Never n ) { } // No-arg constructor - - Array toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - - @Override public long hashCode( XTC x ) { throw XEC.TODO(); } - @Override public boolean equals ( XTC x0, XTC x1 ) { throw XEC.TODO(); } - @Override public Ordered compare( XTC x0, XTC x1 ) { throw XEC.TODO(); } - - @Override public final String toString() { throw XEC.TODO(); } - @Override public long estimateStringLength() { return 128; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt16.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt16.java deleted file mode 100644 index 7666d7c395..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt16.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.Appenderchar; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xec.ecstasy.collections.Array; - -/** - Support XTC UInt16 -*/ -public class UInt16 extends UIntNumber { - public static final UInt16 GOLD = new UInt16(null); - public UInt16(Never n ) { this(0); } // No-arg constructor - - private static UInt16[] CACHE = new UInt16[256]; - static { - for( int i=0; i toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - - - @Override public long hashCode( XTC x ) { throw XEC.TODO(); } - @Override public boolean equals ( XTC x0, XTC x1 ) { throw XEC.TODO(); } - @Override public Ordered compare( XTC x0, XTC x1 ) { throw XEC.TODO(); } - - @Override public final String toString() { return ""+_i; } - @Override public long estimateStringLength() { return (64 - Long.numberOfLeadingZeros(_i)); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt32.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt32.java deleted file mode 100644 index 72bee60c05..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt32.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.Appenderchar; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xec.ecstasy.collections.Array; - -/** - Support XTC UInt32 -*/ -public class UInt32 extends UIntNumber { - public static final UInt32 GOLD = new UInt32(null); - public UInt32(Never n ) { this(0); } // No-arg constructor - - private static UInt32[] CACHE = new UInt32[256]; - static { - for( int i=0; i toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - - - @Override public long hashCode( XTC x ) { throw XEC.TODO(); } - @Override public boolean equals ( XTC x0, XTC x1 ) { throw XEC.TODO(); } - @Override public Ordered compare( XTC x0, XTC x1 ) { throw XEC.TODO(); } - - @Override public final String toString() { return ""+_i; } - @Override public long estimateStringLength() { return (32 - Long.numberOfLeadingZeros(_i)); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt64.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt64.java deleted file mode 100644 index 9abe20c2ac..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt64.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.Appenderchar; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xec.ecstasy.collections.Array; - -/** - Support XTC UInt64 -*/ -public class UInt64 extends UIntNumber { - public static final UInt64 GOLD = new UInt64(null); - public UInt64(Never n ) { this(0); } // No-arg constructor - - private static UInt64[] CACHE = new UInt64[256]; - static { - for( int i=0; i toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - - - @Override public long hashCode( XTC x ) { throw XEC.TODO(); } - @Override public boolean equals ( XTC x0, XTC x1 ) { throw XEC.TODO(); } - @Override public Ordered compare( XTC x0, XTC x1 ) { throw XEC.TODO(); } - - @Override public final String toString() { return ""+_i; } - @Override public long estimateStringLength() { return (64 - Long.numberOfLeadingZeros(_i)); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt8.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt8.java deleted file mode 100644 index 1242227d40..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UInt8.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.Appenderchar; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xec.ecstasy.collections.Array; - -/** - Support XTC UInt8 -*/ -public class UInt8 extends UIntNumber { - public static final UInt8 GOLD = new UInt8(null); - public UInt8(Never n ) { this(0); } // No-arg constructor - - private static UInt8[] CACHE = new UInt8[256]; - static { - for( int i=0; i>1)); - } - public static UInt8 make(byte x) { - return CACHE[x&0xFF]; - } - public final byte _i; - - private UInt8( int i ) { _i = (byte)i; } - - Array toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - - - @Override public long hashCode( XTC x ) { throw XEC.TODO(); } - @Override public boolean equals ( XTC x0, XTC x1 ) { throw XEC.TODO(); } - @Override public Ordered compare( XTC x0, XTC x1 ) { throw XEC.TODO(); } - - @Override public final String toString() { return ""+_i; } - @Override public long estimateStringLength() { return (64 - Long.numberOfLeadingZeros(_i)); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UIntN.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UIntN.java deleted file mode 100644 index 4fced06911..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UIntN.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.Appenderchar; -import org.xvm.xec.ecstasy.Orderable; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.text.Stringable; -import org.xvm.xec.ecstasy.collections.Array; - -/** - Support XTC UIntN -*/ -public class UIntN extends UIntNumber { - public static final UIntN GOLD = new UIntN(null); - public UIntN(Never n ) { } // No-arg constructor - - Array toBitArray(Array.Mutability mut) { throw XEC.TODO(); } - - @Override public long hashCode( XTC x ) { throw XEC.TODO(); } - @Override public boolean equals ( XTC x0, XTC x1 ) { throw XEC.TODO(); } - @Override public Ordered compare( XTC x0, XTC x1 ) { throw XEC.TODO(); } - - @Override public final String toString() { throw XEC.TODO(); } - @Override public long estimateStringLength() { return 128; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UIntNumber.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UIntNumber.java deleted file mode 100644 index 65b7a8a509..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/numbers/UIntNumber.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xec.ecstasy.numbers; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Const; -import org.xvm.xrun.Never; -import org.xvm.xec.ecstasy.Ordered; - -/** - Support XTC UIntNumber -*/ -public abstract class UIntNumber extends IntNumber { - public UIntNumber(Never n ) {} - public UIntNumber() {} - - public static Ordered compare$UIntNumber( XTC gold_type, byte x0, byte x1 ) { - throw XEC.TODO(); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Argument.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Argument.java deleted file mode 100644 index 6091c7dcc7..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Argument.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.xvm.xec.ecstasy.reflect; - -import org.xvm.xec.ecstasy.Const; -import org.xvm.xrun.Never; -import org.xvm.xec.XTC; - -public class Argument extends Const { - public static final Argument GOLD = new Argument(); - public Argument(Never n) {} - public Argument() {} - // --- Comparable - @Override public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Ref.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Ref.java deleted file mode 100644 index 9c29e33f70..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Ref.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.xvm.xec.ecstasy.reflect; - -public interface Ref { -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Type.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Type.java deleted file mode 100644 index 29d2d023dc..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/reflect/Type.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.xvm.xec.ecstasy.reflect; - -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Const; -import org.xvm.xrun.Never; - -public class Type extends Const { - public static final Type GOLD = new Type(); - public Type(Never n) {} - public Type() {} - - // --- Comparable - public static boolean equals$Type( XTC gold, XTC gold0, XTC gold1 ) { return gold0==gold1; } - @Override public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/Char.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/Char.java deleted file mode 100644 index da2fe70740..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/Char.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.xvm.xec.ecstasy.text; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Const; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xrun.Never; -import org.xvm.xrun.XRuntime; - -public class Char extends Const { - public static final Char GOLD = new Char(null); - public Char(Never n) {_i=(char)0;} - public Char(char c) {_i=c;} - public static Char make(char c) { return new Char(c); } - public final char _i; - public static Char construct(char c) { return new Char(c); } - - public static boolean equals$Char( XTC gold, E ord0, E ord1 ) { return ord0==ord1; } - @Override public boolean equals ( XTC x0, XTC x1 ) { return ((Char)x0)._i == ((Char)x1)._i; } - @Override public boolean equals( Object o ) { - if( this==o ) return true; - return o instanceof Char c && _i==c._i; - } - - - @Override public Ordered compare(XTC c0, XTC c1 ) { return compare$Char(GOLD,(Char)c0,(Char)c1); } - public static Ordered compare$Char(Char gold, Char c0, Char c1 ) { - if( c0._i==c1._i ) return Ordered.Equal; - return c0._i < c1._i ? Ordered.Lesser : Ordered.Greater; - } - public static Ordered compare$Char(Char gold, char c0, char c1 ) { - if( c0==c1 ) return Ordered.Equal; - return c0 < c1 ? Ordered.Lesser : Ordered.Greater; - } - - - // ASCII digit check - public long asciiDigit() { - long x = _i-'0'; - XRuntime.$COND = 0 <= x && x <= 9; - return x; - } - // ASCII digit check - public static long asciiDigit(char c) { - long x = c-'0'; - XRuntime.$COND = 0 <= x && x <= 9; - return x; - } - // Unicode version of ASCII digit check - public long decimalValue() { - return asciiDigit(); - } - - public static String quoted(char c) { - throw XEC.TODO(); - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/String.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/String.java deleted file mode 100644 index 584a7cac2f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/String.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.xvm.xec.ecstasy.text; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.xec.ecstasy.Const; -import org.xvm.xec.ecstasy.Iterable; -import org.xvm.xec.ecstasy.Iterator; -import org.xvm.xec.ecstasy.Ordered; -import org.xvm.xec.ecstasy.collections.AryString; -import org.xvm.xrun.Never; -import org.xvm.xrun.XRuntime; - -public class String extends Const implements Iterable { - public static final String GOLD = new String((Never)null); - public String(Never n) { _i=null; } - public final java.lang.String _i; - public String(java.lang.String s) { _i = s; } - - public static String make(java.lang.String s) { return new String(s); } - public static String construct(java.lang.String s) { return new String(s); } // TODO: Intern - - public int length() { return _i.length(); } - @Override public int size$get() { return length(); } - public char charAt(int x) { return _i.charAt(x); } - @Override public java.lang.String toString() { return _i; } - - public static java.lang.String quoted( java.lang.String s ) { - return '"'+s+'"'; - } - // Conditional return - public static long indexOf( java.lang.String src, java.lang.String find, long start ) { - int idx = src.indexOf(find); - XRuntime.$COND = idx != -1; - return idx; - } - public static long indexOf( java.lang.String src, char find, long start ) { - int idx = src.indexOf(find); - XRuntime.$COND = idx != -1; - return idx; - } - public static AryString split( java.lang.String src, char find, boolean omitEmpty, boolean trim ) { - if( omitEmpty ) throw XEC.TODO(); - if( trim ) throw XEC.TODO(); - int idx = src.indexOf(find); - if( idx == -1 ) return AryString.EMPTY; - throw XEC.TODO(); - } - - public static boolean equals$String( XTC gold, E ord0, E ord1 ) { return ord0._i.equals(ord1._i); } - public static boolean equals$String( XTC gold, E ord0, java.lang.String s1 ) { return ord0._i.equals(s1); } - public static boolean equals$String( XTC gold, java.lang.String s0, java.lang.String s1 ) { return s0.equals(s1); } - public static boolean equals$String( XTC gold, XTC c0, XTC c1 ) { return equals$String(gold,(String)c0,(String)c1); } - - @Override public boolean equals( XTC s0, XTC s1 ) { - return equals(((String)s0)._i,((String)s1)._i); - } - - @Override public Ordered compare( XTC s0, XTC s1 ) { - return compare(((String)s0)._i,((String)s1)._i); - } - - public Ordered compare( java.lang.String s0, java.lang.String s1 ) { - int sig = s0.compareTo(s1); - if( sig==0 ) return Ordered.Equal; - return sig<0 ? Ordered.Lesser : Ordered.Greater; - } - - public boolean equals( java.lang.String s0, java.lang.String s1 ) { return s0.equals(s1); } - @Override public boolean equals( Object o ) { - if( this==o ) return true; - return o instanceof String s && _i.equals(s._i); - } - - public long hashCode( java.lang.String s0 ) { return s0.hashCode(); } - @Override public long hashCode( XTC s0 ) { return hashCode(((String)s0)._i); } - public static long hashCode$String( XTC gold, java.lang.String s0 ) { return s0.hashCode(); } - - @Override public Iterator iterator() { return new IterStr(_i); } - static public Iterator iterator(java.lang.String s0) { return new IterStr(s0); } - private static class IterStr extends Iterator { - final java.lang.String _s; - int _i; - IterStr(java.lang.String s) { _s = s; } - @Override public Char next() { throw XEC.TODO(); } - @Override public boolean hasNext() { return _i < _s.length(); } - @Override public char next2() { - boolean has = XRuntime.$COND = _i < _s.length(); - return has ? _s.charAt(_i++) : (char)0; - } - @Override public long next8() { throw XEC.TODO(); } - @Override public java.lang.String nextStr() { throw XEC.TODO(); } - } - - - // --- Freezable - @Override public String freeze(boolean inPlace) { return this; } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/StringBuffer.java b/javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/StringBuffer.java deleted file mode 100644 index f0a67677af..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xec/ecstasy/text/StringBuffer.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.xvm.xec.ecstasy.text; - -import org.xvm.XEC; -import org.xvm.xec.ecstasy.Appenderchar; -import org.xvm.xec.ecstasy.collections.Arychar; - -import static org.xvm.xec.ecstasy.collections.Array.Mutability.*; - -public class StringBuffer extends Arychar - implements Appenderchar, Stringable -{ - - public StringBuffer( ) {} - public StringBuffer(long estSize ) { super(Mutable,0, new char[(int)estSize]); } - - public static StringBuffer construct(long estSize) { return new StringBuffer(estSize); } - public static StringBuffer construct() { return new StringBuffer(8); } - - public StringBuffer add(char v) { - return (StringBuffer)super.add(v); - } - - @Override public StringBuffer appendTo( org.xvm.xec.ecstasy.text.String s) { - for( int i=0; i con = JavaC.XFM.klass(_mod).getConstructor(); - jobj = con.newInstance(); - } catch( NoSuchMethodException nsme ) { - throw XEC.TODO(); // No top-level run method? - } catch( Exception ie ) { - throw XEC.TODO(); - } - - // Find method in the java module class. - if( !xrun.equals("run") ) throw XEC.TODO(); - XRunClz runner = (XRunClz)jobj; - // Invoke the method with args, in another thread. - if( args==null ) runner.run(); - else runner.run(new AryString(1.,args)); - // Return a Joinable on the running thread. - return null; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xrun/MainContainer.java b/javatools_backend/src/main/java/org/xvm/xrun/MainContainer.java deleted file mode 100644 index f7259e5b04..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xrun/MainContainer.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.xvm.xrun; - -import org.xvm.xtc.ModPart; - -// The initial container -public class MainContainer extends Container { - public MainContainer( Container par, ModPart mod ) { - super(par,mod); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xrun/NativeConsole.java b/javatools_backend/src/main/java/org/xvm/xrun/NativeConsole.java deleted file mode 100644 index cd8f0d5569..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xrun/NativeConsole.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.xvm.xrun; - -import org.xvm.xec.ecstasy.io.Console; - -public class NativeConsole implements Console { -} diff --git a/javatools_backend/src/main/java/org/xvm/xrun/NativeContainer.java b/javatools_backend/src/main/java/org/xvm/xrun/NativeContainer.java deleted file mode 100644 index d41afab291..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xrun/NativeContainer.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.xvm.xrun; - -import org.xvm.XEC; - -public class NativeContainer extends Container { - - final NativeConsole _console; - - public NativeContainer() { - super(null,null); - _console = new NativeConsole(); - } - - @Override public NativeConsole console() { return _console; } - @Override public NativeTimer timer () { return new NativeTimer(); } - - // Initialize default things into the container? - void init() { - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xrun/NativeTimer.java b/javatools_backend/src/main/java/org/xvm/xrun/NativeTimer.java deleted file mode 100644 index 7994692c64..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xrun/NativeTimer.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.xvm.xrun; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xec.Fun; -import org.xvm.xtc.ClzBldSet; -import org.xvm.xtc.ClzBuilder; -import org.xvm.xtc.XClz; - -import java.util.Timer; -import java.util.TimerTask; - -/** - Java native implementation of the XTC Timer class -*/ -public class NativeTimer { - // Time is in 128bit picoseconds - public Fun schedule( long lo, long hi, Fun alarm, boolean keepAlive ) { - if( keepAlive ) throw XEC.TODO(); - // shift lo/hi by 1e9 as binary, then correct with double. - long T = 1L<<30; - long loHalf = lo + (T>>1); // Round up pico to milli - long kmsec = (hi<<(64-30))|(loHalf>>>30); - double dmsec = ((double)kmsec)*((double)T)/1e9; - long msec = (long)dmsec; - // debugging check - long delta = msec - System.currentTimeMillis(); - - // Make a timer object; it will self-cancel after running this one task - Timer timer = new Timer(); - var task = new TimerTask() { - final Timer _timer = timer; - public void run() { - alarm.call(); - _timer.cancel(); - } - }; - timer.schedule(task, msec); - - return alarm; - } - - public static String make_timer(XClz xtimer) { - ClzBuilder.add_import(xtimer); - String qual = (XEC.XCLZ+"."+"NativeTimer").intern(); - String nnn = "new "+qual+"()"; - ClzBuilder.add_import(qual); - if( ClzBldSet.find(qual) ) - return nnn; - - SB sb = new SB(); - sb.p("// ---------------------------------------------------------------").nl(); - sb.p("// Auto Generated by XRunClz from "); - xtimer.clz(sb).nl().nl(); - sb.p("package ").p(XEC.XCLZ).p(";").nl().nl(); - sb.fmt("import %0;\n",xtimer.qualified_name()); - sb.fmt("import %0.ecstasy.temporal.Duration;\n",XEC.XCLZ); - sb.fmt("import %0.ecstasy.numbers.Int128;\n",XEC.XCLZ); - sb.fmt("import %0.Fun;\n",XEC.XCLZ); - sb.fmt("import %0.XEC;\n",XEC.ROOT); - sb.nl(); - sb.p("public class NativeTimer implements Timer {\n").ii(); - - sb.ifmt("private final %0.xrun.NativeTimer _timer;",XEC.ROOT).nl(); - sb.ip("public NativeTimer() { _timer = XEC.CONTAINER.get().timer(); }").nl(); - sb.ip("public Duration elapsed$get() { throw XEC.TODO(); }").nl(); - sb.ip("public void elapsed$set( Duration p ) { throw XEC.TODO(); }").nl(); - sb.ip("public void stop( ) { throw XEC.TODO(); }").nl(); - sb.ip("public Fun schedule( Duration delay, Fun alarm ) { \n").ii(); - sb.ip( "Int128 pico = delay.picoseconds$get();\n"); - sb.ip( "return _timer.schedule(pico._lo,pico._hi,alarm,false);\n").di(); - sb.ip("}").nl(); - sb.ip("public void start( ) { throw XEC.TODO(); }").nl(); - sb.ip("public void reset( ) { throw XEC.TODO(); }").nl(); - sb.ip("public Duration resolution$get() { throw XEC.TODO(); }").nl(); - sb.ip("public void resolution$set( Duration p ) { throw XEC.TODO(); }").nl(); - - // Class end - sb.di().ip("}").nl(); - sb.p("// ---------------------------------------------------------------").nl(); - ClzBldSet.add(qual,sb.toString()); - return nnn; - } - - public static String make_clock(XClz xclock) { - ClzBuilder.add_import(xclock); - String qual = (XEC.XCLZ+"."+"NativeClock").intern(); - String nnn = "new "+qual+"()"; - ClzBuilder.add_import(qual); - if( ClzBldSet.find(qual) ) - return nnn; - - SB sb = new SB(); - sb.p("// ---------------------------------------------------------------").nl(); - sb.p("// Auto Generated by XRunClz from "); - xclock.clz(sb).nl().nl(); - sb.p("package ").p(XEC.XCLZ).p(";").nl().nl(); - sb.fmt("import %0;\n",xclock.qualified_name()); - sb.fmt("import %0.ecstasy.temporal.Duration;\n",XEC.XCLZ); - sb.fmt("import %0.ecstasy.numbers.Int128;\n",XEC.XCLZ); - sb.fmt("import %0.ecstasy.Boolean;\n",XEC.XCLZ); - sb.fmt("import %0.ecstasy.temporal.Time;\n",XEC.XCLZ); - sb.fmt("import %0.ecstasy.temporal.TimeZone;\n",XEC.XCLZ); - sb.fmt("import %0.Fun;\n",XEC.XCLZ); - sb.fmt("import %0.XEC;\n",XEC.ROOT); - sb.nl(); - sb.p("public class NativeClock implements Clock {\n").ii(); - - sb.ifmt("private final %0.xrun.NativeTimer _timer;",XEC.ROOT).nl(); - sb.ip("public NativeClock() { _timer = XEC.CONTAINER.get().timer(); }").nl(); - sb.ip("public Duration resolution$get() { throw XEC.TODO(); }").nl(); - sb.ip("public void resolution$set( Duration p ) { throw XEC.TODO(); }").nl(); - sb.ip("public boolean monotonic$get() { throw XEC.TODO(); }").nl(); - sb.ip("public void monotonic$set(boolean b) { throw XEC.TODO(); }").nl(); - - sb.ip("public Time now$get() {").nl().ii(); - sb.ip( "Int128 picos = new Int128(System.currentTimeMillis()).mul(new Int128(1000000000L));\n"); - sb.ip( "return Time.construct(picos,TimeZone.UTC$get());\n").di(); - sb.ip("}").nl(); - - sb.ip("public void now$set(Time t) { throw XEC.TODO(); }").nl(); - - sb.ip("public Fun schedule( Time time, Fun alarm, boolean keepAlive ) { \n").ii(); - sb.ip( "Int128 now = now$get().epochPicos$get();\n"); - sb.ip( "Int128 pico = time.epochPicos$get();\n"); - sb.ip( "Int128 delta = pico.sub(now);\n"); - sb.ip( "return _timer.schedule(delta._lo,delta._hi,alarm,keepAlive);\n").di(); - sb.ip("}").nl(); - - sb.ip("public Fun schedule( Time time, Fun alarm, Boolean keepAlive ) { throw XEC.TODO(); }").nl(); - sb.ip("public TimeZone timezone$get() { throw XEC.TODO(); }").nl(); - sb.ip("public void timezone$set(TimeZone t) { throw XEC.TODO(); }").nl(); - - // Class end - sb.di().ip("}").nl(); - sb.p("// ---------------------------------------------------------------").nl(); - ClzBldSet.add(qual,sb.toString()); - return nnn; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xrun/Never.java b/javatools_backend/src/main/java/org/xvm/xrun/Never.java deleted file mode 100644 index 7a627d3a79..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xrun/Never.java +++ /dev/null @@ -1,3 +0,0 @@ -package org.xvm.xrun; -// Sentinel class can never be made -public abstract class Never { } diff --git a/javatools_backend/src/main/java/org/xvm/xrun/XExpr.java b/javatools_backend/src/main/java/org/xvm/xrun/XExpr.java deleted file mode 100644 index 8329ef41cd..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xrun/XExpr.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.xvm.xrun; - -public interface XExpr { - default long get_long() { return 0; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xrun/XRuntime.java b/javatools_backend/src/main/java/org/xvm/xrun/XRuntime.java deleted file mode 100644 index cb64f80636..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xrun/XRuntime.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.xvm.xrun; - -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - - -/** - Support for thread pools, perhaps other system and runtime services. One - per JVM, per physical hardware. Shared amongst all Containers and services. -*/ -public abstract class XRuntime { - // The executor for XVM services. - public static final ThreadPoolExecutor _executorXVM; - - // The executor for XVM services. - public static final ThreadPoolExecutor _executorIO; - - static { - int parallelism = Integer.parseInt(System.getProperty("xvm.parallelism", "0")); - if (parallelism <= 0) - parallelism = java.lang.Runtime.getRuntime().availableProcessors(); - - ThreadGroup groupXVM = new ThreadGroup("XVM"); - ThreadFactory factoryXVM = r -> { - Thread thread = new Thread(groupXVM, r); - thread.setDaemon(true); - thread.setName("XvmWorker@" + thread.hashCode()); - return thread; - }; - - // TODO: replace with a fair scheduling based ExecutorService; and a concurrent blocking queue - _executorXVM = new ThreadPoolExecutor(parallelism, parallelism, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), factoryXVM); - - ThreadGroup groupIO = new ThreadGroup("IO"); - ThreadFactory factoryIO = r -> { - Thread thread = new Thread(groupIO, r); - thread.setDaemon(true); - thread.setName("IOWorker@" + thread.hashCode()); - return thread; - }; - - _executorIO = new ThreadPoolExecutor(parallelism, 1024, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), factoryIO); - } - - - /** Submit ServiceContext work for eventual processing by the runtime. - * @param task the task to process */ - static protected void submitService(Runnable task) { _executorXVM.submit(task); } - - /** Submit IO work for eventual processing by the runtime. - * @param task the task to process */ - protected static void submitIO(Runnable task) { _executorIO.submit(task); } - - public static void start() {} - - public static void shutdownXVM() { - _executorIO .shutdown(); - _executorXVM.shutdown(); - } - - // $t expression wrapper, to allow side effects in the arguments and still - // have a java expression - public static boolean $t(long x) { return true; } - public static boolean $t(Object x) { return true; } - - // XTC conditionals require a pair of a boolean and something else. Mostly - // conditionals appear to be temporary - passed from a function and - // immediately consumed. So I am implementing them as an unpacked pair. - // When returned from a function, the boolean part is stored here and - // unpacked by the caller immediately. - - // This code: - // condition Person callee() { return (true,person); } - // void caller() { - // if( person=callee() ) do stuff... - // } - // Becomes: - // Person callee() { return XRuntime.True(person); } - // void caller() { - // if( $t(person=callee()) & XRuntime.$COND ) do stuff... - // } - - public static boolean $COND; - public static X False(X o) { $COND=false; return o; } - public static X True (X o) { $COND=true ; return o; } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/CPool.java b/javatools_backend/src/main/java/org/xvm/xtc/CPool.java deleted file mode 100644 index 82736725b0..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/CPool.java +++ /dev/null @@ -1,283 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xtc.cons.*; -import java.math.BigInteger; -import java.util.Arrays; - -/** - Exploring XEC Constant Pool - */ -public class CPool { - // Constants by index - private final Const[] _consts; - public final int _magic, _major, _minor; - - // Parser state - private final byte[] _buf; - private int x; - - // Parse a constant pool - CPool( byte[] buf ) { - _buf = buf; - _magic = i32(); - _major = i32(); - _minor = i32(); - int len = u31(); - _consts = new Const[len]; - } - // Parse a code buffer - public CPool( byte[] buf, Const[] consts ) { - _buf = buf; - _magic = _major = _minor = 0; - _consts = consts; - } - void parse( ) { - int len = _consts.length; - int[] offs = new int[len]; - - // Pass#1; load the constant pool from the stream; compute offsets and make empty objects - for( int i = 0; i < len; i++ ) { - Const.Format f = Const.Format.valueOf(u8()); - offs[i] = x; - _consts[i] = switch( f ) { - case AccessType -> new AccessTCon(this); - case AnnotatedType -> new AnnotTCon(this); - case Annotation -> new Annot(this); - case AnonymousClassType -> new AnonClzTCon(this); - case Any -> new MatchAnyCon(this,f); - case Array, Set, Tuple -> new AryCon(this,f); - case Bit, Int8, Nibble, UInt8 -> new ByteCon(this,f); - case BindTarget -> new MethodBindCon(this); - case Char -> new CharCon(this); - case Class -> new ClassCon(this); - case ConditionNamed-> new NamedCondCon(this,f); - case Date, Duration, FPLiteral, IntLiteral, Path, Time, TimeOfDay -> new LitCon(this,f); - case DecN, FloatN -> new FPNCon(this,f); - case Dec32 -> new Dec32Con(this); - case Dec64 -> new Dec64Con(this); - case Dec128 -> new Dec128Con(this); - case DecoratedClass -> new DecClzCon(this); - case DifferenceType -> new DiffTCon(this); - case DynamicFormal -> new DynFormalCon(this); - case EnumValueConst-> new EnumCon(this,f); - case FSDir, FSFile, FSLink -> new FSNodeCon(this,f); - case FileStore -> new FileStoreCon(this); - case Float32, Float16, BFloat16 -> new Flt32Con(this,f); - case Float64 -> new Flt64Con(this); - case Float128 -> new Flt128Con(this); - case Float8e4 -> new Flt8e4Con(this); - case Float8e5 -> new Flt8e5Con(this); - case FormalTypeChild -> new FormalTChildCon(this); - case ImmutableType -> new ImmutTCon(this); - case InnerChildType -> new InnerDepTCon(this); - case Int16, Int32, Int64, Int128, IntN, UInt16, UInt32, UInt64, UInt128, UIntN -> new IntCon(this,f); - case IntersectionType -> new InterTCon(this); - case IsConst, IsEnum, IsModule, IsPackage, IsClass -> new KeywordCon(f); - case Map, MapEntry -> new MapCon(this,f); - case Method -> new MethodCon(this); - case Module -> new ModCon(this); - case MultiMethod -> new MMethodCon(this); - case Package -> new PackageCon(this); - case ParameterizedType -> new ParamTCon(this); - case ParentClass -> new ParClzCon(this); - case Property -> new PropCon(this); - case PropertyClassType -> new PropClzCon(this); - case Range, RangeExclusive, RangeInclusive -> new RangeCon(this,f); - case RecursiveType -> new RecurTCon(this); - case Register -> new RegCon(this); - case ServiceType -> new ServiceTCon(this); - case Signature -> new SigCon(this); - case SingletonConst, SingletonService -> new SingleCon(this,f); - case String -> new StringCon(this); - case TerminalType -> new TermTCon(this); - case ThisClass -> new ThisClzCon(this); - case TurtleType -> new TSeqTCon(); - case Typedef -> new TDefCon(this); - case TypeParameter -> new TParmCon(this); - case UInt8Array -> new UInt8AryCon(this); - case UnionType -> new UnionTCon(this); - case Version -> new VerCon(this,f); - case VirtualChildType -> new VirtDepTCon(this); - default -> { - System.err.println("Format "+f); - throw XEC.TODO(); - } - }; - } - - // Pass#2. Convert indices into refs; fill in objects. - int oldx = x; - for( int i = 0; i < len; i++ ) { - x = offs[i]; // Reset parsing state - _consts[i].resolve(this); - } - x = oldx; - } - - // Get via index; -1 returns null - public Const get( int idx ) { return idx == -1 ? null : _consts[idx]; } - - // Get from a pre-resolved constant pool - public Const xget() { return get(u31()); } - - // ------------------------------------ - // File parser utilities - public boolean u1 () { return _buf[x++]!=0; } // boolean read - public int u8 () { return _buf[x++]&0xFF; } // Unsigned byte read as an int - public int i8 () { return _buf[x++]; } // Signed byte read as an int - public int u16() { return (u8()<<8) | u8(); } // Unsigned short read as an int - public int i32() { return (u8()<<24) | (u8()<<16) | (u8()<<8) | u8(); } // Signed 4-byte integer read - public long i64() { return (((long)i32())<<32) | ((long)(i32()) & 0xFFFFFFFFL); } - public void undo() { x--; } - static public boolean isDigit(char c) { return '0'<=c && c<='9'; } - - public long pack64() { - // See org.xvm.util.PackedInteger readLong - - // small format: 1 byte value -64..127 - // Check bit 6 for clear; bit 7 is used for the sign and can be set. - int b = i8(); // Signed byte read - if( (b&0xC0) != 0x80 ) - return b; - - // medium format: 13 bit int, combines 5 bits + next byte (and sign extend) - if( (b & 0x20) == 0 ) { - b = b << 27 >> 19 | u8(); - return b; - } - - - // large format: trail mode: next x+1 (2-32) bytes - int size = 1 + (b & 0x1F); - if( size == 1 ) { - // huge format: the actual byte length comes next in the stream - long nestedSize = pack64(); - if( nestedSize < 1 ) throw new IllegalArgumentException("huge integer length (" + nestedSize + " bytes) below minimum (1 bytes)"); - if( nestedSize > 8 ) throw new IllegalArgumentException("huge integer length (" + nestedSize + " bytes) exceeds maximum (8 bytes)"); - size = (int) nestedSize; - } - - long x = i8(); // First byte signed - for( int i=1; i 1) - return 1 + cb; // large format - - //// huge format - //long sizeAndValue = unpackInt(ab, of+1); // pack64? - //return 1 + (int) (sizeAndValue >>> 32) + (int) sizeAndValue; - throw XEC.TODO(); - } - - // Read a BigInteger - public BigInteger bigint(int c) { - assert c > 8; // Use the packed format for smaller stuff - if( c > 1024 ) throw new IllegalArgumentException("integer size of " + c + " bytes; maximum is 1024"); - return new BigInteger(_buf,(x+=c)-c,c); - } - - // Unsigned 31 bit, but might read from packed as larger. - public int u31() { - long n = pack64(); - // this is unsupported in Java; arrays are limited in size by their use - // of signed 32-bit magnitudes and indexes - if( n > Integer.MAX_VALUE ) throw new IllegalArgumentException("index (" + n + ") exceeds 32-bit maximum"); - if( n < -1 ) throw new IllegalArgumentException("negative index (" + n + ") is illegal"); - return (int) n; - } - - // Read a byte array - public byte[] bytes() { return bytes(u31()); } - public byte[] bytes(int len) { - return Arrays.copyOfRange(_buf,x,x+=len); - } - - // Skip an array of idxs - public int skipAry() { - int len = u31(); - for( int i=0; i>>= 1; - i++; - } - return as; - } - - // Read a UTF8 char - public int utf8Char() { - int b = u8(); - if( (b&0x80)==0 ) return (char)b; // ASCII single byte - - // otherwise the format is based on the number of high-order 1-bits: - // #1s first byte trailing # trailing bits code-points - // --- ---------- -------- ---------- ---- ----------------------- - // 2 110xxxxx 10xxxxxx 1 11 U+0080 - U+07FF - // 3 1110xxxx 10xxxxxx 2 16 U+0800 - U+FFFF - // 4 11110xxx 10xxxxxx 3 21 U+10000 - U+1FFFFF - // 5 111110xx 10xxxxxx 4 26 U+200000 - U+3FFFFFF - // 6 1111110x 10xxxxxx 5 31 U+4000000 - U+7FFFFFFF - return switch( Integer.highestOneBit( ~(0xFFFFFF00 | b) ) ) { - case 0b00100000 -> (b & 0b00011111) << 6 | utf8Byte(); - case 0b00010000 -> (b & 0b00001111) << 12 | utf8Byte() << 6 | utf8Byte(); - case 0b00001000 -> (b & 0b00000111) << 18 | utf8Byte() << 12 | utf8Byte() << 6 | utf8Byte(); - case 0b00000100 -> (b & 0b00000011) << 24 | utf8Byte() << 18 | utf8Byte() << 12 | utf8Byte() << 6 | utf8Byte(); - case 0b00000010 -> (b & 0b00000001) << 30 | utf8Byte() << 24 | utf8Byte() << 18 | utf8Byte() << 12 | utf8Byte() << 6 | utf8Byte(); - default -> throw new IllegalArgumentException( "initial byte: " + Integer.toHexString( b ) ); - }; - } - - // Read a UTF8 string - private static final StringBuilder SB = new StringBuilder(); - public String utf8() { - SB.setLength(0); - int len = u31(); - int len2 = len - u31(); - for( int i=0; i 0xFFFF ) throw XEC.TODO(); - SB.append((char)ch); - } - return SB.toString().intern(); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ClassPart.java b/javatools_backend/src/main/java/org/xvm/xtc/ClassPart.java deleted file mode 100644 index decebcf61e..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ClassPart.java +++ /dev/null @@ -1,180 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xec.XTC; -import org.xvm.util.SB; -import org.xvm.xtc.cons.*; - -import static org.xvm.xtc.Part.Composition.*; - -import java.util.HashMap; - -/** - Class part - - -class - closed-struct with methods as fields; FIDXs on concrete methods -interface, delegates - defined as an open-struct with methods as fields -interface abstract method is a leaf (or a lambda leaf with arg counts). No FIDX. -interface concrete method is a full lambda with FIDX. -"class implements iface" - unify the open iface struct against closed class struct -"class extends class" - chain thru a special field " super". -Special type constructor "isa X". -Can drop the env lookup I think. - - */ -public class ClassPart extends Part { - public final LitCon _path; // File name compiling this file - public final Part.Format _f; // Class, Interface, Mixin, Enum, Module, Package - public final int _ord; // Enum ordinal or -1 - - public ClassPart _super; // Super-class. Note that "_par" field is the containing Package, not the superclass - - // Parameterized types, e.g. "Map" - public final String[] _tnames; // String->TCon mapping - public final TCon [] _tcons ; // String->TCon mapping - - // A list of "extra" features about Classes: extends, implements, delegates - public final Contrib[] _contribs; - - public SB _header, _body; // Java source code - public XClz _tclz; // XType class - - ClassPart( Part par, int nFlags, Const id, CondCon cond, CPool X, Part.Format f, int ord ) { - super(par,nFlags,id,null,cond,X); - - _f = f; - _ord = f==Part.Format.ENUMVALUE ? ord : -1; - _contribs = Contrib.xcontribs(_cslen,X); - - // Read a collection of parameters type names and base types. - // Similar to Java "Map" - // we get a list of Key->String, Value->Person. - int len = X.u31(); - _tnames = new String[len]; - _tcons = new TCon [len]; - for( int i=0; i < len; i++ ) { - _tnames[i] = ((StringCon)X.xget())._str; - _tcons[i] = ( TCon)X.xget(); - } - - LitCon path = (LitCon)X.xget(); - if( path == null ) { - ClassPart out; - for( out = outer(); out!=null && path==null; out=outer() ) - path = out._path; - } - _path = path; - } - - // Constructed class parts - ClassPart( Part par, String name, Part.Format f ) { - super(par,name); - _f = f; - _ord = -1; - _tnames = null; - _tcons = null; - _path = null; - _contribs = null; - } - - // Mixin-as-super class from the mixin class - ClassPart( ClassPart mix, String name ) { - super(mix._par,name,mix._id,mix._nFlags); - assert mix._f==Part.Format.MIXIN; - assert name.contains("$"); // The generated mixin name - _f = Part.Format.MIXIN; - _ord = -1; - _path = mix._path; - _tnames = mix._tnames; - _tcons = mix._tcons; - _contribs = mix._contribs; - _name2kid = mix._name2kid; - } - - // Tok, kid-specific internal linking. - @Override void link_innards( XEC.ModRepo repo ) { - // This Class may extend another one. - // Look for extends, implements, etc. contributions - if( _contribs != null ) - for( Contrib c : _contribs ) - if( c._comp==Extends ) - _super = ((ClzCon)c._tContrib).clz(); - } - - - // Hunt this clz for name, plus recursively any Implements/Extends/Delegates - // contribs. "Into" contribs are search 1 level deep only. Order matters on - // the contribs, as the most specific hit should come first - but there may - // be more hits later with more general names. - // - // E.g. - // Looking for "Entry" in SkipListMap. - // SkipListMap implements OrderedMap implements "Entry" - as an @Override interface. - // SkipListMap incorporates CopyableMap.ReplicableCopier which implements CopyableMap - // which implements Map which implements "Entry". - // Map.Entry is the parent interface; OrderedMap.Entry is the child interface, it - // extends Map.Entry as well as other extends. - - @Override public Part child(String s) { return search(s,true); } - - Part search( String s, boolean into ) { - Part p = _name2kid==null ? null : _name2kid.get(s); - if( p!=null ) return p; - - // Search contributions, perhaps recursively. Check them all; should be - // exactly 1 hit but for an assert confirm there is only one. - if( _contribs == null ) return null; - for( Contrib c : _contribs ) { - switch( c._comp ) { - case Into: if( !into ) continue; break; - case Incorporates: into=false; break; - case Implements: case Extends: case Delegates: break; - default: continue; - } - p = ((ClzCon)c._tContrib).clz().search(s,into); - if( p!=null ) return p; - } - return null; - } - - // Modules in XTC do not have to be named after their file path, like they do in Java. - // Example: XTC Module ecstasy.xtclang.org is in a file ecstasy.x. - // I am using the file name as a Java file name... which is also the Java package. - // XTC classes can use their given name, and this will be prefixed with the module as needed. - String name() { return _name; } - - // Module for this class - public ModPart mod() { - Part clz = this; - while( !(clz instanceof ModPart mod) ) - clz = clz._par; - return mod; - } - - // Outer class for nested class - public ClassPart outer() { - Part p = _par; - while( !(p instanceof ClassPart clz) ) { - if( p==null ) return null; - p = p._par; - } - return clz; - } - - // Return XClz, expected already computed - public XClz tclz() { assert _tclz!=null; return _tclz; } - - // Like a Java nested inner, will have an instanceof of the outer - public ClassPart isNestedInnerClass() { - // self -> MMethod -> Class -> [Package or other ???] - Part outer = _par; - if( isStatic() || outer instanceof PackagePart || XClz.make(this).isa(XCons.CONST) ) - return null; - while( !(outer instanceof ClassPart outclz) ) - outer = outer._par; - return outclz; - } - - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ClzBldSet.java b/javatools_backend/src/main/java/org/xvm/xtc/ClzBldSet.java deleted file mode 100644 index c10a41744f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ClzBldSet.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.util.Ary; -import org.xvm.util.SB; -import org.xvm.util.S; - -import java.util.ArrayList; - -// Build a set of Java classes all at once, so 'javac' can compile them all at once. -public abstract class ClzBldSet { - // Mods and classes to have source code generated for. - public static final Ary CLZS = new Ary<>(ClassPart.class); - // All sources to be javac'd at once. Includes some sources generated - // outside ClzBuilder (e.g. generified functional interfaces or tuples) - public static final ArrayList SRCS = new ArrayList<>(); - - // We know we are starting a new gen set here - public static void do_compile( ClassPart clz ) { - assert clz._header==null && clz._body==null; - assert SRCS.isEmpty(); - add(clz); - // ClzBuilder may add new modules+classes to compile. - // While we keep finding things to compile... - for( int i=0; i _locals; // Virtual register numbers to java names - public final Ary _ltypes; // Virtual register numbers to java types - public final int _nouters; // Number of outer-scope pre-boxed locals - - public final int nlocals() { return _locals._len; } - - // A collection of extra imports, generated all along - static HashSet IMPORTS; - // Import base names; collisions will require name munging - static HashMap BASE_IMPORTS; - static HashSet AMBIGUOUS_IMPORTS; - - // A collection of nested classes that all need to appear in this one Java - // compilation unit - static Ary NESTED = new Ary<>(XClz.class); - - - // Make a nested java class builder - public ClzBuilder( ClzBuilder bld, ClassPart nest ) { this(bld._mod,nest,bld._sbhead,bld._sb,false, bld.nlocals()); } - - // Make a (possible nested) java class builder - ClzBuilder( ModPart mod, ClassPart clz, SB sbhead, SB sb, boolean is_top, int nouters ) { - _is_top = is_top; - if( is_top ) { - IMPORTS = new HashSet<>(); // Top-level imports - BASE_IMPORTS = new HashMap<>();// Top-level import base names - AMBIGUOUS_IMPORTS = new HashSet<>(); - CMOD = mod; // Top-level compile unit - CCLZ = clz==null ? mod : clz; // Compile unit class - assert NESTED.isEmpty(); - assert nouters == 0; - } - _is_module = mod==clz; - _mod = mod; - _tmod = mod==null ? null : XClz.make(mod); - _clz = clz; - _tclz = clz==null ? null : XClz.make(clz); - assert clz==null || clz._tclz == _tclz; - _sbhead = sbhead; - _sb = sb; - _locals = new Ary<>(String.class); - _ltypes = new Ary<>(XType .class); - _nouters = nouters; - } - - // For mixins - public ClzBuilder( XClz mod, XClz tclz, SB sbhead, SB sb ) { - _is_top = false; - _is_module = false; - _tmod = mod; - _tclz = tclz; - _mod = (ModPart)mod._clz; - _clz = tclz._clz; - _sbhead = sbhead; - _sb = sb; - _locals = new Ary<>(String.class); - _ltypes = new Ary<>(XType .class); - _nouters = 0; - } - - // Fill in the body of the matching java class - public void jclass( ) { - assert _is_top; - _sbhead.p("// ---------------------------------------------------------------").nl(); - _sbhead.p("// Auto Generated by XEC from ").p( _mod._dir._str).p(_clz._path._str).nl().nl(); - // XTC modules are all unique at the same level (the Repo level). - // XTC classes are unique within a module, but not across modules. - // Java package name includes the XTC module name. - _sbhead.p("package ").p(XEC.XCLZ).p(".").p(_tclz._pack).p(";").nl().nl(); - _sbhead.p("import " ).p(XEC.ROOT).p(".xec.*;").nl(); - _sbhead.p("import " ).p(XEC.ROOT).p(".xrun.*;").nl(); - _sbhead.p("import static ").p(XEC.ROOT).p(".xrun.XRuntime.$t;").nl(); - jclass_body( ); - _sb.p("// ---------------------------------------------------------------").nl(); - // Output imports in the header - for( String imp : IMPORTS ) - _sbhead.p("import ").p(imp).p(";").nl(); - _sbhead.nl(); - _clz._header = _sbhead; - _clz._body = _sb; - // Reset and clear all the statics - IMPORTS = null; - BASE_IMPORTS = null; - for( XClz clz : AMBIGUOUS_IMPORTS ) - clz._ambiguous = false; - AMBIGUOUS_IMPORTS = null; - CMOD = null; - CCLZ = null; - } - - // Java Class body; can be nested (static inner class) - private void jclass_body() { - assert !_tclz._did_gen; - _tclz._did_gen = true; - // While XTC Enum Values are themselves a full-blown class, we're going to make - // an effort to limit ourselves to *Java* enums as the implementation. - // Emit no code here - if( _clz._f == Part.Format.ENUMVALUE ) { - assert _clz._name2kid.size()==1 && ((MethodPart)_clz.child("construct").child("construct")).is_empty_function(); - return; - } - - if( _tclz._super!=null ) - // If this is a normal incorp "mixin<-base" class, make sure the mixin happens - if( _tclz. _clz._f == Part.Format.MIXIN || - _tclz._super._clz._f == Part.Format.MIXIN ) - if( _tclz._clz._par instanceof MethodPart ) add_nested(_tclz._super ); - else add_import(_tclz._super); - - // Actually start emitting class headers - String java_class_name = _tclz._name; - _sb.nl(); // Blank line - if( !_is_top ) _sb.ip("//-----------------").nl(); - boolean is_iface = _clz._f==Part.Format.INTERFACE; - String jpart = is_iface ? "interface " : "class "; - String xpart = _is_module ? "module ": jpart; - _sb.ip("// XTC ").p(xpart).p(_clz._path==null ? _clz._name : _clz._path._str).p(":").p(_clz._name).p(" as Java ").p(jpart).p(java_class_name).nl(); - - // public static class CLZ extends ... - - _sb.ip("public "); - if( _tclz._abstrct ) _sb.p("abstract "); - if( !_is_top ) _sb.p("static "); - _sb.p(jpart).p(_tclz.name()); - _tclz.clz_generic_def(_sb).p(" "); - - // ... extends Const/XTC/etc - if( _tclz._super != null ) { - _sb.p("extends ").p(_tclz._super._name); - _tclz._super.clz_generic_use( _sb, _tclz ); - if( _clz._f==Part.Format.CONST ) { - IMPORTS.add( XEC.XCLZ + ".ecstasy.Const" ); - IMPORTS.add( XEC.XCLZ + ".ecstasy.Ordered" ); - } else if( _clz._f==Part.Format.ENUM ) { - IMPORTS.add(XEC.XCLZ+".ecstasy.Enum"); - } else if( _clz._f==Part.Format.SERVICE ) { - IMPORTS.add(XEC.XCLZ+".ecstasy.Service"); - } - } else if( is_iface ) { - // No extends - } else { - _sb.p("extends ").p(is_runclz() ? "XRunClz" : "XTC"); - } - - // ...implements IMPL - if( _clz._contribs!=null ) { - int once=0; - for( Contrib c : _clz._contribs ) - if( c._comp==Part.Composition.Implements ) { - XClz iclz = switch( c._tContrib ) { - case ParamTCon ptc -> XClz.make(ptc); - case TermTCon ttc -> XClz.make(ttc.clz()); - case VirtDepTCon vtc -> XClz.make(vtc.clz()); - case ImmutTCon imm -> XClz.make(imm); - case InnerDepTCon inn-> XClz.make(inn.clz()); - default -> throw XEC.TODO(); - }; - _sb.p((once++ == 0) ? (is_iface ? "extends " : " implements ") : ", ").p(iclz.name()); - iclz.clz_generic_use(_sb, _tclz); - add_import(iclz); - } - } - - _sb.p(" {").nl().ii(); - - - // Get a GOLDen instance for faster special dispatch rules. - // Use the sentinel "Never" type to get a true Java no-arg constructor - if( !is_iface ) { - if( !_tclz._abstrct ) - _sb.ifmt("public static final %0 GOLD = new %0((Never)null);\n",java_class_name); - _sb.ifmt("protected %0(Never n){super(n);} // A no-arg-no-work constructor\n",java_class_name); - } - - // Force native methods to now appear, so signature matching can assume a - // method always exists. - if( _clz._name2kid!=null ) - for( Part part : _clz._name2kid.values() ) - if( part instanceof MMethodPart mmp ) - // Output java methods. - if( mmp._name2kid==null ) { - mmp.addNative(); - } else { - if( mmp.child(mmp._name) instanceof MethodPart m && m._cons != null ) - for( Const con : m._cons ) - if( con instanceof MethodCon meth ) - if( meth._par.part() instanceof MMethodPart mm && mm._name2kid==null ) - mm.addNative(); - } - - - // Look for a module/class init. This will become the Java / - MMethodPart mm = (MMethodPart)_clz.child("construct"); - if( mm != null && - // Interfaces in XTC can require a constructor with a particular signature. - // Interfaces in Java can NOT - so just do not emit the signature. - !is_iface ) { - // Empty constructor is specified, must be added now - BECAUSE I already - // added another constructor, so I do not get the default Java empty - // constructor "for free" - - // This is an "empty" constructor: it takes required explicit type - // parameters but does no other work. - _sb.ifmt("public %0( ",java_class_name); - for( int i=0; i<_tclz._tns.length; i++ ) - _sb.fmt("$%0 %0,",_tclz._tns[i]); - _sb.unchar().p(" ) { // default XTC empty constructor\n").ii(); - _sb.ip("super( "); - if( _tclz._super==null || _tclz._super._tns.length==0 ) - _sb.p("(Never)null"); - else { - for( int i=0; i<_tclz._tns.length; i++ ) - _sb.fmt("%0,",_tclz._tns[i]); - _sb.unchar(); - } - _sb.p(");").nl(); - // Init any local type variables; these appear in name2kid - for( int i=0; i<_tclz._tns.length; i++ ) - _sb.ifmt("this.%0 = %0;\n",_tclz._tns[i]); - // final boolean _mix; - // _mix = T0 instanceof String && T1 instanceof Foo; - if( _tclz._mixts != null ) { - _sb.ip("_$mix = "); - for( int i=0; i<_tclz._mixts.length; i++ ) - _sb.fmt("%0 instanceof %1 && ",_tclz._tns[i],_tclz._mixts[i].clz()); - _sb.unchar(4).p(";\n"); - } - _sb.di().ip("}\n"); - if( _tclz._mixts != null ) - _sb.ip("boolean _$mix;\n"); - - - // For all other constructors - for( MethodPart meth = (MethodPart)mm.child(mm._name); meth != null; meth = meth._sibling ) { - // To support XTC 'construct' I need a layer of indirection. The Java - // moral equivalent is calling 'this' in a constructor, but XTC allows - // calling 'this' anywhere. - - // "public static Foo construct(typeargs,args) { return new Foo(typeargs).$construct(args).$check(); }" - if( !_tclz._abstrct ) { - _sb.nl(); - keywords(meth,true); - _tclz.clz_generic_def(_sb); - _sb.fmt("%0 construct( ",java_class_name); // Return type - for( String tn : _tclz._tns ) - _sb.fmt("$%0 %0, ",tn); - // Nested inner classes take an outer class arg - ClassPart outer = _clz.isNestedInnerClass(); - if( outer!=null ) - outer._tclz.clz_bare(_sb).p(" $outer, "); - if( meth._args==null ) _sb.unchar(2); - else args(meth,_sb,null,false); - _sb.p(") { return new ").p(java_class_name).p("( "); - for( String tn : _tclz._tns ) - _sb.fmt("%0,",tn); - _sb.unchar().p(").$construct("); - arg_names(meth,_sb, null); - _sb.p(").$check(); }").nl(); - } - - // "private Foo $construct(args) { ..." - _sb.ip("private ").p(java_class_name).p(" "); - // Common empty constructor - if( meth.is_empty_function() ) { - _sb.p("$construct(){ return this; }").nl(); - } else { - jmethod_body(meth,"$construct",true); - } - } - } - - // Property types from interfaces and mixins - for( XClz side : _tclz._sides.keySet() ) { - if( side.isMixin() ) continue; - int[] idxs = _tclz._sides.get(side); - for( int i=0; i HashSet " - public static SB ret_sig( MethodPart m, SB sb ) { - // Check for XTC generic method, needing a Java generic type - if( m._args!=null && m._args.length>1 && m._args[0]._special ) { - // TODO: XClz.clz_def - sb.p("<"); - // Check the type-parm parm flag, and insert Java generics for all - for( int i=0; i "); - } - - // Return type - XType xret = m.xfun().ret(); - if( xret instanceof XClz xclz ) { - xclz.clz_bare(sb); - xclz.clz_generic_use(sb,m.clz()._tclz); - } - else xret.clz(sb); - return sb.p(' '); - } - - // Emit a Java string for this MethodPart. - // Already _sb has the indent set. - // "public static Ary " ... jmethod_body() - public void jmethod( MethodPart m, String mname ) { - assert _locals.isEmpty(); // No locals mapped yet - - // Print out a boxed version, is applicable - XFun xfun = m.xfun(); - if( xfun.hasUnboxedArgs() ) { - // Print out the function header keywords - keywords(m,false); - - // Return signature; stuff like "long " or " HashSet " - ret_sig(m, _sb); - - // Unbox the args and return primitive version - _sb.p(mname).p("( "); - args(m,_sb,"",true); - _sb.p(" )"); - if( m._ast.length==0 ) - _sb.p(";"); // Abstract method - else { - _sb.p(" {").nl().ii().i(); - if( xfun.ret()!=XCons.VOID ) - _sb.p("return "); - _sb.p(mname).p("( "); - for( int i = 0; i < m._args.length; i++ ) { - _sb.p(jname(m._args[i]._name)); - if( xfun.arg(i).isUnboxed() ) - _sb.p("._i"); - _sb.p(", "); - } - _sb.unchar(2).p(" );").nl().di(); - _sb.i().p("}"); - } - _sb.nl(); - } - - // Print out the function header keywords - keywords(m,false); - - // Return signature; stuff like "long " or " HashSet " - ret_sig(m, _sb); - - jmethod_body(m,mname,false); - } - - // Name, argument list, body: - // - // ...method_name( int arg0, String arg1, ...) { - // ...indented_body - // } - public void jmethod_body( MethodPart m, String mname, boolean constructor ) { - // Argument list: - // ... method_name( int arg0, String, arg1, ... ) { - // Mixins rename all args with a "$" - _sb.p(mname).p("( "); - args(m,_sb, _tclz._mixts == null ? null : "$",false); - _sb.p(" ) "); - // Define argument names - XFun xfun = m.xfun(); - // xargs on constructors includes *type variables*, which are NOT in - // method args. Skip those names here. - int ntypes = xfun.nargs() - (m._args==null ? 0 : m._args.length); - if( m._args != null ) - for( int i = 0; i < m._args.length; i++ ) - define(jname(m._args[i]._name),xfun.arg(i+ntypes)); - - // Abstract method, no "body" - if( m._ast.length==0 ) { - _sb.p(";").nl(); - } else { - if( _tclz._mixts != null ) { - // Conditional mixins check the condition and "super out" if they don't apply. - // if( !_$mix ) return super.meth(args) - _sb.p("{\n"); - _sb.ii().ip("if( !_$mix ) return super.").p(mname).p("("); - arg_names(m,_sb,"$"); - _sb.p(");\n"); - // Upcast the args for the condition - if( m._args !=null ) { - int delta = xfun.nargs() - m._args.length; - for( int i = 0; i < m._args.length; i++ ) { - String arg = m._args[i]._name; - XType xt = xfun.arg(i+delta); - int idx = S.find(_tclz._mixts,xt); - if( idx== -1 ) _sb.ifmt("var %0 = %0$;\n",arg); - else _sb.ifmt("%0 %1 = (%0)%1$;\n", _tclz._mixts[idx].clz(),arg); - } - } - _sb.i(); - } - - // Parse the Body - AST ast = ast(m); - // If a constructor, move the super-call up front - if( constructor && _clz._super!=null && ast instanceof MultiAST multi ) - do_super(multi); - // Wrap in required "{}" block - BlockAST blk = ast instanceof BlockAST blk0 ? blk0 : new BlockAST(ast); - // This is a XTC constructor, which in Java is implemented as a factory - // method - which has the normal no-arg Java constructor already called - - // but now the XTC constructor method needs to end in a Java return. - if( constructor && (blk._kids.length==0 || !(blk._kids[blk._kids.length-1] instanceof ThrowAST)) ) - blk = blk.add(new ReturnAST(m,new RegAST(-5/*A_THIS*/,"this",_tclz))); - blk.jcode(_sb); - _sb.nl(); - - if( _tclz._mixts != null ) { - _sb.di().ip("}\n"); - } - } - - // Popped back to the original args - assert (m._args==null ? 0 : m._args.length) == nlocals(); - pop_locals(0); - - if( m._name2kid != null ) - for( Part part : m._name2kid.values() ) { - switch( part ) { - case PropPart pp: - PropBuilder.make_class(this,pp); - break; - case MMethodPart mmp: - // Method-local nested methods. - // Lambda expressions have already been inlined - if( !mmp._name.equals("->") ) { - // Recursively dump nested method - MethodPart meth = (MethodPart)mmp.child(mmp._name); - jmethod(meth,mname+"$"+mmp._name); - } - break; - case ClassPart clz_nest: - // MIXINs always need their BASE - if( clz_nest._f!=Part.Format.MIXIN ) - // Nested class. Becomes a java static inner class - add_nested( XClz.make(clz_nest) ); - break; - case TDefPart tdef: - break; // Do nothing, handled by the XTypes already - default: throw XEC.TODO(); - } - } - } - - // Constructors call other constructors via factory method $constructor, - // skipping the allocation step. - private void do_super( MultiAST ast ) { - for( int i=0; i name+"0"; - case "construct" -> "$construct"; - case "_" -> "$ignore"; - default -> name; - }; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/Contrib.java b/javatools_backend/src/main/java/org/xvm/xtc/Contrib.java deleted file mode 100644 index 54ba936bb5..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/Contrib.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xtc.cons.*; -import org.xvm.util.SB; - -import java.util.HashMap; - -/** - * Represents one contribution to the definition of a class. A class (with the term used in the - * abstract sense, meaning any class, interface, mixin, const, enum, or service) can be composed - * of any number of contributing components. - */ -public class Contrib { - public final Part.Composition _comp; - private final PropCon _prop; - private final SingleCon _inject; - public final Annot _annot; - final HashMap _parms; - - public final TCon _tContrib; - - protected Contrib( CPool X ) { - _comp = Part.Composition.valueOf(X.u8()); - _tContrib = (TCon)X.xget(); - PropCon prop = null; - Annot annot = null; - SingleCon inject = null; - HashMap parms = null; - - assert _tContrib!=null; - switch( _comp ) { - case Extends: - case Implements: - case Into: - case RebasesOnto: - break; - case Annotation: - annot = (Annot)X.xget(); - break; - case Delegates: - prop = (PropCon)X.xget(); - break; - - case Incorporates: - int len = X.u31(); - if( len == 0 ) break; - parms = new HashMap<>(); - for( int i = 0; i < len; i++ ) { - String name = ((StringCon)X.xget())._str; - int ix = X.u31(); - parms.put(name, ix == 0 ? null : (TCon)X.get(ix)); - } - break; - - case Import: - inject = (SingleCon)X.xget(); - if( inject==null ) break; - throw XEC.TODO(); - - default: throw XEC.TODO(); - } - _annot = annot; - _prop = prop; - _inject = inject; - _parms = parms; - } - - @Override public String toString() { return str(new SB()).toString(); } - public SB str(SB sb) { - sb.p(_comp.toString()); - return _tContrib ==null ? sb : _tContrib.str(sb.p(" -> ")); - } - - static Contrib[] xcontribs( int len, CPool X ) { - if( len==0 ) return null; - Contrib[] cs = new Contrib[len]; - for( int i=0; i srcs ) { - - DiagnosticCollector errs = new DiagnosticCollector<>(); - - ArrayList options = new ArrayList<>(); - - JavaCompiler.CompilationTask task = COMPILER.getTask(null, XFILE, errs, options, null, srcs); - - if( !task.call() ) { - errs.getDiagnostics().forEach( System.err::println ); - throw XEC.TODO(); - } - - try { - for( JavaSrc src : srcs ) { - JCodes jc = XFM.get( src._name ); - jc._klass = (Class) LOADER.loadClass( src._name ); - } - } catch( ClassNotFoundException cnfe ) { - throw new RuntimeException(cnfe); - } - } - - // Just wraps the constructor to pass in a URI - public static class SJFOWrap extends SimpleJavaFileObject { - public final String _name; - public SJFOWrap(String name, Kind kind) { - super(URI.create("string:///" + name.replace('.', '/') + kind.extension), kind); - _name = name; - } - } - - public static class JavaSrc extends SJFOWrap { - public String _src; - public JavaSrc(String name, String src) { - super(name, Kind.SOURCE); - _src = src; - } - @Override public CharSequence getCharContent(boolean ignore) { return _src; } - } - - public static class JCodes extends SJFOWrap { - // Free the "buf"! - private static final class BAOS extends ByteArrayOutputStream { byte[] buf() { return buf; } } - final byte[] _buf; - final BAOS _bos; - public Class _klass; - public JCodes(String name, Kind kind) { - super(name, kind); - _bos = new BAOS(); // Initial small buffer, will change during compilation - _buf = null; // Buf from BAOS, which changes during compilation - } - JCodes(String name, File file) { - super(name,Kind.CLASS); - _bos = null; - try { - _buf = Files.readAllBytes(file.toPath()); - } catch(IOException ioe) { - throw new RuntimeException(ioe); - } - } - @Override public ByteArrayOutputStream openOutputStream() { return _bos; } - // Input stream from output stream without copying the buf - @Override public ByteArrayInputStream openInputStream() { - return _buf==null - ? new ByteArrayInputStream(_bos.buf(),0,_bos.size()) - : new ByteArrayInputStream( _buf ,0,_buf.length); - } - } - - private static class XClzLoader extends ClassLoader { - XClzLoader() { super(JavaC.class.getClassLoader()); } - @Override protected Class findClass( String clzname) throws ClassNotFoundException { - JCodes jc = XFM.get(clzname); - return (Class)(jc._buf==null - ? defineClass(clzname, jc._bos.buf(), 0, jc._bos.size()) - : defineClass(clzname, jc. _buf , 0, jc._buf.length)); - } - @Override public String getName() { return "XEC_ClassLoader"; } - } - - // A tree-structured set of hashmaps, mirroring the actual org.xvm.xec directory structure - public static class XFileSys { - public final HashMap _jcodes; // Local class files - public final HashMap _dirs; // Sub-directories of the same - - // Walk and recursively install all existing hand-made Java classes - XFileSys( String prefix, File dir ) { - _jcodes = new HashMap<>(); - _dirs = new HashMap<>(); - if( dir != null ) - for( File file : dir.listFiles() ) { - String fname = file.getName(); - if( file.isDirectory() ) { - _dirs.put(fname,new XFileSys(prefix+"."+fname,file)); - } else { - if( fname.endsWith(".class") ) { - // e.g. "org.xvm.xec.XRunClz" - String base = fname.substring(0,fname.length()-6); - String name = prefix+"."+base; - _jcodes.put(name,new JCodes(name,file)); - } - } - } - } - - XFileSys pack(String clzname, boolean hasBase ) { - // org.xvm.xec.PACK0.PACK1.PACKN.BASECLASSNAME - assert clzname.startsWith(XEC.XCLZ); - // .PACK0.PACK1.PACKN.BASECLASSNAME - String packbase = clzname.substring(XEC.XCLZ.length()); - // .PACK0.PACK1.PACKN - String pack = hasBase ? packbase.substring(0,packbase.lastIndexOf('.')) : packbase; - return _pack(pack,hasBase); - } - - // .PACK0.PACK1.PACKN or null if it does not exist - XFileSys _pack( String pack, boolean create ) { - if( pack.isEmpty() ) return this; - int idx = pack.indexOf('.',1); - String spack = idx == -1 ? pack.substring(1) : pack.substring(1,idx); - XFileSys dir = _dirs.get(spack); - if( dir!=null ) - return idx == -1 ? dir : dir._pack(pack.substring(idx),create); - if( !create ) - return null; - dir = new XFileSys(null,null); - _dirs.put(spack,dir); - return dir; - } - - - JCodes get(String clzname) { - return pack(clzname,true)._jcodes.get(clzname); - } - public Class klass(String clz) { - JCodes jc = get(clz); - return jc == null ? null : jc._klass; - } - public Class klass(ClassPart clz) { - return clz._tclz==null ? null : klass(clz._tclz.qualified_name()); - } - - JCodes put( String clzname, JCodes jc ) { - pack(clzname,true)._jcodes.put(clzname,jc); - return jc; - } - - } - - - // Locally compiled java class files "file system". - private static class XFileManager extends ForwardingJavaFileManager { - public XFileManager(StandardJavaFileManager man) { super(man); } - - @Override public XClzLoader getClassLoader(Location location) { return LOADER; } - // javac will get this JCodes and fill it; we map it before it gets filled - @Override public JavaFileObject getJavaFileForOutput(Location ignore, String name, Kind kind, FileObject sibling) { - JCodes jc = new JCodes(name, kind); - return XFM.put(name,jc); - } - - // Intercept my JCodes looking for the fully qualified Java name. - // Other names belong to e.g. the base system modules. - @Override public String inferBinaryName(Location location, JavaFileObject file) { - return file instanceof JCodes jc - ? jc._name - : super.inferBinaryName(location,file); - } - - // Intercept internally compiled class files, and admit they exist. - @Override public Iterable list(Location location, String packageName, Set kinds, boolean recurse) throws IOException { - if( location == StandardLocation.CLASS_PATH && packageName.startsWith(XEC.XCLZ) ) { - // XTC Package name with leading XEC.XCLZ stripped off - return new PackIter(packageName); - } - return super.list(location,packageName,kinds,recurse); - } - private class PackIter implements Iterable { - final String _pack; - PackIter(String pack) { _pack = pack; } - // Due to generic weirdness, cannot just return "_map.values().iterator()" - // but need to make a private class with generic type JavaFileObject and - // "next()" returns a JCodes which implements JavaFileObject. - @Override public Iterator iterator() { return new Iter(); } - private class Iter implements Iterator { - Iterator _iter; - Iter() { - String pack = _pack; - XFileSys xfm = XFM.pack(_pack,false); - _iter = xfm==null ? null : xfm._jcodes.values().iterator(); - } - @Override public boolean hasNext() { return _iter != null && _iter.hasNext(); } - @Override public JCodes next() { return _iter.next(); } - } - - } - - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/MMethodPart.java b/javatools_backend/src/main/java/org/xvm/xtc/MMethodPart.java deleted file mode 100644 index 027e3ea91f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/MMethodPart.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xtc.cons.*; - -import java.util.HashSet; - -// A bunch of methods, following the kids list -public class MMethodPart extends Part { - MMethodPart( Part par, int nFlags, Const id, CondCon con, CPool X ) { - super(par,nFlags,id,null,con,X); - } - - MMethodPart( Part par, String name ) { super(par,name); } - - @Override public void putkid(String name, Part kid) { - MethodPart old = (MethodPart)child(kid._name); - if( old==null ) super.putkid(kid._name,kid); - else { - while( old._sibling!=null ) old = old._sibling; // Follow linked list to end - old._sibling = (MethodPart)kid; // Append kid to tail of linked list - } - } - - @Override void link_innards( XEC.ModRepo repo ) {} - - // I could construct a tuple of each underlying method - public MethodPart addNative() { - assert NATIVES.contains(_name); - ClassCon tcon = (ClassCon)_par._id; - MethodPart meth = switch( _name ) { - case "equals" -> build(XCons.BOOL,"gold",tcon,"lhs",tcon,"rhs",tcon); - case "hashCode" -> build(XCons.LONG,"gold",tcon); - case "compare" -> build(XCons.ORDERED,"gold",tcon,"lhs",tcon,"rhs",tcon); - case "appendTo" -> build(XCons.APPENDERCHAR,new Parameter[]{new Parameter("buf",XCons.APPENDERCHAR)}); - case "estimateStringLength" -> build(XCons.LONG); - default -> throw XEC.TODO(); - }; - putkid(_name,meth); - return meth; - } - - private MethodPart build(XType xret, Object... os) { - Parameter[] args = new Parameter[os.length>>1]; - for( int i=0; i NATIVES = new HashSet<>() { { - add("add"); - add("addAll"); - add("appendTo"); - add("compare"); - add("construct"); - add("equals"); - add("estimateStringLength"); - add("get"); - add("hashCode"); - add("set"); - } }; -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/MethodPart.java b/javatools_backend/src/main/java/org/xvm/xtc/MethodPart.java deleted file mode 100644 index 64391b7bd6..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/MethodPart.java +++ /dev/null @@ -1,205 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xtc.cons.*; -import org.xvm.util.S; -import java.util.Arrays; - -public class MethodPart extends MMethodPart { - // Linked list of siblings at the same DAG level with the same name - public MethodPart _sibling; - - // Method's "super" - private final MethodCon _supercon; - - public final PartCon[] _supers; - public final Part[] _super_parts; - - // Optional "finally" block - public final MethodCon _finally; - - public final MethodCon _methcon; - - // Annotations - public final Annot[] _annos; - - // Return types - public final Parameter[] _rets; - - // Argument types - public final Parameter[] _args; - public final int _nDefaults; // Number of default arguments - - // Constants for code - public final Const[] _cons; - - // The XEC bytecodes - public final byte[] _code; - // The XEC AST - public final byte[] _ast; - - // The source code - public final String[] _lines; // Source lines - public final int[] _indts; // Indents - public final int _first; // First line number - - // - MethodPart( Part par, int nFlags, MethodCon id, CondCon con, CPool X ) { - super(par,nFlags,id,con,X); - - // Unique "id" since name is not unique - _methcon = id; - - // Linked-list of same-name methods. - _sibling = null; - - // Read annotations - _annos = Annot.xannos(X); - - // Read optional "finally" block - _finally = (MethodCon)X.xget(); - - // Read return types - boolean cret = isConditionalReturn(); - TCon[] rawRets = id.rawRets(); - _rets = rawRets==null ? null : new Parameter[rawRets.length]; - if( rawRets!=null ) - for( int i=0; i0; - - // Read and skip the AST bytes - _ast = X.bytes(); - - // Read the source code - int n = X.u31(); - _first = n > 0 ? X.u31() : -1; - _lines = new String[n]; - _indts = new int[n]; - for( int i=0; i _prefers; - - ModPart( Part par, int nFlags, ModCon con, CondCon cond, CPool X ) { - super(par,nFlags,con,cond,X,Part.Format.MODULE,-1); - - _t = ModuleType.valueOf(X.u8()); - VerCon version = null; - - if( isFingerprint() ) { - _allowedVers = new VerTree(); - for( int i=0, len = X.u31(); i < len; i++ ) - _allowedVers.put(((VerCon)X.xget()).ver(), X.u1()); - - _prefers = new ArrayList<>(); - for( int i=0, len=X.u31(); i < len; i++ ) { - Version ver = ((VerCon)X.xget()).ver(); - if( !_prefers.contains(ver) ) // Duplicate filtering - _prefers.add(ver); - } - } else { - if( X.u1() ) - version = (VerCon)X.xget(); - _allowedVers = null; - _prefers = null; - } - _version = version==null ? null : version.ver(); - _dir = (LitCon)X.xget(); - _time = (LitCon)X.xget(); - } - - // Fingerprints link against a repo to get the actual module - @Override Part link_as( XEC.ModRepo repo ) { - return isFingerprint() ? repo.get(_name) : this; - } - - /** - * Check if this is a fingerprint module, which is a secondary (not main) module in a file - * structure that represents the set of external dependencies on a particular imported module - * from the main module and any embedded modules. - * - * @return true iff this module represents the "fingerprint" of an external module dependency - */ - public boolean isFingerprint() { - return switch( _t ) { - case Optional, Desired, Required -> true; - case Primary, Embedded -> false; - }; - } - - // Find a method by name, or return null - public MethodPart method(String s) { - Part p = child(s); - if( p instanceof MMethodPart mm && s.equals(mm._name) ) { - if( mm._name2kid.size()!=1 ) throw XEC.TODO(); // Disambiguate? - return (MethodPart)mm.child(s); - } - return null; - } - - // Modules in XTC do not have to be named after their file path, like they do in Java. - // Example: XTC Module ecstasy.xtclang.org is in a file ecstasy.x. - // I am using the file name as a Java file name... which is also the Java package. - @Override String name() { - // Subtract off the path ".x" extension and return it as the Java file/package name. - return _path._str.substring(0,_path._str.length()-2).intern(); - } - - - // ----- ModuleType enumeration ---------------------------------------------------------------- - /** - * A module serves one of three primary purposes: - *
    - *
  • The primary module is the module for which the FileStructure exists;
  • - *
  • A fingerprint module represents an imported module;
  • - *
  • An embedded module is an entire module that is embedded within the FileStructure in order - * to fully satisfy the dependencies of an import.
  • - *
- *

- * A fingerprint module has three levels that indicate how desired or required it is: - *

    - *
  • Optional indicates that the dependency is supported, but leaves the decision regarding - * whether or not to import the module to the linker;
  • - *
  • Desired also indicates that the dependency is supported, but even though the dependency - * is not required, the linker should make a best effort to obtain and link in the - * module;
  • - *
  • Required indicates that the primary module can not be loaded unless the fingerprint - * module is obtained and linked in by the linker.
  • - *
- */ - enum ModuleType { - Primary, Optional, Desired, Required, Embedded; - - /** Look up a Format enum by its ordinal. */ - public static ModuleType valueOf(int i) { return MODULE_TYPES[i]; } - private static final ModuleType[] MODULE_TYPES = ModuleType.values(); - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/PackagePart.java b/javatools_backend/src/main/java/org/xvm/xtc/PackagePart.java deleted file mode 100644 index 405cdae7de..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/PackagePart.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.xtc.cons.CondCon; -import org.xvm.xtc.cons.PackageCon; - -/** - Package part - */ -public class PackagePart extends ClassPart { - PackagePart( Part par, int nFlags, PackageCon id, CondCon cond, CPool X ) { - super(par,nFlags,id,cond,X,Part.Format.PACKAGE,-1); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/Parameter.java b/javatools_backend/src/main/java/org/xvm/xtc/Parameter.java deleted file mode 100644 index 0d92fbaf8b..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/Parameter.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xtc.cons.Annot; -import org.xvm.xtc.cons.StringCon; -import org.xvm.xtc.cons.TCon; - -public class Parameter { - // Parameter name - public String _name; - // Parameter type - private final TCon _tcon; - private XType _box, _raw; - // Parameter annotations - public final Annot[] _annots; - // Default value - public final TCon _def; - // True IFF a condition-return or a type-parm parm - public final boolean _special; - // Parameter index, negative for returns - //public final int _idx; - - private Parameter( Annot[] annos, boolean special, TCon tcon, XType xt, String name, TCon def ) { - _name = name; - _tcon = tcon; - _box = xt==null ? null : xt. box(); - _raw = xt==null ? null : xt.unbox(); - _annots = annos; - _def = def; - _special = special; - } - - private static String str(CPool X) { - StringCon str = (StringCon)X.xget(); - return str==null ? null : str._str; - } - Parameter( boolean special, TCon tcon, CPool X ) { - this( Annot.xannos(X), special, (TCon)X.xget(), null, str(X), (TCon)X.xget()); - } - Parameter( String name, TCon tcon) { this(null,false,tcon,null,name,null); } - Parameter( String name, XType xt) { this(null,false,null, xt ,name,null); } - - @Override public String toString() { return _name; } - public TCon tcon() { assert _tcon != null; return _tcon; } - public XType type(boolean box) { - if( box ) return _box == null ? (_box = XType.xtype(_tcon,true )) : _box; - else return _raw == null ? (_raw = XType.xtype(_tcon,false)) : _raw; - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ParmPart.java b/javatools_backend/src/main/java/org/xvm/xtc/ParmPart.java deleted file mode 100644 index 0958050ba0..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ParmPart.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xtc.cons.ParamTCon; -import org.xvm.xtc.cons.TParmCon; -import org.xvm.xtc.cons.TermTCon; - -/** - Package part - */ -public class ParmPart extends Part { - final int _idx; - public ParmPart( MethodPart par, int idx ) { - super(par,0,null,par._args[idx]._name,null,null); - _idx = idx; - } - @Override void link_innards( XEC.ModRepo repo ) {} - Parameter parm() { return ((MethodPart)_par)._args[_idx]; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/Part.java b/javatools_backend/src/main/java/org/xvm/xtc/Part.java deleted file mode 100644 index 32777fe0ec..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/Part.java +++ /dev/null @@ -1,308 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xtc.cons.*; -import org.xvm.util.NonBlockingHashMap; - -/** - DAG structure containment of the existing components/structures. - Handles e.g. the Class hierarchy, Modules, Methods, and Packages. - These things are represented as structures in memory. - */ -abstract public class Part { - public final Const _id; - public final Part _par; // Parent in the parent chain; null ends. Last is FilePart. - public final String _name; // Identifier - public final int _nFlags; // Some bits - public final CondCon _cond; // Conditional component - - // Contributions. A list of "extra" features about this Part. - // Zero except for Class and Prop parts. - final int _cslen; - - // Map from kid name to kid. - public NonBlockingHashMap _name2kid; - - Part( Part par, int nFlags, Const id, String name, CondCon cond, CPool X ) { - _id = id; - _par = par; - assert (par==null) == this instanceof FilePart; // File doesn't have a parent - //assert (id ==null) == this instanceof FilePart; // File doesn't have a id - assert cond==null || !(this instanceof FilePart); // File can't be conditional - - _name = id==null ? name : ((IdCon)id.resolveTypedefs()).name(); - _nFlags = nFlags; - _cond = cond; - - // X is self FilePart. Other parts need to get the length. - // Only Class and Prop have non-zero length. - _cslen = X==null ? 0 : X.u31(); - } - - // Constructed class parts - Part( Part par, String name ) { - _id = null; - _par = par; - _name = name; - _nFlags = 0; - _cond = null; - _cslen = 0; - } - Part( Part par, String name, Const id, int nFlags ) { - _id = id; - _par = par; - _name = name; - _nFlags = nFlags; - _cond = null; - _cslen = 0; - } - - @Override public String toString() { return str(new SB()).toString(); } - public SB str(SB sb) { - sb.p(_name); - return _par==null ? sb : _par.str(sb.p(" -> ")); - } - - // Tik-tok style recursive-descent parsing. This is the Tik, shared amongst - // all kids. The Tok is where we do kid-specific parsing. Since we don't - // have the kids yet, we can't really do a Visitor pattern here. - final void parseKids( CPool X ) { - int cnt = X.u31(); // Number of kids - short order=0; // Order of properties loaded from disk - for( int i=0; ikid mapping - putkid(kid._name,kid); - // Record the order of synthetic properties, used to order synthetic `compare` fields - if( kid instanceof PropPart pp && (pp._nFlags & Part.SYNTHETIC_BIT)!=0 ) - pp._order = order++; - // Here we could be lazy on the child's children, but instead are always eager. - int len = X.u31(); // Length of serialized nested children - if( len > 0 ) // If there are recursively more children - kid.parseKids(X); - } - } - - void putkid(String name, Part kid) { - if( _name2kid==null ) _name2kid = new NonBlockingHashMap<>(); - assert !_name2kid.containsKey(kid._name); - _name2kid.put(kid._name,kid); - } - - // Tik-tok style recursive-descent linking. This is the Tik, shared amongst - // all kids. The Tok is where we do kid-specific linking. If I see too many - // of these tik-tok patterns I'll probably add a Visitor instead. - public final Part link( XEC.ModRepo repo ) { - Part p = XEC.ModRepo.VISIT.get(this); - if( p!=null ) return p; // Already linked - p = link_as(repo); // In-place replacement (Required ModPart becomes Primary ModPart) - XEC.ModRepo.VISIT.put(this,p); // Stop cycles - if( p!=this ) return p.link(repo); // Now link the replacement - - // Link specific part innards - link_innards(repo); // Link internal Const - - // For all child parts - if( _name2kid!=null ) - for( String name : _name2kid.keySet() ) { - Part kid0 = _name2kid.get(name); - Part kid1 = kid0.link(repo); // Link and upgrade - _name2kid.put(name,kid1); // Replace with link and upgrade - } - return this; - } - - // Tok, replace self with a better Part - Part link_as( XEC.ModRepo repo ) { return this; } - - // Tok, kid-specific internal linking. - abstract void link_innards( XEC.ModRepo repo ); - - // Look up a child. - public Part child(String s) { - return _name2kid==null ? null : _name2kid.get(s); - } - - public ClassPart clz() { - Part p = _par; - while( !(p instanceof ClassPart clz) ) - p = p._par; - return clz; - } - - // ----- Enums ----------------------------------------------------------- - /** - * The Format enumeration defines the multiple different binary formats used - * to store component information. Those beginning with "RSVD_" are - * reserved, and must not be used. - */ - public enum Format { - INTERFACE, - CLASS, - CONST, - ENUM, - ENUMVALUE, - MIXIN, - SERVICE, - PACKAGE, - MODULE, - TYPEDEF, - PROPERTY, - METHOD, - RSVD_C, - RSVD_D, - MULTIMETHOD, - FILE; - - /** - * Instantiate a component as it is being read from a stream, reading its body - * @param par the parent component - * @param con the constant for the new component's identity - * @param nFlags the flags that define the common attributes of the component - * @param cond the cond under which the component is present, or null - * @param X file parser support - * @param i enum ordinal - * @return the new component - */ - Part parse( Part par, Const con, int nFlags, CondCon cond, CPool X, int i ) { - assert par!=null; - return switch( this ) { - case MODULE -> new ModPart(par, nFlags, ( ModCon) con, cond, X); - case PACKAGE ->new PackagePart(par, nFlags, (PackageCon) con, cond, X); - case INTERFACE, CLASS, CONST, ENUM, ENUMVALUE, MIXIN, SERVICE - -> new ClassPart(par, nFlags, ( ClassCon) con, cond, X, this, i); - case TYPEDEF -> new TDefPart(par, nFlags, ( TDefCon) con, cond, X); - case PROPERTY -> new PropPart(par, nFlags, ( PropCon) con, cond, X); - case MULTIMETHOD->new MMethodPart(par, nFlags, (MMethodCon) con, cond, X); - case METHOD -> new MethodPart(par, nFlags, ( MethodCon) con, cond, X); - default -> throw new IllegalArgumentException("uninstantiable format: " + this); - }; - } - - /** - * Determine the format from a component's bit-flags value. - * @param nFlags the 2-byte component bit-flags value - * @return the Format specified by the bit flags - */ - static final int FORMAT_MASK = 0x000F, FORMAT_SHIFT = 0; - static Format fromFlags(int nFlags) { - return valueOf((nFlags & FORMAT_MASK) >>> FORMAT_SHIFT); - } - - public static Format valueOf(int i) { return FORMATS[i]; } - private static final Format[] FORMATS = Format.values(); - } - - // ----- enumeration: Component Composition ---------------------------------------------------- - - /** Types of composition. */ - public enum Composition { - /** - * Represents an annotation. - *

- * The constant is a TypeConstant. (It could be a ClassConstant, but TypeConstant - * was selected to keep it compatible with the other compositions.) An annotation has - * optional annotation parameters, each of which is also a constant from the ConstantPool. - */ - Annotation, - /** - * Represents class inheritance. - *

- * The constant is a TypeConstant for the class. - */ - Extends, - /** - * Represents interface inheritance. - *

- * The constant is a TypeConstant. - */ - Implements, - /** - * Represents interface inheritance plus default delegation of interface functionality. - *

- * The constant is a TypeConstant. A "delegates" composition must specify a property that - * provides the reference to which it delegates; this is represented by a PropertyConstant. - */ - Delegates, - /** - * Represents that the class being composed is a mixin that applies to the specified type. - *

- * The constant is a TypeConstant. - */ - Into, - /** - * Represents the combining-in of a mix-in. - *

- * The constant is a TypeConstant. - */ - Incorporates, - /** - * Synthetic (transient) rebasing of a class onto a new category. - */ - RebasesOnto, - /** - * Represents that the package being composed represents an imported module. - *

- * The constant is a ModuleConstant. - */ - Import, - /** - * Synthetic (transient) composition indicating an equivalency. - *

- * The constant is a ClassConstant. - */ - Equal, - ; - - /** - * Look up a Composition enum by its ordinal. - * @param i the ordinal - * @return the Composition enum for the specified ordinal - */ - public static Composition valueOf(int i) { return COMPOSITIONS[i]; } - private static final Composition[] COMPOSITIONS = Composition.values(); - } - - - /** - * If the leading byte of the flags contains a conditional bit, then it isn't actually the - * leading byte of the flags, and instead is an indicator that the conditional format is being - * used, possibly with more than one component of the same name. Specifically, if that leading - * byte has the CONDITIONAL_BIT set, then that byte is followed by a packed integer specifying - * the number of components of the same name, and for each component there is a packed integer - * for the conditional constant ID followed by the body of the component. (The children that go - * with the various conditional components occur in the stream after the last body.) - */ - public static final int CONDITIONAL_BIT = 0x80; - - public static final int ACCESS_MASK = 0x0300, ACCESS_SHIFT = 8; - public static final int ACCESS_PUBLIC = 0x0100; - public static final int ACCESS_PROTECTED = 0x0200; - public static final int ACCESS_PRIVATE = 0x0300; - public static final int ABSTRACT_BIT = 0x0400, ABSTRACT_SHIFT = 10; - public static final int STATIC_BIT = 0x0800, STATIC_SHIFT = 11; - public static final int SYNTHETIC_BIT = 0x1000, SYNTHETIC_SHIFT = 12; - public static final int COND_RET_BIT = 0x2000, COND_RET_SHIFT = 13; - public static final int AUXILIARY_BIT = 0x4000, AUXILIARY_SHIFT = 14; - - public boolean isStatic () { return (_nFlags & STATIC_BIT) != 0; } - public boolean isSynthetic() { return (_nFlags & SYNTHETIC_BIT) != 0; } - public boolean isAuxiliary() { return (_nFlags & AUXILIARY_BIT) != 0; } - public boolean isPublic () { return (_nFlags & ACCESS_MASK) == ACCESS_PUBLIC ; } - public boolean isPrivate () { return (_nFlags & ACCESS_MASK) == ACCESS_PRIVATE; } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/PropBuilder.java b/javatools_backend/src/main/java/org/xvm/xtc/PropBuilder.java deleted file mode 100644 index 4219fa7cdf..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/PropBuilder.java +++ /dev/null @@ -1,205 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xtc.ast.AST; -import org.xvm.xtc.ast.BlockAST; -import org.xvm.xtc.ast.ReturnAST; -import org.xvm.xtc.cons.Const; - -public abstract class PropBuilder { - - // Normal prop impl: - // private Type prop; - // Type prop$get() { return prop; } // Not final, can be overridden - // void prop$set(Type p) { prop=p; } - // - // Injection gets initialized from container: - // private Type prop = _container.prop(); // Container name and prop name matches - // - // Lazy: - // private boolean prop$init; - // Type prop$get() { if( !prop$init ) { prop$init=true; prop=prop$calc(); } return prop; } - // Type prop$calc() { ... } - // - // Const: - // void prop$set(Type p) { throw new ReadOnlyException(); } - // - // Fancier, e.g. marked Lazy, or has non-default get/set or other pieces: - // private Prop$Type prop = new Prop$Type(); - // // Calls are e.g. prop.$get() or prop.$set(p) - public static void make_class( ClzBuilder X, PropPart pp ) { - // Name is unique per-class, so if embedded in XTC method make it unique - // per java class. - String pname = jname(pp); - - XType xtype = XType.xtype(pp._con,false); - if( xtype instanceof XClz xclz ) - ClzBuilder.add_import(xclz); - boolean lazy=false,inject=false; - if( pp._contribs != null ) - for( Contrib c : pp._contribs ) { - String ano = c._annot.part()._name; - if( "Lazy".equals(ano) ) lazy = true; - if( "Inject".equals(ano) ) inject = true; - } - boolean stat = pp.isStatic() || pp._par instanceof ModPart; - boolean tfld = X._tclz.find(pname)!=null; // Is a type field - boolean pub = pp._access == Const.Access.PUBLIC || (pp._access==null && X._tclz.isa(XCons.CONST)); - boolean iface = X._tclz.iface(); - SB sb = X._sb; - - boolean do_def=true, do_get=true, do_set=true; - // Is this prop doing the *default* field definition, get, set? - // Only if no parent is doing the defaults. - if( isAlreadyDef(pp) ) - do_def = do_get = do_set = false; - - // No set on injections, lazy, or final(?) init - if( inject || pp._init != null || lazy ) do_set = false; - - // Interfaces do not get a field, but they do get getters and setters - if( iface ) do_def=false; - - // No set property on type parameters - if( tfld ) do_set = false; - - // If overriding some methods - if( pp._name2kid != null ) { - for( String meth : pp._name2kid.keySet() ) - switch( meth ) { - case "get" : do_get = true; do_def = do_set = false; break; - case "set" : do_set = true; break; - case "=" : do_set = false; break; // Another flavor of init flag - case "->" : assert lazy; do_set = false; break; - case "calc": assert lazy && do_get; break; - default: throw XEC.TODO(); - } - } - - if( do_def ) { - // Definition and init - sb.i(); // Not private, so child can reference - if( stat ) sb.p("static "); - (tfld ? sb.p("XTC") : xtype.clz(sb)).p(" ").p(pname); - // Special init for Inject. Other props get no init()? - if( inject ) - sb.fmt(" = %0.XEC.CONTAINER.get().%1()",XEC.ROOT,pname); - - // Explicit init via function - Part init; - if( pp._name2kid != null && (init=pp._name2kid.get("="))!=null ) { - sb.p(" = "); - MMethodPart mm = (MMethodPart)init; - MethodPart meth = (MethodPart)mm._name2kid.get("="); - ClzBuilder X2 = new ClzBuilder(X,null); - // Method has to be a no-args function, that is executed exactly once here. - // Inline instead. - AST ast = X2.ast(meth); - assert ast instanceof BlockAST blk && blk._kids.length==1 && blk._kids[0] instanceof ReturnAST && !blk.hasTemps(); - ast._kids[0]._kids[0].jcode(sb); - } - // Explicit init via constant - if( pp._init != null ) - sb.p(" = ").p(XValue.val(pp._init)); - sb.p(";\n"); - - // private boolean prop$init; - if( lazy ) - sb.ip("private boolean ").p(pname).p("$init;\n"); - } - - // Type prop$get() { return prop; } OR - // Type prop$get() { if( !prop$init ) { init=true; prop=prop$calc(); } return prop; } - if( do_get ) { - sb.i(); - if( stat ) sb.p("static "); - if( pub ) sb.p("public "); - if( iface ) sb.p("abstract "); - (tfld ? sb.p("XTC") : xtype.clz(sb)).fmt(" %0$get()",pname); - if( iface ) { - sb.p(";").nl(); - } else { - sb.p(" "); - - // Explicit get via function - Part get; - if( pp._name2kid != null && (get=pp._name2kid.get("get"))!=null ) { - MMethodPart mm = (MMethodPart)get; - MethodPart meth = (MethodPart)mm._name2kid.get("get"); - ClzBuilder X2 = new ClzBuilder(X,X._clz); - // Method has to be a no-args function, that is executed exactly once here. - X2.ast(meth).jcode(sb); - } else { - sb.p("{ "); - if( lazy ) - sb.fmt("if( !%0$init ) { %0$init=true; %0 = %0$calc(); } ",pname); - sb.fmt("return %0; }\n",pname); - } - } - } - - // No set property on type parameters - if( do_set ) { - - // Explicit set via function - Part set; - if( pp._name2kid != null && (set=pp._name2kid.get("set"))!=null ) { - MMethodPart mm = (MMethodPart)set; - MethodPart meth = (MethodPart)mm._name2kid.get("set"); - ClzBuilder X2 = new ClzBuilder(X,X._clz); - X2.jmethod(meth,"set"); - - } else { - // void prop$set(Type p) { prop=p; } - sb.i(); - if( stat ) sb.p("static "); - if( pub ) sb.p("public "); - if( iface ) sb.p("abstract "); - sb.fmt("void %0$set( ",pname); - xtype.clz(sb).p(" p )"); - if( iface ) { - sb.p(";").nl(); - } else { - sb.p(" { "); - boolean is_const = pp._par instanceof ClassPart pclz && pclz._f == Part.Format.CONST; - sb.p( is_const ? "throw new ReadOnlyException();" : pname + " = p;").p(" }").nl(); - } - } - } - - // Lazy calc - if( lazy ) { - String ncalc = "->"; - MMethodPart mm = (MMethodPart)pp._name2kid.get(ncalc); - if( mm==null ) - mm = (MMethodPart)pp._name2kid.get(ncalc ="calc"); - MethodPart meth = (MethodPart)mm._name2kid.get(ncalc); - ClzBuilder X2 = new ClzBuilder(X,X._clz); - X2.jmethod(meth,pname+"$calc"); - } - sb.nl(); - - } - - // Property is defined in some super class ? - private static boolean isAlreadyDef( PropPart pp ) { - Part p = pp._par; - while( p!=null && !(p instanceof ClassPart) ) - p = p._par; - while( p instanceof ClassPart cp ) { - if( p != pp._par && p._name2kid !=null && p._name2kid.containsKey( pp._name) ) - return true; - p = cp._super; - } - return false; - } - - - static String jname( PropPart pp ) { - String name = pp._par instanceof MethodPart meth ? meth._name+"$"+pp._name : pp._name; - // Mangle names colliding with java keywords - return ClzBuilder.jname(name); - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/PropPart.java b/javatools_backend/src/main/java/org/xvm/xtc/PropPart.java deleted file mode 100644 index dff962ec6e..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/PropPart.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xtc.cons.*; -import org.xvm.util.S; - -/** - Property part - A property is basically some state (a field in a class) and a getter and setter. - Also used for generic parameterized types: - "mixin NumberArray" - Here "Element" is a PropCon/PropPart - */ -public class PropPart extends Part { - public final Const.Access _access; - public TCon _con; - public Const _init; - public short _order; // Order of properties in sythentic methods for compares - - // A list of "extra" features about Properties - public final Contrib[] _contribs; - - PropPart( Part par, int nFlags, PropCon id, CondCon cond, CPool X ) { - super(par,nFlags,id,null,cond,X); - - // Read the contributions - _contribs = Contrib.xcontribs(_cslen,X); - - int nAccess = X.i8(); - _access = nAccess < 0 ? null : Const.Access.valueOf(nAccess); - _con = (TCon)X.xget(); - _init = X.xget(); - } - - @Override public Part child(String s) { - Part p = super.child(s); - if( p!=null ) return p; - assert _par instanceof ClassPart; - // Generic parameters are matched here, and re-do the lookup in the generic - // type parameter's base type. - TermTCon genttc = _con.is_generic(); - if( genttc!=null ) - return genttc.clz().child(s); - // Things like "get" and "set" - MMethodPart mm = new MMethodPart(this,s); - return mm.addNative(); - } - - @Override void link_innards( XEC.ModRepo repo ) { } - - // Terrible name. Means "this property is a Real(tm) Field", and it - // shows up in the default hashCode, equals, and compare. - public boolean isField() { - // No type fields - if( isAuxiliary() ) return false; - // No equals on static props - if( isStatic() ) return false; - // No equals on get-only properties - if( _name2kid != null && (_name2kid.containsKey("get") || _name2kid.containsKey("->")) ) - return false; - return true; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/RelPart.java b/javatools_backend/src/main/java/org/xvm/xtc/RelPart.java deleted file mode 100644 index e18347c100..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/RelPart.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.xvm.xtc; - -/** - Union or Interface composed interface Part - */ -public class RelPart extends ClassPart { - final Part _p1, _p2; - final Op _op; - public RelPart( Part p1, Part p2, Op op ) { - super(null,make_name(p1._name,p2._name),Part.Format.INTERFACE); - _p1 = p1; - _p2 = p2; - _op = op; - } - private static String make_name( String n1, String n2 ) { - if( n1.compareTo(n2) > 0 ) { String tmp = n1; n1 = n2; n2 = tmp; } - return "["+n1+","+n2+"]"; - } - - @Override Part search(String s, boolean into) { - Part c1 = _p1.child(s); - Part c2 = _p2.child(s); - return _op.search(c1,c2); - } - - public static enum Op { - // For a Union type, the result is one of the Union members - and the - // allowed set of fields we can use is limited to what is common across - // all members - i.e., the intersection. - Union { - @Override Part search(Part c1, Part c2) { - return c1==c2 ? c1 : null; // Must be in both - } - }, - // For an Intersection type, the result is all the Intersection members, - // all at the same time. This pretty much is limited to interfaces, or - // trivial parent/child classes. The allowed set of fields we can use is - // everything in both. - Intersect { - @Override Part search(Part c1, Part c2) { - return c1==null ? c2 : c1; // Must be in either - } - }, - Difference { - @Override Part search(Part c1, Part c2) { - return c1!=null && c2==null ? c1 : null; // Must be in first not 2nd - } - }; - abstract Part search(Part c1, Part c2); - }; -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/TDefPart.java b/javatools_backend/src/main/java/org/xvm/xtc/TDefPart.java deleted file mode 100644 index 5689ed594b..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/TDefPart.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xtc.cons.TCon; -import org.xvm.xtc.cons.TDefCon; -import org.xvm.xtc.cons.CondCon; - -/** - Type Definition part - */ -// TODO: Probably not a Part -public class TDefPart extends Part { - public final TCon _type; - TDefPart( Part par, int nFlags, TDefCon id, CondCon cond, CPool X ) { - super(par,nFlags,id,null,cond,X); - _type = (TCon)X.xget(); - } - - // Tok, kid-specific internal linking. - @Override void link_innards( XEC.ModRepo repo ) { - //_type.link(repo); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/VerTree.java b/javatools_backend/src/main/java/org/xvm/xtc/VerTree.java deleted file mode 100644 index 9e6acc9d0e..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/VerTree.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; - -/* A tree of version */ -public class VerTree { - void put( Version ver, boolean flag ) { - throw XEC.TODO(); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/Version.java b/javatools_backend/src/main/java/org/xvm/xtc/Version.java deleted file mode 100644 index ace4996269..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/Version.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.util.AryInt; - -/** - * Represents an Ecstasy module version. - */ -public class Version implements Comparable { - private static final String[] PREFIXS = {"CI", "Dev", "QC", "alpha", "beta", "rc"}; - - final protected String _s; - final protected int[] _ints; - final protected String _build; - - public Version( String s ) { - _s = s; - int len = s.length(), ix = 0; - AryInt ints = new AryInt(); - String build = null; - - // Parse Version numbers of the form "1.2.3.4" - while( ix < len && CPool.isDigit(s.charAt(ix)) ) { - int n = 0; - while( ix < len && CPool.isDigit(s.charAt(ix)) ) - n = n * 10 + (s.charAt(ix++) - '0'); - ints.push(n); - if( ix == len ) break; - if( s.charAt(ix) == '.' ) { ix++; continue; } - if( s.charAt(ix) == '-' ) { ix++; break; } - throw bad(s); - } - - // Prefix e.g. "-alpha" or "-rc", required to get the next parts - if( ix < len ) { - int old = ix; - for( int i=0; i - - Inner class CollectionImpl // has visible 3 type names: Element,Key,Value - - KeySet extends CollectionImpl - - - Here the "Key" is "HasherMap.Key" and is punning "CI.Element" - - KeySetFreezer mixins to KeySet - - - Here "Element" is a local name, - - - punning "KeySet.Key" thus "HasherMap.Key" AND "CI.Element" - - Tentative New Plan - - Class has self TNames, TVars only, no parents - - - Rename strat for self-names to parent is "aligned,null name for concrete" - - - Example: Base [Key /XTC , Value/XTC] - - - - then Derived [null /String, Value/XTC] - - - - then new Derived [null /String, null /Int] - - Sides: map Interface names to self type index - - - Example: IFace - - - - Base implements IFace - - - - Base.sides{ IFace -> [1,0] } // IFace.Elem maps to Base.type[1]/Value - - Mixin standard gets cloned into a full Class; - - Mixin conditional is Just Another Class with some code-gen rules on when to override - - Counter to New Plan: - - - Example: Base - - - Derived extends Base - - Tentative New Plan#B - - Class has a set of local tvars, which are either renames of parent or standalone - - - Inner class has all Outer directly (no rename, no subtype) - - - Need a rename strat - - All local tvars also have a type; this is a subtype of parent if renamed parent - - IFaces - perhaps can ignore tvars...???? xcc has confirmed ok - - Mixins are *just Classes*. Normal for conditional, custom-per-base for standard. - - 3 things per-type, so now kinda want Ary-of-Struct instead of Struct-of-Ary - - local name - - local type (subtype of parent, if any) - - super class map (or null if new here) - - */ - - -// XClz has a set of self-tvar-names in TNS, and a set of XTypes; a #of local -// TVars (length of _tns), a side mapping from interface XClz type -// indices into the XTS. - -// Example class def: -// Here E is a type variable. -// interface List { ... } // Has 1 TVar -// XClz: List:1{E/XTC} side[] -// Since List is interface, no concrete field for E - -// Example class usage with a concrete type, not a type-variable: -// class Nums implements List { ... } // Has ZERO TVars, and a mapping for List -// XClz: Nums:0{/Int} side[List=[0]]; -// Since Nums is concrete, no super, has concrete field for E - -//Example class usage: -// Name is valid in local scope and NOT in List's scope -// class MyList implements List { ... } -// XClz: MyList:1{Q/XTC}, side[List=[0]] -// Since MyList is concrete, no super, has concrete field for Q/E - -//Example class usage: -// Name and constraint are valid in local scope. -// class MyList implements List { ... } -// XClz: MyList:1{E/Hashable}, side[List=[0]] -// Since MyList is concrete, no super, has concrete field for Q/E - -//Example class usage: -// class CaseInsensitive implements Hasher { .... } -// XClz: Hasher:1{Value/XTC}, side[] -// XClz: CaseInsensitive:1{Value/String}, side[Hasher=[0]] -// Since CaseInsensitive is concrete, no super, has concrete field for String/Value - -//Example class usage: -// class HashSet implements HashMap { .... } -// XClz: HashMap:2{Key/Hashable,Value/XTC}, side[] -// XClz: HashSet:1{E/Hashable}, side[HashMap=[0,0]] -// Since HashSet is concrete, no super, has concrete field for Key/Value - -// Example class usage: -// class MyMap implements HashMap -// XClz: HashMap:2{Key/Hashable,Value/XTC}, side[] -// XClz: MyMap:3[A/XTC,B/XTC,C/Hashable,/String], side[HashMap=[2,3]] -// Since MyMap is concrete, no super, hash concrete field for Key/Value - -// Example class usage: -// class Super -// XClz: Super:1{E/XTC}, side[] -// Since Super is concrete, no super, has concrete field for E -// class Base extends Super -// XClz: Base:1{E/XTC}, side[Super=0] -// Since Base is concrete with Super and Super has field for E, no fields - -public class XClz extends XType { - static final String[] STR0 = new String[0]; - static final HashMap SIDES0 = new HashMap<>(); - - // The uniqueness is on these things: package, name, and all type parms. - public String _pack, _nest, _name; // Package name, nested class name, short name - public String[] _tns; // Type names, matching up to _xts, but might be short - public boolean _ro; // Read/Only type; set if super is set - // Other mappings for super and interface types. - // These map from a ClassPart to an array of local xts indices, one per ClassPart tname - HashMap _sides; - - // Not part of uniqueness, kept as a convenient cache. - public XClz _super; // Super xtype or null - public ModPart _mod; // Self module - public ClassPart _clz; // Self class, can be a module - public int _depth = -99; // Depth for LCA - public boolean _abstrct; // Abstract class - - // Java-name, if any there exists a Java mirror implementation. - // If the name is NOT equal to _pack,_name, then the name - // also directly encodes the parameter. - // Example: XTC Array vs Java Arychar - // XTC Array vs Java Arylong - public String _jpack, _jname; - - // This is a temporary field; set and cleared per-compilation unit. - // If true, in this compilation-unit use the fully qualified name - // to avoid a name conflict. - transient public boolean _ambiguous; - - // Bit for managing file-local code-gen - public boolean _did_gen; - - // Only for mixins, the conditional types - XType[] _mixts; - - // Private no-arg constructor, always use "make" for interning - private XClz() { _pack = "0xDEADBEEF"; } - - - // -------------------------------------------------------------------------- - // Interning: hash and compare the XClz-specific parts, check in the INTERN - // table, manage FREE, fill in based fields. - - // Free XClz to recycle - private static XClz FREE; - - // Using shallow equals & shallow hashCode, not deep, because the parts are already interned - @Override boolean eq(XType xt) { - XClz clz = (XClz)xt; - if( !(S.eq(_name, clz._name) && S.eq(_nest, clz._nest) && S.eq(_pack, clz._pack) && - _ro == clz._ro && - Arrays.equals(_tns, clz._tns ) && - _sides.size() == clz._sides.size() ) ) - return false; - // Deep array equals of a hash table. - for( XClz iclz : _sides.keySet() ) { - int[] idxs0 = _sides.get(iclz); - int[] idxs1 = clz._sides.get(iclz); - if( idxs1 == null ) return false; // Missing in other - if( !Arrays.equals(idxs0,idxs1) ) return false; - } - return true; - } - @Override int hash() { - int hash = _name.hashCode() ^ _nest.hashCode() ^ _pack.hashCode() ^ (_ro ? 2048 : 0); - for( String tname : _tns ) - hash ^= tname.hashCode(); - return hash; - } - - // Intern, but do not fill in the extra info fields. - XClz _intern() { - assert _pack != "0xDEADBEEF" && _sides!=null; // Got set - XClz clz = (XClz)intern(this); - if( clz!=this ) { FREE = this; _pack = "0xDEADBEEF"; } - return clz; - } - - // Intern and fill out a parameterized class from the prototype - XClz _intern( XClz proto ) { - // See if already exists - XClz clz = _intern(); - if( clz != this ) { - assert proto._super==clz._super && (proto._clz==clz._clz || clz._clz==null); - return clz; - } - assert _ro || (_super==null || !_super._ro); // Set if super is set - - _mod = proto._mod; - _clz = proto._clz; - _super = proto._super; - _jpack = proto._jpack; - _jname = proto._jname; - _depth = proto._depth; - return clz; - } - - // -------------------------------------------------------------------------- - - // Makes a new uninterned XCLZ. - // Fills in package,nesting,name,null-ness. - // Default R/W. - // Defaults not-a-java-mirror. - static XClz mallocBase( boolean notNull, String pack, String nest, String name ) { - XClz clz = FREE==null ? new XClz() : FREE; - if( clz==FREE ) FREE=null; - assert clz._pack == "0xDEADBEEF"; // Was from FREE list - - // These next fields are all part of uniqueness - clz._notNull = notNull; // Field in XType - // Class & package names. - clz._pack = pack; - clz._nest = nest; - clz._name = name; - // Default false, check if making R/O - clz._ro = false; - clz._jname = clz._jpack = ""; // So toString doesn't barf on half built XClz - return clz; - } - - // Makes a new uninterned XCLZ from above malloc. - // Fills in package,nesting,name,null-ness. - // Default R/W. - // Defaults not-a-java-mirror. - // Has blank xts/tns arrays ready to be filled in. - static XClz mallocLen( boolean notNull, String pack, String nest, String name, int len ) { - XClz clz = mallocBase(notNull,pack,nest,name); - // See if we can reuse the xts,flds - if( clz._xts==null || clz._xts.length != len ) clz._xts = len==0 ? EMPTY : new XType [len]; - if( clz._tns==null || clz._tns.length != len ) clz._tns = len==0 ? STR0 : new String[len]; - clz._sides = SIDES0; - return clz; - } - - // Makes a new uninterned XClz cloned from the prototype. - // SHARES xts/tns; so these need to be defensively copied before changing. - private XClz _mallocClone() { - XClz clz = mallocBase(_notNull,_pack, _nest, _name); - clz._xts = _xts; - clz._tns = _tns; - clz._sides = _sides; - clz._mod = _mod; - clz._clz = _clz; - return clz; - } - - // Nested names; usually blank - private static String _cnest(ClassPart clz) { - ModPart mod = clz.mod(); - return clz==mod || clz._par instanceof MethodPart meth || !mod._path.equals(clz._path) - ? "" - // Class embedded in a Module file; mangle name to avoid Module name. - // java name is always Module.M$Module.Class - : ("M$"+S.java_class_name(mod.name())).intern(); - } - - private static String _cname( ClassPart clz ) { - ModPart mod = clz.mod(); - String cname = S.java_class_name(clz._name); - // Module: java name is always Module.M$Module - if( clz==mod ) return ("M$"+cname).intern(); - if( clz._par instanceof MethodPart meth ) // Class nested inside a Method - // If the method is in a property, use that for a more unique mangled name - return S.java_class_name(meth._name+"$"+ - (meth._par._par instanceof PropPart prop ? prop._name : clz._name)); - // Normal case, just the class name - return cname; - } - - // "Normal" classes and modules come in here. - private static XClz _malloc( ClassPart clz ) { - return _malloc(clz, _cnest(clz), _cname(clz), get_super(clz)); - } - - // Common XClz constructor for most cases: passed in a bunch of fields - // which vary by the path we get here. - // Fills in common fields. Not interned yet. Handles all kinds of Contribs. - private static XClz _malloc( ClassPart clz, String cnest, String cname, XClz supr ) { - boolean abstrct = false; - assert supr!=null || get_super(clz)==null; - - // Make a basic XClz with space for type vars - ModPart mod = clz.mod(); - XClz xclz = mallocBase( true, pack(clz,mod), cnest, cname ); - xclz._clz = clz; - xclz._mod = mod; // Self module - xclz._jname = xclz._jpack = ""; - - // Fill in self type variables - XType [] xts = xclz._xts = new XType[clz._tnames==null ? 0 : clz._tnames.length]; - String[] tns = xclz._tns = clz._tnames==null ? STR0 : clz._tnames; - for( int i=0; i(); - for( XClz s : mixin._sides.keySet() ) - xclz._sides.put( s==supr ? mixin : s, mixin._sides.get(s) ); - supr = mixin; - - } else { - // Has parameters, so conditional incorporates; the Mixin overrides - // the Base. The Mixin class always exists and requires a runtime - // test to actually execute. - // Object <- Super <- Base <- Mixin <- Derived - // Finish xclz - xclz._super = supr; - xclz._depth = supr==null ? 0 : supr._depth+1; - xclz._abstrct = abstrct; - xclz = xclz._intern(); - // Recursively make mixin with custom name and super - String mixname = (cname+"$"+mixin0._name).intern(); - XClz mixin = _malloc(mixin0._clz,mixin0._nest,mixname,xclz); - mixin._mixts = mixin._xts; - mixin. _xts = xclz ._xts; - // Sides for mixin use xclz as the supr - mixin._sides = new HashMap<>(); - for( XClz s : xclz._sides.keySet() ) - mixin._sides.put( s==supr ? xclz : s, xclz._sides.get(s) ); - supr = xclz; - xclz = mixin; - } - break; - } - case Part.Composition.Extends: - assert clz._super != null; break; // Already picked up - case Part.Composition.Implements: break; // Normal interface. Maybe someday collect them here - case Part.Composition.Delegates: break; // TODO: Dunno what this is supposed to do - case Part.Composition.RebasesOnto: - case Part.Composition.Import: - case Part.Composition.Equal: - throw XEC.TODO(); // TODO - } - } - - xclz._super = supr; - xclz._depth = supr==null ? 0 : supr._depth+1; - xclz._abstrct = abstrct; - - return xclz; - } - - // Gather side types from Implements and Extends and Incorporates. - private void sides( ClassPart clz ) { - _sides = SIDES0; - if( clz==null || clz._contribs == null ) return; - - for( Contrib c : clz._contribs ) - if( c._comp == Part.Composition.Implements || c._comp == Part.Composition.Extends || c._comp == Part.Composition.Incorporates ) - switch( c._tContrib ) { - case TermTCon ttc: break; // no extra type params - case ImmutTCon imm when imm.icon() instanceof TermTCon ttc: break; - case ParamTCon ptc: _sides(ptc,_tns); break; - // No tvars here? - case InnerDepTCon dep: assert dep .clz()._tnames.length==0; break; - case VirtDepTCon virt: assert virt.clz()._tnames.length==0; break; - default: throw XEC.TODO(); // Expecting a PTC here - } - } - - private void sides( ParamTCon ptc, String[] tnames ) { - _sides = SIDES0; - _sides(ptc,tnames); - } - private void _sides( ParamTCon ptc, String[] tnames ) { - // Now I got some sides! - if( _sides == SIDES0 ) _sides = new HashMap<>(); - // Setup a side array from the base type to its parameterized version - XClz pclz = (XClz)xtype(ptc,true); - int[] idxs = new int[ptc._parms.length]; - // Walk the parameterized types; refer back to the class's types - for( int i=0; i { ... } - // XClz: List{E=XTC} - public static XClz make( ClassPart clz ) { - if( clz._tclz != null ) // Check class cache - return clz._tclz; - XClz xclz = _malloc(clz); - XClz xclz2 = xclz._intern(); - assert xclz2 == xclz; // Only intern XTC ClassPart once - clz._tclz = xclz; // Assign the class cache - return xclz; - } - - // Make from a parameterized class: like a - // normal class but the type parms from the PTC. - - // Example class usage with a concrete type, not a type-variable: - // class Nums extends List { ... } - // XClz: Nums{_=Int} - // No field name, since Int is a Type not a TypeVar - - //Example class usage: - // class MyList extends List { ... } - // XClz: MyList{Q=XTC} - // Name is valid in local scope and NOT in List's scope - - //Example class usage: - // class MyList extends List { ... } - // XClz: MyList{H=Hashable} - // Name and constraint are valid in local scope. - - public static XClz make( ParamTCon ptc ) { - // Get the UNparameterized class - ClassPart clz = ptc.clz(); - XClz proto = make(clz); - - // Very specifically, generic parameterized AryXTC means the - // un-element-typed Array, used to make both primitive arrays and - // Object arrays. - if( proto == XCons.ARRAY || proto == XCons.ARRAY_RO ) { - // A generified array needs to remain un-element-typed - if( ptc._parms[0] instanceof TermTCon ttc && ttc.id() instanceof TParmCon ) - return proto; - proto = proto._ro ? XCons.ARYXTC_RO : XCons.ARYXTC; - } - - assert proto._xts.length>0; - XClz xclz = proto._mallocClone(); - xclz._xts = proto._xts.clone(); - xclz._tns = proto._tns.clone(); - // Override parameterized type fields - if( ptc._parms != null ) - for( int i=0; i0; - XClz xclz = proto._mallocClone(); - xclz._xts = proto._xts.clone(); - xclz._tns = proto._tns.clone(); - // Override parameterized type fields - for( String tn : c._parms.keySet() ) { - int i = S.find(xclz._tns,tn); - xclz._xts[i] = xtype(c._parms.get(tn),true,xclz); - } - return xclz._intern(proto); - } - - - // Make a R/O version - public static XClz make( ImmutTCon imm ) { - if( imm.icon() instanceof TermTCon ttc ) { - XClz clz = make(ttc.clz()); - return clz.readOnly(); - } - throw XEC.TODO(); - } - - - // An inner class, which gets the outer class Type variables - public static XClz make( VirtDepTCon virt ) { - ClassPart iclz = virt.part(); // Inner clz - XClz xclz = make(iclz); // Inner xclz - XClz vclz = xclz._mallocClone(); // Inner xclz, cloned - vclz.sides((ParamTCon)virt._par,iclz._tnames); - - XClz vclz2 = vclz._intern(); - if( vclz2 != vclz ) return vclz2; - iclz._tclz = vclz; - return vclz; - } - - // Make a specialized Future type - public static XClz wrapFuture( XType xt ) { - ClzBuilder.add_import(XCons.FUTURE); - if( xt instanceof XClz clz ) ClzBuilder.add_import(clz); - XClz xclz = _malloc(XCons.FUTURE._clz); - xclz._tns = XCons.FUTURE._tns; - xclz._xts[0] = xt; - return xclz._intern(XCons.FUTURE); - } - - // You'd think the clz._super would be it, but not for enums - static XClz get_super( ClassPart clz ) { - if( clz==null ) return null; - if( clz._super!=null ) - return make(clz._super); - // The XTC Enum is a special interface, extending the XTC Const interface. - // They are implemented as normal Java classes, with Enum extending Const. - if( clz._path==null ) { assert clz._f==Part.Format.CLASS; return null; } - if( S.eq(clz._path._str,"ecstasy/Enum.x") ) return XCons.CONST; - // Other enums are flagged via the Part.Format and do not have the - // _super field set. - if( clz._f==Part.Format.CONST ) return XCons.CONST; - if( clz._f==Part.Format.ENUM ) return XCons.ENUM ; - if( clz._f==Part.Format.SERVICE ) return XCons.SERVICE; - // Special intercept for the Const "interface", which maps to the Java - // class (NOT interface) Const.java - if( S.eq(clz._path._str,"ecstasy/Const.x") ) return XCons.XXTC; - // Special intercept for the Service "interface", which maps to the Java - // class (NOT interface) Service.java - if( S.eq(clz._path._str,"ecstasy/Service.x") ) return XCons.XXTC; - return null; - } - - @Override public XClz nullable() { - if( !_notNull ) return this; - XClz clz = _mallocClone(); - clz._notNull = false; - return clz._intern(this); - } - @Override public XClz readOnly() { - if( _ro ) return this; - XClz clz = _mallocClone(); - clz._ro = true; - return clz._intern(this); - } - - @Override public boolean isTuple() { return S.eq(_jname,"Tuple"); } - // TODO: Really needs to be an ISA on XTC Var - @Override public boolean isVar() { return S.eq(_name,"Var") || S.eq(_jname,"Future"); } - // Some kind of array - @Override public boolean isAry() { return S.eq("ecstasy.collections",_pack) && S.eq("Array",_name); } - // XTC array element type - public XType e() { - assert isAry() || isVar(); - return _xts[0]; - } - public final boolean iface() { return _clz!=null && _clz._f==Part.Format.INTERFACE; } - // Is a mixin - public final boolean isMixin() { - return _clz._f==Part.Format.MIXIN; - } - - // Class & package names. - - // Example: tck_module (the module itself) - // _pack: "" - // _nest: "" - // _name: tck_module - - // Example: tck_module.comparison.Compare.AnyValue - // _pack: tck_module.comparison - // _nest: "" - // _name: Compare.AnyValue - - // Example: ecstasy.Enum - // _pack: ecstasy - // _nest: "" - // _name: Enum - - // Example: nQueens.Board - // _pack: nQueens - // _nest: M$nQueens - // _name: Board - - // Example: Collection.x, equals() method, enum NonExistent [NotAValue] - // _pack: ecstasy.collections - // _nest: "" - // _name: Collection.equals$NonExistent - // _name: Collection.equals$NonExistent.NotAValue - private static String pack(ClassPart pclz, ModPart mod) { - return _pack(pclz,mod.name()).intern(); - } - private static String _pack(Part pclz, String mod) { - // Observed "_par" grammar: - // File.Mod - Just the module directly, e.g. module tck - // File.Mod.Clz - stand-alone module, no package - // File.Mod.Pack.Clz - Part of a package deal, e.g. tck.array.Basic - // File.Mod.Pack.Clz.Clz - Nested class (or enum), e.g. ecstasy.collections.Array.ArrayDelegate - // File.Mod.Pack.Pack.Clz - Nested package , e.g. ecstasy.collections.deferred.DeferredCollection - // File.Mod.Pack.Clz.MMeth.Meth.Clz - Method-local class (or enum), e.g. tck.constructors.Basic.Test - // File.Mod.Pack.Clz.Prop.MMeth.Meth.Clz - Method-local class (or enum) as a property init - return switch( pclz._par ) { - case FilePart file -> mod; // e.g. module tck - case ModPart mod2 -> mod; // eg. module ecstasy - // case PackagePart pack; EXTENDS CLASSPART // e.g. ecstasy.collections.deferred - case ClassPart clz -> _pack(clz ,mod)+"."+clz._name; // e.g. ecstasy.collections.Array - case MethodPart meth -> _pack(meth._par,mod); // e.g. tck.constructors.Basic - case PropPart prop -> prop._name+"$"+_pack(prop,mod); - default -> { - for( Part p=pclz; p!=null; p = p._par ) - System.out.print(p.getClass().getSimpleName()+" "); - System.out.println(); - throw XEC.TODO(); - } - }; - } - - @Override public boolean needs_import(boolean self) { - // Built-ins before being 'set' have no clz, and do not needs_import - if( this==XCons.XXTC ) return false; - if( this==XCons.JTRUE ) return false; - if( this==XCons.JFALSE) return false; - if( this==XCons.JNULL ) return false; - if( this==XCons.JSTRING ) return false; - if( this==XCons.JSTRINGN ) return false; - // Everything in java.lang.* imports by default already - if( S.eq("java.lang",_jpack) ) return false; - // Self module is also compile module. - if( self && _clz == ClzBuilder.CCLZ ) return false; // Self does not need to import self - // No clz is reserved for Java builtins with no corresponding XTC class - // (e.g. RangeII). - return true; - } - // No java name means needs a build - public boolean needs_build() { return _jname.isEmpty(); } - - // Find a type name in the superclass chain - public XType find(String tname) { - XClz clz = this; - for( ; clz!=null; clz = clz._super ) { - int idx = S.find(clz._tns,tname); - if( idx!= -1 ) - return clz._xts[idx]; - } - return null; - } - - // Local only find - public XType _find(String tn) { - int idx = S.find(_tns,tn); - return idx == -1 ? null : _xts[idx]; - } - - // Prints/passes the type parameters. - // Other than the java mirrors with types, always: - // Map ... new Map(Key.GOLD,Value.GOLD,....) - // AryXTC yes also: - // AryXTC ... new Ary(Person.GOLD,....) - // Other arrays or mirrors include the class name in the base java name: - // Arylong ... new Arylong(...); // As opposed to: Arylong or AryXTC - // Appenderchar ... new Appenderchar(); // As opposed to: Appendchar or Appender - // Tuples include type names in the printed version but not the XClz version - // Tuple2$long$long // As opposed to Tuple2$long$long - public boolean printsTypeParm() { - return _jname.isEmpty() || // Not a java mirror - S.eq(_jname,"AryXTC") || // The one typed mirror needing an explicit type - (S.eq(_jname,_name) && // Java mirror and name does not include type - !S.eq(_jname,"Tuple") ); // Tuples with types and not generics - } - - @Override public SB str( SB sb, VBitSet visit, VBitSet dups ) { - _clz_bare(sb,false); - if( _super!=null ) sb.p(":").p(_super._name); - if( _tns != null && _tns.length > 0 ) { - sb.p(" {"); - for( int i = 0; i< _tns.length; i++ ) { - sb.p(" "); - if( _tns[i]!=null ) sb.p( _tns[i]); - sb.p(":"); - if( _xts[i] != null ) _xts[i]._str(sb,visit,dups); - sb.p(";"); - } - sb.p("}"); - } - if( !_notNull ) sb.p("?"); - return sb; - } - - - // Bare name, no generics - public String clz_bare( ) { return _clz_bare(new SB(),false).toString(); } - @Override public SB clz_bare( SB sb ) { return _clz_bare(sb,true); } - private SB _clz_bare( SB sb, boolean imprt ) { - // These guys need a fully qualified name to avoid name conflicts - if( this==XCons.JSTRING || this==XCons.JSTRINGN || this==XCons.JOBJECT || _ambiguous ) - return sb.p(qualified_name()); - // Nested class in other module? - if( _clz!=null && _clz._par.getClass() == ClassPart.class && - _clz._par != ClzBuilder.CCLZ ) - return sb.p(qualified_name()); - if( imprt ) ClzBuilder.add_import(this); - // Tuples have a mangled class name without generics - if( isTuple() ) return strTuple(sb); - return sb.p(name()); - } - - // Walk and print Java class name, including generics. If XTC is providing - // e.g. method-specific generic names, use them instead. Using "T" here - // instead of "XTC": " void bar( T gold, AryXTC ary )" - @Override SB _clz( SB sb, ParamTCon ptc ) { - _clz_bare(sb,false); - - // Print generic parameters? - if( _tns.length==0 ) return sb; // None to print - if( !printsTypeParm() ) return sb; // Java mirror encodes the generic type name already - - // Printing generic type parameters - sb.p("<"); - for( int i=0; i<_tns.length; i++ ) { - // No ParamTCon provided, using the generic class as-is - if( ptc==null ) _xts[i]._clz(sb,null); - // ParamTCon has a different name, it's not a type, it's a generic name. - else if( ptc._parms[i] instanceof TermTCon ttc && ttc.part() instanceof ParmPart parm ) - sb.p("$").p(parm._name); - // Structurally recurse - else _xts[i].clz(sb); - sb.p(","); - } - return sb.unchar().p(">"); - } - - public String name( ) { return _jname.isEmpty() ? _name : _jname; } - public String pack( ) { return _jpack.isEmpty() ? _pack : _jpack; } - - // Module: Lib as org.xv.xec.X$Lib - // Class : tck_module.comparison.Compare.AnyValue as org.xv.xec.tck_module.comparison.Compare.AnyValue - public String qualified_name() { - if( S.eq(_jpack,"java.lang") ) - return "java.lang."+_jname; - String name = name(); - if( isTuple() ) name = strTuple(new SB()).toString(); - String pack = pack().isEmpty() ? "" : "."+pack(); - String nest = _nest .isEmpty() ? "" : "."+_nest ; - return (XEC.XCLZ + pack + nest + "." + name).intern(); - } - - // "Foo" - public SB clz_generic_def( SB sb ) { - // No named type arguments - if( _tns.length==0 ) return sb; - - sb.p("< "); - for( int i=0; i<_tns.length; i++ ) { - sb.p("$").p( _tns[i]); - sb.p(" extends " ); - XClz xclz = (XClz)_xts[i]; - if( xclz.iface() ) { - sb.p("XTC & "); - sb.p(xclz.name()); - } else { - sb.p(xclz.clz()); - xclz.clz_generic_def(sb); - } - sb.p(", "); - } - return sb.unchar(2).p("> "); - } - // "Map" - public SB clz_generic_use( SB sb, XClz base ) { - assert !_ambiguous; - // No named type arguments - int[] idxs = base._sides.get(this); - if( idxs==null ) return sb; - sb.p("<"); - for( int idx : idxs ) - if( idx < base._tns.length ) sb.p("$").p(base._tns[idx]).p(", "); - else base._xts[idx].clz_bare(sb).p(", "); - return sb.unchar(2).p("> "); - } - - private SB strTuple( SB sb ) { - sb.p("Tuple").p(_xts.length).p("$"); - for( XType xt : _xts ) - xt.clz_bare(sb).p("$"); - return sb.unchar(); - } - - - // ------------------------------------------------------------------------- - // Does 'this' subclass 'sup' ? - private boolean subClasses( XClz sup ) { - if( _clz==sup._clz ) return true; - if( _super==null ) return false; - return _super.subClasses(sup); - } - - private boolean subIFaces( XClz iface ) { - if( isIFace(iface) ) return true; - return _super != null && _super.subIFaces( iface ); - } - // No chasing class super, yes chasing IFace super - private boolean isIFace( XClz iface ) { - if( _clz!=null && _clz._contribs!=null ) - for( Contrib c : _clz._contribs ) - if( c._comp == Part.Composition.Implements ) { - XClz iclz = (XClz)xtype(c._tContrib, false); - if( iclz == iface || iclz.isIFace(iface) ) - return true; - } - return false; - } - - @Override boolean _isa( XType xt ) { - XClz clz = (XClz)xt; // Contract - if( xt == XCons.XXTC ) return true; // Everything isa XTC - // Interface or subclass check. Const, Service are declared interface in - // XTC but declared a Class in Java. - if( !iface() && clz.iface() && clz != XCons.CONST && clz != XCons.SERVICE ) - return subIFaces(clz); - // Check basic subclassing. Two classes or two interfaces come here. - if( !subClasses(clz) ) return false; - if( _xts.length < clz._xts.length ) return false; - // Now check pieces-parts - for( int i=0; i XBOX = new HashMap<>() {{ - put(NULL ,JNULL ); - put(BOOL ,JBOOL ); - put(BYTE ,JBYTE ); - put(CHAR ,JCHAR ); - put(SHORT,JINT16); - put(INT, JINT32); - put(LONG ,JLONG ); - put(DOUBLE,JDOUBLE); - put(TRUE ,JTRUE ); - put(FALSE,JFALSE); - put(STRING,JSTRING); - put(STRINGN,JSTRINGN); - }}; - // Convert a Java wrapped primitive to the unwrapped primitive - static final HashMap UNBOX = new HashMap<>() {{ - put(JNULL ,NULL ); - put(JBOOL ,BOOL ); - put(JBYTE ,BYTE ); - put(JCHAR ,CHAR ); - put(JINT16,SHORT); - put(JUINT8 ,LONG); - put(JUINT16,LONG); - put(JUINT32,LONG); - put(JINT32,INT ); - put(JDOUBLE,DOUBLE); - put(JLONG ,LONG ); - put(JTRUE ,TRUE ); - put(JFALSE,FALSE); - put(JSTRING,STRING); - }}; - - // Generic array; element type is unknown, and could be primitives or Java Object. - public static XClz ARRAY = make_java("ecstasy.collections","Array","ecstasy.collections","Array",null,"Element",VOID); - public static XClz ARRAY_RO = ARRAY.readOnly(); - // Generic Java Object[], this maps to the ecstasy.collections.Array class - public static XClz ARYXTC = make_java_ary("AryXTC",XXTC ); - public static XClz ARYXTC_RO= ARYXTC.readOnly(); - // Java primitive arrays - public static XClz ARYBOOL = make_java_ary("Aryboolean",JBOOL ); - public static XClz ARYCHAR = make_java_ary("Arychar" ,JCHAR ); - public static XClz ARYSTRING= make_java_ary("AryString" ,JSTRING); - public static XClz ARYINT = make_java_ary("Aryint" ,JINT32 ); - public static XClz ARYLONG = make_java_ary("Arylong" ,JLONG ); - public static XClz ARYUBYTE = make_java_ary("AryUInt8" ,JUINT8 ); - - // Type sig for Iterator, which returns a non-XTC type "Iteratorlong" - // which supports a "long next8()" as well as the expected "Int64 next()". - // No corresponding XTC class. - public static XClz ITERATORLONG = make_java("ecstasy.collections.Arylong", "Iterlong", "ecstasy","Iterator",null,"Element",JLONG ); - public static XClz ITERATORINT = make_java("ecstasy.collections.Aryint", "Iterint", "ecstasy","Iterator",null,"Element",JINT32 ); - public static XClz ITERSTR = make_java("ecstasy.collections.AryString", "IterString","ecstasy","Iterator",null,"Element",JSTRING); - public static XClz ITERATORCHAR = make_java("ecstasy", "Iterator", "ecstasy","Iterator",null,"Element",CHAR ); - - // These are always expanded to some Java constant - public static XClz INTLITERAL = make_java("ecstasy.numbers","IntLiteral","ecstasy.numbers","IntLiteral",CONST); - public static XClz FPLITERAL = make_java("ecstasy.numbers", "FPLiteral","ecstasy.numbers", "FPLiteral",CONST); - - - public static XClz MAP = make_java("ecstasy.collections","Map","ecstasy.collections","Map",null,"Key",XXTC,"Value",XXTC); - - // Some tuples - public static XClz TUPLE0 = make_tuple(); - public static XClz COND_CHAR = make_tuple(BOOL,CHAR); - - - - private static final XClz[] XCLZS = new XClz[] { - null, // IntLiteral - null, // Bit - null, // Nybble - JBYTE , - JINT16 , - JINT32 , - JLONG , - JINT128 , - JINTN , - null, - JUINT16 , - JUINT32 , - JUINT64 , - JUINT128, - JUINTN , - }; - public static XClz format_clz(Const.Format f) { return XCLZS[f.ordinal()]; } - private static final boolean[] IPRIMS = new boolean[] { - false, // IntLiteral - false, // Bit - false, // Nybble - true , // i8 - true , // i16 - true , // i32 - true , // i64 - false, // i128 - false, // BigInteger - true , // u8 - true , // u16 - true , // u32 - true , // u64 - false, // u128 - false, // UBigInteger - }; - public static boolean format_iprims(Const.Format f) { return IPRIMS[f.ordinal()]; } - - - - // Made from a Java class directly; the XTC class shows up later. - // Fields are hand-added and need to match the ClazzPart later. - static XClz make_java( String pack, String name, XClz supr ) { - return _make_java(pack,name,pack,name,supr,XClz.SIDES0,XClz.STR0,XType.EMPTY); - } - - // Specify string/XTC for xts/tns. - static XClz make_java( String jpack, String jname, String pack, String name, XClz supr ) { - return _make_java(jpack,jname,pack,name,supr,XClz.SIDES0,XClz.STR0,XType.EMPTY); - } - static XClz make_java( String jpack, String jname, String pack, String name, XClz supr, String tvar, XType xt ) { - assert tvar!=null; - assert xt !=null; - return _make_java(jpack,jname,pack,name,supr,XClz.SIDES0,new String[]{tvar},new XType[]{xt}); - } - static XClz make_java( String jpack, String jname, String pack, String name, XClz supr, String tvar0, XClz xt0, String tvar1, XClz xt1 ) { - return _make_java(jpack,jname,pack,name,supr,XClz.SIDES0,new String[]{tvar0,tvar1},new XType[]{xt0,xt1}); - } - static XClz make_java( String jpack, String jname, String pack, String name, XClz supr, XClz side_clz, XClz tvar_clz ) { - return _make_java(jpack,jname,pack,name,supr,new HashMap<>(){{put(side_clz,new int[]{0});}},new String[0],new XType[]{tvar_clz}); - } - - private static XClz _make_java( String jpack, String jname, String pack, String name, XClz supr, HashMap sides, String[] tns, XType[] xts ) { - XClz clz = XClz.mallocBase(true, pack,"",name); - clz._jpack = jpack; - clz._jname = jname; - clz._xts = xts; - clz._tns = tns; - clz._sides = sides; - // XXTC root XClz has no XTC _clz - if( pack.isEmpty() && S.eq(name,"XTC") ) { - clz._depth = 0; - return clz._intern(); - } - - // Walk the XTC REPO in parallel to parsing, and find the matching XTC class - String[] packs = pack.split("\\."); - assert packs[0].equals("ecstasy"); - ClassPart pclz = XEC.ECSTASY; - for( int i=1; i(){{put(XCons.ARRAY,new int[]{0});}}; - XClz clz2 = clz._intern(XCons.ARRAY); - assert clz==clz2; - clz._jname = jname; - return clz; - } - - - public static XClz make_tuple( XType... clzs ) { - XClz clz = XClz.mallocLen(true,"ecstasy.collections","","Tuple",clzs.length); - clz._tns = new String[clzs.length]; - for( int i=0; i 1 ) sb.unchar(2); - sb.p(" -> "); - if( _cond ) sb.p("!"); - return _xts[0].str(sb,visit,dups).p(" }"); - } - - @Override SB _clz( SB sb, ParamTCon ptc ) { - if( ptc != null ) { - XClz xargs = (XClz)xtype(ptc._parms[0],true); - if( xargs._xts.length!=nargs() ) throw XEC.TODO(); - } - sb.p("Fun").p(nargs()); - for( int i=1; i<_xts.length; i++ ) { - if( _xts[i]==XCons.JSTRING ) sb.p("XString$"); - else _xts[i].clz_bare(sb).p("$"); - } - if( _cond ) throw XEC.TODO(); // Hack name to include $COND - return sb.unchar(); - } - - // Using shallow equals&hashCode, not deep, because the parts are already interned - @Override boolean eq(XType xt) { return _cond==((XFun)xt)._cond; } - @Override int hash() { return _cond ? 512 : 0; } - @Override boolean _isa( XType xt ) { - XFun fun = (XFun)xt; // Invariant - if( _xts.length != fun._xts.length ) return false; - for( int i=1; i<_xts.length; i++ ) - if( !_xts[i].isa(fun._xts[i]) ) - return false; - // TODO: Need to check covariant returns? - return true; - } - - // Make a callable interface with a particular signature - public XFun make_class( ) { - String tclz = clz(); - String qual = (XEC.XCLZ+"."+tclz).intern(); - ClzBuilder.add_import(qual); - if( ClzBldSet.find(qual) ) - return this; - // The no-arg-no-ret version already exists, essentially a Java "Callable" - if( _xts.length==0 ) return this; - - - /* Gotta build one. Looks like: - interface Fun2$long$String { - long call(long l, String s); - } - */ - SB sb = new SB(); - sb.p("// ---------------------------------------------------------------").nl(); - sb.p("// Auto Generated by XFun from ").p(tclz).nl().nl(); - sb.p("package ").p(XEC.XCLZ).p(";").nl().nl(); - makeImports(sb); - sb.p("public interface ").p(tclz).p(" {").nl().ii(); - sb.ip("abstract "); - // Return - ret().clz(sb); - sb.p(" call( "); - int nargs = nargs(); - if( nargs>0 ) - for( int i=0; i INTERN = new HashMap<>(); - static final XType[] EMPTY = new XType[0]; - - private static int CNT=1; - final int _uid = CNT++; // Unique id, for cycle printing - - // Children, if any - public XType[] _xts; - - // Must a field be initialized not-null? - // Primitives are always "nullable" even when 0. - // XBase.STRING is not-nullable, despite being a XBase. - // XClzs go both ways, depends on if they got unioned with Null or not. - public boolean _notNull; - - // Interning support - static XType intern( XType free ) { - free._hash = 0; - XType jt = INTERN.get(free); - if( jt!=null ) return jt; - INTERN.put(jt=free,free); - return jt; - } - - // -------------------------------------------------------------------------- - - // Fancy print, handling cycles and dups. Suitable for the debugger. - @Override public final String toString() { - // Collect dups and a visit bit - VBitSet visit = new VBitSet(), dups = new VBitSet(); - _dups(visit,dups); - return _str(new SB(),visit.clr(),dups ).toString(); - } - // Non-fancy print. Dies on cycles and dups. Suitable for flat or simple types. - public SB str( SB sb ) { return str(sb,null,null); } - - private void _dups(VBitSet visit, VBitSet dups) { - if( visit.tset(_uid) ) - dups.set(_uid); - else if( _xts!=null ) - for( XType xt : _xts ) - if( xt != null ) - xt._dups(visit,dups); - } - - // Default fancy print, stops at cycles and dups - public SB _str( SB sb, VBitSet visit, VBitSet dups ) { - if( dups!=null && dups.test(_uid) ) { - sb.p("V").p(_uid); - if( visit.tset(_uid) ) return sb; - sb.p(":"); - } - return str(sb,visit,dups); - } - - // Internal specialized print, given dups and string/class flag - abstract SB str( SB sb, VBitSet visit, VBitSet dups ); - - // Alternative Class flavored fancy print - public final String clz() { return _clz(new SB(),null).toString(); } - public final SB clz( SB sb ) { return _clz(sb,null); } - public final SB clz( SB sb, ParamTCon ptc ) { return _clz(sb,ptc); } - public SB clz_bare( SB sb ) { return _clz(sb,null); } - abstract SB _clz( SB sb, ParamTCon ptc ); - - // -------------------------------------------------------------------------- - - public boolean needs_import(boolean self) { return false; } - - public void makeImports( SB sb ) { - HashSet imports = new HashSet<>(); - _makeImports(sb,imports); - sb.nl(); - } - void _makeImports( SB sb, HashSet imports ) { - if( _xts==null ) return; - for( XType xt : _xts ) { - XClz box = xt.box(); - if( box!=null && box.needs_import(false) ) { - String tqual = box.qualified_name(); - if( !imports.contains(tqual) ) { - imports.add(tqual); - sb.fmt("import %0;\n",tqual); - box._makeImports(sb,imports); - } - } - } - } - - - abstract boolean eq( XType xt ); // Subclass specialized eq check - @Override public final boolean equals(Object o) { - if( this==o ) return true; - if( this.getClass() != o.getClass() ) return false; - XType xt = (XType)o; - return _notNull == xt._notNull && - Arrays.equals(_xts,xt._xts) && - eq(xt); - } - - private int _hash; // Hash cache, never 0 - abstract int hash(); // Subclass hash - @Override final public int hashCode() { - if( _hash!=0 ) return _hash; - long hash = hash() ^ (_notNull ? 1024 : 0); - if( _xts!=null ) - for( XType xt : _xts ) - hash = (hash<<25) | (hash>>>(64-25)) ^ xt._uid; - int ihash = (int)(hash ^ (hash>>>32)); - if( ihash==0 ) ihash = 0xdeadbeef; - return (_hash=ihash); - } - - // -------------------------------------------------------------------------- - // Get the boxed version of self - public XClz box() { - if( this instanceof XClz clz ) return clz; - return XBOX.get(this); - } - // Get the unboxed version of self. If this==unbox() then either this is - // already an unboxed primitive, or no unboxed version exits (this is a ref). - // If this!=unbox() then the unbox() version is a primitive of this. - public XType unbox() { - XBase jt = UNBOX.get(this); - return jt==null ? this : jt; - } - public boolean isUnboxed() { return XBOX.containsKey(this); } - public XType box( boolean boxed ) { - return boxed ? this : unbox(); - } - - public XType nullable() { - if( !_notNull ) return this; - throw XEC.TODO(); - } - - static String xjkey(ClassPart clz) { return clz._name + "+" + clz._path._str; } - public boolean primeq() { return XBOX.containsKey(this); } - public boolean zero() { return primeq() && this!=STRING && this!=STRINGN && this!=TRUE && this!=FALSE; } - public String ztype() { return zero() ? "0" : "null"; } - public boolean is_jdk() { return primeq() || this==JNULL; } - - // Either "==name" or ".equals(name)" - public SB do_eq(SB sb, String name) { - return sb.fmt(zero() ? "==%0" : ".equals(%0)", name); - } - - public final boolean isa( XType xt ) { - return this==xt - || (getClass() == xt.getClass() && _isa(xt)) - || (this==XCons.NULL && !xt._notNull); - } - abstract boolean _isa( XType xt ); - public boolean isVar() { return false; } - - public boolean isAry() { return false; } - public boolean isTuple() { return false; } - public XType e() { throw XEC.TODO(); } - - public XType readOnly() { throw XEC.TODO(); } - public boolean isBool() { - return - this==JBOOL || this==BOOL || - this==JTRUE || this==TRUE || - this==JFALSE || this==FALSE; - } - - // -------------------------------------------------------------------------- - - - // Convert an array of Const to an array of XType - public static XType[] xtypes( Const[] cons ) { return xtypes(cons,false); } - public static XType[] xtypes( Const[] cons, boolean box ) { - if( cons==null ) return null; - XType[] xts = new XType[cons.length]; - for( int i=0; i - switch( ttc.part() ) { - case ClassPart clz -> { - if( clz._path !=null && S.eq(clz._path._str,"ecstasy/Object.x") ) - yield XCons.XXTC; - if( S.eq("Null",clz._name) ) - yield XCons.NULL; // Primitive null - XClz xclz = XClz.make(clz); - if( ttc.id() instanceof FormalTChildCon ftcc ) - yield xclz.find(ftcc._name); - yield boxed ? xclz.box() : xclz.unbox(); - } - - case ParmPart parm -> { - if( ttc.id() instanceof TParmCon tpc ) { - // Generic parameter name - yield xtype(parm.parm().tcon(),boxed,self); - } else if( ttc.id() instanceof DynFormalCon dfc ) { - // Generic parameter name - String dynt = ((TermTCon)((ParamTCon)dfc.type())._parms[0]).name(); - yield XBase.make("$"+dynt,true); - } else - throw XEC.TODO(); - } - - // Hidden extra XTC type argument (GOLD instance of the class whose hash - // implementation to use) - case PropPart prop -> xtype(prop._con,false,self); - - case null -> - throw XEC.TODO(); - - default -> throw XEC.TODO(); - }; - - case ParamTCon ptc -> { - ClassPart clz = ptc.clz(); - - // These XTC classes are all intercepted and directly implemented in Java - if( clz._name.equals("Array") && clz._path._str.equals("ecstasy/collections/Array.x") ) - yield XClz.make(ptc); - - if( clz._name.equals("Map") && clz._path._str.equals("ecstasy/maps/Map.x") ) - yield XClz.make(ptc); - - if( clz._name.equals("Function") && clz._path._str.equals("ecstasy/reflect/Function.x") ) { - Const[] args = ((ParamTCon)ptc._parms[0])._parms; - Const[] rets = ((ParamTCon)ptc._parms[1])._parms; - yield XFun.make(null,false,xtypes(args,boxed),xtypes(rets,boxed)).make_class(); - } - - XType telem = ptc._parms==null ? null : xtype(ptc._parms[0],true,self); - - // All the long-based ranges, intervals and iterators are just Ranges now. - if( clz._name.equals("Range" ) && clz._path._str.equals("ecstasy/Range.x" ) || - clz._name.equals("Interval") && clz._path._str.equals("ecstasy/Interval.x") ) { - if( telem== JLONG ) - yield RANGE; // Shortcut class - yield XClz.make(ptc); - } - - if( clz._name.equals("Iterator") && clz._path._str.equals("ecstasy/Iterator.x") ) - yield XClz.make(ptc); - if( clz._name.equals("Iterable") && clz._path._str.equals("ecstasy/Iterable.x") ) - yield XClz.make(ptc); - - if( clz._name.equals("Tuple") && clz._path._str.equals("ecstasy/collections/Tuple.x") ) { - int N = ptc._parms==null ? 0 : ptc._parms.length; - XType[] clzs = new XType[N]; - for( int i=0; i - xtype(itc.icon(),boxed,self).readOnly(); - - // Generalized union types gonna wait awhile. - // Right now, allow null unions only - case UnionTCon utc -> { - XType u2 = xtype(utc._con2,false,self); - if( !(utc._con1 instanceof TermTCon tcon) ) - yield XCons.XXTC; // Not a union+null, bail out - ClassPart clz1 = tcon.clz(); - if( clz1 !=null && clz1._name.equals("Nullable") ) - yield (u2.zero() ? u2.box() : u2).nullable(); - XType u1 = xtype(utc._con1,true,self); - if( u2 instanceof XFun ) u2 = XCons.XXTC; // Union of functions just goes to XTC for now - yield XClz.lca((XClz)u1, u2.box()); - } - - // Generalized union types gonna wait awhile. - // Right now, allow null unions only - case InterTCon utc -> { - XType u2 = xtype(utc._con2,false,self); - XType u1 = xtype(utc._con1,false,self); - yield XInter.make(u1,u2); - } - - case IntCon itc -> XCons.format_clz(itc._f).box(boxed); - case CharCon cc -> JCHAR.box(boxed); - case ByteCon cc -> JBYTE.box(boxed); - case Flt64Con fc -> JDOUBLE.box(boxed); - case Flt32Con fc -> JFLOAT.box(boxed); - - case StringCon sc -> STRING; - - case EnumCon econ -> { - // The enum instance as a ClassPart - ClassPart eclz = (ClassPart)econ.part(); - // The Enum class itself, not the enum - XClz xclz = XClz.make(eclz._super); - // The enum - yield xclz.unbox(); - } - - case LitCon lit -> { - if( lit._f==Const.Format.IntLiteral ) - yield XCons.INTLITERAL; - throw XEC.TODO(); - } - - case AryCon ac -> - xtype(ac.type(),false,self); - case MapCon mc -> - xtype(mc.type(),false,self); - - case MethodCon mcon -> - ((MethodPart)mcon.part()).xfun(); - - case FormalTChildCon ftcc -> - ftcc.clz()._tclz.find(ftcc._name); - - // Property constant - case PropCon prop -> - xtype(((PropPart)prop.part())._con,false,self); - - case SingleCon con0 -> { - if( con0.part() instanceof ModPart mod ) - yield XClz.make(mod); - if( con0.part() instanceof PropPart prop ) - yield XBase.make(PropBuilder.jname(prop),false); - if( con0.part() instanceof ClassPart clz ) - yield XClz.make(clz); - throw XEC.TODO(); - } - - case Dec64Con dcon -> DEC64; - - case Dec128Con dcon -> DEC128; - - case ClassCon ccon -> XClz.make(ccon.clz()); - case AnonClzTCon anon -> XClz.make(anon.clz()); - - case ServiceTCon service -> XCons.SERVICE; - - case VirtDepTCon virt -> XClz.make(virt); - - case AnnotTCon acon -> - switch( acon.clz()._name ) { - case "Inject" -> xtype(acon.con().is_generic(),true,self); - case "Future" -> - XClz.wrapFuture(xtype(((ParamTCon)acon.con())._parms[0],true,self)); - case "Volatile" -> - xtype(acon.con(),false,self); - default -> throw XEC.TODO(); - }; - - case AccessTCon acon -> - xtype(acon._con,boxed,self); - - // Self recursive type - case TSeqTCon tseq -> { - assert self!=null; - yield self; - } - - case InnerDepTCon inn -> xtype(inn._child,boxed,self); - - // A conditional mixin class with perhaps several generic types, - // but one with no constraints lands here. e.g. ListMapIndex - case null -> XCons.XXTC; - default -> throw XEC.TODO(); - }; - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/XValue.java b/javatools_backend/src/main/java/org/xvm/xtc/XValue.java deleted file mode 100644 index 60107fe89d..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/XValue.java +++ /dev/null @@ -1,242 +0,0 @@ -package org.xvm.xtc; - -import org.xvm.XEC; -import org.xvm.xrun.NativeTimer; -import org.xvm.xtc.cons.*; -import org.xvm.util.S; -import org.xvm.util.SB; - -import java.math.BigInteger; - -// Concrete java values from XTC values. -public abstract class XValue { - // Produce a java value from a TCon - private static final SB ASB = new SB(); - static public String val( Const tc ) { - assert ASB.len()==0; - // Caller is a switch, will encode special - if( tc instanceof MatchAnyCon ) return null; - _val(tc); - String rez = ASB.toString(); - ASB.clear(); - return rez; - } - private static SB _val( Const tc ) { - return switch( tc ) { - // Integer constants in XTC are Java Longs - case IntCon ic -> { - if( ic._f==Const.Format.Int128 ) { - ASB.p("Int128.construct("); - if( ic._big != null ) { - long lo = ic._big.longValue(); - BigInteger big = ic._big.shiftRight(64); - long hi = big.longValueExact(); - ASB.p(lo).p("L,").p(hi).p("L"); - } - else ASB.p(ic._x).p("L"); - yield ASB.p(")"); - } - if( ic._big != null ) throw XEC.TODO(); - yield ASB.p(ic._x).p('L'); - } - case Flt64Con fc -> ASB.p(fc._flt); - case Flt32Con fc -> ASB.p(fc._flt); - - // Character constant - case CharCon cc -> - cc._x=='\n' ? ASB.p("'\\n'") : ASB.p('\'').p((char)cc._x).p('\''); - case ByteCon bc -> - ASB.p(bc._x); - - // String constants - case StringCon sc -> - ASB.quote(sc._str); - - // Literal constants - case LitCon lit -> { - if( lit._f==Const.Format.IntLiteral ) { - ClzBuilder.add_import(XEC.XCLZ+".ecstasy.numbers.IntLiteral"); - yield ASB.p("IntLiteral.construct(\"").p(lit._str).p("\")"); - } - yield ASB.quote(lit._str); - } - - // Method constants - case MethodCon mcon -> { - MethodPart meth = (MethodPart)mcon.part(); - // Lambda names "->" are inlined as Java lambdas - String name = ClzBuilder.jname(meth._name); - if( meth._par._par instanceof MethodPart pmeth ) { - if( !name.equals("->") ) - name = ClzBuilder.jname(pmeth._name)+"$"+name; - } else { - // Put qualified name if not in local namespace - ClassPart clz = (ClassPart)meth._par._par; - if( clz!= ClzBuilder.CMOD && clz!=ClzBuilder.CCLZ ) - name = ClzBuilder.add_import(XClz.make(clz)).clz_bare()+"."+name; - } - yield ASB.p(name); - } - - // Property constant. Just the base name, and depending on usage - // will be either console$get() or console$set(value). - case PropCon prop -> { - Part par = prop.part()._par; - if( par != ClzBuilder.CCLZ && prop.part().isStatic() ) { - if( par instanceof ClassPart clz ) - ASB.p(ClzBuilder.add_import(clz).clz_bare()).p('.'); - else if( par instanceof MethodPart meth ) { - ASB.p(meth._name).p('$'); - } else throw XEC.TODO(); - } - yield ASB.p(prop._name).p("$get()"); - } - - // A class Type as a value - case ParamTCon ptc -> { - XType xt = XType.xtype(ptc,true); - // TParmCon is a parameterized type, just use generic - if( ptc._parms[0] instanceof TermTCon ttc && ttc.id() instanceof TParmCon tpc ) - yield ASB.p(tpc._name); - if( ptc._parms[0] instanceof ParamTCon parm && parm.part()._name.equals("Type") ) { // Dynamic formal type? - // Generic named type got a "$" prepended for the Java type, and we - // need the plain type as a normal Java value now. - if( xt instanceof XBase base ) { - assert base._jtype.charAt(0)=='$'; - yield ASB.p(base._jtype.substring(1)); - } - if( xt == XCons.XXTC ) - yield ASB.p("((XTC)null)"); // No concrete type instance in the abstract XTC - yield xt.clz(ASB).p(".GOLD"); - } - if( xt instanceof XClz clz ) - yield ClzBuilder.add_import(clz).clz_bare(ASB).p(".GOLD"); - if( xt instanceof XBase base ) - yield base.box().clz(ASB); - // TODO: ASSERT XClz from PTC, get the gold instance from the one type parameter? - // Assert ntypeparms ==1, get field#0 as the type, get gold from that? - yield ASB.p("org.xvm.xec.ecstasy.reflect.Type.GOLD"); - //throw XEC.TODO(); - } - - // Enums - case EnumCon econ -> { - ClassPart clz = (ClassPart)econ.part(); - String sup_clz = clz._super._name; - // Just use Java null - if( sup_clz.equals("Nullable") ) - yield ASB.p("null"); - // XTC Booleans rewrite as Java booleans - if( sup_clz.equals("Boolean") ) - yield ASB.p(clz._name.equals("False") ? "false" : "true"); - // Use the enum name directly - ClzBuilder.add_import(clz._super); - yield ASB.p(sup_clz).p(".").p(clz._name); - } - - // Singleton class constants (that are not enums) - case SingleCon con0 -> { - if( con0.part() instanceof ModPart mod ) - yield ASB.p( S.java_class_name(mod._name)); - if( con0.part() instanceof PropPart prop ) { - if( prop.clz() != ClzBuilder.CCLZ ) - ASB.p(prop._par._name).p("."); - yield ASB.p(PropBuilder.jname(prop)).p("$get()"); - } - if( con0.part() instanceof ClassPart clz ) - yield ASB.p( S.java_class_name(clz._name)).p(".GOLD"); - - throw XEC.TODO(); - } - - case RangeCon rcon -> { - String ext = rcon._xlo - ? (rcon._xhi ? "EE" : "EI") - : (rcon._xhi ? "IE" : "II"); - ClzBuilder.IMPORTS.add(XEC.XCLZ+".ecstasy.Range"+ext); - ASB.p("new Range").p(ext).p("("); - _val(rcon._lo).p(","); - _val(rcon._hi).p(")"); - yield ASB; - } - - // Array constants - case AryCon ac -> { - assert ac.type() instanceof ImmutTCon; // Immutable array goes to static - XClz ary = (XClz)XType.xtype(ac.type(),false); - ClzBuilder.IMPORTS.add(XEC.XCLZ+".ecstasy.collections.AryXTC"); - // Cannot make a zero-length instance of ARRAY, since its abstract - but - // a zero-length version is meaningful. - if( ary==XCons.ARRAY || ary==XCons.ARRAY_RO ) - yield ASB.p("AryXTC.EMPTY"); // Untyped array creation; cannot hold elements - - // new AryString( .1, "abc", "def"); - // new Arylong ( .1, 0, 1, 2 ); - // new AryXTC( new Arylong(0) ) - ary.clz(ASB.p("new ")).p("( "); - if( S.eq(ary._jname,"AryXTC") ) - ary.e().clz(ASB).p(".GOLD, "); // First arg is element type GOLD - else if( !ary.isTuple() ) { - ASB.p(".1, "); // Double 1st arg to pick constructor - } // Else tuple no extra args - if( ac.cons()!=null ) - for( Const con : ac.cons() ) - _val( con ).p(", "); - yield ASB.unchar(2).p(")"); - } - - // Map constants - case MapCon mc -> { - XType type = XType.xtype(mc._t,false); - type.clz(ASB.p("new ")).p("() {{ "); - for( int i=0; i { - ClassPart clz = ttc.clz(); - if( clz._name.equals("Console") && clz._path._str.equals("ecstasy/io/Console.x") ) - yield ASB.p(XEC.ROOT).p(".XEC.CONTAINER.get()").p(".console()"); - if( clz._name.equals("Random") && clz._path._str.equals("ecstasy/numbers/Random.x") ) - yield ASB.p(XEC.ROOT).p(".XEC.CONTAINER.get()").p(".random()"); - if( clz._name.equals("Timer") && clz._path._str.equals("ecstasy/temporal/Timer.x") ) - yield ASB.p(NativeTimer.make_timer(XClz.make(clz))); - if( clz._name.equals("Clock") && clz._path._str.equals("ecstasy/temporal/Clock.x") ) - yield ASB.p(NativeTimer.make_clock(XClz.make(clz))); - throw XEC.TODO(); - } - - case Dec64Con dcon -> - ASB.p("new Dec64(\"").p(dcon.asStr()).p("\")"); - - case Dec128Con dcon -> - ASB.p("new Dec128(\"").p(dcon.asStr()).p("\")"); - - case ClassCon ccon -> { - ClzBuilder.add_import( ccon.clz() ); - XType x = XType.xtype(ccon,false); - yield x.clz(ASB.p("new ")).p("()"); - } - - case AnnotTCon acon -> - switch( acon.clz()._name ) { - // Gets a special "CONTAINER.inject" call - case "Inject" -> _val(acon.con().is_generic()); - // Wraps the type as "Future". - case "Future" -> XType.xtype(acon,true).clz(ASB.p("new ")).p("()"); - // Does nothing for Java, I believe. It's not a Java "volatile" for sure. - case "Volatile" -> _val(acon.con()); - default -> throw XEC.TODO(); - }; - - - default -> throw XEC.TODO(); - }; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/AST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/AST.java deleted file mode 100644 index 0ce93294e7..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/AST.java +++ /dev/null @@ -1,261 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.XEC; -import org.xvm.xtc.*; -import org.xvm.xtc.cons.Const.NodeType; -import org.xvm.util.SB; -import org.xvm.util.S; - -public abstract class AST { - public static int _uid; // Private counter for temp names - - public AST[] _kids; // Kids - AST _par; // Parent - // Computed type. This varies during the rewrites as I attempt to unbox - // things, or resolve to a sharper type. Occasionally a COND producer wants - // the COND as the primary answer. - XType _type; // Null is unset, never valid. "void" or "int" or "Long" or "AryI64" - // The XRuntime.COND global is used to return a 2nd argument from many calls - // (often flagged as "conditional"). This 2nd argument can be used in nearly - // any boolean context including If's, stacked And expressions "a && b && c", - // as part of conditional assignments "if( Int a = condInt() ) { ... a...}", - // asserts at least. Since its a singleton global, its crushed by the very - // next COND-writer, and has to be consumed quickly. - boolean _cond; // True if also passing the hidden condition flag - - // Simple all-fields constructor - AST( AST[] kids ) { _kids = kids; } - - @Override public String toString() { return jcode(new SB() ).toString(); } - - public XType type() { return _type; } - - // Use the _par parent to find nearest enclosing Block for tmps - BlockAST enclosing_block() { - AST ast = this; - while( !(ast instanceof BlockAST blk) ) - ast = ast._par; - return blk; - } - - // Use the _par parent to find the Nth enclosing switch or loop. - AST enclosing_loop(int i) { - AST ast = this; - while( !ast.is_loopswitch() ) - ast = ast._par; - return i==0 ? ast : ast._par.enclosing_loop(i-1); - } - boolean is_loopswitch() { return false; } - // Adding a continue/break label, if it makes sense - void add_label() { throw XEC.TODO(); } - String label() { throw XEC.TODO(); } - - // Name, if it makes sense - String name() { throw XEC.TODO(); } - - // Cast nth child from a long to an int - boolean castInt(int n) { - AST kid = _kids[n]; - if( kid._type == XCons.INT ) return false; // Already an int - // Update a long constant to an int in-place - if( kid instanceof ConAST con ) { - assert con._type == XCons.LONG; - con._con = con._con.substring(0,con._con.length()-1); - con._type = XCons.INT; - return true; // Did something - } - _kids[n] = new ConvAST(XCons.INT,_kids[n]); - return true; - } - // Replace a constant "false" with a conditional false return - boolean condFalse( int idx, XType zret ) { - if( _kids[idx]._cond ) return false; - assert _kids[idx] instanceof ConAST con && con._con.equals("false"); - _kids[idx] = new ConAST("XRuntime.False("+zret.ztype()+")", XCons.NULL); - _kids[idx]._cond = true; - return true; - } - - - // Set parent and first cut types in the AST - public void doType(AST par) { - _par = par; - if( _kids != null ) - for( AST kid : _kids ) - if( kid != null ) - kid.doType( this ); - doType(); // Non-recursive - } - final AST doType() { - XType type = _type(); // Local type computation - assert _type==null || _type==type; // Allow type to be early set - _type = type; - _cond = _cond(); // Local cond value - return this; - } - // Subclasses must override - abstract XType _type(); - boolean _cond() { return false; } - - // Generic visitor pattern, allowing updates - public AST visit(java.util.function.UnaryOperator F, AST par) { return visit(F,par,true,0); } - private AST visit(java.util.function.UnaryOperator F, AST par, boolean first, int cnt) { - assert cnt<100; - if( _par==null || _par._par==par ) _par = par; - else assert _par==par; - AST[] kids = _kids; - if( kids != null ) - for( int i=0; i= 32 ) - return new RegAST(iop-32,X); // Local variable register - if( iop == NodeType.Escape.ordinal() ) return ast(X); - if( iop >= 0 ) return _ast(X,iop); - if( iop > CONSTANT_OFFSET ) return new RegAST(iop,X); // "special" negative register - // Constants from the limited method constant pool - return new ConAST( X, X.con(CONSTANT_OFFSET-iop) ); - } - - static AST ast( ClzBuilder X ) { return _ast(X,X.u8()); } - - private static AST _ast( ClzBuilder X, int iop ) { - NodeType op = NodeType.NODES[iop]; - return switch( op ) { - case AnnoNamedRegAlloc -> DefRegAST.make(X,true ,true ); - case AnnoRegAlloc -> DefRegAST.make(X,false,true ); - case ArrayAccessExpr -> BinOpAST.make(X,".at(",")"); - case AssertStmt -> AssertAST.make(X); - case Assign -> AssignAST.make(X,true); - case BinOpAssign -> AssignAST.make(X,false); - case BindFunctionExpr -> BindFuncAST.make(X); - case BindMethodExpr->BindMethAST.make(X); - case BitNotExpr -> UniOpAST.make(X,"~",null); - case BreakStmt -> BreakAST.make(X); - case CallExpr -> CallAST.make(X); - case CmpChainExpr -> CmpChainAST.make(X); - case CondOpExpr -> BinOpAST.make(X,false); - case ContinueStmt -> ContinueAST.make(X); - case ConvertExpr -> ConvAST.make(X); - case DivRemExpr -> DivRemAST.make(X); - case DoWhileStmt -> DoWhileAST.make(X); - case ForListStmt -> ForRangeAST.make(X); - case ForMapStmt -> ForRangeAST.make(X); - case ForRangeStmt -> ForRangeAST.make(X); - case ForIterableStmt -> ForIterStmtAST.make(X); - case ForStmt -> ForStmtAST.make(X); - case Greater -> OrderAST.make(X,">"); - case IfElseStmt -> IfAST.make(X,3); - case IfThenStmt -> IfAST.make(X,2); - case InitAst -> InitAST.make(X); - case InvokeExpr -> InvokeAST.make(X,false); - case InvokeAsyncExpr-> InvokeAST.make(X,true ); - case Less -> OrderAST.make(X,"<"); - case LoopStmt -> WhileAST.make(X,true); - case MapExpr -> MapAST.make(X); - case MultiExpr -> MultiAST.make(X,true); - case MultiStmt -> MultiAST.make(X,false); - case NamedRegAlloc-> DefRegAST.make(X,true ,false); - case NarrowedExpr -> NarrowAST.make(X); - case NegExpr -> UniOpAST.make(X,"-",null); - case NewExpr -> NewAST.make(X,false); - case NewChildExpr -> NewAST.make(X,true ); - case NewVirtualExpr ->NewVirtAST.make(X); - case NotExpr -> UniOpAST.make(X,"!",null); - case None -> NoneAST.make(X); - case NotNullExpr -> UniOpAST.make(X,"ELVIS",null); - case OuterExpr -> OuterAST.make(X); - case PostDecExpr -> UniOpAST.make(X,null,"--"); - case PostIncExpr -> UniOpAST.make(X,null,"++"); - case PreDecExpr -> UniOpAST.make(X,"--",null); - case PreIncExpr -> UniOpAST.make(X,"++",null); - case PropertyExpr -> PropertyAST.make(X); - case RefOfExpr -> UniOpAST.make(X,"&",null); - case RegAlloc -> DefRegAST.make(X,false ,false ); - case RelOpExpr -> BinOpAST.make(X,true ); - case Return0Stmt -> ReturnAST.make(X,0); - case Return1Stmt -> ReturnAST.make(X,1); - case ReturnNStmt -> ReturnAST.make(X,X.u31()); - case StmtBlock -> BlockAST.make(X); - case StmtExpr -> ExprAST.make(X); - case SwitchExpr -> SwitchAST.make(X,true); - case SwitchStmt -> SwitchAST.make(X,false); - case TemplateExpr -> TemplateAST.make(X); - case TernaryExpr -> TernaryAST.make(X); - case ThrowExpr -> ThrowAST.make(X); - case TryCatchStmt -> TryCatchAST.make(X); - case TupleExpr -> ListAST.make(X,true); - case UnaryOpExpr -> UniOpAST.make(X); - case VarOfExpr -> UniOpAST.make(X,"&",""); - case WhileDoStmt -> WhileAST.make(X,false); - case UnpackExpr -> UnpackAST.make(X); - - default -> throw XEC.TODO(); - }; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/AssertAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/AssertAST.java deleted file mode 100644 index ba70b94e9a..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/AssertAST.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.xtc.*; - -class AssertAST extends ElvisAST { - static AssertAST make( ClzBuilder X ) { - int flags = X.u31(); - AST cond = (flags&1)!=0 ? ast_term(X) : new ConAST("false",XCons.FALSE); - AST intv = (flags&2)!=0 ? ast_term(X) : null; - AST mesg = (flags&4)!=0 ? ast_term(X) : null; - return new AssertAST(cond,intv,mesg); - } - private AssertAST( AST... kids ) { super(kids); } - @Override XType _type() { - int len = _kids.length; - for( int i=0; i=0; i-- ) - if( !(k0._kids[i] instanceof RegAST reg) || reg._reg != -2/*A_IGNORE*/ ) - return k0._kids[i]._type; - throw XEC.TODO(); // All kids are ignore? - } else if( k1._type.isTuple() ) { - return k1._type; - } else { - return k1._type; - } - } else { - // LHS type - return k0._type; - } - } - - @Override boolean _cond() { - return _kids[1]._cond || // Assignments do not blow "COND" - // Or a conditional assign - _op==AsnOp.AsnIfNotFalse || - _op==AsnOp.AsnIfNotNull || - _op==AsnOp.AsnIfWasFalse || - _op==AsnOp.AsnIfWasTrue || - _op==AsnOp.AsnIfWasNull; - } - - // If is a simple define, return the type else null - XType isDef() { - return _op==AsnOp.Asn && _kids[0] instanceof DefRegAST def ? def._type : null; - } - - @Override public AST rewrite() { - - // Assign of a boxed type to an eagerly unboxed type - if( _type instanceof XBase && _kids[1]._type.unbox()!=_kids[1]._type ) { - _kids[1] = new UniOpAST(new AST[]{_kids[1]},null,"._i",_type); - return this; - } - - // Assign of a non-primitive array - if( _kids[0] instanceof BinOpAST bin && - // Replace with "ary.set(idx,val)" - bin._op0.equals(".at(") ) - return new InvokeAST("set",null,bin._kids[0],bin._kids[1],_kids[1]); - - // Add/push element to array; or op-assign "x+=y" - if( _meth!=null && _op._meth && _kids[0]._type instanceof XClz clz ) { - AST k0 = _kids[0] instanceof NarrowAST n ? n._kids[0] : _kids[0]; - RegAST reg0 = (RegAST)k0; - AST op = new InvokeAST( _meth.name(), clz, _kids.clone() ); - RegAST reg1 = new RegAST(reg0._reg,reg0._name,reg0._type); - return new AssignAST( AsnOp.Asn, _meth, reg1, op ).doType(); - } - - // Multi-assigns - if( _kids[0] instanceof MultiAST m ) { - BlockAST blk = enclosing_block(); - // (Int a, _ b, Double c) = (foo, bar, baz) - if( _kids[1] instanceof MultiAST mm ) { - Ary kids = new Ary<>(AST.class); - for( int i=0; i1 ) throw XEC.TODO(); - return kids.at(0); - - } else { - // XTC: (Int a, String b, Double c) = retTuple(); - // Java: { ...tmps...; tmp = retTuple; a = tmp._f0; b = tmp._f1; c = tmp._f2; } - MultiAST mm = new MultiAST(false,Arrays.copyOf(m._kids,m._kids.length+1)); - // Insert a slot for the "tmp = retTuple" - System.arraycopy(mm._kids,0,mm._kids,1,m._kids.length); - String tmp = blk.add_tmp(_kids[1]._type); - AST reg = new RegAST(tmp,_kids[1]._type); - mm._kids[0] = new AssignAST(reg,_kids[1]).doType(); - // Break out each part - for( int i=0; i { - if( ast instanceof RegAST reg && reg._name.equals(_name) ) - reg._name = tmp; - return null; - },iff); - return this; - } - // XTC assert Int n := S1(), ...n... - // BAST (Assert (XTC) (Multi (Op$AsgnIfNotFalse (DefReg n) (Invoke cond_ret)), other bools ops all anded, including more assigns)) - // BAST (Invoke (XTC) (Multi (Op$AsgnIfNotFalse (DefReg n) (Invoke cond_ret)), other bools ops all anded, including more assigns)) - // BAST (Invoke (XTC) (&& (Op$AsgnIfNotFalse (Reg n) (Invoke cond_ret))... )), other bools ops all anded, including more assigns)) - // Java long n; xassert( $t(n=S1()) && $COND && ...n...) - _tmp = blk.add_tmp(type, _name); - _kids[0] = new RegAST(_tmp,type); - return this; - } - if( !(_par instanceof MultiAST) && !(_par instanceof WhileAST) ) { - // 's' already defined - // XTC s := cond_ret(); - // BAST (Op$AsgnIfNotFalse (Reg s) (Invoke cond_ret)) - // BAST (If (Op$AsgnIfNotFalse (Reg s) (Invoke cond_ret)) (Assign (Reg s) (Ret tmp))) - // Java if( $t(tmp = cond_ret()) && $COND ) s=tmp; - _tmp = enclosing_block().add_tmp(type); - _cond_asgn = _name; - _kids[0] = new RegAST(_tmp,type); - return this; - } // part of a large conditional expression - } - - return null; - } - - // Box as needed - @Override public AST reBox( ) { - XType k0t = _kids[0]._type; - XType k1t = _kids[1]._type; - if( k0t.isUnboxed() || !k1t.isUnboxed() || k1t==XCons.NULL ) - return null; - _kids[1] = _kids[1].reBoxThis(); - return this; - } - - @Override public SB jcode( SB sb ) { - return switch( _op ) { - case AsnIfNotFalse, AsnIfNotNull -> { - // var := (true,val) or var ?= not_null; - if( _cond_asgn!=null ) sb.p("if( "); - // Expression result is the boolean conditional value, - // and the var was previously defined. - // $t(var = expr()) && XRuntime.$COND - AST kid0 = _kids[0]; - if( kid0 instanceof NarrowAST n ) kid0 = n._kids[0]; - String name = kid0 instanceof RegAST reg ? reg._name : ((DefRegAST)kid0)._name; - if( _op == AsnOp.AsnIfNotFalse ) sb.p("$t"); - _kids[1].jcode(sb.p("(").p(name).p(" = ")).p(")"); - sb.p( _op == AsnOp.AsnIfNotFalse ?" && XRuntime.$COND" : "!=null " ); - - // $t(tmp = expr()) && XRuntime.$COND && $t(var = tmp) - if( _cond_asgn != null ) - sb.p(") ").p(_cond_asgn).p(" = ").p(name); - yield sb; - } - - case AsnIfWasFalse -> asnIf(sb,"!","" ); // if(!var ) var = e0; - case AsnIfWasTrue -> asnIf(sb,"" ,"" ); // if( var ) var = e0; - case AsnIfWasNull -> asnIf(sb,"" ,"==null"); // if( var==null) var = e0; - // Converts? a "normal" thing into a "Var" thing. - // Nothing, because loads & stores are all $get and $set now - case Deref -> sb; - - case Asn -> _kids[0] instanceof RegAST reg && reg._type.isVar() - // Assigning a Var uses "$set()" - ? _kids[1].jcode(sb.ip(reg._name).p(".$set(")).p(")") - : asn(sb); - - case AddAsn -> asn(sb); - case SubAsn -> asn(sb); - case MulAsn -> asn(sb); - case DivAsn -> asn(sb); - case OrAsn -> asn(sb); - case XorAsn -> asn(sb); - default -> throw XEC.TODO(); - }; - } - - private SB asn(SB sb) { - _kids[0].jcode(sb).p(" ").p(_op.text).p(" "); - return _kids[1].jcode(sb); - } - - private SB asnIf(SB sb, String pre, String post) { - sb.p("if( ").p(pre).p(_name).p(post).p(" ) ").p(_name).p(" = "); - return _kids[1].jcode(sb); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/BinOpAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/BinOpAST.java deleted file mode 100644 index 0354ff569d..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/BinOpAST.java +++ /dev/null @@ -1,201 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.XEC; -import org.xvm.util.SB; -import org.xvm.util.S; -import org.xvm.xtc.*; -import org.xvm.xtc.cons.Const.BinOp; -import org.xvm.xtc.cons.NumCon; -import org.xvm.xtc.XCons; - -import java.util.HashMap; - -class BinOpAST extends AST { - String _op0, _op1; - - static AST make( ClzBuilder X, boolean has_type ) { - AST[] kids = new AST[2]; - kids[0] = ast_term(X); - BinOp op = BinOp.OPS[X.u31()]; - kids[1] = ast_term(X); - XType type = has_type - ? XType.xtype(X.con(),false) // Type from the AST file - : (op==BinOp.CompOrd ? XCons.ORDERED : XCons.BOOL ); // Must be one of the ordering operators - if( op==BinOp.Else ) // This becomes a ternary op - return new TernaryAST(new AST[]{kids[0],kids[1]},type,false); - return new BinOpAST(op.text,"",type,kids); - } - - static BinOpAST make( ClzBuilder X, String op0, String op1 ) { - AST[] kids = X.kids(2); - return new BinOpAST(op0,op1,null,kids); - } - - BinOpAST( String op0, String op1, XType type, AST... kids ) { - super(kids); - _op0 = op0; - _op1 = op1; - _type = type; - } - - @Override XType _type() { - if( _op0.equals(".at(") ) { - // Tuple or Array - XType tk = _kids[0]._type; - if( tk.isAry() ) - return tk.e(); - if( tk == XCons.JSTRING ) - return XCons.JCHAR; - // Something else (PropCon?) means get the collections' element type - int idx = 0; // Default for non-Tuple - // Tuple at fixed field offset - if( tk.isTuple() && - (idx = isFixedOffset()) == -1 ) - return XCons.XXTC; // Unknown field (not a fixed number) - return idx < tk._xts.length ? tk._xts[idx] : XCons.XXTC; - } - - // Cast to sharper - if( _op0.equals("as") ) - return _type = _kids[1]._type; - - return _type; - } - - // Fixed positive offset in _kids[1], or -1 - private int isFixedOffset() { - return _kids[1] instanceof ConAST con && con._tcon instanceof NumCon num ? (int)num._x : -1; - } - - @Override public AST rewrite() { - - return switch( _op0 ) { - // Range is not a valid Java operator, so need to change everything here - case ".." -> do_range(_kids,XCons.RANGEII); - case "..<" -> do_range(_kids,XCons.RANGEIE); - case "<=>" -> { - ClzBuilder.add_import(XCons.ORDERABLE); - yield new InvokeAST("spaceship",XCons.ORDERED,new ConAST("Orderable"),_kids[0],_kids[1]).doType(); - } - - // This is a ternary null-check or elvis operator. _kids[0] is - // directly the predicate test. I need to restructure this tree: - // ( "?:" pred alt) - // into this tree: - // ( ((tmp=pred)!=null) ? tmp : alt) - case "?:" -> { - TernaryAST tern = new TernaryAST(_kids,_kids[0]._type,false); - tern._par = _par; - tern._kids[0] = tern.doElvis(_kids[0],_kids[0]); - yield tern; - } - - // Cast. Since I treat XTC "Type" as a concrete instance XTC.GOLD, - // I do not need to cast to "Type". Other casts can remain. - case "as" -> _kids[1] instanceof ConAST con && con._con.equals("Type.GOLD") - ? _kids[0] // Types already as values - : null; - - case ".at(" -> { - if( _kids[1]._type!=XCons.LONG ) yield null; // TODO: Handle other kinds of arrays - _type = _type.unbox(); - if( _kids[0]._type == XCons.STRING ) { - _op0 = ".charAt((int)("; _op1 = "))"; - yield this; // progress - } - if( _kids[0]._type.isAry() ) { - _op0 = ".at8("; // Use primitive 'at' instead of generic - yield this; // progress - } - int idx = isFixedOffset(); - if( _kids[0]._type.isTuple() && idx != -1 ) - // Tuple at fixed field offset - yield new PropertyAST(_kids[0],_type,"_f"+idx); - yield null; - } - - - default -> null; - }; - } - - static AST do_range( AST[] kids, XClz rng ) { - return new NewAST(kids,ClzBuilder.add_import(rng)); - } - - @Override public SB jcode( SB sb ) { - if( _op0.equals("as") ) { - _kids[1]._type.clz_bare(sb.p("((")).p(")"); - return _kids[0].jcode(sb).p(")"); - } - expr(sb,_kids[0]).p(_op0); - expr(sb,_kids[1]).p(_op1); - return sb; - } - - // Print 1+(2+3) as "1+2+3" - // Print 1*(2+3) as "1*(2+3)" - SB expr( SB sb, AST ast ) { - boolean wrap = ast instanceof BinOpAST bin && - ! _op1.equals(")") && - !bin._op1.equals(")") && - prec( _op0, bin._op0 ); - if( ast instanceof AssignAST ) wrap=true; - if( _type==XCons.STRING && _kids[1]==ast && - (ast instanceof BinOpAST || ast instanceof TernaryAST || (ast instanceof SwitchAST sast && sast._kids[0] instanceof MultiAST ) ) ) { - sb.p(" "); wrap=true; - } - if( ast instanceof ConAST con && con._con.charAt(0)=='-' ) - sb.p(" "); - if( wrap ) sb.p("("); - ast.jcode(sb); - if( wrap ) sb.p(")"); - return sb; - } - - // Java precedence table - private static final HashMap PRECS = new HashMap<>(){{ - put("._f",17); // Primitive tuple field loads - - put("[" ,16); - - // java unary ops go here - - put("*" ,12); - put("/" ,12); - put("%" ,12); - - put("+" ,11); - put("-" ,11); - - put("<<",10); - put(">>",10); - put(">>>",10); - - put("<" , 9); - put(">" , 9); - put("<=", 9); - put(">=", 9); - - put("==", 8); - put("!=", 8); - - put("&" , 7); - put("^" , 6); - put("|" , 5); - - put("&&" ,4); - put("||" ,3); - - put("?:" ,2); - - put(".charAt((int)(",0); // Not-the-operator - }}; - private boolean prec(String op, String ex) { - Integer ii0 = PRECS.get(op); - Integer ii1 = PRECS.get(ex); - if( ii0==null ) { System.err.println("Missing \""+op+"\" from BinOpAST"); return true; } - if( ii1==null ) { System.err.println("Missing \""+ex+"\" from BinOpAST"); return true; } - return ii0 > ii1; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/BindFuncAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/BindFuncAST.java deleted file mode 100644 index 7fbabf2105..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/BindFuncAST.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.XEC; -import org.xvm.util.S; -import org.xvm.xtc.cons.Const; -import org.xvm.xtc.cons.MethodCon; -import org.xvm.xtc.*; -import org.xvm.util.SB; - -import java.util.Arrays; - - -class BindFuncAST extends AST { - // Which arguments are being bound here. This is basically reverse-currying - // by any other name. - final int[] _idxs; // Which args are being bound - String[] _args; // Remaining args - private final ClzBuilder _X; - private MethodPart _lam; // Avoid double-rewrite on nested BindFunc/Con-> setups (nested lambda expressions) - - static BindFuncAST make( ClzBuilder X ) { - AST target = ast_term(X); - int nargs = X.u31(); - AST[] kids = new AST[nargs+1]; - kids[0] = target; // Target is _kids[0] - int[] idxs = new int[nargs]; - for( int i=0; i") - ? (MethodPart) con._tcon.part() - : null; - } - BindFuncAST( AST body, MethodPart lam ) { - super(new AST[]{body}); - _idxs = null; - _X = null; - _lam = lam; - } - - @Override XType _type() { - int nargs = _kids.length-1; - if( _lam != null ) { - // All the explicit lambda args - _args = new String[_lam._args.length-nargs]; - XType[] xargs = new XType[_lam._args.length-nargs]; - for( int i=nargs; i<_lam._args.length; i++ ) { - String name = _lam._args[i]._name; - XType atype = XType.xtype(_lam._args[i].tcon(),false); - _args[i-nargs] = name; - xargs[i-nargs] = atype; - } - // Build a function type from the given args - return XFun.make(_lam.is_cond_ret(),_lam.ret(),xargs); - - // Currying: pre-binding some method args - } else { - assert nargs==_idxs.length; // Every - return _kids[0]._type; - } - } - - // Make this register Java-effectively-final here - private void make_effectively_final(RegAST reg, MethodPart lam) { - if( isEF(_par,this,reg) ) return; - // New final temp name - String s = _par.enclosing_block().add_final(new RegAST(reg._reg,reg._name,reg._type)); - String old = reg._name; - // Change parameter name in inlined lambda - for( Parameter p : lam._args ) - if( S.eq(p._name,reg._name) ) - { p._name = s; break; } - visit( ast -> { - if( ast instanceof RegAST rast && old.equals(rast._name) ) rast._name = s; - return null; - }, _par ); - } - - private boolean isEF(AST par, AST kid, RegAST reg) { - if( par==null ) return true; - int i=0; while( i< par._kids.length && par._kids[i] != kid ) - if( isRedefTree(par._kids[i++],reg) ) - return false; - return isEF(par._par,par,reg); - } - - private boolean isRedefTree(AST ast,RegAST reg) { - if( ast instanceof DefRegAST def && def._reg==reg._reg ) { - if( def._par instanceof ForRangeAST ) - return def._type instanceof XBase; - // TODO: Not correct, need some kind of final-field indication - if( def._par instanceof BlockAST && def._init!=null ) - return false; - // Not a parent ForRange, need to look more - throw XEC.TODO(); - } - return false; - } - - @Override public AST rewrite() { - // Has embedded AST, already expanded. Not a currying operation - if( _lam != null ) { - // Check for other exposed names being effectively final - for( int i=1; i<_kids.length; i++ ) - if( _kids[i] instanceof RegAST reg ) - make_effectively_final(reg,_lam); - return null; - } - - // Curry some function: no embedded AST, just some arg shuffles - XFun lam = (XFun)_type; - int nargs = _kids.length-1; - // The idx[] args are pre-defined; the remaining args are passed along. - // Example: foo( Int x, String s ) { ...body... } - // The "1th" arg is predefined here, the 0th arg is passed along. - // foo2 = &foo(s="abc") ===>>> - // foo2(long x) = x -> foo(x,"abc"); - // - // All the explicit lambda args: all the args minus the given (curried) args - _args = new String[lam.nargs()-nargs]; - - // Recycle the kids array for the InvokeAST - AST[] ikids = new AST[lam.nargs()+1]; - - // Fill in the args, leaving slot 0 open - int j=0; - for( int i=0; i "); - AST body = _kids[0]; - if( body!= null ) body.jcode(sb); - return sb; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/BindMethAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/BindMethAST.java deleted file mode 100644 index 02287f42f1..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/BindMethAST.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.util.SB; -import org.xvm.xtc.*; -import org.xvm.xtc.cons.*; - -class BindMethAST extends AST { - final MethodPart _meth; - static BindMethAST make( ClzBuilder X ) { - AST target = ast_term(X); - Const meth = X.con(); - Const type = X.con(); - return new BindMethAST( (MethodPart) meth.part(), XType.xtype(type,false), target ); - } - - private BindMethAST( MethodPart meth, XType type, AST... kids ) { - super(kids); - _meth = meth; - _type = type; - } - - @Override XType _type() { return _type; } - @Override String name() { return _meth.jname(); } - - @Override void jpost( SB sb ) { - sb.p("::").p(_meth._name); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/BlockAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/BlockAST.java deleted file mode 100644 index 5bea112c71..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/BlockAST.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.xvm.xtc.ast; - -import java.util.Arrays; -import java.util.HashMap; -import org.xvm.XEC; -import org.xvm.util.Ary; -import org.xvm.util.S; -import org.xvm.util.SB; -import org.xvm.xtc.*; - -public class BlockAST extends ElvisAST { - HashMap> _tmps; // Temp names by type - - static BlockAST make( ClzBuilder X ) { - int nlocals = X.nlocals(); // Count of locals - // Parse kids in order as stmts not exprs - AST[] kids = new AST[X.u31()]; - for( int i=0; i(); - Ary tmps = _tmps.computeIfAbsent( type, k -> new Ary<>( new String[1], 0 ) ); - return tmps.push(name); - } - - // Final versions of some register, to pass into lambdas. Light name mangling. - Ary _finals; - String add_final(RegAST reg) { - if( _finals==null ) _finals = new Ary<>(RegAST.class); - _finals.push(reg); - return "f$"+reg._name; - } - - @Override public AST rewrite() { - if( _elves != null ) { - for( int i=_elves._len-1; i>=0; i-- ) { - Elf elf = _elves.at(i); - AST expr = _kids[elf._idx]; - AST eq = elf.test(); - _kids[elf._idx] = new IfAST(eq,expr); - } - _elves=null; // Been there, done that - return this; - } - - // Yank a blank return - if( _kids.length>0 && _kids[_kids.length-1] instanceof ReturnAST ret && - ret._meth!=null && ret._meth.xfun().ret()==XCons.VOID ) { - // Void return functions execute the return for side effects only - _kids = Arrays.copyOf(_kids,_kids.length-1); - return this; - } - return null; - } - - @Override public SB jcode( SB sb ) { - sb.p("{").ii().nl(); - // Print tmps used by enclosing expressions - if( _tmps!=null ) { - for( XType type : _tmps.keySet() ) { - Ary tmps = _tmps.get(type); - type.clz(sb.i()).p(" "); - for( String tmp : tmps ) - sb.p(tmp).p("= ").p(type.ztype()).p(", "); - sb.unchar(2).p(";").nl(); - } - } - if( _finals!=null ) - for( RegAST reg : _finals ) - sb.ifmt("var f$%0 = %0;",reg._name).nl(); - if( _kids!=null ) - for( int i=0; i<_kids.length; i++ ) { - if( _kids[i]==null ) continue; - _kids[i].jcode(sb.i()); - if( !sb.was_nl() ) - sb.p(";").nl(); - } - return sb.di().ip("}"); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/BreakAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/BreakAST.java deleted file mode 100644 index 636e1a21c1..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/BreakAST.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.util.SB; -import org.xvm.XEC; -import org.xvm.xtc.*; - -class BreakAST extends AST { - final int _d; // Depth; 0 is tightest enclosing - static BreakAST make( ClzBuilder X) { return new BreakAST(X.u31()); } - private BreakAST( int d ) { super(null); _d = d; } - @Override XType _type() { return XCons.VOID; } - @Override public SB jcode ( SB sb ) { - return sb.p("break"); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/CallAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/CallAST.java deleted file mode 100644 index 9022000c6c..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/CallAST.java +++ /dev/null @@ -1,180 +0,0 @@ -package org.xvm.xtc.ast; - -import java.util.Arrays; -import org.xvm.XEC; -import org.xvm.util.S; -import org.xvm.util.SB; -import org.xvm.xtc.*; -import org.xvm.xtc.cons.Const; -import org.xvm.xtc.cons.MethodCon; -import org.xvm.xtc.cons.ParamTCon; - -public class CallAST extends AST { - final XType _ret; // A more precise return type - final String _mixin_tname; // Call to a mixin-super - static CallAST make( ClzBuilder X ) { - // Read return type; this can be more precise than the - // function in _kids[0] - XType ret = XFun.ret(XType.xtypes(X.consts())); - // Read the arguments, then the function expression. - AST[] kids = X.kids_bias(1); - // Move the function to the 0th kid slot. - kids[0] = ast_term(X); // Call expression first - return new CallAST(ret,X._meth,kids); - } - - CallAST( XType ret, MethodPart meth, AST... kids ) { - super(kids); - // Check for a call to super: "super(args)" becomes "super.METHOD(args)". - // If inside an interface (so _meth is a default method), the super - // also needs the correct super interface named. - if( _kids[0] instanceof RegAST reg && reg._reg== -13/*A_SUPER*/ ) { - _kids[0] = new ConAST(null,null,"super."+meth._name,meth.xfun()); - _mixin_tname = meth.clz()._f==Part.Format.MIXIN ? meth.clz()._tnames[0] : null; - } else _mixin_tname = null; - - // Replace default args with their actual default values - for( int i=1; i<_kids.length; i++ ) { - if( _kids[i] instanceof RegAST reg && - reg._reg == -4/*Op.A_DEFAULT*/ ) { // Default reg - // Swap in the default from method defaults - MethodPart meth0 = (MethodPart)((ConAST)_kids[0])._tcon.part(); - _kids[i] = new ConAST(null,meth0._args[i-1]._def); - } - } - - _ret = ret; - _type = _type(); - } - - private CallAST( XType ret, AST... kids ) { - super(kids); - _mixin_tname = null; - _ret = ret; - _type = _type(); - } - static CallAST make(XType ret, String clzname, String methname, AST kid) { - XFun fun = XFun.make(new XType[]{ret,kid._type},false); - ConAST con = new ConAST(clzname+"."+methname,fun); - CallAST call = new CallAST(ret,con,kid); - con._par = call; - call._type = ret; - return call; - } - - @Override XType _type() { return _ret; } - - @Override public AST rewrite() { - // Try to rewrite constant calls. This is required for e.g. "funky - // dispatch" calls - virtual calls off of a type argument. - if( !(_kids[0] instanceof ConAST con) ) return null; // Not a constant call, take as-is - assert _kids[0]._type instanceof XFun; - - // Convert "funky dispatch" calls; something like "Class.equals" - int lidx = con._con.lastIndexOf('.'); - if( lidx == -1 ) return null; // Normal call, take as-is - - // Filter for the special names - String clz = con._con.substring(0,lidx); - String base = con._con.substring(lidx+1); - AST ast = switch( base ) { - case "hashCode" -> _kids.length!=3 ? null : _kids[2]; - case "equals" -> _kids.length!=4 ? null : new BinOpAST("==" ,"",XCons.BOOL,_kids[2],_kids[3]); - case "compare" -> _kids.length!=4 ? null : new BinOpAST("<=>","",XCons.BOOL,_kids[2],_kids[3]); - default -> null; - }; - if( ast==null ) return null; // Not a funky dispatch - - // Primitive funky dispatch goes to Java operators - AST k1 = _kids[1]; - AST k2 = _kids[2]; - if( k2._type instanceof XBase ) { - if( k2._type != XCons.STRING && k2._type != XCons.STRINGN ) - return ast; - clz = XCons.JSTRING.clz(); - ((ConAST)k1)._con = "null"; - ((ConAST)k1)._type= XCons.NULL; - } - // References to become Java primitives - if( clz.equals("Ref") ) - return ast; - - if( k1 instanceof ConAST ) { - // XTC String got force-expanded to not conflict with j.l.String, recompress to the bare name - if( clz.equals("org.xvm.xec.ecstasy.text.String") ) clz = "String"; - if( clz.equals("org.xvm.xec.ecstasy.Object" ) ) clz = "Object"; - // Convert CLZ.equal/cmp(GOLD,arg1,arg2) to their static variant: CLZ.equal/cmp$CLZ(GOLD,arg1,arg2); - // Convert CLZ.hashCode (GOLD,arg1 ) to their static variant: CLZ.hashCode$CLZ (GOLD,arg1,arg2); - con._con += "$"+clz; - // Sharpen the function type - XFun fun = XFun.makeCall(this); - con._type = fun; - if( fun.ret() instanceof XClz xret ) - ClzBuilder.add_import(xret); - return null; - } - - // Dynamic variant - // Convert CLZ.equal/cmp(arg1,arg2) to Java dynamic: GOLD.equal/cmp(arg1,arg2); - // Convert CLZ.hashCode (arg1 ) to Java dynamic: GOLD.hashCode (arg1 ); - MethodPart meth = (MethodPart) con._tcon.part(); - ClassPart clazz = meth.clz(); - ClzBuilder.add_import(clazz); - return new InvokeAST(base,_ret,Arrays.copyOfRange(_kids,1,_kids.length)); - } - - // Box arguments as needed - @Override public AST reBox( ) { - XFun fun = (XFun)_kids[0]._type; - AST progress=null; - for( int i = 1; i < _kids.length; i++ ) { - if( _kids[i]._type instanceof XBase && - fun.arg(i-1).unbox() != fun.arg(i-1) ) - progress = _kids[i] = _kids[i].reBoxThis(); - } - return progress==null ? null : this; - } - - // If the called function takes a type parameter, its return type can be as - // precise as the type parm; XTC does this much type inference. - // XTC : "Foo foo = create(stuff);" - // BAST : "Assign(DefReg Foo is = Call("create",Int,stuff)" - // The Java expects a strongly typed result: - // Java : "Foo foo = create(INT64.GOLD,stuff)" - // However, the create call returns generic Foos: - // XTC: " Foo create( stuff ) { ... }" - // So the Java has to return a generic Foo - // Java: "Foo create( int len )" - private boolean needsGenericCast() { - if( _type instanceof XBase ) return false; // Includes VOID - if( _kids.length<=1 ) return false; - if( !(_kids[1] instanceof ConAST con) ) return false; // Type parameter in slot 1 - if( !(con._tcon instanceof ParamTCon) ) return false; // Not a type parameter - if( con._con.equals("null") ) return false; // Explicit null type parameter - // Will need to upcast return to match type - return true; - } - - @Override public SB jcode( SB sb ) { - // Assume we need a (self!) cast, from some abstract type to a more - // specified local type. - if( needsGenericCast() ) - _type.clz(sb.p("(")).p(")"); - _kids[0].jcode(sb); - AST kid = _kids[0] instanceof NarrowAST n ? n._kids[0] : _kids[0]; - sb.p( (kid instanceof RegAST ? ".call(" : "(") ); - for( int i=1; i<_kids.length; i++ ) { - // If this is a super of a mixin, all mixed args need to cast to the base - // type not mixin type. In general, I've no way to track this; could be - // any combo of fields and locals - but the mixin can only call "supers" - // of some sort or another. - if( _mixin_tname !=null ) - sb.p("($").p(_mixin_tname).p(")"); - _kids[i].jcode(sb).p(", "); - } - if( _kids.length > 1 ) - sb.unchar(2); - return sb.p(")"); - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/CmpChainAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/CmpChainAST.java deleted file mode 100644 index fa23c87807..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/CmpChainAST.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.xtc.*; -import org.xvm.xtc.MethodPart; -import org.xvm.xtc.cons.Const; -import org.xvm.xtc.cons.MethodCon; -import org.xvm.xtc.cons.Const.BinOp; -import org.xvm.util.SB; - -class CmpChainAST extends AST { - final BinOp[] _ops; - final String[] _tmps; - final MethodPart _cmp; - - static CmpChainAST make( ClzBuilder X ) { - AST[] kids = X.kids(); - BinOp[] ops = new BinOp[kids.length-1]; - for( int i=0; i") ) { - - MethodPart lam = (MethodPart) _tcon.part(); - // A builder for the lambda method - ClzBuilder X2 = new ClzBuilder(_X,null); - // All the args from the current scope visible in the lambda body, as - // hidden extra arguments - int nargs = lam._args.length; - for( int i=0; i= 0 - ? _X._ltypes.at(idx) // Name exists in out scope, use that type - : XType.xtype(lam._args[i].tcon(),false); - X2.define(aname,atype); - } - - // Build the lambda AST body - AST body = X2.ast(lam); - // Shortcut: if the body is a Block of a Return of 1 return value, - // skip the block. - if( body instanceof BlockAST && body._kids.length==1 && - body._kids[0] instanceof ReturnAST ret && ret._kids!=null && ret._kids.length==1 ) - body = ret._kids[0]; - body._par = null; - - // If the parent started as a BindFunc, the BindFunc will print the - // lambda header. If there are no extra args, BAST skips the BindFunc, - // but we still need a header - if( !(_par instanceof BindFuncAST && _par._kids[0]==this) ) - body = new BindFuncAST(body,lam).doType(); - - // Swap out the method constant for the AST body - return body; - } - - return null; - } - @Override XType _type() { return _type; } - @Override public SB jcode( SB sb ) { return sb.p(_con); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/ContinueAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/ContinueAST.java deleted file mode 100644 index 76523e7a3c..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/ContinueAST.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.xtc.*; -import org.xvm.util.SB; -import org.xvm.XEC; - -class ContinueAST extends AST { - final int _d; // Depth; 0 is tightest enclosing - static ContinueAST make( ClzBuilder X) { return new ContinueAST(X.u31()); } - private ContinueAST( int d ) { super(null); _d = d; } - - @Override XType _type() { return XCons.VOID; } - - @Override public AST rewrite() { - if( _d > 0 ) - enclosing_loop(_d).add_label(); // Needs a named GOTO - return null; - } - - @Override public SB jcode ( SB sb ) { - AST enclosing = enclosing_loop(_d); - if( enclosing instanceof SwitchAST ) { - if( _par instanceof BlockAST blk && - blk._par==enclosing && - blk._kids[blk._kids.length-1]==this ) - return sb.p("// Fall-through"); - // Requires fall-thru semantics from the middle complex expressions which - // amounts to a GOTO. - throw XEC.TODO(); - } - sb.ip("continue"); - if( _d > 0 ) sb.p(" ").p(enclosing.label()); - return sb; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/ConvAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/ConvAST.java deleted file mode 100644 index 47024078a3..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/ConvAST.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.util.SB; -import org.xvm.XEC; -import org.xvm.xtc.*; -import org.xvm.xtc.cons.Const; -import org.xvm.xtc.cons.MethodCon; - -class ConvAST extends AST { - - static ConvAST make( ClzBuilder X ) { - AST[] kids = X.kids(1); // One expr - Const[] types = X.consts(); - Const[] convs = X.sparse_consts(types.length); - return new ConvAST(kids,types,convs); - } - - private ConvAST( AST[] kids, Const[] types, Const[] convs) { - super(kids); - // Expecting exactly 2 types; first is boolean for a COND. - // Expecting exactly 1 conversion method. - int idx = types.length == 1 ? 0 : 1; - if( types.length != 1 ) { - assert types.length==2 && XType.xtype(types[0],false)==XCons.BOOL; - assert convs.length==2 && convs[0]==null; - } - _type = XType.xtype(types[idx],false); - } - - ConvAST( XType cast, AST kid ) { - super(new AST[]{kid}); - _type = cast; - } - - @Override XType _type() { return _type; } - - @Override public AST rewrite() { - if( _kids[0]._type.isa(_type) )// No change - return _kids[0]; // Drop the Conv - // Converting from a Java primitive - if( _kids[0]._type.is_jdk() ) { - // Converting between java primitives (e.g. long<->double) just uses the - // normal Java cast. - if( _type.is_jdk() ) return null; - // Converting from a Java primitive to other things needs to be boxed - return new NewAST(_kids,(XClz)_type); - } - if( _type==XCons.LONG ) { - // TODO: this needs to handle all flavors - if( _kids[0]._type==XCons.JUINT8 || - _kids[0]._type==XCons.JUINT32 ) - return new UniOpAST(new AST[]{_kids[0]},null,"._i",_type); - return new InvokeAST("toInt",XCons.LONG,_kids); - } - return null; - } - - @Override public SB jcode( SB sb ) { - _type.clz(sb.p("((")).p(")("); - return _kids[0].jcode(sb).p("))"); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/DefRegAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/DefRegAST.java deleted file mode 100644 index be52b8664a..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/DefRegAST.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.XEC; -import org.xvm.xtc.cons.*; -import org.xvm.xtc.*; -import org.xvm.util.S; -import org.xvm.util.SB; - -public class DefRegAST extends AST { - final String _name; - final String _init; - int _reg; // Register number - - static DefRegAST make( ClzBuilder X, boolean named, boolean initd ) { - Const init = initd ? X.con() : null; - Const type = X.con() ; - Const name = named ? X.con() : null; - return new DefRegAST(X,init,type,name); - } - private DefRegAST( ClzBuilder X, Const init, Const type, Const name ) { - super(null); - - // Destination is read first and is type-aware, so read the destination type. - _type = XType.xtype(type,false); - if( _type instanceof XClz clz ) - ClzBuilder.add_import(clz); - _name = name==null ? "$def"+(X._locals._len) : ClzBuilder.jname(((StringCon)name)._str); - - if( init instanceof AnnotTCon anno ) { - _init = XValue.val (anno); - _type = XType.xtype(anno,true); - - } else if( init != null ) { - throw XEC.TODO(); - } else { - _init = null; - } - - // At least Future redefines the type so save the AST architected type - // till after annotation processing - _reg = X.define(_name,_type); - } - public DefRegAST( XType type, String name, String init ) { super(null); _type=type; _name=name; _init=init; } - - @Override String name() { return _name; } - @Override XType _type() { return _type; } - - @Override void jpre( SB sb ) { - if( _type!=null ) _type.clz(sb); - sb.p(" ").p(_name); - if( _init != null ) sb.p(" = ").p(_init); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/DivRemAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/DivRemAST.java deleted file mode 100644 index daa40a0a85..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/DivRemAST.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.XEC; -import org.xvm.xtc.*; -import org.xvm.xtc.cons.ParamTCon; -import org.xvm.util.SB; -import org.xvm.util.S; -import org.xvm.xtc.cons.Const.BinOp; - -class DivRemAST extends AST { - final String _op; - final XType[] _rets; - - static DivRemAST make( ClzBuilder X ) { - AST[] kids = new AST[2]; - kids[0] = ast_term(X); - BinOp op = BinOp.OPS[X.u31()]; - kids[1] = ast_term(X); - XType[] rets = XType.xtypes(X.consts()); - return new DivRemAST(op.text,rets,kids); - } - - DivRemAST( String op, XType[] rets, AST... kids ) { - super(kids); - _op = op; - _rets = rets; - } - - @Override XType _type() { - if( _op.equals("is") ) - return XCons.BOOL; - throw XEC.TODO(); - } - - @Override public SB jcode(SB sb) { - if( _op.equals("is") ) { - if( _kids[1] instanceof ConAST con && con._tcon instanceof ParamTCon ) { - if( con._type==XCons.XXTC ) sb.p("true"); - else { - if( con._type==XCons.XXTC_RO ) sb.p("XTC.isa_ro"); - else _kids[1].jcode(sb).p(".isa"); - _kids[0].jcode(sb.p("(")).p(")"); - } - } else { - // TODO: check immutability - _kids[0].jcode(sb).p(" instanceof "); - _kids[1].jcode(sb); - } - return sb; - - } else - throw XEC.TODO(); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/DoWhileAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/DoWhileAST.java deleted file mode 100644 index c53e910c0c..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/DoWhileAST.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.util.SB; -import org.xvm.xtc.*; -import org.xvm.XEC; - -class DoWhileAST extends AST { - // _kids[0] == Condition - // _kids[1] == Body - // _kids[2+] == Specials - static DoWhileAST make( ClzBuilder X ) { - int nlocals = X.nlocals(); // Count of locals - // Specials Expr Ary, with room for conditon & body - AST[] kids = X.kids_bias(2); - kids[1] = ast(X); // Body - kids[0] = ast_term(X); // Condition - X.pop_locals(nlocals); // Pop scope-locals at end of scope - return new DoWhileAST(kids); - } - private DoWhileAST( AST[] kids ) { super(kids); } - - @Override boolean is_loopswitch() { return true; } - - @Override XType _type() { return XCons.VOID; } - - @Override public SB jcode( SB sb ) { - if( sb.was_nl() ) sb.i(); - sb.p("do {").ii().nl(); - _kids[1].jcode(sb); - sb.di().ip("} while("); - _kids[0].jcode(sb); - return sb.p(")"); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/ElvisAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/ElvisAST.java deleted file mode 100644 index 08f5e7b96b..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/ElvisAST.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.xvm.xtc.ast; - -import java.util.Arrays; -import java.util.HashMap; -import org.xvm.XEC; -import org.xvm.util.Ary; -import org.xvm.util.S; -import org.xvm.util.SB; -import org.xvm.xtc.*; - -// General Elvis Rule -// MultiAST -// e0 && e1 && e2 ... && en - -// Suppose e1 is AST tree with ELVIS(evar). e1 is typed boolean. -// "evar" is some expression with side effects. - -// If ELVIS is not a boolean, we need to insert a test and do e1 afterwards: -// e0 && (tmp=evar)!=null && e1[tmp/evar] && e2 ... && en -// Replacing evar with a tmp to avoid repeating side effects. -// If e1 has several ELVIS's, they all need to have their tests hoisted: -// e1 === foo(ELVIS(v1),ELVIS(v2),ELVIS(v3)) -// Then we get: -// e0 && (tmp1=v1)!=null && (tmp2=v2)!=null && (tmp3=v3)!=null && foo(tmp1,tmp2,tmp3) && e2 .... && en - -// If ELVIS typed boolean, then it must be directly being tested. -// The test e1 below might include {narrowing, TRACE, negate} at least. -// e0 && e1(ELVIS(evar)) && e2 && ... -// We need to replace with a null/zero test inline: -// e0 && e1(evar!=null) && e2 ... && en -// In this case no tmp and no separate test expression. - -abstract class ElvisAST extends AST { - - static class Elf { // Elvis tests to be inserted - int _idx; AST _var; String _tmp; - Elf(int idx, AST var, String tmp) { _idx=idx; _var=var; _tmp=tmp; } - public AST test() { - // Insert Elvis expression: - // A && (expr(elvis)) && C - // A && ((tmp=elvis)!=null) && expr(tmp) && C - AST reg = new RegAST(_tmp,_var._type); - AST asg = new AssignAST(reg,_var); - return new UniOpAST(new AST[]{asg}, - _var._cond ? "$t(" : "(", - _var._cond ? ") && XRuntime.$COND" : ")!=null", - XCons.BOOL); - } - } - Ary _elves; // Elvis variable list - - ElvisAST(AST[]kids) { super(kids); } - - // Some kind of expression: "expr0?.expr+expr.expr..." - // if( tmp=expr0)!=null ) tmp.expr+expr.expr.... - AST doElvis( AST elvis, AST old ) { - if( _elves==null ) _elves = new Ary<>(Elf.class); - // Drop the elvis buried inside the expression and return a tmp - String tmp = enclosing_block().add_tmp(elvis._type); - _elves.push(new Elf(S.find(_kids,old),elvis,tmp)); - return new RegAST(tmp,elvis._type); - } - - @Override public AST rewrite() { - if( _elves == null ) return null; - // Replacing: "...&& elvis(e0) && ..." - // With: "...&& e0!=null && ..." - // OR - needs an extra child slot - - // Replacing: "...&& (e1 elvis(e0)) && ..." - // With: "...&& (tmp=e0)!=null && (e1 tmp) && ..." - // - int xtra = 0; - for( Elf elf : _elves ) - if( elf._var._par != _kids[elf._idx] ) - xtra++; - if( xtra==0 ) - throw XEC.TODO(); - - AST[] kids = new AST[_kids.length+xtra]; - int i=0, j=0; - for( Elf elf : _elves ) { - // Copy, sliding over for extra slot - while( i _kids[0] instanceof ConAST ? null : new InvokeAST(_meth,XCons.STRING,new ConAST("Long",XCons.JLONG),_kids[0]).doType(); - case "toInt64", "toInt" -> _kids[0]; // Autoboxing in Java - case "toChar" -> new ConvAST(XCons.CHAR ,_kids[0]); - case "toInt8" -> new ConvAST(XCons.BYTE ,_kids[0]); - case "toInt16" -> new ConvAST(XCons.SHORT,_kids[0]); - case "toInt32" -> new ConvAST(XCons.INT ,_kids[0]); - // Invert the call for String; FROM 123L.appendTo(sb) TO sb.appendTo(123L) - case "appendTo" -> { S.swap(_kids,0,1); yield this; } - case "toUInt8" -> new BinOpAST( "&", "", XCons.LONG, _kids[0], new ConAST( "0xFFL",XCons.LONG )); - case "toUInt16" -> new BinOpAST( "&", "", XCons.LONG, _kids[0], new ConAST( "0xFFFFL",XCons.LONG )); - case "toUInt32" -> new BinOpAST( "&", "", XCons.LONG, _kids[0], new ConAST( "0xFFFFFFFFL",XCons.LONG )); - case "eq" -> this; //new BinOpAST( "==","", XCons.LONG, _kids ); - case "add" -> llbin( "+" ); - case "sub" -> llbin( "-" ); - case "mul" -> llbin( "*" ); - case "div" -> llbin( "/" ); - case "mod" -> llbin( "%" ); - case "and" -> llbin( "&" ); - case "or" -> llbin( "|" ); - case "xor" -> llbin( "^" ); - case "shiftLeft" -> llbin( "<<" ); - case "shiftRight" -> llbin( ">>" ); - case "shiftAllRight"-> llbin( ">>>" ); - case "to" -> BinOpAST.do_range( _kids, XCons.RANGEII ); - case "toEx" -> BinOpAST.do_range( _kids, XCons.RANGEIE ); - case "exTo" -> BinOpAST.do_range( _kids, XCons.RANGEEI ); - case "exToEx"->BinOpAST.do_range( _kids, XCons.RANGEEE ); - case "valueOf", "equals", "toInt128", "estimateStringLength", "abs" -> - new InvokeAST(_meth,_ret,new ConAST("org.xvm.xec.ecstasy.numbers.IntNumber",XCons.INTNUM),_kids[0]); - case "toDec64" -> new NewAST(new AST[]{_kids[0]},XCons.DEC64); - - default -> throw XEC.TODO(_meth); - }; - } - - // Handle the Float64 calls - if( k0t == XCons.JDOUBLE || k0t == XCons.DOUBLE ) { - return switch( _meth ) { - case "add" -> ddbin( "+" ); - default -> throw XEC.TODO(_meth); - }; - } - - // Handle all the Char to "char" calls - if( k0t == XCons.CHAR ) { - return switch( _meth ) { - case "add" -> new BinOpAST( "+", "", XCons.LONG, _kids ); - case "sub" -> new BinOpAST( "-", "", XCons.LONG, _kids ); - case "toInt64" -> _kids[0]; // no-op cast - case "asciiDigit" -> { - InvokeAST inv = new InvokeAST(_meth,_ret,new ConAST(XEC.XCLZ+".ecstasy.text.Char",XCons.JCHAR),_kids[0]); - inv._cond = true; - yield inv; - } - case "decimalValue", "quoted" -> - new InvokeAST(_meth,_ret,new ConAST(XEC.XCLZ+".ecstasy.text.Char",XCons.JCHAR),_kids[0]); - default -> throw XEC.TODO(_meth); - }; - } - - // XTC String calls mapped to Java String calls - if( k0t == XCons.STRING || k0t == XCons.STRINGN ) { - return switch( _meth ) { - case "toCharArray" -> _par._type== XCons.ARYCHAR ? new NewAST(_kids,XCons.ARYCHAR) : null; - case "appendTo" -> { - // Invert the call for String; FROM "abc".appendTo(sb) TO sb.appendTo("abc") - AST tmp = _kids[0]; _kids[0] = _kids[1]; _kids[1] = tmp; - yield null; - } - case "append", "add" -> new BinOpAST("+","", XCons.STRING, _kids); - // Change "abc".quoted() to e.text.String.quoted("abc") - case "quoted", "iterator" -> - new InvokeAST(_meth,_ret,new ConAST("org.xvm.xec.ecstasy.text.String",XCons.JSTRING),_kids[0]); - // The existing _fun has XTC.String arguments; we're using the Java - // function of the same name which expects bare Java.String, so we want - // to remove any "arguments need boxing", which is based on the _fun. - case "equals", "endsWith", "startsWith" -> { _fun = null; yield null; } - case "substring" -> { - _fun = null; - // Force offset math to be an integer - yield castInt(1) ? this : null; - } - - // Conditional and long index return - case "indexOf" -> { - AST call = new InvokeAST(_meth,_ret,new ConAST(XEC.XCLZ+".ecstasy.text.String",XCons.JSTRING),_kids[0],_kids[1],_kids[2]); - call._cond = true; - yield call; - } - case "slice" -> { - _slice_tmp = enclosing_block().add_tmp(ClzBuilder.add_import(XCons.RANGE)); - yield null; - } - case "split" -> - new InvokeAST(_meth,_ret,new ConAST(XEC.XCLZ+".ecstasy.text.String",XCons.JSTRING),_kids[0],_kids[1],_kids[2],_kids[3]); - default -> throw XEC.TODO(); - }; - } - - // Use fast primitive iterator - if( k0t.isa(XCons.ITERATOR) && _meth.equals("next") ) { - XType elem = k0t._xts[0]; - if( elem.isa(XCons.INTNUM ) ) _meth = "next8"; - else if( elem.isa(XCons.JCHAR ) ) _meth = "next2"; - else if( elem.isa(XCons.JSTRING) ) _meth = "nextStr"; - else return null; - return this; - } - - if( k0t instanceof XClz clz && clz.isTuple() ) { - switch( _meth ) { - case "slice": - BlockAST blk = enclosing_block(); - _slice_tmp = blk.add_tmp(_kids[0]._type); - break; - case "TRACE": break; - case "add": break; - default: throw XEC.TODO(); - } - } - - // Unbox boxed arguments as needed - AST progress = null; - if( _fun != null ) - for( int i=0; i<_fun.nargs(); i++ ) - if( _fun.arg(i) instanceof XBase && !(_kids[i+1]._type instanceof XBase) ) - progress = _kids[i+1] = _kids[i+1].unBoxThis(); - if( progress != null ) return this; - - return null; - } - - private BinOpAST llbin(String op) { - if( _type == XCons.INT ) { - castInt(0); - castInt(1); - return new BinOpAST( op, "", XCons.INT, _kids ); - } - return _type==XCons.LONG ? new BinOpAST( op, "", XCons.LONG, _kids ) : null; - } - private BinOpAST ddbin(String op) { - return _type==XCons.DOUBLE ? new BinOpAST( op, "", XCons.DOUBLE, _kids ) : null; - } - - @Override public AST reBox( ) { - if( _fun==null ) return null; // Baked-in, should be good already - // Internal Java-implemented mirror type; these - // all have primitive versions, no need to reBox. - if( _kids[0]._type instanceof XClz xclz && !xclz._jname.isEmpty() ) - return null; - AST progress=null; - for( int i = 1; i < _kids.length; i++ ) { - if( _kids[i]._type instanceof XBase kbase && kbase != XCons.NULL && - !(_fun.arg(i-1) instanceof XBase) ) - progress = _kids[i] = _kids[i].reBoxThis(); - } - return progress==null ? null : this; - } - - @Override public SB jcode( SB sb ) { - if( sb.was_nl() ) sb.i(); - - // Sharp tuple slices are special in all kinds of ways. - // I have to explode the fields directly. - if( _meth.equals("slice") && _type instanceof XClz clz && clz.isTuple() ) { - assert _kids[1] instanceof NewAST && _kids[1]._type.isa(XCons.RANGE); - AbstractRange rng = AbstractRange.range(_kids[1]); - // new Tuple((tmp=kid0)._f2,tmp._f3,tmp._f4); - sb.p("new "); - clz.clz(sb); - sb.p("((").p(_slice_tmp).p(" = "); - _kids[0].jcode(sb); - sb.p(")"); - for( long i=rng._start; i0 && _kids[0]._type == XCons.VOID ) - return new ListAST(null,_type,_tuple); // Replace void with no-kids - return null; - } - - @Override void jpre( SB sb ) { - if( !_tuple ) throw XEC.TODO(); - _type.clz(sb.p("new ")).p("( "); - } - @Override void jmid( SB sb, int i ) { sb.p(", "); } - @Override void jpost( SB sb ) { sb.unchar(2).p(")"); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/MapAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/MapAST.java deleted file mode 100644 index ee7ca9ae44..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/MapAST.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.util.SB; -import org.xvm.XEC; -import org.xvm.xtc.cons.Const; -import org.xvm.xtc.*; - -class MapAST extends AST { - static MapAST make( ClzBuilder X) { - Const type = X.con(); - XClz tmap = (XClz)XType.xtype(type,false); - AST[] keys = X.kids(); - AST[] vals = X.kids(); - AST[] kids = new AST[keys.length<<1]; - for( int i=0; i() {{").nl().ii(); - for( int i=0; i<_kids.length; i+= 2 ) { - sb.ip("put("); - _kids[i+0].jcode(sb); - sb.p(","); - _kids[i+1].jcode(sb); - sb.p(");").nl(); - } - return sb.di().ip("}}"); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/ast/MultiAST.java b/javatools_backend/src/main/java/org/xvm/xtc/ast/MultiAST.java deleted file mode 100644 index 8134b2b409..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/ast/MultiAST.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.xvm.xtc.ast; - -import org.xvm.XEC; -import org.xvm.util.Ary; -import org.xvm.util.S; -import org.xvm.util.SB; -import org.xvm.xtc.*; - -public class MultiAST extends ElvisAST { - final boolean _expr; - static MultiAST make( ClzBuilder X, boolean expr) { - int len = X.u31(); - AST[] kids = new AST[len]; - for( int i=0; i

- * Note: In addition to resolving typedefs, this method is also used to resolve any - * {@link UnresolvedNameConstant}s used by any structure during the registration phase. - * - * @return this same type, but without any typedefs or resolvable {@link UnresolvedNameConstant}s in it - */ - public Const resolveTypedefs() { return this; } - - // -------- Format ---------------------------------------------------------- - - public enum Format { - IntLiteral("numbers"), - Bit ("numbers"), - Nibble ("numbers"), - Int8 ("numbers"), - Int16 ("numbers"), - Int32 ("numbers"), - Int64 ("numbers"), - Int128 ("numbers"), - IntN ("numbers"), - UInt8 ("numbers"), - UInt16 ("numbers"), - UInt32 ("numbers"), - UInt64 ("numbers"), - UInt128 ("numbers"), - UIntN ("numbers"), - FPLiteral ("numbers"), - Dec32 ("numbers"), - Dec64 ("numbers"), - Dec128 ("numbers"), - DecN ("numbers"), - Float8e4 ("numbers"), - Float8e5 ("numbers"), - BFloat16 ("numbers"), - Float16 ("numbers"), - Float32 ("numbers"), - Float64 ("numbers"), - Float128 ("numbers"), - FloatN ("numbers"), - Char ("text"), - String ("text"), - RegEx ("text"), - Date, // ISO8601 YYYY-MM-DD date format - TimeOfDay, // ISO8601 HH:MM[:SS[.sssssssss]]['Z' | ('+'|'-')hh[:mm]] format - TimeZone, // ISO8601 ['Z' | ('+'|'-')hh[:mm]] format - Time, // ISO8601 date ['T' time] format - Duration, // ISO8601 P[n]Y[n]M[n]DT[n]H[n]M[n]S | P[n]W format - Version ("reflect"), - SingletonConst, // identity constant for a Module, Package, or a static const - EnumValueConst, // identity constant for an enum value - SingletonService, // identity constant of a Service class - Tuple ("collections"), - Array ("collections"), - UInt8Array, // byte[] - Set ("collections"), - MapEntry ("collections"), - Map ("collections"), - Range, - RangeInclusive, - RangeExclusive, - Any, - Path ("fs"), - FileStore ("fs"), - FSDir ("fs"), - FSFile ("fs"), - FSLink ("fs"), - ResponseSender ("http"), - - /* - * Structural identifiers. - */ - Module, - Package, - Class, - Typedef, - Property, - MultiMethod, - Method, - Annotation, - - /* - * FrameDependent (run-time aware) identifiers. - */ - Register, - BindTarget, - - /* - * Pseudo identifiers. - */ - UnresolvedName, - DeferredValue, - ThisClass, - ParentClass, - ChildClass, - TypeParameter, - FormalTypeChild, - DynamicFormal, - Signature, - DecoratedClass, - NativeClass, - IsConst, - IsEnum, - IsModule, - IsPackage, - IsClass, - - /* - * Types. - */ - UnresolvedType, - TerminalType, - ImmutableType, - ServiceType, - AccessType, - AnnotatedType, - ParameterizedType, - TurtleType, - VirtualChildType, - InnerChildType, - AnonymousClassType, - PropertyClassType, - IntersectionType, - CastType, - UnionType, - DifferenceType, - RecursiveType, - - /* - * Conditions. - */ - ConditionNot, - ConditionAll, - ConditionAny, - ConditionNamed, - ConditionPresent, - ConditionVersionMatches, - ConditionVersioned; - - Format() { this(null); } - Format(String sPackage) { _package = sPackage; } - - /** - * Look up a Format enum by its ordinal, without exposing the values array. - * @param i the ordinal - * @return the Format enum for the specified ordinal - */ - public static Format valueOf(int i) { return FORMATS[i]; } - /** All the Format enums in an ordinal array. */ - private static final Format[] FORMATS = Format.values(); - - /** The package name. */ - private final String _package; - } - - - // ----- accessibility levels ------------------------------------------------------------------ - /** - * The Access enumeration refers to the level of accessibility to a class that a reference will have: - *

    - *
  • {@link #STRUCT STRUCT} - direct access to the underlying data structure (but only to the data structure);
  • - *
  • {@link #PUBLIC PUBLIC} - access to the public members of the object's class;
  • - *
  • {@link #PROTECTED PROTECTED} - access to the protected members of the object's class;
  • - *
  • {@link #PRIVATE PRIVATE} - access to the private members of the object's class;
  • - *
- */ - public enum Access { - STRUCT (0), - PUBLIC ( Part.ACCESS_PUBLIC ), - PROTECTED( Part.ACCESS_PROTECTED), - PRIVATE ( Part.ACCESS_PRIVATE ); - - Access(int flags) { this.FLAGS = flags; } - - public static Access valueOf(int i) { return VALUES[i]; } - private static final Access[] VALUES = Access.values(); - - /** - * The integer flags used to encode the access enum. - * @see Part#ACCESS_MASK - * @see Part#ACCESS_SHIFT - * @see Part#ACCESS_PUBLIC - * @see Part#ACCESS_PROTECTED - * @see Part#ACCESS_PRIVATE - */ - public final int FLAGS; - } - - /** - * The qualified name of the Ecstasy core module. This is the only module that has no external - * dependencies (other than a conceptual dependency in the compiler on the prototype module, - * due to the "turtles" problem of Ref.x having properties which are themselves refs). - */ - public static final String ECSTASY_MODULE = "ecstasy.xtclang.org"; - - // ----- NodeType ----------------------------------------------------------- - // Clone of javatools/org.xvm.asm.ast.BinaryAST.NodeType; - public enum NodeType { - None, // 00: - PropertyExpr, // 01: property access - InvokeExpr, // 02: foo() (method) (foo is a const) - CondOpExpr, // 03: "||", "&&", "^^" - Less, // 04: "<" - Greater, // 05: ">" - Assign, // 06: x=y; - NamedRegAlloc, // 07: int x; (classified as an expression to simplify "l-value" design) - RelOpExpr, // 08: "&&", "||", "^", etc. - NarrowedExpr, // 09: - UnaryOpExpr, // 0A: "+", "-", etc. - NewExpr, // 0B: - ThrowExpr, // 0C: - CallExpr, // 0D: foo() (function) (foo is a register/property) - ArrayAccessExpr, // 0E: x[i] - BinOpAssign, // 0F: x*=y; etc. - TernaryExpr, // 10: x ? y : z - OuterExpr, // 11: - NotExpr, // 12: !x - MultiExpr, // 13: (expr1, expr2, ...) - BindFunctionExpr, // 14: bind function's arguments - DivRemExpr, // 15: x /% y - BindMethodExpr, // 16: bind method's target - NotNullExpr, // 17: x? - ConvertExpr, // 18: - TemplateExpr, // 19: - NewChildExpr, // 1A: - TupleExpr, // 1B: - CmpChainExpr, // 1C: x < y <= z, etc. - UnpackExpr, // 1D: - SwitchExpr, // 1E: s = switch () {...} - Escape, // 1F: reserved #31: followed by NodeType ordinal as unsigned byte - NewVirtualExpr, // - ListExpr, // - AnnoRegAlloc, // same as RegAlloc, but annotated - AnnoNamedRegAlloc, // same as NamedRegAlloc, but annotated - RegAlloc, // int _; (classified as an expression to simplify "l-value" design) - RegisterExpr, // _ (unnamed register expr) - InvokeAsyncExpr, // foo^() (method) (foo is a const) - CallAsyncExpr, // foo^() (function) (foo is a register/property) - IsExpr, // x.is(y) - NegExpr, // -x - BitNotExpr, // ~x - PreIncExpr, // --x - PreDecExpr, // ++x - PostIncExpr, // x-- - PostDecExpr, // x++ - RefOfExpr, // &x - VarOfExpr, // &x - ConstantExpr, // - MapExpr, // - StmtExpr, // - NotCond, // if (!(String s ?= foo())){...} TODO - NotNullCond, // if (String s ?= foo()){...} TODO - NotFalseCond, // if (String s := bar()){...} TODO - MatrixAccessExpr, // x[i, j] TODO - AssertStmt, // - StmtBlock, // {...}, do{...}while(False); etc. - MultiStmt, // - IfThenStmt, // if(cond){...} - IfElseStmt, // if(cond){...}else{...} - SwitchStmt, // switch(cond){...} - LoopStmt, // while(True){...} etc. - WhileDoStmt, // while(cond){...} - DoWhileStmt, // do{...}while(cond); - ForStmt, // for(init,cond,next){...} - ForIteratorStmt, // for(var v : iterator){...} - ForRangeStmt, // for(var v : range){...} - ForListStmt, // for(var v : list){...} - ForMapStmt, // for((var k, var v)) : map){...} etc. - ForIterableStmt, // for(var v : iterable){...} - ContinueStmt, // continue; or continue Label; - BreakStmt, // break; or break Label; - Return0Stmt, // return; - Return1Stmt, // return expr; - ReturnNStmt, // return expr, expr, ...; - ReturnTStmt, // return (expr, expr, ...); - TryCatchStmt, // using(res){...}, try(res){...} [catch(T e){...}] - TryFinallyStmt, // try{...} [catch(T e){...}] finally{...} - InitAst, // default initializer TODO move higher? - ; - public static final NodeType[] NODES = NodeType.values(); - } - - // Clone of javatools/org.xvm.asm.ast.BiExprAST.Operator - public enum BinOp { - Else (":" ), // an "else" for nullability checks - CondElse ("?:" ), // the "elvis" operator - CondOr ("||" ), - CondXor ("^^" ), - CondAnd ("&&" ), - BitOr ("|" ), - BitXor ("^" ), - BitAnd ("&" ), - CompEq ("==" ), - CompNeq ("!=" ), - CompLt ("<" ), - CompGt (">" ), - CompLtEq ("<=" ), - CompGtEq (">=" ), - CompOrd ("<=>" ), - As ("as" ), - Is ("is" ), - RangeII (".." ), - RangeIE ("..<" ), - RangeEI (">.." ), - RangeEE (">..<"), - Shl ("<<" ), - Shr (">>" ), - Ushr (">>>" ), - Add ("+" ), - Sub ("-" ), - Mul ("*" ), - Div ("/" ), - Mod ("%" ), - DivRem ("/%" ), - ; - public final String text; - BinOp(String text) { this.text = text; } - public static final BinOp[] OPS = BinOp.values(); - } - - // Clone of javatools/org.xvm.asm.ast.UnaryOpExprAST.Operator - public enum UniOp { - Not ("!" , true ), - Minus ("-" , true ), - Compl ("~" , true ), - PreInc ("++" , true ), - PreDec ("--" , true ), - PostInc ("++" , false), - PostDec ("--" , false), - Ref ("&" , true ), - Var ("&" , true ), - Type ("typeOf:" , true ), - Private ("private:", true ), - Protected ("private:", true ), - Public ("public:" , true ), - Pack ("" , true ), - ToInt (".TOINT()", false), - Trace (".TRACE()", false), - ; - public final String text; - public final boolean pre; - UniOp(String text, boolean pre) { this.text = text; this.pre = pre; } - public static final UniOp[] OPS = UniOp.values(); - } - - // Clone of javatools/org.xvm.asm.ast.AssignAST.Operator - public enum AsnOp { - Asn ("=" , false), // includes "<-" expression - AddAsn ("+=" , true ), - SubAsn ("-=" , true ), - MulAsn ("*=" , true ), - DivAsn ("/=" , true ), - ModAsn ("%=" , true ), - ShiftLAsn ("<<=" , true ), - ShiftRAsn (">>=" , true ), - UShiftRAsn (">>>=", true ), - AndAsn ("&=" , true ), - OrAsn ("|=" , true ), - XorAsn ("^=" , true ), - AsnIfNotFalse (":=" , false), // x := y; (includes when used as a condition, e.g. if (x := y)) - AsnIfNotNull ("?=" , false), // x ?= y; (includes when used as a condition, e.g. if (x := y)) - AsnIfWasTrue ("&&=" , false), - AsnIfWasFalse ("||=" , false), - AsnIfWasNull ("?:=" , false), - Deref ("->" , false), - ; - public final String text; - public final boolean _meth; // Has a MethodCon in the BAST - AsnOp(String text, boolean meth) { this.text = text; _meth = meth; } - public static final AsnOp[] OPS = AsnOp.values(); - } - - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/Dec128Con.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/Dec128Con.java deleted file mode 100644 index 957d52215f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/Dec128Con.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.math.MathContext; - -/** - Exploring XEC Constants - */ -public class Dec128Con extends DecCon { - public final long _dec1; - public Dec128Con( CPool X ) { - super( X.i64()); - _dec1 = X.i64(); - } - - @Override BigDecimal _bd() { return toBigDecimal128(_dec0,_dec1); } - - /** - * @return the significand of the decimal as a Java BigInteger - */ - public static BigInteger getSignificand(long hi, long lo) { - // get the first digit (most significant digit) - int nToG4 = (int) (hi >>> G4_SHIFT); - int nD0 = (nToG4 & 0b011000) == 0b011000 - ? (nToG4 & 0b000001) + 8 - : (nToG4 & 0b000111); - - // keep only the T portion of the high bits (the low bits are all part of the T portion) - hi &= LS46BITS; - - // process the remainder of the T portion in the high bits (except for the last 6 bits that - // overflowed from the low bits) - long nHSig = nD0; - if (nHSig != 0 || hi != 0) { - for (int of = 36; of >= 0; of -= 10) { - nHSig = nHSig * 1000 + decletToInt((int) (hi >>> of)); - } - } - - // process the T portion in the low bits (including the 6 LSBs of the high bits) - long nLSig = 0; - if (nHSig != 0 || lo != 0) { - // grab the 6 bits from the 7th declet that overflowed to the "high bits" long, and - // combine those with the highest 4 bits from the "low bits" long - nHSig = nHSig * 1000 + decletToInt((int) ((hi << 4) | (lo >>> 60))); - - for (int of = 50; of >= 0; of -= 10) { - nLSig = nLSig * 1000 + decletToInt((int) (lo >>> of)); - } - } - - // put the digits from the low and high bits together to form the full significand - BigInteger bintL = nLSig == 0 ? BigInteger.ZERO : BigInteger.valueOf(nLSig); - return nHSig == 0 ? bintL : BigInteger.valueOf(nHSig).multiply(BIGINT_10_TO_18TH).add(bintL); - } - - /** - * @return the exponent of the decimal as a Java int - */ - public static int getExponent( long hi ) { - // combination field is 17 bits (from bit 46 to bit 62), including 12 "pure" exponent bits - int nCombo = (int) (hi >>> 46); - int nExp = (nCombo & 0b0_11000_000000000000) == 0b0_11000_000000000000 - ? (nCombo & 0b0_00110_000000000000) >>> 1 - : (nCombo & 0b0_11000_000000000000) >>> 3; - - // pull the rest of the exponent bits out of "pure" exponent section of the combo bits - // section, and unbias the exponent - return (nExp | nCombo & 0xFFF) - 6176; - } - - /** - * Convert the bits of an IEEE 754 decimal to a Java BigDecimal. - * @param nBits a 128-bit value containing an IEEE 754 decimal - * @return a Java BigDecimal - */ - public static BigDecimal toBigDecimal128(long hi, long lo) { - ensureFiniteHighBits(hi); // Throw if not finite - BigDecimal dec = new BigDecimal(getSignificand(hi,lo), -getExponent(hi), MathContext.DECIMAL128); - return (hi<0) ? dec.negate() : dec; - } - - /** - * Test the passed high 64 bits of a 128-bit decimal to ensure that they are finite; if they are - * not, throw an exception. - * @param hi the high 64 bits of a 128-bit IEEE-754-2008 decimal value - * @throws NumberFormatException if the decimal is either a NaN or an Infinity value - */ - private static void ensureFiniteHighBits(long hi) { - if( (hi & G0_G3_MASK) == G0_G3_MASK ) - throw new NumberFormatException("Not a finite value"); - } - - - /** One million million (10^18), in a BigInteger format. */ - private static final BigInteger BIGINT_10_TO_18TH = new BigInteger("1000000000000000000"); - - /** The least significant 46 bits. */ - private static final long LS46BITS = 0x3FFFFFFFFFFFL; - - /** The amount to shift the G3 bit in the high 64 bits of a 128-bit IEEE 754 decimal. */ - private static final int G3_SHIFT = 59; - /** The bit mask for the G0-G3 bits of the high 64 bits of a 128-bit IEEE 754 decimal. */ - private static final long G0_G3_MASK = 0b1111L << G3_SHIFT; - /** The amount to shift the G4 bit in the high 64 bits of a 128-bit IEEE 754 decimal */ - private static final int G4_SHIFT = 58; -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/Dec32Con.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/Dec32Con.java deleted file mode 100644 index d3f1f3a245..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/Dec32Con.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.math.MathContext; - -/** - Exploring XEC Constants - */ -public class Dec32Con extends DecCon { - public Dec32Con( CPool X ) { - super(X.i32()); - } - - @Override BigDecimal _bd() { return toBigDecimal32((int)_dec0); } - - /** - * Test the passed bits to ensure that they are finite; if they are not, throw an exception. - * @param nBits the 32-bit IEEE-754-2008 decimal value - * @return a finite 32-bit IEEE-754-2008 decimal value - * @throws NumberFormatException if the decimal is either a NaN or an Infinity value - */ - public static int ensureFiniteBits(int nBits) { - if ((nBits & G0_G3_MASK) == G0_G3_MASK) - throw new NumberFormatException("Not a finite value"); - return nBits; - } - - /** - * Convert the bits of an IEEE 754 decimal to a Java BigDecimal. - * @param nBits a 32-bit value containing an IEEE 754 decimal - * @return a Java BigDecimal - */ - public static BigDecimal toBigDecimal32(int nBits) { - ensureFiniteBits(nBits); - - // combination field is 11 bits (from bit 20 to bit 30), including 6 "pure" exponent bits - int nCombo = nBits >>> 20; - int nExp = nCombo & 0b111111; - int nSig; - - // test G0 and G1 - if ((nCombo & 0b011000000000) == 0b011000000000) { - // when the most significant five bits of G are 110xx or 1110x, the leading significand - // digit d0 is 8+G4, a value 8 or 9, and the leading biased exponent bits are 2*G2 + G3, - // a value of 0, 1, or 2 - nExp |= ((nCombo & 0b000110000000) >>> 1); // shift right 7, but then shift left 6 - nSig = ((nCombo & 0b000001000000) >>> 6) + 8; - } else { - // when the most significant five bits of G are 0xxxx or 10xxx, the leading significand - // digit d0 is 4*G2 + 2*G3 + G4, a value in the range 0 through 7, and the leading - // biased exponent bits are 2*G0 + G1, a value 0, 1, or 2; consequently if T is 0 and - // the most significant five bits of G are 00000, 01000, or 10000, then the value is 0: - // v = (-1) S * (+0) - nExp |= (nCombo & 0b011000000000) >>> 3; // shift right 9, but then shift left 6 - nSig = (nCombo & 0b000111000000) >>> 6; - } - - // unbias the exponent - nExp -= 101; - - // unpack the digits from most significant declet to least significan declet - nSig = ((nSig * 1000 + decletToInt(nBits >>> 10)) - * 1000 + decletToInt(nBits )) - * (((nBits & SIGN_BIT) >> 31) | 1); // apply sign - - return new BigDecimal(BigInteger.valueOf(nSig), -nExp, MathContext.DECIMAL32); - } - - /** The sign bit for a 32-bit IEEE 754 decimal. */ - private static final int SIGN_BIT = 0x80000000; - - /** The amount to shift the G3 bit of a 32-bit IEEE 754 decimal. */ - private static final int G3_SHIFT = 27; - - /** The bit mask for the G0-G3 bits of a 32-bit IEEE 754 decimal. */ - private static final int G0_G3_MASK = 0b1111 << G3_SHIFT; - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/Dec64Con.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/Dec64Con.java deleted file mode 100644 index a548b0854e..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/Dec64Con.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.math.MathContext; - -/** - Exploring XEC Constants - */ -public class Dec64Con extends DecCon { - public Dec64Con( long dec64 ) { super(dec64); } - public Dec64Con( CPool X ) { this(X.i64()); } - - - @Override BigDecimal _bd() { return toBigDecimal64(_dec0); } - - /** - * Test the passed bits to ensure that they are finite; if they are not, throw an exception. - * @param nBits the 32-bit IEEE-754-2008 decimal value - * @return a finite 32-bit IEEE-754-2008 decimal value - * @throws NumberFormatException if the decimal is either a NaN or an Infinity value - */ - public static long ensureFiniteBits(long nBits) { - if ((nBits & G0_G3_MASK) == G0_G3_MASK) - throw new NumberFormatException("Not a finite value"); - return nBits; - } - - /** - * Convert a Java BigDecimal to an IEEE 754 64-bit decimal. - * @param dec a Java BigDecimal value - * @return a Java long that contains a 64-bit IEEE 754 decimal value - * @throws RangeException if the value is out of range - */ - public static long toLongBits(BigDecimal dec) { - dec = dec.round(MathContext.DECIMAL64); - - // obtain the significand - long nSig = dec.unscaledValue().longValueExact(); - if (nSig < -9999999999999999L || nSig > 9999999999999999L) - throw new ArithmeticException("significand is >16 digits: " + nSig); - - // bias the exponent (the scale is basically a negative exponent) - int nExp = 398 - dec.scale(); - if (nExp < 0 || nExp >= 768) - throw new ArithmeticException("biased exponent is out of range [0,768): " + nExp); - - long nBits = 0; - if (nSig < 0) - { nBits = SIGN_BIT; nSig = -nSig; } - - // store the least significant 8 bits of the exponent into the combo field starting at G5 - // store the least significant 15 decimal digits of the significand in 5 10-bit declets in T - int nLeft = (int) (nSig / 1_000_000_000L); - int nRight = (int) (nSig % 1_000_000_000L); - nBits |= (((long) (nExp & 0xFF) ) << 50) - | (((long) intToDeclet(nLeft / 1_000 % 1000)) << 40) - | (((long) intToDeclet(nLeft % 1000)) << 30) - | (((long) intToDeclet(nRight / 1_000_000 % 1000)) << 20) - | (((long) intToDeclet(nRight / 1_000 % 1000)) << 10) - | (((long) intToDeclet(nRight % 1000)) ); - - // remaining significand of 8 or 9 is stored in G4 as 0 or 1, with remaining exponent stored - // in G2-G3, and G0-G1 both set to 1; otherwise, remaining significand (3 bits) is stored in - // G2-G4 with remaining exponent stored in G0-G1 - int nSigRem = nLeft / 1_000_000; - int nGBits = nSigRem >= 8 // G01234 - ? (0b11000 | (nSigRem & 0b00001) | ((nExp & 0b11000_00000) >>> 7)) - : ( (nSigRem & 0b00111) | ((nExp & 0b11000_00000) >>> 5)); - - return nBits | ((long) nGBits) << G4_SHIFT; - } - - /** - * Convert the bits of an IEEE 754 decimal to a Java BigDecimal. - * @param nBits a 64-bit value containing an IEEE 754 decimal - * @return a Java BigDecimal - */ - public static BigDecimal toBigDecimal64(long nBits) { - ensureFiniteBits(nBits); - - // combination field is 13 bits (from bit 50 to bit 62), including 8 "pure" exponent bits - int nCombo = (int) (nBits >>> 50); - int nExp = nCombo & 0xFF; - long nSig; - - // test G0 and G1 - if( (nCombo & 0b0_11000_00000000) == 0b0_11000_00000000 ) { - // when the most significant five bits of G are 110xx or 1110x, the leading significand - // digit d0 is 8+G4, a value 8 or 9, and the leading biased exponent bits are 2*G2 + G3, - // a value of 0, 1, or 2 - nExp |= ((nCombo & 0b0_00110_00000000) >>> 1); // shift right 9, but then shift left 8 - nSig = ((nCombo & 0b0_00001_00000000) >>> 8) + 8; - } else { - // when the most significant five bits of G are 0xxxx or 10xxx, the leading significand - // digit d0 is 4*G2 + 2*G3 + G4, a value in the range 0 through 7, and the leading - // biased exponent bits are 2*G0 + G1, a value 0, 1, or 2; consequently if T is 0 and - // the most significant five bits of G are 00000, 01000, or 10000, then the value is 0: - // v = (-1) S * (+0) - nExp |= (nCombo & 0b0_11000_00000000) >>> 3; // shift right 11, but then shift left 8 - nSig = (nCombo & 0b0_00111_00000000) >>> 8; - } - // unbias the exponent - nExp -= 398; - - // unpack the digits from most significant declet to least significant declet - nSig = (((((nSig * 1000 + decletToInt((int) (nBits >>> 40))) - * 1000 + decletToInt((int) (nBits >>> 30))) - * 1000 + decletToInt((int) (nBits >>> 20))) - * 1000 + decletToInt((int) (nBits >>> 10))) - * 1000 + decletToInt((int) (nBits ))) - * (((nBits & SIGN_BIT) >> 63) | 1); // apply sign - - return new BigDecimal(BigInteger.valueOf(nSig), -nExp, MathContext.DECIMAL64); - } - - /** The sign bit for a 64-bit IEEE 754 decimal. */ - private static final long SIGN_BIT = 1L << 63; - - /** The amount to shift the G3 bit of a 64-bit IEEE 754 decimal. */ - private static final int G3_SHIFT = 59; - - /** The bit mask for the G0-G3 bits of a 64-bit IEEE 754 decimal. */ - private static final long G0_G3_MASK = 0b1111L << G3_SHIFT; - - /** The amount to shift the G4 bit of a 64-bit IEEE 754 decimal. */ - private static final int G4_SHIFT = 58; - - /** The value for the G0-G4 bits of a 64-bit IEEE 754 decimal that indicate - that the decimal value is "Not a Number" (NaN). */ - private static final long G0_G4_NAN = 0b11111L << G4_SHIFT; - - /** The value for the G0-G4 bits of a 64-bit IEEE 754 decimal that indicate - that the decimal value is infinite. */ - private static final long G0_G4_INF = 0b11110L << G4_SHIFT; - - /** The amount to shift the G5 bit of a 64-bit IEEE 754 decimal. */ - private static final int G5_SHIFT = 57; - - /** The value of the G5 bit that indicates that a 64-bit IEEE 754 decimal is - a signaling NaN, if the decimal is a NaN. */ - private static final long G5_SIGNAL = 1L << G5_SHIFT; - - /** The decimal value for zero. */ - public static final Dec64Con POS_ZERO = new Dec64Con(0x2238000000000000L); - - /** The decimal value for negative zero. */ - public static final Dec64Con NEG_ZERO = new Dec64Con(0xA238000000000000L); - - /** The decimal value for positive one (1). */ - public static final Dec64Con POS_ONE = new Dec64Con(0x2238000000000001L); - - /** The decimal value for negative one (-1). */ - public static final Dec64Con NEG_ONE = new Dec64Con(0xA238000000000001L); - - /** The decimal value for a "quiet" Not-A-Number (NaN). */ - public static final Dec64Con NaN = new Dec64Con(G0_G4_NAN); - - /** The decimal value for a signaling Not-A-Number (NaN). */ - public static final Dec64Con SNaN = new Dec64Con(G0_G4_NAN | G5_SIGNAL); - - /** The decimal value for positive infinity. */ - public static final Dec64Con POS_INFINITY = new Dec64Con(G0_G4_INF); - - /** The decimal value for negative infinity. */ - public static final Dec64Con NEG_INFINITY = new Dec64Con(SIGN_BIT | G0_G4_INF); -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/DecACon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/DecACon.java deleted file mode 100644 index 01f3007d2a..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/DecACon.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; - -/** - Exploring XEC Constants - */ -public class DecACon extends TCon { - private DecCon _dec; - public DecACon( CPool X ) { X.u31(); } - @Override public void resolve( CPool X ) { _dec = (DecCon)X.xget(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/DecClzCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/DecClzCon.java deleted file mode 100644 index 110c2d3f4f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/DecClzCon.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class DecClzCon extends Const implements IdCon { - private TCon _type; - public DecClzCon( CPool X ) { X.u31(); } - @Override public String name() { throw XEC.TODO(); } - @Override public void resolve( CPool X ) { _type = (TCon)X.xget(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/DecCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/DecCon.java deleted file mode 100644 index aca000c365..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/DecCon.java +++ /dev/null @@ -1,210 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.math.MathContext; - -/** - Exploring XEC Constants - */ -public abstract class DecCon extends TCon { - public final long _dec0; - private BigDecimal _bd; - - public DecCon( long dec ) { _dec0 = dec; } - - BigDecimal bd() { return _bd==null ? (_bd=_bd()) : _bd; } - abstract BigDecimal _bd(); - - public String asStr() { return bd().toString(); } - - /** - * Convert the three least significant decimal digits of the passed integer value to a declet. - *

- * Details are in IEEE 754-2008 section 3.5.2, table 3.4. - * - * @param nDigits the int value containing the digits - * - * @return a declet - */ - public static int intToDeclet(int nDigits) - { - return digitsToDeclet((nDigits / 100) % 10, (nDigits / 10) % 10, nDigits % 10); - } - - /** - * Convert three decimal digits to a declet. - *

- * Details are in IEEE 754-2008 section 3.5.2, table 3.4. - * - * @param d1 4-bit value "d1" from table 3.4 (most significant digit) - * @param d2 4-bit value "d2" from table 3.4 - * @param d3 4-bit value "d3" from table 3.4 (least significant digit) - * - * @return a declet - */ - public static int digitsToDeclet(int d1, int d2, int d3) - { - switch ((d1 & 0b1000) >>> 1 | (d2 & 0b1000) >>> 2 | (d3 & 0b1000) >>> 3) - { - // table 3.4 (const 1's) - // d1.0 d2.0 d3.0 b0123456789 b0 b1 b2 b3 b4 b5 b7 b8 b9 - // -------------- ------------ ------------------------------ ------------------------------ ---------- - case 0b000: return 0b0000000000 | (d1 & 0b111) << 7 | (d2 & 0b111) << 4 | d3 & 0b111; - case 0b001: return 0b0000001000 | (d1 & 0b111) << 7 | (d2 & 0b111) << 4 | d3 & 0b001; - case 0b010: return 0b0000001010 | (d1 & 0b111) << 7 | (d3 & 0b110 | d2 & 0b001) << 4 | d3 & 0b001; - case 0b011: return 0b0001001110 | (d1 & 0b111) << 7 | (d2 & 0b001) << 4 | d3 & 0b001; - case 0b100: return 0b0000001100 | (d3 & 0b110 | d1 & 0b001) << 7 | (d2 & 0b111) << 4 | d3 & 0b001; - case 0b101: return 0b0000101110 | (d2 & 0b110 | d1 & 0b001) << 7 | (d2 & 0b001) << 4 | d3 & 0b001; - case 0b110: return 0b0000001110 | (d3 & 0b110 | d1 & 0b001) << 7 | (d2 & 0b001) << 4 | d3 & 0b001; - case 0b111: return 0b0001101110 | (d1 & 0b001) << 7 | (d2 & 0b001) << 4 | d3 & 0b001; - - default: - throw new IllegalArgumentException("d1=" + d1 + ", d2=" + d2 + ", d3=" + d3); - } - } - - /** - * Convert the passed declet to three decimal digits, and return each of them in the three least - * significant bytes of a Java int. - *

- * Details are in IEEE 754-2008 section 3.5.2, table 3.3. - * - * @param nBits a declet - * - * @return three decimal digits in a Java int, such that bits 0-7 contain the least - * significant digit, bits 8-15 the second, and bits 16-23 the most significant digit - */ - public static int decletToDigits(int nBits) - { - // b6 b7 b8 b3 b4 - switch ((nBits & 0b1110) << 1 | (nBits & 0b1100000) >>> 5) - { - // 0xxxx b0123456789 - default: - return 256 * ( ((nBits & 0b1110000000) >>> 7)) + // d1 = b0 b1 b2 - 16 * ( ((nBits & 0b0001110000) >>> 4)) + // d2 = b3 b4 b5 - ( ((nBits & 0b0000000111) )); // d3 = b7 b8 b9 - // 100xx - case 0b10000: - case 0b10001: - case 0b10010: - case 0b10011: - return 256 * ( ((nBits & 0b1110000000) >>> 7)) + // d1 = b0 b1 b2 - 16 * ( ((nBits & 0b0001110000) >>> 4)) + // d2 = b3 b4 b5 - (8 + ((nBits & 0b0000000001) )); // d3 = 8 + b9 - // 101xx - case 0b10100: - case 0b10101: - case 0b10110: - case 0b10111: - return 256 * ( ((nBits & 0b1110000000) >>> 7)) + // d1 = b0 b1 b2 - 16 * (8 + ((nBits & 0b0000010000) >>> 4)) + // d2 = 8 + b5 - ( ((nBits & 0b0001100000) >>> 4) // d3 = b3 b4 - + ((nBits & 0b0000000001) )); // + b9 - // 110xx - case 0b11000: - case 0b11001: - case 0b11010: - case 0b11011: - return 256 * (8 + ((nBits & 0b0010000000) >>> 7)) + // d1 = 8 + b2 - 16 * ( ((nBits & 0b0001110000) >>> 4)) + // d2 = b3 b4 b5 - ( ((nBits & 0b1100000000) >>> 7) // d3 = b0 b1 - + ((nBits & 0b0000000001) )); // + b9 - // 11100 - case 0b11100: - return 256 * (8 + ((nBits & 0b0010000000) >>> 7)) + // d1 = 8 + b2 - 16 * (8 + ((nBits & 0b0000010000) >>> 4)) + // d2 = 8 + b5 - ( ((nBits & 0b1100000000) >>> 7) // d3 = b0 b1 - + ((nBits & 0b0000000001) )); // + b9 - // 11101 - case 0b11101: - return 256 * (8 + ((nBits & 0b0010000000) >>> 7)) + // d1 = 8 + b2 - 16 * ( ((nBits & 0b1100000000) >>> 7) // d2 = b0 b1 - + ((nBits & 0b0000010000) >>> 4)) + // + b5 - (8 + ((nBits & 0b0000000001) )); // d3 = 8 + b9 - // 11110 - case 0b11110: - return 256 * ( ((nBits & 0b1110000000) >>> 7)) + // d1 = b0 b1 b2 - 16 * (8 + ((nBits & 0b0000010000) >>> 4)) + // d2 = 8 + b5 - (8 + ((nBits & 0b0000000001) )); // d3 = 8 + b9 - // 11111 - case 0b11111: - return 256 * (8 + ((nBits & 0b0010000000) >>> 7)) + // d1 = 8 + b2 - 16 * (8 + ((nBits & 0b0000010000) >>> 4)) + // d2 = 8 + b5 - (8 + ((nBits & 0b0000000001) )); // d3 = 8 + b9 - } - } - - /** - * Convert the passed declet to three decimal digits, and format them as a Java int in - * the range 0-999. - *

- * Details are in IEEE 754-2008 section 3.5.2, table 3.3. - * @param nBits a declet - * @return three decimal digits in a Java int (000-999) - */ - public static int decletToInt(int nBits) { - // b6 b7 b8 b3 b4 - switch ((nBits & 0b1110) << 1 | (nBits & 0b1100000) >>> 5) { - // 0xxxx b0123456789 - default: - return 100 * ( ((nBits & 0b1110000000) >>> 7)) + // d1 = b0 b1 b2 - 10 * ( ((nBits & 0b0001110000) >>> 4)) + // d2 = b3 b4 b5 - ( ((nBits & 0b0000000111) )); // d3 = b7 b8 b9 - // 100xx - case 0b10000: - case 0b10001: - case 0b10010: - case 0b10011: - return 100 * ( ((nBits & 0b1110000000) >>> 7)) + // d1 = b0 b1 b2 - 10 * ( ((nBits & 0b0001110000) >>> 4)) + // d2 = b3 b4 b5 - (8 + ((nBits & 0b0000000001) )); // d3 = 8 + b9 - // 101xx - case 0b10100: - case 0b10101: - case 0b10110: - case 0b10111: - return 100 * ( ((nBits & 0b1110000000) >>> 7)) + // d1 = b0 b1 b2 - 10 * (8 + ((nBits & 0b0000010000) >>> 4)) + // d2 = 8 + b5 - ( ((nBits & 0b0001100000) >>> 4) // d3 = b3 b4 - + ((nBits & 0b0000000001) )); // + b9 - // 110xx - case 0b11000: - case 0b11001: - case 0b11010: - case 0b11011: - return 100 * (8 + ((nBits & 0b0010000000) >>> 7)) + // d1 = 8 + b2 - 10 * ( ((nBits & 0b0001110000) >>> 4)) + // d2 = b3 b4 b5 - ( ((nBits & 0b1100000000) >>> 7) // d3 = b0 b1 - + ((nBits & 0b0000000001) )); // + b9 - // 11100 - case 0b11100: - return 100 * (8 + ((nBits & 0b0010000000) >>> 7)) + // d1 = 8 + b2 - 10 * (8 + ((nBits & 0b0000010000) >>> 4)) + // d2 = 8 + b5 - ( ((nBits & 0b1100000000) >>> 7) // d3 = b0 b1 - + ((nBits & 0b0000000001) )); // + b9 - // 11101 - case 0b11101: - return 100 * (8 + ((nBits & 0b0010000000) >>> 7)) + // d1 = 8 + b2 - 10 * ( ((nBits & 0b1100000000) >>> 7) // d2 = b0 b1 - + ((nBits & 0b0000010000) >>> 4)) + // + b5 - (8 + ((nBits & 0b0000000001) )); // d3 = 8 + b9 - // 11110 - case 0b11110: - return 100 * ( ((nBits & 0b1110000000) >>> 7)) + // d1 = b0 b1 b2 - 10 * (8 + ((nBits & 0b0000010000) >>> 4)) + // d2 = 8 + b5 - (8 + ((nBits & 0b0000000001) )); // d3 = 8 + b9 - // 11111 - case 0b11111: - return 100 * (8 + ((nBits & 0b0010000000) >>> 7)) + // d1 = 8 + b2 - 10 * (8 + ((nBits & 0b0000010000) >>> 4)) + // d2 = 8 + b5 - (8 + ((nBits & 0b0000000001) )); // d3 = 8 + b9 - } - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/DepTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/DepTCon.java deleted file mode 100644 index 814b3e9bfd..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/DepTCon.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.xtc.ClassPart; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public abstract class DepTCon extends TCon implements ClzCon { - public TCon _par; - public ClassPart _part; - DepTCon( CPool X ) { X.u31(); } - @Override public SB str(SB sb) { - sb.p(""); - return _par==null ? sb : _par.str(sb.p(" -> ")); - } - @Override public ClassPart clz () { return part(); } - @Override public ClassPart part() { - return _part==null ? (_part = _part()) : _part; - } - abstract ClassPart _part(); - - @Override public void resolve( CPool X ) { _par = (TCon)X.xget(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/DiffTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/DiffTCon.java deleted file mode 100644 index 0aa19d2cdf..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/DiffTCon.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; -import org.xvm.xtc.RelPart; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class DiffTCon extends RelTCon { - public DiffTCon( CPool X ) { super(X); } - @Override public SB str(SB sb) { - if( _con2 instanceof TermTCon tt ) sb.p(tt.name()); - sb.p("-"); - return _con1.str(sb); - } - @Override RelPart.Op op() { return RelPart.Op.Difference; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/DynFormalCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/DynFormalCon.java deleted file mode 100644 index 71497a4c0b..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/DynFormalCon.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class DynFormalCon extends FormalCon { - // The register unique id within the enclosing method (not used during the compilation). - private final int _reg, _nreg; // Registers - private TCon _type; - private FormalCon _formal; - public DynFormalCon( CPool X ) { - super(X); - _reg = X.u31(); - _nreg = X.u31(); - X.u31(); - X.u31(); - } - @Override public void resolve( CPool X ) { - super.resolve(X); - X.u31(); - X.u31(); - _type = ( TCon)X.xget(); - _formal = (FormalCon)X.xget(); - } - public TCon type() { return _type; } - @Override Part _part() { - if( _type instanceof ParamTCon pt && pt._parms!=null ) - return _formal.part(); - // _part = _type.link(repo); - throw XEC.TODO(); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/EnumCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/EnumCon.java deleted file mode 100644 index 95f5dde4d2..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/EnumCon.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; - -/** - Exploring XEC Constants - */ -public class EnumCon extends SingleCon { - public EnumCon( CPool X, Format f ) { super(X,f); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/FPNCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/FPNCon.java deleted file mode 100644 index 1c04e206f5..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/FPNCon.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; - -/** - Exploring XEC Constants - */ -public class FPNCon extends Const { - final Format _f; - private final byte[] _buf; - public FPNCon( CPool X, Format f ) { - _f = f; - int len = (1 << X.u8()); - _buf = X.bytes(len); - int min = f==Format.DecN ? 4 : 2; - if( len < min || len > 16384 ) - throw new IllegalArgumentException("value length ("+len+") must be a power-of-two between " + min + " and 16384"); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/FSNodeCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/FSNodeCon.java deleted file mode 100644 index d6076cdf43..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/FSNodeCon.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class FSNodeCon extends TCon { - private final Format _f; - private String _name; - private LitCon _create, _mod; - private Const _data; - public FSNodeCon( CPool X, Format f ) { - _f = f; - X.u31(); - X.u31(); - X.u31(); - X.u31(); - } - @Override public void resolve( CPool X ) { - _name =((StringCon)X.xget())._str; - _create = ( LitCon)X.xget(); - _mod = ( LitCon)X.xget(); - _data = X.xget(); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/FileStoreCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/FileStoreCon.java deleted file mode 100644 index 019044953f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/FileStoreCon.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; -import org.xvm.XEC; -import org.xvm.xtc.Part; - -/** - Exploring XEC Constants - */ -public class FileStoreCon extends TCon { - String _path; - FSNodeCon _dir; - public FileStoreCon( CPool X ) { - X.u31(); - X.u31(); - } - @Override public void resolve( CPool X ) { - _path =((StringCon)X.xget())._str; - _dir = (FSNodeCon)X.xget(); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt128Con.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt128Con.java deleted file mode 100644 index bac192c7b6..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt128Con.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class Flt128Con extends Const { - private final byte[] _buf; - public Flt128Con( CPool X ) { _buf = X.bytes(16); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt32Con.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt32Con.java deleted file mode 100644 index 4eac730b3f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt32Con.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class Flt32Con extends TCon { - public final float _flt; - public Flt32Con( CPool X, Format f ) { - _flt = switch( f ) { - case Float32 -> from32 ( X.i32() ); - case BFloat16 -> from16b( X.u16() ); - case Float16 -> from16 ( X.u16() ); - default -> throw XEC.TODO(); - }; - } - - // Normal serialized float - private static float from32( int x ) { - return Float.intBitsToFloat(x); - } - - // Chopped mantissa style - private static float from16b( int x ) { - return Float.intBitsToFloat(x << 16); - } - - // Half precision style - /** - * Convert a 16-bit "half precision" floating point to a "full precision" 32-bit float. - * @param nHalf the 16-bit floating point value stored in a 16-bit Java int, whose bits are - * encoded using the IEEE-754 binary-radix floating point format - * @return a 32-bit float - */ - public static float from16(int nHalf) { - // notes from the IEEE-754 specification: - - // left to right bits of a binary floating point number: - // size bit ids name description - // ---------- ------------ ---- --------------------------- - // 1 bit S sign - // w bits E[0]..E[w-1] E biased exponent - // t=p-1 bits d[1]..d[p-1] T trailing significant field - - // The range of the encoding's biased exponent E shall include: - // - every integer between 1 and 2^w - 2, inclusive, to encode normal numbers - // - the reserved value 0 to encode 0 and subnormal numbers - // - the reserved value 2w - 1 to encode +/-infinity and NaN - - // The representation r of the floating-point datum, and value v of the floating-point datum - // represented, are inferred from the constituent fields as follows: - // a) If E == 2^w-1 and T != 0, then r is qNaN or sNaN and v is NaN regardless of S - // b) If E == 2^w-1 and T == 0, then r=v=(-1)^S * (+infinity) - // c) If 1 <= E <= 2^w-2, then r is (S, (E-bias), (1 + 2^(1-p) * T)) - // the value of the corresponding floating-point number is - // v = (-1)^S * 2^(E-bias) * (1 + 2^(1-p) * T) - // thus normal numbers have an implicit leading significand bit of 1 - // d) If E == 0 and T != 0, then r is (S, emin, (0 + 2^(1-p) * T)) - // the value of the corresponding floating-point number is - // v = (-1)^S * 2^emin * (0 + 2^(1-p) * T) - // thus subnormal numbers have an implicit leading significand bit of 0 - // e) If E == 0 and T ==0, then r is (S, emin, 0) and v = (-1)^S * (+0) - - // parameter bin16 bin32 - // -------------------------------------------- ----- ----- - // k, storage width in bits 16 32 - // p, precision in bits 11 24 - // emax, maximum exponent e 15 127 - // bias, E-e 15 127 - // sign bit 1 1 - // w, exponent field width in bits 5 8 - // t, trailing significant field width in bits 10 23 - - // a quick & dirty implementation: - // int nS = (nHalf >>> 15) & 0x1; - // int nE = (nHalf >>> 10) & 0x1F; - // int nT = (nHalf ) & 0x3FF; - // - // nE = nE == 0x1F - // ? 0xFF // it's 2^w-1; it's all 1's, so keep it all 1's for the 32-bit float - // : nE - 15 + 127; // adjust the exponent from the 16-bit bias to the 32-bit bias - // - // // sign S is now bit 31 - // // exp E is from bit 30 to bit 23 - // // scale T by 13 binary digits (it grew from 10 to 23 bits) - // return Float.intBitsToFloat(nS << 31 | nE << 23 | nT << 13); - - // from: https://stackoverflow.com/questions/6162651/half-precision-floating-point-in-java - int mant = nHalf & 0x03ff; // 10 bits mantissa - int exp = nHalf & 0x7c00; // 5 bits exponent - if (exp == 0x7c00) { // NaN/Inf - exp = 0x3fc00; // -> NaN/Inf - } else if (exp != 0) { // normalized value - exp += 0x1c000; // exp - 15 + 127 - if (mant == 0 && exp > 0x1c400) { // smooth transition - return Float.intBitsToFloat((nHalf & 0x8000) << 16 | exp << 13 | 0x3ff); - } - } else if (mant != 0) { // && exp==0 -> subnormal - exp = 0x1c400; // make it normal - do { - mant <<= 1; // mantissa * 2 - exp -= 0x400; // decrease exp by 1 - } - while ((mant & 0x400) == 0); // while not normal - mant &= 0x3ff; // discard subnormal bit - } // else +/-0 -> +/-0 - return Float.intBitsToFloat( // combine all parts - (nHalf & 0x8000) << 16 // sign << ( 31 - 15 ) - | (exp | mant) << 13); // value << ( 23 - 10 ) - } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt64Con.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt64Con.java deleted file mode 100644 index acb3126088..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt64Con.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class Flt64Con extends TCon { - public final double _flt; - public Flt64Con( CPool X ) { - _flt = Double.longBitsToDouble(X.i64()); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt8e4Con.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt8e4Con.java deleted file mode 100644 index 537c82591a..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt8e4Con.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class Flt8e4Con extends Const { - private final float _flt; - public Flt8e4Con( CPool X ) { - _flt = switch( X.u8() ) { - case 0x00 -> 0.0f; - case 0x80 -> -0.0f; - case 0x7F -> Float.NaN; - case 0xFF -> Float.intBitsToFloat(0xFFC00000); - default -> throw new UnsupportedOperationException("TODO implement non-zero E4M3 float values"); - }; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt8e5Con.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt8e5Con.java deleted file mode 100644 index 3d32ed69f8..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/Flt8e5Con.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class Flt8e5Con extends Const { - private final float _flt; - public Flt8e5Con( CPool X ) { - _flt = switch( X.u8() ) { - case 0x00 -> 0.0f; - case 0x80 -> -0.0f; - case 0x7F -> Float.NaN; - case 0xFF -> Float.intBitsToFloat(0xFFC00000); - case 0x7C -> Float.POSITIVE_INFINITY; - case 0xFC -> Float.NEGATIVE_INFINITY; - default -> throw new UnsupportedOperationException("TODO implement non-zero E5M2 float values"); - }; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/FormalCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/FormalCon.java deleted file mode 100644 index ca4d0de7cb..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/FormalCon.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; - -/** - Exploring XEC Constants. - */ -public abstract class FormalCon extends NamedCon { - FormalCon( CPool X ) { super(X); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/FormalTChildCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/FormalTChildCon.java deleted file mode 100644 index 9491c60c9d..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/FormalTChildCon.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.*; - -/** - Exploring XEC Constants - */ -public class FormalTChildCon extends PropCon implements ClzCon { - public FormalTChildCon( CPool X ) { super(X); } - // Look up the name in the parent class types' - Part _part() { - for( PartCon par = _par; !(par instanceof ClassCon clzcon); par = par._par ) - ; - return clzcon.clz(); - } - public ClassPart clz() { return (ClassPart)part(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/IdCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/IdCon.java deleted file mode 100644 index 2de7bdb9ca..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/IdCon.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.xvm.xtc.cons; - -public abstract interface IdCon { - abstract public String name(); -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/ImmutTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/ImmutTCon.java deleted file mode 100644 index 1863b3268f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/ImmutTCon.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.ClassPart; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class ImmutTCon extends TCon implements ClzCon { - TCon _con; - public ImmutTCon( CPool X ) { X.u31(); } - @Override public SB str(SB sb) { sb.p("R/O"); return _con==null ? sb : _con.str(sb.p(" -> ")); } - @Override public void resolve( CPool X ) { _con = (TCon)X.xget(); } - public TCon icon() { return _con; } - @Override public ClassPart clz() { - return ((ClzCon)_con).clz(); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/InnerDepTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/InnerDepTCon.java deleted file mode 100644 index 0658c4c831..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/InnerDepTCon.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.xtc.ClassPart; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class InnerDepTCon extends DepTCon { - public ClassCon _child; - public InnerDepTCon( CPool X ) { - super(X); - X.u31(); - } - @Override public void resolve( CPool X ) { - super.resolve(X); - _child = (ClassCon)X.xget(); - } - @Override ClassPart _part() { return (ClassPart)_child.part(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/IntCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/IntCon.java deleted file mode 100644 index ee0b461979..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/IntCon.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; -import java.math.BigInteger; - -/** - Exploring XEC Constants - */ -public class IntCon extends NumCon { - public final Format _f; - public final BigInteger _big; // If null, _x holds the value. If not-null _x is 0. - private static final BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE); - private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE); - - private static BigInteger _tmp; - private static long parse( CPool X, Const.Format f ) { - int z = X.isize(); // Read the size; drop extra bits beyond size - long x; - if( z == -1 ) { // Size is Huge - x = 0; - _tmp = X.bigint(X.i32()); // Extra size read before BigInteger - } else if( z <= 9 ) { // Size is Tiny to Large - X.undo(); // Push extra bits back - x = X.pack64(); // Do a normal packed read - _tmp = null; - } else { // Size is modest Huge - BigInteger big = X.bigint(z-1); // Already read size, just do BigInteger - if( LONG_MIN.compareTo(big) <= 0 && big.compareTo(LONG_MAX) <= 0 ) { - x = big.longValueExact(); - _tmp = null; - } else { - x = 0; - _tmp = big; - } - } - - int c = switch( f ) { // Size in bytes of int constant - case Int16, UInt16 -> 2; - case Int32, UInt32 -> 4; - case Int64, UInt64 -> 8; - case Int128, UInt128 -> 16; - case IntN, UIntN -> 1024; - default -> { System.err.println(f); throw XEC.TODO(); } - }; - - boolean unsigned = switch( f ) { - case Int16, Int32, Int64, Int128, IntN -> false; - case UInt16, UInt32, UInt64, UInt128, UIntN -> true; - default -> { System.err.println(f); throw XEC.TODO(); } - }; - - // Sanity check size - if( _tmp==null ) { - // Already fits in a long. Sizes >= 8 will always work. - // Sizes < 8 need a range check. - if( c < 8 ) { - long rng = 1L<<(c<<3); - if( unsigned && x < 0 ) throw new IllegalArgumentException("illegal unsigned value: " + x); - if( unsigned && x >= rng ) throw bad(c,x); - if( !unsigned && !(-(rng>>1) <= x && x < (rng>>1)) ) - throw bad(c,x); - } - } else { - if( unsigned && ((_tmp.bitLength()+7)>>3) > c ) throw bad(c,x); - if( !unsigned && (_tmp.bitLength()>>3) + 1 > c ) throw bad(c,x); - } - return x; - } - - public IntCon( CPool X, Const.Format f ) { - super(parse(X,f)); - _f = f; - _big = _tmp; - } - private static IllegalArgumentException bad(int c, long x) { - return new IllegalArgumentException("value exceeds " + c + " bytes: " + (_tmp==null ? ""+x : _tmp.toString())); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/InterTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/InterTCon.java deleted file mode 100644 index 1954c3a0de..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/InterTCon.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; -import org.xvm.xtc.RelPart; -import org.xvm.XEC; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class InterTCon extends RelTCon { - public InterTCon( CPool X ) { super(X); } - @Override public SB str(SB sb) { - if( _con2 instanceof TermTCon tt ) sb.p(tt.name()); - sb.p("&"); - return _con1.str(sb); - } - @Override RelPart.Op op() { return RelPart.Op.Intersect; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/KeywordCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/KeywordCon.java deleted file mode 100644 index a27d959b3c..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/KeywordCon.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.*; - -/** - Exploring XEC Constants - */ -public class KeywordCon extends Const implements IdCon { - private final Format _f; - public KeywordCon( Format f ) { _f = f; } - @Override public String name() { return _f.toString(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/LitCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/LitCon.java deleted file mode 100644 index ac7c09e0ff..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/LitCon.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class LitCon extends TCon { - public final Format _f; - public String _str; // The actual string constant - public LitCon( CPool X, Format f ) { - _f = f; - X.u31(); - } - @Override public SB str(SB sb) { return sb.p(_str); } - @Override public void resolve( CPool X ) { _str = ((StringCon)X.xget())._str; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/MMethodCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/MMethodCon.java deleted file mode 100644 index caa56995ae..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/MMethodCon.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.*; - -/** - Exploring XEC Constants - */ -public class MMethodCon extends NamedCon { - public MMethodCon( CPool X ) { super(X); } - - @Override Part _part() { - Part p = __part(); - assert p!=null; - return p; - } - - private Part __part() { - // If the default path works, take it - Part par = _par.part(); - Part p = par.child(_name); - if( p != null ) return p; - // If the parent lookup fails, see if the parent is a formal/interface and - // lookup there - if( par instanceof MMethodPart mm ) - return mm.child(mm._name).child(_name); - // If parent lookup fails, try again in Object - return XEC.REPO.get("ecstasy.xtclang.org").child("Object").child(_name); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/MapCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/MapCon.java deleted file mode 100644 index 62234d0685..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/MapCon.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class MapCon extends TCon { - final Format _f; - - public TCon _t; // Type for whole map - public final Const[] _keys, _vals; - - private Part _part; - private Part[] _parts; - public TCon type() { return _t; } // No setter - public MapCon( CPool X, Const.Format f ) { - _f = f; - X.u31(); - int len = X.u31(); - _keys = new Const[len]; - _vals = new Const[len]; - for( int i=0; i ")); } - @Override public void resolve( CPool X ) { _con = X.xget(); } - //@Override public Part link(XEC.ModRepo repo) { - // return _type==null ? (_type = _con.link(repo)) : _type; - //} -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/MethodBindCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/MethodBindCon.java deleted file mode 100644 index 8ae34310c3..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/MethodBindCon.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class MethodBindCon extends PartCon { - public MethodBindCon( CPool X ) { X.u31(); } - @Override public String name() { throw XEC.TODO(); } - @Override public void resolve( CPool X ) { _par = (MethodCon)X.xget(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/MethodCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/MethodCon.java deleted file mode 100644 index 353be36228..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/MethodCon.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.*; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class MethodCon extends PartCon { - public SigCon _sig; - public final int _lamidx; - private boolean _link_start; - public MethodCon( CPool X ) { - X.u31(); // Parent - X.u31(); // Signature - _lamidx = X.u31(); // Lambda - } - @Override public SB str(SB sb) { return super.str(sb.p(_sig._name)); } - @Override public void resolve( CPool X ) { - _par = (MMethodCon)X.xget(); - _sig = (SigCon)X.xget(); - assert _lamidx==0 || ((MMethodCon)_par)._name.equals("->"); - } - - @Override MethodPart _part() { - MMethodPart mm = (MMethodPart)_par.part(); - if( mm._name2kid==null ) - mm.addNative(); - - // Find first child in the parent, head of a linked list of choices - MethodPart meth = (MethodPart)mm.child(name()); - assert meth!=null; - - // Assume if there is one method, it is correct - if( meth._sibling == null ) - return meth; - - // Find matching lambda with the easy exact test - for( MethodPart methx=meth; methx!=null; methx = methx._sibling ) - if( methx._methcon == this ) - return methx; // Early out - - // Need to do a proper instanceof test. - // Do a fully-boxed signature, to compare against a fully-boxed method. - // This is so sharper signatures do not promote `Int64` to `long` - // and then fail to match against generic `XTC` method signatures. - ClassPart clz = (ClassPart)mm._par; - boolean con = MethodPart.is_constructor(_sig._name); - XFun sig = XFun.make(clz, con, - XType.xtypes(_sig._args, true), - XType.xtypes(_sig._rets, true)); - MethodPart rez=null; - for( MethodPart methx=meth; methx!=null; methx = methx._sibling ) { - // Do a fully-boxed method - XFun fun = XFun.make(clz, con, - XType.xtypes(methx._args, true), - XType.xtypes(methx._rets, true) ); - if( sig.isa(fun) ) { - assert rez==null; // Ambiguous - rez = methx; - } - } - assert rez != null; - return rez; - } - - @Override public String name() { return _par.name(); } - public TCon[] rawRets () { return _sig.rawRets (); } - public TCon[] rawParms() { return _sig.rawParms(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/ModCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/ModCon.java deleted file mode 100644 index 952b21f84b..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/ModCon.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class ModCon extends PartCon { - String _name; - public ModCon( CPool X ) { X.u31(); } - @Override public String name() { return _name; } - @Override public SB str(SB sb) { return super.str(sb.p(_name)); } - @Override public void resolve( CPool X ) { _name =((StringCon)X.xget())._str; } - - // Modules do direct lookup in the repo - @Override Part _part() { return XEC.REPO.get(name()); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/NamedCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/NamedCon.java deleted file mode 100644 index 6a4db37a31..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/NamedCon.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public abstract class NamedCon extends PartCon { - public String _name; - NamedCon( CPool X ) { X.u31(); X.u31(); } - @Override public String name() { return _name; } - @Override public SB str(SB sb) { return super.str(sb.p(_name)); } - @Override public void resolve( CPool X ) { - _par = (PartCon)X.xget(); // Parent is parsed before name - _name =((StringCon)X.xget())._str; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/NamedCondCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/NamedCondCon.java deleted file mode 100644 index 8420121f56..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/NamedCondCon.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class NamedCondCon extends CondCon { - private String _name; - - public NamedCondCon( CPool X, Format f ) { - super(f); - X.u31(); - } - @Override public void resolve( CPool X ) { _name =((StringCon)X.xget())._str; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/NumCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/NumCon.java deleted file mode 100644 index a0cb76ec56..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/NumCon.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; - -/** - Exploring XEC Constants - */ -public abstract class NumCon extends TCon { - public final long _x; - public NumCon( long x ) { _x=x; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/PackageCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/PackageCon.java deleted file mode 100644 index a3f693d1bb..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/PackageCon.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; - -/** - Exploring XEC Constants - */ -public class PackageCon extends NamedCon { - public PackageCon( CPool X ) { super(X); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/ParClzCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/ParClzCon.java deleted file mode 100644 index a62a597710..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/ParClzCon.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class ParClzCon extends PartCon { - private PartCon _child; - public ParClzCon( CPool X ) { X.u31(); } - @Override public void resolve( CPool X ) { _child = (PartCon)X.xget(); } - // Look up the name in the parents Part - @Override Part _part() { return _child.part(); } - @Override public String name() { return _child.name(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/ParamTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/ParamTCon.java deleted file mode 100644 index fe23bf490f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/ParamTCon.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.ClassPart; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Parameterized Type Constant. - */ -public class ParamTCon extends PartCon implements ClzCon { - private TCon _con; - public TCon[] _parms; - - public ParamTCon( CPool X ) { - X.u31(); - X.skipAry(); - } - @Override public SB str(SB sb) { - if( _con instanceof TermTCon tt ) sb.p(tt.name()); - sb.p("<>"); - return _parms==null ? sb : _parms[0].str(sb.p(" -> ")); - } - @Override public ClassPart clz () { return (ClassPart)part(); } - @Override Part _part() { return _con.part(); } - @Override public String name() { throw XEC.TODO(); } - - @Override public void resolve( CPool X ) { - _con = (TCon)X.xget(); - _parms = TCon.tcons(X); - } - - // Is a generic TermTCon? - @Override public TermTCon is_generic() { - return _parms.length==1 && _parms[0] instanceof TermTCon ttc ? ttc : null; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/PartCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/PartCon.java deleted file mode 100644 index a8c6f01ae7..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/PartCon.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - General Con class backed by matching Part class - */ -public abstract class PartCon extends TCon implements IdCon { - public PartCon _par; // Parent - Part _part; - @Override public SB str(SB sb) { return _par==null ? sb : _par.str(sb.p(" -> ")); } - - @Override public final Part part() { - return _part == null ? (_part = _part()) : _part; - } - // Look up the name in the parents Part - Part _part() { - return _par.part().child(name()); - } - - // Parse an array of Const from a pre-filled constant pool - public static PartCon[] parts( CPool X ) { - int len = X.u31(); - if( len==0 ) return null; - PartCon[] as = new PartCon[len]; - for( int i=0; i X.u8(); - case RangeExclusive -> 2; - case RangeInclusive -> 0; - default -> throw new IllegalArgumentException("illegal format: "+f); - }; - _xlo = (b&1)!=0; - _xhi = (b&2)!=0; - X.u31(); - X.u31(); - } - public long lo() { return ((NumCon)_lo)._x; } - public long hi() { return ((NumCon)_hi)._x; } - @Override public void resolve( CPool X ) { - if( _f == Format.Range ) X.u8(); - _lo = X.xget(); - _hi = X.xget(); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/RecurTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/RecurTCon.java deleted file mode 100644 index b9c3af3731..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/RecurTCon.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class RecurTCon extends TermTCon { - public RecurTCon( CPool X ) { super(X); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/RegCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/RegCon.java deleted file mode 100644 index 93fa9340da..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/RegCon.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; - -/** - Exploring XEC Constants - */ -public class RegCon extends Const { - private final int _reg; - public RegCon( CPool X ) { _reg = (int)X.pack64(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/RelTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/RelTCon.java deleted file mode 100644 index 95901ca9ae..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/RelTCon.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.RelPart; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public abstract class RelTCon extends TCon implements ClzCon { - public TCon _con1, _con2; - RelPart _part; - public RelTCon( CPool X ) { - X.u31(); - X.u31(); - } - - @Override public RelPart clz() { assert _part!=null; return _part; } - - @Override public void resolve( CPool X ) { - _con1 = (TCon)X.xget(); - _con2 = (TCon)X.xget(); - } - - abstract RelPart.Op op(); -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/ServiceTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/ServiceTCon.java deleted file mode 100644 index 53ed803f41..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/ServiceTCon.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.xtc.ClassPart; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class ServiceTCon extends TCon implements ClzCon { - private TCon _con; - private ClassPart _part; - public ServiceTCon( CPool X ) { X.u31(); } - @Override public void resolve( CPool X ) { _con = (TCon)X.xget(); } - @Override public ClassPart clz() { - if( _part != null ) throw XEC.TODO(); - return _part; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/SigCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/SigCon.java deleted file mode 100644 index 2e6d35f891..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/SigCon.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class SigCon extends TCon implements IdCon { - public String _name; - public TCon[] _args; - public TCon[] _rets; - private boolean _linked; - - public SigCon( CPool X ) { - X.u31(); - X.skipAry(); - X.skipAry(); - } - @Override public SB str(SB sb) { return sb.p(_name).p("{}"); } - - @Override public void resolve( CPool X ) { - _name =((StringCon)X.xget())._str; - _args = TCon.tcons(X); - _rets = TCon.tcons(X); - } - @Override public String name() { return _name; } - public TCon[] rawRets () { return _rets; } - public TCon[] rawParms() { return _args; } - -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/SingleCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/SingleCon.java deleted file mode 100644 index 8d0c812618..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/SingleCon.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; - -/** - Exploring XEC Constants - */ -public class SingleCon extends PartCon { - final Format _f; - public SingleCon( CPool X, Format f ) { - X.u31(); - _f = f; - } - @Override public String name() { throw XEC.TODO(); } - @Override public void resolve( CPool X ) { _par = (PartCon)X.xget(); } - @Override Part _part() { return _par.part(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/StringCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/StringCon.java deleted file mode 100644 index 53872cba2d..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/StringCon.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; -import org.xvm.XEC; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class StringCon extends TCon { - public final String _str; - public StringCon( CPool X ) { _str = X.utf8(); } - @Override public SB str(SB sb) { return sb.p(_str); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/TCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/TCon.java deleted file mode 100644 index 08b6805412..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/TCon.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public abstract class TCon extends Const { - - public static TCon[] tcons( CPool X ) { - int len = X.u31(); - if( len==0 ) return null; - TCon[] cs = new TCon[len]; - for( int i=0; i; V get(K key) { ... }" - */ -public class TParmCon extends FormalCon { - private final int _reg; // Register index - public TParmCon( CPool X ) { - super(X); - _reg = X.u31(); - } - @Override Part _part() { - return new ParmPart((MethodPart)_par.part(),_reg); - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/TSeqTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/TSeqTCon.java deleted file mode 100644 index eed0faae88..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/TSeqTCon.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.util.SB; -import org.xvm.XEC; - -/** - Near as I can tell, this is specifically for making a self-recursive Tuple - with a single type member. - e.g. Type> - e.g. < ParamTypes extends Tuple< ParamTypes>> - e.g. > - e.g. interface Function, ReturnTypes extends Tuple> - extends Signature { - - */ -public class TSeqTCon extends TCon { - @Override public SB str( SB sb ) { return sb.p("self_recur_type_marker"); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/TermTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/TermTCon.java deleted file mode 100644 index 202f05be6b..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/TermTCon.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.*; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class TermTCon extends TCon implements ClzCon { - Const _id; - private Part _part; - public TermTCon( CPool X ) { X.u31(); } - @Override public SB str(SB sb) { return _id.str(sb.p("# -> ")); } - @Override public ClassPart clz() { - Part p = part(); - return p instanceof ClassPart clz ? clz : null; - } - @Override public void resolve( CPool X ) { _id = X.xget(); } - public Const id() { return _id; } - public String name() { return ((IdCon)_id).name(); } - - @Override public Part part() { - return _part==null ? (_part = _id.part()) : _part; - } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/ThisClzCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/ThisClzCon.java deleted file mode 100644 index 2757e3053e..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/ThisClzCon.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.xtc.ClassPart; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class ThisClzCon extends PartCon { - public ThisClzCon( CPool X ) { X.u31(); } - @Override public SB str(SB sb) { return super.str(sb.p("this")); } - @Override public void resolve( CPool X ) { _par = (ClassCon)X.xget(); } - @Override public String name() { return _par.name(); } - - @Override Part _part() { return _par.part(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/UInt8AryCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/UInt8AryCon.java deleted file mode 100644 index b80906860f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/UInt8AryCon.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.CPool; - -/** - Exploring XEC Constants - */ -public class UInt8AryCon extends Const { - private final byte[] _bs; - public UInt8AryCon( CPool X ) { _bs = X.bytes(); } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/UnionTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/UnionTCon.java deleted file mode 100644 index fbb0472768..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/UnionTCon.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.RelPart; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class UnionTCon extends RelTCon { - public UnionTCon( CPool X ) { super(X); } - @Override public SB str(SB sb) { - if( _con2 instanceof TermTCon tt ) sb.p(tt.name()); - sb.p("|"); - return _con1.str(sb); - } - @Override RelPart.Op op() { return RelPart.Op.Union; } -} diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/VerCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/VerCon.java deleted file mode 100644 index 4f6584247f..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/VerCon.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.xtc.*; - -/** - * Represent a version number. - */ -public class VerCon extends LitCon { - private Version _ver; - public VerCon( CPool X, Format format ) { super(X, format); } - public Version ver() { return _ver; } - @Override public void resolve( CPool X ) { - super.resolve(X); - _ver = new Version(_str); - } -} - - - diff --git a/javatools_backend/src/main/java/org/xvm/xtc/cons/VirtDepTCon.java b/javatools_backend/src/main/java/org/xvm/xtc/cons/VirtDepTCon.java deleted file mode 100644 index 833350444b..0000000000 --- a/javatools_backend/src/main/java/org/xvm/xtc/cons/VirtDepTCon.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.xvm.xtc.cons; - -import org.xvm.XEC; -import org.xvm.xtc.CPool; -import org.xvm.xtc.Part; -import org.xvm.xtc.ClassPart; -import org.xvm.util.SB; - -/** - Exploring XEC Constants - */ -public class VirtDepTCon extends DepTCon { - private final boolean _thisClz; - private String _name; - public VirtDepTCon( CPool X ) { - super(X); - X.u31(); - _thisClz = X.u1(); - } - @Override public SB str(SB sb) { return super.str(sb.p(_name)); } - @Override public void resolve( CPool X ) { - super.resolve(X); - _name =((StringCon)X.xget())._str; - } - @Override ClassPart _part() { - Part par = _par.part(); - while( !(par instanceof ClassPart clz) ) - par = par._par; - return (ClassPart)clz.child(_name); - } -}