From c4364363dbd969c9aa27aa7c43fbe6d40544501a Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Sat, 24 Oct 2026 15:25:40 -0700 Subject: Rename escape analysis chapter to 27 --- .../main/java/com/seaofnodes/simple/IterPeeps.java | 230 -- .../main/java/com/seaofnodes/simple/Parser.java | 2580 -------------------- .../src/main/java/com/seaofnodes/simple/Var.java | 56 - .../com/seaofnodes/simple/codegen/BuildLRG.java | 95 - .../com/seaofnodes/simple/codegen/Coalesce.java | 105 - .../com/seaofnodes/simple/codegen/CodeGen.java | 410 ---- .../com/seaofnodes/simple/codegen/ElfExpr.java | 87 - .../com/seaofnodes/simple/codegen/ElfFile.java | 382 --- .../com/seaofnodes/simple/codegen/Encoding.java | 543 ---- .../com/seaofnodes/simple/codegen/FinalizeIR.java | 80 - .../simple/codegen/GlobalCodeMotion.java | 311 --- .../java/com/seaofnodes/simple/codegen/IFG.java | 539 ---- .../com/seaofnodes/simple/codegen/InstSelect.java | 112 - .../java/com/seaofnodes/simple/codegen/LRG.java | 235 -- .../com/seaofnodes/simple/codegen/LinkMem.java | 23 - .../seaofnodes/simple/codegen/ListScheduler.java | 261 -- .../com/seaofnodes/simple/codegen/Machine.java | 109 - .../java/com/seaofnodes/simple/codegen/Opto.java | 265 -- .../com/seaofnodes/simple/codegen/RIPRelSize.java | 14 - .../com/seaofnodes/simple/codegen/RegAlloc.java | 704 ------ .../com/seaofnodes/simple/codegen/RegMask.java | 122 - .../com/seaofnodes/simple/codegen/RegMaskRW.java | 36 - .../com/seaofnodes/simple/codegen/TypeCheck.java | 44 - .../java/com/seaofnodes/simple/node/AddFNode.java | 32 - .../java/com/seaofnodes/simple/node/AddNode.java | 178 -- .../java/com/seaofnodes/simple/node/AndNode.java | 48 - .../com/seaofnodes/simple/node/ArithFNode.java | 31 - .../java/com/seaofnodes/simple/node/ArithNode.java | 206 -- .../java/com/seaofnodes/simple/node/BoolNode.java | 202 -- .../com/seaofnodes/simple/node/BulkMemPhiNode.java | 243 -- .../java/com/seaofnodes/simple/node/CFGNode.java | 222 -- .../java/com/seaofnodes/simple/node/CProjNode.java | 69 - .../com/seaofnodes/simple/node/CallEndMach.java | 36 - .../com/seaofnodes/simple/node/CallEndNode.java | 256 -- .../java/com/seaofnodes/simple/node/CallNode.java | 206 -- .../com/seaofnodes/simple/node/CalleeSaveNode.java | 23 - .../java/com/seaofnodes/simple/node/CastMach.java | 19 - .../java/com/seaofnodes/simple/node/CastNode.java | 79 - .../com/seaofnodes/simple/node/ConFldOffNode.java | 41 - .../com/seaofnodes/simple/node/ConstantNode.java | 67 - .../com/seaofnodes/simple/node/ConvertNode.java | 103 - .../java/com/seaofnodes/simple/node/CtrlNode.java | 16 - .../java/com/seaofnodes/simple/node/DivFNode.java | 27 - .../java/com/seaofnodes/simple/node/DivNode.java | 39 - .../com/seaofnodes/simple/node/EscapeMach.java | 12 - .../com/seaofnodes/simple/node/EscapeNode.java | 60 - .../com/seaofnodes/simple/node/ExternNode.java | 25 - .../java/com/seaofnodes/simple/node/FRefNode.java | 35 - .../com/seaofnodes/simple/node/FldOffNode.java | 24 - .../java/com/seaofnodes/simple/node/FunNode.java | 278 --- .../com/seaofnodes/simple/node/FunPtrNode.java | 12 - .../java/com/seaofnodes/simple/node/GuardMach.java | 17 - .../java/com/seaofnodes/simple/node/GuardNode.java | 66 - .../java/com/seaofnodes/simple/node/IfNode.java | 105 - .../java/com/seaofnodes/simple/node/LoadNode.java | 322 --- .../java/com/seaofnodes/simple/node/LoopNode.java | 104 - .../seaofnodes/simple/node/MachConcreteNode.java | 27 - .../java/com/seaofnodes/simple/node/MachNode.java | 60 - .../com/seaofnodes/simple/node/MemMergeNode.java | 121 - .../java/com/seaofnodes/simple/node/MemOpNode.java | 156 -- .../com/seaofnodes/simple/node/MemPhiNode.java | 53 - .../com/seaofnodes/simple/node/MinusFNode.java | 32 - .../java/com/seaofnodes/simple/node/MinusNode.java | 77 - .../java/com/seaofnodes/simple/node/ModeNode.java | 12 - .../java/com/seaofnodes/simple/node/MulFNode.java | 37 - .../java/com/seaofnodes/simple/node/MulNode.java | 64 - .../java/com/seaofnodes/simple/node/MultiNode.java | 29 - .../java/com/seaofnodes/simple/node/NeverNode.java | 23 - .../java/com/seaofnodes/simple/node/NewNode.java | 112 - .../main/java/com/seaofnodes/simple/node/Node.java | 705 ------ .../java/com/seaofnodes/simple/node/NotNode.java | 26 - .../java/com/seaofnodes/simple/node/OrNode.java | 43 - .../java/com/seaofnodes/simple/node/ParmNode.java | 93 - .../java/com/seaofnodes/simple/node/PhiNode.java | 306 --- .../java/com/seaofnodes/simple/node/ProjNode.java | 54 - .../com/seaofnodes/simple/node/PtrToIntMach.java | 17 - .../com/seaofnodes/simple/node/PtrToIntNode.java | 35 - .../com/seaofnodes/simple/node/ReadOnlyMach.java | 19 - .../com/seaofnodes/simple/node/ReadOnlyNode.java | 27 - .../com/seaofnodes/simple/node/RegionNode.java | 174 -- .../com/seaofnodes/simple/node/ReturnNode.java | 186 -- .../com/seaofnodes/simple/node/RoundF32Node.java | 34 - .../java/com/seaofnodes/simple/node/SarNode.java | 36 - .../java/com/seaofnodes/simple/node/ScopeNode.java | 534 ---- .../java/com/seaofnodes/simple/node/ShlNode.java | 48 - .../java/com/seaofnodes/simple/node/ShrNode.java | 31 - .../java/com/seaofnodes/simple/node/SplitNode.java | 28 - .../java/com/seaofnodes/simple/node/StartNode.java | 69 - .../java/com/seaofnodes/simple/node/StopNode.java | 96 - .../java/com/seaofnodes/simple/node/StoreNode.java | 205 -- .../com/seaofnodes/simple/node/StructNode.java | 56 - .../java/com/seaofnodes/simple/node/SubFNode.java | 28 - .../java/com/seaofnodes/simple/node/SubNode.java | 55 - .../com/seaofnodes/simple/node/ToFloatNode.java | 27 - .../com/seaofnodes/simple/node/ToIntegerNode.java | 23 - .../java/com/seaofnodes/simple/node/XCtrlNode.java | 16 - .../java/com/seaofnodes/simple/node/XorNode.java | 42 - .../seaofnodes/simple/node/cpus/arm/AddARM.java | 21 - .../seaofnodes/simple/node/cpus/arm/AddFARM.java | 23 - .../seaofnodes/simple/node/cpus/arm/AddIARM.java | 28 - .../seaofnodes/simple/node/cpus/arm/AndARM.java | 22 - .../seaofnodes/simple/node/cpus/arm/AndIARM.java | 25 - .../seaofnodes/simple/node/cpus/arm/AsrARM.java | 19 - .../seaofnodes/simple/node/cpus/arm/AsrIARM.java | 32 - .../seaofnodes/simple/node/cpus/arm/BranchARM.java | 78 - .../seaofnodes/simple/node/cpus/arm/CallARM.java | 51 - .../seaofnodes/simple/node/cpus/arm/CallRRARM.java | 33 - .../seaofnodes/simple/node/cpus/arm/CmpARM.java | 23 - .../seaofnodes/simple/node/cpus/arm/CmpFARM.java | 22 - .../seaofnodes/simple/node/cpus/arm/CmpIARM.java | 41 - .../seaofnodes/simple/node/cpus/arm/DivARM.java | 20 - .../seaofnodes/simple/node/cpus/arm/DivFARM.java | 20 - .../seaofnodes/simple/node/cpus/arm/ExtendARM.java | 31 - .../seaofnodes/simple/node/cpus/arm/F8ToIARM.java | 21 - .../seaofnodes/simple/node/cpus/arm/FloatARM.java | 44 - .../seaofnodes/simple/node/cpus/arm/FunARM.java | 22 - .../seaofnodes/simple/node/cpus/arm/I2F8ARM.java | 26 - .../seaofnodes/simple/node/cpus/arm/IntARM.java | 36 - .../seaofnodes/simple/node/cpus/arm/LoadARM.java | 34 - .../seaofnodes/simple/node/cpus/arm/LslARM.java | 20 - .../seaofnodes/simple/node/cpus/arm/LslIARM.java | 34 - .../seaofnodes/simple/node/cpus/arm/LsrARM.java | 20 - .../seaofnodes/simple/node/cpus/arm/LsrIARM.java | 29 - .../seaofnodes/simple/node/cpus/arm/MemOpARM.java | 79 - .../seaofnodes/simple/node/cpus/arm/MulARM.java | 20 - .../seaofnodes/simple/node/cpus/arm/MulFARM.java | 19 - .../seaofnodes/simple/node/cpus/arm/NegARM.java | 25 - .../seaofnodes/simple/node/cpus/arm/NewARM.java | 38 - .../seaofnodes/simple/node/cpus/arm/NotARM.java | 28 - .../com/seaofnodes/simple/node/cpus/arm/OrARM.java | 21 - .../seaofnodes/simple/node/cpus/arm/OrIARM.java | 25 - .../seaofnodes/simple/node/cpus/arm/ParmARM.java | 17 - .../seaofnodes/simple/node/cpus/arm/ProjARM.java | 15 - .../seaofnodes/simple/node/cpus/arm/RetARM.java | 16 - .../seaofnodes/simple/node/cpus/arm/SetARM.java | 34 - .../seaofnodes/simple/node/cpus/arm/SplitARM.java | 66 - .../simple/node/cpus/arm/SplitFlagsARM.java | 21 - .../simple/node/cpus/arm/SplitGPRARM.java | 11 - .../seaofnodes/simple/node/cpus/arm/StoreARM.java | 38 - .../seaofnodes/simple/node/cpus/arm/SubARM.java | 20 - .../seaofnodes/simple/node/cpus/arm/SubFARM.java | 19 - .../seaofnodes/simple/node/cpus/arm/SubIARM.java | 29 - .../seaofnodes/simple/node/cpus/arm/TFPARM.java | 58 - .../seaofnodes/simple/node/cpus/arm/TMPARM.java | 55 - .../seaofnodes/simple/node/cpus/arm/UJmpARM.java | 48 - .../seaofnodes/simple/node/cpus/arm/XorARM.java | 20 - .../seaofnodes/simple/node/cpus/arm/XorIARM.java | 27 - .../com/seaofnodes/simple/node/cpus/arm/arm.java | 467 ---- .../seaofnodes/simple/node/cpus/riscv/AUIPC.java | 43 - .../simple/node/cpus/riscv/AddFRISC.java | 18 - .../simple/node/cpus/riscv/AddIRISC.java | 22 - .../seaofnodes/simple/node/cpus/riscv/AddRISC.java | 21 - .../simple/node/cpus/riscv/AndIRISC.java | 13 - .../seaofnodes/simple/node/cpus/riscv/AndRISC.java | 16 - .../simple/node/cpus/riscv/BranchRISC.java | 95 - .../simple/node/cpus/riscv/CallRISC.java | 63 - .../simple/node/cpus/riscv/CallRRISC.java | 32 - .../simple/node/cpus/riscv/DivFRISC.java | 20 - .../seaofnodes/simple/node/cpus/riscv/DivRISC.java | 17 - .../simple/node/cpus/riscv/ExtendRISC.java | 32 - .../simple/node/cpus/riscv/F8ToIRISC.java | 19 - .../seaofnodes/simple/node/cpus/riscv/FltRISC.java | 47 - .../seaofnodes/simple/node/cpus/riscv/FunRISC.java | 23 - .../simple/node/cpus/riscv/I2F8RISC.java | 24 - .../seaofnodes/simple/node/cpus/riscv/ImmRISC.java | 55 - .../simple/node/cpus/riscv/Int8RISC.java | 47 - .../seaofnodes/simple/node/cpus/riscv/IntRISC.java | 31 - .../com/seaofnodes/simple/node/cpus/riscv/LUI.java | 33 - .../simple/node/cpus/riscv/LoadRISC.java | 30 - .../simple/node/cpus/riscv/MemOpRISC.java | 80 - .../simple/node/cpus/riscv/MulFRISC.java | 18 - .../seaofnodes/simple/node/cpus/riscv/MulRISC.java | 17 - .../seaofnodes/simple/node/cpus/riscv/NegRISC.java | 21 - .../seaofnodes/simple/node/cpus/riscv/NewRISC.java | 48 - .../seaofnodes/simple/node/cpus/riscv/NotRISC.java | 22 - .../seaofnodes/simple/node/cpus/riscv/OrIRISC.java | 13 - .../seaofnodes/simple/node/cpus/riscv/OrRISC.java | 16 - .../simple/node/cpus/riscv/ParmRISC.java | 17 - .../simple/node/cpus/riscv/ProjRISC.java | 15 - .../seaofnodes/simple/node/cpus/riscv/RetRISC.java | 22 - .../simple/node/cpus/riscv/SetFRISC.java | 34 - .../simple/node/cpus/riscv/SetIRISC.java | 21 - .../seaofnodes/simple/node/cpus/riscv/SetRISC.java | 20 - .../simple/node/cpus/riscv/SllIRISC.java | 13 - .../seaofnodes/simple/node/cpus/riscv/SllRISC.java | 17 - .../simple/node/cpus/riscv/SplitRISC.java | 67 - .../simple/node/cpus/riscv/SraIRISC.java | 15 - .../seaofnodes/simple/node/cpus/riscv/SraRISC.java | 17 - .../simple/node/cpus/riscv/SrlIRISC.java | 13 - .../seaofnodes/simple/node/cpus/riscv/SrlRISC.java | 17 - .../simple/node/cpus/riscv/StoreRISC.java | 50 - .../simple/node/cpus/riscv/SubFRISC.java | 18 - .../seaofnodes/simple/node/cpus/riscv/SubRISC.java | 16 - .../seaofnodes/simple/node/cpus/riscv/TFPRISC.java | 49 - .../seaofnodes/simple/node/cpus/riscv/TMPRISC.java | 42 - .../simple/node/cpus/riscv/UJmpRISC.java | 49 - .../simple/node/cpus/riscv/XorIRISC.java | 14 - .../seaofnodes/simple/node/cpus/riscv/XorRISC.java | 16 - .../seaofnodes/simple/node/cpus/riscv/riscv.java | 429 ---- .../simple/node/cpus/x86_64_v2/AddFMemX86.java | 33 - .../simple/node/cpus/x86_64_v2/AddFX86.java | 24 - .../simple/node/cpus/x86_64_v2/AddIX86.java | 23 - .../simple/node/cpus/x86_64_v2/AddMemX86.java | 24 - .../simple/node/cpus/x86_64_v2/AddX86.java | 11 - .../simple/node/cpus/x86_64_v2/AndIX86.java | 11 - .../simple/node/cpus/x86_64_v2/AndX86.java | 11 - .../simple/node/cpus/x86_64_v2/CallRX86.java | 30 - .../simple/node/cpus/x86_64_v2/CallX86.java | 49 - .../simple/node/cpus/x86_64_v2/CmpFX86.java | 24 - .../simple/node/cpus/x86_64_v2/CmpIX86.java | 38 - .../simple/node/cpus/x86_64_v2/CmpMemX86.java | 44 - .../simple/node/cpus/x86_64_v2/CmpX86.java | 28 - .../simple/node/cpus/x86_64_v2/DivFX86.java | 24 - .../simple/node/cpus/x86_64_v2/DivX86.java | 25 - .../simple/node/cpus/x86_64_v2/ExtendX86.java | 29 - .../simple/node/cpus/x86_64_v2/F8ToIX86.java | 22 - .../simple/node/cpus/x86_64_v2/FltX86.java | 36 - .../simple/node/cpus/x86_64_v2/FunX86.java | 31 - .../simple/node/cpus/x86_64_v2/I2f8X86.java | 21 - .../simple/node/cpus/x86_64_v2/ImmX86.java | 32 - .../simple/node/cpus/x86_64_v2/IntX86.java | 40 - .../simple/node/cpus/x86_64_v2/JmpX86.java | 65 - .../simple/node/cpus/x86_64_v2/LeaX86.java | 38 - .../simple/node/cpus/x86_64_v2/LoadX86.java | 44 - .../simple/node/cpus/x86_64_v2/MemAddX86.java | 28 - .../simple/node/cpus/x86_64_v2/MemOpX86.java | 89 - .../simple/node/cpus/x86_64_v2/MulFX86.java | 24 - .../simple/node/cpus/x86_64_v2/MulIX86.java | 27 - .../simple/node/cpus/x86_64_v2/MulX86.java | 24 - .../simple/node/cpus/x86_64_v2/NegX86.java | 20 - .../simple/node/cpus/x86_64_v2/NewX86.java | 23 - .../simple/node/cpus/x86_64_v2/NotX86.java | 21 - .../simple/node/cpus/x86_64_v2/OrIX86.java | 11 - .../simple/node/cpus/x86_64_v2/OrX86.java | 11 - .../simple/node/cpus/x86_64_v2/ParmX86.java | 17 - .../simple/node/cpus/x86_64_v2/ProjX86.java | 15 - .../simple/node/cpus/x86_64_v2/RegX86.java | 22 - .../simple/node/cpus/x86_64_v2/RetX86.java | 15 - .../simple/node/cpus/x86_64_v2/SarIX86.java | 32 - .../simple/node/cpus/x86_64_v2/SarX86.java | 21 - .../simple/node/cpus/x86_64_v2/SetX86.java | 44 - .../simple/node/cpus/x86_64_v2/ShlIX86.java | 32 - .../simple/node/cpus/x86_64_v2/ShlX86.java | 21 - .../simple/node/cpus/x86_64_v2/ShrIX86.java | 27 - .../simple/node/cpus/x86_64_v2/ShrX86.java | 21 - .../simple/node/cpus/x86_64_v2/SplitFlagsX86.java | 25 - .../simple/node/cpus/x86_64_v2/SplitX86.java | 52 - .../simple/node/cpus/x86_64_v2/StoreX86.java | 48 - .../simple/node/cpus/x86_64_v2/SubFX86.java | 23 - .../simple/node/cpus/x86_64_v2/SubX86.java | 10 - .../simple/node/cpus/x86_64_v2/TFPX86.java | 53 - .../simple/node/cpus/x86_64_v2/TMPX86.java | 40 - .../simple/node/cpus/x86_64_v2/UJmpX86.java | 41 - .../simple/node/cpus/x86_64_v2/XorIX86.java | 11 - .../simple/node/cpus/x86_64_v2/XorX86.java | 11 - .../simple/node/cpus/x86_64_v2/x86_64_v2.java | 565 ----- .../com/seaofnodes/simple/print/ASMPrinter.java | 85 - .../com/seaofnodes/simple/print/IRPrinter.java | 61 - .../simple/print/SimpleGraphAdapter.java | 57 - .../simple/print/SimpleGraphObserver.java | 35 - .../src/main/java/com/seaofnodes/simple/sys.java | 25 - .../java/com/seaofnodes/simple/type/Field.java | 140 -- .../main/java/com/seaofnodes/simple/type/Type.java | 543 ---- .../com/seaofnodes/simple/type/TypeConAry.java | 79 - .../com/seaofnodes/simple/type/TypeConAryB.java | 20 - .../com/seaofnodes/simple/type/TypeConAryI.java | 16 - .../java/com/seaofnodes/simple/type/TypeFloat.java | 110 - .../com/seaofnodes/simple/type/TypeFunPtr.java | 282 --- .../com/seaofnodes/simple/type/TypeInteger.java | 183 -- .../java/com/seaofnodes/simple/type/TypeMem.java | 197 -- .../com/seaofnodes/simple/type/TypeMemPtr.java | 181 -- .../java/com/seaofnodes/simple/type/TypeNil.java | 62 - .../java/com/seaofnodes/simple/type/TypePtr.java | 55 - .../java/com/seaofnodes/simple/type/TypeRPC.java | 111 - .../com/seaofnodes/simple/type/TypeScalar.java | 31 - .../com/seaofnodes/simple/type/TypeStruct.java | 514 ---- .../java/com/seaofnodes/simple/type/TypeTuple.java | 136 -- .../main/java/com/seaofnodes/simple/type/XInt.java | 241 -- .../main/java/com/seaofnodes/simple/util/Ary.java | 229 -- .../java/com/seaofnodes/simple/util/AryInt.java | 192 -- .../main/java/com/seaofnodes/simple/util/SB.java | 99 - .../java/com/seaofnodes/simple/util/Utils.java | 53 - chapter-escape/src/main/smp/sys.smp | 199 -- 283 files changed, 24377 deletions(-) delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/IterPeeps.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/Parser.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/Var.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/BuildLRG.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/Coalesce.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/ElfExpr.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/Encoding.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/FinalizeIR.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/IFG.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/InstSelect.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/LRG.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/LinkMem.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/ListScheduler.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/Machine.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/Opto.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/RIPRelSize.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/RegMask.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/RegMaskRW.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/codegen/TypeCheck.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/AddFNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/AddNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/AndNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ArithFNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ArithNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/BoolNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/BulkMemPhiNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/CFGNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/CProjNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/CallEndMach.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/CallEndNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/CallNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/CalleeSaveNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/CastMach.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/CastNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ConstantNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ConvertNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/CtrlNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/DivFNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/DivNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/EscapeMach.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/EscapeNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ExternNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/FRefNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/FldOffNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/FunNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/GuardMach.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/GuardNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/IfNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/LoadNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/LoopNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MachConcreteNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MachNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MemOpNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MemPhiNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MinusFNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MinusNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ModeNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MulFNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MulNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/MultiNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/NeverNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/NewNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/Node.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/NotNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/OrNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ParmNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/PhiNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ProjNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/PtrToIntMach.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/PtrToIntNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ReadOnlyMach.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ReadOnlyNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/RegionNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ReturnNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/SarNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ScopeNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ShlNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ShrNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/SplitNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/StartNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/StopNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/StoreNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/StructNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/SubFNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/SubNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/ToIntegerNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/XCtrlNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/XorNode.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpFARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/F8ToIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/FunARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/NegARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/ParmARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/ProjARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitFlagsARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitGPRARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddIRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndIRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/F8ToIRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FunRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/Int8RISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LUI.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NegRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrIRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ParmRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ProjRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/RetRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetIRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllIRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraIRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlIRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorRISC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddMemX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AndIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AndX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/F8ToIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemOpX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NegX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NotX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/OrIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/OrX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ParmX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ProjX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitFlagsX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/XorIX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/XorX86.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/print/IRPrinter.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/sys.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/Field.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/Type.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeConAry.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeConAryB.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeConAryI.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeFloat.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeInteger.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeMem.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeNil.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypePtr.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeRPC.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeScalar.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeStruct.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/TypeTuple.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/type/XInt.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/util/Ary.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/util/AryInt.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/util/SB.java delete mode 100644 chapter-escape/src/main/java/com/seaofnodes/simple/util/Utils.java delete mode 100644 chapter-escape/src/main/smp/sys.smp (limited to 'chapter-escape/src/main') diff --git a/chapter-escape/src/main/java/com/seaofnodes/simple/IterPeeps.java b/chapter-escape/src/main/java/com/seaofnodes/simple/IterPeeps.java deleted file mode 100644 index 2fe4e172..00000000 --- a/chapter-escape/src/main/java/com/seaofnodes/simple/IterPeeps.java +++ /dev/null @@ -1,230 +0,0 @@ -package com.seaofnodes.simple; - -import com.seaofnodes.simple.codegen.CodeGen; -import com.seaofnodes.simple.type.Type; -import com.seaofnodes.simple.type.TypeInteger; -import com.seaofnodes.simple.util.Ary; -import com.seaofnodes.simple.node.*; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Random; - -/** - * The IterPeeps runs after parsing. It iterates the peepholes to a fixed point - * so that no more peepholes apply. This should be linear because peepholes rarely - * (never?) increase code size. The graph should monotonically reduce in some - * dimension, which is usually size. It might also reduce in e.g. number of - * MulNodes or Load/Store nodes, swapping out more "expensive" Nodes for cheaper - * ones. - *
- * The theoretical overall worklist is mindless just grabbing the next thing and - * doing it. If the graph changes, put the neighbors on the worklist. - *
- * Lather, Rinse, Repeat until the worklist runs dry. - *

- * The main issues we have to deal with: - * - *

- */ -public class IterPeeps { - - public final WorkList _work; - - private final WorkList _workInline; - - public IterPeeps( long seed ) { - _work = new WorkList<>(seed); - _workInline = new WorkList<>(seed); - } - - @SuppressWarnings("unchecked") - public N add( N n ) { return (N)_work.push(n); } - - public void addAll( Ary ary ) { _work.addAll(ary); } - - /** - * Iterate peepholes to a fixed point - */ - public void iterate( CodeGen code ) { - while( true ) { - iteratePeeps(code); - CallEndNode cend; - while( (cend=_workInline.pop())!=null ) - if( cend.inlineSmall() ) break; - if( cend==null ) return; - } - } - - // Only try growing inlines once the shrinking peepholes reach a fixed point. - private void iteratePeeps( CodeGen code ) { - assert progressOnList(code, _work, true); - int cnt=0; - - Node n; - while( (n=_work.pop()) != null ) { - if( n.isDead() ) continue; - if( n instanceof CallEndNode cend ) _workInline.push(cend); - cnt++; // Useful for debugging, searching which peephole broke things - var obs = CodeGen.CODE._obs; - if( obs != null ) obs.before(n); - Node x = n.peepholeOpt(); - if( x != null ) { - if( x.isDead() ) { - if( obs != null ) obs.after(n, x, true); - continue; - } - // peepholeOpt can return brand-new nodes, needing an initial type set - if( x._type==null ) x.setType(x.compute()); - // Changes require neighbors onto the worklist - if( x != n || !(x instanceof ConstantNode) ) { - // All outputs of n (changing node) not x (prior existing node). - for( Node z : n._outputs ) _work.push(z); - // Everybody gets a free "go again" in case they didn't get - // made in their final form. - _work.push(x); - // If the result is not self, revisit all inputs (because - // there's a new user), and replace in the graph. - if( x != n ) { - for( Node z : n. _inputs ) _work.push(z); - for( Node z : x._outputs ) _work.push(z); - n.subsume(x); - } - } - // If there are distant neighbors, move to worklist - n.moveDepsToWorklist(); - assert progressOnList(code, _work, true); // Very expensive assert - } - if( n.isUnused() && !(n instanceof StopNode) ) - n.kill(); // Just plain dead - if( obs != null ) obs.after(n, x, true); - } - - } - - // Visit ALL nodes and confirm the invariant: - // Either you are on the _work worklist OR running `iter()` makes no progress. - - // This invariant ensures that no progress is missed, i.e., when the - // worklist is empty we have indeed done all that can be done. To help - // with debugging, the {@code assert} is broken out in a place where it is easy to - // stop if a change is found. - - // Also, the normal usage of `iter()` may attempt peepholes with distance - // neighbors and these should fail, but will then try to add dependencies - // {@link #Node.addDep} which is a side effect in an assert. The {@link - // #midAssert} is used to stop this side effect. - // Pessimistic solver assert - public static boolean progressOnList(CodeGen code, WorkList list, boolean dir ) { - code._midAssert = true; - Node changed = code._stop.walk( n -> { - Node m = n; - Type nval = n.compute(); - if( (!n.iskeep() || n._nid<=8) && // Types must be forwards, even if on worklist - ( dir - ? nval.isa(n._type) // Pesi: new value lifts over old - : n._type.isa(nval) // Opto: new value falls over old - ) ) { - if( list.on(n) ) return null; - m = n.peepholeOpt(); - if( m==null ) return null; - } - System.err.println("BREAK HERE FOR BUG"); - return m; - }); - code._midAssert = false; - return changed==null; - } - - /** - * Classic WorkList, with a fast add/remove, dup removal, random pull. - * The Node's nid is used to check membership in the worklist. - */ - @SuppressWarnings("unchecked") - public static class WorkList { - - private Node[] _es; - private int _len; - private final BitSet _on; // Bit set if Node._nid is on WorkList - private final Random _R; // For randomizing pull from the WorkList - private final long _seed; - - /* Useful stat - how many nodes are processed in the post parse iterative opt */ - private long _totalWork = 0; - - public WorkList() { this(123); } - WorkList(long seed) { - _es = new Node[1]; - _len=0; - _on = new BitSet(); - _seed = seed; - _R = new Random(); - _R.setSeed(_seed); - } - - /** - * Pushes a Node on the WorkList, ensuring no duplicates - * If Node is null it will not be added. - */ - public E push( E x ) { - if( x==null ) return null; - int idx = x._nid; - if( !_on.get(idx) ) { - _on.set(idx); - if( _len==_es.length ) - _es = Arrays.copyOf(_es,_len<<1); - _es[_len++] = x; - _totalWork++; - } - return x; - } - - public void addAll( Ary ary ) { - for( E n : ary ) - push(n); - } - - /** - * True if Node is on the WorkList - */ - public boolean on( E x ) { return _on.get(x._nid); } - public boolean isEmpty() { return _len==0; } - - /** - * Removes a random Node from the WorkList; null if WorkList is empty - */ - public E pop() { - if( _len == 0 ) return null; - int idx = _R.nextInt(_len); - E x = (E)_es[idx]; - _es[idx] = _es[--_len]; // Compress array - _on.clear(x._nid); - return x; - } - - public void clear() { - _len = 0; - _on.clear(); - _R.setSeed(_seed); - _totalWork = 0; - } - } -} diff --git a/chapter-escape/src/main/java/com/seaofnodes/simple/Parser.java b/chapter-escape/src/main/java/com/seaofnodes/simple/Parser.java deleted file mode 100644 index 19dd1c29..00000000 --- a/chapter-escape/src/main/java/com/seaofnodes/simple/Parser.java +++ /dev/null @@ -1,2580 +0,0 @@ -package com.seaofnodes.simple; - -import com.seaofnodes.simple.codegen.CodeGen; -import com.seaofnodes.simple.node.*; -import com.seaofnodes.simple.type.*; -import com.seaofnodes.simple.util.Ary; -import com.seaofnodes.simple.util.Utils; -import com.seaofnodes.simple.node.ScopeNode.Kind; -import java.util.*; - -/** - * The Parser converts a Simple source program to the Sea of Nodes intermediate - * representation directly in one pass. There is no intermediate Abstract - * Syntax Tree structure. - *

- * This is a simple recursive descent parser. All lexical analysis is done here as well. - */ -public class Parser { - - public static ConstantNode ZERO; // Very common node, cached here - public static ConstantNode NIL; // Very common node, cached here - public static XCtrlNode XCTRL; // Very common node, cached here - - // Compile driver - public final CodeGen _code; - - // The Lexer. Thin wrapper over a byte[] buffer with a cursor. - private Lexer _lexer; - - /** - * Current ScopeNode - ScopeNodes change as we parse code, but at any point of time - * there is one current ScopeNode. The reason the current ScopeNode can change is to do with how - * we handle branching. See {@link #parseIf()}. - *

- * Each ScopeNode contains a stack of lexical scopes, each scope is a symbol table that binds - * variable names to Nodes. The top of this stack represents current scope. - *

- * We keep a list of all ScopeNodes so that we can show them in graphs. - * @see #parseIf() - * @see #_xScopes - */ - public ScopeNode _scope; - - /** - * List of keywords disallowed as identifiers - */ - public static final HashSet KEYWORDS = new HashSet<>(){{ - add("bool"); - add("break"); - add("byte"); - add("continue"); - add("else"); - add("f32"); - add("f64"); - add("false"); - add("flt"); - add("i16"); - add("i32"); - add("i64"); - add("i8"); - add("if"); - add("int"); - add("new"); - add("null"); - add("return"); - add("struct"); - add("true"); - add("u1"); - add("u16"); - add("u32"); - add("u8"); - add("while"); - }}; - - /** - * We clone ScopeNodes when control flows branch; it is useful to have - * a list of all active ScopeNodes for purposes of visualization of the SoN graph - */ - public final Stack _xScopes = new Stack<>(); - - ScopeNode _continueScope; - ScopeNode _breakScope; // Merge all the while-breaks here - FunNode _fun; // Current function being parsed - - // Mapping from a type name to a Type. The string name matches - // `type.str()` call. - public static HashMap TYPES = defaultTypes(); - - // Mapping from a type name to the constructor for a Type. - public final HashMap INITS; - - - public Parser(CodeGen code, TypeInteger arg) { - _code = code; - _scope = new ScopeNode(); - _continueScope = _breakScope = null; - ZERO = con(TypeInteger.ZERO).keep(); - NIL = con(Type.NIL).keep(); - XCTRL= new XCtrlNode().peephole().keep(); - TYPES = defaultTypes(); - INITS = new HashMap<>(); - } - - @Override - public String toString() { return _lexer.toString(); } - - public static HashMap defaultTypes() { - return new HashMap<>() {{ - put("bool",TypeInteger.U1 ); - put("byte",TypeInteger.U8 ); - put("f32" ,TypeFloat .F32); - put("f64" ,TypeFloat .F64); - put("flt" ,TypeFloat .F64); - put("i16" ,TypeInteger.I16); - put("i32" ,TypeInteger.I32); - put("i64" ,TypeInteger.BOT); - put("i8" ,TypeInteger.I8 ); - put("int" ,TypeInteger.BOT); - put("u1" ,TypeInteger.U1 ); - put("u16" ,TypeInteger.U16); - put("u32" ,TypeInteger.U32); - put("u8" ,TypeInteger.U8 ); - put("val" ,Type.TOP); // Marker type, indicates type inference - put("var" ,Type.BOTTOM); // Marker type, indicates type inference - }}; - } - - // Debugging utility to find a Node by index - public Node f(int nid) { return _code.f(nid); } - - private Node ctrl() { return _scope.ctrl(); } - private N ctrl(N n) { return _scope.ctrl(n); } - - public void parse() { - // Graph callbacks during scope setup need a source position. - _lexer = new Lexer(sys.SYS); - - _scope.define(ScopeNode.CTRL, Type.CONTROL , false, null, _lexer); - _scope.define(ScopeNode.MEM0, TypeMem.BOT , false, null, _lexer); - _scope.define(ScopeNode.ARG0, TypeInteger.BOT, false, null, _lexer); - - ctrl(XCTRL); - _scope.mem(con(TypeMem.BOT)); - - // Parse the sys import - while( !_lexer.isEOF() ) { - parseStatement(); - _lexer.skipWhiteSpace(); - } - - // Reset lexer for program text - _lexer = new Lexer(_code._src); - _xScopes.push(_scope); - - // Parse whole program, as-if function header "{ int arg -> body }" - parseFunctionBody( _code._main,loc(),"arg"); - - // Kill an empty default main. Keep only if it was explicitly defined - // (programmer asked for a "main") or it has stuff (i.e. beginner - // default main). - FunNode main = _code.link(_code._main); - StopNode stop = _code._stop; - // Gather an explicit main - FunNode xmain = null; - for( Node n : stop._inputs ) - if( n instanceof ReturnNode ret && "main".equals(ret.fun()._name) ) - if( xmain != null ) throw Utils.TODO(); - else xmain = ret.fun(); - - if( main.ret().expr()._type==Type.TOP && main.uctrl()==null ) { - // Kill an empty default main; so it does not attempt to put a - // "main" in any final ELF file - main.setDef(1,XCTRL); // Delete default start input - stop.delDef(stop._inputs.find(main.ret())); - if( xmain != null ) - _code.setMain(xmain); - - } else { - // We have a non-empty default main. - if( xmain != null ) - // Found an explicit "main" AND we have a default "main" - throw error("Cannot define both an explicit main and a default main"); - main._name = "main"; - } - - if( !_lexer.isEOF() ) throw _errorSyntax("unexpected"); - - // Clean up and reset - _xScopes.pop(); - _scope.kill(); - for( StructNode init : INITS.values() ) - init.unkeep().kill(); - INITS.clear(); - for( Ary captures : CAPTURES.values() ) - for( Node value : captures ) value.unkill(); - CAPTURES.clear(); - stop.peephole(); - // Helpers are built with init(), so their complete call graph exists - // before any inlining. Seed those nodes now along with the parsed body. - _code._start.walk(n -> { _code.add(n); return null; }); - } - - /** - * Parses a function body, assuming the header is parsed. - */ - private ReturnNode parseFunctionBody( TypeFunPtr sig, Lexer loc, String... ids) { - return parseFunctionBody(sig, loc, null, ids); - } - - private FunNode _privateFun; - private HashMap _fieldVars; - private record Constructor(TypeFunPtr sig, Lexer loc, int body, String[] ids, java.util.BitSet finals) {} - private Constructor _constructor; - private final HashMap ALLOCS = new HashMap<>(); - private final HashMap INITIALIZERS = new HashMap<>(); - private final HashMap> CAPTURES = new HashMap<>(); - private Ary _captures; - - private ReturnNode parseFunctionBody(TypeFunPtr sig, Lexer loc, java.util.BitSet finals, String... ids) { - return parseFunctionBody(sig,loc,finals,false,ids); - } - - private ReturnNode parseFunctionBody(TypeFunPtr sig, Lexer loc, java.util.BitSet finals, boolean initializer, String... ids) { - // If this is a method, record & restore the existing struct fields, - // which are also the struct initializers. The method might update - // mutable fields, so when the function parse is done reset back to - // pre-function-parse values. - Node[] preParse = new Node[_scope.nIns()]; - for( int i=0; i<_scope.nIns(); i++ ) - preParse[i] = _scope.in(i)==null ? null : _scope.in(i).keep(); - - // Stack parser state on the local Java stack, and unstack it later - FunNode oldfun = _fun; - FunNode oldPrivate = _privateFun; - HashMap oldFields = _fieldVars; - Constructor oldConstructor = _constructor; - _fieldVars = new HashMap<>(); - _constructor = null; - Ary oldCaptures = _captures; - _captures = initializer ? new Ary<>(Node.class) : null; - ScopeNode breakScope = _breakScope; _breakScope = null; - ScopeNode continueScope = _continueScope; _continueScope = null; - - FunNode fun = _fun = (FunNode)peep(new FunNode(loc(),sig,_nestedType,null,_code._start)); - // Once the function header is available, install in linker table - - // allowing recursive functions. Linker matches on declared args and - // exact fidx, and ignores the return (because the fidx will only match - // the exact single function). - _code.link(fun); - _privateFun = sig.ret() instanceof TypeMem ? fun : null; - fun._constructor = _privateFun!=null; - - Node rpc = new ParmNode("$rpc",0,TypeRPC.BOT,fun,con(TypeRPC.BOT)).peephole(); - - // Build a multi-exit return point for all function returns - RegionNode r = new RegionNode( null,null,null).init(); - assert r.inProgress(); - PhiNode rmem = new BulkMemPhiNode(ScopeNode.MEM0,r,null).init(); - PhiNode rrez = (sig.ret() instanceof TypeMem - ? new BulkMemPhiNode("#selfMem",r,null) : new PhiNode(ScopeNode.ARG0,r,null)).init(); - ReturnNode ret = new ReturnNode(r, rmem, rrez, rpc, fun).init(); - fun.setRet(ret); - assert ret.inProgress(); - _code._stop.addDef(ret); - - - // Pre-call the function from Start, with worse-case arguments. This - // represents all the future, yet-to-be-parsed functions calls and - // external calls. - _scope.push(new Kind.Func(_privateFun!=null)); - ctrl(fun); // Scope control from function - // Unknown callers supply whole memory; field aliases are discovered lazily. - _scope.mem(new ParmNode(ScopeNode.MEM0,1,TypeMem.BOT,fun,new ProjNode(_code._start,1,ScopeNode.MEM0).peephole()).peephole()); - // All args, "as-if" called externally - for( int i=0; i=0; j-- ) - if( _scope.var(j)._name.equals(f._fname) ) { v=_scope.var(j); break; } - assert v!=null; - _fieldVars.put(f._fname,v); - if( !f._one ) { - Node value=missingInit(defaults.in(i),new java.util.BitSet()) ? con(Type.BOTTOM) - : new LoadNode(loc(),f._fname,f._alias,privateMem(),self(),off(shape,f._fname),true).peephole(); - _scope.update(v,value); - } - } - } - Node last=ZERO; - while (!peek('}') && !_lexer.isEOF()) { - last = parseStatement(); - if( initializer ) fields = initFields(fields); - } - if( initializer ) { - finishFields(); - CAPTURES.put(_nestedType,_captures); - if( _constructor!=null ) { - Constructor ctor=_constructor; - int end=pos(ctor.body()); - ReturnNode body=parseFunctionBody(ctor.sig(),ctor.loc(),ctor.finals(),ctor.ids()); - body.fun().setName(shortName(_nestedType)); - require("}"); - pos(end); - } - } - if( _privateFun==fun ) last = storeFields(initializer); - - // Last expression is the return except for the top-level main - if( ctrl()._type==Type.CONTROL ) - if( fun.sig() != _code._main ) - fun.addReturn(ctrl(), _scope.mem(), last); - else { - fun.setDef(1,XCTRL); // Kill default main - _code.addAll(fun._outputs); - } - - // Pop off the inProgress node on the multi-exit Region merge - assert r.inProgress(); - r ._inputs.pop(); - rmem._inputs.pop(); - rrez._inputs.pop(); - r._loc = loc(); // Final position - assert !r.inProgress(); - - // Force peeps, which have been avoided due to inProgress - ret.setDef(1,rmem.peephole()); - ret.setDef(2,rrez.peephole()); - ret.setDef(0,r.peephole()); - ret = (ReturnNode)ret.peephole(); - - // Function scope ends - if( initializer ) _scope.pop(); - _scope.pop(); - _fun = oldfun; - _privateFun = oldPrivate; - _fieldVars = oldFields; - _constructor = oldConstructor; - _captures = oldCaptures; - _breakScope = breakScope; - _continueScope = continueScope; - - // Reset all fields to pre-parse days - for( int i=0; i - * '{' statements '}' - * - * Does not parse the opening or closing '{}' - * @return a {@link Node} or {@code null} - */ - private Node parseBlock(Kind kind) { - // Enter a new scope - _scope.push(kind); - Node last = ZERO; - while (!peek('}') && !_lexer.isEOF()) - last = parseStatement(); - // Exit scope - last.keep(); - _scope.pop(); - return last.unkeep(); - } - - /** - * Parses a statement - * - *

-     *     returnStatement | declStatement | blockStatement | ifStatement | expressionStatement
-     * 
- * @return a {@link Node} or {@code null} - */ - private Node parseStatement() { - if( matchx("return") ) return parseReturn(); - else if (matchx("if") ) return parseIf(); - else if (matchx("while") ) return parseWhile(); - else if (matchx("for") ) return parseFor(); - else if (matchx("break") ) return parseBreak(); - else if (matchx("continue")) return parseContinue(); - else if (matchx("struct") ) return parseStruct(); - else if (_scope.inConstructor() && matchx("new")) return parseConstructorDeclaration(); - else if (matchx(";") ) return null; // Empty statement - // Break ambiguity around leading function types and starting a block - else if (peek('{') && !isTypeFun() ) { - match("{"); - return require(parseBlock(new Kind.Block()),"}"); - } - // Declaration or normal assignment/expression - else return parseDeclarationStatement(); - } - - // In a struct declaration, new names the constructor. Its body still - // parses as a function; in expressions, new allocates and calls it. - private Node parseConstructorDeclaration() { - Lexer loc=loc(); - String name=requireId(); - String expect=shortName(_nestedType); - if( !name.equals(expect) ) - throw error("Constructor name '"+name+"' must match type name '"+expect+"'"); - require("="); - Node ctor=constructorFunc(); - TypeFunPtr sig=(TypeFunPtr)ctor._type; - Node lift=liftExpr(ctor,sig,true); - if( !_scope.define(name,sig,true,lift,loc) ) - throw error("Redefining constructor '"+name+"'"); - _scope.lookup(name)._init=true; - return require(lift,";"); - } - - /** - * Parses a while statement - * - *
-     *     while ( expression ) statement
-     * 
- * @return a {@link Node}, never {@code null} - */ - private Node parseWhile() { - require("("); - return parseLooping(false); - } - - - /** - * Parses a for statement - * - *
-     *     for( var x=init; test; incr ) body
-     * 
- * @return a {@link Node}, never {@code null} - */ - private Node parseFor() { - // { var x=init,y=init,...; - // while( test ) { - // body; - // next; - // } - // } - require("("); - _scope.push(new Kind.Block()); // Scope for the index variables - if( !match(";") ) // Can be empty init "for(;test;next) body" - parseDeclarationStatement(); // Non-empty init - Node rez = parseLooping(true); - _scope.pop(); // Exit index variable scope - return rez; - } - - // Shared by `for` and `while` - private Node parseLooping( boolean doFor ) { - - var savedContinueScope = _continueScope; - var savedBreakScope = _breakScope; - - // Loop region has two control inputs, the first is the entry - // point, and second is back edge that is set after loop is parsed - // (see end_loop() call below). Note that the absence of back edge is - // used as an indicator to switch off peepholes of the region and - // associated phis; see {@code inProgress()}. - - ctrl(new LoopNode(loc(),ctrl()).peephole()); // Note we set back edge to null here - - // At loop head, we clone the current Scope (this includes all - // names in every nesting level within the Scope). - // We create phis eagerly for all the names we find, see dup(). - - // Save the current scope as the loop head - ScopeNode head = _scope.keep(); - // Clone the head Scope to create a new Scope for the body. - // Create phis eagerly as part of cloning - _xScopes.push(_scope = _scope.dup(true)); // The true argument triggers creating phis - - // Parse predicate - var pred = peek(';') ? con(1) : parseAsgn(); - require( doFor ? ";" : ")" ); - - // IfNode takes current control and predicate - Node ifNode = new IfNode(ctrl(), pred.keep()).peephole(); - // Setup projection nodes - Node ifT = new CProjNode(ifNode. keep(), 0, "True" ).peephole().keep(); - Node ifF = new CProjNode(ifNode.unkeep(), 1, "False").peephole(); - - // for( ;;next ) body - int nextPos = -1, nextEnd = -1; - if( doFor ) { - // Skip the next expression and parse it later - nextPos = pos(); - skipAsgn(); - nextEnd = pos(); - require(")"); - } - - // Clone the body Scope to create the break/exit Scope which accounts for any - // side effects in the predicate. The break/exit Scope will be the final - // scope after the loop, and its control input is the False branch of - // the loop predicate. Note that body Scope is still our current scope. - ctrl(ifF); - _xScopes.push(_breakScope = _scope.dup()); - _breakScope.addGuards(ifF,pred,true); // Up-cast predicate - - // No continues yet - _continueScope = null; - - // Parse the true side, which corresponds to loop body - // Our current scope is the body Scope - ctrl(ifT.unkeep()); // set ctrl token to ifTrue projection - _scope.addGuards(ifT,pred.unkeep(),false); // Up-cast predicate - parseStatement().isKill(); // Parse loop body - _scope.removeGuards(ifT); - - // Merge the loop bottom into other continue statements - if (_continueScope != null) { - _continueScope = jumpTo(_continueScope); - _scope.kill(); - _scope = _continueScope; - } - - // Now append the next code onto the body code - if( doFor ) { - int old = pos(nextPos); - if( !peek(')') ) - parseAsgn(); - if( pos() != nextEnd ) - throw errorSyntax( "Unexpected code after expression" ); - pos(old); - } - - // The true branch loops back, so whatever is current _scope.ctrl gets - // added to head loop as input. endLoop() updates the head scope, and - // goes through all the phis that were created earlier. For each phi, - // it sets the second input to the corresponding input from the back - // edge. If the phi is redundant, it is replaced by its sole input. - var exit = _breakScope; - head.endLoop(_scope, exit); - head.unkeep().kill(); - - _xScopes.pop(); // Cleanup - _xScopes.pop(); // Cleanup - - _continueScope = savedContinueScope; - _breakScope = savedBreakScope; - - // At exit the false control is the current control, and - // the scope is the exit scope after the exit test. - // During sys parsing, there is no xscope here. - if( !_xScopes.isEmpty() ) { - _xScopes.pop(); - _xScopes.push( exit ); - } - _scope = exit; - return ZERO; - } - - private ScopeNode jumpTo(ScopeNode toScope) { - ScopeNode cur = _scope.dup(); - ctrl(XCTRL); // Kill current scope - // Prune nested lexical scopes that have depth > than the loop head - // We use _breakScope as a proxy for the loop head scope to obtain the depth - while( cur.depth() > _breakScope.depth() ) - cur.pop(); - // If this is a continue then first time the target is null - // So we just use the pruned current scope as the base for the - // "continue" - if( toScope == null ) - return cur; - // toScope is either the break scope, or a scope that was created here - assert toScope.depth() <= _breakScope.depth(); - toScope.ctrl(toScope.mergeScopes(cur,loc()).peephole()); - return toScope; - } - - private void checkLoopActive() { if (_breakScope == null) throw error("No active loop for a break or continue"); } - - private Node parseContinue() { checkLoopActive(); _continueScope = require(jumpTo( _continueScope ),";"); return ZERO; } - private Node parseBreak () { - checkLoopActive(); - // At the time of the break, and loop-exit conditions are only valid if - // they are ALSO valid at the break. It is the intersection of - // conditions here, not the union. - _breakScope.removeGuards(_breakScope.ctrl()); - _breakScope = require(jumpTo(_breakScope ),";"); - _breakScope.addGuards(_breakScope.ctrl(), null, false); - return ZERO; - } - - // Look for an unbalanced `)`, skipping balanced - private void skipAsgn() { - int paren=0; - while( true ) - // Next X char handles skipping complex comments - switch( _lexer.nextXChar() ) { - case Character.MAX_VALUE: - throw Utils.TODO(); - case ')': - if( --paren<0 ) { - posT( pos() - 1 ); - return; // Leave the `)` behind - } - break; - case '(': paren ++; break; - default: break; - } - } - - - /** - * Parses a statement - * - *
-     *     if ( expression ) statement [else statement]
-     * 
- * @return a {@link Node}, never {@code null} - */ - private Node parseIf() { - // Parse predicate - require("("); - var pred = require(parseAsgn(), ")"); - return parseTrinary(pred,"else"); - } - - // Parse a conditional expression, merging results. - private Node parseTrinary( Node pred, String fside ) { - // IfNode takes current control and predicate - pred.keep(); - Node ifNode = new IfNode(ctrl(), pred).peephole(); - // Setup projection nodes - Node ifT = new CProjNode(ifNode. keep(), 0, "True" ).peephole().keep(); - Node ifF = new CProjNode(ifNode.unkeep(), 1, "False").peephole().keep(); - // In if true branch, the ifT proj node becomes the ctrl - // But first clone the scope and set it as current - ScopeNode fScope = _scope.dup(); // Duplicate current scope - fScope.ctrl(ifF); // The pending arm already starts at False - _xScopes.push(fScope); // For graph visualization we need all scopes - - // Parse the true side - ctrl(ifT.unkeep()); // set ctrl token to ifTrue projection - _scope.addGuards(ifT,pred,false); // Up-cast predicate - // Parse true-side flavor - Node lhs = switch( fside ) { - case "else" -> parseStatement(); // if( pred ) stmts; - case ":" -> parseAsgn(); // pred ? asgn; - case "&&" -> parseLogical(); // pred && expr - case "||" -> pred; // pred || expr_is_ignored - default -> throw Utils.TODO(); - }; - lhs.keep(); - _scope.removeGuards(ifT); - - // See if a one-sided def was made: "if(pred) int x = 1;" and throw. - // See if any forward-refs were made, and copy them to the other side: - // "pred ? n*fact(n-1) : 1" - fScope.balanceIf(_scope); - - ScopeNode tScope = _scope; - - // Parse the false side - _scope = fScope; // Restore scope, then parse else block if any - ifF.unkeep(); // fScope already owns the false control - // Up-cast predicate, even if not else clause, because predicate can - // remain true if the true clause exits: `if( !ptr ) return 0; return ptr.fld;` - _scope.addGuards(ifF,pred,true); - // Parse false-side flavor - boolean doRHS = false; // RHS is optional for if/else and trinary - Node rhs = switch( fside ) { - case "else" -> (doRHS=match(fside)) ? parseStatement() : con(lhs._type.makeZero()); - case ":" -> (doRHS=match(fside)) ? parseAsgn() : con(lhs._type.makeZero()); - case "&&" -> rhs = pred; - case "||" -> rhs = parseLogical(); - default -> throw Utils.TODO(); - }; - rhs.keep(); - _scope.removeGuards(ifF); - if( doRHS || fside.equals("||") ) - fScope = _scope; - pred.unkeep(); - - // Check the trinary widening int/flt - if( !fside.equals("else") ) { - rhs = widenInt( rhs.unkeep(), lhs._type ).keep(); - lhs = widenInt( lhs.unkeep(), rhs._type ).keep(); - } - - _scope = tScope; - _xScopes.pop(); // Discard pushed from graph display - // See if a one-sided def was made: "if(pred) int x = 1;" and throw. - // See if any forward-refs were made, and copy them to the other side: - // "pred ? n*fact(n-1) : 1" - tScope.balanceIf(fScope); - - // Merge results - RegionNode r = ctrl(tScope.mergeScopes(fScope,loc())); - Node ret = peep(new PhiNode("",r,lhs.unkeep(),rhs.unkeep())); - // Immediately fail e.g. `arg ? 7 : ptr` - ParseException err; - if( !fside.equals("else") && (err=ret.err()) !=null ) throw err; - r.peephole(); - return ret; - } - - /** - * Parses a return statement; "return" already parsed. - * The $ctrl edge is killed. - * - *
-     *     'return' expr ;
-     * 
- * @return an expression {@link Node}, never {@code null} - */ - private Node parseReturn() { - var expr = require(parseAsgn(), ";"); - // Force the lazy whole-memory Phi before closing this exit. - if( _privateFun==_fun ) - throw error("A constructor cannot return a value"); - _fun.addReturn(ctrl(), _scope.mem(), expr); - ctrl(XCTRL); // Kill control - return expr; - } - - - - /** Parse: [name '='] expr - */ - private Node parseAsgn() { - int old = pos(); - String name = _lexer.matchId(); - int old_pre_equals = pos(); - // Just a plain expression, no assignment. - // Distinguish `var==expr` from `var=expr` - if( name==null || KEYWORDS.contains(name) || !matchOpx('=','=') ) - { pos(old); return parseExpression(); } - - // Find variable to update - Var def = _scope.lookup(name); - if( def==null ) - throw error("Undefined name '" + name + "'"); - - // If a method var, allow nested blocks and methods, but not fcns or other structs. - // Else safety check for accessing fields out of function scope. - if( instance(def) ) { - pos(old_pre_equals); // setup for `self.name = expr` - Var selfVar = _scope.lookup("self"); - Node self = liftExpr(_scope.in(selfVar),selfVar.type(),true); - return parsePostfixName(self,name); - } - - // TOP fields are for late-initialized fields; these have never - // been written to, and this must be the final write. Other writes - // outside the constructor need to check the final bit. - if( _scope.in(def._idx)._type!=Type.TOP && def._final && - // Inside an allocation, final assign is OK, outside nope. - // The alloc() call added the allocation scope - !_scope.canInit(def) ) - throw error("Cannot reassign final '"+name+"'"); - checkSharedField(def); - - // Parse assignment expression - checkCaptureWrite(def); - Node expr = parseAsgn(); - - // Lift expression, based on type - Node lift = liftExpr(expr.keep(), def.type(), true); - // Update - _scope.update(name,lift); - // Return un-lifted expr - return expr.unkeep(); - } - - // Apply declared access permissions; widen floats and narrow integers. - // Early error if types do not match variable. - private Node liftExpr(Node expr, Type t, boolean isLoad) { - if( t==Type.BOTTOM || t==Type.TOP ) return expr; - // Constructor sentinels record missing initialization, not a value - // needing conversion. Keep them visible to the completion check. - if( expr instanceof ConstantNode && !(expr instanceof FRefNode) && - (expr._type==Type.TOP || expr._type==Type.BOTTOM) ) return expr; - if( t instanceof TypeMemPtr tmp && tmp.isFinal() ) - expr = peep(new ReadOnlyNode(expr)); - if( expr instanceof FunPtrNode && t instanceof TypeFunPtr ) return expr; - return peep(new ConvertNode(t,expr)); - } - - private Node widenInt( Node expr, Type t ) { - return (expr._type instanceof TypeInteger || expr._type==Type.NIL) && t instanceof TypeFloat - ? peep(new ToFloatNode(expr)) : expr; - } - - /** - * Parse declaration or expression statement - * declStmt = type var['=' exprAsgn][, var['=' exprAsgn]]* ';' | exprAsgn ';' - *

- * exprAsgn = var '=' exprAsgn | expr - */ - private Node parseDeclarationStatement() { - int old = pos(); - Type t = type(); - if( peek('.') ) // Ambiguity static vars: "type.var", parse as expression - { pos(old); t=null; } - if( t == null ) - return require(parseAsgn(),";"); - - // now parse var['=' asgnexpr] in a loop - Node n = parseDeclaration(t); - while( match(",") ) - n = parseDeclaration(t); - return require(n,";"); - } - - // Widen a reassignable binding without discarding the initializer's - // permissions. Lattice glb includes readonly memory and is too broad here. - private Type inferredType(Type t) { - if( t instanceof TypeMemPtr tmp ) { - if( tmp._obj.isAry() ) { - Type elem = tmp._obj._fields[1]._t; - if( elem instanceof TypeConAry ) - elem = ((TypeMemPtr)TYPES.get(tmp._obj._name))._obj._fields[1]._t; - return typeAry(elem,tmp._obj._fields[1]._final).withAccess(tmp._ro).makeNullable(); - } - Type base = TYPES.get(tmp._obj._name); - TypeMemPtr ptr = (TypeMemPtr)base; - return ptr.withAccess(tmp._ro).makeNullable(); - } - return t.glb(false); - } - - // The binding modifier sits immediately before the name. It never - // changes permissions on the referenced object. - private boolean bindingFinal(Type t) { - if( match("!") ) return false; - if( match("~") ) return true; - return t==Type.TOP || t instanceof TypeNil; - } - - /** Parse final: [!|~]var['=' asgn] - */ - private Node parseDeclaration(Type t) { - assert t!=null; - // Has var/val instead of a user-declared type - boolean inferType = t==Type.TOP || t==Type.BOTTOM; - boolean xfinal = bindingFinal(t); - Lexer loc = loc(); - String name = requireId(); - // Optional initializing expression follows - boolean fld_final = false; // Fixed field independent of pointee access - boolean initialized = match("="); - Node expr; - if( initialized ) { - expr = isExternDecl() ? externDecl(name,t) - : _scope.inConstructor() && name.equals(shortName(_nestedType)) - ? constructorFunc() : parseAsgn(); - // var/val, then type comes from expression - if( inferType ) { - if( expr._type==Type.NIL ) - throw error("a not-null/non-zero expression"); - t = expr._type; - if( !xfinal ) t = inferredType(t); // Widen if not final - // A final field is still a local variable during construction. - // Its constant default is a value, not a one-value declaration - // type: later assignments and loop Phis may change it. - else if( _scope.inConstructor() && !(t instanceof TypeFunPtr) ) { - Type wide=inferredType(t); - t = t instanceof TypeMemPtr ptr && ptr.notNull() - ? TypeMemPtr.make((byte)2,((TypeMemPtr)wide)._obj,false).withAccess(ptr._ro) : wide; - } - } - // expr is a constant function - if( t instanceof TypeFunPtr && expr._type instanceof TypeFunPtr tfp && tfp.isConstant() ) { - if( expr instanceof ExternNode ) t = expr._type; // Upgrade declared type to exact function - else if( _code._link(tfp)!=null ) _code.link(tfp).setName(name); // Assign debug name to Simple function - } - - } else { - // Need an expression to infer the type. - // Also, if not-null then need an initializing expression. - // Allowed in a class def, because type/init will happen in the constructor. - if( (inferType || (t instanceof TypeNil tn && !tn.nullable() )) && !_scope.inConstructor() ) - throw errorSyntax("=expression"); - // Initial value for uninitialized struct fields. - expr = switch( t ) { - // Nullable pointers get a NIL; not-null get a TOP which - // signals that they *must* be initialized in the constructor. - case TypeNil tn -> tn.nullable() ? NIL : con(Type.TOP); - case TypeInteger ti -> xfinal ? con(Type.TOP) : ZERO; - case TypeFloat tf -> con(xfinal ? Type.TOP : TypeFloat.FZERO); - // Bottom signals type inference: they must be initialized in - // the constructor and that's when we'll discover the type. - case Type tt -> { assert tt==Type.BOTTOM; yield con(tt); } - }; - // Nullable fields are set in the constructor, but remain shallow final. - // e.g. final pointer to a r/w array - if( t instanceof TypeNil tn && !tn.nullable() && xfinal ) - fld_final = true; - } - - // Lift expression, based on type - Node lift = liftExpr(expr, t, true); - - // Lift type to the declaration. This will report as an error later if - // we cannot lift the type. - // Define a new name - if( !_scope.define(name,t,xfinal || fld_final,lift, loc) ) - throw error("Redefining name '" + name + "'", loc); - _scope.lookup(name)._init = initialized; - return lift; - } - - - - /** - * Parse a struct declaration, and return the following statement. - * Structs cannot be redefined, but can be nested. - * - * @return zero - */ - private String _nestedType; - private static String shortName(String name) { return name.substring(name.lastIndexOf('.')+1); } - - private Node parseStruct() { - String old = _nestedType; - String name = requireId(); - if( old!=null ) name=old+"."+name; - _nestedType=name; - TypeMemPtr ptr = TYPES.get(name) instanceof TypeMemPtr p ? p : TypeMemPtr.make(TypeStruct.open(name)); - TYPES.put(name,ptr); - require("{"); - TypeFunPtr sig = _code.makeFun(TypeFunPtr.make(false,false,new Type[]{ptr,TypeMem.BOT},TypeMem.BOT)); - ReturnNode init = parseFunctionBody(sig,loc(),null,true,"self","#selfMem"); - init.fun()._name=name+"."; - INITIALIZERS.put(name,init); - TypeStruct shape = ((TypeMemPtr)TYPES.get(name))._obj; - ALLOCS.put(name,makeAllocator(shape,init)); - _nestedType=old; - require("}"); - require(";"); - return ZERO; - } - - private int initFields(int index) { - TypeStruct shape = ((TypeMemPtr)TYPES.get(_nestedType))._obj; - while( index<_scope.nIns() ) { - Var v = _scope.var(index++); - if( v.isFRef() ) continue; - Node value = _scope.in(v); - // Only function declarations are shared across instances. A final - // data field can change in a named or inline constructor, so a - // constant default does not justify folding every future read. - boolean constant = v._final && v._init && value._type instanceof TypeFunPtr && value._type.isConstant(); - Field field = Field.make(v._name,v.type(),_code.getALIAS(),v._final,constant); - shape=shape.add(field); - TYPES.put(_nestedType,TypeMemPtr.make(shape)); - _fieldVars.put(v._name,v); - } - return index; - } - - private void finishFields() { - TypeStruct shape = ((TypeMemPtr)TYPES.get(_nestedType))._obj.close(); - TYPES.put(_nestedType,TypeMemPtr.make(shape)); - StructNode constants = new StructNode(shape); - int first = _scope._kinds.last()._lexSize; - for( int i=first; i<_scope.nIns(); i++ ) - if( !_scope.var(i).isFRef() ) constants.addDef(_scope.in(i)); - constants.setType(constants.compute()); - INITS.put(_nestedType,constants.keep()); - } - - private Node self() { return _scope.in(_scope.lookup("self")); } - private Node privateMem() { return _scope.in(_scope.lookup("#selfMem")); } - - private boolean privateSelf(Node ptr) { - if( _privateFun!=_fun || _privateFun==null ) return false; - while( ptr instanceof ConvertNode || ptr instanceof ReadOnlyNode || ptr instanceof GuardNode ) ptr=ptr.in(1); - Node self=self(); - while( self instanceof ConvertNode || self instanceof ReadOnlyNode || self instanceof GuardNode ) self=self.in(1); - return ptr==self; - } - private boolean mayBeSelf(Node ptr, java.util.BitSet seen) { - if( _privateFun==null || _privateFun!=_fun || seen.get(ptr._nid) ) return false; - seen.set(ptr._nid); - if( privateSelf(ptr) ) return true; - if( ptr instanceof ConvertNode || ptr instanceof ReadOnlyNode || ptr instanceof GuardNode ) - return mayBeSelf(ptr.in(1),seen); - if( ptr instanceof PhiNode && !(ptr instanceof ParmNode) ) - for( int i=1; i types = new Ary<>(Type.class); - Ary names = new Ary<>(String.class); - types.add(TYPES.get(_nestedType)); names.add("self"); - types.add(TypeMem.BOT); names.add("#selfMem"); - java.util.BitSet finals = new java.util.BitSet(); - finals.set(0); // Rebinding self would detach the pointer from its private memory. - while( true ) { - Type t=type(); - if( t==null ) break; - finals.set(names.size(),bindingFinal(t)); - types.add(t); names.add(requireId()); - match(","); - } - require("->"); - TypeFunPtr sig = _code.makeFun(TypeFunPtr.make(false,false,types.asAry(),TypeMem.BOT)); - // Bind the signature now, but parse the body after the field list is - // closed. Then even a later field has a local SSA slot before branches - // and loops are parsed. Strings/comments must not affect brace depth. - _constructor=new Constructor(sig,loc(),pos(),names.asAry(),finals); - int depth=1; - while( depth>0 ) { - if( peek('"') ) { parseString(); continue; } - if( match("'") ) { parseChar(); continue; } - char ch=_lexer.nextXChar(); - if( ch==Character.MAX_VALUE ) throw errorSyntax("}"); - if( ch=='{' ) depth++; - if( ch=='}' ) depth--; - } - return con(sig); - } - - private CallEndNode rawCall(Node ctrl, Node pub, ReturnNode target, Node... args) { - Node[] inputs = new Node[args.length+3]; - inputs[0]=ctrl; inputs[1]=pub; - System.arraycopy(args,0,inputs,2,args.length); - inputs[inputs.length-1]=new FunPtrNode(target.fun().sig(),target).peephole(); - // Keep the complete declaration-side caller set before any inlining. - CallNode call = new CallNode(loc(),inputs).init(); - CallEndNode end = new CallEndNode(call).init(); - call.link(target.fun()); - return end; - } - - private Node publish(TypeStruct shape, Node ctrl, Node pub, Node priv, Node ptr) { - priv.keep(); ptr.keep(); - for( Field f : shape._fields ) if( !f._one ) { - pub.keep(); - Node esc = new EscapeNode(loc(),f,ctrl,pub,priv,ptr).peephole(); - Node next = new MemMergeNode(pub,f._alias,esc).peephole(); - pub.unkeep(); pub=next; - } - ptr.unkeep(); priv.unkill(); - return pub; - } - - private TypeFunPtr makeAllocator(TypeStruct shape, ReturnNode init) { - Field cf=shape.field(shortName(shape._name)); - TypeFunPtr ctor=cf!=null && cf._t instanceof TypeFunPtr f ? f : null; - int nargs=ctor==null ? 0 : ctor.nargs()-2; - Ary captures=CAPTURES.get(shape._name); - Type[] types=new Type[nargs+captures.size()]; - for( int i=0; i"; fun._constructor=true; - _code.link(fun); - Node rpc=new ParmNode("$rpc",0,TypeRPC.BOT,fun,con(TypeRPC.BOT)).init(); - Node pub=new ParmNode(ScopeNode.MEM0,1,TypeMem.BOT,fun,new ProjNode(_code._start,1,ScopeNode.MEM0).peephole()).init(); - Node[] args=new Node[nargs+2]; - for( int i=0; i")) || id==null ) - return posT(old1); // Reset lexer to reparse - pos(old2); // Reset lexer to reparse - // Yes a forward ref, so declare it - TYPES.put(tname,((TypeMemPtr)t1).withAccess(false)); - // Return the (array, final) type - return t2; - } - - // Make an array type of t - private TypeMemPtr typeAry( Type t, boolean efinal ) { - if( t instanceof TypeMemPtr tmp && tmp.notNull() ) - throw error("Arrays of reference types must always be nullable"); - String tname = "[]"+t.str(); - TypeMemPtr ta = (TypeMemPtr)TYPES.get(tname); - if( ta==null ) - // Remember final version - TYPES.put(tname, ta = TypeMemPtr.make( TypeStruct.makeAry(tname,TypeInteger.U32,_code.getALIAS(),t,_code.getALIAS(),true) )); - // Reuse aliases, but preserve this occurrence's element permissions. - TypeStruct ary = ta._obj; - return TypeMemPtr.make(TypeStruct.makeAry(tname,TypeInteger.U32,ary._fields[0]._alias,t,ary._fields[1]._alias,efinal)); - } - - // A function type is `{ type... -> type }` or `{ type }`. - private Type typeFunPtr() { - int old = pos(); // Record lexer position - match("{"); // Skip already-peeked '{' - Type t0 = type(); // Either return or first arg - if( t0==null ) return posT(old); // Not a function - if( match("}") ) // No-arg function { -> type } - return TypeFunPtr.make(match("?"),false,TypeFunPtr.TEMPTY,t0); - Ary ts = new Ary<>(Type.class); - ts.push(t0); // First argument - while( true ) { - if( match("->") ) { // End of arguments, parse return - Type ret = type(); - if( ret==null || !match("}") ) - return posT(old); // Not a function - return TypeFunPtr.make(match("?"),false,ts.asAry(),ret); - } - Type t1 = type(); - if( t1==null ) return posT(old); // Not a function - ts.push(t1); - } - } - - // True if a TypeFunPtr, without advancing parser - private boolean isTypeFun() { - int old = pos(); - if( typeFunPtr()==null ) return false; - pos(old); - return true; - } - - /** - * Parse an expression of the form: - * - *

-     *     expr : bitwise [? expr [: expr]]
-     * 
- * @return an expression {@link Node}, never {@code null} - */ - private Node parseExpression() { - Node expr = parseLogical(); - return match("?") ? parseTrinary(expr,":") : expr; - } - - /** - * Parse an bitwise expression - * - *
-     *     bitwise : compareExpr (('&' | '|' | '^') compareExpr)*
-     * 
- * @return a bitwise expression {@link Node}, never {@code null} - */ - - private Node parseLogical() { - Node lhs = parseBitwise(); - while (true) { - if( false ) ; - else if( match("&&") ) lhs = parseTrinary(lhs, "&&"); - else if( match("||") ) lhs = parseTrinary(lhs, "||"); - else break; - } - return lhs; - } - - private Node parseBitwise() { - Node lhs = parseEquality(); - while( true ) { - if( false ) ; - else if( matchOp('&') ) lhs = new AndNode(loc(),lhs,null); - else if( matchOp('|') ) lhs = new OrNode(loc(),lhs,null); - else if( match ("^") ) lhs = new XorNode(loc(),lhs,null); - else break; - lhs.setDef(2,parseEquality()); - lhs = peep(lhs); - } - return lhs; - } - - - - /** - * Parse an eq/ne expression - */ - private Node parseEquality() { - Node lhs = parseComparison(); - while( true ) { - boolean eq = false; - if( match("==") ) eq = true; - else if( !match("!=") ) break; - lhs.keep(); - Node rhs = parseComparison(); - lhs = peep(new BoolNode.EQ(lhs.unkeep(),rhs)); - if( !eq ) lhs = peep(new NotNode(lhs)); - } - return lhs; - } - - /** - * Parse an expression of the form: - * - *
-     *     expr : shiftExpr < shiftExpr <= shiftExpr...
-     *     expr : shiftExpr > shiftExpr >= shiftExpr...
-     * 
- * @return an comparator expression {@link Node}, never {@code null} - */ - private Node parseComparison() { - Node lhs = parseShift(); - int dir = 0; - - while( true ) { - int dir0; - if( false ) ; - else if( match("<=" ) ) dir0 = -1; - else if( match(">=" ) ) dir0 = -2; - else if( match("<" ) ) dir0 = 1; - else if( match(">" ) ) dir0 = 2; - else break; - lhs.keep(); - // Check and record direction - if( dir==0 ) { - dir = Math.abs(dir0); - Node rhs = parseShift(); - lhs = makeCompBool(dir0,lhs.unkeep(),rhs); // Convert to a bool - } else if( dir == Math.abs(dir0) ) { - // e0 < lhs < ??? - Node ifNode = new IfNode(ctrl(), lhs).peephole(); - Node ifT = new CProjNode(ifNode. keep(), 0, "True" ).peephole(); - Node ifF = new CProjNode(ifNode.unkeep(), 1, "False").peephole(); - // False side does nothing - ScopeNode fScope = _scope.dup(); - fScope.ctrl(ifF); - // True side executes next part of range - ctrl(ifT); - _scope.addGuards(ifT,lhs,false); - Node rhs = parseShift(); - _scope.removeGuards(ifT); // TODO: I think should remain true as long as possible - Node next = makeCompBool(dir0, lhs, rhs).keep(); - // Merge result - RegionNode r = ctrl(_scope.mergeScopes(fScope, loc())); - assert next._type.meet(lhs._type).isa( TypeInteger.BOOL ); - lhs = peep(new PhiNode("",r,next.unkeep(),lhs.unkeep())); - r.peephole(); - } else { - throw error("Mixing relational directions in a chained relational test"); - } - } - return lhs; - } - - private Node makeCompBool( int dir0, Node lhs, Node rhs ) { - // Convert to a bool - if( Math.abs(dir0)==2 ) // Swap direction - { Node tmp = lhs; lhs = rhs; rhs = tmp; } - lhs = peep(dir0 < 0 ? new BoolNode.LE(lhs,rhs) : new BoolNode.LT(lhs,rhs)); - return peep(lhs); - } - - - /** - * Parse an additive expression - * - *
-     *     shiftExpr : additiveExpr (('<<' | '>>' | '>>>') additiveExpr)*
-     * 
- * @return a shift expression {@link Node}, never {@code null} - */ - private Node parseShift() { - Node lhs = parseAddition(); - while( true ) { - if( false ) ; - else if( match("<<") ) lhs = new ShlNode(loc(),lhs,null); - else if( match(">>>")) lhs = new ShrNode(loc(),lhs,null); - else if( match(">>") ) lhs = new SarNode(loc(),lhs,null); - else break; - lhs.setDef(2,parseAddition()); - ParseException err; - if( (err=lhs.err()) != null ) - throw err; - lhs = peep(lhs); - } - return lhs; - } - - /** - * Parse an additive expression - * - *
-     *     additiveExpr : multiplicativeExpr (('+' | '-') multiplicativeExpr)*
-     * 
- * @return an add expression {@link Node}, never {@code null} - */ - private Node parseAddition() { - Node lhs = parseMultiplication(); - while( true ) { - if( false ) ; - else if( match("+") ) lhs = new AddNode(lhs,null); - else if( match("-") ) lhs = new SubNode(lhs,null); - else break; - lhs.setDef(2,parseMultiplication()); - lhs = peep(lhs); - } - return lhs; - } - - /** - * Parse an multiplicativeExpr expression - * - *
-     *     multiplicativeExpr : unaryExpr (('*' | '/') unaryExpr)*
-     * 
- * @return a multiply expression {@link Node}, never {@code null} - */ - private Node parseMultiplication() { - var lhs = parseUnary(); - while( true ) { - if( false ) ; - else if( match("*") ) lhs = new MulNode(lhs,null); - else if( match("/") ) lhs = new DivNode(lhs,null); - else break; - lhs.setDef(2,parseUnary()); - lhs = peep(lhs); - } - return lhs; - } - - /** - * Parse a unary minus expression. - * - *
-     *     unaryExpr : ('-') unaryExpr | '!') unaryExpr | postfixExpr | primaryExpr | '--' Id | '++' Id
-     * 
- * @return a unary expression {@link Node}, never {@code null} - */ - private Node parseUnary() { - // Pre-dec/pre-inc - int old = pos(); - if( match("--") || match("++") ) { - int delta = _lexer.peek(-1)=='+' ? 1 : -1; // Pre vs post - String name = _lexer.matchId(); - if( name!=null ) { - Var n = _scope.lookup(name); - if( n != null && !(n.type() instanceof TypeMemPtr) ) { - if( n._final && !_scope.canInit(n) ) - throw error("Cannot reassign final '"+n._name+"'"); - checkSharedField(n); - Node expr = liftExpr(peep(new AddNode(_scope.in(n),con(delta))),n.type(),true); - _scope.update(n,expr); - return expr; - } - } - // Reset, try again - pos(old); - } - if (match("-")) return peep(new MinusNode(parseUnary())); - if (match("!")) return peep(new NotNode(parseUnary())); - // Else be a primary expression - return parsePrimary(); - } - - /** - * Parse a primary expression: - * - *
-     *     primaryExpr : integerLiteral | "string" | 'char' | true | false | null |
-     *                   new Type | '(' expression ')' | Id['++','--'] |
-     *                   [static.]* Id
-     * 
- * @return a primary {@link Node}, never {@code null} - */ - private Node parsePrimary() { - if( _lexer.isNumber(_lexer.peek()) ) return parseLiteral(); - if( _lexer.peek('"') ) return newString(parseString()); - if( matchx("true" ) ) return con(1); - if( matchx("false") ) return ZERO; - if( matchx("null" ) ) return NIL; - if( match ("'" ) ) return parseChar(); - if( match ("(" ) ) return parsePostfix(require(parseAsgn(), ")")); - if( matchx("new" ) ) return parsePostfix(alloc()); - if( match ("{" ) ) return parsePostfix(require(func(),"}")); - - // Parse static variable lookup: `type.fld` in the type namespace - // CNC: not a full type parse, just a typename parse - int pos = pos(); - Type t = type(); - if( t!=null ) { - if( peek('.') ) - // A namespace lookup is not a reference declaration. - return parsePostfix(con(TYPES.get(((TypeMemPtr)t)._obj._name))); - //pos(pos); // TODO: not a `type.fld` - //return null; - throw Utils.TODO(); - } - - // Expect an identifier now - - // - if null, make fref, normal var handling - // - if final constant, normal var handling - // - if method var, scan skipping blocks & methods, must hit correct struct no fcns - // - if normal var, scan skipping blocks, allowing last fcn - // - NO fcns nested in methods, NO methods nested in fcns - - String id = _lexer.matchId(); - if( id == null || KEYWORDS.contains(id) ) - throw errorSyntax("an identifier or expression"); - Var var = _scope.lookup(id); - - if( var==null ) { - // If missing, assume a forward reference - _scope.define(id, FRefNode.FREF_TYPE, true, XCTRL, loc()); - var = _scope.lookup(id); - } - - // If a method var, allow nested blocks and methods, but not fcns or other structs. - // Else safety check for accessing fields out of function scope. - if( instance(var) ) { - Var selfVar = _scope.lookup("self"); - Node self = liftExpr(_scope.in(selfVar),selfVar.type(),true); - return parsePostfixName(self,id); - } - - // Load local value - Node oldValue = _scope.in(var); - if( oldValue instanceof ConstantNode && !(oldValue instanceof FRefNode) && oldValue._type==Type.BOTTOM ) - throw error("Cannot read uninitialized field '"+id+"'"); - Node rvalue = liftExpr(oldValue,var.type(),true); - if( rvalue!=oldValue ) _scope.update(var,rvalue); - if( rvalue instanceof ConstantNode && rvalue._type == Type.BOTTOM ) - if( rvalue instanceof FRefNode ) - return parsePostfix(rvalue); - else throw error("Cannot read uninitialized field '"+id+"'"); - - // Check for assign-update, x += e0; - char ch = _lexer.matchOperAssign(); - if( ch==0 ) // Normal primary, check for postfix updates - return parsePostfix(rvalue); - // Assign-update direct into Scope - if( var._final && !_scope.canInit(var) ) - throw error("Cannot reassign final '"+var._name+"'"); - checkSharedField(var); - checkCaptureWrite(var); - Node op = opAssign(ch,rvalue, var.type() ); - _scope.update(var,op); - return postfix(ch) ? rvalue.unkeep() : op; - } - - // true if instance variable lookup (var is in any number of nested blocks, - // then an instance function then inside a struct declaration). - private boolean instance(Var var ) { - // If a method var, allow nested blocks and methods, but not fcns or other structs - Kind kind = _scope.kind(var); - if( kind instanceof Kind.Define ) { - if( var.isFRef() ) return false; // Promote an unresolved lexical name, not self.name. - if( _privateFun==_fun && _privateFun!=null ) return true; - for( int i = _scope.depth()-1; i>=0 && var._idx < _scope._kinds.at(i)._lexSize; i-- ) { - Kind xkind = _scope._kinds.at(i); - if( xkind instanceof Kind.Block ) continue; - if( xkind instanceof Kind.Func ) { - if( _scope._kinds.at(i-1)==kind ) - return true; // Instance variable: lookup in a method in a decl - } - throw Utils.TODO(); - } - } else { - // If a normal var, allow any nested blocks, and a last fcn - - // but not functions further out (which involves capture). - Node def = _scope.in(var._idx); - if( _captures!=null && _scope.kind(var) instanceof Kind.Func && - !(var._final && def._type.isConstant()) && !(def instanceof FRefNode) ) { - if( !(def instanceof ParmNode parm && parm.fun()==_fun) ) { - _captures.add(def.keep()); - Type type=def._type; - int index=_fun.sig().nargs(); - _fun.addParseArg(type); - _scope.update(var,new ParmNode(var._name,index+2,type,_fun,con(type)).init()); - } - return false; - } - for( int i = _scope.depth()-1; i>=0 && var._idx < _scope._kinds.at(i)._lexSize; i-- ) - if( _scope._kinds.at(i) instanceof Kind.Func && - !(def instanceof FRefNode) && !(var._final && def._type.isConstant()) ) - throw error("Variable '"+var._name+"' is out of function scope and must be a final constant"); - } - return false; - } - - private void checkCaptureWrite(Var var) { - if( _captures==null ) return; - for( int i=_scope.depth()-1; i>=0 && var._idx<_scope._kinds.at(i)._lexSize; i-- ) - if( _scope._kinds.at(i) instanceof Kind.Func ) - throw error("Cannot assign captured variable '"+var._name+"' in an initializer"); - } - - // Inline constructors have local field slots too, but shared function - // declarations have no instance slot to publish. Do not silently discard - // an assignment to one of those declarations. - private void checkSharedField(Var var) { - if( !_scope.canInit(var) ) return; - if( _scope.kind(var) instanceof Kind.Define ) { - checkPrivateWrite(var._name); - return; - } - for( int i=_scope.depth()-1; i>0; i-- ) - if( _scope._kinds.at(i) instanceof Kind.Alloc alloc ) { - Field field=alloc._tmp._obj.field(var._name); - if( field!=null && field._one ) - throw error("Cannot reassign shared function '"+var._name+"'"); - return; - } - } - - // Check for assign-update, "x += e0". - // Returns "x + e0"; the caller assigns value. - // if ch is postfix, then lhs is kept and caller will unkeep and return it. - private Node opAssign( char ch, Node lhs, Type t ) { - // RHS of the update. - lhs.keep(); // Alive across parseAsgn - Node rhs = - (byte)ch == 1 ? con( 1) : // var++ - (byte)ch == -1 ? con(-1) : // var-- - parseAsgn(); // var op= rhs - if( !postfix(ch) ) lhs.unkeep(); // Allow to die in next peep - // 4 cases: - // int + int ==>> narrow int - // int + flt ==>> error, caller must fail assigning flt into int - // flt + int ==>> use float op, wrap toFloat() - // flt + flt ==>> use float op - Node op = switch(ch) { - case 1, (char)-1, - '+' -> new AddNode(lhs,rhs); - case '-' -> new SubNode(lhs,rhs); - case '*' -> new MulNode(lhs,rhs); - case '/' -> new DivNode(lhs,rhs); - case '&' -> new AndNode(loc(),lhs,rhs); - case '|' -> new OrNode(loc(),lhs,rhs); - case '^' -> new XorNode(loc(),lhs,rhs); - case Lexer.SHL -> new ShlNode(loc(),lhs,rhs); - case Lexer.SAR -> new SarNode(loc(),lhs,rhs); - case Lexer.SHR -> new ShrNode(loc(),lhs,rhs); - default -> throw Utils.TODO(); - }; - // Convert to float ops, or narrow int types; error if not declared type. - // Also, if postfix LHS is still keep() - return liftExpr(peep(op),t,true); - } - - - /** - Parse an allocation - */ - private Node alloc() { - Type t = type(); - if( t==null ) throw error("Expected a type"); - // Parse ary[ length_expr ] - if( match("[") ) { - if( !t.makeZero().isa(t) ) - throw error("Cannot allocate a non-nullable, since arrays always zero/null fill"); - Node len = parseAsgn(); - if( !(len._type instanceof TypeInteger) ) - throw error("Cannot allocate an array with length "+len._type); - require("]"); - TypeMemPtr tmp = typeAry(t,false); - return newArray(tmp._obj,len); - } - - if( !(t instanceof TypeMemPtr tmp) ) - throw error("Cannot allocate a "+t.str()); - - TypeStruct shape=tmp._obj; - TypeFunPtr sig=ALLOCS.get(shape._name); - if( sig==null ) throw error("Unknown struct type '"+shape._name+"'"); - if( !peek('{') ) { - // Obvious missing defaults can still be diagnosed here. A user - // constructor or a merge needs the later publication check. - if( shape.field(shortName(shape._name))==null ) { - StructNode defaults=INITS.get(shape._name); - Type initial=INITIALIZERS.get(shape._name).expr()._type; - for( int i=0; i args=new Ary<>(Node.class); - if( match("(") ) { - while( !peek(')') ) { - Node arg=parseAsgn(); - checkPublication(arg); - args.add(arg.keep()); - if( !match(",") ) break; - } - require(")"); - } - for( Node capture : CAPTURES.get(shape._name) ) { - checkPublication(capture); - args.add(capture.keep()); - } - if( args.size()!=sig.nargs() ) throw error("Wrong number of constructor arguments for '"+shape._name+"'"); - for( Node arg : args ) arg.unkeep(); - return callWithArgs(fptr,args.asAry()); - } - require("{"); - Node alloc=new NewNode(TypeMemPtr.make(shape),ctrl(),null,off(shape," len")).init(); - Node ptr=new ProjNode(alloc,0,shape._name).init().keep(); - Node priv=new ProjNode(alloc,1,"#selfMem").init(); - Ary captures=CAPTURES.get(shape._name); - Node[] args=new Node[captures.size()+2]; - args[0]=ptr; args[1]=priv; - for( int i=0; i