├── .gitattributes ├── .github └── workflows │ ├── rt3-unit-tests.yml │ └── rt4core-unit-tests.yml ├── .gitignore ├── .readthedocs.yml ├── README.md ├── build.gradle ├── buildSrc ├── build.gradle └── src │ ├── main │ ├── groovy │ │ └── java-conventions.gradle │ └── java │ │ └── uk │ │ └── co │ │ └── farowl │ │ ├── vsj2dy │ │ └── generate │ │ │ └── DynamicAPITask.java │ │ └── vsj3 │ │ └── generate │ │ └── evo1 │ │ └── DynamicAPIevo1Task.java │ └── test │ └── java │ └── uk │ └── co │ └── farowl │ └── vsj2dy │ └── generate │ └── TestDynamicAPITask.java ├── docs ├── docs.gradle └── src │ └── site │ └── sphinx │ ├── Makefile │ ├── architecture │ ├── _architecture.rst │ ├── arch-attribute-access.rst │ ├── arch-plain-java-object.rst │ ├── code-and-frame.rst │ ├── compiled-code.rst │ ├── descriptors.rst │ ├── functions-in-java.rst │ ├── interpreter-structure.rst │ ├── object-implementation.rst │ ├── testdot.uml │ └── type-slots.rst │ ├── background │ └── _background.rst │ ├── coding │ ├── _coding.rst │ ├── coding-standard.rst │ └── porting-cpython.rst │ ├── conf.py │ ├── generated-code │ ├── _generated-code.rst │ ├── attribute-access.rst │ ├── attributes-java.rst │ ├── attributes-python.rst │ ├── built-in-inheritance.rst │ ├── comparison-and-loops.rst │ ├── function-definition-and-call.rst │ ├── interpreter-cpython-byte-code.rst │ ├── introduction.rst │ ├── refactor-to-evo3.rst │ ├── refactor-to-evo4.rst │ ├── sequences-and-indexing.rst │ └── type-and-arithmetic.rst │ ├── index.rst │ ├── make.bat │ ├── performance │ ├── _performance.rst │ ├── binary-operations.rst │ ├── unary-operations.rst │ └── validity.rst │ ├── plain-java-object-2 │ ├── _plain-java-object-2.rst │ ├── basic-patterns.rst │ ├── introduction.rst │ ├── object-and-pytype-java.rst │ ├── object-and-pytype.rst │ ├── subclasses-in-python.rst │ └── type-system-init.rst │ ├── plain-java-object │ ├── _plain-java-object.rst │ ├── built-in-methods.rst │ ├── hash-dictionary.rst │ ├── introduction.rst │ ├── modules-in-java.rst │ ├── operations-builtin.rst │ └── type-new-init.rst │ ├── reference │ └── python3-objects.inv │ ├── requirements.txt │ └── treepython │ ├── _treepython.rst │ ├── ast_java.rst │ ├── ref_interp_help.rst │ ├── simple_statements.rst │ └── type+dispatch.rst ├── dy2 ├── dy2.gradle └── src │ └── main │ ├── dynamicAPI │ └── AbstractProxy.dynapi │ └── java │ └── uk │ └── co │ └── farowl │ └── vsj2dy │ └── evo4 │ └── AbstractProxyModel.java ├── dy2bm ├── dy2bm.gradle └── src │ └── main │ └── java │ └── uk │ └── co │ └── farowl │ └── vsj2dybm │ └── evo4 │ ├── MainLoop.java │ ├── PyFloatBinary.java │ ├── PyFloatUnary.java │ ├── PyLongBinary.java │ └── PyLongUnary.java ├── dy3bm.dism ├── dy3bm ├── dy3bm.gradle └── src │ └── main │ └── java │ └── uk │ └── co │ └── farowl │ └── vsj3dybm │ └── evo1 │ ├── DebugFloatBinary.java │ ├── DebugFloatUnary.java │ ├── DebugLongBinary.java │ ├── DebugLongUnary.java │ ├── MainLoop.java │ ├── PyFloatBinary.java │ ├── PyFloatUnary.java │ ├── PyLongBinary.java │ └── PyLongUnary.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── idioms ├── idioms.gradle └── src │ └── main │ └── java │ └── uk │ └── co │ └── farowl │ └── vsj3 │ └── evo1 │ ├── BMExceptionSupplier.java │ └── BMExceptionSupplierMainLoop.java ├── jy2bm ├── jy2bm.gradle └── src │ └── main │ └── java │ └── uk │ └── co │ └── farowl │ └── jy2bm │ ├── MainLoop.java │ ├── PyFloatBinary.java │ ├── PyFloatUnary.java │ ├── PyLongBinary.java │ └── PyLongUnary.java ├── rt1 ├── rt1.gradle └── src │ ├── main │ ├── asdl │ │ └── uk │ │ │ └── co │ │ │ └── farowl │ │ │ └── vsj1 │ │ │ └── TreePython.asdl │ ├── java │ │ └── uk │ │ │ └── co │ │ │ └── farowl │ │ │ └── vsj1 │ │ │ ├── BigIntegerOperations.java │ │ │ ├── BinOpCallSite.java │ │ │ ├── DoubleOperations.java │ │ │ ├── ExecNode.java │ │ │ ├── IntegerOperations.java │ │ │ ├── LongOperations.java │ │ │ ├── MixedNumberOperations.java │ │ │ ├── Operations.java │ │ │ ├── Py.java │ │ │ └── UnaryOpCallSite.java │ └── python │ │ ├── astutil.py │ │ ├── codeutil.py │ │ └── symbolutil.py │ └── test │ ├── asdl │ └── uk │ │ └── co │ │ └── farowl │ │ └── vsj1 │ │ ├── Python.asdl │ │ └── example │ │ ├── TreePythonEx1.asdl │ │ ├── TreePythonEx5.asdl │ │ └── TreePythonEx6.asdl │ ├── java │ └── uk │ │ └── co │ │ └── farowl │ │ └── vsj1 │ │ ├── example │ │ ├── ExecNodeEx5.java │ │ ├── TestEx1.java │ │ ├── TestEx2.java │ │ ├── TestEx3.java │ │ ├── TestEx4.java │ │ ├── TestEx5.java │ │ ├── TestEx6.java │ │ ├── TestEx7.java │ │ ├── TestEx8.java │ │ ├── TestEx9.java │ │ ├── TestInterp1.java │ │ ├── TestInterp2.java │ │ ├── TestInterp3.java │ │ ├── TestInterp4.java │ │ └── TestInterp5.java │ │ └── experiment │ │ └── state │ │ ├── CVFinalizeMemLeak.java │ │ └── CVFinalizeWeakRef.java │ └── python │ └── vsj1 │ ├── code_testgen.py │ ├── symtable_testgen.py │ ├── variable_access.py │ └── variable_access_testgen.py ├── rt2 ├── rt2.gradle └── src │ ├── main │ ├── java │ │ ├── module-info.java │ │ └── uk │ │ │ └── co │ │ │ └── farowl │ │ │ └── vsj2 │ │ │ ├── evo2 │ │ │ ├── Abstract.java │ │ │ ├── BaseException.java │ │ │ ├── CPythonFrame.java │ │ │ ├── Cell.java │ │ │ ├── Comparison.java │ │ │ ├── IndexError.java │ │ │ ├── InterpreterError.java │ │ │ ├── Mapping.java │ │ │ ├── Number.java │ │ │ ├── Opcode.java │ │ │ ├── OverflowError.java │ │ │ ├── Py.java │ │ │ ├── PyBaseObject.java │ │ │ ├── PyBool.java │ │ │ ├── PyBytes.java │ │ │ ├── PyCode.java │ │ │ ├── PyDictionary.java │ │ │ ├── PyException.java │ │ │ ├── PyFloat.java │ │ │ ├── PyFrame.java │ │ │ ├── PyList.java │ │ │ ├── PyLong.java │ │ │ ├── PyObject.java │ │ │ ├── PyObjectUtil.java │ │ │ ├── PyTuple.java │ │ │ ├── PyType.java │ │ │ ├── PyUnicode.java │ │ │ ├── Sequence.java │ │ │ ├── Slot.java │ │ │ ├── SystemError.java │ │ │ ├── ThreadState.java │ │ │ └── TypeError.java │ │ │ ├── evo3 │ │ │ ├── Abstract.java │ │ │ ├── AttributeError.java │ │ │ ├── BaseException.java │ │ │ ├── BuiltinsModule.java │ │ │ ├── CPythonCode.java │ │ │ ├── CPythonFrame.java │ │ │ ├── Callables.java │ │ │ ├── ClassShorthand.java │ │ │ ├── Comparison.java │ │ │ ├── DeprecationWarning.java │ │ │ ├── Exposed.java │ │ │ ├── ID.java │ │ │ ├── IndexError.java │ │ │ ├── Interpreter.java │ │ │ ├── InterpreterError.java │ │ │ ├── JavaModule.java │ │ │ ├── KeyError.java │ │ │ ├── LookupError.java │ │ │ ├── Mapping.java │ │ │ ├── MethodDef.java │ │ │ ├── NameError.java │ │ │ ├── NotImplementedError.java │ │ │ ├── Number.java │ │ │ ├── Opcode.java │ │ │ ├── OverflowError.java │ │ │ ├── Py.java │ │ │ ├── PyBaseObject.java │ │ │ ├── PyBool.java │ │ │ ├── PyBytes.java │ │ │ ├── PyCell.java │ │ │ ├── PyCode.java │ │ │ ├── PyDict.java │ │ │ ├── PyException.java │ │ │ ├── PyFloat.java │ │ │ ├── PyFrame.java │ │ │ ├── PyFunction.java │ │ │ ├── PyJavaFunction.java │ │ │ ├── PyList.java │ │ │ ├── PyLong.java │ │ │ ├── PyModule.java │ │ │ ├── PyObject.java │ │ │ ├── PyObjectUtil.java │ │ │ ├── PyTuple.java │ │ │ ├── PyType.java │ │ │ ├── PyUnicode.java │ │ │ ├── RuntimeError.java │ │ │ ├── RuntimeWarning.java │ │ │ ├── Sequence.java │ │ │ ├── Slot.java │ │ │ ├── SystemError.java │ │ │ ├── ThreadState.java │ │ │ ├── Tuple.java │ │ │ ├── TypeError.java │ │ │ ├── TypedTuple.java │ │ │ ├── UnboundLocalError.java │ │ │ ├── ValueError.java │ │ │ ├── Warning.java │ │ │ └── Warnings.java │ │ │ └── evo4 │ │ │ ├── Abstract.java │ │ │ ├── AbstractPyObject.java │ │ │ ├── AttributeError.java │ │ │ ├── BaseException.java │ │ │ ├── BuiltinsModule.java │ │ │ ├── CPythonCode.java │ │ │ ├── CPythonFrame.java │ │ │ ├── Callables.java │ │ │ ├── ClassShorthand.java │ │ │ ├── Clinic.java │ │ │ ├── Comparison.java │ │ │ ├── DataDescriptor.java │ │ │ ├── DeprecationWarning.java │ │ │ ├── Descriptor.java │ │ │ ├── Exposed.java │ │ │ ├── Exposer.java │ │ │ ├── ID.java │ │ │ ├── IndexError.java │ │ │ ├── Interpreter.java │ │ │ ├── InterpreterError.java │ │ │ ├── JavaModule.java │ │ │ ├── KeyError.java │ │ │ ├── LookupError.java │ │ │ ├── MethodDef.java │ │ │ ├── MissingFeature.java │ │ │ ├── NameError.java │ │ │ ├── NotImplementedError.java │ │ │ ├── Number.java │ │ │ ├── Opcode.java │ │ │ ├── OverflowError.java │ │ │ ├── Py.java │ │ │ ├── PyBaseObject.java │ │ │ ├── PyBool.java │ │ │ ├── PyBytes.java │ │ │ ├── PyCell.java │ │ │ ├── PyCode.java │ │ │ ├── PyDict.java │ │ │ ├── PyException.java │ │ │ ├── PyFloat.java │ │ │ ├── PyFrame.java │ │ │ ├── PyFunction.java │ │ │ ├── PyGetSetDescr.java │ │ │ ├── PyJavaCallable.java │ │ │ ├── PyJavaFunction.java │ │ │ ├── PyJavaMethod.java │ │ │ ├── PyList.java │ │ │ ├── PyLong.java │ │ │ ├── PyMemberDescr.java │ │ │ ├── PyMethodDescr.java │ │ │ ├── PyMethodWrapper.java │ │ │ ├── PyModule.java │ │ │ ├── PyObject.java │ │ │ ├── PyObjectDict.java │ │ │ ├── PyObjectUtil.java │ │ │ ├── PyRT.java │ │ │ ├── PySequence.java │ │ │ ├── PyTuple.java │ │ │ ├── PyType.java │ │ │ ├── PyUnicode.java │ │ │ ├── PyWrapperDescr.java │ │ │ ├── RecursionError.java │ │ │ ├── RuntimeError.java │ │ │ ├── RuntimeWarning.java │ │ │ ├── Sequence.java │ │ │ ├── Slot.java │ │ │ ├── SystemError.java │ │ │ ├── ThreadState.java │ │ │ ├── TypeError.java │ │ │ ├── UnboundLocalError.java │ │ │ ├── ValueError.java │ │ │ ├── VectorCallable.java │ │ │ ├── Warning.java │ │ │ └── Warnings.java │ └── javadoc │ │ └── project-styles.css │ └── test │ ├── java │ └── uk │ │ └── co │ │ └── farowl │ │ └── vsj2 │ │ ├── PyByteCode1.java │ │ ├── evo2 │ │ ├── PyByteCode2.java │ │ └── PyByteCode3.java │ │ ├── evo3 │ │ ├── PyByteCode2.java │ │ ├── PyByteCode3.java │ │ ├── PyByteCode4.java │ │ └── PyByteCode5.java │ │ └── evo4 │ │ ├── ExposerTest.java │ │ ├── InheritanceTest.java │ │ ├── PyByteCode2.java │ │ ├── PyByteCode3.java │ │ ├── PyByteCode4.java │ │ ├── PyByteCode5.java │ │ ├── PyByteCode6.java │ │ ├── PyTupleTest.java │ │ └── PyTypeTest.java │ └── python │ └── vsj2 │ ├── __init__.py │ ├── exparser.py │ ├── py_byte_code1.ex.py │ ├── py_byte_code1.py │ ├── py_byte_code2.ex.py │ ├── py_byte_code2_evo2.py │ ├── py_byte_code2_evo3.py │ ├── py_byte_code2_evo4.py │ ├── py_byte_code3.ex.py │ ├── py_byte_code3_evo2.py │ ├── py_byte_code3_evo3.py │ ├── py_byte_code3_evo4.py │ ├── py_byte_code4.ex.py │ ├── py_byte_code4_evo3.py │ ├── py_byte_code4_evo4.py │ ├── py_byte_code5.ex.py │ ├── py_byte_code5_evo3.py │ ├── py_byte_code5_evo4.py │ ├── py_byte_code6.ex.py │ ├── py_byte_code6_evo4.py │ ├── srcgen.py │ └── testgen.py ├── rt2bm ├── rt2bm.gradle └── src │ └── main │ └── java │ └── uk │ └── co │ └── farowl │ └── vsj2bm │ └── evo4 │ ├── MainLoop.java │ ├── PyFloatBinary.java │ ├── PyFloatUnary.java │ ├── PyLongBinary.java │ └── PyLongUnary.java ├── rt3 ├── rt3.gradle ├── src │ ├── main │ │ ├── dynamicAPI │ │ │ └── AbstractProxy.dynapi │ │ ├── java │ │ │ └── uk │ │ │ │ └── co │ │ │ │ └── farowl │ │ │ │ └── vsj3 │ │ │ │ └── evo1 │ │ │ │ ├── Abstract.java │ │ │ │ ├── AbstractPyIterator.java │ │ │ │ ├── AbstractPyObject.java │ │ │ │ ├── ArgParser.java │ │ │ │ ├── ArgumentError.java │ │ │ │ ├── ArithmeticError.java │ │ │ │ ├── AttributeError.java │ │ │ │ ├── BaseException.java │ │ │ │ ├── BuiltinsModule.java │ │ │ │ ├── CPython311Code.java │ │ │ │ ├── CPython311Frame.java │ │ │ │ ├── CPython311Function.java │ │ │ │ ├── Callables.java │ │ │ │ ├── ClassShorthand.java │ │ │ │ ├── Clinic.java │ │ │ │ ├── Comparison.java │ │ │ │ ├── CraftedPyObject.java │ │ │ │ ├── DataDescriptor.java │ │ │ │ ├── DeprecationWarning.java │ │ │ │ ├── DerivedPyObject.java │ │ │ │ ├── Descriptor.java │ │ │ │ ├── DictPyObject.java │ │ │ │ ├── EOFError.java │ │ │ │ ├── Exposed.java │ │ │ │ ├── Exposer.java │ │ │ │ ├── FastCall.java │ │ │ │ ├── IndexError.java │ │ │ │ ├── Interpreter.java │ │ │ │ ├── JavaModule.java │ │ │ │ ├── KeyError.java │ │ │ │ ├── LookupError.java │ │ │ │ ├── MemoryError.java │ │ │ │ ├── MethodDescriptor.java │ │ │ │ ├── MethodSignature.java │ │ │ │ ├── ModuleDef.java │ │ │ │ ├── ModuleExposer.java │ │ │ │ ├── NameError.java │ │ │ │ ├── OSError.java │ │ │ │ ├── Opcode311.java │ │ │ │ ├── Operations.java │ │ │ │ ├── OverflowError.java │ │ │ │ ├── Py.java │ │ │ │ ├── PyBaseObject.java │ │ │ │ ├── PyBool.java │ │ │ │ ├── PyBytes.java │ │ │ │ ├── PyCell.java │ │ │ │ ├── PyCode.java │ │ │ │ ├── PyDict.java │ │ │ │ ├── PyEllipsis.java │ │ │ │ ├── PyException.java │ │ │ │ ├── PyFloat.java │ │ │ │ ├── PyFrame.java │ │ │ │ ├── PyFunction.java │ │ │ │ ├── PyGetSetDescr.java │ │ │ │ ├── PyIterator.java │ │ │ │ ├── PyJavaFunction.java │ │ │ │ ├── PyList.java │ │ │ │ ├── PyLong.java │ │ │ │ ├── PyMapping.java │ │ │ │ ├── PyMemberDescr.java │ │ │ │ ├── PyMethodDescr.java │ │ │ │ ├── PyMethodWrapper.java │ │ │ │ ├── PyModule.java │ │ │ │ ├── PyNone.java │ │ │ │ ├── PyNotImplemented.java │ │ │ │ ├── PyNumber.java │ │ │ │ ├── PyObjectUtil.java │ │ │ │ ├── PyRT.java │ │ │ │ ├── PySequence.java │ │ │ │ ├── PySlice.java │ │ │ │ ├── PyStaticMethod.java │ │ │ │ ├── PyTuple.java │ │ │ │ ├── PyType.java │ │ │ │ ├── PyUnicode.java │ │ │ │ ├── PyWrapperDescr.java │ │ │ │ ├── RecursionError.java │ │ │ │ ├── RuntimeError.java │ │ │ │ ├── RuntimeWarning.java │ │ │ │ ├── ScopeKind.java │ │ │ │ ├── Singleton.java │ │ │ │ ├── Slot.java │ │ │ │ ├── StopIteration.java │ │ │ │ ├── SystemError.java │ │ │ │ ├── ThreadState.java │ │ │ │ ├── TypeError.java │ │ │ │ ├── TypeExposer.java │ │ │ │ ├── UnboundLocalError.java │ │ │ │ ├── ValueError.java │ │ │ │ ├── Warning.java │ │ │ │ ├── Warnings.java │ │ │ │ ├── ZeroDivisionError.java │ │ │ │ ├── _base │ │ │ │ └── package-info.java │ │ │ │ ├── base │ │ │ │ ├── InterpreterError.java │ │ │ │ ├── MethodKind.java │ │ │ │ ├── MissingFeature.java │ │ │ │ └── package-info.java │ │ │ │ ├── modules │ │ │ │ ├── marshal.java │ │ │ │ └── package-info.java │ │ │ │ ├── package-info.java │ │ │ │ └── stringlib │ │ │ │ ├── AbstractIntArrayBuilder.java │ │ │ │ ├── ByteArrayBuilder.java │ │ │ │ ├── ByteArrayReverseBuilder.java │ │ │ │ ├── FieldNameIterator.java │ │ │ │ ├── FloatFormatter.java │ │ │ │ ├── IntArrayBuilder.java │ │ │ │ ├── IntArrayReverseBuilder.java │ │ │ │ ├── IntegerFormatter.java │ │ │ │ ├── InternalFormat.java │ │ │ │ ├── MarkupIterator.java │ │ │ │ ├── TextFormatter.java │ │ │ │ └── package-info.java │ │ ├── javaTemplate │ │ │ └── uk │ │ │ │ └── co │ │ │ │ └── farowl │ │ │ │ └── vsj3 │ │ │ │ └── evo1 │ │ │ │ ├── PyFloatBinops.java │ │ │ │ ├── PyFloatMethods.java │ │ │ │ ├── PyLongBinops.java │ │ │ │ ├── PyLongMethods.java │ │ │ │ └── PyUnicodeMethods.java │ │ └── javadoc │ │ │ └── project-styles.css │ └── test │ │ ├── java │ │ └── uk │ │ │ └── co │ │ │ └── farowl │ │ │ └── vsj3 │ │ │ └── evo1 │ │ │ ├── AbstractAPITest.java │ │ │ ├── AbstractNumberAPITest.java │ │ │ ├── AbstractSequenceAPITest.java │ │ │ ├── ArgParserTest.java │ │ │ ├── AttrGetSetTest.java │ │ │ ├── BinaryCallSiteTest.java │ │ │ ├── BinarySlotWrapperTest.java │ │ │ ├── BuiltinsModuleTest.java │ │ │ ├── CPython311CodeTest.java │ │ │ ├── ComparisonSlotWrapperTest.java │ │ │ ├── ExposerTest.java │ │ │ ├── FloatDivisionTest.java │ │ │ ├── FormatTest.java │ │ │ ├── IntegerDivisionTest.java │ │ │ ├── LookupTest.java │ │ │ ├── MethodDescriptorTest.java │ │ │ ├── MethodHandleFormationTest.java │ │ │ ├── ModuleExposerMethodTest.java │ │ │ ├── ModuleExposerTest.java │ │ │ ├── OperationsFormationTest.java │ │ │ ├── PyListTest.java │ │ │ ├── PyTest.java │ │ │ ├── PyTypeTest.java │ │ │ ├── PyUnicodeTest.java │ │ │ ├── SlotWrapperTestBase.java │ │ │ ├── TypeExposerGetSetTest.java │ │ │ ├── TypeExposerMemberTest.java │ │ │ ├── TypeExposerMethodTest.java │ │ │ ├── TypeExposerNewMethodTest.java │ │ │ ├── TypeExposerSlotWrapperTest.java │ │ │ ├── TypeExposerStaticMethodTest.java │ │ │ ├── TypeExposerTest.java │ │ │ ├── UnaryCallSiteTest.java │ │ │ ├── UnarySlotWrapperTest.java │ │ │ ├── UnitTestSupport.java │ │ │ ├── modules │ │ │ └── marshalTest.java │ │ │ └── stringlib │ │ │ └── FormatParsingTest.java │ │ └── pythonExample │ │ └── vsj3 │ │ └── evo1 │ │ ├── attr_access_builtin.py │ │ ├── binary_op.py │ │ ├── bool_left_arith.py │ │ ├── bool_right_arith.py │ │ ├── builtins_module.py │ │ ├── call_method_builtin.py │ │ ├── comparison.py │ │ ├── for_loop.py │ │ ├── function_call.py │ │ ├── function_closure.py │ │ ├── function_def.py │ │ ├── function_locals.py │ │ ├── iterables.py │ │ ├── list_dot_product.py │ │ ├── list_index.py │ │ ├── load_store_name.py │ │ ├── multi_if.py │ │ ├── simple_if.py │ │ ├── simple_loop.py │ │ ├── tuple_dot_product.py │ │ ├── tuple_index.py │ │ └── unary_op.py └── tools │ └── python │ ├── lib │ ├── compile_examples.py │ ├── evo1 │ │ ├── PyFloat.py │ │ ├── PyLong.py │ │ ├── PyUnicode.py │ │ ├── __init__.py │ │ └── base.py │ └── srcgen.py │ └── vsj3evo1 │ ├── java_object_gen.py │ └── marshal_test.py ├── rt3bm ├── rt3bm.gradle └── src │ └── main │ └── java │ └── uk │ └── co │ └── farowl │ └── vsj3bm │ └── evo1 │ ├── DebugLongBinary.java │ ├── DebugLongUnary.java │ ├── MainLoop.java │ ├── PyFloatBinary.java │ ├── PyFloatUnary.java │ ├── PyLongBinary.java │ └── PyLongUnary.java ├── rt4client ├── config │ └── app.logging.properties ├── rt4client.gradle └── src │ ├── main │ └── java │ │ ├── module-info.java │ │ └── uk │ │ └── co │ │ └── farowl │ │ └── vsj4c │ │ ├── app │ │ ├── ClientApp.java │ │ ├── MyType.java │ │ └── package-info.java │ │ └── ext │ │ ├── Extension.java │ │ └── package-info.java │ └── test │ └── java │ └── uk │ └── co │ └── farowl │ └── vsj4c │ └── package-info.java ├── rt4core ├── config │ ├── kernelTest.logging.properties │ └── test.logging.properties ├── rt4core.gradle ├── src │ ├── kernelTest │ │ └── java │ │ │ └── uk │ │ │ └── co │ │ │ └── farowl │ │ │ └── vsj4 │ │ │ └── runtime │ │ │ ├── BootstrapTest.java │ │ │ ├── TypeInitTest.java │ │ │ ├── TypeInitTestFromSpec.java │ │ │ ├── TypeInitTestNameError.java │ │ │ ├── TypeInitTestObject.java │ │ │ ├── TypeInitTestPyExc.java │ │ │ ├── TypeInitTestReentrant.java │ │ │ ├── TypeInitTestRegistry.java │ │ │ ├── TypeInitTestStopIteration.java │ │ │ ├── TypeInitTestType.java │ │ │ └── kernel │ │ │ └── TypeFactoryTest.java │ ├── main │ │ ├── java │ │ │ ├── module-info.java │ │ │ └── uk │ │ │ │ └── co │ │ │ │ └── farowl │ │ │ │ └── vsj4 │ │ │ │ ├── core │ │ │ │ └── package-info.java │ │ │ │ ├── runtime │ │ │ │ ├── Abstract.java │ │ │ │ ├── AbstractPyIterator.java │ │ │ │ ├── ArgParser.java │ │ │ │ ├── ArgumentError.java │ │ │ │ ├── Callables.java │ │ │ │ ├── ClassShorthand.java │ │ │ │ ├── Comparison.java │ │ │ │ ├── DataDescriptor.java │ │ │ │ ├── Descriptor.java │ │ │ │ ├── Exposed.java │ │ │ │ ├── Exposer.java │ │ │ │ ├── FastCall.java │ │ │ │ ├── Feature.java │ │ │ │ ├── MethodDescriptor.java │ │ │ │ ├── MethodSignature.java │ │ │ │ ├── Py.java │ │ │ │ ├── PyAttributeError.java │ │ │ │ ├── PyBaseException.java │ │ │ │ ├── PyBool.java │ │ │ │ ├── PyBytes.java │ │ │ │ ├── PyDict.java │ │ │ │ ├── PyErr.java │ │ │ │ ├── PyExc.java │ │ │ │ ├── PyFloat.java │ │ │ │ ├── PyGetSetDescr.java │ │ │ │ ├── PyIterator.java │ │ │ │ ├── PyJavaFunction.java │ │ │ │ ├── PyKeyError.java │ │ │ │ ├── PyList.java │ │ │ │ ├── PyLong.java │ │ │ │ ├── PyMemberDescr.java │ │ │ │ ├── PyMethodDescr.java │ │ │ │ ├── PyMethodWrapper.java │ │ │ │ ├── PyNameError.java │ │ │ │ ├── PyNone.java │ │ │ │ ├── PyNotImplemented.java │ │ │ │ ├── PyNumber.java │ │ │ │ ├── PyObject.java │ │ │ │ ├── PySequence.java │ │ │ │ ├── PySlice.java │ │ │ │ ├── PyStaticMethod.java │ │ │ │ ├── PyStopIteration.java │ │ │ │ ├── PyTuple.java │ │ │ │ ├── PyType.java │ │ │ │ ├── PyUnicode.java │ │ │ │ ├── PyUtil.java │ │ │ │ ├── PyWrapperDescr.java │ │ │ │ ├── TypeExposerImplementation.java │ │ │ │ ├── TypeFlag.java │ │ │ │ ├── TypeSpec.java │ │ │ │ ├── TypeSystem.java │ │ │ │ ├── TypedPyObject.java │ │ │ │ ├── Warnings.java │ │ │ │ ├── WithClass.java │ │ │ │ ├── WithClassAssignment.java │ │ │ │ ├── WithDict.java │ │ │ │ ├── WithDictAssignment.java │ │ │ │ ├── bootstrap │ │ │ │ │ └── package-info.java │ │ │ │ ├── internal │ │ │ │ │ ├── Clinic.java │ │ │ │ │ ├── NamedSpec.java │ │ │ │ │ ├── Singleton.java │ │ │ │ │ ├── _PyUtil.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── kernel │ │ │ │ │ ├── AdoptedRepresentation.java │ │ │ │ │ ├── AdoptiveType.java │ │ │ │ │ ├── BaseType.java │ │ │ │ │ ├── KernelType.java │ │ │ │ │ ├── KernelTypeFlag.java │ │ │ │ │ ├── MROCalculator.java │ │ │ │ │ ├── PyObjectMethods.java │ │ │ │ │ ├── ReplaceableType.java │ │ │ │ │ ├── Representation.java │ │ │ │ │ ├── SharedRepresentation.java │ │ │ │ │ ├── SimpleType.java │ │ │ │ │ ├── SpecialMethod.java │ │ │ │ │ ├── TypeExposer.java │ │ │ │ │ ├── TypeFactory.java │ │ │ │ │ ├── TypeRegistry.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── package-info.java │ │ │ │ └── subclass │ │ │ │ │ ├── SubclassFactory.java │ │ │ │ │ ├── SubclassSpec.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── stringlib │ │ │ │ ├── AbstractIntArrayBuilder.java │ │ │ │ ├── ByteArrayBuilder.java │ │ │ │ ├── ByteArrayReverseBuilder.java │ │ │ │ ├── IntArrayBuilder.java │ │ │ │ ├── IntArrayReverseBuilder.java │ │ │ │ └── package-info.java │ │ │ │ └── support │ │ │ │ ├── InterpreterError.java │ │ │ │ ├── JavaClassShorthand.java │ │ │ │ ├── MethodKind.java │ │ │ │ ├── MissingFeature.java │ │ │ │ ├── ScopeKind.java │ │ │ │ ├── internal │ │ │ │ ├── EmptyException.java │ │ │ │ ├── Util.java │ │ │ │ └── package-info.java │ │ │ │ └── package-info.java │ │ ├── javaTemplate │ │ │ └── uk │ │ │ │ └── co │ │ │ │ └── farowl │ │ │ │ └── vsj4 │ │ │ │ └── runtime │ │ │ │ ├── PyFloatBinops.java │ │ │ │ ├── PyFloatMethods.java │ │ │ │ ├── PyLongBinops.java │ │ │ │ ├── PyLongMethods.java │ │ │ │ └── PyUnicodeMethods.java │ │ └── javadoc │ │ │ ├── modular.options │ │ │ └── project-styles.css │ └── test │ │ └── java │ │ └── uk │ │ └── co │ │ └── farowl │ │ └── vsj4 │ │ └── runtime │ │ ├── AbstractAPITest.java │ │ ├── AbstractNumberAPITest.java │ │ ├── AbstractSequenceAPITest.java │ │ ├── ArgParserTest.java │ │ ├── BinarySlotWrapperTest.java │ │ ├── ComparisonSlotWrapperTest.java │ │ ├── ExposerTest.java │ │ ├── PyTypeTest.java │ │ ├── PyUnicodeTest.java │ │ ├── PyUtilTest.java │ │ ├── SlotWrapperTestBase.java │ │ ├── TypeExposerGetSetTest.java │ │ ├── TypeExposerMemberTest.java │ │ ├── TypeExposerMethodTest.java │ │ ├── TypeExposerNewMethodTest.java │ │ ├── TypeExposerSlotWrapperTest.java │ │ ├── TypeExposerStaticMethodTest.java │ │ ├── TypeExposerTest.java │ │ ├── UnarySlotWrapperTest.java │ │ ├── UnitTestSupport.java │ │ └── kernel │ │ ├── MethodHandleFormationTest.java │ │ ├── PyExcTypesTest.java │ │ └── SubclassCreationTest.java └── tools │ └── python │ ├── java_object_gen.py │ ├── lib │ └── srcgen.py │ └── template │ ├── PyFloat.py │ ├── PyLong.py │ ├── PyUnicode.py │ ├── __init__.py │ └── base.py ├── settings.gradle └── vsj-tools ├── settings.gradle ├── src ├── main │ ├── antlr │ │ └── uk │ │ │ └── co │ │ │ └── farowl │ │ │ └── asdl │ │ │ └── ASDL.g4 │ ├── java │ │ └── uk │ │ │ └── co │ │ │ └── farowl │ │ │ └── asdl │ │ │ ├── ASDLCompiler.java │ │ │ ├── ASTBuilderParseVisitor.java │ │ │ ├── Compile.java │ │ │ ├── ast │ │ │ ├── AsdlTree.java │ │ │ ├── DefaultErrorHandler.java │ │ │ └── ErrorHandler.java │ │ │ ├── code │ │ │ ├── CodeTree.java │ │ │ ├── DefinitionBuilder.java │ │ │ ├── FieldAdder.java │ │ │ ├── ProductFieldAdder.java │ │ │ ├── Scope.java │ │ │ └── SumFieldAdder.java │ │ │ └── gradle │ │ │ ├── ASDLPlugin.java │ │ │ └── ASDLTask.java │ └── resources │ │ └── uk │ │ └── co │ │ └── farowl │ │ └── asdl │ │ └── ast │ │ ├── ASDL.stg │ │ └── Java.stg └── test │ ├── java │ └── uk │ │ └── co │ │ └── farowl │ │ └── asdl │ │ └── ast │ │ └── AsdlTreeTest.java │ └── resources │ ├── Python.asdl │ ├── TestUserDefined.stg │ ├── asdl.asdl │ ├── error │ ├── repeatDefinition.asdl │ └── syntaxError.asdl │ └── simple.asdl └── vsj-tools.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behaviour, in case people don't have core.autocrlf set. 2 | * text=input eol=lf 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | #*.asdl text 7 | 8 | # 9 | # Declare files that will always have CRLF line endings on checkout. 10 | # 11 | #*. text eol=crlf 12 | 13 | # 14 | # Denote all files that are truly binary and should not be modified. 15 | # 16 | *.png binary 17 | *.jpg binary 18 | *.jar binary 19 | 20 | # Intersphinx inventory 21 | *.inv binary 22 | -------------------------------------------------------------------------------- /.github/workflows/rt3-unit-tests.yml: -------------------------------------------------------------------------------- 1 | # Run unit tests on rt3 sub-project (GitHub action) 2 | name: rt3 unit tests 3 | 4 | on: [push] 5 | 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | rt3-unit-tests-Ubuntu-jdk-17: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - run: echo "Branch ${{ github.ref }} of repository ${{ github.repository }}." 16 | - uses: actions/checkout@v4 17 | 18 | - uses: gradle/actions/wrapper-validation@v4 19 | 20 | - name: Set up JDK 17 21 | uses: actions/setup-java@v4 22 | with: 23 | distribution: 'temurin' 24 | java-version: '17' 25 | 26 | - name: Set up Python 3.11 27 | uses: actions/setup-python@v4 28 | with: 29 | # This has to match the language version we're targeting 30 | python-version: '3.11' 31 | 32 | - name: Unit test with Gradle 33 | run: ./gradlew --no-daemon rt3:test 34 | -------------------------------------------------------------------------------- /.github/workflows/rt4core-unit-tests.yml: -------------------------------------------------------------------------------- 1 | # Run unit tests on rt4 core sub-project (GitHub action) 2 | name: rt4 core unit tests 3 | 4 | on: [push] 5 | 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | rt4-unit-tests-Ubuntu-jdk-17: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - run: echo "Branch ${{ github.ref }} of repository ${{ github.repository }}." 16 | - uses: actions/checkout@v4 17 | 18 | - uses: gradle/actions/wrapper-validation@v4 19 | 20 | - name: Set up JDK 17 21 | uses: actions/setup-java@v4 22 | with: 23 | distribution: 'temurin' 24 | java-version: '17' 25 | 26 | - name: Set up Python 3.11 27 | uses: actions/setup-python@v4 28 | with: 29 | # This has to match the language version we're targeting 30 | python-version: '3.11' 31 | 32 | - name: Unit test with Gradle 33 | run: ./gradlew --no-daemon rt4core:test 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore: things not to put under source control 2 | 3 | # Project specific structure 4 | **/bin/ 5 | /local/ 6 | **/venv/ 7 | **/venv/ 8 | **/.venv/ 9 | **/*-env/ 10 | 11 | # Generated during build 12 | **/build/ 13 | **/_build/ 14 | **/_static/ 15 | **/_templates/ 16 | 17 | # Places and extensions I use for non-SCM-able scraps 18 | /scraps/ 19 | /temp/ 20 | *.saved 21 | 22 | # IDE Files (I don't check mine in: get your own!) 23 | .classpath 24 | .externalToolBuilders/ 25 | .project 26 | .settings/ 27 | .pydevproject 28 | .idea/ 29 | 30 | # Droppings of various tools, not for the record 31 | *.class 32 | *.log 33 | *.pyc 34 | *.pyd 35 | *.pyo 36 | *.orig 37 | *.rej 38 | *.swp 39 | *.tmp 40 | \#* 41 | *~ 42 | 43 | **/.gradle/ 44 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yml 2 | 3 | # Read the Docs configuration file for Sphinx projects 4 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 5 | 6 | # Required 7 | version: 2 8 | 9 | # Set the OS, Python version and other tools you might need 10 | build: 11 | os: ubuntu-22.04 12 | tools: 13 | python: "3.12" 14 | # You can also specify other tool versions 15 | 16 | # Thanks to https://www.devhowto.dev/misc/sphinx-readthedocs-plantuml.html 17 | apt_packages: 18 | - plantuml 19 | 20 | # Build documentation in the "docs/" directory with Sphinx 21 | sphinx: 22 | configuration: docs/src/site/sphinx/conf.py 23 | # You can configure Sphinx to use a different builder, 24 | # for instance use the dirhtml builder for simpler URLs 25 | # builder: "dirhtml" 26 | # Fail on all warnings to avoid broken references 27 | # fail_on_warning: true 28 | 29 | # Optionally build additional formats such as PDF and ePub 30 | formats: 31 | - htmlzip 32 | # - pdf 33 | # - epub 34 | 35 | # Optional but recommended, declare the Python requirements required 36 | # to build your documentation 37 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 38 | python: 39 | install: 40 | - requirements: docs/src/site/sphinx/requirements.txt 41 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * $projectDir/build.gradle 3 | * 4 | * Root project build file for The Very Slow Jython Project. 5 | */ 6 | 7 | 8 | plugins { 9 | id 'maven-publish' 10 | } 11 | 12 | 13 | description = 'Very Slow Jython' 14 | group = 'uk.co.farowl' 15 | version = '0.4.0-SNAPSHOT' 16 | 17 | 18 | allprojects { 19 | 20 | tasks.withType(JavaCompile) { 21 | sourceCompatibility = JavaVersion.VERSION_17 22 | options.encoding = 'UTF-8' 23 | } 24 | 25 | tasks.withType(Javadoc) { 26 | options.encoding = 'UTF-8' 27 | } 28 | 29 | repositories { 30 | mavenLocal() 31 | mavenCentral() 32 | } 33 | } 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /buildSrc/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * $projectDir/buildSrc/build.gradle 3 | * 4 | * Project build file for buildSrc in The Very Slow Jython Project. 5 | */ 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | // ASM to generate classes that go in the library 13 | implementation 'org.ow2.asm:asm:9.0' 14 | 15 | // JUnit 5 dependencies 16 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.+' 17 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.+' 18 | } 19 | 20 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/java-conventions.gradle: -------------------------------------------------------------------------------- 1 | // rt2.java-conventions.gradle 2 | 3 | // See: 4 | // https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_modular 5 | 6 | java { 7 | modularity.inferModulePath = true 8 | } 9 | -------------------------------------------------------------------------------- /docs/docs.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * docs subproject (narrative setting out ideas on interpreter construction). 3 | * 4 | * The docs will appear in ./build/site relative to the location of this file. 5 | * 6 | * Code-level documentation (e.g. Javadocs) are generated within the 7 | * corresponding subprojects. 8 | */ 9 | 10 | plugins { 11 | id 'base' 12 | // Plugins from repositories (must include a version number) 13 | // Sphinx for our docs. https://trustin.github.io/sphinx-gradle-plugin 14 | id 'kr.motd.sphinx' version '2.6.1' // 15 | } 16 | 17 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/architecture/_architecture.rst: -------------------------------------------------------------------------------- 1 | .. architecture/_architecture.rst 2 | 3 | 4 | Architecture 5 | ############ 6 | 7 | .. note:: This chapter 8 | (uniquely in the document as a whole) 9 | tries to capture the latest thinking rather than the journey. 10 | But parts are not always revised as things move on, 11 | so tends to be more inconsistent than the rest. 12 | (When settled, it should be in part of the Jython project.) 13 | 14 | Previous chapters describe actual implementation experiments. 15 | This chapter is for stepping back from the realised code. 16 | Apart from analysis (of CPython etc.), 17 | it will collect together two broad kinds of idea 18 | about the architecture of a Java implementation of Python: 19 | 20 | * Ideas tested by the implementation experiments and shown to be useful. 21 | 22 | * Untested speculations. 23 | These may be tested in due course, 24 | in the experimental code of this project, 25 | quite likely resulting in some adjustment. 26 | 27 | There will also be some issues we don't know how to address (yet). 28 | Hopefully, these give rise to speculations 29 | and then tested ideas that address them. 30 | 31 | .. toctree:: 32 | :maxdepth: 2 33 | 34 | arch-plain-java-object 35 | object-implementation 36 | type-slots 37 | arch-attribute-access 38 | interpreter-structure 39 | code-and-frame 40 | compiled-code 41 | functions-in-java 42 | descriptors 43 | 44 | 45 | This chapter has diagrams generated with PlantUML 46 | (if this diagnostic panel appears): 47 | 48 | .. uml:: testdot.uml 49 | 50 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/architecture/compiled-code.rst: -------------------------------------------------------------------------------- 1 | .. architecture/compiled-code.rst 2 | 3 | 4 | Compiled Code (Python to JVM) 5 | ############################# 6 | 7 | This section is for discussion of 8 | the sort of JVM code that the Python compiler should output. 9 | (If it proves possible to keep them apart, 10 | it will be about the output rather than the compiler.) 11 | 12 | .. note:: At the time of writing, 13 | we have the precedent set by Jython 2, 14 | but we are fairly sure that the availability in Java 15 | of features for dynamic language implementation, 16 | will radically alter this output. 17 | Changes in the Python language since Python 2, 18 | will also require new constructs. 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/architecture/testdot.uml: -------------------------------------------------------------------------------- 1 | @startuml 2 | testdot 3 | @enduml 4 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/coding/_coding.rst: -------------------------------------------------------------------------------- 1 | .. coding/_coding.rst 2 | 3 | 4 | Writing Code 5 | ############ 6 | 7 | This chapter contains topics related to the process and conventions of coding 8 | for the Very Slow Jython project. 9 | 10 | .. toctree:: 11 | 12 | coding-standard 13 | porting-cpython 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/generated-code/_generated-code.rst: -------------------------------------------------------------------------------- 1 | .. generated-code/_generated-code.rst 2 | 3 | 4 | A Generated Code Interpreter 5 | ############################ 6 | 7 | In this chapter we start afresh on a second model run-time system 8 | in sub-project ``rt2``. 9 | We use the knowledge gained writing the code in sub-project ``rt1`` 10 | to bank some architectural concepts 11 | (that will hopefully prove enduring) 12 | but take a different approach to implementation. 13 | 14 | .. toctree:: 15 | 16 | introduction 17 | interpreter-cpython-byte-code 18 | type-and-arithmetic 19 | sequences-and-indexing 20 | built-in-inheritance 21 | comparison-and-loops 22 | refactor-to-evo3 23 | function-definition-and-call 24 | refactor-to-evo4 25 | attribute-access 26 | attributes-java 27 | attributes-python 28 | 29 | .. I think the chapters might go like this, 30 | but I'm not certain enough to create the files: 31 | mutable-types (object base and a hint of inheritance) 32 | attribute-access 33 | exceptions 34 | class-definition-and-instantiation 35 | inheritance 36 | adopted-java-types 37 | found-java-types 38 | code-objects-in-java-bytecode 39 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/index.rst: -------------------------------------------------------------------------------- 1 | .. The Very Slow Jython Project documentation master file, created by 2 | sphinx-quickstart on Fri Oct 21 23:39:23 2016. 3 | 4 | 5 | The Very Slow Jython Project 6 | ############################ 7 | 8 | A project to re-think implementation choices in the `Jython`_ core, 9 | through the gradual, narrated evolution of a toy implementation. 10 | 11 | .. _Jython: http://www.jython.org 12 | 13 | Contents 14 | ******** 15 | 16 | .. toctree:: 17 | :numbered: 3 18 | :maxdepth: 3 19 | 20 | background/_background 21 | treepython/_treepython 22 | generated-code/_generated-code 23 | plain-java-object/_plain-java-object 24 | plain-java-object-2/_plain-java-object-2 25 | performance/_performance 26 | architecture/_architecture 27 | coding/_coding 28 | 29 | 30 | Indices and tables 31 | ****************** 32 | 33 | * :ref:`genindex` 34 | * :ref:`modindex` 35 | * :ref:`search` 36 | 37 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/plain-java-object-2/_plain-java-object-2.rst: -------------------------------------------------------------------------------- 1 | .. plain-java-object/_plain-java-object.rst 2 | 3 | 4 | The Plain Java Object Model Extended 5 | #################################### 6 | 7 | This chapter marks yet another fresh start, 8 | although we are far from abandoning what was gained last chapter. 9 | The Plain Object model is considered established, 10 | we retain much of the apparatus of method exposure and calling, 11 | and the Python byte code interpreter frame is little changed. 12 | 13 | In the fourth model run-time system ``rt4``, 14 | we aim initially for these new things: 15 | 16 | #. Properly address Java classes as Python types. 17 | #. Handle special methods as methods first: 18 | type slots are just optimisation. 19 | #. Control visibility of the Jython API using Java modules. 20 | 21 | We elaborate on these aims in the :doc:`introduction`. 22 | 23 | .. toctree:: 24 | 25 | introduction 26 | basic-patterns 27 | object-and-pytype 28 | subclasses-in-python 29 | object-and-pytype-java 30 | type-system-init 31 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/plain-java-object/_plain-java-object.rst: -------------------------------------------------------------------------------- 1 | .. plain-java-object/_plain-java-object.rst 2 | 3 | 4 | A Plain Java Object Interpreter 5 | ############################### 6 | 7 | In this chapter we start afresh on a third model run-time system 8 | in sub-project ``rt3``. 9 | 10 | We will test a series of ideas that may make it possible 11 | to treat any Java object as a Python object. 12 | Jython 2 achieves this by wrapping objects 13 | that are not instances of some sub-class of ``PyObject`` in a proxy. 14 | We will attempt to do this so that the interpreter (or compiled code) 15 | handles the object directly. 16 | 17 | Concepts developed in sub-project ``rt2`` will be heavily re-used. 18 | 19 | 20 | .. toctree:: 21 | 22 | introduction 23 | operations-builtin 24 | hash-dictionary 25 | built-in-methods 26 | modules-in-java 27 | type-new-init 28 | 29 | .. A reminder of the chapters in the rt2 chapter: 30 | interpreter-cpython-byte-code 31 | type-and-arithmetic 32 | sequences-and-indexing 33 | built-in-inheritance 34 | comparison-and-loops 35 | refactor-to-evo3 36 | function-definition-and-call 37 | refactor-to-evo4 38 | attribute-access 39 | attributes-java 40 | attributes-python 41 | 42 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/reference/python3-objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeff5/very-slow-jython/c778bd7aac1136f01ad32efb36f51885cc35f194/docs/src/site/sphinx/reference/python3-objects.inv -------------------------------------------------------------------------------- /docs/src/site/sphinx/requirements.txt: -------------------------------------------------------------------------------- 1 | # requirements to build the documentation 2 | 3 | Sphinx>=2.2 4 | sphinxcontrib-plantuml 5 | -------------------------------------------------------------------------------- /docs/src/site/sphinx/treepython/_treepython.rst: -------------------------------------------------------------------------------- 1 | .. treepython/_treepthyon.rst 2 | 3 | 4 | A Tree-Python Interpreter 5 | ######################### 6 | 7 | .. toctree:: 8 | 9 | ref_interp_help 10 | ast_java 11 | type+dispatch 12 | simple_statements 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /dy2/src/main/dynamicAPI/AbstractProxy.dynapi: -------------------------------------------------------------------------------- 1 | # Name the methods to generate here 2 | 3 | package uk.co.farowl.vsj2dy.evo4 4 | 5 | class AbstractProxy 6 | 7 | unary negative 8 | binary add 9 | binary subtract 10 | binary multiply 11 | -------------------------------------------------------------------------------- /dy2/src/main/java/uk/co/farowl/vsj2dy/evo4/AbstractProxyModel.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2dy.evo4; 2 | 3 | import uk.co.farowl.vsj2.evo4.Number; 4 | import uk.co.farowl.vsj2.evo4.PyObject; 5 | 6 | public class AbstractProxyModel { 7 | 8 | private AbstractProxyModel() {} // No instances 9 | 10 | public static PyObject negative(PyObject v) throws Throwable { 11 | return Number.negative(v); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /dy2bm/src/main/java/uk/co/farowl/vsj2dybm/evo4/MainLoop.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2dybm.evo4; 2 | 3 | import uk.co.farowl.vsj2.evo4.Py; 4 | import uk.co.farowl.vsj2.evo4.PyObject; 5 | import uk.co.farowl.vsj2.evo4.Number; 6 | 7 | /** 8 | * A program that calls a selected method in the benchmark to explore in 9 | * isolation the way in which it gets optimised by the JVM. (See 10 | * {@code dy2bm.gradle} task {@code mainloop}. 11 | */ 12 | public class MainLoop { 13 | 14 | public static void main(String[] args) throws Throwable { 15 | PyFloatBinary test = new PyFloatBinary(); 16 | double sum = 0.0; 17 | for (int i = 0; i < 10_000; i++) { 18 | test.fvo = Py.val(i * 2.001); 19 | test.fwo = Py.val(i * 1.001); 20 | PyObject r = test.quartic(); 21 | //System.out.println(String.format("\nPartial = %s\n", r)); 22 | sum += Number.toFloat(r).doubleValue(); 23 | } 24 | System.out.println(String.format("Sum = %14.3e", sum)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dy3bm.dism: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeff5/very-slow-jython/c778bd7aac1136f01ad32efb36f51885cc35f194/dy3bm.dism -------------------------------------------------------------------------------- /dy3bm/src/main/java/uk/co/farowl/vsj3dybm/evo1/DebugFloatBinary.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3dybm.evo1; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * A program that calls a selected method in the benchmark so that we 7 | * can explore it with the debugger, outside the JMH framework. 8 | */ 9 | public class DebugFloatBinary { 10 | 11 | public static void main(String[] args) throws Throwable { 12 | 13 | PyLongBinary test = new PyLongBinary(); 14 | Object r = test.addbig(); 15 | 16 | // Second time the ClassValue should be ready for us 17 | test.bigv = BigInteger.valueOf(Integer.MIN_VALUE + 1); 18 | test.bigw = BigInteger.valueOf(-1); 19 | r = test.addbig(); 20 | 21 | System.out.println(String.format("Result = %s (%s)", r, 22 | r.getClass().getSimpleName())); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dy3bm/src/main/java/uk/co/farowl/vsj3dybm/evo1/DebugFloatUnary.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3dybm.evo1; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * A program that calls a selected method in the benchmark so that we 7 | * can explore it with the debugger, outside the JMH framework. 8 | */ 9 | public class DebugFloatUnary { 10 | 11 | public static void main(String[] args) throws Throwable { 12 | 13 | PyLongUnary test = new PyLongUnary(); 14 | Object r = test.negbig(); 15 | 16 | // Second time the ClassValue should be ready for us 17 | test.bigv = BigInteger.valueOf(Integer.MIN_VALUE+1); 18 | r = test.negbig(); 19 | 20 | System.out.println(String.format("Result = %s (%s)", r, 21 | r.getClass().getSimpleName())); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dy3bm/src/main/java/uk/co/farowl/vsj3dybm/evo1/DebugLongBinary.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3dybm.evo1; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * A program that calls a selected method in the benchmark so that we 7 | * can explore it with the debugger, outside the JMH framework. 8 | */ 9 | public class DebugLongBinary { 10 | 11 | public static void main(String[] args) throws Throwable { 12 | 13 | PyLongBinary test = new PyLongBinary(); 14 | Object r = test.addbig(); 15 | 16 | // Second time the ClassValue should be ready for us 17 | test.bigv = BigInteger.valueOf(Integer.MIN_VALUE + 1); 18 | test.bigw = BigInteger.valueOf(-1); 19 | r = test.addbig(); 20 | 21 | System.out.println(String.format("Result = %s (%s)", r, 22 | r.getClass().getSimpleName())); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dy3bm/src/main/java/uk/co/farowl/vsj3dybm/evo1/DebugLongUnary.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3dybm.evo1; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * A program that calls a selected method in the benchmark so that we 7 | * can explore it with the debugger, outside the JMH framework. 8 | */ 9 | public class DebugLongUnary { 10 | 11 | public static void main(String[] args) throws Throwable { 12 | 13 | PyLongUnary test = new PyLongUnary(); 14 | Object r = test.negbig(); 15 | 16 | // Second time the ClassValue should be ready for us 17 | test.bigv = BigInteger.valueOf(Integer.MIN_VALUE+1); 18 | r = test.negbig(); 19 | 20 | System.out.println(String.format("Result = %s (%s)", r, 21 | r.getClass().getSimpleName())); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dy3bm/src/main/java/uk/co/farowl/vsj3dybm/evo1/MainLoop.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3dybm.evo1; 2 | 3 | import uk.co.farowl.vsj3.evo1.Py; 4 | import uk.co.farowl.vsj3.evo1.PyFloat; 5 | 6 | /** 7 | * A program that calls a selected method in the benchmark to explore in 8 | * isolation the way in which it gets optimised by the JVM. (See 9 | * {@code rt3bm.gradle} task {@code mainloop}. 10 | */ 11 | public class MainLoop { 12 | 13 | public static void main(String[] args) throws Throwable { 14 | PyFloatBinary test = new PyFloatBinary(); 15 | double sum = 0.0; 16 | for (int i = 0; i < 10_000; i++) { 17 | test.v = i * 2.001; 18 | test.w = i * 1.001; 19 | // Object r = test.quartic(); 20 | 21 | Object r = test.add_float_int_java(); 22 | 23 | // System.out.println(String.format("\nPartial = %s\n", r)); 24 | sum += PyFloat.doubleValue(r); 25 | } 26 | System.out.println(String.format("Sum = %14.3e", sum)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeff5/very-slow-jython/c778bd7aac1136f01ad32efb36f51885cc35f194/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /idioms/src/main/java/uk/co/farowl/vsj3/evo1/BMExceptionSupplierMainLoop.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import uk.co.farowl.vsj3.evo1.PyUnicode; 7 | 8 | /** 9 | * A program that calls a selected method in the benchmark to explore in 10 | * isolation the way in which it gets optimised by the JVM. (See 11 | * {@code idiom.gradle} task {@code exceptionSupplierLoop}. 12 | */ 13 | public class BMExceptionSupplierMainLoop { 14 | 15 | public static void main(String[] args) throws Throwable { 16 | BMExceptionSupplier test = 17 | new BMExceptionSupplier(); 18 | Set sum = new HashSet(); 19 | for (int i = 0; i < 1000; i++) { 20 | test.vs = "name" + i; 21 | test.vu = PyUnicode.fromJavaString("name" + i); 22 | test.vi = i; 23 | sum.addAll(test.checkAll()); 24 | } 25 | // Dummy output prevents optimisation to nothing 26 | System.out.println(String.format("Unique = %10d", sum.size())); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /jy2bm/src/main/java/uk/co/farowl/jy2bm/MainLoop.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.jy2bm; 2 | 3 | import org.python.core.Py; 4 | import org.python.core.PyObject; 5 | 6 | /** 7 | * A program that calls a selected method in the benchmark to explore in 8 | * isolation the way in which it gets optimised by the JVM. (See 9 | * {@code jy2bm.gradle} task {@code mainloop}. 10 | */ 11 | public class MainLoop { 12 | 13 | public static void main(String[] args) { 14 | PyFloatBinary test = new PyFloatBinary(); 15 | double sum = 0.0; 16 | for (int i = 0; i < 10_000; i++) { 17 | test.fvo = Py.newFloat(i * 2.001); 18 | test.fwo = Py.newFloat(i * 1.001); 19 | PyObject r = test.quartic(); 20 | //System.out.println(String.format("\nPartial = %s\n", r)); 21 | sum += r.asDouble(); 22 | } 23 | System.out.println(String.format("Sum = %14.3e", sum)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /rt1/src/main/java/uk/co/farowl/vsj1/ExecNode.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj1; 2 | 3 | import java.lang.invoke.CallSite; 4 | 5 | /** 6 | * A base class for nodes in the AST or another tree that supports their 7 | * execution as code. 8 | */ 9 | public class ExecNode { 10 | public CallSite site; 11 | } 12 | -------------------------------------------------------------------------------- /rt1/src/test/asdl/uk/co/farowl/vsj1/example/TreePythonEx1.asdl: -------------------------------------------------------------------------------- 1 | -- TreePythonEx1.asdl 2 | -- Used by TestEx1 ... TestEx4 3 | 4 | module TreePythonEx1 5 | { 6 | expr = BinOp(expr left, operator op, expr right) 7 | | Constant(constant value, string? kind) 8 | | Name(identifier id, expr_context ctx) 9 | 10 | operator = Add | Sub | Mult | Div 11 | expr_context = Load | Store | Del 12 | } -------------------------------------------------------------------------------- /rt1/src/test/asdl/uk/co/farowl/vsj1/example/TreePythonEx5.asdl: -------------------------------------------------------------------------------- 1 | -- TreePythonEx5.asdl 2 | -- Used by TestEx5 3 | -- Identical to TreePythonEx1.asdl apart from the module name, but compiled 4 | -- with parameter base = ExecNodeEx5 to provide a "site" member on each Node. 5 | 6 | module TreePythonEx5 7 | { 8 | expr = BinOp(expr left, operator op, expr right) 9 | | Constant(constant value, string? kind) 10 | | Name(identifier id, expr_context ctx) 11 | 12 | operator = Add | Sub | Mult | Div 13 | expr_context = Load | Store | Del 14 | } -------------------------------------------------------------------------------- /rt1/src/test/asdl/uk/co/farowl/vsj1/example/TreePythonEx6.asdl: -------------------------------------------------------------------------------- 1 | -- TreePythonEx6.asdl 2 | -- Used by TestEx6 ... TestEx9 3 | -- Extends TreePythonEx1.asdl with unary operations, and compiled 4 | -- with parameter base = ExecNodeEx5 to provide a "site" member on each Node. 5 | 6 | module TreePythonEx6 7 | { 8 | expr = BinOp(expr left, operator op, expr right) 9 | | UnaryOp(unaryop op, expr operand) 10 | | Constant(constant value, string? kind) 11 | | Name(identifier id, expr_context ctx) 12 | 13 | operator = Add | Sub | Mult | Div 14 | unaryop = UAdd | USub 15 | expr_context = Load | Store | Del 16 | } -------------------------------------------------------------------------------- /rt1/src/test/java/uk/co/farowl/vsj1/example/ExecNodeEx5.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj1.example; 2 | 3 | import java.lang.invoke.CallSite; 4 | 5 | /** 6 | * A base class (for use in tests only, from TestEx5 on) for nodes in the 7 | * AST or another tree that supports their execution as code. 8 | */ 9 | public class ExecNodeEx5 { 10 | 11 | public CallSite site; 12 | } 13 | -------------------------------------------------------------------------------- /rt2/rt2.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * rt2 subproject (model interpreter runtime to test our ideas). 3 | */ 4 | 5 | plugins { 6 | id 'java-library' 7 | id 'jvm-test-suite' 8 | } 9 | 10 | 11 | dependencies {} 12 | 13 | // Configure the jvm-test-suite plug-in 14 | testing { 15 | suites { 16 | test { 17 | useJUnitJupiter() 18 | } 19 | } 20 | } 21 | 22 | 23 | // Some adjustments to Javadoc to ensure complex tables readable 24 | 25 | tasks.withType(Javadoc) { 26 | 27 | options.showFromPackage() 28 | 29 | // addStringOption inserts one "-" for us :/ 30 | // CSS adjustments (initially only for table style) 31 | options.addStringOption("-add-stylesheet", 32 | "src/main/javadoc/project-styles.css") 33 | 34 | // Enable "custom" tags used in JDK Javadoc since JSR-335. 35 | // https://nipafx.dev/javadoc-tags-apiNote-implSpec-implNote 36 | options.tags( 37 | "apiNote:a:API Note:", 38 | "implSpec:a:Implementation Requirements:", 39 | "implNote:a:Implementation Note:", 40 | // Unfortunately we must add these standard tags too, 41 | // so they come after the ones we want to enable. 42 | "param", "return", "throws", 43 | "since", "version", "serialData", "see") 44 | } 45 | 46 | 47 | tasks.withType(JavaCompile) { 48 | 49 | options.deprecation = true 50 | } 51 | -------------------------------------------------------------------------------- /rt2/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module uk.co.farowl.vsj2rt { 2 | exports uk.co.farowl.vsj2.evo4; 3 | } -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/BaseException.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** The Python {@code BaseException} exception. */ 4 | class BaseException extends RuntimeException implements PyObject { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("BaseException", BaseException.class); 9 | private final PyType type; 10 | 11 | @Override 12 | public PyType getType() { return type; } 13 | 14 | /** 15 | * Constructor for sub-class use specifying {@link #type}. 16 | * 17 | * @param type object being constructed 18 | * @param msg a Java format string for the message 19 | * @param args to insert in the format string 20 | */ 21 | protected BaseException(PyType type, String msg, Object... args) { 22 | super(String.format(msg, args)); 23 | this.type = type; 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public BaseException(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/Cell.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** Holder for objects appearing in the closure of a function. */ 4 | class Cell { 5 | 6 | PyObject obj; 7 | 8 | Cell(PyObject obj) { this.obj = obj; } 9 | 10 | @Override 11 | public String toString() { 12 | return String.format("", obj); 13 | } 14 | static final Cell[] EMPTY_ARRAY = new Cell[0]; 15 | } 16 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/IndexError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** The Python {@code IndexError} exception. */ 4 | class IndexError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("IndexError", IndexError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected IndexError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public IndexError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/InterpreterError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** 4 | * Internal error thrown when the Python implementation cannot be relied 5 | * on to work. A Python exception (a {@code PyObject} that might be 6 | * caught in Python code) is not then appropriate. Typically thrown 7 | * during initialisation or for irrecoverable internal errors. 8 | */ 9 | class InterpreterError extends RuntimeException { 10 | 11 | /** 12 | * Constructor specifying a message. 13 | * 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected InterpreterError(String msg, Object... args) { 18 | super(String.format(msg, args)); 19 | } 20 | 21 | /** 22 | * Constructor specifying a cause and a message. 23 | * 24 | * @param cause a Java exception behind the interpreter error 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | protected InterpreterError(Throwable cause, String msg, 29 | Object... args) { 30 | super(String.format(msg, args), cause); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/Mapping.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | 5 | /** Compare CPython {@code abstract.h}: {@code Py_Mapping_*}. */ 6 | class Mapping extends Abstract { 7 | 8 | /** 9 | * Python size of {@code o}, a mapping. 10 | * 11 | * @param o to operate on 12 | * @return derived size 13 | * @throws Throwable from invoked method implementations 14 | */ 15 | static PyObject size(PyObject o) throws Throwable { 16 | // Note that the slot is called length but this method, size. 17 | PyType oType = o.getType(); 18 | 19 | try { 20 | MethodHandle mh = oType.mapping.length; 21 | return (PyObject) mh.invokeExact(o); 22 | } catch (Slot.EmptyException e) {} 23 | 24 | if (Slot.MP.length.isDefinedFor(oType)) 25 | // Caller should have tried Abstract.size 26 | throw typeError(NOT_MAPPING, o); 27 | throw typeError(HAS_NO_LEN, o); 28 | } 29 | 30 | private static final String NOT_MAPPING = "%.200s is not a mapping"; 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/OverflowError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** The Python {@code OverflowError} exception. */ 4 | class OverflowError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("OverflowError", OverflowError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected OverflowError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public OverflowError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/Py.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** Runtime */ 4 | class Py { 5 | 6 | private static class Singleton implements PyObject { 7 | 8 | final PyType type; 9 | 10 | @Override 11 | public PyType getType() { return type; } 12 | String name; 13 | 14 | Singleton(String name) { 15 | this.name = name; 16 | type = new PyType(name, getClass()); 17 | } 18 | 19 | @Override 20 | public String toString() { return name; } 21 | } 22 | 23 | /** Python {@code None} object. */ 24 | static final PyObject None = new Singleton("None") {}; 25 | 26 | /** Python {@code NotImplemented} object. */ 27 | static final PyObject NotImplemented = 28 | new Singleton("NotImplemented") {}; 29 | } 30 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/PyBaseObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** The Python {@code object} object. */ 4 | class PyBaseObject implements PyObject { 5 | 6 | static PyType TYPE = new PyType("object", null, PyBaseObject.class); 7 | 8 | @Override 9 | public PyType getType() { return TYPE; } 10 | 11 | PyBaseObject() { } 12 | 13 | @Override 14 | public String toString() { return "<'"+TYPE.name + "' object>"; } 15 | 16 | // slot functions ------------------------------------------------- 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/PyBool.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** The Python {@code bool} object. */ 6 | class PyBool extends PyLong { 7 | 8 | /** The type of Python object this class implements. */ 9 | static final PyType TYPE = 10 | new PyType("bool", PyLong.TYPE, PyBool.class); 11 | 12 | @Override 13 | public PyType getType() { return TYPE; } 14 | 15 | /** Python {@code False} object. */ 16 | static final PyBool False = new PyBool(false); 17 | 18 | /** Python {@code True} object. */ 19 | static final PyBool True = new PyBool(true); 20 | 21 | // Private so we can guarantee the doubleton. :) 22 | private PyBool(boolean value) { 23 | super(value ? BigInteger.ONE : BigInteger.ZERO); 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return asSize() == 0 ? "False" : "True"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/PyBytes.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** The Python {@code bytes} object. */ 4 | class PyBytes implements PyObject { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = new PyType("bytes", PyType.class); 8 | 9 | @Override 10 | public PyType getType() { return TYPE; } 11 | final byte[] value; 12 | 13 | PyBytes(byte[] value) { 14 | this.value = new byte[value.length]; 15 | System.arraycopy(value, 0, this.value, 0, value.length); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/PyDictionary.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * The Python {@code dict} object. The Java API is provided directly by 7 | * the base class implementing {@code Map}, while the Python API has 8 | * been implemented on top of the Java one. 9 | */ 10 | class PyDictionary extends HashMap 11 | implements PyObject { 12 | 13 | /** The type of Python object this class implements. */ 14 | static final PyType TYPE = new PyType("dict", PyDictionary.class); 15 | 16 | @Override 17 | public PyType getType() { return TYPE; } 18 | } 19 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/PyException.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** The Python {@code Exception} exception. */ 4 | class PyException extends BaseException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("Exception", PyException.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected PyException(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public PyException(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/PyObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** All Python object implementations implement this interface. */ 4 | interface PyObject { 5 | 6 | /** 7 | * The Python {@code type} of this object. 8 | * 9 | * @return {@code type} of this object 10 | */ 11 | PyType getType(); 12 | } 13 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/PyObjectUtil.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** Miscellaneous static helpers common to built-in objects. */ 4 | class PyObjectUtil { 5 | 6 | /** Helper to create an exception for internal type error. 7 | * 8 | * @param v mismatching object 9 | * @param expected type expected 10 | * @return exception to throw 11 | */ 12 | static InterpreterError typeMismatch(PyObject v, PyType expected) { 13 | String fmt = "'%s' argument to slot where '%s' expected"; 14 | return new InterpreterError(fmt, v.getType().name, 15 | expected.name); 16 | } 17 | 18 | /** 19 | * Convert comparison result (int) to rich comparison result. 20 | * Typically, {@code u} is the result of 21 | * {@link Comparable#compareTo(Object)}. 22 | * 23 | * @param u comparison result 24 | * @param op kind of rich comparison requested 25 | * @return rich comparison result (Python {@code bool}) 26 | */ 27 | static PyObject richCompareHelper(int u, Comparison op) { 28 | boolean r = false; 29 | switch (op) { 30 | case LE: r = u <= 0; break; 31 | case LT: r = u < 0; break; 32 | case EQ: r = u == 0; break; 33 | case NE: r = u != 0; break; 34 | case GE: r = u >= 0; break; 35 | case GT: r = u > 0; break; 36 | default: // pass 37 | } 38 | return r ? PyBool.True : PyBool.False; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/SystemError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** The Python {@code SystemError} exception. */ 4 | class SystemError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("SystemError", SystemError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected SystemError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public SystemError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/ThreadState.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** 4 | * Represents a platform thread (that is, a Java {@code Thread}) 5 | * internally to the interpreter. 6 | */ 7 | // Used here only to represent the stack of frames. 8 | class ThreadState { 9 | 10 | /** The top frame of the call stack. */ 11 | PyFrame frame = null; 12 | /** 13 | * The Java {@code Thread} where this {@code ThreadState} was 14 | * created 15 | */ 16 | final Thread thread; 17 | 18 | // Missing: exception support (main. generators and co-routines). 19 | // Missing: hooks for _threadmodule (join, resources, etc.). 20 | PyFrame swap(PyFrame frame) { 21 | PyFrame prevFrame = this.frame; 22 | this.frame = frame; 23 | return prevFrame; 24 | } 25 | 26 | ThreadState() { this.thread = Thread.currentThread(); } 27 | } 28 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo2/TypeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo2; 2 | 3 | /** The Python {@code TypeError} exception. */ 4 | class TypeError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = new PyType("TypeError", TypeError.class); 8 | 9 | /** 10 | * Constructor for sub-class use specifying {@link #type}. 11 | * 12 | * @param type object being constructed 13 | * @param msg a Java format string for the message 14 | * @param args to insert in the format string 15 | */ 16 | protected TypeError(PyType type, String msg, Object... args) { 17 | super(type, msg, args); 18 | } 19 | 20 | /** 21 | * Constructor specifying a message. 22 | * 23 | * @param msg a Java format string for the message 24 | * @param args to insert in the format string 25 | */ 26 | public TypeError(String msg, Object... args) { 27 | this(TYPE, msg, args); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/AttributeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code AttributeError} exception. */ 4 | class AttributeError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("AttributeError", AttributeError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected AttributeError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public AttributeError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/BaseException.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code BaseException} exception. */ 4 | class BaseException extends RuntimeException implements PyObject { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("BaseException", BaseException.class); 9 | private final PyType type; 10 | 11 | @Override 12 | public PyType getType() { return type; } 13 | 14 | /** 15 | * Constructor for sub-class use specifying {@link #type}. 16 | * 17 | * @param type object being constructed 18 | * @param msg a Java format string for the message 19 | * @param args to insert in the format string 20 | */ 21 | protected BaseException(PyType type, String msg, Object... args) { 22 | super(String.format(msg, args)); 23 | this.type = type; 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public BaseException(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/ClassShorthand.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | import uk.co.farowl.vsj2.evo3.Slot.Self; 4 | 5 | /** Some shorthands used to construct method signatures, etc.. */ 6 | interface ClassShorthand { 7 | 8 | static final Class O = PyObject.class; 9 | static final Class U = PyUnicode.class; 10 | static final Class S = Self.class; 11 | static final Class I = int.class; 12 | static final Class B = boolean.class; 13 | static final Class T = PyType.class; 14 | static final Class V = void.class; 15 | static final Class CMP = Comparison.class; 16 | static final Class TUPLE = PyTuple.class; 17 | static final Class DICT = PyDict.class; 18 | static final Class OA = PyObject[].class; 19 | } -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/DeprecationWarning.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code DeprecationWarning} exception. */ 4 | class DeprecationWarning extends Warning { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("DeprecationWarning", DeprecationWarning.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected DeprecationWarning(PyType type, String msg, 18 | Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor for sub-class use specifying {@link #type}. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public DeprecationWarning(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/Exposed.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.ElementType.PARAMETER; 5 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 6 | 7 | import java.lang.annotation.Documented; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | interface Exposed { 12 | 13 | @Documented 14 | @Retention(RUNTIME) 15 | @Target(METHOD) 16 | @interface Function {} 17 | 18 | @Documented 19 | @Retention(RUNTIME) 20 | @Target(METHOD) 21 | @interface DocString { 22 | String value(); 23 | } 24 | 25 | @Documented 26 | @Retention(RUNTIME) 27 | @Target(PARAMETER) 28 | @interface Args {} 29 | } 30 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/ID.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** 4 | * Constants for names used frequently in the runtime. These may be 5 | * supplied as keys in a dictionary look-up. Every constant is textually 6 | * equal to its own name. 7 | */ 8 | // This file could easily be generated by a script (but wasn't). 9 | class ID { 10 | 11 | static final PyUnicode __build_class__ = Py.str("__build_class__"); 12 | static final PyUnicode __builtins__ = Py.str("__builtins__"); 13 | static final PyUnicode __mro_entries__ = Py.str("__mro_entries__"); 14 | static final PyUnicode __name__ = Py.str("__name__"); 15 | } 16 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/IndexError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code IndexError} exception. */ 4 | class IndexError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("IndexError", IndexError.class); 9 | 10 | /** Constructor for sub-class use specifying {@link #type}. 11 | * @param type object being constructed 12 | * @param msg a Java format string for the message 13 | * @param args to insert in the format string 14 | */protected IndexError(PyType type, String msg, Object... args) { 15 | super(type, msg, args); 16 | } 17 | 18 | /** Constructor specifying a message. 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */public IndexError(String msg, Object... args) { 22 | this(TYPE, msg, args); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/InterpreterError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** 4 | * Internal error thrown when the Python implementation cannot be relied 5 | * on to work. A Python exception (a {@code PyObject} that might be 6 | * caught in Python code) is not then appropriate. Typically thrown 7 | * during initialisation or for irrecoverable internal errors. 8 | */ 9 | class InterpreterError extends RuntimeException { 10 | 11 | /** 12 | * Constructor specifying a message. 13 | * 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected InterpreterError(String msg, Object... args) { 18 | super(String.format(msg, args)); 19 | } 20 | 21 | /** 22 | * Constructor specifying a cause and a message. 23 | * 24 | * @param cause a Java exception behind the interpreter error 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | protected InterpreterError(Throwable cause, String msg, 29 | Object... args) { 30 | super(String.format(msg, args), cause); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/KeyError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code KeyError} exception. */ 4 | class KeyError extends LookupError { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = new PyType("KeyError", KeyError.class); 8 | 9 | final PyObject key; 10 | 11 | protected KeyError(PyObject key, PyType type, String msg, 12 | Object... args) { 13 | super(type, msg, args); 14 | this.key = key; 15 | } 16 | 17 | public KeyError(PyObject key, String msg, Object... args) { 18 | this(key, TYPE, msg, key.toString(), args); 19 | } 20 | 21 | static class Duplicate extends KeyError { 22 | public Duplicate(PyObject key) { 23 | super(key, "duplicate key %s", key.toString()); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/LookupError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code LookupError} exception. */ 4 | class LookupError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("LookupError", LookupError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected LookupError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public LookupError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/Mapping.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | 5 | /** Compare CPython {@code abstract.h}: {@code Py_Mapping_*}. */ 6 | class Mapping extends Abstract { 7 | 8 | /** 9 | * Python size of {@code o}, a mapping. 10 | * 11 | * @param o to operate on 12 | * @return derived size 13 | * @throws Throwable from invoked method implementations 14 | */ 15 | static int size(PyObject o) throws Throwable { 16 | // Note that the slot is called sq_length but this method, size. 17 | PyType oType = o.getType(); 18 | 19 | try { 20 | MethodHandle mh = oType.mp_length; 21 | return (int) mh.invokeExact(o); 22 | } catch (Slot.EmptyException e) {} 23 | 24 | if (Slot.mp_length.isDefinedFor(oType)) // ... sq_ or mp_? 25 | // Caller should have tried Abstract.size 26 | throw typeError(NOT_MAPPING, o); 27 | throw typeError(HAS_NO_LEN, o); 28 | } 29 | 30 | private static final String NOT_MAPPING = "%.200s is not a mapping"; 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/NameError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code NameError} exception. */ 4 | class NameError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = new PyType("NameError", NameError.class); 8 | 9 | /** 10 | * Constructor for sub-class use specifying {@link #type}. 11 | * 12 | * @param type object being constructed 13 | * @param msg a Java format string for the message 14 | * @param args to insert in the format string 15 | */ 16 | protected NameError(PyType type, String msg, Object... args) { 17 | super(type, msg, args); 18 | } 19 | 20 | /** 21 | * Constructor specifying a message. 22 | * 23 | * @param msg a Java format string for the message 24 | * @param args to insert in the format string 25 | */ 26 | public NameError(String msg, Object... args) { 27 | this(TYPE, msg, args); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/NotImplementedError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code NotImplementedError} exception. */ 4 | 5 | public class NotImplementedError extends RuntimeError { 6 | 7 | /** The type of Python object this class implements. */ 8 | static final PyType TYPE = new PyType("NotImplementedError", 9 | NotImplementedError.class); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected NotImplementedError(PyType type, String msg, 19 | Object... args) { 20 | super(type, msg, args); 21 | } 22 | 23 | /** 24 | * Constructor specifying a message. 25 | * 26 | * @param msg a Java format string for the message 27 | * @param args to insert in the format string 28 | */ 29 | public NotImplementedError(String msg, Object... args) { 30 | this(TYPE, msg, args); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/OverflowError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code OverflowError} exception. */ 4 | class OverflowError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("OverflowError", OverflowError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected OverflowError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public OverflowError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/PyBaseObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code object} object. */ 4 | class PyBaseObject implements PyObject { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType.OBJECT_TYPE; 8 | 9 | @Override 10 | public PyType getType() { return TYPE; } 11 | 12 | PyBaseObject() {} 13 | 14 | @Override 15 | public String toString() { return "<'" + TYPE.name + "' object>"; } 16 | 17 | // slot functions ------------------------------------------------- 18 | 19 | } 20 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/PyBytes.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code bytes} object. */ 4 | class PyBytes implements PyObject { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = new PyType("bytes", PyBytes.class); 8 | private static final byte[] EMPTY_BYTE_ARRAY = new byte[] {}; 9 | static final PyBytes EMPTY = new PyBytes(EMPTY_BYTE_ARRAY); 10 | 11 | @Override 12 | public PyType getType() { return TYPE; } 13 | final byte[] value; 14 | 15 | PyBytes(byte[] value) { 16 | if (value.length == 0) 17 | this.value = EMPTY_BYTE_ARRAY; 18 | else { 19 | this.value = new byte[value.length]; 20 | System.arraycopy(value, 0, this.value, 0, value.length); 21 | } 22 | } 23 | 24 | PyBytes(int... value) { 25 | int n = value.length; 26 | if (n == 0) 27 | this.value = EMPTY_BYTE_ARRAY; 28 | else { 29 | byte[] b = new byte[n]; 30 | for (int i = 0; i < n; i++) { 31 | b[i] = (byte) (value[i] & 0xff); 32 | } 33 | this.value = b; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/PyCell.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** Holder for objects appearing in the closure of a function. */ 4 | class PyCell implements PyObject { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = new PyType("cell", PyCell.class); 8 | 9 | @Override 10 | public PyType getType() { return TYPE; } 11 | 12 | PyObject obj; 13 | 14 | PyCell(PyObject obj) { this.obj = obj; } 15 | 16 | @Override 17 | public String toString() { 18 | return String.format("", obj); 19 | } 20 | static final PyCell[] EMPTY_ARRAY = new PyCell[0]; 21 | } 22 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/PyException.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code Exception} exception. */ 4 | class PyException extends BaseException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("Exception", PyException.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected PyException(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public PyException(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/PyModule.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code module} object. */ 4 | class PyModule implements PyObject { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = new PyType("module", PyModule.class); 8 | 9 | @Override 10 | public PyType getType() { return TYPE; } 11 | 12 | /** Name of this module. **/ 13 | final String name; 14 | 15 | /** Dictionary (globals) of this module. **/ 16 | final PyDict dict = new PyDict(); 17 | 18 | PyModule(String name) { this.name = name; } 19 | 20 | /** 21 | * Initialise the module instance. This is the Java equivalent of 22 | * the module body. The main action will be to add entries to 23 | * {@link #dict}. These become the members (globals) of the module. 24 | */ 25 | void init() {} 26 | 27 | @Override 28 | public String toString() { 29 | return String.format("", name); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/PyObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** All Python object implementations implement this interface. */ 4 | interface PyObject { 5 | 6 | /** 7 | * The Python {@code type} of this object. 8 | * 9 | * @return {@code type} of this object 10 | */ 11 | PyType getType(); 12 | } 13 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/PyObjectUtil.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** Miscellaneous static helpers common to built-in objects. */ 4 | class PyObjectUtil { 5 | 6 | /** 7 | * Convert comparison result (int) to rich comparison result. 8 | * Typically, {@code u} is the result of 9 | * {@link Comparable#compareTo(Object)}. 10 | * 11 | * @param u comparison result 12 | * @param op kind of rich comparison requested 13 | * @return rich comparison result (Python {@code bool}) 14 | */ 15 | static PyObject richCompareHelper(int u, Comparison op) { 16 | boolean r = false; 17 | switch (op) { 18 | case LE: r = u <= 0; break; 19 | case LT: r = u < 0; break; 20 | case EQ: r = u == 0; break; 21 | case NE: r = u != 0; break; 22 | case GE: r = u >= 0; break; 23 | case GT: r = u > 0; break; 24 | default: // pass 25 | } 26 | return r ? PyBool.True : PyBool.False; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/RuntimeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code RuntimeError} exception. */ 4 | public class RuntimeError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("RuntimeError", RuntimeError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected RuntimeError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public RuntimeError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/RuntimeWarning.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code RuntimeWarning} exception. */ 4 | class RuntimeWarning extends Warning { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("RuntimeWarning", RuntimeWarning.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected RuntimeWarning(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor for sub-class use specifying {@link #type}. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public RuntimeWarning(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/SystemError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code SystemError} exception. */ 4 | class SystemError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("SystemError", SystemError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected SystemError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public SystemError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/TypeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code TypeError} exception. */ 4 | class TypeError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = new PyType("TypeError", TypeError.class); 8 | 9 | /** 10 | * Constructor for sub-class use specifying {@link #type}. 11 | * 12 | * @param type object being constructed 13 | * @param msg a Java format string for the message 14 | * @param args to insert in the format string 15 | */ 16 | protected TypeError(PyType type, String msg, Object... args) { 17 | super(type, msg, args); 18 | } 19 | 20 | /** 21 | * Constructor specifying a message. 22 | * 23 | * @param msg a Java format string for the message 24 | * @param args to insert in the format string 25 | */ 26 | public TypeError(String msg, Object... args) { 27 | this(TYPE, msg, args); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/UnboundLocalError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code UnboundLocalError} exception. */ 4 | class UnboundLocalError extends NameError { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("UnboundLocalError", UnboundLocalError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected UnboundLocalError(PyType type, String msg, 18 | Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public UnboundLocalError(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/ValueError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code ValueError} exception. */ 4 | class ValueError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | new PyType("ValueError", ValueError.class); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected ValueError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public ValueError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo3/Warning.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo3; 2 | 3 | /** The Python {@code Warning} exception. */ 4 | class Warning extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = new PyType("Warning", Warning.class); 8 | 9 | /** 10 | * Constructor for sub-class use specifying {@link #type}. 11 | * 12 | * @param type object being constructed 13 | * @param msg a Java format string for the message 14 | * @param args to insert in the format string 15 | */ 16 | protected Warning(PyType type, String msg, Object... args) { 17 | super(type, msg, args); 18 | } 19 | 20 | /** 21 | * Constructor for sub-class use specifying {@link #type}. 22 | * 23 | * @param msg a Java format string for the message 24 | * @param args to insert in the format string 25 | */ 26 | public Warning(String msg, Object... args) { 27 | this(TYPE, msg, args); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/AbstractPyObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** 4 | * Class that may be used as a base for Python objects (but doesn't have 5 | * to be) to supply some universally needed methods and the type. 6 | */ 7 | abstract class AbstractPyObject implements PyObject { 8 | 9 | private PyType type; 10 | 11 | /** 12 | * Constructor specifying the Python type, as returned by 13 | * {@link #getType()}. As this is a base for the implementation of 14 | * all sorts of Python types, it needs to be told which one it is. 15 | * 16 | * @param type actual Python type being created 17 | */ 18 | protected AbstractPyObject(PyType type) { this.type = type; } 19 | 20 | @Override 21 | public PyType getType() { return type; } 22 | 23 | @Override 24 | public String toString() { return Py.defaultToString(this); } 25 | 26 | // slot functions ------------------------------------------------- 27 | /* 28 | * It should be possible to declare special (instance) methods in 29 | * this class to save work in implementation classes of Python 30 | * types. The processing of special methods would treat them as 31 | * defined afresh by each exposed implementation (each class that 32 | * calls PyType.fromSpec()). This may be undesirable where 33 | * sub-classes that are object implementations should instead 34 | * Python-inherit their definition. 35 | */ 36 | } 37 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/AttributeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code AttributeError} exception. */ 4 | class AttributeError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType.fromSpec( 8 | new PyType.Spec("AttributeError", AttributeError.class) 9 | .base(PyException.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected AttributeError(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public AttributeError(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/ClassShorthand.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | import uk.co.farowl.vsj2.evo4.Slot.Cls; 4 | import uk.co.farowl.vsj2.evo4.Slot.Self; 5 | 6 | /** Some shorthands used to construct method signatures, etc.. */ 7 | interface ClassShorthand { 8 | 9 | static final Class O = PyObject.class; 10 | static final Class U = PyUnicode.class; 11 | static final Class S = Self.class; 12 | static final Class C = Cls.class; 13 | static final Class I = int.class; 14 | static final Class B = boolean.class; 15 | static final Class T = PyType.class; 16 | static final Class V = void.class; 17 | static final Class CMP = Comparison.class; 18 | static final Class TUPLE = PyTuple.class; 19 | static final Class DICT = PyDict.class; 20 | static final Class OA = PyObject[].class; 21 | } -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/DeprecationWarning.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code DeprecationWarning} exception. */ 4 | class DeprecationWarning extends Warning { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | PyType.fromSpec(new PyType.Spec("DeprecationWarning", 9 | DeprecationWarning.class).base(Warning.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected DeprecationWarning(PyType type, String msg, 19 | Object... args) { 20 | super(type, msg, args); 21 | } 22 | 23 | /** 24 | * Constructor for sub-class use specifying {@link #type}. 25 | * 26 | * @param msg a Java format string for the message 27 | * @param args to insert in the format string 28 | */ 29 | public DeprecationWarning(String msg, Object... args) { 30 | this(TYPE, msg, args); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/IndexError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code IndexError} exception. */ 4 | class IndexError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType 8 | .fromSpec(new PyType.Spec("IndexError", IndexError.class) 9 | .base(PyException.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected IndexError(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public IndexError(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/InterpreterError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** 4 | * Internal error thrown when the Python implementation cannot be relied 5 | * on to work. A Python exception (a {@code PyObject} that might be 6 | * caught in Python code) is not then appropriate. Typically thrown 7 | * during initialisation or for irrecoverable internal errors. 8 | */ 9 | class InterpreterError extends RuntimeException { 10 | 11 | /** 12 | * Constructor specifying a message. 13 | * 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected InterpreterError(String msg, Object... args) { 18 | super(String.format(msg, args)); 19 | } 20 | 21 | /** 22 | * Constructor specifying a cause and a message. 23 | * 24 | * @param cause a Java exception behind the interpreter error 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | protected InterpreterError(Throwable cause, String msg, 29 | Object... args) { 30 | super(String.format(msg, args), cause); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/KeyError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code KeyError} exception. */ 4 | class KeyError extends LookupError { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | PyType.fromSpec(new PyType.Spec("KeyError", KeyError.class) 9 | .base(LookupError.TYPE)); 10 | 11 | final PyObject key; 12 | 13 | protected KeyError(PyObject key, PyType type, String msg, 14 | Object... args) { 15 | super(type, msg, args); 16 | this.key = key; 17 | } 18 | 19 | public KeyError(PyObject key, String msg, Object... args) { 20 | this(key, TYPE, msg, key.toString(), args); 21 | } 22 | 23 | static class Duplicate extends KeyError { 24 | 25 | public Duplicate(PyObject key) { 26 | super(key, "duplicate key %s", key.toString()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/LookupError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code LookupError} exception. */ 4 | class LookupError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType 8 | .fromSpec(new PyType.Spec("LookupError", LookupError.class) 9 | .base(PyException.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected LookupError(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public LookupError(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/MissingFeature.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** 4 | * Thrown when we reach a combination of circumstances in the 5 | * interpreter that may arise from legitimate use, but we aren't ready 6 | * to implement it. 7 | *

8 | * What does the reference implementation do at this point? 9 | */ 10 | class MissingFeature extends InterpreterError { 11 | 12 | /** 13 | * Constructor specifying a message. 14 | * 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected MissingFeature(String msg, Object... args) { 19 | super(String.format(msg, args)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/NameError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code NameError} exception. */ 4 | class NameError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType 8 | .fromSpec(new PyType.Spec("NameError", NameError.class) 9 | .base(PyException.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected NameError(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public NameError(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/NotImplementedError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code NotImplementedError} exception. */ 4 | class NotImplementedError extends RuntimeError { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | PyType.fromSpec(new PyType.Spec("NotImplementedError", 9 | NotImplementedError.class).base(RuntimeError.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected NotImplementedError(PyType type, String msg, 19 | Object... args) { 20 | super(type, msg, args); 21 | } 22 | 23 | /** 24 | * Constructor specifying a message. 25 | * 26 | * @param msg a Java format string for the message 27 | * @param args to insert in the format string 28 | */ 29 | public NotImplementedError(String msg, Object... args) { 30 | this(TYPE, msg, args); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/OverflowError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code OverflowError} exception. */ 4 | class OverflowError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType.fromSpec( 8 | new PyType.Spec("OverflowError", OverflowError.class)); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected OverflowError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public OverflowError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/PyCell.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | import uk.co.farowl.vsj2.evo4.PyType.Spec; 6 | 7 | /** Holder for objects appearing in the closure of a function. */ 8 | class PyCell implements PyObject { 9 | 10 | /** The type of Python object this class implements. */ 11 | static final PyType TYPE = PyType.fromSpec( 12 | new Spec("cell", PyCell.class, MethodHandles.lookup())); 13 | 14 | PyObject obj; 15 | 16 | PyCell(PyObject obj) { this.obj = obj; } 17 | 18 | static final PyCell[] EMPTY_ARRAY = new PyCell[0]; 19 | 20 | // Type admits no subclasses. 21 | @Override 22 | public PyType getType() { return TYPE; } 23 | 24 | @Override 25 | public String toString() { return Py.defaultToString(this); } 26 | 27 | // slot functions ------------------------------------------------- 28 | 29 | @SuppressWarnings("unused") 30 | private PyObject __repr__() { 31 | return Py.str(String.format("", obj)); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/PyException.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code Exception} exception. */ 4 | class PyException extends BaseException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType 8 | .fromSpec(new PyType.Spec("Exception", PyException.class) 9 | .base(BaseException.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected PyException(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public PyException(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/PyJavaFunction.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** 4 | * A specialisation of the Python {@code builtin_function_or_method} 5 | * object, used to represent a function defined in Java. 6 | */ 7 | class PyJavaFunction extends PyJavaCallable { 8 | 9 | // Compare CPython PyCFunction_NewEx in methodobject.c 10 | PyJavaFunction(MethodDef methodDef, PyUnicode moduleName) { 11 | super(methodDef, null, methodDef.getVectorHandle(), moduleName); 12 | } 13 | 14 | PyJavaFunction(MethodDef methodDef) { this(methodDef, null); } 15 | 16 | @Override 17 | public PyObject __call__(PyTuple args, PyDict kwargs) 18 | throws Throwable { 19 | try { 20 | return (PyObject) opCall.invokeExact(args, kwargs); 21 | } catch (MethodDef.BadCallException bce) { 22 | // After the BCE, check() should always throw. 23 | methodDef.check(args, kwargs); 24 | // It didn't :( so this is an internal error 25 | throw new InterpreterError(bce, 26 | "Unexplained BadCallException in __call__"); 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/PyJavaMethod.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** 4 | * A specialisation of the Python {@code builtin_function_or_method} 5 | * object, used to represent a method defined in Java and bound to a 6 | * particular target. 7 | */ 8 | class PyJavaMethod extends PyJavaCallable { 9 | 10 | // Compare CPython PyCFunction_NewEx in methodobject.c 11 | PyJavaMethod(MethodDef methodDef, PyObject self) { 12 | super(methodDef, self, methodDef.getBoundHandle(self), null); 13 | } 14 | 15 | @Override 16 | public PyObject __call__(PyTuple args, PyDict kwargs) 17 | throws Throwable { 18 | // Prepend self to arguments 19 | int n = args.size(); 20 | if (n == 0) 21 | args = Py.tuple(self); 22 | else { 23 | PyObject[] a = new PyObject[n + 1]; 24 | a[0] = self; 25 | System.arraycopy(args.value, 0, a, 1, n); 26 | args = Py.tuple(a); 27 | } 28 | // Make classic call 29 | try { 30 | return (PyObject) opCall.invokeExact(args, kwargs); 31 | } catch (MethodDef.BadCallException bce) { 32 | // After the BCE, check() should always throw. 33 | methodDef.check(args, kwargs); 34 | // It didn't :( so this is an internal error 35 | throw new InterpreterError(bce, 36 | "Unexplained BadCallException in __call__"); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/PyObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** All Python object implementations implement this interface. */ 4 | public interface PyObject { 5 | 6 | /** 7 | * The Python {@code type} of this object. 8 | * 9 | * @return {@code type} of this object 10 | */ 11 | PyType getType(); 12 | } 13 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/PyObjectDict.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Python objects that have instance dictionaries implement this 7 | * interface. 8 | */ 9 | public interface PyObjectDict extends PyObject { 10 | 11 | /** 12 | * The dictionary of the instance, (not necessarily a Python 13 | * {@code dict} or writable. If the returned {@code Map} is not 14 | * writable, it should throw a Java 15 | * {@code UnsupportedOperationException} on attempts to modify it. 16 | * 17 | * @implSpec A class that implements {@code PyObjectDict} should 18 | * always return a mapping, which may be 19 | * {@code Collections.emptyMap()} if the instance 20 | * dictionary is intended to be permanently empty. 21 | * @return a mapping to treat like a dictionary (not {@code null}). 22 | */ 23 | Map getDict(); 24 | } 25 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/PySequence.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** 4 | * Sequences exhibit certain common behaviours and utilities that 5 | * implement them need to call back into the object by this interface. 6 | * This interface cannot be used as a marker for objects that implement 7 | * the sequence protocol because it is perfectly possible for a 8 | * user-defined Python type to do so without its Java implementation 9 | * implementing {@code PySequence}. A proxy class could be created that 10 | * holds such an object and does implement {@code PySequence}. 11 | */ 12 | interface PySequence extends PyObject { 13 | 14 | // /** Get one element from the sequence. */ 15 | // PyObject getItem(int i); 16 | 17 | // /** Set one element from the sequence (if mutable). */ 18 | // void setItem(int i, PyObject v); 19 | 20 | // /** 21 | // * Return a sequence of the target type, concatenating this with a 22 | // * sequence of possibly different type. 23 | // */ 24 | // S concat(PyObject other); 25 | 26 | /** 27 | * Return a sequence of the target type, by repeatedly concatenating 28 | * {@code n} copies of the present value. 29 | * 30 | * @param n number of repeats 31 | * @return repeating sequence 32 | */ 33 | // S repeat(int n); 34 | PySequence repeat(int n); 35 | } 36 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/RecursionError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code RecursionError} exception. */ 4 | class RecursionError extends RuntimeError { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType.fromSpec( 8 | new PyType.Spec("RecursionError", RecursionError.class) 9 | .base(RuntimeError.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected RecursionError(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public RecursionError(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/RuntimeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code RuntimeError} exception. */ 4 | class RuntimeError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType.fromSpec( 8 | new PyType.Spec("RuntimeError", RuntimeError.class) 9 | .base(PyException.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected RuntimeError(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public RuntimeError(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/RuntimeWarning.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code RuntimeWarning} exception. */ 4 | class RuntimeWarning extends Warning { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType.fromSpec( 8 | new PyType.Spec("RuntimeWarning", RuntimeWarning.class) 9 | .base(Warning.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected RuntimeWarning(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor for sub-class use specifying {@link #type}. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public RuntimeWarning(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/SystemError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code SystemError} exception. */ 4 | class SystemError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType.fromSpec( 8 | new PyType.Spec("SystemError", SystemError.class)); 9 | 10 | /** 11 | * Constructor for sub-class use specifying {@link #type}. 12 | * 13 | * @param type object being constructed 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | protected SystemError(PyType type, String msg, Object... args) { 18 | super(type, msg, args); 19 | } 20 | 21 | /** 22 | * Constructor specifying a message. 23 | * 24 | * @param msg a Java format string for the message 25 | * @param args to insert in the format string 26 | */ 27 | public SystemError(String msg, Object... args) { 28 | this(TYPE, msg, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/TypeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code TypeError} exception. */ 4 | class TypeError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType 8 | .fromSpec(new PyType.Spec("TypeError", TypeError.class) 9 | .base(PyException.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected TypeError(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public TypeError(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/UnboundLocalError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code UnboundLocalError} exception. */ 4 | class UnboundLocalError extends NameError { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | PyType.fromSpec(new PyType.Spec("UnboundLocalError", 9 | UnboundLocalError.class).base(NameError.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected UnboundLocalError(PyType type, String msg, 19 | Object... args) { 20 | super(type, msg, args); 21 | } 22 | 23 | /** 24 | * Constructor specifying a message. 25 | * 26 | * @param msg a Java format string for the message 27 | * @param args to insert in the format string 28 | */ 29 | public UnboundLocalError(String msg, Object... args) { 30 | this(TYPE, msg, args); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/ValueError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code ValueError} exception. */ 4 | class ValueError extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = PyType 8 | .fromSpec(new PyType.Spec("ValueError", ValueError.class) 9 | .base(PyException.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected ValueError(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor specifying a message. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public ValueError(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/java/uk/co/farowl/vsj2/evo4/Warning.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2.evo4; 2 | 3 | /** The Python {@code Warning} exception. */ 4 | class Warning extends PyException { 5 | 6 | /** The type of Python object this class implements. */ 7 | static final PyType TYPE = 8 | PyType.fromSpec(new PyType.Spec("Warning", Warning.class) 9 | .base(PyException.TYPE)); 10 | 11 | /** 12 | * Constructor for sub-class use specifying {@link #type}. 13 | * 14 | * @param type object being constructed 15 | * @param msg a Java format string for the message 16 | * @param args to insert in the format string 17 | */ 18 | protected Warning(PyType type, String msg, Object... args) { 19 | super(type, msg, args); 20 | } 21 | 22 | /** 23 | * Constructor for sub-class use specifying {@link #type}. 24 | * 25 | * @param msg a Java format string for the message 26 | * @param args to insert in the format string 27 | */ 28 | public Warning(String msg, Object... args) { 29 | this(TYPE, msg, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rt2/src/main/javadoc/project-styles.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /* Styles supplementary to the standard Javadoc doclet. */ 4 | 5 | /* Table layout for framed data. */ 6 | table.framed-layout { 7 | border: 1px solid black; 8 | border-collapse: collapse; 9 | } 10 | 11 | table.framed-layout th, table.framed-layout td { 12 | border: 1px solid black; 13 | text-align: center; 14 | min-width: 2em; 15 | } 16 | 17 | table.framed-layout td.label { 18 | text-align: left; 19 | font-weight: bold; 20 | } -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeff5/very-slow-jython/c778bd7aac1136f01ad32efb36f51885cc35f194/rt2/src/test/python/vsj2/__init__.py -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code1.ex.py: -------------------------------------------------------------------------------- 1 | # Examples for PyByteCode1.java 2 | 3 | # This looks like a Python module but it isn't. These are code fragments that 4 | # the module vsj2.exparser will break apart to generate test material. 5 | 6 | # load_store_name: 7 | a, b = 1, 2 8 | # ? a, b, c 9 | a = b 10 | b = 4 11 | c = 6 12 | 13 | # load_store_name_ex: 14 | a, b = "Hello", "World" 15 | # ? a, b, c 16 | a = b 17 | b = 2.0 18 | c = 'begins!' 19 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code1.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | import os 4 | from contextlib import closing 5 | from vsj2.exparser import LineToken, Lines 6 | from vsj2.srcgen import PyObjectTestEmitter, PyObjectEmitter 7 | 8 | 9 | # ------------------------- Main Program ------------------------- 10 | 11 | 12 | def generate(test, writer=None): 13 | """Generate Java code to test one program example""" 14 | # Strip blank lines from end of example 15 | body = test.body 16 | while len(body[-1]) == 0: 17 | body.pop(-1) 18 | # Generate the text of a test based on this example 19 | with closing(PyObjectTestEmitter(test, writer)) as e: 20 | e.emit_test_material() 21 | e.emit_test_cases() 22 | e.emit_line("") 23 | 24 | 25 | def main(examples): 26 | print(" // from {}\n".format(os.path.basename(examples))) 27 | # Open the input and wrap in a parser 28 | with closing(Lines(open(examples))) as lines: 29 | # Anything before the first heading is not part of any test 30 | lines.parse_preamble() 31 | # Each test in the file produces a code object and one or more tests 32 | while lines.kind() != LineToken.EOF: 33 | test = lines.parse_test() 34 | generate(test, PyObjectEmitter()) 35 | 36 | 37 | if __name__ == "__main__": 38 | # Derive the examples file name from this one 39 | print(" // Code generated by {}".format(os.path.basename(__file__))) 40 | main(".ex".join(os.path.splitext(__file__))) 41 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code2.ex.py: -------------------------------------------------------------------------------- 1 | # Examples for PyByteCode2.java 2 | 3 | # This looks like a Python module but it isn't. These are code fragments that 4 | # the module vsj2.exparser will break apart to generate test material. 5 | 6 | # load_store_name: 7 | a, b = 1, 2 8 | # ? a, b, c 9 | a = b 10 | b = 4 11 | c = 6 12 | 13 | # negate: 14 | a, b = 6, -7 15 | a, b = 6., -7. 16 | # ? a, b 17 | a, b = -a, -b 18 | 19 | # binary: 20 | a, b = 7, 6 21 | a, b = 7., 6. 22 | a, b = 7., 6 23 | a, b = 7, 6. 24 | # ? sum, diff, prod 25 | sum = a + b 26 | diff = a - b 27 | prod = a * b 28 | 29 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code2_evo2.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code2_evo3.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code2_evo4.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code3_evo2.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code3_evo3.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code3_evo4.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code4.ex.py: -------------------------------------------------------------------------------- 1 | # Examples for PyByteCode4.java 2 | 3 | # This looks like a Python module but it isn't. These are code fragments that 4 | # the module vsj2.exparser will break apart to generate test material. 5 | 6 | # boolean_and: 7 | u = False 8 | u = True 9 | u = 15 10 | # ? a, b, c, d 11 | a = u & False 12 | b = u & True 13 | c = 42 & u 14 | d = 43 & u 15 | 16 | # boolean_or: 17 | u = False 18 | u = True 19 | u = 15 20 | # ? a, b, c, d 21 | a = u | False 22 | b = u | True 23 | c = 42 | u 24 | d = 43 | u 25 | 26 | # boolean_xor: 27 | u = False 28 | u = True 29 | u = 15 30 | # ? a, b, c, d 31 | a = u ^ False 32 | b = u ^ True 33 | c = 42 ^ u 34 | d = 43 ^ u 35 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code4_evo3.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code4_evo4.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code5_evo3.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code5_evo4.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2/src/test/python/vsj2/py_byte_code6_evo4.py: -------------------------------------------------------------------------------- 1 | # Generate examples for the bytecode interpreter 2 | 3 | from vsj2.testgen import main 4 | 5 | main(__file__) 6 | -------------------------------------------------------------------------------- /rt2bm/src/main/java/uk/co/farowl/vsj2bm/evo4/MainLoop.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj2bm.evo4; 2 | 3 | import uk.co.farowl.vsj2.evo4.Number; 4 | import uk.co.farowl.vsj2.evo4.Py; 5 | import uk.co.farowl.vsj2.evo4.PyObject; 6 | 7 | /** 8 | * A program that calls a selected method in the benchmark to explore in 9 | * isolation the way in which it gets optimised by the JVM. (See 10 | * {@code rt2bm.gradle} task {@code mainloop}. 11 | */ 12 | public class MainLoop { 13 | 14 | public static void main(String[] args) throws Throwable { 15 | PyFloatBinary test = new PyFloatBinary(); 16 | double sum = 0.0; 17 | for (int i = 0; i < 10_000; i++) { 18 | test.fvo = Py.val(i * 2.001); 19 | test.fwo = Py.val(i * 1.001); 20 | PyObject r = test.quartic(); 21 | //System.out.println(String.format("\nPartial = %s\n", r)); 22 | sum += Number.toFloat(r).doubleValue(); 23 | } 24 | System.out.println(String.format("Sum = %14.3e", sum)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /rt3/src/main/dynamicAPI/AbstractProxy.dynapi: -------------------------------------------------------------------------------- 1 | # Name the methods to generate here 2 | 3 | package uk.co.farowl.vsj3.evo1 4 | 5 | class AbstractProxy 6 | 7 | unary negative 8 | binary add 9 | binary subtract 10 | binary multiply 11 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/AbstractPyObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | /** 4 | * Class that may be used as a base for Python objects (but doesn't have 5 | * to be) to supply some universally needed methods and the type. 6 | */ 7 | abstract class AbstractPyObject implements CraftedPyObject { 8 | 9 | private PyType type; 10 | 11 | /** 12 | * Constructor specifying the Python type, as returned by 13 | * {@link #getType()}. As this is a base for the implementation of 14 | * all sorts of Python types, it needs to be told which one it is. 15 | * 16 | * @param type actual Python type being created 17 | */ 18 | protected AbstractPyObject(PyType type) { 19 | this.type = type; 20 | } 21 | 22 | @Override 23 | public PyType getType() { return type; } 24 | 25 | @Override 26 | public String toString() { 27 | return Py.defaultToString(this); 28 | } 29 | 30 | // slot functions ------------------------------------------------- 31 | /* 32 | * It should be possible to declare special (instance) methods in 33 | * this class to save work in implementation classes of Python 34 | * types. The processing of special methods would treat them as 35 | * defined afresh by each exposed implementation (each class that 36 | * calls PyType.fromSpec()). This may be undesirable where 37 | * sub-classes that are object implementations should instead 38 | * Python-inherit their definition. 39 | */ 40 | } 41 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/ArithmeticError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code ArithmeticError} exception. */ 6 | public class ArithmeticError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code ArithmeticError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("ArithmeticError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected ArithmeticError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public ArithmeticError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/AttributeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code AttributeError} exception. */ 6 | public class AttributeError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code AttributeError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("AttributeError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected AttributeError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public AttributeError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/ClassShorthand.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | /** 4 | * Some shorthands used to construct method signatures, 5 | * {@code MethodType}s, etc.. 6 | */ 7 | interface ClassShorthand { 8 | /** Shorthand for {@code Object.class}. */ 9 | static final Class O = Object.class; 10 | /** Shorthand for {@code Class.class}. */ 11 | static final Class C = Class.class; 12 | /** Shorthand for {@code String.class}. */ 13 | static final Class S = String.class; 14 | /** Shorthand for {@code int.class}. */ 15 | static final Class I = int.class; 16 | /** Shorthand for {@code boolean.class}. */ 17 | static final Class B = boolean.class; 18 | /** Shorthand for {@code PyType.class}. */ 19 | static final Class T = PyType.class; 20 | /** Shorthand for {@code void.class}. */ 21 | static final Class V = void.class; 22 | /** Shorthand for {@code Comparison.class}. */ 23 | static final Class CMP = Comparison.class; 24 | /** Shorthand for {@code PyTuple.class}. */ 25 | static final Class TUPLE = PyTuple.class; 26 | /** Shorthand for {@code PyDict.class}. */ 27 | static final Class DICT = PyDict.class; 28 | /** Shorthand for {@code Object[].class}. */ 29 | static final Class OA = Object[].class; 30 | /** Shorthand for {@code String[].class}. */ 31 | static final Class SA = String[].class; 32 | } 33 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/CraftedPyObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | /** 4 | * All Python object implementations that we write ourselves implement 5 | * this interface. 6 | */ 7 | public interface CraftedPyObject { 8 | /** 9 | * The Python {@code type} of this object. 10 | * 11 | * @return {@code type} of this object 12 | */ 13 | PyType getType(); 14 | } 15 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/DeprecationWarning.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code DeprecationWarning} exception. */ 6 | public class DeprecationWarning extends Warning { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** 10 | * The type object of Python {@code DeprecationWarning} exceptions. 11 | */ 12 | @SuppressWarnings("hiding") 13 | public static final PyType TYPE = 14 | PyType.fromSpec(new PyType.Spec("DeprecationWarning", 15 | MethodHandles.lookup()).base(Warning.TYPE)); 16 | 17 | /** 18 | * Constructor for sub-class use specifying {@link #type}. 19 | * 20 | * @param type object being constructed 21 | * @param msg a Java format string for the message 22 | * @param args to insert in the format string 23 | */ 24 | protected DeprecationWarning(PyType type, String msg, 25 | Object... args) { 26 | super(type, msg, args); 27 | } 28 | 29 | /** 30 | * Constructor for sub-class use specifying {@link #type}. 31 | * 32 | * @param msg a Java format string for the message 33 | * @param args to insert in the format string 34 | */ 35 | public DeprecationWarning(String msg, Object... args) { 36 | this(TYPE, msg, args); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/DerivedPyObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | /** 4 | * {@code DerivedPyObject} is a marker interface that identifies an 5 | * object that is an instance of a class defined in Python. 6 | */ 7 | interface DerivedPyObject extends CraftedPyObject {} 8 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/DictPyObject.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Python objects that have instance dictionaries implement this 7 | * interface. 8 | */ 9 | public interface DictPyObject extends CraftedPyObject { 10 | /** 11 | * The dictionary of the instance, (not necessarily a Python 12 | * {@code dict} or writable. If the returned {@code Map} is not 13 | * writable, it should throw a Java 14 | * {@code UnsupportedOperationException} on attempts to modify it. 15 | * 16 | * @implSpec A class that implements {@code PyObjectDict} should 17 | * always return a mapping, which may be 18 | * {@code Collections.emptyMap()} if the instance dictionary is 19 | * intended to be permanently empty. 20 | * @return a mapping to treat like a dictionary (not {@code null}). 21 | */ 22 | Map getDict(); 23 | } 24 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/EOFError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code EOFError} exception. */ 6 | public class EOFError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code EOFError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("EOFError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected EOFError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public EOFError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/IndexError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code IndexError} exception. */ 6 | public class IndexError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code IndexError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("IndexError", MethodHandles.lookup()) 13 | .base(LookupError.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected IndexError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public IndexError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/LookupError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code LookupError} exception. */ 6 | public class LookupError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code LookupError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("LookupError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected LookupError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public LookupError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/MemoryError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code MemoryError} exception. */ 6 | public class MemoryError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code MemoryError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("MemoryError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected MemoryError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public MemoryError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/NameError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code NameError} exception. */ 6 | public class NameError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code NameError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("NameError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected NameError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public NameError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/OverflowError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code OverflowError} exception. */ 6 | public class OverflowError extends ArithmeticError { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type of Python object this class implements. */ 10 | static final PyType TYPE = PyType.fromSpec( 11 | new PyType.Spec("OverflowError", MethodHandles.lookup())); 12 | 13 | /** 14 | * Constructor for sub-class use specifying {@link #type}. 15 | * 16 | * @param type object being constructed 17 | * @param msg a Java format string for the message 18 | * @param args to insert in the format string 19 | */ 20 | protected OverflowError(PyType type, String msg, Object... args) { 21 | super(type, msg, args); 22 | } 23 | 24 | /** 25 | * Constructor specifying a message. 26 | * 27 | * @param msg a Java format string for the message 28 | * @param args to insert in the format string 29 | */ 30 | public OverflowError(String msg, Object... args) { 31 | this(TYPE, msg, args); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/PyEllipsis.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2023 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj3.evo1; 4 | 5 | import java.lang.invoke.MethodHandles; 6 | 7 | /** The Python {@code ...} (ellipsis) object. */ 8 | public final class PyEllipsis extends Singleton { 9 | 10 | /** The Python type of {@code Ellipsis}. */ 11 | public static final PyType TYPE = PyType.fromSpec( // 12 | new PyType.Spec("ellipsis", MethodHandles.lookup()) 13 | .flagNot(PyType.Flag.BASETYPE)); 14 | 15 | /** The only instance, published as {@link Py#Ellipsis}. */ 16 | static final PyEllipsis INSTANCE = new PyEllipsis(); 17 | 18 | private PyEllipsis() { super(TYPE, "Ellipsis"); } 19 | } 20 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/PyException.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code Exception} exception. */ 6 | public class PyException extends BaseException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code Exception} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("Exception", MethodHandles.lookup()) 13 | .base(BaseException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected PyException(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public PyException(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/PyNone.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2023 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj3.evo1; 4 | 5 | import java.lang.invoke.MethodHandles; 6 | 7 | /** The Python {@code None} object. */ 8 | public final class PyNone extends Singleton { 9 | 10 | /** The Python type of {@code None}. */ 11 | public static final PyType TYPE = PyType.fromSpec( // 12 | new PyType.Spec("NoneType", MethodHandles.lookup()) 13 | .flagNot(PyType.Flag.BASETYPE)); 14 | 15 | /** The only instance, published as {@link Py#None}. */ 16 | static final PyNone INSTANCE = new PyNone(); 17 | 18 | private PyNone() { super(TYPE, "None"); } 19 | 20 | // Special methods ----------------------------------------------- 21 | 22 | @SuppressWarnings({"static-method", "unused"}) 23 | private boolean __bool__() { return false; } 24 | } 25 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/PyNotImplemented.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2023 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj3.evo1; 4 | 5 | import java.lang.invoke.MethodHandles; 6 | 7 | /** The Python {@code NotImplemented} object. */ 8 | public final class PyNotImplemented extends Singleton { 9 | 10 | /** The Python type of {@code PyNotImplemented}. */ 11 | public static final PyType TYPE = PyType.fromSpec( // 12 | new PyType.Spec("NotImplementedType", 13 | MethodHandles.lookup()) 14 | .flagNot(PyType.Flag.BASETYPE)); 15 | 16 | /** The only instance, published as {@link Py#NotImplemented}. */ 17 | static final PyNotImplemented INSTANCE = new PyNotImplemented(); 18 | 19 | private PyNotImplemented() { super(TYPE, "NotImplemented"); } 20 | } 21 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/RecursionError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code RecursionError} exception. */ 6 | public class RecursionError extends RuntimeError { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code RecursionError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("RecursionError", MethodHandles.lookup()) 13 | .base(RuntimeError.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected RecursionError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public RecursionError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/RuntimeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code RuntimeError} exception. */ 6 | public class RuntimeError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code RuntimeError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("RuntimeError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type of object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected RuntimeError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public RuntimeError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/RuntimeWarning.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code RuntimeWarning} exception. */ 6 | class RuntimeWarning extends Warning { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type of Python object this class implements. */ 10 | static final PyType TYPE = PyType.fromSpec( 11 | new PyType.Spec("RuntimeWarning", MethodHandles.lookup()) 12 | .base(Warning.TYPE)); 13 | 14 | /** 15 | * Constructor for sub-class use specifying {@link #type}. 16 | * 17 | * @param type object being constructed 18 | * @param msg a Java format string for the message 19 | * @param args to insert in the format string 20 | */ 21 | protected RuntimeWarning(PyType type, String msg, Object... args) { 22 | super(type, msg, args); 23 | } 24 | 25 | /** 26 | * Constructor for sub-class use specifying {@link #type}. 27 | * 28 | * @param msg a Java format string for the message 29 | * @param args to insert in the format string 30 | */ 31 | public RuntimeWarning(String msg, Object... args) { 32 | this(TYPE, msg, args); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/ScopeKind.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | /** Exposers are of type or module kind. */ 4 | enum ScopeKind { 5 | 6 | MODULE("$module"), // 7 | TYPE("$self"); 8 | 9 | ScopeKind(String selfName) { 10 | this.selfName = selfName; 11 | } 12 | 13 | /** Name of a "self" parameter in instance methods. */ 14 | String selfName; 15 | } 16 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/Singleton.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2023 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj3.evo1; 4 | 5 | abstract class Singleton implements CraftedPyObject { 6 | 7 | /** The Python type of the object implemented. */ 8 | final PyType type; 9 | 10 | /** 11 | * The name in Python of the object implemented as returned by 12 | * {@code repr()}. 13 | */ 14 | private final String name; 15 | 16 | protected Singleton(PyType type, String name) { 17 | this.name = name; 18 | this.type = type; 19 | } 20 | 21 | protected Object __repr__() { return name; } 22 | 23 | @Override 24 | public String toString() { return name; } 25 | 26 | @Override 27 | public PyType getType() { return type; } 28 | } 29 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/StopIteration.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code StopIteration} exception. */ 6 | public class StopIteration extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type of Python object this class implements. */ 10 | public static final PyType TYPE = PyType.fromSpec( 11 | new PyType.Spec("StopIteration", MethodHandles.lookup()) 12 | .base(PyException.TYPE)); 13 | 14 | /** 15 | * Constructor for sub-class use specifying {@link #type}. 16 | * 17 | * @param type object being constructed 18 | * @param msg a Java format string for the message 19 | * @param args to insert in the format string 20 | */ 21 | protected StopIteration(PyType type, String msg, Object... args) { 22 | super(type, msg, args); 23 | } 24 | 25 | /** 26 | * Constructor specifying a message. 27 | * 28 | * @param msg a Java format string for the message 29 | * @param args to insert in the format string 30 | */ 31 | public StopIteration(String msg, Object... args) { 32 | this(TYPE, msg, args); 33 | } 34 | 35 | /** 36 | * Constructor specifying no arguments. 37 | */ 38 | public StopIteration() { this(TYPE, ""); } 39 | } 40 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/SystemError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code SystemError} exception. */ 6 | public class SystemError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code SystemError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("SystemError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected SystemError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public SystemError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/TypeError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code TypeError} exception. */ 6 | public class TypeError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code TypeError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("TypeError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected TypeError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public TypeError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/UnboundLocalError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code UnboundLocalError} exception. */ 6 | public class UnboundLocalError extends NameError { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** 10 | * The type object of Python {@code UnboundLocalError} exceptions. 11 | */ 12 | @SuppressWarnings("hiding") 13 | public static final PyType TYPE = PyType.fromSpec( 14 | new PyType.Spec("UnboundLocalError", MethodHandles.lookup()) 15 | .base(NameError.TYPE)); 16 | 17 | /** 18 | * Constructor for sub-class use specifying {@link #type}. 19 | * 20 | * @param type object being constructed 21 | * @param msg a Java format string for the message 22 | * @param args to insert in the format string 23 | */ 24 | protected UnboundLocalError(PyType type, String msg, 25 | Object... args) { 26 | super(type, msg, args); 27 | } 28 | 29 | /** 30 | * Constructor specifying a message. 31 | * 32 | * @param msg a Java format string for the message 33 | * @param args to insert in the format string 34 | */ 35 | public UnboundLocalError(String msg, Object... args) { 36 | this(TYPE, msg, args); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/ValueError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code ValueError} exception. */ 6 | public class ValueError extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code ValueError} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType.fromSpec( 12 | new PyType.Spec("ValueError", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected ValueError(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public ValueError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/Warning.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code Warning} exception. */ 6 | public class Warning extends PyException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code Warning} exceptions. */ 10 | @SuppressWarnings("hiding") 11 | public static final PyType TYPE = PyType 12 | .fromSpec(new PyType.Spec("Warning", MethodHandles.lookup()) 13 | .base(PyException.TYPE)); 14 | 15 | /** 16 | * Constructor for sub-class use specifying {@link #type}. 17 | * 18 | * @param type object being constructed 19 | * @param msg a Java format string for the message 20 | * @param args to insert in the format string 21 | */ 22 | protected Warning(PyType type, String msg, Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor for sub-class use specifying {@link #type}. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public Warning(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/ZeroDivisionError.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** The Python {@code ZeroDivisionError} exception. */ 6 | public class ZeroDivisionError extends ArithmeticError { 7 | private static final long serialVersionUID = 1L; 8 | 9 | /** The type object of Python {@code ZeroDivisionError} exceptions. */ 10 | public static final PyType TYPE = PyType.fromSpec( 11 | new PyType.Spec("ZeroDivisionError", MethodHandles.lookup()) 12 | .base(ArithmeticError.TYPE)); 13 | 14 | /** 15 | * Constructor for sub-class use specifying {@link #type}. 16 | * 17 | * @param type object being constructed 18 | * @param msg a Java format string for the message 19 | * @param args to insert in the format string 20 | */ 21 | protected ZeroDivisionError(PyType type, String msg, 22 | Object... args) { 23 | super(type, msg, args); 24 | } 25 | 26 | /** 27 | * Constructor specifying a message. 28 | * 29 | * @param msg a Java format string for the message 30 | * @param args to insert in the format string 31 | */ 32 | public ZeroDivisionError(String msg, Object... args) { 33 | this(TYPE, msg, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/_base/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code private_base} package contains classes that support the 3 | * interpreter without requiring it to be initialised. (Specifically, 4 | * they may be used before the Python type system is in working order, 5 | * and without causing it to initialise.) 6 | *

7 | * Classes {@code public} in this package are not intended to be 8 | * accessible to users. They are public so that the implementation can 9 | * use them. 10 | */ 11 | package uk.co.farowl.vsj3.evo1._base; 12 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/base/MissingFeature.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1.base; 2 | 3 | /** 4 | * Thrown when we reach a combination of circumstances in the 5 | * interpreter that may arise from legitimate use, but we aren't ready 6 | * to implement it. 7 | *

8 | * What does the reference implementation do at this point? 9 | */ 10 | public class MissingFeature extends InterpreterError { 11 | private static final long serialVersionUID = 1L; 12 | 13 | /** 14 | * Constructor specifying a message. 15 | * 16 | * @param msg a Java format string for the message 17 | * @param args to insert in the format string 18 | */ 19 | public MissingFeature(String msg, Object... args) { 20 | super(String.format(msg, args)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/base/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code base} package contains classes that support the 3 | * interpreter without requiring it to be initialised. (Specifically, 4 | * they may be used before the Python type system is in working order, 5 | * and without causing it to initialise.) 6 | *

7 | * Classes {@code public} in this package are intended to be accessible 8 | * to users (meaning extension writers and those embedding the 9 | * interpreter in an application). 10 | */ 11 | package uk.co.farowl.vsj3.evo1.base; 12 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/modules/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code modules} package contains built-in modules implemented in 3 | * Java. As far as possible, the class name is equal to the Python 4 | * module name, to aid to navigation. They will mostly be used from 5 | * Python via an {@code import}, but use from Java is also possible. 6 | */ 7 | package uk.co.farowl.vsj3.evo1.modules; 8 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package contains the classes that implement the objects of the 3 | * Python language language. 4 | */ 5 | package uk.co.farowl.vsj3.evo1; 6 | -------------------------------------------------------------------------------- /rt3/src/main/java/uk/co/farowl/vsj3/evo1/stringlib/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code stringlib} package contains classes that support the 3 | * implementation of built-in types, and relevant to strings, formatting 4 | * or arrays of integers (that feature heavily in the implementation of 5 | * {@code str}). 6 | *

7 | * Classes {@code public} in this package are provisionally intended to 8 | * be accessible to users (meaning extension writers and those embedding 9 | * the interpreter in an application). 10 | */ 11 | package uk.co.farowl.vsj3.evo1.stringlib; 12 | -------------------------------------------------------------------------------- /rt3/src/main/javaTemplate/uk/co/farowl/vsj3/evo1/PyUnicodeMethods.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3.evo1; 2 | 3 | import uk.co.farowl.vsj3.evo1.PyObjectUtil.NoConversion; 4 | import uk.co.farowl.vsj3.evo1.PyUnicode.CodepointDelegate; 5 | import static uk.co.farowl.vsj3.evo1.PyUnicode.adapt; 6 | 7 | import java.util.Iterator; 8 | 9 | // $OBJECT_GENERATOR$ PyUnicodeGenerator 10 | 11 | /** 12 | * This class contains static methods implementing operations on the 13 | * Python {@code str} object, supplementary to those defined in 14 | * {@link PyUnicode}. 15 | *

16 | * Implementations of binary operations defined here will have 17 | * {@code Object} as their second argument, and should return 18 | * {@link Py#NotImplemented} when the type in that position is not 19 | * supported. 20 | */ 21 | class PyUnicodeMethods { 22 | 23 | private PyUnicodeMethods() {} // no instances 24 | 25 | // $SPECIAL_METHODS$ --------------------------------------------- 26 | 27 | // plumbing ------------------------------------------------------ 28 | 29 | /** 30 | * Compare sequences for equality. This is a little simpler than 31 | * {@code compareTo}. 32 | * 33 | * @param a sequence 34 | * @param b another 35 | * @return whether values equal 36 | */ 37 | private static boolean eq(CodepointDelegate a, CodepointDelegate b) { 38 | // Lengths must be equal 39 | if (a.length() != b.length()) { return false; } 40 | // Scan the code points in a and b 41 | Iterator ib = b.iterator(); 42 | for (int c : a) { if (c != ib.next()) { return false; } } 43 | return true; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /rt3/src/main/javadoc/project-styles.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /* Styles supplementary to the standard Javadoc doclet. */ 4 | 5 | /* Table layout for framed data. */ 6 | table.framed-layout { 7 | border: 1px solid black; 8 | border-collapse: collapse; 9 | } 10 | 11 | table.framed-layout th, table.framed-layout td { 12 | border: 1px solid black; 13 | text-align: center; 14 | min-width: 2em; 15 | } 16 | 17 | table.framed-layout td.label { 18 | text-align: left; 19 | font-weight: bold; 20 | } -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/attr_access_builtin.py: -------------------------------------------------------------------------------- 1 | # attr_access_builtin.py 2 | 3 | # True, "hello" and 1 will be in co_consts 4 | true_and = True.__and__.__name__ 5 | 6 | # PyJavaMethod.self exposed as __self__ is target 7 | hello = "hello".replace.__self__ 8 | 9 | # 'int.__sub__' from logic behind type.__qualname__ 10 | one_sub = (1).__sub__.__qualname__ 11 | 12 | # bool is in the dictionary of builtins 13 | bool_add = bool.__add__.__name__ 14 | 15 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/binary_op.py: -------------------------------------------------------------------------------- 1 | # binary_op.py 2 | 3 | a = 7 4 | b = 6 5 | 6 | sum = a + b 7 | diff = a - b 8 | prod = a * b 9 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/bool_left_arith.py: -------------------------------------------------------------------------------- 1 | # bool_left_arith.py 2 | # binary operations invoked as bool op number 3 | 4 | t = True 5 | f = False 6 | 7 | # Note bool is a sub-class of int 8 | u = 42 9 | a = t + u 10 | b = t * u 11 | c = f * u 12 | d = -f 13 | 14 | # Note bool is *not* a sub-class of float 15 | u = 42. 16 | a1 = t + u 17 | b1 = t * u 18 | c1 = f * u 19 | 20 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/bool_right_arith.py: -------------------------------------------------------------------------------- 1 | # bool_right_arith.py 2 | # binary operations invoked as number op bool 3 | 4 | t = True 5 | f = False 6 | 7 | # Note bool is a sub-class of int 8 | u = 42 9 | a = u + t 10 | b = u * t 11 | c = u * f 12 | d = -t 13 | 14 | # Note bool is *not* a sub-class of float 15 | u = 42. 16 | a1 = u + t 17 | b1 = u * t 18 | c1 = u * f 19 | 20 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/builtins_module.py: -------------------------------------------------------------------------------- 1 | # builtins_module.py 2 | # 3 | # The focus of this test is the way the interpreter resolves names 4 | # in the builtins dictionary (after local and global namespaces). 5 | # This happens in opcodes LOAD_NAME and LOAD_GLOBAL. 6 | 7 | # Access sample objects from the builtins module implicitly 8 | # Opcode is LOAD_NAME 9 | int_name = int.__name__ 10 | max_name = max.__name__ 11 | 12 | # Call functions to prove we can 13 | # Opcode is LOAD_NAME 14 | ai = abs(-42) 15 | af = abs(-41.9) 16 | 17 | # Access from within a nested scope 18 | 19 | def f(x): 20 | # Opcode is LOAD_GLOBAL 21 | return abs(x), min.__name__ 22 | 23 | aj, min_name = f(-123_000_000_000) 24 | 25 | # Sometimes __builtins__ is not the builtins module. Find it with: 26 | bi = max.__self__ 27 | 28 | # Check explicit attribute access to the (real) builtins module 29 | bi_int_name = bi.int.__name__ 30 | bi_max_name = bi.max.__name__ 31 | 32 | 33 | # Not marshallable 34 | del bi, f 35 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/call_method_builtin.py: -------------------------------------------------------------------------------- 1 | # call_method_builtin.py 2 | 3 | # Call methods on some built-in types to exercise CALL_METHOD 4 | 5 | a = "abracadabra" 6 | 7 | asc = a.isascii() 8 | A = a.upper() 9 | 10 | # Signature: strip(self, chars=None, /) 11 | cad = a.strip("bar") 12 | wood = " \twood \x85\r\n".strip() 13 | 14 | # Signature: replace(self, old, new, count=-1, /) 15 | sox = a.replace("bra", "sock") 16 | sock = a.replace("bra", "sock", 1) 17 | 18 | # Signature: split(self, /, sep=None, maxsplit=-1) 19 | split1 = a.split('br', 1) 20 | split = a.split('bra') 21 | split0 = a.split() 22 | split1k = a.split('br', maxsplit=1) 23 | split2k = a.split(maxsplit=4, sep='a') 24 | 25 | # Force use of CALL_FUNCTION_EX 0 26 | sock_ex = a.replace(*("bra", "sock", 1)) 27 | 28 | # Force use of CALL_FUNCTION_EX 1 29 | split1k_ex = a.split('br', **{'maxsplit':1}) 30 | 31 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/comparison.py: -------------------------------------------------------------------------------- 1 | # comparison.py 2 | 3 | # Tests of the order comparisons 4 | 5 | a = 2 6 | b = 4 7 | 8 | lt = a < b 9 | le = a <= b 10 | eq = a == b 11 | ne = a != b 12 | ge = a >= b 13 | gt = a > b 14 | 15 | a = 4 16 | b = 2 17 | 18 | lt1 = a < b 19 | le1 = a <= b 20 | eq1 = a == b 21 | ne1 = a != b 22 | ge1 = a >= b 23 | gt1 = a > b 24 | 25 | a = 2 26 | b = 2 27 | 28 | lt2 = a < b 29 | le2 = a <= b 30 | eq2 = a == b 31 | ne2 = a != b 32 | ge2 = a >= b 33 | gt2 = a > b 34 | 35 | 36 | # Tests of 'in' 37 | 38 | p = "pig" 39 | t = ("cow", 2, p, None, 42.0) 40 | f0 = 1 in t 41 | f1 = "c" in t 42 | t1x = "c" not in t 43 | f2 = 42.1 in t 44 | f3 = (2,) in t 45 | f4 = "c" in t[2] 46 | 47 | t0 = 2 in t 48 | t1 = "pig" in t 49 | f1x = p not in t 50 | t2 = None in t 51 | t3 = 42 in t 52 | t4 = "p" in t[2] 53 | 54 | 55 | # Tests of 'is' 56 | 57 | t5 = t[3] is None 58 | t6 = t[2] is p 59 | f6x = p is not t[2] 60 | t7 = t[0] is not None 61 | 62 | f5 = t[1] is None 63 | f6 = p is t[4] 64 | 65 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/for_loop.py: -------------------------------------------------------------------------------- 1 | # for_loop.py 2 | 3 | # Execute various kinds of for loop 4 | # This is primarily a test of creating iterators 5 | # on the types involved. 6 | 7 | # Opcodes GET_ITER, FOR_ITER, JUMP_BACKWARD 8 | 9 | tuple_sum = 0 10 | for i in (13, 14, 15): 11 | tuple_sum = tuple_sum + i 12 | 13 | list_sum = 0 14 | for j in (a := [-30, 48, -60]): 15 | list_sum = list_sum + j 16 | 17 | # Requires list.append exposed and POP_TOP 18 | #hello_list = [] 19 | #for c in "hello": 20 | # hello_list.append(c) 21 | 22 | 23 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/function_def.py: -------------------------------------------------------------------------------- 1 | # function_def.py 2 | # 3 | # We create function objects with various signatures 4 | # and check some properties of each. 5 | 6 | def foo(): 7 | pass 8 | 9 | foo_name = foo.__name__ 10 | foo_qualname = foo.__qualname__ 11 | foo_defaults = foo.__name__ 12 | foo_kwdefaults = foo.__name__ 13 | foo_module = foo.__module__ # None, in the way we run this. 14 | 15 | 16 | def bar(a, b, c=3, *, d=4, e=5): 17 | # A body so that varnames is not just arguments 18 | x = a + b 19 | y = c + d * e 20 | return x * y 21 | 22 | bar.__module__ = 42 23 | 24 | bar_name = bar.__name__ 25 | bar_qualname = bar.__qualname__ 26 | bar_defaults = bar.__name__ 27 | bar_kwdefaults = bar.__name__ 28 | bar_module = bar.__module__ 29 | bar_module = bar.__module__ 30 | # XXX dict.__contains__ missing and bug in Comparison.IN 31 | #bar_globals_foo = foo in bar.__globals__ 32 | 33 | 34 | def baz(a, b, c=30, *aa, d=40, e=50): 35 | "This is a documentation string." 36 | pass 37 | 38 | baz_name = baz.__name__ 39 | baz_qualname = baz.__qualname__ 40 | baz_defaults = baz.__name__ 41 | baz_kwdefaults = baz.__name__ 42 | baz_doc = baz.__doc__ 43 | 44 | 45 | def qux(a, b, c=300, *aa, d=400, e=500, **kk): 46 | pass 47 | 48 | qux_name = qux.__name__ 49 | qux_qualname = qux.__qualname__ 50 | qux_defaults = qux.__name__ 51 | qux_kwdefaults = qux.__name__ 52 | 53 | 54 | # Delete since function object not marshallable: 55 | del foo, bar, baz, qux 56 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/function_locals.py: -------------------------------------------------------------------------------- 1 | # function_locals.py 2 | # 3 | # We define a nest of functions with cell and free variables, 4 | # and investigate how they look to the locals() built-in. 5 | 6 | 7 | # Each outer function returns its nested function for inspection 8 | def f1(a, b, u=1): 9 | # cell vars are (cell|free): (a, b, z |) 10 | z = 1 11 | a = (a + b) * u 12 | def f2(c = -1, v = 2): 13 | # cell vars are (cell|free): (c, y | a, b, z) 14 | nonlocal z 15 | y = 11 + z 16 | z = v 17 | def f3(d, e): 18 | # cell vars are (cell|free): (| a, b, c, y, z) 19 | nonlocal y, z 20 | w = 111 21 | x = w + y + z 22 | y = 3 + w 23 | z = 4 + a 24 | return locals() 25 | return f3, locals() 26 | return f2 27 | 28 | 29 | ### Tests of inner function definition and closure handling. 30 | 31 | f2 = f1(2, 4, 7) 32 | f3, f2_locals = f2() 33 | f3_locals = f3(3, 5) 34 | 35 | 36 | # Delete since function object not marshallable: 37 | del f1, f2, f3 38 | del f2_locals['f3'] 39 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/iterables.py: -------------------------------------------------------------------------------- 1 | # iterables.py 2 | 3 | a, b, c = 1, 2, 3 4 | a1, b1, c1 = ('a', 'b', 'c') 5 | 6 | u = (0, 1, 2, 3, 4, 5, 6, 7) 7 | a2, b2, *list, x2, y2, z2 = u 8 | # list = [2, 3, 4] 9 | 10 | t = (*list,) 11 | s = (a2, b2, *list, x2, y2, *t, z2) 12 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/list_dot_product.py: -------------------------------------------------------------------------------- 1 | # list_dot_product.py 2 | 3 | # Multiply-add of float vectors (without for loops) 4 | # Also, multiplication as repetition. 5 | 6 | n = 2 7 | 8 | a = [1.2, 3.4, 5.6, 7.8] * (3 * n) 9 | b = (4 * n) * [1.2, 4.5, 7.8] 10 | n = 12 * n # lists are this long 11 | 12 | i = 0 13 | sum = 0.0 14 | 15 | while i < n: 16 | sum = sum + a[i] * b[i] 17 | i = i + 1 18 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/list_index.py: -------------------------------------------------------------------------------- 1 | # list_index.py 2 | 3 | # Just enough to exercise indexed access opcodes and methods 4 | 5 | c = 22.0 6 | 7 | d = [20, "hello", c] 8 | a = d[0] 9 | b = d[1] 10 | d[2] = a + c 11 | c = d[2] 12 | 13 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/load_store_name.py: -------------------------------------------------------------------------------- 1 | # load_store_name.py 2 | 3 | a = 1 4 | β = 2 # non-ascii 5 | 6 | c = β 7 | β = 4 8 | a = c 9 | 10 | ਛਲ = β -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/multi_if.py: -------------------------------------------------------------------------------- 1 | # multi_if.py 2 | 3 | # Opcodes POP_JUMP_FORWARD_IF_FALSE, POP_JUMP_FORWARD_IF_TRUE, 4 | # and JUMP_FORWARD. 5 | 6 | a = False 7 | b = False 8 | 9 | if a and b: 10 | r = 2 11 | elif a or b: 12 | r = 1 13 | else: 14 | r = 0 15 | 16 | a = False 17 | b = True 18 | if a and b: 19 | r1 = 2 20 | elif a or b: 21 | r1 = 1 22 | else: 23 | r1 = 0 24 | 25 | a = True 26 | b = False 27 | if a and b: 28 | r2 = 2 29 | elif a or b: 30 | r2 = 1 31 | else: 32 | r2 = 0 33 | 34 | a = True 35 | b = True 36 | if a and b: 37 | r3 = 2 38 | elif a or b: 39 | r3 = 1 40 | else: 41 | r3 = 0 42 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/simple_if.py: -------------------------------------------------------------------------------- 1 | # simple_if.py 2 | 3 | # Opcodes POP_JUMP_FORWARD_IF_FALSE, JUMP_FORWARD 4 | b = False 5 | if b: 6 | r0 = 1 7 | else: 8 | r0 = 0 9 | 10 | b = True 11 | if b: 12 | r1 = 1 13 | else: 14 | r1 = 0 15 | 16 | b = 0 17 | if b: 18 | r2 = 1 19 | else: 20 | r2 = 0 21 | 22 | b = 1 23 | r3 = 1 if b else 0 24 | 25 | b = "" 26 | r4 = 1 if b else 0 27 | 28 | b = "something" 29 | r5 = 1 if b else 0 30 | 31 | b = None 32 | r6 = 1 if b else 0 33 | 34 | # Opcodes POP_JUMP_FORWARD_IF_NOT_NONE 35 | if b is None: 36 | r7 = 1 37 | else: 38 | r7 = 0 39 | 40 | # Opcode is POP_JUMP_FORWARD_IF_NONE 41 | if b is not None: 42 | r8 = 1 43 | else: 44 | r8 = 0 45 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/simple_loop.py: -------------------------------------------------------------------------------- 1 | # simple_loop.py 2 | 3 | n = 6 4 | 5 | # ? n, sum 6 | sum = 0 7 | while n > 0: 8 | sum = sum + n 9 | n = n - 1 10 | 11 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/tuple_dot_product.py: -------------------------------------------------------------------------------- 1 | # tuple_dot_product.py 2 | 3 | # Multiply-add of int and float vectors (without for loops) 4 | 5 | a = (2, 3, 4) 6 | b = (3, 4, 6) 7 | n = 3 8 | 9 | # ? sum 10 | 11 | sum = a[0] * b[0] 12 | i = 1 13 | while i < n: 14 | sum = sum + a[i] * b[i] 15 | i = i + 1 16 | 17 | a= (1., 2., 3., 4.) 18 | b = (4., 3., 4., 5.) 19 | n = 4 20 | 21 | sum2 = a[0] * b[0] 22 | i = 1 23 | while i < n: 24 | sum2 = sum2 + a[i] * b[i] 25 | i = i + 1 26 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/tuple_index.py: -------------------------------------------------------------------------------- 1 | # tuple_index.py 2 | 3 | # Just enough to exercise indexed access opcodes and methods 4 | 5 | c = 22.0 6 | 7 | d = (20, "hello", c) 8 | b = d[1] 9 | c = d[2] + d[0] 10 | -------------------------------------------------------------------------------- /rt3/src/test/pythonExample/vsj3/evo1/unary_op.py: -------------------------------------------------------------------------------- 1 | # unary_op.py 2 | 3 | a = 6. 4 | b = -7 5 | 6 | a = -a 7 | b = -b 8 | c = ~b 9 | -------------------------------------------------------------------------------- /rt3/tools/python/lib/evo1/__init__.py: -------------------------------------------------------------------------------- 1 | # evo1 package: generators and other tooling 2 | 3 | # These classes support the processing of template files into 4 | # the Java class definitions that realise Python objects 5 | # and their methods. 6 | 7 | from .base import ImplementationGenerator, TypeInfo, WorkingType, OpInfo 8 | from .PyFloat import PyFloatGenerator 9 | from .PyLong import PyLongGenerator 10 | from .PyUnicode import PyUnicodeGenerator 11 | 12 | 13 | -------------------------------------------------------------------------------- /rt3bm/src/main/java/uk/co/farowl/vsj3bm/evo1/DebugLongBinary.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3bm.evo1; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * A program that calls a selected method in the benchmark so that we 7 | * can explore it with the debugger, outside the JMH framework. 8 | */ 9 | public class DebugLongBinary { 10 | 11 | public static void main(String[] args) throws Throwable { 12 | 13 | PyLongBinary test = new PyLongBinary(); 14 | Object r = test.addbig(); 15 | 16 | // Second time the ClassValue should be ready for us 17 | test.bigvo = BigInteger.valueOf(Integer.MIN_VALUE + 1); 18 | test.bigwo = BigInteger.valueOf(-1); 19 | r = test.addbig(); 20 | 21 | System.out.println(String.format("Result = %s (%s)", r, 22 | r.getClass().getSimpleName())); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /rt3bm/src/main/java/uk/co/farowl/vsj3bm/evo1/DebugLongUnary.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3bm.evo1; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * A program that calls a selected method in the benchmark so that we 7 | * can explore it with the debugger, outside the JMH framework. 8 | */ 9 | public class DebugLongUnary { 10 | 11 | public static void main(String[] args) throws Throwable { 12 | 13 | PyLongUnary test = new PyLongUnary(); 14 | Object r = test.negbig(); 15 | 16 | // Second time the ClassValue should be ready for us 17 | test.bigv = BigInteger.valueOf(Integer.MIN_VALUE+1); 18 | r = test.negbig(); 19 | 20 | System.out.println(String.format("Result = %s (%s)", r, 21 | r.getClass().getSimpleName())); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /rt3bm/src/main/java/uk/co/farowl/vsj3bm/evo1/MainLoop.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj3bm.evo1; 2 | 3 | import uk.co.farowl.vsj3.evo1.PyFloat; 4 | 5 | /** 6 | * A program that calls a selected method in the benchmark to explore in 7 | * isolation the way in which it gets optimised by the JVM. (See 8 | * {@code rt2bm.gradle} task {@code mainloop}. 9 | */ 10 | public class MainLoop { 11 | 12 | public static void main(String[] args) throws Throwable { 13 | PyFloatBinary test = new PyFloatBinary(); 14 | double sum = 0.0; 15 | for (int i = 0; i < 10_000; i++) { 16 | test.v = i * 2.001; 17 | test.w = i * 1.001; 18 | Object r = test.quartic(); 19 | //System.out.println(String.format("\nPartial = %s\n", r)); 20 | sum += PyFloat.doubleValue(r); 21 | } 22 | System.out.println(String.format("Sum = %14.3e", sum)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /rt4client/rt4client.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * rt4client subproject (uses API from the core rt4 sub-project). 3 | */ 4 | 5 | plugins { 6 | // Apply the Java application plugin. 7 | id 'application' 8 | id 'jvm-test-suite' 9 | } 10 | 11 | 12 | java { 13 | toolchain { 14 | languageVersion = JavaLanguageVersion.of(17) 15 | } 16 | } 17 | 18 | 19 | repositories { 20 | // Use Maven Central for resolving dependencies. 21 | mavenCentral() 22 | } 23 | 24 | 25 | dependencies { 26 | implementation project(':rt4core') 27 | implementation 'org.slf4j:slf4j-api:2.0.13' 28 | 29 | runtimeOnly 'org.slf4j:slf4j-jdk14:2.0.13' 30 | } 31 | 32 | 33 | application { 34 | mainModule = 'uk.co.farowl.rt4client' 35 | mainClass = 'uk.co.farowl.vsj4c.app.ClientApp' 36 | } 37 | 38 | // Configure the jvm-test-suite plug-in 39 | testing { 40 | suites { 41 | test { 42 | useJUnitJupiter() 43 | } 44 | } 45 | } 46 | 47 | 48 | tasks.withType(JavaCompile) { 49 | 50 | options.encoding = 'UTF-8' 51 | 52 | // Use only public API 53 | options.compilerArgs.addAll(['--release', '17']) 54 | // deprecation is noisy 55 | options.deprecation = true 56 | // retain parameter names (for use by exposer) 57 | options.compilerArgs.add('-parameters') 58 | } 59 | -------------------------------------------------------------------------------- /rt4client/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /** A client application to the Very Slow Jython rt4 API. */ 2 | module uk.co.farowl.rt4client { 3 | exports uk.co.farowl.vsj4c.app; 4 | 5 | requires uk.co.farowl.rt4core; 6 | 7 | requires org.slf4j.jul; 8 | } 9 | -------------------------------------------------------------------------------- /rt4client/src/main/java/uk/co/farowl/vsj4c/app/MyType.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj4c.app; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | import uk.co.farowl.vsj4.runtime.Exposed; 6 | import uk.co.farowl.vsj4.runtime.PyType; 7 | import uk.co.farowl.vsj4.runtime.PyUtil; 8 | import uk.co.farowl.vsj4.runtime.TypeSpec; 9 | 10 | /** An example Python type defined in an application. */ 11 | class MyType { 12 | 13 | private int content; 14 | 15 | MyType(int content) { this.content = content; } 16 | 17 | Object __str__() { return "MyType(" + content + ")"; } 18 | 19 | @Exposed.PythonMethod 20 | void set_content(int v) { 21 | this.content = 2 * v; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return PyUtil.defaultToString(this); 27 | } 28 | 29 | static final PyType TYPE = PyType.fromSpec(new TypeSpec("MyType", 30 | MethodHandles.lookup())); 31 | } -------------------------------------------------------------------------------- /rt4client/src/main/java/uk/co/farowl/vsj4c/app/package-info.java: -------------------------------------------------------------------------------- 1 | /** A client application to the Very Slow Jython rt4 API. */ 2 | package uk.co.farowl.vsj4c.app; 3 | -------------------------------------------------------------------------------- /rt4client/src/main/java/uk/co/farowl/vsj4c/ext/Extension.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj4c.ext; 2 | 3 | import uk.co.farowl.vsj4.runtime.Exposed; 4 | 5 | public class Extension 6 | // extends JavaModule 7 | { 8 | 9 | @Exposed.PythonMethod 10 | public int foo(int x) { 11 | return ((x - 12) * x + 47) * x - 18; 12 | } 13 | 14 | public Extension() { 15 | // super(DEFINITION); 16 | } 17 | 18 | // private static final JavaModule.Definition DEFINITION = 19 | // JavaModule.define("my_extension", MethodHandles.lookup()); 20 | } 21 | -------------------------------------------------------------------------------- /rt4client/src/main/java/uk/co/farowl/vsj4c/ext/package-info.java: -------------------------------------------------------------------------------- 1 | /** Extension modules using the Very Slow Jython rt4 API. */ 2 | package uk.co.farowl.vsj4c.ext; 3 | -------------------------------------------------------------------------------- /rt4client/src/test/java/uk/co/farowl/vsj4c/package-info.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj4c; 2 | -------------------------------------------------------------------------------- /rt4core/src/kernelTest/java/uk/co/farowl/vsj4/runtime/TypeInitTestFromSpec.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2024 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import java.lang.invoke.MethodHandles; 6 | 7 | import org.junit.jupiter.api.BeforeAll; 8 | import org.junit.jupiter.api.DisplayName; 9 | 10 | /** 11 | * Test that the Python type system comes into operation in a consistent 12 | * state after creating a type with {@link PyType#fromSpec(TypeSpec)}. 13 | * The tests are all in the superclass: this class supplies only the 14 | * initialising event in {@link #setUpClass()}. 15 | */ 16 | @DisplayName("After creating a type with PyType.fromSpec() ...") 17 | class TypeInitTestFromSpec extends TypeInitTest { 18 | 19 | /** Initialised in {@link #setUpClass()}. */ 20 | static MyType myType; 21 | 22 | /** Example user-defined type. */ 23 | static class MyType { 24 | /** Construct trivially. */ 25 | MyType() {} 26 | 27 | /** The Python type. */ 28 | PyType TYPE = PyType.fromSpec( 29 | new TypeSpec("MyType", MethodHandles.lookup())); 30 | } 31 | 32 | /** Start by using a Python type defined in Java. */ 33 | @BeforeAll 34 | static void setUpClass() { myType = new MyType(); } 35 | } 36 | -------------------------------------------------------------------------------- /rt4core/src/kernelTest/java/uk/co/farowl/vsj4/runtime/TypeInitTestNameError.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertNotNull; 6 | 7 | import org.junit.jupiter.api.BeforeAll; 8 | import org.junit.jupiter.api.DisplayName; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * Test that the Python type system comes into operation in a consistent 13 | * state after referencing the class {@link PyNameError}. Most of the 14 | * tests are in the superclass. 15 | */ 16 | @DisplayName("After getting PyNameError.TYPE ...") 17 | @SuppressWarnings("static-method") 18 | class TypeInitTestNameError extends TypeInitTest { 19 | 20 | /** Initialised in {@link #setUpClass()}. */ 21 | static PyType type; 22 | 23 | /** Start by creating an instance of {@code PyNameError}. */ 24 | @BeforeAll 25 | static void setUpClass() { type = PyNameError.TYPE; } 26 | 27 | @Test 28 | @DisplayName("PyNameError.TYPE is not null") 29 | void type_not_null() { assertNotNull(type); } 30 | 31 | @Test 32 | @DisplayName("PyExc.NameError is not null") 33 | void name_error_not_null() { assertNotNull(PyExc.NameError); } 34 | 35 | @Test 36 | @DisplayName("PyExc.KeyError is not null") 37 | void key_error_not_null() { assertNotNull(PyExc.KeyError); } 38 | 39 | @Test 40 | @DisplayName("PyExc.UnboundLocalError is not null") 41 | void unbound_local_error_not_null() { 42 | assertNotNull(PyExc.UnboundLocalError); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /rt4core/src/kernelTest/java/uk/co/farowl/vsj4/runtime/TypeInitTestObject.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2024 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import org.junit.jupiter.api.BeforeAll; 6 | import org.junit.jupiter.api.DisplayName; 7 | 8 | /** 9 | * Test that the Python type system comes into operation in a consistent 10 | * state after getting {@link PyObject#TYPE} The tests are all in the 11 | * superclass: this class supplies only the initialising event in 12 | * {@link #setUpClass()}. 13 | */ 14 | @DisplayName("After getting PyObject.TYPE ...") 15 | class TypeInitTestObject extends TypeInitTest { 16 | 17 | /** Initialised in {@link #setUpClass()}. */ 18 | static PyType object; 19 | 20 | /** Start by touching the type object {@code object}. */ 21 | @BeforeAll 22 | static void setUpClass() { object = PyObject.TYPE; } 23 | } 24 | -------------------------------------------------------------------------------- /rt4core/src/kernelTest/java/uk/co/farowl/vsj4/runtime/TypeInitTestPyExc.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertNotNull; 6 | 7 | import org.junit.jupiter.api.BeforeAll; 8 | import org.junit.jupiter.api.DisplayName; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * Test that the Python type system comes into operation in a consistent 13 | * state after referencing a type through {@link PyExc}. Most of the 14 | * tests are in the superclass. 15 | */ 16 | @DisplayName("After getting PyExc.UnboundLocalError ...") 17 | @SuppressWarnings("static-method") 18 | class TypeInitTestPyExc extends TypeInitTest { 19 | 20 | /** Initialised in {@link #setUpClass()}. */ 21 | static PyType type; 22 | 23 | /** Start by touching the type object {@code UnboundLocalError}. */ 24 | @BeforeAll 25 | static void setUpClass() { type = PyExc.UnboundLocalError; } 26 | 27 | @Test 28 | @DisplayName("The result is not null") 29 | void object_not_null() { assertNotNull(type); } 30 | 31 | @Test 32 | @DisplayName("PyExc.TypeError is not null") 33 | void typeerror_not_null() { assertNotNull(PyExc.TypeError); } 34 | 35 | @Test 36 | @DisplayName("PyExc.StopIteration is not null") 37 | void stopiter_not_null() { assertNotNull(PyExc.StopIteration); } 38 | 39 | @Test 40 | @DisplayName("PyExc.KeyError is not null") 41 | void keyerror_not_null() { assertNotNull(PyExc.KeyError); } 42 | } 43 | -------------------------------------------------------------------------------- /rt4core/src/kernelTest/java/uk/co/farowl/vsj4/runtime/TypeInitTestRegistry.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import org.junit.jupiter.api.BeforeAll; 6 | import org.junit.jupiter.api.DisplayName; 7 | 8 | import uk.co.farowl.vsj4.runtime.kernel.TypeRegistry; 9 | 10 | /** 11 | * Test that the Python type system comes into operation in a consistent 12 | * state after the registry is initialised explicitly. The tests are all 13 | * in the superclass: this class supplies only the initialising event in 14 | * {@link #setUpClass()}. 15 | */ 16 | @DisplayName("After TypeRegistry.getInstance() ...") 17 | class TypeInitTestRegistry extends TypeInitTest { 18 | 19 | /** Initialised in {@link #setUpClass()}. */ 20 | static TypeRegistry registry; 21 | 22 | /** Start by touching the type registry singleton itself. */ 23 | @BeforeAll 24 | static void setUpClass() { registry = TypeSystem.registry; } 25 | } 26 | -------------------------------------------------------------------------------- /rt4core/src/kernelTest/java/uk/co/farowl/vsj4/runtime/TypeInitTestStopIteration.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertNotNull; 6 | 7 | import org.junit.jupiter.api.BeforeAll; 8 | import org.junit.jupiter.api.DisplayName; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * Test that the Python type system comes into operation in a consistent 13 | * state after creating an instance of {@link PyStopIteration}, which 14 | * references a type through {@link PyExc} in its static initialisation. 15 | * Most of the tests are in the superclass. 16 | */ 17 | @DisplayName("After constructing a PyStopIteration ...") 18 | @SuppressWarnings("static-method") 19 | class TypeInitTestStopIteration extends TypeInitTest { 20 | 21 | /** Initialised in {@link #setUpClass()}. */ 22 | static Object object; 23 | 24 | /** Start by creating an instance of {@code PyStopIteration}. */ 25 | @BeforeAll 26 | static void setUpClass() { object = new PyStopIteration(); } 27 | 28 | @Test 29 | @DisplayName("PyStopIteration.TYPE is not null") 30 | void type_not_null() { assertNotNull(PyStopIteration.TYPE); } 31 | 32 | @Test 33 | @DisplayName("PyExc.TypeError is not null") 34 | void typeerror_not_null() { assertNotNull(PyExc.TypeError); } 35 | 36 | @Test 37 | @DisplayName("PyExc.StopIteration is not null") 38 | void stopiter_not_null() { assertNotNull(PyExc.StopIteration); } 39 | } 40 | -------------------------------------------------------------------------------- /rt4core/src/kernelTest/java/uk/co/farowl/vsj4/runtime/TypeInitTestType.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2024 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import org.junit.jupiter.api.BeforeAll; 6 | import org.junit.jupiter.api.DisplayName; 7 | 8 | /** 9 | * Test that the Python type system comes into operation in a consistent 10 | * state after getting {@link PyType#TYPE()} The tests are all in the 11 | * superclass: this class supplies only the initialising event in 12 | * {@link #setUpClass()}. 13 | */ 14 | @DisplayName("After calling PyType.TYPE() ...") 15 | class TypeInitTestType extends TypeInitTest { 16 | 17 | /** Initialised in {@link #setUpClass()}. */ 18 | static PyType type; 19 | 20 | /** Start by touching the type object {@code type}. */ 21 | @BeforeAll 22 | static void setUpClass() { type = PyType.TYPE(); } 23 | } 24 | -------------------------------------------------------------------------------- /rt4core/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | /** The Very Slow Jython rt4 core classes and API. */ 4 | module uk.co.farowl.rt4core { 5 | // exports uk.co.farowl.vsj4.core; 6 | exports uk.co.farowl.vsj4.runtime; 7 | exports uk.co.farowl.vsj4.support; 8 | exports uk.co.farowl.vsj4.stringlib; 9 | 10 | requires transitive org.slf4j; 11 | requires org.objectweb.asm; 12 | requires org.objectweb.asm.tree; 13 | } 14 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/core/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code core} package contains API classes sufficient to embed a 3 | * Jython interpreter, to run Python scripts, and to use Python objects 4 | * through a "pure Object" interface. 5 | *

6 | * Applications that define their own extension types, or need the Java 7 | * API on built-in objects, will need the {@code runtime} package. 8 | *

9 | * Classes {@code public} in this package are accessible to a client 10 | * application that {@code requires} the module in its module 11 | * declaration. 12 | */ 13 | package uk.co.farowl.vsj4.core; 14 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/ClassShorthand.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import uk.co.farowl.vsj4.support.JavaClassShorthand; 6 | 7 | /** 8 | * Some shorthands used to construct method signatures of runtime 9 | * methods, {@code MethodType}s, etc.. Clients can access the constants 10 | * by implementing the interface (slightly frowned upon in public code), 11 | * or paste this into their imports section:

12 | import static uk.co.farowl.vsj4.runtime.ClassShorthand.*;
13 |  *
14 | */ 15 | public interface ClassShorthand extends JavaClassShorthand { 16 | /** Shorthand for {@code PyType.class}. */ 17 | public static final Class T = PyType.class; 18 | /** Shorthand for {@code Comparison.class}. */ 19 | // static final Class CMP = Comparison.class; 20 | /** Shorthand for {@code PyTuple.class}. */ 21 | static final Class TUPLE = PyTuple.class; 22 | /** Shorthand for {@code PyDict.class}. */ 23 | static final Class DICT = PyDict.class; 24 | } 25 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/PyNone.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import java.lang.invoke.MethodHandles; 6 | 7 | import uk.co.farowl.vsj4.runtime.internal.Singleton; 8 | 9 | /** The Python {@code None} object. */ 10 | public final class PyNone extends Singleton { 11 | 12 | /** The Python type of {@code None}. */ 13 | public static final PyType TYPE = PyType.fromSpec( // 14 | new TypeSpec("NoneType", MethodHandles.lookup())); 15 | 16 | /** The only instance, published as {@link Py#None}. */ 17 | public static final PyNone INSTANCE = new PyNone(); 18 | 19 | private PyNone() { super(TYPE, "None"); } 20 | 21 | // Special methods ----------------------------------------------- 22 | 23 | @SuppressWarnings({"static-method", "unused"}) 24 | private boolean __bool__() { return false; } 25 | } 26 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/PyNotImplemented.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import java.lang.invoke.MethodHandles; 6 | 7 | import uk.co.farowl.vsj4.runtime.internal.Singleton; 8 | 9 | /** The Python {@code NotImplemented} object. */ 10 | public final class PyNotImplemented extends Singleton { 11 | 12 | /** The Python type of {@code NotImplemented}. */ 13 | public static final PyType TYPE = PyType.fromSpec( // 14 | new TypeSpec("NotImplementedType", MethodHandles.lookup())); 15 | 16 | /** The only instance, published as {@link Py#NotImplemented}. */ 17 | static final PyNotImplemented INSTANCE = new PyNotImplemented(); 18 | 19 | private PyNotImplemented() { super(TYPE, "NotImplemented"); } 20 | 21 | // Special methods ----------------------------------------------- 22 | 23 | @SuppressWarnings({"static-method", "unused"}) 24 | private boolean __bool__() { 25 | Warnings.format(PyExc.DeprecationWarning, 1, BOOLEAN_CONTEXT); 26 | return true; 27 | } 28 | 29 | private static final String BOOLEAN_CONTEXT = 30 | "NotImplemented should not be used in a boolean context"; 31 | } 32 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/PyObject.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | /** 6 | * Public static methods associated with the Python type {@code object}. 7 | * The Python {@code object} type is represented by 8 | * {@code java.lang.Object} and not by instances of this class. 9 | *

10 | * The Java implementation class of a type defined in Python will 11 | * be derived from the canonical implementation class of the "solid 12 | * base" it inherits in Python. This may well be {@code Object}. 13 | */ 14 | // Compare CPython PyBaseObject_Type in typeobject.c 15 | public final class PyObject { 16 | 17 | /** The type object {@code object}. */ 18 | public static final PyType TYPE = 19 | /* 20 | * This looks a bit weird, but we need to make sure PyType 21 | * gets initialised, and the whole type system behind it, 22 | * before the first type object becomes visible. 23 | */ 24 | PyType.of(new Object()); 25 | 26 | /** One cannot make instances of this class. */ 27 | private PyObject() {} 28 | } 29 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/WithClass.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2024 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | /** 6 | * An instance of a class implementing {@code WithClass} reports an 7 | * explicit Python type, generally exposed as a {@code __class__} 8 | * attribute. Java classes that are the crafted representations of 9 | * Python types implement this interface. 10 | *

11 | * The type may be the same for all instances of the same Java class or 12 | * be assignable within certain constraints (see 13 | * {@link WithClassAssignment}). 14 | */ 15 | public interface WithClass { 16 | /** 17 | * Return the actual Python type of the object. 18 | * 19 | * @return the actual type of the object 20 | */ 21 | // @Exposed.Get(name="__class__") 22 | PyType getType(); 23 | } 24 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/WithDict.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * An instance of a class implementing {@code WithDict} possesses a 9 | * dictionary, generally exposed as a {@code __dict__} attribute. The 10 | * dictionary is not necessarily a Python {@code dict} or directly 11 | * writable. (A {@code type} object, for example, implements 12 | * {@link #getDict()} to return only an unmodifiable view of its 13 | * dictionary.) See also {@link WithDictAssignment}. 14 | */ 15 | public interface WithDict extends WithClass { 16 | /** 17 | * The instance dictionary. This is not necessarily a Python 18 | * {@code dict}, and may not be directly writable. Some implementing 19 | * types override the signature to specify the return is a 20 | * fully-fledged Python {@code dict}. 21 | * 22 | * @return instance dictionary 23 | */ 24 | // @Exposed.Get(name="__dict__") 25 | Map getDict(); 26 | } 27 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/bootstrap/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code runtime.bootstrap} package contains parts of the Python 3 | * run-time system (types mainly) needed early in the creation of the 4 | * object system, but not needing privileged access to the 5 | * {@code runtime.kernel} package. Classes are placed here if their 6 | * static initialisation must occur in the bootstrap thread. 7 | *

8 | * This package is not exported. Classes {@code public} in this package 9 | * are accessible across the module, but not to client programs. 10 | */ 11 | // XXX Should all be package-private in kernel instead? 12 | package uk.co.farowl.vsj4.runtime.bootstrap; 13 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/internal/Singleton.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.runtime.internal; 4 | 5 | import uk.co.farowl.vsj4.runtime.PyType; 6 | import uk.co.farowl.vsj4.runtime.WithClass; 7 | 8 | /** 9 | * A base class for Python singletons {@code None}, 10 | * {@code NotImplemented}, {@code ...}. 11 | */ 12 | public abstract class Singleton implements WithClass { 13 | 14 | /** The Python type of the object implemented. */ 15 | private final PyType type; 16 | 17 | /** 18 | * The name in Python of the object implemented as returned by 19 | * {@code repr()}. 20 | */ 21 | private final String name; 22 | 23 | /** 24 | * Specify the Python type and repr-name. 25 | * 26 | * @param type of the single instance 27 | * @param name that {@code repr()} should produce. 28 | */ 29 | protected Singleton(PyType type, String name) { 30 | this.name = name; 31 | this.type = type; 32 | } 33 | 34 | @Override 35 | public String toString() { return name; } 36 | 37 | @Override 38 | public PyType getType() { return type; } 39 | 40 | // Special methods ----------------------------------------------- 41 | 42 | /** 43 | * {@code __repr__} 44 | * 45 | * @return {@code repr(this)} as defined in constructor. 46 | */ 47 | protected Object __repr__() { 48 | return name; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code runtime.internal} package contains internal parts of the 3 | * Python run-time system supporting compiled Python code during 4 | * execution. 5 | *

6 | * This package is not exported. Classes {@code public} in this package 7 | * are accessible across the module, but not to client programs. Classes 8 | * belonging to the {@code runtime} layer should, for preference, be 9 | * created here, then carefully re-factored as it becomes necessary to 10 | * make them API. 11 | */ 12 | package uk.co.farowl.vsj4.runtime.internal; 13 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/kernel/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code runtime.kernel} package contains internal parts that 3 | * initialise the and provide the type system. 4 | *

5 | * This package is not exported. Classes {@code public} in this package 6 | * are accessible across the module, but not to client programs. 7 | */ 8 | package uk.co.farowl.vsj4.runtime.kernel; 9 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code runtime} package contains API classes that support 3 | * compiled Python code during execution, extension modules in Java, and 4 | * applications that embed Jython. It is possible to embed Jython and 5 | * make use of Python through a "pure Object" interface, but 6 | * applications that make detailed use of the run-time need this 7 | * package. 8 | *

9 | * Classes {@code public} in this package are accessible to a client 10 | * application that {@code requires} the module in its module 11 | * declaration. 12 | */ 13 | package uk.co.farowl.vsj4.runtime; 14 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/runtime/subclass/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code runtime.subclass} package contains ephemeral generated 3 | * representations of classes defined in Python. Instances of classes 4 | * public in this package are created by the type object of the Python 5 | * class. 6 | *

7 | * This package is not exported. Nothing outside the runtime needs to 8 | * reference them. 9 | */ 10 | package uk.co.farowl.vsj4.runtime.subclass; 11 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/stringlib/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code stringlib} package contains classes that support the 3 | * implementation of built-in types, and relevant to strings, formatting 4 | * or arrays of integers (that feature heavily in the implementation of 5 | * {@code str}). 6 | *

7 | * Classes {@code public} in this package are provisionally intended to 8 | * be accessible to users (meaning extension writers and those embedding 9 | * the interpreter in an application). 10 | */ 11 | package uk.co.farowl.vsj4.stringlib; 12 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/support/JavaClassShorthand.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2025 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.support; 4 | 5 | /** 6 | * Some shorthands used to construct method signatures, 7 | * {@code MethodType}s, etc.. Clients can access the constants by 8 | * implementing the interface (slightly frowned upon in public code), or 9 | * paste this into their imports section:

10 | import static uk.co.farowl.vsj4.support.JavaClassShorthand.*;
11 |  *
12 | */ 13 | public interface JavaClassShorthand { 14 | /** Shorthand for {@code Object.class}. */ 15 | static final Class O = Object.class; 16 | /** Shorthand for {@code Class.class}. */ 17 | static final Class C = Class.class; 18 | /** Shorthand for {@code String.class}. */ 19 | static final Class S = String.class; 20 | /** Shorthand for {@code int.class}. */ 21 | static final Class I = int.class; 22 | /** Shorthand for {@code boolean.class}. */ 23 | static final Class B = boolean.class; 24 | /** Shorthand for {@code void.class}. */ 25 | static final Class V = void.class; 26 | /** Shorthand for {@code Object[].class}. */ 27 | static final Class OA = Object[].class; 28 | /** Shorthand for {@code String[].class}. */ 29 | static final Class SA = String[].class; 30 | } 31 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/support/MissingFeature.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.vsj4.support; 2 | 3 | /** 4 | * Thrown when we reach a combination of circumstances in the 5 | * interpreter that may arise from legitimate use, but we aren't ready 6 | * to implement it. 7 | */ 8 | public class MissingFeature extends InterpreterError { 9 | private static final long serialVersionUID = 1L; 10 | 11 | /** 12 | * Constructor specifying a message. 13 | * 14 | * @param msg a Java format string for the message 15 | * @param args to insert in the format string 16 | */ 17 | public MissingFeature(String msg, Object... args) { 18 | super(String.format("Missing feature: " + msg, args)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/support/ScopeKind.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2024 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.support; 4 | 5 | /** 6 | * The scope within which a method was found affects argument 7 | * processing, how it is processed for exposure, and how its signature 8 | * is presented in documentation. 9 | */ 10 | public enum ScopeKind { 11 | /** The method is for a module. */ 12 | MODULE("$module"), 13 | /** The method is for a type. */ 14 | TYPE("$self"); 15 | 16 | /** @param selfName appearance of self in a documentation string. */ 17 | ScopeKind(String selfName) { 18 | this.selfName = selfName; 19 | } 20 | 21 | /** Name of a "self" parameter in instance methods. */ 22 | public String selfName; 23 | } 24 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/support/internal/EmptyException.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2024 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.support.internal; 4 | 5 | /** 6 | * The type of exception thrown by invoking an "empty" 7 | * {@code MethodHandle} in the runtime system. By convention, we 8 | * initialise undefined method handles to a handle that throws this 9 | * exception. We may then invoke them without checking for {@code null}, 10 | * as long as we are prepared to catch {@code EmptyException}. 11 | *

12 | * The exception is "lightweight" (it comes with no message or stack 13 | * trace) so it must be caught close enough to the invocation that we 14 | * can still identify the cause. 15 | */ 16 | public class EmptyException extends Exception { 17 | /** 18 | * Constructor for (a small number of) anonymous instances. 19 | * Suppression and stack trace are disabled since this is nearly a 20 | * singleton. 21 | */ 22 | public EmptyException() { super(null, null, false, false); } 23 | 24 | private static final long serialVersionUID = 1L; 25 | } 26 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/support/internal/Util.java: -------------------------------------------------------------------------------- 1 | // Copyright (c)2024 Jython Developers. 2 | // Licensed to PSF under a contributor agreement. 3 | package uk.co.farowl.vsj4.support.internal; 4 | 5 | import java.lang.reflect.Array; 6 | 7 | /** 8 | * Convenient constants etc. for use across the implementation and not 9 | * needing the type system to be working. 10 | */ 11 | public class Util { 12 | /** An empty array of objects. */ 13 | public static final Object[] EMPTY_ARRAY = new Object[0]; 14 | /** An empty array of String. */ 15 | public static final String[] EMPTY_STRING_ARRAY = new String[0]; 16 | /** Single re-used instance of {@code EmptyException}. */ 17 | public static final EmptyException EMPTY_EXCEPTION = 18 | new EmptyException(); 19 | 20 | /** 21 | * Return a new array in which a given element is placed first, 22 | * followed by the elements of an existing array. 23 | * 24 | * @param Element type of the arrays 25 | * @param a0 first element of new array 26 | * @param a1plus rest of elements in new array 27 | * @return new copy array with first element inserted 28 | */ 29 | public static T[] prepend(T a0, T[] a1plus) { 30 | int n = a1plus.length; 31 | Class elemType = a1plus.getClass().getComponentType(); 32 | @SuppressWarnings("unchecked") 33 | T[] a = elemType == Object.class ? (T[])new Object[1 + n] 34 | : (T[])Array.newInstance(elemType, 1 + n); 35 | a[0] = a0; 36 | System.arraycopy(a1plus, 0, a, 1, n); 37 | return a; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/support/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code support.internal} package contains classes that support 3 | * the interpreter without requiring it to be initialised. 4 | * (Specifically, they may be used before the Python type system is in 5 | * working order, and without causing it to initialise.) 6 | *

7 | * This package is not exported. Classes {@code public} in this package 8 | * are accessible across the module, but not to client programs. Classes 9 | * belonging to this level should, for preference, be created here, then 10 | * carefully re-factored as it becomes necessary to make them API. 11 | */ 12 | package uk.co.farowl.vsj4.support.internal; 13 | -------------------------------------------------------------------------------- /rt4core/src/main/java/uk/co/farowl/vsj4/support/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The {@code base} package contains API classes that support the 3 | * interpreter without requiring it to be initialised. (Specifically, 4 | * they may be used before the Python type system is in working order, 5 | * and without causing it to initialise.) 6 | *

7 | * Classes {@code public} in this package are accessible to a client 8 | * application that {@code requires} the module in its module 9 | * declaration. 10 | */ 11 | package uk.co.farowl.vsj4.support; 12 | -------------------------------------------------------------------------------- /rt4core/src/main/javadoc/project-styles.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /* Styles supplementary to the standard Javadoc doclet. */ 4 | 5 | /* Table layout for framed data. */ 6 | table.framed-layout { 7 | border: 1px solid black; 8 | border-collapse: collapse; 9 | } 10 | 11 | table.framed-layout th, table.framed-layout td { 12 | border: 1px solid black; 13 | text-align: center; 14 | min-width: 2em; 15 | } 16 | 17 | table.framed-layout td.label { 18 | text-align: left; 19 | font-weight: bold; 20 | } -------------------------------------------------------------------------------- /rt4core/tools/python/template/__init__.py: -------------------------------------------------------------------------------- 1 | # template package: processing of template files 2 | 3 | # These classes support the processing of template files into 4 | # the Java class definitions that help realise Python objects 5 | # and their methods. 6 | 7 | from .base import ImplementationGenerator, TypeInfo, WorkingType, OpInfo 8 | from .PyFloat import PyFloatGenerator 9 | from .PyLong import PyLongGenerator 10 | from .PyUnicode import PyUnicodeGenerator 11 | 12 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * $projectDir/settings.gradle 3 | * 4 | * Settings file for multiproject build of very-slow-jython. 5 | */ 6 | 7 | rootProject.name = 'very-slow-jython' 8 | 9 | // Disabling docs for now as the plug-in doesn't build diagrams. 10 | //include 'docs' // narrative of the project 11 | 12 | include 'rt1' // model runtime phase 1 (using AST) 13 | include 'rt2' // model runtime phase 2 (using method handles) 14 | include 'rt2bm' // benchmarks for runtime phase 2 15 | include 'jy2bm' // benchmarks for Jython 2 (comparison) 16 | include 'dy2' // experimental extension to rt2 (using indy) 17 | include 'dy2bm' // benchmarks for runtime phase 2 (using indy) 18 | include 'rt3' // model runtime phase 3 (using java.lang.Object) 19 | include 'rt3bm' // benchmarks for runtime phase 3 20 | include 'dy3bm' // benchmarks for runtime phase 3 (using indy) 21 | include 'rt4core' // model runtime core phase 4 (modular API) 22 | include 'rt4client' // sample API client of rt4 23 | include 'idioms' // benchmarks for implementation idioms 24 | 25 | // Sub-project build files are named after the sub-project. 26 | 27 | rootProject.children.each { 28 | it.buildFileName = it.name + '.gradle' 29 | // println "" + it + " : " + it.buildFileName 30 | } 31 | 32 | 33 | // Tools used to generate or evaluate the runtime 34 | includeBuild 'vsj-tools' 35 | 36 | -------------------------------------------------------------------------------- /vsj-tools/settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * vsj-tools/settings.gradle 3 | * 4 | * Settings for an included build of very-slow-jython. 5 | */ 6 | 7 | rootProject.name = 'vsj-tools' 8 | 9 | rootProject.buildFileName = rootProject.name + '.gradle' 10 | -------------------------------------------------------------------------------- /vsj-tools/src/main/java/uk/co/farowl/asdl/ast/DefaultErrorHandler.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.asdl.ast; 2 | 3 | import uk.co.farowl.asdl.ast.AsdlTree.SemanticError; 4 | 5 | /** 6 | * An error handler for use by anything that processes the AST, and which counts and prints to 7 | * System.err the reported errors. 8 | */ 9 | public class DefaultErrorHandler implements ErrorHandler { 10 | 11 | /** Counter of errors. */ 12 | protected int errors; 13 | 14 | /** Constructor */ 15 | public DefaultErrorHandler() { 16 | errors = 0; 17 | } 18 | 19 | @Override 20 | public void report(SemanticError se) { 21 | errors += 1; 22 | System.err.println(se.getMessage()); 23 | } 24 | 25 | @Override 26 | public int getNumberOfErrors() { 27 | return errors; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /vsj-tools/src/main/java/uk/co/farowl/asdl/ast/ErrorHandler.java: -------------------------------------------------------------------------------- 1 | package uk.co.farowl.asdl.ast; 2 | 3 | /** Error handler as accepted by the AST processing and code generation classes. */ 4 | public interface ErrorHandler { 5 | 6 | /** 7 | * Report an error, specified as an exception. 8 | * 9 | * @param se the error 10 | */ 11 | void report(AsdlTree.SemanticError se); 12 | 13 | /** 14 | * Return cumulative total of errors reported. 15 | * 16 | * @return cumulative total 17 | */ 18 | int getNumberOfErrors(); 19 | } 20 | -------------------------------------------------------------------------------- /vsj-tools/src/test/resources/TestUserDefined.stg: -------------------------------------------------------------------------------- 1 | /* 2 | * Templates to test generation from the ASDL code tree. 3 | */ 4 | 5 | // Dump out some characteristics of the module 6 | main(command, asdlCodeRoot) ::= << 7 | Tool= 8 | File= 9 | name= 10 | >> 11 | 12 | // Check that a named template is correctly chosen 13 | test(command, asdlCodeRoot) ::= << 14 | [test] 15 | name= 16 | >> -------------------------------------------------------------------------------- /vsj-tools/src/test/resources/asdl.asdl: -------------------------------------------------------------------------------- 1 | -- ASDL specification in ASDL 2 | -- * = repetition, ? = optional, there is no + for one or more 3 | 4 | module Asdl { 5 | 6 | asdl_module = (identifier name, identifier* imports, asdl_type* defs) 7 | 8 | asdl_type = SumType(field*, constructor, constructor*) 9 | | ProductType(field, field*) 10 | attributes (identifier) 11 | 12 | constructor = Con(identifier, field*) 13 | 14 | field = Id | Option | Sequence 15 | attributes (identifier*, identifier?) 16 | 17 | } 18 | -------------------------------------------------------------------------------- /vsj-tools/src/test/resources/error/repeatDefinition.asdl: -------------------------------------------------------------------------------- 1 | module repeatDefinition { 2 | typea = (int x, int* y) attributes (string*dummy) 3 | typeb = A | B 4 | typea = Test1(typea x, typeb x) 5 | | Test2(typea z) 6 | attributes(string w) 7 | s1 = S1 | S2 | S3 | S1 | S5 8 | p1 = (s3* aa, int bb, s2 aa) 9 | s2 = Test1(int* a, int b, identifier a) 10 | | Test2(typea* a, typeb? b, typeb b, typea a) 11 | | Test1 12 | p2 = (typea cc, typeb dd, s3? ee) 13 | attributes(int* ff, int gg, s3? ff) 14 | s3 = T1(int f, int* g, string h) 15 | | T2(int h) 16 | attributes(typea i, typeb g, int j) 17 | p3 = (typea hh, typeb ii, s3? jj) 18 | attributes(int* kk, int ll, s3? ii) 19 | } 20 | -------------------------------------------------------------------------------- /vsj-tools/src/test/resources/error/syntaxError.asdl: -------------------------------------------------------------------------------- 1 | module syntaxError { 2 | typea = (int x int* y) attributes (string*dummy) 3 | typeb = A | B | 4 | ccc = Test1(typea x, typeb y) 5 | | (typea z) 6 | attributes(string w) 7 | } -------------------------------------------------------------------------------- /vsj-tools/src/test/resources/simple.asdl: -------------------------------------------------------------------------------- 1 | module simple { 2 | typea = (int x, int* y) attributes (string*dummy) 3 | typeb = A | B 4 | ccc = Test1(typea x, typeb y) 5 | | Test2(typea z) 6 | attributes(string w) 7 | } -------------------------------------------------------------------------------- /vsj-tools/vsj-tools.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * vsj-tools build file 3 | * 4 | * These are tools on which the Very Slow Jython Project depends at *build* 5 | * time, so this is structured as an independent build. It is included in the 6 | * main VSJ build through its settings file. 7 | */ 8 | 9 | plugins { 10 | id 'java' 11 | id 'antlr' 12 | id 'java-gradle-plugin' 13 | } 14 | 15 | description = 'Tools for Very Slow Jython' 16 | group = 'uk.co.farowl' 17 | version = '0.3.0-SNAPSHOT' 18 | 19 | 20 | repositories { 21 | mavenLocal() 22 | mavenCentral() 23 | } 24 | 25 | dependencies { 26 | antlr "org.antlr:antlr4:4.7" // use ANTLR version 4 27 | 28 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.+' 29 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.+' 30 | } 31 | 32 | 33 | generateGrammarSource { 34 | arguments += ["-visitor"] 35 | } 36 | 37 | 38 | 39 | gradlePlugin { 40 | plugins { 41 | asdlCompilerPlugin { 42 | id = 'uk.co.farowl.asdl.compiler' 43 | implementationClass = 'uk.co.farowl.asdl.gradle.ASDLPlugin' 44 | displayName = 'ASDL Compiler Plugin' 45 | description = 'Compile Abstract Syntax Description Language to Java' 46 | } 47 | } 48 | } 49 | 50 | --------------------------------------------------------------------------------