From 06f26130833658d9e8b29e068c9177c8e03bc937 Mon Sep 17 00:00:00 2001 From: Zak Yani Star Fenton Date: Sun, 8 Jun 2025 23:58:21 +1000 Subject: [PATCH] Initial commit of main compiler sources (or should I say ... SAUCES!) --- slangc/.DS_Store | Bin 0 -> 8196 bytes slangc/api/BytecodeHeap.sauce | 1646 +++++++++++ slangc/api/BytecodeInstructionWriter.sauce | 1023 +++++++ slangc/api/BytecodeOutput.sauce | 29 + slangc/api/BytecodeTarget.sauce | 339 +++ slangc/api/CacheManager.sauce | 13 + slangc/api/CompilerPackage.sauce | 34 + slangc/api/CompilerSet.sauce | 43 + slangc/api/CompilerTarget.sauce | 34 + slangc/api/CompilerWorld.sauce | 766 ++++++ slangc/api/DataFile.sauce | 17 + slangc/api/MetaOrAlias.sauce | 12 + slangc/api/NullReporter.sauce | 34 + slangc/api/ProvidesOrDepends.sauce | 17 + slangc/api/Reporter.sauce | 10 + slangc/api/TypeOption.sauce | 93 + slangc/api/Unit.sauce | 245 ++ slangc/bytecode/BytecodeObject.sauce | 30 + slangc/bytecode/FieldSignature.sauce | 36 + slangc/bytecode/Instruction.sauce | 12 + slangc/bytecode/MajorOpcode.sauce | 10 + slangc/bytecode/MethodSignature.sauce | 60 + slangc/bytecode/MinorOpcode.sauce | 50 + slangc/bytecode/StackMachineAdapter.sauce | 171 ++ slangc/bytecode/StackMachineVisitor.sauce | 67 + slangc/bytecode/StackType.sauce | 16 + slangc/bytecode/SystemVisitor.sauce | 5 + slangc/bytecode/TypeSignature.sauce | 53 + slangc/bytecode/TypeVisitor.sauce | 6 + slangc/bytecode/Visitor.sauce | 5 + .../codegraph/AbstractClassDefinition.sauce | 5 + slangc/codegraph/AbstractConstructor.sauce | 5 + slangc/codegraph/AbstractContainer.sauce | 9 + slangc/codegraph/AbstractEnumDefinition.sauce | 5 + slangc/codegraph/AbstractField.sauce | 5 + .../AbstractInterfaceDefinition.sauce | 5 + slangc/codegraph/AbstractInvokable.sauce | 5 + slangc/codegraph/AbstractLink.sauce | 7 + slangc/codegraph/AbstractMember.sauce | 7 + slangc/codegraph/AbstractMethod.sauce | 5 + slangc/codegraph/AbstractNamedElement.sauce | 15 + slangc/codegraph/AbstractPackage.sauce | 5 + slangc/codegraph/AbstractSet.sauce | 11 + slangc/codegraph/AbstractTagDefinition.sauce | 5 + slangc/codegraph/AbstractTypeDefinition.sauce | 10 + slangc/codegraph/AbstractWorld.sauce | 5 + slangc/codegraph/ContainerType.sauce | 8 + slangc/codegraph/DynamicClassDefinition.sauce | 21 + slangc/codegraph/DynamicConstructor.sauce | 9 + slangc/codegraph/DynamicContainer.sauce | 31 + slangc/codegraph/DynamicEnumDefinition.sauce | 13 + slangc/codegraph/DynamicField.sauce | 9 + .../DynamicInterfaceDefinition.sauce | 13 + slangc/codegraph/DynamicInvokable.sauce | 19 + slangc/codegraph/DynamicLink.sauce | 10 + slangc/codegraph/DynamicMethod.sauce | 10 + slangc/codegraph/DynamicNamedElement.sauce | 87 + slangc/codegraph/DynamicPackage.sauce | 12 + slangc/codegraph/DynamicSet.sauce | 12 + slangc/codegraph/DynamicTagDefinition.sauce | 13 + slangc/codegraph/DynamicType.sauce | 35 + slangc/codegraph/DynamicWorld.sauce | 13 + slangc/codegraph/MemberType.sauce | 8 + slangc/codegraph/TypeType.sauce | 9 + slangc/model/AbstractMemberSet.sauce | 66 + slangc/model/AliasTypeModel.sauce | 65 + slangc/model/ArrayTypeModel.sauce | 90 + slangc/model/AttributeModel.sauce | 9 + slangc/model/AttributeOwner.sauce | 5 + slangc/model/AttributeSet.sauce | 272 ++ slangc/model/BuiltinTypeBehaviour.sauce | 66 + slangc/model/BuiltinTypeModel.sauce | 45 + slangc/model/ClauseModel.sauce | 89 + slangc/model/CombinedImportModel.sauce | 42 + slangc/model/ExpressionModel.sauce | 313 +++ slangc/model/ExpressionOwner.sauce | 5 + slangc/model/ExpressionResult.sauce | 226 ++ slangc/model/FieldModel.sauce | 204 ++ slangc/model/FieldSet.sauce | 15 + slangc/model/Flags.sauce | 26 + slangc/model/ImportModel.sauce | 32 + slangc/model/InnerTypeModel.sauce | 28 + slangc/model/InnerTypeScope.sauce | 351 +++ slangc/model/InnerTypeSet.sauce | 15 + slangc/model/LocalStorageModel.sauce | 73 + slangc/model/LocalVariableSlot.sauce | 83 + slangc/model/MemberCategory.sauce | 7 + slangc/model/MemberModel.sauce | 94 + slangc/model/MethodModel.sauce | 646 +++++ slangc/model/MethodSet.sauce | 15 + slangc/model/Named.sauce | 5 + slangc/model/NodeData.sauce | 45 + slangc/model/PackageImportModel.sauce | 34 + slangc/model/PackageModel.sauce | 289 ++ slangc/model/ParameterModel.sauce | 44 + slangc/model/ParameterSet.sauce | 78 + slangc/model/SourceModel.sauce | 124 + slangc/model/SpecialisedTypeModel.sauce | 49 + slangc/model/StatementModel.sauce | 99 + slangc/model/StatementOrExpression.sauce | 15 + slangc/model/StatementOwner.sauce | 16 + slangc/model/StorageSlot.sauce | 12 + slangc/model/SyntheticTypeModel.sauce | 19 + slangc/model/SystemModel.sauce | 378 +++ slangc/model/TemplateArgument.sauce | 21 + slangc/model/TemplateArgumentModel.sauce | 81 + slangc/model/TemplateArguments.sauce | 91 + slangc/model/TemplateModel.sauce | 62 + slangc/model/TypeImportModel.sauce | 74 + slangc/model/TypeLevel.sauce | 14 + slangc/model/TypeModel.sauce | 379 +++ slangc/model/TypeTemplateArgument.sauce | 50 + slangc/model/TypeType.sauce | 13 + slangc/model/UserTypeModel.sauce | 889 ++++++ slangc/model/clauses/Arguments.sauce | 81 + slangc/model/clauses/CatchClause.sauce | 75 + slangc/model/clauses/ElseClause.sauce | 51 + slangc/model/clauses/Expressions.sauce | 106 + .../clauses/ExpressionsOrVariables.sauce | 16 + slangc/model/clauses/FinallyClause.sauce | 52 + slangc/model/clauses/SwitchMembers.sauce | 95 + slangc/model/clauses/UnrecognisedClause.sauce | 25 + slangc/model/clauses/Variables.sauce | 94 + .../expressions/ArrayIndexExpression.sauce | 87 + .../ArrayInitialiserExpression.sauce | 94 + .../expressions/AssignmentExpression.sauce | 123 + .../AutomaticMethodCallExpression.sauce | 85 + .../model/expressions/BinaryExpression.sauce | 255 ++ slangc/model/expressions/CastExpression.sauce | 65 + .../expressions/ConditionalExpression.sauce | 103 + .../model/expressions/CountExpression.sauce | 93 + .../GenericReferenceExpression.sauce | 56 + .../expressions/InstanceofExpression.sauce | 64 + .../model/expressions/LiteralExpression.sauce | 198 ++ .../expressions/NewClassExpression.sauce | 106 + .../NewClearedArrayExpression.sauce | 69 + .../NewInitialisedArrayExpression.sauce | 61 + .../expressions/NewObjectExpression.sauce | 86 + .../NormalMethodCallExpression.sauce | 115 + .../expressions/OuterThisExpression.sauce | 84 + .../expressions/ReferenceExpression.sauce | 110 + .../expressions/SubreferenceExpression.sauce | 223 ++ .../SuperConstructorCallExpression.sauce | 94 + .../SuperMethodCallExpression.sauce | 88 + .../SuperReferenceExpression.sauce | 96 + .../ThisConstructorCallExpression.sauce | 93 + slangc/model/expressions/ThisExpression.sauce | 41 + .../ThisMethodCallExpression.sauce | 88 + slangc/model/expressions/TypeExpression.sauce | 68 + .../model/expressions/UnaryExpression.sauce | 122 + .../expressions/UnrecognisedExpression.sauce | 44 + slangc/model/statements/AssertStatement.sauce | 68 + slangc/model/statements/BlockStatement.sauce | 109 + slangc/model/statements/BreakStatement.sauce | 33 + .../model/statements/CaseLabelStatement.sauce | 77 + .../model/statements/ContinueStatement.sauce | 33 + .../statements/DefaultLabelStatement.sauce | 28 + .../model/statements/DoWhileStatement.sauce | 99 + slangc/model/statements/EmptyStatement.sauce | 29 + .../statements/ExpressionStatement.sauce | 79 + slangc/model/statements/ForStatement.sauce | 139 + slangc/model/statements/IfStatement.sauce | 104 + .../ReturnExpressionStatement.sauce | 78 + .../statements/ReturnNothingStatement.sauce | 29 + slangc/model/statements/SwitchStatement.sauce | 173 ++ .../statements/SynchronizedStatement.sauce | 86 + slangc/model/statements/ThrowStatement.sauce | 77 + slangc/model/statements/TryStatement.sauce | 121 + .../statements/TypeDeclarationStatement.sauce | 47 + .../statements/UnrecognisedStatement.sauce | 32 + .../model/statements/VariableStatement.sauce | 107 + slangc/model/statements/WhileStatement.sauce | 95 + slangc/parser/Annotation.sauce | 15 + slangc/parser/AnnotationType.sauce | 9 + slangc/parser/Branch.sauce | 122 + slangc/parser/CleopatraModeLanguage.sauce | 257 ++ slangc/parser/CommentAnnotation.sauce | 23 + slangc/parser/ErrorAnnotation.sauce | 23 + slangc/parser/ErrorType.sauce | 10 + slangc/parser/Language.sauce | 310 +++ slangc/parser/LegacyLanguage.sauce | 82 + slangc/parser/Location.sauce | 56 + slangc/parser/LocationAnnotation.sauce | 56 + slangc/parser/LocationType.sauce | 9 + slangc/parser/Node.sauce | 173 ++ slangc/parser/NodeType.sauce | 268 ++ slangc/parser/NoteAnnotation.sauce | 23 + slangc/parser/Parse.sauce | 2399 +++++++++++++++++ slangc/parser/Scan.sauce | 423 +++ slangc/parser/ScanWalker.sauce | 115 + slangc/parser/Source.sauce | 134 + slangc/parser/SourceEncoding.sauce | 136 + slangc/parser/SourcePosition.sauce | 46 + slangc/parser/SourceSnippet.sauce | 36 + slangc/parser/SourceWalker.sauce | 82 + slangc/parser/Token.sauce | 126 + slangc/parser/TokenType.sauce | 23 + slangc/parser/WarningAnnotation.sauce | 23 + slangc/parser/WarningType.sauce | 5 + slangc/sdk/ArgsLoader.sauce | 79 + slangc/sdk/CompilerMain.sauce | 482 ++++ slangc/sdk/SimpleBytecodeOutput.sauce | 54 + slangc/sdk/SimpleCacheManager.sauce | 34 + slangc/sdk/SimpleReporter.sauce | 16 + slangc/sdk/SimpleSource.sauce | 54 + slangc/sdk/UnicodeCharacter.sauce | 5 + slangc/sdk/UnicodeSource.sauce | 97 + slangc/streams/ArrayOutput.sauce | 39 + slangc/streams/File.sauce | 53 + slangc/streams/FileInput.sauce | 33 + slangc/streams/FileOutput.sauce | 17 + slangc/streams/LogWriter.sauce | 18 + slangc/streams/SimpleVFS.sauce | 95 + slangc/streams/VFS.sauce | 21 + 214 files changed, 22210 insertions(+) create mode 100644 slangc/.DS_Store create mode 100644 slangc/api/BytecodeHeap.sauce create mode 100644 slangc/api/BytecodeInstructionWriter.sauce create mode 100644 slangc/api/BytecodeOutput.sauce create mode 100644 slangc/api/BytecodeTarget.sauce create mode 100644 slangc/api/CacheManager.sauce create mode 100644 slangc/api/CompilerPackage.sauce create mode 100644 slangc/api/CompilerSet.sauce create mode 100644 slangc/api/CompilerTarget.sauce create mode 100644 slangc/api/CompilerWorld.sauce create mode 100644 slangc/api/DataFile.sauce create mode 100644 slangc/api/MetaOrAlias.sauce create mode 100644 slangc/api/NullReporter.sauce create mode 100644 slangc/api/ProvidesOrDepends.sauce create mode 100644 slangc/api/Reporter.sauce create mode 100644 slangc/api/TypeOption.sauce create mode 100644 slangc/api/Unit.sauce create mode 100644 slangc/bytecode/BytecodeObject.sauce create mode 100644 slangc/bytecode/FieldSignature.sauce create mode 100644 slangc/bytecode/Instruction.sauce create mode 100644 slangc/bytecode/MajorOpcode.sauce create mode 100644 slangc/bytecode/MethodSignature.sauce create mode 100644 slangc/bytecode/MinorOpcode.sauce create mode 100644 slangc/bytecode/StackMachineAdapter.sauce create mode 100644 slangc/bytecode/StackMachineVisitor.sauce create mode 100644 slangc/bytecode/StackType.sauce create mode 100644 slangc/bytecode/SystemVisitor.sauce create mode 100644 slangc/bytecode/TypeSignature.sauce create mode 100644 slangc/bytecode/TypeVisitor.sauce create mode 100644 slangc/bytecode/Visitor.sauce create mode 100644 slangc/codegraph/AbstractClassDefinition.sauce create mode 100644 slangc/codegraph/AbstractConstructor.sauce create mode 100644 slangc/codegraph/AbstractContainer.sauce create mode 100644 slangc/codegraph/AbstractEnumDefinition.sauce create mode 100644 slangc/codegraph/AbstractField.sauce create mode 100644 slangc/codegraph/AbstractInterfaceDefinition.sauce create mode 100644 slangc/codegraph/AbstractInvokable.sauce create mode 100644 slangc/codegraph/AbstractLink.sauce create mode 100644 slangc/codegraph/AbstractMember.sauce create mode 100644 slangc/codegraph/AbstractMethod.sauce create mode 100644 slangc/codegraph/AbstractNamedElement.sauce create mode 100644 slangc/codegraph/AbstractPackage.sauce create mode 100644 slangc/codegraph/AbstractSet.sauce create mode 100644 slangc/codegraph/AbstractTagDefinition.sauce create mode 100644 slangc/codegraph/AbstractTypeDefinition.sauce create mode 100644 slangc/codegraph/AbstractWorld.sauce create mode 100644 slangc/codegraph/ContainerType.sauce create mode 100644 slangc/codegraph/DynamicClassDefinition.sauce create mode 100644 slangc/codegraph/DynamicConstructor.sauce create mode 100644 slangc/codegraph/DynamicContainer.sauce create mode 100644 slangc/codegraph/DynamicEnumDefinition.sauce create mode 100644 slangc/codegraph/DynamicField.sauce create mode 100644 slangc/codegraph/DynamicInterfaceDefinition.sauce create mode 100644 slangc/codegraph/DynamicInvokable.sauce create mode 100644 slangc/codegraph/DynamicLink.sauce create mode 100644 slangc/codegraph/DynamicMethod.sauce create mode 100644 slangc/codegraph/DynamicNamedElement.sauce create mode 100644 slangc/codegraph/DynamicPackage.sauce create mode 100644 slangc/codegraph/DynamicSet.sauce create mode 100644 slangc/codegraph/DynamicTagDefinition.sauce create mode 100644 slangc/codegraph/DynamicType.sauce create mode 100644 slangc/codegraph/DynamicWorld.sauce create mode 100644 slangc/codegraph/MemberType.sauce create mode 100644 slangc/codegraph/TypeType.sauce create mode 100644 slangc/model/AbstractMemberSet.sauce create mode 100644 slangc/model/AliasTypeModel.sauce create mode 100644 slangc/model/ArrayTypeModel.sauce create mode 100644 slangc/model/AttributeModel.sauce create mode 100644 slangc/model/AttributeOwner.sauce create mode 100644 slangc/model/AttributeSet.sauce create mode 100644 slangc/model/BuiltinTypeBehaviour.sauce create mode 100644 slangc/model/BuiltinTypeModel.sauce create mode 100644 slangc/model/ClauseModel.sauce create mode 100644 slangc/model/CombinedImportModel.sauce create mode 100644 slangc/model/ExpressionModel.sauce create mode 100644 slangc/model/ExpressionOwner.sauce create mode 100644 slangc/model/ExpressionResult.sauce create mode 100644 slangc/model/FieldModel.sauce create mode 100644 slangc/model/FieldSet.sauce create mode 100644 slangc/model/Flags.sauce create mode 100644 slangc/model/ImportModel.sauce create mode 100644 slangc/model/InnerTypeModel.sauce create mode 100644 slangc/model/InnerTypeScope.sauce create mode 100644 slangc/model/InnerTypeSet.sauce create mode 100644 slangc/model/LocalStorageModel.sauce create mode 100644 slangc/model/LocalVariableSlot.sauce create mode 100644 slangc/model/MemberCategory.sauce create mode 100644 slangc/model/MemberModel.sauce create mode 100644 slangc/model/MethodModel.sauce create mode 100644 slangc/model/MethodSet.sauce create mode 100644 slangc/model/Named.sauce create mode 100644 slangc/model/NodeData.sauce create mode 100644 slangc/model/PackageImportModel.sauce create mode 100644 slangc/model/PackageModel.sauce create mode 100644 slangc/model/ParameterModel.sauce create mode 100644 slangc/model/ParameterSet.sauce create mode 100644 slangc/model/SourceModel.sauce create mode 100644 slangc/model/SpecialisedTypeModel.sauce create mode 100644 slangc/model/StatementModel.sauce create mode 100644 slangc/model/StatementOrExpression.sauce create mode 100644 slangc/model/StatementOwner.sauce create mode 100644 slangc/model/StorageSlot.sauce create mode 100644 slangc/model/SyntheticTypeModel.sauce create mode 100644 slangc/model/SystemModel.sauce create mode 100644 slangc/model/TemplateArgument.sauce create mode 100644 slangc/model/TemplateArgumentModel.sauce create mode 100644 slangc/model/TemplateArguments.sauce create mode 100644 slangc/model/TemplateModel.sauce create mode 100644 slangc/model/TypeImportModel.sauce create mode 100644 slangc/model/TypeLevel.sauce create mode 100644 slangc/model/TypeModel.sauce create mode 100644 slangc/model/TypeTemplateArgument.sauce create mode 100644 slangc/model/TypeType.sauce create mode 100644 slangc/model/UserTypeModel.sauce create mode 100644 slangc/model/clauses/Arguments.sauce create mode 100644 slangc/model/clauses/CatchClause.sauce create mode 100644 slangc/model/clauses/ElseClause.sauce create mode 100644 slangc/model/clauses/Expressions.sauce create mode 100644 slangc/model/clauses/ExpressionsOrVariables.sauce create mode 100644 slangc/model/clauses/FinallyClause.sauce create mode 100644 slangc/model/clauses/SwitchMembers.sauce create mode 100644 slangc/model/clauses/UnrecognisedClause.sauce create mode 100644 slangc/model/clauses/Variables.sauce create mode 100644 slangc/model/expressions/ArrayIndexExpression.sauce create mode 100644 slangc/model/expressions/ArrayInitialiserExpression.sauce create mode 100644 slangc/model/expressions/AssignmentExpression.sauce create mode 100644 slangc/model/expressions/AutomaticMethodCallExpression.sauce create mode 100644 slangc/model/expressions/BinaryExpression.sauce create mode 100644 slangc/model/expressions/CastExpression.sauce create mode 100644 slangc/model/expressions/ConditionalExpression.sauce create mode 100644 slangc/model/expressions/CountExpression.sauce create mode 100644 slangc/model/expressions/GenericReferenceExpression.sauce create mode 100644 slangc/model/expressions/InstanceofExpression.sauce create mode 100644 slangc/model/expressions/LiteralExpression.sauce create mode 100644 slangc/model/expressions/NewClassExpression.sauce create mode 100644 slangc/model/expressions/NewClearedArrayExpression.sauce create mode 100644 slangc/model/expressions/NewInitialisedArrayExpression.sauce create mode 100644 slangc/model/expressions/NewObjectExpression.sauce create mode 100644 slangc/model/expressions/NormalMethodCallExpression.sauce create mode 100644 slangc/model/expressions/OuterThisExpression.sauce create mode 100644 slangc/model/expressions/ReferenceExpression.sauce create mode 100644 slangc/model/expressions/SubreferenceExpression.sauce create mode 100644 slangc/model/expressions/SuperConstructorCallExpression.sauce create mode 100644 slangc/model/expressions/SuperMethodCallExpression.sauce create mode 100644 slangc/model/expressions/SuperReferenceExpression.sauce create mode 100644 slangc/model/expressions/ThisConstructorCallExpression.sauce create mode 100644 slangc/model/expressions/ThisExpression.sauce create mode 100644 slangc/model/expressions/ThisMethodCallExpression.sauce create mode 100644 slangc/model/expressions/TypeExpression.sauce create mode 100644 slangc/model/expressions/UnaryExpression.sauce create mode 100644 slangc/model/expressions/UnrecognisedExpression.sauce create mode 100644 slangc/model/statements/AssertStatement.sauce create mode 100644 slangc/model/statements/BlockStatement.sauce create mode 100644 slangc/model/statements/BreakStatement.sauce create mode 100644 slangc/model/statements/CaseLabelStatement.sauce create mode 100644 slangc/model/statements/ContinueStatement.sauce create mode 100644 slangc/model/statements/DefaultLabelStatement.sauce create mode 100644 slangc/model/statements/DoWhileStatement.sauce create mode 100644 slangc/model/statements/EmptyStatement.sauce create mode 100644 slangc/model/statements/ExpressionStatement.sauce create mode 100644 slangc/model/statements/ForStatement.sauce create mode 100644 slangc/model/statements/IfStatement.sauce create mode 100644 slangc/model/statements/ReturnExpressionStatement.sauce create mode 100644 slangc/model/statements/ReturnNothingStatement.sauce create mode 100644 slangc/model/statements/SwitchStatement.sauce create mode 100644 slangc/model/statements/SynchronizedStatement.sauce create mode 100644 slangc/model/statements/ThrowStatement.sauce create mode 100644 slangc/model/statements/TryStatement.sauce create mode 100644 slangc/model/statements/TypeDeclarationStatement.sauce create mode 100644 slangc/model/statements/UnrecognisedStatement.sauce create mode 100644 slangc/model/statements/VariableStatement.sauce create mode 100644 slangc/model/statements/WhileStatement.sauce create mode 100644 slangc/parser/Annotation.sauce create mode 100644 slangc/parser/AnnotationType.sauce create mode 100644 slangc/parser/Branch.sauce create mode 100644 slangc/parser/CleopatraModeLanguage.sauce create mode 100644 slangc/parser/CommentAnnotation.sauce create mode 100644 slangc/parser/ErrorAnnotation.sauce create mode 100644 slangc/parser/ErrorType.sauce create mode 100644 slangc/parser/Language.sauce create mode 100644 slangc/parser/LegacyLanguage.sauce create mode 100644 slangc/parser/Location.sauce create mode 100644 slangc/parser/LocationAnnotation.sauce create mode 100644 slangc/parser/LocationType.sauce create mode 100644 slangc/parser/Node.sauce create mode 100644 slangc/parser/NodeType.sauce create mode 100644 slangc/parser/NoteAnnotation.sauce create mode 100644 slangc/parser/Parse.sauce create mode 100644 slangc/parser/Scan.sauce create mode 100644 slangc/parser/ScanWalker.sauce create mode 100644 slangc/parser/Source.sauce create mode 100644 slangc/parser/SourceEncoding.sauce create mode 100644 slangc/parser/SourcePosition.sauce create mode 100644 slangc/parser/SourceSnippet.sauce create mode 100644 slangc/parser/SourceWalker.sauce create mode 100644 slangc/parser/Token.sauce create mode 100644 slangc/parser/TokenType.sauce create mode 100644 slangc/parser/WarningAnnotation.sauce create mode 100644 slangc/parser/WarningType.sauce create mode 100644 slangc/sdk/ArgsLoader.sauce create mode 100644 slangc/sdk/CompilerMain.sauce create mode 100644 slangc/sdk/SimpleBytecodeOutput.sauce create mode 100644 slangc/sdk/SimpleCacheManager.sauce create mode 100644 slangc/sdk/SimpleReporter.sauce create mode 100644 slangc/sdk/SimpleSource.sauce create mode 100644 slangc/sdk/UnicodeCharacter.sauce create mode 100644 slangc/sdk/UnicodeSource.sauce create mode 100644 slangc/streams/ArrayOutput.sauce create mode 100644 slangc/streams/File.sauce create mode 100644 slangc/streams/FileInput.sauce create mode 100644 slangc/streams/FileOutput.sauce create mode 100644 slangc/streams/LogWriter.sauce create mode 100644 slangc/streams/SimpleVFS.sauce create mode 100644 slangc/streams/VFS.sauce diff --git a/slangc/.DS_Store b/slangc/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9911a927c4aa4b1db35f3e392af79f1667de515f GIT binary patch literal 8196 zcmeI1L5tHs6vyAR-EGPu^q|;_5b#>GUCM%ZiFNnj)ruZeYO)EtVbe@$Qj3&@TwTA4 z;88z`-^G*u-^{F}X{&fyT%89q|77O9Wajrmrjrtp7|z2!QHO{e6xQ}0stv~dT-K~+ zT5doE;z=F{i41VoUh}mLmVhN-30MM_fF$1wOp-#1 zD*m5-=N~Mxsrf$eC7330miKyJMXlc0*=;&aXU};(I+cr2?&tGt=+9pA*)u7V;PTiH zp2yK*+`jo(rnw)d(M$!zVFZ^~FXA+mi=mvSVWwh7y2EKXt#P}vTn>8sUAKQQIPbd4 z2m8IQJHYXI%ei&;{==u^vt*LW3pG;`<|RW+r)(c^vc}=fzHv zpJo?@)iYXX{n=2A*fb<2;ltZABH$~;mR?d(LyU)VD>|R!eA>);7SSn0KJ(X AhyVZp literal 0 HcmV?d00001 diff --git a/slangc/api/BytecodeHeap.sauce b/slangc/api/BytecodeHeap.sauce new file mode 100644 index 0000000..fcc5e3d --- /dev/null +++ b/slangc/api/BytecodeHeap.sauce @@ -0,0 +1,1646 @@ +package slangc.api; + +import slang.data.Map; +import slangc.bytecode.FieldSignature; +import slangc.bytecode.MethodSignature; +import slangc.bytecode.TypeSignature; +import slangc.sdk.SimpleBytecodeOutput; + +public class BytecodeHeap { + private Record[] records = new Record[0]; + private int numberFree; + private final int maximumRecords; + private Map constStringMap = new Map(99999); + private Map constStringUnprocessedMap = new Map(); + private Map packageMap = new Map(99); + private Map typeSignatureMap = new Map(999); + private Map fieldSignatureMap = new Map(9999); + private Map methodSignatureMap = new Map(12345); + private Map constStringInt32Map = new Map(); + private Map constStringInt64Map = new Map(); + private Map constStringUint32Map = new Map(); + private Map constStringUint64Map = new Map(); + private Map constStringFloat32Map = new Map(); + private Map constStringFloat64Map = new Map(); + + public enum RecordType { + INVALID, + + STRING_UTF8, + ARRAY_INT8, + ARRAY_INT16, + ARRAY_INT32, + ARRAY_INT64, + ARRAY_FLOAT32, + ARRAY_FLOAT64, + + OBJECT_LIKE, + + CONST_INT32, + CONST_INT64, + CONST_FLOAT32, + CONST_FLOAT64 + } + + /** This is used to specify the "class" of an encoded OBJECT_LIKE typeName */ + public enum StandardClass { + NULL, + FALSE, + TRUE, + SIMPLEARRAY, + SIMPLETYPEREF, + ARRAYTYPEREF, // TODO... + SPECIALTYPEREF, // TODO... + STATICFIELDREF, + STATICMETHODREF, + INSTANCEFIELDREF, + INSTANCEMETHODREF, + INTERFACEMETHODREF, // TODO... + + /** Used to defer number-processing to a secondary stage. This may allow future versions of the + * compiler to work on platforms that don't have full number stack such as JavaScript, as well as + * being a reference encoding for future e.g. bigint/bigdecimal types) */ + STRING_INT32, + STRING_INT64, + STRING_FLOAT32, + STRING_FLOAT64, + + STRING_UTF8, // Processed UTF-8 string data + STRING_UNPROCESSED, // A string with arbitrary \escape sequences encoded as written in source + CONST_INT32, + CONST_INT64, + CONST_FLOAT32, + CONST_FLOAT64, + + ARRAY_INT8, + ARRAY_INT16, + ARRAY_INT32, + ARRAY_INT64, + ARRAY_FLOAT32, + ARRAY_FLOAT64, + ARRAY_BYTECODE, // TODO... + ARRAY_DEBUG16, // TODO... + ARRAY_LABELS, // TODO... + + PACKAGE, + TYPE, + STATIC_FIELD, + INSTANCE_FIELD, + STATIC_METHOD, + INSTANCE_METHOD, + INTERFACE_METHOD, + + FILE, + FILE_BYTES, + DEPENDS, + PROVIDES, + ENTRYPOINT, + RUNTIMEDATA, + METADATA, + + CONSTRUCTORMETHODREF, + STATICINITMETHODREF, + INSTANCE_CONSTRUCTOR, + STATIC_INIT, + + STRING_UINT32, + STRING_UINT64 + } + + public static abstract class Record { + public final BytecodeHeap heap; + public final int recordIndex; + + public Record(BytecodeHeap heap, int recordIndex) { + super(); + this.heap = heap; + this.recordIndex = recordIndex; + heap.assignRecord(this); + } + + public boolean usingCompressedFormat() { + return false; + } + + public BytecodeHeap getHeap() { + return heap; + } + + public int getRecordIndex() { + return recordIndex; + } + + public abstract RecordType getRecordType(); + public abstract StandardClass getStandardClass(); + + public void writeArrayPart(BytecodeOutput o) { + /* No array part by default. */ + } + + public int elementsLength() { + return 0; + } + + private int cachedSize = -1; + public void clearCachedSize() { + cachedSize = -1; + } + + public int getArraySizeInBytes() { + if (cachedSize >= 0) { + return cachedSize; + } + if (isEmbeddedData()) { + return 0; + } + /*if (elementsLength() == 0) { + return 0; + }*/ + BytecodeOutput o = new SimpleBytecodeOutput(); + writeArrayPart(o); + int result = o.getCount(); + o.endOfFile(); + cachedSize = result; + return result; + } + + public void writeObjectHead(BytecodeOutput output) { + output.write8((byte) getRecordType().value); + output.write8((byte) getStandardClass().value); + output.write8((byte) 0); + output.write8((byte) 0); + output.write32(0); + } + + public boolean isEmbeddedData() { + return false; + } + + protected void innerWriteEmbeddedData(BytecodeOutput output) { + throw new Error("innerWriteEmbeddedData should be overridden for types with embedded data"); + } + + public final void writeEmbeddedData(BytecodeOutput output) { + if (!isEmbeddedData()) { + throw new Error("This record doesn't have embedded data (a pointer should be written instead)"); + } + int countBefore = output.getCount(); + + innerWriteEmbeddedData(output); + + /* Automatically pad if necessary. */ + while (output.getCount() < countBefore + 8) { + output.write8((byte)0); + } + + if (output.getCount() != countBefore + 8) { + throw new Error("Embedded data was too large! Expected 8 bytes but got " + (output.getCount() - countBefore)); + } + } + + public int getTableEntrySize(int compressionLevel) { + switch (compressionLevel) { + case 0: + return 16; + case 1: + return 8; + case 2: + return 4; + case 3: + if (getArraySizeInBytes() < 256) { + return 2; + } else { + return 4; + } + default: + throw new Error("Invalid compression level: " + compressionLevel + " (expecting 0-3)"); + } + } + + public String innerDebugString() { + return "TODO"; + } + + public String debugString() { + return getRecordType().name() + "#" + recordIndex + "(" + innerDebugString() + ")"; + } + } + + public static class ConstString extends Record { + private final String value; + + public ConstString(BytecodeHeap heap, int recordIndex, String value) { + super(heap, recordIndex); + if (value == null) { + throw new Error("Bad string (got null)"); + } + this.value = value; + } + + public String getStringValue() { + return value; + } + + public String innerDebugString() { + return "\"" + getStringValue() + "\""; + } + + @Override + public RecordType getRecordType() { + return RecordType.STRING_UTF8; + } + + @Override + public StandardClass getStandardClass() { + return StandardClass.STRING_UTF8; + } + + @Override + public void writeArrayPart(BytecodeOutput output) { + try { + byte[] bytes = getStringValue().signedBytes(); + for (int i = 0; i < bytes.length; i++) { + output.write8(bytes[i]); + } + } catch (Error e) { + throw new Error("Unable to encode string as UTF-8", e); + } + } + } + + public static class ConstInt32 extends Record { + private final int value; + + public ConstInt32(BytecodeHeap heap, int recordIndex, int value) { + super(heap, recordIndex); + this.value = value; + } + + public int getValue() { + return value; + } + + @Override + public RecordType getRecordType() { + return RecordType.CONST_INT32; + } + + @Override + public StandardClass getStandardClass() { + return StandardClass.CONST_INT32; + } + } + + public static class ConstInt64 extends Record { + private final long value; + + public ConstInt64(BytecodeHeap heap, int recordIndex, long value) { + super(heap, recordIndex); + this.value = value; + } + + public long getValue() { + return value; + } + + @Override + public RecordType getRecordType() { + return RecordType.CONST_INT64; + } + + @Override + public StandardClass getStandardClass() { + return StandardClass.CONST_INT64; + } + } + + public static class ConstFloat32 extends Record { + private final float value; + + public ConstFloat32(BytecodeHeap heap, int recordIndex, float value) { + super(heap, recordIndex); + this.value = value; + } + + public float getValue() { + return value; + } + + @Override + public RecordType getRecordType() { + return RecordType.CONST_FLOAT32; + } + + @Override + public StandardClass getStandardClass() { + return StandardClass.CONST_FLOAT32; + } + } + + public static class ConstFloat64 extends Record { + private final double value; + + public ConstFloat64(BytecodeHeap heap, int recordIndex, double value) { + super(heap, recordIndex); + this.value = value; + } + + public double getValue() { + return value; + } + + @Override + public RecordType getRecordType() { + return RecordType.CONST_FLOAT64; + } + + @Override + public StandardClass getStandardClass() { + return StandardClass.CONST_FLOAT64; + } + } + + public static class ObjectLike extends Record { + private final StandardClass standardClass; + private Record[] elements; + + public ObjectLike(BytecodeHeap heap, int recordIndex, StandardClass standardClass, int size) { + super(heap, recordIndex); + this.standardClass = standardClass; + elements = new Record[size]; + for (int i = 0; i < size; i++) { + elements[i] = heap.getNull(); + } + } + + public String innerDebugString() { + String result = ""; + for (int i = 0; i < elements.length; i++) { + if (i > 0) { + result = result + ","; + } + result = result+elements[i].debugString(); + } + return result; + } + + @Override + public boolean usingCompressedFormat() { + for (int i = 0; i < elements.length; i++) { + if (elements[i].getRecordIndex() >= 65536) { + return false; + } + } + return true; + } + + public void resizeElements(int newSize) { + Record[] newElements = new Record[newSize]; + for (int i = 0; i < newElements.length; i++) { + if (i < elements.length) { + newElements[i] = elements[i]; + } else { + newElements[i] = getHeap().getNull(); + } + } + elements = newElements; + } + + public void appendElement(Record r) { + int idx = elementsLength(); + resizeElements(idx + 1); + setElement(idx, r); + } + + public StandardClass getStandardClass() { + return standardClass; + } + + @Override + public int elementsLength() { + return elements.length; + } + + public Record getElement(int i) { + return elements[i]; + } + + public void setElement(int i, Record r) { + clearCachedSize(); + elements[i] = r; + } + + @Override + public RecordType getRecordType() { + return RecordType.OBJECT_LIKE; + } + + @Override + public void writeArrayPart(BytecodeOutput output) { + if (usingCompressedFormat()) { + for (int i = 0; i < elements.length; i++) { + output.write16((short) elements[i].getRecordIndex()); + } + } else { + for (int i = 0; i < elements.length; i++) { + output.write32(elements[i].getRecordIndex()); + } + } + } + } + + public static class ArrayInt8 extends Record { + private final StandardClass standardClass; + private byte[] elements; + + public ArrayInt8(BytecodeHeap heap, int recordIndex, StandardClass standardClass, int size) { + super(heap, recordIndex); + this.standardClass = standardClass; + elements = new byte[size]; + } + + @Override + public int elementsLength() { + return elements.length; + } + + public byte getElement(int i) { + return elements[i]; + } + + public void setElement(int i, byte r) { + clearCachedSize(); + elements[i] = r; + } + + public void resizeElements(int newSize) { + byte[] newElements = new byte[newSize]; + for (int i = 0; i < newElements.length; i++) { + if (i < elements.length) { + newElements[i] = elements[i]; + } else { + //newElements[i] = 0; + } + } + elements = newElements; + } + + public void appendElement(byte r) { + int idx = elementsLength(); + resizeElements(idx + 1); + setElement(idx, r); + } + + @Override + public RecordType getRecordType() { + return RecordType.ARRAY_INT8; + } + + @Override + public StandardClass getStandardClass() { + return standardClass; + } + + @Override + public void writeArrayPart(BytecodeOutput output) { + boolean cmp = usingCompressedFormat(); + for (int i = 0; i < elements.length; i++) { + output.write8(elements[i]); + } + } + + @Override + public boolean usingCompressedFormat() { + return false; + } + } + + public static class ArrayInt16 extends Record { + private final StandardClass standardClass; + private short[] elements; + + public ArrayInt16(BytecodeHeap heap, int recordIndex, StandardClass standardClass, int size) { + super(heap, recordIndex); + this.standardClass = standardClass; + elements = new short[size]; + } + + @Override + public int elementsLength() { + return elements.length; + } + + public short getElement(int i) { + return elements[i]; + } + + public void setElement(int i, short r) { + clearCachedSize(); + elements[i] = r; + } + + public void resizeElements(int newSize) { + short[] newElements = new short[newSize]; + for (int i = 0; i < newElements.length; i++) { + if (i < elements.length) { + newElements[i] = elements[i]; + } else { + //newElements[i] = 0; + } + } + elements = newElements; + } + + public void appendElement(short r) { + int idx = elementsLength(); + resizeElements(idx + 1); + setElement(idx, r); + } + + @Override + public RecordType getRecordType() { + return RecordType.ARRAY_INT16; + } + + @Override + public StandardClass getStandardClass() { + return standardClass; + } + + @Override + public void writeArrayPart(BytecodeOutput output) { + boolean cmp = usingCompressedFormat(); + for (int i = 0; i < elements.length; i++) { + if (cmp) { + output.write8((byte)elements[i]); + } else { + output.write16(elements[i]); + } + } + } + + @Override + public boolean usingCompressedFormat() { + for (int i = 0; i < elements.length; i++) { + byte tmp = (byte) elements[i]; + if ((((short) tmp) & 0xFF) != elements[i]) { + return false; + } + } + return true; + } + } + + public static class ArrayInt32 extends Record { + private final StandardClass standardClass; + private int[] elements; + + public ArrayInt32(BytecodeHeap heap, int recordIndex, StandardClass standardClass, int size) { + super(heap, recordIndex); + this.standardClass = standardClass; + elements = new int[size]; + } + + @Override + public int elementsLength() { + return elements.length; + } + + public int getElement(int i) { + return elements[i]; + } + + public void setElement(int i, int r) { + //if ((r & 0xFFFF) != r) throw new Error("XXX temporary error: Can't compress " + r); + clearCachedSize(); + elements[i] = r; + } + + public void resizeElements(int newSize) { + int[] newElements = new int[newSize]; + for (int i = 0; i < newElements.length; i++) { + if (i < elements.length) { + newElements[i] = elements[i]; + } else { + //newElements[i] = 0; + } + } + elements = newElements; + } + + public void appendElement(int r) { + int idx = elementsLength(); + resizeElements(idx + 1); + setElement(idx, r); + } + + @Override + public RecordType getRecordType() { + return RecordType.ARRAY_INT32; + } + + @Override + public StandardClass getStandardClass() { + return standardClass; + } + + @Override + public void writeArrayPart(BytecodeOutput output) { + boolean cmp = usingCompressedFormat(); + for (int i = 0; i < elements.length; i++) { + if (cmp) { + output.write16((short)elements[i]); + } else { + output.write32(elements[i]); + } + } + } + + @Override + public boolean usingCompressedFormat() { + for (int i = 0; i < elements.length; i++) { + int tmp = elements[i]; + if ((tmp & 0xFFFF) != elements[i]) { + return false; + } + } + return true; + } + } + + public BytecodeHeap(int maximumRecords, boolean initialise) { + this.maximumRecords = maximumRecords; + + if (initialise) { + initialiseHeap(); + } + } + + public void initialiseHeap() { + int nullId = nextFreeRecordIndex(); + if (nullId != 0) { + throw new Error("Can't initialise heap, null id already seems to exist!"); + } + if (newObjectLike(StandardClass.NULL, 0).getRecordIndex() != 0) { + throw new Error("Failed to create initial records"); + } + if (newObjectLike(StandardClass.FALSE, 0).getRecordIndex() != 1) { + throw new Error("Failed to create initial records"); + } + if (newObjectLike(StandardClass.TRUE, 0).getRecordIndex() != 2) { + throw new Error("Failed to create initial records"); + } + if (newObjectLike(StandardClass.SIMPLEARRAY, 0).getRecordIndex() != 3) { // Package array + throw new Error("Failed to create initial records"); + } + if (newObjectLike(StandardClass.SIMPLEARRAY, 0).getRecordIndex() != 4) { // Provides/depends array + throw new Error("Failed to create initial records"); + } + if (newObjectLike(StandardClass.SIMPLEARRAY, 0).getRecordIndex() != 5) { // Entrypoints array + throw new Error("Failed to create initial records"); + } + if (newObjectLike(StandardClass.SIMPLEARRAY, 32).getRecordIndex() != 6) { // Runtimedata array + throw new Error("Failed to create initial records"); + } + if (newObjectLike(StandardClass.SIMPLEARRAY, 0).getRecordIndex() != 7) { // Important metadata array + throw new Error("Failed to create initial records"); + } + if (newObjectLike(StandardClass.SIMPLEARRAY, 0).getRecordIndex() != 8) { // Other metadata array + throw new Error("Failed to create initial records"); + } + } + + public ObjectLike getNull() { + ObjectLike result = (ObjectLike)records[0]; + if (result == null) { + throw new Error("Invalid null record"); + } + return result; + } + + public ObjectLike getFalse() { + ObjectLike result = (ObjectLike)records[1]; + if (result == null) { + throw new Error("Invalid false record"); + } + return result; + } + + public ObjectLike getTrue() { + ObjectLike result = (ObjectLike)records[2]; + if (result == null) { + throw new Error("Invalid true record"); + } + return result; + } + + public ObjectLike getPackageArray() { + ObjectLike result = (ObjectLike)records[3]; + if (result == null) { + throw new Error("Invalid package-array record"); + } + return result; + } + + public ObjectLike getDependsArray() { + ObjectLike result = (ObjectLike)records[4]; + if (result == null) { + throw new Error("Invalid depends-array record"); + } + return result; + } + + public ObjectLike getEntrypointsArray() { + ObjectLike result = (ObjectLike)records[5]; + if (result == null) { + throw new Error("Invalid entrypoints-array record"); + } + return result; + } + + public ObjectLike getRuntimedataArray() { + ObjectLike result = (ObjectLike)records[6]; + if (result == null) { + throw new Error("Invalid runtimeinfo-array record"); + } + return result; + } + + public ObjectLike getImportantMetadataArray() { + ObjectLike result = (ObjectLike)records[7]; + if (result == null) { + throw new Error("Invalid importantmetadata-array record"); + } + return result; + } + + public ObjectLike getOtherMetadataArray() { + ObjectLike result = (ObjectLike)records[8]; + if (result == null) { + throw new Error("Invalid othermetadata-array record"); + } + return result; + } + + public int getCurrentHeapSize() { + return records.length; + } + + public int getHeapAllocationGranularity() { + return 1024; + } + + public void expandHeap(int atLeast) { + int newLimit = getCurrentHeapSize() + atLeast; + while (newLimit < getMaximumRecords() && (newLimit % getHeapAllocationGranularity()) != 0) { + newLimit++; + } + if (newLimit > getMaximumRecords()) { + throw new Error("Unable to expand heap (hit the maximum of " + getMaximumRecords() + " records)"); + } + numberFree += (newLimit - getCurrentHeapSize()); + Record[] newRecords = new Record[newLimit]; + for (int i = 0; i < getCurrentHeapSize(); i++) { + newRecords[i] = records[i]; + } + records = newRecords; + } + + public int objectTableSize(int compressionLevel) { + return objectTableSize(compressionLevel, getCurrentHeapSize()); + } + + public int objectTableSize(int compressionLevel, int upto) { + switch (compressionLevel) { + case 0: + return (highestUsedRecordIndex() + 1) * 16; + case 1: + return (highestUsedRecordIndex() + 1) * 8; + case 2: + return (highestUsedRecordIndex() + 1) * 4; + default: { + int sz = 0; + for (int i = 0; i < upto; i++) { + if (records[i] != null) { + sz += records[i].getTableEntrySize(compressionLevel); + } + } + return sz; + } + } + } + + public void writeObjectTable(BytecodeOutput output, int compressionLevel, int dataGranularity) { + int dataOffset = 0; + for (int i = 0; i <= highestUsedRecordIndex(); i++) { + Record r = records[i]; + if (r == null) { + switch (compressionLevel) { + case 0: + output.write64(0); + output.write64(0); + break; + case 1: + output.write64(0); + break; + case 2: + output.write32(0); + break; + case 3: + output.write16((short) 0); + break; + default: + throw new Error("Bad compression level " + compressionLevel); + } + } else { + int cl = r.getStandardClass().value; + if (r.usingCompressedFormat()) { + cl |= (1<<7); + } + int len = r.getArraySizeInBytes(); + switch (compressionLevel) { + case 0: + output.write32(cl); + output.write32(len); + output.write64(dataOffset); + break; + case 1: + output.write32((len << 8) | (cl & 0xFF)); + output.write32(dataOffset); + break; + case 2: + output.write32((len << 8) | (cl & 0xFF)); + break; + case 3: + if (r.getTableEntrySize(compressionLevel) == 2) { + output.write16((short) ((len << 8) | ((cl | (1<<6)) & 0xFF))); + } else { + output.write32((len << 8) | (cl & 0xFF)); + } + break; + default: + throw new Error("Bad compression level " + compressionLevel); + } + + dataOffset += records[i].getArraySizeInBytes(); + while ((dataOffset % dataGranularity) != 0) { + dataOffset++; + } + } + } + } + + public int objectTableIndexSize(int compressionLevel, int maxpool) { + switch (compressionLevel) { + case 3: { + int sz = 0; + int top = this.highestUsedRecordIndex(); + for (int i = 0; i <= top; i++) { + if (i % maxpool == 0) { + sz += 16; + } + } + return sz; + } + default: + return 0; // An index is not required unless the object table is compressed + } + } + + public int writeObjectTableIndex(BytecodeOutput output, int compressionLevel, int maxpool, int dataGranularity) { + switch (compressionLevel) { + case 3: { + int sz = 0; + int tableoffset = 0; + int top = this.highestUsedRecordIndex(); + boolean writtenDots = false; + for (int i = 0; i <= top; i++) { + Record r = records[i]; + if (i % maxpool == 0) { + output.write64(tableoffset); + output.write64(dataOffset(i, dataGranularity)); + if (i > maxpool*4 && i < top-maxpool*4) { + if (!writtenDots) { + Log.line("..."); + writtenDots = true; + } + } else { + Log.line("Writing index #" + (i/maxpool) + ": table offset " + tableoffset + " data offset " + dataOffset(i, dataGranularity)); + } + sz += 16; + } + tableoffset += r.getTableEntrySize(compressionLevel); + } + return sz; + } + default: + return 0; // An index is not required unless the object table is compressed + } + } + + public void writeData(BytecodeOutput output, int granularity) { + int offset = 0; + for (int i = 0; i <= highestUsedRecordIndex(); i++) { + Record r = records[i]; + if (r != null) { + r.writeArrayPart(output); + offset += r.getArraySizeInBytes(); + while ((offset % granularity) != 0) { + output.write8((byte)0); + offset++; + } + } + } + } + + public int fileHeaderSize(int compressionLevel, int maxpool, int dataGranularity, int sectionGranularity) { + return 64 * 4; + } + + private void writeStringTag(BytecodeOutput output, String data, int size) { + try { + byte[] x = data.signedBytes(); + if (x.length > size) { + throw new Error("String is too long (expected maximum of " + size + " bytes but got " + x.length + " bytes)"); + } + for (int i = 0; i < size; i++) { + output.write8((byte) (i < x.length ? x[i] : 0)); + } + } catch (Error e) { + throw new Error("Unable to encode string (system error?)", e); + } + } + + private void writeFileHeader(BytecodeOutput output, String tagdata, int compressionLevel, int maxpool, + int dataGranularity, int sectionGranularity) { + // Section 0 (file top header) + writeStringTag(output, tagdata, 32); // Optional user-defined tag, may reference interpreter on Unix-like systems + writeStringTag(output, "BYTECODE FILE01", 16); // Magic number + output.write8((byte)1); // File format version + output.write8((byte)4); // Number of file headers (including this top-header part) + output.write16((short)64); + output.write32(0); // Reserved for checksum + output.write64(fileSize(compressionLevel, maxpool, dataGranularity, sectionGranularity)); + + int sectionDataOffset = fileHeaderSize(compressionLevel, maxpool, dataGranularity, sectionGranularity); + while ((sectionDataOffset % sectionGranularity) != 0) { + sectionDataOffset++; + } + + // Section 1 (index, if provided) + if (objectTableIndexSize(compressionLevel, maxpool) == 0) { + for (int i = 0; i < 64; i++) { + output.write8((byte)0); + } + } else { + output.write32(maxpool); + output.write32(compressionLevel); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + + writeStringTag(output, "INDEX", 8); + output.write64(0); + output.write64(sectionDataOffset); + output.write64(objectTableIndexSize(compressionLevel, maxpool)); + sectionDataOffset += objectTableIndexSize(compressionLevel, maxpool); + while ((sectionDataOffset % sectionGranularity) != 0) { + sectionDataOffset++; + } + } + + // Section 2 (object table) + output.write32(highestUsedRecordIndex() + 1); + output.write32(compressionLevel); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + + writeStringTag(output, "TABLE", 8); + output.write64(0); + output.write64(sectionDataOffset); + output.write64(objectTableSize(compressionLevel)); + sectionDataOffset += objectTableSize(compressionLevel); + while ((sectionDataOffset % sectionGranularity) != 0) { + sectionDataOffset++; + } + + // Section 3 (object data) + + output.write32(dataGranularity);//sectionDataOffset += objectTableIndexSize(compressionLevel, maxpool); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + output.write32(0); + + writeStringTag(output, "DATA", 8); + output.write64(0); + output.write64(sectionDataOffset); + output.write64(dataSize(dataGranularity)); + sectionDataOffset += dataSize(dataGranularity); + while ((sectionDataOffset % sectionGranularity) != 0) { + sectionDataOffset++; + } + } + + public int fileSize(int compressionLevel, int maxpool, int dataGranularity, int sectionGranularity) { + int sz = fileHeaderSize(compressionLevel, maxpool, dataGranularity, sectionGranularity); + + while (sz % sectionGranularity != 0) { + sz++; + } + + sz += objectTableIndexSize(compressionLevel, maxpool); + + while (sz % sectionGranularity != 0) { + sz++; + } + + sz += objectTableSize(compressionLevel); + + while (sz % sectionGranularity != 0) { + sz++; + } + + sz += dataSize(dataGranularity); + + while (sz % sectionGranularity != 0) { + sz++; + } + + return sz; + } + + public void writeAll(BytecodeOutput output, String tagdata, int compressionLevel, int maxpool, int dataGranularity, int sectionGranularity) { + Log.line("aA"); + int base = output.getCount(); + int expectedOffset = 0; + + Log.line("A"); + writeFileHeader(output, tagdata, compressionLevel, maxpool, dataGranularity, sectionGranularity); + Log.line("B"); + expectedOffset = fileHeaderSize(compressionLevel, maxpool, dataGranularity, sectionGranularity); + Log.line("C"); + while (expectedOffset % sectionGranularity != 0) { + output.write8((byte)0); + expectedOffset++; + } + Log.line("D"); + + writeObjectTableIndex(output, compressionLevel, maxpool, dataGranularity); + expectedOffset += objectTableIndexSize(compressionLevel, maxpool); + while (expectedOffset % sectionGranularity != 0) { + output.write8((byte)0); + expectedOffset++; + } + Log.line("E"); + + writeObjectTable(output, compressionLevel, dataGranularity); + expectedOffset += objectTableSize(compressionLevel); + while (expectedOffset % sectionGranularity != 0) { + output.write8((byte)0); + expectedOffset++; + } + Log.line("F"); + + writeData(output, dataGranularity); + expectedOffset += dataSize(dataGranularity); + while (expectedOffset % sectionGranularity != 0) { + output.write8((byte)0); + expectedOffset++; + } + Log.line("G"); + } + + public int dataOffset(int index, int granularity) { + int total = 0; + for (int i = 0; i < index; i++) { + if (records[i] != null) { + total += records[i].getArraySizeInBytes(); + while ((total % granularity) != 0) { + total++; + } + } + } + return total; + } + + public int dataSize(int granularity) { + return dataOffset(getCurrentHeapSize(), granularity); + } + + public int highestUsedRecordIndex() { + return highestUsedIndex; + ///* + int highestUsed = -1; + for (int i = 0; i < getCurrentHeapSize(); i++) { + if (records[i] != null) { + highestUsed = i; + } + } + return highestUsed; + //*/ + } + + private int nextFreeHint = 0; + + public int nextFreeRecordIndex() { + if (numberFree < 1) { + expandHeap(1); + } + if (numberFree < 1) { + throw new Error("Heap expansion failed unexpectedly"); + } + + for (int i = nextFreeHint; i < getCurrentHeapSize(); i++) { + if (records[i] == null) { + nextFreeHint = i; + return i; + } + } + + throw new Error("Internal free count doesn't match - no free records found"); + } + + private int highestUsedIndex = -1; + + /* This is called internally from the Record constructor, so the creator only needs to find a free index. */ + private void assignRecord(Record r) { + assert r.heap == this; + assert records[r.recordIndex] == null; + records[r.recordIndex] = r; + if (r.recordIndex > highestUsedIndex) { + highestUsedIndex = r.recordIndex; + } + numberFree--; + } + + public ObjectLike newObjectLike(StandardClass cl, int size) { + int idx = nextFreeRecordIndex(); + return new ObjectLike(this, idx, cl, size); + } + + public ArrayInt8 newArrayInt8(StandardClass standardClass, int size) { + int idx = nextFreeRecordIndex(); + return new ArrayInt8(this, idx, standardClass, size); + } + + public ArrayInt16 newArrayInt16(StandardClass standardClass, int size) { + int idx = nextFreeRecordIndex(); + return new ArrayInt16(this, idx, standardClass, size); + } + + public ArrayInt32 newArrayInt32(StandardClass standardClass, int size) { + int idx = nextFreeRecordIndex(); + return new ArrayInt32(this, idx, standardClass, size); + } + + public ArrayInt32 newInstructions(int size) { + return newArrayInt32(StandardClass.ARRAY_BYTECODE, size); + } + + public ArrayInt32 newLabels(int size) { + return newArrayInt32(StandardClass.ARRAY_LABELS, size); + } + + public ArrayInt16 newDebug(int size) { + return newArrayInt16(StandardClass.ARRAY_DEBUG16, size); + } + + public ConstString getConstString(String value) { + if (constStringMap.hasKey(value)) { + return constStringMap.get(value); + } + int idx = nextFreeRecordIndex(); + ConstString str = new ConstString(this, idx, value); + constStringMap.set(value, str); + return str; + } + + /** Used for encoding quoted strings which may contain escape codes. If the + * string doesn't contain any fancy formatting, then it's encoded directly as + * a regular string constant (in UTF-8 format). Otherwise it's encoded as + * STRING_UNPROCESSED object containing a reference to the string exactly + * as written in the source code (including quotes, since future versions + * may allow string modifiers to specify a certain encoding or even regex + * syntax etc.). + */ + public Record getConstStringLiteral(String value) { + if (value.startsWith("\"") && value.endsWith("\"") && !value.search("\\")) { + return getConstString(value.sub(1, value.ints().length - 1)); + } + if (constStringUnprocessedMap.hasKey(value)) { + return constStringUnprocessedMap.get(value); + } + ConstString strval = getConstString(value); + ObjectLike result = newObjectLike(StandardClass.STRING_UNPROCESSED, 1); + result.setElement(0, strval); + + constStringUnprocessedMap.set(value, result); + + return result; + } + + public Record getConstInt32(String value) { + if (constStringInt32Map.hasKey(value)) { + return constStringInt32Map.get(value); + } + ConstString strval = getConstString(value); + ObjectLike result = newObjectLike(StandardClass.STRING_INT32, 1); + result.setElement(0, strval); + + constStringInt32Map.set(value, result); + + return result; + } + + public Record getConstInt64(String value) { + if (constStringInt64Map.hasKey(value)) { + return constStringInt64Map.get(value); + } + ConstString strval = getConstString(value); + ObjectLike result = newObjectLike(StandardClass.STRING_INT64, 1); + result.setElement(0, strval); + + constStringInt64Map.set(value, result); + + return result; + } + + public Record getConstUint32(String value) { + if (constStringUint32Map.hasKey(value)) { + return constStringUint32Map.get(value); + } + ConstString strval = getConstString(value); + ObjectLike result = newObjectLike(StandardClass.STRING_UINT32, 1); + result.setElement(0, strval); + + constStringUint32Map.set(value, result); + + return result; + } + + public Record getConstUint64(String value) { + if (constStringUint64Map.hasKey(value)) { + return constStringUint64Map.get(value); + } + ConstString strval = getConstString(value); + ObjectLike result = newObjectLike(StandardClass.STRING_UINT64, 1); + result.setElement(0, strval); + + constStringUint64Map.set(value, result); + + return result; + } + + public Record getConstFloat32(String value) { + if (constStringFloat32Map.hasKey(value)) { + return constStringFloat32Map.get(value); + } + ConstString strval = getConstString(value); + ObjectLike result = newObjectLike(StandardClass.STRING_FLOAT32, 1); + result.setElement(0, strval); + + constStringFloat32Map.set(value, result); + + return result; + } + + public Record getConstFloat64(String value) { + if (constStringFloat64Map.hasKey(value)) { + return constStringFloat64Map.get(value); + } + ConstString strval = getConstString(value); + ObjectLike result = newObjectLike(StandardClass.STRING_FLOAT64, 1); + result.setElement(0, strval); + + constStringFloat64Map.set(value, result); + + return result; + } + + public ObjectLike getPackage(String value) { + if (packageMap.hasKey(value)) { + return packageMap.get(value); + } + ConstString strval = getConstString(value); + ObjectLike result = newObjectLike(StandardClass.PACKAGE, 3); + result.setElement(0, strval); + result.setElement(1, getNull()); + result.setElement(2, newObjectLike(StandardClass.SIMPLEARRAY, 0)); + getPackageArray().appendElement(result); + + packageMap.set(value, result); + + return result; + } + + public ObjectLike getTypeSignature(TypeSignature value) { + //Log.line("Looking up type signature " + value.toString()); + if (typeSignatureMap.hasKey(value)) { + //Log.line("Using " + typeSignatureMap.get(value).debugString()); + return typeSignatureMap.get(value); + } + ObjectLike result = newObjectLike(StandardClass.SIMPLETYPEREF, 2); + result.setElement(0, value.packageName == null ? getNull() : (ObjectLike) getConstString(value.packageName)); + result.setElement(1, getConstString(value.typeName)); + + typeSignatureMap.set(value, result); + + //Log.line("Created " + typeSignatureMap.get(value).debugString()); + + return result; + } + + public ObjectLike getFieldSignature(FieldSignature value) { + if (fieldSignatureMap.hasKey(value)) { + return fieldSignatureMap.get(value); + } + ObjectLike result = newObjectLike(value.isStatic ? StandardClass.STATICFIELDREF : StandardClass.INSTANCEFIELDREF, 3); + result.setElement(0, getTypeSignature(value.owner)); + result.setElement(1, getTypeSignature(value.storageType)); + result.setElement(2, getConstString(value.name)); + + fieldSignatureMap.set(value, result); + + return result; + } + + public ObjectLike getMethodSignature(MethodSignature value) { + if (methodSignatureMap.hasKey(value)) { + return methodSignatureMap.get(value); + } + StandardClass cl; + switch (value.kind) { + case MethodSignature.Kind.CONSTRUCTOR: + cl = StandardClass.CONSTRUCTORMETHODREF; + break; + case MethodSignature.Kind.STATIC_INIT: + cl = StandardClass.STATICINITMETHODREF; + break; + case MethodSignature.Kind.STATIC_METHOD: + cl = StandardClass.STATICMETHODREF; + break; + case MethodSignature.Kind.INSTANCE_METHOD: + cl = StandardClass.INSTANCEMETHODREF; + break; + case MethodSignature.Kind.INTERFACE_METHOD: + cl = StandardClass.INTERFACEMETHODREF; + break; + default: + throw new Error("Internal error: Unrecognised method kind " + value.kind); + } + ObjectLike result = newObjectLike(cl, 4); + result.setElement(0, getTypeSignature(value.owner)); + result.setElement(1, getTypeSignature(value.returnType)); + result.setElement(2, getConstString(value.name)); + if (value.argumentTypes != null && value.argumentTypes.length > 0) { + ObjectLike argtypes = newObjectLike(StandardClass.SIMPLEARRAY, value.argumentTypes.length); + result.setElement(3, argtypes); + for (int i = 0; i < value.argumentTypes.length; i++) { + argtypes.setElement(i, getTypeSignature(value.argumentTypes[i])); + } + } + + methodSignatureMap.set(value, result); + + return result; + } + + public static enum FileFields { + PACKAGENAME, + INNERNAME, + DATA, + META, + DEBUGNAME + } + + public ObjectLike newFile(String packagename, String innername, byte[] data, String typeinfo, String debugname) { + ObjectLike result = newObjectLike(StandardClass.FILE, FileFields.lookupCount(FileFields.class)); + result.setElement(FileFields.PACKAGENAME.value, packagename == null ? getNull() : (ObjectLike) getConstString(packagename)); + result.setElement(FileFields.INNERNAME.value, getConstString(innername)); + result.setElement(FileFields.META.value, typeinfo == null ? getNull() : (ObjectLike) getConstString(typeinfo)); + result.setElement(FileFields.DEBUGNAME.value, debugname == null ? getNull() : (ObjectLike) getConstString(debugname)); + + ArrayInt8 dataarray = newArrayInt8(StandardClass.FILE_BYTES, data.length); + for (int i = 0; i < data.length; i++) { + dataarray.setElement(i, data[i]); + } + result.setElement(FileFields.DATA.value, dataarray); + + ObjectLike pkgtypes = (ObjectLike) getPackage(packagename).getElement(2); + pkgtypes.appendElement(result); + + return result; + } + + public static enum DependsFields { + NAME, + VERSION, + HINT, + HASH + } + + public ObjectLike newDepends(String name, String version, String hint, String hash) { + ObjectLike result = newObjectLike(StandardClass.DEPENDS, DependsFields.lookupCount(DependsFields.class)); + result.setElement(DependsFields.NAME.value, name == null ? getNull() : (ObjectLike) getConstString(name)); + result.setElement(DependsFields.VERSION.value, version == null ? getNull() : (ObjectLike) getConstString(version)); + result.setElement(DependsFields.HINT.value, hint == null ? getNull() : (ObjectLike) getConstString(hint)); + result.setElement(DependsFields.HASH.value, hash == null ? getNull() : (ObjectLike) getConstString(hash)); + + getDependsArray().appendElement(result); + + return result; + } + + public static enum ProvidesFields { + NAME, + VERSION + } + + public ObjectLike newProvides(String name, String version) { + ObjectLike result = newObjectLike(StandardClass.PROVIDES, ProvidesFields.lookupCount(ProvidesFields.class)); + result.setElement(ProvidesFields.NAME.value, name == null ? getNull() : (ObjectLike) getConstString(name)); + result.setElement(ProvidesFields.VERSION.value, version == null ? getNull() : (ObjectLike) getConstString(version)); + + getDependsArray().appendElement(result); + + return result; + } + + public static enum MetadataFields { + KEY, + VALUE, + } + + public ObjectLike newMetadata(boolean important, String key, String value) { + ObjectLike result = newObjectLike(StandardClass.METADATA, MetadataFields.lookupCount(MetadataFields.class)); + result.setElement(MetadataFields.KEY.value, key == null ? getNull() : (ObjectLike) getConstString(key)); + result.setElement(MetadataFields.VALUE.value, value == null ? getNull() : (ObjectLike) getConstString(value)); + + if (important) { + getImportantMetadataArray().appendElement(result); + } else { + getOtherMetadataArray().appendElement(result); + } + + return result; + } + + public static enum RuntimedataFields { + TYPE, + FORMATOPTS, + FLAGS + } + + public ObjectLike registerRuntimeType(int indexOrNeg, int kind, TypeSignature type, String formatopts, boolean isBuiltin, boolean isNumber, boolean isFloat, boolean isSigned, int nbits) { + int flags = kind; + if (isBuiltin) { + flags |= (1 << 8); + } + if (isNumber) { + flags |= (1 << 9); + } + if (isFloat) { + flags |= (1 << 10); + } + if (isSigned) { + flags |= (1 << 11); + } + flags |= (nbits << 16); + + ObjectLike result = newObjectLike(StandardClass.RUNTIMEDATA, RuntimedataFields.lookupCount(RuntimedataFields.class)); + //System.err.println("Adding runtime data #" + indexOrNeg + " at index #" + result.getRecordIndex()); + result.setElement(RuntimedataFields.TYPE.value, type == null ? getNull() : getTypeSignature(type)); + result.setElement(RuntimedataFields.FORMATOPTS.value, formatopts == null ? getNull() : (ObjectLike) getConstString(formatopts)); + result.setElement(RuntimedataFields.FLAGS.value, getConstInt32("" + flags)); + + if (indexOrNeg < 0) { + getRuntimedataArray().appendElement(result); + } else { + getRuntimedataArray().setElement(indexOrNeg, result); + } + + return result; + } + + public static enum TypeFields { + SIGNATURE, + FLAGS, + BASE, + INTERFACES, + MEMBERS, + FILENAME + } + + public ObjectLike newType(int flags, TypeSignature sig) { + ObjectLike result = newObjectLike(StandardClass.TYPE, TypeFields.lookupCount(TypeFields.class)); + result.setElement(0, getTypeSignature(sig)); + result.setElement(1, getNull());//newObjectLike(StandardClass.SIMPLEARRAY, 0)); + result.setElement(2, getNull()); + result.setElement(3, getNull());//newObjectLike(StandardClass.SIMPLEARRAY, 0)); + result.setElement(4, getNull()); + result.setElement(TypeFields.FLAGS.value, getConstInt32("" + flags)); + + ObjectLike pkgtypes = (ObjectLike) getPackage(sig.packageName).getElement(2); + pkgtypes.appendElement(result); + + return result; + } + + public void addMember(ObjectLike type, Record member) { + if (type.getElement(TypeFields.MEMBERS.value) == getNull()) { + type.setElement(TypeFields.MEMBERS.value, newObjectLike(StandardClass.SIMPLEARRAY, 0)); + } + ObjectLike memberArray = (ObjectLike) type.getElement(TypeFields.MEMBERS.value); + memberArray.appendElement(member); + } + + public static enum FieldFields { + SIGNATURE, + FLAGS + } + + + public ObjectLike newField(ObjectLike type, int flags, FieldSignature sig) { + ObjectLike result = newObjectLike(sig.isStatic ? StandardClass.STATIC_FIELD : StandardClass.INSTANCE_FIELD, FieldFields.lookupCount(FieldFields.class)); + result.setElement(FieldFields.SIGNATURE.value, getFieldSignature(sig)); + result.setElement(FieldFields.FLAGS.value, getConstInt32("" + flags)); + + addMember(type, result); + + return result; + } + + public static enum MethodFields { + SIGNATURE, + FLAGS, + BYTECODE, + EXCEPTIONS, + DEBUG, + LOCALS, + MAXSTACK, + THROWS + } + static int methodFieldsCount = MethodFields.lookupCount(MethodFields.class); + + public ObjectLike newMethod(ObjectLike type, int flags, MethodSignature sig, int nlocals) { + StandardClass t; + switch (sig.kind) { + case MethodSignature.Kind.INSTANCE_METHOD: + t = StandardClass.INSTANCE_METHOD; + break; + case MethodSignature.Kind.STATIC_METHOD: + t = StandardClass.STATIC_METHOD; + break; + case MethodSignature.Kind.CONSTRUCTOR: + t = StandardClass.INSTANCE_CONSTRUCTOR; + break; + case MethodSignature.Kind.STATIC_INIT: + t = StandardClass.STATIC_INIT; + break; + case MethodSignature.Kind.INTERFACE_METHOD: + t = StandardClass.INTERFACE_METHOD; + break; + default: + throw new Error("Unexpected method signature kind: " + sig.kind); + } + ObjectLike result = newObjectLike(t, methodFieldsCount); + result.setElement(MethodFields.SIGNATURE.value, getMethodSignature(sig)); + result.setElement(MethodFields.FLAGS.value, getConstInt32("" + flags)); + result.setElement(MethodFields.LOCALS.value, getConstInt32("" + nlocals)); + + addMember(type, result); + + return result; + } + + public int getMaximumRecords() { + return maximumRecords; + } + + public ObjectLike getMemberExtendedFlags(ObjectLike member) { + if (member.getElement(MethodFields.FLAGS.value).getStandardClass() != StandardClass.SIMPLEARRAY) { + ObjectLike result = newObjectLike(StandardClass.SIMPLEARRAY, 1); + result.setElement(0, member.getElement(MethodFields.FLAGS.value)); + member.setElement(MethodFields.FLAGS.value, result); + } + return (ObjectLike) member.getElement(MethodFields.FLAGS.value); + } + + public void addMemberTranslation(ObjectLike member, String language, String name) { + ObjectLike tr = newObjectLike(StandardClass.METADATA, MetadataFields.lookupCount(MetadataFields.class)); + tr.setElement(MetadataFields.KEY.value, language == null ? getNull() : (ObjectLike) getConstString(language)); + tr.setElement(MetadataFields.VALUE.value, name == null ? getNull() : (ObjectLike) getConstString(name)); + getMemberExtendedFlags(member).appendElement(tr); + } +} diff --git a/slangc/api/BytecodeInstructionWriter.sauce b/slangc/api/BytecodeInstructionWriter.sauce new file mode 100644 index 0000000..21671a5 --- /dev/null +++ b/slangc/api/BytecodeInstructionWriter.sauce @@ -0,0 +1,1023 @@ +package slangc.api; + +import slang.data.List; +import slangc.api.BytecodeHeap; +import slangc.api.TypeOption; +import slangc.bytecode.FieldSignature; +import slangc.bytecode.MethodSignature; +import slangc.bytecode.TypeSignature; +import slangc.model.BuiltinTypeModel; +import slangc.model.TypeModel; +import slangc.model.UserTypeModel; +import slangc.parser.AnnotationType; +import slangc.parser.ErrorType; +import slangc.parser.LocationAnnotation; +import slangc.parser.Node; + +public class BytecodeInstructionWriter { + public final BytecodeTarget target; + public final TypeModel owner; + public final BytecodeHeap.ObjectLike method; + private BytecodeHeap.ArrayInt32 instructions; + private List sourceStack = new List(); + private List